Finalize aappv2 data models migration
This commit is contained in:
13
modules/applications/sheets/_module.mjs
Normal file
13
modules/applications/sheets/_module.mjs
Normal file
@@ -0,0 +1,13 @@
|
||||
/**
|
||||
* Index des fiches AppV2 pour Maléfices
|
||||
*/
|
||||
// Actor sheets
|
||||
export { default as MaleficesPersonnageSheet } from './malefices-personnage-sheet.mjs';
|
||||
export { default as MaleficesNPCActorSheet } from './malefices-npc-actor-sheet.mjs';
|
||||
// Item sheets
|
||||
export { default as MaleficesArmeSheet } from './malefices-arme-sheet.mjs';
|
||||
export { default as MaleficesEquipementSheet } from './malefices-equipement-sheet.mjs';
|
||||
export { default as MaleficesArchetypeSheet } from './malefices-archetype-sheet.mjs';
|
||||
export { default as MaleficesTarotSheet } from './malefices-tarot-sheet.mjs';
|
||||
export { default as MaleficesSortilegeSheet } from './malefices-sortilege-sheet.mjs';
|
||||
export { default as MaleficesElementbioSheet } from './malefices-elementbio-sheet.mjs';
|
||||
132
modules/applications/sheets/base-item-sheet.mjs
Normal file
132
modules/applications/sheets/base-item-sheet.mjs
Normal file
@@ -0,0 +1,132 @@
|
||||
const { HandlebarsApplicationMixin } = foundry.applications.api
|
||||
|
||||
export default class MaleficesItemSheet extends HandlebarsApplicationMixin(foundry.applications.sheets.ItemSheetV2) {
|
||||
constructor(options = {}) {
|
||||
super(options)
|
||||
this.#dragDrop = this.#createDragDropHandlers()
|
||||
}
|
||||
|
||||
#dragDrop
|
||||
|
||||
/** @override */
|
||||
static DEFAULT_OPTIONS = {
|
||||
classes: ["fvtt-malefices", "item"],
|
||||
position: {
|
||||
width: 620,
|
||||
height: 600,
|
||||
},
|
||||
form: {
|
||||
submitOnChange: true,
|
||||
},
|
||||
window: {
|
||||
resizable: true,
|
||||
},
|
||||
dragDrop: [{ dragSelector: "[data-drag]", dropSelector: null }],
|
||||
actions: {
|
||||
editImage: MaleficesItemSheet.#onEditImage,
|
||||
postItem: MaleficesItemSheet.#onPostItem,
|
||||
},
|
||||
}
|
||||
|
||||
/** @type {object} */
|
||||
tabGroups = { primary: "description" }
|
||||
|
||||
/** @override */
|
||||
async _prepareContext() {
|
||||
const context = {
|
||||
fields: this.document.schema.fields,
|
||||
systemFields: this.document.system.schema.fields,
|
||||
item: this.document,
|
||||
system: this.document.system,
|
||||
source: this.document.toObject(),
|
||||
enrichedDescription: await foundry.applications.ux.TextEditor.implementation.enrichHTML(
|
||||
this.document.system.description ?? "", { async: true }
|
||||
),
|
||||
isEditable: this.isEditable,
|
||||
cssClass: this.isEditable ? "editable" : "locked",
|
||||
isGM: game.user.isGM,
|
||||
config: game.system.malefices.config,
|
||||
}
|
||||
return context
|
||||
}
|
||||
|
||||
/** @override */
|
||||
_onRender(context, options) {
|
||||
super._onRender(context, options)
|
||||
this.#dragDrop.forEach((d) => d.bind(this.element))
|
||||
|
||||
// Manual tab navigation
|
||||
const nav = this.element.querySelector('nav.tabs[data-group]')
|
||||
if (nav) {
|
||||
const group = nav.dataset.group
|
||||
const activeTab = this.tabGroups[group] || "description"
|
||||
nav.querySelectorAll('[data-tab]').forEach(link => {
|
||||
const tab = link.dataset.tab
|
||||
link.classList.toggle('active', tab === activeTab)
|
||||
link.addEventListener('click', (event) => {
|
||||
event.preventDefault()
|
||||
this.tabGroups[group] = tab
|
||||
this.render()
|
||||
})
|
||||
})
|
||||
this.element.querySelectorAll('[data-group="' + group + '"][data-tab]').forEach(content => {
|
||||
content.classList.toggle('active', content.dataset.tab === activeTab)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// #region Drag-and-Drop
|
||||
#createDragDropHandlers() {
|
||||
return this.options.dragDrop.map((d) => {
|
||||
d.permissions = {
|
||||
dragstart: this._canDragStart.bind(this),
|
||||
drop: this._canDragDrop.bind(this),
|
||||
}
|
||||
d.callbacks = {
|
||||
dragstart: this._onDragStart.bind(this),
|
||||
dragover: this._onDragOver.bind(this),
|
||||
drop: this._onDrop.bind(this),
|
||||
}
|
||||
return new foundry.applications.ux.DragDrop.implementation(d)
|
||||
})
|
||||
}
|
||||
|
||||
_canDragStart(selector) { return this.isEditable }
|
||||
_canDragDrop(selector) { return this.isEditable }
|
||||
|
||||
_onDragStart(event) {
|
||||
const dragData = { type: "Item", uuid: this.document.uuid }
|
||||
event.dataTransfer.setData("text/plain", JSON.stringify(dragData))
|
||||
}
|
||||
|
||||
_onDragOver(event) {}
|
||||
|
||||
async _onDrop(event) {}
|
||||
// #endregion
|
||||
|
||||
// #region Actions
|
||||
static async #onEditImage(event, target) {
|
||||
const fp = new FilePicker({
|
||||
type: "image",
|
||||
current: this.document.img,
|
||||
callback: (path) => { this.document.update({ img: path }) },
|
||||
})
|
||||
return fp.browse()
|
||||
}
|
||||
|
||||
static async #onPostItem(event, target) {
|
||||
let chatData = foundry.utils.duplicate(this.document)
|
||||
if (this.document.actor) {
|
||||
chatData.actor = { id: this.document.actor.id }
|
||||
}
|
||||
if (chatData.img?.includes("/blank.png")) {
|
||||
chatData.img = null
|
||||
}
|
||||
chatData.jsondata = JSON.stringify({ compendium: "postedItem", payload: chatData })
|
||||
const html = await foundry.applications.handlebars.renderTemplate(
|
||||
'systems/fvtt-malefices/templates/post-item.hbs', chatData
|
||||
)
|
||||
ChatMessage.create({ user: game.user.id, content: html })
|
||||
}
|
||||
// #endregion
|
||||
}
|
||||
35
modules/applications/sheets/malefices-archetype-sheet.mjs
Normal file
35
modules/applications/sheets/malefices-archetype-sheet.mjs
Normal file
@@ -0,0 +1,35 @@
|
||||
import MaleficesItemSheet from "./base-item-sheet.mjs"
|
||||
import { MaleficesUtility } from "../../malefices-utility.js"
|
||||
|
||||
export default class MaleficesArchetypeSheet extends MaleficesItemSheet {
|
||||
static DEFAULT_OPTIONS = {
|
||||
classes: ["archetype"],
|
||||
position: { width: 620 },
|
||||
window: { contentClasses: ["archetype-content"] },
|
||||
}
|
||||
|
||||
static PARTS = {
|
||||
main: { template: "systems/fvtt-malefices/templates/items/item-archetype-sheet.hbs" },
|
||||
}
|
||||
|
||||
tabGroups = { primary: "details" }
|
||||
|
||||
#getTabs() {
|
||||
const tabs = {
|
||||
details: { id: "details", group: "primary", label: "Détails" },
|
||||
description: { id: "description", group: "primary", label: "Description" },
|
||||
}
|
||||
for (const v of Object.values(tabs)) {
|
||||
v.active = this.tabGroups[v.group] === v.id
|
||||
v.cssClass = v.active ? "active" : ""
|
||||
}
|
||||
return tabs
|
||||
}
|
||||
|
||||
async _prepareContext() {
|
||||
const context = await super._prepareContext()
|
||||
context.tabs = this.#getTabs()
|
||||
context.tarots = MaleficesUtility.getTarots()
|
||||
return context
|
||||
}
|
||||
}
|
||||
33
modules/applications/sheets/malefices-arme-sheet.mjs
Normal file
33
modules/applications/sheets/malefices-arme-sheet.mjs
Normal file
@@ -0,0 +1,33 @@
|
||||
import MaleficesItemSheet from "./base-item-sheet.mjs"
|
||||
|
||||
export default class MaleficesArmeSheet extends MaleficesItemSheet {
|
||||
static DEFAULT_OPTIONS = {
|
||||
classes: ["arme"],
|
||||
position: { width: 640 },
|
||||
window: { contentClasses: ["arme-content"] },
|
||||
}
|
||||
|
||||
static PARTS = {
|
||||
main: { template: "systems/fvtt-malefices/templates/items/item-arme-sheet.hbs" },
|
||||
}
|
||||
|
||||
tabGroups = { primary: "details" }
|
||||
|
||||
#getTabs() {
|
||||
const tabs = {
|
||||
details: { id: "details", group: "primary", label: "Détails" },
|
||||
description: { id: "description", group: "primary", label: "Description" },
|
||||
}
|
||||
for (const v of Object.values(tabs)) {
|
||||
v.active = this.tabGroups[v.group] === v.id
|
||||
v.cssClass = v.active ? "active" : ""
|
||||
}
|
||||
return tabs
|
||||
}
|
||||
|
||||
async _prepareContext() {
|
||||
const context = await super._prepareContext()
|
||||
context.tabs = this.#getTabs()
|
||||
return context
|
||||
}
|
||||
}
|
||||
225
modules/applications/sheets/malefices-base-actor-sheet.mjs
Normal file
225
modules/applications/sheets/malefices-base-actor-sheet.mjs
Normal file
@@ -0,0 +1,225 @@
|
||||
const { HandlebarsApplicationMixin } = foundry.applications.api
|
||||
|
||||
import { MaleficesUtility } from "../../malefices-utility.js"
|
||||
|
||||
export default class MaleficesActorSheet extends HandlebarsApplicationMixin(foundry.applications.sheets.ActorSheetV2) {
|
||||
|
||||
constructor(options = {}) {
|
||||
super(options)
|
||||
this.#dragDrop = this.#createDragDropHandlers()
|
||||
this._editScore = true
|
||||
}
|
||||
|
||||
#dragDrop
|
||||
|
||||
/** @override */
|
||||
static DEFAULT_OPTIONS = {
|
||||
classes: ["fvtt-malefices", "actor"],
|
||||
position: {
|
||||
width: 640,
|
||||
height: 680,
|
||||
},
|
||||
form: {
|
||||
submitOnChange: true,
|
||||
},
|
||||
window: {
|
||||
resizable: true,
|
||||
},
|
||||
dragDrop: [{ dragSelector: ".item-list .item", dropSelector: null }],
|
||||
actions: {
|
||||
editImage: MaleficesActorSheet.#onEditImage,
|
||||
toggleSheet: MaleficesActorSheet.#onToggleSheet,
|
||||
editItem: MaleficesActorSheet.#onEditItem,
|
||||
deleteItem: MaleficesActorSheet.#onDeleteItem,
|
||||
createItem: MaleficesActorSheet.#onCreateItem,
|
||||
equipItem: MaleficesActorSheet.#onEquipItem,
|
||||
modifyQuantity: MaleficesActorSheet.#onModifyQuantity,
|
||||
modifyAmmo: MaleficesActorSheet.#onModifyAmmo,
|
||||
rollAttribut: MaleficesActorSheet.#onRollAttribut,
|
||||
rollArme: MaleficesActorSheet.#onRollArme,
|
||||
editSubActor: MaleficesActorSheet.#onEditSubActor,
|
||||
deleteSubActor: MaleficesActorSheet.#onDeleteSubActor,
|
||||
},
|
||||
}
|
||||
|
||||
/** @type {object} */
|
||||
tabGroups = { primary: "main" }
|
||||
|
||||
/** @override */
|
||||
async _prepareContext() {
|
||||
const actor = this.document
|
||||
return {
|
||||
actor,
|
||||
system: actor.system,
|
||||
source: actor.toObject(),
|
||||
fields: actor.schema.fields,
|
||||
systemFields: actor.system.schema.fields,
|
||||
isEditable: this.isEditable,
|
||||
cssClass: this.isEditable ? "editable" : "locked",
|
||||
isGM: game.user.isGM,
|
||||
config: game.system.malefices.config,
|
||||
editScore: this._editScore,
|
||||
}
|
||||
}
|
||||
|
||||
/** @override */
|
||||
_onRender(context, options) {
|
||||
super._onRender(context, options)
|
||||
this.#dragDrop.forEach((d) => d.bind(this.element))
|
||||
|
||||
// Ignore Enter key in text inputs (not textarea)
|
||||
this.element.addEventListener('keydown', (e) => {
|
||||
if (e.key === 'Enter' && e.target.tagName !== 'TEXTAREA') e.preventDefault()
|
||||
})
|
||||
|
||||
// Manual tab navigation
|
||||
const nav = this.element.querySelector('nav.tabs[data-group]')
|
||||
if (nav) {
|
||||
const group = nav.dataset.group
|
||||
const activeTab = this.tabGroups[group] || "main"
|
||||
nav.querySelectorAll('[data-tab]').forEach(link => {
|
||||
link.classList.toggle('active', link.dataset.tab === activeTab)
|
||||
link.addEventListener('click', (event) => {
|
||||
event.preventDefault()
|
||||
this.tabGroups[group] = link.dataset.tab
|
||||
this.render()
|
||||
})
|
||||
})
|
||||
this.element.querySelectorAll(`[data-group="${group}"][data-tab]`).forEach(content => {
|
||||
content.classList.toggle('active', content.dataset.tab === activeTab)
|
||||
})
|
||||
}
|
||||
|
||||
// Handle .update-field change events (legacy support)
|
||||
this.element.querySelectorAll('.update-field').forEach(el => {
|
||||
el.addEventListener('change', (ev) => {
|
||||
const fieldName = ev.currentTarget.dataset.fieldName
|
||||
const value = Number(ev.currentTarget.value)
|
||||
this.actor.update({ [fieldName]: value })
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
// #region Drag-and-Drop
|
||||
#createDragDropHandlers() {
|
||||
return this.options.dragDrop.map((d) => {
|
||||
d.permissions = {
|
||||
dragstart: this._canDragStart.bind(this),
|
||||
drop: this._canDragDrop.bind(this),
|
||||
}
|
||||
d.callbacks = {
|
||||
dragstart: this._onDragStart.bind(this),
|
||||
dragover: this._onDragOver.bind(this),
|
||||
drop: this._onDrop.bind(this),
|
||||
}
|
||||
return new foundry.applications.ux.DragDrop.implementation(d)
|
||||
})
|
||||
}
|
||||
|
||||
_canDragStart(selector) { return this.isEditable }
|
||||
_canDragDrop(selector) { return this.isEditable }
|
||||
|
||||
_onDragStart(event) {
|
||||
const li = event.currentTarget.closest('.item')
|
||||
if (!li) return
|
||||
const itemId = li.dataset.itemId
|
||||
const item = this.actor.items.get(itemId)
|
||||
if (item) {
|
||||
event.dataTransfer.setData("text/plain", JSON.stringify({ type: "Item", uuid: item.uuid }))
|
||||
}
|
||||
}
|
||||
|
||||
_onDragOver(event) {}
|
||||
|
||||
async _onDrop(event) {
|
||||
const data = foundry.applications.ux.TextEditor.implementation.getDragEventData(event)
|
||||
if (data?.type === "Actor") {
|
||||
const actor = await fromUuid(data.uuid)
|
||||
if (actor) this.actor.addSubActor(actor.id)
|
||||
} else {
|
||||
super._onDrop(event)
|
||||
}
|
||||
}
|
||||
// #endregion
|
||||
|
||||
// #region Actions
|
||||
static async #onEditImage(event, target) {
|
||||
const fp = new FilePicker({
|
||||
type: "image",
|
||||
current: this.document.img,
|
||||
callback: (path) => { this.document.update({ img: path }) },
|
||||
})
|
||||
return fp.browse()
|
||||
}
|
||||
|
||||
static async #onToggleSheet(event, target) {
|
||||
this._editScore = !this._editScore
|
||||
this.render()
|
||||
}
|
||||
|
||||
static async #onEditItem(event, target) {
|
||||
const li = target.closest(".item")
|
||||
const itemId = li?.dataset.itemId
|
||||
if (!itemId) return
|
||||
this.actor.items.get(itemId)?.sheet.render(true)
|
||||
}
|
||||
|
||||
static async #onDeleteItem(event, target) {
|
||||
const li = target.closest(".item")
|
||||
MaleficesUtility.confirmDelete(this, li)
|
||||
}
|
||||
|
||||
static async #onCreateItem(event, target) {
|
||||
const dataType = target.dataset.type
|
||||
this.actor.createEmbeddedDocuments('Item', [{ name: "NewItem", type: dataType }], { renderSheet: true })
|
||||
}
|
||||
|
||||
static async #onEquipItem(event, target) {
|
||||
const li = target.closest(".item")
|
||||
const itemId = li?.dataset.itemId
|
||||
if (!itemId) return
|
||||
await this.actor.equipItem(itemId)
|
||||
this.render()
|
||||
}
|
||||
|
||||
static async #onModifyQuantity(event, target) {
|
||||
const li = target.closest(".item")
|
||||
const itemId = li?.dataset.itemId
|
||||
if (!itemId) return
|
||||
const delta = parseInt(target.dataset.delta) || 0
|
||||
this.actor.incDecQuantity(itemId, delta)
|
||||
}
|
||||
|
||||
static async #onModifyAmmo(event, target) {
|
||||
const li = target.closest(".item")
|
||||
const itemId = li?.dataset.itemId
|
||||
if (!itemId) return
|
||||
const delta = parseInt(target.dataset.delta) || 0
|
||||
this.actor.incDecAmmo(itemId, delta)
|
||||
}
|
||||
|
||||
static async #onRollAttribut(event, target) {
|
||||
const attrKey = target.dataset.attrKey
|
||||
this.actor.rollAttribut(attrKey)
|
||||
}
|
||||
|
||||
static async #onRollArme(event, target) {
|
||||
const armeId = target.dataset.armeId
|
||||
this.actor.rollArme(armeId)
|
||||
}
|
||||
|
||||
static async #onEditSubActor(event, target) {
|
||||
const li = target.closest(".item")
|
||||
const actorId = li?.dataset.actorId
|
||||
if (!actorId) return
|
||||
game.actors.get(actorId)?.sheet.render(true)
|
||||
}
|
||||
|
||||
static async #onDeleteSubActor(event, target) {
|
||||
const li = target.closest(".item")
|
||||
const actorId = li?.dataset.actorId
|
||||
if (!actorId) return
|
||||
this.actor.delSubActor(actorId)
|
||||
}
|
||||
// #endregion
|
||||
}
|
||||
32
modules/applications/sheets/malefices-elementbio-sheet.mjs
Normal file
32
modules/applications/sheets/malefices-elementbio-sheet.mjs
Normal file
@@ -0,0 +1,32 @@
|
||||
import MaleficesItemSheet from "./base-item-sheet.mjs"
|
||||
|
||||
export default class MaleficesElementbioSheet extends MaleficesItemSheet {
|
||||
static DEFAULT_OPTIONS = {
|
||||
classes: ["elementbio"],
|
||||
position: { width: 620 },
|
||||
window: { contentClasses: ["elementbio-content"] },
|
||||
}
|
||||
|
||||
static PARTS = {
|
||||
main: { template: "systems/fvtt-malefices/templates/items/item-elementbio-sheet.hbs" },
|
||||
}
|
||||
|
||||
tabGroups = { primary: "description" }
|
||||
|
||||
#getTabs() {
|
||||
const tabs = {
|
||||
description: { id: "description", group: "primary", label: "Description" },
|
||||
}
|
||||
for (const v of Object.values(tabs)) {
|
||||
v.active = this.tabGroups[v.group] === v.id
|
||||
v.cssClass = v.active ? "active" : ""
|
||||
}
|
||||
return tabs
|
||||
}
|
||||
|
||||
async _prepareContext() {
|
||||
const context = await super._prepareContext()
|
||||
context.tabs = this.#getTabs()
|
||||
return context
|
||||
}
|
||||
}
|
||||
32
modules/applications/sheets/malefices-equipement-sheet.mjs
Normal file
32
modules/applications/sheets/malefices-equipement-sheet.mjs
Normal file
@@ -0,0 +1,32 @@
|
||||
import MaleficesItemSheet from "./base-item-sheet.mjs"
|
||||
|
||||
export default class MaleficesEquipementSheet extends MaleficesItemSheet {
|
||||
static DEFAULT_OPTIONS = {
|
||||
classes: ["equipement"],
|
||||
position: { width: 620 },
|
||||
window: { contentClasses: ["equipement-content"] },
|
||||
}
|
||||
|
||||
static PARTS = {
|
||||
main: { template: "systems/fvtt-malefices/templates/items/item-equipement-sheet.hbs" },
|
||||
}
|
||||
|
||||
tabGroups = { primary: "description" }
|
||||
|
||||
#getTabs() {
|
||||
const tabs = {
|
||||
description: { id: "description", group: "primary", label: "Description" },
|
||||
}
|
||||
for (const v of Object.values(tabs)) {
|
||||
v.active = this.tabGroups[v.group] === v.id
|
||||
v.cssClass = v.active ? "active" : ""
|
||||
}
|
||||
return tabs
|
||||
}
|
||||
|
||||
async _prepareContext() {
|
||||
const context = await super._prepareContext()
|
||||
context.tabs = this.#getTabs()
|
||||
return context
|
||||
}
|
||||
}
|
||||
27
modules/applications/sheets/malefices-npc-actor-sheet.mjs
Normal file
27
modules/applications/sheets/malefices-npc-actor-sheet.mjs
Normal file
@@ -0,0 +1,27 @@
|
||||
import MaleficesActorSheet from "./malefices-base-actor-sheet.mjs"
|
||||
|
||||
export default class MaleficesNPCActorSheet extends MaleficesActorSheet {
|
||||
|
||||
/** @override */
|
||||
static DEFAULT_OPTIONS = {
|
||||
classes: ["pnj"],
|
||||
position: { width: 560, height: 460 },
|
||||
}
|
||||
|
||||
/** @override */
|
||||
static PARTS = {
|
||||
main: { template: "systems/fvtt-malefices/templates/actors/npc-sheet.hbs" },
|
||||
}
|
||||
|
||||
/** @override */
|
||||
tabGroups = { primary: "main" }
|
||||
|
||||
/** @override */
|
||||
async _prepareContext() {
|
||||
const context = await super._prepareContext()
|
||||
context.enrichedDescription = await foundry.applications.ux.TextEditor.implementation.enrichHTML(
|
||||
this.document.system.description ?? "", { async: true }
|
||||
)
|
||||
return context
|
||||
}
|
||||
}
|
||||
48
modules/applications/sheets/malefices-personnage-sheet.mjs
Normal file
48
modules/applications/sheets/malefices-personnage-sheet.mjs
Normal file
@@ -0,0 +1,48 @@
|
||||
import MaleficesActorSheet from "./malefices-base-actor-sheet.mjs"
|
||||
|
||||
export default class MaleficesPersonnageSheet extends MaleficesActorSheet {
|
||||
|
||||
/** @override */
|
||||
static DEFAULT_OPTIONS = {
|
||||
classes: ["personnage"],
|
||||
position: { width: 640, height: 680 },
|
||||
}
|
||||
|
||||
/** @override */
|
||||
static PARTS = {
|
||||
main: { template: "systems/fvtt-malefices/templates/actors/actor-sheet.hbs" },
|
||||
}
|
||||
|
||||
/** @override */
|
||||
tabGroups = { primary: "main" }
|
||||
|
||||
/** @override */
|
||||
async _prepareContext() {
|
||||
const context = await super._prepareContext()
|
||||
const actor = this.document
|
||||
|
||||
context.armes = foundry.utils.duplicate(actor.getArmes())
|
||||
context.tarots = foundry.utils.duplicate(actor.getTarots())
|
||||
context.tarotsCache = foundry.utils.duplicate(actor.getHiddenTarots())
|
||||
context.archetype = foundry.utils.duplicate(actor.getArchetype())
|
||||
context.equipements = foundry.utils.duplicate(actor.getEquipements())
|
||||
context.elementsbio = actor.getElementsBio()
|
||||
context.sorts = actor.getSorts()
|
||||
context.phyMalus = actor.getPhysiqueMalus()
|
||||
context.subActors = foundry.utils.duplicate(actor.getSubActors())
|
||||
|
||||
// Expose nested biodata schema fields for {{formInput}} helper
|
||||
context.biodataFields = actor.system.schema.fields.biodata.fields
|
||||
|
||||
context.enrichedDescription = await foundry.applications.ux.TextEditor.implementation.enrichHTML(
|
||||
actor.system.biodata?.description ?? "", { async: true }
|
||||
)
|
||||
context.enrichedNotes = await foundry.applications.ux.TextEditor.implementation.enrichHTML(
|
||||
actor.system.biodata?.notes ?? "", { async: true }
|
||||
)
|
||||
context.enrichedEquipementlibre = await foundry.applications.ux.TextEditor.implementation.enrichHTML(
|
||||
actor.system.equipementlibre ?? "", { async: true }
|
||||
)
|
||||
return context
|
||||
}
|
||||
}
|
||||
33
modules/applications/sheets/malefices-sortilege-sheet.mjs
Normal file
33
modules/applications/sheets/malefices-sortilege-sheet.mjs
Normal file
@@ -0,0 +1,33 @@
|
||||
import MaleficesItemSheet from "./base-item-sheet.mjs"
|
||||
|
||||
export default class MaleficesSortilegeSheet extends MaleficesItemSheet {
|
||||
static DEFAULT_OPTIONS = {
|
||||
classes: ["sortilege"],
|
||||
position: { width: 620 },
|
||||
window: { contentClasses: ["sortilege-content"] },
|
||||
}
|
||||
|
||||
static PARTS = {
|
||||
main: { template: "systems/fvtt-malefices/templates/items/item-sortilege-sheet.hbs" },
|
||||
}
|
||||
|
||||
tabGroups = { primary: "details" }
|
||||
|
||||
#getTabs() {
|
||||
const tabs = {
|
||||
details: { id: "details", group: "primary", label: "Détails" },
|
||||
description: { id: "description", group: "primary", label: "Description" },
|
||||
}
|
||||
for (const v of Object.values(tabs)) {
|
||||
v.active = this.tabGroups[v.group] === v.id
|
||||
v.cssClass = v.active ? "active" : ""
|
||||
}
|
||||
return tabs
|
||||
}
|
||||
|
||||
async _prepareContext() {
|
||||
const context = await super._prepareContext()
|
||||
context.tabs = this.#getTabs()
|
||||
return context
|
||||
}
|
||||
}
|
||||
33
modules/applications/sheets/malefices-tarot-sheet.mjs
Normal file
33
modules/applications/sheets/malefices-tarot-sheet.mjs
Normal file
@@ -0,0 +1,33 @@
|
||||
import MaleficesItemSheet from "./base-item-sheet.mjs"
|
||||
|
||||
export default class MaleficesTarotSheet extends MaleficesItemSheet {
|
||||
static DEFAULT_OPTIONS = {
|
||||
classes: ["tarot"],
|
||||
position: { width: 660, height: 640 },
|
||||
window: { contentClasses: ["tarot-content"] },
|
||||
}
|
||||
|
||||
static PARTS = {
|
||||
main: { template: "systems/fvtt-malefices/templates/items/item-tarot-sheet.hbs" },
|
||||
}
|
||||
|
||||
tabGroups = { primary: "details" }
|
||||
|
||||
#getTabs() {
|
||||
const tabs = {
|
||||
details: { id: "details", group: "primary", label: "Détails" },
|
||||
description: { id: "description", group: "primary", label: "Description" },
|
||||
}
|
||||
for (const v of Object.values(tabs)) {
|
||||
v.active = this.tabGroups[v.group] === v.id
|
||||
v.cssClass = v.active ? "active" : ""
|
||||
}
|
||||
return tabs
|
||||
}
|
||||
|
||||
async _prepareContext() {
|
||||
const context = await super._prepareContext()
|
||||
context.tabs = this.#getTabs()
|
||||
return context
|
||||
}
|
||||
}
|
||||
@@ -389,8 +389,7 @@ export class MaleficesActor extends Actor {
|
||||
|
||||
/* -------------------------------------------- */
|
||||
async startRoll(rollData) {
|
||||
let rollDialog = await MaleficesRollDialog.create(this, rollData)
|
||||
rollDialog.render(true)
|
||||
await MaleficesRollDialog.create(this, rollData)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -125,7 +125,6 @@ export class MaleficesCommands {
|
||||
tirageData.secretCards.push({ name: "???", img: "systems/fvtt-malefices/images/tarots/background.webp" })
|
||||
|
||||
let tirageDialog = await MaleficesTirageTarotDialog.create(this, tirageData)
|
||||
tirageDialog.render(true)
|
||||
}
|
||||
}
|
||||
/* --------------------------------------------- */
|
||||
|
||||
@@ -80,20 +80,14 @@ export class MaleficesItemSheet extends foundry.appv1.sheets.ItemSheet {
|
||||
if (this.actor) {
|
||||
chatData.actor = { id: this.actor.id };
|
||||
}
|
||||
// Don't post any image for the item (which would leave a large gap) if the default image is used
|
||||
if (chatData.img.includes("/blank.png")) {
|
||||
if (chatData.img?.includes("/blank.png")) {
|
||||
chatData.img = null;
|
||||
}
|
||||
// JSON object for easy creation
|
||||
chatData.jsondata = JSON.stringify(
|
||||
{
|
||||
compendium: "postedItem",
|
||||
payload: chatData,
|
||||
});
|
||||
chatData.config = game.system.malefices.config
|
||||
chatData.jsondata = JSON.stringify({ compendium: "postedItem", payload: chatData })
|
||||
|
||||
renderTemplate('systems/Malefices/templates/post-item.html', chatData).then(html => {
|
||||
let chatOptions = MaleficesUtility.chatDataSetup(html);
|
||||
ChatMessage.create(chatOptions)
|
||||
foundry.applications.handlebars.renderTemplate('systems/fvtt-malefices/templates/post-item.hbs', chatData).then(html => {
|
||||
ChatMessage.create(MaleficesUtility.chatDataSetup(html))
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { MaleficesUtility } from "./malefices-utility.js";
|
||||
|
||||
export const defaultItemImg = {
|
||||
arme: "systems/fvtt-malefices/images/icons/arme.webp",
|
||||
arme: "systems/fvtt-malefices/images/icons/epee.webp",
|
||||
equipement: "systems/fvtt-malefices/images/icons/equipement.webp",
|
||||
elementbio: "systems/fvtt-malefices/images/icons/wisdom.webp",
|
||||
archetype: "systems/fvtt-malefices/images/icons/archetype.webp",
|
||||
|
||||
@@ -9,9 +9,6 @@
|
||||
/* -------------------------------------------- */
|
||||
// Import Modules
|
||||
import { MaleficesActor } from "./malefices-actor.js";
|
||||
import { MaleficesItemSheet } from "./malefices-item-sheet.js";
|
||||
import { MaleficesActorSheet } from "./malefices-actor-sheet.js";
|
||||
import { MaleficesNPCSheet } from "./malefices-npc-sheet.js";
|
||||
import { MaleficesUtility } from "./malefices-utility.js";
|
||||
import { MaleficesCombat } from "./malefices-combat.js";
|
||||
import { MaleficesItem } from "./malefices-item.js";
|
||||
@@ -20,6 +17,12 @@ import { MaleficesCharacterSummary } from "./malefices-summary-app.js"
|
||||
import { MALEFICES_CONFIG } from "./malefices-config.js"
|
||||
import { ClassCounter} from "https://www.uberwald.me/fvtt_appcount/count-class-ready.js"
|
||||
|
||||
// Import DataModels
|
||||
import * as models from "./models/index.mjs"
|
||||
|
||||
// Import AppV2 Sheets
|
||||
import * as sheets from "./applications/sheets/_module.mjs"
|
||||
|
||||
/* -------------------------------------------- */
|
||||
/* Foundry VTT Initialization */
|
||||
/* -------------------------------------------- */
|
||||
@@ -54,33 +57,51 @@ Hooks.once("init", async function () {
|
||||
// Define custom Entity classes
|
||||
CONFIG.Combat.documentClass = MaleficesCombat
|
||||
CONFIG.Actor.documentClass = MaleficesActor
|
||||
CONFIG.Actor.dataModels = {
|
||||
personnage: models.PersonnageDataModel,
|
||||
pnj: models.PnjDataModel
|
||||
}
|
||||
|
||||
CONFIG.Item.documentClass = MaleficesItem
|
||||
CONFIG.Item.dataModels = {
|
||||
arme: models.ArmeDataModel,
|
||||
equipement: models.EquipementDataModel,
|
||||
archetype: models.ArchetypeDataModel,
|
||||
tarot: models.TarotDataModel,
|
||||
sortilege: models.SortilegeDataModel,
|
||||
elementbio: models.ElementbioDataModel
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
// Register sheet application classes
|
||||
// Register AppV2 Actor Sheets
|
||||
foundry.documents.collections.Actors.unregisterSheet("core", foundry.appv1.sheets.ActorSheet);
|
||||
foundry.documents.collections.Actors.registerSheet("fvtt-malefices", MaleficesActorSheet, { types: ["personnage"], makeDefault: true });
|
||||
foundry.documents.collections.Actors.registerSheet("fvtt-malefices", MaleficesNPCSheet, { types: ["pnj"], makeDefault: false });
|
||||
foundry.documents.collections.Actors.registerSheet("fvtt-malefices", sheets.MaleficesPersonnageSheet, { types: ["personnage"], makeDefault: true });
|
||||
foundry.documents.collections.Actors.registerSheet("fvtt-malefices", sheets.MaleficesNPCActorSheet, { types: ["pnj"], makeDefault: true });
|
||||
|
||||
// Register AppV2 Item Sheets
|
||||
foundry.documents.collections.Items.unregisterSheet("core", foundry.appv1.sheets.ItemSheet);
|
||||
foundry.documents.collections.Items.registerSheet("fvtt-malefices", MaleficesItemSheet, { makeDefault: true });
|
||||
foundry.documents.collections.Items.registerSheet("fvtt-malefices", sheets.MaleficesArmeSheet, { types: ["arme"], makeDefault: true });
|
||||
foundry.documents.collections.Items.registerSheet("fvtt-malefices", sheets.MaleficesEquipementSheet, { types: ["equipement"], makeDefault: true });
|
||||
foundry.documents.collections.Items.registerSheet("fvtt-malefices", sheets.MaleficesArchetypeSheet, { types: ["archetype"], makeDefault: true });
|
||||
foundry.documents.collections.Items.registerSheet("fvtt-malefices", sheets.MaleficesTarotSheet, { types: ["tarot"], makeDefault: true });
|
||||
foundry.documents.collections.Items.registerSheet("fvtt-malefices", sheets.MaleficesSortilegeSheet, { types: ["sortilege"], makeDefault: true });
|
||||
foundry.documents.collections.Items.registerSheet("fvtt-malefices", sheets.MaleficesElementbioSheet, { types: ["elementbio"], makeDefault: true });
|
||||
|
||||
MaleficesUtility.init()
|
||||
|
||||
});
|
||||
|
||||
/* -------------------------------------------- */
|
||||
function welcomeMessage() {
|
||||
async function welcomeMessage() {
|
||||
if (game.user.isGM) {
|
||||
const content = await foundry.applications.handlebars.renderTemplate(
|
||||
'systems/fvtt-malefices/templates/chat/welcome-message.hbs', {}
|
||||
)
|
||||
ChatMessage.create({
|
||||
user: game.user.id,
|
||||
whisper: [game.user.id],
|
||||
content: `<div id="welcome-message-malefices"><span class="rdd-roll-part">
|
||||
<strong>Bienvenu dans Malefices, le JDR qui sent le souffre !</strong>
|
||||
<p>Le Livre de Base de Maléfices v4 est nécessaire pour jouer : https://arkhane-asylum.fr/en/malefices/</p>
|
||||
<p>Maléfices et un jeu de rôle publié par Arkhane Asylum Publishing, tout les droits leur appartiennent.</p>
|
||||
<p>Système développé par LeRatierBretonnien avec l'aide de la Dame du Lac et Malik, support sur le <a href="https://discord.gg/pPSDNJk">Discord FR de Foundry</a>.</p>
|
||||
<p>Commandes : /tirage pour le tirage des tarots, /carte pour tirer une simple carte et /resume pour le résumé des PJs (MJ seulement)` });
|
||||
content
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,91 +1,57 @@
|
||||
import { MaleficesUtility } from "./malefices-utility.js";
|
||||
|
||||
export class MaleficesRollDialog extends Dialog {
|
||||
export class MaleficesRollDialog {
|
||||
|
||||
/* -------------------------------------------- */
|
||||
static async create(actor, rollData) {
|
||||
const isCard = rollData?.attr?.iscard
|
||||
const template = isCard
|
||||
? 'systems/fvtt-malefices/templates/dialogs/confrontation-dialog.hbs'
|
||||
: 'systems/fvtt-malefices/templates/dialogs/roll-dialog-generic.hbs'
|
||||
|
||||
let options = { classes: ["MaleficesDialog"], width: 540, height: 'fit-content', 'z-index': 99999 }
|
||||
let html
|
||||
if (rollData?.attr?.iscard) {
|
||||
html = await foundry.applications.handlebars.renderTemplate('systems/fvtt-malefices/templates/dialogs/confrontation-dialog.hbs', rollData);
|
||||
} else {
|
||||
html = await foundry.applications.handlebars.renderTemplate('systems/fvtt-malefices/templates/dialogs/roll-dialog-generic.hbs', rollData);
|
||||
}
|
||||
const content = await foundry.applications.handlebars.renderTemplate(template, rollData)
|
||||
|
||||
return new MaleficesRollDialog(actor, rollData, html, options);
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
constructor(actor, rollData, html, options, close = undefined) {
|
||||
let isCard = rollData?.attr?.iscard
|
||||
let conf = {
|
||||
title: (isCard) ? "Jet" : "Tirage",
|
||||
content: html,
|
||||
buttons: {
|
||||
roll: {
|
||||
icon: '<i class="fas fa-check"></i>',
|
||||
label: (isCard) ? "Tirer une carte" : "Lancer le dé",
|
||||
callback: () => { this.roll() }
|
||||
},
|
||||
cancel: {
|
||||
icon: '<i class="fas fa-times"></i>',
|
||||
label: "Annuler",
|
||||
callback: () => { this.close() }
|
||||
}
|
||||
return foundry.applications.api.DialogV2.wait({
|
||||
window: {
|
||||
title: isCard ? "Tirage" : "Jet de dé",
|
||||
icon: isCard ? "fa-solid fa-layer-group" : "fa-solid fa-dice-d20",
|
||||
},
|
||||
close: close
|
||||
}
|
||||
|
||||
super(conf, options);
|
||||
|
||||
this.actor = actor;
|
||||
this.rollData = rollData;
|
||||
classes: ["malefices-roll-dialog"],
|
||||
position: { width: 540 },
|
||||
modal: false,
|
||||
rejectClose: false,
|
||||
content,
|
||||
buttons: [
|
||||
{
|
||||
action: "roll",
|
||||
label: isCard ? "Tirer une carte" : "Lancer le dé",
|
||||
icon: isCard ? "fa-solid fa-layer-group" : "fa-solid fa-check",
|
||||
default: true,
|
||||
callback: (event, button, dialog) => {
|
||||
MaleficesRollDialog._updateRollDataFromForm(rollData, button.form.elements)
|
||||
if (isCard) {
|
||||
MaleficesUtility.tirageConfrontationMalefices(rollData)
|
||||
} else {
|
||||
MaleficesUtility.rollMalefices(rollData)
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
action: "cancel",
|
||||
label: "Annuler",
|
||||
icon: "fa-solid fa-times",
|
||||
}
|
||||
],
|
||||
})
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
roll() {
|
||||
let isCard = this.rollData?.attr?.iscard
|
||||
if (isCard) {
|
||||
MaleficesUtility.tirageConfrontationMalefices(this.rollData)
|
||||
} else {
|
||||
MaleficesUtility.rollMalefices(this.rollData)
|
||||
}
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
async refreshDialog() {
|
||||
const content = await renderTemplate("systems/fvtt-malefices/templates/dialogs/roll-dialog-generic.hbs", this.rollData)
|
||||
this.data.content = content
|
||||
this.render(true)
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
activateListeners(html) {
|
||||
super.activateListeners(html);
|
||||
|
||||
function onLoad() {
|
||||
}
|
||||
$(function () { onLoad(); });
|
||||
|
||||
html.find('#bonusMalusSituation').change((event) => {
|
||||
this.rollData.bonusMalusSituation = Number(event.currentTarget.value)
|
||||
})
|
||||
html.find('#bonusMalusPerso').change((event) => {
|
||||
this.rollData.bonusMalusPerso = Number(event.currentTarget.value)
|
||||
})
|
||||
html.find('#bonusMalusDef').change((event) => {
|
||||
this.rollData.bonusMalusDef = Number(event.currentTarget.value)
|
||||
})
|
||||
html.find('#bonusMalusPortee').change((event) => {
|
||||
this.rollData.bonusMalusPortee = Number(event.currentTarget.value)
|
||||
})
|
||||
html.find('#confrontationDegre').change((event) => {
|
||||
this.rollData.confrontationDegre = Number(event.currentTarget.value)
|
||||
})
|
||||
html.find('#confrontationModif').change((event) => {
|
||||
this.rollData.confrontationModif = Number(event.currentTarget.value)
|
||||
})
|
||||
|
||||
static _updateRollDataFromForm(rollData, elements) {
|
||||
if (elements.bonusMalusPerso) rollData.bonusMalusPerso = Number(elements.bonusMalusPerso.value)
|
||||
if (elements.bonusMalusSituation) rollData.bonusMalusSituation = Number(elements.bonusMalusSituation.value)
|
||||
if (elements.bonusMalusDef) rollData.bonusMalusDef = Number(elements.bonusMalusDef.value)
|
||||
if (elements.bonusMalusPortee) rollData.bonusMalusPortee = Number(elements.bonusMalusPortee.value)
|
||||
if (elements.confrontationDegre) rollData.confrontationDegre = Number(elements.confrontationDegre.value)
|
||||
if (elements.confrontationModif) rollData.confrontationModif = Number(elements.confrontationModif.value)
|
||||
}
|
||||
}
|
||||
@@ -1,134 +1,133 @@
|
||||
/* -------------------------------------------- */
|
||||
import { MaleficesUtility } from "./malefices-utility.js";
|
||||
|
||||
const { HandlebarsApplicationMixin, ApplicationV2 } = foundry.applications.api
|
||||
|
||||
/* -------------------------------------------- */
|
||||
export class MaleficesCharacterSummary extends Application {
|
||||
export class MaleficesCharacterSummary extends HandlebarsApplicationMixin(ApplicationV2) {
|
||||
|
||||
/* -------------------------------------------- */
|
||||
static DEFAULT_OPTIONS = {
|
||||
id: "malefices-character-summary",
|
||||
classes: ["MaleficesDialog"],
|
||||
window: { title: "Résumé des Personnages", resizable: true },
|
||||
position: { width: 960, height: "auto" },
|
||||
dragDrop: [{ dragSelector: null, dropSelector: ".character-summary-container" }],
|
||||
}
|
||||
|
||||
static PARTS = {
|
||||
form: { template: "systems/fvtt-malefices/templates/dialogs/character-summary.hbs" }
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
static displayPCSummary() {
|
||||
if (game.user.isGM) {
|
||||
game.system.malefices.charSummary.render(true)
|
||||
game.system.malefices.charSummary.render({ force: true })
|
||||
} else {
|
||||
ui.notifications.info("Commande /tirage réservée au MJ !")
|
||||
ui.notifications.info("Commande /resume réservée au MJ !")
|
||||
}
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
updatePCSummary() {
|
||||
if (this.rendered) {
|
||||
this.render(true)
|
||||
if (this.element?.isConnected) {
|
||||
this.render({ force: true })
|
||||
}
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
static createSummaryPos() {
|
||||
return { top: 200, left: 200 };
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
static ready() {
|
||||
if (!game.user.isGM) { // Uniquement si GM
|
||||
if (!game.user.isGM) {
|
||||
return
|
||||
}
|
||||
let charSummary = new MaleficesCharacterSummary()
|
||||
game.system.malefices.charSummary = charSummary
|
||||
game.system.malefices.charSummary = new MaleficesCharacterSummary()
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
constructor() {
|
||||
super();
|
||||
//game.settings.set("world", "character-summary-data", {npcList: [], x:0, y:0})
|
||||
this.settings = game.settings.get("world", "character-summary-data")
|
||||
constructor(options = {}) {
|
||||
super(options)
|
||||
const saved = game.settings.get("world", "character-summary-data")
|
||||
this.extraList = saved.extraList ?? saved.npcList ?? []
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
static get defaultOptions() {
|
||||
return foundry.utils.mergeObject(super.defaultOptions, {
|
||||
template: "systems/fvtt-malefices/templates/dialogs/character-summary.hbs",
|
||||
popOut: true,
|
||||
resizable: true,
|
||||
dragDrop: [{ dragSelector: ".items-list .item", dropSelector: null }],
|
||||
classes: ["bol", "dialog"], width: 920, height: 'fit-content'
|
||||
async _prepareContext(_options) {
|
||||
const pcs = game.actors.filter(ac => ac.type === "personnage" && ac.hasPlayerOwner)
|
||||
const extras = []
|
||||
const validList = []
|
||||
for (const actorId of this.extraList) {
|
||||
const actor = game.actors.get(actorId)
|
||||
if (actor) { extras.push(actor); validList.push(actorId) }
|
||||
}
|
||||
if (validList.length !== this.extraList.length) {
|
||||
this.extraList = validList
|
||||
this._persist()
|
||||
}
|
||||
return { pcs, extras, config: game.system.malefices.config }
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
_onRender(_context, _options) {
|
||||
const el = this.element
|
||||
|
||||
el.querySelectorAll('.actor-open').forEach(a => {
|
||||
a.addEventListener('click', event => {
|
||||
const li = event.currentTarget.closest('.item')
|
||||
const actor = game.actors.get(li.dataset.actorId)
|
||||
actor?.sheet.render(true)
|
||||
})
|
||||
})
|
||||
|
||||
el.querySelectorAll('.summary-roll').forEach(a => {
|
||||
a.addEventListener('click', event => {
|
||||
const li = event.currentTarget.closest('.item')
|
||||
const actor = game.actors.get(li.dataset.actorId)
|
||||
const key = event.currentTarget.dataset.key
|
||||
actor?.rollAttribut(key)
|
||||
})
|
||||
})
|
||||
|
||||
el.querySelectorAll('.actor-delete').forEach(a => {
|
||||
a.addEventListener('click', event => {
|
||||
const li = event.currentTarget.closest('.item')
|
||||
this.extraList = this.extraList.filter(id => id !== li.dataset.actorId)
|
||||
this._persist()
|
||||
this.render({ force: true })
|
||||
})
|
||||
})
|
||||
|
||||
const dropZone = el.querySelector('.character-summary-container')
|
||||
if (dropZone) {
|
||||
dropZone.addEventListener('dragover', ev => ev.preventDefault())
|
||||
dropZone.addEventListener('drop', ev => { ev.stopPropagation(); this._onDrop(ev) })
|
||||
}
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
getData() {
|
||||
let formData = super.getData();
|
||||
_canDragDrop(_selector) { return true }
|
||||
|
||||
formData.pcs = game.actors.filter(ac => ac.type == "personnage" && ac.hasPlayerOwner)
|
||||
formData.npcs = []
|
||||
let newList = []
|
||||
let toUpdate = false
|
||||
for (let actorId of this.settings.npcList) {
|
||||
let actor = game.actors.get(actorId)
|
||||
if (actor) {
|
||||
formData.npcs.push(actor)
|
||||
newList.push(actorId)
|
||||
} else {
|
||||
toUpdate = true
|
||||
}
|
||||
}
|
||||
formData.config = game.system.malefices.config
|
||||
|
||||
if (toUpdate) {
|
||||
this.settings.npcList = newList
|
||||
//console.log("Going to update ...", this.settings)
|
||||
game.settings.set("world", "character-summary-data", this.settings)
|
||||
}
|
||||
|
||||
return formData
|
||||
/* -------------------------------------------- */
|
||||
_persist() {
|
||||
const saved = game.settings.get("world", "character-summary-data")
|
||||
game.settings.set("world", "character-summary-data", { ...saved, extraList: this.extraList })
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
updateNPC() {
|
||||
game.settings.set("world", "character-summary-data", game.system.malefices.charSummary.settings)
|
||||
game.system.malefices.charSummary.close()
|
||||
setTimeout(function () { game.system.malefices.charSummary.render(true) }, 500)
|
||||
_saveAndRefresh() {
|
||||
this.render({ force: true })
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
async _onDrop(event) {
|
||||
//console.log("Dragged data are : ", dragData)
|
||||
let data = event.dataTransfer.getData('text/plain')
|
||||
let dataItem = JSON.parse(data)
|
||||
let actor = fromUuidSync(dataItem.uuid)
|
||||
if (actor) {
|
||||
game.system.malefices.charSummary.settings.npcList.push(actor.id)
|
||||
game.system.malefices.charSummary.updateNPC()
|
||||
|
||||
} else {
|
||||
ui.notifications.warn("Pas d'acteur trouvé")
|
||||
}
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
/** @override */
|
||||
async activateListeners(html) {
|
||||
super.activateListeners(html);
|
||||
|
||||
html.find('.actor-open').click((event) => {
|
||||
const li = $(event.currentTarget).parents(".item")
|
||||
const actor = game.actors.get(li.data("actor-id"))
|
||||
actor.sheet.render(true)
|
||||
})
|
||||
|
||||
html.find('.summary-roll').click((event) => {
|
||||
const li = $(event.currentTarget).parents(".item")
|
||||
const actor = game.actors.get(li.data("actor-id"))
|
||||
let type = $(event.currentTarget).data("type")
|
||||
let key = $(event.currentTarget).data("key")
|
||||
actor.rollAttribut(key)
|
||||
})
|
||||
|
||||
html.find('.actor-delete').click(event => {
|
||||
const li = $(event.currentTarget).parents(".item");
|
||||
let actorId = li.data("actor-id")
|
||||
let newList = game.system.malefices.charSummary.settings.npcList.filter(id => id != actorId)
|
||||
game.system.malefices.charSummary.settings.npcList = newList
|
||||
game.system.malefices.charSummary.updateNPC()
|
||||
})
|
||||
|
||||
try {
|
||||
const dataItem = JSON.parse(event.dataTransfer.getData('text/plain'))
|
||||
const actor = fromUuidSync(dataItem.uuid)
|
||||
if (actor && !this.extraList.includes(actor.id)) {
|
||||
this.extraList.push(actor.id)
|
||||
this._persist()
|
||||
this.render({ force: true })
|
||||
}
|
||||
} catch(e) { /* not a valid drag payload */ }
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,155 +1,132 @@
|
||||
import { MaleficesUtility } from "./malefices-utility.js";
|
||||
|
||||
export class MaleficesTirageTarotDialog extends Dialog {
|
||||
const { HandlebarsApplicationMixin, ApplicationV2 } = foundry.applications.api
|
||||
|
||||
export class MaleficesTirageTarotDialog extends HandlebarsApplicationMixin(ApplicationV2) {
|
||||
|
||||
/* -------------------------------------------- */
|
||||
static async create(actor, tirageData) {
|
||||
static DEFAULT_OPTIONS = {
|
||||
id: "malefices-tirage-tarot",
|
||||
classes: ["MaleficesDialog"],
|
||||
window: { title: "Tirage des Tarots", resizable: true },
|
||||
position: { width: 720, height: 740 },
|
||||
}
|
||||
|
||||
let options = { classes: ["MaleficesDialog"], width: 720, height: 740, 'z-index': 99999 };
|
||||
let html = await foundry.applications.handlebars.renderTemplate('systems/fvtt-malefices/templates/dialogs/tirage-tarot-dialog.hbs', tirageData);
|
||||
|
||||
return new MaleficesTirageTarotDialog(actor, tirageData, html, options);
|
||||
static PARTS = {
|
||||
form: { template: 'systems/fvtt-malefices/templates/dialogs/tirage-tarot-dialog.hbs' }
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
constructor(actor, tirageData, html, options, close = undefined) {
|
||||
let conf = {
|
||||
title: "Tirage des tarots",
|
||||
content: html,
|
||||
buttons: {
|
||||
cancel: {
|
||||
icon: '<i class="fas fa-times"></i>',
|
||||
label: "Fermer/Annuler",
|
||||
callback: () => { this.close() }
|
||||
}
|
||||
},
|
||||
close: close
|
||||
}
|
||||
constructor(actor, tirageData, options = {}) {
|
||||
super(options)
|
||||
this.actor = actor
|
||||
this.tirageData = tirageData
|
||||
}
|
||||
|
||||
super(conf, options);
|
||||
/* -------------------------------------------- */
|
||||
static async create(actor, tirageData) {
|
||||
const app = new MaleficesTirageTarotDialog(actor, tirageData)
|
||||
app.render({ force: true })
|
||||
return app
|
||||
}
|
||||
|
||||
this.actor = actor;
|
||||
this.tirageData = tirageData;
|
||||
/* -------------------------------------------- */
|
||||
async _prepareContext(_options) {
|
||||
return { ...this.tirageData }
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
_onRender(_context, _options) {
|
||||
const el = this.element
|
||||
|
||||
el.querySelector('#playerId')?.addEventListener('change', (event) => {
|
||||
if (event.currentTarget.value !== "none") {
|
||||
this.tirageData.playerId = event.currentTarget.value
|
||||
this.processSelectedPlayer()
|
||||
}
|
||||
})
|
||||
|
||||
el.querySelector('#actorId')?.addEventListener('change', (event) => {
|
||||
if (event.currentTarget.value !== "none") {
|
||||
this.attributeToActor(event.currentTarget.value)
|
||||
}
|
||||
})
|
||||
|
||||
el.querySelector('.tirage-close-btn')?.addEventListener('click', () => this.close())
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
async sendCardRequest() {
|
||||
this.tirageData.state = 'waiting-user-card'
|
||||
let msg = await MaleficesUtility.createChatMessage(this.tirageData.user.name, "useronly", {
|
||||
content: await renderTemplate(`systems/fvtt-malefices/templates/chat/request-tarot-card.hbs`, this.tirageData)
|
||||
await MaleficesUtility.createChatMessage(this.tirageData.user.name, "useronly", {
|
||||
content: await foundry.applications.handlebars.renderTemplate(`systems/fvtt-malefices/templates/chat/request-tarot-card.hbs`, this.tirageData)
|
||||
})
|
||||
//msg.setFlag("world", "tirage-data", this.tirageData)
|
||||
console.log("MSG IS", msg)
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
drawCard() {
|
||||
let index = Math.round(Math.random() * (this.tirageData.deck.length-1))
|
||||
let index = Math.round(Math.random() * (this.tirageData.deck.length - 1))
|
||||
let selectedCard = this.tirageData.deck[index]
|
||||
selectedCard.system.ispositif = true
|
||||
if ( selectedCard.system.isdualside) { // Cas des cartes pouvant avoir 2 sens
|
||||
if (selectedCard.system.isdualside) {
|
||||
selectedCard.system.ispositif = (Math.random() > 0.5)
|
||||
}
|
||||
console.log("CARD SELECTED:", selectedCard)
|
||||
// Cas spécial de la Roue de la Fortune
|
||||
if ( selectedCard.name.toLowerCase().includes("fortune")) {
|
||||
if (selectedCard.name.toLowerCase().includes("fortune")) {
|
||||
this.tirageData.maxPlayerCard += 1
|
||||
this.tirageData.maxSecretCard += 1
|
||||
}
|
||||
let newList = []
|
||||
for(let card of this.tirageData.deck) {
|
||||
if (card.name != selectedCard.name) {
|
||||
newList.push(card)
|
||||
}
|
||||
}
|
||||
this.tirageData.deck = newList
|
||||
|
||||
this.tirageData.deck = this.tirageData.deck.filter(c => c.name !== selectedCard.name)
|
||||
return selectedCard
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
async addCard( msgId ) {
|
||||
async addCard(msgId) {
|
||||
MaleficesUtility.removeChatMessageId(msgId)
|
||||
|
||||
let selectedCard = this.drawCard()
|
||||
selectedCard.system.isgm = false
|
||||
await MaleficesUtility.createChatMessage(this.tirageData.user.name, "gmroll", {
|
||||
content: await renderTemplate(`systems/fvtt-malefices/templates/chat/display-tarot-card.hbs`, selectedCard)
|
||||
content: await foundry.applications.handlebars.renderTemplate(`systems/fvtt-malefices/templates/chat/display-tarot-card.hbs`, selectedCard)
|
||||
})
|
||||
if (this.tirageData.cards[0].name == "???") {
|
||||
this.tirageData.cards.shift()
|
||||
}
|
||||
if (this.tirageData.cards[0].name == "???") this.tirageData.cards.shift()
|
||||
this.tirageData.cards.push(selectedCard)
|
||||
this.tirageData.nbCard++
|
||||
|
||||
if (this.tirageData.nbCard == this.tirageData.maxPlayerCard) {
|
||||
for (let i=0; i<this.tirageData.maxSecretCard; i++) {
|
||||
let selectedCard = this.drawCard()
|
||||
selectedCard.system.isgm = true
|
||||
for (let i = 0; i < this.tirageData.maxSecretCard; i++) {
|
||||
let secretCard = this.drawCard()
|
||||
secretCard.system.isgm = true
|
||||
await MaleficesUtility.createChatMessage(this.tirageData.user.name, "blindroll", {
|
||||
content: await foundry.applications.handlebars.renderTemplate(`systems/fvtt-malefices/templates/chat/display-tarot-card.hbs`, selectedCard)
|
||||
content: await foundry.applications.handlebars.renderTemplate(`systems/fvtt-malefices/templates/chat/display-tarot-card.hbs`, secretCard)
|
||||
})
|
||||
if (this.tirageData.secretCards[0].name == "???") {
|
||||
this.tirageData.secretCards.shift()
|
||||
}
|
||||
this.tirageData.secretCards.push(selectedCard)
|
||||
if (this.tirageData.secretCards[0].name == "???") this.tirageData.secretCards.shift()
|
||||
this.tirageData.secretCards.push(secretCard)
|
||||
}
|
||||
this.tirageData.actors = foundry.utils.duplicate(game.actors)
|
||||
this.tirageData.state = 'attribute-to-actor'
|
||||
}else {
|
||||
} else {
|
||||
this.sendCardRequest()
|
||||
}
|
||||
this.refreshDialog()
|
||||
this.render({ force: true })
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
async processSelectedPlayer() {
|
||||
let user = game.users.get(this.tirageData.playerId)
|
||||
this.tirageData.user = user
|
||||
this.tirageData.user = game.users.get(this.tirageData.playerId)
|
||||
this.tirageData.players = null
|
||||
console.log("Going to work with ", user.name)
|
||||
game.system.malefices.currentTirage = this
|
||||
this.refreshDialog()
|
||||
this.render({ force: true })
|
||||
this.sendCardRequest()
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
attributeToActor(actorId) {
|
||||
let actor = game.actors.get(actorId)
|
||||
const actor = game.actors.get(actorId)
|
||||
if (actor) {
|
||||
actor.createEmbeddedDocuments('Item', this.tirageData.cards)
|
||||
actor.createEmbeddedDocuments('Item', this.tirageData.secretCards)
|
||||
ui.notifications.info("Les cartes ont été attribuées à " + actor.name)
|
||||
}
|
||||
}
|
||||
/* -------------------------------------------- */
|
||||
async refreshDialog() {
|
||||
const content = await foundry.applications.handlebars.renderTemplate("systems/fvtt-malefices/templates/dialogs/tirage-tarot-dialog.hbs", this.tirageData)
|
||||
this.data.content = content
|
||||
this.render(true)
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
activateListeners(html) {
|
||||
super.activateListeners(html);
|
||||
|
||||
let dialog = this;
|
||||
function onLoad() {
|
||||
}
|
||||
$(function () { onLoad(); });
|
||||
|
||||
html.find('#playerId').change((event) => {
|
||||
if ( event.currentTarget.value != "none") {
|
||||
dialog.tirageData.playerId = event.currentTarget.value
|
||||
dialog.processSelectedPlayer()
|
||||
}
|
||||
})
|
||||
html.find('#actorId').change((event) => {
|
||||
if ( event.currentTarget.value != "none") {
|
||||
let actorId = event.currentTarget.value
|
||||
dialog.attributeToActor(actorId)
|
||||
}
|
||||
})
|
||||
|
||||
}
|
||||
}
|
||||
@@ -56,7 +56,7 @@ export class MaleficesUtility {
|
||||
name: "character-summary-data",
|
||||
scope: "world",
|
||||
config: false,
|
||||
default: { npcList: [], x: 200, y: 200 },
|
||||
default: { extraList: [], x: 200, y: 200 },
|
||||
type: Object
|
||||
})
|
||||
|
||||
@@ -135,8 +135,13 @@ export class MaleficesUtility {
|
||||
|
||||
const templatePaths = [
|
||||
'systems/fvtt-malefices/templates/actors/editor-notes-gm.hbs',
|
||||
'systems/fvtt-malefices/templates/items/partial-item-header.hbs',
|
||||
'systems/fvtt-malefices/templates/items/partial-item-nav.hbs',
|
||||
'systems/fvtt-malefices/templates/items/partial-item-description.hbs'
|
||||
'systems/fvtt-malefices/templates/items/partial-item-description.hbs',
|
||||
'systems/fvtt-malefices/templates/post-item.hbs',
|
||||
'systems/fvtt-malefices/templates/actors/npc-sheet.hbs',
|
||||
'systems/fvtt-malefices/templates/chat/welcome-message.hbs',
|
||||
'systems/fvtt-malefices/templates/dialogs/character-summary.hbs'
|
||||
]
|
||||
return foundry.applications.handlebars.loadTemplates(templatePaths);
|
||||
}
|
||||
@@ -385,7 +390,7 @@ export class MaleficesUtility {
|
||||
rollData.total = selectedCard.value
|
||||
rollData.selectedCard = selectedCard
|
||||
await MaleficesUtility.createChatMessage(actor.name, "gmroll", {
|
||||
content: await renderTemplate(`systems/fvtt-malefices/templates/chat/display-tarot-card.hbs`, selectedCard)
|
||||
content: await foundry.applications.handlebars.renderTemplate(`systems/fvtt-malefices/templates/chat/display-tarot-card.hbs`, selectedCard)
|
||||
})
|
||||
|
||||
this.computeResults(rollData)
|
||||
@@ -399,7 +404,7 @@ export class MaleficesUtility {
|
||||
}
|
||||
|
||||
await MaleficesUtility.createChatMessage(actor.name, "gmroll", {
|
||||
content: await renderTemplate(`systems/fvtt-malefices/templates/chat/chat-confrontation-result.hbs`, rollData)
|
||||
content: await foundry.applications.handlebars.renderTemplate(`systems/fvtt-malefices/templates/chat/chat-confrontation-result.hbs`, rollData)
|
||||
})
|
||||
this.processSpecialCard(actor, rollData)
|
||||
}
|
||||
@@ -554,30 +559,16 @@ export class MaleficesUtility {
|
||||
|
||||
/* -------------------------------------------- */
|
||||
static async confirmDelete(actorSheet, li) {
|
||||
let itemId = li.data("item-id");
|
||||
let msgTxt = "<p>Are you sure to remove this Item ?";
|
||||
let buttons = {
|
||||
delete: {
|
||||
icon: '<i class="fas fa-check"></i>',
|
||||
label: "Yes, remove it",
|
||||
callback: () => {
|
||||
actorSheet.actor.deleteEmbeddedDocuments("Item", [itemId]);
|
||||
li.slideUp(200, () => actorSheet.render(false));
|
||||
}
|
||||
},
|
||||
cancel: {
|
||||
icon: '<i class="fas fa-times"></i>',
|
||||
label: "Cancel"
|
||||
}
|
||||
}
|
||||
msgTxt += "</p>";
|
||||
let d = new Dialog({
|
||||
title: "Confirm removal",
|
||||
content: msgTxt,
|
||||
buttons: buttons,
|
||||
default: "cancel"
|
||||
const itemId = li.dataset.itemId;
|
||||
const confirmed = await foundry.applications.api.DialogV2.confirm({
|
||||
window: { title: "Confirmer la suppression" },
|
||||
content: "<p>Supprimer cet objet ?</p>",
|
||||
yes: { label: "Supprimer", icon: "fas fa-trash" },
|
||||
no: { label: "Annuler", icon: "fas fa-times" },
|
||||
});
|
||||
d.render(true);
|
||||
if (confirmed) {
|
||||
actorSheet.actor.deleteEmbeddedDocuments("Item", [itemId]);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
12
modules/models/archetype.mjs
Normal file
12
modules/models/archetype.mjs
Normal file
@@ -0,0 +1,12 @@
|
||||
/**
|
||||
* Data model pour les archétypes
|
||||
*/
|
||||
export default class ArchetypeDataModel extends foundry.abstract.TypeDataModel {
|
||||
static defineSchema() {
|
||||
const fields = foundry.data.fields;
|
||||
return {
|
||||
lametutelaire: new fields.StringField({ initial: "" }),
|
||||
description: new fields.HTMLField({ initial: "" })
|
||||
};
|
||||
}
|
||||
}
|
||||
19
modules/models/arme.mjs
Normal file
19
modules/models/arme.mjs
Normal file
@@ -0,0 +1,19 @@
|
||||
/**
|
||||
* Data model pour les armes
|
||||
*/
|
||||
export default class ArmeDataModel extends foundry.abstract.TypeDataModel {
|
||||
static defineSchema() {
|
||||
const fields = foundry.data.fields;
|
||||
return {
|
||||
armetype: new fields.StringField({ initial: "" }),
|
||||
porteecourte: new fields.StringField({ initial: "" }),
|
||||
porteemoyenne: new fields.StringField({ initial: "" }),
|
||||
dommagenormale: new fields.NumberField({ initial: 0, integer: true }),
|
||||
dommagepart: new fields.NumberField({ initial: 0, integer: true }),
|
||||
dommagecritique: new fields.NumberField({ initial: 0, integer: true }),
|
||||
dommagecritiqueKO: new fields.BooleanField({ initial: false }),
|
||||
dommagecritiquemort: new fields.BooleanField({ initial: false }),
|
||||
description: new fields.HTMLField({ initial: "" })
|
||||
};
|
||||
}
|
||||
}
|
||||
11
modules/models/elementbio.mjs
Normal file
11
modules/models/elementbio.mjs
Normal file
@@ -0,0 +1,11 @@
|
||||
/**
|
||||
* Data model pour les éléments biographiques
|
||||
*/
|
||||
export default class ElementbioDataModel extends foundry.abstract.TypeDataModel {
|
||||
static defineSchema() {
|
||||
const fields = foundry.data.fields;
|
||||
return {
|
||||
description: new fields.HTMLField({ initial: "" })
|
||||
};
|
||||
}
|
||||
}
|
||||
11
modules/models/equipement.mjs
Normal file
11
modules/models/equipement.mjs
Normal file
@@ -0,0 +1,11 @@
|
||||
/**
|
||||
* Data model pour les équipements
|
||||
*/
|
||||
export default class EquipementDataModel extends foundry.abstract.TypeDataModel {
|
||||
static defineSchema() {
|
||||
const fields = foundry.data.fields;
|
||||
return {
|
||||
description: new fields.HTMLField({ initial: "" })
|
||||
};
|
||||
}
|
||||
}
|
||||
15
modules/models/index.mjs
Normal file
15
modules/models/index.mjs
Normal file
@@ -0,0 +1,15 @@
|
||||
/**
|
||||
* Index des DataModels pour Maléfices
|
||||
*/
|
||||
|
||||
// Modèles d'acteurs
|
||||
export { default as PersonnageDataModel } from './personnage.mjs';
|
||||
export { default as PnjDataModel } from './pnj.mjs';
|
||||
|
||||
// Modèles d'items
|
||||
export { default as ArmeDataModel } from './arme.mjs';
|
||||
export { default as EquipementDataModel } from './equipement.mjs';
|
||||
export { default as ArchetypeDataModel } from './archetype.mjs';
|
||||
export { default as TarotDataModel } from './tarot.mjs';
|
||||
export { default as SortilegeDataModel } from './sortilege.mjs';
|
||||
export { default as ElementbioDataModel } from './elementbio.mjs';
|
||||
95
modules/models/personnage.mjs
Normal file
95
modules/models/personnage.mjs
Normal file
@@ -0,0 +1,95 @@
|
||||
/**
|
||||
* Data model pour les personnages joueurs (type "personnage")
|
||||
*/
|
||||
export default class PersonnageDataModel extends foundry.abstract.TypeDataModel {
|
||||
static defineSchema() {
|
||||
const fields = foundry.data.fields;
|
||||
return {
|
||||
// Template biodata
|
||||
biodata: new fields.SchemaField({
|
||||
age: new fields.NumberField({ initial: 0, integer: true }),
|
||||
size: new fields.StringField({ initial: "" }),
|
||||
lieunaissance: new fields.StringField({ initial: "" }),
|
||||
nationalite: new fields.StringField({ initial: "" }),
|
||||
profession: new fields.StringField({ initial: "" }),
|
||||
residence: new fields.StringField({ initial: "" }),
|
||||
milieusocial: new fields.StringField({ initial: "" }),
|
||||
poids: new fields.StringField({ initial: "" }),
|
||||
cheveux: new fields.StringField({ initial: "" }),
|
||||
sexe: new fields.StringField({ initial: "" }),
|
||||
yeux: new fields.StringField({ initial: "" }),
|
||||
enfance: new fields.StringField({ initial: "" }),
|
||||
adulte: new fields.StringField({ initial: "" }),
|
||||
loisirs: new fields.StringField({ initial: "" }),
|
||||
singularite: new fields.StringField({ initial: "" }),
|
||||
politique: new fields.StringField({ initial: "" }),
|
||||
religion: new fields.StringField({ initial: "" }),
|
||||
fantastique: new fields.StringField({ initial: "" }),
|
||||
description: new fields.HTMLField({ initial: "" }),
|
||||
notes: new fields.HTMLField({ initial: "" }),
|
||||
gmnotes: new fields.HTMLField({ initial: "" })
|
||||
}),
|
||||
// Template core
|
||||
subactors: new fields.ArrayField(new fields.StringField(), { initial: [] }),
|
||||
lamesdestin: new fields.ArrayField(new fields.StringField(), { initial: [] }),
|
||||
pointdestin: new fields.NumberField({ initial: 1, integer: true }),
|
||||
fluide: new fields.NumberField({ initial: 5, integer: true }),
|
||||
mpmb: new fields.NumberField({ initial: 0, integer: true }),
|
||||
mpmn: new fields.NumberField({ initial: 0, integer: true }),
|
||||
equipementlibre: new fields.HTMLField({ initial: "" }),
|
||||
attributs: new fields.SchemaField({
|
||||
constitution: new fields.SchemaField({
|
||||
label: new fields.StringField({ initial: "Constitution" }),
|
||||
abbrev: new fields.StringField({ initial: "constitution" }),
|
||||
value: new fields.NumberField({ initial: 0, integer: true }),
|
||||
hasmax: new fields.BooleanField({ initial: true }),
|
||||
max: new fields.NumberField({ initial: 0, integer: true })
|
||||
}),
|
||||
physique: new fields.SchemaField({
|
||||
label: new fields.StringField({ initial: "Aptitudes Physiques" }),
|
||||
abbrev: new fields.StringField({ initial: "physique" }),
|
||||
value: new fields.NumberField({ initial: 0, integer: true }),
|
||||
hasmax: new fields.BooleanField({ initial: false }),
|
||||
max: new fields.NumberField({ initial: 0, integer: true })
|
||||
}),
|
||||
culturegenerale: new fields.SchemaField({
|
||||
label: new fields.StringField({ initial: "Culture Générale" }),
|
||||
abbrev: new fields.StringField({ initial: "culturegenerale" }),
|
||||
value: new fields.NumberField({ initial: 0, integer: true }),
|
||||
hasmax: new fields.BooleanField({ initial: false }),
|
||||
max: new fields.NumberField({ initial: 0, integer: true })
|
||||
}),
|
||||
habilite: new fields.SchemaField({
|
||||
label: new fields.StringField({ initial: "Habilité" }),
|
||||
abbrev: new fields.StringField({ initial: "habilite" }),
|
||||
value: new fields.NumberField({ initial: 0, integer: true }),
|
||||
hasmax: new fields.BooleanField({ initial: false }),
|
||||
max: new fields.NumberField({ initial: 0, integer: true })
|
||||
}),
|
||||
perception: new fields.SchemaField({
|
||||
label: new fields.StringField({ initial: "Perception" }),
|
||||
abbrev: new fields.StringField({ initial: "perception" }),
|
||||
value: new fields.NumberField({ initial: 0, integer: true }),
|
||||
hasmax: new fields.BooleanField({ initial: false }),
|
||||
max: new fields.NumberField({ initial: 0, integer: true })
|
||||
}),
|
||||
spiritualite: new fields.SchemaField({
|
||||
label: new fields.StringField({ initial: "Spiritualite" }),
|
||||
abbrev: new fields.StringField({ initial: "spiritualite" }),
|
||||
value: new fields.NumberField({ initial: 0, integer: true }),
|
||||
hasmax: new fields.BooleanField({ initial: false }),
|
||||
iscard: new fields.BooleanField({ initial: true }),
|
||||
max: new fields.NumberField({ initial: 0, integer: true })
|
||||
}),
|
||||
rationnalite: new fields.SchemaField({
|
||||
label: new fields.StringField({ initial: "Rationnalite" }),
|
||||
abbrev: new fields.StringField({ initial: "rationnalite" }),
|
||||
value: new fields.NumberField({ initial: 0, integer: true }),
|
||||
hasmax: new fields.BooleanField({ initial: false }),
|
||||
iscard: new fields.BooleanField({ initial: true }),
|
||||
max: new fields.NumberField({ initial: 0, integer: true })
|
||||
})
|
||||
})
|
||||
};
|
||||
}
|
||||
}
|
||||
12
modules/models/pnj.mjs
Normal file
12
modules/models/pnj.mjs
Normal file
@@ -0,0 +1,12 @@
|
||||
/**
|
||||
* Data model pour les PNJ (type "pnj")
|
||||
*/
|
||||
export default class PnjDataModel extends foundry.abstract.TypeDataModel {
|
||||
static defineSchema() {
|
||||
const fields = foundry.data.fields;
|
||||
return {
|
||||
npctype: new fields.StringField({ initial: "" }),
|
||||
description: new fields.HTMLField({ initial: "" })
|
||||
};
|
||||
}
|
||||
}
|
||||
12
modules/models/sortilege.mjs
Normal file
12
modules/models/sortilege.mjs
Normal file
@@ -0,0 +1,12 @@
|
||||
/**
|
||||
* Data model pour les sortilèges
|
||||
*/
|
||||
export default class SortilegeDataModel extends foundry.abstract.TypeDataModel {
|
||||
static defineSchema() {
|
||||
const fields = foundry.data.fields;
|
||||
return {
|
||||
seuil: new fields.NumberField({ initial: 0, integer: true }),
|
||||
description: new fields.HTMLField({ initial: "" })
|
||||
};
|
||||
}
|
||||
}
|
||||
17
modules/models/tarot.mjs
Normal file
17
modules/models/tarot.mjs
Normal file
@@ -0,0 +1,17 @@
|
||||
/**
|
||||
* Data model pour les lames de tarot
|
||||
*/
|
||||
export default class TarotDataModel extends foundry.abstract.TypeDataModel {
|
||||
static defineSchema() {
|
||||
const fields = foundry.data.fields;
|
||||
return {
|
||||
tarottype: new fields.StringField({ initial: "" }),
|
||||
numericvalueup: new fields.NumberField({ initial: 0, integer: true }),
|
||||
numericvaluedown: new fields.NumberField({ initial: 0, integer: true }),
|
||||
isdualside: new fields.BooleanField({ initial: false }),
|
||||
ispositif: new fields.BooleanField({ initial: true }),
|
||||
isgm: new fields.BooleanField({ initial: false }),
|
||||
description: new fields.HTMLField({ initial: "" })
|
||||
};
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user