Gestion des signes draconiques #455

Closed
vincent.vandeme wants to merge 233 commits from v1.4-signes-draconiques into master
4 changed files with 143 additions and 106 deletions
Showing only changes of commit d743578f3f - Show all commits

View File

@ -236,29 +236,35 @@ export class RdDActor extends Actor {
return RdDItemCompetence.findCompetence(this.data.items, name);
}
/* -------------------------------------------- */
getObjet(id) {
return id ? this.items.find(it => it._id == id) : undefined;
}
getItemOfType(type, id) {
return id ? this.data.items.find(it => it._id == id && it.type == type) : undefined;
}
getTache(id) {
return this.data.items.find(item => item.type == 'tache' && item._id == id);
return this.getItemOfType(id, 'tache');
}
getMeditation(id) {
return this.data.items.find(item => item.type == 'meditation' && item._id == id);
return this.getItemOfType(id, 'meditation');
}
getChant(id) {
return this.data.items.find(item => item.type == 'chant' && item._id == id);
return this.getItemOfType(id, 'chant');
}
getDanse(id) {
return this.data.items.find(item => item.type == 'danse' && item._id == id);
return this.getItemOfType(id, 'danse');
}
getMusique(id) {
return this.data.items.find(item => item.type == 'musique' && item._id == id);
return this.getItemOfType(id, 'musique');
}
getOeuvre(id, type = 'oeuvre') {
return this.data.items.find(item => item.type == type && item._id == id);
return this.getItemOfType(type, id);
}
getJeu(id) {
return this.data.items.find(item => item.type == 'jeu' && item._id == id);
return this.getItemOfType(id, 'jeu');
}
getRecetteCuisine(id) {
return this.data.items.find(item => item.type == 'recettecuisine' && item._id == id);
return this.getItemOfType(id, 'recettecuisine');
}
/* -------------------------------------------- */
getBestDraconic() {
@ -271,6 +277,7 @@ export class RdDActor extends Actor {
getDemiReve() {
return Misc.templateData(this).reve.tmrpos.coord;
}
/* -------------------------------------------- */
async deleteSortReserve(sortReserve) {
let reserve = duplicate(Misc.templateData(this).reve.reserve);
@ -768,42 +775,55 @@ export class RdDActor extends Actor {
/* -------------------------------------------- */
validateConteneur(itemId, conteneurId) {
let conteneurDest = this.items.find(conteneur => conteneurId == conteneur.id); // recup conteneur
let conteneurSrc = this.items.find(conteneur => itemId == conteneur.id && conteneur.type == 'conteneur');
if (conteneurSrc) { // Si c'est un conteneur, il faut vérifier qu'on ne le déplace pas vers un sous-conteneur lui appartenant
for (let id of conteneurSrc.data.data.contenu) {
let subObjet = this.items.find(subobj => id == subobj.id);
if (subObjet && subObjet.id == conteneurDest.id) {
ui.notifications.warn("Impossible de déplacer un conteneur parent dans son fils !");
const dest = this.getObjet(conteneurId);
if (dest?.type != 'conteneur') {
ui.notifications.warn(`Impossible de déplacer un objet (${item.name}) vers un ${dest.type} qui n'est pas un conteneur (${dest.name}) !`);
return false;
}
const item = this.getObjet(itemId);
if (this._isConteneurContenu(item, conteneurId)) {
ui.notifications.warn(`Impossible de déplacer un conteneur parent (${item.name}) dans un de ses contenus ${dest.name} !`);
return false; // Loop detected !
}
if (subObjet && subObjet.type == 'conteneur') {
return this.validateConteneur(subObjet.id, conteneurId);
}
}
}
return true;
}
_isConteneurContenu(item, conteneurId) {
if (item?.type == 'conteneur') { // Si c'est un conteneur, il faut vérifier qu'on ne le déplace pas vers un sous-conteneur lui appartenant
for (let id of Misc.templateData(item).contenu) {
let subObjet = this.getObjet(id);
if (subObjet?.id == conteneurId) {
return true; // Loop detected !
}
if (subObjet?.type == 'conteneur') {
return this._isConteneurContenu(subObjet, conteneurId);
}
}
}
return false;
}
/* -------------------------------------------- */
getRecursiveEnc(objet) {
let sumEnc = 0;
if (objet.type == 'conteneur') {
for (let id of objet.data.data.contenu) {
let subobjet = this.items.find(objet => (id == objet.id));
if (subobjet) {
if (subobjet && subobjet.type == 'conteneur') {
sumEnc += this.getRecursiveEnc(subobjet);
} else {
sumEnc += Number(subobjet.data.data.encombrement) * Number(subobjet.data.data.quantite);
if (!objet) {
return 0;
}
const tplData = Misc.templateData(objet);
if (objet.type != 'conteneur') {
return Number(tplData.encombrement) * Number(tplData.quantite);
}
const encContenus = tplData.contenu.map(idContenu => this.getRecursiveEnc(this.getObjet(idContenu)));
return encContenus.reduce((a, b) => a + b, 0)
+ Number(tplData.encombrement) /* TODO? Number(tplData.quantite) -- on pourrait avoir plusieurs conteneurs...*/
}
sumEnc += Number(objet.data.data.encombrement)
} else {
sumEnc += Number(objet.data.data.encombrement) * Number(objet.data.data.quantite);
/* -------------------------------------------- */
isConteneurSuffisant(itemId, conteneurId) {
if ( !conteneurId){
// on peut toujours vider son sac
return true;
}
return sumEnc;
return this.validateConteneur(itemId, conteneurId) && this.testConteneurCapacite(itemId, conteneurId);
}
/* -------------------------------------------- */
@ -811,37 +831,42 @@ export class RdDActor extends Actor {
* pour recevoir le nouvel objet
*/
testConteneurCapacite(itemId, conteneurId) {
if (!conteneurId) return true; // pas de conteneur (porté sur soi), donc toujours OK.
let conteneur = this.items.find(conteneur => conteneurId == conteneur.id); // recup conteneur
let conteneur = this.getObjet(conteneurId); // recup conteneur (ou undefined)
//console.log("Conteneur trouvé : ", conteneur);
if (conteneur && conteneur.type == "conteneur") {
// Calculer le total actuel des contenus
let encContenu = this.getRecursiveEnc(conteneur) - Number(conteneur.data.data.encombrement);
let nouvelObjet = this.items.find(objet => (itemId == objet.id)); // On chope l'objet
let newEnc = (nouvelObjet) ? this.getRecursiveEnc(nouvelObjet) : 0; // Calculer le total actuel du nouvel objet
//console.log( currentEnc, newEnc, conteneur.data.data.capacite, conteneur.name);
if (nouvelObjet && ((encContenu + newEnc) > Number(conteneur.data.data.capacite))) {
ui.notifications.warn("Capacité d'encombrement insuffisante dans le conteneur !");
return false;
if (conteneur?.type != "conteneur") {
return true;
}
const tplConteneur = Misc.templateData(conteneur);
// Calculer le total actuel des contenus
let encContenu = this.getRecursiveEnc(conteneur) - Number(tplConteneur.encombrement);
let nouvelObjet = this.getObjet(itemId);
let newEnc = this.getRecursiveEnc(nouvelObjet); // Calculer le total actuel du nouvel objet
//console.log( currentEnc, newEnc, tplConteneur.capacite, conteneur.name);
if (nouvelObjet && ((encContenu + newEnc) > Number(tplConteneur.capacite))) {
ui.notifications.warn(
`Le conteneur ${conteneur.name} a une capacité de ${tplConteneur.capacite}, et contient déjà ${encContenu}.
Impossible d'y ranger: ${nouvelObjet.name} d'encombrement ${newEnc}!`);
return false;
}
return true;
}
/* -------------------------------------------- */
buildSubConteneurObjetList(conteneurId, deleteList) {
let conteneur = this.items.find(conteneur => conteneurId == conteneur._id); // recup conteneur
if (conteneur && conteneur.type == 'conteneur') { // Si présent
for (let subId of conteneur.data.data.contenu) {
let subObj = this.items.find(subobjet => subId == subobjet._id); // recup conteneur
if (subObj && subObj.type == 'conteneur') {
let conteneur = this.getObjet(conteneurId);
if (conteneur?.type == 'conteneur') { // Si c'est un conteneur
for (let subId of Misc.templateData(conteneur).contenu) {
let subObj = this.getObjet(subId);
if (subObj) {
if (subObj.type == 'conteneur') {
this.buildSubConteneurObjetList(subId, deleteList);
}
if (subObj) // Robust...
deleteList.push({ id: subId, conteneurId: conteneurId });
}
}
}
}
/* -------------------------------------------- */
async deleteAllConteneur(itemId) {
@ -858,11 +883,10 @@ export class RdDActor extends Actor {
/** Supprime un item d'un conteneur, sur la base
* de leurs ID */
async enleverDeConteneur(itemId, conteneurId) {
if (!conteneurId) return; // pas de conteneur (porté sur soi)
let conteneur = this.items.find(conteneur => conteneurId == conteneur.id); // recup conteneur
if (conteneur) { // Si présent
let data2use = duplicate(conteneur.data);
//console.log("Suppression du conteneur1", conteneurId, itemId, conteneur.data.data.contenu);
let conteneur = this.getObjet(conteneurId);
if (conteneur?.type == 'conteneur') { // Si présent
let data2use = duplicate(Misc.data(conteneur));
//console.log("Suppression du conteneur1", conteneurId, itemId, data2use.data.contenu);
let contenu = data2use.data.contenu;
let index = contenu.indexOf(itemId);
while (index >= 0) { // Force cleanup, itemId is unique
@ -877,10 +901,9 @@ export class RdDActor extends Actor {
/** Ajoute un item dans un conteneur, sur la base
* de leurs ID */
async ajouterAConteneur(itemId, conteneurId) {
if (!conteneurId) return; // pas de conteneur (porté sur soi)
let conteneur = this.items.find(conteneur => conteneurId == conteneur.id);
if (conteneur && conteneur.data.type == 'conteneur') {
let data2use = duplicate(conteneur.data);
let conteneur = this.getObjet(conteneurId);
if (conteneur?.type == 'conteneur') {
let data2use = duplicate(Misc.data(conteneur));
data2use.data.contenu.push(itemId);
await this.updateEmbeddedEntity("OwnedItem", data2use);
}
@ -889,10 +912,10 @@ export class RdDActor extends Actor {
/* -------------------------------------------- */
/** Fonction de remise à plat de l'équipement (ie vide les champs 'contenu') */
async nettoyerConteneurs() {
let conteneurList = this.items.filter(conteneur => conteneur.type == 'conteneur');
let conteneurs = this.items.filter(it => it.type == 'conteneur');
let conteneurFixedList = [];
for (let conteneur of conteneurList) {
if (conteneur.data.data.contenu.length > 0) {
for (let conteneur of conteneurs) {
if (Misc.templateData(conteneur).contenu.length > 0) {
conteneurFixedList.push({ _id: conteneur._id, 'data.contenu': [] });
}
}
@ -1051,7 +1074,7 @@ export class RdDActor extends Actor {
/* -------------------------------------------- */
async ajouterRefoulement(value = 1) {
let refoulement = Misc.templateData(this).reve.refoulement.value + value;
let total = new Roll("1d20").evaluate( {async: false}).total;
let total = new Roll("1d20").evaluate({ async: false }).total;
if (total <= refoulement) {
refoulement = 0;
await this.ajouterSouffle({ chat: true });
@ -2127,7 +2150,7 @@ export class RdDActor extends Actor {
async rollDanse(id) {
const actorData = Misc.data(this);
const artData = { art: 'danse', verbe: 'Danser', forceCarac: {} };
const oeuvre = duplicate(this.getOeuvre(id, artData.art));
const oeuvre = duplicate(this.getItemOfType(id, artData.art));
const selectedCarac = this._getCaracDanse(oeuvre);
if (oeuvre.data.agilite) {
artData.forceCarac['agilite'] = duplicate(actorData.data.carac.agilite);
@ -2149,7 +2172,7 @@ export class RdDActor extends Actor {
/* -------------------------------------------- */
async rollMusique(id) {
const artData = { art: 'musique', verbe: 'Jouer' };
const oeuvre = duplicate(this.getOeuvre(id, artData.art));
const oeuvre = duplicate(this.getItemOfType(id, artData.art));
await this._rollArt(artData, "ouie", oeuvre);
}
@ -2181,7 +2204,7 @@ export class RdDActor extends Actor {
async rollOeuvre(id) {
const artData = { art: 'oeuvre', verbe: 'Interpréter' };
const oeuvre = duplicate(this.getOeuvre(id));
const oeuvre = duplicate(this.getItemOfType(id, artData.art));
await this._rollArt(artData, oeuvre.data.default_carac, oeuvre);
}
@ -2799,14 +2822,13 @@ export class RdDActor extends Actor {
|| entite.isEntiteCauchemarAccordee(this)) {
return true;
}
let rolled = await RdDResolutionTable.roll(this.getReveActuel(), - Number(entite.data.data.carac.niveau.value));
const actorData = Misc.data(this);
const tplData = Misc.templateData(this);
let rolled = await RdDResolutionTable.roll(this.getReveActuel(), - Number(tplData.carac.niveau.value));
const rollData = {
alias: this.name,
rolled: rolled,
entite: entite.name,
selectedCarac: actorData.data.carac.reve
selectedCarac: tplData.carac.reve
};
if (rolled.isSuccess) {
@ -2890,7 +2912,7 @@ export class RdDActor extends Actor {
if (dataObj) {
dataObj.payload.data.cout = sumDenier / 100; // Mise à jour du prix en sols , avec le prix acheté
dataObj.payload.data.quantite = quantite;
await this.createEmbeddedDocuments('Item',[dataObj.payload]);
await this.createEmbeddedDocuments('Item', [dataObj.payload]);
msg += `<br>Et l'objet <strong>${dataObj.payload.name}</strong> a été ajouté à votre inventaire.`;
}
} else {
@ -2958,15 +2980,8 @@ export class RdDActor extends Actor {
/* -------------------------------------------- */
listeVehicules() {
const actorData = Misc.data(this);
return this._buildActorLinksList(
actorData.data.subacteurs?.vehicules ?? [],
vehicle => {
return {
id: vehicle.id, name: vehicle.data.name, categorie: vehicle.data.data.categorie,
structure: vehicle.data.data.structure, img: vehicle.data.img
};
});
const listeVehichules = Misc.templateData(this).subacteurs?.vehicules ?? [];
return this._buildActorLinksList(listeVehichules, vehicle => RdDActor._vehicleData(vehicle));
}
/* -------------------------------------------- */
@ -2979,12 +2994,27 @@ export class RdDActor extends Actor {
return this._buildActorLinksList(Misc.templateData(this).subacteurs?.montures ?? []);
}
_buildActorLinksList(links, actorTransformation = it => { return { id: it.id, name: it.data.name, img: it.data.img }; }) {
_buildActorLinksList(links, actorTransformation = it => RdDActor._buildActorData(it)) {
return links.map(link => game.actors.get(link.id))
.filter(it => it != null)
.map(actorTransformation);
}
static _vehicleData(vehicle) {
const vehicleData = Misc.data(vehicle);
return {
id: vehicle.id,
name: vehicleData.name,
img: vehicleData.img,
categorie: vehicleData.data.categorie,
structure: vehicleData.data.structure,
};
}
static _buildActorData(it) {
return { id: it.id, name: it.data.name, img: it.data.img };
}
/* -------------------------------------------- */
async pushSubacteur(actor, dataArray, dataPath, dataName) {
let alreadyPresent = dataArray.find(attached => attached.id == actor.data._id);

View File

@ -124,7 +124,7 @@ export class RdDItemSheet extends ItemSheet {
event.preventDefault();
let level = RdDItemCompetence.getNiveauBase(event.currentTarget.value);
this.object.data.data.base = level;
Misc.templateData(this.object).base = level;
$("#base").val( level );
}

View File

@ -968,7 +968,7 @@ export class RdDCombat {
surprise: this.defender.getSurprise(true),
needParadeSignificative: ReglesOptionelles.isUsing('categorieParade') && RdDItemArme.needParadeSignificative(armeAttaque, armeParade),
needResist: RdDItemArme.needArmeResist(armeAttaque, armeParade),
carac: this.defender.data.data.carac,
carac: Misc.templateData(this.defender).carac,
show: {}
};
defenderRoll.diviseurSignificative = this._getDiviseurSignificative(defenderRoll);
@ -1067,7 +1067,7 @@ export class RdDCombat {
competence: competence,
surprise: this.defender.getSurprise(true),
surpriseDefenseur: this.defender.getSurprise(true),
carac: this.defender.data.data.carac,
carac: Misc.templateData(this.defender).carac,
show: {}
};
rollData.diviseurSignificative = this._getDiviseurSignificative(rollData);
@ -1252,7 +1252,7 @@ export class RdDCombat {
return true;
}
let rolled = await RdDResolutionTable.roll(this.attacker.getReveActuel(), - Number(this.defender.data.data.carac.niveau.value));
let rolled = await RdDResolutionTable.roll(this.attacker.getReveActuel(), - Number(Misc.templateData(this.defender).carac.niveau.value));
let message = {
content: "Jet de points actuels de rêve à " + rolled.finalLevel + RdDResolutionTable.explain(rolled) + "<br>",

View File

@ -256,30 +256,37 @@ export class RdDUtility {
.concat(formData.potions)
.concat(formData.herbes)
.concat(formData.ingredients);
formData.competences = (formData.itemsByType.competence??[]).concat(formData.itemsByType.competencecreature??[]);
formData.competences = (formData.itemsByType.competence ?? []).concat(formData.itemsByType.competencecreature ?? []);
}
/* -------------------------------------------- */
static async processItemDropEvent(actorSheet, event) {
let dragData = JSON.parse(event.dataTransfer.getData("text/plain"));
console.log(dragData, actorSheet.actor.id);
let dropID = $(event.target).parents(".item").attr("data-item-id"); // Only relevant if container drop
let objetId = dragData.id || dragData.data._id;
console.log("DRAG", dragData);
if (dragData.type == 'Item') {
if (dropID) { // Dropped over an item !!!
if (actorSheet.objetVersConteneur[objetId] != dropID && objetId != dropID) {
if (actorSheet.actor.validateConteneur(objetId, dropID) && actorSheet.actor.testConteneurCapacite(objetId, dropID)) {
await actorSheet.actor.enleverDeConteneur(objetId, actorSheet.objetVersConteneur[objetId]);
await actorSheet.actor.ajouterAConteneur(objetId, dropID);
}
}
}
if (dragData.actorId && dragData.actorId != actorSheet.actor.id) { // Un acteur est à l'origine de l'item -> deplacement
console.log("Moving objects");
if (dragData.actorId) {
if (dragData.actorId != actorSheet.actor.id) {
console.log("Moving objects", dragData);
actorSheet.actor.moveItemsBetweenActors(objetId, dragData.actorId);
return false;
}
else {
// rangement
const destId = $(event.target).parents(".item").attr("data-item-id");
const srcId = actorSheet.objetVersConteneur[objetId];
if (srcId != destId && objetId != destId && actorSheet.actor.isConteneurSuffisant(objetId, destId)) {
if (srcId) {
await actorSheet.actor.enleverDeConteneur(objetId, srcId);
}
if (destId) { // Dropped over an item !!!
await actorSheet.actor.ajouterAConteneur(objetId, destId);
}
}
}
}
actorSheet.actor.computeEncombrementTotalEtMalusArmure();
} else if (dragData.type == "Actor") {
actorSheet.actor.addSubacteur(objetId);
@ -540,7 +547,7 @@ export class RdDUtility {
html.on("click", '#payer-button', event => {
let sumdenier = event.currentTarget.attributes['data-somme-denier'].value;
let quantite = 1;
if ( event.currentTarget.attributes['data-quantite'] ) {
if (event.currentTarget.attributes['data-quantite']) {
quantite = event.currentTarget.attributes['data-quantite'].value;
}
let jsondata = event.currentTarget.attributes['data-jsondata']
@ -643,7 +650,7 @@ export class RdDUtility {
/* -------------------------------------------- */
static async confirmerSuppression(actorSheet, li) {
let itemId = li.data("item-id");
let objet = actorSheet.actor.items.find(item => item._id == itemId);
let objet = actorSheet.actor.getObjet(itemId);
let msgTxt = "<p>Etes vous certain de vouloir supprimer cet objet ?";
let buttons = {
delete: {