Migration vers DataModels et appv2

This commit is contained in:
2026-01-10 22:49:38 +01:00
parent 6066091d8d
commit b1bce86604
96 changed files with 216 additions and 5420 deletions

View File

@@ -1,26 +0,0 @@
/**
* Extend the basic ActorSheet with some very simple modifications
* @extends {ActorSheet}
*/
import { HeritiersActorSheet } from "./heritiers-actor-sheet.js";
import { HeritiersUtility } from "./heritiers-utility.js";
/* -------------------------------------------- */
export class HeritiersActorPNJSheet extends HeritiersActorSheet {
/** @override */
static get defaultOptions() {
return foundry.utils.mergeObject(super.defaultOptions, {
classes: ["fvtt-les-heritiers", "sheet", "actor"],
template: "systems/fvtt-les-heritiers/templates/actor-pnj-sheet.html",
width: 780,
height: 840,
tabs: [{ navSelector: ".sheet-tabs", contentSelector: ".sheet-body", initial: "stats" }],
dragDrop: [{ dragSelector: ".item-list .item", dropSelector: null }],
editScore: false
})
}
}

View File

@@ -1,277 +0,0 @@
/**
* Extend the basic ActorSheet with some very simple modifications
* @extends {ActorSheet}
*/
import { HeritiersUtility } from "./heritiers-utility.js";
/* -------------------------------------------- */
export class HeritiersActorSheet extends foundry.appv1.sheets.ActorSheet {
/** @override */
static get defaultOptions() {
return foundry.utils.mergeObject(super.defaultOptions, {
classes: ["fvtt-les-heritiers", "sheet", "actor"],
template: "systems/fvtt-les-heritiers/templates/actor-sheet.html",
width: 780,
height: 840,
tabs: [{ navSelector: ".sheet-tabs", contentSelector: ".sheet-body", initial: "stats" }],
dragDrop: [{ dragSelector: ".item-list .item", dropSelector: null }],
editScore: false
})
}
/* -------------------------------------------- */
async getData() {
const objectData = foundry.utils.duplicate(this.object)
let formData = {
title: this.title,
id: objectData.id,
type: objectData.type,
img: objectData.img,
name: objectData.name,
editable: this.isEditable,
cssClass: this.isEditable ? "editable" : "locked",
system: objectData.system,
effects: this.object.effects.map(e => foundry.utils.deepClone(e.data)),
limited: this.object.limited,
skills: this.actor.getSkills(),
utileSkillsMental: this.actor.organizeUtileSkills("mental"),
utileSkillsPhysical: this.actor.organizeUtileSkills("physical"),
competencesMagie: HeritiersUtility.getCompetencesMagie(),
futileSkills: this.actor.organizeFutileSkills(),
contacts: this.actor.organizeContacts(),
armes: foundry.utils.duplicate(this.actor.getWeapons()),
monnaies: foundry.utils.duplicate(this.actor.getMonnaies()),
pouvoirs: foundry.utils.duplicate(this.actor.getPouvoirs()),
fee: foundry.utils.duplicate(this.actor.getFee() || {}),
protections: foundry.utils.duplicate(this.actor.getArmors()),
combat: this.actor.getCombatValues(),
equipements: foundry.utils.duplicate(this.actor.getEquipments()),
avantages: foundry.utils.duplicate(this.actor.getAvantages()),
atouts: foundry.utils.duplicate(this.actor.getAtouts()),
capacites: foundry.utils.duplicate(this.actor.getCapacites()),
desavantages: foundry.utils.duplicate(this.actor.getDesavantages()),
profils: foundry.utils.duplicate(this.actor.getProfils()),
pvMalus: this.actor.getPvMalus(),
heritage: game.settings.get("fvtt-les-heritiers", "heritiers-heritage"),
initiative: this.actor.getFlag("world", "last-initiative") || -1,
description: await foundry.applications.ux.TextEditor.implementation.enrichHTML(this.object.system.biodata.description, { async: true }),
revesetranges: await foundry.applications.ux.TextEditor.implementation.enrichHTML(this.object.system.biodata.revesetranges, { async: true }),
secretsdecouverts: await foundry.applications.ux.TextEditor.implementation.enrichHTML(this.object.system.biodata.secretsdecouverts, { async: true }),
questions: await foundry.applications.ux.TextEditor.implementation.enrichHTML(this.object.system.biodata.questions, { async: true }),
habitat: await foundry.applications.ux.TextEditor.implementation.enrichHTML(this.object.system.biodata.habitat, { async: true }),
playernotes: await foundry.applications.ux.TextEditor.implementation.enrichHTML(this.object.system.biodata.playernotes, { async: true }),
magieList: this.actor.prepareMagie(),
options: this.options,
owner: this.document.isOwner,
editScore: this.options.editScore,
config: game.system.lesheritiers.config,
isGM: game.user.isGM,
isPNJ: (this.actor.type == "pnj")
}
this.formData = formData;
console.log("PC : ", formData, this.object);
return formData;
}
/* -------------------------------------------- */
dialogRecupUsage() {
new Dialog({
title: "Récupération des Points d'Usage",
content: "<p>Combien de Points d'Usage souhaitez-vous récupérer ?</p>",
buttons: {
one: {
icon: '<i class="fas fa-check"></i>',
label: "1 Point",
callback: () => {
this.actor.recupUsage(1)
}
},
two: {
icon: '<i class="fas fa-check"></i>',
label: "2 Points",
callback: () => {
this.actor.recupUsage(2)
}
},
four: {
icon: '<i class="fas fa-check"></i>',
label: "4 Points",
callback: () => {
this.actor.recupUsage(4)
}
},
all: {
icon: '<i class="fas fa-check"></i>',
label: "Tous les Points",
callback: () => {
this.actor.recupUsage(100)
}
}
}
}).render(true)
}
/* -------------------------------------------- */
/** @override */
activateListeners(html) {
super.activateListeners(html);
// Everything below here is only needed if the sheet is editable
if (!this.options.editable) return;
// Update Inventory Item
html.find('.item-edit').click(ev => {
const li = $(ev.currentTarget).parents(".item")
let itemId = li.data("item-id")
const item = this.actor.items.get(itemId)
item.sheet.render(true)
})
// Delete Inventory Item
html.find('.item-delete').click(ev => {
const li = $(ev.currentTarget).parents(".item");
HeritiersUtility.confirmDelete(this, li);
})
html.find('.edit-item-data').change(ev => {
const li = $(ev.currentTarget).parents(".item")
let itemId = li.data("item-id")
let itemType = li.data("item-type")
let itemField = $(ev.currentTarget).data("item-field")
let dataType = $(ev.currentTarget).data("dtype")
let value = ev.currentTarget.value
this.actor.editItemField(itemId, itemType, itemField, dataType, value)
})
html.find('.adversite-modify').click(event => {
const li = $(event.currentTarget).parents(".item")
let adv = li.data("adversite")
let value = Number($(event.currentTarget).data("adversite-value"))
this.actor.incDecAdversite(adv, value)
})
html.find('.quantity-modify').click(event => {
const li = $(event.currentTarget).parents(".item")
const value = Number($(event.currentTarget).data("quantite-value"))
this.actor.incDecQuantity(li.data("item-id"), value);
})
html.find('[data-action="quantityIncrease"]').click(event => {
event.preventDefault()
event.stopPropagation()
const li = $(event.currentTarget).parents(".item")
this.actor.incDecQuantity(li.data("item-id"), 1);
})
html.find('[data-action="quantityDecrease"]').click(event => {
event.preventDefault()
event.stopPropagation()
const li = $(event.currentTarget).parents(".item")
this.actor.incDecQuantity(li.data("item-id"), -1);
})
html.find('.roll-initiative').click((event) => {
this.actor.rollInitiative()
})
html.find('.roll-carac').click((event) => {
const key = $(event.currentTarget).data("key")
this.actor.rollCarac(key, false)
})
html.find('.roll-rang').click((event) => {
const key = $(event.currentTarget).data("rang-key")
this.actor.rollRang(key, false)
})
html.find('.roll-root-competence').click((event) => {
const compKey = $(event.currentTarget).data("attr-key")
this.actor.rollRootCompetence(compKey)
})
html.find('.roll-competence').click((event) => {
const li = $(event.currentTarget).parents(".item")
let compId = li.data("item-id")
this.actor.rollCompetence(compId)
})
html.find('.roll-sort').click((event) => {
const li = $(event.currentTarget).parents(".item")
let sortId = li.data("item-id")
this.actor.rollSort(sortId)
})
html.find('.roll-attaque-arme').click((event) => {
const li = $(event.currentTarget).parents(".item")
let armeId = li.data("item-id")
this.actor.rollAttaqueArme(armeId)
})
html.find('.roll-attaque-brutale-arme').click((event) => {
const li = $(event.currentTarget).parents(".item")
let armeId = li.data("item-id")
this.actor.rollAttaqueBrutaleArme(armeId)
})
html.find('.roll-attaque-charge-arme').click((event) => {
const li = $(event.currentTarget).parents(".item")
let armeId = li.data("item-id")
this.actor.rollAttaqueChargeArme(armeId)
})
html.find('.roll-assomer-arme').click((event) => {
const li = $(event.currentTarget).parents(".item")
let armeId = li.data("item-id")
this.actor.rollAssomerArme(armeId)
})
html.find('.roll-pouvoir').click((event) => {
const li = $(event.currentTarget).parents(".item")
let pouvoirId = li.data("item-id")
this.actor.rollPouvoir(pouvoirId)
})
html.find('.dialog-recup-usage').click((event) => {
this.dialogRecupUsage()
})
html.find('.item-add').click((event) => {
const itemType = $(event.currentTarget).data("type")
if (itemType == "sort") {
// Get data-sort-competence
let sortCompetence = $(event.currentTarget).data("sort-competence");
if (sortCompetence) {
this.actor.createEmbeddedDocuments('Item', [{ name: `Nouveau ${itemType} de ${sortCompetence}`, type: itemType, system: { competence: sortCompetence } }], { renderSheet: true })
return
}
}
this.actor.createEmbeddedDocuments('Item', [{ name: `Nouveau ${itemType}`, type: itemType }], { renderSheet: true })
})
html.find('.lock-unlock-sheet').click((event) => {
this.options.editScore = !this.options.editScore;
this.render(true);
});
html.find('.item-equip').click(ev => {
const li = $(ev.currentTarget).parents(".item");
this.actor.equipItem(li.data("item-id"));
this.render(true);
});
}
/* -------------------------------------------- */
/** @override */
setPosition(options = {}) {
const position = super.setPosition(options);
const sheetBody = this.element.find(".sheet-body");
const bodyHeight = position.height - 192;
sheetBody.css("height", bodyHeight);
return position;
}
/* -------------------------------------------- */
/*async _onDropItem(event, dragData) {
let data = event.dataTransfer.getData('text/plain')
let dataItem = JSON.parse( data)
let item = fromUuidSync(dataItem.uuid)
if (item.pack) {
item = await HeritiersUtility.searchItem(item)
}
super._onDropItem(event, dragData)
}*/
}

