diff --git a/module/actor-creature-sheet.js b/module/actor-creature-sheet.js index 823c6495..b9a820d7 100644 --- a/module/actor-creature-sheet.js +++ b/module/actor-creature-sheet.js @@ -8,18 +8,18 @@ import { HtmlUtility } from "./html-utility.js"; import { RdDUtility } from "./rdd-utility.js"; import { RdDActorSheet } from "./actor-sheet.js"; -/* -------------------------------------------- */ +/* -------------------------------------------- */ export class RdDActorCreatureSheet extends RdDActorSheet { /** @override */ - static get defaultOptions() { - return mergeObject(super.defaultOptions, { - classes: ["rdd", "sheet", "actor"], - template: "systems/foundryvtt-reve-de-dragon/templates/actor-creature-sheet.html", + static get defaultOptions() { + return mergeObject(super.defaultOptions, { + classes: ["rdd", "sheet", "actor"], + template: "systems/foundryvtt-reve-de-dragon/templates/actor-creature-sheet.html", width: 640, height: 720, - tabs: [{navSelector: ".sheet-tabs", contentSelector: ".sheet-body", initial: "carac"}], - dragDrop: [{dragSelector: ".item-list .item", dropSelector: null}] + tabs: [{ navSelector: ".sheet-tabs", contentSelector: ".sheet-body", initial: "carac" }], + dragDrop: [{ dragSelector: ".item-list .item", dropSelector: null }] }); } @@ -41,30 +41,30 @@ export class RdDActorCreatureSheet extends RdDActorSheet { // Compute current carac sum let sum = 0; - Object.values(data.data.carac).forEach(carac => { if (!carac.derivee) { sum += parseInt(carac.value) } } ); + Object.values(data.data.carac).forEach(carac => { if (!carac.derivee) { sum += parseInt(carac.value) } }); data.data.caracSum = sum; - + data.data.carac.taille.isTaille = true; // To avoid button link; data.data.blessures.resume = this.actor.computeResumeBlessure(data.data.blessures); data.data.isGM = game.user.isGM; data.data.competencecreature = data.itemsByType["competencecreature"]; - + this.actor.computeEncombrementTotalEtMalusArmure(); - RdDUtility.filterItemsPerTypeForSheet(data ); - RdDUtility.buildArbreDeConteneur( this, data ); + RdDUtility.filterItemsPerTypeForSheet(data); + RdDUtility.buildArbreDeConteneur(this, data); data.data.encTotal = this.actor.encTotal; data.data.isGM = game.user.isGM; - console.log("Creature : ", this.objetVersConteneur , data); + console.log("Creature : ", this.objetVersConteneur, data); return data; } /* -------------------------------------------- */ /** @override */ - activateListeners(html) { + activateListeners(html) { super.activateListeners(html); HtmlUtility._showControlWhen($(".gm-only"), game.user.isGM); @@ -72,101 +72,25 @@ export class RdDActorCreatureSheet extends RdDActorSheet { // 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.actor.getOwnedItem(li.data("itemId")); - item.sheet.render(true); - }); - - // Delete Inventory Item - html.find('.item-delete').click(ev => { - const li = $(ev.currentTarget).parents(".item"); - this.actor.deleteOwnedItem(li.data("itemId")); - li.slideUp(200, () => this.render(false)); - }); - - // Blessure control - html.find('.blessure-control').click(ev => { - const li = $(ev.currentTarget).parents(".item"); - let btype = li.data("blessure-type"); - let index = li.data('blessure-index'); - let active = $(ev.currentTarget).data('blessure-active'); - //console.log(btype, index, active); - this.actor.manageBlessureFromSheet(btype, index, active).then( this.render(true) ); - }); - - // Blessure data - html.find('.blessures-soins').change(ev => { - const li = $(ev.currentTarget).parents(".item"); - let btype = li.data('blessure-type'); - let index = li.data('blessure-index'); - let psoins = li.find('input[name=premiers_soins]').val(); - let pcomplets = li.find('input[name=soins_complets]').val(); - let jours = li.find('input[name=jours]').val(); - let loc = li.find('input[name=localisation]').val(); - //console.log(btype, index, psoins, pcomplets, jours, loc); - this.actor.setDataBlessureFromSheet(btype, index, psoins, pcomplets, jours, loc).then( this.render(true) ); - }); - - // Roll Carac - html.find('.carac-label a').click((event) => { - let caracName = event.currentTarget.attributes.name.value; - this.actor.rollCarac( caracName.toLowerCase() ); - }); - // On competence change html.find('.creature-carac').change((event) => { - let compName = event.currentTarget.attributes.compname.value; - this.actor.updateCreatureCompetence( compName, "carac_value", parseInt(event.target.value) ); - } ); + let compName = event.currentTarget.attributes.compname.value; + this.actor.updateCreatureCompetence(compName, "carac_value", parseInt(event.target.value)); + }); html.find('.creature-niveau').change((event) => { - let compName = event.currentTarget.attributes.compname.value; - this.actor.updateCreatureCompetence( compName, "niveau", parseInt(event.target.value) ); - } ); - html.find('.creature-dommages').change((event) => { - let compName = event.currentTarget.attributes.compname.value; - this.actor.updateCreatureCompetence( compName, "dommages", parseInt(event.target.value) ); - } ); - - // Roll Skill - html.find('.competence-label a').click((event) => { - let compName = event.currentTarget.text; - this.actor.rollCompetenceCreature( compName ); + let compName = event.currentTarget.attributes.compname.value; + this.actor.updateCreatureCompetence(compName, "niveau", parseInt(event.target.value)); }); - - html.find('#vie-plus').click((event) => { - this.actor.santeIncDec("vie", 1); - this.render(true); - }); - html.find('#vie-moins').click((event) => { - this.actor.santeIncDec("vie", -1); - this.render(true); - }); - html.find('#endurance-plus').click((event) => { - this.actor.santeIncDec("endurance", 1); - this.render(true); - }); - html.find('#endurance-moins').click((event) => { - this.actor.santeIncDec("endurance", -1); - this.render(true); - }); - - html.find('#encaisser-direct').click(ev => { - this.actor.encaisser(); - }); - - html.find('#remise-a-neuf').click(ev => { - if (game.user.isGM) { - this.actor.remiseANeuf(); - } + html.find('.creature-dommages').change((event) => { + let compName = event.currentTarget.attributes.compname.value; + this.actor.updateCreatureCompetence(compName, "dommages", parseInt(event.target.value)); }); } - + /* -------------------------------------------- */ /** @override */ - setPosition(options={}) { + setPosition(options = {}) { const position = super.setPosition(options); const sheetBody = this.element.find(".sheet-body"); const bodyHeight = position.height - 192; diff --git a/module/actor-entite-sheet.js b/module/actor-entite-sheet.js index ea5a1e23..8e9f3c93 100644 --- a/module/actor-entite-sheet.js +++ b/module/actor-entite-sheet.js @@ -96,7 +96,7 @@ export class RdDActorEntiteSheet extends ActorSheet { // Roll Skill html.find('.competence-label a').click((event) => { let compName = event.currentTarget.text; - this.actor.rollCompetenceCreature( compName ); + this.actor.rollCompetence( compName ); }); html.find('#endurance-plus').click((event) => { @@ -112,7 +112,7 @@ export class RdDActorEntiteSheet extends ActorSheet { this.actor.encaisser(); }); - html.find('#remise-a-neuf').click(ev => { + html.find('.remise-a-neuf').click(ev => { if (game.user.isGM) { this.actor.remiseANeuf(); } diff --git a/module/actor-sheet.js b/module/actor-sheet.js index 293f4f47..33e4f2c3 100644 --- a/module/actor-sheet.js +++ b/module/actor-sheet.js @@ -207,9 +207,10 @@ export class RdDActorSheet extends ActorSheet { this.actor.encaisser(); }); - html.find('#remise-a-neuf').click(ev => { + html.find('.remise-a-neuf').click(ev => { if (game.user.isGM) { this.actor.remiseANeuf(); + ev.preventDefault(); } }); html.find('#creer-tache').click(ev => { diff --git a/module/actor.js b/module/actor.js index 78aa7024..1e89f187 100644 --- a/module/actor.js +++ b/module/actor.js @@ -391,7 +391,9 @@ export class RdDActor extends Actor { } await this.update({ "data.blessures": blessures }); } - await this.setEthylisme(1); + if (this.isPersonnage()) { + await this.setEthylisme(1); + } await this.santeIncDec("vie", this.data.data.sante.vie.max - this.data.data.sante.vie.value); await this.santeIncDec("endurance", this.data.data.sante.endurance.max - this.data.data.sante.endurance.value); @@ -1149,7 +1151,7 @@ export class RdDActor extends Actor { const sante = duplicate(this.data.data.sante); let compteur = sante[name]; if (!compteur) { - return; + return ; } let result = { sonne: false, @@ -1751,8 +1753,13 @@ export class RdDActor extends Actor { /* -------------------------------------------- */ async rollCompetence(name) { let rollData = { competence: this.getCompetence(name) } - + if (rollData.competence.type == 'competencecreature') { + if (rollData.competence.data.iscombat) { + const arme = RdDItemCompetenceCreature.toArme(competence); + RdDCombat.createUsingTarget(this).attaque(competence, arme); + return; + } // Fake competence pour créature RdDItemCompetenceCreature.setRollDataCreature(rollData); } @@ -2123,19 +2130,6 @@ export class RdDActor extends Actor { this.currentTMR.render(true); } - - /* -------------------------------------------- */ - async rollCompetenceCreature(compName) { - const competence = this.getCompetence(compName); - if (competence.type == 'competencecreature' && competence.data.iscombat) { - const arme = RdDItemCompetenceCreature.toArme(competence); - RdDCombat.createUsingTarget(this).attaque(competence, arme); - } - else { - this.rollCompetence(competence.name); - } - } - /* -------------------------------------------- */ rollArme(compName, armeName = undefined) { let arme = armeName ? this.data.items.find(item => item.name == armeName && RdDItemArme.isArme(item)) : undefined; @@ -2175,36 +2169,18 @@ export class RdDActor extends Actor { /* -------------------------------------------- */ computeArmure(attackerRoll) { - let dmg = attackerRoll.dmg.dmgArme + attackerRoll.dmg.dmgActor; + let dmg = (attackerRoll.dmg.dmgArme ??0) + (attackerRoll.dmg.dmgActor ?? 0); let arme = attackerRoll.arme; - // TODO: arc ignore armure let protection = 0; - for (const item of this.data.items) { - if (item.type == "armure" && item.data.equipe) { - let update = duplicate(item); - protection += new Roll(update.data.protection.toString()).roll().total; - update.data.deterioration = Misc.toInt(update.data.deterioration) + dmg; - dmg = 0; // Reset it - if (update.data.deterioration >= 10) { - update.data.deterioration = 0; - let res = /\d+/.exec(update.data.protection); - if (res) - update.data.protection = "1d" + update.data.protection; - // if ( update.data.protection.toString().length == 1 ) - // update.data.protection = "1d"+update.data.protection; - else if (res = /(\d+d\d+)(\-\d+)?/.exec(update.data.protection)) { - let malus = Misc.toInt(res[2]) - 1; - update.data.protection = res[1] + malus; - } - else { - ui.notifications.warn(`La valeur d'armure de votre ${item.name} est incorrecte`) - } - ChatMessage.create({ content: "Détérioration d'armure: " + update.data.protection }); - } - this.updateEmbeddedEntity("OwnedItem", update); + const armures = this.data.items.filter(it => it.type == "armure" && it.data.equipe); + for (const item of armures) { + protection += new Roll(item.data.protection.toString()).roll().total; + if (dmg > 0) { + this._deteriorerArmure(item, dmg); + dmg = 0; } } - // TODO: max armure (chutes) + // TODO: max armure sur chutes... const penetration = arme ? Misc.toInt(arme.data.penetration) : 0; protection = Math.max(protection - penetration, 0); protection += this.getProtectionNaturelle(); @@ -2212,6 +2188,27 @@ export class RdDActor extends Actor { return protection; } + _deteriorerArmure(item, dmg) { + let update = duplicate(item); + update.data.deterioration = (update.data.deterioration ?? 0) + dmg; + if (update.data.deterioration >= 10) { + update.data.deterioration = 0; + let res = /\d+/.exec(update.data.protection); + if (!res) { + update.data.protection = "1d" + update.data.protection; + } + else if (res = /(\d+d\d+)(\-\d+)?/.exec(update.data.protection)) { + let malus = Misc.toInt(res[2]) - 1; + update.data.protection = res[1] + malus; + } + else { + ui.notifications.warn(`La valeur d'armure de votre ${item.name} est incorrecte`); + } + ChatMessage.create({ content: "Votre armure s'est détériorée, elle protège maintenant de " + update.data.protection }); + } + this.updateEmbeddedEntity("OwnedItem", update); + } + /* -------------------------------------------- */ async encaisser() { let data = { ajustementsEncaissement: RdDUtility.getAjustementsEncaissement() }; @@ -2231,7 +2228,9 @@ export class RdDActor extends Actor { let encaissement = this.jetEncaissement(rollData); this.ajouterBlessure(encaissement); // Will upate the result table - const perteVie = await this.santeIncDec("vie", - encaissement.vie); + const perteVie = this.isEntiteCauchemar() + ? { newValue: 0} + : await this.santeIncDec("vie", - encaissement.vie); const perteEndurance = await this.santeIncDec("endurance", -encaissement.endurance, (encaissement.critiques > 0)); this.computeEtatGeneral(); @@ -2245,7 +2244,7 @@ export class RdDActor extends Actor { encaissement.sonne = perteEndurance.sonne; encaissement.jetEndurance = perteEndurance.jetEndurance; encaissement.endurance = santeOrig.endurance.value - perteEndurance.newValue; - encaissement.vie = santeOrig.vie.value - perteVie.newValue; + encaissement.vie = this.isEntiteCauchemar() ? 0 : (santeOrig.vie.value - perteVie.newValue); ChatUtility.createChatWithRollMode(this.name, { roll: encaissement.roll, diff --git a/module/rdd-combat.js b/module/rdd-combat.js index c4183b1b..d4cd0726 100644 --- a/module/rdd-combat.js +++ b/module/rdd-combat.js @@ -107,27 +107,27 @@ export class RdDCombat { /* -------------------------------------------- */ static _getAttaque(attackerId) { return game.system.rdd.combatStore.attaques[attackerId]; - } - + } + /* -------------------------------------------- */ static _deleteAttaque(attackerId) { delete game.system.rdd.combatStore.attaques[attackerId]; - } + } /* -------------------------------------------- */ static _storeDefense(defenderRoll) { game.system.rdd.combatStore.defenses[defenderRoll.passeArme] = duplicate(defenderRoll); - } + } /* -------------------------------------------- */ static _getDefense(passeArme) { return game.system.rdd.combatStore.defenses[passeArme]; - } - + } + /* -------------------------------------------- */ static _deleteDefense(passeArme) { - delete game.system.rdd.combatStore.defenses; - } + delete game.system.rdd.combatStore.defenses[passeArme]; + } /* -------------------------------------------- */ static create(attacker, defender, defenderTokenId, target = undefined) { @@ -135,15 +135,11 @@ export class RdDCombat { } /* -------------------------------------------- */ - static createForEvent(event) { - let attackerId = event.currentTarget.attributes['data-attackerId'].value; - let attacker = game.actors.get(attackerId); - - const dataDefenderTokenId = event.currentTarget.attributes['data-defenderTokenId']; - if (dataDefenderTokenId) { - const defenderTokenId = dataDefenderTokenId.value; - let defenderToken = canvas.tokens.get(defenderTokenId); - let defender = defenderToken.actor; + static createForAttackerAndDefender(attackerId, defenderTokenId) { + const attacker = game.actors.get(attackerId); + if (defenderTokenId) { + const defenderToken = canvas.tokens.get(defenderTokenId); + const defender = defenderToken.actor; return RdDCombat.create(attacker, defender, defenderTokenId); } @@ -166,17 +162,19 @@ export class RdDCombat { } /* -------------------------------------------- */ - static onMsgDefense(msgData) { - let defenderToken = canvas.tokens.get(msgData.defenderTokenId); + static onMsgDefense(msg) { + let defenderToken = canvas.tokens.get(msg.defenderTokenId); if (defenderToken) { if (!game.user.isGM && !game.user.character) { // vérification / sanity check ui.notifications.error("Le joueur " + game.user.name + " n'est connecté à aucun personnage. Impossible de continuer."); return; } - if ((game.user.isGM && !defenderToken.actor.hasPlayerOwner) || (defenderToken.actor.hasPlayerOwner && (game.user.character.id == defenderToken.actor.data._id))) { - const defenderRoll = msgData.defenderRoll; - RdDCombat._storeAttaque(msgData.attackerId, defenderRoll.attackerRoll); + if ((game.user.isGM && !defenderToken.actor.hasPlayerOwner) || (defenderToken.actor.hasPlayerOwner && (game.user.character._id == defenderToken.actor.data._id))) { + const rddCombat = RdDCombat.createForAttackerAndDefender(msg.attackerId, msg.defenderTokenId); + const defenderRoll = msg.defenderRoll; + RdDCombat._storeAttaque(msg.attackerId, defenderRoll.attackerRoll); RdDCombat._storeDefense(defenderRoll); + rddCombat._chatMessageDefense(msg.paramChatDefense); } } } @@ -202,8 +200,12 @@ export class RdDCombat { '#echec-total-attaque', ]) { html.on("click", button, event => { + const rddCombat = RdDCombat.createForAttackerAndDefender( + event.currentTarget.attributes['data-attackerId']?.value, + event.currentTarget.attributes['data-defenderTokenId']?.value); + + rddCombat.onEvent(button, event); event.preventDefault(); - RdDCombat.createForEvent(event).onEvent(button, event); }); } html.on("click", '#chat-jet-vie', event => { @@ -308,7 +310,7 @@ export class RdDCombat { /* -------------------------------------------- */ removeChatMessageActionsPasseArme(passeArme) { - if (game.settings.get("foundryvtt-reve-de-dragon", "supprimer-dialogues-combat-chat")) { + if (game.user.isGM && game.settings.get("foundryvtt-reve-de-dragon", "supprimer-dialogues-combat-chat")) { ChatUtility.removeMyChatMessageContaining(`