Vincent Vandemeulebrouck
1bf247db33
La confusion entre les Item "objets" et le champ formData.objets rendait les Item "objets" indisponibles (par exemple, les vêtements)
299 lines
12 KiB
JavaScript
299 lines
12 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 } from "../item.js";
|
|
|
|
/* -------------------------------------------- */
|
|
/**
|
|
* Extend the basic ActorSheet with some very simple modifications
|
|
* @extends {ActorSheet}
|
|
*/
|
|
export class RdDBaseActorSheet extends ActorSheet {
|
|
|
|
/** @override */
|
|
static get defaultOptions() {
|
|
RdDUtility.initAfficheContenu();
|
|
return mergeObject(super.defaultOptions, {
|
|
classes: ["rdd", "sheet", "actor"],
|
|
template: "systems/foundryvtt-reve-de-dragon/templates/actor-sheet.html",
|
|
width: 550,
|
|
tabs: [{ navSelector: ".sheet-tabs", contentSelector: ".sheet-body", initial: "carac" }],
|
|
dragDrop: [{ dragSelector: ".item-list .item", dropSelector: undefined }],
|
|
showCompNiveauBase: false,
|
|
vueDetaillee: false
|
|
});
|
|
}
|
|
|
|
/* -------------------------------------------- */
|
|
async getData() {
|
|
Monnaie.validerMonnaies(this.actor.itemTypes['monnaie']);
|
|
|
|
this.actor.recompute();
|
|
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)
|
|
}
|
|
|
|
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);
|
|
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('.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('.actor-montrer').click(async event => this.actor.postActorToChat());
|
|
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-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();
|
|
});
|
|
}
|
|
|
|
_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 = duplicate(item);
|
|
splitItem.system.quantite = split;
|
|
await this.actor.createEmbeddedDocuments('Item', [splitItem])
|
|
}
|
|
}
|
|
|
|
vendre(item) {
|
|
item?.proposerVente(this.actor.getQuantiteDisponible(item));
|
|
}
|
|
|
|
}
|