View File

@@ -1,217 +0,0 @@
import { HeritiersUtility } from "./heritiers-utility.js";
/**
* Extend the basic ItemSheet with some very simple modifications
* @extends {ItemSheet}
*/
export class HeritiersItemSheet extends foundry.appv1.sheets.ItemSheet {
/** @override */
static get defaultOptions() {
return foundry.utils.mergeObject(super.defaultOptions, {
classes: ["fvtt-les-heritiers", "sheet", "item"],
dragDrop: [{ dragSelector: null, dropSelector: null }],
width: 620,
height: 550,
tabs: [{ navSelector: ".sheet-tabs", contentSelector: ".sheet-body", initial: "description" }]
});
}
/* -------------------------------------------- */
_getHeaderButtons() {
let buttons = super._getHeaderButtons();
// Add "Post to chat" button
// We previously restricted this to GM and editable items only. If you ever find this comment because it broke something: eh, sorry!
buttons.unshift(
{
class: "post",
icon: "fas fa-comment",
onclick: ev => { }
})
return buttons
}
/* -------------------------------------------- */
/** @override */
setPosition(options = {}) {
const position = super.setPosition(options);
const sheetBody = this.element.find(".sheet-body");
const bodyHeight = position.height - 192;
sheetBody.css("height", bodyHeight);
if (this.item.type.includes('weapon')) {
position.width = 640;
}
return position;
}
/* -------------------------------------------- */
async getData() {
const objectData = foundry.utils.duplicate(this.object)
let formData = {
title: this.title,
id: this.id,
type: objectData.type,
img: objectData.img,
name: objectData.name,
editable: this.isEditable,
cssClass: this.isEditable ? "editable" : "locked",
system: objectData.system,
limited: this.object.limited,
options: this.options,
owner: this.document.isOwner,
config: game.system.lesheritiers.config,
isArmeMelee: HeritiersUtility.isArmeMelee(this.object),
description: await foundry.applications.ux.TextEditor.implementation.enrichHTML(this.object.system.description, { async: true }),
mr: (this.object.type == 'specialisation'),
isGM: game.user.isGM,
usageMax: -1
}
// Items specific data
if (this.object.type == 'pouvoir' && this.document.isOwner && this.actor) {
formData.usageMax = this.actor.getPouvoirUsageMax(this.object)
if (this.object.system.pointsusagecourant == -1) {
this.object.system.pointsusagecourant = formData.usageMax
}
}
if (this.object.type == 'sort') {
formData.competencesMagie = HeritiersUtility.getCompetencesMagie()
}
//this.options.editable = !(this.object.origin == "embeddedItem");
console.log("ITEM DATA", formData, this);
return formData;
}
/* -------------------------------------------- */
_getHeaderButtons() {
let buttons = super._getHeaderButtons();
buttons.unshift({
class: "post",
icon: "fas fa-comment",
onclick: ev => this.postItem()
});
return buttons
}
/* -------------------------------------------- */
postItem() {
let chatData = foundry.utils.duplicate(HeritiersUtility.data(this.item));
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")) {
chatData.img = null;
}
// JSON object for easy creation
chatData.jsondata = JSON.stringify(
{
compendium: "postedItem",
payload: chatData,
});
renderTemplate('systems/fvtt-Heritiers-rpg/templates/post-item.html', chatData).then(html => {
let chatOptions = HeritiersUtility.chatDataSetup(html);
ChatMessage.create(chatOptions)
});
}
/* -------------------------------------------- */
/** @override */
activateListeners(html) {
super.activateListeners(html);
// Everything below here is only needed if the sheet is editable
if (!this.options.editable) return;
// Update Inventory Item
html.find('.item-edit').click(ev => {
const li = $(ev.currentTarget).parents(".item")
const item = this.object.options.actor.getOwnedItem(li.data("item-id"))
item.sheet.render(true);
});
html.find('.delete-subitem').click(ev => {
this.deleteSubitem(ev);
})
html.find('#add-specialite').click(ev => {
let spec = foundry.utils.duplicate(this.item.system.specialites) || []
spec.push({ name: "Nouvelle Spécialité", id: foundry.utils.randomID(16), used: false })
this.item.update({ 'system.specialites': spec })
})
html.find('.delete-specialite').click(ev => {
const li = $(ev.currentTarget).parents(".specialite-item")
let index = li.data("specialite-index")
let spec = foundry.utils.duplicate(this.item.system.specialites) || []
spec.splice(index, 1)
this.item.update({ 'system.specialites': spec })
})
html.find('.edit-specialite').change(ev => {
const li = $(ev.currentTarget).parents(".specialite-item")
let index = li.data("specialite-index")
let spec = foundry.utils.duplicate(this.item.system.specialites) || []
if (spec[index]) {
spec[index].name = ev.currentTarget.value
spec[index].id = spec[index].id || foundry.utils.randomID(16)
this.item.update({ 'system.specialites': spec })
}
})
html.find('.edit-specialite-description').change(ev => {
const li = $(ev.currentTarget).parents(".specialite-item")
let index = li.data("specialite-index")
let spec = foundry.utils.duplicate(this.item.system.specialites) || []
if (spec[index]) {
spec[index].description = ev.currentTarget.value
spec[index].id = spec[index].id || foundry.utils.randomID(16)
this.item.update({ 'system.specialites': spec })
}
})
html.find('#add-automation').click(ev => {
let autom = foundry.utils.duplicate(this.object.system.automations)
autom.push({ eventtype: "on-drop", name: "Automatisation 1", competence: "", minLevel: 0, id: foundry.utils.randomID(16) })
this.object.update({ 'system.automations': autom })
})
html.find('.delete-automation').click(ev => {
const li = $(ev.currentTarget).parents(".automation-item")
let index = li.data("automation-index")
let autom = foundry.utils.duplicate(this.object.system.automations)
autom.splice(index, 1)
this.object.update({ 'system.automations': autom })
})
html.find('.automation-edit-field').change(ev => {
let index = $(ev.currentTarget).data("automation-index")
let field = $(ev.currentTarget).data("automation-field")
let auto = foundry.utils.duplicate(this.object.system.automations)
auto[index][field] = ev.currentTarget.value
auto[index].id = auto[index].id || foundry.utils.randomID(16)
this.object.update({ 'system.automations': auto })
})
// Update Inventory Item
html.find('.item-delete').click(ev => {
const li = $(ev.currentTarget).parents(".item");
let itemId = li.data("item-id");
let itemType = li.data("item-type");
});
}
/* -------------------------------------------- */
get template() {
let type = this.item.type;
return `systems/fvtt-les-heritiers/templates/item-${type}-sheet.hbs`;
}
/* -------------------------------------------- */
/** @override */
_updateObject(event, formData) {
return this.object.update(formData);
}
}

