Vincent Vandemeulebrouck
f207cb7325
Ajout d'un helper Handlebars pour accéder à l'objet RDD_CONFIG sans avoir besoin de l'ajouter dans les données pour rendu du template
327 lines
13 KiB
JavaScript
327 lines
13 KiB
JavaScript
import { RdDUtility } from "../rdd-utility.js";
|
|
import { Misc } from "../misc.js";
|
|
import { DialogSplitItem } from "../dialog-split-item.js";
|
|
import { RdDSheetUtility } from "../rdd-sheet-utility.js";
|
|
import { Monnaie } from "../item-monnaie.js";
|
|
import { RdDItem, TYPES } from "../item.js";
|
|
import { RdDItemCompetenceCreature } from "../item-competencecreature.js";
|
|
|
|
/* -------------------------------------------- */
|
|
/**
|
|
* Extend the basic ActorSheet with some very simple modifications
|
|
* @extends {ActorSheet}
|
|
*/
|
|
export class RdDBaseActorSheet extends ActorSheet {
|
|
|
|
/** @override */
|
|
static get defaultOptions() {
|
|
return foundry.utils.mergeObject(ActorSheet.defaultOptions, {
|
|
classes: ["rdd", "sheet", "actor"],
|
|
tabs: [{ navSelector: ".sheet-tabs", contentSelector: ".sheet-body", initial: "carac" }],
|
|
dragDrop: [{ dragSelector: ".item-list .item", dropSelector: undefined }],
|
|
vueDetaillee: false
|
|
}, { inplace: false })
|
|
}
|
|
|
|
/* -------------------------------------------- */
|
|
async getData() {
|
|
Monnaie.validerMonnaies(this.actor.itemTypes['monnaie']);
|
|
|
|
this.actor.computeEtatGeneral();
|
|
let formData = {
|
|
title: this.title,
|
|
id: this.actor.id,
|
|
type: this.actor.type,
|
|
img: this.actor.img,
|
|
name: this.actor.name,
|
|
system: this.actor.system,
|
|
description: await TextEditor.enrichHTML(this.actor.system.description, { async: true }),
|
|
notesmj: await TextEditor.enrichHTML(this.actor.system.notesmj, { async: true }),
|
|
options: RdDSheetUtility.mergeDocumentRights(this.options, this.actor, this.isEditable),
|
|
effects: this.actor.effects
|
|
}
|
|
|
|
RdDBaseActorSheet.filterItemsPerTypeForSheet(formData, this.actor.itemTypes);
|
|
formData.calc = {
|
|
fortune: Monnaie.toSolsDeniers(this.actor.getFortune()),
|
|
prixTotalEquipement: this.actor.computePrixTotalEquipement(),
|
|
encTotal: await this.actor.computeEncTotal(),
|
|
}
|
|
|
|
this.objetVersConteneur = RdDUtility.buildArbreDeConteneurs(formData.conteneurs, formData.inventaires);
|
|
this._appliquerRechercheObjets(formData.conteneurs, formData.inventaires);
|
|
formData.conteneurs = RdDUtility.conteneursRacine(formData.conteneurs);
|
|
formData.competences.filter(it => it.type == TYPES.competencecreature)
|
|
.forEach(it => it.isdommages = RdDItemCompetenceCreature.isDommages(it))
|
|
return formData;
|
|
}
|
|
|
|
_appliquerRechercheObjets(conteneurs, inventaires) {
|
|
if (this.options.recherche?.text) {
|
|
const recherche = this.options.recherche;
|
|
const allVisible = inventaires.filter(it => it.isNomTypeLike(recherche.text)).map(it => it.id);
|
|
let addVisible = conteneurs.filter(it => it.isNomTypeLike(recherche.text)).map(it => it.id)
|
|
do {
|
|
allVisible.push(...addVisible)
|
|
const parentsIds = conteneurs.filter(it => it.system.contenu.find(id => allVisible.includes(id))).map(it => it.id)
|
|
addVisible = parentsIds.filter(id => !allVisible.includes(id))
|
|
}
|
|
while (addVisible.length > 0)
|
|
inventaires.forEach(it => it.system.isHidden = !allVisible.includes(it.id))
|
|
conteneurs.forEach(it => it.system.isHidden = !allVisible.includes(it.id))
|
|
}
|
|
else {
|
|
inventaires.forEach(it => it.system.isHidden = false)
|
|
conteneurs.forEach(it => it.system.isHidden = false)
|
|
}
|
|
}
|
|
|
|
/* -------------------------------------------- */
|
|
static filterItemsPerTypeForSheet(formData, itemTypes) {
|
|
formData.blessures = Misc.arrayOrEmpty(itemTypes['blessure']);
|
|
formData.recettescuisine = Misc.arrayOrEmpty(itemTypes['recettecuisine']);
|
|
formData.recettesAlchimiques = Misc.arrayOrEmpty(itemTypes['recettealchimique']);
|
|
formData.maladies = Misc.arrayOrEmpty(itemTypes['maladie']);
|
|
formData.poisons = Misc.arrayOrEmpty(itemTypes['poison']);
|
|
formData.possessions = Misc.arrayOrEmpty(itemTypes['possession']);
|
|
formData.maladiesPoisons = formData.maladies.concat(formData.poisons);
|
|
formData.competences = (itemTypes['competence'] ?? []).concat(itemTypes['competencecreature'] ?? []);
|
|
formData.sortsReserve = Misc.arrayOrEmpty(itemTypes['sortreserve']);
|
|
|
|
formData.sorts = Misc.arrayOrEmpty(itemTypes['sort']);
|
|
formData.rencontres = Misc.arrayOrEmpty(itemTypes['rencontre']);
|
|
formData.casestmr = Misc.arrayOrEmpty(itemTypes['casetmr']);
|
|
formData.signesdraconiques = Misc.arrayOrEmpty(itemTypes['signedraconique']);
|
|
formData.queues = Misc.arrayOrEmpty(itemTypes['queue']);
|
|
formData.souffles = Misc.arrayOrEmpty(itemTypes['souffle']);
|
|
formData.ombres = Misc.arrayOrEmpty(itemTypes['ombre']);
|
|
formData.tetes = Misc.arrayOrEmpty(itemTypes['tete']);
|
|
formData.taches = Misc.arrayOrEmpty(itemTypes['tache']);
|
|
formData.meditations = Misc.arrayOrEmpty(itemTypes['meditation']);
|
|
formData.chants = Misc.arrayOrEmpty(itemTypes['chant']);
|
|
formData.danses = Misc.arrayOrEmpty(itemTypes['danse']);
|
|
formData.musiques = Misc.arrayOrEmpty(itemTypes['musique']);
|
|
formData.oeuvres = Misc.arrayOrEmpty(itemTypes['oeuvre']);
|
|
formData.jeux = Misc.arrayOrEmpty(itemTypes['jeu']);
|
|
|
|
formData.services = Misc.arrayOrEmpty(itemTypes['service']);
|
|
formData.conteneurs = Misc.arrayOrEmpty(itemTypes['conteneur']);
|
|
formData.materiel = Misc.arrayOrEmpty(itemTypes['objet']);
|
|
formData.armes = Misc.arrayOrEmpty(itemTypes['arme']);
|
|
formData.armures = Misc.arrayOrEmpty(itemTypes['armure']);
|
|
formData.munitions = Misc.arrayOrEmpty(itemTypes['munition']);
|
|
formData.livres = Misc.arrayOrEmpty(itemTypes['livre']);
|
|
formData.potions = Misc.arrayOrEmpty(itemTypes['potion']);
|
|
formData.plantes = Misc.arrayOrEmpty(itemTypes['plante']);
|
|
formData.ingredients = Misc.arrayOrEmpty(itemTypes['ingredient']);
|
|
formData.faunes = Misc.arrayOrEmpty(itemTypes['faune']);
|
|
formData.herbes = Misc.arrayOrEmpty(itemTypes['herbe']);
|
|
formData.nourritureboissons = Misc.arrayOrEmpty(itemTypes['nourritureboisson']);
|
|
formData.gemmes = Misc.arrayOrEmpty(itemTypes['gemme']);
|
|
formData.monnaies = Misc.arrayOrEmpty(itemTypes['monnaie']).sort(Monnaie.triValeurEntiere());
|
|
formData.objets = Misc.arrayOrEmpty(itemTypes['objet'])
|
|
|
|
formData.inventaires = RdDItem.getItemTypesInventaire('all')
|
|
.map(t => Misc.arrayOrEmpty(itemTypes[t]))
|
|
.reduce((a, b) => a.concat(b), [])
|
|
.sort(Misc.ascending(it => it.name));
|
|
}
|
|
|
|
/* -------------------------------------------- */ /** @override */
|
|
activateListeners(html) {
|
|
super.activateListeners(html);
|
|
this.html = html;
|
|
|
|
this.html.find('.conteneur-name a').click(async event => {
|
|
RdDUtility.toggleAfficheContenu(this.getItemId(event));
|
|
this.render(true);
|
|
});
|
|
this.html.find('.actor-montrer').click(async event => this.actor.postActorToChat());
|
|
this.html.find('.item-edit').click(async event => this.getItem(event)?.sheet.render(true))
|
|
this.html.find('.item-montrer').click(async event => this.getItem(event)?.postItemToChat());
|
|
|
|
this.html.find('.recherche')
|
|
.each((index, field) => {
|
|
this._rechercheSelectArea(field);
|
|
})
|
|
.keyup(async event => this._rechercherKeyup(event))
|
|
.change(async event => this._rechercherKeyup(event));
|
|
this.html.find('.recherche').prop("disabled", false);
|
|
|
|
// Everything below here is only needed if the sheet is editable
|
|
if (!this.options.editable) return;
|
|
|
|
this.html.find('.item-action').click(async event => {
|
|
const item = RdDSheetUtility.getItem(event, this.actor);
|
|
item?.actionPrincipale(this.actor, async () => this.render())
|
|
});
|
|
|
|
|
|
this.html.find('.item-split').click(async event => {
|
|
const item = this.getItem(event);
|
|
RdDSheetUtility.splitItem(item, this.actor);
|
|
});
|
|
this.html.find('.item-quantite-plus').click(async event => this.actor.itemQuantiteIncDec(this.getItemId(event), 1));
|
|
this.html.find('.item-quantite-moins').click(async event => this.actor.itemQuantiteIncDec(this.getItemId(event), -1));
|
|
this.html.find('.item-delete').click(async event => RdDUtility.confirmActorItemDelete(this, this.getItem(event)));
|
|
this.html.find('.item-vendre').click(async event => this.vendre(this.getItem(event)));
|
|
|
|
this.html.find('.creer-un-objet').click(async event => {
|
|
this.selectObjetTypeToCreate();
|
|
});
|
|
this.html.find('.nettoyer-conteneurs').click(async event => {
|
|
this.actor.nettoyerConteneurs();
|
|
});
|
|
|
|
this.html.find('.vue-detaillee').click(async event => {
|
|
this.options.vueDetaillee = !this.options.vueDetaillee;
|
|
this.render(true);
|
|
});
|
|
|
|
if (this.options.vueDetaillee) {
|
|
// On carac change
|
|
this.html.find('.carac-value').change(async event => {
|
|
let caracName = event.currentTarget.name.replace(".value", "").replace("system.carac.", "");
|
|
this.actor.updateCarac(caracName, parseInt(event.target.value));
|
|
});
|
|
// On competence change
|
|
this.html.find('.competence-value').change(async event => {
|
|
let compName = event.currentTarget.attributes.compname.value;
|
|
//console.log("Competence changed :", compName);
|
|
this.actor.updateCompetence(compName, parseInt(event.target.value));
|
|
});
|
|
}
|
|
|
|
}
|
|
|
|
_rechercherKeyup(event) {
|
|
const currentTarget = event.currentTarget;
|
|
const nouvelleRecherche = this._optionRecherche(currentTarget);
|
|
if (this.options.recherche?.text != nouvelleRecherche?.text) {
|
|
this.options.recherche = nouvelleRecherche;
|
|
if (this.timerRecherche) {
|
|
clearTimeout(this.timerRecherche);
|
|
}
|
|
this.timerRecherche = setTimeout(() => {
|
|
this.timerRecherche = undefined;
|
|
this.render(true);
|
|
}, 500);
|
|
}
|
|
}
|
|
|
|
_rechercheSelectArea(field) {
|
|
if (this.options.recherche) {
|
|
field.focus();
|
|
field.setSelectionRange(this.options.recherche.start, this.options.recherche.end);
|
|
}
|
|
}
|
|
|
|
getItemId(event) {
|
|
return RdDSheetUtility.getItemId(event);
|
|
}
|
|
|
|
getItem(event) {
|
|
return RdDSheetUtility.getItem(event, this.actor);
|
|
}
|
|
|
|
_optionRecherche(target) {
|
|
if (!target.value?.length) {
|
|
return undefined;
|
|
}
|
|
return {
|
|
text: target.value,
|
|
start: target.selectionStart,
|
|
end: target.selectionEnd,
|
|
};
|
|
}
|
|
/* -------------------------------------------- */
|
|
_getHeaderButtons() {
|
|
let buttons = super._getHeaderButtons();
|
|
buttons.unshift({
|
|
class: "montrer",
|
|
icon: "fas fa-comment",
|
|
onclick: ev => this.actor.postActorToChat()
|
|
});
|
|
return buttons
|
|
}
|
|
|
|
/* -------------------------------------------- */
|
|
async _onDropItem(event, dragData) {
|
|
const destItemId = this.html.find(event.target)?.closest('.item').attr('data-item-id')
|
|
const dropParams = await RdDSheetUtility.prepareItemDropParameters(destItemId, this.actor, dragData, this.objetVersConteneur)
|
|
if (dropParams) {
|
|
const callSuper = await this.actor.processDropItem(dropParams)
|
|
if (callSuper) {
|
|
await super._onDropItem(event, dragData)
|
|
}
|
|
}
|
|
}
|
|
|
|
/* -------------------------------------------- */
|
|
async selectObjetTypeToCreate() {
|
|
let types = this.getTypesInventaire().sort(Misc.ascending(type => Misc.typeName('Item', type)));
|
|
let content = `<span class="competence-label">Selectionnez le type d'équipement</span><select class="item-type">`;
|
|
for (let typeName of types) {
|
|
content += `<option value="${typeName}">${Misc.typeName('Item', typeName)}</option>`
|
|
}
|
|
content += '</select>';
|
|
let d = new Dialog({
|
|
title: "Créer un équipement",
|
|
content: content,
|
|
buttons: {
|
|
create: {
|
|
icon: '<i class="fas fa-check"></i>',
|
|
label: "Créer l'objet",
|
|
callback: () => this.actor.createItem($(".item-type").val())
|
|
}
|
|
}
|
|
});
|
|
d.render(true);
|
|
}
|
|
|
|
getTypesInventaire() {
|
|
return RdDItem.getItemTypesInventaire();
|
|
}
|
|
|
|
/** @override */
|
|
setPosition(options = {}) {
|
|
const position = super.setPosition(options);
|
|
const sheetHeader = this.element.find(".sheet-header");
|
|
const sheetTabs = this.element.find(".sheet-tabs");
|
|
const sheetBody = this.element.find(".sheet-body");
|
|
let bodyHeight = position.height - sheetHeader[0].clientHeight;
|
|
if (sheetTabs.length > 0) {
|
|
bodyHeight -= sheetTabs[0].clientHeight;
|
|
}
|
|
sheetBody.css("height", bodyHeight);
|
|
return position;
|
|
}
|
|
|
|
|
|
/* -------------------------------------------- */
|
|
/** @override */
|
|
_updateObject(event, formData) {
|
|
// Update the Actor
|
|
return this.actor.update(formData);
|
|
}
|
|
|
|
async splitItem(item) {
|
|
const dialog = await DialogSplitItem.create(item, (item, split) => this._onSplitItem(item, split));
|
|
dialog.render(true);
|
|
}
|
|
|
|
async _onSplitItem(item, split) {
|
|
if (split >= 1 && split < item.system.quantite) {
|
|
await item.diminuerQuantite(split);
|
|
const splitItem = foundry.utils.duplicate(item);
|
|
splitItem.system.quantite = split;
|
|
await this.actor.createEmbeddedDocuments('Item', [splitItem])
|
|
}
|
|
}
|
|
|
|
vendre(item) {
|
|
item?.proposerVente(this.actor.getQuantiteDisponible(item));
|
|
}
|
|
|
|
}
|