View File

@@ -1,146 +0,0 @@
import { HeritiersUtility } from "./heritiers-utility.js";
export class HeritiersRollDialog extends Dialog {
/* -------------------------------------------- */
static async create(actor, rollData) {
let options = { classes: ["HeritiersDialog"], width: 420, height: 'fit-content', 'z-index': 99999 };
let html = await foundry.applications.handlebars.renderTemplate('systems/fvtt-les-heritiers/templates/roll-dialog-generic.html', rollData);
return new HeritiersRollDialog(actor, rollData, html, options);
}
/* -------------------------------------------- */
constructor(actor, rollData, html, options, close = undefined) {
let buttons = {
rolld8: {
icon: '<i class="fas fa-check"></i>',
label: "Lancer 1d8",
callback: () => { this.roll("d8") }
}
}
let enableD10 = false
let enableD12 = false
if (rollData.mode == "pouvoir" || rollData.competence?.system.niveau > 0) {
enableD10 = true
}
if (rollData.mode == "pouvoir" || rollData.competence?.system.niveau > 1) {
enableD12 = true
}
if (enableD10) {
buttons.rolld10 = {
icon: '<i class="fas fa-check"></i>',
label: "Lancer 1d10",
callback: () => { this.roll("d10") }
}
}
if (enableD12) {
buttons.rolld12 = {
icon: '<i class="fas fa-check"></i>',
label: "Lancer 1d12",
callback: () => { this.roll("d12") }
}
}
if (rollData.tricherie) {
buttons["rollTricherie"] = {
icon: '<i class="fas fa-check"></i>',
label: "Avec 1 Tricherie",
callback: () => { this.roll("tricherie") }
}
}
if (rollData.heritage) {
buttons["rollHeritage"] = {
icon: '<i class="fas fa-check"></i>',
label: "Avec 1 Héritage",
callback: () => { this.roll("heritage") }
}
}
buttons["Cancel"] = {
icon: '<i class="fas fa-times"></i>',
label: "Annuler",
callback: () => { this.close() }
}
let conf = {
title: "Test de Capacité",
content: html,
buttons: buttons,
close: close
}
// Overwrite in case of carac only -> 1d8
if (rollData.mode == "carac") {
conf.buttons = {
rolld8: {
icon: '<i class="fas fa-check"></i>',
label: "Lancer 1d8",
callback: () => { this.roll("d8") }
},
cancel: {
icon: '<i class="fas fa-times"></i>',
label: "Annuler",
callback: () => { this.close() }
}
}
}
super(conf, options);
this.actor = actor
this.rollData = rollData
}
/* -------------------------------------------- */
roll(dice) {
if (dice == "heritage") {
this.rollData.useHeritage = true
}
else {
if (dice == "tricherie") {
this.rollData.useTricherie = true
} else {
this.rollData.mainDice = dice
}
}
HeritiersUtility.rollHeritiers(this.rollData)
}
/* -------------------------------------------- */
activateListeners(html) {
super.activateListeners(html);
function onLoad() {
}
$(function () { onLoad(); });
html.find('#sdValue').change(async (event) => {
this.rollData.sdValue = Number(event.currentTarget.value)
})
html.find('#caracKey').change(async (event) => {
//console.log("caracKey", event.currentTarget.value)
this.rollData.caracKey = String(event.currentTarget.value)
})
html.find('#bonus-malus-context').change((event) => {
this.rollData.bonusMalusContext = Number(event.currentTarget.value)
})
html.find('#bonus-attaque-plusieurs').change((event) => {
this.rollData.bonusAttaquePlusieurs = Number(event.currentTarget.value)
})
html.find('#useSpecialite').change((event) => {
this.rollData.useSpecialite = event.currentTarget.checked
})
html.find('#pouvoirPointsUsage').change((event) => {
this.rollData.pouvoirPointsUsage = Number(event.currentTarget.value)
})
html.find('#attaqueDos').change((event) => {
this.rollData.attaqueDos = event.currentTarget.checked
})
html.find('#bonus-attaque-seconde-arme').change((event) => {
this.rollData.secondeArme = String(event.currentTarget.value)
})
html.find('#attaque-cible').change((event) => {
this.rollData.attaqueCible = String(event.currentTarget.value)
})
}
}

View File

@@ -200,7 +200,7 @@ export class HeritiersUtility {
static async preloadHandlebarsTemplates() {
const templatePaths = [
'systems/fvtt-les-heritiers/templates/editor-notes-gm.html',
'systems/fvtt-les-heritiers/templates/editor-notes-gm.hbs',
'systems/fvtt-les-heritiers/templates/partial-item-header.hbs',
'systems/fvtt-les-heritiers/templates/partial-item-description.hbs',
'systems/fvtt-les-heritiers/templates/partial-item-nav.hbs',