diff --git a/.history/modules/mournblade-cyd2-actor_20251026001301.js b/.history/modules/mournblade-cyd2-actor_20251026001301.js
deleted file mode 100644
index 24a1abe..0000000
--- a/.history/modules/mournblade-cyd2-actor_20251026001301.js
+++ /dev/null
@@ -1,811 +0,0 @@
-/* -------------------------------------------- */
-import { MournbladeCYD2Utility } from "./mournblade-cyd2-utility.js";
-import { MournbladeCYD2RollDialog } from "./mournblade-cyd2-roll-dialog.js";
-
-/* -------------------------------------------- */
-const __degatsBonus = [-2, -2, -1, -1, 0, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 8, 8, 9, 9, 10, 10]
-const __vitesseBonus = [-2, -2, -1, -1, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8]
-
-/* -------------------------------------------- */
-/**
- * Extend the base Actor entity by defining a custom roll data structure which is ideal for the Simple system.
- * @extends {Actor}
- */
-export class MournbladeCYD2Actor extends Actor {
-
- /* -------------------------------------------- */
- /**
- * Override the create() function to provide additional SoS functionality.
- *
- * This overrided create() function adds initial items
- * Namely: Basic skills, money,
- *
- * @param {Object} data Barebones actor data which this function adds onto.
- * @param {Object} options (Unused) Additional options which customize the creation workflow.
- *
- */
-
- static async create(data, options) {
-
- // Case of compendium global import
- if (data instanceof Array) {
- return super.create(data, options);
- }
- // If the created actor has items (only applicable to duplicated actors) bypass the new actor creation logic
- if (data.items) {
- let actor = super.create(data, options);
- return actor;
- }
-
- if (data.type == 'personnage') {
- const skills = await MournbladeCYD2Utility.loadCompendium("fvtt-mournblade-cyd2.skills")
- data.items = skills.map(i => i.toObject())
- }
- if (data.type == 'creature') {
- const skills = await MournbladeCYD2Utility.loadCompendium("fvtt-mournblade-cyd2.skills-creatures")
- data.items = skills.map(i => i.toObject())
- data.items.push({ name: "Arme naturelle 1", type: 'arme', img: "systems/fvtt-mournblade-cyd2/assets/icons/melee.webp", system: { typearme: "contact", bonusmaniementoff: 0, seuildefense: 0, degats: "0" } })
- data.items.push({ name: "Arme naturelle 2", type: 'arme', img: "systems/fvtt-mournblade-cyd2/assets/icons/melee.webp", system: { typearme: "contact", bonusmaniementoff: 0, seuildefense: 0, degats: "0" } })
- }
-
- return super.create(data, options);
- }
-
- /* -------------------------------------------- */
- getBonusDefenseFromTalents() {
- let talents = this.items.filter(item => item.type == "talent" && item.system.isautomated)
- let bonus = 0
- for (let talent of talents) {
- for (let auto of talent.system.automations) {
- if (auto.eventtype == "bonus-permanent" && auto.bonusname == "bonus-defensif") {
- bonus += Number(auto.bonus || 0)
- }
- }
- }
- return bonus
- }
-
- /* -------------------------------------------- */
- prepareArme(arme) {
- if (this.type == "cellule") {
- return arme
- }
-
- arme = foundry.utils.duplicate(arme)
- let combat = this.getCombatValues()
- if (arme.system.typearme == "contact" || arme.system.typearme == "contactjet") {
- let bonusDefense = this.getBonusDefenseFromTalents()
- arme.system.competence = foundry.utils.duplicate(this.items.find(item => item.type == "competence" && item.name.toLowerCase() == "mêlée"))
- arme.system.attrKey = "pui"
- arme.system.totalDegats = arme.system.degats + "+" + combat.bonusDegatsTotal
- arme.system.totalOffensif = this.system.attributs.pui.value + arme.system.competence.system.niveau + arme.system.bonusmaniementoff + (this.system.combat.monte ? 3 : 0)
- arme.system.totalDefensif = combat.defenseTotal + arme.system.competence.system.niveau + arme.system.seuildefense + bonusDefense + (this.system.combat.monte ? 3 : 0)
- console.log("Arme", arme.system.totalDefensif, combat, arme.system.competence.system.niveau, arme.system.seuildefense, bonusDefense)
- arme.system.isdefense = true
- arme.system.isMelee = true
- arme.system.isDistance = false
- }
- if (arme.system.typearme == "jet" || arme.system.typearme == "tir") {
- arme.system.competence = foundry.utils.duplicate(this.items.find(item => item.type == "competence" && item.name.toLowerCase() == "armes à distance"))
- arme.system.attrKey = "adr"
- arme.system.totalOffensif = this.system.attributs.adr.value + arme.system.competence.system.niveau + arme.system.bonusmaniementoff
- arme.system.totalDegats = arme.system.degats
- arme.system.isMelee = false
- arme.system.isDistance = true
- if (arme.system.isdefense) {
- arme.system.totalDefensif = combat.defenseTotal + arme.system.competence.system.niveau + arme.system.seuildefense
- }
- }
- return arme
- }
-
- /* -------------------------------------------- */
- getItemSorted(types) {
- let items = this.items.filter(item => types.includes(item.type)) || []
- MournbladeCYD2Utility.sortArrayObjectsByName(items)
- return items
- }
- getWeapons() {
- let armes = []
- for (let arme of this.items) {
- if (arme.type == "arme") {
- armes.push(this.prepareArme(arme))
- }
- }
- MournbladeCYD2Utility.sortArrayObjectsByName(armes)
- return armes
- }
- getMonnaies() {
- return this.getItemSorted(["monnaie"])
- }
- getEquipments() {
- return this.getItemSorted(["equipement"])
- }
- getArtefacts() {
- return this.getItemSorted(["artefact"])
- }
- getArmors() {
- return this.getItemSorted(["protection"])
- }
- getHistoriques() {
- return this.getItemSorted(["historique"])
- }
- getProfils() {
- return this.getItemSorted(["profil"])
- }
- getTalents() {
- return this.getItemSorted(["talent"])
- }
- getRessources() {
- return this.getItemSorted(["ressource"])
- }
- getContacts() {
- return this.getItemSorted(["contact"])
- }
- getMutations() {
- return this.getItemSorted(["mutation"])
- }
- getDons() {
- return this.getItemSorted(["don"])
- }
- getPactes() {
- return this.getItemSorted(["pacte"])
- }
- getTendances() {
- return this.getItemSorted(["tendance"])
- }
- getRunes() {
- return this.getItemSorted(["rune"])
- }
- getTraitsChaotiques() {
- return this.getItemSorted(["traitchaotique"])
- }
- getTraitsEspeces() {
- return this.getItemSorted(["traitespece"])
- }
-
- /* -------------------------------------------- */
- getSkills() {
- let comp = []
- for (let item of this.items) {
- item = foundry.utils.duplicate(item)
- if (item.type == "competence") {
- item.system.attribut1total = item.system.niveau + (this.system.attributs[item.system.attribut1]?.value || 0)
- item.system.attribut2total = item.system.niveau + (this.system.attributs[item.system.attribut2]?.value || 0)
- item.system.attribut3total = item.system.niveau + (this.system.attributs[item.system.attribut3]?.value || 0)
- if (item.system.niveau == 0) {
- item.system.attribut1total -= 3
- item.system.attribut2total -= 3
- item.system.attribut3total -= 3
- }
- item.system.attribut1label = this.system.attributs[item.system.attribut1]?.label || ""
- item.system.attribut2label = this.system.attributs[item.system.attribut2]?.label || ""
- item.system.attribut3label = this.system.attributs[item.system.attribut3]?.label || ""
- comp.push(item)
- }
- }
- MournbladeCYD2Utility.sortArrayObjectsByName(comp)
- return comp
- }
-
- /* ----------------------- --------------------- */
- addMember(actorId) {
- let members = foundry.utils.duplicate(this.system.members)
- members.push({ id: actorId })
- this.update({ 'system.members': members })
- }
- async removeMember(actorId) {
- let members = this.system.members.filter(it => it.id != actorId)
- this.update({ 'system.members': members })
- }
-
- /* -------------------------------------------- */
- getDefenseBase() {
- return Math.max(this.system.attributs.tre.value, this.system.attributs.adr.value)
- }
-
- /* -------------------------------------------- */
- getVitesseBase() {
- return 5 + __vitesseBonus[this.system.attributs.adr.value]
- }
- /* -------------------------------------------- */
- getProtection() {
- let equipProtection = 0
- for (let armor of this.items) {
- if (armor.type == "protection" && armor.system.equipped) {
- equipProtection += Number(armor.system.protection)
- }
- }
- if (equipProtection < 4) {
- return 4 + equipProtection // Cas des boucliers + sans armure
- }
- return equipProtection // Uniquement la protection des armures + boucliers
- }
-
- /* -------------------------------------------- */
- getCombatValues() {
- if (this.type == "cellule") {
- return {
- initBase: 0,
- initTotal: 0,
- bonusDegats: 0,
- bonusDegatsTotal: 0,
- vitesseBase: 0,
- vitesseTotal: 0,
- defenseBase: 0,
- protection: 0,
- defenseTotal: 0
- }
- }
-
- let combat = {
- initBase: this.system.attributs.adr.value,
- initTotal: this.system.attributs.adr.value + this.system.combat.initbonus,
- bonusDegats: this.getBonusDegats(),
- bonusDegatsTotal: this.getBonusDegats() + this.system.combat.bonusdegats,
- vitesseBase: this.getVitesseBase(),
- vitesseTotal: this.getVitesseBase() + this.system.combat.vitessebonus,
- defenseBase: this.getDefenseBase(),
- protection: this.getProtection(),
- defenseTotal: this.getDefenseBase() + this.system.combat.defensebonus + this.getProtection() - this.getTotalAdversite() + (this.system.combat.defensetotale ? 3 : 0)
- }
- return combat
- }
-
- /* -------------------------------------------- */
- prepareBaseData() {
- }
-
- /* -------------------------------------------- */
- async prepareData() {
- super.prepareData();
- }
-
- /* -------------------------------------------- */
- prepareDerivedData() {
-
- if (this.type == 'personnage') {
- let talentBonus = this.getVigueurBonus()
- let vigueur = Math.floor((this.system.attributs.pui.value + this.system.attributs.tre.value) / 2) + talentBonus + this.system.sante.vigueurmodifier
- if (vigueur != this.system.sante.vigueur) {
- this.update({ 'system.sante.vigueur': vigueur })
- }
- }
- super.prepareDerivedData()
- }
-
- /* -------------------------------------------- */
- _preUpdate(changed, options, user) {
- if (changed?.system?.sante?.etat && changed?.system?.sante?.etat != this.system.sante.etat) {
- setTimeout(() => {
- this.processCombativite(changed.system.sante)
- }, 800)
- }
- super._preUpdate(changed, options, user);
- }
-
- /* -------------------------------------------- */
- _onUpdate(data, options, user) {
- super._onUpdate(data, options, user);
- }
- /* -------------------------------------------- */
- getItemById(id) {
- let item = this.items.find(item => item.id == id);
- if (item) {
- item = foundry.utils.duplicate(item)
- }
- return item;
- }
-
- /* -------------------------------------------- */
- async equipItem(itemId) {
- let item = this.items.find(item => item.id == itemId)
- if (item && item.system) {
- let update = { _id: item.id, "system.equipped": !item.system.equipped }
- await this.updateEmbeddedDocuments('Item', [update]); // Updates one EmbeddedEntity
- }
- }
-
- /* -------------------------------------------- */
- editItemField(itemId, itemType, itemField, dataType, value) {
- let item = this.items.find(item => item.id == itemId)
- if (item) {
- console.log("Item ", item, itemField, dataType, value)
- if (dataType.toLowerCase() == "number") {
- value = Number(value)
- } else {
- value = String(value)
- }
- let update = { _id: item.id, [`system.${itemField}`]: value };
- this.updateEmbeddedDocuments("Item", [update])
- }
- }
-
- /* -------------------------------------------- */
- checkAttribut(attribut, minLevel) {
- let attr = this.system.attributs.find(at => at.labelnorm == attribut.toLowerCase())
- if (attr && attr.value >= minLevel) {
- return { isValid: true, attr: foundry.utils.duplicate(attr) }
- }
- return { isValid: false }
- }
- /* -------------------------------------------- */
- checkAttributOrCompetenceLevel(compName, minLevel) {
- let comp = this.items.find(i => i.type == "competence" && i.name.toLowerCase() == compName.toLowerCase() && i.system.niveau >= minLevel)
- if (comp) {
- return { isValid: true, item: foundry.utils.duplicate(comp) }
- } else {
- for (let attrKey in this.system.attributs) {
- if (this.system.attributs[attrKey].label.toLowerCase() == compName.toLowerCase() && this.system.attributs[attrKey].value >= minLevel) {
- return { isValid: true, item: foundry.utils.duplicate(this.system.attributs[attrKey]) }
- }
- }
- }
- return { isValid: false, warningMessage: `Prérequis insuffisant : la compétence/attribut ${compName} doit être de niveau ${minLevel} au minimum` }
- }
- /* -------------------------------------------- */
- addCompetenceBonus(compName, bonus, baCost) {
- let comp = this.items.find(i => i.type == "competence" && i.name.toLowerCase() == compName.toLowerCase())
- if (comp) {
- comp = foundry.utils.duplicate(comp)
- comp.system.bonus = bonus
- comp.system.baCost = baCost
- return { isValid: true, item: comp }
- }
- return { isValid: false, warningMessage: `Compétence ${compName} non trouvée` }
- }
- /* -------------------------------------------- */
- checkIfCompetence(compName) {
- let comp = this.items.find(i => i.type == "competence" && i.name.toLowerCase() == compName.toLowerCase())
- if (comp) {
- return { isValid: true, item: comp }
- }
- return { isValid: false }
- }
- /* -------------------------------------------- */
- getVigueur() {
- return this.system.sante.vigueur
- }
-
- /* -------------------------------------------- */
- getVigueurBonus() {
- let talents = this.items.filter(item => item.type == "talent" && item.system.isautomated)
- let bonus = 0
- for (let talent of talents) {
- for (let auto of talent.system.automations) {
- if (auto.eventtype == "bonus-permanent" && auto.bonusname == "vigueur") {
- bonus += Number(auto.bonus || 0)
- }
- }
- }
- return bonus
- }
-
- /* -------------------------------------------- */
- getBonneAventure() {
- return this.system.bonneaventure.actuelle
- }
- /* -------------------------------------------- */
- checkBonneAventure(cost) {
- return (this.system.bonneaventure.actuelle >= cost)
- }
- /* -------------------------------------------- */
- changeBonneAventure(value) {
- let newBA = this.system.bonneaventure.actuelle
- newBA += value
- this.update({ 'system.bonneaventure.actuelle': newBA })
- }
-
- /* -------------------------------------------- */
- getEclat() {
- return this.system.eclat.value
- }
-
- /* -------------------------------------------- */
- changeEclat(value) {
- let newE = this.system.eclat.value
- newE += value
- this.update({ 'system.eclat.value': newE })
- }
-
- /* -------------------------------------------- */
- compareName(a, b) {
- if (a.name < b.name) {
- return -1;
- }
- if (a.name > b.name) {
- return 1;
- }
- return 0;
- }
-
- /* -------------------------------------------- */
- getAttribute(attrKey) {
- return this.system.attributes[attrKey]
- }
-
- /* -------------------------------------------- */
- getBonusDegats() {
- return 0;
- }
-
- /* -------------------------------------------- */
- changeEtatCombativite(value) {
- if (value === "vaincu") {
- value = 200
- }
- let sante = foundry.utils.duplicate(this.system.sante)
- sante.etat += Number(value)
- sante.etat = Math.max(sante.etat, 0)
- sante.etat = Math.min(sante.etat, this.system.sante.nbcombativite)
- this.update({ 'system.sante': sante })
- if (sante.etat == this.system.sante.nbcombativite) {
- ChatMessage.create({ content: `${this.name} est vaincu !` })
- }
- // Duplicated ! this.processCombativite(sante)
- }
-
- /* -------------------------------------------- */
- processCombativite(sante) {
- sante = sante || foundry.utils.duplicate(this.system.sante)
- // Gestion des états affaibli et très affaibli
- if (sante.etat == this.system.sante.nbcombativite - 2 || sante.etat == this.system.sante.nbcombativite - 1) {
- if (sante.etat == this.system.sante.nbcombativite - 2 && this.items.find(item => item.type == "talent" && item.name.toLowerCase() == "encaissement")) {
- ChatMessage.create({ content: `${this.name} ne subit pas les 2 adversités rouge grâce à Encaissement. Pensez à les ajouter à la fin de la scène !` })
- } else if (sante.etat == this.system.sante.nbcombativite - 1 && this.items.find(item => item.type == "talent" && item.name.toLowerCase().includes("vaillant"))) {
- ChatMessage.create({ content: `${this.name} ne subit pas les 2 adversités rouge grâce à Vaillant. Pensez à les ajouter à la fin de la scène !` })
- } else {
- ChatMessage.create({ content: `${this.name} subit 2 adversités rouge !` })
- this.incDecAdversite("rouge", 2)
- }
- }
- }
-
- /* -------------------------------------------- */
- async equipGear(equipmentId) {
- let item = this.items.find(item => item.id == equipmentId);
- if (item?.system?.data) {
- let update = { _id: item.id, "system.equipped": !item.system.equipped };
- await this.updateEmbeddedDocuments('Item', [update]); // Updates one EmbeddedEntity
- }
- }
-
- /* -------------------------------------------- */
- getSubActors() {
- let subActors = [];
- for (let id of this.system.subactors) {
- subActors.push(foundry.utils.duplicate(game.actors.get(id)));
- }
- return subActors;
- }
- /* -------------------------------------------- */
- async addSubActor(subActorId) {
- let subActors = foundry.utils.duplicate(this.system.subactors);
- subActors.push(subActorId);
- await this.update({ 'system.subactors': subActors });
- }
- /* -------------------------------------------- */
- async delSubActor(subActorId) {
- let newArray = [];
- for (let id of this.system.subactors) {
- if (id != subActorId) {
- newArray.push(id);
- }
- }
- await this.update({ 'system.subactors': newArray });
- }
-
- /* -------------------------------------------- */
- getTotalAdversite() {
- return this.system.adversite.bleue + this.system.adversite.rouge + this.system.adversite.noire
- }
-
- /* -------------------------------------------- */
- async incDecAdversite(adv, incDec = 0) {
- let adversite = foundry.utils.duplicate(this.system.adversite)
- adversite[adv] += Number(incDec)
- adversite[adv] = Math.max(adversite[adv], 0)
- adversite[adv] = Math.min(adversite[adv], 20)
- this.update({ 'system.adversite': adversite })
- }
- /* -------------------------------------------- */
- async incDecQuantity(objetId, incDec = 0) {
- let objetQ = this.items.get(objetId)
- if (objetQ) {
- let newQ = objetQ.system.quantite + incDec
- newQ = Math.max(newQ, 0)
- await this.updateEmbeddedDocuments('Item', [{ _id: objetQ.id, 'system.quantite': newQ }]); // pdates one EmbeddedEntity
- }
- }
-
- /* -------------------------------------------- */
- computeRichesse() {
- let valueSC = 0
- for (let monnaie of this.items) {
- if (monnaie.type == "monnaie") {
- valueSC += Number(monnaie.system.prixsc) * Number(monnaie.system.quantite)
- }
- }
- return MournbladeCYD2Utility.computeMonnaieDetails(valueSC)
- }
-
- /* -------------------------------------------- */
- computeValeurEquipement() {
- let valueSC = 0
- for (let equip of this.items) {
- if (equip.type == "equipement" || equip.type == "arme" || equip.type == "protection") {
- valueSC += Number(equip.system.prixsc) * Number(equip.system.quantite ?? 1)
- valueSC += (Number(equip.system.prixca) * Number(equip.system.quantite ?? 1)) * 20
- valueSC += (Number(equip.system.prixpo) * Number(equip.system.quantite ?? 1)) * 400
- }
- }
- return MournbladeCYD2Utility.computeMonnaieDetails(valueSC)
- }
-
- /* -------------------------------------------- */
- getCompetence(compId) {
- return this.items.get(compId)
- }
-
- /* -------------------------------------------- */
- async setPredilectionUsed(compId, predIdx) {
- let comp = this.items.get(compId)
- let pred = foundry.utils.duplicate(comp.system.predilections)
- pred[predIdx].used = true
- await this.updateEmbeddedDocuments('Item', [{ _id: compId, 'system.predilections': pred }])
- }
-
- /* -------------------------------------------- */
- getInitiativeScore() {
- let init = this.getFlag("world", "last-initiative")
- return init || -1
- }
-
- /* -------------------------------------------- */
- getBestAttackValue() {
- let attackList = this.items.filter(item => (item.type == "arme" || item.type == "talent") && item.system.equipped)
- let maxOff = 0
- let bestArme
- for (let arme of attackList) {
- if (arme.type == "arme") {
- arme = this.prepareArme(arme)
- }
- if (arme.system.totalOffensif > maxOff) {
- maxOff = arme.system.totalOffensif
- bestArme = foundry.utils.duplicate(arme)
- }
- }
- return bestArme
- }
-
- /* -------------------------------------------- */
- getBestDefenseValue() {
- let defenseList = this.items.filter(item => (item.type == "arme") && item.system.equipped)
- let maxDef = 0
- let bestArme
- for (let arme of defenseList) {
- if (arme.type == "arme") {
- arme = this.prepareArme(arme)
- }
- if (arme.system.totalDefensif > maxDef) {
- maxDef = arme.system.totalDefensif
- bestArme = foundry.utils.duplicate(arme)
- }
- }
- return bestArme
- }
-
- /* -------------------------------------------- */
- searchRelevantTalents(competence) {
- let talents = []
-
- for (let talent of this.items) {
- if (talent.type == "talent" && talent.system.isautomated && talent.system.automations.length > 0) {
- for (let auto of talent.system.automations) {
- if (auto.eventtype === "prepare-roll") {
- if (auto.competence.toLowerCase() == competence.name.toLowerCase()) {
- talent = foundry.utils.duplicate(talent)
- talent.system.bonus = auto.bonus
- talent.system.baCost = auto.baCost
- talents.push(talent)
- }
- }
- }
- }
- }
- return talents
- }
-
- /* -------------------------------------------- */
- buildListeAdversites() {
- return []
- }
-
- /* -------------------------------------------- */
- getCommonRollData(attrKey = undefined, compId = undefined, compName = undefined) {
- let rollData = MournbladeCYD2Utility.getBasicRollData()
- rollData.alias = this.name
- rollData.actorImg = this.img
- rollData.actorId = this.id
- rollData.tokenId = this.token?.id
- rollData.img = this.img
- rollData.attributs = MournbladeCYD2Utility.getAttributs()
- rollData.maitriseId = "none"
- rollData.nbEclat = this.system.eclat.value
- rollData.nbBA = this.system.bonneaventure.actuelle
- rollData.nbAdversites = this.getTotalAdversite()
- rollData.talents = []
- rollData.attrKey2 = "none"
- rollData.coupDevastateur = this.items.find(it => it.type == "talent" && it.name.toLowerCase() == "coup dévastateur" && !it.system.used)
- rollData.hasAmbidextre = this.items.find(it => it.type == "talent" && it.name.toLowerCase() == "ambidextre")
- rollData.hasFeinte = this.system.bonneaventure.actuelle > 0 && this.items.find(it => it.type == "talent" && it.name.toLowerCase() == "feinte")
- rollData.isMonte = this.system.combat.monte
- rollData.config = game.system.mournbladecyd2.config
-
- if (attrKey) {
- rollData.attrKey = attrKey
- if (attrKey != "tochoose") {
- rollData.actionImg = "systems/fvtt-mournblade-cyd2/assets/icons/" + this.system.attributs[attrKey].labelnorm + ".webp"
- rollData.attr = foundry.utils.duplicate(this.system.attributs[attrKey])
- }
- }
- if (compId) {
- rollData.competence = foundry.utils.duplicate(this.items.get(compId) || {})
- let maitrises = [{ key: "none", label: "Aucune" }]
- rollData.competence.system.predilections.forEach(function (item) {
- if (item.maitrise) {
- maitrises.push({ key: item.id, label: item.name });
- }
- })
- rollData.maitrises = maitrises // rollData.competence.system.predilections.filter(p => p.maitrise)
- rollData.actionImg = rollData.competence?.img
- rollData.talents = this.searchRelevantTalents(rollData.competence)
- }
- if (compName) {
- rollData.competence = foundry.utils.duplicate(this.items.find(item => item.name.toLowerCase() == compName.toLowerCase()) || {})
- rollData.actionImg = rollData.competence?.img
- }
- return rollData
- }
-
- /* -------------------------------------------- */
- async rollAttribut(attrKey, isInit = false) {
- let rollData = this.getCommonRollData(attrKey)
- rollData.multiplier = (isInit) ? 1 : 2
- rollData.isInit = isInit
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
-
- /* -------------------------------------------- */
- async rollCompetence(attrKey, compId) {
- let rollData = this.getCommonRollData(attrKey, compId)
- rollData.multiplier = 1 // Attr multiplier, always 1 in competence mode
- console.log("RollDatra", rollData)
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
-
- /* -------------------------------------------- */
- async rollArmeOffensif(armeId) {
- let arme = this.items.get(armeId)
- if (arme.type == "arme") {
- arme = this.prepareArme(arme)
- }
- let rollData = this.getCommonRollData(arme.system.attrKey, arme.system.competence._id)
- rollData.arme = arme
- MournbladeCYD2Utility.updateWithTarget(rollData)
- console.log("ARME!", rollData)
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
- /* -------------------------------------------- */
- async rollAssommer() {
- let rollData = this.getCommonRollData("pui", undefined, "Filouterie")
- rollData.assomer = true
- rollData.conditionsCommunes = true
- MournbladeCYD2Utility.updateWithTarget(rollData)
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
- /* -------------------------------------------- */
- async rollCoupBas() {
- let rollData = this.getCommonRollData("pui", undefined, "Mêlée")
- rollData.coupBas = true
- rollData.conditionsCommunes = true
- MournbladeCYD2Utility.updateWithTarget(rollData)
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
- /* -------------------------------------------- */
- async rollImmobiliser() {
- let rollData = this.getCommonRollData("pui", undefined, "Mêlée")
- rollData.immobiliser = true
- rollData.conditionsCommunes = true
- rollData.cibleconsciente = true
- MournbladeCYD2Utility.updateWithTarget(rollData)
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
- /* -------------------------------------------- */
- async rollRepousser() {
- let rollData = this.getCommonRollData("pui", undefined, "Mêlée")
- rollData.repousser = true
- rollData.conditionsCommunes = true
- rollData.cibleconsciente = true
- MournbladeCYD2Utility.updateWithTarget(rollData)
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
- /* -------------------------------------------- */
- async rollDesengager() {
- let rollData = this.getCommonRollData("adr", undefined, "Mouvements")
- rollData.desengager = true
- rollData.conditionsCommunes = true
- MournbladeCYD2Utility.updateWithTarget(rollData)
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
-
- /* -------------------------------------------- */
- async rollArmeDegats(armeId, targetVigueur = undefined, rollDataInput = undefined) {
- let arme = this.items.get(armeId)
- if (arme.type == "arme") {
- arme = this.prepareArme(arme)
- }
- console.log("DEGATS", arme, targetVigueur, rollDataInput)
- let roll
- let bonus = 0
- let bonus2 = 0
-
- if (rollDataInput?.applyCoupDevastateur) {
- bonus2 = Math.floor(this.system.attributs.pui.value / 2)
- let talent = this.items.find(item => item.type == "talent" && item.name.toLowerCase() == "coup dévastateur")
- this.updateEmbeddedDocuments('Item', [{ _id: talent.id, 'system.used': true }])
- }
-
- if (rollDataInput?.isHeroique) {
- if (rollDataInput?.attaqueCharge) {
- bonus = 5
- }
- if (rollDataInput?.chargeCavalerie) {
- bonus = 6
- }
- roll = await new Roll("2d10rr10+" + arme.system.totalDegats + "+" + bonus + "+" + bonus2).roll()
- } else {
- if (rollDataInput?.attaqueCharge) {
- bonus = 3
- }
- if (rollDataInput?.chargeCavalerie) {
- bonus = 4
- }
- roll = await new Roll("1d10+" + arme.system.totalDegats + "+" + bonus + "+" + bonus2).roll()
- }
- await MournbladeCYD2Utility.showDiceSoNice(roll, game.settings.get("core", "rollMode"));
- let nbEtatPerdus = 0
- if (targetVigueur) {
- nbEtatPerdus = Math.floor(roll.total / targetVigueur)
- }
- //console.log(roll)
- let rollData = {
- arme: arme,
- finalResult: roll.total,
- formula: roll.formula,
- alias: this.name,
- actorImg: this.img,
- actorId: this.id,
- defenderTokenId: rollDataInput?.defenderTokenId,
- actionImg: arme.img,
- targetVigueur: targetVigueur,
- nbEtatPerdus: nbEtatPerdus
- }
- MournbladeCYD2Utility.createChatWithRollMode(rollData.alias, {
- content: await renderTemplate(`systems/fvtt-mournblade-cyd2/templates/chat-degats-result.html`, rollData)
- })
-
- if (rollDataInput?.defenderTokenId && nbEtatPerdus) {
- MournbladeCYD2Utility.applyCombativite(rollDataInput, nbEtatPerdus)
- }
-
- }
-}
diff --git a/.history/modules/mournblade-cyd2-actor_20251026001548.js b/.history/modules/mournblade-cyd2-actor_20251026001548.js
deleted file mode 100644
index 24a1abe..0000000
--- a/.history/modules/mournblade-cyd2-actor_20251026001548.js
+++ /dev/null
@@ -1,811 +0,0 @@
-/* -------------------------------------------- */
-import { MournbladeCYD2Utility } from "./mournblade-cyd2-utility.js";
-import { MournbladeCYD2RollDialog } from "./mournblade-cyd2-roll-dialog.js";
-
-/* -------------------------------------------- */
-const __degatsBonus = [-2, -2, -1, -1, 0, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 8, 8, 9, 9, 10, 10]
-const __vitesseBonus = [-2, -2, -1, -1, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8]
-
-/* -------------------------------------------- */
-/**
- * Extend the base Actor entity by defining a custom roll data structure which is ideal for the Simple system.
- * @extends {Actor}
- */
-export class MournbladeCYD2Actor extends Actor {
-
- /* -------------------------------------------- */
- /**
- * Override the create() function to provide additional SoS functionality.
- *
- * This overrided create() function adds initial items
- * Namely: Basic skills, money,
- *
- * @param {Object} data Barebones actor data which this function adds onto.
- * @param {Object} options (Unused) Additional options which customize the creation workflow.
- *
- */
-
- static async create(data, options) {
-
- // Case of compendium global import
- if (data instanceof Array) {
- return super.create(data, options);
- }
- // If the created actor has items (only applicable to duplicated actors) bypass the new actor creation logic
- if (data.items) {
- let actor = super.create(data, options);
- return actor;
- }
-
- if (data.type == 'personnage') {
- const skills = await MournbladeCYD2Utility.loadCompendium("fvtt-mournblade-cyd2.skills")
- data.items = skills.map(i => i.toObject())
- }
- if (data.type == 'creature') {
- const skills = await MournbladeCYD2Utility.loadCompendium("fvtt-mournblade-cyd2.skills-creatures")
- data.items = skills.map(i => i.toObject())
- data.items.push({ name: "Arme naturelle 1", type: 'arme', img: "systems/fvtt-mournblade-cyd2/assets/icons/melee.webp", system: { typearme: "contact", bonusmaniementoff: 0, seuildefense: 0, degats: "0" } })
- data.items.push({ name: "Arme naturelle 2", type: 'arme', img: "systems/fvtt-mournblade-cyd2/assets/icons/melee.webp", system: { typearme: "contact", bonusmaniementoff: 0, seuildefense: 0, degats: "0" } })
- }
-
- return super.create(data, options);
- }
-
- /* -------------------------------------------- */
- getBonusDefenseFromTalents() {
- let talents = this.items.filter(item => item.type == "talent" && item.system.isautomated)
- let bonus = 0
- for (let talent of talents) {
- for (let auto of talent.system.automations) {
- if (auto.eventtype == "bonus-permanent" && auto.bonusname == "bonus-defensif") {
- bonus += Number(auto.bonus || 0)
- }
- }
- }
- return bonus
- }
-
- /* -------------------------------------------- */
- prepareArme(arme) {
- if (this.type == "cellule") {
- return arme
- }
-
- arme = foundry.utils.duplicate(arme)
- let combat = this.getCombatValues()
- if (arme.system.typearme == "contact" || arme.system.typearme == "contactjet") {
- let bonusDefense = this.getBonusDefenseFromTalents()
- arme.system.competence = foundry.utils.duplicate(this.items.find(item => item.type == "competence" && item.name.toLowerCase() == "mêlée"))
- arme.system.attrKey = "pui"
- arme.system.totalDegats = arme.system.degats + "+" + combat.bonusDegatsTotal
- arme.system.totalOffensif = this.system.attributs.pui.value + arme.system.competence.system.niveau + arme.system.bonusmaniementoff + (this.system.combat.monte ? 3 : 0)
- arme.system.totalDefensif = combat.defenseTotal + arme.system.competence.system.niveau + arme.system.seuildefense + bonusDefense + (this.system.combat.monte ? 3 : 0)
- console.log("Arme", arme.system.totalDefensif, combat, arme.system.competence.system.niveau, arme.system.seuildefense, bonusDefense)
- arme.system.isdefense = true
- arme.system.isMelee = true
- arme.system.isDistance = false
- }
- if (arme.system.typearme == "jet" || arme.system.typearme == "tir") {
- arme.system.competence = foundry.utils.duplicate(this.items.find(item => item.type == "competence" && item.name.toLowerCase() == "armes à distance"))
- arme.system.attrKey = "adr"
- arme.system.totalOffensif = this.system.attributs.adr.value + arme.system.competence.system.niveau + arme.system.bonusmaniementoff
- arme.system.totalDegats = arme.system.degats
- arme.system.isMelee = false
- arme.system.isDistance = true
- if (arme.system.isdefense) {
- arme.system.totalDefensif = combat.defenseTotal + arme.system.competence.system.niveau + arme.system.seuildefense
- }
- }
- return arme
- }
-
- /* -------------------------------------------- */
- getItemSorted(types) {
- let items = this.items.filter(item => types.includes(item.type)) || []
- MournbladeCYD2Utility.sortArrayObjectsByName(items)
- return items
- }
- getWeapons() {
- let armes = []
- for (let arme of this.items) {
- if (arme.type == "arme") {
- armes.push(this.prepareArme(arme))
- }
- }
- MournbladeCYD2Utility.sortArrayObjectsByName(armes)
- return armes
- }
- getMonnaies() {
- return this.getItemSorted(["monnaie"])
- }
- getEquipments() {
- return this.getItemSorted(["equipement"])
- }
- getArtefacts() {
- return this.getItemSorted(["artefact"])
- }
- getArmors() {
- return this.getItemSorted(["protection"])
- }
- getHistoriques() {
- return this.getItemSorted(["historique"])
- }
- getProfils() {
- return this.getItemSorted(["profil"])
- }
- getTalents() {
- return this.getItemSorted(["talent"])
- }
- getRessources() {
- return this.getItemSorted(["ressource"])
- }
- getContacts() {
- return this.getItemSorted(["contact"])
- }
- getMutations() {
- return this.getItemSorted(["mutation"])
- }
- getDons() {
- return this.getItemSorted(["don"])
- }
- getPactes() {
- return this.getItemSorted(["pacte"])
- }
- getTendances() {
- return this.getItemSorted(["tendance"])
- }
- getRunes() {
- return this.getItemSorted(["rune"])
- }
- getTraitsChaotiques() {
- return this.getItemSorted(["traitchaotique"])
- }
- getTraitsEspeces() {
- return this.getItemSorted(["traitespece"])
- }
-
- /* -------------------------------------------- */
- getSkills() {
- let comp = []
- for (let item of this.items) {
- item = foundry.utils.duplicate(item)
- if (item.type == "competence") {
- item.system.attribut1total = item.system.niveau + (this.system.attributs[item.system.attribut1]?.value || 0)
- item.system.attribut2total = item.system.niveau + (this.system.attributs[item.system.attribut2]?.value || 0)
- item.system.attribut3total = item.system.niveau + (this.system.attributs[item.system.attribut3]?.value || 0)
- if (item.system.niveau == 0) {
- item.system.attribut1total -= 3
- item.system.attribut2total -= 3
- item.system.attribut3total -= 3
- }
- item.system.attribut1label = this.system.attributs[item.system.attribut1]?.label || ""
- item.system.attribut2label = this.system.attributs[item.system.attribut2]?.label || ""
- item.system.attribut3label = this.system.attributs[item.system.attribut3]?.label || ""
- comp.push(item)
- }
- }
- MournbladeCYD2Utility.sortArrayObjectsByName(comp)
- return comp
- }
-
- /* ----------------------- --------------------- */
- addMember(actorId) {
- let members = foundry.utils.duplicate(this.system.members)
- members.push({ id: actorId })
- this.update({ 'system.members': members })
- }
- async removeMember(actorId) {
- let members = this.system.members.filter(it => it.id != actorId)
- this.update({ 'system.members': members })
- }
-
- /* -------------------------------------------- */
- getDefenseBase() {
- return Math.max(this.system.attributs.tre.value, this.system.attributs.adr.value)
- }
-
- /* -------------------------------------------- */
- getVitesseBase() {
- return 5 + __vitesseBonus[this.system.attributs.adr.value]
- }
- /* -------------------------------------------- */
- getProtection() {
- let equipProtection = 0
- for (let armor of this.items) {
- if (armor.type == "protection" && armor.system.equipped) {
- equipProtection += Number(armor.system.protection)
- }
- }
- if (equipProtection < 4) {
- return 4 + equipProtection // Cas des boucliers + sans armure
- }
- return equipProtection // Uniquement la protection des armures + boucliers
- }
-
- /* -------------------------------------------- */
- getCombatValues() {
- if (this.type == "cellule") {
- return {
- initBase: 0,
- initTotal: 0,
- bonusDegats: 0,
- bonusDegatsTotal: 0,
- vitesseBase: 0,
- vitesseTotal: 0,
- defenseBase: 0,
- protection: 0,
- defenseTotal: 0
- }
- }
-
- let combat = {
- initBase: this.system.attributs.adr.value,
- initTotal: this.system.attributs.adr.value + this.system.combat.initbonus,
- bonusDegats: this.getBonusDegats(),
- bonusDegatsTotal: this.getBonusDegats() + this.system.combat.bonusdegats,
- vitesseBase: this.getVitesseBase(),
- vitesseTotal: this.getVitesseBase() + this.system.combat.vitessebonus,
- defenseBase: this.getDefenseBase(),
- protection: this.getProtection(),
- defenseTotal: this.getDefenseBase() + this.system.combat.defensebonus + this.getProtection() - this.getTotalAdversite() + (this.system.combat.defensetotale ? 3 : 0)
- }
- return combat
- }
-
- /* -------------------------------------------- */
- prepareBaseData() {
- }
-
- /* -------------------------------------------- */
- async prepareData() {
- super.prepareData();
- }
-
- /* -------------------------------------------- */
- prepareDerivedData() {
-
- if (this.type == 'personnage') {
- let talentBonus = this.getVigueurBonus()
- let vigueur = Math.floor((this.system.attributs.pui.value + this.system.attributs.tre.value) / 2) + talentBonus + this.system.sante.vigueurmodifier
- if (vigueur != this.system.sante.vigueur) {
- this.update({ 'system.sante.vigueur': vigueur })
- }
- }
- super.prepareDerivedData()
- }
-
- /* -------------------------------------------- */
- _preUpdate(changed, options, user) {
- if (changed?.system?.sante?.etat && changed?.system?.sante?.etat != this.system.sante.etat) {
- setTimeout(() => {
- this.processCombativite(changed.system.sante)
- }, 800)
- }
- super._preUpdate(changed, options, user);
- }
-
- /* -------------------------------------------- */
- _onUpdate(data, options, user) {
- super._onUpdate(data, options, user);
- }
- /* -------------------------------------------- */
- getItemById(id) {
- let item = this.items.find(item => item.id == id);
- if (item) {
- item = foundry.utils.duplicate(item)
- }
- return item;
- }
-
- /* -------------------------------------------- */
- async equipItem(itemId) {
- let item = this.items.find(item => item.id == itemId)
- if (item && item.system) {
- let update = { _id: item.id, "system.equipped": !item.system.equipped }
- await this.updateEmbeddedDocuments('Item', [update]); // Updates one EmbeddedEntity
- }
- }
-
- /* -------------------------------------------- */
- editItemField(itemId, itemType, itemField, dataType, value) {
- let item = this.items.find(item => item.id == itemId)
- if (item) {
- console.log("Item ", item, itemField, dataType, value)
- if (dataType.toLowerCase() == "number") {
- value = Number(value)
- } else {
- value = String(value)
- }
- let update = { _id: item.id, [`system.${itemField}`]: value };
- this.updateEmbeddedDocuments("Item", [update])
- }
- }
-
- /* -------------------------------------------- */
- checkAttribut(attribut, minLevel) {
- let attr = this.system.attributs.find(at => at.labelnorm == attribut.toLowerCase())
- if (attr && attr.value >= minLevel) {
- return { isValid: true, attr: foundry.utils.duplicate(attr) }
- }
- return { isValid: false }
- }
- /* -------------------------------------------- */
- checkAttributOrCompetenceLevel(compName, minLevel) {
- let comp = this.items.find(i => i.type == "competence" && i.name.toLowerCase() == compName.toLowerCase() && i.system.niveau >= minLevel)
- if (comp) {
- return { isValid: true, item: foundry.utils.duplicate(comp) }
- } else {
- for (let attrKey in this.system.attributs) {
- if (this.system.attributs[attrKey].label.toLowerCase() == compName.toLowerCase() && this.system.attributs[attrKey].value >= minLevel) {
- return { isValid: true, item: foundry.utils.duplicate(this.system.attributs[attrKey]) }
- }
- }
- }
- return { isValid: false, warningMessage: `Prérequis insuffisant : la compétence/attribut ${compName} doit être de niveau ${minLevel} au minimum` }
- }
- /* -------------------------------------------- */
- addCompetenceBonus(compName, bonus, baCost) {
- let comp = this.items.find(i => i.type == "competence" && i.name.toLowerCase() == compName.toLowerCase())
- if (comp) {
- comp = foundry.utils.duplicate(comp)
- comp.system.bonus = bonus
- comp.system.baCost = baCost
- return { isValid: true, item: comp }
- }
- return { isValid: false, warningMessage: `Compétence ${compName} non trouvée` }
- }
- /* -------------------------------------------- */
- checkIfCompetence(compName) {
- let comp = this.items.find(i => i.type == "competence" && i.name.toLowerCase() == compName.toLowerCase())
- if (comp) {
- return { isValid: true, item: comp }
- }
- return { isValid: false }
- }
- /* -------------------------------------------- */
- getVigueur() {
- return this.system.sante.vigueur
- }
-
- /* -------------------------------------------- */
- getVigueurBonus() {
- let talents = this.items.filter(item => item.type == "talent" && item.system.isautomated)
- let bonus = 0
- for (let talent of talents) {
- for (let auto of talent.system.automations) {
- if (auto.eventtype == "bonus-permanent" && auto.bonusname == "vigueur") {
- bonus += Number(auto.bonus || 0)
- }
- }
- }
- return bonus
- }
-
- /* -------------------------------------------- */
- getBonneAventure() {
- return this.system.bonneaventure.actuelle
- }
- /* -------------------------------------------- */
- checkBonneAventure(cost) {
- return (this.system.bonneaventure.actuelle >= cost)
- }
- /* -------------------------------------------- */
- changeBonneAventure(value) {
- let newBA = this.system.bonneaventure.actuelle
- newBA += value
- this.update({ 'system.bonneaventure.actuelle': newBA })
- }
-
- /* -------------------------------------------- */
- getEclat() {
- return this.system.eclat.value
- }
-
- /* -------------------------------------------- */
- changeEclat(value) {
- let newE = this.system.eclat.value
- newE += value
- this.update({ 'system.eclat.value': newE })
- }
-
- /* -------------------------------------------- */
- compareName(a, b) {
- if (a.name < b.name) {
- return -1;
- }
- if (a.name > b.name) {
- return 1;
- }
- return 0;
- }
-
- /* -------------------------------------------- */
- getAttribute(attrKey) {
- return this.system.attributes[attrKey]
- }
-
- /* -------------------------------------------- */
- getBonusDegats() {
- return 0;
- }
-
- /* -------------------------------------------- */
- changeEtatCombativite(value) {
- if (value === "vaincu") {
- value = 200
- }
- let sante = foundry.utils.duplicate(this.system.sante)
- sante.etat += Number(value)
- sante.etat = Math.max(sante.etat, 0)
- sante.etat = Math.min(sante.etat, this.system.sante.nbcombativite)
- this.update({ 'system.sante': sante })
- if (sante.etat == this.system.sante.nbcombativite) {
- ChatMessage.create({ content: `${this.name} est vaincu !` })
- }
- // Duplicated ! this.processCombativite(sante)
- }
-
- /* -------------------------------------------- */
- processCombativite(sante) {
- sante = sante || foundry.utils.duplicate(this.system.sante)
- // Gestion des états affaibli et très affaibli
- if (sante.etat == this.system.sante.nbcombativite - 2 || sante.etat == this.system.sante.nbcombativite - 1) {
- if (sante.etat == this.system.sante.nbcombativite - 2 && this.items.find(item => item.type == "talent" && item.name.toLowerCase() == "encaissement")) {
- ChatMessage.create({ content: `${this.name} ne subit pas les 2 adversités rouge grâce à Encaissement. Pensez à les ajouter à la fin de la scène !` })
- } else if (sante.etat == this.system.sante.nbcombativite - 1 && this.items.find(item => item.type == "talent" && item.name.toLowerCase().includes("vaillant"))) {
- ChatMessage.create({ content: `${this.name} ne subit pas les 2 adversités rouge grâce à Vaillant. Pensez à les ajouter à la fin de la scène !` })
- } else {
- ChatMessage.create({ content: `${this.name} subit 2 adversités rouge !` })
- this.incDecAdversite("rouge", 2)
- }
- }
- }
-
- /* -------------------------------------------- */
- async equipGear(equipmentId) {
- let item = this.items.find(item => item.id == equipmentId);
- if (item?.system?.data) {
- let update = { _id: item.id, "system.equipped": !item.system.equipped };
- await this.updateEmbeddedDocuments('Item', [update]); // Updates one EmbeddedEntity
- }
- }
-
- /* -------------------------------------------- */
- getSubActors() {
- let subActors = [];
- for (let id of this.system.subactors) {
- subActors.push(foundry.utils.duplicate(game.actors.get(id)));
- }
- return subActors;
- }
- /* -------------------------------------------- */
- async addSubActor(subActorId) {
- let subActors = foundry.utils.duplicate(this.system.subactors);
- subActors.push(subActorId);
- await this.update({ 'system.subactors': subActors });
- }
- /* -------------------------------------------- */
- async delSubActor(subActorId) {
- let newArray = [];
- for (let id of this.system.subactors) {
- if (id != subActorId) {
- newArray.push(id);
- }
- }
- await this.update({ 'system.subactors': newArray });
- }
-
- /* -------------------------------------------- */
- getTotalAdversite() {
- return this.system.adversite.bleue + this.system.adversite.rouge + this.system.adversite.noire
- }
-
- /* -------------------------------------------- */
- async incDecAdversite(adv, incDec = 0) {
- let adversite = foundry.utils.duplicate(this.system.adversite)
- adversite[adv] += Number(incDec)
- adversite[adv] = Math.max(adversite[adv], 0)
- adversite[adv] = Math.min(adversite[adv], 20)
- this.update({ 'system.adversite': adversite })
- }
- /* -------------------------------------------- */
- async incDecQuantity(objetId, incDec = 0) {
- let objetQ = this.items.get(objetId)
- if (objetQ) {
- let newQ = objetQ.system.quantite + incDec
- newQ = Math.max(newQ, 0)
- await this.updateEmbeddedDocuments('Item', [{ _id: objetQ.id, 'system.quantite': newQ }]); // pdates one EmbeddedEntity
- }
- }
-
- /* -------------------------------------------- */
- computeRichesse() {
- let valueSC = 0
- for (let monnaie of this.items) {
- if (monnaie.type == "monnaie") {
- valueSC += Number(monnaie.system.prixsc) * Number(monnaie.system.quantite)
- }
- }
- return MournbladeCYD2Utility.computeMonnaieDetails(valueSC)
- }
-
- /* -------------------------------------------- */
- computeValeurEquipement() {
- let valueSC = 0
- for (let equip of this.items) {
- if (equip.type == "equipement" || equip.type == "arme" || equip.type == "protection") {
- valueSC += Number(equip.system.prixsc) * Number(equip.system.quantite ?? 1)
- valueSC += (Number(equip.system.prixca) * Number(equip.system.quantite ?? 1)) * 20
- valueSC += (Number(equip.system.prixpo) * Number(equip.system.quantite ?? 1)) * 400
- }
- }
- return MournbladeCYD2Utility.computeMonnaieDetails(valueSC)
- }
-
- /* -------------------------------------------- */
- getCompetence(compId) {
- return this.items.get(compId)
- }
-
- /* -------------------------------------------- */
- async setPredilectionUsed(compId, predIdx) {
- let comp = this.items.get(compId)
- let pred = foundry.utils.duplicate(comp.system.predilections)
- pred[predIdx].used = true
- await this.updateEmbeddedDocuments('Item', [{ _id: compId, 'system.predilections': pred }])
- }
-
- /* -------------------------------------------- */
- getInitiativeScore() {
- let init = this.getFlag("world", "last-initiative")
- return init || -1
- }
-
- /* -------------------------------------------- */
- getBestAttackValue() {
- let attackList = this.items.filter(item => (item.type == "arme" || item.type == "talent") && item.system.equipped)
- let maxOff = 0
- let bestArme
- for (let arme of attackList) {
- if (arme.type == "arme") {
- arme = this.prepareArme(arme)
- }
- if (arme.system.totalOffensif > maxOff) {
- maxOff = arme.system.totalOffensif
- bestArme = foundry.utils.duplicate(arme)
- }
- }
- return bestArme
- }
-
- /* -------------------------------------------- */
- getBestDefenseValue() {
- let defenseList = this.items.filter(item => (item.type == "arme") && item.system.equipped)
- let maxDef = 0
- let bestArme
- for (let arme of defenseList) {
- if (arme.type == "arme") {
- arme = this.prepareArme(arme)
- }
- if (arme.system.totalDefensif > maxDef) {
- maxDef = arme.system.totalDefensif
- bestArme = foundry.utils.duplicate(arme)
- }
- }
- return bestArme
- }
-
- /* -------------------------------------------- */
- searchRelevantTalents(competence) {
- let talents = []
-
- for (let talent of this.items) {
- if (talent.type == "talent" && talent.system.isautomated && talent.system.automations.length > 0) {
- for (let auto of talent.system.automations) {
- if (auto.eventtype === "prepare-roll") {
- if (auto.competence.toLowerCase() == competence.name.toLowerCase()) {
- talent = foundry.utils.duplicate(talent)
- talent.system.bonus = auto.bonus
- talent.system.baCost = auto.baCost
- talents.push(talent)
- }
- }
- }
- }
- }
- return talents
- }
-
- /* -------------------------------------------- */
- buildListeAdversites() {
- return []
- }
-
- /* -------------------------------------------- */
- getCommonRollData(attrKey = undefined, compId = undefined, compName = undefined) {
- let rollData = MournbladeCYD2Utility.getBasicRollData()
- rollData.alias = this.name
- rollData.actorImg = this.img
- rollData.actorId = this.id
- rollData.tokenId = this.token?.id
- rollData.img = this.img
- rollData.attributs = MournbladeCYD2Utility.getAttributs()
- rollData.maitriseId = "none"
- rollData.nbEclat = this.system.eclat.value
- rollData.nbBA = this.system.bonneaventure.actuelle
- rollData.nbAdversites = this.getTotalAdversite()
- rollData.talents = []
- rollData.attrKey2 = "none"
- rollData.coupDevastateur = this.items.find(it => it.type == "talent" && it.name.toLowerCase() == "coup dévastateur" && !it.system.used)
- rollData.hasAmbidextre = this.items.find(it => it.type == "talent" && it.name.toLowerCase() == "ambidextre")
- rollData.hasFeinte = this.system.bonneaventure.actuelle > 0 && this.items.find(it => it.type == "talent" && it.name.toLowerCase() == "feinte")
- rollData.isMonte = this.system.combat.monte
- rollData.config = game.system.mournbladecyd2.config
-
- if (attrKey) {
- rollData.attrKey = attrKey
- if (attrKey != "tochoose") {
- rollData.actionImg = "systems/fvtt-mournblade-cyd2/assets/icons/" + this.system.attributs[attrKey].labelnorm + ".webp"
- rollData.attr = foundry.utils.duplicate(this.system.attributs[attrKey])
- }
- }
- if (compId) {
- rollData.competence = foundry.utils.duplicate(this.items.get(compId) || {})
- let maitrises = [{ key: "none", label: "Aucune" }]
- rollData.competence.system.predilections.forEach(function (item) {
- if (item.maitrise) {
- maitrises.push({ key: item.id, label: item.name });
- }
- })
- rollData.maitrises = maitrises // rollData.competence.system.predilections.filter(p => p.maitrise)
- rollData.actionImg = rollData.competence?.img
- rollData.talents = this.searchRelevantTalents(rollData.competence)
- }
- if (compName) {
- rollData.competence = foundry.utils.duplicate(this.items.find(item => item.name.toLowerCase() == compName.toLowerCase()) || {})
- rollData.actionImg = rollData.competence?.img
- }
- return rollData
- }
-
- /* -------------------------------------------- */
- async rollAttribut(attrKey, isInit = false) {
- let rollData = this.getCommonRollData(attrKey)
- rollData.multiplier = (isInit) ? 1 : 2
- rollData.isInit = isInit
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
-
- /* -------------------------------------------- */
- async rollCompetence(attrKey, compId) {
- let rollData = this.getCommonRollData(attrKey, compId)
- rollData.multiplier = 1 // Attr multiplier, always 1 in competence mode
- console.log("RollDatra", rollData)
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
-
- /* -------------------------------------------- */
- async rollArmeOffensif(armeId) {
- let arme = this.items.get(armeId)
- if (arme.type == "arme") {
- arme = this.prepareArme(arme)
- }
- let rollData = this.getCommonRollData(arme.system.attrKey, arme.system.competence._id)
- rollData.arme = arme
- MournbladeCYD2Utility.updateWithTarget(rollData)
- console.log("ARME!", rollData)
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
- /* -------------------------------------------- */
- async rollAssommer() {
- let rollData = this.getCommonRollData("pui", undefined, "Filouterie")
- rollData.assomer = true
- rollData.conditionsCommunes = true
- MournbladeCYD2Utility.updateWithTarget(rollData)
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
- /* -------------------------------------------- */
- async rollCoupBas() {
- let rollData = this.getCommonRollData("pui", undefined, "Mêlée")
- rollData.coupBas = true
- rollData.conditionsCommunes = true
- MournbladeCYD2Utility.updateWithTarget(rollData)
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
- /* -------------------------------------------- */
- async rollImmobiliser() {
- let rollData = this.getCommonRollData("pui", undefined, "Mêlée")
- rollData.immobiliser = true
- rollData.conditionsCommunes = true
- rollData.cibleconsciente = true
- MournbladeCYD2Utility.updateWithTarget(rollData)
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
- /* -------------------------------------------- */
- async rollRepousser() {
- let rollData = this.getCommonRollData("pui", undefined, "Mêlée")
- rollData.repousser = true
- rollData.conditionsCommunes = true
- rollData.cibleconsciente = true
- MournbladeCYD2Utility.updateWithTarget(rollData)
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
- /* -------------------------------------------- */
- async rollDesengager() {
- let rollData = this.getCommonRollData("adr", undefined, "Mouvements")
- rollData.desengager = true
- rollData.conditionsCommunes = true
- MournbladeCYD2Utility.updateWithTarget(rollData)
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
-
- /* -------------------------------------------- */
- async rollArmeDegats(armeId, targetVigueur = undefined, rollDataInput = undefined) {
- let arme = this.items.get(armeId)
- if (arme.type == "arme") {
- arme = this.prepareArme(arme)
- }
- console.log("DEGATS", arme, targetVigueur, rollDataInput)
- let roll
- let bonus = 0
- let bonus2 = 0
-
- if (rollDataInput?.applyCoupDevastateur) {
- bonus2 = Math.floor(this.system.attributs.pui.value / 2)
- let talent = this.items.find(item => item.type == "talent" && item.name.toLowerCase() == "coup dévastateur")
- this.updateEmbeddedDocuments('Item', [{ _id: talent.id, 'system.used': true }])
- }
-
- if (rollDataInput?.isHeroique) {
- if (rollDataInput?.attaqueCharge) {
- bonus = 5
- }
- if (rollDataInput?.chargeCavalerie) {
- bonus = 6
- }
- roll = await new Roll("2d10rr10+" + arme.system.totalDegats + "+" + bonus + "+" + bonus2).roll()
- } else {
- if (rollDataInput?.attaqueCharge) {
- bonus = 3
- }
- if (rollDataInput?.chargeCavalerie) {
- bonus = 4
- }
- roll = await new Roll("1d10+" + arme.system.totalDegats + "+" + bonus + "+" + bonus2).roll()
- }
- await MournbladeCYD2Utility.showDiceSoNice(roll, game.settings.get("core", "rollMode"));
- let nbEtatPerdus = 0
- if (targetVigueur) {
- nbEtatPerdus = Math.floor(roll.total / targetVigueur)
- }
- //console.log(roll)
- let rollData = {
- arme: arme,
- finalResult: roll.total,
- formula: roll.formula,
- alias: this.name,
- actorImg: this.img,
- actorId: this.id,
- defenderTokenId: rollDataInput?.defenderTokenId,
- actionImg: arme.img,
- targetVigueur: targetVigueur,
- nbEtatPerdus: nbEtatPerdus
- }
- MournbladeCYD2Utility.createChatWithRollMode(rollData.alias, {
- content: await renderTemplate(`systems/fvtt-mournblade-cyd2/templates/chat-degats-result.html`, rollData)
- })
-
- if (rollDataInput?.defenderTokenId && nbEtatPerdus) {
- MournbladeCYD2Utility.applyCombativite(rollDataInput, nbEtatPerdus)
- }
-
- }
-}
diff --git a/.history/modules/mournblade-cyd2-actor_20251026002613.js b/.history/modules/mournblade-cyd2-actor_20251026002613.js
deleted file mode 100644
index fcbc134..0000000
--- a/.history/modules/mournblade-cyd2-actor_20251026002613.js
+++ /dev/null
@@ -1,822 +0,0 @@
-/* -------------------------------------------- */
-import { MournbladeCYD2Utility } from "./mournblade-cyd2-utility.js";
-import { MournbladeCYD2RollDialog } from "./mournblade-cyd2-roll-dialog.js";
-
-/* -------------------------------------------- */
-const __degatsBonus = [-2, -2, -1, -1, 0, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 8, 8, 9, 9, 10, 10]
-const __vitesseBonus = [-2, -2, -1, -1, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8]
-
-/* -------------------------------------------- */
-/**
- * Extend the base Actor entity by defining a custom roll data structure which is ideal for the Simple system.
- * @extends {Actor}
- */
-export class MournbladeCYD2Actor extends Actor {
-
- /* -------------------------------------------- */
- /**
- * Override the create() function to provide additional SoS functionality.
- *
- * This overrided create() function adds initial items
- * Namely: Basic skills, money,
- *
- * @param {Object} data Barebones actor data which this function adds onto.
- * @param {Object} options (Unused) Additional options which customize the creation workflow.
- *
- */
-
- static async create(data, options) {
-
- // Case of compendium global import
- if (data instanceof Array) {
- return super.create(data, options);
- }
- // If the created actor has items (only applicable to duplicated actors) bypass the new actor creation logic
- if (data.items) {
- let actor = super.create(data, options);
- return actor;
- }
-
- if (data.type == 'personnage') {
- const skills = await MournbladeCYD2Utility.loadCompendium("fvtt-mournblade-cyd2.skills")
- data.items = skills.map(i => i.toObject())
- }
- if (data.type == 'creature') {
- const skills = await MournbladeCYD2Utility.loadCompendium("fvtt-mournblade-cyd2.skills-creatures")
- data.items = skills.map(i => i.toObject())
- data.items.push({ name: "Arme naturelle 1", type: 'arme', img: "systems/fvtt-mournblade-cyd2/assets/icons/melee.webp", system: { typearme: "contact", bonusmaniementoff: 0, seuildefense: 0, degats: "0" } })
- data.items.push({ name: "Arme naturelle 2", type: 'arme', img: "systems/fvtt-mournblade-cyd2/assets/icons/melee.webp", system: { typearme: "contact", bonusmaniementoff: 0, seuildefense: 0, degats: "0" } })
- }
-
- return super.create(data, options);
- }
-
- /* -------------------------------------------- */
- getBonusDefenseFromTalents() {
- let talents = this.items.filter(item => item.type == "talent" && item.system.isautomated)
- let bonus = 0
- for (let talent of talents) {
- for (let auto of talent.system.automations) {
- if (auto.eventtype == "bonus-permanent" && auto.bonusname == "bonus-defensif") {
- bonus += Number(auto.bonus || 0)
- }
- }
- }
- return bonus
- }
-
- /* -------------------------------------------- */
- prepareArme(arme) {
- if (this.type == "cellule") {
- return arme
- }
-
- arme = foundry.utils.duplicate(arme)
- let combat = this.getCombatValues()
- if (arme.system.typearme == "contact" || arme.system.typearme == "contactjet") {
- let bonusDefense = this.getBonusDefenseFromTalents()
- arme.system.competence = foundry.utils.duplicate(this.items.find(item => item.type == "competence" && item.name.toLowerCase() == "mêlée"))
- arme.system.attrKey = "pui"
- arme.system.totalDegats = arme.system.degats + "+" + combat.bonusDegatsTotal
- arme.system.totalOffensif = this.system.attributs.pui.value + arme.system.competence.system.niveau + arme.system.bonusmaniementoff + (this.system.combat.monte ? 3 : 0)
- arme.system.totalDefensif = combat.defenseTotal + arme.system.competence.system.niveau + arme.system.seuildefense + bonusDefense + (this.system.combat.monte ? 3 : 0)
- console.log("Arme", arme.system.totalDefensif, combat, arme.system.competence.system.niveau, arme.system.seuildefense, bonusDefense)
- arme.system.isdefense = true
- arme.system.isMelee = true
- arme.system.isDistance = false
- }
- if (arme.system.typearme == "jet" || arme.system.typearme == "tir") {
- arme.system.competence = foundry.utils.duplicate(this.items.find(item => item.type == "competence" && item.name.toLowerCase() == "armes à distance"))
- arme.system.attrKey = "adr"
- arme.system.totalOffensif = this.system.attributs.adr.value + arme.system.competence.system.niveau + arme.system.bonusmaniementoff
- arme.system.totalDegats = arme.system.degats
- arme.system.isMelee = false
- arme.system.isDistance = true
- if (arme.system.isdefense) {
- arme.system.totalDefensif = combat.defenseTotal + arme.system.competence.system.niveau + arme.system.seuildefense
- }
- }
- return arme
- }
-
- /* -------------------------------------------- */
- getItemSorted(types) {
- let items = this.items.filter(item => types.includes(item.type)) || []
- MournbladeCYD2Utility.sortArrayObjectsByName(items)
- return items
- }
- getWeapons() {
- let armes = []
- for (let arme of this.items) {
- if (arme.type == "arme") {
- armes.push(this.prepareArme(arme))
- }
- }
- MournbladeCYD2Utility.sortArrayObjectsByName(armes)
- return armes
- }
- getMonnaies() {
- return this.getItemSorted(["monnaie"])
- }
- getEquipments() {
- return this.getItemSorted(["equipement"])
- }
- getArtefacts() {
- return this.getItemSorted(["artefact"])
- }
- getArmors() {
- return this.getItemSorted(["protection"])
- }
- getHistoriques() {
- return this.getItemSorted(["historique"])
- }
- getProfils() {
- return this.getItemSorted(["profil"])
- }
- getTalents() {
- return this.getItemSorted(["talent"])
- }
- getRessources() {
- return this.getItemSorted(["ressource"])
- }
- getContacts() {
- return this.getItemSorted(["contact"])
- }
- getMutations() {
- return this.getItemSorted(["mutation"])
- }
- getDons() {
- return this.getItemSorted(["don"])
- }
- getPactes() {
- return this.getItemSorted(["pacte"])
- }
- getTendances() {
- return this.getItemSorted(["tendance"])
- }
- getRunes() {
- return this.getItemSorted(["rune"])
- }
- getTraitsChaotiques() {
- return this.getItemSorted(["traitchaotique"])
- }
- getTraitsEspeces() {
- return this.getItemSorted(["traitespece"])
- }
-
- /* -------------------------------------------- */
- getAspect() {
- return (this.system.balance.loi > this.system.balance.chaos) ? this.system.balance.loi : this.system.balance.chaos
- }
- getMarge() {
- return Math.abs(this.system.balance.loi - this.system.balance.chaos)
- }
- getAlignement() {
- return (this.system.balance.loi > this.system.balance.chaos) ? "loyal" : "chaotique"
- }
-
- /* -------------------------------------------- */
- getSkills() {
- let comp = []
- for (let item of this.items) {
- item = foundry.utils.duplicate(item)
- if (item.type == "competence") {
- item.system.attribut1total = item.system.niveau + (this.system.attributs[item.system.attribut1]?.value || 0)
- item.system.attribut2total = item.system.niveau + (this.system.attributs[item.system.attribut2]?.value || 0)
- item.system.attribut3total = item.system.niveau + (this.system.attributs[item.system.attribut3]?.value || 0)
- if (item.system.niveau == 0) {
- item.system.attribut1total -= 3
- item.system.attribut2total -= 3
- item.system.attribut3total -= 3
- }
- item.system.attribut1label = this.system.attributs[item.system.attribut1]?.label || ""
- item.system.attribut2label = this.system.attributs[item.system.attribut2]?.label || ""
- item.system.attribut3label = this.system.attributs[item.system.attribut3]?.label || ""
- comp.push(item)
- }
- }
- MournbladeCYD2Utility.sortArrayObjectsByName(comp)
- return comp
- }
-
- /* ----------------------- --------------------- */
- addMember(actorId) {
- let members = foundry.utils.duplicate(this.system.members)
- members.push({ id: actorId })
- this.update({ 'system.members': members })
- }
- async removeMember(actorId) {
- let members = this.system.members.filter(it => it.id != actorId)
- this.update({ 'system.members': members })
- }
-
- /* -------------------------------------------- */
- getDefenseBase() {
- return Math.max(this.system.attributs.tre.value, this.system.attributs.adr.value)
- }
-
- /* -------------------------------------------- */
- getVitesseBase() {
- return 5 + __vitesseBonus[this.system.attributs.adr.value]
- }
- /* -------------------------------------------- */
- getProtection() {
- let equipProtection = 0
- for (let armor of this.items) {
- if (armor.type == "protection" && armor.system.equipped) {
- equipProtection += Number(armor.system.protection)
- }
- }
- if (equipProtection < 4) {
- return 4 + equipProtection // Cas des boucliers + sans armure
- }
- return equipProtection // Uniquement la protection des armures + boucliers
- }
-
- /* -------------------------------------------- */
- getCombatValues() {
- if (this.type == "cellule") {
- return {
- initBase: 0,
- initTotal: 0,
- bonusDegats: 0,
- bonusDegatsTotal: 0,
- vitesseBase: 0,
- vitesseTotal: 0,
- defenseBase: 0,
- protection: 0,
- defenseTotal: 0
- }
- }
-
- let combat = {
- initBase: this.system.attributs.adr.value,
- initTotal: this.system.attributs.adr.value + this.system.combat.initbonus,
- bonusDegats: this.getBonusDegats(),
- bonusDegatsTotal: this.getBonusDegats() + this.system.combat.bonusdegats,
- vitesseBase: this.getVitesseBase(),
- vitesseTotal: this.getVitesseBase() + this.system.combat.vitessebonus,
- defenseBase: this.getDefenseBase(),
- protection: this.getProtection(),
- defenseTotal: this.getDefenseBase() + this.system.combat.defensebonus + this.getProtection() - this.getTotalAdversite() + (this.system.combat.defensetotale ? 3 : 0)
- }
- return combat
- }
-
- /* -------------------------------------------- */
- prepareBaseData() {
- }
-
- /* -------------------------------------------- */
- async prepareData() {
- super.prepareData();
- }
-
- /* -------------------------------------------- */
- prepareDerivedData() {
-
- if (this.type == 'personnage') {
- let talentBonus = this.getVigueurBonus()
- let vigueur = Math.floor((this.system.attributs.pui.value + this.system.attributs.tre.value) / 2) + talentBonus + this.system.sante.vigueurmodifier
- if (vigueur != this.system.sante.vigueur) {
- this.update({ 'system.sante.vigueur': vigueur })
- }
- }
- super.prepareDerivedData()
- }
-
- /* -------------------------------------------- */
- _preUpdate(changed, options, user) {
- if (changed?.system?.sante?.etat && changed?.system?.sante?.etat != this.system.sante.etat) {
- setTimeout(() => {
- this.processCombativite(changed.system.sante)
- }, 800)
- }
- super._preUpdate(changed, options, user);
- }
-
- /* -------------------------------------------- */
- _onUpdate(data, options, user) {
- super._onUpdate(data, options, user);
- }
- /* -------------------------------------------- */
- getItemById(id) {
- let item = this.items.find(item => item.id == id);
- if (item) {
- item = foundry.utils.duplicate(item)
- }
- return item;
- }
-
- /* -------------------------------------------- */
- async equipItem(itemId) {
- let item = this.items.find(item => item.id == itemId)
- if (item && item.system) {
- let update = { _id: item.id, "system.equipped": !item.system.equipped }
- await this.updateEmbeddedDocuments('Item', [update]); // Updates one EmbeddedEntity
- }
- }
-
- /* -------------------------------------------- */
- editItemField(itemId, itemType, itemField, dataType, value) {
- let item = this.items.find(item => item.id == itemId)
- if (item) {
- console.log("Item ", item, itemField, dataType, value)
- if (dataType.toLowerCase() == "number") {
- value = Number(value)
- } else {
- value = String(value)
- }
- let update = { _id: item.id, [`system.${itemField}`]: value };
- this.updateEmbeddedDocuments("Item", [update])
- }
- }
-
- /* -------------------------------------------- */
- checkAttribut(attribut, minLevel) {
- let attr = this.system.attributs.find(at => at.labelnorm == attribut.toLowerCase())
- if (attr && attr.value >= minLevel) {
- return { isValid: true, attr: foundry.utils.duplicate(attr) }
- }
- return { isValid: false }
- }
- /* -------------------------------------------- */
- checkAttributOrCompetenceLevel(compName, minLevel) {
- let comp = this.items.find(i => i.type == "competence" && i.name.toLowerCase() == compName.toLowerCase() && i.system.niveau >= minLevel)
- if (comp) {
- return { isValid: true, item: foundry.utils.duplicate(comp) }
- } else {
- for (let attrKey in this.system.attributs) {
- if (this.system.attributs[attrKey].label.toLowerCase() == compName.toLowerCase() && this.system.attributs[attrKey].value >= minLevel) {
- return { isValid: true, item: foundry.utils.duplicate(this.system.attributs[attrKey]) }
- }
- }
- }
- return { isValid: false, warningMessage: `Prérequis insuffisant : la compétence/attribut ${compName} doit être de niveau ${minLevel} au minimum` }
- }
- /* -------------------------------------------- */
- addCompetenceBonus(compName, bonus, baCost) {
- let comp = this.items.find(i => i.type == "competence" && i.name.toLowerCase() == compName.toLowerCase())
- if (comp) {
- comp = foundry.utils.duplicate(comp)
- comp.system.bonus = bonus
- comp.system.baCost = baCost
- return { isValid: true, item: comp }
- }
- return { isValid: false, warningMessage: `Compétence ${compName} non trouvée` }
- }
- /* -------------------------------------------- */
- checkIfCompetence(compName) {
- let comp = this.items.find(i => i.type == "competence" && i.name.toLowerCase() == compName.toLowerCase())
- if (comp) {
- return { isValid: true, item: comp }
- }
- return { isValid: false }
- }
- /* -------------------------------------------- */
- getVigueur() {
- return this.system.sante.vigueur
- }
-
- /* -------------------------------------------- */
- getVigueurBonus() {
- let talents = this.items.filter(item => item.type == "talent" && item.system.isautomated)
- let bonus = 0
- for (let talent of talents) {
- for (let auto of talent.system.automations) {
- if (auto.eventtype == "bonus-permanent" && auto.bonusname == "vigueur") {
- bonus += Number(auto.bonus || 0)
- }
- }
- }
- return bonus
- }
-
- /* -------------------------------------------- */
- getBonneAventure() {
- return this.system.bonneaventure.actuelle
- }
- /* -------------------------------------------- */
- checkBonneAventure(cost) {
- return (this.system.bonneaventure.actuelle >= cost)
- }
- /* -------------------------------------------- */
- changeBonneAventure(value) {
- let newBA = this.system.bonneaventure.actuelle
- newBA += value
- this.update({ 'system.bonneaventure.actuelle': newBA })
- }
-
- /* -------------------------------------------- */
- getEclat() {
- return this.system.eclat.value
- }
-
- /* -------------------------------------------- */
- changeEclat(value) {
- let newE = this.system.eclat.value
- newE += value
- this.update({ 'system.eclat.value': newE })
- }
-
- /* -------------------------------------------- */
- compareName(a, b) {
- if (a.name < b.name) {
- return -1;
- }
- if (a.name > b.name) {
- return 1;
- }
- return 0;
- }
-
- /* -------------------------------------------- */
- getAttribute(attrKey) {
- return this.system.attributes[attrKey]
- }
-
- /* -------------------------------------------- */
- getBonusDegats() {
- return 0;
- }
-
- /* -------------------------------------------- */
- changeEtatCombativite(value) {
- if (value === "vaincu") {
- value = 200
- }
- let sante = foundry.utils.duplicate(this.system.sante)
- sante.etat += Number(value)
- sante.etat = Math.max(sante.etat, 0)
- sante.etat = Math.min(sante.etat, this.system.sante.nbcombativite)
- this.update({ 'system.sante': sante })
- if (sante.etat == this.system.sante.nbcombativite) {
- ChatMessage.create({ content: `${this.name} est vaincu !` })
- }
- // Duplicated ! this.processCombativite(sante)
- }
-
- /* -------------------------------------------- */
- processCombativite(sante) {
- sante = sante || foundry.utils.duplicate(this.system.sante)
- // Gestion des états affaibli et très affaibli
- if (sante.etat == this.system.sante.nbcombativite - 2 || sante.etat == this.system.sante.nbcombativite - 1) {
- if (sante.etat == this.system.sante.nbcombativite - 2 && this.items.find(item => item.type == "talent" && item.name.toLowerCase() == "encaissement")) {
- ChatMessage.create({ content: `${this.name} ne subit pas les 2 adversités rouge grâce à Encaissement. Pensez à les ajouter à la fin de la scène !` })
- } else if (sante.etat == this.system.sante.nbcombativite - 1 && this.items.find(item => item.type == "talent" && item.name.toLowerCase().includes("vaillant"))) {
- ChatMessage.create({ content: `${this.name} ne subit pas les 2 adversités rouge grâce à Vaillant. Pensez à les ajouter à la fin de la scène !` })
- } else {
- ChatMessage.create({ content: `${this.name} subit 2 adversités rouge !` })
- this.incDecAdversite("rouge", 2)
- }
- }
- }
-
- /* -------------------------------------------- */
- async equipGear(equipmentId) {
- let item = this.items.find(item => item.id == equipmentId);
- if (item?.system?.data) {
- let update = { _id: item.id, "system.equipped": !item.system.equipped };
- await this.updateEmbeddedDocuments('Item', [update]); // Updates one EmbeddedEntity
- }
- }
-
- /* -------------------------------------------- */
- getSubActors() {
- let subActors = [];
- for (let id of this.system.subactors) {
- subActors.push(foundry.utils.duplicate(game.actors.get(id)));
- }
- return subActors;
- }
- /* -------------------------------------------- */
- async addSubActor(subActorId) {
- let subActors = foundry.utils.duplicate(this.system.subactors);
- subActors.push(subActorId);
- await this.update({ 'system.subactors': subActors });
- }
- /* -------------------------------------------- */
- async delSubActor(subActorId) {
- let newArray = [];
- for (let id of this.system.subactors) {
- if (id != subActorId) {
- newArray.push(id);
- }
- }
- await this.update({ 'system.subactors': newArray });
- }
-
- /* -------------------------------------------- */
- getTotalAdversite() {
- return this.system.adversite.bleue + this.system.adversite.rouge + this.system.adversite.noire
- }
-
- /* -------------------------------------------- */
- async incDecAdversite(adv, incDec = 0) {
- let adversite = foundry.utils.duplicate(this.system.adversite)
- adversite[adv] += Number(incDec)
- adversite[adv] = Math.max(adversite[adv], 0)
- adversite[adv] = Math.min(adversite[adv], 20)
- this.update({ 'system.adversite': adversite })
- }
- /* -------------------------------------------- */
- async incDecQuantity(objetId, incDec = 0) {
- let objetQ = this.items.get(objetId)
- if (objetQ) {
- let newQ = objetQ.system.quantite + incDec
- newQ = Math.max(newQ, 0)
- await this.updateEmbeddedDocuments('Item', [{ _id: objetQ.id, 'system.quantite': newQ }]); // pdates one EmbeddedEntity
- }
- }
-
- /* -------------------------------------------- */
- computeRichesse() {
- let valueSC = 0
- for (let monnaie of this.items) {
- if (monnaie.type == "monnaie") {
- valueSC += Number(monnaie.system.prixsc) * Number(monnaie.system.quantite)
- }
- }
- return MournbladeCYD2Utility.computeMonnaieDetails(valueSC)
- }
-
- /* -------------------------------------------- */
- computeValeurEquipement() {
- let valueSC = 0
- for (let equip of this.items) {
- if (equip.type == "equipement" || equip.type == "arme" || equip.type == "protection") {
- valueSC += Number(equip.system.prixsc) * Number(equip.system.quantite ?? 1)
- valueSC += (Number(equip.system.prixca) * Number(equip.system.quantite ?? 1)) * 20
- valueSC += (Number(equip.system.prixpo) * Number(equip.system.quantite ?? 1)) * 400
- }
- }
- return MournbladeCYD2Utility.computeMonnaieDetails(valueSC)
- }
-
- /* -------------------------------------------- */
- getCompetence(compId) {
- return this.items.get(compId)
- }
-
- /* -------------------------------------------- */
- async setPredilectionUsed(compId, predIdx) {
- let comp = this.items.get(compId)
- let pred = foundry.utils.duplicate(comp.system.predilections)
- pred[predIdx].used = true
- await this.updateEmbeddedDocuments('Item', [{ _id: compId, 'system.predilections': pred }])
- }
-
- /* -------------------------------------------- */
- getInitiativeScore() {
- let init = this.getFlag("world", "last-initiative")
- return init || -1
- }
-
- /* -------------------------------------------- */
- getBestAttackValue() {
- let attackList = this.items.filter(item => (item.type == "arme" || item.type == "talent") && item.system.equipped)
- let maxOff = 0
- let bestArme
- for (let arme of attackList) {
- if (arme.type == "arme") {
- arme = this.prepareArme(arme)
- }
- if (arme.system.totalOffensif > maxOff) {
- maxOff = arme.system.totalOffensif
- bestArme = foundry.utils.duplicate(arme)
- }
- }
- return bestArme
- }
-
- /* -------------------------------------------- */
- getBestDefenseValue() {
- let defenseList = this.items.filter(item => (item.type == "arme") && item.system.equipped)
- let maxDef = 0
- let bestArme
- for (let arme of defenseList) {
- if (arme.type == "arme") {
- arme = this.prepareArme(arme)
- }
- if (arme.system.totalDefensif > maxDef) {
- maxDef = arme.system.totalDefensif
- bestArme = foundry.utils.duplicate(arme)
- }
- }
- return bestArme
- }
-
- /* -------------------------------------------- */
- searchRelevantTalents(competence) {
- let talents = []
-
- for (let talent of this.items) {
- if (talent.type == "talent" && talent.system.isautomated && talent.system.automations.length > 0) {
- for (let auto of talent.system.automations) {
- if (auto.eventtype === "prepare-roll") {
- if (auto.competence.toLowerCase() == competence.name.toLowerCase()) {
- talent = foundry.utils.duplicate(talent)
- talent.system.bonus = auto.bonus
- talent.system.baCost = auto.baCost
- talents.push(talent)
- }
- }
- }
- }
- }
- return talents
- }
-
- /* -------------------------------------------- */
- buildListeAdversites() {
- return []
- }
-
- /* -------------------------------------------- */
- getCommonRollData(attrKey = undefined, compId = undefined, compName = undefined) {
- let rollData = MournbladeCYD2Utility.getBasicRollData()
- rollData.alias = this.name
- rollData.actorImg = this.img
- rollData.actorId = this.id
- rollData.tokenId = this.token?.id
- rollData.img = this.img
- rollData.attributs = MournbladeCYD2Utility.getAttributs()
- rollData.maitriseId = "none"
- rollData.nbEclat = this.system.eclat.value
- rollData.nbBA = this.system.bonneaventure.actuelle
- rollData.nbAdversites = this.getTotalAdversite()
- rollData.talents = []
- rollData.attrKey2 = "none"
- rollData.coupDevastateur = this.items.find(it => it.type == "talent" && it.name.toLowerCase() == "coup dévastateur" && !it.system.used)
- rollData.hasAmbidextre = this.items.find(it => it.type == "talent" && it.name.toLowerCase() == "ambidextre")
- rollData.hasFeinte = this.system.bonneaventure.actuelle > 0 && this.items.find(it => it.type == "talent" && it.name.toLowerCase() == "feinte")
- rollData.isMonte = this.system.combat.monte
- rollData.config = game.system.mournbladecyd2.config
-
- if (attrKey) {
- rollData.attrKey = attrKey
- if (attrKey != "tochoose") {
- rollData.actionImg = "systems/fvtt-mournblade-cyd2/assets/icons/" + this.system.attributs[attrKey].labelnorm + ".webp"
- rollData.attr = foundry.utils.duplicate(this.system.attributs[attrKey])
- }
- }
- if (compId) {
- rollData.competence = foundry.utils.duplicate(this.items.get(compId) || {})
- let maitrises = [{ key: "none", label: "Aucune" }]
- rollData.competence.system.predilections.forEach(function (item) {
- if (item.maitrise) {
- maitrises.push({ key: item.id, label: item.name });
- }
- })
- rollData.maitrises = maitrises // rollData.competence.system.predilections.filter(p => p.maitrise)
- rollData.actionImg = rollData.competence?.img
- rollData.talents = this.searchRelevantTalents(rollData.competence)
- }
- if (compName) {
- rollData.competence = foundry.utils.duplicate(this.items.find(item => item.name.toLowerCase() == compName.toLowerCase()) || {})
- rollData.actionImg = rollData.competence?.img
- }
- return rollData
- }
-
- /* -------------------------------------------- */
- async rollAttribut(attrKey, isInit = false) {
- let rollData = this.getCommonRollData(attrKey)
- rollData.multiplier = (isInit) ? 1 : 2
- rollData.isInit = isInit
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
-
- /* -------------------------------------------- */
- async rollCompetence(attrKey, compId) {
- let rollData = this.getCommonRollData(attrKey, compId)
- rollData.multiplier = 1 // Attr multiplier, always 1 in competence mode
- console.log("RollDatra", rollData)
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
-
- /* -------------------------------------------- */
- async rollArmeOffensif(armeId) {
- let arme = this.items.get(armeId)
- if (arme.type == "arme") {
- arme = this.prepareArme(arme)
- }
- let rollData = this.getCommonRollData(arme.system.attrKey, arme.system.competence._id)
- rollData.arme = arme
- MournbladeCYD2Utility.updateWithTarget(rollData)
- console.log("ARME!", rollData)
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
- /* -------------------------------------------- */
- async rollAssommer() {
- let rollData = this.getCommonRollData("pui", undefined, "Filouterie")
- rollData.assomer = true
- rollData.conditionsCommunes = true
- MournbladeCYD2Utility.updateWithTarget(rollData)
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
- /* -------------------------------------------- */
- async rollCoupBas() {
- let rollData = this.getCommonRollData("pui", undefined, "Mêlée")
- rollData.coupBas = true
- rollData.conditionsCommunes = true
- MournbladeCYD2Utility.updateWithTarget(rollData)
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
- /* -------------------------------------------- */
- async rollImmobiliser() {
- let rollData = this.getCommonRollData("pui", undefined, "Mêlée")
- rollData.immobiliser = true
- rollData.conditionsCommunes = true
- rollData.cibleconsciente = true
- MournbladeCYD2Utility.updateWithTarget(rollData)
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
- /* -------------------------------------------- */
- async rollRepousser() {
- let rollData = this.getCommonRollData("pui", undefined, "Mêlée")
- rollData.repousser = true
- rollData.conditionsCommunes = true
- rollData.cibleconsciente = true
- MournbladeCYD2Utility.updateWithTarget(rollData)
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
- /* -------------------------------------------- */
- async rollDesengager() {
- let rollData = this.getCommonRollData("adr", undefined, "Mouvements")
- rollData.desengager = true
- rollData.conditionsCommunes = true
- MournbladeCYD2Utility.updateWithTarget(rollData)
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
-
- /* -------------------------------------------- */
- async rollArmeDegats(armeId, targetVigueur = undefined, rollDataInput = undefined) {
- let arme = this.items.get(armeId)
- if (arme.type == "arme") {
- arme = this.prepareArme(arme)
- }
- console.log("DEGATS", arme, targetVigueur, rollDataInput)
- let roll
- let bonus = 0
- let bonus2 = 0
-
- if (rollDataInput?.applyCoupDevastateur) {
- bonus2 = Math.floor(this.system.attributs.pui.value / 2)
- let talent = this.items.find(item => item.type == "talent" && item.name.toLowerCase() == "coup dévastateur")
- this.updateEmbeddedDocuments('Item', [{ _id: talent.id, 'system.used': true }])
- }
-
- if (rollDataInput?.isHeroique) {
- if (rollDataInput?.attaqueCharge) {
- bonus = 5
- }
- if (rollDataInput?.chargeCavalerie) {
- bonus = 6
- }
- roll = await new Roll("2d10rr10+" + arme.system.totalDegats + "+" + bonus + "+" + bonus2).roll()
- } else {
- if (rollDataInput?.attaqueCharge) {
- bonus = 3
- }
- if (rollDataInput?.chargeCavalerie) {
- bonus = 4
- }
- roll = await new Roll("1d10+" + arme.system.totalDegats + "+" + bonus + "+" + bonus2).roll()
- }
- await MournbladeCYD2Utility.showDiceSoNice(roll, game.settings.get("core", "rollMode"));
- let nbEtatPerdus = 0
- if (targetVigueur) {
- nbEtatPerdus = Math.floor(roll.total / targetVigueur)
- }
- //console.log(roll)
- let rollData = {
- arme: arme,
- finalResult: roll.total,
- formula: roll.formula,
- alias: this.name,
- actorImg: this.img,
- actorId: this.id,
- defenderTokenId: rollDataInput?.defenderTokenId,
- actionImg: arme.img,
- targetVigueur: targetVigueur,
- nbEtatPerdus: nbEtatPerdus
- }
- MournbladeCYD2Utility.createChatWithRollMode(rollData.alias, {
- content: await renderTemplate(`systems/fvtt-mournblade-cyd2/templates/chat-degats-result.html`, rollData)
- })
-
- if (rollDataInput?.defenderTokenId && nbEtatPerdus) {
- MournbladeCYD2Utility.applyCombativite(rollDataInput, nbEtatPerdus)
- }
-
- }
-}
diff --git a/.history/modules/mournblade-cyd2-actor_20251026002719.js b/.history/modules/mournblade-cyd2-actor_20251026002719.js
deleted file mode 100644
index fcbc134..0000000
--- a/.history/modules/mournblade-cyd2-actor_20251026002719.js
+++ /dev/null
@@ -1,822 +0,0 @@
-/* -------------------------------------------- */
-import { MournbladeCYD2Utility } from "./mournblade-cyd2-utility.js";
-import { MournbladeCYD2RollDialog } from "./mournblade-cyd2-roll-dialog.js";
-
-/* -------------------------------------------- */
-const __degatsBonus = [-2, -2, -1, -1, 0, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 8, 8, 9, 9, 10, 10]
-const __vitesseBonus = [-2, -2, -1, -1, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8]
-
-/* -------------------------------------------- */
-/**
- * Extend the base Actor entity by defining a custom roll data structure which is ideal for the Simple system.
- * @extends {Actor}
- */
-export class MournbladeCYD2Actor extends Actor {
-
- /* -------------------------------------------- */
- /**
- * Override the create() function to provide additional SoS functionality.
- *
- * This overrided create() function adds initial items
- * Namely: Basic skills, money,
- *
- * @param {Object} data Barebones actor data which this function adds onto.
- * @param {Object} options (Unused) Additional options which customize the creation workflow.
- *
- */
-
- static async create(data, options) {
-
- // Case of compendium global import
- if (data instanceof Array) {
- return super.create(data, options);
- }
- // If the created actor has items (only applicable to duplicated actors) bypass the new actor creation logic
- if (data.items) {
- let actor = super.create(data, options);
- return actor;
- }
-
- if (data.type == 'personnage') {
- const skills = await MournbladeCYD2Utility.loadCompendium("fvtt-mournblade-cyd2.skills")
- data.items = skills.map(i => i.toObject())
- }
- if (data.type == 'creature') {
- const skills = await MournbladeCYD2Utility.loadCompendium("fvtt-mournblade-cyd2.skills-creatures")
- data.items = skills.map(i => i.toObject())
- data.items.push({ name: "Arme naturelle 1", type: 'arme', img: "systems/fvtt-mournblade-cyd2/assets/icons/melee.webp", system: { typearme: "contact", bonusmaniementoff: 0, seuildefense: 0, degats: "0" } })
- data.items.push({ name: "Arme naturelle 2", type: 'arme', img: "systems/fvtt-mournblade-cyd2/assets/icons/melee.webp", system: { typearme: "contact", bonusmaniementoff: 0, seuildefense: 0, degats: "0" } })
- }
-
- return super.create(data, options);
- }
-
- /* -------------------------------------------- */
- getBonusDefenseFromTalents() {
- let talents = this.items.filter(item => item.type == "talent" && item.system.isautomated)
- let bonus = 0
- for (let talent of talents) {
- for (let auto of talent.system.automations) {
- if (auto.eventtype == "bonus-permanent" && auto.bonusname == "bonus-defensif") {
- bonus += Number(auto.bonus || 0)
- }
- }
- }
- return bonus
- }
-
- /* -------------------------------------------- */
- prepareArme(arme) {
- if (this.type == "cellule") {
- return arme
- }
-
- arme = foundry.utils.duplicate(arme)
- let combat = this.getCombatValues()
- if (arme.system.typearme == "contact" || arme.system.typearme == "contactjet") {
- let bonusDefense = this.getBonusDefenseFromTalents()
- arme.system.competence = foundry.utils.duplicate(this.items.find(item => item.type == "competence" && item.name.toLowerCase() == "mêlée"))
- arme.system.attrKey = "pui"
- arme.system.totalDegats = arme.system.degats + "+" + combat.bonusDegatsTotal
- arme.system.totalOffensif = this.system.attributs.pui.value + arme.system.competence.system.niveau + arme.system.bonusmaniementoff + (this.system.combat.monte ? 3 : 0)
- arme.system.totalDefensif = combat.defenseTotal + arme.system.competence.system.niveau + arme.system.seuildefense + bonusDefense + (this.system.combat.monte ? 3 : 0)
- console.log("Arme", arme.system.totalDefensif, combat, arme.system.competence.system.niveau, arme.system.seuildefense, bonusDefense)
- arme.system.isdefense = true
- arme.system.isMelee = true
- arme.system.isDistance = false
- }
- if (arme.system.typearme == "jet" || arme.system.typearme == "tir") {
- arme.system.competence = foundry.utils.duplicate(this.items.find(item => item.type == "competence" && item.name.toLowerCase() == "armes à distance"))
- arme.system.attrKey = "adr"
- arme.system.totalOffensif = this.system.attributs.adr.value + arme.system.competence.system.niveau + arme.system.bonusmaniementoff
- arme.system.totalDegats = arme.system.degats
- arme.system.isMelee = false
- arme.system.isDistance = true
- if (arme.system.isdefense) {
- arme.system.totalDefensif = combat.defenseTotal + arme.system.competence.system.niveau + arme.system.seuildefense
- }
- }
- return arme
- }
-
- /* -------------------------------------------- */
- getItemSorted(types) {
- let items = this.items.filter(item => types.includes(item.type)) || []
- MournbladeCYD2Utility.sortArrayObjectsByName(items)
- return items
- }
- getWeapons() {
- let armes = []
- for (let arme of this.items) {
- if (arme.type == "arme") {
- armes.push(this.prepareArme(arme))
- }
- }
- MournbladeCYD2Utility.sortArrayObjectsByName(armes)
- return armes
- }
- getMonnaies() {
- return this.getItemSorted(["monnaie"])
- }
- getEquipments() {
- return this.getItemSorted(["equipement"])
- }
- getArtefacts() {
- return this.getItemSorted(["artefact"])
- }
- getArmors() {
- return this.getItemSorted(["protection"])
- }
- getHistoriques() {
- return this.getItemSorted(["historique"])
- }
- getProfils() {
- return this.getItemSorted(["profil"])
- }
- getTalents() {
- return this.getItemSorted(["talent"])
- }
- getRessources() {
- return this.getItemSorted(["ressource"])
- }
- getContacts() {
- return this.getItemSorted(["contact"])
- }
- getMutations() {
- return this.getItemSorted(["mutation"])
- }
- getDons() {
- return this.getItemSorted(["don"])
- }
- getPactes() {
- return this.getItemSorted(["pacte"])
- }
- getTendances() {
- return this.getItemSorted(["tendance"])
- }
- getRunes() {
- return this.getItemSorted(["rune"])
- }
- getTraitsChaotiques() {
- return this.getItemSorted(["traitchaotique"])
- }
- getTraitsEspeces() {
- return this.getItemSorted(["traitespece"])
- }
-
- /* -------------------------------------------- */
- getAspect() {
- return (this.system.balance.loi > this.system.balance.chaos) ? this.system.balance.loi : this.system.balance.chaos
- }
- getMarge() {
- return Math.abs(this.system.balance.loi - this.system.balance.chaos)
- }
- getAlignement() {
- return (this.system.balance.loi > this.system.balance.chaos) ? "loyal" : "chaotique"
- }
-
- /* -------------------------------------------- */
- getSkills() {
- let comp = []
- for (let item of this.items) {
- item = foundry.utils.duplicate(item)
- if (item.type == "competence") {
- item.system.attribut1total = item.system.niveau + (this.system.attributs[item.system.attribut1]?.value || 0)
- item.system.attribut2total = item.system.niveau + (this.system.attributs[item.system.attribut2]?.value || 0)
- item.system.attribut3total = item.system.niveau + (this.system.attributs[item.system.attribut3]?.value || 0)
- if (item.system.niveau == 0) {
- item.system.attribut1total -= 3
- item.system.attribut2total -= 3
- item.system.attribut3total -= 3
- }
- item.system.attribut1label = this.system.attributs[item.system.attribut1]?.label || ""
- item.system.attribut2label = this.system.attributs[item.system.attribut2]?.label || ""
- item.system.attribut3label = this.system.attributs[item.system.attribut3]?.label || ""
- comp.push(item)
- }
- }
- MournbladeCYD2Utility.sortArrayObjectsByName(comp)
- return comp
- }
-
- /* ----------------------- --------------------- */
- addMember(actorId) {
- let members = foundry.utils.duplicate(this.system.members)
- members.push({ id: actorId })
- this.update({ 'system.members': members })
- }
- async removeMember(actorId) {
- let members = this.system.members.filter(it => it.id != actorId)
- this.update({ 'system.members': members })
- }
-
- /* -------------------------------------------- */
- getDefenseBase() {
- return Math.max(this.system.attributs.tre.value, this.system.attributs.adr.value)
- }
-
- /* -------------------------------------------- */
- getVitesseBase() {
- return 5 + __vitesseBonus[this.system.attributs.adr.value]
- }
- /* -------------------------------------------- */
- getProtection() {
- let equipProtection = 0
- for (let armor of this.items) {
- if (armor.type == "protection" && armor.system.equipped) {
- equipProtection += Number(armor.system.protection)
- }
- }
- if (equipProtection < 4) {
- return 4 + equipProtection // Cas des boucliers + sans armure
- }
- return equipProtection // Uniquement la protection des armures + boucliers
- }
-
- /* -------------------------------------------- */
- getCombatValues() {
- if (this.type == "cellule") {
- return {
- initBase: 0,
- initTotal: 0,
- bonusDegats: 0,
- bonusDegatsTotal: 0,
- vitesseBase: 0,
- vitesseTotal: 0,
- defenseBase: 0,
- protection: 0,
- defenseTotal: 0
- }
- }
-
- let combat = {
- initBase: this.system.attributs.adr.value,
- initTotal: this.system.attributs.adr.value + this.system.combat.initbonus,
- bonusDegats: this.getBonusDegats(),
- bonusDegatsTotal: this.getBonusDegats() + this.system.combat.bonusdegats,
- vitesseBase: this.getVitesseBase(),
- vitesseTotal: this.getVitesseBase() + this.system.combat.vitessebonus,
- defenseBase: this.getDefenseBase(),
- protection: this.getProtection(),
- defenseTotal: this.getDefenseBase() + this.system.combat.defensebonus + this.getProtection() - this.getTotalAdversite() + (this.system.combat.defensetotale ? 3 : 0)
- }
- return combat
- }
-
- /* -------------------------------------------- */
- prepareBaseData() {
- }
-
- /* -------------------------------------------- */
- async prepareData() {
- super.prepareData();
- }
-
- /* -------------------------------------------- */
- prepareDerivedData() {
-
- if (this.type == 'personnage') {
- let talentBonus = this.getVigueurBonus()
- let vigueur = Math.floor((this.system.attributs.pui.value + this.system.attributs.tre.value) / 2) + talentBonus + this.system.sante.vigueurmodifier
- if (vigueur != this.system.sante.vigueur) {
- this.update({ 'system.sante.vigueur': vigueur })
- }
- }
- super.prepareDerivedData()
- }
-
- /* -------------------------------------------- */
- _preUpdate(changed, options, user) {
- if (changed?.system?.sante?.etat && changed?.system?.sante?.etat != this.system.sante.etat) {
- setTimeout(() => {
- this.processCombativite(changed.system.sante)
- }, 800)
- }
- super._preUpdate(changed, options, user);
- }
-
- /* -------------------------------------------- */
- _onUpdate(data, options, user) {
- super._onUpdate(data, options, user);
- }
- /* -------------------------------------------- */
- getItemById(id) {
- let item = this.items.find(item => item.id == id);
- if (item) {
- item = foundry.utils.duplicate(item)
- }
- return item;
- }
-
- /* -------------------------------------------- */
- async equipItem(itemId) {
- let item = this.items.find(item => item.id == itemId)
- if (item && item.system) {
- let update = { _id: item.id, "system.equipped": !item.system.equipped }
- await this.updateEmbeddedDocuments('Item', [update]); // Updates one EmbeddedEntity
- }
- }
-
- /* -------------------------------------------- */
- editItemField(itemId, itemType, itemField, dataType, value) {
- let item = this.items.find(item => item.id == itemId)
- if (item) {
- console.log("Item ", item, itemField, dataType, value)
- if (dataType.toLowerCase() == "number") {
- value = Number(value)
- } else {
- value = String(value)
- }
- let update = { _id: item.id, [`system.${itemField}`]: value };
- this.updateEmbeddedDocuments("Item", [update])
- }
- }
-
- /* -------------------------------------------- */
- checkAttribut(attribut, minLevel) {
- let attr = this.system.attributs.find(at => at.labelnorm == attribut.toLowerCase())
- if (attr && attr.value >= minLevel) {
- return { isValid: true, attr: foundry.utils.duplicate(attr) }
- }
- return { isValid: false }
- }
- /* -------------------------------------------- */
- checkAttributOrCompetenceLevel(compName, minLevel) {
- let comp = this.items.find(i => i.type == "competence" && i.name.toLowerCase() == compName.toLowerCase() && i.system.niveau >= minLevel)
- if (comp) {
- return { isValid: true, item: foundry.utils.duplicate(comp) }
- } else {
- for (let attrKey in this.system.attributs) {
- if (this.system.attributs[attrKey].label.toLowerCase() == compName.toLowerCase() && this.system.attributs[attrKey].value >= minLevel) {
- return { isValid: true, item: foundry.utils.duplicate(this.system.attributs[attrKey]) }
- }
- }
- }
- return { isValid: false, warningMessage: `Prérequis insuffisant : la compétence/attribut ${compName} doit être de niveau ${minLevel} au minimum` }
- }
- /* -------------------------------------------- */
- addCompetenceBonus(compName, bonus, baCost) {
- let comp = this.items.find(i => i.type == "competence" && i.name.toLowerCase() == compName.toLowerCase())
- if (comp) {
- comp = foundry.utils.duplicate(comp)
- comp.system.bonus = bonus
- comp.system.baCost = baCost
- return { isValid: true, item: comp }
- }
- return { isValid: false, warningMessage: `Compétence ${compName} non trouvée` }
- }
- /* -------------------------------------------- */
- checkIfCompetence(compName) {
- let comp = this.items.find(i => i.type == "competence" && i.name.toLowerCase() == compName.toLowerCase())
- if (comp) {
- return { isValid: true, item: comp }
- }
- return { isValid: false }
- }
- /* -------------------------------------------- */
- getVigueur() {
- return this.system.sante.vigueur
- }
-
- /* -------------------------------------------- */
- getVigueurBonus() {
- let talents = this.items.filter(item => item.type == "talent" && item.system.isautomated)
- let bonus = 0
- for (let talent of talents) {
- for (let auto of talent.system.automations) {
- if (auto.eventtype == "bonus-permanent" && auto.bonusname == "vigueur") {
- bonus += Number(auto.bonus || 0)
- }
- }
- }
- return bonus
- }
-
- /* -------------------------------------------- */
- getBonneAventure() {
- return this.system.bonneaventure.actuelle
- }
- /* -------------------------------------------- */
- checkBonneAventure(cost) {
- return (this.system.bonneaventure.actuelle >= cost)
- }
- /* -------------------------------------------- */
- changeBonneAventure(value) {
- let newBA = this.system.bonneaventure.actuelle
- newBA += value
- this.update({ 'system.bonneaventure.actuelle': newBA })
- }
-
- /* -------------------------------------------- */
- getEclat() {
- return this.system.eclat.value
- }
-
- /* -------------------------------------------- */
- changeEclat(value) {
- let newE = this.system.eclat.value
- newE += value
- this.update({ 'system.eclat.value': newE })
- }
-
- /* -------------------------------------------- */
- compareName(a, b) {
- if (a.name < b.name) {
- return -1;
- }
- if (a.name > b.name) {
- return 1;
- }
- return 0;
- }
-
- /* -------------------------------------------- */
- getAttribute(attrKey) {
- return this.system.attributes[attrKey]
- }
-
- /* -------------------------------------------- */
- getBonusDegats() {
- return 0;
- }
-
- /* -------------------------------------------- */
- changeEtatCombativite(value) {
- if (value === "vaincu") {
- value = 200
- }
- let sante = foundry.utils.duplicate(this.system.sante)
- sante.etat += Number(value)
- sante.etat = Math.max(sante.etat, 0)
- sante.etat = Math.min(sante.etat, this.system.sante.nbcombativite)
- this.update({ 'system.sante': sante })
- if (sante.etat == this.system.sante.nbcombativite) {
- ChatMessage.create({ content: `${this.name} est vaincu !` })
- }
- // Duplicated ! this.processCombativite(sante)
- }
-
- /* -------------------------------------------- */
- processCombativite(sante) {
- sante = sante || foundry.utils.duplicate(this.system.sante)
- // Gestion des états affaibli et très affaibli
- if (sante.etat == this.system.sante.nbcombativite - 2 || sante.etat == this.system.sante.nbcombativite - 1) {
- if (sante.etat == this.system.sante.nbcombativite - 2 && this.items.find(item => item.type == "talent" && item.name.toLowerCase() == "encaissement")) {
- ChatMessage.create({ content: `${this.name} ne subit pas les 2 adversités rouge grâce à Encaissement. Pensez à les ajouter à la fin de la scène !` })
- } else if (sante.etat == this.system.sante.nbcombativite - 1 && this.items.find(item => item.type == "talent" && item.name.toLowerCase().includes("vaillant"))) {
- ChatMessage.create({ content: `${this.name} ne subit pas les 2 adversités rouge grâce à Vaillant. Pensez à les ajouter à la fin de la scène !` })
- } else {
- ChatMessage.create({ content: `${this.name} subit 2 adversités rouge !` })
- this.incDecAdversite("rouge", 2)
- }
- }
- }
-
- /* -------------------------------------------- */
- async equipGear(equipmentId) {
- let item = this.items.find(item => item.id == equipmentId);
- if (item?.system?.data) {
- let update = { _id: item.id, "system.equipped": !item.system.equipped };
- await this.updateEmbeddedDocuments('Item', [update]); // Updates one EmbeddedEntity
- }
- }
-
- /* -------------------------------------------- */
- getSubActors() {
- let subActors = [];
- for (let id of this.system.subactors) {
- subActors.push(foundry.utils.duplicate(game.actors.get(id)));
- }
- return subActors;
- }
- /* -------------------------------------------- */
- async addSubActor(subActorId) {
- let subActors = foundry.utils.duplicate(this.system.subactors);
- subActors.push(subActorId);
- await this.update({ 'system.subactors': subActors });
- }
- /* -------------------------------------------- */
- async delSubActor(subActorId) {
- let newArray = [];
- for (let id of this.system.subactors) {
- if (id != subActorId) {
- newArray.push(id);
- }
- }
- await this.update({ 'system.subactors': newArray });
- }
-
- /* -------------------------------------------- */
- getTotalAdversite() {
- return this.system.adversite.bleue + this.system.adversite.rouge + this.system.adversite.noire
- }
-
- /* -------------------------------------------- */
- async incDecAdversite(adv, incDec = 0) {
- let adversite = foundry.utils.duplicate(this.system.adversite)
- adversite[adv] += Number(incDec)
- adversite[adv] = Math.max(adversite[adv], 0)
- adversite[adv] = Math.min(adversite[adv], 20)
- this.update({ 'system.adversite': adversite })
- }
- /* -------------------------------------------- */
- async incDecQuantity(objetId, incDec = 0) {
- let objetQ = this.items.get(objetId)
- if (objetQ) {
- let newQ = objetQ.system.quantite + incDec
- newQ = Math.max(newQ, 0)
- await this.updateEmbeddedDocuments('Item', [{ _id: objetQ.id, 'system.quantite': newQ }]); // pdates one EmbeddedEntity
- }
- }
-
- /* -------------------------------------------- */
- computeRichesse() {
- let valueSC = 0
- for (let monnaie of this.items) {
- if (monnaie.type == "monnaie") {
- valueSC += Number(monnaie.system.prixsc) * Number(monnaie.system.quantite)
- }
- }
- return MournbladeCYD2Utility.computeMonnaieDetails(valueSC)
- }
-
- /* -------------------------------------------- */
- computeValeurEquipement() {
- let valueSC = 0
- for (let equip of this.items) {
- if (equip.type == "equipement" || equip.type == "arme" || equip.type == "protection") {
- valueSC += Number(equip.system.prixsc) * Number(equip.system.quantite ?? 1)
- valueSC += (Number(equip.system.prixca) * Number(equip.system.quantite ?? 1)) * 20
- valueSC += (Number(equip.system.prixpo) * Number(equip.system.quantite ?? 1)) * 400
- }
- }
- return MournbladeCYD2Utility.computeMonnaieDetails(valueSC)
- }
-
- /* -------------------------------------------- */
- getCompetence(compId) {
- return this.items.get(compId)
- }
-
- /* -------------------------------------------- */
- async setPredilectionUsed(compId, predIdx) {
- let comp = this.items.get(compId)
- let pred = foundry.utils.duplicate(comp.system.predilections)
- pred[predIdx].used = true
- await this.updateEmbeddedDocuments('Item', [{ _id: compId, 'system.predilections': pred }])
- }
-
- /* -------------------------------------------- */
- getInitiativeScore() {
- let init = this.getFlag("world", "last-initiative")
- return init || -1
- }
-
- /* -------------------------------------------- */
- getBestAttackValue() {
- let attackList = this.items.filter(item => (item.type == "arme" || item.type == "talent") && item.system.equipped)
- let maxOff = 0
- let bestArme
- for (let arme of attackList) {
- if (arme.type == "arme") {
- arme = this.prepareArme(arme)
- }
- if (arme.system.totalOffensif > maxOff) {
- maxOff = arme.system.totalOffensif
- bestArme = foundry.utils.duplicate(arme)
- }
- }
- return bestArme
- }
-
- /* -------------------------------------------- */
- getBestDefenseValue() {
- let defenseList = this.items.filter(item => (item.type == "arme") && item.system.equipped)
- let maxDef = 0
- let bestArme
- for (let arme of defenseList) {
- if (arme.type == "arme") {
- arme = this.prepareArme(arme)
- }
- if (arme.system.totalDefensif > maxDef) {
- maxDef = arme.system.totalDefensif
- bestArme = foundry.utils.duplicate(arme)
- }
- }
- return bestArme
- }
-
- /* -------------------------------------------- */
- searchRelevantTalents(competence) {
- let talents = []
-
- for (let talent of this.items) {
- if (talent.type == "talent" && talent.system.isautomated && talent.system.automations.length > 0) {
- for (let auto of talent.system.automations) {
- if (auto.eventtype === "prepare-roll") {
- if (auto.competence.toLowerCase() == competence.name.toLowerCase()) {
- talent = foundry.utils.duplicate(talent)
- talent.system.bonus = auto.bonus
- talent.system.baCost = auto.baCost
- talents.push(talent)
- }
- }
- }
- }
- }
- return talents
- }
-
- /* -------------------------------------------- */
- buildListeAdversites() {
- return []
- }
-
- /* -------------------------------------------- */
- getCommonRollData(attrKey = undefined, compId = undefined, compName = undefined) {
- let rollData = MournbladeCYD2Utility.getBasicRollData()
- rollData.alias = this.name
- rollData.actorImg = this.img
- rollData.actorId = this.id
- rollData.tokenId = this.token?.id
- rollData.img = this.img
- rollData.attributs = MournbladeCYD2Utility.getAttributs()
- rollData.maitriseId = "none"
- rollData.nbEclat = this.system.eclat.value
- rollData.nbBA = this.system.bonneaventure.actuelle
- rollData.nbAdversites = this.getTotalAdversite()
- rollData.talents = []
- rollData.attrKey2 = "none"
- rollData.coupDevastateur = this.items.find(it => it.type == "talent" && it.name.toLowerCase() == "coup dévastateur" && !it.system.used)
- rollData.hasAmbidextre = this.items.find(it => it.type == "talent" && it.name.toLowerCase() == "ambidextre")
- rollData.hasFeinte = this.system.bonneaventure.actuelle > 0 && this.items.find(it => it.type == "talent" && it.name.toLowerCase() == "feinte")
- rollData.isMonte = this.system.combat.monte
- rollData.config = game.system.mournbladecyd2.config
-
- if (attrKey) {
- rollData.attrKey = attrKey
- if (attrKey != "tochoose") {
- rollData.actionImg = "systems/fvtt-mournblade-cyd2/assets/icons/" + this.system.attributs[attrKey].labelnorm + ".webp"
- rollData.attr = foundry.utils.duplicate(this.system.attributs[attrKey])
- }
- }
- if (compId) {
- rollData.competence = foundry.utils.duplicate(this.items.get(compId) || {})
- let maitrises = [{ key: "none", label: "Aucune" }]
- rollData.competence.system.predilections.forEach(function (item) {
- if (item.maitrise) {
- maitrises.push({ key: item.id, label: item.name });
- }
- })
- rollData.maitrises = maitrises // rollData.competence.system.predilections.filter(p => p.maitrise)
- rollData.actionImg = rollData.competence?.img
- rollData.talents = this.searchRelevantTalents(rollData.competence)
- }
- if (compName) {
- rollData.competence = foundry.utils.duplicate(this.items.find(item => item.name.toLowerCase() == compName.toLowerCase()) || {})
- rollData.actionImg = rollData.competence?.img
- }
- return rollData
- }
-
- /* -------------------------------------------- */
- async rollAttribut(attrKey, isInit = false) {
- let rollData = this.getCommonRollData(attrKey)
- rollData.multiplier = (isInit) ? 1 : 2
- rollData.isInit = isInit
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
-
- /* -------------------------------------------- */
- async rollCompetence(attrKey, compId) {
- let rollData = this.getCommonRollData(attrKey, compId)
- rollData.multiplier = 1 // Attr multiplier, always 1 in competence mode
- console.log("RollDatra", rollData)
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
-
- /* -------------------------------------------- */
- async rollArmeOffensif(armeId) {
- let arme = this.items.get(armeId)
- if (arme.type == "arme") {
- arme = this.prepareArme(arme)
- }
- let rollData = this.getCommonRollData(arme.system.attrKey, arme.system.competence._id)
- rollData.arme = arme
- MournbladeCYD2Utility.updateWithTarget(rollData)
- console.log("ARME!", rollData)
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
- /* -------------------------------------------- */
- async rollAssommer() {
- let rollData = this.getCommonRollData("pui", undefined, "Filouterie")
- rollData.assomer = true
- rollData.conditionsCommunes = true
- MournbladeCYD2Utility.updateWithTarget(rollData)
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
- /* -------------------------------------------- */
- async rollCoupBas() {
- let rollData = this.getCommonRollData("pui", undefined, "Mêlée")
- rollData.coupBas = true
- rollData.conditionsCommunes = true
- MournbladeCYD2Utility.updateWithTarget(rollData)
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
- /* -------------------------------------------- */
- async rollImmobiliser() {
- let rollData = this.getCommonRollData("pui", undefined, "Mêlée")
- rollData.immobiliser = true
- rollData.conditionsCommunes = true
- rollData.cibleconsciente = true
- MournbladeCYD2Utility.updateWithTarget(rollData)
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
- /* -------------------------------------------- */
- async rollRepousser() {
- let rollData = this.getCommonRollData("pui", undefined, "Mêlée")
- rollData.repousser = true
- rollData.conditionsCommunes = true
- rollData.cibleconsciente = true
- MournbladeCYD2Utility.updateWithTarget(rollData)
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
- /* -------------------------------------------- */
- async rollDesengager() {
- let rollData = this.getCommonRollData("adr", undefined, "Mouvements")
- rollData.desengager = true
- rollData.conditionsCommunes = true
- MournbladeCYD2Utility.updateWithTarget(rollData)
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
-
- /* -------------------------------------------- */
- async rollArmeDegats(armeId, targetVigueur = undefined, rollDataInput = undefined) {
- let arme = this.items.get(armeId)
- if (arme.type == "arme") {
- arme = this.prepareArme(arme)
- }
- console.log("DEGATS", arme, targetVigueur, rollDataInput)
- let roll
- let bonus = 0
- let bonus2 = 0
-
- if (rollDataInput?.applyCoupDevastateur) {
- bonus2 = Math.floor(this.system.attributs.pui.value / 2)
- let talent = this.items.find(item => item.type == "talent" && item.name.toLowerCase() == "coup dévastateur")
- this.updateEmbeddedDocuments('Item', [{ _id: talent.id, 'system.used': true }])
- }
-
- if (rollDataInput?.isHeroique) {
- if (rollDataInput?.attaqueCharge) {
- bonus = 5
- }
- if (rollDataInput?.chargeCavalerie) {
- bonus = 6
- }
- roll = await new Roll("2d10rr10+" + arme.system.totalDegats + "+" + bonus + "+" + bonus2).roll()
- } else {
- if (rollDataInput?.attaqueCharge) {
- bonus = 3
- }
- if (rollDataInput?.chargeCavalerie) {
- bonus = 4
- }
- roll = await new Roll("1d10+" + arme.system.totalDegats + "+" + bonus + "+" + bonus2).roll()
- }
- await MournbladeCYD2Utility.showDiceSoNice(roll, game.settings.get("core", "rollMode"));
- let nbEtatPerdus = 0
- if (targetVigueur) {
- nbEtatPerdus = Math.floor(roll.total / targetVigueur)
- }
- //console.log(roll)
- let rollData = {
- arme: arme,
- finalResult: roll.total,
- formula: roll.formula,
- alias: this.name,
- actorImg: this.img,
- actorId: this.id,
- defenderTokenId: rollDataInput?.defenderTokenId,
- actionImg: arme.img,
- targetVigueur: targetVigueur,
- nbEtatPerdus: nbEtatPerdus
- }
- MournbladeCYD2Utility.createChatWithRollMode(rollData.alias, {
- content: await renderTemplate(`systems/fvtt-mournblade-cyd2/templates/chat-degats-result.html`, rollData)
- })
-
- if (rollDataInput?.defenderTokenId && nbEtatPerdus) {
- MournbladeCYD2Utility.applyCombativite(rollDataInput, nbEtatPerdus)
- }
-
- }
-}
diff --git a/.history/modules/mournblade-cyd2-actor_20251026082021.js b/.history/modules/mournblade-cyd2-actor_20251026082021.js
deleted file mode 100644
index 2657656..0000000
--- a/.history/modules/mournblade-cyd2-actor_20251026082021.js
+++ /dev/null
@@ -1,828 +0,0 @@
-/* -------------------------------------------- */
-import { MournbladeCYD2Utility } from "./mournblade-cyd2-utility.js";
-import { MournbladeCYD2RollDialog } from "./mournblade-cyd2-roll-dialog.js";
-
-/* -------------------------------------------- */
-const __degatsBonus = [-2, -2, -1, -1, 0, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 8, 8, 9, 9, 10, 10]
-const __vitesseBonus = [-2, -2, -1, -1, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8]
-
-/* -------------------------------------------- */
-/**
- * Extend the base Actor entity by defining a custom roll data structure which is ideal for the Simple system.
- * @extends {Actor}
- */
-export class MournbladeCYD2Actor extends Actor {
-
- /* -------------------------------------------- */
- /**
- * Override the create() function to provide additional SoS functionality.
- *
- * This overrided create() function adds initial items
- * Namely: Basic skills, money,
- *
- * @param {Object} data Barebones actor data which this function adds onto.
- * @param {Object} options (Unused) Additional options which customize the creation workflow.
- *
- */
-
- static async create(data, options) {
-
- // Case of compendium global import
- if (data instanceof Array) {
- return super.create(data, options);
- }
- // If the created actor has items (only applicable to duplicated actors) bypass the new actor creation logic
- if (data.items) {
- let actor = super.create(data, options);
- return actor;
- }
-
- if (data.type == 'personnage') {
- const skills = await MournbladeCYD2Utility.loadCompendium("fvtt-mournblade-cyd2.skills")
- data.items = skills.map(i => i.toObject())
- }
- if (data.type == 'creature') {
- const skills = await MournbladeCYD2Utility.loadCompendium("fvtt-mournblade-cyd2.skills-creatures")
- data.items = skills.map(i => i.toObject())
- data.items.push({ name: "Arme naturelle 1", type: 'arme', img: "systems/fvtt-mournblade-cyd2/assets/icons/melee.webp", system: { typearme: "contact", bonusmaniementoff: 0, seuildefense: 0, degats: "0" } })
- data.items.push({ name: "Arme naturelle 2", type: 'arme', img: "systems/fvtt-mournblade-cyd2/assets/icons/melee.webp", system: { typearme: "contact", bonusmaniementoff: 0, seuildefense: 0, degats: "0" } })
- }
-
- return super.create(data, options);
- }
-
- /* -------------------------------------------- */
- getBonusDefenseFromTalents() {
- let talents = this.items.filter(item => item.type == "talent" && item.system.isautomated)
- let bonus = 0
- for (let talent of talents) {
- for (let auto of talent.system.automations) {
- if (auto.eventtype == "bonus-permanent" && auto.bonusname == "bonus-defensif") {
- bonus += Number(auto.bonus || 0)
- }
- }
- }
- return bonus
- }
-
- /* -------------------------------------------- */
- prepareArme(arme) {
- if (this.type == "cellule") {
- return arme
- }
-
- arme = foundry.utils.duplicate(arme)
- let combat = this.getCombatValues()
- if (arme.system.typearme == "contact" || arme.system.typearme == "contactjet") {
- let bonusDefense = this.getBonusDefenseFromTalents()
- arme.system.competence = foundry.utils.duplicate(this.items.find(item => item.type == "competence" && item.name.toLowerCase() == "mêlée"))
- arme.system.attrKey = "pui"
- arme.system.totalDegats = arme.system.degats + "+" + combat.bonusDegatsTotal
- arme.system.totalOffensif = this.system.attributs.pui.value + arme.system.competence.system.niveau + arme.system.bonusmaniementoff + (this.system.combat.monte ? 3 : 0)
- arme.system.totalDefensif = combat.defenseTotal + arme.system.competence.system.niveau + arme.system.seuildefense + bonusDefense + (this.system.combat.monte ? 3 : 0)
- console.log("Arme", arme.system.totalDefensif, combat, arme.system.competence.system.niveau, arme.system.seuildefense, bonusDefense)
- arme.system.isdefense = true
- arme.system.isMelee = true
- arme.system.isDistance = false
- }
- if (arme.system.typearme == "jet" || arme.system.typearme == "tir") {
- arme.system.competence = foundry.utils.duplicate(this.items.find(item => item.type == "competence" && item.name.toLowerCase() == "armes à distance"))
- arme.system.attrKey = "adr"
- arme.system.totalOffensif = this.system.attributs.adr.value + arme.system.competence.system.niveau + arme.system.bonusmaniementoff
- arme.system.totalDegats = arme.system.degats
- arme.system.isMelee = false
- arme.system.isDistance = true
- if (arme.system.isdefense) {
- arme.system.totalDefensif = combat.defenseTotal + arme.system.competence.system.niveau + arme.system.seuildefense
- }
- }
- return arme
- }
-
- /* -------------------------------------------- */
- getItemSorted(types) {
- let items = this.items.filter(item => types.includes(item.type)) || []
- MournbladeCYD2Utility.sortArrayObjectsByName(items)
- return items
- }
- getWeapons() {
- let armes = []
- for (let arme of this.items) {
- if (arme.type == "arme") {
- armes.push(this.prepareArme(arme))
- }
- }
- MournbladeCYD2Utility.sortArrayObjectsByName(armes)
- return armes
- }
- getMonnaies() {
- return this.getItemSorted(["monnaie"])
- }
- getEquipments() {
- return this.getItemSorted(["equipement"])
- }
- getArtefacts() {
- return this.getItemSorted(["artefact"])
- }
- getArmors() {
- return this.getItemSorted(["protection"])
- }
- getHistoriques() {
- return this.getItemSorted(["historique"])
- }
- getProfils() {
- return this.getItemSorted(["profil"])
- }
- getTalents() {
- return this.getItemSorted(["talent"])
- }
- getRessources() {
- return this.getItemSorted(["ressource"])
- }
- getContacts() {
- return this.getItemSorted(["contact"])
- }
- getMutations() {
- return this.getItemSorted(["mutation"])
- }
- getDons() {
- return this.getItemSorted(["don"])
- }
- getPactes() {
- return this.getItemSorted(["pacte"])
- }
- getTendances() {
- return this.getItemSorted(["tendance"])
- }
- getRunes() {
- return this.getItemSorted(["rune"])
- }
- getTraitsChaotiques() {
- return this.getItemSorted(["traitchaotique"])
- }
- getTraitsEspeces() {
- return this.getItemSorted(["traitespece"])
- }
-
- /* -------------------------------------------- */
- getAspect() {
- return (this.system.balance.loi > this.system.balance.chaos) ? this.system.balance.loi : this.system.balance.chaos
- }
- getMarge() {
- return Math.abs(this.system.balance.loi - this.system.balance.chaos)
- }
- getAlignement() {
- return (this.system.balance.loi > this.system.balance.chaos) ? "loyal" : "chaotique"
- }
-
- /* -------------------------------------------- */
- getSkills() {
- let comp = []
- for (let item of this.items) {
- item = foundry.utils.duplicate(item)
- if (item.type == "competence") {
- item.system.attribut1total = item.system.niveau + (this.system.attributs[item.system.attribut1]?.value || 0)
- item.system.attribut2total = item.system.niveau + (this.system.attributs[item.system.attribut2]?.value || 0)
- item.system.attribut3total = item.system.niveau + (this.system.attributs[item.system.attribut3]?.value || 0)
- if (item.system.niveau == 0) {
- item.system.attribut1total -= 3
- item.system.attribut2total -= 3
- item.system.attribut3total -= 3
- }
- item.system.attribut1label = this.system.attributs[item.system.attribut1]?.label || ""
- item.system.attribut2label = this.system.attributs[item.system.attribut2]?.label || ""
- item.system.attribut3label = this.system.attributs[item.system.attribut3]?.label || ""
- comp.push(item)
- }
- }
- MournbladeCYD2Utility.sortArrayObjectsByName(comp)
- return comp
- }
-
- /* ----------------------- --------------------- */
- addMember(actorId) {
- let members = foundry.utils.duplicate(this.system.members)
- members.push({ id: actorId })
- this.update({ 'system.members': members })
- }
- async removeMember(actorId) {
- let members = this.system.members.filter(it => it.id != actorId)
- this.update({ 'system.members': members })
- }
-
- /* -------------------------------------------- */
- getDefenseBase() {
- return Math.max(this.system.attributs.tre.value, this.system.attributs.adr.value)
- }
-
- /* -------------------------------------------- */
- getVitesseBase() {
- return 5 + __vitesseBonus[this.system.attributs.adr.value]
- }
- /* -------------------------------------------- */
- getProtection() {
- let equipProtection = 0
- for (let armor of this.items) {
- if (armor.type == "protection" && armor.system.equipped) {
- equipProtection += Number(armor.system.protection)
- }
- }
- if (equipProtection < 4) {
- return 4 + equipProtection // Cas des boucliers + sans armure
- }
- return equipProtection // Uniquement la protection des armures + boucliers
- }
-
- /* -------------------------------------------- */
- getCombatValues() {
- if (this.type == "cellule") {
- return {
- initBase: 0,
- initTotal: 0,
- bonusDegats: 0,
- bonusDegatsTotal: 0,
- vitesseBase: 0,
- vitesseTotal: 0,
- defenseBase: 0,
- protection: 0,
- defenseTotal: 0
- }
- }
-
- let combat = {
- initBase: this.system.attributs.adr.value,
- initTotal: this.system.attributs.adr.value + this.system.combat.initbonus,
- bonusDegats: this.getBonusDegats(),
- bonusDegatsTotal: this.getBonusDegats() + this.system.combat.bonusdegats,
- vitesseBase: this.getVitesseBase(),
- vitesseTotal: this.getVitesseBase() + this.system.combat.vitessebonus,
- defenseBase: this.getDefenseBase(),
- protection: this.getProtection(),
- defenseTotal: this.getDefenseBase() + this.system.combat.defensebonus + this.getProtection() - this.getTotalAdversite() + (this.system.combat.defensetotale ? 3 : 0)
- }
- return combat
- }
-
- /* -------------------------------------------- */
- prepareBaseData() {
- }
-
- /* -------------------------------------------- */
- async prepareData() {
- super.prepareData();
- }
-
- /* -------------------------------------------- */
- prepareDerivedData() {
-
- if (this.type == 'personnage') {
- let talentBonus = this.getVigueurBonus()
- let vigueur = Math.floor((this.system.attributs.pui.value + this.system.attributs.tre.value) / 2) + talentBonus + this.system.sante.vigueurmodifier
- if (vigueur != this.system.sante.vigueur) {
- this.update({ 'system.sante.vigueur': vigueur })
- }
-
- let seuilPouvoirBonus = this.getSeuilPouvoirBonus()
- let seuilPouvoir = Math.floor((this.system.attributs.tre.value + this.system.attributs.cla.value) / 2) + seuilPouvoirBonus + this.system.ame.seuilpouvoirmodifier
- if (seuilPouvoir != this.system.ame.seuilpouvoir) {
- this.update({ 'system.ame.seuilpouvoir': seuilPouvoir })
- }
- }
- super.prepareDerivedData()
- }
-
- /* -------------------------------------------- */
- _preUpdate(changed, options, user) {
- if (changed?.system?.sante?.etat && changed?.system?.sante?.etat != this.system.sante.etat) {
- setTimeout(() => {
- this.processCombativite(changed.system.sante)
- }, 800)
- }
- super._preUpdate(changed, options, user);
- }
-
- /* -------------------------------------------- */
- _onUpdate(data, options, user) {
- super._onUpdate(data, options, user);
- }
- /* -------------------------------------------- */
- getItemById(id) {
- let item = this.items.find(item => item.id == id);
- if (item) {
- item = foundry.utils.duplicate(item)
- }
- return item;
- }
-
- /* -------------------------------------------- */
- async equipItem(itemId) {
- let item = this.items.find(item => item.id == itemId)
- if (item && item.system) {
- let update = { _id: item.id, "system.equipped": !item.system.equipped }
- await this.updateEmbeddedDocuments('Item', [update]); // Updates one EmbeddedEntity
- }
- }
-
- /* -------------------------------------------- */
- editItemField(itemId, itemType, itemField, dataType, value) {
- let item = this.items.find(item => item.id == itemId)
- if (item) {
- console.log("Item ", item, itemField, dataType, value)
- if (dataType.toLowerCase() == "number") {
- value = Number(value)
- } else {
- value = String(value)
- }
- let update = { _id: item.id, [`system.${itemField}`]: value };
- this.updateEmbeddedDocuments("Item", [update])
- }
- }
-
- /* -------------------------------------------- */
- checkAttribut(attribut, minLevel) {
- let attr = this.system.attributs.find(at => at.labelnorm == attribut.toLowerCase())
- if (attr && attr.value >= minLevel) {
- return { isValid: true, attr: foundry.utils.duplicate(attr) }
- }
- return { isValid: false }
- }
- /* -------------------------------------------- */
- checkAttributOrCompetenceLevel(compName, minLevel) {
- let comp = this.items.find(i => i.type == "competence" && i.name.toLowerCase() == compName.toLowerCase() && i.system.niveau >= minLevel)
- if (comp) {
- return { isValid: true, item: foundry.utils.duplicate(comp) }
- } else {
- for (let attrKey in this.system.attributs) {
- if (this.system.attributs[attrKey].label.toLowerCase() == compName.toLowerCase() && this.system.attributs[attrKey].value >= minLevel) {
- return { isValid: true, item: foundry.utils.duplicate(this.system.attributs[attrKey]) }
- }
- }
- }
- return { isValid: false, warningMessage: `Prérequis insuffisant : la compétence/attribut ${compName} doit être de niveau ${minLevel} au minimum` }
- }
- /* -------------------------------------------- */
- addCompetenceBonus(compName, bonus, baCost) {
- let comp = this.items.find(i => i.type == "competence" && i.name.toLowerCase() == compName.toLowerCase())
- if (comp) {
- comp = foundry.utils.duplicate(comp)
- comp.system.bonus = bonus
- comp.system.baCost = baCost
- return { isValid: true, item: comp }
- }
- return { isValid: false, warningMessage: `Compétence ${compName} non trouvée` }
- }
- /* -------------------------------------------- */
- checkIfCompetence(compName) {
- let comp = this.items.find(i => i.type == "competence" && i.name.toLowerCase() == compName.toLowerCase())
- if (comp) {
- return { isValid: true, item: comp }
- }
- return { isValid: false }
- }
- /* -------------------------------------------- */
- getVigueur() {
- return this.system.sante.vigueur
- }
-
- /* -------------------------------------------- */
- getVigueurBonus() {
- let talents = this.items.filter(item => item.type == "talent" && item.system.isautomated)
- let bonus = 0
- for (let talent of talents) {
- for (let auto of talent.system.automations) {
- if (auto.eventtype == "bonus-permanent" && auto.bonusname == "vigueur") {
- bonus += Number(auto.bonus || 0)
- }
- }
- }
- return bonus
- }
-
- /* -------------------------------------------- */
- getBonneAventure() {
- return this.system.bonneaventure.actuelle
- }
- /* -------------------------------------------- */
- checkBonneAventure(cost) {
- return (this.system.bonneaventure.actuelle >= cost)
- }
- /* -------------------------------------------- */
- changeBonneAventure(value) {
- let newBA = this.system.bonneaventure.actuelle
- newBA += value
- this.update({ 'system.bonneaventure.actuelle': newBA })
- }
-
- /* -------------------------------------------- */
- getEclat() {
- return this.system.eclat.value
- }
-
- /* -------------------------------------------- */
- changeEclat(value) {
- let newE = this.system.eclat.value
- newE += value
- this.update({ 'system.eclat.value': newE })
- }
-
- /* -------------------------------------------- */
- compareName(a, b) {
- if (a.name < b.name) {
- return -1;
- }
- if (a.name > b.name) {
- return 1;
- }
- return 0;
- }
-
- /* -------------------------------------------- */
- getAttribute(attrKey) {
- return this.system.attributes[attrKey]
- }
-
- /* -------------------------------------------- */
- getBonusDegats() {
- return 0;
- }
-
- /* -------------------------------------------- */
- changeEtatCombativite(value) {
- if (value === "vaincu") {
- value = 200
- }
- let sante = foundry.utils.duplicate(this.system.sante)
- sante.etat += Number(value)
- sante.etat = Math.max(sante.etat, 0)
- sante.etat = Math.min(sante.etat, this.system.sante.nbcombativite)
- this.update({ 'system.sante': sante })
- if (sante.etat == this.system.sante.nbcombativite) {
- ChatMessage.create({ content: `${this.name} est vaincu !` })
- }
- // Duplicated ! this.processCombativite(sante)
- }
-
- /* -------------------------------------------- */
- processCombativite(sante) {
- sante = sante || foundry.utils.duplicate(this.system.sante)
- // Gestion des états affaibli et très affaibli
- if (sante.etat == this.system.sante.nbcombativite - 2 || sante.etat == this.system.sante.nbcombativite - 1) {
- if (sante.etat == this.system.sante.nbcombativite - 2 && this.items.find(item => item.type == "talent" && item.name.toLowerCase() == "encaissement")) {
- ChatMessage.create({ content: `${this.name} ne subit pas les 2 adversités rouge grâce à Encaissement. Pensez à les ajouter à la fin de la scène !` })
- } else if (sante.etat == this.system.sante.nbcombativite - 1 && this.items.find(item => item.type == "talent" && item.name.toLowerCase().includes("vaillant"))) {
- ChatMessage.create({ content: `${this.name} ne subit pas les 2 adversités rouge grâce à Vaillant. Pensez à les ajouter à la fin de la scène !` })
- } else {
- ChatMessage.create({ content: `${this.name} subit 2 adversités rouge !` })
- this.incDecAdversite("rouge", 2)
- }
- }
- }
-
- /* -------------------------------------------- */
- async equipGear(equipmentId) {
- let item = this.items.find(item => item.id == equipmentId);
- if (item?.system?.data) {
- let update = { _id: item.id, "system.equipped": !item.system.equipped };
- await this.updateEmbeddedDocuments('Item', [update]); // Updates one EmbeddedEntity
- }
- }
-
- /* -------------------------------------------- */
- getSubActors() {
- let subActors = [];
- for (let id of this.system.subactors) {
- subActors.push(foundry.utils.duplicate(game.actors.get(id)));
- }
- return subActors;
- }
- /* -------------------------------------------- */
- async addSubActor(subActorId) {
- let subActors = foundry.utils.duplicate(this.system.subactors);
- subActors.push(subActorId);
- await this.update({ 'system.subactors': subActors });
- }
- /* -------------------------------------------- */
- async delSubActor(subActorId) {
- let newArray = [];
- for (let id of this.system.subactors) {
- if (id != subActorId) {
- newArray.push(id);
- }
- }
- await this.update({ 'system.subactors': newArray });
- }
-
- /* -------------------------------------------- */
- getTotalAdversite() {
- return this.system.adversite.bleue + this.system.adversite.rouge + this.system.adversite.noire
- }
-
- /* -------------------------------------------- */
- async incDecAdversite(adv, incDec = 0) {
- let adversite = foundry.utils.duplicate(this.system.adversite)
- adversite[adv] += Number(incDec)
- adversite[adv] = Math.max(adversite[adv], 0)
- adversite[adv] = Math.min(adversite[adv], 20)
- this.update({ 'system.adversite': adversite })
- }
- /* -------------------------------------------- */
- async incDecQuantity(objetId, incDec = 0) {
- let objetQ = this.items.get(objetId)
- if (objetQ) {
- let newQ = objetQ.system.quantite + incDec
- newQ = Math.max(newQ, 0)
- await this.updateEmbeddedDocuments('Item', [{ _id: objetQ.id, 'system.quantite': newQ }]); // pdates one EmbeddedEntity
- }
- }
-
- /* -------------------------------------------- */
- computeRichesse() {
- let valueSC = 0
- for (let monnaie of this.items) {
- if (monnaie.type == "monnaie") {
- valueSC += Number(monnaie.system.prixsc) * Number(monnaie.system.quantite)
- }
- }
- return MournbladeCYD2Utility.computeMonnaieDetails(valueSC)
- }
-
- /* -------------------------------------------- */
- computeValeurEquipement() {
- let valueSC = 0
- for (let equip of this.items) {
- if (equip.type == "equipement" || equip.type == "arme" || equip.type == "protection") {
- valueSC += Number(equip.system.prixsc) * Number(equip.system.quantite ?? 1)
- valueSC += (Number(equip.system.prixca) * Number(equip.system.quantite ?? 1)) * 20
- valueSC += (Number(equip.system.prixpo) * Number(equip.system.quantite ?? 1)) * 400
- }
- }
- return MournbladeCYD2Utility.computeMonnaieDetails(valueSC)
- }
-
- /* -------------------------------------------- */
- getCompetence(compId) {
- return this.items.get(compId)
- }
-
- /* -------------------------------------------- */
- async setPredilectionUsed(compId, predIdx) {
- let comp = this.items.get(compId)
- let pred = foundry.utils.duplicate(comp.system.predilections)
- pred[predIdx].used = true
- await this.updateEmbeddedDocuments('Item', [{ _id: compId, 'system.predilections': pred }])
- }
-
- /* -------------------------------------------- */
- getInitiativeScore() {
- let init = this.getFlag("world", "last-initiative")
- return init || -1
- }
-
- /* -------------------------------------------- */
- getBestAttackValue() {
- let attackList = this.items.filter(item => (item.type == "arme" || item.type == "talent") && item.system.equipped)
- let maxOff = 0
- let bestArme
- for (let arme of attackList) {
- if (arme.type == "arme") {
- arme = this.prepareArme(arme)
- }
- if (arme.system.totalOffensif > maxOff) {
- maxOff = arme.system.totalOffensif
- bestArme = foundry.utils.duplicate(arme)
- }
- }
- return bestArme
- }
-
- /* -------------------------------------------- */
- getBestDefenseValue() {
- let defenseList = this.items.filter(item => (item.type == "arme") && item.system.equipped)
- let maxDef = 0
- let bestArme
- for (let arme of defenseList) {
- if (arme.type == "arme") {
- arme = this.prepareArme(arme)
- }
- if (arme.system.totalDefensif > maxDef) {
- maxDef = arme.system.totalDefensif
- bestArme = foundry.utils.duplicate(arme)
- }
- }
- return bestArme
- }
-
- /* -------------------------------------------- */
- searchRelevantTalents(competence) {
- let talents = []
-
- for (let talent of this.items) {
- if (talent.type == "talent" && talent.system.isautomated && talent.system.automations.length > 0) {
- for (let auto of talent.system.automations) {
- if (auto.eventtype === "prepare-roll") {
- if (auto.competence.toLowerCase() == competence.name.toLowerCase()) {
- talent = foundry.utils.duplicate(talent)
- talent.system.bonus = auto.bonus
- talent.system.baCost = auto.baCost
- talents.push(talent)
- }
- }
- }
- }
- }
- return talents
- }
-
- /* -------------------------------------------- */
- buildListeAdversites() {
- return []
- }
-
- /* -------------------------------------------- */
- getCommonRollData(attrKey = undefined, compId = undefined, compName = undefined) {
- let rollData = MournbladeCYD2Utility.getBasicRollData()
- rollData.alias = this.name
- rollData.actorImg = this.img
- rollData.actorId = this.id
- rollData.tokenId = this.token?.id
- rollData.img = this.img
- rollData.attributs = MournbladeCYD2Utility.getAttributs()
- rollData.maitriseId = "none"
- rollData.nbEclat = this.system.eclat.value
- rollData.nbBA = this.system.bonneaventure.actuelle
- rollData.nbAdversites = this.getTotalAdversite()
- rollData.talents = []
- rollData.attrKey2 = "none"
- rollData.coupDevastateur = this.items.find(it => it.type == "talent" && it.name.toLowerCase() == "coup dévastateur" && !it.system.used)
- rollData.hasAmbidextre = this.items.find(it => it.type == "talent" && it.name.toLowerCase() == "ambidextre")
- rollData.hasFeinte = this.system.bonneaventure.actuelle > 0 && this.items.find(it => it.type == "talent" && it.name.toLowerCase() == "feinte")
- rollData.isMonte = this.system.combat.monte
- rollData.config = game.system.mournbladecyd2.config
-
- if (attrKey) {
- rollData.attrKey = attrKey
- if (attrKey != "tochoose") {
- rollData.actionImg = "systems/fvtt-mournblade-cyd2/assets/icons/" + this.system.attributs[attrKey].labelnorm + ".webp"
- rollData.attr = foundry.utils.duplicate(this.system.attributs[attrKey])
- }
- }
- if (compId) {
- rollData.competence = foundry.utils.duplicate(this.items.get(compId) || {})
- let maitrises = [{ key: "none", label: "Aucune" }]
- rollData.competence.system.predilections.forEach(function (item) {
- if (item.maitrise) {
- maitrises.push({ key: item.id, label: item.name });
- }
- })
- rollData.maitrises = maitrises // rollData.competence.system.predilections.filter(p => p.maitrise)
- rollData.actionImg = rollData.competence?.img
- rollData.talents = this.searchRelevantTalents(rollData.competence)
- }
- if (compName) {
- rollData.competence = foundry.utils.duplicate(this.items.find(item => item.name.toLowerCase() == compName.toLowerCase()) || {})
- rollData.actionImg = rollData.competence?.img
- }
- return rollData
- }
-
- /* -------------------------------------------- */
- async rollAttribut(attrKey, isInit = false) {
- let rollData = this.getCommonRollData(attrKey)
- rollData.multiplier = (isInit) ? 1 : 2
- rollData.isInit = isInit
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
-
- /* -------------------------------------------- */
- async rollCompetence(attrKey, compId) {
- let rollData = this.getCommonRollData(attrKey, compId)
- rollData.multiplier = 1 // Attr multiplier, always 1 in competence mode
- console.log("RollDatra", rollData)
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
-
- /* -------------------------------------------- */
- async rollArmeOffensif(armeId) {
- let arme = this.items.get(armeId)
- if (arme.type == "arme") {
- arme = this.prepareArme(arme)
- }
- let rollData = this.getCommonRollData(arme.system.attrKey, arme.system.competence._id)
- rollData.arme = arme
- MournbladeCYD2Utility.updateWithTarget(rollData)
- console.log("ARME!", rollData)
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
- /* -------------------------------------------- */
- async rollAssommer() {
- let rollData = this.getCommonRollData("pui", undefined, "Filouterie")
- rollData.assomer = true
- rollData.conditionsCommunes = true
- MournbladeCYD2Utility.updateWithTarget(rollData)
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
- /* -------------------------------------------- */
- async rollCoupBas() {
- let rollData = this.getCommonRollData("pui", undefined, "Mêlée")
- rollData.coupBas = true
- rollData.conditionsCommunes = true
- MournbladeCYD2Utility.updateWithTarget(rollData)
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
- /* -------------------------------------------- */
- async rollImmobiliser() {
- let rollData = this.getCommonRollData("pui", undefined, "Mêlée")
- rollData.immobiliser = true
- rollData.conditionsCommunes = true
- rollData.cibleconsciente = true
- MournbladeCYD2Utility.updateWithTarget(rollData)
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
- /* -------------------------------------------- */
- async rollRepousser() {
- let rollData = this.getCommonRollData("pui", undefined, "Mêlée")
- rollData.repousser = true
- rollData.conditionsCommunes = true
- rollData.cibleconsciente = true
- MournbladeCYD2Utility.updateWithTarget(rollData)
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
- /* -------------------------------------------- */
- async rollDesengager() {
- let rollData = this.getCommonRollData("adr", undefined, "Mouvements")
- rollData.desengager = true
- rollData.conditionsCommunes = true
- MournbladeCYD2Utility.updateWithTarget(rollData)
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
-
- /* -------------------------------------------- */
- async rollArmeDegats(armeId, targetVigueur = undefined, rollDataInput = undefined) {
- let arme = this.items.get(armeId)
- if (arme.type == "arme") {
- arme = this.prepareArme(arme)
- }
- console.log("DEGATS", arme, targetVigueur, rollDataInput)
- let roll
- let bonus = 0
- let bonus2 = 0
-
- if (rollDataInput?.applyCoupDevastateur) {
- bonus2 = Math.floor(this.system.attributs.pui.value / 2)
- let talent = this.items.find(item => item.type == "talent" && item.name.toLowerCase() == "coup dévastateur")
- this.updateEmbeddedDocuments('Item', [{ _id: talent.id, 'system.used': true }])
- }
-
- if (rollDataInput?.isHeroique) {
- if (rollDataInput?.attaqueCharge) {
- bonus = 5
- }
- if (rollDataInput?.chargeCavalerie) {
- bonus = 6
- }
- roll = await new Roll("2d10rr10+" + arme.system.totalDegats + "+" + bonus + "+" + bonus2).roll()
- } else {
- if (rollDataInput?.attaqueCharge) {
- bonus = 3
- }
- if (rollDataInput?.chargeCavalerie) {
- bonus = 4
- }
- roll = await new Roll("1d10+" + arme.system.totalDegats + "+" + bonus + "+" + bonus2).roll()
- }
- await MournbladeCYD2Utility.showDiceSoNice(roll, game.settings.get("core", "rollMode"));
- let nbEtatPerdus = 0
- if (targetVigueur) {
- nbEtatPerdus = Math.floor(roll.total / targetVigueur)
- }
- //console.log(roll)
- let rollData = {
- arme: arme,
- finalResult: roll.total,
- formula: roll.formula,
- alias: this.name,
- actorImg: this.img,
- actorId: this.id,
- defenderTokenId: rollDataInput?.defenderTokenId,
- actionImg: arme.img,
- targetVigueur: targetVigueur,
- nbEtatPerdus: nbEtatPerdus
- }
- MournbladeCYD2Utility.createChatWithRollMode(rollData.alias, {
- content: await renderTemplate(`systems/fvtt-mournblade-cyd2/templates/chat-degats-result.html`, rollData)
- })
-
- if (rollDataInput?.defenderTokenId && nbEtatPerdus) {
- MournbladeCYD2Utility.applyCombativite(rollDataInput, nbEtatPerdus)
- }
-
- }
-}
diff --git a/.history/modules/mournblade-cyd2-actor_20251026082036.js b/.history/modules/mournblade-cyd2-actor_20251026082036.js
deleted file mode 100644
index 81caa70..0000000
--- a/.history/modules/mournblade-cyd2-actor_20251026082036.js
+++ /dev/null
@@ -1,847 +0,0 @@
-/* -------------------------------------------- */
-import { MournbladeCYD2Utility } from "./mournblade-cyd2-utility.js";
-import { MournbladeCYD2RollDialog } from "./mournblade-cyd2-roll-dialog.js";
-
-/* -------------------------------------------- */
-const __degatsBonus = [-2, -2, -1, -1, 0, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 8, 8, 9, 9, 10, 10]
-const __vitesseBonus = [-2, -2, -1, -1, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8]
-
-/* -------------------------------------------- */
-/**
- * Extend the base Actor entity by defining a custom roll data structure which is ideal for the Simple system.
- * @extends {Actor}
- */
-export class MournbladeCYD2Actor extends Actor {
-
- /* -------------------------------------------- */
- /**
- * Override the create() function to provide additional SoS functionality.
- *
- * This overrided create() function adds initial items
- * Namely: Basic skills, money,
- *
- * @param {Object} data Barebones actor data which this function adds onto.
- * @param {Object} options (Unused) Additional options which customize the creation workflow.
- *
- */
-
- static async create(data, options) {
-
- // Case of compendium global import
- if (data instanceof Array) {
- return super.create(data, options);
- }
- // If the created actor has items (only applicable to duplicated actors) bypass the new actor creation logic
- if (data.items) {
- let actor = super.create(data, options);
- return actor;
- }
-
- if (data.type == 'personnage') {
- const skills = await MournbladeCYD2Utility.loadCompendium("fvtt-mournblade-cyd2.skills")
- data.items = skills.map(i => i.toObject())
- }
- if (data.type == 'creature') {
- const skills = await MournbladeCYD2Utility.loadCompendium("fvtt-mournblade-cyd2.skills-creatures")
- data.items = skills.map(i => i.toObject())
- data.items.push({ name: "Arme naturelle 1", type: 'arme', img: "systems/fvtt-mournblade-cyd2/assets/icons/melee.webp", system: { typearme: "contact", bonusmaniementoff: 0, seuildefense: 0, degats: "0" } })
- data.items.push({ name: "Arme naturelle 2", type: 'arme', img: "systems/fvtt-mournblade-cyd2/assets/icons/melee.webp", system: { typearme: "contact", bonusmaniementoff: 0, seuildefense: 0, degats: "0" } })
- }
-
- return super.create(data, options);
- }
-
- /* -------------------------------------------- */
- getBonusDefenseFromTalents() {
- let talents = this.items.filter(item => item.type == "talent" && item.system.isautomated)
- let bonus = 0
- for (let talent of talents) {
- for (let auto of talent.system.automations) {
- if (auto.eventtype == "bonus-permanent" && auto.bonusname == "bonus-defensif") {
- bonus += Number(auto.bonus || 0)
- }
- }
- }
- return bonus
- }
-
- /* -------------------------------------------- */
- prepareArme(arme) {
- if (this.type == "cellule") {
- return arme
- }
-
- arme = foundry.utils.duplicate(arme)
- let combat = this.getCombatValues()
- if (arme.system.typearme == "contact" || arme.system.typearme == "contactjet") {
- let bonusDefense = this.getBonusDefenseFromTalents()
- arme.system.competence = foundry.utils.duplicate(this.items.find(item => item.type == "competence" && item.name.toLowerCase() == "mêlée"))
- arme.system.attrKey = "pui"
- arme.system.totalDegats = arme.system.degats + "+" + combat.bonusDegatsTotal
- arme.system.totalOffensif = this.system.attributs.pui.value + arme.system.competence.system.niveau + arme.system.bonusmaniementoff + (this.system.combat.monte ? 3 : 0)
- arme.system.totalDefensif = combat.defenseTotal + arme.system.competence.system.niveau + arme.system.seuildefense + bonusDefense + (this.system.combat.monte ? 3 : 0)
- console.log("Arme", arme.system.totalDefensif, combat, arme.system.competence.system.niveau, arme.system.seuildefense, bonusDefense)
- arme.system.isdefense = true
- arme.system.isMelee = true
- arme.system.isDistance = false
- }
- if (arme.system.typearme == "jet" || arme.system.typearme == "tir") {
- arme.system.competence = foundry.utils.duplicate(this.items.find(item => item.type == "competence" && item.name.toLowerCase() == "armes à distance"))
- arme.system.attrKey = "adr"
- arme.system.totalOffensif = this.system.attributs.adr.value + arme.system.competence.system.niveau + arme.system.bonusmaniementoff
- arme.system.totalDegats = arme.system.degats
- arme.system.isMelee = false
- arme.system.isDistance = true
- if (arme.system.isdefense) {
- arme.system.totalDefensif = combat.defenseTotal + arme.system.competence.system.niveau + arme.system.seuildefense
- }
- }
- return arme
- }
-
- /* -------------------------------------------- */
- getItemSorted(types) {
- let items = this.items.filter(item => types.includes(item.type)) || []
- MournbladeCYD2Utility.sortArrayObjectsByName(items)
- return items
- }
- getWeapons() {
- let armes = []
- for (let arme of this.items) {
- if (arme.type == "arme") {
- armes.push(this.prepareArme(arme))
- }
- }
- MournbladeCYD2Utility.sortArrayObjectsByName(armes)
- return armes
- }
- getMonnaies() {
- return this.getItemSorted(["monnaie"])
- }
- getEquipments() {
- return this.getItemSorted(["equipement"])
- }
- getArtefacts() {
- return this.getItemSorted(["artefact"])
- }
- getArmors() {
- return this.getItemSorted(["protection"])
- }
- getHistoriques() {
- return this.getItemSorted(["historique"])
- }
- getProfils() {
- return this.getItemSorted(["profil"])
- }
- getTalents() {
- return this.getItemSorted(["talent"])
- }
- getRessources() {
- return this.getItemSorted(["ressource"])
- }
- getContacts() {
- return this.getItemSorted(["contact"])
- }
- getMutations() {
- return this.getItemSorted(["mutation"])
- }
- getDons() {
- return this.getItemSorted(["don"])
- }
- getPactes() {
- return this.getItemSorted(["pacte"])
- }
- getTendances() {
- return this.getItemSorted(["tendance"])
- }
- getRunes() {
- return this.getItemSorted(["rune"])
- }
- getTraitsChaotiques() {
- return this.getItemSorted(["traitchaotique"])
- }
- getTraitsEspeces() {
- return this.getItemSorted(["traitespece"])
- }
-
- /* -------------------------------------------- */
- getAspect() {
- return (this.system.balance.loi > this.system.balance.chaos) ? this.system.balance.loi : this.system.balance.chaos
- }
- getMarge() {
- return Math.abs(this.system.balance.loi - this.system.balance.chaos)
- }
- getAlignement() {
- return (this.system.balance.loi > this.system.balance.chaos) ? "loyal" : "chaotique"
- }
-
- /* -------------------------------------------- */
- getSkills() {
- let comp = []
- for (let item of this.items) {
- item = foundry.utils.duplicate(item)
- if (item.type == "competence") {
- item.system.attribut1total = item.system.niveau + (this.system.attributs[item.system.attribut1]?.value || 0)
- item.system.attribut2total = item.system.niveau + (this.system.attributs[item.system.attribut2]?.value || 0)
- item.system.attribut3total = item.system.niveau + (this.system.attributs[item.system.attribut3]?.value || 0)
- if (item.system.niveau == 0) {
- item.system.attribut1total -= 3
- item.system.attribut2total -= 3
- item.system.attribut3total -= 3
- }
- item.system.attribut1label = this.system.attributs[item.system.attribut1]?.label || ""
- item.system.attribut2label = this.system.attributs[item.system.attribut2]?.label || ""
- item.system.attribut3label = this.system.attributs[item.system.attribut3]?.label || ""
- comp.push(item)
- }
- }
- MournbladeCYD2Utility.sortArrayObjectsByName(comp)
- return comp
- }
-
- /* ----------------------- --------------------- */
- addMember(actorId) {
- let members = foundry.utils.duplicate(this.system.members)
- members.push({ id: actorId })
- this.update({ 'system.members': members })
- }
- async removeMember(actorId) {
- let members = this.system.members.filter(it => it.id != actorId)
- this.update({ 'system.members': members })
- }
-
- /* -------------------------------------------- */
- getDefenseBase() {
- return Math.max(this.system.attributs.tre.value, this.system.attributs.adr.value)
- }
-
- /* -------------------------------------------- */
- getVitesseBase() {
- return 5 + __vitesseBonus[this.system.attributs.adr.value]
- }
- /* -------------------------------------------- */
- getProtection() {
- let equipProtection = 0
- for (let armor of this.items) {
- if (armor.type == "protection" && armor.system.equipped) {
- equipProtection += Number(armor.system.protection)
- }
- }
- if (equipProtection < 4) {
- return 4 + equipProtection // Cas des boucliers + sans armure
- }
- return equipProtection // Uniquement la protection des armures + boucliers
- }
-
- /* -------------------------------------------- */
- getCombatValues() {
- if (this.type == "cellule") {
- return {
- initBase: 0,
- initTotal: 0,
- bonusDegats: 0,
- bonusDegatsTotal: 0,
- vitesseBase: 0,
- vitesseTotal: 0,
- defenseBase: 0,
- protection: 0,
- defenseTotal: 0
- }
- }
-
- let combat = {
- initBase: this.system.attributs.adr.value,
- initTotal: this.system.attributs.adr.value + this.system.combat.initbonus,
- bonusDegats: this.getBonusDegats(),
- bonusDegatsTotal: this.getBonusDegats() + this.system.combat.bonusdegats,
- vitesseBase: this.getVitesseBase(),
- vitesseTotal: this.getVitesseBase() + this.system.combat.vitessebonus,
- defenseBase: this.getDefenseBase(),
- protection: this.getProtection(),
- defenseTotal: this.getDefenseBase() + this.system.combat.defensebonus + this.getProtection() - this.getTotalAdversite() + (this.system.combat.defensetotale ? 3 : 0)
- }
- return combat
- }
-
- /* -------------------------------------------- */
- prepareBaseData() {
- }
-
- /* -------------------------------------------- */
- async prepareData() {
- super.prepareData();
- }
-
- /* -------------------------------------------- */
- prepareDerivedData() {
-
- if (this.type == 'personnage') {
- let talentBonus = this.getVigueurBonus()
- let vigueur = Math.floor((this.system.attributs.pui.value + this.system.attributs.tre.value) / 2) + talentBonus + this.system.sante.vigueurmodifier
- if (vigueur != this.system.sante.vigueur) {
- this.update({ 'system.sante.vigueur': vigueur })
- }
-
- let seuilPouvoirBonus = this.getSeuilPouvoirBonus()
- let seuilPouvoir = Math.floor((this.system.attributs.tre.value + this.system.attributs.cla.value) / 2) + seuilPouvoirBonus + this.system.ame.seuilpouvoirmodifier
- if (seuilPouvoir != this.system.ame.seuilpouvoir) {
- this.update({ 'system.ame.seuilpouvoir': seuilPouvoir })
- }
- }
- super.prepareDerivedData()
- }
-
- /* -------------------------------------------- */
- _preUpdate(changed, options, user) {
- if (changed?.system?.sante?.etat && changed?.system?.sante?.etat != this.system.sante.etat) {
- setTimeout(() => {
- this.processCombativite(changed.system.sante)
- }, 800)
- }
- super._preUpdate(changed, options, user);
- }
-
- /* -------------------------------------------- */
- _onUpdate(data, options, user) {
- super._onUpdate(data, options, user);
- }
- /* -------------------------------------------- */
- getItemById(id) {
- let item = this.items.find(item => item.id == id);
- if (item) {
- item = foundry.utils.duplicate(item)
- }
- return item;
- }
-
- /* -------------------------------------------- */
- async equipItem(itemId) {
- let item = this.items.find(item => item.id == itemId)
- if (item && item.system) {
- let update = { _id: item.id, "system.equipped": !item.system.equipped }
- await this.updateEmbeddedDocuments('Item', [update]); // Updates one EmbeddedEntity
- }
- }
-
- /* -------------------------------------------- */
- editItemField(itemId, itemType, itemField, dataType, value) {
- let item = this.items.find(item => item.id == itemId)
- if (item) {
- console.log("Item ", item, itemField, dataType, value)
- if (dataType.toLowerCase() == "number") {
- value = Number(value)
- } else {
- value = String(value)
- }
- let update = { _id: item.id, [`system.${itemField}`]: value };
- this.updateEmbeddedDocuments("Item", [update])
- }
- }
-
- /* -------------------------------------------- */
- checkAttribut(attribut, minLevel) {
- let attr = this.system.attributs.find(at => at.labelnorm == attribut.toLowerCase())
- if (attr && attr.value >= minLevel) {
- return { isValid: true, attr: foundry.utils.duplicate(attr) }
- }
- return { isValid: false }
- }
- /* -------------------------------------------- */
- checkAttributOrCompetenceLevel(compName, minLevel) {
- let comp = this.items.find(i => i.type == "competence" && i.name.toLowerCase() == compName.toLowerCase() && i.system.niveau >= minLevel)
- if (comp) {
- return { isValid: true, item: foundry.utils.duplicate(comp) }
- } else {
- for (let attrKey in this.system.attributs) {
- if (this.system.attributs[attrKey].label.toLowerCase() == compName.toLowerCase() && this.system.attributs[attrKey].value >= minLevel) {
- return { isValid: true, item: foundry.utils.duplicate(this.system.attributs[attrKey]) }
- }
- }
- }
- return { isValid: false, warningMessage: `Prérequis insuffisant : la compétence/attribut ${compName} doit être de niveau ${minLevel} au minimum` }
- }
- /* -------------------------------------------- */
- addCompetenceBonus(compName, bonus, baCost) {
- let comp = this.items.find(i => i.type == "competence" && i.name.toLowerCase() == compName.toLowerCase())
- if (comp) {
- comp = foundry.utils.duplicate(comp)
- comp.system.bonus = bonus
- comp.system.baCost = baCost
- return { isValid: true, item: comp }
- }
- return { isValid: false, warningMessage: `Compétence ${compName} non trouvée` }
- }
- /* -------------------------------------------- */
- checkIfCompetence(compName) {
- let comp = this.items.find(i => i.type == "competence" && i.name.toLowerCase() == compName.toLowerCase())
- if (comp) {
- return { isValid: true, item: comp }
- }
- return { isValid: false }
- }
- /* -------------------------------------------- */
- getVigueur() {
- return this.system.sante.vigueur
- }
-
- /* -------------------------------------------- */
- getVigueurBonus() {
- let talents = this.items.filter(item => item.type == "talent" && item.system.isautomated)
- let bonus = 0
- for (let talent of talents) {
- for (let auto of talent.system.automations) {
- if (auto.eventtype == "bonus-permanent" && auto.bonusname == "vigueur") {
- bonus += Number(auto.bonus || 0)
- }
- }
- }
- return bonus
- }
-
- /* -------------------------------------------- */
- getSeuilPouvoir() {
- return this.system.ame.seuilpouvoir
- }
-
- /* -------------------------------------------- */
- getSeuilPouvoirBonus() {
- let talents = this.items.filter(item => item.type == "talent" && item.system.isautomated)
- let bonus = 0
- for (let talent of talents) {
- for (let auto of talent.system.automations) {
- if (auto.eventtype == "bonus-permanent" && auto.bonusname == "seuilpouvoir") {
- bonus += Number(auto.bonus || 0)
- }
- }
- }
- return bonus
- }
-
- /* -------------------------------------------- */
- getBonneAventure() {
- return this.system.bonneaventure.actuelle
- }
- /* -------------------------------------------- */
- checkBonneAventure(cost) {
- return (this.system.bonneaventure.actuelle >= cost)
- }
- /* -------------------------------------------- */
- changeBonneAventure(value) {
- let newBA = this.system.bonneaventure.actuelle
- newBA += value
- this.update({ 'system.bonneaventure.actuelle': newBA })
- }
-
- /* -------------------------------------------- */
- getEclat() {
- return this.system.eclat.value
- }
-
- /* -------------------------------------------- */
- changeEclat(value) {
- let newE = this.system.eclat.value
- newE += value
- this.update({ 'system.eclat.value': newE })
- }
-
- /* -------------------------------------------- */
- compareName(a, b) {
- if (a.name < b.name) {
- return -1;
- }
- if (a.name > b.name) {
- return 1;
- }
- return 0;
- }
-
- /* -------------------------------------------- */
- getAttribute(attrKey) {
- return this.system.attributes[attrKey]
- }
-
- /* -------------------------------------------- */
- getBonusDegats() {
- return 0;
- }
-
- /* -------------------------------------------- */
- changeEtatCombativite(value) {
- if (value === "vaincu") {
- value = 200
- }
- let sante = foundry.utils.duplicate(this.system.sante)
- sante.etat += Number(value)
- sante.etat = Math.max(sante.etat, 0)
- sante.etat = Math.min(sante.etat, this.system.sante.nbcombativite)
- this.update({ 'system.sante': sante })
- if (sante.etat == this.system.sante.nbcombativite) {
- ChatMessage.create({ content: `${this.name} est vaincu !` })
- }
- // Duplicated ! this.processCombativite(sante)
- }
-
- /* -------------------------------------------- */
- processCombativite(sante) {
- sante = sante || foundry.utils.duplicate(this.system.sante)
- // Gestion des états affaibli et très affaibli
- if (sante.etat == this.system.sante.nbcombativite - 2 || sante.etat == this.system.sante.nbcombativite - 1) {
- if (sante.etat == this.system.sante.nbcombativite - 2 && this.items.find(item => item.type == "talent" && item.name.toLowerCase() == "encaissement")) {
- ChatMessage.create({ content: `${this.name} ne subit pas les 2 adversités rouge grâce à Encaissement. Pensez à les ajouter à la fin de la scène !` })
- } else if (sante.etat == this.system.sante.nbcombativite - 1 && this.items.find(item => item.type == "talent" && item.name.toLowerCase().includes("vaillant"))) {
- ChatMessage.create({ content: `${this.name} ne subit pas les 2 adversités rouge grâce à Vaillant. Pensez à les ajouter à la fin de la scène !` })
- } else {
- ChatMessage.create({ content: `${this.name} subit 2 adversités rouge !` })
- this.incDecAdversite("rouge", 2)
- }
- }
- }
-
- /* -------------------------------------------- */
- async equipGear(equipmentId) {
- let item = this.items.find(item => item.id == equipmentId);
- if (item?.system?.data) {
- let update = { _id: item.id, "system.equipped": !item.system.equipped };
- await this.updateEmbeddedDocuments('Item', [update]); // Updates one EmbeddedEntity
- }
- }
-
- /* -------------------------------------------- */
- getSubActors() {
- let subActors = [];
- for (let id of this.system.subactors) {
- subActors.push(foundry.utils.duplicate(game.actors.get(id)));
- }
- return subActors;
- }
- /* -------------------------------------------- */
- async addSubActor(subActorId) {
- let subActors = foundry.utils.duplicate(this.system.subactors);
- subActors.push(subActorId);
- await this.update({ 'system.subactors': subActors });
- }
- /* -------------------------------------------- */
- async delSubActor(subActorId) {
- let newArray = [];
- for (let id of this.system.subactors) {
- if (id != subActorId) {
- newArray.push(id);
- }
- }
- await this.update({ 'system.subactors': newArray });
- }
-
- /* -------------------------------------------- */
- getTotalAdversite() {
- return this.system.adversite.bleue + this.system.adversite.rouge + this.system.adversite.noire
- }
-
- /* -------------------------------------------- */
- async incDecAdversite(adv, incDec = 0) {
- let adversite = foundry.utils.duplicate(this.system.adversite)
- adversite[adv] += Number(incDec)
- adversite[adv] = Math.max(adversite[adv], 0)
- adversite[adv] = Math.min(adversite[adv], 20)
- this.update({ 'system.adversite': adversite })
- }
- /* -------------------------------------------- */
- async incDecQuantity(objetId, incDec = 0) {
- let objetQ = this.items.get(objetId)
- if (objetQ) {
- let newQ = objetQ.system.quantite + incDec
- newQ = Math.max(newQ, 0)
- await this.updateEmbeddedDocuments('Item', [{ _id: objetQ.id, 'system.quantite': newQ }]); // pdates one EmbeddedEntity
- }
- }
-
- /* -------------------------------------------- */
- computeRichesse() {
- let valueSC = 0
- for (let monnaie of this.items) {
- if (monnaie.type == "monnaie") {
- valueSC += Number(monnaie.system.prixsc) * Number(monnaie.system.quantite)
- }
- }
- return MournbladeCYD2Utility.computeMonnaieDetails(valueSC)
- }
-
- /* -------------------------------------------- */
- computeValeurEquipement() {
- let valueSC = 0
- for (let equip of this.items) {
- if (equip.type == "equipement" || equip.type == "arme" || equip.type == "protection") {
- valueSC += Number(equip.system.prixsc) * Number(equip.system.quantite ?? 1)
- valueSC += (Number(equip.system.prixca) * Number(equip.system.quantite ?? 1)) * 20
- valueSC += (Number(equip.system.prixpo) * Number(equip.system.quantite ?? 1)) * 400
- }
- }
- return MournbladeCYD2Utility.computeMonnaieDetails(valueSC)
- }
-
- /* -------------------------------------------- */
- getCompetence(compId) {
- return this.items.get(compId)
- }
-
- /* -------------------------------------------- */
- async setPredilectionUsed(compId, predIdx) {
- let comp = this.items.get(compId)
- let pred = foundry.utils.duplicate(comp.system.predilections)
- pred[predIdx].used = true
- await this.updateEmbeddedDocuments('Item', [{ _id: compId, 'system.predilections': pred }])
- }
-
- /* -------------------------------------------- */
- getInitiativeScore() {
- let init = this.getFlag("world", "last-initiative")
- return init || -1
- }
-
- /* -------------------------------------------- */
- getBestAttackValue() {
- let attackList = this.items.filter(item => (item.type == "arme" || item.type == "talent") && item.system.equipped)
- let maxOff = 0
- let bestArme
- for (let arme of attackList) {
- if (arme.type == "arme") {
- arme = this.prepareArme(arme)
- }
- if (arme.system.totalOffensif > maxOff) {
- maxOff = arme.system.totalOffensif
- bestArme = foundry.utils.duplicate(arme)
- }
- }
- return bestArme
- }
-
- /* -------------------------------------------- */
- getBestDefenseValue() {
- let defenseList = this.items.filter(item => (item.type == "arme") && item.system.equipped)
- let maxDef = 0
- let bestArme
- for (let arme of defenseList) {
- if (arme.type == "arme") {
- arme = this.prepareArme(arme)
- }
- if (arme.system.totalDefensif > maxDef) {
- maxDef = arme.system.totalDefensif
- bestArme = foundry.utils.duplicate(arme)
- }
- }
- return bestArme
- }
-
- /* -------------------------------------------- */
- searchRelevantTalents(competence) {
- let talents = []
-
- for (let talent of this.items) {
- if (talent.type == "talent" && talent.system.isautomated && talent.system.automations.length > 0) {
- for (let auto of talent.system.automations) {
- if (auto.eventtype === "prepare-roll") {
- if (auto.competence.toLowerCase() == competence.name.toLowerCase()) {
- talent = foundry.utils.duplicate(talent)
- talent.system.bonus = auto.bonus
- talent.system.baCost = auto.baCost
- talents.push(talent)
- }
- }
- }
- }
- }
- return talents
- }
-
- /* -------------------------------------------- */
- buildListeAdversites() {
- return []
- }
-
- /* -------------------------------------------- */
- getCommonRollData(attrKey = undefined, compId = undefined, compName = undefined) {
- let rollData = MournbladeCYD2Utility.getBasicRollData()
- rollData.alias = this.name
- rollData.actorImg = this.img
- rollData.actorId = this.id
- rollData.tokenId = this.token?.id
- rollData.img = this.img
- rollData.attributs = MournbladeCYD2Utility.getAttributs()
- rollData.maitriseId = "none"
- rollData.nbEclat = this.system.eclat.value
- rollData.nbBA = this.system.bonneaventure.actuelle
- rollData.nbAdversites = this.getTotalAdversite()
- rollData.talents = []
- rollData.attrKey2 = "none"
- rollData.coupDevastateur = this.items.find(it => it.type == "talent" && it.name.toLowerCase() == "coup dévastateur" && !it.system.used)
- rollData.hasAmbidextre = this.items.find(it => it.type == "talent" && it.name.toLowerCase() == "ambidextre")
- rollData.hasFeinte = this.system.bonneaventure.actuelle > 0 && this.items.find(it => it.type == "talent" && it.name.toLowerCase() == "feinte")
- rollData.isMonte = this.system.combat.monte
- rollData.config = game.system.mournbladecyd2.config
-
- if (attrKey) {
- rollData.attrKey = attrKey
- if (attrKey != "tochoose") {
- rollData.actionImg = "systems/fvtt-mournblade-cyd2/assets/icons/" + this.system.attributs[attrKey].labelnorm + ".webp"
- rollData.attr = foundry.utils.duplicate(this.system.attributs[attrKey])
- }
- }
- if (compId) {
- rollData.competence = foundry.utils.duplicate(this.items.get(compId) || {})
- let maitrises = [{ key: "none", label: "Aucune" }]
- rollData.competence.system.predilections.forEach(function (item) {
- if (item.maitrise) {
- maitrises.push({ key: item.id, label: item.name });
- }
- })
- rollData.maitrises = maitrises // rollData.competence.system.predilections.filter(p => p.maitrise)
- rollData.actionImg = rollData.competence?.img
- rollData.talents = this.searchRelevantTalents(rollData.competence)
- }
- if (compName) {
- rollData.competence = foundry.utils.duplicate(this.items.find(item => item.name.toLowerCase() == compName.toLowerCase()) || {})
- rollData.actionImg = rollData.competence?.img
- }
- return rollData
- }
-
- /* -------------------------------------------- */
- async rollAttribut(attrKey, isInit = false) {
- let rollData = this.getCommonRollData(attrKey)
- rollData.multiplier = (isInit) ? 1 : 2
- rollData.isInit = isInit
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
-
- /* -------------------------------------------- */
- async rollCompetence(attrKey, compId) {
- let rollData = this.getCommonRollData(attrKey, compId)
- rollData.multiplier = 1 // Attr multiplier, always 1 in competence mode
- console.log("RollDatra", rollData)
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
-
- /* -------------------------------------------- */
- async rollArmeOffensif(armeId) {
- let arme = this.items.get(armeId)
- if (arme.type == "arme") {
- arme = this.prepareArme(arme)
- }
- let rollData = this.getCommonRollData(arme.system.attrKey, arme.system.competence._id)
- rollData.arme = arme
- MournbladeCYD2Utility.updateWithTarget(rollData)
- console.log("ARME!", rollData)
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
- /* -------------------------------------------- */
- async rollAssommer() {
- let rollData = this.getCommonRollData("pui", undefined, "Filouterie")
- rollData.assomer = true
- rollData.conditionsCommunes = true
- MournbladeCYD2Utility.updateWithTarget(rollData)
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
- /* -------------------------------------------- */
- async rollCoupBas() {
- let rollData = this.getCommonRollData("pui", undefined, "Mêlée")
- rollData.coupBas = true
- rollData.conditionsCommunes = true
- MournbladeCYD2Utility.updateWithTarget(rollData)
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
- /* -------------------------------------------- */
- async rollImmobiliser() {
- let rollData = this.getCommonRollData("pui", undefined, "Mêlée")
- rollData.immobiliser = true
- rollData.conditionsCommunes = true
- rollData.cibleconsciente = true
- MournbladeCYD2Utility.updateWithTarget(rollData)
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
- /* -------------------------------------------- */
- async rollRepousser() {
- let rollData = this.getCommonRollData("pui", undefined, "Mêlée")
- rollData.repousser = true
- rollData.conditionsCommunes = true
- rollData.cibleconsciente = true
- MournbladeCYD2Utility.updateWithTarget(rollData)
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
- /* -------------------------------------------- */
- async rollDesengager() {
- let rollData = this.getCommonRollData("adr", undefined, "Mouvements")
- rollData.desengager = true
- rollData.conditionsCommunes = true
- MournbladeCYD2Utility.updateWithTarget(rollData)
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
-
- /* -------------------------------------------- */
- async rollArmeDegats(armeId, targetVigueur = undefined, rollDataInput = undefined) {
- let arme = this.items.get(armeId)
- if (arme.type == "arme") {
- arme = this.prepareArme(arme)
- }
- console.log("DEGATS", arme, targetVigueur, rollDataInput)
- let roll
- let bonus = 0
- let bonus2 = 0
-
- if (rollDataInput?.applyCoupDevastateur) {
- bonus2 = Math.floor(this.system.attributs.pui.value / 2)
- let talent = this.items.find(item => item.type == "talent" && item.name.toLowerCase() == "coup dévastateur")
- this.updateEmbeddedDocuments('Item', [{ _id: talent.id, 'system.used': true }])
- }
-
- if (rollDataInput?.isHeroique) {
- if (rollDataInput?.attaqueCharge) {
- bonus = 5
- }
- if (rollDataInput?.chargeCavalerie) {
- bonus = 6
- }
- roll = await new Roll("2d10rr10+" + arme.system.totalDegats + "+" + bonus + "+" + bonus2).roll()
- } else {
- if (rollDataInput?.attaqueCharge) {
- bonus = 3
- }
- if (rollDataInput?.chargeCavalerie) {
- bonus = 4
- }
- roll = await new Roll("1d10+" + arme.system.totalDegats + "+" + bonus + "+" + bonus2).roll()
- }
- await MournbladeCYD2Utility.showDiceSoNice(roll, game.settings.get("core", "rollMode"));
- let nbEtatPerdus = 0
- if (targetVigueur) {
- nbEtatPerdus = Math.floor(roll.total / targetVigueur)
- }
- //console.log(roll)
- let rollData = {
- arme: arme,
- finalResult: roll.total,
- formula: roll.formula,
- alias: this.name,
- actorImg: this.img,
- actorId: this.id,
- defenderTokenId: rollDataInput?.defenderTokenId,
- actionImg: arme.img,
- targetVigueur: targetVigueur,
- nbEtatPerdus: nbEtatPerdus
- }
- MournbladeCYD2Utility.createChatWithRollMode(rollData.alias, {
- content: await renderTemplate(`systems/fvtt-mournblade-cyd2/templates/chat-degats-result.html`, rollData)
- })
-
- if (rollDataInput?.defenderTokenId && nbEtatPerdus) {
- MournbladeCYD2Utility.applyCombativite(rollDataInput, nbEtatPerdus)
- }
-
- }
-}
diff --git a/.history/modules/mournblade-cyd2-actor_20251026082126.js b/.history/modules/mournblade-cyd2-actor_20251026082126.js
deleted file mode 100644
index b07a59e..0000000
--- a/.history/modules/mournblade-cyd2-actor_20251026082126.js
+++ /dev/null
@@ -1,852 +0,0 @@
-/* -------------------------------------------- */
-import { MournbladeCYD2Utility } from "./mournblade-cyd2-utility.js";
-import { MournbladeCYD2RollDialog } from "./mournblade-cyd2-roll-dialog.js";
-
-/* -------------------------------------------- */
-const __degatsBonus = [-2, -2, -1, -1, 0, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 8, 8, 9, 9, 10, 10]
-const __vitesseBonus = [-2, -2, -1, -1, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8]
-
-/* -------------------------------------------- */
-/**
- * Extend the base Actor entity by defining a custom roll data structure which is ideal for the Simple system.
- * @extends {Actor}
- */
-export class MournbladeCYD2Actor extends Actor {
-
- /* -------------------------------------------- */
- /**
- * Override the create() function to provide additional SoS functionality.
- *
- * This overrided create() function adds initial items
- * Namely: Basic skills, money,
- *
- * @param {Object} data Barebones actor data which this function adds onto.
- * @param {Object} options (Unused) Additional options which customize the creation workflow.
- *
- */
-
- static async create(data, options) {
-
- // Case of compendium global import
- if (data instanceof Array) {
- return super.create(data, options);
- }
- // If the created actor has items (only applicable to duplicated actors) bypass the new actor creation logic
- if (data.items) {
- let actor = super.create(data, options);
- return actor;
- }
-
- if (data.type == 'personnage') {
- const skills = await MournbladeCYD2Utility.loadCompendium("fvtt-mournblade-cyd2.skills")
- data.items = skills.map(i => i.toObject())
- }
- if (data.type == 'creature') {
- const skills = await MournbladeCYD2Utility.loadCompendium("fvtt-mournblade-cyd2.skills-creatures")
- data.items = skills.map(i => i.toObject())
- data.items.push({ name: "Arme naturelle 1", type: 'arme', img: "systems/fvtt-mournblade-cyd2/assets/icons/melee.webp", system: { typearme: "contact", bonusmaniementoff: 0, seuildefense: 0, degats: "0" } })
- data.items.push({ name: "Arme naturelle 2", type: 'arme', img: "systems/fvtt-mournblade-cyd2/assets/icons/melee.webp", system: { typearme: "contact", bonusmaniementoff: 0, seuildefense: 0, degats: "0" } })
- }
-
- return super.create(data, options);
- }
-
- /* -------------------------------------------- */
- getBonusDefenseFromTalents() {
- let talents = this.items.filter(item => item.type == "talent" && item.system.isautomated)
- let bonus = 0
- for (let talent of talents) {
- for (let auto of talent.system.automations) {
- if (auto.eventtype == "bonus-permanent" && auto.bonusname == "bonus-defensif") {
- bonus += Number(auto.bonus || 0)
- }
- }
- }
- return bonus
- }
-
- /* -------------------------------------------- */
- prepareArme(arme) {
- if (this.type == "cellule") {
- return arme
- }
-
- arme = foundry.utils.duplicate(arme)
- let combat = this.getCombatValues()
- if (arme.system.typearme == "contact" || arme.system.typearme == "contactjet") {
- let bonusDefense = this.getBonusDefenseFromTalents()
- arme.system.competence = foundry.utils.duplicate(this.items.find(item => item.type == "competence" && item.name.toLowerCase() == "mêlée"))
- arme.system.attrKey = "pui"
- arme.system.totalDegats = arme.system.degats + "+" + combat.bonusDegatsTotal
- arme.system.totalOffensif = this.system.attributs.pui.value + arme.system.competence.system.niveau + arme.system.bonusmaniementoff + (this.system.combat.monte ? 3 : 0)
- arme.system.totalDefensif = combat.defenseTotal + arme.system.competence.system.niveau + arme.system.seuildefense + bonusDefense + (this.system.combat.monte ? 3 : 0)
- console.log("Arme", arme.system.totalDefensif, combat, arme.system.competence.system.niveau, arme.system.seuildefense, bonusDefense)
- arme.system.isdefense = true
- arme.system.isMelee = true
- arme.system.isDistance = false
- }
- if (arme.system.typearme == "jet" || arme.system.typearme == "tir") {
- arme.system.competence = foundry.utils.duplicate(this.items.find(item => item.type == "competence" && item.name.toLowerCase() == "armes à distance"))
- arme.system.attrKey = "adr"
- arme.system.totalOffensif = this.system.attributs.adr.value + arme.system.competence.system.niveau + arme.system.bonusmaniementoff
- arme.system.totalDegats = arme.system.degats
- arme.system.isMelee = false
- arme.system.isDistance = true
- if (arme.system.isdefense) {
- arme.system.totalDefensif = combat.defenseTotal + arme.system.competence.system.niveau + arme.system.seuildefense
- }
- }
- return arme
- }
-
- /* -------------------------------------------- */
- getItemSorted(types) {
- let items = this.items.filter(item => types.includes(item.type)) || []
- MournbladeCYD2Utility.sortArrayObjectsByName(items)
- return items
- }
- getWeapons() {
- let armes = []
- for (let arme of this.items) {
- if (arme.type == "arme") {
- armes.push(this.prepareArme(arme))
- }
- }
- MournbladeCYD2Utility.sortArrayObjectsByName(armes)
- return armes
- }
- getMonnaies() {
- return this.getItemSorted(["monnaie"])
- }
- getEquipments() {
- return this.getItemSorted(["equipement"])
- }
- getArtefacts() {
- return this.getItemSorted(["artefact"])
- }
- getArmors() {
- return this.getItemSorted(["protection"])
- }
- getHistoriques() {
- return this.getItemSorted(["historique"])
- }
- getProfils() {
- return this.getItemSorted(["profil"])
- }
- getTalents() {
- return this.getItemSorted(["talent"])
- }
- getRessources() {
- return this.getItemSorted(["ressource"])
- }
- getContacts() {
- return this.getItemSorted(["contact"])
- }
- getMutations() {
- return this.getItemSorted(["mutation"])
- }
- getDons() {
- return this.getItemSorted(["don"])
- }
- getPactes() {
- return this.getItemSorted(["pacte"])
- }
- getTendances() {
- return this.getItemSorted(["tendance"])
- }
- getRunes() {
- return this.getItemSorted(["rune"])
- }
- getTraitsChaotiques() {
- return this.getItemSorted(["traitchaotique"])
- }
- getTraitsEspeces() {
- return this.getItemSorted(["traitespece"])
- }
-
- /* -------------------------------------------- */
- getAspect() {
- return (this.system.balance.loi > this.system.balance.chaos) ? this.system.balance.loi : this.system.balance.chaos
- }
- getMarge() {
- return Math.abs(this.system.balance.loi - this.system.balance.chaos)
- }
- getAlignement() {
- return (this.system.balance.loi > this.system.balance.chaos) ? "loyal" : "chaotique"
- }
-
- /* -------------------------------------------- */
- getSkills() {
- let comp = []
- for (let item of this.items) {
- item = foundry.utils.duplicate(item)
- if (item.type == "competence") {
- item.system.attribut1total = item.system.niveau + (this.system.attributs[item.system.attribut1]?.value || 0)
- item.system.attribut2total = item.system.niveau + (this.system.attributs[item.system.attribut2]?.value || 0)
- item.system.attribut3total = item.system.niveau + (this.system.attributs[item.system.attribut3]?.value || 0)
- if (item.system.niveau == 0) {
- item.system.attribut1total -= 3
- item.system.attribut2total -= 3
- item.system.attribut3total -= 3
- }
- item.system.attribut1label = this.system.attributs[item.system.attribut1]?.label || ""
- item.system.attribut2label = this.system.attributs[item.system.attribut2]?.label || ""
- item.system.attribut3label = this.system.attributs[item.system.attribut3]?.label || ""
- comp.push(item)
- }
- }
- MournbladeCYD2Utility.sortArrayObjectsByName(comp)
- return comp
- }
-
- /* ----------------------- --------------------- */
- addMember(actorId) {
- let members = foundry.utils.duplicate(this.system.members)
- members.push({ id: actorId })
- this.update({ 'system.members': members })
- }
- async removeMember(actorId) {
- let members = this.system.members.filter(it => it.id != actorId)
- this.update({ 'system.members': members })
- }
-
- /* -------------------------------------------- */
- getDefenseBase() {
- return Math.max(this.system.attributs.tre.value, this.system.attributs.adr.value)
- }
-
- /* -------------------------------------------- */
- getVitesseBase() {
- return 5 + __vitesseBonus[this.system.attributs.adr.value]
- }
- /* -------------------------------------------- */
- getProtection() {
- let equipProtection = 0
- for (let armor of this.items) {
- if (armor.type == "protection" && armor.system.equipped) {
- equipProtection += Number(armor.system.protection)
- }
- }
- if (equipProtection < 4) {
- return 4 + equipProtection // Cas des boucliers + sans armure
- }
- return equipProtection // Uniquement la protection des armures + boucliers
- }
-
- /* -------------------------------------------- */
- getCombatValues() {
- if (this.type == "cellule") {
- return {
- initBase: 0,
- initTotal: 0,
- bonusDegats: 0,
- bonusDegatsTotal: 0,
- vitesseBase: 0,
- vitesseTotal: 0,
- defenseBase: 0,
- protection: 0,
- defenseTotal: 0
- }
- }
-
- let combat = {
- initBase: this.system.attributs.adr.value,
- initTotal: this.system.attributs.adr.value + this.system.combat.initbonus,
- bonusDegats: this.getBonusDegats(),
- bonusDegatsTotal: this.getBonusDegats() + this.system.combat.bonusdegats,
- vitesseBase: this.getVitesseBase(),
- vitesseTotal: this.getVitesseBase() + this.system.combat.vitessebonus,
- defenseBase: this.getDefenseBase(),
- protection: this.getProtection(),
- defenseTotal: this.getDefenseBase() + this.system.combat.defensebonus + this.getProtection() - this.getTotalAdversite() + (this.system.combat.defensetotale ? 3 : 0)
- }
- return combat
- }
-
- /* -------------------------------------------- */
- prepareBaseData() {
- }
-
- /* -------------------------------------------- */
- async prepareData() {
- super.prepareData();
- }
-
- /* -------------------------------------------- */
- prepareDerivedData() {
-
- if (this.type == 'personnage') {
- let talentBonus = this.getVigueurBonus()
- let vigueur = Math.floor((this.system.attributs.pui.value + this.system.attributs.tre.value) / 2) + talentBonus + this.system.sante.vigueurmodifier
- if (vigueur != this.system.sante.vigueur) {
- this.update({ 'system.sante.vigueur': vigueur })
- }
-
- let seuilPouvoirBonus = this.getSeuilPouvoirBonus()
- let seuilPouvoir = Math.floor((this.system.attributs.tre.value + this.system.attributs.cla.value) / 2) + seuilPouvoirBonus + this.system.ame.seuilpouvoirmodifier
- if (seuilPouvoir != this.system.ame.seuilpouvoir) {
- this.update({ 'system.ame.seuilpouvoir': seuilPouvoir })
- }
- }
- super.prepareDerivedData()
- }
-
- /* -------------------------------------------- */
- _preUpdate(changed, options, user) {
- if (changed?.system?.sante?.etat && changed?.system?.sante?.etat != this.system.sante.etat) {
- setTimeout(() => {
- this.processCombativite(changed.system.sante)
- }, 800)
- }
- if (changed?.system?.ame?.etat && changed?.system?.ame?.etat != this.system.ame.etat) {
- setTimeout(() => {
- this.processAme(changed.system.ame)
- }, 800)
- }
- super._preUpdate(changed, options, user);
- }
-
- /* -------------------------------------------- */
- _onUpdate(data, options, user) {
- super._onUpdate(data, options, user);
- }
- /* -------------------------------------------- */
- getItemById(id) {
- let item = this.items.find(item => item.id == id);
- if (item) {
- item = foundry.utils.duplicate(item)
- }
- return item;
- }
-
- /* -------------------------------------------- */
- async equipItem(itemId) {
- let item = this.items.find(item => item.id == itemId)
- if (item && item.system) {
- let update = { _id: item.id, "system.equipped": !item.system.equipped }
- await this.updateEmbeddedDocuments('Item', [update]); // Updates one EmbeddedEntity
- }
- }
-
- /* -------------------------------------------- */
- editItemField(itemId, itemType, itemField, dataType, value) {
- let item = this.items.find(item => item.id == itemId)
- if (item) {
- console.log("Item ", item, itemField, dataType, value)
- if (dataType.toLowerCase() == "number") {
- value = Number(value)
- } else {
- value = String(value)
- }
- let update = { _id: item.id, [`system.${itemField}`]: value };
- this.updateEmbeddedDocuments("Item", [update])
- }
- }
-
- /* -------------------------------------------- */
- checkAttribut(attribut, minLevel) {
- let attr = this.system.attributs.find(at => at.labelnorm == attribut.toLowerCase())
- if (attr && attr.value >= minLevel) {
- return { isValid: true, attr: foundry.utils.duplicate(attr) }
- }
- return { isValid: false }
- }
- /* -------------------------------------------- */
- checkAttributOrCompetenceLevel(compName, minLevel) {
- let comp = this.items.find(i => i.type == "competence" && i.name.toLowerCase() == compName.toLowerCase() && i.system.niveau >= minLevel)
- if (comp) {
- return { isValid: true, item: foundry.utils.duplicate(comp) }
- } else {
- for (let attrKey in this.system.attributs) {
- if (this.system.attributs[attrKey].label.toLowerCase() == compName.toLowerCase() && this.system.attributs[attrKey].value >= minLevel) {
- return { isValid: true, item: foundry.utils.duplicate(this.system.attributs[attrKey]) }
- }
- }
- }
- return { isValid: false, warningMessage: `Prérequis insuffisant : la compétence/attribut ${compName} doit être de niveau ${minLevel} au minimum` }
- }
- /* -------------------------------------------- */
- addCompetenceBonus(compName, bonus, baCost) {
- let comp = this.items.find(i => i.type == "competence" && i.name.toLowerCase() == compName.toLowerCase())
- if (comp) {
- comp = foundry.utils.duplicate(comp)
- comp.system.bonus = bonus
- comp.system.baCost = baCost
- return { isValid: true, item: comp }
- }
- return { isValid: false, warningMessage: `Compétence ${compName} non trouvée` }
- }
- /* -------------------------------------------- */
- checkIfCompetence(compName) {
- let comp = this.items.find(i => i.type == "competence" && i.name.toLowerCase() == compName.toLowerCase())
- if (comp) {
- return { isValid: true, item: comp }
- }
- return { isValid: false }
- }
- /* -------------------------------------------- */
- getVigueur() {
- return this.system.sante.vigueur
- }
-
- /* -------------------------------------------- */
- getVigueurBonus() {
- let talents = this.items.filter(item => item.type == "talent" && item.system.isautomated)
- let bonus = 0
- for (let talent of talents) {
- for (let auto of talent.system.automations) {
- if (auto.eventtype == "bonus-permanent" && auto.bonusname == "vigueur") {
- bonus += Number(auto.bonus || 0)
- }
- }
- }
- return bonus
- }
-
- /* -------------------------------------------- */
- getSeuilPouvoir() {
- return this.system.ame.seuilpouvoir
- }
-
- /* -------------------------------------------- */
- getSeuilPouvoirBonus() {
- let talents = this.items.filter(item => item.type == "talent" && item.system.isautomated)
- let bonus = 0
- for (let talent of talents) {
- for (let auto of talent.system.automations) {
- if (auto.eventtype == "bonus-permanent" && auto.bonusname == "seuilpouvoir") {
- bonus += Number(auto.bonus || 0)
- }
- }
- }
- return bonus
- }
-
- /* -------------------------------------------- */
- getBonneAventure() {
- return this.system.bonneaventure.actuelle
- }
- /* -------------------------------------------- */
- checkBonneAventure(cost) {
- return (this.system.bonneaventure.actuelle >= cost)
- }
- /* -------------------------------------------- */
- changeBonneAventure(value) {
- let newBA = this.system.bonneaventure.actuelle
- newBA += value
- this.update({ 'system.bonneaventure.actuelle': newBA })
- }
-
- /* -------------------------------------------- */
- getEclat() {
- return this.system.eclat.value
- }
-
- /* -------------------------------------------- */
- changeEclat(value) {
- let newE = this.system.eclat.value
- newE += value
- this.update({ 'system.eclat.value': newE })
- }
-
- /* -------------------------------------------- */
- compareName(a, b) {
- if (a.name < b.name) {
- return -1;
- }
- if (a.name > b.name) {
- return 1;
- }
- return 0;
- }
-
- /* -------------------------------------------- */
- getAttribute(attrKey) {
- return this.system.attributes[attrKey]
- }
-
- /* -------------------------------------------- */
- getBonusDegats() {
- return 0;
- }
-
- /* -------------------------------------------- */
- changeEtatCombativite(value) {
- if (value === "vaincu") {
- value = 200
- }
- let sante = foundry.utils.duplicate(this.system.sante)
- sante.etat += Number(value)
- sante.etat = Math.max(sante.etat, 0)
- sante.etat = Math.min(sante.etat, this.system.sante.nbcombativite)
- this.update({ 'system.sante': sante })
- if (sante.etat == this.system.sante.nbcombativite) {
- ChatMessage.create({ content: `${this.name} est vaincu !` })
- }
- // Duplicated ! this.processCombativite(sante)
- }
-
- /* -------------------------------------------- */
- processCombativite(sante) {
- sante = sante || foundry.utils.duplicate(this.system.sante)
- // Gestion des états affaibli et très affaibli
- if (sante.etat == this.system.sante.nbcombativite - 2 || sante.etat == this.system.sante.nbcombativite - 1) {
- if (sante.etat == this.system.sante.nbcombativite - 2 && this.items.find(item => item.type == "talent" && item.name.toLowerCase() == "encaissement")) {
- ChatMessage.create({ content: `${this.name} ne subit pas les 2 adversités rouge grâce à Encaissement. Pensez à les ajouter à la fin de la scène !` })
- } else if (sante.etat == this.system.sante.nbcombativite - 1 && this.items.find(item => item.type == "talent" && item.name.toLowerCase().includes("vaillant"))) {
- ChatMessage.create({ content: `${this.name} ne subit pas les 2 adversités rouge grâce à Vaillant. Pensez à les ajouter à la fin de la scène !` })
- } else {
- ChatMessage.create({ content: `${this.name} subit 2 adversités rouge !` })
- this.incDecAdversite("rouge", 2)
- }
- }
- }
-
- /* -------------------------------------------- */
- async equipGear(equipmentId) {
- let item = this.items.find(item => item.id == equipmentId);
- if (item?.system?.data) {
- let update = { _id: item.id, "system.equipped": !item.system.equipped };
- await this.updateEmbeddedDocuments('Item', [update]); // Updates one EmbeddedEntity
- }
- }
-
- /* -------------------------------------------- */
- getSubActors() {
- let subActors = [];
- for (let id of this.system.subactors) {
- subActors.push(foundry.utils.duplicate(game.actors.get(id)));
- }
- return subActors;
- }
- /* -------------------------------------------- */
- async addSubActor(subActorId) {
- let subActors = foundry.utils.duplicate(this.system.subactors);
- subActors.push(subActorId);
- await this.update({ 'system.subactors': subActors });
- }
- /* -------------------------------------------- */
- async delSubActor(subActorId) {
- let newArray = [];
- for (let id of this.system.subactors) {
- if (id != subActorId) {
- newArray.push(id);
- }
- }
- await this.update({ 'system.subactors': newArray });
- }
-
- /* -------------------------------------------- */
- getTotalAdversite() {
- return this.system.adversite.bleue + this.system.adversite.rouge + this.system.adversite.noire
- }
-
- /* -------------------------------------------- */
- async incDecAdversite(adv, incDec = 0) {
- let adversite = foundry.utils.duplicate(this.system.adversite)
- adversite[adv] += Number(incDec)
- adversite[adv] = Math.max(adversite[adv], 0)
- adversite[adv] = Math.min(adversite[adv], 20)
- this.update({ 'system.adversite': adversite })
- }
- /* -------------------------------------------- */
- async incDecQuantity(objetId, incDec = 0) {
- let objetQ = this.items.get(objetId)
- if (objetQ) {
- let newQ = objetQ.system.quantite + incDec
- newQ = Math.max(newQ, 0)
- await this.updateEmbeddedDocuments('Item', [{ _id: objetQ.id, 'system.quantite': newQ }]); // pdates one EmbeddedEntity
- }
- }
-
- /* -------------------------------------------- */
- computeRichesse() {
- let valueSC = 0
- for (let monnaie of this.items) {
- if (monnaie.type == "monnaie") {
- valueSC += Number(monnaie.system.prixsc) * Number(monnaie.system.quantite)
- }
- }
- return MournbladeCYD2Utility.computeMonnaieDetails(valueSC)
- }
-
- /* -------------------------------------------- */
- computeValeurEquipement() {
- let valueSC = 0
- for (let equip of this.items) {
- if (equip.type == "equipement" || equip.type == "arme" || equip.type == "protection") {
- valueSC += Number(equip.system.prixsc) * Number(equip.system.quantite ?? 1)
- valueSC += (Number(equip.system.prixca) * Number(equip.system.quantite ?? 1)) * 20
- valueSC += (Number(equip.system.prixpo) * Number(equip.system.quantite ?? 1)) * 400
- }
- }
- return MournbladeCYD2Utility.computeMonnaieDetails(valueSC)
- }
-
- /* -------------------------------------------- */
- getCompetence(compId) {
- return this.items.get(compId)
- }
-
- /* -------------------------------------------- */
- async setPredilectionUsed(compId, predIdx) {
- let comp = this.items.get(compId)
- let pred = foundry.utils.duplicate(comp.system.predilections)
- pred[predIdx].used = true
- await this.updateEmbeddedDocuments('Item', [{ _id: compId, 'system.predilections': pred }])
- }
-
- /* -------------------------------------------- */
- getInitiativeScore() {
- let init = this.getFlag("world", "last-initiative")
- return init || -1
- }
-
- /* -------------------------------------------- */
- getBestAttackValue() {
- let attackList = this.items.filter(item => (item.type == "arme" || item.type == "talent") && item.system.equipped)
- let maxOff = 0
- let bestArme
- for (let arme of attackList) {
- if (arme.type == "arme") {
- arme = this.prepareArme(arme)
- }
- if (arme.system.totalOffensif > maxOff) {
- maxOff = arme.system.totalOffensif
- bestArme = foundry.utils.duplicate(arme)
- }
- }
- return bestArme
- }
-
- /* -------------------------------------------- */
- getBestDefenseValue() {
- let defenseList = this.items.filter(item => (item.type == "arme") && item.system.equipped)
- let maxDef = 0
- let bestArme
- for (let arme of defenseList) {
- if (arme.type == "arme") {
- arme = this.prepareArme(arme)
- }
- if (arme.system.totalDefensif > maxDef) {
- maxDef = arme.system.totalDefensif
- bestArme = foundry.utils.duplicate(arme)
- }
- }
- return bestArme
- }
-
- /* -------------------------------------------- */
- searchRelevantTalents(competence) {
- let talents = []
-
- for (let talent of this.items) {
- if (talent.type == "talent" && talent.system.isautomated && talent.system.automations.length > 0) {
- for (let auto of talent.system.automations) {
- if (auto.eventtype === "prepare-roll") {
- if (auto.competence.toLowerCase() == competence.name.toLowerCase()) {
- talent = foundry.utils.duplicate(talent)
- talent.system.bonus = auto.bonus
- talent.system.baCost = auto.baCost
- talents.push(talent)
- }
- }
- }
- }
- }
- return talents
- }
-
- /* -------------------------------------------- */
- buildListeAdversites() {
- return []
- }
-
- /* -------------------------------------------- */
- getCommonRollData(attrKey = undefined, compId = undefined, compName = undefined) {
- let rollData = MournbladeCYD2Utility.getBasicRollData()
- rollData.alias = this.name
- rollData.actorImg = this.img
- rollData.actorId = this.id
- rollData.tokenId = this.token?.id
- rollData.img = this.img
- rollData.attributs = MournbladeCYD2Utility.getAttributs()
- rollData.maitriseId = "none"
- rollData.nbEclat = this.system.eclat.value
- rollData.nbBA = this.system.bonneaventure.actuelle
- rollData.nbAdversites = this.getTotalAdversite()
- rollData.talents = []
- rollData.attrKey2 = "none"
- rollData.coupDevastateur = this.items.find(it => it.type == "talent" && it.name.toLowerCase() == "coup dévastateur" && !it.system.used)
- rollData.hasAmbidextre = this.items.find(it => it.type == "talent" && it.name.toLowerCase() == "ambidextre")
- rollData.hasFeinte = this.system.bonneaventure.actuelle > 0 && this.items.find(it => it.type == "talent" && it.name.toLowerCase() == "feinte")
- rollData.isMonte = this.system.combat.monte
- rollData.config = game.system.mournbladecyd2.config
-
- if (attrKey) {
- rollData.attrKey = attrKey
- if (attrKey != "tochoose") {
- rollData.actionImg = "systems/fvtt-mournblade-cyd2/assets/icons/" + this.system.attributs[attrKey].labelnorm + ".webp"
- rollData.attr = foundry.utils.duplicate(this.system.attributs[attrKey])
- }
- }
- if (compId) {
- rollData.competence = foundry.utils.duplicate(this.items.get(compId) || {})
- let maitrises = [{ key: "none", label: "Aucune" }]
- rollData.competence.system.predilections.forEach(function (item) {
- if (item.maitrise) {
- maitrises.push({ key: item.id, label: item.name });
- }
- })
- rollData.maitrises = maitrises // rollData.competence.system.predilections.filter(p => p.maitrise)
- rollData.actionImg = rollData.competence?.img
- rollData.talents = this.searchRelevantTalents(rollData.competence)
- }
- if (compName) {
- rollData.competence = foundry.utils.duplicate(this.items.find(item => item.name.toLowerCase() == compName.toLowerCase()) || {})
- rollData.actionImg = rollData.competence?.img
- }
- return rollData
- }
-
- /* -------------------------------------------- */
- async rollAttribut(attrKey, isInit = false) {
- let rollData = this.getCommonRollData(attrKey)
- rollData.multiplier = (isInit) ? 1 : 2
- rollData.isInit = isInit
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
-
- /* -------------------------------------------- */
- async rollCompetence(attrKey, compId) {
- let rollData = this.getCommonRollData(attrKey, compId)
- rollData.multiplier = 1 // Attr multiplier, always 1 in competence mode
- console.log("RollDatra", rollData)
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
-
- /* -------------------------------------------- */
- async rollArmeOffensif(armeId) {
- let arme = this.items.get(armeId)
- if (arme.type == "arme") {
- arme = this.prepareArme(arme)
- }
- let rollData = this.getCommonRollData(arme.system.attrKey, arme.system.competence._id)
- rollData.arme = arme
- MournbladeCYD2Utility.updateWithTarget(rollData)
- console.log("ARME!", rollData)
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
- /* -------------------------------------------- */
- async rollAssommer() {
- let rollData = this.getCommonRollData("pui", undefined, "Filouterie")
- rollData.assomer = true
- rollData.conditionsCommunes = true
- MournbladeCYD2Utility.updateWithTarget(rollData)
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
- /* -------------------------------------------- */
- async rollCoupBas() {
- let rollData = this.getCommonRollData("pui", undefined, "Mêlée")
- rollData.coupBas = true
- rollData.conditionsCommunes = true
- MournbladeCYD2Utility.updateWithTarget(rollData)
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
- /* -------------------------------------------- */
- async rollImmobiliser() {
- let rollData = this.getCommonRollData("pui", undefined, "Mêlée")
- rollData.immobiliser = true
- rollData.conditionsCommunes = true
- rollData.cibleconsciente = true
- MournbladeCYD2Utility.updateWithTarget(rollData)
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
- /* -------------------------------------------- */
- async rollRepousser() {
- let rollData = this.getCommonRollData("pui", undefined, "Mêlée")
- rollData.repousser = true
- rollData.conditionsCommunes = true
- rollData.cibleconsciente = true
- MournbladeCYD2Utility.updateWithTarget(rollData)
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
- /* -------------------------------------------- */
- async rollDesengager() {
- let rollData = this.getCommonRollData("adr", undefined, "Mouvements")
- rollData.desengager = true
- rollData.conditionsCommunes = true
- MournbladeCYD2Utility.updateWithTarget(rollData)
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
-
- /* -------------------------------------------- */
- async rollArmeDegats(armeId, targetVigueur = undefined, rollDataInput = undefined) {
- let arme = this.items.get(armeId)
- if (arme.type == "arme") {
- arme = this.prepareArme(arme)
- }
- console.log("DEGATS", arme, targetVigueur, rollDataInput)
- let roll
- let bonus = 0
- let bonus2 = 0
-
- if (rollDataInput?.applyCoupDevastateur) {
- bonus2 = Math.floor(this.system.attributs.pui.value / 2)
- let talent = this.items.find(item => item.type == "talent" && item.name.toLowerCase() == "coup dévastateur")
- this.updateEmbeddedDocuments('Item', [{ _id: talent.id, 'system.used': true }])
- }
-
- if (rollDataInput?.isHeroique) {
- if (rollDataInput?.attaqueCharge) {
- bonus = 5
- }
- if (rollDataInput?.chargeCavalerie) {
- bonus = 6
- }
- roll = await new Roll("2d10rr10+" + arme.system.totalDegats + "+" + bonus + "+" + bonus2).roll()
- } else {
- if (rollDataInput?.attaqueCharge) {
- bonus = 3
- }
- if (rollDataInput?.chargeCavalerie) {
- bonus = 4
- }
- roll = await new Roll("1d10+" + arme.system.totalDegats + "+" + bonus + "+" + bonus2).roll()
- }
- await MournbladeCYD2Utility.showDiceSoNice(roll, game.settings.get("core", "rollMode"));
- let nbEtatPerdus = 0
- if (targetVigueur) {
- nbEtatPerdus = Math.floor(roll.total / targetVigueur)
- }
- //console.log(roll)
- let rollData = {
- arme: arme,
- finalResult: roll.total,
- formula: roll.formula,
- alias: this.name,
- actorImg: this.img,
- actorId: this.id,
- defenderTokenId: rollDataInput?.defenderTokenId,
- actionImg: arme.img,
- targetVigueur: targetVigueur,
- nbEtatPerdus: nbEtatPerdus
- }
- MournbladeCYD2Utility.createChatWithRollMode(rollData.alias, {
- content: await renderTemplate(`systems/fvtt-mournblade-cyd2/templates/chat-degats-result.html`, rollData)
- })
-
- if (rollDataInput?.defenderTokenId && nbEtatPerdus) {
- MournbladeCYD2Utility.applyCombativite(rollDataInput, nbEtatPerdus)
- }
-
- }
-}
diff --git a/.history/modules/mournblade-cyd2-actor_20251026082146.js b/.history/modules/mournblade-cyd2-actor_20251026082146.js
deleted file mode 100644
index 6907fbb..0000000
--- a/.history/modules/mournblade-cyd2-actor_20251026082146.js
+++ /dev/null
@@ -1,867 +0,0 @@
-/* -------------------------------------------- */
-import { MournbladeCYD2Utility } from "./mournblade-cyd2-utility.js";
-import { MournbladeCYD2RollDialog } from "./mournblade-cyd2-roll-dialog.js";
-
-/* -------------------------------------------- */
-const __degatsBonus = [-2, -2, -1, -1, 0, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 8, 8, 9, 9, 10, 10]
-const __vitesseBonus = [-2, -2, -1, -1, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8]
-
-/* -------------------------------------------- */
-/**
- * Extend the base Actor entity by defining a custom roll data structure which is ideal for the Simple system.
- * @extends {Actor}
- */
-export class MournbladeCYD2Actor extends Actor {
-
- /* -------------------------------------------- */
- /**
- * Override the create() function to provide additional SoS functionality.
- *
- * This overrided create() function adds initial items
- * Namely: Basic skills, money,
- *
- * @param {Object} data Barebones actor data which this function adds onto.
- * @param {Object} options (Unused) Additional options which customize the creation workflow.
- *
- */
-
- static async create(data, options) {
-
- // Case of compendium global import
- if (data instanceof Array) {
- return super.create(data, options);
- }
- // If the created actor has items (only applicable to duplicated actors) bypass the new actor creation logic
- if (data.items) {
- let actor = super.create(data, options);
- return actor;
- }
-
- if (data.type == 'personnage') {
- const skills = await MournbladeCYD2Utility.loadCompendium("fvtt-mournblade-cyd2.skills")
- data.items = skills.map(i => i.toObject())
- }
- if (data.type == 'creature') {
- const skills = await MournbladeCYD2Utility.loadCompendium("fvtt-mournblade-cyd2.skills-creatures")
- data.items = skills.map(i => i.toObject())
- data.items.push({ name: "Arme naturelle 1", type: 'arme', img: "systems/fvtt-mournblade-cyd2/assets/icons/melee.webp", system: { typearme: "contact", bonusmaniementoff: 0, seuildefense: 0, degats: "0" } })
- data.items.push({ name: "Arme naturelle 2", type: 'arme', img: "systems/fvtt-mournblade-cyd2/assets/icons/melee.webp", system: { typearme: "contact", bonusmaniementoff: 0, seuildefense: 0, degats: "0" } })
- }
-
- return super.create(data, options);
- }
-
- /* -------------------------------------------- */
- getBonusDefenseFromTalents() {
- let talents = this.items.filter(item => item.type == "talent" && item.system.isautomated)
- let bonus = 0
- for (let talent of talents) {
- for (let auto of talent.system.automations) {
- if (auto.eventtype == "bonus-permanent" && auto.bonusname == "bonus-defensif") {
- bonus += Number(auto.bonus || 0)
- }
- }
- }
- return bonus
- }
-
- /* -------------------------------------------- */
- prepareArme(arme) {
- if (this.type == "cellule") {
- return arme
- }
-
- arme = foundry.utils.duplicate(arme)
- let combat = this.getCombatValues()
- if (arme.system.typearme == "contact" || arme.system.typearme == "contactjet") {
- let bonusDefense = this.getBonusDefenseFromTalents()
- arme.system.competence = foundry.utils.duplicate(this.items.find(item => item.type == "competence" && item.name.toLowerCase() == "mêlée"))
- arme.system.attrKey = "pui"
- arme.system.totalDegats = arme.system.degats + "+" + combat.bonusDegatsTotal
- arme.system.totalOffensif = this.system.attributs.pui.value + arme.system.competence.system.niveau + arme.system.bonusmaniementoff + (this.system.combat.monte ? 3 : 0)
- arme.system.totalDefensif = combat.defenseTotal + arme.system.competence.system.niveau + arme.system.seuildefense + bonusDefense + (this.system.combat.monte ? 3 : 0)
- console.log("Arme", arme.system.totalDefensif, combat, arme.system.competence.system.niveau, arme.system.seuildefense, bonusDefense)
- arme.system.isdefense = true
- arme.system.isMelee = true
- arme.system.isDistance = false
- }
- if (arme.system.typearme == "jet" || arme.system.typearme == "tir") {
- arme.system.competence = foundry.utils.duplicate(this.items.find(item => item.type == "competence" && item.name.toLowerCase() == "armes à distance"))
- arme.system.attrKey = "adr"
- arme.system.totalOffensif = this.system.attributs.adr.value + arme.system.competence.system.niveau + arme.system.bonusmaniementoff
- arme.system.totalDegats = arme.system.degats
- arme.system.isMelee = false
- arme.system.isDistance = true
- if (arme.system.isdefense) {
- arme.system.totalDefensif = combat.defenseTotal + arme.system.competence.system.niveau + arme.system.seuildefense
- }
- }
- return arme
- }
-
- /* -------------------------------------------- */
- getItemSorted(types) {
- let items = this.items.filter(item => types.includes(item.type)) || []
- MournbladeCYD2Utility.sortArrayObjectsByName(items)
- return items
- }
- getWeapons() {
- let armes = []
- for (let arme of this.items) {
- if (arme.type == "arme") {
- armes.push(this.prepareArme(arme))
- }
- }
- MournbladeCYD2Utility.sortArrayObjectsByName(armes)
- return armes
- }
- getMonnaies() {
- return this.getItemSorted(["monnaie"])
- }
- getEquipments() {
- return this.getItemSorted(["equipement"])
- }
- getArtefacts() {
- return this.getItemSorted(["artefact"])
- }
- getArmors() {
- return this.getItemSorted(["protection"])
- }
- getHistoriques() {
- return this.getItemSorted(["historique"])
- }
- getProfils() {
- return this.getItemSorted(["profil"])
- }
- getTalents() {
- return this.getItemSorted(["talent"])
- }
- getRessources() {
- return this.getItemSorted(["ressource"])
- }
- getContacts() {
- return this.getItemSorted(["contact"])
- }
- getMutations() {
- return this.getItemSorted(["mutation"])
- }
- getDons() {
- return this.getItemSorted(["don"])
- }
- getPactes() {
- return this.getItemSorted(["pacte"])
- }
- getTendances() {
- return this.getItemSorted(["tendance"])
- }
- getRunes() {
- return this.getItemSorted(["rune"])
- }
- getTraitsChaotiques() {
- return this.getItemSorted(["traitchaotique"])
- }
- getTraitsEspeces() {
- return this.getItemSorted(["traitespece"])
- }
-
- /* -------------------------------------------- */
- getAspect() {
- return (this.system.balance.loi > this.system.balance.chaos) ? this.system.balance.loi : this.system.balance.chaos
- }
- getMarge() {
- return Math.abs(this.system.balance.loi - this.system.balance.chaos)
- }
- getAlignement() {
- return (this.system.balance.loi > this.system.balance.chaos) ? "loyal" : "chaotique"
- }
-
- /* -------------------------------------------- */
- getSkills() {
- let comp = []
- for (let item of this.items) {
- item = foundry.utils.duplicate(item)
- if (item.type == "competence") {
- item.system.attribut1total = item.system.niveau + (this.system.attributs[item.system.attribut1]?.value || 0)
- item.system.attribut2total = item.system.niveau + (this.system.attributs[item.system.attribut2]?.value || 0)
- item.system.attribut3total = item.system.niveau + (this.system.attributs[item.system.attribut3]?.value || 0)
- if (item.system.niveau == 0) {
- item.system.attribut1total -= 3
- item.system.attribut2total -= 3
- item.system.attribut3total -= 3
- }
- item.system.attribut1label = this.system.attributs[item.system.attribut1]?.label || ""
- item.system.attribut2label = this.system.attributs[item.system.attribut2]?.label || ""
- item.system.attribut3label = this.system.attributs[item.system.attribut3]?.label || ""
- comp.push(item)
- }
- }
- MournbladeCYD2Utility.sortArrayObjectsByName(comp)
- return comp
- }
-
- /* ----------------------- --------------------- */
- addMember(actorId) {
- let members = foundry.utils.duplicate(this.system.members)
- members.push({ id: actorId })
- this.update({ 'system.members': members })
- }
- async removeMember(actorId) {
- let members = this.system.members.filter(it => it.id != actorId)
- this.update({ 'system.members': members })
- }
-
- /* -------------------------------------------- */
- getDefenseBase() {
- return Math.max(this.system.attributs.tre.value, this.system.attributs.adr.value)
- }
-
- /* -------------------------------------------- */
- getVitesseBase() {
- return 5 + __vitesseBonus[this.system.attributs.adr.value]
- }
- /* -------------------------------------------- */
- getProtection() {
- let equipProtection = 0
- for (let armor of this.items) {
- if (armor.type == "protection" && armor.system.equipped) {
- equipProtection += Number(armor.system.protection)
- }
- }
- if (equipProtection < 4) {
- return 4 + equipProtection // Cas des boucliers + sans armure
- }
- return equipProtection // Uniquement la protection des armures + boucliers
- }
-
- /* -------------------------------------------- */
- getCombatValues() {
- if (this.type == "cellule") {
- return {
- initBase: 0,
- initTotal: 0,
- bonusDegats: 0,
- bonusDegatsTotal: 0,
- vitesseBase: 0,
- vitesseTotal: 0,
- defenseBase: 0,
- protection: 0,
- defenseTotal: 0
- }
- }
-
- let combat = {
- initBase: this.system.attributs.adr.value,
- initTotal: this.system.attributs.adr.value + this.system.combat.initbonus,
- bonusDegats: this.getBonusDegats(),
- bonusDegatsTotal: this.getBonusDegats() + this.system.combat.bonusdegats,
- vitesseBase: this.getVitesseBase(),
- vitesseTotal: this.getVitesseBase() + this.system.combat.vitessebonus,
- defenseBase: this.getDefenseBase(),
- protection: this.getProtection(),
- defenseTotal: this.getDefenseBase() + this.system.combat.defensebonus + this.getProtection() - this.getTotalAdversite() + (this.system.combat.defensetotale ? 3 : 0)
- }
- return combat
- }
-
- /* -------------------------------------------- */
- prepareBaseData() {
- }
-
- /* -------------------------------------------- */
- async prepareData() {
- super.prepareData();
- }
-
- /* -------------------------------------------- */
- prepareDerivedData() {
-
- if (this.type == 'personnage') {
- let talentBonus = this.getVigueurBonus()
- let vigueur = Math.floor((this.system.attributs.pui.value + this.system.attributs.tre.value) / 2) + talentBonus + this.system.sante.vigueurmodifier
- if (vigueur != this.system.sante.vigueur) {
- this.update({ 'system.sante.vigueur': vigueur })
- }
-
- let seuilPouvoirBonus = this.getSeuilPouvoirBonus()
- let seuilPouvoir = Math.floor((this.system.attributs.tre.value + this.system.attributs.cla.value) / 2) + seuilPouvoirBonus + this.system.ame.seuilpouvoirmodifier
- if (seuilPouvoir != this.system.ame.seuilpouvoir) {
- this.update({ 'system.ame.seuilpouvoir': seuilPouvoir })
- }
- }
- super.prepareDerivedData()
- }
-
- /* -------------------------------------------- */
- _preUpdate(changed, options, user) {
- if (changed?.system?.sante?.etat && changed?.system?.sante?.etat != this.system.sante.etat) {
- setTimeout(() => {
- this.processCombativite(changed.system.sante)
- }, 800)
- }
- if (changed?.system?.ame?.etat && changed?.system?.ame?.etat != this.system.ame.etat) {
- setTimeout(() => {
- this.processAme(changed.system.ame)
- }, 800)
- }
- super._preUpdate(changed, options, user);
- }
-
- /* -------------------------------------------- */
- _onUpdate(data, options, user) {
- super._onUpdate(data, options, user);
- }
- /* -------------------------------------------- */
- getItemById(id) {
- let item = this.items.find(item => item.id == id);
- if (item) {
- item = foundry.utils.duplicate(item)
- }
- return item;
- }
-
- /* -------------------------------------------- */
- async equipItem(itemId) {
- let item = this.items.find(item => item.id == itemId)
- if (item && item.system) {
- let update = { _id: item.id, "system.equipped": !item.system.equipped }
- await this.updateEmbeddedDocuments('Item', [update]); // Updates one EmbeddedEntity
- }
- }
-
- /* -------------------------------------------- */
- editItemField(itemId, itemType, itemField, dataType, value) {
- let item = this.items.find(item => item.id == itemId)
- if (item) {
- console.log("Item ", item, itemField, dataType, value)
- if (dataType.toLowerCase() == "number") {
- value = Number(value)
- } else {
- value = String(value)
- }
- let update = { _id: item.id, [`system.${itemField}`]: value };
- this.updateEmbeddedDocuments("Item", [update])
- }
- }
-
- /* -------------------------------------------- */
- checkAttribut(attribut, minLevel) {
- let attr = this.system.attributs.find(at => at.labelnorm == attribut.toLowerCase())
- if (attr && attr.value >= minLevel) {
- return { isValid: true, attr: foundry.utils.duplicate(attr) }
- }
- return { isValid: false }
- }
- /* -------------------------------------------- */
- checkAttributOrCompetenceLevel(compName, minLevel) {
- let comp = this.items.find(i => i.type == "competence" && i.name.toLowerCase() == compName.toLowerCase() && i.system.niveau >= minLevel)
- if (comp) {
- return { isValid: true, item: foundry.utils.duplicate(comp) }
- } else {
- for (let attrKey in this.system.attributs) {
- if (this.system.attributs[attrKey].label.toLowerCase() == compName.toLowerCase() && this.system.attributs[attrKey].value >= minLevel) {
- return { isValid: true, item: foundry.utils.duplicate(this.system.attributs[attrKey]) }
- }
- }
- }
- return { isValid: false, warningMessage: `Prérequis insuffisant : la compétence/attribut ${compName} doit être de niveau ${minLevel} au minimum` }
- }
- /* -------------------------------------------- */
- addCompetenceBonus(compName, bonus, baCost) {
- let comp = this.items.find(i => i.type == "competence" && i.name.toLowerCase() == compName.toLowerCase())
- if (comp) {
- comp = foundry.utils.duplicate(comp)
- comp.system.bonus = bonus
- comp.system.baCost = baCost
- return { isValid: true, item: comp }
- }
- return { isValid: false, warningMessage: `Compétence ${compName} non trouvée` }
- }
- /* -------------------------------------------- */
- checkIfCompetence(compName) {
- let comp = this.items.find(i => i.type == "competence" && i.name.toLowerCase() == compName.toLowerCase())
- if (comp) {
- return { isValid: true, item: comp }
- }
- return { isValid: false }
- }
- /* -------------------------------------------- */
- getVigueur() {
- return this.system.sante.vigueur
- }
-
- /* -------------------------------------------- */
- getVigueurBonus() {
- let talents = this.items.filter(item => item.type == "talent" && item.system.isautomated)
- let bonus = 0
- for (let talent of talents) {
- for (let auto of talent.system.automations) {
- if (auto.eventtype == "bonus-permanent" && auto.bonusname == "vigueur") {
- bonus += Number(auto.bonus || 0)
- }
- }
- }
- return bonus
- }
-
- /* -------------------------------------------- */
- getSeuilPouvoir() {
- return this.system.ame.seuilpouvoir
- }
-
- /* -------------------------------------------- */
- getSeuilPouvoirBonus() {
- let talents = this.items.filter(item => item.type == "talent" && item.system.isautomated)
- let bonus = 0
- for (let talent of talents) {
- for (let auto of talent.system.automations) {
- if (auto.eventtype == "bonus-permanent" && auto.bonusname == "seuilpouvoir") {
- bonus += Number(auto.bonus || 0)
- }
- }
- }
- return bonus
- }
-
- /* -------------------------------------------- */
- getBonneAventure() {
- return this.system.bonneaventure.actuelle
- }
- /* -------------------------------------------- */
- checkBonneAventure(cost) {
- return (this.system.bonneaventure.actuelle >= cost)
- }
- /* -------------------------------------------- */
- changeBonneAventure(value) {
- let newBA = this.system.bonneaventure.actuelle
- newBA += value
- this.update({ 'system.bonneaventure.actuelle': newBA })
- }
-
- /* -------------------------------------------- */
- getEclat() {
- return this.system.eclat.value
- }
-
- /* -------------------------------------------- */
- changeEclat(value) {
- let newE = this.system.eclat.value
- newE += value
- this.update({ 'system.eclat.value': newE })
- }
-
- /* -------------------------------------------- */
- compareName(a, b) {
- if (a.name < b.name) {
- return -1;
- }
- if (a.name > b.name) {
- return 1;
- }
- return 0;
- }
-
- /* -------------------------------------------- */
- getAttribute(attrKey) {
- return this.system.attributes[attrKey]
- }
-
- /* -------------------------------------------- */
- getBonusDegats() {
- return 0;
- }
-
- /* -------------------------------------------- */
- changeEtatCombativite(value) {
- if (value === "vaincu") {
- value = 200
- }
- let sante = foundry.utils.duplicate(this.system.sante)
- sante.etat += Number(value)
- sante.etat = Math.max(sante.etat, 0)
- sante.etat = Math.min(sante.etat, this.system.sante.nbcombativite)
- this.update({ 'system.sante': sante })
- if (sante.etat == this.system.sante.nbcombativite) {
- ChatMessage.create({ content: `${this.name} est vaincu !` })
- }
- // Duplicated ! this.processCombativite(sante)
- }
-
- /* -------------------------------------------- */
- processCombativite(sante) {
- sante = sante || foundry.utils.duplicate(this.system.sante)
- // Gestion des états affaibli et très affaibli
- if (sante.etat == this.system.sante.nbcombativite - 2 || sante.etat == this.system.sante.nbcombativite - 1) {
- if (sante.etat == this.system.sante.nbcombativite - 2 && this.items.find(item => item.type == "talent" && item.name.toLowerCase() == "encaissement")) {
- ChatMessage.create({ content: `${this.name} ne subit pas les 2 adversités rouge grâce à Encaissement. Pensez à les ajouter à la fin de la scène !` })
- } else if (sante.etat == this.system.sante.nbcombativite - 1 && this.items.find(item => item.type == "talent" && item.name.toLowerCase().includes("vaillant"))) {
- ChatMessage.create({ content: `${this.name} ne subit pas les 2 adversités rouge grâce à Vaillant. Pensez à les ajouter à la fin de la scène !` })
- } else {
- ChatMessage.create({ content: `${this.name} subit 2 adversités rouge !` })
- this.incDecAdversite("rouge", 2)
- }
- }
- }
-
- /* -------------------------------------------- */
- processAme(ame) {
- ame = ame || foundry.utils.duplicate(this.system.ame)
- // Gestion des états Traumatisé, Très Traumatisé et Brisé
- if (ame.etat == this.system.ame.nbame - 3 || ame.etat == this.system.ame.nbame - 2 || ame.etat == this.system.ame.nbame - 1) {
- if (ame.etat == this.system.ame.nbame - 3) {
- ChatMessage.create({ content: `${this.name} est Traumatisé !` })
- } else if (ame.etat == this.system.ame.nbame - 2) {
- ChatMessage.create({ content: `${this.name} est Très Traumatisé !` })
- } else if (ame.etat == this.system.ame.nbame - 1) {
- ChatMessage.create({ content: `${this.name} est Brisé !` })
- }
- }
- }
-
- /* -------------------------------------------- */
- async equipGear(equipmentId) {
- let item = this.items.find(item => item.id == equipmentId);
- if (item?.system?.data) {
- let update = { _id: item.id, "system.equipped": !item.system.equipped };
- await this.updateEmbeddedDocuments('Item', [update]); // Updates one EmbeddedEntity
- }
- }
-
- /* -------------------------------------------- */
- getSubActors() {
- let subActors = [];
- for (let id of this.system.subactors) {
- subActors.push(foundry.utils.duplicate(game.actors.get(id)));
- }
- return subActors;
- }
- /* -------------------------------------------- */
- async addSubActor(subActorId) {
- let subActors = foundry.utils.duplicate(this.system.subactors);
- subActors.push(subActorId);
- await this.update({ 'system.subactors': subActors });
- }
- /* -------------------------------------------- */
- async delSubActor(subActorId) {
- let newArray = [];
- for (let id of this.system.subactors) {
- if (id != subActorId) {
- newArray.push(id);
- }
- }
- await this.update({ 'system.subactors': newArray });
- }
-
- /* -------------------------------------------- */
- getTotalAdversite() {
- return this.system.adversite.bleue + this.system.adversite.rouge + this.system.adversite.noire
- }
-
- /* -------------------------------------------- */
- async incDecAdversite(adv, incDec = 0) {
- let adversite = foundry.utils.duplicate(this.system.adversite)
- adversite[adv] += Number(incDec)
- adversite[adv] = Math.max(adversite[adv], 0)
- adversite[adv] = Math.min(adversite[adv], 20)
- this.update({ 'system.adversite': adversite })
- }
- /* -------------------------------------------- */
- async incDecQuantity(objetId, incDec = 0) {
- let objetQ = this.items.get(objetId)
- if (objetQ) {
- let newQ = objetQ.system.quantite + incDec
- newQ = Math.max(newQ, 0)
- await this.updateEmbeddedDocuments('Item', [{ _id: objetQ.id, 'system.quantite': newQ }]); // pdates one EmbeddedEntity
- }
- }
-
- /* -------------------------------------------- */
- computeRichesse() {
- let valueSC = 0
- for (let monnaie of this.items) {
- if (monnaie.type == "monnaie") {
- valueSC += Number(monnaie.system.prixsc) * Number(monnaie.system.quantite)
- }
- }
- return MournbladeCYD2Utility.computeMonnaieDetails(valueSC)
- }
-
- /* -------------------------------------------- */
- computeValeurEquipement() {
- let valueSC = 0
- for (let equip of this.items) {
- if (equip.type == "equipement" || equip.type == "arme" || equip.type == "protection") {
- valueSC += Number(equip.system.prixsc) * Number(equip.system.quantite ?? 1)
- valueSC += (Number(equip.system.prixca) * Number(equip.system.quantite ?? 1)) * 20
- valueSC += (Number(equip.system.prixpo) * Number(equip.system.quantite ?? 1)) * 400
- }
- }
- return MournbladeCYD2Utility.computeMonnaieDetails(valueSC)
- }
-
- /* -------------------------------------------- */
- getCompetence(compId) {
- return this.items.get(compId)
- }
-
- /* -------------------------------------------- */
- async setPredilectionUsed(compId, predIdx) {
- let comp = this.items.get(compId)
- let pred = foundry.utils.duplicate(comp.system.predilections)
- pred[predIdx].used = true
- await this.updateEmbeddedDocuments('Item', [{ _id: compId, 'system.predilections': pred }])
- }
-
- /* -------------------------------------------- */
- getInitiativeScore() {
- let init = this.getFlag("world", "last-initiative")
- return init || -1
- }
-
- /* -------------------------------------------- */
- getBestAttackValue() {
- let attackList = this.items.filter(item => (item.type == "arme" || item.type == "talent") && item.system.equipped)
- let maxOff = 0
- let bestArme
- for (let arme of attackList) {
- if (arme.type == "arme") {
- arme = this.prepareArme(arme)
- }
- if (arme.system.totalOffensif > maxOff) {
- maxOff = arme.system.totalOffensif
- bestArme = foundry.utils.duplicate(arme)
- }
- }
- return bestArme
- }
-
- /* -------------------------------------------- */
- getBestDefenseValue() {
- let defenseList = this.items.filter(item => (item.type == "arme") && item.system.equipped)
- let maxDef = 0
- let bestArme
- for (let arme of defenseList) {
- if (arme.type == "arme") {
- arme = this.prepareArme(arme)
- }
- if (arme.system.totalDefensif > maxDef) {
- maxDef = arme.system.totalDefensif
- bestArme = foundry.utils.duplicate(arme)
- }
- }
- return bestArme
- }
-
- /* -------------------------------------------- */
- searchRelevantTalents(competence) {
- let talents = []
-
- for (let talent of this.items) {
- if (talent.type == "talent" && talent.system.isautomated && talent.system.automations.length > 0) {
- for (let auto of talent.system.automations) {
- if (auto.eventtype === "prepare-roll") {
- if (auto.competence.toLowerCase() == competence.name.toLowerCase()) {
- talent = foundry.utils.duplicate(talent)
- talent.system.bonus = auto.bonus
- talent.system.baCost = auto.baCost
- talents.push(talent)
- }
- }
- }
- }
- }
- return talents
- }
-
- /* -------------------------------------------- */
- buildListeAdversites() {
- return []
- }
-
- /* -------------------------------------------- */
- getCommonRollData(attrKey = undefined, compId = undefined, compName = undefined) {
- let rollData = MournbladeCYD2Utility.getBasicRollData()
- rollData.alias = this.name
- rollData.actorImg = this.img
- rollData.actorId = this.id
- rollData.tokenId = this.token?.id
- rollData.img = this.img
- rollData.attributs = MournbladeCYD2Utility.getAttributs()
- rollData.maitriseId = "none"
- rollData.nbEclat = this.system.eclat.value
- rollData.nbBA = this.system.bonneaventure.actuelle
- rollData.nbAdversites = this.getTotalAdversite()
- rollData.talents = []
- rollData.attrKey2 = "none"
- rollData.coupDevastateur = this.items.find(it => it.type == "talent" && it.name.toLowerCase() == "coup dévastateur" && !it.system.used)
- rollData.hasAmbidextre = this.items.find(it => it.type == "talent" && it.name.toLowerCase() == "ambidextre")
- rollData.hasFeinte = this.system.bonneaventure.actuelle > 0 && this.items.find(it => it.type == "talent" && it.name.toLowerCase() == "feinte")
- rollData.isMonte = this.system.combat.monte
- rollData.config = game.system.mournbladecyd2.config
-
- if (attrKey) {
- rollData.attrKey = attrKey
- if (attrKey != "tochoose") {
- rollData.actionImg = "systems/fvtt-mournblade-cyd2/assets/icons/" + this.system.attributs[attrKey].labelnorm + ".webp"
- rollData.attr = foundry.utils.duplicate(this.system.attributs[attrKey])
- }
- }
- if (compId) {
- rollData.competence = foundry.utils.duplicate(this.items.get(compId) || {})
- let maitrises = [{ key: "none", label: "Aucune" }]
- rollData.competence.system.predilections.forEach(function (item) {
- if (item.maitrise) {
- maitrises.push({ key: item.id, label: item.name });
- }
- })
- rollData.maitrises = maitrises // rollData.competence.system.predilections.filter(p => p.maitrise)
- rollData.actionImg = rollData.competence?.img
- rollData.talents = this.searchRelevantTalents(rollData.competence)
- }
- if (compName) {
- rollData.competence = foundry.utils.duplicate(this.items.find(item => item.name.toLowerCase() == compName.toLowerCase()) || {})
- rollData.actionImg = rollData.competence?.img
- }
- return rollData
- }
-
- /* -------------------------------------------- */
- async rollAttribut(attrKey, isInit = false) {
- let rollData = this.getCommonRollData(attrKey)
- rollData.multiplier = (isInit) ? 1 : 2
- rollData.isInit = isInit
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
-
- /* -------------------------------------------- */
- async rollCompetence(attrKey, compId) {
- let rollData = this.getCommonRollData(attrKey, compId)
- rollData.multiplier = 1 // Attr multiplier, always 1 in competence mode
- console.log("RollDatra", rollData)
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
-
- /* -------------------------------------------- */
- async rollArmeOffensif(armeId) {
- let arme = this.items.get(armeId)
- if (arme.type == "arme") {
- arme = this.prepareArme(arme)
- }
- let rollData = this.getCommonRollData(arme.system.attrKey, arme.system.competence._id)
- rollData.arme = arme
- MournbladeCYD2Utility.updateWithTarget(rollData)
- console.log("ARME!", rollData)
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
- /* -------------------------------------------- */
- async rollAssommer() {
- let rollData = this.getCommonRollData("pui", undefined, "Filouterie")
- rollData.assomer = true
- rollData.conditionsCommunes = true
- MournbladeCYD2Utility.updateWithTarget(rollData)
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
- /* -------------------------------------------- */
- async rollCoupBas() {
- let rollData = this.getCommonRollData("pui", undefined, "Mêlée")
- rollData.coupBas = true
- rollData.conditionsCommunes = true
- MournbladeCYD2Utility.updateWithTarget(rollData)
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
- /* -------------------------------------------- */
- async rollImmobiliser() {
- let rollData = this.getCommonRollData("pui", undefined, "Mêlée")
- rollData.immobiliser = true
- rollData.conditionsCommunes = true
- rollData.cibleconsciente = true
- MournbladeCYD2Utility.updateWithTarget(rollData)
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
- /* -------------------------------------------- */
- async rollRepousser() {
- let rollData = this.getCommonRollData("pui", undefined, "Mêlée")
- rollData.repousser = true
- rollData.conditionsCommunes = true
- rollData.cibleconsciente = true
- MournbladeCYD2Utility.updateWithTarget(rollData)
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
- /* -------------------------------------------- */
- async rollDesengager() {
- let rollData = this.getCommonRollData("adr", undefined, "Mouvements")
- rollData.desengager = true
- rollData.conditionsCommunes = true
- MournbladeCYD2Utility.updateWithTarget(rollData)
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
-
- /* -------------------------------------------- */
- async rollArmeDegats(armeId, targetVigueur = undefined, rollDataInput = undefined) {
- let arme = this.items.get(armeId)
- if (arme.type == "arme") {
- arme = this.prepareArme(arme)
- }
- console.log("DEGATS", arme, targetVigueur, rollDataInput)
- let roll
- let bonus = 0
- let bonus2 = 0
-
- if (rollDataInput?.applyCoupDevastateur) {
- bonus2 = Math.floor(this.system.attributs.pui.value / 2)
- let talent = this.items.find(item => item.type == "talent" && item.name.toLowerCase() == "coup dévastateur")
- this.updateEmbeddedDocuments('Item', [{ _id: talent.id, 'system.used': true }])
- }
-
- if (rollDataInput?.isHeroique) {
- if (rollDataInput?.attaqueCharge) {
- bonus = 5
- }
- if (rollDataInput?.chargeCavalerie) {
- bonus = 6
- }
- roll = await new Roll("2d10rr10+" + arme.system.totalDegats + "+" + bonus + "+" + bonus2).roll()
- } else {
- if (rollDataInput?.attaqueCharge) {
- bonus = 3
- }
- if (rollDataInput?.chargeCavalerie) {
- bonus = 4
- }
- roll = await new Roll("1d10+" + arme.system.totalDegats + "+" + bonus + "+" + bonus2).roll()
- }
- await MournbladeCYD2Utility.showDiceSoNice(roll, game.settings.get("core", "rollMode"));
- let nbEtatPerdus = 0
- if (targetVigueur) {
- nbEtatPerdus = Math.floor(roll.total / targetVigueur)
- }
- //console.log(roll)
- let rollData = {
- arme: arme,
- finalResult: roll.total,
- formula: roll.formula,
- alias: this.name,
- actorImg: this.img,
- actorId: this.id,
- defenderTokenId: rollDataInput?.defenderTokenId,
- actionImg: arme.img,
- targetVigueur: targetVigueur,
- nbEtatPerdus: nbEtatPerdus
- }
- MournbladeCYD2Utility.createChatWithRollMode(rollData.alias, {
- content: await renderTemplate(`systems/fvtt-mournblade-cyd2/templates/chat-degats-result.html`, rollData)
- })
-
- if (rollDataInput?.defenderTokenId && nbEtatPerdus) {
- MournbladeCYD2Utility.applyCombativite(rollDataInput, nbEtatPerdus)
- }
-
- }
-}
diff --git a/.history/modules/mournblade-cyd2-actor_20251026082203.js b/.history/modules/mournblade-cyd2-actor_20251026082203.js
deleted file mode 100644
index 7b6f6ef..0000000
--- a/.history/modules/mournblade-cyd2-actor_20251026082203.js
+++ /dev/null
@@ -1,882 +0,0 @@
-/* -------------------------------------------- */
-import { MournbladeCYD2Utility } from "./mournblade-cyd2-utility.js";
-import { MournbladeCYD2RollDialog } from "./mournblade-cyd2-roll-dialog.js";
-
-/* -------------------------------------------- */
-const __degatsBonus = [-2, -2, -1, -1, 0, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 8, 8, 9, 9, 10, 10]
-const __vitesseBonus = [-2, -2, -1, -1, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8]
-
-/* -------------------------------------------- */
-/**
- * Extend the base Actor entity by defining a custom roll data structure which is ideal for the Simple system.
- * @extends {Actor}
- */
-export class MournbladeCYD2Actor extends Actor {
-
- /* -------------------------------------------- */
- /**
- * Override the create() function to provide additional SoS functionality.
- *
- * This overrided create() function adds initial items
- * Namely: Basic skills, money,
- *
- * @param {Object} data Barebones actor data which this function adds onto.
- * @param {Object} options (Unused) Additional options which customize the creation workflow.
- *
- */
-
- static async create(data, options) {
-
- // Case of compendium global import
- if (data instanceof Array) {
- return super.create(data, options);
- }
- // If the created actor has items (only applicable to duplicated actors) bypass the new actor creation logic
- if (data.items) {
- let actor = super.create(data, options);
- return actor;
- }
-
- if (data.type == 'personnage') {
- const skills = await MournbladeCYD2Utility.loadCompendium("fvtt-mournblade-cyd2.skills")
- data.items = skills.map(i => i.toObject())
- }
- if (data.type == 'creature') {
- const skills = await MournbladeCYD2Utility.loadCompendium("fvtt-mournblade-cyd2.skills-creatures")
- data.items = skills.map(i => i.toObject())
- data.items.push({ name: "Arme naturelle 1", type: 'arme', img: "systems/fvtt-mournblade-cyd2/assets/icons/melee.webp", system: { typearme: "contact", bonusmaniementoff: 0, seuildefense: 0, degats: "0" } })
- data.items.push({ name: "Arme naturelle 2", type: 'arme', img: "systems/fvtt-mournblade-cyd2/assets/icons/melee.webp", system: { typearme: "contact", bonusmaniementoff: 0, seuildefense: 0, degats: "0" } })
- }
-
- return super.create(data, options);
- }
-
- /* -------------------------------------------- */
- getBonusDefenseFromTalents() {
- let talents = this.items.filter(item => item.type == "talent" && item.system.isautomated)
- let bonus = 0
- for (let talent of talents) {
- for (let auto of talent.system.automations) {
- if (auto.eventtype == "bonus-permanent" && auto.bonusname == "bonus-defensif") {
- bonus += Number(auto.bonus || 0)
- }
- }
- }
- return bonus
- }
-
- /* -------------------------------------------- */
- prepareArme(arme) {
- if (this.type == "cellule") {
- return arme
- }
-
- arme = foundry.utils.duplicate(arme)
- let combat = this.getCombatValues()
- if (arme.system.typearme == "contact" || arme.system.typearme == "contactjet") {
- let bonusDefense = this.getBonusDefenseFromTalents()
- arme.system.competence = foundry.utils.duplicate(this.items.find(item => item.type == "competence" && item.name.toLowerCase() == "mêlée"))
- arme.system.attrKey = "pui"
- arme.system.totalDegats = arme.system.degats + "+" + combat.bonusDegatsTotal
- arme.system.totalOffensif = this.system.attributs.pui.value + arme.system.competence.system.niveau + arme.system.bonusmaniementoff + (this.system.combat.monte ? 3 : 0)
- arme.system.totalDefensif = combat.defenseTotal + arme.system.competence.system.niveau + arme.system.seuildefense + bonusDefense + (this.system.combat.monte ? 3 : 0)
- console.log("Arme", arme.system.totalDefensif, combat, arme.system.competence.system.niveau, arme.system.seuildefense, bonusDefense)
- arme.system.isdefense = true
- arme.system.isMelee = true
- arme.system.isDistance = false
- }
- if (arme.system.typearme == "jet" || arme.system.typearme == "tir") {
- arme.system.competence = foundry.utils.duplicate(this.items.find(item => item.type == "competence" && item.name.toLowerCase() == "armes à distance"))
- arme.system.attrKey = "adr"
- arme.system.totalOffensif = this.system.attributs.adr.value + arme.system.competence.system.niveau + arme.system.bonusmaniementoff
- arme.system.totalDegats = arme.system.degats
- arme.system.isMelee = false
- arme.system.isDistance = true
- if (arme.system.isdefense) {
- arme.system.totalDefensif = combat.defenseTotal + arme.system.competence.system.niveau + arme.system.seuildefense
- }
- }
- return arme
- }
-
- /* -------------------------------------------- */
- getItemSorted(types) {
- let items = this.items.filter(item => types.includes(item.type)) || []
- MournbladeCYD2Utility.sortArrayObjectsByName(items)
- return items
- }
- getWeapons() {
- let armes = []
- for (let arme of this.items) {
- if (arme.type == "arme") {
- armes.push(this.prepareArme(arme))
- }
- }
- MournbladeCYD2Utility.sortArrayObjectsByName(armes)
- return armes
- }
- getMonnaies() {
- return this.getItemSorted(["monnaie"])
- }
- getEquipments() {
- return this.getItemSorted(["equipement"])
- }
- getArtefacts() {
- return this.getItemSorted(["artefact"])
- }
- getArmors() {
- return this.getItemSorted(["protection"])
- }
- getHistoriques() {
- return this.getItemSorted(["historique"])
- }
- getProfils() {
- return this.getItemSorted(["profil"])
- }
- getTalents() {
- return this.getItemSorted(["talent"])
- }
- getRessources() {
- return this.getItemSorted(["ressource"])
- }
- getContacts() {
- return this.getItemSorted(["contact"])
- }
- getMutations() {
- return this.getItemSorted(["mutation"])
- }
- getDons() {
- return this.getItemSorted(["don"])
- }
- getPactes() {
- return this.getItemSorted(["pacte"])
- }
- getTendances() {
- return this.getItemSorted(["tendance"])
- }
- getRunes() {
- return this.getItemSorted(["rune"])
- }
- getTraitsChaotiques() {
- return this.getItemSorted(["traitchaotique"])
- }
- getTraitsEspeces() {
- return this.getItemSorted(["traitespece"])
- }
-
- /* -------------------------------------------- */
- getAspect() {
- return (this.system.balance.loi > this.system.balance.chaos) ? this.system.balance.loi : this.system.balance.chaos
- }
- getMarge() {
- return Math.abs(this.system.balance.loi - this.system.balance.chaos)
- }
- getAlignement() {
- return (this.system.balance.loi > this.system.balance.chaos) ? "loyal" : "chaotique"
- }
-
- /* -------------------------------------------- */
- getSkills() {
- let comp = []
- for (let item of this.items) {
- item = foundry.utils.duplicate(item)
- if (item.type == "competence") {
- item.system.attribut1total = item.system.niveau + (this.system.attributs[item.system.attribut1]?.value || 0)
- item.system.attribut2total = item.system.niveau + (this.system.attributs[item.system.attribut2]?.value || 0)
- item.system.attribut3total = item.system.niveau + (this.system.attributs[item.system.attribut3]?.value || 0)
- if (item.system.niveau == 0) {
- item.system.attribut1total -= 3
- item.system.attribut2total -= 3
- item.system.attribut3total -= 3
- }
- item.system.attribut1label = this.system.attributs[item.system.attribut1]?.label || ""
- item.system.attribut2label = this.system.attributs[item.system.attribut2]?.label || ""
- item.system.attribut3label = this.system.attributs[item.system.attribut3]?.label || ""
- comp.push(item)
- }
- }
- MournbladeCYD2Utility.sortArrayObjectsByName(comp)
- return comp
- }
-
- /* ----------------------- --------------------- */
- addMember(actorId) {
- let members = foundry.utils.duplicate(this.system.members)
- members.push({ id: actorId })
- this.update({ 'system.members': members })
- }
- async removeMember(actorId) {
- let members = this.system.members.filter(it => it.id != actorId)
- this.update({ 'system.members': members })
- }
-
- /* -------------------------------------------- */
- getDefenseBase() {
- return Math.max(this.system.attributs.tre.value, this.system.attributs.adr.value)
- }
-
- /* -------------------------------------------- */
- getVitesseBase() {
- return 5 + __vitesseBonus[this.system.attributs.adr.value]
- }
- /* -------------------------------------------- */
- getProtection() {
- let equipProtection = 0
- for (let armor of this.items) {
- if (armor.type == "protection" && armor.system.equipped) {
- equipProtection += Number(armor.system.protection)
- }
- }
- if (equipProtection < 4) {
- return 4 + equipProtection // Cas des boucliers + sans armure
- }
- return equipProtection // Uniquement la protection des armures + boucliers
- }
-
- /* -------------------------------------------- */
- getCombatValues() {
- if (this.type == "cellule") {
- return {
- initBase: 0,
- initTotal: 0,
- bonusDegats: 0,
- bonusDegatsTotal: 0,
- vitesseBase: 0,
- vitesseTotal: 0,
- defenseBase: 0,
- protection: 0,
- defenseTotal: 0
- }
- }
-
- let combat = {
- initBase: this.system.attributs.adr.value,
- initTotal: this.system.attributs.adr.value + this.system.combat.initbonus,
- bonusDegats: this.getBonusDegats(),
- bonusDegatsTotal: this.getBonusDegats() + this.system.combat.bonusdegats,
- vitesseBase: this.getVitesseBase(),
- vitesseTotal: this.getVitesseBase() + this.system.combat.vitessebonus,
- defenseBase: this.getDefenseBase(),
- protection: this.getProtection(),
- defenseTotal: this.getDefenseBase() + this.system.combat.defensebonus + this.getProtection() - this.getTotalAdversite() + (this.system.combat.defensetotale ? 3 : 0)
- }
- return combat
- }
-
- /* -------------------------------------------- */
- prepareBaseData() {
- }
-
- /* -------------------------------------------- */
- async prepareData() {
- super.prepareData();
- }
-
- /* -------------------------------------------- */
- prepareDerivedData() {
-
- if (this.type == 'personnage') {
- let talentBonus = this.getVigueurBonus()
- let vigueur = Math.floor((this.system.attributs.pui.value + this.system.attributs.tre.value) / 2) + talentBonus + this.system.sante.vigueurmodifier
- if (vigueur != this.system.sante.vigueur) {
- this.update({ 'system.sante.vigueur': vigueur })
- }
-
- let seuilPouvoirBonus = this.getSeuilPouvoirBonus()
- let seuilPouvoir = Math.floor((this.system.attributs.tre.value + this.system.attributs.cla.value) / 2) + seuilPouvoirBonus + this.system.ame.seuilpouvoirmodifier
- if (seuilPouvoir != this.system.ame.seuilpouvoir) {
- this.update({ 'system.ame.seuilpouvoir': seuilPouvoir })
- }
- }
- super.prepareDerivedData()
- }
-
- /* -------------------------------------------- */
- _preUpdate(changed, options, user) {
- if (changed?.system?.sante?.etat && changed?.system?.sante?.etat != this.system.sante.etat) {
- setTimeout(() => {
- this.processCombativite(changed.system.sante)
- }, 800)
- }
- if (changed?.system?.ame?.etat && changed?.system?.ame?.etat != this.system.ame.etat) {
- setTimeout(() => {
- this.processAme(changed.system.ame)
- }, 800)
- }
- super._preUpdate(changed, options, user);
- }
-
- /* -------------------------------------------- */
- _onUpdate(data, options, user) {
- super._onUpdate(data, options, user);
- }
- /* -------------------------------------------- */
- getItemById(id) {
- let item = this.items.find(item => item.id == id);
- if (item) {
- item = foundry.utils.duplicate(item)
- }
- return item;
- }
-
- /* -------------------------------------------- */
- async equipItem(itemId) {
- let item = this.items.find(item => item.id == itemId)
- if (item && item.system) {
- let update = { _id: item.id, "system.equipped": !item.system.equipped }
- await this.updateEmbeddedDocuments('Item', [update]); // Updates one EmbeddedEntity
- }
- }
-
- /* -------------------------------------------- */
- editItemField(itemId, itemType, itemField, dataType, value) {
- let item = this.items.find(item => item.id == itemId)
- if (item) {
- console.log("Item ", item, itemField, dataType, value)
- if (dataType.toLowerCase() == "number") {
- value = Number(value)
- } else {
- value = String(value)
- }
- let update = { _id: item.id, [`system.${itemField}`]: value };
- this.updateEmbeddedDocuments("Item", [update])
- }
- }
-
- /* -------------------------------------------- */
- checkAttribut(attribut, minLevel) {
- let attr = this.system.attributs.find(at => at.labelnorm == attribut.toLowerCase())
- if (attr && attr.value >= minLevel) {
- return { isValid: true, attr: foundry.utils.duplicate(attr) }
- }
- return { isValid: false }
- }
- /* -------------------------------------------- */
- checkAttributOrCompetenceLevel(compName, minLevel) {
- let comp = this.items.find(i => i.type == "competence" && i.name.toLowerCase() == compName.toLowerCase() && i.system.niveau >= minLevel)
- if (comp) {
- return { isValid: true, item: foundry.utils.duplicate(comp) }
- } else {
- for (let attrKey in this.system.attributs) {
- if (this.system.attributs[attrKey].label.toLowerCase() == compName.toLowerCase() && this.system.attributs[attrKey].value >= minLevel) {
- return { isValid: true, item: foundry.utils.duplicate(this.system.attributs[attrKey]) }
- }
- }
- }
- return { isValid: false, warningMessage: `Prérequis insuffisant : la compétence/attribut ${compName} doit être de niveau ${minLevel} au minimum` }
- }
- /* -------------------------------------------- */
- addCompetenceBonus(compName, bonus, baCost) {
- let comp = this.items.find(i => i.type == "competence" && i.name.toLowerCase() == compName.toLowerCase())
- if (comp) {
- comp = foundry.utils.duplicate(comp)
- comp.system.bonus = bonus
- comp.system.baCost = baCost
- return { isValid: true, item: comp }
- }
- return { isValid: false, warningMessage: `Compétence ${compName} non trouvée` }
- }
- /* -------------------------------------------- */
- checkIfCompetence(compName) {
- let comp = this.items.find(i => i.type == "competence" && i.name.toLowerCase() == compName.toLowerCase())
- if (comp) {
- return { isValid: true, item: comp }
- }
- return { isValid: false }
- }
- /* -------------------------------------------- */
- getVigueur() {
- return this.system.sante.vigueur
- }
-
- /* -------------------------------------------- */
- getVigueurBonus() {
- let talents = this.items.filter(item => item.type == "talent" && item.system.isautomated)
- let bonus = 0
- for (let talent of talents) {
- for (let auto of talent.system.automations) {
- if (auto.eventtype == "bonus-permanent" && auto.bonusname == "vigueur") {
- bonus += Number(auto.bonus || 0)
- }
- }
- }
- return bonus
- }
-
- /* -------------------------------------------- */
- getSeuilPouvoir() {
- return this.system.ame.seuilpouvoir
- }
-
- /* -------------------------------------------- */
- getSeuilPouvoirBonus() {
- let talents = this.items.filter(item => item.type == "talent" && item.system.isautomated)
- let bonus = 0
- for (let talent of talents) {
- for (let auto of talent.system.automations) {
- if (auto.eventtype == "bonus-permanent" && auto.bonusname == "seuilpouvoir") {
- bonus += Number(auto.bonus || 0)
- }
- }
- }
- return bonus
- }
-
- /* -------------------------------------------- */
- getBonneAventure() {
- return this.system.bonneaventure.actuelle
- }
- /* -------------------------------------------- */
- checkBonneAventure(cost) {
- return (this.system.bonneaventure.actuelle >= cost)
- }
- /* -------------------------------------------- */
- changeBonneAventure(value) {
- let newBA = this.system.bonneaventure.actuelle
- newBA += value
- this.update({ 'system.bonneaventure.actuelle': newBA })
- }
-
- /* -------------------------------------------- */
- getEclat() {
- return this.system.eclat.value
- }
-
- /* -------------------------------------------- */
- changeEclat(value) {
- let newE = this.system.eclat.value
- newE += value
- this.update({ 'system.eclat.value': newE })
- }
-
- /* -------------------------------------------- */
- compareName(a, b) {
- if (a.name < b.name) {
- return -1;
- }
- if (a.name > b.name) {
- return 1;
- }
- return 0;
- }
-
- /* -------------------------------------------- */
- getAttribute(attrKey) {
- return this.system.attributes[attrKey]
- }
-
- /* -------------------------------------------- */
- getBonusDegats() {
- return 0;
- }
-
- /* -------------------------------------------- */
- changeEtatCombativite(value) {
- if (value === "vaincu") {
- value = 200
- }
- let sante = foundry.utils.duplicate(this.system.sante)
- sante.etat += Number(value)
- sante.etat = Math.max(sante.etat, 0)
- sante.etat = Math.min(sante.etat, this.system.sante.nbcombativite)
- this.update({ 'system.sante': sante })
- if (sante.etat == this.system.sante.nbcombativite) {
- ChatMessage.create({ content: `${this.name} est vaincu !` })
- }
- // Duplicated ! this.processCombativite(sante)
- }
-
- /* -------------------------------------------- */
- changeEtatAme(value) {
- if (value === "brise") {
- value = 200
- }
- let ame = foundry.utils.duplicate(this.system.ame)
- ame.etat += Number(value)
- ame.etat = Math.max(ame.etat, 0)
- ame.etat = Math.min(ame.etat, this.system.ame.nbame - 1)
- this.update({ 'system.ame': ame })
- if (ame.etat == this.system.ame.nbame - 1) {
- ChatMessage.create({ content: `${this.name} est brisé !` })
- }
- }
-
- /* -------------------------------------------- */
- processCombativite(sante) {
- sante = sante || foundry.utils.duplicate(this.system.sante)
- // Gestion des états affaibli et très affaibli
- if (sante.etat == this.system.sante.nbcombativite - 2 || sante.etat == this.system.sante.nbcombativite - 1) {
- if (sante.etat == this.system.sante.nbcombativite - 2 && this.items.find(item => item.type == "talent" && item.name.toLowerCase() == "encaissement")) {
- ChatMessage.create({ content: `${this.name} ne subit pas les 2 adversités rouge grâce à Encaissement. Pensez à les ajouter à la fin de la scène !` })
- } else if (sante.etat == this.system.sante.nbcombativite - 1 && this.items.find(item => item.type == "talent" && item.name.toLowerCase().includes("vaillant"))) {
- ChatMessage.create({ content: `${this.name} ne subit pas les 2 adversités rouge grâce à Vaillant. Pensez à les ajouter à la fin de la scène !` })
- } else {
- ChatMessage.create({ content: `${this.name} subit 2 adversités rouge !` })
- this.incDecAdversite("rouge", 2)
- }
- }
- }
-
- /* -------------------------------------------- */
- processAme(ame) {
- ame = ame || foundry.utils.duplicate(this.system.ame)
- // Gestion des états Traumatisé, Très Traumatisé et Brisé
- if (ame.etat == this.system.ame.nbame - 3 || ame.etat == this.system.ame.nbame - 2 || ame.etat == this.system.ame.nbame - 1) {
- if (ame.etat == this.system.ame.nbame - 3) {
- ChatMessage.create({ content: `${this.name} est Traumatisé !` })
- } else if (ame.etat == this.system.ame.nbame - 2) {
- ChatMessage.create({ content: `${this.name} est Très Traumatisé !` })
- } else if (ame.etat == this.system.ame.nbame - 1) {
- ChatMessage.create({ content: `${this.name} est Brisé !` })
- }
- }
- }
-
- /* -------------------------------------------- */
- async equipGear(equipmentId) {
- let item = this.items.find(item => item.id == equipmentId);
- if (item?.system?.data) {
- let update = { _id: item.id, "system.equipped": !item.system.equipped };
- await this.updateEmbeddedDocuments('Item', [update]); // Updates one EmbeddedEntity
- }
- }
-
- /* -------------------------------------------- */
- getSubActors() {
- let subActors = [];
- for (let id of this.system.subactors) {
- subActors.push(foundry.utils.duplicate(game.actors.get(id)));
- }
- return subActors;
- }
- /* -------------------------------------------- */
- async addSubActor(subActorId) {
- let subActors = foundry.utils.duplicate(this.system.subactors);
- subActors.push(subActorId);
- await this.update({ 'system.subactors': subActors });
- }
- /* -------------------------------------------- */
- async delSubActor(subActorId) {
- let newArray = [];
- for (let id of this.system.subactors) {
- if (id != subActorId) {
- newArray.push(id);
- }
- }
- await this.update({ 'system.subactors': newArray });
- }
-
- /* -------------------------------------------- */
- getTotalAdversite() {
- return this.system.adversite.bleue + this.system.adversite.rouge + this.system.adversite.noire
- }
-
- /* -------------------------------------------- */
- async incDecAdversite(adv, incDec = 0) {
- let adversite = foundry.utils.duplicate(this.system.adversite)
- adversite[adv] += Number(incDec)
- adversite[adv] = Math.max(adversite[adv], 0)
- adversite[adv] = Math.min(adversite[adv], 20)
- this.update({ 'system.adversite': adversite })
- }
- /* -------------------------------------------- */
- async incDecQuantity(objetId, incDec = 0) {
- let objetQ = this.items.get(objetId)
- if (objetQ) {
- let newQ = objetQ.system.quantite + incDec
- newQ = Math.max(newQ, 0)
- await this.updateEmbeddedDocuments('Item', [{ _id: objetQ.id, 'system.quantite': newQ }]); // pdates one EmbeddedEntity
- }
- }
-
- /* -------------------------------------------- */
- computeRichesse() {
- let valueSC = 0
- for (let monnaie of this.items) {
- if (monnaie.type == "monnaie") {
- valueSC += Number(monnaie.system.prixsc) * Number(monnaie.system.quantite)
- }
- }
- return MournbladeCYD2Utility.computeMonnaieDetails(valueSC)
- }
-
- /* -------------------------------------------- */
- computeValeurEquipement() {
- let valueSC = 0
- for (let equip of this.items) {
- if (equip.type == "equipement" || equip.type == "arme" || equip.type == "protection") {
- valueSC += Number(equip.system.prixsc) * Number(equip.system.quantite ?? 1)
- valueSC += (Number(equip.system.prixca) * Number(equip.system.quantite ?? 1)) * 20
- valueSC += (Number(equip.system.prixpo) * Number(equip.system.quantite ?? 1)) * 400
- }
- }
- return MournbladeCYD2Utility.computeMonnaieDetails(valueSC)
- }
-
- /* -------------------------------------------- */
- getCompetence(compId) {
- return this.items.get(compId)
- }
-
- /* -------------------------------------------- */
- async setPredilectionUsed(compId, predIdx) {
- let comp = this.items.get(compId)
- let pred = foundry.utils.duplicate(comp.system.predilections)
- pred[predIdx].used = true
- await this.updateEmbeddedDocuments('Item', [{ _id: compId, 'system.predilections': pred }])
- }
-
- /* -------------------------------------------- */
- getInitiativeScore() {
- let init = this.getFlag("world", "last-initiative")
- return init || -1
- }
-
- /* -------------------------------------------- */
- getBestAttackValue() {
- let attackList = this.items.filter(item => (item.type == "arme" || item.type == "talent") && item.system.equipped)
- let maxOff = 0
- let bestArme
- for (let arme of attackList) {
- if (arme.type == "arme") {
- arme = this.prepareArme(arme)
- }
- if (arme.system.totalOffensif > maxOff) {
- maxOff = arme.system.totalOffensif
- bestArme = foundry.utils.duplicate(arme)
- }
- }
- return bestArme
- }
-
- /* -------------------------------------------- */
- getBestDefenseValue() {
- let defenseList = this.items.filter(item => (item.type == "arme") && item.system.equipped)
- let maxDef = 0
- let bestArme
- for (let arme of defenseList) {
- if (arme.type == "arme") {
- arme = this.prepareArme(arme)
- }
- if (arme.system.totalDefensif > maxDef) {
- maxDef = arme.system.totalDefensif
- bestArme = foundry.utils.duplicate(arme)
- }
- }
- return bestArme
- }
-
- /* -------------------------------------------- */
- searchRelevantTalents(competence) {
- let talents = []
-
- for (let talent of this.items) {
- if (talent.type == "talent" && talent.system.isautomated && talent.system.automations.length > 0) {
- for (let auto of talent.system.automations) {
- if (auto.eventtype === "prepare-roll") {
- if (auto.competence.toLowerCase() == competence.name.toLowerCase()) {
- talent = foundry.utils.duplicate(talent)
- talent.system.bonus = auto.bonus
- talent.system.baCost = auto.baCost
- talents.push(talent)
- }
- }
- }
- }
- }
- return talents
- }
-
- /* -------------------------------------------- */
- buildListeAdversites() {
- return []
- }
-
- /* -------------------------------------------- */
- getCommonRollData(attrKey = undefined, compId = undefined, compName = undefined) {
- let rollData = MournbladeCYD2Utility.getBasicRollData()
- rollData.alias = this.name
- rollData.actorImg = this.img
- rollData.actorId = this.id
- rollData.tokenId = this.token?.id
- rollData.img = this.img
- rollData.attributs = MournbladeCYD2Utility.getAttributs()
- rollData.maitriseId = "none"
- rollData.nbEclat = this.system.eclat.value
- rollData.nbBA = this.system.bonneaventure.actuelle
- rollData.nbAdversites = this.getTotalAdversite()
- rollData.talents = []
- rollData.attrKey2 = "none"
- rollData.coupDevastateur = this.items.find(it => it.type == "talent" && it.name.toLowerCase() == "coup dévastateur" && !it.system.used)
- rollData.hasAmbidextre = this.items.find(it => it.type == "talent" && it.name.toLowerCase() == "ambidextre")
- rollData.hasFeinte = this.system.bonneaventure.actuelle > 0 && this.items.find(it => it.type == "talent" && it.name.toLowerCase() == "feinte")
- rollData.isMonte = this.system.combat.monte
- rollData.config = game.system.mournbladecyd2.config
-
- if (attrKey) {
- rollData.attrKey = attrKey
- if (attrKey != "tochoose") {
- rollData.actionImg = "systems/fvtt-mournblade-cyd2/assets/icons/" + this.system.attributs[attrKey].labelnorm + ".webp"
- rollData.attr = foundry.utils.duplicate(this.system.attributs[attrKey])
- }
- }
- if (compId) {
- rollData.competence = foundry.utils.duplicate(this.items.get(compId) || {})
- let maitrises = [{ key: "none", label: "Aucune" }]
- rollData.competence.system.predilections.forEach(function (item) {
- if (item.maitrise) {
- maitrises.push({ key: item.id, label: item.name });
- }
- })
- rollData.maitrises = maitrises // rollData.competence.system.predilections.filter(p => p.maitrise)
- rollData.actionImg = rollData.competence?.img
- rollData.talents = this.searchRelevantTalents(rollData.competence)
- }
- if (compName) {
- rollData.competence = foundry.utils.duplicate(this.items.find(item => item.name.toLowerCase() == compName.toLowerCase()) || {})
- rollData.actionImg = rollData.competence?.img
- }
- return rollData
- }
-
- /* -------------------------------------------- */
- async rollAttribut(attrKey, isInit = false) {
- let rollData = this.getCommonRollData(attrKey)
- rollData.multiplier = (isInit) ? 1 : 2
- rollData.isInit = isInit
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
-
- /* -------------------------------------------- */
- async rollCompetence(attrKey, compId) {
- let rollData = this.getCommonRollData(attrKey, compId)
- rollData.multiplier = 1 // Attr multiplier, always 1 in competence mode
- console.log("RollDatra", rollData)
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
-
- /* -------------------------------------------- */
- async rollArmeOffensif(armeId) {
- let arme = this.items.get(armeId)
- if (arme.type == "arme") {
- arme = this.prepareArme(arme)
- }
- let rollData = this.getCommonRollData(arme.system.attrKey, arme.system.competence._id)
- rollData.arme = arme
- MournbladeCYD2Utility.updateWithTarget(rollData)
- console.log("ARME!", rollData)
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
- /* -------------------------------------------- */
- async rollAssommer() {
- let rollData = this.getCommonRollData("pui", undefined, "Filouterie")
- rollData.assomer = true
- rollData.conditionsCommunes = true
- MournbladeCYD2Utility.updateWithTarget(rollData)
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
- /* -------------------------------------------- */
- async rollCoupBas() {
- let rollData = this.getCommonRollData("pui", undefined, "Mêlée")
- rollData.coupBas = true
- rollData.conditionsCommunes = true
- MournbladeCYD2Utility.updateWithTarget(rollData)
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
- /* -------------------------------------------- */
- async rollImmobiliser() {
- let rollData = this.getCommonRollData("pui", undefined, "Mêlée")
- rollData.immobiliser = true
- rollData.conditionsCommunes = true
- rollData.cibleconsciente = true
- MournbladeCYD2Utility.updateWithTarget(rollData)
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
- /* -------------------------------------------- */
- async rollRepousser() {
- let rollData = this.getCommonRollData("pui", undefined, "Mêlée")
- rollData.repousser = true
- rollData.conditionsCommunes = true
- rollData.cibleconsciente = true
- MournbladeCYD2Utility.updateWithTarget(rollData)
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
- /* -------------------------------------------- */
- async rollDesengager() {
- let rollData = this.getCommonRollData("adr", undefined, "Mouvements")
- rollData.desengager = true
- rollData.conditionsCommunes = true
- MournbladeCYD2Utility.updateWithTarget(rollData)
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
-
- /* -------------------------------------------- */
- async rollArmeDegats(armeId, targetVigueur = undefined, rollDataInput = undefined) {
- let arme = this.items.get(armeId)
- if (arme.type == "arme") {
- arme = this.prepareArme(arme)
- }
- console.log("DEGATS", arme, targetVigueur, rollDataInput)
- let roll
- let bonus = 0
- let bonus2 = 0
-
- if (rollDataInput?.applyCoupDevastateur) {
- bonus2 = Math.floor(this.system.attributs.pui.value / 2)
- let talent = this.items.find(item => item.type == "talent" && item.name.toLowerCase() == "coup dévastateur")
- this.updateEmbeddedDocuments('Item', [{ _id: talent.id, 'system.used': true }])
- }
-
- if (rollDataInput?.isHeroique) {
- if (rollDataInput?.attaqueCharge) {
- bonus = 5
- }
- if (rollDataInput?.chargeCavalerie) {
- bonus = 6
- }
- roll = await new Roll("2d10rr10+" + arme.system.totalDegats + "+" + bonus + "+" + bonus2).roll()
- } else {
- if (rollDataInput?.attaqueCharge) {
- bonus = 3
- }
- if (rollDataInput?.chargeCavalerie) {
- bonus = 4
- }
- roll = await new Roll("1d10+" + arme.system.totalDegats + "+" + bonus + "+" + bonus2).roll()
- }
- await MournbladeCYD2Utility.showDiceSoNice(roll, game.settings.get("core", "rollMode"));
- let nbEtatPerdus = 0
- if (targetVigueur) {
- nbEtatPerdus = Math.floor(roll.total / targetVigueur)
- }
- //console.log(roll)
- let rollData = {
- arme: arme,
- finalResult: roll.total,
- formula: roll.formula,
- alias: this.name,
- actorImg: this.img,
- actorId: this.id,
- defenderTokenId: rollDataInput?.defenderTokenId,
- actionImg: arme.img,
- targetVigueur: targetVigueur,
- nbEtatPerdus: nbEtatPerdus
- }
- MournbladeCYD2Utility.createChatWithRollMode(rollData.alias, {
- content: await renderTemplate(`systems/fvtt-mournblade-cyd2/templates/chat-degats-result.html`, rollData)
- })
-
- if (rollDataInput?.defenderTokenId && nbEtatPerdus) {
- MournbladeCYD2Utility.applyCombativite(rollDataInput, nbEtatPerdus)
- }
-
- }
-}
diff --git a/.history/modules/mournblade-cyd2-actor_20251026082310.js b/.history/modules/mournblade-cyd2-actor_20251026082310.js
deleted file mode 100644
index d8049de..0000000
--- a/.history/modules/mournblade-cyd2-actor_20251026082310.js
+++ /dev/null
@@ -1,882 +0,0 @@
-/* -------------------------------------------- */
-import { MournbladeCYD2Utility } from "./mournblade-cyd2-utility.js";
-import { MournbladeCYD2RollDialog } from "./mournblade-cyd2-roll-dialog.js";
-
-/* -------------------------------------------- */
-const __degatsBonus = [-2, -2, -1, -1, 0, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 8, 8, 9, 9, 10, 10]
-const __vitesseBonus = [-2, -2, -1, -1, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8]
-
-/* -------------------------------------------- */
-/**
- * Extend the base Actor entity by defining a custom roll data structure which is ideal for the Simple system.
- * @extends {Actor}
- */
-export class MournbladeCYD2Actor extends Actor {
-
- /* -------------------------------------------- */
- /**
- * Override the create() function to provide additional SoS functionality.
- *
- * This overrided create() function adds initial items
- * Namely: Basic skills, money,
- *
- * @param {Object} data Barebones actor data which this function adds onto.
- * @param {Object} options (Unused) Additional options which customize the creation workflow.
- *
- */
-
- static async create(data, options) {
-
- // Case of compendium global import
- if (data instanceof Array) {
- return super.create(data, options);
- }
- // If the created actor has items (only applicable to duplicated actors) bypass the new actor creation logic
- if (data.items) {
- let actor = super.create(data, options);
- return actor;
- }
-
- if (data.type == 'personnage') {
- const skills = await MournbladeCYD2Utility.loadCompendium("fvtt-mournblade-cyd2.skills")
- data.items = skills.map(i => i.toObject())
- }
- if (data.type == 'creature') {
- const skills = await MournbladeCYD2Utility.loadCompendium("fvtt-mournblade-cyd2.skills-creatures")
- data.items = skills.map(i => i.toObject())
- data.items.push({ name: "Arme naturelle 1", type: 'arme', img: "systems/fvtt-mournblade-cyd2/assets/icons/melee.webp", system: { typearme: "contact", bonusmaniementoff: 0, seuildefense: 0, degats: "0" } })
- data.items.push({ name: "Arme naturelle 2", type: 'arme', img: "systems/fvtt-mournblade-cyd2/assets/icons/melee.webp", system: { typearme: "contact", bonusmaniementoff: 0, seuildefense: 0, degats: "0" } })
- }
-
- return super.create(data, options);
- }
-
- /* -------------------------------------------- */
- getBonusDefenseFromTalents() {
- let talents = this.items.filter(item => item.type == "talent" && item.system.isautomated)
- let bonus = 0
- for (let talent of talents) {
- for (let auto of talent.system.automations) {
- if (auto.eventtype == "bonus-permanent" && auto.bonusname == "bonus-defensif") {
- bonus += Number(auto.bonus || 0)
- }
- }
- }
- return bonus
- }
-
- /* -------------------------------------------- */
- prepareArme(arme) {
- if (this.type == "cellule") {
- return arme
- }
-
- arme = foundry.utils.duplicate(arme)
- let combat = this.getCombatValues()
- if (arme.system.typearme == "contact" || arme.system.typearme == "contactjet") {
- let bonusDefense = this.getBonusDefenseFromTalents()
- arme.system.competence = foundry.utils.duplicate(this.items.find(item => item.type == "competence" && item.name.toLowerCase() == "mêlée"))
- arme.system.attrKey = "pui"
- arme.system.totalDegats = arme.system.degats + "+" + combat.bonusDegatsTotal
- arme.system.totalOffensif = this.system.attributs.pui.value + arme.system.competence.system.niveau + arme.system.bonusmaniementoff + (this.system.combat.monte ? 3 : 0)
- arme.system.totalDefensif = combat.defenseTotal + arme.system.competence.system.niveau + arme.system.seuildefense + bonusDefense + (this.system.combat.monte ? 3 : 0)
- console.log("Arme", arme.system.totalDefensif, combat, arme.system.competence.system.niveau, arme.system.seuildefense, bonusDefense)
- arme.system.isdefense = true
- arme.system.isMelee = true
- arme.system.isDistance = false
- }
- if (arme.system.typearme == "jet" || arme.system.typearme == "tir") {
- arme.system.competence = foundry.utils.duplicate(this.items.find(item => item.type == "competence" && item.name.toLowerCase() == "armes à distance"))
- arme.system.attrKey = "adr"
- arme.system.totalOffensif = this.system.attributs.adr.value + arme.system.competence.system.niveau + arme.system.bonusmaniementoff
- arme.system.totalDegats = arme.system.degats
- arme.system.isMelee = false
- arme.system.isDistance = true
- if (arme.system.isdefense) {
- arme.system.totalDefensif = combat.defenseTotal + arme.system.competence.system.niveau + arme.system.seuildefense
- }
- }
- return arme
- }
-
- /* -------------------------------------------- */
- getItemSorted(types) {
- let items = this.items.filter(item => types.includes(item.type)) || []
- MournbladeCYD2Utility.sortArrayObjectsByName(items)
- return items
- }
- getWeapons() {
- let armes = []
- for (let arme of this.items) {
- if (arme.type == "arme") {
- armes.push(this.prepareArme(arme))
- }
- }
- MournbladeCYD2Utility.sortArrayObjectsByName(armes)
- return armes
- }
- getMonnaies() {
- return this.getItemSorted(["monnaie"])
- }
- getEquipments() {
- return this.getItemSorted(["equipement"])
- }
- getArtefacts() {
- return this.getItemSorted(["artefact"])
- }
- getArmors() {
- return this.getItemSorted(["protection"])
- }
- getHistoriques() {
- return this.getItemSorted(["historique"])
- }
- getProfils() {
- return this.getItemSorted(["profil"])
- }
- getTalents() {
- return this.getItemSorted(["talent"])
- }
- getRessources() {
- return this.getItemSorted(["ressource"])
- }
- getContacts() {
- return this.getItemSorted(["contact"])
- }
- getMutations() {
- return this.getItemSorted(["mutation"])
- }
- getDons() {
- return this.getItemSorted(["don"])
- }
- getPactes() {
- return this.getItemSorted(["pacte"])
- }
- getTendances() {
- return this.getItemSorted(["tendance"])
- }
- getRunes() {
- return this.getItemSorted(["rune"])
- }
- getTraitsChaotiques() {
- return this.getItemSorted(["traitchaotique"])
- }
- getTraitsEspeces() {
- return this.getItemSorted(["traitespece"])
- }
-
- /* -------------------------------------------- */
- getAspect() {
- return (this.system.balance.loi > this.system.balance.chaos) ? this.system.balance.loi : this.system.balance.chaos
- }
- getMarge() {
- return Math.abs(this.system.balance.loi - this.system.balance.chaos)
- }
- getAlignement() {
- return (this.system.balance.loi > this.system.balance.chaos) ? "loyal" : "chaotique"
- }
-
- /* -------------------------------------------- */
- getSkills() {
- let comp = []
- for (let item of this.items) {
- item = foundry.utils.duplicate(item)
- if (item.type == "competence") {
- item.system.attribut1total = item.system.niveau + (this.system.attributs[item.system.attribut1]?.value || 0)
- item.system.attribut2total = item.system.niveau + (this.system.attributs[item.system.attribut2]?.value || 0)
- item.system.attribut3total = item.system.niveau + (this.system.attributs[item.system.attribut3]?.value || 0)
- if (item.system.niveau == 0) {
- item.system.attribut1total -= 3
- item.system.attribut2total -= 3
- item.system.attribut3total -= 3
- }
- item.system.attribut1label = this.system.attributs[item.system.attribut1]?.label || ""
- item.system.attribut2label = this.system.attributs[item.system.attribut2]?.label || ""
- item.system.attribut3label = this.system.attributs[item.system.attribut3]?.label || ""
- comp.push(item)
- }
- }
- MournbladeCYD2Utility.sortArrayObjectsByName(comp)
- return comp
- }
-
- /* ----------------------- --------------------- */
- addMember(actorId) {
- let members = foundry.utils.duplicate(this.system.members)
- members.push({ id: actorId })
- this.update({ 'system.members': members })
- }
- async removeMember(actorId) {
- let members = this.system.members.filter(it => it.id != actorId)
- this.update({ 'system.members': members })
- }
-
- /* -------------------------------------------- */
- getDefenseBase() {
- return Math.max(this.system.attributs.tre.value, this.system.attributs.adr.value)
- }
-
- /* -------------------------------------------- */
- getVitesseBase() {
- return 5 + __vitesseBonus[this.system.attributs.adr.value]
- }
- /* -------------------------------------------- */
- getProtection() {
- let equipProtection = 0
- for (let armor of this.items) {
- if (armor.type == "protection" && armor.system.equipped) {
- equipProtection += Number(armor.system.protection)
- }
- }
- if (equipProtection < 4) {
- return 4 + equipProtection // Cas des boucliers + sans armure
- }
- return equipProtection // Uniquement la protection des armures + boucliers
- }
-
- /* -------------------------------------------- */
- getCombatValues() {
- if (this.type == "cellule") {
- return {
- initBase: 0,
- initTotal: 0,
- bonusDegats: 0,
- bonusDegatsTotal: 0,
- vitesseBase: 0,
- vitesseTotal: 0,
- defenseBase: 0,
- protection: 0,
- defenseTotal: 0
- }
- }
-
- let combat = {
- initBase: this.system.attributs.adr.value,
- initTotal: this.system.attributs.adr.value + this.system.combat.initbonus,
- bonusDegats: this.getBonusDegats(),
- bonusDegatsTotal: this.getBonusDegats() + this.system.combat.bonusdegats,
- vitesseBase: this.getVitesseBase(),
- vitesseTotal: this.getVitesseBase() + this.system.combat.vitessebonus,
- defenseBase: this.getDefenseBase(),
- protection: this.getProtection(),
- defenseTotal: this.getDefenseBase() + this.system.combat.defensebonus + this.getProtection() - this.getTotalAdversite() + (this.system.combat.defensetotale ? 3 : 0)
- }
- return combat
- }
-
- /* -------------------------------------------- */
- prepareBaseData() {
- }
-
- /* -------------------------------------------- */
- async prepareData() {
- super.prepareData();
- }
-
- /* -------------------------------------------- */
- prepareDerivedData() {
-
- if (this.type == 'personnage') {
- let talentBonus = this.getVigueurBonus()
- let vigueur = Math.floor((this.system.attributs.pui.value + this.system.attributs.tre.value) / 2) + talentBonus + this.system.sante.vigueurmodifier
- if (vigueur != this.system.sante.vigueur) {
- this.update({ 'system.sante.vigueur': vigueur })
- }
-
- let seuilPouvoirBonus = this.getSeuilPouvoirBonus()
- let seuilPouvoir = Math.floor((this.system.attributs.tre.value + this.system.attributs.cla.value) / 2) + seuilPouvoirBonus + this.system.ame.seuilpouvoirmodifier
- if (seuilPouvoir != this.system.ame.seuilpouvoir) {
- this.update({ 'system.ame.seuilpouvoir': seuilPouvoir })
- }
- }
- super.prepareDerivedData()
- }
-
- /* -------------------------------------------- */
- _preUpdate(changed, options, user) {
- if (changed?.system?.sante?.etat && changed?.system?.sante?.etat != this.system.sante.etat) {
- setTimeout(() => {
- this.processCombativite(changed.system.sante)
- }, 800)
- }
- if (changed?.system?.ame?.etat && changed?.system?.ame?.etat != this.system.ame.etat) {
- setTimeout(() => {
- this.processAme(changed.system.ame)
- }, 800)
- }
- super._preUpdate(changed, options, user);
- }
-
- /* -------------------------------------------- */
- _onUpdate(data, options, user) {
- super._onUpdate(data, options, user);
- }
- /* -------------------------------------------- */
- getItemById(id) {
- let item = this.items.find(item => item.id == id);
- if (item) {
- item = foundry.utils.duplicate(item)
- }
- return item;
- }
-
- /* -------------------------------------------- */
- async equipItem(itemId) {
- let item = this.items.find(item => item.id == itemId)
- if (item && item.system) {
- let update = { _id: item.id, "system.equipped": !item.system.equipped }
- await this.updateEmbeddedDocuments('Item', [update]); // Updates one EmbeddedEntity
- }
- }
-
- /* -------------------------------------------- */
- editItemField(itemId, itemType, itemField, dataType, value) {
- let item = this.items.find(item => item.id == itemId)
- if (item) {
- console.log("Item ", item, itemField, dataType, value)
- if (dataType.toLowerCase() == "number") {
- value = Number(value)
- } else {
- value = String(value)
- }
- let update = { _id: item.id, [`system.${itemField}`]: value };
- this.updateEmbeddedDocuments("Item", [update])
- }
- }
-
- /* -------------------------------------------- */
- checkAttribut(attribut, minLevel) {
- let attr = this.system.attributs.find(at => at.labelnorm == attribut.toLowerCase())
- if (attr && attr.value >= minLevel) {
- return { isValid: true, attr: foundry.utils.duplicate(attr) }
- }
- return { isValid: false }
- }
- /* -------------------------------------------- */
- checkAttributOrCompetenceLevel(compName, minLevel) {
- let comp = this.items.find(i => i.type == "competence" && i.name.toLowerCase() == compName.toLowerCase() && i.system.niveau >= minLevel)
- if (comp) {
- return { isValid: true, item: foundry.utils.duplicate(comp) }
- } else {
- for (let attrKey in this.system.attributs) {
- if (this.system.attributs[attrKey].label.toLowerCase() == compName.toLowerCase() && this.system.attributs[attrKey].value >= minLevel) {
- return { isValid: true, item: foundry.utils.duplicate(this.system.attributs[attrKey]) }
- }
- }
- }
- return { isValid: false, warningMessage: `Prérequis insuffisant : la compétence/attribut ${compName} doit être de niveau ${minLevel} au minimum` }
- }
- /* -------------------------------------------- */
- addCompetenceBonus(compName, bonus, baCost) {
- let comp = this.items.find(i => i.type == "competence" && i.name.toLowerCase() == compName.toLowerCase())
- if (comp) {
- comp = foundry.utils.duplicate(comp)
- comp.system.bonus = bonus
- comp.system.baCost = baCost
- return { isValid: true, item: comp }
- }
- return { isValid: false, warningMessage: `Compétence ${compName} non trouvée` }
- }
- /* -------------------------------------------- */
- checkIfCompetence(compName) {
- let comp = this.items.find(i => i.type == "competence" && i.name.toLowerCase() == compName.toLowerCase())
- if (comp) {
- return { isValid: true, item: comp }
- }
- return { isValid: false }
- }
- /* -------------------------------------------- */
- getVigueur() {
- return this.system.sante.vigueur
- }
-
- /* -------------------------------------------- */
- getVigueurBonus() {
- let talents = this.items.filter(item => item.type == "talent" && item.system.isautomated)
- let bonus = 0
- for (let talent of talents) {
- for (let auto of talent.system.automations) {
- if (auto.eventtype == "bonus-permanent" && auto.bonusname == "vigueur") {
- bonus += Number(auto.bonus || 0)
- }
- }
- }
- return bonus
- }
-
- /* -------------------------------------------- */
- getSeuilPouvoir() {
- return this.system.ame.seuilpouvoir
- }
-
- /* -------------------------------------------- */
- getSeuilPouvoirBonus() {
- let talents = this.items.filter(item => item.type == "talent" && item.system.isautomated)
- let bonus = 0
- for (let talent of talents) {
- for (let auto of talent.system.automations) {
- if (auto.eventtype == "bonus-permanent" && auto.bonusname == "seuilpouvoir") {
- bonus += Number(auto.bonus || 0)
- }
- }
- }
- return bonus
- }
-
- /* -------------------------------------------- */
- getBonneAventure() {
- return this.system.bonneaventure.actuelle
- }
- /* -------------------------------------------- */
- checkBonneAventure(cost) {
- return (this.system.bonneaventure.actuelle >= cost)
- }
- /* -------------------------------------------- */
- changeBonneAventure(value) {
- let newBA = this.system.bonneaventure.actuelle
- newBA += value
- this.update({ 'system.bonneaventure.actuelle': newBA })
- }
-
- /* -------------------------------------------- */
- getEclat() {
- return this.system.eclat.value
- }
-
- /* -------------------------------------------- */
- changeEclat(value) {
- let newE = this.system.eclat.value
- newE += value
- this.update({ 'system.eclat.value': newE })
- }
-
- /* -------------------------------------------- */
- compareName(a, b) {
- if (a.name < b.name) {
- return -1;
- }
- if (a.name > b.name) {
- return 1;
- }
- return 0;
- }
-
- /* -------------------------------------------- */
- getAttribute(attrKey) {
- return this.system.attributes[attrKey]
- }
-
- /* -------------------------------------------- */
- getBonusDegats() {
- return 0;
- }
-
- /* -------------------------------------------- */
- changeEtatCombativite(value) {
- if (value === "vaincu") {
- value = 200
- }
- let sante = foundry.utils.duplicate(this.system.sante)
- sante.etat += Number(value)
- sante.etat = Math.max(sante.etat, 0)
- sante.etat = Math.min(sante.etat, this.system.sante.nbcombativite)
- this.update({ 'system.sante': sante })
- if (sante.etat == this.system.sante.nbcombativite) {
- ChatMessage.create({ content: `${this.name} est vaincu !` })
- }
- // Duplicated ! this.processCombativite(sante)
- }
-
- /* -------------------------------------------- */
- changeEtatAme(value) {
- if (value === "brise") {
- value = 200
- }
- let ame = foundry.utils.duplicate(this.system.ame)
- ame.etat += Number(value)
- ame.etat = Math.max(ame.etat, 0)
- ame.etat = Math.min(ame.etat, this.system.ame.nbame - 1)
- this.update({ 'system.ame': ame })
- if (ame.etat == this.system.ame.nbame - 1) {
- ChatMessage.create({ content: `${this.name} est brisé !` })
- }
- }
-
- /* -------------------------------------------- */
- processCombativite(sante) {
- sante = sante || foundry.utils.duplicate(this.system.sante)
- // Gestion des états affaibli et très affaibli
- if (sante.etat == this.system.sante.nbcombativite - 2 || sante.etat == this.system.sante.nbcombativite - 1) {
- if (sante.etat == this.system.sante.nbcombativite - 2 && this.items.find(item => item.type == "talent" && item.name.toLowerCase() == "encaissement")) {
- ChatMessage.create({ content: `${this.name} ne subit pas les 2 adversités rouge grâce à Encaissement. Pensez à les ajouter à la fin de la scène !` })
- } else if (sante.etat == this.system.sante.nbcombativite - 1 && this.items.find(item => item.type == "talent" && item.name.toLowerCase().includes("vaillant"))) {
- ChatMessage.create({ content: `${this.name} ne subit pas les 2 adversités rouge grâce à Vaillant. Pensez à les ajouter à la fin de la scène !` })
- } else {
- ChatMessage.create({ content: `${this.name} subit 2 adversités rouge !` })
- this.incDecAdversite("rouge", 2)
- }
- }
- }
-
- /* -------------------------------------------- */
- processAme(ame) {
- ame = ame || foundry.utils.duplicate(this.system.ame)
- // Gestion des états Traumatisé, Très Traumatisé et Brisé
- if (ame.etat == this.system.ame.nbame - 3 || ame.etat == this.system.ame.nbame - 2 || ame.etat == this.system.ame.nbame - 1) {
- if (ame.etat == this.system.ame.nbame - 3) {
- ChatMessage.create({ content: `${this.name} est Traumatisé !` })
- } else if (ame.etat == this.system.ame.nbame - 2) {
- ChatMessage.create({ content: `${this.name} est Très Traumatisé !` })
- } else if (ame.etat == this.system.ame.nbame - 1) {
- ChatMessage.create({ content: `${this.name} est Brisé !` })
- }
- }
- }
-
- /* -------------------------------------------- */
- async equipGear(equipmentId) {
- let item = this.items.find(item => item.id == equipmentId);
- if (item?.system?.data) {
- let update = { _id: item.id, "system.equipped": !item.system.equipped };
- await this.updateEmbeddedDocuments('Item', [update]); // Updates one EmbeddedEntity
- }
- }
-
- /* -------------------------------------------- */
- getSubActors() {
- let subActors = [];
- for (let id of this.system.subactors) {
- subActors.push(foundry.utils.duplicate(game.actors.get(id)));
- }
- return subActors;
- }
- /* -------------------------------------------- */
- async addSubActor(subActorId) {
- let subActors = foundry.utils.duplicate(this.system.subactors);
- subActors.push(subActorId);
- await this.update({ 'system.subactors': subActors });
- }
- /* -------------------------------------------- */
- async delSubActor(subActorId) {
- let newArray = [];
- for (let id of this.system.subactors) {
- if (id != subActorId) {
- newArray.push(id);
- }
- }
- await this.update({ 'system.subactors': newArray });
- }
-
- /* -------------------------------------------- */
- getTotalAdversite() {
- return this.system.adversite.bleue + this.system.adversite.rouge + this.system.adversite.noire
- }
-
- /* -------------------------------------------- */
- async incDecAdversite(adv, incDec = 0) {
- let adversite = foundry.utils.duplicate(this.system.adversite)
- adversite[adv] += Number(incDec)
- adversite[adv] = Math.max(adversite[adv], 0)
- adversite[adv] = Math.min(adversite[adv], 20)
- this.update({ 'system.adversite': adversite })
- }
- /* -------------------------------------------- */
- async incDecQuantity(objetId, incDec = 0) {
- let objetQ = this.items.get(objetId)
- if (objetQ) {
- let newQ = objetQ.system.quantite + incDec
- newQ = Math.max(newQ, 0)
- await this.updateEmbeddedDocuments('Item', [{ _id: objetQ.id, 'system.quantite': newQ }]); // pdates one EmbeddedEntity
- }
- }
-
- /* -------------------------------------------- */
- computeRichesse() {
- let valueSC = 0
- for (let monnaie of this.items) {
- if (monnaie.type == "monnaie") {
- valueSC += Number(monnaie.system.prixsc) * Number(monnaie.system.quantite)
- }
- }
- return MournbladeCYD2Utility.computeMonnaieDetails(valueSC)
- }
-
- /* -------------------------------------------- */
- computeValeurEquipement() {
- let valueSC = 0
- for (let equip of this.items) {
- if (equip.type == "equipement" || equip.type == "arme" || equip.type == "protection") {
- valueSC += Number(equip.system.prixsc) * Number(equip.system.quantite ?? 1)
- valueSC += (Number(equip.system.prixca) * Number(equip.system.quantite ?? 1)) * 20
- valueSC += (Number(equip.system.prixpo) * Number(equip.system.quantite ?? 1)) * 400
- }
- }
- return MournbladeCYD2Utility.computeMonnaieDetails(valueSC)
- }
-
- /* -------------------------------------------- */
- getCompetence(compId) {
- return this.items.get(compId)
- }
-
- /* -------------------------------------------- */
- async setPredilectionUsed(compId, predIdx) {
- let comp = this.items.get(compId)
- let pred = foundry.utils.duplicate(comp.system.predilections)
- pred[predIdx].used = true
- await this.updateEmbeddedDocuments('Item', [{ _id: compId, 'system.predilections': pred }])
- }
-
- /* -------------------------------------------- */
- getInitiativeScore() {
- let init = this.getFlag("world", "last-initiative")
- return init || -1
- }
-
- /* -------------------------------------------- */
- getBestAttackValue() {
- let attackList = this.items.filter(item => (item.type == "arme" || item.type == "talent") && item.system.equipped)
- let maxOff = 0
- let bestArme
- for (let arme of attackList) {
- if (arme.type == "arme") {
- arme = this.prepareArme(arme)
- }
- if (arme.system.totalOffensif > maxOff) {
- maxOff = arme.system.totalOffensif
- bestArme = foundry.utils.duplicate(arme)
- }
- }
- return bestArme
- }
-
- /* -------------------------------------------- */
- getBestDefenseValue() {
- let defenseList = this.items.filter(item => (item.type == "arme") && item.system.equipped)
- let maxDef = 0
- let bestArme
- for (let arme of defenseList) {
- if (arme.type == "arme") {
- arme = this.prepareArme(arme)
- }
- if (arme.system.totalDefensif > maxDef) {
- maxDef = arme.system.totalDefensif
- bestArme = foundry.utils.duplicate(arme)
- }
- }
- return bestArme
- }
-
- /* -------------------------------------------- */
- searchRelevantTalents(competence) {
- let talents = []
-
- for (let talent of this.items) {
- if (talent.type == "talent" && talent.system.isautomated && talent.system.automations.length > 0) {
- for (let auto of talent.system.automations) {
- if (auto.eventtype === "prepare-roll") {
- if (auto.competence.toLowerCase() == competence.name.toLowerCase()) {
- talent = foundry.utils.duplicate(talent)
- talent.system.bonus = auto.bonus
- talent.system.baCost = auto.baCost
- talents.push(talent)
- }
- }
- }
- }
- }
- return talents
- }
-
- /* -------------------------------------------- */
- buildListeAdversites() {
- return []
- }
-
- /* -------------------------------------------- */
- getCommonRollData(attrKey = undefined, compId = undefined, compName = undefined) {
- let rollData = MournbladeCYD2Utility.getBasicRollData()
- rollData.alias = this.name
- rollData.actorImg = this.img
- rollData.actorId = this.id
- rollData.tokenId = this.token?.id
- rollData.img = this.img
- rollData.attributs = MournbladeCYD2Utility.getAttributs()
- rollData.maitriseId = "none"
- rollData.nbEclat = this.system.eclat.value
- rollData.nbBA = this.system.bonneaventure.actuelle
- rollData.nbAdversites = this.getTotalAdversite()
- rollData.talents = []
- rollData.attrKey2 = "none"
- rollData.coupDevastateur = this.items.find(it => it.type == "talent" && it.name.toLowerCase() == "coup dévastateur" && !it.system.used)
- rollData.hasAmbidextre = this.items.find(it => it.type == "talent" && it.name.toLowerCase() == "ambidextre")
- rollData.hasFeinte = this.system.bonneaventure.actuelle > 0 && this.items.find(it => it.type == "talent" && it.name.toLowerCase() == "feinte")
- rollData.isMonte = this.system.combat.monte
- rollData.config = game.system.mournbladecyd2.config
-
- if (attrKey) {
- rollData.attrKey = attrKey
- if (attrKey != "tochoose") {
- rollData.actionImg = "systems/fvtt-mournblade-cyd2/assets/icons/" + this.system.attributs[attrKey].labelnorm + ".webp"
- rollData.attr = foundry.utils.duplicate(this.system.attributs[attrKey])
- }
- }
- if (compId) {
- rollData.competence = foundry.utils.duplicate(this.items.get(compId) || {})
- let maitrises = [{ key: "none", label: "Aucune" }]
- rollData.competence.system.predilections.forEach(function (item) {
- if (item.maitrise) {
- maitrises.push({ key: item.id, label: item.name });
- }
- })
- rollData.maitrises = maitrises // rollData.competence.system.predilections.filter(p => p.maitrise)
- rollData.actionImg = rollData.competence?.img
- rollData.talents = this.searchRelevantTalents(rollData.competence)
- }
- if (compName) {
- rollData.competence = foundry.utils.duplicate(this.items.find(item => item.name.toLowerCase() == compName.toLowerCase()) || {})
- rollData.actionImg = rollData.competence?.img
- }
- return rollData
- }
-
- /* -------------------------------------------- */
- async rollAttribut(attrKey, isInit = false) {
- let rollData = this.getCommonRollData(attrKey)
- rollData.multiplier = (isInit) ? 1 : 2
- rollData.isInit = isInit
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
-
- /* -------------------------------------------- */
- async rollCompetence(attrKey, compId) {
- let rollData = this.getCommonRollData(attrKey, compId)
- rollData.multiplier = 1 // Attr multiplier, always 1 in competence mode
- console.log("RollDatra", rollData)
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
-
- /* -------------------------------------------- */
- async rollArmeOffensif(armeId) {
- let arme = this.items.get(armeId)
- if (arme.type == "arme") {
- arme = this.prepareArme(arme)
- }
- let rollData = this.getCommonRollData(arme.system.attrKey, arme.system.competence._id)
- rollData.arme = arme
- MournbladeCYD2Utility.updateWithTarget(rollData)
- console.log("ARME!", rollData)
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
- /* -------------------------------------------- */
- async rollAssommer() {
- let rollData = this.getCommonRollData("pui", undefined, "Filouterie")
- rollData.assomer = true
- rollData.conditionsCommunes = true
- MournbladeCYD2Utility.updateWithTarget(rollData)
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
- /* -------------------------------------------- */
- async rollCoupBas() {
- let rollData = this.getCommonRollData("pui", undefined, "Mêlée")
- rollData.coupBas = true
- rollData.conditionsCommunes = true
- MournbladeCYD2Utility.updateWithTarget(rollData)
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
- /* -------------------------------------------- */
- async rollImmobiliser() {
- let rollData = this.getCommonRollData("pui", undefined, "Mêlée")
- rollData.immobiliser = true
- rollData.conditionsCommunes = true
- rollData.cibleconsciente = true
- MournbladeCYD2Utility.updateWithTarget(rollData)
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
- /* -------------------------------------------- */
- async rollRepousser() {
- let rollData = this.getCommonRollData("pui", undefined, "Mêlée")
- rollData.repousser = true
- rollData.conditionsCommunes = true
- rollData.cibleconsciente = true
- MournbladeCYD2Utility.updateWithTarget(rollData)
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
- /* -------------------------------------------- */
- async rollDesengager() {
- let rollData = this.getCommonRollData("adr", undefined, "Mouvements")
- rollData.desengager = true
- rollData.conditionsCommunes = true
- MournbladeCYD2Utility.updateWithTarget(rollData)
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
-
- /* -------------------------------------------- */
- async rollArmeDegats(armeId, targetVigueur = undefined, rollDataInput = undefined) {
- let arme = this.items.get(armeId)
- if (arme.type == "arme") {
- arme = this.prepareArme(arme)
- }
- console.log("DEGATS", arme, targetVigueur, rollDataInput)
- let roll
- let bonus = 0
- let bonus2 = 0
-
- if (rollDataInput?.applyCoupDevastateur) {
- bonus2 = Math.floor(this.system.attributs.pui.value / 2)
- let talent = this.items.find(item => item.type == "talent" && item.name.toLowerCase() == "coup dévastateur")
- this.updateEmbeddedDocuments('Item', [{ _id: talent.id, 'system.used': true }])
- }
-
- if (rollDataInput?.isHeroique) {
- if (rollDataInput?.attaqueCharge) {
- bonus = 5
- }
- if (rollDataInput?.chargeCavalerie) {
- bonus = 6
- }
- roll = await new Roll("2d10rr10+" + arme.system.totalDegats + "+" + bonus + "+" + bonus2).roll()
- } else {
- if (rollDataInput?.attaqueCharge) {
- bonus = 3
- }
- if (rollDataInput?.chargeCavalerie) {
- bonus = 4
- }
- roll = await new Roll("1d10+" + arme.system.totalDegats + "+" + bonus + "+" + bonus2).roll()
- }
- await MournbladeCYD2Utility.showDiceSoNice(roll, game.settings.get("core", "rollMode"));
- let nbEtatPerdus = 0
- if (targetVigueur) {
- nbEtatPerdus = Math.floor(roll.total / targetVigueur)
- }
- //console.log(roll)
- let rollData = {
- arme: arme,
- finalResult: roll.total,
- formula: roll.formula,
- alias: this.name,
- actorImg: this.img,
- actorId: this.id,
- defenderTokenId: rollDataInput?.defenderTokenId,
- actionImg: arme.img,
- targetVigueur: targetVigueur,
- nbEtatPerdus: nbEtatPerdus
- }
- MournbladeCYD2Utility.createChatWithRollMode(rollData.alias, {
- content: await renderTemplate(`systems/fvtt-mournblade-cyd2/templates/chat-degats-result.html`, rollData)
- })
-
- if (rollDataInput?.defenderTokenId && nbEtatPerdus) {
- MournbladeCYD2Utility.applyCombativite(rollDataInput, nbEtatPerdus)
- }
-
- }
-}
diff --git a/.history/modules/mournblade-cyd2-actor_20251026082551.js b/.history/modules/mournblade-cyd2-actor_20251026082551.js
deleted file mode 100644
index 2b6b4d9..0000000
--- a/.history/modules/mournblade-cyd2-actor_20251026082551.js
+++ /dev/null
@@ -1,884 +0,0 @@
-/* -------------------------------------------- */
-import { MournbladeCYD2Utility } from "./mournblade-cyd2-utility.js";
-import { MournbladeCYD2RollDialog } from "./mournblade-cyd2-roll-dialog.js";
-
-/* -------------------------------------------- */
-const __degatsBonus = [-2, -2, -1, -1, 0, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 8, 8, 9, 9, 10, 10]
-const __vitesseBonus = [-2, -2, -1, -1, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8]
-
-/* -------------------------------------------- */
-/**
- * Extend the base Actor entity by defining a custom roll data structure which is ideal for the Simple system.
- * @extends {Actor}
- */
-export class MournbladeCYD2Actor extends Actor {
-
- /* -------------------------------------------- */
- /**
- * Override the create() function to provide additional SoS functionality.
- *
- * This overrided create() function adds initial items
- * Namely: Basic skills, money,
- *
- * @param {Object} data Barebones actor data which this function adds onto.
- * @param {Object} options (Unused) Additional options which customize the creation workflow.
- *
- */
-
- static async create(data, options) {
-
- // Case of compendium global import
- if (data instanceof Array) {
- return super.create(data, options);
- }
- // If the created actor has items (only applicable to duplicated actors) bypass the new actor creation logic
- if (data.items) {
- let actor = super.create(data, options);
- return actor;
- }
-
- if (data.type == 'personnage') {
- const skills = await MournbladeCYD2Utility.loadCompendium("fvtt-mournblade-cyd2.skills")
- data.items = skills.map(i => i.toObject())
- }
- if (data.type == 'creature') {
- const skills = await MournbladeCYD2Utility.loadCompendium("fvtt-mournblade-cyd2.skills-creatures")
- data.items = skills.map(i => i.toObject())
- data.items.push({ name: "Arme naturelle 1", type: 'arme', img: "systems/fvtt-mournblade-cyd2/assets/icons/melee.webp", system: { typearme: "contact", bonusmaniementoff: 0, seuildefense: 0, degats: "0" } })
- data.items.push({ name: "Arme naturelle 2", type: 'arme', img: "systems/fvtt-mournblade-cyd2/assets/icons/melee.webp", system: { typearme: "contact", bonusmaniementoff: 0, seuildefense: 0, degats: "0" } })
- }
-
- return super.create(data, options);
- }
-
- /* -------------------------------------------- */
- getBonusDefenseFromTalents() {
- let talents = this.items.filter(item => item.type == "talent" && item.system.isautomated)
- let bonus = 0
- for (let talent of talents) {
- for (let auto of talent.system.automations) {
- if (auto.eventtype == "bonus-permanent" && auto.bonusname == "bonus-defensif") {
- bonus += Number(auto.bonus || 0)
- }
- }
- }
- return bonus
- }
-
- /* -------------------------------------------- */
- prepareArme(arme) {
- if (this.type == "cellule") {
- return arme
- }
-
- arme = foundry.utils.duplicate(arme)
- let combat = this.getCombatValues()
- if (arme.system.typearme == "contact" || arme.system.typearme == "contactjet") {
- let bonusDefense = this.getBonusDefenseFromTalents()
- arme.system.competence = foundry.utils.duplicate(this.items.find(item => item.type == "competence" && item.name.toLowerCase() == "mêlée"))
- arme.system.attrKey = "pui"
- arme.system.totalDegats = arme.system.degats + "+" + combat.bonusDegatsTotal
- arme.system.totalOffensif = this.system.attributs.pui.value + arme.system.competence.system.niveau + arme.system.bonusmaniementoff + (this.system.combat.monte ? 3 : 0)
- arme.system.totalDefensif = combat.defenseTotal + arme.system.competence.system.niveau + arme.system.seuildefense + bonusDefense + (this.system.combat.monte ? 3 : 0)
- console.log("Arme", arme.system.totalDefensif, combat, arme.system.competence.system.niveau, arme.system.seuildefense, bonusDefense)
- arme.system.isdefense = true
- arme.system.isMelee = true
- arme.system.isDistance = false
- }
- if (arme.system.typearme == "jet" || arme.system.typearme == "tir") {
- arme.system.competence = foundry.utils.duplicate(this.items.find(item => item.type == "competence" && item.name.toLowerCase() == "armes à distance"))
- arme.system.attrKey = "adr"
- arme.system.totalOffensif = this.system.attributs.adr.value + arme.system.competence.system.niveau + arme.system.bonusmaniementoff
- arme.system.totalDegats = arme.system.degats
- arme.system.isMelee = false
- arme.system.isDistance = true
- if (arme.system.isdefense) {
- arme.system.totalDefensif = combat.defenseTotal + arme.system.competence.system.niveau + arme.system.seuildefense
- }
- }
- return arme
- }
-
- /* -------------------------------------------- */
- getItemSorted(types) {
- let items = this.items.filter(item => types.includes(item.type)) || []
- MournbladeCYD2Utility.sortArrayObjectsByName(items)
- return items
- }
- getWeapons() {
- let armes = []
- for (let arme of this.items) {
- if (arme.type == "arme") {
- armes.push(this.prepareArme(arme))
- }
- }
- MournbladeCYD2Utility.sortArrayObjectsByName(armes)
- return armes
- }
- getMonnaies() {
- return this.getItemSorted(["monnaie"])
- }
- getEquipments() {
- return this.getItemSorted(["equipement"])
- }
- getArtefacts() {
- return this.getItemSorted(["artefact"])
- }
- getArmors() {
- return this.getItemSorted(["protection"])
- }
- getHistoriques() {
- return this.getItemSorted(["historique"])
- }
- getProfils() {
- return this.getItemSorted(["profil"])
- }
- getTalents() {
- return this.getItemSorted(["talent"])
- }
- getRessources() {
- return this.getItemSorted(["ressource"])
- }
- getContacts() {
- return this.getItemSorted(["contact"])
- }
- getMutations() {
- return this.getItemSorted(["mutation"])
- }
- getDons() {
- return this.getItemSorted(["don"])
- }
- getPactes() {
- return this.getItemSorted(["pacte"])
- }
- getTendances() {
- return this.getItemSorted(["tendance"])
- }
- getRunes() {
- return this.getItemSorted(["rune"])
- }
- getTraitsChaotiques() {
- return this.getItemSorted(["traitchaotique"])
- }
- getTraitsEspeces() {
- return this.getItemSorted(["traitespece"])
- }
-
- /* -------------------------------------------- */
- getAspect() {
- return (this.system.balance.loi > this.system.balance.chaos) ? this.system.balance.loi : this.system.balance.chaos
- }
- getMarge() {
- return Math.abs(this.system.balance.loi - this.system.balance.chaos)
- }
- getAlignement() {
- return (this.system.balance.loi > this.system.balance.chaos) ? "loyal" : "chaotique"
- }
-
- /* -------------------------------------------- */
- getSkills() {
- let comp = []
- for (let item of this.items) {
- item = foundry.utils.duplicate(item)
- if (item.type == "competence") {
- item.system.attribut1total = item.system.niveau + (this.system.attributs[item.system.attribut1]?.value || 0)
- item.system.attribut2total = item.system.niveau + (this.system.attributs[item.system.attribut2]?.value || 0)
- item.system.attribut3total = item.system.niveau + (this.system.attributs[item.system.attribut3]?.value || 0)
- if (item.system.niveau == 0) {
- item.system.attribut1total -= 3
- item.system.attribut2total -= 3
- item.system.attribut3total -= 3
- }
- item.system.attribut1label = this.system.attributs[item.system.attribut1]?.label || ""
- item.system.attribut2label = this.system.attributs[item.system.attribut2]?.label || ""
- item.system.attribut3label = this.system.attributs[item.system.attribut3]?.label || ""
- comp.push(item)
- }
- }
- MournbladeCYD2Utility.sortArrayObjectsByName(comp)
- return comp
- }
-
- /* ----------------------- --------------------- */
- addMember(actorId) {
- let members = foundry.utils.duplicate(this.system.members)
- members.push({ id: actorId })
- this.update({ 'system.members': members })
- }
- async removeMember(actorId) {
- let members = this.system.members.filter(it => it.id != actorId)
- this.update({ 'system.members': members })
- }
-
- /* -------------------------------------------- */
- getDefenseBase() {
- return Math.max(this.system.attributs.tre.value, this.system.attributs.adr.value)
- }
-
- /* -------------------------------------------- */
- getVitesseBase() {
- return 5 + __vitesseBonus[this.system.attributs.adr.value]
- }
- /* -------------------------------------------- */
- getProtection() {
- let equipProtection = 0
- for (let armor of this.items) {
- if (armor.type == "protection" && armor.system.equipped) {
- equipProtection += Number(armor.system.protection)
- }
- }
- if (equipProtection < 4) {
- return 4 + equipProtection // Cas des boucliers + sans armure
- }
- return equipProtection // Uniquement la protection des armures + boucliers
- }
-
- /* -------------------------------------------- */
- getCombatValues() {
- if (this.type == "cellule") {
- return {
- initBase: 0,
- initTotal: 0,
- bonusDegats: 0,
- bonusDegatsTotal: 0,
- vitesseBase: 0,
- vitesseTotal: 0,
- defenseBase: 0,
- protection: 0,
- defenseTotal: 0
- }
- }
-
- let combat = {
- initBase: this.system.attributs.adr.value,
- initTotal: this.system.attributs.adr.value + this.system.combat.initbonus,
- bonusDegats: this.getBonusDegats(),
- bonusDegatsTotal: this.getBonusDegats() + this.system.combat.bonusdegats,
- vitesseBase: this.getVitesseBase(),
- vitesseTotal: this.getVitesseBase() + this.system.combat.vitessebonus,
- defenseBase: this.getDefenseBase(),
- protection: this.getProtection(),
- defenseTotal: this.getDefenseBase() + this.system.combat.defensebonus + this.getProtection() - this.getTotalAdversite() + (this.system.combat.defensetotale ? 3 : 0)
- }
- return combat
- }
-
- /* -------------------------------------------- */
- prepareBaseData() {
- }
-
- /* -------------------------------------------- */
- async prepareData() {
- super.prepareData();
- }
-
- /* -------------------------------------------- */
- prepareDerivedData() {
-
- if (this.type == 'personnage') {
- let talentBonus = this.getVigueurBonus()
- let vigueur = Math.floor((this.system.attributs.pui.value + this.system.attributs.tre.value) / 2) + talentBonus + this.system.sante.vigueurmodifier
- if (vigueur != this.system.sante.vigueur) {
- this.update({ 'system.sante.vigueur': vigueur })
- }
-
- let seuilPouvoirBonus = this.getSeuilPouvoirBonus()
- let seuilPouvoir = Math.floor((this.system.attributs.tre.value + this.system.attributs.cla.value) / 2) + seuilPouvoirBonus + this.system.ame.seuilpouvoirmodifier
- if (seuilPouvoir != this.system.ame.seuilpouvoir) {
- this.update({ 'system.ame.seuilpouvoir': seuilPouvoir })
- }
- }
- super.prepareDerivedData()
- }
-
- /* -------------------------------------------- */
- _preUpdate(changed, options, user) {
- if (changed?.system?.sante?.etat && changed?.system?.sante?.etat != this.system.sante.etat) {
- setTimeout(() => {
- this.processCombativite(changed.system.sante)
- }, 800)
- }
- if (changed?.system?.ame?.etat && changed?.system?.ame?.etat != this.system.ame.etat) {
- setTimeout(() => {
- this.processAme(changed.system.ame)
- }, 800)
- }
- super._preUpdate(changed, options, user);
- }
-
- /* -------------------------------------------- */
- _onUpdate(data, options, user) {
- super._onUpdate(data, options, user);
- }
- /* -------------------------------------------- */
- getItemById(id) {
- let item = this.items.find(item => item.id == id);
- if (item) {
- item = foundry.utils.duplicate(item)
- }
- return item;
- }
-
- /* -------------------------------------------- */
- async equipItem(itemId) {
- let item = this.items.find(item => item.id == itemId)
- if (item && item.system) {
- let update = { _id: item.id, "system.equipped": !item.system.equipped }
- await this.updateEmbeddedDocuments('Item', [update]); // Updates one EmbeddedEntity
- }
- }
-
- /* -------------------------------------------- */
- editItemField(itemId, itemType, itemField, dataType, value) {
- let item = this.items.find(item => item.id == itemId)
- if (item) {
- console.log("Item ", item, itemField, dataType, value)
- if (dataType.toLowerCase() == "number") {
- value = Number(value)
- } else {
- value = String(value)
- }
- let update = { _id: item.id, [`system.${itemField}`]: value };
- this.updateEmbeddedDocuments("Item", [update])
- }
- }
-
- /* -------------------------------------------- */
- checkAttribut(attribut, minLevel) {
- let attr = this.system.attributs.find(at => at.labelnorm == attribut.toLowerCase())
- if (attr && attr.value >= minLevel) {
- return { isValid: true, attr: foundry.utils.duplicate(attr) }
- }
- return { isValid: false }
- }
- /* -------------------------------------------- */
- checkAttributOrCompetenceLevel(compName, minLevel) {
- let comp = this.items.find(i => i.type == "competence" && i.name.toLowerCase() == compName.toLowerCase() && i.system.niveau >= minLevel)
- if (comp) {
- return { isValid: true, item: foundry.utils.duplicate(comp) }
- } else {
- for (let attrKey in this.system.attributs) {
- if (this.system.attributs[attrKey].label.toLowerCase() == compName.toLowerCase() && this.system.attributs[attrKey].value >= minLevel) {
- return { isValid: true, item: foundry.utils.duplicate(this.system.attributs[attrKey]) }
- }
- }
- }
- return { isValid: false, warningMessage: `Prérequis insuffisant : la compétence/attribut ${compName} doit être de niveau ${minLevel} au minimum` }
- }
- /* -------------------------------------------- */
- addCompetenceBonus(compName, bonus, baCost) {
- let comp = this.items.find(i => i.type == "competence" && i.name.toLowerCase() == compName.toLowerCase())
- if (comp) {
- comp = foundry.utils.duplicate(comp)
- comp.system.bonus = bonus
- comp.system.baCost = baCost
- return { isValid: true, item: comp }
- }
- return { isValid: false, warningMessage: `Compétence ${compName} non trouvée` }
- }
- /* -------------------------------------------- */
- checkIfCompetence(compName) {
- let comp = this.items.find(i => i.type == "competence" && i.name.toLowerCase() == compName.toLowerCase())
- if (comp) {
- return { isValid: true, item: comp }
- }
- return { isValid: false }
- }
- /* -------------------------------------------- */
- getVigueur() {
- return this.system.sante.vigueur
- }
-
- /* -------------------------------------------- */
- getVigueurBonus() {
- let talents = this.items.filter(item => item.type == "talent" && item.system.isautomated)
- let bonus = 0
- for (let talent of talents) {
- for (let auto of talent.system.automations) {
- if (auto.eventtype == "bonus-permanent" && auto.bonusname == "vigueur") {
- bonus += Number(auto.bonus || 0)
- }
- }
- }
- return bonus
- }
-
- /* -------------------------------------------- */
- getSeuilPouvoir() {
- return this.system.ame.seuilpouvoir
- }
-
- /* -------------------------------------------- */
- getSeuilPouvoirBonus() {
- let talents = this.items.filter(item => item.type == "talent" && item.system.isautomated)
- let bonus = 0
- for (let talent of talents) {
- for (let auto of talent.system.automations) {
- if (auto.eventtype == "bonus-permanent" && auto.bonusname == "seuilpouvoir") {
- bonus += Number(auto.bonus || 0)
- }
- }
- }
- return bonus
- }
-
- /* -------------------------------------------- */
- getBonneAventure() {
- return this.system.bonneaventure.actuelle
- }
- /* -------------------------------------------- */
- checkBonneAventure(cost) {
- return (this.system.bonneaventure.actuelle >= cost)
- }
- /* -------------------------------------------- */
- changeBonneAventure(value) {
- let newBA = this.system.bonneaventure.actuelle
- newBA += value
- this.update({ 'system.bonneaventure.actuelle': newBA })
- }
-
- /* -------------------------------------------- */
- getEclat() {
- return this.system.eclat.value
- }
-
- /* -------------------------------------------- */
- changeEclat(value) {
- let newE = this.system.eclat.value
- newE += value
- this.update({ 'system.eclat.value': newE })
- }
-
- /* -------------------------------------------- */
- compareName(a, b) {
- if (a.name < b.name) {
- return -1;
- }
- if (a.name > b.name) {
- return 1;
- }
- return 0;
- }
-
- /* -------------------------------------------- */
- getAttribute(attrKey) {
- return this.system.attributes[attrKey]
- }
-
- /* -------------------------------------------- */
- getBonusDegats() {
- return 0;
- }
-
- /* -------------------------------------------- */
- changeEtatCombativite(value) {
- if (value === "vaincu") {
- value = 200
- }
- let sante = foundry.utils.duplicate(this.system.sante)
- sante.etat += Number(value)
- sante.etat = Math.max(sante.etat, 0)
- sante.etat = Math.min(sante.etat, this.system.sante.nbcombativite)
- this.update({ 'system.sante': sante })
- if (sante.etat == this.system.sante.nbcombativite) {
- ChatMessage.create({ content: `${this.name} est vaincu !` })
- }
- // Duplicated ! this.processCombativite(sante)
- }
-
- /* -------------------------------------------- */
- changeEtatAme(value) {
- if (value === "brise") {
- value = 200
- }
- let ame = foundry.utils.duplicate(this.system.ame)
- ame.etat += Number(value)
- ame.etat = Math.max(ame.etat, 0)
- // L'état ne peut pas dépasser le maximum actuel d'âme
- let maxAme = Math.min(this.system.ame.max || this.system.ame.nbame, this.system.ame.nbame - 1)
- ame.etat = Math.min(ame.etat, maxAme)
- this.update({ 'system.ame': ame })
- if (ame.etat >= maxAme) {
- ChatMessage.create({ content: `${this.name} est brisé !` })
- }
- }
-
- /* -------------------------------------------- */
- processCombativite(sante) {
- sante = sante || foundry.utils.duplicate(this.system.sante)
- // Gestion des états affaibli et très affaibli
- if (sante.etat == this.system.sante.nbcombativite - 2 || sante.etat == this.system.sante.nbcombativite - 1) {
- if (sante.etat == this.system.sante.nbcombativite - 2 && this.items.find(item => item.type == "talent" && item.name.toLowerCase() == "encaissement")) {
- ChatMessage.create({ content: `${this.name} ne subit pas les 2 adversités rouge grâce à Encaissement. Pensez à les ajouter à la fin de la scène !` })
- } else if (sante.etat == this.system.sante.nbcombativite - 1 && this.items.find(item => item.type == "talent" && item.name.toLowerCase().includes("vaillant"))) {
- ChatMessage.create({ content: `${this.name} ne subit pas les 2 adversités rouge grâce à Vaillant. Pensez à les ajouter à la fin de la scène !` })
- } else {
- ChatMessage.create({ content: `${this.name} subit 2 adversités rouge !` })
- this.incDecAdversite("rouge", 2)
- }
- }
- }
-
- /* -------------------------------------------- */
- processAme(ame) {
- ame = ame || foundry.utils.duplicate(this.system.ame)
- // Gestion des états Traumatisé, Très Traumatisé et Brisé
- if (ame.etat == this.system.ame.nbame - 3 || ame.etat == this.system.ame.nbame - 2 || ame.etat == this.system.ame.nbame - 1) {
- if (ame.etat == this.system.ame.nbame - 3) {
- ChatMessage.create({ content: `${this.name} est Traumatisé !` })
- } else if (ame.etat == this.system.ame.nbame - 2) {
- ChatMessage.create({ content: `${this.name} est Très Traumatisé !` })
- } else if (ame.etat == this.system.ame.nbame - 1) {
- ChatMessage.create({ content: `${this.name} est Brisé !` })
- }
- }
- }
-
- /* -------------------------------------------- */
- async equipGear(equipmentId) {
- let item = this.items.find(item => item.id == equipmentId);
- if (item?.system?.data) {
- let update = { _id: item.id, "system.equipped": !item.system.equipped };
- await this.updateEmbeddedDocuments('Item', [update]); // Updates one EmbeddedEntity
- }
- }
-
- /* -------------------------------------------- */
- getSubActors() {
- let subActors = [];
- for (let id of this.system.subactors) {
- subActors.push(foundry.utils.duplicate(game.actors.get(id)));
- }
- return subActors;
- }
- /* -------------------------------------------- */
- async addSubActor(subActorId) {
- let subActors = foundry.utils.duplicate(this.system.subactors);
- subActors.push(subActorId);
- await this.update({ 'system.subactors': subActors });
- }
- /* -------------------------------------------- */
- async delSubActor(subActorId) {
- let newArray = [];
- for (let id of this.system.subactors) {
- if (id != subActorId) {
- newArray.push(id);
- }
- }
- await this.update({ 'system.subactors': newArray });
- }
-
- /* -------------------------------------------- */
- getTotalAdversite() {
- return this.system.adversite.bleue + this.system.adversite.rouge + this.system.adversite.noire
- }
-
- /* -------------------------------------------- */
- async incDecAdversite(adv, incDec = 0) {
- let adversite = foundry.utils.duplicate(this.system.adversite)
- adversite[adv] += Number(incDec)
- adversite[adv] = Math.max(adversite[adv], 0)
- adversite[adv] = Math.min(adversite[adv], 20)
- this.update({ 'system.adversite': adversite })
- }
- /* -------------------------------------------- */
- async incDecQuantity(objetId, incDec = 0) {
- let objetQ = this.items.get(objetId)
- if (objetQ) {
- let newQ = objetQ.system.quantite + incDec
- newQ = Math.max(newQ, 0)
- await this.updateEmbeddedDocuments('Item', [{ _id: objetQ.id, 'system.quantite': newQ }]); // pdates one EmbeddedEntity
- }
- }
-
- /* -------------------------------------------- */
- computeRichesse() {
- let valueSC = 0
- for (let monnaie of this.items) {
- if (monnaie.type == "monnaie") {
- valueSC += Number(monnaie.system.prixsc) * Number(monnaie.system.quantite)
- }
- }
- return MournbladeCYD2Utility.computeMonnaieDetails(valueSC)
- }
-
- /* -------------------------------------------- */
- computeValeurEquipement() {
- let valueSC = 0
- for (let equip of this.items) {
- if (equip.type == "equipement" || equip.type == "arme" || equip.type == "protection") {
- valueSC += Number(equip.system.prixsc) * Number(equip.system.quantite ?? 1)
- valueSC += (Number(equip.system.prixca) * Number(equip.system.quantite ?? 1)) * 20
- valueSC += (Number(equip.system.prixpo) * Number(equip.system.quantite ?? 1)) * 400
- }
- }
- return MournbladeCYD2Utility.computeMonnaieDetails(valueSC)
- }
-
- /* -------------------------------------------- */
- getCompetence(compId) {
- return this.items.get(compId)
- }
-
- /* -------------------------------------------- */
- async setPredilectionUsed(compId, predIdx) {
- let comp = this.items.get(compId)
- let pred = foundry.utils.duplicate(comp.system.predilections)
- pred[predIdx].used = true
- await this.updateEmbeddedDocuments('Item', [{ _id: compId, 'system.predilections': pred }])
- }
-
- /* -------------------------------------------- */
- getInitiativeScore() {
- let init = this.getFlag("world", "last-initiative")
- return init || -1
- }
-
- /* -------------------------------------------- */
- getBestAttackValue() {
- let attackList = this.items.filter(item => (item.type == "arme" || item.type == "talent") && item.system.equipped)
- let maxOff = 0
- let bestArme
- for (let arme of attackList) {
- if (arme.type == "arme") {
- arme = this.prepareArme(arme)
- }
- if (arme.system.totalOffensif > maxOff) {
- maxOff = arme.system.totalOffensif
- bestArme = foundry.utils.duplicate(arme)
- }
- }
- return bestArme
- }
-
- /* -------------------------------------------- */
- getBestDefenseValue() {
- let defenseList = this.items.filter(item => (item.type == "arme") && item.system.equipped)
- let maxDef = 0
- let bestArme
- for (let arme of defenseList) {
- if (arme.type == "arme") {
- arme = this.prepareArme(arme)
- }
- if (arme.system.totalDefensif > maxDef) {
- maxDef = arme.system.totalDefensif
- bestArme = foundry.utils.duplicate(arme)
- }
- }
- return bestArme
- }
-
- /* -------------------------------------------- */
- searchRelevantTalents(competence) {
- let talents = []
-
- for (let talent of this.items) {
- if (talent.type == "talent" && talent.system.isautomated && talent.system.automations.length > 0) {
- for (let auto of talent.system.automations) {
- if (auto.eventtype === "prepare-roll") {
- if (auto.competence.toLowerCase() == competence.name.toLowerCase()) {
- talent = foundry.utils.duplicate(talent)
- talent.system.bonus = auto.bonus
- talent.system.baCost = auto.baCost
- talents.push(talent)
- }
- }
- }
- }
- }
- return talents
- }
-
- /* -------------------------------------------- */
- buildListeAdversites() {
- return []
- }
-
- /* -------------------------------------------- */
- getCommonRollData(attrKey = undefined, compId = undefined, compName = undefined) {
- let rollData = MournbladeCYD2Utility.getBasicRollData()
- rollData.alias = this.name
- rollData.actorImg = this.img
- rollData.actorId = this.id
- rollData.tokenId = this.token?.id
- rollData.img = this.img
- rollData.attributs = MournbladeCYD2Utility.getAttributs()
- rollData.maitriseId = "none"
- rollData.nbEclat = this.system.eclat.value
- rollData.nbBA = this.system.bonneaventure.actuelle
- rollData.nbAdversites = this.getTotalAdversite()
- rollData.talents = []
- rollData.attrKey2 = "none"
- rollData.coupDevastateur = this.items.find(it => it.type == "talent" && it.name.toLowerCase() == "coup dévastateur" && !it.system.used)
- rollData.hasAmbidextre = this.items.find(it => it.type == "talent" && it.name.toLowerCase() == "ambidextre")
- rollData.hasFeinte = this.system.bonneaventure.actuelle > 0 && this.items.find(it => it.type == "talent" && it.name.toLowerCase() == "feinte")
- rollData.isMonte = this.system.combat.monte
- rollData.config = game.system.mournbladecyd2.config
-
- if (attrKey) {
- rollData.attrKey = attrKey
- if (attrKey != "tochoose") {
- rollData.actionImg = "systems/fvtt-mournblade-cyd2/assets/icons/" + this.system.attributs[attrKey].labelnorm + ".webp"
- rollData.attr = foundry.utils.duplicate(this.system.attributs[attrKey])
- }
- }
- if (compId) {
- rollData.competence = foundry.utils.duplicate(this.items.get(compId) || {})
- let maitrises = [{ key: "none", label: "Aucune" }]
- rollData.competence.system.predilections.forEach(function (item) {
- if (item.maitrise) {
- maitrises.push({ key: item.id, label: item.name });
- }
- })
- rollData.maitrises = maitrises // rollData.competence.system.predilections.filter(p => p.maitrise)
- rollData.actionImg = rollData.competence?.img
- rollData.talents = this.searchRelevantTalents(rollData.competence)
- }
- if (compName) {
- rollData.competence = foundry.utils.duplicate(this.items.find(item => item.name.toLowerCase() == compName.toLowerCase()) || {})
- rollData.actionImg = rollData.competence?.img
- }
- return rollData
- }
-
- /* -------------------------------------------- */
- async rollAttribut(attrKey, isInit = false) {
- let rollData = this.getCommonRollData(attrKey)
- rollData.multiplier = (isInit) ? 1 : 2
- rollData.isInit = isInit
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
-
- /* -------------------------------------------- */
- async rollCompetence(attrKey, compId) {
- let rollData = this.getCommonRollData(attrKey, compId)
- rollData.multiplier = 1 // Attr multiplier, always 1 in competence mode
- console.log("RollDatra", rollData)
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
-
- /* -------------------------------------------- */
- async rollArmeOffensif(armeId) {
- let arme = this.items.get(armeId)
- if (arme.type == "arme") {
- arme = this.prepareArme(arme)
- }
- let rollData = this.getCommonRollData(arme.system.attrKey, arme.system.competence._id)
- rollData.arme = arme
- MournbladeCYD2Utility.updateWithTarget(rollData)
- console.log("ARME!", rollData)
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
- /* -------------------------------------------- */
- async rollAssommer() {
- let rollData = this.getCommonRollData("pui", undefined, "Filouterie")
- rollData.assomer = true
- rollData.conditionsCommunes = true
- MournbladeCYD2Utility.updateWithTarget(rollData)
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
- /* -------------------------------------------- */
- async rollCoupBas() {
- let rollData = this.getCommonRollData("pui", undefined, "Mêlée")
- rollData.coupBas = true
- rollData.conditionsCommunes = true
- MournbladeCYD2Utility.updateWithTarget(rollData)
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
- /* -------------------------------------------- */
- async rollImmobiliser() {
- let rollData = this.getCommonRollData("pui", undefined, "Mêlée")
- rollData.immobiliser = true
- rollData.conditionsCommunes = true
- rollData.cibleconsciente = true
- MournbladeCYD2Utility.updateWithTarget(rollData)
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
- /* -------------------------------------------- */
- async rollRepousser() {
- let rollData = this.getCommonRollData("pui", undefined, "Mêlée")
- rollData.repousser = true
- rollData.conditionsCommunes = true
- rollData.cibleconsciente = true
- MournbladeCYD2Utility.updateWithTarget(rollData)
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
- /* -------------------------------------------- */
- async rollDesengager() {
- let rollData = this.getCommonRollData("adr", undefined, "Mouvements")
- rollData.desengager = true
- rollData.conditionsCommunes = true
- MournbladeCYD2Utility.updateWithTarget(rollData)
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
-
- /* -------------------------------------------- */
- async rollArmeDegats(armeId, targetVigueur = undefined, rollDataInput = undefined) {
- let arme = this.items.get(armeId)
- if (arme.type == "arme") {
- arme = this.prepareArme(arme)
- }
- console.log("DEGATS", arme, targetVigueur, rollDataInput)
- let roll
- let bonus = 0
- let bonus2 = 0
-
- if (rollDataInput?.applyCoupDevastateur) {
- bonus2 = Math.floor(this.system.attributs.pui.value / 2)
- let talent = this.items.find(item => item.type == "talent" && item.name.toLowerCase() == "coup dévastateur")
- this.updateEmbeddedDocuments('Item', [{ _id: talent.id, 'system.used': true }])
- }
-
- if (rollDataInput?.isHeroique) {
- if (rollDataInput?.attaqueCharge) {
- bonus = 5
- }
- if (rollDataInput?.chargeCavalerie) {
- bonus = 6
- }
- roll = await new Roll("2d10rr10+" + arme.system.totalDegats + "+" + bonus + "+" + bonus2).roll()
- } else {
- if (rollDataInput?.attaqueCharge) {
- bonus = 3
- }
- if (rollDataInput?.chargeCavalerie) {
- bonus = 4
- }
- roll = await new Roll("1d10+" + arme.system.totalDegats + "+" + bonus + "+" + bonus2).roll()
- }
- await MournbladeCYD2Utility.showDiceSoNice(roll, game.settings.get("core", "rollMode"));
- let nbEtatPerdus = 0
- if (targetVigueur) {
- nbEtatPerdus = Math.floor(roll.total / targetVigueur)
- }
- //console.log(roll)
- let rollData = {
- arme: arme,
- finalResult: roll.total,
- formula: roll.formula,
- alias: this.name,
- actorImg: this.img,
- actorId: this.id,
- defenderTokenId: rollDataInput?.defenderTokenId,
- actionImg: arme.img,
- targetVigueur: targetVigueur,
- nbEtatPerdus: nbEtatPerdus
- }
- MournbladeCYD2Utility.createChatWithRollMode(rollData.alias, {
- content: await renderTemplate(`systems/fvtt-mournblade-cyd2/templates/chat-degats-result.html`, rollData)
- })
-
- if (rollDataInput?.defenderTokenId && nbEtatPerdus) {
- MournbladeCYD2Utility.applyCombativite(rollDataInput, nbEtatPerdus)
- }
-
- }
-}
diff --git a/.history/modules/mournblade-cyd2-actor_20251026082604.js b/.history/modules/mournblade-cyd2-actor_20251026082604.js
deleted file mode 100644
index dfe8444..0000000
--- a/.history/modules/mournblade-cyd2-actor_20251026082604.js
+++ /dev/null
@@ -1,888 +0,0 @@
-/* -------------------------------------------- */
-import { MournbladeCYD2Utility } from "./mournblade-cyd2-utility.js";
-import { MournbladeCYD2RollDialog } from "./mournblade-cyd2-roll-dialog.js";
-
-/* -------------------------------------------- */
-const __degatsBonus = [-2, -2, -1, -1, 0, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 8, 8, 9, 9, 10, 10]
-const __vitesseBonus = [-2, -2, -1, -1, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8]
-
-/* -------------------------------------------- */
-/**
- * Extend the base Actor entity by defining a custom roll data structure which is ideal for the Simple system.
- * @extends {Actor}
- */
-export class MournbladeCYD2Actor extends Actor {
-
- /* -------------------------------------------- */
- /**
- * Override the create() function to provide additional SoS functionality.
- *
- * This overrided create() function adds initial items
- * Namely: Basic skills, money,
- *
- * @param {Object} data Barebones actor data which this function adds onto.
- * @param {Object} options (Unused) Additional options which customize the creation workflow.
- *
- */
-
- static async create(data, options) {
-
- // Case of compendium global import
- if (data instanceof Array) {
- return super.create(data, options);
- }
- // If the created actor has items (only applicable to duplicated actors) bypass the new actor creation logic
- if (data.items) {
- let actor = super.create(data, options);
- return actor;
- }
-
- if (data.type == 'personnage') {
- const skills = await MournbladeCYD2Utility.loadCompendium("fvtt-mournblade-cyd2.skills")
- data.items = skills.map(i => i.toObject())
- }
- if (data.type == 'creature') {
- const skills = await MournbladeCYD2Utility.loadCompendium("fvtt-mournblade-cyd2.skills-creatures")
- data.items = skills.map(i => i.toObject())
- data.items.push({ name: "Arme naturelle 1", type: 'arme', img: "systems/fvtt-mournblade-cyd2/assets/icons/melee.webp", system: { typearme: "contact", bonusmaniementoff: 0, seuildefense: 0, degats: "0" } })
- data.items.push({ name: "Arme naturelle 2", type: 'arme', img: "systems/fvtt-mournblade-cyd2/assets/icons/melee.webp", system: { typearme: "contact", bonusmaniementoff: 0, seuildefense: 0, degats: "0" } })
- }
-
- return super.create(data, options);
- }
-
- /* -------------------------------------------- */
- getBonusDefenseFromTalents() {
- let talents = this.items.filter(item => item.type == "talent" && item.system.isautomated)
- let bonus = 0
- for (let talent of talents) {
- for (let auto of talent.system.automations) {
- if (auto.eventtype == "bonus-permanent" && auto.bonusname == "bonus-defensif") {
- bonus += Number(auto.bonus || 0)
- }
- }
- }
- return bonus
- }
-
- /* -------------------------------------------- */
- prepareArme(arme) {
- if (this.type == "cellule") {
- return arme
- }
-
- arme = foundry.utils.duplicate(arme)
- let combat = this.getCombatValues()
- if (arme.system.typearme == "contact" || arme.system.typearme == "contactjet") {
- let bonusDefense = this.getBonusDefenseFromTalents()
- arme.system.competence = foundry.utils.duplicate(this.items.find(item => item.type == "competence" && item.name.toLowerCase() == "mêlée"))
- arme.system.attrKey = "pui"
- arme.system.totalDegats = arme.system.degats + "+" + combat.bonusDegatsTotal
- arme.system.totalOffensif = this.system.attributs.pui.value + arme.system.competence.system.niveau + arme.system.bonusmaniementoff + (this.system.combat.monte ? 3 : 0)
- arme.system.totalDefensif = combat.defenseTotal + arme.system.competence.system.niveau + arme.system.seuildefense + bonusDefense + (this.system.combat.monte ? 3 : 0)
- console.log("Arme", arme.system.totalDefensif, combat, arme.system.competence.system.niveau, arme.system.seuildefense, bonusDefense)
- arme.system.isdefense = true
- arme.system.isMelee = true
- arme.system.isDistance = false
- }
- if (arme.system.typearme == "jet" || arme.system.typearme == "tir") {
- arme.system.competence = foundry.utils.duplicate(this.items.find(item => item.type == "competence" && item.name.toLowerCase() == "armes à distance"))
- arme.system.attrKey = "adr"
- arme.system.totalOffensif = this.system.attributs.adr.value + arme.system.competence.system.niveau + arme.system.bonusmaniementoff
- arme.system.totalDegats = arme.system.degats
- arme.system.isMelee = false
- arme.system.isDistance = true
- if (arme.system.isdefense) {
- arme.system.totalDefensif = combat.defenseTotal + arme.system.competence.system.niveau + arme.system.seuildefense
- }
- }
- return arme
- }
-
- /* -------------------------------------------- */
- getItemSorted(types) {
- let items = this.items.filter(item => types.includes(item.type)) || []
- MournbladeCYD2Utility.sortArrayObjectsByName(items)
- return items
- }
- getWeapons() {
- let armes = []
- for (let arme of this.items) {
- if (arme.type == "arme") {
- armes.push(this.prepareArme(arme))
- }
- }
- MournbladeCYD2Utility.sortArrayObjectsByName(armes)
- return armes
- }
- getMonnaies() {
- return this.getItemSorted(["monnaie"])
- }
- getEquipments() {
- return this.getItemSorted(["equipement"])
- }
- getArtefacts() {
- return this.getItemSorted(["artefact"])
- }
- getArmors() {
- return this.getItemSorted(["protection"])
- }
- getHistoriques() {
- return this.getItemSorted(["historique"])
- }
- getProfils() {
- return this.getItemSorted(["profil"])
- }
- getTalents() {
- return this.getItemSorted(["talent"])
- }
- getRessources() {
- return this.getItemSorted(["ressource"])
- }
- getContacts() {
- return this.getItemSorted(["contact"])
- }
- getMutations() {
- return this.getItemSorted(["mutation"])
- }
- getDons() {
- return this.getItemSorted(["don"])
- }
- getPactes() {
- return this.getItemSorted(["pacte"])
- }
- getTendances() {
- return this.getItemSorted(["tendance"])
- }
- getRunes() {
- return this.getItemSorted(["rune"])
- }
- getTraitsChaotiques() {
- return this.getItemSorted(["traitchaotique"])
- }
- getTraitsEspeces() {
- return this.getItemSorted(["traitespece"])
- }
-
- /* -------------------------------------------- */
- getAspect() {
- return (this.system.balance.loi > this.system.balance.chaos) ? this.system.balance.loi : this.system.balance.chaos
- }
- getMarge() {
- return Math.abs(this.system.balance.loi - this.system.balance.chaos)
- }
- getAlignement() {
- return (this.system.balance.loi > this.system.balance.chaos) ? "loyal" : "chaotique"
- }
-
- /* -------------------------------------------- */
- getSkills() {
- let comp = []
- for (let item of this.items) {
- item = foundry.utils.duplicate(item)
- if (item.type == "competence") {
- item.system.attribut1total = item.system.niveau + (this.system.attributs[item.system.attribut1]?.value || 0)
- item.system.attribut2total = item.system.niveau + (this.system.attributs[item.system.attribut2]?.value || 0)
- item.system.attribut3total = item.system.niveau + (this.system.attributs[item.system.attribut3]?.value || 0)
- if (item.system.niveau == 0) {
- item.system.attribut1total -= 3
- item.system.attribut2total -= 3
- item.system.attribut3total -= 3
- }
- item.system.attribut1label = this.system.attributs[item.system.attribut1]?.label || ""
- item.system.attribut2label = this.system.attributs[item.system.attribut2]?.label || ""
- item.system.attribut3label = this.system.attributs[item.system.attribut3]?.label || ""
- comp.push(item)
- }
- }
- MournbladeCYD2Utility.sortArrayObjectsByName(comp)
- return comp
- }
-
- /* ----------------------- --------------------- */
- addMember(actorId) {
- let members = foundry.utils.duplicate(this.system.members)
- members.push({ id: actorId })
- this.update({ 'system.members': members })
- }
- async removeMember(actorId) {
- let members = this.system.members.filter(it => it.id != actorId)
- this.update({ 'system.members': members })
- }
-
- /* -------------------------------------------- */
- getDefenseBase() {
- return Math.max(this.system.attributs.tre.value, this.system.attributs.adr.value)
- }
-
- /* -------------------------------------------- */
- getVitesseBase() {
- return 5 + __vitesseBonus[this.system.attributs.adr.value]
- }
- /* -------------------------------------------- */
- getProtection() {
- let equipProtection = 0
- for (let armor of this.items) {
- if (armor.type == "protection" && armor.system.equipped) {
- equipProtection += Number(armor.system.protection)
- }
- }
- if (equipProtection < 4) {
- return 4 + equipProtection // Cas des boucliers + sans armure
- }
- return equipProtection // Uniquement la protection des armures + boucliers
- }
-
- /* -------------------------------------------- */
- getCombatValues() {
- if (this.type == "cellule") {
- return {
- initBase: 0,
- initTotal: 0,
- bonusDegats: 0,
- bonusDegatsTotal: 0,
- vitesseBase: 0,
- vitesseTotal: 0,
- defenseBase: 0,
- protection: 0,
- defenseTotal: 0
- }
- }
-
- let combat = {
- initBase: this.system.attributs.adr.value,
- initTotal: this.system.attributs.adr.value + this.system.combat.initbonus,
- bonusDegats: this.getBonusDegats(),
- bonusDegatsTotal: this.getBonusDegats() + this.system.combat.bonusdegats,
- vitesseBase: this.getVitesseBase(),
- vitesseTotal: this.getVitesseBase() + this.system.combat.vitessebonus,
- defenseBase: this.getDefenseBase(),
- protection: this.getProtection(),
- defenseTotal: this.getDefenseBase() + this.system.combat.defensebonus + this.getProtection() - this.getTotalAdversite() + (this.system.combat.defensetotale ? 3 : 0)
- }
- return combat
- }
-
- /* -------------------------------------------- */
- prepareBaseData() {
- }
-
- /* -------------------------------------------- */
- async prepareData() {
- super.prepareData();
- }
-
- /* -------------------------------------------- */
- prepareDerivedData() {
-
- if (this.type == 'personnage') {
- let talentBonus = this.getVigueurBonus()
- let vigueur = Math.floor((this.system.attributs.pui.value + this.system.attributs.tre.value) / 2) + talentBonus + this.system.sante.vigueurmodifier
- if (vigueur != this.system.sante.vigueur) {
- this.update({ 'system.sante.vigueur': vigueur })
- }
-
- let seuilPouvoirBonus = this.getSeuilPouvoirBonus()
- let seuilPouvoir = Math.floor((this.system.attributs.tre.value + this.system.attributs.cla.value) / 2) + seuilPouvoirBonus + this.system.ame.seuilpouvoirmodifier
- if (seuilPouvoir != this.system.ame.seuilpouvoir) {
- this.update({ 'system.ame.seuilpouvoir': seuilPouvoir })
- }
- }
- super.prepareDerivedData()
- }
-
- /* -------------------------------------------- */
- _preUpdate(changed, options, user) {
- if (changed?.system?.sante?.etat && changed?.system?.sante?.etat != this.system.sante.etat) {
- setTimeout(() => {
- this.processCombativite(changed.system.sante)
- }, 800)
- }
- if (changed?.system?.ame?.etat && changed?.system?.ame?.etat != this.system.ame.etat) {
- setTimeout(() => {
- this.processAme(changed.system.ame)
- }, 800)
- }
- super._preUpdate(changed, options, user);
- }
-
- /* -------------------------------------------- */
- _onUpdate(data, options, user) {
- super._onUpdate(data, options, user);
- }
- /* -------------------------------------------- */
- getItemById(id) {
- let item = this.items.find(item => item.id == id);
- if (item) {
- item = foundry.utils.duplicate(item)
- }
- return item;
- }
-
- /* -------------------------------------------- */
- async equipItem(itemId) {
- let item = this.items.find(item => item.id == itemId)
- if (item && item.system) {
- let update = { _id: item.id, "system.equipped": !item.system.equipped }
- await this.updateEmbeddedDocuments('Item', [update]); // Updates one EmbeddedEntity
- }
- }
-
- /* -------------------------------------------- */
- editItemField(itemId, itemType, itemField, dataType, value) {
- let item = this.items.find(item => item.id == itemId)
- if (item) {
- console.log("Item ", item, itemField, dataType, value)
- if (dataType.toLowerCase() == "number") {
- value = Number(value)
- } else {
- value = String(value)
- }
- let update = { _id: item.id, [`system.${itemField}`]: value };
- this.updateEmbeddedDocuments("Item", [update])
- }
- }
-
- /* -------------------------------------------- */
- checkAttribut(attribut, minLevel) {
- let attr = this.system.attributs.find(at => at.labelnorm == attribut.toLowerCase())
- if (attr && attr.value >= minLevel) {
- return { isValid: true, attr: foundry.utils.duplicate(attr) }
- }
- return { isValid: false }
- }
- /* -------------------------------------------- */
- checkAttributOrCompetenceLevel(compName, minLevel) {
- let comp = this.items.find(i => i.type == "competence" && i.name.toLowerCase() == compName.toLowerCase() && i.system.niveau >= minLevel)
- if (comp) {
- return { isValid: true, item: foundry.utils.duplicate(comp) }
- } else {
- for (let attrKey in this.system.attributs) {
- if (this.system.attributs[attrKey].label.toLowerCase() == compName.toLowerCase() && this.system.attributs[attrKey].value >= minLevel) {
- return { isValid: true, item: foundry.utils.duplicate(this.system.attributs[attrKey]) }
- }
- }
- }
- return { isValid: false, warningMessage: `Prérequis insuffisant : la compétence/attribut ${compName} doit être de niveau ${minLevel} au minimum` }
- }
- /* -------------------------------------------- */
- addCompetenceBonus(compName, bonus, baCost) {
- let comp = this.items.find(i => i.type == "competence" && i.name.toLowerCase() == compName.toLowerCase())
- if (comp) {
- comp = foundry.utils.duplicate(comp)
- comp.system.bonus = bonus
- comp.system.baCost = baCost
- return { isValid: true, item: comp }
- }
- return { isValid: false, warningMessage: `Compétence ${compName} non trouvée` }
- }
- /* -------------------------------------------- */
- checkIfCompetence(compName) {
- let comp = this.items.find(i => i.type == "competence" && i.name.toLowerCase() == compName.toLowerCase())
- if (comp) {
- return { isValid: true, item: comp }
- }
- return { isValid: false }
- }
- /* -------------------------------------------- */
- getVigueur() {
- return this.system.sante.vigueur
- }
-
- /* -------------------------------------------- */
- getVigueurBonus() {
- let talents = this.items.filter(item => item.type == "talent" && item.system.isautomated)
- let bonus = 0
- for (let talent of talents) {
- for (let auto of talent.system.automations) {
- if (auto.eventtype == "bonus-permanent" && auto.bonusname == "vigueur") {
- bonus += Number(auto.bonus || 0)
- }
- }
- }
- return bonus
- }
-
- /* -------------------------------------------- */
- getSeuilPouvoir() {
- return this.system.ame.seuilpouvoir
- }
-
- /* -------------------------------------------- */
- getSeuilPouvoirBonus() {
- let talents = this.items.filter(item => item.type == "talent" && item.system.isautomated)
- let bonus = 0
- for (let talent of talents) {
- for (let auto of talent.system.automations) {
- if (auto.eventtype == "bonus-permanent" && auto.bonusname == "seuilpouvoir") {
- bonus += Number(auto.bonus || 0)
- }
- }
- }
- return bonus
- }
-
- /* -------------------------------------------- */
- getBonneAventure() {
- return this.system.bonneaventure.actuelle
- }
- /* -------------------------------------------- */
- checkBonneAventure(cost) {
- return (this.system.bonneaventure.actuelle >= cost)
- }
- /* -------------------------------------------- */
- changeBonneAventure(value) {
- let newBA = this.system.bonneaventure.actuelle
- newBA += value
- this.update({ 'system.bonneaventure.actuelle': newBA })
- }
-
- /* -------------------------------------------- */
- getEclat() {
- return this.system.eclat.value
- }
-
- /* -------------------------------------------- */
- changeEclat(value) {
- let newE = this.system.eclat.value
- newE += value
- this.update({ 'system.eclat.value': newE })
- }
-
- /* -------------------------------------------- */
- compareName(a, b) {
- if (a.name < b.name) {
- return -1;
- }
- if (a.name > b.name) {
- return 1;
- }
- return 0;
- }
-
- /* -------------------------------------------- */
- getAttribute(attrKey) {
- return this.system.attributes[attrKey]
- }
-
- /* -------------------------------------------- */
- getBonusDegats() {
- return 0;
- }
-
- /* -------------------------------------------- */
- changeEtatCombativite(value) {
- if (value === "vaincu") {
- value = 200
- }
- let sante = foundry.utils.duplicate(this.system.sante)
- sante.etat += Number(value)
- sante.etat = Math.max(sante.etat, 0)
- sante.etat = Math.min(sante.etat, this.system.sante.nbcombativite)
- this.update({ 'system.sante': sante })
- if (sante.etat == this.system.sante.nbcombativite) {
- ChatMessage.create({ content: `${this.name} est vaincu !` })
- }
- // Duplicated ! this.processCombativite(sante)
- }
-
- /* -------------------------------------------- */
- changeEtatAme(value) {
- if (value === "brise") {
- value = 200
- }
- let ame = foundry.utils.duplicate(this.system.ame)
- ame.etat += Number(value)
- ame.etat = Math.max(ame.etat, 0)
- // L'état ne peut pas dépasser le maximum actuel d'âme
- let maxAme = Math.min(this.system.ame.max || this.system.ame.nbame, this.system.ame.nbame - 1)
- ame.etat = Math.min(ame.etat, maxAme)
- this.update({ 'system.ame': ame })
- if (ame.etat >= maxAme) {
- ChatMessage.create({ content: `${this.name} est brisé !` })
- }
- }
-
- /* -------------------------------------------- */
- processCombativite(sante) {
- sante = sante || foundry.utils.duplicate(this.system.sante)
- // Gestion des états affaibli et très affaibli
- if (sante.etat == this.system.sante.nbcombativite - 2 || sante.etat == this.system.sante.nbcombativite - 1) {
- if (sante.etat == this.system.sante.nbcombativite - 2 && this.items.find(item => item.type == "talent" && item.name.toLowerCase() == "encaissement")) {
- ChatMessage.create({ content: `${this.name} ne subit pas les 2 adversités rouge grâce à Encaissement. Pensez à les ajouter à la fin de la scène !` })
- } else if (sante.etat == this.system.sante.nbcombativite - 1 && this.items.find(item => item.type == "talent" && item.name.toLowerCase().includes("vaillant"))) {
- ChatMessage.create({ content: `${this.name} ne subit pas les 2 adversités rouge grâce à Vaillant. Pensez à les ajouter à la fin de la scène !` })
- } else {
- ChatMessage.create({ content: `${this.name} subit 2 adversités rouge !` })
- this.incDecAdversite("rouge", 2)
- }
- }
- }
-
- /* -------------------------------------------- */
- processAme(ame) {
- ame = ame || foundry.utils.duplicate(this.system.ame)
- let maxAme = Math.min(this.system.ame.max || this.system.ame.nbame, this.system.ame.nbame - 1)
- // Gestion des états Traumatisé, Très Traumatisé et Brisé en fonction du maximum actuel
- // Les seuils sont calculés par rapport au maximum d'âme actuel
- if (maxAme >= 2 && ame.etat >= maxAme - 2) {
- if (ame.etat == maxAme - 2) {
- ChatMessage.create({ content: `${this.name} est Traumatisé !` })
- } else if (ame.etat == maxAme - 1) {
- ChatMessage.create({ content: `${this.name} est Très Traumatisé !` })
- } else if (ame.etat >= maxAme) {
- ChatMessage.create({ content: `${this.name} est Brisé !` })
- }
- } else if (ame.etat >= maxAme) {
- ChatMessage.create({ content: `${this.name} est Brisé !` })
- }
- }
-
- /* -------------------------------------------- */
- async equipGear(equipmentId) {
- let item = this.items.find(item => item.id == equipmentId);
- if (item?.system?.data) {
- let update = { _id: item.id, "system.equipped": !item.system.equipped };
- await this.updateEmbeddedDocuments('Item', [update]); // Updates one EmbeddedEntity
- }
- }
-
- /* -------------------------------------------- */
- getSubActors() {
- let subActors = [];
- for (let id of this.system.subactors) {
- subActors.push(foundry.utils.duplicate(game.actors.get(id)));
- }
- return subActors;
- }
- /* -------------------------------------------- */
- async addSubActor(subActorId) {
- let subActors = foundry.utils.duplicate(this.system.subactors);
- subActors.push(subActorId);
- await this.update({ 'system.subactors': subActors });
- }
- /* -------------------------------------------- */
- async delSubActor(subActorId) {
- let newArray = [];
- for (let id of this.system.subactors) {
- if (id != subActorId) {
- newArray.push(id);
- }
- }
- await this.update({ 'system.subactors': newArray });
- }
-
- /* -------------------------------------------- */
- getTotalAdversite() {
- return this.system.adversite.bleue + this.system.adversite.rouge + this.system.adversite.noire
- }
-
- /* -------------------------------------------- */
- async incDecAdversite(adv, incDec = 0) {
- let adversite = foundry.utils.duplicate(this.system.adversite)
- adversite[adv] += Number(incDec)
- adversite[adv] = Math.max(adversite[adv], 0)
- adversite[adv] = Math.min(adversite[adv], 20)
- this.update({ 'system.adversite': adversite })
- }
- /* -------------------------------------------- */
- async incDecQuantity(objetId, incDec = 0) {
- let objetQ = this.items.get(objetId)
- if (objetQ) {
- let newQ = objetQ.system.quantite + incDec
- newQ = Math.max(newQ, 0)
- await this.updateEmbeddedDocuments('Item', [{ _id: objetQ.id, 'system.quantite': newQ }]); // pdates one EmbeddedEntity
- }
- }
-
- /* -------------------------------------------- */
- computeRichesse() {
- let valueSC = 0
- for (let monnaie of this.items) {
- if (monnaie.type == "monnaie") {
- valueSC += Number(monnaie.system.prixsc) * Number(monnaie.system.quantite)
- }
- }
- return MournbladeCYD2Utility.computeMonnaieDetails(valueSC)
- }
-
- /* -------------------------------------------- */
- computeValeurEquipement() {
- let valueSC = 0
- for (let equip of this.items) {
- if (equip.type == "equipement" || equip.type == "arme" || equip.type == "protection") {
- valueSC += Number(equip.system.prixsc) * Number(equip.system.quantite ?? 1)
- valueSC += (Number(equip.system.prixca) * Number(equip.system.quantite ?? 1)) * 20
- valueSC += (Number(equip.system.prixpo) * Number(equip.system.quantite ?? 1)) * 400
- }
- }
- return MournbladeCYD2Utility.computeMonnaieDetails(valueSC)
- }
-
- /* -------------------------------------------- */
- getCompetence(compId) {
- return this.items.get(compId)
- }
-
- /* -------------------------------------------- */
- async setPredilectionUsed(compId, predIdx) {
- let comp = this.items.get(compId)
- let pred = foundry.utils.duplicate(comp.system.predilections)
- pred[predIdx].used = true
- await this.updateEmbeddedDocuments('Item', [{ _id: compId, 'system.predilections': pred }])
- }
-
- /* -------------------------------------------- */
- getInitiativeScore() {
- let init = this.getFlag("world", "last-initiative")
- return init || -1
- }
-
- /* -------------------------------------------- */
- getBestAttackValue() {
- let attackList = this.items.filter(item => (item.type == "arme" || item.type == "talent") && item.system.equipped)
- let maxOff = 0
- let bestArme
- for (let arme of attackList) {
- if (arme.type == "arme") {
- arme = this.prepareArme(arme)
- }
- if (arme.system.totalOffensif > maxOff) {
- maxOff = arme.system.totalOffensif
- bestArme = foundry.utils.duplicate(arme)
- }
- }
- return bestArme
- }
-
- /* -------------------------------------------- */
- getBestDefenseValue() {
- let defenseList = this.items.filter(item => (item.type == "arme") && item.system.equipped)
- let maxDef = 0
- let bestArme
- for (let arme of defenseList) {
- if (arme.type == "arme") {
- arme = this.prepareArme(arme)
- }
- if (arme.system.totalDefensif > maxDef) {
- maxDef = arme.system.totalDefensif
- bestArme = foundry.utils.duplicate(arme)
- }
- }
- return bestArme
- }
-
- /* -------------------------------------------- */
- searchRelevantTalents(competence) {
- let talents = []
-
- for (let talent of this.items) {
- if (talent.type == "talent" && talent.system.isautomated && talent.system.automations.length > 0) {
- for (let auto of talent.system.automations) {
- if (auto.eventtype === "prepare-roll") {
- if (auto.competence.toLowerCase() == competence.name.toLowerCase()) {
- talent = foundry.utils.duplicate(talent)
- talent.system.bonus = auto.bonus
- talent.system.baCost = auto.baCost
- talents.push(talent)
- }
- }
- }
- }
- }
- return talents
- }
-
- /* -------------------------------------------- */
- buildListeAdversites() {
- return []
- }
-
- /* -------------------------------------------- */
- getCommonRollData(attrKey = undefined, compId = undefined, compName = undefined) {
- let rollData = MournbladeCYD2Utility.getBasicRollData()
- rollData.alias = this.name
- rollData.actorImg = this.img
- rollData.actorId = this.id
- rollData.tokenId = this.token?.id
- rollData.img = this.img
- rollData.attributs = MournbladeCYD2Utility.getAttributs()
- rollData.maitriseId = "none"
- rollData.nbEclat = this.system.eclat.value
- rollData.nbBA = this.system.bonneaventure.actuelle
- rollData.nbAdversites = this.getTotalAdversite()
- rollData.talents = []
- rollData.attrKey2 = "none"
- rollData.coupDevastateur = this.items.find(it => it.type == "talent" && it.name.toLowerCase() == "coup dévastateur" && !it.system.used)
- rollData.hasAmbidextre = this.items.find(it => it.type == "talent" && it.name.toLowerCase() == "ambidextre")
- rollData.hasFeinte = this.system.bonneaventure.actuelle > 0 && this.items.find(it => it.type == "talent" && it.name.toLowerCase() == "feinte")
- rollData.isMonte = this.system.combat.monte
- rollData.config = game.system.mournbladecyd2.config
-
- if (attrKey) {
- rollData.attrKey = attrKey
- if (attrKey != "tochoose") {
- rollData.actionImg = "systems/fvtt-mournblade-cyd2/assets/icons/" + this.system.attributs[attrKey].labelnorm + ".webp"
- rollData.attr = foundry.utils.duplicate(this.system.attributs[attrKey])
- }
- }
- if (compId) {
- rollData.competence = foundry.utils.duplicate(this.items.get(compId) || {})
- let maitrises = [{ key: "none", label: "Aucune" }]
- rollData.competence.system.predilections.forEach(function (item) {
- if (item.maitrise) {
- maitrises.push({ key: item.id, label: item.name });
- }
- })
- rollData.maitrises = maitrises // rollData.competence.system.predilections.filter(p => p.maitrise)
- rollData.actionImg = rollData.competence?.img
- rollData.talents = this.searchRelevantTalents(rollData.competence)
- }
- if (compName) {
- rollData.competence = foundry.utils.duplicate(this.items.find(item => item.name.toLowerCase() == compName.toLowerCase()) || {})
- rollData.actionImg = rollData.competence?.img
- }
- return rollData
- }
-
- /* -------------------------------------------- */
- async rollAttribut(attrKey, isInit = false) {
- let rollData = this.getCommonRollData(attrKey)
- rollData.multiplier = (isInit) ? 1 : 2
- rollData.isInit = isInit
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
-
- /* -------------------------------------------- */
- async rollCompetence(attrKey, compId) {
- let rollData = this.getCommonRollData(attrKey, compId)
- rollData.multiplier = 1 // Attr multiplier, always 1 in competence mode
- console.log("RollDatra", rollData)
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
-
- /* -------------------------------------------- */
- async rollArmeOffensif(armeId) {
- let arme = this.items.get(armeId)
- if (arme.type == "arme") {
- arme = this.prepareArme(arme)
- }
- let rollData = this.getCommonRollData(arme.system.attrKey, arme.system.competence._id)
- rollData.arme = arme
- MournbladeCYD2Utility.updateWithTarget(rollData)
- console.log("ARME!", rollData)
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
- /* -------------------------------------------- */
- async rollAssommer() {
- let rollData = this.getCommonRollData("pui", undefined, "Filouterie")
- rollData.assomer = true
- rollData.conditionsCommunes = true
- MournbladeCYD2Utility.updateWithTarget(rollData)
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
- /* -------------------------------------------- */
- async rollCoupBas() {
- let rollData = this.getCommonRollData("pui", undefined, "Mêlée")
- rollData.coupBas = true
- rollData.conditionsCommunes = true
- MournbladeCYD2Utility.updateWithTarget(rollData)
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
- /* -------------------------------------------- */
- async rollImmobiliser() {
- let rollData = this.getCommonRollData("pui", undefined, "Mêlée")
- rollData.immobiliser = true
- rollData.conditionsCommunes = true
- rollData.cibleconsciente = true
- MournbladeCYD2Utility.updateWithTarget(rollData)
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
- /* -------------------------------------------- */
- async rollRepousser() {
- let rollData = this.getCommonRollData("pui", undefined, "Mêlée")
- rollData.repousser = true
- rollData.conditionsCommunes = true
- rollData.cibleconsciente = true
- MournbladeCYD2Utility.updateWithTarget(rollData)
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
- /* -------------------------------------------- */
- async rollDesengager() {
- let rollData = this.getCommonRollData("adr", undefined, "Mouvements")
- rollData.desengager = true
- rollData.conditionsCommunes = true
- MournbladeCYD2Utility.updateWithTarget(rollData)
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
-
- /* -------------------------------------------- */
- async rollArmeDegats(armeId, targetVigueur = undefined, rollDataInput = undefined) {
- let arme = this.items.get(armeId)
- if (arme.type == "arme") {
- arme = this.prepareArme(arme)
- }
- console.log("DEGATS", arme, targetVigueur, rollDataInput)
- let roll
- let bonus = 0
- let bonus2 = 0
-
- if (rollDataInput?.applyCoupDevastateur) {
- bonus2 = Math.floor(this.system.attributs.pui.value / 2)
- let talent = this.items.find(item => item.type == "talent" && item.name.toLowerCase() == "coup dévastateur")
- this.updateEmbeddedDocuments('Item', [{ _id: talent.id, 'system.used': true }])
- }
-
- if (rollDataInput?.isHeroique) {
- if (rollDataInput?.attaqueCharge) {
- bonus = 5
- }
- if (rollDataInput?.chargeCavalerie) {
- bonus = 6
- }
- roll = await new Roll("2d10rr10+" + arme.system.totalDegats + "+" + bonus + "+" + bonus2).roll()
- } else {
- if (rollDataInput?.attaqueCharge) {
- bonus = 3
- }
- if (rollDataInput?.chargeCavalerie) {
- bonus = 4
- }
- roll = await new Roll("1d10+" + arme.system.totalDegats + "+" + bonus + "+" + bonus2).roll()
- }
- await MournbladeCYD2Utility.showDiceSoNice(roll, game.settings.get("core", "rollMode"));
- let nbEtatPerdus = 0
- if (targetVigueur) {
- nbEtatPerdus = Math.floor(roll.total / targetVigueur)
- }
- //console.log(roll)
- let rollData = {
- arme: arme,
- finalResult: roll.total,
- formula: roll.formula,
- alias: this.name,
- actorImg: this.img,
- actorId: this.id,
- defenderTokenId: rollDataInput?.defenderTokenId,
- actionImg: arme.img,
- targetVigueur: targetVigueur,
- nbEtatPerdus: nbEtatPerdus
- }
- MournbladeCYD2Utility.createChatWithRollMode(rollData.alias, {
- content: await renderTemplate(`systems/fvtt-mournblade-cyd2/templates/chat-degats-result.html`, rollData)
- })
-
- if (rollDataInput?.defenderTokenId && nbEtatPerdus) {
- MournbladeCYD2Utility.applyCombativite(rollDataInput, nbEtatPerdus)
- }
-
- }
-}
diff --git a/.history/modules/mournblade-cyd2-actor_20251026082619.js b/.history/modules/mournblade-cyd2-actor_20251026082619.js
deleted file mode 100644
index d2dabe2..0000000
--- a/.history/modules/mournblade-cyd2-actor_20251026082619.js
+++ /dev/null
@@ -1,893 +0,0 @@
-/* -------------------------------------------- */
-import { MournbladeCYD2Utility } from "./mournblade-cyd2-utility.js";
-import { MournbladeCYD2RollDialog } from "./mournblade-cyd2-roll-dialog.js";
-
-/* -------------------------------------------- */
-const __degatsBonus = [-2, -2, -1, -1, 0, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 8, 8, 9, 9, 10, 10]
-const __vitesseBonus = [-2, -2, -1, -1, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8]
-
-/* -------------------------------------------- */
-/**
- * Extend the base Actor entity by defining a custom roll data structure which is ideal for the Simple system.
- * @extends {Actor}
- */
-export class MournbladeCYD2Actor extends Actor {
-
- /* -------------------------------------------- */
- /**
- * Override the create() function to provide additional SoS functionality.
- *
- * This overrided create() function adds initial items
- * Namely: Basic skills, money,
- *
- * @param {Object} data Barebones actor data which this function adds onto.
- * @param {Object} options (Unused) Additional options which customize the creation workflow.
- *
- */
-
- static async create(data, options) {
-
- // Case of compendium global import
- if (data instanceof Array) {
- return super.create(data, options);
- }
- // If the created actor has items (only applicable to duplicated actors) bypass the new actor creation logic
- if (data.items) {
- let actor = super.create(data, options);
- return actor;
- }
-
- if (data.type == 'personnage') {
- const skills = await MournbladeCYD2Utility.loadCompendium("fvtt-mournblade-cyd2.skills")
- data.items = skills.map(i => i.toObject())
- }
- if (data.type == 'creature') {
- const skills = await MournbladeCYD2Utility.loadCompendium("fvtt-mournblade-cyd2.skills-creatures")
- data.items = skills.map(i => i.toObject())
- data.items.push({ name: "Arme naturelle 1", type: 'arme', img: "systems/fvtt-mournblade-cyd2/assets/icons/melee.webp", system: { typearme: "contact", bonusmaniementoff: 0, seuildefense: 0, degats: "0" } })
- data.items.push({ name: "Arme naturelle 2", type: 'arme', img: "systems/fvtt-mournblade-cyd2/assets/icons/melee.webp", system: { typearme: "contact", bonusmaniementoff: 0, seuildefense: 0, degats: "0" } })
- }
-
- return super.create(data, options);
- }
-
- /* -------------------------------------------- */
- getBonusDefenseFromTalents() {
- let talents = this.items.filter(item => item.type == "talent" && item.system.isautomated)
- let bonus = 0
- for (let talent of talents) {
- for (let auto of talent.system.automations) {
- if (auto.eventtype == "bonus-permanent" && auto.bonusname == "bonus-defensif") {
- bonus += Number(auto.bonus || 0)
- }
- }
- }
- return bonus
- }
-
- /* -------------------------------------------- */
- prepareArme(arme) {
- if (this.type == "cellule") {
- return arme
- }
-
- arme = foundry.utils.duplicate(arme)
- let combat = this.getCombatValues()
- if (arme.system.typearme == "contact" || arme.system.typearme == "contactjet") {
- let bonusDefense = this.getBonusDefenseFromTalents()
- arme.system.competence = foundry.utils.duplicate(this.items.find(item => item.type == "competence" && item.name.toLowerCase() == "mêlée"))
- arme.system.attrKey = "pui"
- arme.system.totalDegats = arme.system.degats + "+" + combat.bonusDegatsTotal
- arme.system.totalOffensif = this.system.attributs.pui.value + arme.system.competence.system.niveau + arme.system.bonusmaniementoff + (this.system.combat.monte ? 3 : 0)
- arme.system.totalDefensif = combat.defenseTotal + arme.system.competence.system.niveau + arme.system.seuildefense + bonusDefense + (this.system.combat.monte ? 3 : 0)
- console.log("Arme", arme.system.totalDefensif, combat, arme.system.competence.system.niveau, arme.system.seuildefense, bonusDefense)
- arme.system.isdefense = true
- arme.system.isMelee = true
- arme.system.isDistance = false
- }
- if (arme.system.typearme == "jet" || arme.system.typearme == "tir") {
- arme.system.competence = foundry.utils.duplicate(this.items.find(item => item.type == "competence" && item.name.toLowerCase() == "armes à distance"))
- arme.system.attrKey = "adr"
- arme.system.totalOffensif = this.system.attributs.adr.value + arme.system.competence.system.niveau + arme.system.bonusmaniementoff
- arme.system.totalDegats = arme.system.degats
- arme.system.isMelee = false
- arme.system.isDistance = true
- if (arme.system.isdefense) {
- arme.system.totalDefensif = combat.defenseTotal + arme.system.competence.system.niveau + arme.system.seuildefense
- }
- }
- return arme
- }
-
- /* -------------------------------------------- */
- getItemSorted(types) {
- let items = this.items.filter(item => types.includes(item.type)) || []
- MournbladeCYD2Utility.sortArrayObjectsByName(items)
- return items
- }
- getWeapons() {
- let armes = []
- for (let arme of this.items) {
- if (arme.type == "arme") {
- armes.push(this.prepareArme(arme))
- }
- }
- MournbladeCYD2Utility.sortArrayObjectsByName(armes)
- return armes
- }
- getMonnaies() {
- return this.getItemSorted(["monnaie"])
- }
- getEquipments() {
- return this.getItemSorted(["equipement"])
- }
- getArtefacts() {
- return this.getItemSorted(["artefact"])
- }
- getArmors() {
- return this.getItemSorted(["protection"])
- }
- getHistoriques() {
- return this.getItemSorted(["historique"])
- }
- getProfils() {
- return this.getItemSorted(["profil"])
- }
- getTalents() {
- return this.getItemSorted(["talent"])
- }
- getRessources() {
- return this.getItemSorted(["ressource"])
- }
- getContacts() {
- return this.getItemSorted(["contact"])
- }
- getMutations() {
- return this.getItemSorted(["mutation"])
- }
- getDons() {
- return this.getItemSorted(["don"])
- }
- getPactes() {
- return this.getItemSorted(["pacte"])
- }
- getTendances() {
- return this.getItemSorted(["tendance"])
- }
- getRunes() {
- return this.getItemSorted(["rune"])
- }
- getTraitsChaotiques() {
- return this.getItemSorted(["traitchaotique"])
- }
- getTraitsEspeces() {
- return this.getItemSorted(["traitespece"])
- }
-
- /* -------------------------------------------- */
- getAspect() {
- return (this.system.balance.loi > this.system.balance.chaos) ? this.system.balance.loi : this.system.balance.chaos
- }
- getMarge() {
- return Math.abs(this.system.balance.loi - this.system.balance.chaos)
- }
- getAlignement() {
- return (this.system.balance.loi > this.system.balance.chaos) ? "loyal" : "chaotique"
- }
-
- /* -------------------------------------------- */
- getSkills() {
- let comp = []
- for (let item of this.items) {
- item = foundry.utils.duplicate(item)
- if (item.type == "competence") {
- item.system.attribut1total = item.system.niveau + (this.system.attributs[item.system.attribut1]?.value || 0)
- item.system.attribut2total = item.system.niveau + (this.system.attributs[item.system.attribut2]?.value || 0)
- item.system.attribut3total = item.system.niveau + (this.system.attributs[item.system.attribut3]?.value || 0)
- if (item.system.niveau == 0) {
- item.system.attribut1total -= 3
- item.system.attribut2total -= 3
- item.system.attribut3total -= 3
- }
- item.system.attribut1label = this.system.attributs[item.system.attribut1]?.label || ""
- item.system.attribut2label = this.system.attributs[item.system.attribut2]?.label || ""
- item.system.attribut3label = this.system.attributs[item.system.attribut3]?.label || ""
- comp.push(item)
- }
- }
- MournbladeCYD2Utility.sortArrayObjectsByName(comp)
- return comp
- }
-
- /* ----------------------- --------------------- */
- addMember(actorId) {
- let members = foundry.utils.duplicate(this.system.members)
- members.push({ id: actorId })
- this.update({ 'system.members': members })
- }
- async removeMember(actorId) {
- let members = this.system.members.filter(it => it.id != actorId)
- this.update({ 'system.members': members })
- }
-
- /* -------------------------------------------- */
- getDefenseBase() {
- return Math.max(this.system.attributs.tre.value, this.system.attributs.adr.value)
- }
-
- /* -------------------------------------------- */
- getVitesseBase() {
- return 5 + __vitesseBonus[this.system.attributs.adr.value]
- }
- /* -------------------------------------------- */
- getProtection() {
- let equipProtection = 0
- for (let armor of this.items) {
- if (armor.type == "protection" && armor.system.equipped) {
- equipProtection += Number(armor.system.protection)
- }
- }
- if (equipProtection < 4) {
- return 4 + equipProtection // Cas des boucliers + sans armure
- }
- return equipProtection // Uniquement la protection des armures + boucliers
- }
-
- /* -------------------------------------------- */
- getCombatValues() {
- if (this.type == "cellule") {
- return {
- initBase: 0,
- initTotal: 0,
- bonusDegats: 0,
- bonusDegatsTotal: 0,
- vitesseBase: 0,
- vitesseTotal: 0,
- defenseBase: 0,
- protection: 0,
- defenseTotal: 0
- }
- }
-
- let combat = {
- initBase: this.system.attributs.adr.value,
- initTotal: this.system.attributs.adr.value + this.system.combat.initbonus,
- bonusDegats: this.getBonusDegats(),
- bonusDegatsTotal: this.getBonusDegats() + this.system.combat.bonusdegats,
- vitesseBase: this.getVitesseBase(),
- vitesseTotal: this.getVitesseBase() + this.system.combat.vitessebonus,
- defenseBase: this.getDefenseBase(),
- protection: this.getProtection(),
- defenseTotal: this.getDefenseBase() + this.system.combat.defensebonus + this.getProtection() - this.getTotalAdversite() + (this.system.combat.defensetotale ? 3 : 0)
- }
- return combat
- }
-
- /* -------------------------------------------- */
- prepareBaseData() {
- }
-
- /* -------------------------------------------- */
- async prepareData() {
- super.prepareData();
- }
-
- /* -------------------------------------------- */
- prepareDerivedData() {
-
- if (this.type == 'personnage') {
- let talentBonus = this.getVigueurBonus()
- let vigueur = Math.floor((this.system.attributs.pui.value + this.system.attributs.tre.value) / 2) + talentBonus + this.system.sante.vigueurmodifier
- if (vigueur != this.system.sante.vigueur) {
- this.update({ 'system.sante.vigueur': vigueur })
- }
-
- let seuilPouvoirBonus = this.getSeuilPouvoirBonus()
- let seuilPouvoir = Math.floor((this.system.attributs.tre.value + this.system.attributs.cla.value) / 2) + seuilPouvoirBonus + this.system.ame.seuilpouvoirmodifier
- if (seuilPouvoir != this.system.ame.seuilpouvoir) {
- this.update({ 'system.ame.seuilpouvoir': seuilPouvoir })
- }
- }
- super.prepareDerivedData()
- }
-
- /* -------------------------------------------- */
- _preUpdate(changed, options, user) {
- if (changed?.system?.sante?.etat && changed?.system?.sante?.etat != this.system.sante.etat) {
- setTimeout(() => {
- this.processCombativite(changed.system.sante)
- }, 800)
- }
- if (changed?.system?.ame?.etat && changed?.system?.ame?.etat != this.system.ame.etat) {
- setTimeout(() => {
- this.processAme(changed.system.ame)
- }, 800)
- }
- super._preUpdate(changed, options, user);
- }
-
- /* -------------------------------------------- */
- _onUpdate(data, options, user) {
- super._onUpdate(data, options, user);
- }
- /* -------------------------------------------- */
- getItemById(id) {
- let item = this.items.find(item => item.id == id);
- if (item) {
- item = foundry.utils.duplicate(item)
- }
- return item;
- }
-
- /* -------------------------------------------- */
- async equipItem(itemId) {
- let item = this.items.find(item => item.id == itemId)
- if (item && item.system) {
- let update = { _id: item.id, "system.equipped": !item.system.equipped }
- await this.updateEmbeddedDocuments('Item', [update]); // Updates one EmbeddedEntity
- }
- }
-
- /* -------------------------------------------- */
- editItemField(itemId, itemType, itemField, dataType, value) {
- let item = this.items.find(item => item.id == itemId)
- if (item) {
- console.log("Item ", item, itemField, dataType, value)
- if (dataType.toLowerCase() == "number") {
- value = Number(value)
- } else {
- value = String(value)
- }
- let update = { _id: item.id, [`system.${itemField}`]: value };
- this.updateEmbeddedDocuments("Item", [update])
- }
- }
-
- /* -------------------------------------------- */
- checkAttribut(attribut, minLevel) {
- let attr = this.system.attributs.find(at => at.labelnorm == attribut.toLowerCase())
- if (attr && attr.value >= minLevel) {
- return { isValid: true, attr: foundry.utils.duplicate(attr) }
- }
- return { isValid: false }
- }
- /* -------------------------------------------- */
- checkAttributOrCompetenceLevel(compName, minLevel) {
- let comp = this.items.find(i => i.type == "competence" && i.name.toLowerCase() == compName.toLowerCase() && i.system.niveau >= minLevel)
- if (comp) {
- return { isValid: true, item: foundry.utils.duplicate(comp) }
- } else {
- for (let attrKey in this.system.attributs) {
- if (this.system.attributs[attrKey].label.toLowerCase() == compName.toLowerCase() && this.system.attributs[attrKey].value >= minLevel) {
- return { isValid: true, item: foundry.utils.duplicate(this.system.attributs[attrKey]) }
- }
- }
- }
- return { isValid: false, warningMessage: `Prérequis insuffisant : la compétence/attribut ${compName} doit être de niveau ${minLevel} au minimum` }
- }
- /* -------------------------------------------- */
- addCompetenceBonus(compName, bonus, baCost) {
- let comp = this.items.find(i => i.type == "competence" && i.name.toLowerCase() == compName.toLowerCase())
- if (comp) {
- comp = foundry.utils.duplicate(comp)
- comp.system.bonus = bonus
- comp.system.baCost = baCost
- return { isValid: true, item: comp }
- }
- return { isValid: false, warningMessage: `Compétence ${compName} non trouvée` }
- }
- /* -------------------------------------------- */
- checkIfCompetence(compName) {
- let comp = this.items.find(i => i.type == "competence" && i.name.toLowerCase() == compName.toLowerCase())
- if (comp) {
- return { isValid: true, item: comp }
- }
- return { isValid: false }
- }
- /* -------------------------------------------- */
- getVigueur() {
- return this.system.sante.vigueur
- }
-
- /* -------------------------------------------- */
- getVigueurBonus() {
- let talents = this.items.filter(item => item.type == "talent" && item.system.isautomated)
- let bonus = 0
- for (let talent of talents) {
- for (let auto of talent.system.automations) {
- if (auto.eventtype == "bonus-permanent" && auto.bonusname == "vigueur") {
- bonus += Number(auto.bonus || 0)
- }
- }
- }
- return bonus
- }
-
- /* -------------------------------------------- */
- getSeuilPouvoir() {
- return this.system.ame.seuilpouvoir
- }
-
- /* -------------------------------------------- */
- getSeuilPouvoirBonus() {
- let talents = this.items.filter(item => item.type == "talent" && item.system.isautomated)
- let bonus = 0
- for (let talent of talents) {
- for (let auto of talent.system.automations) {
- if (auto.eventtype == "bonus-permanent" && auto.bonusname == "seuilpouvoir") {
- bonus += Number(auto.bonus || 0)
- }
- }
- }
- return bonus
- }
-
- /* -------------------------------------------- */
- getAmeMax() {
- return Math.min(this.system.ame.max || this.system.ame.nbame, this.system.ame.nbame)
- }
-
- /* -------------------------------------------- */
- getBonneAventure() {
- return this.system.bonneaventure.actuelle
- }
- /* -------------------------------------------- */
- checkBonneAventure(cost) {
- return (this.system.bonneaventure.actuelle >= cost)
- }
- /* -------------------------------------------- */
- changeBonneAventure(value) {
- let newBA = this.system.bonneaventure.actuelle
- newBA += value
- this.update({ 'system.bonneaventure.actuelle': newBA })
- }
-
- /* -------------------------------------------- */
- getEclat() {
- return this.system.eclat.value
- }
-
- /* -------------------------------------------- */
- changeEclat(value) {
- let newE = this.system.eclat.value
- newE += value
- this.update({ 'system.eclat.value': newE })
- }
-
- /* -------------------------------------------- */
- compareName(a, b) {
- if (a.name < b.name) {
- return -1;
- }
- if (a.name > b.name) {
- return 1;
- }
- return 0;
- }
-
- /* -------------------------------------------- */
- getAttribute(attrKey) {
- return this.system.attributes[attrKey]
- }
-
- /* -------------------------------------------- */
- getBonusDegats() {
- return 0;
- }
-
- /* -------------------------------------------- */
- changeEtatCombativite(value) {
- if (value === "vaincu") {
- value = 200
- }
- let sante = foundry.utils.duplicate(this.system.sante)
- sante.etat += Number(value)
- sante.etat = Math.max(sante.etat, 0)
- sante.etat = Math.min(sante.etat, this.system.sante.nbcombativite)
- this.update({ 'system.sante': sante })
- if (sante.etat == this.system.sante.nbcombativite) {
- ChatMessage.create({ content: `${this.name} est vaincu !` })
- }
- // Duplicated ! this.processCombativite(sante)
- }
-
- /* -------------------------------------------- */
- changeEtatAme(value) {
- if (value === "brise") {
- value = 200
- }
- let ame = foundry.utils.duplicate(this.system.ame)
- ame.etat += Number(value)
- ame.etat = Math.max(ame.etat, 0)
- // L'état ne peut pas dépasser le maximum actuel d'âme
- let maxAme = Math.min(this.system.ame.max || this.system.ame.nbame, this.system.ame.nbame - 1)
- ame.etat = Math.min(ame.etat, maxAme)
- this.update({ 'system.ame': ame })
- if (ame.etat >= maxAme) {
- ChatMessage.create({ content: `${this.name} est brisé !` })
- }
- }
-
- /* -------------------------------------------- */
- processCombativite(sante) {
- sante = sante || foundry.utils.duplicate(this.system.sante)
- // Gestion des états affaibli et très affaibli
- if (sante.etat == this.system.sante.nbcombativite - 2 || sante.etat == this.system.sante.nbcombativite - 1) {
- if (sante.etat == this.system.sante.nbcombativite - 2 && this.items.find(item => item.type == "talent" && item.name.toLowerCase() == "encaissement")) {
- ChatMessage.create({ content: `${this.name} ne subit pas les 2 adversités rouge grâce à Encaissement. Pensez à les ajouter à la fin de la scène !` })
- } else if (sante.etat == this.system.sante.nbcombativite - 1 && this.items.find(item => item.type == "talent" && item.name.toLowerCase().includes("vaillant"))) {
- ChatMessage.create({ content: `${this.name} ne subit pas les 2 adversités rouge grâce à Vaillant. Pensez à les ajouter à la fin de la scène !` })
- } else {
- ChatMessage.create({ content: `${this.name} subit 2 adversités rouge !` })
- this.incDecAdversite("rouge", 2)
- }
- }
- }
-
- /* -------------------------------------------- */
- processAme(ame) {
- ame = ame || foundry.utils.duplicate(this.system.ame)
- let maxAme = Math.min(this.system.ame.max || this.system.ame.nbame, this.system.ame.nbame - 1)
- // Gestion des états Traumatisé, Très Traumatisé et Brisé en fonction du maximum actuel
- // Les seuils sont calculés par rapport au maximum d'âme actuel
- if (maxAme >= 2 && ame.etat >= maxAme - 2) {
- if (ame.etat == maxAme - 2) {
- ChatMessage.create({ content: `${this.name} est Traumatisé !` })
- } else if (ame.etat == maxAme - 1) {
- ChatMessage.create({ content: `${this.name} est Très Traumatisé !` })
- } else if (ame.etat >= maxAme) {
- ChatMessage.create({ content: `${this.name} est Brisé !` })
- }
- } else if (ame.etat >= maxAme) {
- ChatMessage.create({ content: `${this.name} est Brisé !` })
- }
- }
-
- /* -------------------------------------------- */
- async equipGear(equipmentId) {
- let item = this.items.find(item => item.id == equipmentId);
- if (item?.system?.data) {
- let update = { _id: item.id, "system.equipped": !item.system.equipped };
- await this.updateEmbeddedDocuments('Item', [update]); // Updates one EmbeddedEntity
- }
- }
-
- /* -------------------------------------------- */
- getSubActors() {
- let subActors = [];
- for (let id of this.system.subactors) {
- subActors.push(foundry.utils.duplicate(game.actors.get(id)));
- }
- return subActors;
- }
- /* -------------------------------------------- */
- async addSubActor(subActorId) {
- let subActors = foundry.utils.duplicate(this.system.subactors);
- subActors.push(subActorId);
- await this.update({ 'system.subactors': subActors });
- }
- /* -------------------------------------------- */
- async delSubActor(subActorId) {
- let newArray = [];
- for (let id of this.system.subactors) {
- if (id != subActorId) {
- newArray.push(id);
- }
- }
- await this.update({ 'system.subactors': newArray });
- }
-
- /* -------------------------------------------- */
- getTotalAdversite() {
- return this.system.adversite.bleue + this.system.adversite.rouge + this.system.adversite.noire
- }
-
- /* -------------------------------------------- */
- async incDecAdversite(adv, incDec = 0) {
- let adversite = foundry.utils.duplicate(this.system.adversite)
- adversite[adv] += Number(incDec)
- adversite[adv] = Math.max(adversite[adv], 0)
- adversite[adv] = Math.min(adversite[adv], 20)
- this.update({ 'system.adversite': adversite })
- }
- /* -------------------------------------------- */
- async incDecQuantity(objetId, incDec = 0) {
- let objetQ = this.items.get(objetId)
- if (objetQ) {
- let newQ = objetQ.system.quantite + incDec
- newQ = Math.max(newQ, 0)
- await this.updateEmbeddedDocuments('Item', [{ _id: objetQ.id, 'system.quantite': newQ }]); // pdates one EmbeddedEntity
- }
- }
-
- /* -------------------------------------------- */
- computeRichesse() {
- let valueSC = 0
- for (let monnaie of this.items) {
- if (monnaie.type == "monnaie") {
- valueSC += Number(monnaie.system.prixsc) * Number(monnaie.system.quantite)
- }
- }
- return MournbladeCYD2Utility.computeMonnaieDetails(valueSC)
- }
-
- /* -------------------------------------------- */
- computeValeurEquipement() {
- let valueSC = 0
- for (let equip of this.items) {
- if (equip.type == "equipement" || equip.type == "arme" || equip.type == "protection") {
- valueSC += Number(equip.system.prixsc) * Number(equip.system.quantite ?? 1)
- valueSC += (Number(equip.system.prixca) * Number(equip.system.quantite ?? 1)) * 20
- valueSC += (Number(equip.system.prixpo) * Number(equip.system.quantite ?? 1)) * 400
- }
- }
- return MournbladeCYD2Utility.computeMonnaieDetails(valueSC)
- }
-
- /* -------------------------------------------- */
- getCompetence(compId) {
- return this.items.get(compId)
- }
-
- /* -------------------------------------------- */
- async setPredilectionUsed(compId, predIdx) {
- let comp = this.items.get(compId)
- let pred = foundry.utils.duplicate(comp.system.predilections)
- pred[predIdx].used = true
- await this.updateEmbeddedDocuments('Item', [{ _id: compId, 'system.predilections': pred }])
- }
-
- /* -------------------------------------------- */
- getInitiativeScore() {
- let init = this.getFlag("world", "last-initiative")
- return init || -1
- }
-
- /* -------------------------------------------- */
- getBestAttackValue() {
- let attackList = this.items.filter(item => (item.type == "arme" || item.type == "talent") && item.system.equipped)
- let maxOff = 0
- let bestArme
- for (let arme of attackList) {
- if (arme.type == "arme") {
- arme = this.prepareArme(arme)
- }
- if (arme.system.totalOffensif > maxOff) {
- maxOff = arme.system.totalOffensif
- bestArme = foundry.utils.duplicate(arme)
- }
- }
- return bestArme
- }
-
- /* -------------------------------------------- */
- getBestDefenseValue() {
- let defenseList = this.items.filter(item => (item.type == "arme") && item.system.equipped)
- let maxDef = 0
- let bestArme
- for (let arme of defenseList) {
- if (arme.type == "arme") {
- arme = this.prepareArme(arme)
- }
- if (arme.system.totalDefensif > maxDef) {
- maxDef = arme.system.totalDefensif
- bestArme = foundry.utils.duplicate(arme)
- }
- }
- return bestArme
- }
-
- /* -------------------------------------------- */
- searchRelevantTalents(competence) {
- let talents = []
-
- for (let talent of this.items) {
- if (talent.type == "talent" && talent.system.isautomated && talent.system.automations.length > 0) {
- for (let auto of talent.system.automations) {
- if (auto.eventtype === "prepare-roll") {
- if (auto.competence.toLowerCase() == competence.name.toLowerCase()) {
- talent = foundry.utils.duplicate(talent)
- talent.system.bonus = auto.bonus
- talent.system.baCost = auto.baCost
- talents.push(talent)
- }
- }
- }
- }
- }
- return talents
- }
-
- /* -------------------------------------------- */
- buildListeAdversites() {
- return []
- }
-
- /* -------------------------------------------- */
- getCommonRollData(attrKey = undefined, compId = undefined, compName = undefined) {
- let rollData = MournbladeCYD2Utility.getBasicRollData()
- rollData.alias = this.name
- rollData.actorImg = this.img
- rollData.actorId = this.id
- rollData.tokenId = this.token?.id
- rollData.img = this.img
- rollData.attributs = MournbladeCYD2Utility.getAttributs()
- rollData.maitriseId = "none"
- rollData.nbEclat = this.system.eclat.value
- rollData.nbBA = this.system.bonneaventure.actuelle
- rollData.nbAdversites = this.getTotalAdversite()
- rollData.talents = []
- rollData.attrKey2 = "none"
- rollData.coupDevastateur = this.items.find(it => it.type == "talent" && it.name.toLowerCase() == "coup dévastateur" && !it.system.used)
- rollData.hasAmbidextre = this.items.find(it => it.type == "talent" && it.name.toLowerCase() == "ambidextre")
- rollData.hasFeinte = this.system.bonneaventure.actuelle > 0 && this.items.find(it => it.type == "talent" && it.name.toLowerCase() == "feinte")
- rollData.isMonte = this.system.combat.monte
- rollData.config = game.system.mournbladecyd2.config
-
- if (attrKey) {
- rollData.attrKey = attrKey
- if (attrKey != "tochoose") {
- rollData.actionImg = "systems/fvtt-mournblade-cyd2/assets/icons/" + this.system.attributs[attrKey].labelnorm + ".webp"
- rollData.attr = foundry.utils.duplicate(this.system.attributs[attrKey])
- }
- }
- if (compId) {
- rollData.competence = foundry.utils.duplicate(this.items.get(compId) || {})
- let maitrises = [{ key: "none", label: "Aucune" }]
- rollData.competence.system.predilections.forEach(function (item) {
- if (item.maitrise) {
- maitrises.push({ key: item.id, label: item.name });
- }
- })
- rollData.maitrises = maitrises // rollData.competence.system.predilections.filter(p => p.maitrise)
- rollData.actionImg = rollData.competence?.img
- rollData.talents = this.searchRelevantTalents(rollData.competence)
- }
- if (compName) {
- rollData.competence = foundry.utils.duplicate(this.items.find(item => item.name.toLowerCase() == compName.toLowerCase()) || {})
- rollData.actionImg = rollData.competence?.img
- }
- return rollData
- }
-
- /* -------------------------------------------- */
- async rollAttribut(attrKey, isInit = false) {
- let rollData = this.getCommonRollData(attrKey)
- rollData.multiplier = (isInit) ? 1 : 2
- rollData.isInit = isInit
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
-
- /* -------------------------------------------- */
- async rollCompetence(attrKey, compId) {
- let rollData = this.getCommonRollData(attrKey, compId)
- rollData.multiplier = 1 // Attr multiplier, always 1 in competence mode
- console.log("RollDatra", rollData)
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
-
- /* -------------------------------------------- */
- async rollArmeOffensif(armeId) {
- let arme = this.items.get(armeId)
- if (arme.type == "arme") {
- arme = this.prepareArme(arme)
- }
- let rollData = this.getCommonRollData(arme.system.attrKey, arme.system.competence._id)
- rollData.arme = arme
- MournbladeCYD2Utility.updateWithTarget(rollData)
- console.log("ARME!", rollData)
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
- /* -------------------------------------------- */
- async rollAssommer() {
- let rollData = this.getCommonRollData("pui", undefined, "Filouterie")
- rollData.assomer = true
- rollData.conditionsCommunes = true
- MournbladeCYD2Utility.updateWithTarget(rollData)
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
- /* -------------------------------------------- */
- async rollCoupBas() {
- let rollData = this.getCommonRollData("pui", undefined, "Mêlée")
- rollData.coupBas = true
- rollData.conditionsCommunes = true
- MournbladeCYD2Utility.updateWithTarget(rollData)
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
- /* -------------------------------------------- */
- async rollImmobiliser() {
- let rollData = this.getCommonRollData("pui", undefined, "Mêlée")
- rollData.immobiliser = true
- rollData.conditionsCommunes = true
- rollData.cibleconsciente = true
- MournbladeCYD2Utility.updateWithTarget(rollData)
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
- /* -------------------------------------------- */
- async rollRepousser() {
- let rollData = this.getCommonRollData("pui", undefined, "Mêlée")
- rollData.repousser = true
- rollData.conditionsCommunes = true
- rollData.cibleconsciente = true
- MournbladeCYD2Utility.updateWithTarget(rollData)
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
- /* -------------------------------------------- */
- async rollDesengager() {
- let rollData = this.getCommonRollData("adr", undefined, "Mouvements")
- rollData.desengager = true
- rollData.conditionsCommunes = true
- MournbladeCYD2Utility.updateWithTarget(rollData)
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
-
- /* -------------------------------------------- */
- async rollArmeDegats(armeId, targetVigueur = undefined, rollDataInput = undefined) {
- let arme = this.items.get(armeId)
- if (arme.type == "arme") {
- arme = this.prepareArme(arme)
- }
- console.log("DEGATS", arme, targetVigueur, rollDataInput)
- let roll
- let bonus = 0
- let bonus2 = 0
-
- if (rollDataInput?.applyCoupDevastateur) {
- bonus2 = Math.floor(this.system.attributs.pui.value / 2)
- let talent = this.items.find(item => item.type == "talent" && item.name.toLowerCase() == "coup dévastateur")
- this.updateEmbeddedDocuments('Item', [{ _id: talent.id, 'system.used': true }])
- }
-
- if (rollDataInput?.isHeroique) {
- if (rollDataInput?.attaqueCharge) {
- bonus = 5
- }
- if (rollDataInput?.chargeCavalerie) {
- bonus = 6
- }
- roll = await new Roll("2d10rr10+" + arme.system.totalDegats + "+" + bonus + "+" + bonus2).roll()
- } else {
- if (rollDataInput?.attaqueCharge) {
- bonus = 3
- }
- if (rollDataInput?.chargeCavalerie) {
- bonus = 4
- }
- roll = await new Roll("1d10+" + arme.system.totalDegats + "+" + bonus + "+" + bonus2).roll()
- }
- await MournbladeCYD2Utility.showDiceSoNice(roll, game.settings.get("core", "rollMode"));
- let nbEtatPerdus = 0
- if (targetVigueur) {
- nbEtatPerdus = Math.floor(roll.total / targetVigueur)
- }
- //console.log(roll)
- let rollData = {
- arme: arme,
- finalResult: roll.total,
- formula: roll.formula,
- alias: this.name,
- actorImg: this.img,
- actorId: this.id,
- defenderTokenId: rollDataInput?.defenderTokenId,
- actionImg: arme.img,
- targetVigueur: targetVigueur,
- nbEtatPerdus: nbEtatPerdus
- }
- MournbladeCYD2Utility.createChatWithRollMode(rollData.alias, {
- content: await renderTemplate(`systems/fvtt-mournblade-cyd2/templates/chat-degats-result.html`, rollData)
- })
-
- if (rollDataInput?.defenderTokenId && nbEtatPerdus) {
- MournbladeCYD2Utility.applyCombativite(rollDataInput, nbEtatPerdus)
- }
-
- }
-}
diff --git a/.history/modules/mournblade-cyd2-actor_20251026082724.js b/.history/modules/mournblade-cyd2-actor_20251026082724.js
deleted file mode 100644
index d2dabe2..0000000
--- a/.history/modules/mournblade-cyd2-actor_20251026082724.js
+++ /dev/null
@@ -1,893 +0,0 @@
-/* -------------------------------------------- */
-import { MournbladeCYD2Utility } from "./mournblade-cyd2-utility.js";
-import { MournbladeCYD2RollDialog } from "./mournblade-cyd2-roll-dialog.js";
-
-/* -------------------------------------------- */
-const __degatsBonus = [-2, -2, -1, -1, 0, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 8, 8, 9, 9, 10, 10]
-const __vitesseBonus = [-2, -2, -1, -1, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8]
-
-/* -------------------------------------------- */
-/**
- * Extend the base Actor entity by defining a custom roll data structure which is ideal for the Simple system.
- * @extends {Actor}
- */
-export class MournbladeCYD2Actor extends Actor {
-
- /* -------------------------------------------- */
- /**
- * Override the create() function to provide additional SoS functionality.
- *
- * This overrided create() function adds initial items
- * Namely: Basic skills, money,
- *
- * @param {Object} data Barebones actor data which this function adds onto.
- * @param {Object} options (Unused) Additional options which customize the creation workflow.
- *
- */
-
- static async create(data, options) {
-
- // Case of compendium global import
- if (data instanceof Array) {
- return super.create(data, options);
- }
- // If the created actor has items (only applicable to duplicated actors) bypass the new actor creation logic
- if (data.items) {
- let actor = super.create(data, options);
- return actor;
- }
-
- if (data.type == 'personnage') {
- const skills = await MournbladeCYD2Utility.loadCompendium("fvtt-mournblade-cyd2.skills")
- data.items = skills.map(i => i.toObject())
- }
- if (data.type == 'creature') {
- const skills = await MournbladeCYD2Utility.loadCompendium("fvtt-mournblade-cyd2.skills-creatures")
- data.items = skills.map(i => i.toObject())
- data.items.push({ name: "Arme naturelle 1", type: 'arme', img: "systems/fvtt-mournblade-cyd2/assets/icons/melee.webp", system: { typearme: "contact", bonusmaniementoff: 0, seuildefense: 0, degats: "0" } })
- data.items.push({ name: "Arme naturelle 2", type: 'arme', img: "systems/fvtt-mournblade-cyd2/assets/icons/melee.webp", system: { typearme: "contact", bonusmaniementoff: 0, seuildefense: 0, degats: "0" } })
- }
-
- return super.create(data, options);
- }
-
- /* -------------------------------------------- */
- getBonusDefenseFromTalents() {
- let talents = this.items.filter(item => item.type == "talent" && item.system.isautomated)
- let bonus = 0
- for (let talent of talents) {
- for (let auto of talent.system.automations) {
- if (auto.eventtype == "bonus-permanent" && auto.bonusname == "bonus-defensif") {
- bonus += Number(auto.bonus || 0)
- }
- }
- }
- return bonus
- }
-
- /* -------------------------------------------- */
- prepareArme(arme) {
- if (this.type == "cellule") {
- return arme
- }
-
- arme = foundry.utils.duplicate(arme)
- let combat = this.getCombatValues()
- if (arme.system.typearme == "contact" || arme.system.typearme == "contactjet") {
- let bonusDefense = this.getBonusDefenseFromTalents()
- arme.system.competence = foundry.utils.duplicate(this.items.find(item => item.type == "competence" && item.name.toLowerCase() == "mêlée"))
- arme.system.attrKey = "pui"
- arme.system.totalDegats = arme.system.degats + "+" + combat.bonusDegatsTotal
- arme.system.totalOffensif = this.system.attributs.pui.value + arme.system.competence.system.niveau + arme.system.bonusmaniementoff + (this.system.combat.monte ? 3 : 0)
- arme.system.totalDefensif = combat.defenseTotal + arme.system.competence.system.niveau + arme.system.seuildefense + bonusDefense + (this.system.combat.monte ? 3 : 0)
- console.log("Arme", arme.system.totalDefensif, combat, arme.system.competence.system.niveau, arme.system.seuildefense, bonusDefense)
- arme.system.isdefense = true
- arme.system.isMelee = true
- arme.system.isDistance = false
- }
- if (arme.system.typearme == "jet" || arme.system.typearme == "tir") {
- arme.system.competence = foundry.utils.duplicate(this.items.find(item => item.type == "competence" && item.name.toLowerCase() == "armes à distance"))
- arme.system.attrKey = "adr"
- arme.system.totalOffensif = this.system.attributs.adr.value + arme.system.competence.system.niveau + arme.system.bonusmaniementoff
- arme.system.totalDegats = arme.system.degats
- arme.system.isMelee = false
- arme.system.isDistance = true
- if (arme.system.isdefense) {
- arme.system.totalDefensif = combat.defenseTotal + arme.system.competence.system.niveau + arme.system.seuildefense
- }
- }
- return arme
- }
-
- /* -------------------------------------------- */
- getItemSorted(types) {
- let items = this.items.filter(item => types.includes(item.type)) || []
- MournbladeCYD2Utility.sortArrayObjectsByName(items)
- return items
- }
- getWeapons() {
- let armes = []
- for (let arme of this.items) {
- if (arme.type == "arme") {
- armes.push(this.prepareArme(arme))
- }
- }
- MournbladeCYD2Utility.sortArrayObjectsByName(armes)
- return armes
- }
- getMonnaies() {
- return this.getItemSorted(["monnaie"])
- }
- getEquipments() {
- return this.getItemSorted(["equipement"])
- }
- getArtefacts() {
- return this.getItemSorted(["artefact"])
- }
- getArmors() {
- return this.getItemSorted(["protection"])
- }
- getHistoriques() {
- return this.getItemSorted(["historique"])
- }
- getProfils() {
- return this.getItemSorted(["profil"])
- }
- getTalents() {
- return this.getItemSorted(["talent"])
- }
- getRessources() {
- return this.getItemSorted(["ressource"])
- }
- getContacts() {
- return this.getItemSorted(["contact"])
- }
- getMutations() {
- return this.getItemSorted(["mutation"])
- }
- getDons() {
- return this.getItemSorted(["don"])
- }
- getPactes() {
- return this.getItemSorted(["pacte"])
- }
- getTendances() {
- return this.getItemSorted(["tendance"])
- }
- getRunes() {
- return this.getItemSorted(["rune"])
- }
- getTraitsChaotiques() {
- return this.getItemSorted(["traitchaotique"])
- }
- getTraitsEspeces() {
- return this.getItemSorted(["traitespece"])
- }
-
- /* -------------------------------------------- */
- getAspect() {
- return (this.system.balance.loi > this.system.balance.chaos) ? this.system.balance.loi : this.system.balance.chaos
- }
- getMarge() {
- return Math.abs(this.system.balance.loi - this.system.balance.chaos)
- }
- getAlignement() {
- return (this.system.balance.loi > this.system.balance.chaos) ? "loyal" : "chaotique"
- }
-
- /* -------------------------------------------- */
- getSkills() {
- let comp = []
- for (let item of this.items) {
- item = foundry.utils.duplicate(item)
- if (item.type == "competence") {
- item.system.attribut1total = item.system.niveau + (this.system.attributs[item.system.attribut1]?.value || 0)
- item.system.attribut2total = item.system.niveau + (this.system.attributs[item.system.attribut2]?.value || 0)
- item.system.attribut3total = item.system.niveau + (this.system.attributs[item.system.attribut3]?.value || 0)
- if (item.system.niveau == 0) {
- item.system.attribut1total -= 3
- item.system.attribut2total -= 3
- item.system.attribut3total -= 3
- }
- item.system.attribut1label = this.system.attributs[item.system.attribut1]?.label || ""
- item.system.attribut2label = this.system.attributs[item.system.attribut2]?.label || ""
- item.system.attribut3label = this.system.attributs[item.system.attribut3]?.label || ""
- comp.push(item)
- }
- }
- MournbladeCYD2Utility.sortArrayObjectsByName(comp)
- return comp
- }
-
- /* ----------------------- --------------------- */
- addMember(actorId) {
- let members = foundry.utils.duplicate(this.system.members)
- members.push({ id: actorId })
- this.update({ 'system.members': members })
- }
- async removeMember(actorId) {
- let members = this.system.members.filter(it => it.id != actorId)
- this.update({ 'system.members': members })
- }
-
- /* -------------------------------------------- */
- getDefenseBase() {
- return Math.max(this.system.attributs.tre.value, this.system.attributs.adr.value)
- }
-
- /* -------------------------------------------- */
- getVitesseBase() {
- return 5 + __vitesseBonus[this.system.attributs.adr.value]
- }
- /* -------------------------------------------- */
- getProtection() {
- let equipProtection = 0
- for (let armor of this.items) {
- if (armor.type == "protection" && armor.system.equipped) {
- equipProtection += Number(armor.system.protection)
- }
- }
- if (equipProtection < 4) {
- return 4 + equipProtection // Cas des boucliers + sans armure
- }
- return equipProtection // Uniquement la protection des armures + boucliers
- }
-
- /* -------------------------------------------- */
- getCombatValues() {
- if (this.type == "cellule") {
- return {
- initBase: 0,
- initTotal: 0,
- bonusDegats: 0,
- bonusDegatsTotal: 0,
- vitesseBase: 0,
- vitesseTotal: 0,
- defenseBase: 0,
- protection: 0,
- defenseTotal: 0
- }
- }
-
- let combat = {
- initBase: this.system.attributs.adr.value,
- initTotal: this.system.attributs.adr.value + this.system.combat.initbonus,
- bonusDegats: this.getBonusDegats(),
- bonusDegatsTotal: this.getBonusDegats() + this.system.combat.bonusdegats,
- vitesseBase: this.getVitesseBase(),
- vitesseTotal: this.getVitesseBase() + this.system.combat.vitessebonus,
- defenseBase: this.getDefenseBase(),
- protection: this.getProtection(),
- defenseTotal: this.getDefenseBase() + this.system.combat.defensebonus + this.getProtection() - this.getTotalAdversite() + (this.system.combat.defensetotale ? 3 : 0)
- }
- return combat
- }
-
- /* -------------------------------------------- */
- prepareBaseData() {
- }
-
- /* -------------------------------------------- */
- async prepareData() {
- super.prepareData();
- }
-
- /* -------------------------------------------- */
- prepareDerivedData() {
-
- if (this.type == 'personnage') {
- let talentBonus = this.getVigueurBonus()
- let vigueur = Math.floor((this.system.attributs.pui.value + this.system.attributs.tre.value) / 2) + talentBonus + this.system.sante.vigueurmodifier
- if (vigueur != this.system.sante.vigueur) {
- this.update({ 'system.sante.vigueur': vigueur })
- }
-
- let seuilPouvoirBonus = this.getSeuilPouvoirBonus()
- let seuilPouvoir = Math.floor((this.system.attributs.tre.value + this.system.attributs.cla.value) / 2) + seuilPouvoirBonus + this.system.ame.seuilpouvoirmodifier
- if (seuilPouvoir != this.system.ame.seuilpouvoir) {
- this.update({ 'system.ame.seuilpouvoir': seuilPouvoir })
- }
- }
- super.prepareDerivedData()
- }
-
- /* -------------------------------------------- */
- _preUpdate(changed, options, user) {
- if (changed?.system?.sante?.etat && changed?.system?.sante?.etat != this.system.sante.etat) {
- setTimeout(() => {
- this.processCombativite(changed.system.sante)
- }, 800)
- }
- if (changed?.system?.ame?.etat && changed?.system?.ame?.etat != this.system.ame.etat) {
- setTimeout(() => {
- this.processAme(changed.system.ame)
- }, 800)
- }
- super._preUpdate(changed, options, user);
- }
-
- /* -------------------------------------------- */
- _onUpdate(data, options, user) {
- super._onUpdate(data, options, user);
- }
- /* -------------------------------------------- */
- getItemById(id) {
- let item = this.items.find(item => item.id == id);
- if (item) {
- item = foundry.utils.duplicate(item)
- }
- return item;
- }
-
- /* -------------------------------------------- */
- async equipItem(itemId) {
- let item = this.items.find(item => item.id == itemId)
- if (item && item.system) {
- let update = { _id: item.id, "system.equipped": !item.system.equipped }
- await this.updateEmbeddedDocuments('Item', [update]); // Updates one EmbeddedEntity
- }
- }
-
- /* -------------------------------------------- */
- editItemField(itemId, itemType, itemField, dataType, value) {
- let item = this.items.find(item => item.id == itemId)
- if (item) {
- console.log("Item ", item, itemField, dataType, value)
- if (dataType.toLowerCase() == "number") {
- value = Number(value)
- } else {
- value = String(value)
- }
- let update = { _id: item.id, [`system.${itemField}`]: value };
- this.updateEmbeddedDocuments("Item", [update])
- }
- }
-
- /* -------------------------------------------- */
- checkAttribut(attribut, minLevel) {
- let attr = this.system.attributs.find(at => at.labelnorm == attribut.toLowerCase())
- if (attr && attr.value >= minLevel) {
- return { isValid: true, attr: foundry.utils.duplicate(attr) }
- }
- return { isValid: false }
- }
- /* -------------------------------------------- */
- checkAttributOrCompetenceLevel(compName, minLevel) {
- let comp = this.items.find(i => i.type == "competence" && i.name.toLowerCase() == compName.toLowerCase() && i.system.niveau >= minLevel)
- if (comp) {
- return { isValid: true, item: foundry.utils.duplicate(comp) }
- } else {
- for (let attrKey in this.system.attributs) {
- if (this.system.attributs[attrKey].label.toLowerCase() == compName.toLowerCase() && this.system.attributs[attrKey].value >= minLevel) {
- return { isValid: true, item: foundry.utils.duplicate(this.system.attributs[attrKey]) }
- }
- }
- }
- return { isValid: false, warningMessage: `Prérequis insuffisant : la compétence/attribut ${compName} doit être de niveau ${minLevel} au minimum` }
- }
- /* -------------------------------------------- */
- addCompetenceBonus(compName, bonus, baCost) {
- let comp = this.items.find(i => i.type == "competence" && i.name.toLowerCase() == compName.toLowerCase())
- if (comp) {
- comp = foundry.utils.duplicate(comp)
- comp.system.bonus = bonus
- comp.system.baCost = baCost
- return { isValid: true, item: comp }
- }
- return { isValid: false, warningMessage: `Compétence ${compName} non trouvée` }
- }
- /* -------------------------------------------- */
- checkIfCompetence(compName) {
- let comp = this.items.find(i => i.type == "competence" && i.name.toLowerCase() == compName.toLowerCase())
- if (comp) {
- return { isValid: true, item: comp }
- }
- return { isValid: false }
- }
- /* -------------------------------------------- */
- getVigueur() {
- return this.system.sante.vigueur
- }
-
- /* -------------------------------------------- */
- getVigueurBonus() {
- let talents = this.items.filter(item => item.type == "talent" && item.system.isautomated)
- let bonus = 0
- for (let talent of talents) {
- for (let auto of talent.system.automations) {
- if (auto.eventtype == "bonus-permanent" && auto.bonusname == "vigueur") {
- bonus += Number(auto.bonus || 0)
- }
- }
- }
- return bonus
- }
-
- /* -------------------------------------------- */
- getSeuilPouvoir() {
- return this.system.ame.seuilpouvoir
- }
-
- /* -------------------------------------------- */
- getSeuilPouvoirBonus() {
- let talents = this.items.filter(item => item.type == "talent" && item.system.isautomated)
- let bonus = 0
- for (let talent of talents) {
- for (let auto of talent.system.automations) {
- if (auto.eventtype == "bonus-permanent" && auto.bonusname == "seuilpouvoir") {
- bonus += Number(auto.bonus || 0)
- }
- }
- }
- return bonus
- }
-
- /* -------------------------------------------- */
- getAmeMax() {
- return Math.min(this.system.ame.max || this.system.ame.nbame, this.system.ame.nbame)
- }
-
- /* -------------------------------------------- */
- getBonneAventure() {
- return this.system.bonneaventure.actuelle
- }
- /* -------------------------------------------- */
- checkBonneAventure(cost) {
- return (this.system.bonneaventure.actuelle >= cost)
- }
- /* -------------------------------------------- */
- changeBonneAventure(value) {
- let newBA = this.system.bonneaventure.actuelle
- newBA += value
- this.update({ 'system.bonneaventure.actuelle': newBA })
- }
-
- /* -------------------------------------------- */
- getEclat() {
- return this.system.eclat.value
- }
-
- /* -------------------------------------------- */
- changeEclat(value) {
- let newE = this.system.eclat.value
- newE += value
- this.update({ 'system.eclat.value': newE })
- }
-
- /* -------------------------------------------- */
- compareName(a, b) {
- if (a.name < b.name) {
- return -1;
- }
- if (a.name > b.name) {
- return 1;
- }
- return 0;
- }
-
- /* -------------------------------------------- */
- getAttribute(attrKey) {
- return this.system.attributes[attrKey]
- }
-
- /* -------------------------------------------- */
- getBonusDegats() {
- return 0;
- }
-
- /* -------------------------------------------- */
- changeEtatCombativite(value) {
- if (value === "vaincu") {
- value = 200
- }
- let sante = foundry.utils.duplicate(this.system.sante)
- sante.etat += Number(value)
- sante.etat = Math.max(sante.etat, 0)
- sante.etat = Math.min(sante.etat, this.system.sante.nbcombativite)
- this.update({ 'system.sante': sante })
- if (sante.etat == this.system.sante.nbcombativite) {
- ChatMessage.create({ content: `${this.name} est vaincu !` })
- }
- // Duplicated ! this.processCombativite(sante)
- }
-
- /* -------------------------------------------- */
- changeEtatAme(value) {
- if (value === "brise") {
- value = 200
- }
- let ame = foundry.utils.duplicate(this.system.ame)
- ame.etat += Number(value)
- ame.etat = Math.max(ame.etat, 0)
- // L'état ne peut pas dépasser le maximum actuel d'âme
- let maxAme = Math.min(this.system.ame.max || this.system.ame.nbame, this.system.ame.nbame - 1)
- ame.etat = Math.min(ame.etat, maxAme)
- this.update({ 'system.ame': ame })
- if (ame.etat >= maxAme) {
- ChatMessage.create({ content: `${this.name} est brisé !` })
- }
- }
-
- /* -------------------------------------------- */
- processCombativite(sante) {
- sante = sante || foundry.utils.duplicate(this.system.sante)
- // Gestion des états affaibli et très affaibli
- if (sante.etat == this.system.sante.nbcombativite - 2 || sante.etat == this.system.sante.nbcombativite - 1) {
- if (sante.etat == this.system.sante.nbcombativite - 2 && this.items.find(item => item.type == "talent" && item.name.toLowerCase() == "encaissement")) {
- ChatMessage.create({ content: `${this.name} ne subit pas les 2 adversités rouge grâce à Encaissement. Pensez à les ajouter à la fin de la scène !` })
- } else if (sante.etat == this.system.sante.nbcombativite - 1 && this.items.find(item => item.type == "talent" && item.name.toLowerCase().includes("vaillant"))) {
- ChatMessage.create({ content: `${this.name} ne subit pas les 2 adversités rouge grâce à Vaillant. Pensez à les ajouter à la fin de la scène !` })
- } else {
- ChatMessage.create({ content: `${this.name} subit 2 adversités rouge !` })
- this.incDecAdversite("rouge", 2)
- }
- }
- }
-
- /* -------------------------------------------- */
- processAme(ame) {
- ame = ame || foundry.utils.duplicate(this.system.ame)
- let maxAme = Math.min(this.system.ame.max || this.system.ame.nbame, this.system.ame.nbame - 1)
- // Gestion des états Traumatisé, Très Traumatisé et Brisé en fonction du maximum actuel
- // Les seuils sont calculés par rapport au maximum d'âme actuel
- if (maxAme >= 2 && ame.etat >= maxAme - 2) {
- if (ame.etat == maxAme - 2) {
- ChatMessage.create({ content: `${this.name} est Traumatisé !` })
- } else if (ame.etat == maxAme - 1) {
- ChatMessage.create({ content: `${this.name} est Très Traumatisé !` })
- } else if (ame.etat >= maxAme) {
- ChatMessage.create({ content: `${this.name} est Brisé !` })
- }
- } else if (ame.etat >= maxAme) {
- ChatMessage.create({ content: `${this.name} est Brisé !` })
- }
- }
-
- /* -------------------------------------------- */
- async equipGear(equipmentId) {
- let item = this.items.find(item => item.id == equipmentId);
- if (item?.system?.data) {
- let update = { _id: item.id, "system.equipped": !item.system.equipped };
- await this.updateEmbeddedDocuments('Item', [update]); // Updates one EmbeddedEntity
- }
- }
-
- /* -------------------------------------------- */
- getSubActors() {
- let subActors = [];
- for (let id of this.system.subactors) {
- subActors.push(foundry.utils.duplicate(game.actors.get(id)));
- }
- return subActors;
- }
- /* -------------------------------------------- */
- async addSubActor(subActorId) {
- let subActors = foundry.utils.duplicate(this.system.subactors);
- subActors.push(subActorId);
- await this.update({ 'system.subactors': subActors });
- }
- /* -------------------------------------------- */
- async delSubActor(subActorId) {
- let newArray = [];
- for (let id of this.system.subactors) {
- if (id != subActorId) {
- newArray.push(id);
- }
- }
- await this.update({ 'system.subactors': newArray });
- }
-
- /* -------------------------------------------- */
- getTotalAdversite() {
- return this.system.adversite.bleue + this.system.adversite.rouge + this.system.adversite.noire
- }
-
- /* -------------------------------------------- */
- async incDecAdversite(adv, incDec = 0) {
- let adversite = foundry.utils.duplicate(this.system.adversite)
- adversite[adv] += Number(incDec)
- adversite[adv] = Math.max(adversite[adv], 0)
- adversite[adv] = Math.min(adversite[adv], 20)
- this.update({ 'system.adversite': adversite })
- }
- /* -------------------------------------------- */
- async incDecQuantity(objetId, incDec = 0) {
- let objetQ = this.items.get(objetId)
- if (objetQ) {
- let newQ = objetQ.system.quantite + incDec
- newQ = Math.max(newQ, 0)
- await this.updateEmbeddedDocuments('Item', [{ _id: objetQ.id, 'system.quantite': newQ }]); // pdates one EmbeddedEntity
- }
- }
-
- /* -------------------------------------------- */
- computeRichesse() {
- let valueSC = 0
- for (let monnaie of this.items) {
- if (monnaie.type == "monnaie") {
- valueSC += Number(monnaie.system.prixsc) * Number(monnaie.system.quantite)
- }
- }
- return MournbladeCYD2Utility.computeMonnaieDetails(valueSC)
- }
-
- /* -------------------------------------------- */
- computeValeurEquipement() {
- let valueSC = 0
- for (let equip of this.items) {
- if (equip.type == "equipement" || equip.type == "arme" || equip.type == "protection") {
- valueSC += Number(equip.system.prixsc) * Number(equip.system.quantite ?? 1)
- valueSC += (Number(equip.system.prixca) * Number(equip.system.quantite ?? 1)) * 20
- valueSC += (Number(equip.system.prixpo) * Number(equip.system.quantite ?? 1)) * 400
- }
- }
- return MournbladeCYD2Utility.computeMonnaieDetails(valueSC)
- }
-
- /* -------------------------------------------- */
- getCompetence(compId) {
- return this.items.get(compId)
- }
-
- /* -------------------------------------------- */
- async setPredilectionUsed(compId, predIdx) {
- let comp = this.items.get(compId)
- let pred = foundry.utils.duplicate(comp.system.predilections)
- pred[predIdx].used = true
- await this.updateEmbeddedDocuments('Item', [{ _id: compId, 'system.predilections': pred }])
- }
-
- /* -------------------------------------------- */
- getInitiativeScore() {
- let init = this.getFlag("world", "last-initiative")
- return init || -1
- }
-
- /* -------------------------------------------- */
- getBestAttackValue() {
- let attackList = this.items.filter(item => (item.type == "arme" || item.type == "talent") && item.system.equipped)
- let maxOff = 0
- let bestArme
- for (let arme of attackList) {
- if (arme.type == "arme") {
- arme = this.prepareArme(arme)
- }
- if (arme.system.totalOffensif > maxOff) {
- maxOff = arme.system.totalOffensif
- bestArme = foundry.utils.duplicate(arme)
- }
- }
- return bestArme
- }
-
- /* -------------------------------------------- */
- getBestDefenseValue() {
- let defenseList = this.items.filter(item => (item.type == "arme") && item.system.equipped)
- let maxDef = 0
- let bestArme
- for (let arme of defenseList) {
- if (arme.type == "arme") {
- arme = this.prepareArme(arme)
- }
- if (arme.system.totalDefensif > maxDef) {
- maxDef = arme.system.totalDefensif
- bestArme = foundry.utils.duplicate(arme)
- }
- }
- return bestArme
- }
-
- /* -------------------------------------------- */
- searchRelevantTalents(competence) {
- let talents = []
-
- for (let talent of this.items) {
- if (talent.type == "talent" && talent.system.isautomated && talent.system.automations.length > 0) {
- for (let auto of talent.system.automations) {
- if (auto.eventtype === "prepare-roll") {
- if (auto.competence.toLowerCase() == competence.name.toLowerCase()) {
- talent = foundry.utils.duplicate(talent)
- talent.system.bonus = auto.bonus
- talent.system.baCost = auto.baCost
- talents.push(talent)
- }
- }
- }
- }
- }
- return talents
- }
-
- /* -------------------------------------------- */
- buildListeAdversites() {
- return []
- }
-
- /* -------------------------------------------- */
- getCommonRollData(attrKey = undefined, compId = undefined, compName = undefined) {
- let rollData = MournbladeCYD2Utility.getBasicRollData()
- rollData.alias = this.name
- rollData.actorImg = this.img
- rollData.actorId = this.id
- rollData.tokenId = this.token?.id
- rollData.img = this.img
- rollData.attributs = MournbladeCYD2Utility.getAttributs()
- rollData.maitriseId = "none"
- rollData.nbEclat = this.system.eclat.value
- rollData.nbBA = this.system.bonneaventure.actuelle
- rollData.nbAdversites = this.getTotalAdversite()
- rollData.talents = []
- rollData.attrKey2 = "none"
- rollData.coupDevastateur = this.items.find(it => it.type == "talent" && it.name.toLowerCase() == "coup dévastateur" && !it.system.used)
- rollData.hasAmbidextre = this.items.find(it => it.type == "talent" && it.name.toLowerCase() == "ambidextre")
- rollData.hasFeinte = this.system.bonneaventure.actuelle > 0 && this.items.find(it => it.type == "talent" && it.name.toLowerCase() == "feinte")
- rollData.isMonte = this.system.combat.monte
- rollData.config = game.system.mournbladecyd2.config
-
- if (attrKey) {
- rollData.attrKey = attrKey
- if (attrKey != "tochoose") {
- rollData.actionImg = "systems/fvtt-mournblade-cyd2/assets/icons/" + this.system.attributs[attrKey].labelnorm + ".webp"
- rollData.attr = foundry.utils.duplicate(this.system.attributs[attrKey])
- }
- }
- if (compId) {
- rollData.competence = foundry.utils.duplicate(this.items.get(compId) || {})
- let maitrises = [{ key: "none", label: "Aucune" }]
- rollData.competence.system.predilections.forEach(function (item) {
- if (item.maitrise) {
- maitrises.push({ key: item.id, label: item.name });
- }
- })
- rollData.maitrises = maitrises // rollData.competence.system.predilections.filter(p => p.maitrise)
- rollData.actionImg = rollData.competence?.img
- rollData.talents = this.searchRelevantTalents(rollData.competence)
- }
- if (compName) {
- rollData.competence = foundry.utils.duplicate(this.items.find(item => item.name.toLowerCase() == compName.toLowerCase()) || {})
- rollData.actionImg = rollData.competence?.img
- }
- return rollData
- }
-
- /* -------------------------------------------- */
- async rollAttribut(attrKey, isInit = false) {
- let rollData = this.getCommonRollData(attrKey)
- rollData.multiplier = (isInit) ? 1 : 2
- rollData.isInit = isInit
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
-
- /* -------------------------------------------- */
- async rollCompetence(attrKey, compId) {
- let rollData = this.getCommonRollData(attrKey, compId)
- rollData.multiplier = 1 // Attr multiplier, always 1 in competence mode
- console.log("RollDatra", rollData)
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
-
- /* -------------------------------------------- */
- async rollArmeOffensif(armeId) {
- let arme = this.items.get(armeId)
- if (arme.type == "arme") {
- arme = this.prepareArme(arme)
- }
- let rollData = this.getCommonRollData(arme.system.attrKey, arme.system.competence._id)
- rollData.arme = arme
- MournbladeCYD2Utility.updateWithTarget(rollData)
- console.log("ARME!", rollData)
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
- /* -------------------------------------------- */
- async rollAssommer() {
- let rollData = this.getCommonRollData("pui", undefined, "Filouterie")
- rollData.assomer = true
- rollData.conditionsCommunes = true
- MournbladeCYD2Utility.updateWithTarget(rollData)
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
- /* -------------------------------------------- */
- async rollCoupBas() {
- let rollData = this.getCommonRollData("pui", undefined, "Mêlée")
- rollData.coupBas = true
- rollData.conditionsCommunes = true
- MournbladeCYD2Utility.updateWithTarget(rollData)
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
- /* -------------------------------------------- */
- async rollImmobiliser() {
- let rollData = this.getCommonRollData("pui", undefined, "Mêlée")
- rollData.immobiliser = true
- rollData.conditionsCommunes = true
- rollData.cibleconsciente = true
- MournbladeCYD2Utility.updateWithTarget(rollData)
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
- /* -------------------------------------------- */
- async rollRepousser() {
- let rollData = this.getCommonRollData("pui", undefined, "Mêlée")
- rollData.repousser = true
- rollData.conditionsCommunes = true
- rollData.cibleconsciente = true
- MournbladeCYD2Utility.updateWithTarget(rollData)
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
- /* -------------------------------------------- */
- async rollDesengager() {
- let rollData = this.getCommonRollData("adr", undefined, "Mouvements")
- rollData.desengager = true
- rollData.conditionsCommunes = true
- MournbladeCYD2Utility.updateWithTarget(rollData)
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
-
- /* -------------------------------------------- */
- async rollArmeDegats(armeId, targetVigueur = undefined, rollDataInput = undefined) {
- let arme = this.items.get(armeId)
- if (arme.type == "arme") {
- arme = this.prepareArme(arme)
- }
- console.log("DEGATS", arme, targetVigueur, rollDataInput)
- let roll
- let bonus = 0
- let bonus2 = 0
-
- if (rollDataInput?.applyCoupDevastateur) {
- bonus2 = Math.floor(this.system.attributs.pui.value / 2)
- let talent = this.items.find(item => item.type == "talent" && item.name.toLowerCase() == "coup dévastateur")
- this.updateEmbeddedDocuments('Item', [{ _id: talent.id, 'system.used': true }])
- }
-
- if (rollDataInput?.isHeroique) {
- if (rollDataInput?.attaqueCharge) {
- bonus = 5
- }
- if (rollDataInput?.chargeCavalerie) {
- bonus = 6
- }
- roll = await new Roll("2d10rr10+" + arme.system.totalDegats + "+" + bonus + "+" + bonus2).roll()
- } else {
- if (rollDataInput?.attaqueCharge) {
- bonus = 3
- }
- if (rollDataInput?.chargeCavalerie) {
- bonus = 4
- }
- roll = await new Roll("1d10+" + arme.system.totalDegats + "+" + bonus + "+" + bonus2).roll()
- }
- await MournbladeCYD2Utility.showDiceSoNice(roll, game.settings.get("core", "rollMode"));
- let nbEtatPerdus = 0
- if (targetVigueur) {
- nbEtatPerdus = Math.floor(roll.total / targetVigueur)
- }
- //console.log(roll)
- let rollData = {
- arme: arme,
- finalResult: roll.total,
- formula: roll.formula,
- alias: this.name,
- actorImg: this.img,
- actorId: this.id,
- defenderTokenId: rollDataInput?.defenderTokenId,
- actionImg: arme.img,
- targetVigueur: targetVigueur,
- nbEtatPerdus: nbEtatPerdus
- }
- MournbladeCYD2Utility.createChatWithRollMode(rollData.alias, {
- content: await renderTemplate(`systems/fvtt-mournblade-cyd2/templates/chat-degats-result.html`, rollData)
- })
-
- if (rollDataInput?.defenderTokenId && nbEtatPerdus) {
- MournbladeCYD2Utility.applyCombativite(rollDataInput, nbEtatPerdus)
- }
-
- }
-}
diff --git a/.history/modules/mournblade-cyd2-actor_20251026083107.js b/.history/modules/mournblade-cyd2-actor_20251026083107.js
deleted file mode 100644
index 137cd4c..0000000
--- a/.history/modules/mournblade-cyd2-actor_20251026083107.js
+++ /dev/null
@@ -1,907 +0,0 @@
-/* -------------------------------------------- */
-import { MournbladeCYD2Utility } from "./mournblade-cyd2-utility.js";
-import { MournbladeCYD2RollDialog } from "./mournblade-cyd2-roll-dialog.js";
-
-/* -------------------------------------------- */
-const __degatsBonus = [-2, -2, -1, -1, 0, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 8, 8, 9, 9, 10, 10]
-const __vitesseBonus = [-2, -2, -1, -1, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8]
-
-/* -------------------------------------------- */
-/**
- * Extend the base Actor entity by defining a custom roll data structure which is ideal for the Simple system.
- * @extends {Actor}
- */
-export class MournbladeCYD2Actor extends Actor {
-
- /* -------------------------------------------- */
- /**
- * Override the create() function to provide additional SoS functionality.
- *
- * This overrided create() function adds initial items
- * Namely: Basic skills, money,
- *
- * @param {Object} data Barebones actor data which this function adds onto.
- * @param {Object} options (Unused) Additional options which customize the creation workflow.
- *
- */
-
- static async create(data, options) {
-
- // Case of compendium global import
- if (data instanceof Array) {
- return super.create(data, options);
- }
- // If the created actor has items (only applicable to duplicated actors) bypass the new actor creation logic
- if (data.items) {
- let actor = super.create(data, options);
- return actor;
- }
-
- if (data.type == 'personnage') {
- const skills = await MournbladeCYD2Utility.loadCompendium("fvtt-mournblade-cyd2.skills")
- data.items = skills.map(i => i.toObject())
- }
- if (data.type == 'creature') {
- const skills = await MournbladeCYD2Utility.loadCompendium("fvtt-mournblade-cyd2.skills-creatures")
- data.items = skills.map(i => i.toObject())
- data.items.push({ name: "Arme naturelle 1", type: 'arme', img: "systems/fvtt-mournblade-cyd2/assets/icons/melee.webp", system: { typearme: "contact", bonusmaniementoff: 0, seuildefense: 0, degats: "0" } })
- data.items.push({ name: "Arme naturelle 2", type: 'arme', img: "systems/fvtt-mournblade-cyd2/assets/icons/melee.webp", system: { typearme: "contact", bonusmaniementoff: 0, seuildefense: 0, degats: "0" } })
- }
-
- return super.create(data, options);
- }
-
- /* -------------------------------------------- */
- getBonusDefenseFromTalents() {
- let talents = this.items.filter(item => item.type == "talent" && item.system.isautomated)
- let bonus = 0
- for (let talent of talents) {
- for (let auto of talent.system.automations) {
- if (auto.eventtype == "bonus-permanent" && auto.bonusname == "bonus-defensif") {
- bonus += Number(auto.bonus || 0)
- }
- }
- }
- return bonus
- }
-
- /* -------------------------------------------- */
- prepareArme(arme) {
- if (this.type == "cellule") {
- return arme
- }
-
- arme = foundry.utils.duplicate(arme)
- let combat = this.getCombatValues()
- if (arme.system.typearme == "contact" || arme.system.typearme == "contactjet") {
- let bonusDefense = this.getBonusDefenseFromTalents()
- arme.system.competence = foundry.utils.duplicate(this.items.find(item => item.type == "competence" && item.name.toLowerCase() == "mêlée"))
- arme.system.attrKey = "pui"
- arme.system.totalDegats = arme.system.degats + "+" + combat.bonusDegatsTotal
- arme.system.totalOffensif = this.system.attributs.pui.value + arme.system.competence.system.niveau + arme.system.bonusmaniementoff + (this.system.combat.monte ? 3 : 0)
- arme.system.totalDefensif = combat.defenseTotal + arme.system.competence.system.niveau + arme.system.seuildefense + bonusDefense + (this.system.combat.monte ? 3 : 0)
- console.log("Arme", arme.system.totalDefensif, combat, arme.system.competence.system.niveau, arme.system.seuildefense, bonusDefense)
- arme.system.isdefense = true
- arme.system.isMelee = true
- arme.system.isDistance = false
- }
- if (arme.system.typearme == "jet" || arme.system.typearme == "tir") {
- arme.system.competence = foundry.utils.duplicate(this.items.find(item => item.type == "competence" && item.name.toLowerCase() == "armes à distance"))
- arme.system.attrKey = "adr"
- arme.system.totalOffensif = this.system.attributs.adr.value + arme.system.competence.system.niveau + arme.system.bonusmaniementoff
- arme.system.totalDegats = arme.system.degats
- arme.system.isMelee = false
- arme.system.isDistance = true
- if (arme.system.isdefense) {
- arme.system.totalDefensif = combat.defenseTotal + arme.system.competence.system.niveau + arme.system.seuildefense
- }
- }
- return arme
- }
-
- /* -------------------------------------------- */
- getItemSorted(types) {
- let items = this.items.filter(item => types.includes(item.type)) || []
- MournbladeCYD2Utility.sortArrayObjectsByName(items)
- return items
- }
- getWeapons() {
- let armes = []
- for (let arme of this.items) {
- if (arme.type == "arme") {
- armes.push(this.prepareArme(arme))
- }
- }
- MournbladeCYD2Utility.sortArrayObjectsByName(armes)
- return armes
- }
- getMonnaies() {
- return this.getItemSorted(["monnaie"])
- }
- getEquipments() {
- return this.getItemSorted(["equipement"])
- }
- getArtefacts() {
- return this.getItemSorted(["artefact"])
- }
- getArmors() {
- return this.getItemSorted(["protection"])
- }
- getHistoriques() {
- return this.getItemSorted(["historique"])
- }
- getProfils() {
- return this.getItemSorted(["profil"])
- }
- getTalents() {
- return this.getItemSorted(["talent"])
- }
- getRessources() {
- return this.getItemSorted(["ressource"])
- }
- getContacts() {
- return this.getItemSorted(["contact"])
- }
- getMutations() {
- return this.getItemSorted(["mutation"])
- }
- getDons() {
- return this.getItemSorted(["don"])
- }
- getPactes() {
- return this.getItemSorted(["pacte"])
- }
- getTendances() {
- return this.getItemSorted(["tendance"])
- }
- getRunes() {
- return this.getItemSorted(["rune"])
- }
- getTraitsChaotiques() {
- return this.getItemSorted(["traitchaotique"])
- }
- getTraitsEspeces() {
- return this.getItemSorted(["traitespece"])
- }
-
- /* -------------------------------------------- */
- getAspect() {
- return (this.system.balance.loi > this.system.balance.chaos) ? this.system.balance.loi : this.system.balance.chaos
- }
- getMarge() {
- return Math.abs(this.system.balance.loi - this.system.balance.chaos)
- }
- getAlignement() {
- return (this.system.balance.loi > this.system.balance.chaos) ? "loyal" : "chaotique"
- }
-
- /* -------------------------------------------- */
- getSkills() {
- let comp = []
- for (let item of this.items) {
- item = foundry.utils.duplicate(item)
- if (item.type == "competence") {
- item.system.attribut1total = item.system.niveau + (this.system.attributs[item.system.attribut1]?.value || 0)
- item.system.attribut2total = item.system.niveau + (this.system.attributs[item.system.attribut2]?.value || 0)
- item.system.attribut3total = item.system.niveau + (this.system.attributs[item.system.attribut3]?.value || 0)
- if (item.system.niveau == 0) {
- item.system.attribut1total -= 3
- item.system.attribut2total -= 3
- item.system.attribut3total -= 3
- }
- item.system.attribut1label = this.system.attributs[item.system.attribut1]?.label || ""
- item.system.attribut2label = this.system.attributs[item.system.attribut2]?.label || ""
- item.system.attribut3label = this.system.attributs[item.system.attribut3]?.label || ""
- comp.push(item)
- }
- }
- MournbladeCYD2Utility.sortArrayObjectsByName(comp)
- return comp
- }
-
- /* ----------------------- --------------------- */
- addMember(actorId) {
- let members = foundry.utils.duplicate(this.system.members)
- members.push({ id: actorId })
- this.update({ 'system.members': members })
- }
- async removeMember(actorId) {
- let members = this.system.members.filter(it => it.id != actorId)
- this.update({ 'system.members': members })
- }
-
- /* -------------------------------------------- */
- getDefenseBase() {
- return Math.max(this.system.attributs.tre.value, this.system.attributs.adr.value)
- }
-
- /* -------------------------------------------- */
- getVitesseBase() {
- return 5 + __vitesseBonus[this.system.attributs.adr.value]
- }
- /* -------------------------------------------- */
- getProtection() {
- let equipProtection = 0
- for (let armor of this.items) {
- if (armor.type == "protection" && armor.system.equipped) {
- equipProtection += Number(armor.system.protection)
- }
- }
- if (equipProtection < 4) {
- return 4 + equipProtection // Cas des boucliers + sans armure
- }
- return equipProtection // Uniquement la protection des armures + boucliers
- }
-
- /* -------------------------------------------- */
- getCombatValues() {
- if (this.type == "cellule") {
- return {
- initBase: 0,
- initTotal: 0,
- bonusDegats: 0,
- bonusDegatsTotal: 0,
- vitesseBase: 0,
- vitesseTotal: 0,
- defenseBase: 0,
- protection: 0,
- defenseTotal: 0
- }
- }
-
- let combat = {
- initBase: this.system.attributs.adr.value,
- initTotal: this.system.attributs.adr.value + this.system.combat.initbonus,
- bonusDegats: this.getBonusDegats(),
- bonusDegatsTotal: this.getBonusDegats() + this.system.combat.bonusdegats,
- vitesseBase: this.getVitesseBase(),
- vitesseTotal: this.getVitesseBase() + this.system.combat.vitessebonus,
- defenseBase: this.getDefenseBase(),
- protection: this.getProtection(),
- defenseTotal: this.getDefenseBase() + this.system.combat.defensebonus + this.getProtection() - this.getTotalAdversite() + (this.system.combat.defensetotale ? 3 : 0)
- }
- return combat
- }
-
- /* -------------------------------------------- */
- prepareBaseData() {
- }
-
- /* -------------------------------------------- */
- async prepareData() {
- super.prepareData();
- }
-
- /* -------------------------------------------- */
- prepareDerivedData() {
-
- if (this.type == 'personnage') {
- let talentBonus = this.getVigueurBonus()
- let vigueur = Math.floor((this.system.attributs.pui.value + this.system.attributs.tre.value) / 2) + talentBonus + this.system.sante.vigueurmodifier
- if (vigueur != this.system.sante.vigueur) {
- this.update({ 'system.sante.vigueur': vigueur })
- }
-
- let seuilPouvoirBonus = this.getSeuilPouvoirBonus()
- let seuilPouvoir = Math.floor((this.system.attributs.tre.value + this.system.attributs.cla.value) / 2) + seuilPouvoirBonus + this.system.ame.seuilpouvoirmodifier
- if (seuilPouvoir != this.system.ame.seuilpouvoir) {
- this.update({ 'system.ame.seuilpouvoir': seuilPouvoir })
- }
- }
- super.prepareDerivedData()
- }
-
- /* -------------------------------------------- */
- _preUpdate(changed, options, user) {
- if (changed?.system?.sante?.etat && changed?.system?.sante?.etat != this.system.sante.etat) {
- setTimeout(() => {
- this.processCombativite(changed.system.sante)
- }, 800)
- }
- if (changed?.system?.ame?.etat && changed?.system?.ame?.etat != this.system.ame.etat) {
- // S'assurer que l'état ne dépasse pas le maximum actuel d'âme
- let maxAme = Math.min(this.system.ame.max || this.system.ame.nbame, this.system.ame.nbame)
- if (changed.system.ame.etat > maxAme) {
- changed.system.ame.etat = maxAme
- }
- if (changed.system.ame.etat < 0) {
- changed.system.ame.etat = 0
- }
- setTimeout(() => {
- this.processAme(changed.system.ame)
- }, 800)
- }
- // Si le maximum d'âme change, s'assurer que l'état actuel ne le dépasse pas
- if (changed?.system?.ame?.max && changed.system.ame.max != this.system.ame.max) {
- if (this.system.ame.etat > changed.system.ame.max) {
- changed.system.ame.etat = changed.system.ame.max
- }
- }
- super._preUpdate(changed, options, user);
- }
-
- /* -------------------------------------------- */
- _onUpdate(data, options, user) {
- super._onUpdate(data, options, user);
- }
- /* -------------------------------------------- */
- getItemById(id) {
- let item = this.items.find(item => item.id == id);
- if (item) {
- item = foundry.utils.duplicate(item)
- }
- return item;
- }
-
- /* -------------------------------------------- */
- async equipItem(itemId) {
- let item = this.items.find(item => item.id == itemId)
- if (item && item.system) {
- let update = { _id: item.id, "system.equipped": !item.system.equipped }
- await this.updateEmbeddedDocuments('Item', [update]); // Updates one EmbeddedEntity
- }
- }
-
- /* -------------------------------------------- */
- editItemField(itemId, itemType, itemField, dataType, value) {
- let item = this.items.find(item => item.id == itemId)
- if (item) {
- console.log("Item ", item, itemField, dataType, value)
- if (dataType.toLowerCase() == "number") {
- value = Number(value)
- } else {
- value = String(value)
- }
- let update = { _id: item.id, [`system.${itemField}`]: value };
- this.updateEmbeddedDocuments("Item", [update])
- }
- }
-
- /* -------------------------------------------- */
- checkAttribut(attribut, minLevel) {
- let attr = this.system.attributs.find(at => at.labelnorm == attribut.toLowerCase())
- if (attr && attr.value >= minLevel) {
- return { isValid: true, attr: foundry.utils.duplicate(attr) }
- }
- return { isValid: false }
- }
- /* -------------------------------------------- */
- checkAttributOrCompetenceLevel(compName, minLevel) {
- let comp = this.items.find(i => i.type == "competence" && i.name.toLowerCase() == compName.toLowerCase() && i.system.niveau >= minLevel)
- if (comp) {
- return { isValid: true, item: foundry.utils.duplicate(comp) }
- } else {
- for (let attrKey in this.system.attributs) {
- if (this.system.attributs[attrKey].label.toLowerCase() == compName.toLowerCase() && this.system.attributs[attrKey].value >= minLevel) {
- return { isValid: true, item: foundry.utils.duplicate(this.system.attributs[attrKey]) }
- }
- }
- }
- return { isValid: false, warningMessage: `Prérequis insuffisant : la compétence/attribut ${compName} doit être de niveau ${minLevel} au minimum` }
- }
- /* -------------------------------------------- */
- addCompetenceBonus(compName, bonus, baCost) {
- let comp = this.items.find(i => i.type == "competence" && i.name.toLowerCase() == compName.toLowerCase())
- if (comp) {
- comp = foundry.utils.duplicate(comp)
- comp.system.bonus = bonus
- comp.system.baCost = baCost
- return { isValid: true, item: comp }
- }
- return { isValid: false, warningMessage: `Compétence ${compName} non trouvée` }
- }
- /* -------------------------------------------- */
- checkIfCompetence(compName) {
- let comp = this.items.find(i => i.type == "competence" && i.name.toLowerCase() == compName.toLowerCase())
- if (comp) {
- return { isValid: true, item: comp }
- }
- return { isValid: false }
- }
- /* -------------------------------------------- */
- getVigueur() {
- return this.system.sante.vigueur
- }
-
- /* -------------------------------------------- */
- getVigueurBonus() {
- let talents = this.items.filter(item => item.type == "talent" && item.system.isautomated)
- let bonus = 0
- for (let talent of talents) {
- for (let auto of talent.system.automations) {
- if (auto.eventtype == "bonus-permanent" && auto.bonusname == "vigueur") {
- bonus += Number(auto.bonus || 0)
- }
- }
- }
- return bonus
- }
-
- /* -------------------------------------------- */
- getSeuilPouvoir() {
- return this.system.ame.seuilpouvoir
- }
-
- /* -------------------------------------------- */
- getSeuilPouvoirBonus() {
- let talents = this.items.filter(item => item.type == "talent" && item.system.isautomated)
- let bonus = 0
- for (let talent of talents) {
- for (let auto of talent.system.automations) {
- if (auto.eventtype == "bonus-permanent" && auto.bonusname == "seuilpouvoir") {
- bonus += Number(auto.bonus || 0)
- }
- }
- }
- return bonus
- }
-
- /* -------------------------------------------- */
- getAmeMax() {
- return Math.min(this.system.ame.max || this.system.ame.nbame, this.system.ame.nbame)
- }
-
- /* -------------------------------------------- */
- getBonneAventure() {
- return this.system.bonneaventure.actuelle
- }
- /* -------------------------------------------- */
- checkBonneAventure(cost) {
- return (this.system.bonneaventure.actuelle >= cost)
- }
- /* -------------------------------------------- */
- changeBonneAventure(value) {
- let newBA = this.system.bonneaventure.actuelle
- newBA += value
- this.update({ 'system.bonneaventure.actuelle': newBA })
- }
-
- /* -------------------------------------------- */
- getEclat() {
- return this.system.eclat.value
- }
-
- /* -------------------------------------------- */
- changeEclat(value) {
- let newE = this.system.eclat.value
- newE += value
- this.update({ 'system.eclat.value': newE })
- }
-
- /* -------------------------------------------- */
- compareName(a, b) {
- if (a.name < b.name) {
- return -1;
- }
- if (a.name > b.name) {
- return 1;
- }
- return 0;
- }
-
- /* -------------------------------------------- */
- getAttribute(attrKey) {
- return this.system.attributes[attrKey]
- }
-
- /* -------------------------------------------- */
- getBonusDegats() {
- return 0;
- }
-
- /* -------------------------------------------- */
- changeEtatCombativite(value) {
- if (value === "vaincu") {
- value = 200
- }
- let sante = foundry.utils.duplicate(this.system.sante)
- sante.etat += Number(value)
- sante.etat = Math.max(sante.etat, 0)
- sante.etat = Math.min(sante.etat, this.system.sante.nbcombativite)
- this.update({ 'system.sante': sante })
- if (sante.etat == this.system.sante.nbcombativite) {
- ChatMessage.create({ content: `${this.name} est vaincu !` })
- }
- // Duplicated ! this.processCombativite(sante)
- }
-
- /* -------------------------------------------- */
- changeEtatAme(value) {
- if (value === "brise") {
- value = 200
- }
- let ame = foundry.utils.duplicate(this.system.ame)
- ame.etat += Number(value)
- ame.etat = Math.max(ame.etat, 0)
- // L'état ne peut pas dépasser le maximum actuel d'âme
- let maxAme = Math.min(this.system.ame.max || this.system.ame.nbame, this.system.ame.nbame - 1)
- ame.etat = Math.min(ame.etat, maxAme)
- this.update({ 'system.ame': ame })
- if (ame.etat >= maxAme) {
- ChatMessage.create({ content: `${this.name} est brisé !` })
- }
- }
-
- /* -------------------------------------------- */
- processCombativite(sante) {
- sante = sante || foundry.utils.duplicate(this.system.sante)
- // Gestion des états affaibli et très affaibli
- if (sante.etat == this.system.sante.nbcombativite - 2 || sante.etat == this.system.sante.nbcombativite - 1) {
- if (sante.etat == this.system.sante.nbcombativite - 2 && this.items.find(item => item.type == "talent" && item.name.toLowerCase() == "encaissement")) {
- ChatMessage.create({ content: `${this.name} ne subit pas les 2 adversités rouge grâce à Encaissement. Pensez à les ajouter à la fin de la scène !` })
- } else if (sante.etat == this.system.sante.nbcombativite - 1 && this.items.find(item => item.type == "talent" && item.name.toLowerCase().includes("vaillant"))) {
- ChatMessage.create({ content: `${this.name} ne subit pas les 2 adversités rouge grâce à Vaillant. Pensez à les ajouter à la fin de la scène !` })
- } else {
- ChatMessage.create({ content: `${this.name} subit 2 adversités rouge !` })
- this.incDecAdversite("rouge", 2)
- }
- }
- }
-
- /* -------------------------------------------- */
- processAme(ame) {
- ame = ame || foundry.utils.duplicate(this.system.ame)
- let maxAme = Math.min(this.system.ame.max || this.system.ame.nbame, this.system.ame.nbame - 1)
- // Gestion des états Traumatisé, Très Traumatisé et Brisé en fonction du maximum actuel
- // Les seuils sont calculés par rapport au maximum d'âme actuel
- if (maxAme >= 2 && ame.etat >= maxAme - 2) {
- if (ame.etat == maxAme - 2) {
- ChatMessage.create({ content: `${this.name} est Traumatisé !` })
- } else if (ame.etat == maxAme - 1) {
- ChatMessage.create({ content: `${this.name} est Très Traumatisé !` })
- } else if (ame.etat >= maxAme) {
- ChatMessage.create({ content: `${this.name} est Brisé !` })
- }
- } else if (ame.etat >= maxAme) {
- ChatMessage.create({ content: `${this.name} est Brisé !` })
- }
- }
-
- /* -------------------------------------------- */
- async equipGear(equipmentId) {
- let item = this.items.find(item => item.id == equipmentId);
- if (item?.system?.data) {
- let update = { _id: item.id, "system.equipped": !item.system.equipped };
- await this.updateEmbeddedDocuments('Item', [update]); // Updates one EmbeddedEntity
- }
- }
-
- /* -------------------------------------------- */
- getSubActors() {
- let subActors = [];
- for (let id of this.system.subactors) {
- subActors.push(foundry.utils.duplicate(game.actors.get(id)));
- }
- return subActors;
- }
- /* -------------------------------------------- */
- async addSubActor(subActorId) {
- let subActors = foundry.utils.duplicate(this.system.subactors);
- subActors.push(subActorId);
- await this.update({ 'system.subactors': subActors });
- }
- /* -------------------------------------------- */
- async delSubActor(subActorId) {
- let newArray = [];
- for (let id of this.system.subactors) {
- if (id != subActorId) {
- newArray.push(id);
- }
- }
- await this.update({ 'system.subactors': newArray });
- }
-
- /* -------------------------------------------- */
- getTotalAdversite() {
- return this.system.adversite.bleue + this.system.adversite.rouge + this.system.adversite.noire
- }
-
- /* -------------------------------------------- */
- async incDecAdversite(adv, incDec = 0) {
- let adversite = foundry.utils.duplicate(this.system.adversite)
- adversite[adv] += Number(incDec)
- adversite[adv] = Math.max(adversite[adv], 0)
- adversite[adv] = Math.min(adversite[adv], 20)
- this.update({ 'system.adversite': adversite })
- }
- /* -------------------------------------------- */
- async incDecQuantity(objetId, incDec = 0) {
- let objetQ = this.items.get(objetId)
- if (objetQ) {
- let newQ = objetQ.system.quantite + incDec
- newQ = Math.max(newQ, 0)
- await this.updateEmbeddedDocuments('Item', [{ _id: objetQ.id, 'system.quantite': newQ }]); // pdates one EmbeddedEntity
- }
- }
-
- /* -------------------------------------------- */
- computeRichesse() {
- let valueSC = 0
- for (let monnaie of this.items) {
- if (monnaie.type == "monnaie") {
- valueSC += Number(monnaie.system.prixsc) * Number(monnaie.system.quantite)
- }
- }
- return MournbladeCYD2Utility.computeMonnaieDetails(valueSC)
- }
-
- /* -------------------------------------------- */
- computeValeurEquipement() {
- let valueSC = 0
- for (let equip of this.items) {
- if (equip.type == "equipement" || equip.type == "arme" || equip.type == "protection") {
- valueSC += Number(equip.system.prixsc) * Number(equip.system.quantite ?? 1)
- valueSC += (Number(equip.system.prixca) * Number(equip.system.quantite ?? 1)) * 20
- valueSC += (Number(equip.system.prixpo) * Number(equip.system.quantite ?? 1)) * 400
- }
- }
- return MournbladeCYD2Utility.computeMonnaieDetails(valueSC)
- }
-
- /* -------------------------------------------- */
- getCompetence(compId) {
- return this.items.get(compId)
- }
-
- /* -------------------------------------------- */
- async setPredilectionUsed(compId, predIdx) {
- let comp = this.items.get(compId)
- let pred = foundry.utils.duplicate(comp.system.predilections)
- pred[predIdx].used = true
- await this.updateEmbeddedDocuments('Item', [{ _id: compId, 'system.predilections': pred }])
- }
-
- /* -------------------------------------------- */
- getInitiativeScore() {
- let init = this.getFlag("world", "last-initiative")
- return init || -1
- }
-
- /* -------------------------------------------- */
- getBestAttackValue() {
- let attackList = this.items.filter(item => (item.type == "arme" || item.type == "talent") && item.system.equipped)
- let maxOff = 0
- let bestArme
- for (let arme of attackList) {
- if (arme.type == "arme") {
- arme = this.prepareArme(arme)
- }
- if (arme.system.totalOffensif > maxOff) {
- maxOff = arme.system.totalOffensif
- bestArme = foundry.utils.duplicate(arme)
- }
- }
- return bestArme
- }
-
- /* -------------------------------------------- */
- getBestDefenseValue() {
- let defenseList = this.items.filter(item => (item.type == "arme") && item.system.equipped)
- let maxDef = 0
- let bestArme
- for (let arme of defenseList) {
- if (arme.type == "arme") {
- arme = this.prepareArme(arme)
- }
- if (arme.system.totalDefensif > maxDef) {
- maxDef = arme.system.totalDefensif
- bestArme = foundry.utils.duplicate(arme)
- }
- }
- return bestArme
- }
-
- /* -------------------------------------------- */
- searchRelevantTalents(competence) {
- let talents = []
-
- for (let talent of this.items) {
- if (talent.type == "talent" && talent.system.isautomated && talent.system.automations.length > 0) {
- for (let auto of talent.system.automations) {
- if (auto.eventtype === "prepare-roll") {
- if (auto.competence.toLowerCase() == competence.name.toLowerCase()) {
- talent = foundry.utils.duplicate(talent)
- talent.system.bonus = auto.bonus
- talent.system.baCost = auto.baCost
- talents.push(talent)
- }
- }
- }
- }
- }
- return talents
- }
-
- /* -------------------------------------------- */
- buildListeAdversites() {
- return []
- }
-
- /* -------------------------------------------- */
- getCommonRollData(attrKey = undefined, compId = undefined, compName = undefined) {
- let rollData = MournbladeCYD2Utility.getBasicRollData()
- rollData.alias = this.name
- rollData.actorImg = this.img
- rollData.actorId = this.id
- rollData.tokenId = this.token?.id
- rollData.img = this.img
- rollData.attributs = MournbladeCYD2Utility.getAttributs()
- rollData.maitriseId = "none"
- rollData.nbEclat = this.system.eclat.value
- rollData.nbBA = this.system.bonneaventure.actuelle
- rollData.nbAdversites = this.getTotalAdversite()
- rollData.talents = []
- rollData.attrKey2 = "none"
- rollData.coupDevastateur = this.items.find(it => it.type == "talent" && it.name.toLowerCase() == "coup dévastateur" && !it.system.used)
- rollData.hasAmbidextre = this.items.find(it => it.type == "talent" && it.name.toLowerCase() == "ambidextre")
- rollData.hasFeinte = this.system.bonneaventure.actuelle > 0 && this.items.find(it => it.type == "talent" && it.name.toLowerCase() == "feinte")
- rollData.isMonte = this.system.combat.monte
- rollData.config = game.system.mournbladecyd2.config
-
- if (attrKey) {
- rollData.attrKey = attrKey
- if (attrKey != "tochoose") {
- rollData.actionImg = "systems/fvtt-mournblade-cyd2/assets/icons/" + this.system.attributs[attrKey].labelnorm + ".webp"
- rollData.attr = foundry.utils.duplicate(this.system.attributs[attrKey])
- }
- }
- if (compId) {
- rollData.competence = foundry.utils.duplicate(this.items.get(compId) || {})
- let maitrises = [{ key: "none", label: "Aucune" }]
- rollData.competence.system.predilections.forEach(function (item) {
- if (item.maitrise) {
- maitrises.push({ key: item.id, label: item.name });
- }
- })
- rollData.maitrises = maitrises // rollData.competence.system.predilections.filter(p => p.maitrise)
- rollData.actionImg = rollData.competence?.img
- rollData.talents = this.searchRelevantTalents(rollData.competence)
- }
- if (compName) {
- rollData.competence = foundry.utils.duplicate(this.items.find(item => item.name.toLowerCase() == compName.toLowerCase()) || {})
- rollData.actionImg = rollData.competence?.img
- }
- return rollData
- }
-
- /* -------------------------------------------- */
- async rollAttribut(attrKey, isInit = false) {
- let rollData = this.getCommonRollData(attrKey)
- rollData.multiplier = (isInit) ? 1 : 2
- rollData.isInit = isInit
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
-
- /* -------------------------------------------- */
- async rollCompetence(attrKey, compId) {
- let rollData = this.getCommonRollData(attrKey, compId)
- rollData.multiplier = 1 // Attr multiplier, always 1 in competence mode
- console.log("RollDatra", rollData)
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
-
- /* -------------------------------------------- */
- async rollArmeOffensif(armeId) {
- let arme = this.items.get(armeId)
- if (arme.type == "arme") {
- arme = this.prepareArme(arme)
- }
- let rollData = this.getCommonRollData(arme.system.attrKey, arme.system.competence._id)
- rollData.arme = arme
- MournbladeCYD2Utility.updateWithTarget(rollData)
- console.log("ARME!", rollData)
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
- /* -------------------------------------------- */
- async rollAssommer() {
- let rollData = this.getCommonRollData("pui", undefined, "Filouterie")
- rollData.assomer = true
- rollData.conditionsCommunes = true
- MournbladeCYD2Utility.updateWithTarget(rollData)
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
- /* -------------------------------------------- */
- async rollCoupBas() {
- let rollData = this.getCommonRollData("pui", undefined, "Mêlée")
- rollData.coupBas = true
- rollData.conditionsCommunes = true
- MournbladeCYD2Utility.updateWithTarget(rollData)
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
- /* -------------------------------------------- */
- async rollImmobiliser() {
- let rollData = this.getCommonRollData("pui", undefined, "Mêlée")
- rollData.immobiliser = true
- rollData.conditionsCommunes = true
- rollData.cibleconsciente = true
- MournbladeCYD2Utility.updateWithTarget(rollData)
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
- /* -------------------------------------------- */
- async rollRepousser() {
- let rollData = this.getCommonRollData("pui", undefined, "Mêlée")
- rollData.repousser = true
- rollData.conditionsCommunes = true
- rollData.cibleconsciente = true
- MournbladeCYD2Utility.updateWithTarget(rollData)
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
- /* -------------------------------------------- */
- async rollDesengager() {
- let rollData = this.getCommonRollData("adr", undefined, "Mouvements")
- rollData.desengager = true
- rollData.conditionsCommunes = true
- MournbladeCYD2Utility.updateWithTarget(rollData)
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
-
- /* -------------------------------------------- */
- async rollArmeDegats(armeId, targetVigueur = undefined, rollDataInput = undefined) {
- let arme = this.items.get(armeId)
- if (arme.type == "arme") {
- arme = this.prepareArme(arme)
- }
- console.log("DEGATS", arme, targetVigueur, rollDataInput)
- let roll
- let bonus = 0
- let bonus2 = 0
-
- if (rollDataInput?.applyCoupDevastateur) {
- bonus2 = Math.floor(this.system.attributs.pui.value / 2)
- let talent = this.items.find(item => item.type == "talent" && item.name.toLowerCase() == "coup dévastateur")
- this.updateEmbeddedDocuments('Item', [{ _id: talent.id, 'system.used': true }])
- }
-
- if (rollDataInput?.isHeroique) {
- if (rollDataInput?.attaqueCharge) {
- bonus = 5
- }
- if (rollDataInput?.chargeCavalerie) {
- bonus = 6
- }
- roll = await new Roll("2d10rr10+" + arme.system.totalDegats + "+" + bonus + "+" + bonus2).roll()
- } else {
- if (rollDataInput?.attaqueCharge) {
- bonus = 3
- }
- if (rollDataInput?.chargeCavalerie) {
- bonus = 4
- }
- roll = await new Roll("1d10+" + arme.system.totalDegats + "+" + bonus + "+" + bonus2).roll()
- }
- await MournbladeCYD2Utility.showDiceSoNice(roll, game.settings.get("core", "rollMode"));
- let nbEtatPerdus = 0
- if (targetVigueur) {
- nbEtatPerdus = Math.floor(roll.total / targetVigueur)
- }
- //console.log(roll)
- let rollData = {
- arme: arme,
- finalResult: roll.total,
- formula: roll.formula,
- alias: this.name,
- actorImg: this.img,
- actorId: this.id,
- defenderTokenId: rollDataInput?.defenderTokenId,
- actionImg: arme.img,
- targetVigueur: targetVigueur,
- nbEtatPerdus: nbEtatPerdus
- }
- MournbladeCYD2Utility.createChatWithRollMode(rollData.alias, {
- content: await renderTemplate(`systems/fvtt-mournblade-cyd2/templates/chat-degats-result.html`, rollData)
- })
-
- if (rollDataInput?.defenderTokenId && nbEtatPerdus) {
- MournbladeCYD2Utility.applyCombativite(rollDataInput, nbEtatPerdus)
- }
-
- }
-}
diff --git a/.history/modules/mournblade-cyd2-actor_20251026083143.js b/.history/modules/mournblade-cyd2-actor_20251026083143.js
deleted file mode 100644
index 6d2b2cd..0000000
--- a/.history/modules/mournblade-cyd2-actor_20251026083143.js
+++ /dev/null
@@ -1,907 +0,0 @@
-/* -------------------------------------------- */
-import { MournbladeCYD2Utility } from "./mournblade-cyd2-utility.js";
-import { MournbladeCYD2RollDialog } from "./mournblade-cyd2-roll-dialog.js";
-
-/* -------------------------------------------- */
-const __degatsBonus = [-2, -2, -1, -1, 0, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 8, 8, 9, 9, 10, 10]
-const __vitesseBonus = [-2, -2, -1, -1, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8]
-
-/* -------------------------------------------- */
-/**
- * Extend the base Actor entity by defining a custom roll data structure which is ideal for the Simple system.
- * @extends {Actor}
- */
-export class MournbladeCYD2Actor extends Actor {
-
- /* -------------------------------------------- */
- /**
- * Override the create() function to provide additional SoS functionality.
- *
- * This overrided create() function adds initial items
- * Namely: Basic skills, money,
- *
- * @param {Object} data Barebones actor data which this function adds onto.
- * @param {Object} options (Unused) Additional options which customize the creation workflow.
- *
- */
-
- static async create(data, options) {
-
- // Case of compendium global import
- if (data instanceof Array) {
- return super.create(data, options);
- }
- // If the created actor has items (only applicable to duplicated actors) bypass the new actor creation logic
- if (data.items) {
- let actor = super.create(data, options);
- return actor;
- }
-
- if (data.type == 'personnage') {
- const skills = await MournbladeCYD2Utility.loadCompendium("fvtt-mournblade-cyd2.skills")
- data.items = skills.map(i => i.toObject())
- }
- if (data.type == 'creature') {
- const skills = await MournbladeCYD2Utility.loadCompendium("fvtt-mournblade-cyd2.skills-creatures")
- data.items = skills.map(i => i.toObject())
- data.items.push({ name: "Arme naturelle 1", type: 'arme', img: "systems/fvtt-mournblade-cyd2/assets/icons/melee.webp", system: { typearme: "contact", bonusmaniementoff: 0, seuildefense: 0, degats: "0" } })
- data.items.push({ name: "Arme naturelle 2", type: 'arme', img: "systems/fvtt-mournblade-cyd2/assets/icons/melee.webp", system: { typearme: "contact", bonusmaniementoff: 0, seuildefense: 0, degats: "0" } })
- }
-
- return super.create(data, options);
- }
-
- /* -------------------------------------------- */
- getBonusDefenseFromTalents() {
- let talents = this.items.filter(item => item.type == "talent" && item.system.isautomated)
- let bonus = 0
- for (let talent of talents) {
- for (let auto of talent.system.automations) {
- if (auto.eventtype == "bonus-permanent" && auto.bonusname == "bonus-defensif") {
- bonus += Number(auto.bonus || 0)
- }
- }
- }
- return bonus
- }
-
- /* -------------------------------------------- */
- prepareArme(arme) {
- if (this.type == "cellule") {
- return arme
- }
-
- arme = foundry.utils.duplicate(arme)
- let combat = this.getCombatValues()
- if (arme.system.typearme == "contact" || arme.system.typearme == "contactjet") {
- let bonusDefense = this.getBonusDefenseFromTalents()
- arme.system.competence = foundry.utils.duplicate(this.items.find(item => item.type == "competence" && item.name.toLowerCase() == "mêlée"))
- arme.system.attrKey = "pui"
- arme.system.totalDegats = arme.system.degats + "+" + combat.bonusDegatsTotal
- arme.system.totalOffensif = this.system.attributs.pui.value + arme.system.competence.system.niveau + arme.system.bonusmaniementoff + (this.system.combat.monte ? 3 : 0)
- arme.system.totalDefensif = combat.defenseTotal + arme.system.competence.system.niveau + arme.system.seuildefense + bonusDefense + (this.system.combat.monte ? 3 : 0)
- console.log("Arme", arme.system.totalDefensif, combat, arme.system.competence.system.niveau, arme.system.seuildefense, bonusDefense)
- arme.system.isdefense = true
- arme.system.isMelee = true
- arme.system.isDistance = false
- }
- if (arme.system.typearme == "jet" || arme.system.typearme == "tir") {
- arme.system.competence = foundry.utils.duplicate(this.items.find(item => item.type == "competence" && item.name.toLowerCase() == "armes à distance"))
- arme.system.attrKey = "adr"
- arme.system.totalOffensif = this.system.attributs.adr.value + arme.system.competence.system.niveau + arme.system.bonusmaniementoff
- arme.system.totalDegats = arme.system.degats
- arme.system.isMelee = false
- arme.system.isDistance = true
- if (arme.system.isdefense) {
- arme.system.totalDefensif = combat.defenseTotal + arme.system.competence.system.niveau + arme.system.seuildefense
- }
- }
- return arme
- }
-
- /* -------------------------------------------- */
- getItemSorted(types) {
- let items = this.items.filter(item => types.includes(item.type)) || []
- MournbladeCYD2Utility.sortArrayObjectsByName(items)
- return items
- }
- getWeapons() {
- let armes = []
- for (let arme of this.items) {
- if (arme.type == "arme") {
- armes.push(this.prepareArme(arme))
- }
- }
- MournbladeCYD2Utility.sortArrayObjectsByName(armes)
- return armes
- }
- getMonnaies() {
- return this.getItemSorted(["monnaie"])
- }
- getEquipments() {
- return this.getItemSorted(["equipement"])
- }
- getArtefacts() {
- return this.getItemSorted(["artefact"])
- }
- getArmors() {
- return this.getItemSorted(["protection"])
- }
- getHistoriques() {
- return this.getItemSorted(["historique"])
- }
- getProfils() {
- return this.getItemSorted(["profil"])
- }
- getTalents() {
- return this.getItemSorted(["talent"])
- }
- getRessources() {
- return this.getItemSorted(["ressource"])
- }
- getContacts() {
- return this.getItemSorted(["contact"])
- }
- getMutations() {
- return this.getItemSorted(["mutation"])
- }
- getDons() {
- return this.getItemSorted(["don"])
- }
- getPactes() {
- return this.getItemSorted(["pacte"])
- }
- getTendances() {
- return this.getItemSorted(["tendance"])
- }
- getRunes() {
- return this.getItemSorted(["rune"])
- }
- getTraitsChaotiques() {
- return this.getItemSorted(["traitchaotique"])
- }
- getTraitsEspeces() {
- return this.getItemSorted(["traitespece"])
- }
-
- /* -------------------------------------------- */
- getAspect() {
- return (this.system.balance.loi > this.system.balance.chaos) ? this.system.balance.loi : this.system.balance.chaos
- }
- getMarge() {
- return Math.abs(this.system.balance.loi - this.system.balance.chaos)
- }
- getAlignement() {
- return (this.system.balance.loi > this.system.balance.chaos) ? "loyal" : "chaotique"
- }
-
- /* -------------------------------------------- */
- getSkills() {
- let comp = []
- for (let item of this.items) {
- item = foundry.utils.duplicate(item)
- if (item.type == "competence") {
- item.system.attribut1total = item.system.niveau + (this.system.attributs[item.system.attribut1]?.value || 0)
- item.system.attribut2total = item.system.niveau + (this.system.attributs[item.system.attribut2]?.value || 0)
- item.system.attribut3total = item.system.niveau + (this.system.attributs[item.system.attribut3]?.value || 0)
- if (item.system.niveau == 0) {
- item.system.attribut1total -= 3
- item.system.attribut2total -= 3
- item.system.attribut3total -= 3
- }
- item.system.attribut1label = this.system.attributs[item.system.attribut1]?.label || ""
- item.system.attribut2label = this.system.attributs[item.system.attribut2]?.label || ""
- item.system.attribut3label = this.system.attributs[item.system.attribut3]?.label || ""
- comp.push(item)
- }
- }
- MournbladeCYD2Utility.sortArrayObjectsByName(comp)
- return comp
- }
-
- /* ----------------------- --------------------- */
- addMember(actorId) {
- let members = foundry.utils.duplicate(this.system.members)
- members.push({ id: actorId })
- this.update({ 'system.members': members })
- }
- async removeMember(actorId) {
- let members = this.system.members.filter(it => it.id != actorId)
- this.update({ 'system.members': members })
- }
-
- /* -------------------------------------------- */
- getDefenseBase() {
- return Math.max(this.system.attributs.tre.value, this.system.attributs.adr.value)
- }
-
- /* -------------------------------------------- */
- getVitesseBase() {
- return 5 + __vitesseBonus[this.system.attributs.adr.value]
- }
- /* -------------------------------------------- */
- getProtection() {
- let equipProtection = 0
- for (let armor of this.items) {
- if (armor.type == "protection" && armor.system.equipped) {
- equipProtection += Number(armor.system.protection)
- }
- }
- if (equipProtection < 4) {
- return 4 + equipProtection // Cas des boucliers + sans armure
- }
- return equipProtection // Uniquement la protection des armures + boucliers
- }
-
- /* -------------------------------------------- */
- getCombatValues() {
- if (this.type == "cellule") {
- return {
- initBase: 0,
- initTotal: 0,
- bonusDegats: 0,
- bonusDegatsTotal: 0,
- vitesseBase: 0,
- vitesseTotal: 0,
- defenseBase: 0,
- protection: 0,
- defenseTotal: 0
- }
- }
-
- let combat = {
- initBase: this.system.attributs.adr.value,
- initTotal: this.system.attributs.adr.value + this.system.combat.initbonus,
- bonusDegats: this.getBonusDegats(),
- bonusDegatsTotal: this.getBonusDegats() + this.system.combat.bonusdegats,
- vitesseBase: this.getVitesseBase(),
- vitesseTotal: this.getVitesseBase() + this.system.combat.vitessebonus,
- defenseBase: this.getDefenseBase(),
- protection: this.getProtection(),
- defenseTotal: this.getDefenseBase() + this.system.combat.defensebonus + this.getProtection() - this.getTotalAdversite() + (this.system.combat.defensetotale ? 3 : 0)
- }
- return combat
- }
-
- /* -------------------------------------------- */
- prepareBaseData() {
- }
-
- /* -------------------------------------------- */
- async prepareData() {
- super.prepareData();
- }
-
- /* -------------------------------------------- */
- prepareDerivedData() {
-
- if (this.type == 'personnage') {
- let talentBonus = this.getVigueurBonus()
- let vigueur = Math.floor((this.system.attributs.pui.value + this.system.attributs.tre.value) / 2) + talentBonus + this.system.sante.vigueurmodifier
- if (vigueur != this.system.sante.vigueur) {
- this.update({ 'system.sante.vigueur': vigueur })
- }
-
- let seuilPouvoirBonus = this.getSeuilPouvoirBonus()
- let seuilPouvoir = Math.floor((this.system.attributs.tre.value + this.system.attributs.cla.value) / 2) + seuilPouvoirBonus + this.system.ame.seuilpouvoirmodifier
- if (seuilPouvoir != this.system.ame.seuilpouvoir) {
- this.update({ 'system.ame.seuilpouvoir': seuilPouvoir })
- }
- }
- super.prepareDerivedData()
- }
-
- /* -------------------------------------------- */
- _preUpdate(changed, options, user) {
- if (changed?.system?.sante?.etat && changed?.system?.sante?.etat != this.system.sante.etat) {
- setTimeout(() => {
- this.processCombativite(changed.system.sante)
- }, 800)
- }
- if (changed?.system?.ame?.etat && changed?.system?.ame?.etat != this.system.ame.etat) {
- // S'assurer que l'état ne dépasse pas le maximum actuel d'âme
- let maxAme = Math.min(this.system.ame.max || this.system.ame.nbame, this.system.ame.nbame)
- if (changed.system.ame.etat > maxAme) {
- changed.system.ame.etat = maxAme
- }
- if (changed.system.ame.etat < 0) {
- changed.system.ame.etat = 0
- }
- setTimeout(() => {
- this.processAme(changed.system.ame)
- }, 800)
- }
- // Si le maximum d'âme change, s'assurer que l'état actuel ne le dépasse pas
- if (changed?.system?.ame?.max && changed.system.ame.max != this.system.ame.max) {
- if (this.system.ame.etat > changed.system.ame.max) {
- changed.system.ame.etat = changed.system.ame.max
- }
- }
- super._preUpdate(changed, options, user);
- }
-
- /* -------------------------------------------- */
- _onUpdate(data, options, user) {
- super._onUpdate(data, options, user);
- }
- /* -------------------------------------------- */
- getItemById(id) {
- let item = this.items.find(item => item.id == id);
- if (item) {
- item = foundry.utils.duplicate(item)
- }
- return item;
- }
-
- /* -------------------------------------------- */
- async equipItem(itemId) {
- let item = this.items.find(item => item.id == itemId)
- if (item && item.system) {
- let update = { _id: item.id, "system.equipped": !item.system.equipped }
- await this.updateEmbeddedDocuments('Item', [update]); // Updates one EmbeddedEntity
- }
- }
-
- /* -------------------------------------------- */
- editItemField(itemId, itemType, itemField, dataType, value) {
- let item = this.items.find(item => item.id == itemId)
- if (item) {
- console.log("Item ", item, itemField, dataType, value)
- if (dataType.toLowerCase() == "number") {
- value = Number(value)
- } else {
- value = String(value)
- }
- let update = { _id: item.id, [`system.${itemField}`]: value };
- this.updateEmbeddedDocuments("Item", [update])
- }
- }
-
- /* -------------------------------------------- */
- checkAttribut(attribut, minLevel) {
- let attr = this.system.attributs.find(at => at.labelnorm == attribut.toLowerCase())
- if (attr && attr.value >= minLevel) {
- return { isValid: true, attr: foundry.utils.duplicate(attr) }
- }
- return { isValid: false }
- }
- /* -------------------------------------------- */
- checkAttributOrCompetenceLevel(compName, minLevel) {
- let comp = this.items.find(i => i.type == "competence" && i.name.toLowerCase() == compName.toLowerCase() && i.system.niveau >= minLevel)
- if (comp) {
- return { isValid: true, item: foundry.utils.duplicate(comp) }
- } else {
- for (let attrKey in this.system.attributs) {
- if (this.system.attributs[attrKey].label.toLowerCase() == compName.toLowerCase() && this.system.attributs[attrKey].value >= minLevel) {
- return { isValid: true, item: foundry.utils.duplicate(this.system.attributs[attrKey]) }
- }
- }
- }
- return { isValid: false, warningMessage: `Prérequis insuffisant : la compétence/attribut ${compName} doit être de niveau ${minLevel} au minimum` }
- }
- /* -------------------------------------------- */
- addCompetenceBonus(compName, bonus, baCost) {
- let comp = this.items.find(i => i.type == "competence" && i.name.toLowerCase() == compName.toLowerCase())
- if (comp) {
- comp = foundry.utils.duplicate(comp)
- comp.system.bonus = bonus
- comp.system.baCost = baCost
- return { isValid: true, item: comp }
- }
- return { isValid: false, warningMessage: `Compétence ${compName} non trouvée` }
- }
- /* -------------------------------------------- */
- checkIfCompetence(compName) {
- let comp = this.items.find(i => i.type == "competence" && i.name.toLowerCase() == compName.toLowerCase())
- if (comp) {
- return { isValid: true, item: comp }
- }
- return { isValid: false }
- }
- /* -------------------------------------------- */
- getVigueur() {
- return this.system.sante.vigueur
- }
-
- /* -------------------------------------------- */
- getVigueurBonus() {
- let talents = this.items.filter(item => item.type == "talent" && item.system.isautomated)
- let bonus = 0
- for (let talent of talents) {
- for (let auto of talent.system.automations) {
- if (auto.eventtype == "bonus-permanent" && auto.bonusname == "vigueur") {
- bonus += Number(auto.bonus || 0)
- }
- }
- }
- return bonus
- }
-
- /* -------------------------------------------- */
- getSeuilPouvoir() {
- return this.system.ame.seuilpouvoir
- }
-
- /* -------------------------------------------- */
- getSeuilPouvoirBonus() {
- let talents = this.items.filter(item => item.type == "talent" && item.system.isautomated)
- let bonus = 0
- for (let talent of talents) {
- for (let auto of talent.system.automations) {
- if (auto.eventtype == "bonus-permanent" && auto.bonusname == "seuilpouvoir") {
- bonus += Number(auto.bonus || 0)
- }
- }
- }
- return bonus
- }
-
- /* -------------------------------------------- */
- getAmeMax() {
- return Math.min(this.system.ame.max || this.system.ame.nbame, this.system.ame.nbame)
- }
-
- /* -------------------------------------------- */
- getBonneAventure() {
- return this.system.bonneaventure.actuelle
- }
- /* -------------------------------------------- */
- checkBonneAventure(cost) {
- return (this.system.bonneaventure.actuelle >= cost)
- }
- /* -------------------------------------------- */
- changeBonneAventure(value) {
- let newBA = this.system.bonneaventure.actuelle
- newBA += value
- this.update({ 'system.bonneaventure.actuelle': newBA })
- }
-
- /* -------------------------------------------- */
- getEclat() {
- return this.system.eclat.value
- }
-
- /* -------------------------------------------- */
- changeEclat(value) {
- let newE = this.system.eclat.value
- newE += value
- this.update({ 'system.eclat.value': newE })
- }
-
- /* -------------------------------------------- */
- compareName(a, b) {
- if (a.name < b.name) {
- return -1;
- }
- if (a.name > b.name) {
- return 1;
- }
- return 0;
- }
-
- /* -------------------------------------------- */
- getAttribute(attrKey) {
- return this.system.attributes[attrKey]
- }
-
- /* -------------------------------------------- */
- getBonusDegats() {
- return 0;
- }
-
- /* -------------------------------------------- */
- changeEtatCombativite(value) {
- if (value === "vaincu") {
- value = 200
- }
- let sante = foundry.utils.duplicate(this.system.sante)
- sante.etat += Number(value)
- sante.etat = Math.max(sante.etat, 0)
- sante.etat = Math.min(sante.etat, this.system.sante.nbcombativite)
- this.update({ 'system.sante': sante })
- if (sante.etat == this.system.sante.nbcombativite) {
- ChatMessage.create({ content: `${this.name} est vaincu !` })
- }
- // Duplicated ! this.processCombativite(sante)
- }
-
- /* -------------------------------------------- */
- changeEtatAme(value) {
- if (value === "brise") {
- value = 200
- }
- let ame = foundry.utils.duplicate(this.system.ame)
- ame.etat += Number(value)
- ame.etat = Math.max(ame.etat, 0)
- // L'état ne peut pas dépasser le maximum actuel d'âme
- let maxAme = Math.min(this.system.ame.max || this.system.ame.nbame, this.system.ame.nbame)
- ame.etat = Math.min(ame.etat, maxAme)
- this.update({ 'system.ame': ame })
- if (ame.etat >= maxAme) {
- ChatMessage.create({ content: `${this.name} est brisé !` })
- }
- }
-
- /* -------------------------------------------- */
- processCombativite(sante) {
- sante = sante || foundry.utils.duplicate(this.system.sante)
- // Gestion des états affaibli et très affaibli
- if (sante.etat == this.system.sante.nbcombativite - 2 || sante.etat == this.system.sante.nbcombativite - 1) {
- if (sante.etat == this.system.sante.nbcombativite - 2 && this.items.find(item => item.type == "talent" && item.name.toLowerCase() == "encaissement")) {
- ChatMessage.create({ content: `${this.name} ne subit pas les 2 adversités rouge grâce à Encaissement. Pensez à les ajouter à la fin de la scène !` })
- } else if (sante.etat == this.system.sante.nbcombativite - 1 && this.items.find(item => item.type == "talent" && item.name.toLowerCase().includes("vaillant"))) {
- ChatMessage.create({ content: `${this.name} ne subit pas les 2 adversités rouge grâce à Vaillant. Pensez à les ajouter à la fin de la scène !` })
- } else {
- ChatMessage.create({ content: `${this.name} subit 2 adversités rouge !` })
- this.incDecAdversite("rouge", 2)
- }
- }
- }
-
- /* -------------------------------------------- */
- processAme(ame) {
- ame = ame || foundry.utils.duplicate(this.system.ame)
- let maxAme = Math.min(this.system.ame.max || this.system.ame.nbame, this.system.ame.nbame - 1)
- // Gestion des états Traumatisé, Très Traumatisé et Brisé en fonction du maximum actuel
- // Les seuils sont calculés par rapport au maximum d'âme actuel
- if (maxAme >= 2 && ame.etat >= maxAme - 2) {
- if (ame.etat == maxAme - 2) {
- ChatMessage.create({ content: `${this.name} est Traumatisé !` })
- } else if (ame.etat == maxAme - 1) {
- ChatMessage.create({ content: `${this.name} est Très Traumatisé !` })
- } else if (ame.etat >= maxAme) {
- ChatMessage.create({ content: `${this.name} est Brisé !` })
- }
- } else if (ame.etat >= maxAme) {
- ChatMessage.create({ content: `${this.name} est Brisé !` })
- }
- }
-
- /* -------------------------------------------- */
- async equipGear(equipmentId) {
- let item = this.items.find(item => item.id == equipmentId);
- if (item?.system?.data) {
- let update = { _id: item.id, "system.equipped": !item.system.equipped };
- await this.updateEmbeddedDocuments('Item', [update]); // Updates one EmbeddedEntity
- }
- }
-
- /* -------------------------------------------- */
- getSubActors() {
- let subActors = [];
- for (let id of this.system.subactors) {
- subActors.push(foundry.utils.duplicate(game.actors.get(id)));
- }
- return subActors;
- }
- /* -------------------------------------------- */
- async addSubActor(subActorId) {
- let subActors = foundry.utils.duplicate(this.system.subactors);
- subActors.push(subActorId);
- await this.update({ 'system.subactors': subActors });
- }
- /* -------------------------------------------- */
- async delSubActor(subActorId) {
- let newArray = [];
- for (let id of this.system.subactors) {
- if (id != subActorId) {
- newArray.push(id);
- }
- }
- await this.update({ 'system.subactors': newArray });
- }
-
- /* -------------------------------------------- */
- getTotalAdversite() {
- return this.system.adversite.bleue + this.system.adversite.rouge + this.system.adversite.noire
- }
-
- /* -------------------------------------------- */
- async incDecAdversite(adv, incDec = 0) {
- let adversite = foundry.utils.duplicate(this.system.adversite)
- adversite[adv] += Number(incDec)
- adversite[adv] = Math.max(adversite[adv], 0)
- adversite[adv] = Math.min(adversite[adv], 20)
- this.update({ 'system.adversite': adversite })
- }
- /* -------------------------------------------- */
- async incDecQuantity(objetId, incDec = 0) {
- let objetQ = this.items.get(objetId)
- if (objetQ) {
- let newQ = objetQ.system.quantite + incDec
- newQ = Math.max(newQ, 0)
- await this.updateEmbeddedDocuments('Item', [{ _id: objetQ.id, 'system.quantite': newQ }]); // pdates one EmbeddedEntity
- }
- }
-
- /* -------------------------------------------- */
- computeRichesse() {
- let valueSC = 0
- for (let monnaie of this.items) {
- if (monnaie.type == "monnaie") {
- valueSC += Number(monnaie.system.prixsc) * Number(monnaie.system.quantite)
- }
- }
- return MournbladeCYD2Utility.computeMonnaieDetails(valueSC)
- }
-
- /* -------------------------------------------- */
- computeValeurEquipement() {
- let valueSC = 0
- for (let equip of this.items) {
- if (equip.type == "equipement" || equip.type == "arme" || equip.type == "protection") {
- valueSC += Number(equip.system.prixsc) * Number(equip.system.quantite ?? 1)
- valueSC += (Number(equip.system.prixca) * Number(equip.system.quantite ?? 1)) * 20
- valueSC += (Number(equip.system.prixpo) * Number(equip.system.quantite ?? 1)) * 400
- }
- }
- return MournbladeCYD2Utility.computeMonnaieDetails(valueSC)
- }
-
- /* -------------------------------------------- */
- getCompetence(compId) {
- return this.items.get(compId)
- }
-
- /* -------------------------------------------- */
- async setPredilectionUsed(compId, predIdx) {
- let comp = this.items.get(compId)
- let pred = foundry.utils.duplicate(comp.system.predilections)
- pred[predIdx].used = true
- await this.updateEmbeddedDocuments('Item', [{ _id: compId, 'system.predilections': pred }])
- }
-
- /* -------------------------------------------- */
- getInitiativeScore() {
- let init = this.getFlag("world", "last-initiative")
- return init || -1
- }
-
- /* -------------------------------------------- */
- getBestAttackValue() {
- let attackList = this.items.filter(item => (item.type == "arme" || item.type == "talent") && item.system.equipped)
- let maxOff = 0
- let bestArme
- for (let arme of attackList) {
- if (arme.type == "arme") {
- arme = this.prepareArme(arme)
- }
- if (arme.system.totalOffensif > maxOff) {
- maxOff = arme.system.totalOffensif
- bestArme = foundry.utils.duplicate(arme)
- }
- }
- return bestArme
- }
-
- /* -------------------------------------------- */
- getBestDefenseValue() {
- let defenseList = this.items.filter(item => (item.type == "arme") && item.system.equipped)
- let maxDef = 0
- let bestArme
- for (let arme of defenseList) {
- if (arme.type == "arme") {
- arme = this.prepareArme(arme)
- }
- if (arme.system.totalDefensif > maxDef) {
- maxDef = arme.system.totalDefensif
- bestArme = foundry.utils.duplicate(arme)
- }
- }
- return bestArme
- }
-
- /* -------------------------------------------- */
- searchRelevantTalents(competence) {
- let talents = []
-
- for (let talent of this.items) {
- if (talent.type == "talent" && talent.system.isautomated && talent.system.automations.length > 0) {
- for (let auto of talent.system.automations) {
- if (auto.eventtype === "prepare-roll") {
- if (auto.competence.toLowerCase() == competence.name.toLowerCase()) {
- talent = foundry.utils.duplicate(talent)
- talent.system.bonus = auto.bonus
- talent.system.baCost = auto.baCost
- talents.push(talent)
- }
- }
- }
- }
- }
- return talents
- }
-
- /* -------------------------------------------- */
- buildListeAdversites() {
- return []
- }
-
- /* -------------------------------------------- */
- getCommonRollData(attrKey = undefined, compId = undefined, compName = undefined) {
- let rollData = MournbladeCYD2Utility.getBasicRollData()
- rollData.alias = this.name
- rollData.actorImg = this.img
- rollData.actorId = this.id
- rollData.tokenId = this.token?.id
- rollData.img = this.img
- rollData.attributs = MournbladeCYD2Utility.getAttributs()
- rollData.maitriseId = "none"
- rollData.nbEclat = this.system.eclat.value
- rollData.nbBA = this.system.bonneaventure.actuelle
- rollData.nbAdversites = this.getTotalAdversite()
- rollData.talents = []
- rollData.attrKey2 = "none"
- rollData.coupDevastateur = this.items.find(it => it.type == "talent" && it.name.toLowerCase() == "coup dévastateur" && !it.system.used)
- rollData.hasAmbidextre = this.items.find(it => it.type == "talent" && it.name.toLowerCase() == "ambidextre")
- rollData.hasFeinte = this.system.bonneaventure.actuelle > 0 && this.items.find(it => it.type == "talent" && it.name.toLowerCase() == "feinte")
- rollData.isMonte = this.system.combat.monte
- rollData.config = game.system.mournbladecyd2.config
-
- if (attrKey) {
- rollData.attrKey = attrKey
- if (attrKey != "tochoose") {
- rollData.actionImg = "systems/fvtt-mournblade-cyd2/assets/icons/" + this.system.attributs[attrKey].labelnorm + ".webp"
- rollData.attr = foundry.utils.duplicate(this.system.attributs[attrKey])
- }
- }
- if (compId) {
- rollData.competence = foundry.utils.duplicate(this.items.get(compId) || {})
- let maitrises = [{ key: "none", label: "Aucune" }]
- rollData.competence.system.predilections.forEach(function (item) {
- if (item.maitrise) {
- maitrises.push({ key: item.id, label: item.name });
- }
- })
- rollData.maitrises = maitrises // rollData.competence.system.predilections.filter(p => p.maitrise)
- rollData.actionImg = rollData.competence?.img
- rollData.talents = this.searchRelevantTalents(rollData.competence)
- }
- if (compName) {
- rollData.competence = foundry.utils.duplicate(this.items.find(item => item.name.toLowerCase() == compName.toLowerCase()) || {})
- rollData.actionImg = rollData.competence?.img
- }
- return rollData
- }
-
- /* -------------------------------------------- */
- async rollAttribut(attrKey, isInit = false) {
- let rollData = this.getCommonRollData(attrKey)
- rollData.multiplier = (isInit) ? 1 : 2
- rollData.isInit = isInit
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
-
- /* -------------------------------------------- */
- async rollCompetence(attrKey, compId) {
- let rollData = this.getCommonRollData(attrKey, compId)
- rollData.multiplier = 1 // Attr multiplier, always 1 in competence mode
- console.log("RollDatra", rollData)
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
-
- /* -------------------------------------------- */
- async rollArmeOffensif(armeId) {
- let arme = this.items.get(armeId)
- if (arme.type == "arme") {
- arme = this.prepareArme(arme)
- }
- let rollData = this.getCommonRollData(arme.system.attrKey, arme.system.competence._id)
- rollData.arme = arme
- MournbladeCYD2Utility.updateWithTarget(rollData)
- console.log("ARME!", rollData)
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
- /* -------------------------------------------- */
- async rollAssommer() {
- let rollData = this.getCommonRollData("pui", undefined, "Filouterie")
- rollData.assomer = true
- rollData.conditionsCommunes = true
- MournbladeCYD2Utility.updateWithTarget(rollData)
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
- /* -------------------------------------------- */
- async rollCoupBas() {
- let rollData = this.getCommonRollData("pui", undefined, "Mêlée")
- rollData.coupBas = true
- rollData.conditionsCommunes = true
- MournbladeCYD2Utility.updateWithTarget(rollData)
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
- /* -------------------------------------------- */
- async rollImmobiliser() {
- let rollData = this.getCommonRollData("pui", undefined, "Mêlée")
- rollData.immobiliser = true
- rollData.conditionsCommunes = true
- rollData.cibleconsciente = true
- MournbladeCYD2Utility.updateWithTarget(rollData)
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
- /* -------------------------------------------- */
- async rollRepousser() {
- let rollData = this.getCommonRollData("pui", undefined, "Mêlée")
- rollData.repousser = true
- rollData.conditionsCommunes = true
- rollData.cibleconsciente = true
- MournbladeCYD2Utility.updateWithTarget(rollData)
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
- /* -------------------------------------------- */
- async rollDesengager() {
- let rollData = this.getCommonRollData("adr", undefined, "Mouvements")
- rollData.desengager = true
- rollData.conditionsCommunes = true
- MournbladeCYD2Utility.updateWithTarget(rollData)
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
-
- /* -------------------------------------------- */
- async rollArmeDegats(armeId, targetVigueur = undefined, rollDataInput = undefined) {
- let arme = this.items.get(armeId)
- if (arme.type == "arme") {
- arme = this.prepareArme(arme)
- }
- console.log("DEGATS", arme, targetVigueur, rollDataInput)
- let roll
- let bonus = 0
- let bonus2 = 0
-
- if (rollDataInput?.applyCoupDevastateur) {
- bonus2 = Math.floor(this.system.attributs.pui.value / 2)
- let talent = this.items.find(item => item.type == "talent" && item.name.toLowerCase() == "coup dévastateur")
- this.updateEmbeddedDocuments('Item', [{ _id: talent.id, 'system.used': true }])
- }
-
- if (rollDataInput?.isHeroique) {
- if (rollDataInput?.attaqueCharge) {
- bonus = 5
- }
- if (rollDataInput?.chargeCavalerie) {
- bonus = 6
- }
- roll = await new Roll("2d10rr10+" + arme.system.totalDegats + "+" + bonus + "+" + bonus2).roll()
- } else {
- if (rollDataInput?.attaqueCharge) {
- bonus = 3
- }
- if (rollDataInput?.chargeCavalerie) {
- bonus = 4
- }
- roll = await new Roll("1d10+" + arme.system.totalDegats + "+" + bonus + "+" + bonus2).roll()
- }
- await MournbladeCYD2Utility.showDiceSoNice(roll, game.settings.get("core", "rollMode"));
- let nbEtatPerdus = 0
- if (targetVigueur) {
- nbEtatPerdus = Math.floor(roll.total / targetVigueur)
- }
- //console.log(roll)
- let rollData = {
- arme: arme,
- finalResult: roll.total,
- formula: roll.formula,
- alias: this.name,
- actorImg: this.img,
- actorId: this.id,
- defenderTokenId: rollDataInput?.defenderTokenId,
- actionImg: arme.img,
- targetVigueur: targetVigueur,
- nbEtatPerdus: nbEtatPerdus
- }
- MournbladeCYD2Utility.createChatWithRollMode(rollData.alias, {
- content: await renderTemplate(`systems/fvtt-mournblade-cyd2/templates/chat-degats-result.html`, rollData)
- })
-
- if (rollDataInput?.defenderTokenId && nbEtatPerdus) {
- MournbladeCYD2Utility.applyCombativite(rollDataInput, nbEtatPerdus)
- }
-
- }
-}
diff --git a/.history/modules/mournblade-cyd2-actor_20251026083155.js b/.history/modules/mournblade-cyd2-actor_20251026083155.js
deleted file mode 100644
index 6d2b2cd..0000000
--- a/.history/modules/mournblade-cyd2-actor_20251026083155.js
+++ /dev/null
@@ -1,907 +0,0 @@
-/* -------------------------------------------- */
-import { MournbladeCYD2Utility } from "./mournblade-cyd2-utility.js";
-import { MournbladeCYD2RollDialog } from "./mournblade-cyd2-roll-dialog.js";
-
-/* -------------------------------------------- */
-const __degatsBonus = [-2, -2, -1, -1, 0, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 8, 8, 9, 9, 10, 10]
-const __vitesseBonus = [-2, -2, -1, -1, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8]
-
-/* -------------------------------------------- */
-/**
- * Extend the base Actor entity by defining a custom roll data structure which is ideal for the Simple system.
- * @extends {Actor}
- */
-export class MournbladeCYD2Actor extends Actor {
-
- /* -------------------------------------------- */
- /**
- * Override the create() function to provide additional SoS functionality.
- *
- * This overrided create() function adds initial items
- * Namely: Basic skills, money,
- *
- * @param {Object} data Barebones actor data which this function adds onto.
- * @param {Object} options (Unused) Additional options which customize the creation workflow.
- *
- */
-
- static async create(data, options) {
-
- // Case of compendium global import
- if (data instanceof Array) {
- return super.create(data, options);
- }
- // If the created actor has items (only applicable to duplicated actors) bypass the new actor creation logic
- if (data.items) {
- let actor = super.create(data, options);
- return actor;
- }
-
- if (data.type == 'personnage') {
- const skills = await MournbladeCYD2Utility.loadCompendium("fvtt-mournblade-cyd2.skills")
- data.items = skills.map(i => i.toObject())
- }
- if (data.type == 'creature') {
- const skills = await MournbladeCYD2Utility.loadCompendium("fvtt-mournblade-cyd2.skills-creatures")
- data.items = skills.map(i => i.toObject())
- data.items.push({ name: "Arme naturelle 1", type: 'arme', img: "systems/fvtt-mournblade-cyd2/assets/icons/melee.webp", system: { typearme: "contact", bonusmaniementoff: 0, seuildefense: 0, degats: "0" } })
- data.items.push({ name: "Arme naturelle 2", type: 'arme', img: "systems/fvtt-mournblade-cyd2/assets/icons/melee.webp", system: { typearme: "contact", bonusmaniementoff: 0, seuildefense: 0, degats: "0" } })
- }
-
- return super.create(data, options);
- }
-
- /* -------------------------------------------- */
- getBonusDefenseFromTalents() {
- let talents = this.items.filter(item => item.type == "talent" && item.system.isautomated)
- let bonus = 0
- for (let talent of talents) {
- for (let auto of talent.system.automations) {
- if (auto.eventtype == "bonus-permanent" && auto.bonusname == "bonus-defensif") {
- bonus += Number(auto.bonus || 0)
- }
- }
- }
- return bonus
- }
-
- /* -------------------------------------------- */
- prepareArme(arme) {
- if (this.type == "cellule") {
- return arme
- }
-
- arme = foundry.utils.duplicate(arme)
- let combat = this.getCombatValues()
- if (arme.system.typearme == "contact" || arme.system.typearme == "contactjet") {
- let bonusDefense = this.getBonusDefenseFromTalents()
- arme.system.competence = foundry.utils.duplicate(this.items.find(item => item.type == "competence" && item.name.toLowerCase() == "mêlée"))
- arme.system.attrKey = "pui"
- arme.system.totalDegats = arme.system.degats + "+" + combat.bonusDegatsTotal
- arme.system.totalOffensif = this.system.attributs.pui.value + arme.system.competence.system.niveau + arme.system.bonusmaniementoff + (this.system.combat.monte ? 3 : 0)
- arme.system.totalDefensif = combat.defenseTotal + arme.system.competence.system.niveau + arme.system.seuildefense + bonusDefense + (this.system.combat.monte ? 3 : 0)
- console.log("Arme", arme.system.totalDefensif, combat, arme.system.competence.system.niveau, arme.system.seuildefense, bonusDefense)
- arme.system.isdefense = true
- arme.system.isMelee = true
- arme.system.isDistance = false
- }
- if (arme.system.typearme == "jet" || arme.system.typearme == "tir") {
- arme.system.competence = foundry.utils.duplicate(this.items.find(item => item.type == "competence" && item.name.toLowerCase() == "armes à distance"))
- arme.system.attrKey = "adr"
- arme.system.totalOffensif = this.system.attributs.adr.value + arme.system.competence.system.niveau + arme.system.bonusmaniementoff
- arme.system.totalDegats = arme.system.degats
- arme.system.isMelee = false
- arme.system.isDistance = true
- if (arme.system.isdefense) {
- arme.system.totalDefensif = combat.defenseTotal + arme.system.competence.system.niveau + arme.system.seuildefense
- }
- }
- return arme
- }
-
- /* -------------------------------------------- */
- getItemSorted(types) {
- let items = this.items.filter(item => types.includes(item.type)) || []
- MournbladeCYD2Utility.sortArrayObjectsByName(items)
- return items
- }
- getWeapons() {
- let armes = []
- for (let arme of this.items) {
- if (arme.type == "arme") {
- armes.push(this.prepareArme(arme))
- }
- }
- MournbladeCYD2Utility.sortArrayObjectsByName(armes)
- return armes
- }
- getMonnaies() {
- return this.getItemSorted(["monnaie"])
- }
- getEquipments() {
- return this.getItemSorted(["equipement"])
- }
- getArtefacts() {
- return this.getItemSorted(["artefact"])
- }
- getArmors() {
- return this.getItemSorted(["protection"])
- }
- getHistoriques() {
- return this.getItemSorted(["historique"])
- }
- getProfils() {
- return this.getItemSorted(["profil"])
- }
- getTalents() {
- return this.getItemSorted(["talent"])
- }
- getRessources() {
- return this.getItemSorted(["ressource"])
- }
- getContacts() {
- return this.getItemSorted(["contact"])
- }
- getMutations() {
- return this.getItemSorted(["mutation"])
- }
- getDons() {
- return this.getItemSorted(["don"])
- }
- getPactes() {
- return this.getItemSorted(["pacte"])
- }
- getTendances() {
- return this.getItemSorted(["tendance"])
- }
- getRunes() {
- return this.getItemSorted(["rune"])
- }
- getTraitsChaotiques() {
- return this.getItemSorted(["traitchaotique"])
- }
- getTraitsEspeces() {
- return this.getItemSorted(["traitespece"])
- }
-
- /* -------------------------------------------- */
- getAspect() {
- return (this.system.balance.loi > this.system.balance.chaos) ? this.system.balance.loi : this.system.balance.chaos
- }
- getMarge() {
- return Math.abs(this.system.balance.loi - this.system.balance.chaos)
- }
- getAlignement() {
- return (this.system.balance.loi > this.system.balance.chaos) ? "loyal" : "chaotique"
- }
-
- /* -------------------------------------------- */
- getSkills() {
- let comp = []
- for (let item of this.items) {
- item = foundry.utils.duplicate(item)
- if (item.type == "competence") {
- item.system.attribut1total = item.system.niveau + (this.system.attributs[item.system.attribut1]?.value || 0)
- item.system.attribut2total = item.system.niveau + (this.system.attributs[item.system.attribut2]?.value || 0)
- item.system.attribut3total = item.system.niveau + (this.system.attributs[item.system.attribut3]?.value || 0)
- if (item.system.niveau == 0) {
- item.system.attribut1total -= 3
- item.system.attribut2total -= 3
- item.system.attribut3total -= 3
- }
- item.system.attribut1label = this.system.attributs[item.system.attribut1]?.label || ""
- item.system.attribut2label = this.system.attributs[item.system.attribut2]?.label || ""
- item.system.attribut3label = this.system.attributs[item.system.attribut3]?.label || ""
- comp.push(item)
- }
- }
- MournbladeCYD2Utility.sortArrayObjectsByName(comp)
- return comp
- }
-
- /* ----------------------- --------------------- */
- addMember(actorId) {
- let members = foundry.utils.duplicate(this.system.members)
- members.push({ id: actorId })
- this.update({ 'system.members': members })
- }
- async removeMember(actorId) {
- let members = this.system.members.filter(it => it.id != actorId)
- this.update({ 'system.members': members })
- }
-
- /* -------------------------------------------- */
- getDefenseBase() {
- return Math.max(this.system.attributs.tre.value, this.system.attributs.adr.value)
- }
-
- /* -------------------------------------------- */
- getVitesseBase() {
- return 5 + __vitesseBonus[this.system.attributs.adr.value]
- }
- /* -------------------------------------------- */
- getProtection() {
- let equipProtection = 0
- for (let armor of this.items) {
- if (armor.type == "protection" && armor.system.equipped) {
- equipProtection += Number(armor.system.protection)
- }
- }
- if (equipProtection < 4) {
- return 4 + equipProtection // Cas des boucliers + sans armure
- }
- return equipProtection // Uniquement la protection des armures + boucliers
- }
-
- /* -------------------------------------------- */
- getCombatValues() {
- if (this.type == "cellule") {
- return {
- initBase: 0,
- initTotal: 0,
- bonusDegats: 0,
- bonusDegatsTotal: 0,
- vitesseBase: 0,
- vitesseTotal: 0,
- defenseBase: 0,
- protection: 0,
- defenseTotal: 0
- }
- }
-
- let combat = {
- initBase: this.system.attributs.adr.value,
- initTotal: this.system.attributs.adr.value + this.system.combat.initbonus,
- bonusDegats: this.getBonusDegats(),
- bonusDegatsTotal: this.getBonusDegats() + this.system.combat.bonusdegats,
- vitesseBase: this.getVitesseBase(),
- vitesseTotal: this.getVitesseBase() + this.system.combat.vitessebonus,
- defenseBase: this.getDefenseBase(),
- protection: this.getProtection(),
- defenseTotal: this.getDefenseBase() + this.system.combat.defensebonus + this.getProtection() - this.getTotalAdversite() + (this.system.combat.defensetotale ? 3 : 0)
- }
- return combat
- }
-
- /* -------------------------------------------- */
- prepareBaseData() {
- }
-
- /* -------------------------------------------- */
- async prepareData() {
- super.prepareData();
- }
-
- /* -------------------------------------------- */
- prepareDerivedData() {
-
- if (this.type == 'personnage') {
- let talentBonus = this.getVigueurBonus()
- let vigueur = Math.floor((this.system.attributs.pui.value + this.system.attributs.tre.value) / 2) + talentBonus + this.system.sante.vigueurmodifier
- if (vigueur != this.system.sante.vigueur) {
- this.update({ 'system.sante.vigueur': vigueur })
- }
-
- let seuilPouvoirBonus = this.getSeuilPouvoirBonus()
- let seuilPouvoir = Math.floor((this.system.attributs.tre.value + this.system.attributs.cla.value) / 2) + seuilPouvoirBonus + this.system.ame.seuilpouvoirmodifier
- if (seuilPouvoir != this.system.ame.seuilpouvoir) {
- this.update({ 'system.ame.seuilpouvoir': seuilPouvoir })
- }
- }
- super.prepareDerivedData()
- }
-
- /* -------------------------------------------- */
- _preUpdate(changed, options, user) {
- if (changed?.system?.sante?.etat && changed?.system?.sante?.etat != this.system.sante.etat) {
- setTimeout(() => {
- this.processCombativite(changed.system.sante)
- }, 800)
- }
- if (changed?.system?.ame?.etat && changed?.system?.ame?.etat != this.system.ame.etat) {
- // S'assurer que l'état ne dépasse pas le maximum actuel d'âme
- let maxAme = Math.min(this.system.ame.max || this.system.ame.nbame, this.system.ame.nbame)
- if (changed.system.ame.etat > maxAme) {
- changed.system.ame.etat = maxAme
- }
- if (changed.system.ame.etat < 0) {
- changed.system.ame.etat = 0
- }
- setTimeout(() => {
- this.processAme(changed.system.ame)
- }, 800)
- }
- // Si le maximum d'âme change, s'assurer que l'état actuel ne le dépasse pas
- if (changed?.system?.ame?.max && changed.system.ame.max != this.system.ame.max) {
- if (this.system.ame.etat > changed.system.ame.max) {
- changed.system.ame.etat = changed.system.ame.max
- }
- }
- super._preUpdate(changed, options, user);
- }
-
- /* -------------------------------------------- */
- _onUpdate(data, options, user) {
- super._onUpdate(data, options, user);
- }
- /* -------------------------------------------- */
- getItemById(id) {
- let item = this.items.find(item => item.id == id);
- if (item) {
- item = foundry.utils.duplicate(item)
- }
- return item;
- }
-
- /* -------------------------------------------- */
- async equipItem(itemId) {
- let item = this.items.find(item => item.id == itemId)
- if (item && item.system) {
- let update = { _id: item.id, "system.equipped": !item.system.equipped }
- await this.updateEmbeddedDocuments('Item', [update]); // Updates one EmbeddedEntity
- }
- }
-
- /* -------------------------------------------- */
- editItemField(itemId, itemType, itemField, dataType, value) {
- let item = this.items.find(item => item.id == itemId)
- if (item) {
- console.log("Item ", item, itemField, dataType, value)
- if (dataType.toLowerCase() == "number") {
- value = Number(value)
- } else {
- value = String(value)
- }
- let update = { _id: item.id, [`system.${itemField}`]: value };
- this.updateEmbeddedDocuments("Item", [update])
- }
- }
-
- /* -------------------------------------------- */
- checkAttribut(attribut, minLevel) {
- let attr = this.system.attributs.find(at => at.labelnorm == attribut.toLowerCase())
- if (attr && attr.value >= minLevel) {
- return { isValid: true, attr: foundry.utils.duplicate(attr) }
- }
- return { isValid: false }
- }
- /* -------------------------------------------- */
- checkAttributOrCompetenceLevel(compName, minLevel) {
- let comp = this.items.find(i => i.type == "competence" && i.name.toLowerCase() == compName.toLowerCase() && i.system.niveau >= minLevel)
- if (comp) {
- return { isValid: true, item: foundry.utils.duplicate(comp) }
- } else {
- for (let attrKey in this.system.attributs) {
- if (this.system.attributs[attrKey].label.toLowerCase() == compName.toLowerCase() && this.system.attributs[attrKey].value >= minLevel) {
- return { isValid: true, item: foundry.utils.duplicate(this.system.attributs[attrKey]) }
- }
- }
- }
- return { isValid: false, warningMessage: `Prérequis insuffisant : la compétence/attribut ${compName} doit être de niveau ${minLevel} au minimum` }
- }
- /* -------------------------------------------- */
- addCompetenceBonus(compName, bonus, baCost) {
- let comp = this.items.find(i => i.type == "competence" && i.name.toLowerCase() == compName.toLowerCase())
- if (comp) {
- comp = foundry.utils.duplicate(comp)
- comp.system.bonus = bonus
- comp.system.baCost = baCost
- return { isValid: true, item: comp }
- }
- return { isValid: false, warningMessage: `Compétence ${compName} non trouvée` }
- }
- /* -------------------------------------------- */
- checkIfCompetence(compName) {
- let comp = this.items.find(i => i.type == "competence" && i.name.toLowerCase() == compName.toLowerCase())
- if (comp) {
- return { isValid: true, item: comp }
- }
- return { isValid: false }
- }
- /* -------------------------------------------- */
- getVigueur() {
- return this.system.sante.vigueur
- }
-
- /* -------------------------------------------- */
- getVigueurBonus() {
- let talents = this.items.filter(item => item.type == "talent" && item.system.isautomated)
- let bonus = 0
- for (let talent of talents) {
- for (let auto of talent.system.automations) {
- if (auto.eventtype == "bonus-permanent" && auto.bonusname == "vigueur") {
- bonus += Number(auto.bonus || 0)
- }
- }
- }
- return bonus
- }
-
- /* -------------------------------------------- */
- getSeuilPouvoir() {
- return this.system.ame.seuilpouvoir
- }
-
- /* -------------------------------------------- */
- getSeuilPouvoirBonus() {
- let talents = this.items.filter(item => item.type == "talent" && item.system.isautomated)
- let bonus = 0
- for (let talent of talents) {
- for (let auto of talent.system.automations) {
- if (auto.eventtype == "bonus-permanent" && auto.bonusname == "seuilpouvoir") {
- bonus += Number(auto.bonus || 0)
- }
- }
- }
- return bonus
- }
-
- /* -------------------------------------------- */
- getAmeMax() {
- return Math.min(this.system.ame.max || this.system.ame.nbame, this.system.ame.nbame)
- }
-
- /* -------------------------------------------- */
- getBonneAventure() {
- return this.system.bonneaventure.actuelle
- }
- /* -------------------------------------------- */
- checkBonneAventure(cost) {
- return (this.system.bonneaventure.actuelle >= cost)
- }
- /* -------------------------------------------- */
- changeBonneAventure(value) {
- let newBA = this.system.bonneaventure.actuelle
- newBA += value
- this.update({ 'system.bonneaventure.actuelle': newBA })
- }
-
- /* -------------------------------------------- */
- getEclat() {
- return this.system.eclat.value
- }
-
- /* -------------------------------------------- */
- changeEclat(value) {
- let newE = this.system.eclat.value
- newE += value
- this.update({ 'system.eclat.value': newE })
- }
-
- /* -------------------------------------------- */
- compareName(a, b) {
- if (a.name < b.name) {
- return -1;
- }
- if (a.name > b.name) {
- return 1;
- }
- return 0;
- }
-
- /* -------------------------------------------- */
- getAttribute(attrKey) {
- return this.system.attributes[attrKey]
- }
-
- /* -------------------------------------------- */
- getBonusDegats() {
- return 0;
- }
-
- /* -------------------------------------------- */
- changeEtatCombativite(value) {
- if (value === "vaincu") {
- value = 200
- }
- let sante = foundry.utils.duplicate(this.system.sante)
- sante.etat += Number(value)
- sante.etat = Math.max(sante.etat, 0)
- sante.etat = Math.min(sante.etat, this.system.sante.nbcombativite)
- this.update({ 'system.sante': sante })
- if (sante.etat == this.system.sante.nbcombativite) {
- ChatMessage.create({ content: `${this.name} est vaincu !` })
- }
- // Duplicated ! this.processCombativite(sante)
- }
-
- /* -------------------------------------------- */
- changeEtatAme(value) {
- if (value === "brise") {
- value = 200
- }
- let ame = foundry.utils.duplicate(this.system.ame)
- ame.etat += Number(value)
- ame.etat = Math.max(ame.etat, 0)
- // L'état ne peut pas dépasser le maximum actuel d'âme
- let maxAme = Math.min(this.system.ame.max || this.system.ame.nbame, this.system.ame.nbame)
- ame.etat = Math.min(ame.etat, maxAme)
- this.update({ 'system.ame': ame })
- if (ame.etat >= maxAme) {
- ChatMessage.create({ content: `${this.name} est brisé !` })
- }
- }
-
- /* -------------------------------------------- */
- processCombativite(sante) {
- sante = sante || foundry.utils.duplicate(this.system.sante)
- // Gestion des états affaibli et très affaibli
- if (sante.etat == this.system.sante.nbcombativite - 2 || sante.etat == this.system.sante.nbcombativite - 1) {
- if (sante.etat == this.system.sante.nbcombativite - 2 && this.items.find(item => item.type == "talent" && item.name.toLowerCase() == "encaissement")) {
- ChatMessage.create({ content: `${this.name} ne subit pas les 2 adversités rouge grâce à Encaissement. Pensez à les ajouter à la fin de la scène !` })
- } else if (sante.etat == this.system.sante.nbcombativite - 1 && this.items.find(item => item.type == "talent" && item.name.toLowerCase().includes("vaillant"))) {
- ChatMessage.create({ content: `${this.name} ne subit pas les 2 adversités rouge grâce à Vaillant. Pensez à les ajouter à la fin de la scène !` })
- } else {
- ChatMessage.create({ content: `${this.name} subit 2 adversités rouge !` })
- this.incDecAdversite("rouge", 2)
- }
- }
- }
-
- /* -------------------------------------------- */
- processAme(ame) {
- ame = ame || foundry.utils.duplicate(this.system.ame)
- let maxAme = Math.min(this.system.ame.max || this.system.ame.nbame, this.system.ame.nbame - 1)
- // Gestion des états Traumatisé, Très Traumatisé et Brisé en fonction du maximum actuel
- // Les seuils sont calculés par rapport au maximum d'âme actuel
- if (maxAme >= 2 && ame.etat >= maxAme - 2) {
- if (ame.etat == maxAme - 2) {
- ChatMessage.create({ content: `${this.name} est Traumatisé !` })
- } else if (ame.etat == maxAme - 1) {
- ChatMessage.create({ content: `${this.name} est Très Traumatisé !` })
- } else if (ame.etat >= maxAme) {
- ChatMessage.create({ content: `${this.name} est Brisé !` })
- }
- } else if (ame.etat >= maxAme) {
- ChatMessage.create({ content: `${this.name} est Brisé !` })
- }
- }
-
- /* -------------------------------------------- */
- async equipGear(equipmentId) {
- let item = this.items.find(item => item.id == equipmentId);
- if (item?.system?.data) {
- let update = { _id: item.id, "system.equipped": !item.system.equipped };
- await this.updateEmbeddedDocuments('Item', [update]); // Updates one EmbeddedEntity
- }
- }
-
- /* -------------------------------------------- */
- getSubActors() {
- let subActors = [];
- for (let id of this.system.subactors) {
- subActors.push(foundry.utils.duplicate(game.actors.get(id)));
- }
- return subActors;
- }
- /* -------------------------------------------- */
- async addSubActor(subActorId) {
- let subActors = foundry.utils.duplicate(this.system.subactors);
- subActors.push(subActorId);
- await this.update({ 'system.subactors': subActors });
- }
- /* -------------------------------------------- */
- async delSubActor(subActorId) {
- let newArray = [];
- for (let id of this.system.subactors) {
- if (id != subActorId) {
- newArray.push(id);
- }
- }
- await this.update({ 'system.subactors': newArray });
- }
-
- /* -------------------------------------------- */
- getTotalAdversite() {
- return this.system.adversite.bleue + this.system.adversite.rouge + this.system.adversite.noire
- }
-
- /* -------------------------------------------- */
- async incDecAdversite(adv, incDec = 0) {
- let adversite = foundry.utils.duplicate(this.system.adversite)
- adversite[adv] += Number(incDec)
- adversite[adv] = Math.max(adversite[adv], 0)
- adversite[adv] = Math.min(adversite[adv], 20)
- this.update({ 'system.adversite': adversite })
- }
- /* -------------------------------------------- */
- async incDecQuantity(objetId, incDec = 0) {
- let objetQ = this.items.get(objetId)
- if (objetQ) {
- let newQ = objetQ.system.quantite + incDec
- newQ = Math.max(newQ, 0)
- await this.updateEmbeddedDocuments('Item', [{ _id: objetQ.id, 'system.quantite': newQ }]); // pdates one EmbeddedEntity
- }
- }
-
- /* -------------------------------------------- */
- computeRichesse() {
- let valueSC = 0
- for (let monnaie of this.items) {
- if (monnaie.type == "monnaie") {
- valueSC += Number(monnaie.system.prixsc) * Number(monnaie.system.quantite)
- }
- }
- return MournbladeCYD2Utility.computeMonnaieDetails(valueSC)
- }
-
- /* -------------------------------------------- */
- computeValeurEquipement() {
- let valueSC = 0
- for (let equip of this.items) {
- if (equip.type == "equipement" || equip.type == "arme" || equip.type == "protection") {
- valueSC += Number(equip.system.prixsc) * Number(equip.system.quantite ?? 1)
- valueSC += (Number(equip.system.prixca) * Number(equip.system.quantite ?? 1)) * 20
- valueSC += (Number(equip.system.prixpo) * Number(equip.system.quantite ?? 1)) * 400
- }
- }
- return MournbladeCYD2Utility.computeMonnaieDetails(valueSC)
- }
-
- /* -------------------------------------------- */
- getCompetence(compId) {
- return this.items.get(compId)
- }
-
- /* -------------------------------------------- */
- async setPredilectionUsed(compId, predIdx) {
- let comp = this.items.get(compId)
- let pred = foundry.utils.duplicate(comp.system.predilections)
- pred[predIdx].used = true
- await this.updateEmbeddedDocuments('Item', [{ _id: compId, 'system.predilections': pred }])
- }
-
- /* -------------------------------------------- */
- getInitiativeScore() {
- let init = this.getFlag("world", "last-initiative")
- return init || -1
- }
-
- /* -------------------------------------------- */
- getBestAttackValue() {
- let attackList = this.items.filter(item => (item.type == "arme" || item.type == "talent") && item.system.equipped)
- let maxOff = 0
- let bestArme
- for (let arme of attackList) {
- if (arme.type == "arme") {
- arme = this.prepareArme(arme)
- }
- if (arme.system.totalOffensif > maxOff) {
- maxOff = arme.system.totalOffensif
- bestArme = foundry.utils.duplicate(arme)
- }
- }
- return bestArme
- }
-
- /* -------------------------------------------- */
- getBestDefenseValue() {
- let defenseList = this.items.filter(item => (item.type == "arme") && item.system.equipped)
- let maxDef = 0
- let bestArme
- for (let arme of defenseList) {
- if (arme.type == "arme") {
- arme = this.prepareArme(arme)
- }
- if (arme.system.totalDefensif > maxDef) {
- maxDef = arme.system.totalDefensif
- bestArme = foundry.utils.duplicate(arme)
- }
- }
- return bestArme
- }
-
- /* -------------------------------------------- */
- searchRelevantTalents(competence) {
- let talents = []
-
- for (let talent of this.items) {
- if (talent.type == "talent" && talent.system.isautomated && talent.system.automations.length > 0) {
- for (let auto of talent.system.automations) {
- if (auto.eventtype === "prepare-roll") {
- if (auto.competence.toLowerCase() == competence.name.toLowerCase()) {
- talent = foundry.utils.duplicate(talent)
- talent.system.bonus = auto.bonus
- talent.system.baCost = auto.baCost
- talents.push(talent)
- }
- }
- }
- }
- }
- return talents
- }
-
- /* -------------------------------------------- */
- buildListeAdversites() {
- return []
- }
-
- /* -------------------------------------------- */
- getCommonRollData(attrKey = undefined, compId = undefined, compName = undefined) {
- let rollData = MournbladeCYD2Utility.getBasicRollData()
- rollData.alias = this.name
- rollData.actorImg = this.img
- rollData.actorId = this.id
- rollData.tokenId = this.token?.id
- rollData.img = this.img
- rollData.attributs = MournbladeCYD2Utility.getAttributs()
- rollData.maitriseId = "none"
- rollData.nbEclat = this.system.eclat.value
- rollData.nbBA = this.system.bonneaventure.actuelle
- rollData.nbAdversites = this.getTotalAdversite()
- rollData.talents = []
- rollData.attrKey2 = "none"
- rollData.coupDevastateur = this.items.find(it => it.type == "talent" && it.name.toLowerCase() == "coup dévastateur" && !it.system.used)
- rollData.hasAmbidextre = this.items.find(it => it.type == "talent" && it.name.toLowerCase() == "ambidextre")
- rollData.hasFeinte = this.system.bonneaventure.actuelle > 0 && this.items.find(it => it.type == "talent" && it.name.toLowerCase() == "feinte")
- rollData.isMonte = this.system.combat.monte
- rollData.config = game.system.mournbladecyd2.config
-
- if (attrKey) {
- rollData.attrKey = attrKey
- if (attrKey != "tochoose") {
- rollData.actionImg = "systems/fvtt-mournblade-cyd2/assets/icons/" + this.system.attributs[attrKey].labelnorm + ".webp"
- rollData.attr = foundry.utils.duplicate(this.system.attributs[attrKey])
- }
- }
- if (compId) {
- rollData.competence = foundry.utils.duplicate(this.items.get(compId) || {})
- let maitrises = [{ key: "none", label: "Aucune" }]
- rollData.competence.system.predilections.forEach(function (item) {
- if (item.maitrise) {
- maitrises.push({ key: item.id, label: item.name });
- }
- })
- rollData.maitrises = maitrises // rollData.competence.system.predilections.filter(p => p.maitrise)
- rollData.actionImg = rollData.competence?.img
- rollData.talents = this.searchRelevantTalents(rollData.competence)
- }
- if (compName) {
- rollData.competence = foundry.utils.duplicate(this.items.find(item => item.name.toLowerCase() == compName.toLowerCase()) || {})
- rollData.actionImg = rollData.competence?.img
- }
- return rollData
- }
-
- /* -------------------------------------------- */
- async rollAttribut(attrKey, isInit = false) {
- let rollData = this.getCommonRollData(attrKey)
- rollData.multiplier = (isInit) ? 1 : 2
- rollData.isInit = isInit
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
-
- /* -------------------------------------------- */
- async rollCompetence(attrKey, compId) {
- let rollData = this.getCommonRollData(attrKey, compId)
- rollData.multiplier = 1 // Attr multiplier, always 1 in competence mode
- console.log("RollDatra", rollData)
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
-
- /* -------------------------------------------- */
- async rollArmeOffensif(armeId) {
- let arme = this.items.get(armeId)
- if (arme.type == "arme") {
- arme = this.prepareArme(arme)
- }
- let rollData = this.getCommonRollData(arme.system.attrKey, arme.system.competence._id)
- rollData.arme = arme
- MournbladeCYD2Utility.updateWithTarget(rollData)
- console.log("ARME!", rollData)
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
- /* -------------------------------------------- */
- async rollAssommer() {
- let rollData = this.getCommonRollData("pui", undefined, "Filouterie")
- rollData.assomer = true
- rollData.conditionsCommunes = true
- MournbladeCYD2Utility.updateWithTarget(rollData)
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
- /* -------------------------------------------- */
- async rollCoupBas() {
- let rollData = this.getCommonRollData("pui", undefined, "Mêlée")
- rollData.coupBas = true
- rollData.conditionsCommunes = true
- MournbladeCYD2Utility.updateWithTarget(rollData)
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
- /* -------------------------------------------- */
- async rollImmobiliser() {
- let rollData = this.getCommonRollData("pui", undefined, "Mêlée")
- rollData.immobiliser = true
- rollData.conditionsCommunes = true
- rollData.cibleconsciente = true
- MournbladeCYD2Utility.updateWithTarget(rollData)
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
- /* -------------------------------------------- */
- async rollRepousser() {
- let rollData = this.getCommonRollData("pui", undefined, "Mêlée")
- rollData.repousser = true
- rollData.conditionsCommunes = true
- rollData.cibleconsciente = true
- MournbladeCYD2Utility.updateWithTarget(rollData)
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
- /* -------------------------------------------- */
- async rollDesengager() {
- let rollData = this.getCommonRollData("adr", undefined, "Mouvements")
- rollData.desengager = true
- rollData.conditionsCommunes = true
- MournbladeCYD2Utility.updateWithTarget(rollData)
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
-
- /* -------------------------------------------- */
- async rollArmeDegats(armeId, targetVigueur = undefined, rollDataInput = undefined) {
- let arme = this.items.get(armeId)
- if (arme.type == "arme") {
- arme = this.prepareArme(arme)
- }
- console.log("DEGATS", arme, targetVigueur, rollDataInput)
- let roll
- let bonus = 0
- let bonus2 = 0
-
- if (rollDataInput?.applyCoupDevastateur) {
- bonus2 = Math.floor(this.system.attributs.pui.value / 2)
- let talent = this.items.find(item => item.type == "talent" && item.name.toLowerCase() == "coup dévastateur")
- this.updateEmbeddedDocuments('Item', [{ _id: talent.id, 'system.used': true }])
- }
-
- if (rollDataInput?.isHeroique) {
- if (rollDataInput?.attaqueCharge) {
- bonus = 5
- }
- if (rollDataInput?.chargeCavalerie) {
- bonus = 6
- }
- roll = await new Roll("2d10rr10+" + arme.system.totalDegats + "+" + bonus + "+" + bonus2).roll()
- } else {
- if (rollDataInput?.attaqueCharge) {
- bonus = 3
- }
- if (rollDataInput?.chargeCavalerie) {
- bonus = 4
- }
- roll = await new Roll("1d10+" + arme.system.totalDegats + "+" + bonus + "+" + bonus2).roll()
- }
- await MournbladeCYD2Utility.showDiceSoNice(roll, game.settings.get("core", "rollMode"));
- let nbEtatPerdus = 0
- if (targetVigueur) {
- nbEtatPerdus = Math.floor(roll.total / targetVigueur)
- }
- //console.log(roll)
- let rollData = {
- arme: arme,
- finalResult: roll.total,
- formula: roll.formula,
- alias: this.name,
- actorImg: this.img,
- actorId: this.id,
- defenderTokenId: rollDataInput?.defenderTokenId,
- actionImg: arme.img,
- targetVigueur: targetVigueur,
- nbEtatPerdus: nbEtatPerdus
- }
- MournbladeCYD2Utility.createChatWithRollMode(rollData.alias, {
- content: await renderTemplate(`systems/fvtt-mournblade-cyd2/templates/chat-degats-result.html`, rollData)
- })
-
- if (rollDataInput?.defenderTokenId && nbEtatPerdus) {
- MournbladeCYD2Utility.applyCombativite(rollDataInput, nbEtatPerdus)
- }
-
- }
-}
diff --git a/.history/modules/mournblade-cyd2-actor_20251026083156.js b/.history/modules/mournblade-cyd2-actor_20251026083156.js
deleted file mode 100644
index 8955866..0000000
--- a/.history/modules/mournblade-cyd2-actor_20251026083156.js
+++ /dev/null
@@ -1,907 +0,0 @@
-/* -------------------------------------------- */
-import { MournbladeCYD2Utility } from "./mournblade-cyd2-utility.js";
-import { MournbladeCYD2RollDialog } from "./mournblade-cyd2-roll-dialog.js";
-
-/* -------------------------------------------- */
-const __degatsBonus = [-2, -2, -1, -1, 0, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 8, 8, 9, 9, 10, 10]
-const __vitesseBonus = [-2, -2, -1, -1, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8]
-
-/* -------------------------------------------- */
-/**
- * Extend the base Actor entity by defining a custom roll data structure which is ideal for the Simple system.
- * @extends {Actor}
- */
-export class MournbladeCYD2Actor extends Actor {
-
- /* -------------------------------------------- */
- /**
- * Override the create() function to provide additional SoS functionality.
- *
- * This overrided create() function adds initial items
- * Namely: Basic skills, money,
- *
- * @param {Object} data Barebones actor data which this function adds onto.
- * @param {Object} options (Unused) Additional options which customize the creation workflow.
- *
- */
-
- static async create(data, options) {
-
- // Case of compendium global import
- if (data instanceof Array) {
- return super.create(data, options);
- }
- // If the created actor has items (only applicable to duplicated actors) bypass the new actor creation logic
- if (data.items) {
- let actor = super.create(data, options);
- return actor;
- }
-
- if (data.type == 'personnage') {
- const skills = await MournbladeCYD2Utility.loadCompendium("fvtt-mournblade-cyd2.skills")
- data.items = skills.map(i => i.toObject())
- }
- if (data.type == 'creature') {
- const skills = await MournbladeCYD2Utility.loadCompendium("fvtt-mournblade-cyd2.skills-creatures")
- data.items = skills.map(i => i.toObject())
- data.items.push({ name: "Arme naturelle 1", type: 'arme', img: "systems/fvtt-mournblade-cyd2/assets/icons/melee.webp", system: { typearme: "contact", bonusmaniementoff: 0, seuildefense: 0, degats: "0" } })
- data.items.push({ name: "Arme naturelle 2", type: 'arme', img: "systems/fvtt-mournblade-cyd2/assets/icons/melee.webp", system: { typearme: "contact", bonusmaniementoff: 0, seuildefense: 0, degats: "0" } })
- }
-
- return super.create(data, options);
- }
-
- /* -------------------------------------------- */
- getBonusDefenseFromTalents() {
- let talents = this.items.filter(item => item.type == "talent" && item.system.isautomated)
- let bonus = 0
- for (let talent of talents) {
- for (let auto of talent.system.automations) {
- if (auto.eventtype == "bonus-permanent" && auto.bonusname == "bonus-defensif") {
- bonus += Number(auto.bonus || 0)
- }
- }
- }
- return bonus
- }
-
- /* -------------------------------------------- */
- prepareArme(arme) {
- if (this.type == "cellule") {
- return arme
- }
-
- arme = foundry.utils.duplicate(arme)
- let combat = this.getCombatValues()
- if (arme.system.typearme == "contact" || arme.system.typearme == "contactjet") {
- let bonusDefense = this.getBonusDefenseFromTalents()
- arme.system.competence = foundry.utils.duplicate(this.items.find(item => item.type == "competence" && item.name.toLowerCase() == "mêlée"))
- arme.system.attrKey = "pui"
- arme.system.totalDegats = arme.system.degats + "+" + combat.bonusDegatsTotal
- arme.system.totalOffensif = this.system.attributs.pui.value + arme.system.competence.system.niveau + arme.system.bonusmaniementoff + (this.system.combat.monte ? 3 : 0)
- arme.system.totalDefensif = combat.defenseTotal + arme.system.competence.system.niveau + arme.system.seuildefense + bonusDefense + (this.system.combat.monte ? 3 : 0)
- console.log("Arme", arme.system.totalDefensif, combat, arme.system.competence.system.niveau, arme.system.seuildefense, bonusDefense)
- arme.system.isdefense = true
- arme.system.isMelee = true
- arme.system.isDistance = false
- }
- if (arme.system.typearme == "jet" || arme.system.typearme == "tir") {
- arme.system.competence = foundry.utils.duplicate(this.items.find(item => item.type == "competence" && item.name.toLowerCase() == "armes à distance"))
- arme.system.attrKey = "adr"
- arme.system.totalOffensif = this.system.attributs.adr.value + arme.system.competence.system.niveau + arme.system.bonusmaniementoff
- arme.system.totalDegats = arme.system.degats
- arme.system.isMelee = false
- arme.system.isDistance = true
- if (arme.system.isdefense) {
- arme.system.totalDefensif = combat.defenseTotal + arme.system.competence.system.niveau + arme.system.seuildefense
- }
- }
- return arme
- }
-
- /* -------------------------------------------- */
- getItemSorted(types) {
- let items = this.items.filter(item => types.includes(item.type)) || []
- MournbladeCYD2Utility.sortArrayObjectsByName(items)
- return items
- }
- getWeapons() {
- let armes = []
- for (let arme of this.items) {
- if (arme.type == "arme") {
- armes.push(this.prepareArme(arme))
- }
- }
- MournbladeCYD2Utility.sortArrayObjectsByName(armes)
- return armes
- }
- getMonnaies() {
- return this.getItemSorted(["monnaie"])
- }
- getEquipments() {
- return this.getItemSorted(["equipement"])
- }
- getArtefacts() {
- return this.getItemSorted(["artefact"])
- }
- getArmors() {
- return this.getItemSorted(["protection"])
- }
- getHistoriques() {
- return this.getItemSorted(["historique"])
- }
- getProfils() {
- return this.getItemSorted(["profil"])
- }
- getTalents() {
- return this.getItemSorted(["talent"])
- }
- getRessources() {
- return this.getItemSorted(["ressource"])
- }
- getContacts() {
- return this.getItemSorted(["contact"])
- }
- getMutations() {
- return this.getItemSorted(["mutation"])
- }
- getDons() {
- return this.getItemSorted(["don"])
- }
- getPactes() {
- return this.getItemSorted(["pacte"])
- }
- getTendances() {
- return this.getItemSorted(["tendance"])
- }
- getRunes() {
- return this.getItemSorted(["rune"])
- }
- getTraitsChaotiques() {
- return this.getItemSorted(["traitchaotique"])
- }
- getTraitsEspeces() {
- return this.getItemSorted(["traitespece"])
- }
-
- /* -------------------------------------------- */
- getAspect() {
- return (this.system.balance.loi > this.system.balance.chaos) ? this.system.balance.loi : this.system.balance.chaos
- }
- getMarge() {
- return Math.abs(this.system.balance.loi - this.system.balance.chaos)
- }
- getAlignement() {
- return (this.system.balance.loi > this.system.balance.chaos) ? "loyal" : "chaotique"
- }
-
- /* -------------------------------------------- */
- getSkills() {
- let comp = []
- for (let item of this.items) {
- item = foundry.utils.duplicate(item)
- if (item.type == "competence") {
- item.system.attribut1total = item.system.niveau + (this.system.attributs[item.system.attribut1]?.value || 0)
- item.system.attribut2total = item.system.niveau + (this.system.attributs[item.system.attribut2]?.value || 0)
- item.system.attribut3total = item.system.niveau + (this.system.attributs[item.system.attribut3]?.value || 0)
- if (item.system.niveau == 0) {
- item.system.attribut1total -= 3
- item.system.attribut2total -= 3
- item.system.attribut3total -= 3
- }
- item.system.attribut1label = this.system.attributs[item.system.attribut1]?.label || ""
- item.system.attribut2label = this.system.attributs[item.system.attribut2]?.label || ""
- item.system.attribut3label = this.system.attributs[item.system.attribut3]?.label || ""
- comp.push(item)
- }
- }
- MournbladeCYD2Utility.sortArrayObjectsByName(comp)
- return comp
- }
-
- /* ----------------------- --------------------- */
- addMember(actorId) {
- let members = foundry.utils.duplicate(this.system.members)
- members.push({ id: actorId })
- this.update({ 'system.members': members })
- }
- async removeMember(actorId) {
- let members = this.system.members.filter(it => it.id != actorId)
- this.update({ 'system.members': members })
- }
-
- /* -------------------------------------------- */
- getDefenseBase() {
- return Math.max(this.system.attributs.tre.value, this.system.attributs.adr.value)
- }
-
- /* -------------------------------------------- */
- getVitesseBase() {
- return 5 + __vitesseBonus[this.system.attributs.adr.value]
- }
- /* -------------------------------------------- */
- getProtection() {
- let equipProtection = 0
- for (let armor of this.items) {
- if (armor.type == "protection" && armor.system.equipped) {
- equipProtection += Number(armor.system.protection)
- }
- }
- if (equipProtection < 4) {
- return 4 + equipProtection // Cas des boucliers + sans armure
- }
- return equipProtection // Uniquement la protection des armures + boucliers
- }
-
- /* -------------------------------------------- */
- getCombatValues() {
- if (this.type == "cellule") {
- return {
- initBase: 0,
- initTotal: 0,
- bonusDegats: 0,
- bonusDegatsTotal: 0,
- vitesseBase: 0,
- vitesseTotal: 0,
- defenseBase: 0,
- protection: 0,
- defenseTotal: 0
- }
- }
-
- let combat = {
- initBase: this.system.attributs.adr.value,
- initTotal: this.system.attributs.adr.value + this.system.combat.initbonus,
- bonusDegats: this.getBonusDegats(),
- bonusDegatsTotal: this.getBonusDegats() + this.system.combat.bonusdegats,
- vitesseBase: this.getVitesseBase(),
- vitesseTotal: this.getVitesseBase() + this.system.combat.vitessebonus,
- defenseBase: this.getDefenseBase(),
- protection: this.getProtection(),
- defenseTotal: this.getDefenseBase() + this.system.combat.defensebonus + this.getProtection() - this.getTotalAdversite() + (this.system.combat.defensetotale ? 3 : 0)
- }
- return combat
- }
-
- /* -------------------------------------------- */
- prepareBaseData() {
- }
-
- /* -------------------------------------------- */
- async prepareData() {
- super.prepareData();
- }
-
- /* -------------------------------------------- */
- prepareDerivedData() {
-
- if (this.type == 'personnage') {
- let talentBonus = this.getVigueurBonus()
- let vigueur = Math.floor((this.system.attributs.pui.value + this.system.attributs.tre.value) / 2) + talentBonus + this.system.sante.vigueurmodifier
- if (vigueur != this.system.sante.vigueur) {
- this.update({ 'system.sante.vigueur': vigueur })
- }
-
- let seuilPouvoirBonus = this.getSeuilPouvoirBonus()
- let seuilPouvoir = Math.floor((this.system.attributs.tre.value + this.system.attributs.cla.value) / 2) + seuilPouvoirBonus + this.system.ame.seuilpouvoirmodifier
- if (seuilPouvoir != this.system.ame.seuilpouvoir) {
- this.update({ 'system.ame.seuilpouvoir': seuilPouvoir })
- }
- }
- super.prepareDerivedData()
- }
-
- /* -------------------------------------------- */
- _preUpdate(changed, options, user) {
- if (changed?.system?.sante?.etat && changed?.system?.sante?.etat != this.system.sante.etat) {
- setTimeout(() => {
- this.processCombativite(changed.system.sante)
- }, 800)
- }
- if (changed?.system?.ame?.etat && changed?.system?.ame?.etat != this.system.ame.etat) {
- // S'assurer que l'état ne dépasse pas le maximum actuel d'âme
- let maxAme = Math.min(this.system.ame.max || this.system.ame.nbame, this.system.ame.nbame)
- if (changed.system.ame.etat > maxAme) {
- changed.system.ame.etat = maxAme
- }
- if (changed.system.ame.etat < 0) {
- changed.system.ame.etat = 0
- }
- setTimeout(() => {
- this.processAme(changed.system.ame)
- }, 800)
- }
- // Si le maximum d'âme change, s'assurer que l'état actuel ne le dépasse pas
- if (changed?.system?.ame?.max && changed.system.ame.max != this.system.ame.max) {
- if (this.system.ame.etat > changed.system.ame.max) {
- changed.system.ame.etat = changed.system.ame.max
- }
- }
- super._preUpdate(changed, options, user);
- }
-
- /* -------------------------------------------- */
- _onUpdate(data, options, user) {
- super._onUpdate(data, options, user);
- }
- /* -------------------------------------------- */
- getItemById(id) {
- let item = this.items.find(item => item.id == id);
- if (item) {
- item = foundry.utils.duplicate(item)
- }
- return item;
- }
-
- /* -------------------------------------------- */
- async equipItem(itemId) {
- let item = this.items.find(item => item.id == itemId)
- if (item && item.system) {
- let update = { _id: item.id, "system.equipped": !item.system.equipped }
- await this.updateEmbeddedDocuments('Item', [update]); // Updates one EmbeddedEntity
- }
- }
-
- /* -------------------------------------------- */
- editItemField(itemId, itemType, itemField, dataType, value) {
- let item = this.items.find(item => item.id == itemId)
- if (item) {
- console.log("Item ", item, itemField, dataType, value)
- if (dataType.toLowerCase() == "number") {
- value = Number(value)
- } else {
- value = String(value)
- }
- let update = { _id: item.id, [`system.${itemField}`]: value };
- this.updateEmbeddedDocuments("Item", [update])
- }
- }
-
- /* -------------------------------------------- */
- checkAttribut(attribut, minLevel) {
- let attr = this.system.attributs.find(at => at.labelnorm == attribut.toLowerCase())
- if (attr && attr.value >= minLevel) {
- return { isValid: true, attr: foundry.utils.duplicate(attr) }
- }
- return { isValid: false }
- }
- /* -------------------------------------------- */
- checkAttributOrCompetenceLevel(compName, minLevel) {
- let comp = this.items.find(i => i.type == "competence" && i.name.toLowerCase() == compName.toLowerCase() && i.system.niveau >= minLevel)
- if (comp) {
- return { isValid: true, item: foundry.utils.duplicate(comp) }
- } else {
- for (let attrKey in this.system.attributs) {
- if (this.system.attributs[attrKey].label.toLowerCase() == compName.toLowerCase() && this.system.attributs[attrKey].value >= minLevel) {
- return { isValid: true, item: foundry.utils.duplicate(this.system.attributs[attrKey]) }
- }
- }
- }
- return { isValid: false, warningMessage: `Prérequis insuffisant : la compétence/attribut ${compName} doit être de niveau ${minLevel} au minimum` }
- }
- /* -------------------------------------------- */
- addCompetenceBonus(compName, bonus, baCost) {
- let comp = this.items.find(i => i.type == "competence" && i.name.toLowerCase() == compName.toLowerCase())
- if (comp) {
- comp = foundry.utils.duplicate(comp)
- comp.system.bonus = bonus
- comp.system.baCost = baCost
- return { isValid: true, item: comp }
- }
- return { isValid: false, warningMessage: `Compétence ${compName} non trouvée` }
- }
- /* -------------------------------------------- */
- checkIfCompetence(compName) {
- let comp = this.items.find(i => i.type == "competence" && i.name.toLowerCase() == compName.toLowerCase())
- if (comp) {
- return { isValid: true, item: comp }
- }
- return { isValid: false }
- }
- /* -------------------------------------------- */
- getVigueur() {
- return this.system.sante.vigueur
- }
-
- /* -------------------------------------------- */
- getVigueurBonus() {
- let talents = this.items.filter(item => item.type == "talent" && item.system.isautomated)
- let bonus = 0
- for (let talent of talents) {
- for (let auto of talent.system.automations) {
- if (auto.eventtype == "bonus-permanent" && auto.bonusname == "vigueur") {
- bonus += Number(auto.bonus || 0)
- }
- }
- }
- return bonus
- }
-
- /* -------------------------------------------- */
- getSeuilPouvoir() {
- return this.system.ame.seuilpouvoir
- }
-
- /* -------------------------------------------- */
- getSeuilPouvoirBonus() {
- let talents = this.items.filter(item => item.type == "talent" && item.system.isautomated)
- let bonus = 0
- for (let talent of talents) {
- for (let auto of talent.system.automations) {
- if (auto.eventtype == "bonus-permanent" && auto.bonusname == "seuilpouvoir") {
- bonus += Number(auto.bonus || 0)
- }
- }
- }
- return bonus
- }
-
- /* -------------------------------------------- */
- getAmeMax() {
- return Math.min(this.system.ame.max || this.system.ame.nbame, this.system.ame.nbame)
- }
-
- /* -------------------------------------------- */
- getBonneAventure() {
- return this.system.bonneaventure.actuelle
- }
- /* -------------------------------------------- */
- checkBonneAventure(cost) {
- return (this.system.bonneaventure.actuelle >= cost)
- }
- /* -------------------------------------------- */
- changeBonneAventure(value) {
- let newBA = this.system.bonneaventure.actuelle
- newBA += value
- this.update({ 'system.bonneaventure.actuelle': newBA })
- }
-
- /* -------------------------------------------- */
- getEclat() {
- return this.system.eclat.value
- }
-
- /* -------------------------------------------- */
- changeEclat(value) {
- let newE = this.system.eclat.value
- newE += value
- this.update({ 'system.eclat.value': newE })
- }
-
- /* -------------------------------------------- */
- compareName(a, b) {
- if (a.name < b.name) {
- return -1;
- }
- if (a.name > b.name) {
- return 1;
- }
- return 0;
- }
-
- /* -------------------------------------------- */
- getAttribute(attrKey) {
- return this.system.attributes[attrKey]
- }
-
- /* -------------------------------------------- */
- getBonusDegats() {
- return 0;
- }
-
- /* -------------------------------------------- */
- changeEtatCombativite(value) {
- if (value === "vaincu") {
- value = 200
- }
- let sante = foundry.utils.duplicate(this.system.sante)
- sante.etat += Number(value)
- sante.etat = Math.max(sante.etat, 0)
- sante.etat = Math.min(sante.etat, this.system.sante.nbcombativite)
- this.update({ 'system.sante': sante })
- if (sante.etat == this.system.sante.nbcombativite) {
- ChatMessage.create({ content: `${this.name} est vaincu !` })
- }
- // Duplicated ! this.processCombativite(sante)
- }
-
- /* -------------------------------------------- */
- changeEtatAme(value) {
- if (value === "brise") {
- value = 200
- }
- let ame = foundry.utils.duplicate(this.system.ame)
- ame.etat += Number(value)
- ame.etat = Math.max(ame.etat, 0)
- // L'état ne peut pas dépasser le maximum actuel d'âme
- let maxAme = Math.min(this.system.ame.max || this.system.ame.nbame, this.system.ame.nbame)
- ame.etat = Math.min(ame.etat, maxAme)
- this.update({ 'system.ame': ame })
- if (ame.etat >= maxAme) {
- ChatMessage.create({ content: `${this.name} est brisé !` })
- }
- }
-
- /* -------------------------------------------- */
- processCombativite(sante) {
- sante = sante || foundry.utils.duplicate(this.system.sante)
- // Gestion des états affaibli et très affaibli
- if (sante.etat == this.system.sante.nbcombativite - 2 || sante.etat == this.system.sante.nbcombativite - 1) {
- if (sante.etat == this.system.sante.nbcombativite - 2 && this.items.find(item => item.type == "talent" && item.name.toLowerCase() == "encaissement")) {
- ChatMessage.create({ content: `${this.name} ne subit pas les 2 adversités rouge grâce à Encaissement. Pensez à les ajouter à la fin de la scène !` })
- } else if (sante.etat == this.system.sante.nbcombativite - 1 && this.items.find(item => item.type == "talent" && item.name.toLowerCase().includes("vaillant"))) {
- ChatMessage.create({ content: `${this.name} ne subit pas les 2 adversités rouge grâce à Vaillant. Pensez à les ajouter à la fin de la scène !` })
- } else {
- ChatMessage.create({ content: `${this.name} subit 2 adversités rouge !` })
- this.incDecAdversite("rouge", 2)
- }
- }
- }
-
- /* -------------------------------------------- */
- processAme(ame) {
- ame = ame || foundry.utils.duplicate(this.system.ame)
- let maxAme = Math.min(this.system.ame.max || this.system.ame.nbame, this.system.ame.nbame)
- // Gestion des états Traumatisé, Très Traumatisé et Brisé en fonction du maximum actuel
- // Les seuils sont calculés par rapport au maximum d'âme actuel
- if (maxAme >= 3 && ame.etat >= maxAme - 2) {
- if (ame.etat == maxAme - 2) {
- ChatMessage.create({ content: `${this.name} est Traumatisé !` })
- } else if (ame.etat == maxAme - 1) {
- ChatMessage.create({ content: `${this.name} est Très Traumatisé !` })
- } else if (ame.etat >= maxAme) {
- ChatMessage.create({ content: `${this.name} est Brisé !` })
- }
- } else if (ame.etat >= maxAme) {
- ChatMessage.create({ content: `${this.name} est Brisé !` })
- }
- }
-
- /* -------------------------------------------- */
- async equipGear(equipmentId) {
- let item = this.items.find(item => item.id == equipmentId);
- if (item?.system?.data) {
- let update = { _id: item.id, "system.equipped": !item.system.equipped };
- await this.updateEmbeddedDocuments('Item', [update]); // Updates one EmbeddedEntity
- }
- }
-
- /* -------------------------------------------- */
- getSubActors() {
- let subActors = [];
- for (let id of this.system.subactors) {
- subActors.push(foundry.utils.duplicate(game.actors.get(id)));
- }
- return subActors;
- }
- /* -------------------------------------------- */
- async addSubActor(subActorId) {
- let subActors = foundry.utils.duplicate(this.system.subactors);
- subActors.push(subActorId);
- await this.update({ 'system.subactors': subActors });
- }
- /* -------------------------------------------- */
- async delSubActor(subActorId) {
- let newArray = [];
- for (let id of this.system.subactors) {
- if (id != subActorId) {
- newArray.push(id);
- }
- }
- await this.update({ 'system.subactors': newArray });
- }
-
- /* -------------------------------------------- */
- getTotalAdversite() {
- return this.system.adversite.bleue + this.system.adversite.rouge + this.system.adversite.noire
- }
-
- /* -------------------------------------------- */
- async incDecAdversite(adv, incDec = 0) {
- let adversite = foundry.utils.duplicate(this.system.adversite)
- adversite[adv] += Number(incDec)
- adversite[adv] = Math.max(adversite[adv], 0)
- adversite[adv] = Math.min(adversite[adv], 20)
- this.update({ 'system.adversite': adversite })
- }
- /* -------------------------------------------- */
- async incDecQuantity(objetId, incDec = 0) {
- let objetQ = this.items.get(objetId)
- if (objetQ) {
- let newQ = objetQ.system.quantite + incDec
- newQ = Math.max(newQ, 0)
- await this.updateEmbeddedDocuments('Item', [{ _id: objetQ.id, 'system.quantite': newQ }]); // pdates one EmbeddedEntity
- }
- }
-
- /* -------------------------------------------- */
- computeRichesse() {
- let valueSC = 0
- for (let monnaie of this.items) {
- if (monnaie.type == "monnaie") {
- valueSC += Number(monnaie.system.prixsc) * Number(monnaie.system.quantite)
- }
- }
- return MournbladeCYD2Utility.computeMonnaieDetails(valueSC)
- }
-
- /* -------------------------------------------- */
- computeValeurEquipement() {
- let valueSC = 0
- for (let equip of this.items) {
- if (equip.type == "equipement" || equip.type == "arme" || equip.type == "protection") {
- valueSC += Number(equip.system.prixsc) * Number(equip.system.quantite ?? 1)
- valueSC += (Number(equip.system.prixca) * Number(equip.system.quantite ?? 1)) * 20
- valueSC += (Number(equip.system.prixpo) * Number(equip.system.quantite ?? 1)) * 400
- }
- }
- return MournbladeCYD2Utility.computeMonnaieDetails(valueSC)
- }
-
- /* -------------------------------------------- */
- getCompetence(compId) {
- return this.items.get(compId)
- }
-
- /* -------------------------------------------- */
- async setPredilectionUsed(compId, predIdx) {
- let comp = this.items.get(compId)
- let pred = foundry.utils.duplicate(comp.system.predilections)
- pred[predIdx].used = true
- await this.updateEmbeddedDocuments('Item', [{ _id: compId, 'system.predilections': pred }])
- }
-
- /* -------------------------------------------- */
- getInitiativeScore() {
- let init = this.getFlag("world", "last-initiative")
- return init || -1
- }
-
- /* -------------------------------------------- */
- getBestAttackValue() {
- let attackList = this.items.filter(item => (item.type == "arme" || item.type == "talent") && item.system.equipped)
- let maxOff = 0
- let bestArme
- for (let arme of attackList) {
- if (arme.type == "arme") {
- arme = this.prepareArme(arme)
- }
- if (arme.system.totalOffensif > maxOff) {
- maxOff = arme.system.totalOffensif
- bestArme = foundry.utils.duplicate(arme)
- }
- }
- return bestArme
- }
-
- /* -------------------------------------------- */
- getBestDefenseValue() {
- let defenseList = this.items.filter(item => (item.type == "arme") && item.system.equipped)
- let maxDef = 0
- let bestArme
- for (let arme of defenseList) {
- if (arme.type == "arme") {
- arme = this.prepareArme(arme)
- }
- if (arme.system.totalDefensif > maxDef) {
- maxDef = arme.system.totalDefensif
- bestArme = foundry.utils.duplicate(arme)
- }
- }
- return bestArme
- }
-
- /* -------------------------------------------- */
- searchRelevantTalents(competence) {
- let talents = []
-
- for (let talent of this.items) {
- if (talent.type == "talent" && talent.system.isautomated && talent.system.automations.length > 0) {
- for (let auto of talent.system.automations) {
- if (auto.eventtype === "prepare-roll") {
- if (auto.competence.toLowerCase() == competence.name.toLowerCase()) {
- talent = foundry.utils.duplicate(talent)
- talent.system.bonus = auto.bonus
- talent.system.baCost = auto.baCost
- talents.push(talent)
- }
- }
- }
- }
- }
- return talents
- }
-
- /* -------------------------------------------- */
- buildListeAdversites() {
- return []
- }
-
- /* -------------------------------------------- */
- getCommonRollData(attrKey = undefined, compId = undefined, compName = undefined) {
- let rollData = MournbladeCYD2Utility.getBasicRollData()
- rollData.alias = this.name
- rollData.actorImg = this.img
- rollData.actorId = this.id
- rollData.tokenId = this.token?.id
- rollData.img = this.img
- rollData.attributs = MournbladeCYD2Utility.getAttributs()
- rollData.maitriseId = "none"
- rollData.nbEclat = this.system.eclat.value
- rollData.nbBA = this.system.bonneaventure.actuelle
- rollData.nbAdversites = this.getTotalAdversite()
- rollData.talents = []
- rollData.attrKey2 = "none"
- rollData.coupDevastateur = this.items.find(it => it.type == "talent" && it.name.toLowerCase() == "coup dévastateur" && !it.system.used)
- rollData.hasAmbidextre = this.items.find(it => it.type == "talent" && it.name.toLowerCase() == "ambidextre")
- rollData.hasFeinte = this.system.bonneaventure.actuelle > 0 && this.items.find(it => it.type == "talent" && it.name.toLowerCase() == "feinte")
- rollData.isMonte = this.system.combat.monte
- rollData.config = game.system.mournbladecyd2.config
-
- if (attrKey) {
- rollData.attrKey = attrKey
- if (attrKey != "tochoose") {
- rollData.actionImg = "systems/fvtt-mournblade-cyd2/assets/icons/" + this.system.attributs[attrKey].labelnorm + ".webp"
- rollData.attr = foundry.utils.duplicate(this.system.attributs[attrKey])
- }
- }
- if (compId) {
- rollData.competence = foundry.utils.duplicate(this.items.get(compId) || {})
- let maitrises = [{ key: "none", label: "Aucune" }]
- rollData.competence.system.predilections.forEach(function (item) {
- if (item.maitrise) {
- maitrises.push({ key: item.id, label: item.name });
- }
- })
- rollData.maitrises = maitrises // rollData.competence.system.predilections.filter(p => p.maitrise)
- rollData.actionImg = rollData.competence?.img
- rollData.talents = this.searchRelevantTalents(rollData.competence)
- }
- if (compName) {
- rollData.competence = foundry.utils.duplicate(this.items.find(item => item.name.toLowerCase() == compName.toLowerCase()) || {})
- rollData.actionImg = rollData.competence?.img
- }
- return rollData
- }
-
- /* -------------------------------------------- */
- async rollAttribut(attrKey, isInit = false) {
- let rollData = this.getCommonRollData(attrKey)
- rollData.multiplier = (isInit) ? 1 : 2
- rollData.isInit = isInit
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
-
- /* -------------------------------------------- */
- async rollCompetence(attrKey, compId) {
- let rollData = this.getCommonRollData(attrKey, compId)
- rollData.multiplier = 1 // Attr multiplier, always 1 in competence mode
- console.log("RollDatra", rollData)
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
-
- /* -------------------------------------------- */
- async rollArmeOffensif(armeId) {
- let arme = this.items.get(armeId)
- if (arme.type == "arme") {
- arme = this.prepareArme(arme)
- }
- let rollData = this.getCommonRollData(arme.system.attrKey, arme.system.competence._id)
- rollData.arme = arme
- MournbladeCYD2Utility.updateWithTarget(rollData)
- console.log("ARME!", rollData)
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
- /* -------------------------------------------- */
- async rollAssommer() {
- let rollData = this.getCommonRollData("pui", undefined, "Filouterie")
- rollData.assomer = true
- rollData.conditionsCommunes = true
- MournbladeCYD2Utility.updateWithTarget(rollData)
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
- /* -------------------------------------------- */
- async rollCoupBas() {
- let rollData = this.getCommonRollData("pui", undefined, "Mêlée")
- rollData.coupBas = true
- rollData.conditionsCommunes = true
- MournbladeCYD2Utility.updateWithTarget(rollData)
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
- /* -------------------------------------------- */
- async rollImmobiliser() {
- let rollData = this.getCommonRollData("pui", undefined, "Mêlée")
- rollData.immobiliser = true
- rollData.conditionsCommunes = true
- rollData.cibleconsciente = true
- MournbladeCYD2Utility.updateWithTarget(rollData)
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
- /* -------------------------------------------- */
- async rollRepousser() {
- let rollData = this.getCommonRollData("pui", undefined, "Mêlée")
- rollData.repousser = true
- rollData.conditionsCommunes = true
- rollData.cibleconsciente = true
- MournbladeCYD2Utility.updateWithTarget(rollData)
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
- /* -------------------------------------------- */
- async rollDesengager() {
- let rollData = this.getCommonRollData("adr", undefined, "Mouvements")
- rollData.desengager = true
- rollData.conditionsCommunes = true
- MournbladeCYD2Utility.updateWithTarget(rollData)
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
-
- /* -------------------------------------------- */
- async rollArmeDegats(armeId, targetVigueur = undefined, rollDataInput = undefined) {
- let arme = this.items.get(armeId)
- if (arme.type == "arme") {
- arme = this.prepareArme(arme)
- }
- console.log("DEGATS", arme, targetVigueur, rollDataInput)
- let roll
- let bonus = 0
- let bonus2 = 0
-
- if (rollDataInput?.applyCoupDevastateur) {
- bonus2 = Math.floor(this.system.attributs.pui.value / 2)
- let talent = this.items.find(item => item.type == "talent" && item.name.toLowerCase() == "coup dévastateur")
- this.updateEmbeddedDocuments('Item', [{ _id: talent.id, 'system.used': true }])
- }
-
- if (rollDataInput?.isHeroique) {
- if (rollDataInput?.attaqueCharge) {
- bonus = 5
- }
- if (rollDataInput?.chargeCavalerie) {
- bonus = 6
- }
- roll = await new Roll("2d10rr10+" + arme.system.totalDegats + "+" + bonus + "+" + bonus2).roll()
- } else {
- if (rollDataInput?.attaqueCharge) {
- bonus = 3
- }
- if (rollDataInput?.chargeCavalerie) {
- bonus = 4
- }
- roll = await new Roll("1d10+" + arme.system.totalDegats + "+" + bonus + "+" + bonus2).roll()
- }
- await MournbladeCYD2Utility.showDiceSoNice(roll, game.settings.get("core", "rollMode"));
- let nbEtatPerdus = 0
- if (targetVigueur) {
- nbEtatPerdus = Math.floor(roll.total / targetVigueur)
- }
- //console.log(roll)
- let rollData = {
- arme: arme,
- finalResult: roll.total,
- formula: roll.formula,
- alias: this.name,
- actorImg: this.img,
- actorId: this.id,
- defenderTokenId: rollDataInput?.defenderTokenId,
- actionImg: arme.img,
- targetVigueur: targetVigueur,
- nbEtatPerdus: nbEtatPerdus
- }
- MournbladeCYD2Utility.createChatWithRollMode(rollData.alias, {
- content: await renderTemplate(`systems/fvtt-mournblade-cyd2/templates/chat-degats-result.html`, rollData)
- })
-
- if (rollDataInput?.defenderTokenId && nbEtatPerdus) {
- MournbladeCYD2Utility.applyCombativite(rollDataInput, nbEtatPerdus)
- }
-
- }
-}
diff --git a/.history/modules/mournblade-cyd2-actor_20251026083157.js b/.history/modules/mournblade-cyd2-actor_20251026083157.js
deleted file mode 100644
index 8955866..0000000
--- a/.history/modules/mournblade-cyd2-actor_20251026083157.js
+++ /dev/null
@@ -1,907 +0,0 @@
-/* -------------------------------------------- */
-import { MournbladeCYD2Utility } from "./mournblade-cyd2-utility.js";
-import { MournbladeCYD2RollDialog } from "./mournblade-cyd2-roll-dialog.js";
-
-/* -------------------------------------------- */
-const __degatsBonus = [-2, -2, -1, -1, 0, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 8, 8, 9, 9, 10, 10]
-const __vitesseBonus = [-2, -2, -1, -1, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8]
-
-/* -------------------------------------------- */
-/**
- * Extend the base Actor entity by defining a custom roll data structure which is ideal for the Simple system.
- * @extends {Actor}
- */
-export class MournbladeCYD2Actor extends Actor {
-
- /* -------------------------------------------- */
- /**
- * Override the create() function to provide additional SoS functionality.
- *
- * This overrided create() function adds initial items
- * Namely: Basic skills, money,
- *
- * @param {Object} data Barebones actor data which this function adds onto.
- * @param {Object} options (Unused) Additional options which customize the creation workflow.
- *
- */
-
- static async create(data, options) {
-
- // Case of compendium global import
- if (data instanceof Array) {
- return super.create(data, options);
- }
- // If the created actor has items (only applicable to duplicated actors) bypass the new actor creation logic
- if (data.items) {
- let actor = super.create(data, options);
- return actor;
- }
-
- if (data.type == 'personnage') {
- const skills = await MournbladeCYD2Utility.loadCompendium("fvtt-mournblade-cyd2.skills")
- data.items = skills.map(i => i.toObject())
- }
- if (data.type == 'creature') {
- const skills = await MournbladeCYD2Utility.loadCompendium("fvtt-mournblade-cyd2.skills-creatures")
- data.items = skills.map(i => i.toObject())
- data.items.push({ name: "Arme naturelle 1", type: 'arme', img: "systems/fvtt-mournblade-cyd2/assets/icons/melee.webp", system: { typearme: "contact", bonusmaniementoff: 0, seuildefense: 0, degats: "0" } })
- data.items.push({ name: "Arme naturelle 2", type: 'arme', img: "systems/fvtt-mournblade-cyd2/assets/icons/melee.webp", system: { typearme: "contact", bonusmaniementoff: 0, seuildefense: 0, degats: "0" } })
- }
-
- return super.create(data, options);
- }
-
- /* -------------------------------------------- */
- getBonusDefenseFromTalents() {
- let talents = this.items.filter(item => item.type == "talent" && item.system.isautomated)
- let bonus = 0
- for (let talent of talents) {
- for (let auto of talent.system.automations) {
- if (auto.eventtype == "bonus-permanent" && auto.bonusname == "bonus-defensif") {
- bonus += Number(auto.bonus || 0)
- }
- }
- }
- return bonus
- }
-
- /* -------------------------------------------- */
- prepareArme(arme) {
- if (this.type == "cellule") {
- return arme
- }
-
- arme = foundry.utils.duplicate(arme)
- let combat = this.getCombatValues()
- if (arme.system.typearme == "contact" || arme.system.typearme == "contactjet") {
- let bonusDefense = this.getBonusDefenseFromTalents()
- arme.system.competence = foundry.utils.duplicate(this.items.find(item => item.type == "competence" && item.name.toLowerCase() == "mêlée"))
- arme.system.attrKey = "pui"
- arme.system.totalDegats = arme.system.degats + "+" + combat.bonusDegatsTotal
- arme.system.totalOffensif = this.system.attributs.pui.value + arme.system.competence.system.niveau + arme.system.bonusmaniementoff + (this.system.combat.monte ? 3 : 0)
- arme.system.totalDefensif = combat.defenseTotal + arme.system.competence.system.niveau + arme.system.seuildefense + bonusDefense + (this.system.combat.monte ? 3 : 0)
- console.log("Arme", arme.system.totalDefensif, combat, arme.system.competence.system.niveau, arme.system.seuildefense, bonusDefense)
- arme.system.isdefense = true
- arme.system.isMelee = true
- arme.system.isDistance = false
- }
- if (arme.system.typearme == "jet" || arme.system.typearme == "tir") {
- arme.system.competence = foundry.utils.duplicate(this.items.find(item => item.type == "competence" && item.name.toLowerCase() == "armes à distance"))
- arme.system.attrKey = "adr"
- arme.system.totalOffensif = this.system.attributs.adr.value + arme.system.competence.system.niveau + arme.system.bonusmaniementoff
- arme.system.totalDegats = arme.system.degats
- arme.system.isMelee = false
- arme.system.isDistance = true
- if (arme.system.isdefense) {
- arme.system.totalDefensif = combat.defenseTotal + arme.system.competence.system.niveau + arme.system.seuildefense
- }
- }
- return arme
- }
-
- /* -------------------------------------------- */
- getItemSorted(types) {
- let items = this.items.filter(item => types.includes(item.type)) || []
- MournbladeCYD2Utility.sortArrayObjectsByName(items)
- return items
- }
- getWeapons() {
- let armes = []
- for (let arme of this.items) {
- if (arme.type == "arme") {
- armes.push(this.prepareArme(arme))
- }
- }
- MournbladeCYD2Utility.sortArrayObjectsByName(armes)
- return armes
- }
- getMonnaies() {
- return this.getItemSorted(["monnaie"])
- }
- getEquipments() {
- return this.getItemSorted(["equipement"])
- }
- getArtefacts() {
- return this.getItemSorted(["artefact"])
- }
- getArmors() {
- return this.getItemSorted(["protection"])
- }
- getHistoriques() {
- return this.getItemSorted(["historique"])
- }
- getProfils() {
- return this.getItemSorted(["profil"])
- }
- getTalents() {
- return this.getItemSorted(["talent"])
- }
- getRessources() {
- return this.getItemSorted(["ressource"])
- }
- getContacts() {
- return this.getItemSorted(["contact"])
- }
- getMutations() {
- return this.getItemSorted(["mutation"])
- }
- getDons() {
- return this.getItemSorted(["don"])
- }
- getPactes() {
- return this.getItemSorted(["pacte"])
- }
- getTendances() {
- return this.getItemSorted(["tendance"])
- }
- getRunes() {
- return this.getItemSorted(["rune"])
- }
- getTraitsChaotiques() {
- return this.getItemSorted(["traitchaotique"])
- }
- getTraitsEspeces() {
- return this.getItemSorted(["traitespece"])
- }
-
- /* -------------------------------------------- */
- getAspect() {
- return (this.system.balance.loi > this.system.balance.chaos) ? this.system.balance.loi : this.system.balance.chaos
- }
- getMarge() {
- return Math.abs(this.system.balance.loi - this.system.balance.chaos)
- }
- getAlignement() {
- return (this.system.balance.loi > this.system.balance.chaos) ? "loyal" : "chaotique"
- }
-
- /* -------------------------------------------- */
- getSkills() {
- let comp = []
- for (let item of this.items) {
- item = foundry.utils.duplicate(item)
- if (item.type == "competence") {
- item.system.attribut1total = item.system.niveau + (this.system.attributs[item.system.attribut1]?.value || 0)
- item.system.attribut2total = item.system.niveau + (this.system.attributs[item.system.attribut2]?.value || 0)
- item.system.attribut3total = item.system.niveau + (this.system.attributs[item.system.attribut3]?.value || 0)
- if (item.system.niveau == 0) {
- item.system.attribut1total -= 3
- item.system.attribut2total -= 3
- item.system.attribut3total -= 3
- }
- item.system.attribut1label = this.system.attributs[item.system.attribut1]?.label || ""
- item.system.attribut2label = this.system.attributs[item.system.attribut2]?.label || ""
- item.system.attribut3label = this.system.attributs[item.system.attribut3]?.label || ""
- comp.push(item)
- }
- }
- MournbladeCYD2Utility.sortArrayObjectsByName(comp)
- return comp
- }
-
- /* ----------------------- --------------------- */
- addMember(actorId) {
- let members = foundry.utils.duplicate(this.system.members)
- members.push({ id: actorId })
- this.update({ 'system.members': members })
- }
- async removeMember(actorId) {
- let members = this.system.members.filter(it => it.id != actorId)
- this.update({ 'system.members': members })
- }
-
- /* -------------------------------------------- */
- getDefenseBase() {
- return Math.max(this.system.attributs.tre.value, this.system.attributs.adr.value)
- }
-
- /* -------------------------------------------- */
- getVitesseBase() {
- return 5 + __vitesseBonus[this.system.attributs.adr.value]
- }
- /* -------------------------------------------- */
- getProtection() {
- let equipProtection = 0
- for (let armor of this.items) {
- if (armor.type == "protection" && armor.system.equipped) {
- equipProtection += Number(armor.system.protection)
- }
- }
- if (equipProtection < 4) {
- return 4 + equipProtection // Cas des boucliers + sans armure
- }
- return equipProtection // Uniquement la protection des armures + boucliers
- }
-
- /* -------------------------------------------- */
- getCombatValues() {
- if (this.type == "cellule") {
- return {
- initBase: 0,
- initTotal: 0,
- bonusDegats: 0,
- bonusDegatsTotal: 0,
- vitesseBase: 0,
- vitesseTotal: 0,
- defenseBase: 0,
- protection: 0,
- defenseTotal: 0
- }
- }
-
- let combat = {
- initBase: this.system.attributs.adr.value,
- initTotal: this.system.attributs.adr.value + this.system.combat.initbonus,
- bonusDegats: this.getBonusDegats(),
- bonusDegatsTotal: this.getBonusDegats() + this.system.combat.bonusdegats,
- vitesseBase: this.getVitesseBase(),
- vitesseTotal: this.getVitesseBase() + this.system.combat.vitessebonus,
- defenseBase: this.getDefenseBase(),
- protection: this.getProtection(),
- defenseTotal: this.getDefenseBase() + this.system.combat.defensebonus + this.getProtection() - this.getTotalAdversite() + (this.system.combat.defensetotale ? 3 : 0)
- }
- return combat
- }
-
- /* -------------------------------------------- */
- prepareBaseData() {
- }
-
- /* -------------------------------------------- */
- async prepareData() {
- super.prepareData();
- }
-
- /* -------------------------------------------- */
- prepareDerivedData() {
-
- if (this.type == 'personnage') {
- let talentBonus = this.getVigueurBonus()
- let vigueur = Math.floor((this.system.attributs.pui.value + this.system.attributs.tre.value) / 2) + talentBonus + this.system.sante.vigueurmodifier
- if (vigueur != this.system.sante.vigueur) {
- this.update({ 'system.sante.vigueur': vigueur })
- }
-
- let seuilPouvoirBonus = this.getSeuilPouvoirBonus()
- let seuilPouvoir = Math.floor((this.system.attributs.tre.value + this.system.attributs.cla.value) / 2) + seuilPouvoirBonus + this.system.ame.seuilpouvoirmodifier
- if (seuilPouvoir != this.system.ame.seuilpouvoir) {
- this.update({ 'system.ame.seuilpouvoir': seuilPouvoir })
- }
- }
- super.prepareDerivedData()
- }
-
- /* -------------------------------------------- */
- _preUpdate(changed, options, user) {
- if (changed?.system?.sante?.etat && changed?.system?.sante?.etat != this.system.sante.etat) {
- setTimeout(() => {
- this.processCombativite(changed.system.sante)
- }, 800)
- }
- if (changed?.system?.ame?.etat && changed?.system?.ame?.etat != this.system.ame.etat) {
- // S'assurer que l'état ne dépasse pas le maximum actuel d'âme
- let maxAme = Math.min(this.system.ame.max || this.system.ame.nbame, this.system.ame.nbame)
- if (changed.system.ame.etat > maxAme) {
- changed.system.ame.etat = maxAme
- }
- if (changed.system.ame.etat < 0) {
- changed.system.ame.etat = 0
- }
- setTimeout(() => {
- this.processAme(changed.system.ame)
- }, 800)
- }
- // Si le maximum d'âme change, s'assurer que l'état actuel ne le dépasse pas
- if (changed?.system?.ame?.max && changed.system.ame.max != this.system.ame.max) {
- if (this.system.ame.etat > changed.system.ame.max) {
- changed.system.ame.etat = changed.system.ame.max
- }
- }
- super._preUpdate(changed, options, user);
- }
-
- /* -------------------------------------------- */
- _onUpdate(data, options, user) {
- super._onUpdate(data, options, user);
- }
- /* -------------------------------------------- */
- getItemById(id) {
- let item = this.items.find(item => item.id == id);
- if (item) {
- item = foundry.utils.duplicate(item)
- }
- return item;
- }
-
- /* -------------------------------------------- */
- async equipItem(itemId) {
- let item = this.items.find(item => item.id == itemId)
- if (item && item.system) {
- let update = { _id: item.id, "system.equipped": !item.system.equipped }
- await this.updateEmbeddedDocuments('Item', [update]); // Updates one EmbeddedEntity
- }
- }
-
- /* -------------------------------------------- */
- editItemField(itemId, itemType, itemField, dataType, value) {
- let item = this.items.find(item => item.id == itemId)
- if (item) {
- console.log("Item ", item, itemField, dataType, value)
- if (dataType.toLowerCase() == "number") {
- value = Number(value)
- } else {
- value = String(value)
- }
- let update = { _id: item.id, [`system.${itemField}`]: value };
- this.updateEmbeddedDocuments("Item", [update])
- }
- }
-
- /* -------------------------------------------- */
- checkAttribut(attribut, minLevel) {
- let attr = this.system.attributs.find(at => at.labelnorm == attribut.toLowerCase())
- if (attr && attr.value >= minLevel) {
- return { isValid: true, attr: foundry.utils.duplicate(attr) }
- }
- return { isValid: false }
- }
- /* -------------------------------------------- */
- checkAttributOrCompetenceLevel(compName, minLevel) {
- let comp = this.items.find(i => i.type == "competence" && i.name.toLowerCase() == compName.toLowerCase() && i.system.niveau >= minLevel)
- if (comp) {
- return { isValid: true, item: foundry.utils.duplicate(comp) }
- } else {
- for (let attrKey in this.system.attributs) {
- if (this.system.attributs[attrKey].label.toLowerCase() == compName.toLowerCase() && this.system.attributs[attrKey].value >= minLevel) {
- return { isValid: true, item: foundry.utils.duplicate(this.system.attributs[attrKey]) }
- }
- }
- }
- return { isValid: false, warningMessage: `Prérequis insuffisant : la compétence/attribut ${compName} doit être de niveau ${minLevel} au minimum` }
- }
- /* -------------------------------------------- */
- addCompetenceBonus(compName, bonus, baCost) {
- let comp = this.items.find(i => i.type == "competence" && i.name.toLowerCase() == compName.toLowerCase())
- if (comp) {
- comp = foundry.utils.duplicate(comp)
- comp.system.bonus = bonus
- comp.system.baCost = baCost
- return { isValid: true, item: comp }
- }
- return { isValid: false, warningMessage: `Compétence ${compName} non trouvée` }
- }
- /* -------------------------------------------- */
- checkIfCompetence(compName) {
- let comp = this.items.find(i => i.type == "competence" && i.name.toLowerCase() == compName.toLowerCase())
- if (comp) {
- return { isValid: true, item: comp }
- }
- return { isValid: false }
- }
- /* -------------------------------------------- */
- getVigueur() {
- return this.system.sante.vigueur
- }
-
- /* -------------------------------------------- */
- getVigueurBonus() {
- let talents = this.items.filter(item => item.type == "talent" && item.system.isautomated)
- let bonus = 0
- for (let talent of talents) {
- for (let auto of talent.system.automations) {
- if (auto.eventtype == "bonus-permanent" && auto.bonusname == "vigueur") {
- bonus += Number(auto.bonus || 0)
- }
- }
- }
- return bonus
- }
-
- /* -------------------------------------------- */
- getSeuilPouvoir() {
- return this.system.ame.seuilpouvoir
- }
-
- /* -------------------------------------------- */
- getSeuilPouvoirBonus() {
- let talents = this.items.filter(item => item.type == "talent" && item.system.isautomated)
- let bonus = 0
- for (let talent of talents) {
- for (let auto of talent.system.automations) {
- if (auto.eventtype == "bonus-permanent" && auto.bonusname == "seuilpouvoir") {
- bonus += Number(auto.bonus || 0)
- }
- }
- }
- return bonus
- }
-
- /* -------------------------------------------- */
- getAmeMax() {
- return Math.min(this.system.ame.max || this.system.ame.nbame, this.system.ame.nbame)
- }
-
- /* -------------------------------------------- */
- getBonneAventure() {
- return this.system.bonneaventure.actuelle
- }
- /* -------------------------------------------- */
- checkBonneAventure(cost) {
- return (this.system.bonneaventure.actuelle >= cost)
- }
- /* -------------------------------------------- */
- changeBonneAventure(value) {
- let newBA = this.system.bonneaventure.actuelle
- newBA += value
- this.update({ 'system.bonneaventure.actuelle': newBA })
- }
-
- /* -------------------------------------------- */
- getEclat() {
- return this.system.eclat.value
- }
-
- /* -------------------------------------------- */
- changeEclat(value) {
- let newE = this.system.eclat.value
- newE += value
- this.update({ 'system.eclat.value': newE })
- }
-
- /* -------------------------------------------- */
- compareName(a, b) {
- if (a.name < b.name) {
- return -1;
- }
- if (a.name > b.name) {
- return 1;
- }
- return 0;
- }
-
- /* -------------------------------------------- */
- getAttribute(attrKey) {
- return this.system.attributes[attrKey]
- }
-
- /* -------------------------------------------- */
- getBonusDegats() {
- return 0;
- }
-
- /* -------------------------------------------- */
- changeEtatCombativite(value) {
- if (value === "vaincu") {
- value = 200
- }
- let sante = foundry.utils.duplicate(this.system.sante)
- sante.etat += Number(value)
- sante.etat = Math.max(sante.etat, 0)
- sante.etat = Math.min(sante.etat, this.system.sante.nbcombativite)
- this.update({ 'system.sante': sante })
- if (sante.etat == this.system.sante.nbcombativite) {
- ChatMessage.create({ content: `${this.name} est vaincu !` })
- }
- // Duplicated ! this.processCombativite(sante)
- }
-
- /* -------------------------------------------- */
- changeEtatAme(value) {
- if (value === "brise") {
- value = 200
- }
- let ame = foundry.utils.duplicate(this.system.ame)
- ame.etat += Number(value)
- ame.etat = Math.max(ame.etat, 0)
- // L'état ne peut pas dépasser le maximum actuel d'âme
- let maxAme = Math.min(this.system.ame.max || this.system.ame.nbame, this.system.ame.nbame)
- ame.etat = Math.min(ame.etat, maxAme)
- this.update({ 'system.ame': ame })
- if (ame.etat >= maxAme) {
- ChatMessage.create({ content: `${this.name} est brisé !` })
- }
- }
-
- /* -------------------------------------------- */
- processCombativite(sante) {
- sante = sante || foundry.utils.duplicate(this.system.sante)
- // Gestion des états affaibli et très affaibli
- if (sante.etat == this.system.sante.nbcombativite - 2 || sante.etat == this.system.sante.nbcombativite - 1) {
- if (sante.etat == this.system.sante.nbcombativite - 2 && this.items.find(item => item.type == "talent" && item.name.toLowerCase() == "encaissement")) {
- ChatMessage.create({ content: `${this.name} ne subit pas les 2 adversités rouge grâce à Encaissement. Pensez à les ajouter à la fin de la scène !` })
- } else if (sante.etat == this.system.sante.nbcombativite - 1 && this.items.find(item => item.type == "talent" && item.name.toLowerCase().includes("vaillant"))) {
- ChatMessage.create({ content: `${this.name} ne subit pas les 2 adversités rouge grâce à Vaillant. Pensez à les ajouter à la fin de la scène !` })
- } else {
- ChatMessage.create({ content: `${this.name} subit 2 adversités rouge !` })
- this.incDecAdversite("rouge", 2)
- }
- }
- }
-
- /* -------------------------------------------- */
- processAme(ame) {
- ame = ame || foundry.utils.duplicate(this.system.ame)
- let maxAme = Math.min(this.system.ame.max || this.system.ame.nbame, this.system.ame.nbame)
- // Gestion des états Traumatisé, Très Traumatisé et Brisé en fonction du maximum actuel
- // Les seuils sont calculés par rapport au maximum d'âme actuel
- if (maxAme >= 3 && ame.etat >= maxAme - 2) {
- if (ame.etat == maxAme - 2) {
- ChatMessage.create({ content: `${this.name} est Traumatisé !` })
- } else if (ame.etat == maxAme - 1) {
- ChatMessage.create({ content: `${this.name} est Très Traumatisé !` })
- } else if (ame.etat >= maxAme) {
- ChatMessage.create({ content: `${this.name} est Brisé !` })
- }
- } else if (ame.etat >= maxAme) {
- ChatMessage.create({ content: `${this.name} est Brisé !` })
- }
- }
-
- /* -------------------------------------------- */
- async equipGear(equipmentId) {
- let item = this.items.find(item => item.id == equipmentId);
- if (item?.system?.data) {
- let update = { _id: item.id, "system.equipped": !item.system.equipped };
- await this.updateEmbeddedDocuments('Item', [update]); // Updates one EmbeddedEntity
- }
- }
-
- /* -------------------------------------------- */
- getSubActors() {
- let subActors = [];
- for (let id of this.system.subactors) {
- subActors.push(foundry.utils.duplicate(game.actors.get(id)));
- }
- return subActors;
- }
- /* -------------------------------------------- */
- async addSubActor(subActorId) {
- let subActors = foundry.utils.duplicate(this.system.subactors);
- subActors.push(subActorId);
- await this.update({ 'system.subactors': subActors });
- }
- /* -------------------------------------------- */
- async delSubActor(subActorId) {
- let newArray = [];
- for (let id of this.system.subactors) {
- if (id != subActorId) {
- newArray.push(id);
- }
- }
- await this.update({ 'system.subactors': newArray });
- }
-
- /* -------------------------------------------- */
- getTotalAdversite() {
- return this.system.adversite.bleue + this.system.adversite.rouge + this.system.adversite.noire
- }
-
- /* -------------------------------------------- */
- async incDecAdversite(adv, incDec = 0) {
- let adversite = foundry.utils.duplicate(this.system.adversite)
- adversite[adv] += Number(incDec)
- adversite[adv] = Math.max(adversite[adv], 0)
- adversite[adv] = Math.min(adversite[adv], 20)
- this.update({ 'system.adversite': adversite })
- }
- /* -------------------------------------------- */
- async incDecQuantity(objetId, incDec = 0) {
- let objetQ = this.items.get(objetId)
- if (objetQ) {
- let newQ = objetQ.system.quantite + incDec
- newQ = Math.max(newQ, 0)
- await this.updateEmbeddedDocuments('Item', [{ _id: objetQ.id, 'system.quantite': newQ }]); // pdates one EmbeddedEntity
- }
- }
-
- /* -------------------------------------------- */
- computeRichesse() {
- let valueSC = 0
- for (let monnaie of this.items) {
- if (monnaie.type == "monnaie") {
- valueSC += Number(monnaie.system.prixsc) * Number(monnaie.system.quantite)
- }
- }
- return MournbladeCYD2Utility.computeMonnaieDetails(valueSC)
- }
-
- /* -------------------------------------------- */
- computeValeurEquipement() {
- let valueSC = 0
- for (let equip of this.items) {
- if (equip.type == "equipement" || equip.type == "arme" || equip.type == "protection") {
- valueSC += Number(equip.system.prixsc) * Number(equip.system.quantite ?? 1)
- valueSC += (Number(equip.system.prixca) * Number(equip.system.quantite ?? 1)) * 20
- valueSC += (Number(equip.system.prixpo) * Number(equip.system.quantite ?? 1)) * 400
- }
- }
- return MournbladeCYD2Utility.computeMonnaieDetails(valueSC)
- }
-
- /* -------------------------------------------- */
- getCompetence(compId) {
- return this.items.get(compId)
- }
-
- /* -------------------------------------------- */
- async setPredilectionUsed(compId, predIdx) {
- let comp = this.items.get(compId)
- let pred = foundry.utils.duplicate(comp.system.predilections)
- pred[predIdx].used = true
- await this.updateEmbeddedDocuments('Item', [{ _id: compId, 'system.predilections': pred }])
- }
-
- /* -------------------------------------------- */
- getInitiativeScore() {
- let init = this.getFlag("world", "last-initiative")
- return init || -1
- }
-
- /* -------------------------------------------- */
- getBestAttackValue() {
- let attackList = this.items.filter(item => (item.type == "arme" || item.type == "talent") && item.system.equipped)
- let maxOff = 0
- let bestArme
- for (let arme of attackList) {
- if (arme.type == "arme") {
- arme = this.prepareArme(arme)
- }
- if (arme.system.totalOffensif > maxOff) {
- maxOff = arme.system.totalOffensif
- bestArme = foundry.utils.duplicate(arme)
- }
- }
- return bestArme
- }
-
- /* -------------------------------------------- */
- getBestDefenseValue() {
- let defenseList = this.items.filter(item => (item.type == "arme") && item.system.equipped)
- let maxDef = 0
- let bestArme
- for (let arme of defenseList) {
- if (arme.type == "arme") {
- arme = this.prepareArme(arme)
- }
- if (arme.system.totalDefensif > maxDef) {
- maxDef = arme.system.totalDefensif
- bestArme = foundry.utils.duplicate(arme)
- }
- }
- return bestArme
- }
-
- /* -------------------------------------------- */
- searchRelevantTalents(competence) {
- let talents = []
-
- for (let talent of this.items) {
- if (talent.type == "talent" && talent.system.isautomated && talent.system.automations.length > 0) {
- for (let auto of talent.system.automations) {
- if (auto.eventtype === "prepare-roll") {
- if (auto.competence.toLowerCase() == competence.name.toLowerCase()) {
- talent = foundry.utils.duplicate(talent)
- talent.system.bonus = auto.bonus
- talent.system.baCost = auto.baCost
- talents.push(talent)
- }
- }
- }
- }
- }
- return talents
- }
-
- /* -------------------------------------------- */
- buildListeAdversites() {
- return []
- }
-
- /* -------------------------------------------- */
- getCommonRollData(attrKey = undefined, compId = undefined, compName = undefined) {
- let rollData = MournbladeCYD2Utility.getBasicRollData()
- rollData.alias = this.name
- rollData.actorImg = this.img
- rollData.actorId = this.id
- rollData.tokenId = this.token?.id
- rollData.img = this.img
- rollData.attributs = MournbladeCYD2Utility.getAttributs()
- rollData.maitriseId = "none"
- rollData.nbEclat = this.system.eclat.value
- rollData.nbBA = this.system.bonneaventure.actuelle
- rollData.nbAdversites = this.getTotalAdversite()
- rollData.talents = []
- rollData.attrKey2 = "none"
- rollData.coupDevastateur = this.items.find(it => it.type == "talent" && it.name.toLowerCase() == "coup dévastateur" && !it.system.used)
- rollData.hasAmbidextre = this.items.find(it => it.type == "talent" && it.name.toLowerCase() == "ambidextre")
- rollData.hasFeinte = this.system.bonneaventure.actuelle > 0 && this.items.find(it => it.type == "talent" && it.name.toLowerCase() == "feinte")
- rollData.isMonte = this.system.combat.monte
- rollData.config = game.system.mournbladecyd2.config
-
- if (attrKey) {
- rollData.attrKey = attrKey
- if (attrKey != "tochoose") {
- rollData.actionImg = "systems/fvtt-mournblade-cyd2/assets/icons/" + this.system.attributs[attrKey].labelnorm + ".webp"
- rollData.attr = foundry.utils.duplicate(this.system.attributs[attrKey])
- }
- }
- if (compId) {
- rollData.competence = foundry.utils.duplicate(this.items.get(compId) || {})
- let maitrises = [{ key: "none", label: "Aucune" }]
- rollData.competence.system.predilections.forEach(function (item) {
- if (item.maitrise) {
- maitrises.push({ key: item.id, label: item.name });
- }
- })
- rollData.maitrises = maitrises // rollData.competence.system.predilections.filter(p => p.maitrise)
- rollData.actionImg = rollData.competence?.img
- rollData.talents = this.searchRelevantTalents(rollData.competence)
- }
- if (compName) {
- rollData.competence = foundry.utils.duplicate(this.items.find(item => item.name.toLowerCase() == compName.toLowerCase()) || {})
- rollData.actionImg = rollData.competence?.img
- }
- return rollData
- }
-
- /* -------------------------------------------- */
- async rollAttribut(attrKey, isInit = false) {
- let rollData = this.getCommonRollData(attrKey)
- rollData.multiplier = (isInit) ? 1 : 2
- rollData.isInit = isInit
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
-
- /* -------------------------------------------- */
- async rollCompetence(attrKey, compId) {
- let rollData = this.getCommonRollData(attrKey, compId)
- rollData.multiplier = 1 // Attr multiplier, always 1 in competence mode
- console.log("RollDatra", rollData)
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
-
- /* -------------------------------------------- */
- async rollArmeOffensif(armeId) {
- let arme = this.items.get(armeId)
- if (arme.type == "arme") {
- arme = this.prepareArme(arme)
- }
- let rollData = this.getCommonRollData(arme.system.attrKey, arme.system.competence._id)
- rollData.arme = arme
- MournbladeCYD2Utility.updateWithTarget(rollData)
- console.log("ARME!", rollData)
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
- /* -------------------------------------------- */
- async rollAssommer() {
- let rollData = this.getCommonRollData("pui", undefined, "Filouterie")
- rollData.assomer = true
- rollData.conditionsCommunes = true
- MournbladeCYD2Utility.updateWithTarget(rollData)
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
- /* -------------------------------------------- */
- async rollCoupBas() {
- let rollData = this.getCommonRollData("pui", undefined, "Mêlée")
- rollData.coupBas = true
- rollData.conditionsCommunes = true
- MournbladeCYD2Utility.updateWithTarget(rollData)
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
- /* -------------------------------------------- */
- async rollImmobiliser() {
- let rollData = this.getCommonRollData("pui", undefined, "Mêlée")
- rollData.immobiliser = true
- rollData.conditionsCommunes = true
- rollData.cibleconsciente = true
- MournbladeCYD2Utility.updateWithTarget(rollData)
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
- /* -------------------------------------------- */
- async rollRepousser() {
- let rollData = this.getCommonRollData("pui", undefined, "Mêlée")
- rollData.repousser = true
- rollData.conditionsCommunes = true
- rollData.cibleconsciente = true
- MournbladeCYD2Utility.updateWithTarget(rollData)
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
- /* -------------------------------------------- */
- async rollDesengager() {
- let rollData = this.getCommonRollData("adr", undefined, "Mouvements")
- rollData.desengager = true
- rollData.conditionsCommunes = true
- MournbladeCYD2Utility.updateWithTarget(rollData)
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
-
- /* -------------------------------------------- */
- async rollArmeDegats(armeId, targetVigueur = undefined, rollDataInput = undefined) {
- let arme = this.items.get(armeId)
- if (arme.type == "arme") {
- arme = this.prepareArme(arme)
- }
- console.log("DEGATS", arme, targetVigueur, rollDataInput)
- let roll
- let bonus = 0
- let bonus2 = 0
-
- if (rollDataInput?.applyCoupDevastateur) {
- bonus2 = Math.floor(this.system.attributs.pui.value / 2)
- let talent = this.items.find(item => item.type == "talent" && item.name.toLowerCase() == "coup dévastateur")
- this.updateEmbeddedDocuments('Item', [{ _id: talent.id, 'system.used': true }])
- }
-
- if (rollDataInput?.isHeroique) {
- if (rollDataInput?.attaqueCharge) {
- bonus = 5
- }
- if (rollDataInput?.chargeCavalerie) {
- bonus = 6
- }
- roll = await new Roll("2d10rr10+" + arme.system.totalDegats + "+" + bonus + "+" + bonus2).roll()
- } else {
- if (rollDataInput?.attaqueCharge) {
- bonus = 3
- }
- if (rollDataInput?.chargeCavalerie) {
- bonus = 4
- }
- roll = await new Roll("1d10+" + arme.system.totalDegats + "+" + bonus + "+" + bonus2).roll()
- }
- await MournbladeCYD2Utility.showDiceSoNice(roll, game.settings.get("core", "rollMode"));
- let nbEtatPerdus = 0
- if (targetVigueur) {
- nbEtatPerdus = Math.floor(roll.total / targetVigueur)
- }
- //console.log(roll)
- let rollData = {
- arme: arme,
- finalResult: roll.total,
- formula: roll.formula,
- alias: this.name,
- actorImg: this.img,
- actorId: this.id,
- defenderTokenId: rollDataInput?.defenderTokenId,
- actionImg: arme.img,
- targetVigueur: targetVigueur,
- nbEtatPerdus: nbEtatPerdus
- }
- MournbladeCYD2Utility.createChatWithRollMode(rollData.alias, {
- content: await renderTemplate(`systems/fvtt-mournblade-cyd2/templates/chat-degats-result.html`, rollData)
- })
-
- if (rollDataInput?.defenderTokenId && nbEtatPerdus) {
- MournbladeCYD2Utility.applyCombativite(rollDataInput, nbEtatPerdus)
- }
-
- }
-}
diff --git a/.history/modules/mournblade-cyd2-actor_20251026083444.js b/.history/modules/mournblade-cyd2-actor_20251026083444.js
deleted file mode 100644
index 7d1b577..0000000
--- a/.history/modules/mournblade-cyd2-actor_20251026083444.js
+++ /dev/null
@@ -1,893 +0,0 @@
-/* -------------------------------------------- */
-import { MournbladeCYD2Utility } from "./mournblade-cyd2-utility.js";
-import { MournbladeCYD2RollDialog } from "./mournblade-cyd2-roll-dialog.js";
-
-/* -------------------------------------------- */
-const __degatsBonus = [-2, -2, -1, -1, 0, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 8, 8, 9, 9, 10, 10]
-const __vitesseBonus = [-2, -2, -1, -1, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8]
-
-/* -------------------------------------------- */
-/**
- * Extend the base Actor entity by defining a custom roll data structure which is ideal for the Simple system.
- * @extends {Actor}
- */
-export class MournbladeCYD2Actor extends Actor {
-
- /* -------------------------------------------- */
- /**
- * Override the create() function to provide additional SoS functionality.
- *
- * This overrided create() function adds initial items
- * Namely: Basic skills, money,
- *
- * @param {Object} data Barebones actor data which this function adds onto.
- * @param {Object} options (Unused) Additional options which customize the creation workflow.
- *
- */
-
- static async create(data, options) {
-
- // Case of compendium global import
- if (data instanceof Array) {
- return super.create(data, options);
- }
- // If the created actor has items (only applicable to duplicated actors) bypass the new actor creation logic
- if (data.items) {
- let actor = super.create(data, options);
- return actor;
- }
-
- if (data.type == 'personnage') {
- const skills = await MournbladeCYD2Utility.loadCompendium("fvtt-mournblade-cyd2.skills")
- data.items = skills.map(i => i.toObject())
- }
- if (data.type == 'creature') {
- const skills = await MournbladeCYD2Utility.loadCompendium("fvtt-mournblade-cyd2.skills-creatures")
- data.items = skills.map(i => i.toObject())
- data.items.push({ name: "Arme naturelle 1", type: 'arme', img: "systems/fvtt-mournblade-cyd2/assets/icons/melee.webp", system: { typearme: "contact", bonusmaniementoff: 0, seuildefense: 0, degats: "0" } })
- data.items.push({ name: "Arme naturelle 2", type: 'arme', img: "systems/fvtt-mournblade-cyd2/assets/icons/melee.webp", system: { typearme: "contact", bonusmaniementoff: 0, seuildefense: 0, degats: "0" } })
- }
-
- return super.create(data, options);
- }
-
- /* -------------------------------------------- */
- getBonusDefenseFromTalents() {
- let talents = this.items.filter(item => item.type == "talent" && item.system.isautomated)
- let bonus = 0
- for (let talent of talents) {
- for (let auto of talent.system.automations) {
- if (auto.eventtype == "bonus-permanent" && auto.bonusname == "bonus-defensif") {
- bonus += Number(auto.bonus || 0)
- }
- }
- }
- return bonus
- }
-
- /* -------------------------------------------- */
- prepareArme(arme) {
- if (this.type == "cellule") {
- return arme
- }
-
- arme = foundry.utils.duplicate(arme)
- let combat = this.getCombatValues()
- if (arme.system.typearme == "contact" || arme.system.typearme == "contactjet") {
- let bonusDefense = this.getBonusDefenseFromTalents()
- arme.system.competence = foundry.utils.duplicate(this.items.find(item => item.type == "competence" && item.name.toLowerCase() == "mêlée"))
- arme.system.attrKey = "pui"
- arme.system.totalDegats = arme.system.degats + "+" + combat.bonusDegatsTotal
- arme.system.totalOffensif = this.system.attributs.pui.value + arme.system.competence.system.niveau + arme.system.bonusmaniementoff + (this.system.combat.monte ? 3 : 0)
- arme.system.totalDefensif = combat.defenseTotal + arme.system.competence.system.niveau + arme.system.seuildefense + bonusDefense + (this.system.combat.monte ? 3 : 0)
- console.log("Arme", arme.system.totalDefensif, combat, arme.system.competence.system.niveau, arme.system.seuildefense, bonusDefense)
- arme.system.isdefense = true
- arme.system.isMelee = true
- arme.system.isDistance = false
- }
- if (arme.system.typearme == "jet" || arme.system.typearme == "tir") {
- arme.system.competence = foundry.utils.duplicate(this.items.find(item => item.type == "competence" && item.name.toLowerCase() == "armes à distance"))
- arme.system.attrKey = "adr"
- arme.system.totalOffensif = this.system.attributs.adr.value + arme.system.competence.system.niveau + arme.system.bonusmaniementoff
- arme.system.totalDegats = arme.system.degats
- arme.system.isMelee = false
- arme.system.isDistance = true
- if (arme.system.isdefense) {
- arme.system.totalDefensif = combat.defenseTotal + arme.system.competence.system.niveau + arme.system.seuildefense
- }
- }
- return arme
- }
-
- /* -------------------------------------------- */
- getItemSorted(types) {
- let items = this.items.filter(item => types.includes(item.type)) || []
- MournbladeCYD2Utility.sortArrayObjectsByName(items)
- return items
- }
- getWeapons() {
- let armes = []
- for (let arme of this.items) {
- if (arme.type == "arme") {
- armes.push(this.prepareArme(arme))
- }
- }
- MournbladeCYD2Utility.sortArrayObjectsByName(armes)
- return armes
- }
- getMonnaies() {
- return this.getItemSorted(["monnaie"])
- }
- getEquipments() {
- return this.getItemSorted(["equipement"])
- }
- getArtefacts() {
- return this.getItemSorted(["artefact"])
- }
- getArmors() {
- return this.getItemSorted(["protection"])
- }
- getHistoriques() {
- return this.getItemSorted(["historique"])
- }
- getProfils() {
- return this.getItemSorted(["profil"])
- }
- getTalents() {
- return this.getItemSorted(["talent"])
- }
- getRessources() {
- return this.getItemSorted(["ressource"])
- }
- getContacts() {
- return this.getItemSorted(["contact"])
- }
- getMutations() {
- return this.getItemSorted(["mutation"])
- }
- getDons() {
- return this.getItemSorted(["don"])
- }
- getPactes() {
- return this.getItemSorted(["pacte"])
- }
- getTendances() {
- return this.getItemSorted(["tendance"])
- }
- getRunes() {
- return this.getItemSorted(["rune"])
- }
- getTraitsChaotiques() {
- return this.getItemSorted(["traitchaotique"])
- }
- getTraitsEspeces() {
- return this.getItemSorted(["traitespece"])
- }
-
- /* -------------------------------------------- */
- getAspect() {
- return (this.system.balance.loi > this.system.balance.chaos) ? this.system.balance.loi : this.system.balance.chaos
- }
- getMarge() {
- return Math.abs(this.system.balance.loi - this.system.balance.chaos)
- }
- getAlignement() {
- return (this.system.balance.loi > this.system.balance.chaos) ? "loyal" : "chaotique"
- }
-
- /* -------------------------------------------- */
- getSkills() {
- let comp = []
- for (let item of this.items) {
- item = foundry.utils.duplicate(item)
- if (item.type == "competence") {
- item.system.attribut1total = item.system.niveau + (this.system.attributs[item.system.attribut1]?.value || 0)
- item.system.attribut2total = item.system.niveau + (this.system.attributs[item.system.attribut2]?.value || 0)
- item.system.attribut3total = item.system.niveau + (this.system.attributs[item.system.attribut3]?.value || 0)
- if (item.system.niveau == 0) {
- item.system.attribut1total -= 3
- item.system.attribut2total -= 3
- item.system.attribut3total -= 3
- }
- item.system.attribut1label = this.system.attributs[item.system.attribut1]?.label || ""
- item.system.attribut2label = this.system.attributs[item.system.attribut2]?.label || ""
- item.system.attribut3label = this.system.attributs[item.system.attribut3]?.label || ""
- comp.push(item)
- }
- }
- MournbladeCYD2Utility.sortArrayObjectsByName(comp)
- return comp
- }
-
- /* ----------------------- --------------------- */
- addMember(actorId) {
- let members = foundry.utils.duplicate(this.system.members)
- members.push({ id: actorId })
- this.update({ 'system.members': members })
- }
- async removeMember(actorId) {
- let members = this.system.members.filter(it => it.id != actorId)
- this.update({ 'system.members': members })
- }
-
- /* -------------------------------------------- */
- getDefenseBase() {
- return Math.max(this.system.attributs.tre.value, this.system.attributs.adr.value)
- }
-
- /* -------------------------------------------- */
- getVitesseBase() {
- return 5 + __vitesseBonus[this.system.attributs.adr.value]
- }
- /* -------------------------------------------- */
- getProtection() {
- let equipProtection = 0
- for (let armor of this.items) {
- if (armor.type == "protection" && armor.system.equipped) {
- equipProtection += Number(armor.system.protection)
- }
- }
- if (equipProtection < 4) {
- return 4 + equipProtection // Cas des boucliers + sans armure
- }
- return equipProtection // Uniquement la protection des armures + boucliers
- }
-
- /* -------------------------------------------- */
- getCombatValues() {
- if (this.type == "cellule") {
- return {
- initBase: 0,
- initTotal: 0,
- bonusDegats: 0,
- bonusDegatsTotal: 0,
- vitesseBase: 0,
- vitesseTotal: 0,
- defenseBase: 0,
- protection: 0,
- defenseTotal: 0
- }
- }
-
- let combat = {
- initBase: this.system.attributs.adr.value,
- initTotal: this.system.attributs.adr.value + this.system.combat.initbonus,
- bonusDegats: this.getBonusDegats(),
- bonusDegatsTotal: this.getBonusDegats() + this.system.combat.bonusdegats,
- vitesseBase: this.getVitesseBase(),
- vitesseTotal: this.getVitesseBase() + this.system.combat.vitessebonus,
- defenseBase: this.getDefenseBase(),
- protection: this.getProtection(),
- defenseTotal: this.getDefenseBase() + this.system.combat.defensebonus + this.getProtection() - this.getTotalAdversite() + (this.system.combat.defensetotale ? 3 : 0)
- }
- return combat
- }
-
- /* -------------------------------------------- */
- prepareBaseData() {
- }
-
- /* -------------------------------------------- */
- async prepareData() {
- super.prepareData();
- }
-
- /* -------------------------------------------- */
- prepareDerivedData() {
-
- if (this.type == 'personnage') {
- let talentBonus = this.getVigueurBonus()
- let vigueur = Math.floor((this.system.attributs.pui.value + this.system.attributs.tre.value) / 2) + talentBonus + this.system.sante.vigueurmodifier
- if (vigueur != this.system.sante.vigueur) {
- this.update({ 'system.sante.vigueur': vigueur })
- }
-
- let seuilPouvoirBonus = this.getSeuilPouvoirBonus()
- let seuilPouvoir = Math.floor((this.system.attributs.tre.value + this.system.attributs.cla.value) / 2) + seuilPouvoirBonus + this.system.ame.seuilpouvoirmodifier
- if (seuilPouvoir != this.system.ame.seuilpouvoir) {
- this.update({ 'system.ame.seuilpouvoir': seuilPouvoir })
- }
- }
- super.prepareDerivedData()
- }
-
- /* -------------------------------------------- */
- _preUpdate(changed, options, user) {
- if (changed?.system?.sante?.etat && changed?.system?.sante?.etat != this.system.sante.etat) {
- setTimeout(() => {
- this.processCombativite(changed.system.sante)
- }, 800)
- }
- if (changed?.system?.ame?.etat && changed?.system?.ame?.etat != this.system.ame.etat) {
- setTimeout(() => {
- this.processAme(changed.system.ame)
- }, 800)
- }
- super._preUpdate(changed, options, user);
- }
-
- /* -------------------------------------------- */
- _onUpdate(data, options, user) {
- super._onUpdate(data, options, user);
- }
- /* -------------------------------------------- */
- getItemById(id) {
- let item = this.items.find(item => item.id == id);
- if (item) {
- item = foundry.utils.duplicate(item)
- }
- return item;
- }
-
- /* -------------------------------------------- */
- async equipItem(itemId) {
- let item = this.items.find(item => item.id == itemId)
- if (item && item.system) {
- let update = { _id: item.id, "system.equipped": !item.system.equipped }
- await this.updateEmbeddedDocuments('Item', [update]); // Updates one EmbeddedEntity
- }
- }
-
- /* -------------------------------------------- */
- editItemField(itemId, itemType, itemField, dataType, value) {
- let item = this.items.find(item => item.id == itemId)
- if (item) {
- console.log("Item ", item, itemField, dataType, value)
- if (dataType.toLowerCase() == "number") {
- value = Number(value)
- } else {
- value = String(value)
- }
- let update = { _id: item.id, [`system.${itemField}`]: value };
- this.updateEmbeddedDocuments("Item", [update])
- }
- }
-
- /* -------------------------------------------- */
- checkAttribut(attribut, minLevel) {
- let attr = this.system.attributs.find(at => at.labelnorm == attribut.toLowerCase())
- if (attr && attr.value >= minLevel) {
- return { isValid: true, attr: foundry.utils.duplicate(attr) }
- }
- return { isValid: false }
- }
- /* -------------------------------------------- */
- checkAttributOrCompetenceLevel(compName, minLevel) {
- let comp = this.items.find(i => i.type == "competence" && i.name.toLowerCase() == compName.toLowerCase() && i.system.niveau >= minLevel)
- if (comp) {
- return { isValid: true, item: foundry.utils.duplicate(comp) }
- } else {
- for (let attrKey in this.system.attributs) {
- if (this.system.attributs[attrKey].label.toLowerCase() == compName.toLowerCase() && this.system.attributs[attrKey].value >= minLevel) {
- return { isValid: true, item: foundry.utils.duplicate(this.system.attributs[attrKey]) }
- }
- }
- }
- return { isValid: false, warningMessage: `Prérequis insuffisant : la compétence/attribut ${compName} doit être de niveau ${minLevel} au minimum` }
- }
- /* -------------------------------------------- */
- addCompetenceBonus(compName, bonus, baCost) {
- let comp = this.items.find(i => i.type == "competence" && i.name.toLowerCase() == compName.toLowerCase())
- if (comp) {
- comp = foundry.utils.duplicate(comp)
- comp.system.bonus = bonus
- comp.system.baCost = baCost
- return { isValid: true, item: comp }
- }
- return { isValid: false, warningMessage: `Compétence ${compName} non trouvée` }
- }
- /* -------------------------------------------- */
- checkIfCompetence(compName) {
- let comp = this.items.find(i => i.type == "competence" && i.name.toLowerCase() == compName.toLowerCase())
- if (comp) {
- return { isValid: true, item: comp }
- }
- return { isValid: false }
- }
- /* -------------------------------------------- */
- getVigueur() {
- return this.system.sante.vigueur
- }
-
- /* -------------------------------------------- */
- getVigueurBonus() {
- let talents = this.items.filter(item => item.type == "talent" && item.system.isautomated)
- let bonus = 0
- for (let talent of talents) {
- for (let auto of talent.system.automations) {
- if (auto.eventtype == "bonus-permanent" && auto.bonusname == "vigueur") {
- bonus += Number(auto.bonus || 0)
- }
- }
- }
- return bonus
- }
-
- /* -------------------------------------------- */
- getSeuilPouvoir() {
- return this.system.ame.seuilpouvoir
- }
-
- /* -------------------------------------------- */
- getSeuilPouvoirBonus() {
- let talents = this.items.filter(item => item.type == "talent" && item.system.isautomated)
- let bonus = 0
- for (let talent of talents) {
- for (let auto of talent.system.automations) {
- if (auto.eventtype == "bonus-permanent" && auto.bonusname == "seuilpouvoir") {
- bonus += Number(auto.bonus || 0)
- }
- }
- }
- return bonus
- }
-
- /* -------------------------------------------- */
- getAmeMax() {
- return Math.min(this.system.ame.max || this.system.ame.nbame, this.system.ame.nbame)
- }
-
- /* -------------------------------------------- */
- getBonneAventure() {
- return this.system.bonneaventure.actuelle
- }
- /* -------------------------------------------- */
- checkBonneAventure(cost) {
- return (this.system.bonneaventure.actuelle >= cost)
- }
- /* -------------------------------------------- */
- changeBonneAventure(value) {
- let newBA = this.system.bonneaventure.actuelle
- newBA += value
- this.update({ 'system.bonneaventure.actuelle': newBA })
- }
-
- /* -------------------------------------------- */
- getEclat() {
- return this.system.eclat.value
- }
-
- /* -------------------------------------------- */
- changeEclat(value) {
- let newE = this.system.eclat.value
- newE += value
- this.update({ 'system.eclat.value': newE })
- }
-
- /* -------------------------------------------- */
- compareName(a, b) {
- if (a.name < b.name) {
- return -1;
- }
- if (a.name > b.name) {
- return 1;
- }
- return 0;
- }
-
- /* -------------------------------------------- */
- getAttribute(attrKey) {
- return this.system.attributes[attrKey]
- }
-
- /* -------------------------------------------- */
- getBonusDegats() {
- return 0;
- }
-
- /* -------------------------------------------- */
- changeEtatCombativite(value) {
- if (value === "vaincu") {
- value = 200
- }
- let sante = foundry.utils.duplicate(this.system.sante)
- sante.etat += Number(value)
- sante.etat = Math.max(sante.etat, 0)
- sante.etat = Math.min(sante.etat, this.system.sante.nbcombativite)
- this.update({ 'system.sante': sante })
- if (sante.etat == this.system.sante.nbcombativite) {
- ChatMessage.create({ content: `${this.name} est vaincu !` })
- }
- // Duplicated ! this.processCombativite(sante)
- }
-
- /* -------------------------------------------- */
- changeEtatAme(value) {
- if (value === "brise") {
- value = 200
- }
- let ame = foundry.utils.duplicate(this.system.ame)
- ame.etat += Number(value)
- ame.etat = Math.max(ame.etat, 0)
- // L'état ne peut pas dépasser le maximum actuel d'âme
- let maxAme = Math.min(this.system.ame.max || this.system.ame.nbame, this.system.ame.nbame)
- ame.etat = Math.min(ame.etat, maxAme)
- this.update({ 'system.ame': ame })
- if (ame.etat >= maxAme) {
- ChatMessage.create({ content: `${this.name} est brisé !` })
- }
- }
-
- /* -------------------------------------------- */
- processCombativite(sante) {
- sante = sante || foundry.utils.duplicate(this.system.sante)
- // Gestion des états affaibli et très affaibli
- if (sante.etat == this.system.sante.nbcombativite - 2 || sante.etat == this.system.sante.nbcombativite - 1) {
- if (sante.etat == this.system.sante.nbcombativite - 2 && this.items.find(item => item.type == "talent" && item.name.toLowerCase() == "encaissement")) {
- ChatMessage.create({ content: `${this.name} ne subit pas les 2 adversités rouge grâce à Encaissement. Pensez à les ajouter à la fin de la scène !` })
- } else if (sante.etat == this.system.sante.nbcombativite - 1 && this.items.find(item => item.type == "talent" && item.name.toLowerCase().includes("vaillant"))) {
- ChatMessage.create({ content: `${this.name} ne subit pas les 2 adversités rouge grâce à Vaillant. Pensez à les ajouter à la fin de la scène !` })
- } else {
- ChatMessage.create({ content: `${this.name} subit 2 adversités rouge !` })
- this.incDecAdversite("rouge", 2)
- }
- }
- }
-
- /* -------------------------------------------- */
- processAme(ame) {
- ame = ame || foundry.utils.duplicate(this.system.ame)
- let maxAme = Math.min(this.system.ame.max || this.system.ame.nbame, this.system.ame.nbame)
- // Gestion des états Traumatisé, Très Traumatisé et Brisé en fonction du maximum actuel
- // Les seuils sont calculés par rapport au maximum d'âme actuel
- if (maxAme >= 3 && ame.etat >= maxAme - 2) {
- if (ame.etat == maxAme - 2) {
- ChatMessage.create({ content: `${this.name} est Traumatisé !` })
- } else if (ame.etat == maxAme - 1) {
- ChatMessage.create({ content: `${this.name} est Très Traumatisé !` })
- } else if (ame.etat >= maxAme) {
- ChatMessage.create({ content: `${this.name} est Brisé !` })
- }
- } else if (ame.etat >= maxAme) {
- ChatMessage.create({ content: `${this.name} est Brisé !` })
- }
- }
-
- /* -------------------------------------------- */
- async equipGear(equipmentId) {
- let item = this.items.find(item => item.id == equipmentId);
- if (item?.system?.data) {
- let update = { _id: item.id, "system.equipped": !item.system.equipped };
- await this.updateEmbeddedDocuments('Item', [update]); // Updates one EmbeddedEntity
- }
- }
-
- /* -------------------------------------------- */
- getSubActors() {
- let subActors = [];
- for (let id of this.system.subactors) {
- subActors.push(foundry.utils.duplicate(game.actors.get(id)));
- }
- return subActors;
- }
- /* -------------------------------------------- */
- async addSubActor(subActorId) {
- let subActors = foundry.utils.duplicate(this.system.subactors);
- subActors.push(subActorId);
- await this.update({ 'system.subactors': subActors });
- }
- /* -------------------------------------------- */
- async delSubActor(subActorId) {
- let newArray = [];
- for (let id of this.system.subactors) {
- if (id != subActorId) {
- newArray.push(id);
- }
- }
- await this.update({ 'system.subactors': newArray });
- }
-
- /* -------------------------------------------- */
- getTotalAdversite() {
- return this.system.adversite.bleue + this.system.adversite.rouge + this.system.adversite.noire
- }
-
- /* -------------------------------------------- */
- async incDecAdversite(adv, incDec = 0) {
- let adversite = foundry.utils.duplicate(this.system.adversite)
- adversite[adv] += Number(incDec)
- adversite[adv] = Math.max(adversite[adv], 0)
- adversite[adv] = Math.min(adversite[adv], 20)
- this.update({ 'system.adversite': adversite })
- }
- /* -------------------------------------------- */
- async incDecQuantity(objetId, incDec = 0) {
- let objetQ = this.items.get(objetId)
- if (objetQ) {
- let newQ = objetQ.system.quantite + incDec
- newQ = Math.max(newQ, 0)
- await this.updateEmbeddedDocuments('Item', [{ _id: objetQ.id, 'system.quantite': newQ }]); // pdates one EmbeddedEntity
- }
- }
-
- /* -------------------------------------------- */
- computeRichesse() {
- let valueSC = 0
- for (let monnaie of this.items) {
- if (monnaie.type == "monnaie") {
- valueSC += Number(monnaie.system.prixsc) * Number(monnaie.system.quantite)
- }
- }
- return MournbladeCYD2Utility.computeMonnaieDetails(valueSC)
- }
-
- /* -------------------------------------------- */
- computeValeurEquipement() {
- let valueSC = 0
- for (let equip of this.items) {
- if (equip.type == "equipement" || equip.type == "arme" || equip.type == "protection") {
- valueSC += Number(equip.system.prixsc) * Number(equip.system.quantite ?? 1)
- valueSC += (Number(equip.system.prixca) * Number(equip.system.quantite ?? 1)) * 20
- valueSC += (Number(equip.system.prixpo) * Number(equip.system.quantite ?? 1)) * 400
- }
- }
- return MournbladeCYD2Utility.computeMonnaieDetails(valueSC)
- }
-
- /* -------------------------------------------- */
- getCompetence(compId) {
- return this.items.get(compId)
- }
-
- /* -------------------------------------------- */
- async setPredilectionUsed(compId, predIdx) {
- let comp = this.items.get(compId)
- let pred = foundry.utils.duplicate(comp.system.predilections)
- pred[predIdx].used = true
- await this.updateEmbeddedDocuments('Item', [{ _id: compId, 'system.predilections': pred }])
- }
-
- /* -------------------------------------------- */
- getInitiativeScore() {
- let init = this.getFlag("world", "last-initiative")
- return init || -1
- }
-
- /* -------------------------------------------- */
- getBestAttackValue() {
- let attackList = this.items.filter(item => (item.type == "arme" || item.type == "talent") && item.system.equipped)
- let maxOff = 0
- let bestArme
- for (let arme of attackList) {
- if (arme.type == "arme") {
- arme = this.prepareArme(arme)
- }
- if (arme.system.totalOffensif > maxOff) {
- maxOff = arme.system.totalOffensif
- bestArme = foundry.utils.duplicate(arme)
- }
- }
- return bestArme
- }
-
- /* -------------------------------------------- */
- getBestDefenseValue() {
- let defenseList = this.items.filter(item => (item.type == "arme") && item.system.equipped)
- let maxDef = 0
- let bestArme
- for (let arme of defenseList) {
- if (arme.type == "arme") {
- arme = this.prepareArme(arme)
- }
- if (arme.system.totalDefensif > maxDef) {
- maxDef = arme.system.totalDefensif
- bestArme = foundry.utils.duplicate(arme)
- }
- }
- return bestArme
- }
-
- /* -------------------------------------------- */
- searchRelevantTalents(competence) {
- let talents = []
-
- for (let talent of this.items) {
- if (talent.type == "talent" && talent.system.isautomated && talent.system.automations.length > 0) {
- for (let auto of talent.system.automations) {
- if (auto.eventtype === "prepare-roll") {
- if (auto.competence.toLowerCase() == competence.name.toLowerCase()) {
- talent = foundry.utils.duplicate(talent)
- talent.system.bonus = auto.bonus
- talent.system.baCost = auto.baCost
- talents.push(talent)
- }
- }
- }
- }
- }
- return talents
- }
-
- /* -------------------------------------------- */
- buildListeAdversites() {
- return []
- }
-
- /* -------------------------------------------- */
- getCommonRollData(attrKey = undefined, compId = undefined, compName = undefined) {
- let rollData = MournbladeCYD2Utility.getBasicRollData()
- rollData.alias = this.name
- rollData.actorImg = this.img
- rollData.actorId = this.id
- rollData.tokenId = this.token?.id
- rollData.img = this.img
- rollData.attributs = MournbladeCYD2Utility.getAttributs()
- rollData.maitriseId = "none"
- rollData.nbEclat = this.system.eclat.value
- rollData.nbBA = this.system.bonneaventure.actuelle
- rollData.nbAdversites = this.getTotalAdversite()
- rollData.talents = []
- rollData.attrKey2 = "none"
- rollData.coupDevastateur = this.items.find(it => it.type == "talent" && it.name.toLowerCase() == "coup dévastateur" && !it.system.used)
- rollData.hasAmbidextre = this.items.find(it => it.type == "talent" && it.name.toLowerCase() == "ambidextre")
- rollData.hasFeinte = this.system.bonneaventure.actuelle > 0 && this.items.find(it => it.type == "talent" && it.name.toLowerCase() == "feinte")
- rollData.isMonte = this.system.combat.monte
- rollData.config = game.system.mournbladecyd2.config
-
- if (attrKey) {
- rollData.attrKey = attrKey
- if (attrKey != "tochoose") {
- rollData.actionImg = "systems/fvtt-mournblade-cyd2/assets/icons/" + this.system.attributs[attrKey].labelnorm + ".webp"
- rollData.attr = foundry.utils.duplicate(this.system.attributs[attrKey])
- }
- }
- if (compId) {
- rollData.competence = foundry.utils.duplicate(this.items.get(compId) || {})
- let maitrises = [{ key: "none", label: "Aucune" }]
- rollData.competence.system.predilections.forEach(function (item) {
- if (item.maitrise) {
- maitrises.push({ key: item.id, label: item.name });
- }
- })
- rollData.maitrises = maitrises // rollData.competence.system.predilections.filter(p => p.maitrise)
- rollData.actionImg = rollData.competence?.img
- rollData.talents = this.searchRelevantTalents(rollData.competence)
- }
- if (compName) {
- rollData.competence = foundry.utils.duplicate(this.items.find(item => item.name.toLowerCase() == compName.toLowerCase()) || {})
- rollData.actionImg = rollData.competence?.img
- }
- return rollData
- }
-
- /* -------------------------------------------- */
- async rollAttribut(attrKey, isInit = false) {
- let rollData = this.getCommonRollData(attrKey)
- rollData.multiplier = (isInit) ? 1 : 2
- rollData.isInit = isInit
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
-
- /* -------------------------------------------- */
- async rollCompetence(attrKey, compId) {
- let rollData = this.getCommonRollData(attrKey, compId)
- rollData.multiplier = 1 // Attr multiplier, always 1 in competence mode
- console.log("RollDatra", rollData)
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
-
- /* -------------------------------------------- */
- async rollArmeOffensif(armeId) {
- let arme = this.items.get(armeId)
- if (arme.type == "arme") {
- arme = this.prepareArme(arme)
- }
- let rollData = this.getCommonRollData(arme.system.attrKey, arme.system.competence._id)
- rollData.arme = arme
- MournbladeCYD2Utility.updateWithTarget(rollData)
- console.log("ARME!", rollData)
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
- /* -------------------------------------------- */
- async rollAssommer() {
- let rollData = this.getCommonRollData("pui", undefined, "Filouterie")
- rollData.assomer = true
- rollData.conditionsCommunes = true
- MournbladeCYD2Utility.updateWithTarget(rollData)
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
- /* -------------------------------------------- */
- async rollCoupBas() {
- let rollData = this.getCommonRollData("pui", undefined, "Mêlée")
- rollData.coupBas = true
- rollData.conditionsCommunes = true
- MournbladeCYD2Utility.updateWithTarget(rollData)
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
- /* -------------------------------------------- */
- async rollImmobiliser() {
- let rollData = this.getCommonRollData("pui", undefined, "Mêlée")
- rollData.immobiliser = true
- rollData.conditionsCommunes = true
- rollData.cibleconsciente = true
- MournbladeCYD2Utility.updateWithTarget(rollData)
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
- /* -------------------------------------------- */
- async rollRepousser() {
- let rollData = this.getCommonRollData("pui", undefined, "Mêlée")
- rollData.repousser = true
- rollData.conditionsCommunes = true
- rollData.cibleconsciente = true
- MournbladeCYD2Utility.updateWithTarget(rollData)
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
- /* -------------------------------------------- */
- async rollDesengager() {
- let rollData = this.getCommonRollData("adr", undefined, "Mouvements")
- rollData.desengager = true
- rollData.conditionsCommunes = true
- MournbladeCYD2Utility.updateWithTarget(rollData)
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
-
- /* -------------------------------------------- */
- async rollArmeDegats(armeId, targetVigueur = undefined, rollDataInput = undefined) {
- let arme = this.items.get(armeId)
- if (arme.type == "arme") {
- arme = this.prepareArme(arme)
- }
- console.log("DEGATS", arme, targetVigueur, rollDataInput)
- let roll
- let bonus = 0
- let bonus2 = 0
-
- if (rollDataInput?.applyCoupDevastateur) {
- bonus2 = Math.floor(this.system.attributs.pui.value / 2)
- let talent = this.items.find(item => item.type == "talent" && item.name.toLowerCase() == "coup dévastateur")
- this.updateEmbeddedDocuments('Item', [{ _id: talent.id, 'system.used': true }])
- }
-
- if (rollDataInput?.isHeroique) {
- if (rollDataInput?.attaqueCharge) {
- bonus = 5
- }
- if (rollDataInput?.chargeCavalerie) {
- bonus = 6
- }
- roll = await new Roll("2d10rr10+" + arme.system.totalDegats + "+" + bonus + "+" + bonus2).roll()
- } else {
- if (rollDataInput?.attaqueCharge) {
- bonus = 3
- }
- if (rollDataInput?.chargeCavalerie) {
- bonus = 4
- }
- roll = await new Roll("1d10+" + arme.system.totalDegats + "+" + bonus + "+" + bonus2).roll()
- }
- await MournbladeCYD2Utility.showDiceSoNice(roll, game.settings.get("core", "rollMode"));
- let nbEtatPerdus = 0
- if (targetVigueur) {
- nbEtatPerdus = Math.floor(roll.total / targetVigueur)
- }
- //console.log(roll)
- let rollData = {
- arme: arme,
- finalResult: roll.total,
- formula: roll.formula,
- alias: this.name,
- actorImg: this.img,
- actorId: this.id,
- defenderTokenId: rollDataInput?.defenderTokenId,
- actionImg: arme.img,
- targetVigueur: targetVigueur,
- nbEtatPerdus: nbEtatPerdus
- }
- MournbladeCYD2Utility.createChatWithRollMode(rollData.alias, {
- content: await renderTemplate(`systems/fvtt-mournblade-cyd2/templates/chat-degats-result.html`, rollData)
- })
-
- if (rollDataInput?.defenderTokenId && nbEtatPerdus) {
- MournbladeCYD2Utility.applyCombativite(rollDataInput, nbEtatPerdus)
- }
-
- }
-}
diff --git a/.history/modules/mournblade-cyd2-actor_20251026083447.js b/.history/modules/mournblade-cyd2-actor_20251026083447.js
deleted file mode 100644
index 249612f..0000000
--- a/.history/modules/mournblade-cyd2-actor_20251026083447.js
+++ /dev/null
@@ -1,893 +0,0 @@
-/* -------------------------------------------- */
-import { MournbladeCYD2Utility } from "./mournblade-cyd2-utility.js";
-import { MournbladeCYD2RollDialog } from "./mournblade-cyd2-roll-dialog.js";
-
-/* -------------------------------------------- */
-const __degatsBonus = [-2, -2, -1, -1, 0, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 8, 8, 9, 9, 10, 10]
-const __vitesseBonus = [-2, -2, -1, -1, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8]
-
-/* -------------------------------------------- */
-/**
- * Extend the base Actor entity by defining a custom roll data structure which is ideal for the Simple system.
- * @extends {Actor}
- */
-export class MournbladeCYD2Actor extends Actor {
-
- /* -------------------------------------------- */
- /**
- * Override the create() function to provide additional SoS functionality.
- *
- * This overrided create() function adds initial items
- * Namely: Basic skills, money,
- *
- * @param {Object} data Barebones actor data which this function adds onto.
- * @param {Object} options (Unused) Additional options which customize the creation workflow.
- *
- */
-
- static async create(data, options) {
-
- // Case of compendium global import
- if (data instanceof Array) {
- return super.create(data, options);
- }
- // If the created actor has items (only applicable to duplicated actors) bypass the new actor creation logic
- if (data.items) {
- let actor = super.create(data, options);
- return actor;
- }
-
- if (data.type == 'personnage') {
- const skills = await MournbladeCYD2Utility.loadCompendium("fvtt-mournblade-cyd2.skills")
- data.items = skills.map(i => i.toObject())
- }
- if (data.type == 'creature') {
- const skills = await MournbladeCYD2Utility.loadCompendium("fvtt-mournblade-cyd2.skills-creatures")
- data.items = skills.map(i => i.toObject())
- data.items.push({ name: "Arme naturelle 1", type: 'arme', img: "systems/fvtt-mournblade-cyd2/assets/icons/melee.webp", system: { typearme: "contact", bonusmaniementoff: 0, seuildefense: 0, degats: "0" } })
- data.items.push({ name: "Arme naturelle 2", type: 'arme', img: "systems/fvtt-mournblade-cyd2/assets/icons/melee.webp", system: { typearme: "contact", bonusmaniementoff: 0, seuildefense: 0, degats: "0" } })
- }
-
- return super.create(data, options);
- }
-
- /* -------------------------------------------- */
- getBonusDefenseFromTalents() {
- let talents = this.items.filter(item => item.type == "talent" && item.system.isautomated)
- let bonus = 0
- for (let talent of talents) {
- for (let auto of talent.system.automations) {
- if (auto.eventtype == "bonus-permanent" && auto.bonusname == "bonus-defensif") {
- bonus += Number(auto.bonus || 0)
- }
- }
- }
- return bonus
- }
-
- /* -------------------------------------------- */
- prepareArme(arme) {
- if (this.type == "cellule") {
- return arme
- }
-
- arme = foundry.utils.duplicate(arme)
- let combat = this.getCombatValues()
- if (arme.system.typearme == "contact" || arme.system.typearme == "contactjet") {
- let bonusDefense = this.getBonusDefenseFromTalents()
- arme.system.competence = foundry.utils.duplicate(this.items.find(item => item.type == "competence" && item.name.toLowerCase() == "mêlée"))
- arme.system.attrKey = "pui"
- arme.system.totalDegats = arme.system.degats + "+" + combat.bonusDegatsTotal
- arme.system.totalOffensif = this.system.attributs.pui.value + arme.system.competence.system.niveau + arme.system.bonusmaniementoff + (this.system.combat.monte ? 3 : 0)
- arme.system.totalDefensif = combat.defenseTotal + arme.system.competence.system.niveau + arme.system.seuildefense + bonusDefense + (this.system.combat.monte ? 3 : 0)
- console.log("Arme", arme.system.totalDefensif, combat, arme.system.competence.system.niveau, arme.system.seuildefense, bonusDefense)
- arme.system.isdefense = true
- arme.system.isMelee = true
- arme.system.isDistance = false
- }
- if (arme.system.typearme == "jet" || arme.system.typearme == "tir") {
- arme.system.competence = foundry.utils.duplicate(this.items.find(item => item.type == "competence" && item.name.toLowerCase() == "armes à distance"))
- arme.system.attrKey = "adr"
- arme.system.totalOffensif = this.system.attributs.adr.value + arme.system.competence.system.niveau + arme.system.bonusmaniementoff
- arme.system.totalDegats = arme.system.degats
- arme.system.isMelee = false
- arme.system.isDistance = true
- if (arme.system.isdefense) {
- arme.system.totalDefensif = combat.defenseTotal + arme.system.competence.system.niveau + arme.system.seuildefense
- }
- }
- return arme
- }
-
- /* -------------------------------------------- */
- getItemSorted(types) {
- let items = this.items.filter(item => types.includes(item.type)) || []
- MournbladeCYD2Utility.sortArrayObjectsByName(items)
- return items
- }
- getWeapons() {
- let armes = []
- for (let arme of this.items) {
- if (arme.type == "arme") {
- armes.push(this.prepareArme(arme))
- }
- }
- MournbladeCYD2Utility.sortArrayObjectsByName(armes)
- return armes
- }
- getMonnaies() {
- return this.getItemSorted(["monnaie"])
- }
- getEquipments() {
- return this.getItemSorted(["equipement"])
- }
- getArtefacts() {
- return this.getItemSorted(["artefact"])
- }
- getArmors() {
- return this.getItemSorted(["protection"])
- }
- getHistoriques() {
- return this.getItemSorted(["historique"])
- }
- getProfils() {
- return this.getItemSorted(["profil"])
- }
- getTalents() {
- return this.getItemSorted(["talent"])
- }
- getRessources() {
- return this.getItemSorted(["ressource"])
- }
- getContacts() {
- return this.getItemSorted(["contact"])
- }
- getMutations() {
- return this.getItemSorted(["mutation"])
- }
- getDons() {
- return this.getItemSorted(["don"])
- }
- getPactes() {
- return this.getItemSorted(["pacte"])
- }
- getTendances() {
- return this.getItemSorted(["tendance"])
- }
- getRunes() {
- return this.getItemSorted(["rune"])
- }
- getTraitsChaotiques() {
- return this.getItemSorted(["traitchaotique"])
- }
- getTraitsEspeces() {
- return this.getItemSorted(["traitespece"])
- }
-
- /* -------------------------------------------- */
- getAspect() {
- return (this.system.balance.loi > this.system.balance.chaos) ? this.system.balance.loi : this.system.balance.chaos
- }
- getMarge() {
- return Math.abs(this.system.balance.loi - this.system.balance.chaos)
- }
- getAlignement() {
- return (this.system.balance.loi > this.system.balance.chaos) ? "loyal" : "chaotique"
- }
-
- /* -------------------------------------------- */
- getSkills() {
- let comp = []
- for (let item of this.items) {
- item = foundry.utils.duplicate(item)
- if (item.type == "competence") {
- item.system.attribut1total = item.system.niveau + (this.system.attributs[item.system.attribut1]?.value || 0)
- item.system.attribut2total = item.system.niveau + (this.system.attributs[item.system.attribut2]?.value || 0)
- item.system.attribut3total = item.system.niveau + (this.system.attributs[item.system.attribut3]?.value || 0)
- if (item.system.niveau == 0) {
- item.system.attribut1total -= 3
- item.system.attribut2total -= 3
- item.system.attribut3total -= 3
- }
- item.system.attribut1label = this.system.attributs[item.system.attribut1]?.label || ""
- item.system.attribut2label = this.system.attributs[item.system.attribut2]?.label || ""
- item.system.attribut3label = this.system.attributs[item.system.attribut3]?.label || ""
- comp.push(item)
- }
- }
- MournbladeCYD2Utility.sortArrayObjectsByName(comp)
- return comp
- }
-
- /* ----------------------- --------------------- */
- addMember(actorId) {
- let members = foundry.utils.duplicate(this.system.members)
- members.push({ id: actorId })
- this.update({ 'system.members': members })
- }
- async removeMember(actorId) {
- let members = this.system.members.filter(it => it.id != actorId)
- this.update({ 'system.members': members })
- }
-
- /* -------------------------------------------- */
- getDefenseBase() {
- return Math.max(this.system.attributs.tre.value, this.system.attributs.adr.value)
- }
-
- /* -------------------------------------------- */
- getVitesseBase() {
- return 5 + __vitesseBonus[this.system.attributs.adr.value]
- }
- /* -------------------------------------------- */
- getProtection() {
- let equipProtection = 0
- for (let armor of this.items) {
- if (armor.type == "protection" && armor.system.equipped) {
- equipProtection += Number(armor.system.protection)
- }
- }
- if (equipProtection < 4) {
- return 4 + equipProtection // Cas des boucliers + sans armure
- }
- return equipProtection // Uniquement la protection des armures + boucliers
- }
-
- /* -------------------------------------------- */
- getCombatValues() {
- if (this.type == "cellule") {
- return {
- initBase: 0,
- initTotal: 0,
- bonusDegats: 0,
- bonusDegatsTotal: 0,
- vitesseBase: 0,
- vitesseTotal: 0,
- defenseBase: 0,
- protection: 0,
- defenseTotal: 0
- }
- }
-
- let combat = {
- initBase: this.system.attributs.adr.value,
- initTotal: this.system.attributs.adr.value + this.system.combat.initbonus,
- bonusDegats: this.getBonusDegats(),
- bonusDegatsTotal: this.getBonusDegats() + this.system.combat.bonusdegats,
- vitesseBase: this.getVitesseBase(),
- vitesseTotal: this.getVitesseBase() + this.system.combat.vitessebonus,
- defenseBase: this.getDefenseBase(),
- protection: this.getProtection(),
- defenseTotal: this.getDefenseBase() + this.system.combat.defensebonus + this.getProtection() - this.getTotalAdversite() + (this.system.combat.defensetotale ? 3 : 0)
- }
- return combat
- }
-
- /* -------------------------------------------- */
- prepareBaseData() {
- }
-
- /* -------------------------------------------- */
- async prepareData() {
- super.prepareData();
- }
-
- /* -------------------------------------------- */
- prepareDerivedData() {
-
- if (this.type == 'personnage') {
- let talentBonus = this.getVigueurBonus()
- let vigueur = Math.floor((this.system.attributs.pui.value + this.system.attributs.tre.value) / 2) + talentBonus + this.system.sante.vigueurmodifier
- if (vigueur != this.system.sante.vigueur) {
- this.update({ 'system.sante.vigueur': vigueur })
- }
-
- let seuilPouvoirBonus = this.getSeuilPouvoirBonus()
- let seuilPouvoir = Math.floor((this.system.attributs.tre.value + this.system.attributs.cla.value) / 2) + seuilPouvoirBonus + this.system.ame.seuilpouvoirmodifier
- if (seuilPouvoir != this.system.ame.seuilpouvoir) {
- this.update({ 'system.ame.seuilpouvoir': seuilPouvoir })
- }
- }
- super.prepareDerivedData()
- }
-
- /* -------------------------------------------- */
- _preUpdate(changed, options, user) {
- if (changed?.system?.sante?.etat && changed?.system?.sante?.etat != this.system.sante.etat) {
- setTimeout(() => {
- this.processCombativite(changed.system.sante)
- }, 800)
- }
- if (changed?.system?.ame?.etat && changed?.system?.ame?.etat != this.system.ame.etat) {
- setTimeout(() => {
- this.processAme(changed.system.ame)
- }, 800)
- }
- super._preUpdate(changed, options, user);
- }
-
- /* -------------------------------------------- */
- _onUpdate(data, options, user) {
- super._onUpdate(data, options, user);
- }
- /* -------------------------------------------- */
- getItemById(id) {
- let item = this.items.find(item => item.id == id);
- if (item) {
- item = foundry.utils.duplicate(item)
- }
- return item;
- }
-
- /* -------------------------------------------- */
- async equipItem(itemId) {
- let item = this.items.find(item => item.id == itemId)
- if (item && item.system) {
- let update = { _id: item.id, "system.equipped": !item.system.equipped }
- await this.updateEmbeddedDocuments('Item', [update]); // Updates one EmbeddedEntity
- }
- }
-
- /* -------------------------------------------- */
- editItemField(itemId, itemType, itemField, dataType, value) {
- let item = this.items.find(item => item.id == itemId)
- if (item) {
- console.log("Item ", item, itemField, dataType, value)
- if (dataType.toLowerCase() == "number") {
- value = Number(value)
- } else {
- value = String(value)
- }
- let update = { _id: item.id, [`system.${itemField}`]: value };
- this.updateEmbeddedDocuments("Item", [update])
- }
- }
-
- /* -------------------------------------------- */
- checkAttribut(attribut, minLevel) {
- let attr = this.system.attributs.find(at => at.labelnorm == attribut.toLowerCase())
- if (attr && attr.value >= minLevel) {
- return { isValid: true, attr: foundry.utils.duplicate(attr) }
- }
- return { isValid: false }
- }
- /* -------------------------------------------- */
- checkAttributOrCompetenceLevel(compName, minLevel) {
- let comp = this.items.find(i => i.type == "competence" && i.name.toLowerCase() == compName.toLowerCase() && i.system.niveau >= minLevel)
- if (comp) {
- return { isValid: true, item: foundry.utils.duplicate(comp) }
- } else {
- for (let attrKey in this.system.attributs) {
- if (this.system.attributs[attrKey].label.toLowerCase() == compName.toLowerCase() && this.system.attributs[attrKey].value >= minLevel) {
- return { isValid: true, item: foundry.utils.duplicate(this.system.attributs[attrKey]) }
- }
- }
- }
- return { isValid: false, warningMessage: `Prérequis insuffisant : la compétence/attribut ${compName} doit être de niveau ${minLevel} au minimum` }
- }
- /* -------------------------------------------- */
- addCompetenceBonus(compName, bonus, baCost) {
- let comp = this.items.find(i => i.type == "competence" && i.name.toLowerCase() == compName.toLowerCase())
- if (comp) {
- comp = foundry.utils.duplicate(comp)
- comp.system.bonus = bonus
- comp.system.baCost = baCost
- return { isValid: true, item: comp }
- }
- return { isValid: false, warningMessage: `Compétence ${compName} non trouvée` }
- }
- /* -------------------------------------------- */
- checkIfCompetence(compName) {
- let comp = this.items.find(i => i.type == "competence" && i.name.toLowerCase() == compName.toLowerCase())
- if (comp) {
- return { isValid: true, item: comp }
- }
- return { isValid: false }
- }
- /* -------------------------------------------- */
- getVigueur() {
- return this.system.sante.vigueur
- }
-
- /* -------------------------------------------- */
- getVigueurBonus() {
- let talents = this.items.filter(item => item.type == "talent" && item.system.isautomated)
- let bonus = 0
- for (let talent of talents) {
- for (let auto of talent.system.automations) {
- if (auto.eventtype == "bonus-permanent" && auto.bonusname == "vigueur") {
- bonus += Number(auto.bonus || 0)
- }
- }
- }
- return bonus
- }
-
- /* -------------------------------------------- */
- getSeuilPouvoir() {
- return this.system.ame.seuilpouvoir
- }
-
- /* -------------------------------------------- */
- getSeuilPouvoirBonus() {
- let talents = this.items.filter(item => item.type == "talent" && item.system.isautomated)
- let bonus = 0
- for (let talent of talents) {
- for (let auto of talent.system.automations) {
- if (auto.eventtype == "bonus-permanent" && auto.bonusname == "seuilpouvoir") {
- bonus += Number(auto.bonus || 0)
- }
- }
- }
- return bonus
- }
-
- /* -------------------------------------------- */
- getAmeMax() {
- return Math.min(this.system.ame.max || this.system.ame.nbame, this.system.ame.nbame)
- }
-
- /* -------------------------------------------- */
- getBonneAventure() {
- return this.system.bonneaventure.actuelle
- }
- /* -------------------------------------------- */
- checkBonneAventure(cost) {
- return (this.system.bonneaventure.actuelle >= cost)
- }
- /* -------------------------------------------- */
- changeBonneAventure(value) {
- let newBA = this.system.bonneaventure.actuelle
- newBA += value
- this.update({ 'system.bonneaventure.actuelle': newBA })
- }
-
- /* -------------------------------------------- */
- getEclat() {
- return this.system.eclat.value
- }
-
- /* -------------------------------------------- */
- changeEclat(value) {
- let newE = this.system.eclat.value
- newE += value
- this.update({ 'system.eclat.value': newE })
- }
-
- /* -------------------------------------------- */
- compareName(a, b) {
- if (a.name < b.name) {
- return -1;
- }
- if (a.name > b.name) {
- return 1;
- }
- return 0;
- }
-
- /* -------------------------------------------- */
- getAttribute(attrKey) {
- return this.system.attributes[attrKey]
- }
-
- /* -------------------------------------------- */
- getBonusDegats() {
- return 0;
- }
-
- /* -------------------------------------------- */
- changeEtatCombativite(value) {
- if (value === "vaincu") {
- value = 200
- }
- let sante = foundry.utils.duplicate(this.system.sante)
- sante.etat += Number(value)
- sante.etat = Math.max(sante.etat, 0)
- sante.etat = Math.min(sante.etat, this.system.sante.nbcombativite)
- this.update({ 'system.sante': sante })
- if (sante.etat == this.system.sante.nbcombativite) {
- ChatMessage.create({ content: `${this.name} est vaincu !` })
- }
- // Duplicated ! this.processCombativite(sante)
- }
-
- /* -------------------------------------------- */
- changeEtatAme(value) {
- if (value === "brise") {
- value = 200
- }
- let ame = foundry.utils.duplicate(this.system.ame)
- ame.etat += Number(value)
- ame.etat = Math.max(ame.etat, 0)
- // L'état ne peut pas dépasser le maximum actuel d'âme
- let maxAme = Math.min(this.system.ame.max || this.system.ame.nbame, this.system.ame.nbame - 1)
- ame.etat = Math.min(ame.etat, maxAme)
- this.update({ 'system.ame': ame })
- if (ame.etat >= maxAme) {
- ChatMessage.create({ content: `${this.name} est brisé !` })
- }
- }
-
- /* -------------------------------------------- */
- processCombativite(sante) {
- sante = sante || foundry.utils.duplicate(this.system.sante)
- // Gestion des états affaibli et très affaibli
- if (sante.etat == this.system.sante.nbcombativite - 2 || sante.etat == this.system.sante.nbcombativite - 1) {
- if (sante.etat == this.system.sante.nbcombativite - 2 && this.items.find(item => item.type == "talent" && item.name.toLowerCase() == "encaissement")) {
- ChatMessage.create({ content: `${this.name} ne subit pas les 2 adversités rouge grâce à Encaissement. Pensez à les ajouter à la fin de la scène !` })
- } else if (sante.etat == this.system.sante.nbcombativite - 1 && this.items.find(item => item.type == "talent" && item.name.toLowerCase().includes("vaillant"))) {
- ChatMessage.create({ content: `${this.name} ne subit pas les 2 adversités rouge grâce à Vaillant. Pensez à les ajouter à la fin de la scène !` })
- } else {
- ChatMessage.create({ content: `${this.name} subit 2 adversités rouge !` })
- this.incDecAdversite("rouge", 2)
- }
- }
- }
-
- /* -------------------------------------------- */
- processAme(ame) {
- ame = ame || foundry.utils.duplicate(this.system.ame)
- let maxAme = Math.min(this.system.ame.max || this.system.ame.nbame, this.system.ame.nbame)
- // Gestion des états Traumatisé, Très Traumatisé et Brisé en fonction du maximum actuel
- // Les seuils sont calculés par rapport au maximum d'âme actuel
- if (maxAme >= 3 && ame.etat >= maxAme - 2) {
- if (ame.etat == maxAme - 2) {
- ChatMessage.create({ content: `${this.name} est Traumatisé !` })
- } else if (ame.etat == maxAme - 1) {
- ChatMessage.create({ content: `${this.name} est Très Traumatisé !` })
- } else if (ame.etat >= maxAme) {
- ChatMessage.create({ content: `${this.name} est Brisé !` })
- }
- } else if (ame.etat >= maxAme) {
- ChatMessage.create({ content: `${this.name} est Brisé !` })
- }
- }
-
- /* -------------------------------------------- */
- async equipGear(equipmentId) {
- let item = this.items.find(item => item.id == equipmentId);
- if (item?.system?.data) {
- let update = { _id: item.id, "system.equipped": !item.system.equipped };
- await this.updateEmbeddedDocuments('Item', [update]); // Updates one EmbeddedEntity
- }
- }
-
- /* -------------------------------------------- */
- getSubActors() {
- let subActors = [];
- for (let id of this.system.subactors) {
- subActors.push(foundry.utils.duplicate(game.actors.get(id)));
- }
- return subActors;
- }
- /* -------------------------------------------- */
- async addSubActor(subActorId) {
- let subActors = foundry.utils.duplicate(this.system.subactors);
- subActors.push(subActorId);
- await this.update({ 'system.subactors': subActors });
- }
- /* -------------------------------------------- */
- async delSubActor(subActorId) {
- let newArray = [];
- for (let id of this.system.subactors) {
- if (id != subActorId) {
- newArray.push(id);
- }
- }
- await this.update({ 'system.subactors': newArray });
- }
-
- /* -------------------------------------------- */
- getTotalAdversite() {
- return this.system.adversite.bleue + this.system.adversite.rouge + this.system.adversite.noire
- }
-
- /* -------------------------------------------- */
- async incDecAdversite(adv, incDec = 0) {
- let adversite = foundry.utils.duplicate(this.system.adversite)
- adversite[adv] += Number(incDec)
- adversite[adv] = Math.max(adversite[adv], 0)
- adversite[adv] = Math.min(adversite[adv], 20)
- this.update({ 'system.adversite': adversite })
- }
- /* -------------------------------------------- */
- async incDecQuantity(objetId, incDec = 0) {
- let objetQ = this.items.get(objetId)
- if (objetQ) {
- let newQ = objetQ.system.quantite + incDec
- newQ = Math.max(newQ, 0)
- await this.updateEmbeddedDocuments('Item', [{ _id: objetQ.id, 'system.quantite': newQ }]); // pdates one EmbeddedEntity
- }
- }
-
- /* -------------------------------------------- */
- computeRichesse() {
- let valueSC = 0
- for (let monnaie of this.items) {
- if (monnaie.type == "monnaie") {
- valueSC += Number(monnaie.system.prixsc) * Number(monnaie.system.quantite)
- }
- }
- return MournbladeCYD2Utility.computeMonnaieDetails(valueSC)
- }
-
- /* -------------------------------------------- */
- computeValeurEquipement() {
- let valueSC = 0
- for (let equip of this.items) {
- if (equip.type == "equipement" || equip.type == "arme" || equip.type == "protection") {
- valueSC += Number(equip.system.prixsc) * Number(equip.system.quantite ?? 1)
- valueSC += (Number(equip.system.prixca) * Number(equip.system.quantite ?? 1)) * 20
- valueSC += (Number(equip.system.prixpo) * Number(equip.system.quantite ?? 1)) * 400
- }
- }
- return MournbladeCYD2Utility.computeMonnaieDetails(valueSC)
- }
-
- /* -------------------------------------------- */
- getCompetence(compId) {
- return this.items.get(compId)
- }
-
- /* -------------------------------------------- */
- async setPredilectionUsed(compId, predIdx) {
- let comp = this.items.get(compId)
- let pred = foundry.utils.duplicate(comp.system.predilections)
- pred[predIdx].used = true
- await this.updateEmbeddedDocuments('Item', [{ _id: compId, 'system.predilections': pred }])
- }
-
- /* -------------------------------------------- */
- getInitiativeScore() {
- let init = this.getFlag("world", "last-initiative")
- return init || -1
- }
-
- /* -------------------------------------------- */
- getBestAttackValue() {
- let attackList = this.items.filter(item => (item.type == "arme" || item.type == "talent") && item.system.equipped)
- let maxOff = 0
- let bestArme
- for (let arme of attackList) {
- if (arme.type == "arme") {
- arme = this.prepareArme(arme)
- }
- if (arme.system.totalOffensif > maxOff) {
- maxOff = arme.system.totalOffensif
- bestArme = foundry.utils.duplicate(arme)
- }
- }
- return bestArme
- }
-
- /* -------------------------------------------- */
- getBestDefenseValue() {
- let defenseList = this.items.filter(item => (item.type == "arme") && item.system.equipped)
- let maxDef = 0
- let bestArme
- for (let arme of defenseList) {
- if (arme.type == "arme") {
- arme = this.prepareArme(arme)
- }
- if (arme.system.totalDefensif > maxDef) {
- maxDef = arme.system.totalDefensif
- bestArme = foundry.utils.duplicate(arme)
- }
- }
- return bestArme
- }
-
- /* -------------------------------------------- */
- searchRelevantTalents(competence) {
- let talents = []
-
- for (let talent of this.items) {
- if (talent.type == "talent" && talent.system.isautomated && talent.system.automations.length > 0) {
- for (let auto of talent.system.automations) {
- if (auto.eventtype === "prepare-roll") {
- if (auto.competence.toLowerCase() == competence.name.toLowerCase()) {
- talent = foundry.utils.duplicate(talent)
- talent.system.bonus = auto.bonus
- talent.system.baCost = auto.baCost
- talents.push(talent)
- }
- }
- }
- }
- }
- return talents
- }
-
- /* -------------------------------------------- */
- buildListeAdversites() {
- return []
- }
-
- /* -------------------------------------------- */
- getCommonRollData(attrKey = undefined, compId = undefined, compName = undefined) {
- let rollData = MournbladeCYD2Utility.getBasicRollData()
- rollData.alias = this.name
- rollData.actorImg = this.img
- rollData.actorId = this.id
- rollData.tokenId = this.token?.id
- rollData.img = this.img
- rollData.attributs = MournbladeCYD2Utility.getAttributs()
- rollData.maitriseId = "none"
- rollData.nbEclat = this.system.eclat.value
- rollData.nbBA = this.system.bonneaventure.actuelle
- rollData.nbAdversites = this.getTotalAdversite()
- rollData.talents = []
- rollData.attrKey2 = "none"
- rollData.coupDevastateur = this.items.find(it => it.type == "talent" && it.name.toLowerCase() == "coup dévastateur" && !it.system.used)
- rollData.hasAmbidextre = this.items.find(it => it.type == "talent" && it.name.toLowerCase() == "ambidextre")
- rollData.hasFeinte = this.system.bonneaventure.actuelle > 0 && this.items.find(it => it.type == "talent" && it.name.toLowerCase() == "feinte")
- rollData.isMonte = this.system.combat.monte
- rollData.config = game.system.mournbladecyd2.config
-
- if (attrKey) {
- rollData.attrKey = attrKey
- if (attrKey != "tochoose") {
- rollData.actionImg = "systems/fvtt-mournblade-cyd2/assets/icons/" + this.system.attributs[attrKey].labelnorm + ".webp"
- rollData.attr = foundry.utils.duplicate(this.system.attributs[attrKey])
- }
- }
- if (compId) {
- rollData.competence = foundry.utils.duplicate(this.items.get(compId) || {})
- let maitrises = [{ key: "none", label: "Aucune" }]
- rollData.competence.system.predilections.forEach(function (item) {
- if (item.maitrise) {
- maitrises.push({ key: item.id, label: item.name });
- }
- })
- rollData.maitrises = maitrises // rollData.competence.system.predilections.filter(p => p.maitrise)
- rollData.actionImg = rollData.competence?.img
- rollData.talents = this.searchRelevantTalents(rollData.competence)
- }
- if (compName) {
- rollData.competence = foundry.utils.duplicate(this.items.find(item => item.name.toLowerCase() == compName.toLowerCase()) || {})
- rollData.actionImg = rollData.competence?.img
- }
- return rollData
- }
-
- /* -------------------------------------------- */
- async rollAttribut(attrKey, isInit = false) {
- let rollData = this.getCommonRollData(attrKey)
- rollData.multiplier = (isInit) ? 1 : 2
- rollData.isInit = isInit
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
-
- /* -------------------------------------------- */
- async rollCompetence(attrKey, compId) {
- let rollData = this.getCommonRollData(attrKey, compId)
- rollData.multiplier = 1 // Attr multiplier, always 1 in competence mode
- console.log("RollDatra", rollData)
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
-
- /* -------------------------------------------- */
- async rollArmeOffensif(armeId) {
- let arme = this.items.get(armeId)
- if (arme.type == "arme") {
- arme = this.prepareArme(arme)
- }
- let rollData = this.getCommonRollData(arme.system.attrKey, arme.system.competence._id)
- rollData.arme = arme
- MournbladeCYD2Utility.updateWithTarget(rollData)
- console.log("ARME!", rollData)
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
- /* -------------------------------------------- */
- async rollAssommer() {
- let rollData = this.getCommonRollData("pui", undefined, "Filouterie")
- rollData.assomer = true
- rollData.conditionsCommunes = true
- MournbladeCYD2Utility.updateWithTarget(rollData)
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
- /* -------------------------------------------- */
- async rollCoupBas() {
- let rollData = this.getCommonRollData("pui", undefined, "Mêlée")
- rollData.coupBas = true
- rollData.conditionsCommunes = true
- MournbladeCYD2Utility.updateWithTarget(rollData)
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
- /* -------------------------------------------- */
- async rollImmobiliser() {
- let rollData = this.getCommonRollData("pui", undefined, "Mêlée")
- rollData.immobiliser = true
- rollData.conditionsCommunes = true
- rollData.cibleconsciente = true
- MournbladeCYD2Utility.updateWithTarget(rollData)
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
- /* -------------------------------------------- */
- async rollRepousser() {
- let rollData = this.getCommonRollData("pui", undefined, "Mêlée")
- rollData.repousser = true
- rollData.conditionsCommunes = true
- rollData.cibleconsciente = true
- MournbladeCYD2Utility.updateWithTarget(rollData)
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
- /* -------------------------------------------- */
- async rollDesengager() {
- let rollData = this.getCommonRollData("adr", undefined, "Mouvements")
- rollData.desengager = true
- rollData.conditionsCommunes = true
- MournbladeCYD2Utility.updateWithTarget(rollData)
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
-
- /* -------------------------------------------- */
- async rollArmeDegats(armeId, targetVigueur = undefined, rollDataInput = undefined) {
- let arme = this.items.get(armeId)
- if (arme.type == "arme") {
- arme = this.prepareArme(arme)
- }
- console.log("DEGATS", arme, targetVigueur, rollDataInput)
- let roll
- let bonus = 0
- let bonus2 = 0
-
- if (rollDataInput?.applyCoupDevastateur) {
- bonus2 = Math.floor(this.system.attributs.pui.value / 2)
- let talent = this.items.find(item => item.type == "talent" && item.name.toLowerCase() == "coup dévastateur")
- this.updateEmbeddedDocuments('Item', [{ _id: talent.id, 'system.used': true }])
- }
-
- if (rollDataInput?.isHeroique) {
- if (rollDataInput?.attaqueCharge) {
- bonus = 5
- }
- if (rollDataInput?.chargeCavalerie) {
- bonus = 6
- }
- roll = await new Roll("2d10rr10+" + arme.system.totalDegats + "+" + bonus + "+" + bonus2).roll()
- } else {
- if (rollDataInput?.attaqueCharge) {
- bonus = 3
- }
- if (rollDataInput?.chargeCavalerie) {
- bonus = 4
- }
- roll = await new Roll("1d10+" + arme.system.totalDegats + "+" + bonus + "+" + bonus2).roll()
- }
- await MournbladeCYD2Utility.showDiceSoNice(roll, game.settings.get("core", "rollMode"));
- let nbEtatPerdus = 0
- if (targetVigueur) {
- nbEtatPerdus = Math.floor(roll.total / targetVigueur)
- }
- //console.log(roll)
- let rollData = {
- arme: arme,
- finalResult: roll.total,
- formula: roll.formula,
- alias: this.name,
- actorImg: this.img,
- actorId: this.id,
- defenderTokenId: rollDataInput?.defenderTokenId,
- actionImg: arme.img,
- targetVigueur: targetVigueur,
- nbEtatPerdus: nbEtatPerdus
- }
- MournbladeCYD2Utility.createChatWithRollMode(rollData.alias, {
- content: await renderTemplate(`systems/fvtt-mournblade-cyd2/templates/chat-degats-result.html`, rollData)
- })
-
- if (rollDataInput?.defenderTokenId && nbEtatPerdus) {
- MournbladeCYD2Utility.applyCombativite(rollDataInput, nbEtatPerdus)
- }
-
- }
-}
diff --git a/.history/modules/mournblade-cyd2-actor_20251026083449.js b/.history/modules/mournblade-cyd2-actor_20251026083449.js
deleted file mode 100644
index d2dabe2..0000000
--- a/.history/modules/mournblade-cyd2-actor_20251026083449.js
+++ /dev/null
@@ -1,893 +0,0 @@
-/* -------------------------------------------- */
-import { MournbladeCYD2Utility } from "./mournblade-cyd2-utility.js";
-import { MournbladeCYD2RollDialog } from "./mournblade-cyd2-roll-dialog.js";
-
-/* -------------------------------------------- */
-const __degatsBonus = [-2, -2, -1, -1, 0, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 8, 8, 9, 9, 10, 10]
-const __vitesseBonus = [-2, -2, -1, -1, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8]
-
-/* -------------------------------------------- */
-/**
- * Extend the base Actor entity by defining a custom roll data structure which is ideal for the Simple system.
- * @extends {Actor}
- */
-export class MournbladeCYD2Actor extends Actor {
-
- /* -------------------------------------------- */
- /**
- * Override the create() function to provide additional SoS functionality.
- *
- * This overrided create() function adds initial items
- * Namely: Basic skills, money,
- *
- * @param {Object} data Barebones actor data which this function adds onto.
- * @param {Object} options (Unused) Additional options which customize the creation workflow.
- *
- */
-
- static async create(data, options) {
-
- // Case of compendium global import
- if (data instanceof Array) {
- return super.create(data, options);
- }
- // If the created actor has items (only applicable to duplicated actors) bypass the new actor creation logic
- if (data.items) {
- let actor = super.create(data, options);
- return actor;
- }
-
- if (data.type == 'personnage') {
- const skills = await MournbladeCYD2Utility.loadCompendium("fvtt-mournblade-cyd2.skills")
- data.items = skills.map(i => i.toObject())
- }
- if (data.type == 'creature') {
- const skills = await MournbladeCYD2Utility.loadCompendium("fvtt-mournblade-cyd2.skills-creatures")
- data.items = skills.map(i => i.toObject())
- data.items.push({ name: "Arme naturelle 1", type: 'arme', img: "systems/fvtt-mournblade-cyd2/assets/icons/melee.webp", system: { typearme: "contact", bonusmaniementoff: 0, seuildefense: 0, degats: "0" } })
- data.items.push({ name: "Arme naturelle 2", type: 'arme', img: "systems/fvtt-mournblade-cyd2/assets/icons/melee.webp", system: { typearme: "contact", bonusmaniementoff: 0, seuildefense: 0, degats: "0" } })
- }
-
- return super.create(data, options);
- }
-
- /* -------------------------------------------- */
- getBonusDefenseFromTalents() {
- let talents = this.items.filter(item => item.type == "talent" && item.system.isautomated)
- let bonus = 0
- for (let talent of talents) {
- for (let auto of talent.system.automations) {
- if (auto.eventtype == "bonus-permanent" && auto.bonusname == "bonus-defensif") {
- bonus += Number(auto.bonus || 0)
- }
- }
- }
- return bonus
- }
-
- /* -------------------------------------------- */
- prepareArme(arme) {
- if (this.type == "cellule") {
- return arme
- }
-
- arme = foundry.utils.duplicate(arme)
- let combat = this.getCombatValues()
- if (arme.system.typearme == "contact" || arme.system.typearme == "contactjet") {
- let bonusDefense = this.getBonusDefenseFromTalents()
- arme.system.competence = foundry.utils.duplicate(this.items.find(item => item.type == "competence" && item.name.toLowerCase() == "mêlée"))
- arme.system.attrKey = "pui"
- arme.system.totalDegats = arme.system.degats + "+" + combat.bonusDegatsTotal
- arme.system.totalOffensif = this.system.attributs.pui.value + arme.system.competence.system.niveau + arme.system.bonusmaniementoff + (this.system.combat.monte ? 3 : 0)
- arme.system.totalDefensif = combat.defenseTotal + arme.system.competence.system.niveau + arme.system.seuildefense + bonusDefense + (this.system.combat.monte ? 3 : 0)
- console.log("Arme", arme.system.totalDefensif, combat, arme.system.competence.system.niveau, arme.system.seuildefense, bonusDefense)
- arme.system.isdefense = true
- arme.system.isMelee = true
- arme.system.isDistance = false
- }
- if (arme.system.typearme == "jet" || arme.system.typearme == "tir") {
- arme.system.competence = foundry.utils.duplicate(this.items.find(item => item.type == "competence" && item.name.toLowerCase() == "armes à distance"))
- arme.system.attrKey = "adr"
- arme.system.totalOffensif = this.system.attributs.adr.value + arme.system.competence.system.niveau + arme.system.bonusmaniementoff
- arme.system.totalDegats = arme.system.degats
- arme.system.isMelee = false
- arme.system.isDistance = true
- if (arme.system.isdefense) {
- arme.system.totalDefensif = combat.defenseTotal + arme.system.competence.system.niveau + arme.system.seuildefense
- }
- }
- return arme
- }
-
- /* -------------------------------------------- */
- getItemSorted(types) {
- let items = this.items.filter(item => types.includes(item.type)) || []
- MournbladeCYD2Utility.sortArrayObjectsByName(items)
- return items
- }
- getWeapons() {
- let armes = []
- for (let arme of this.items) {
- if (arme.type == "arme") {
- armes.push(this.prepareArme(arme))
- }
- }
- MournbladeCYD2Utility.sortArrayObjectsByName(armes)
- return armes
- }
- getMonnaies() {
- return this.getItemSorted(["monnaie"])
- }
- getEquipments() {
- return this.getItemSorted(["equipement"])
- }
- getArtefacts() {
- return this.getItemSorted(["artefact"])
- }
- getArmors() {
- return this.getItemSorted(["protection"])
- }
- getHistoriques() {
- return this.getItemSorted(["historique"])
- }
- getProfils() {
- return this.getItemSorted(["profil"])
- }
- getTalents() {
- return this.getItemSorted(["talent"])
- }
- getRessources() {
- return this.getItemSorted(["ressource"])
- }
- getContacts() {
- return this.getItemSorted(["contact"])
- }
- getMutations() {
- return this.getItemSorted(["mutation"])
- }
- getDons() {
- return this.getItemSorted(["don"])
- }
- getPactes() {
- return this.getItemSorted(["pacte"])
- }
- getTendances() {
- return this.getItemSorted(["tendance"])
- }
- getRunes() {
- return this.getItemSorted(["rune"])
- }
- getTraitsChaotiques() {
- return this.getItemSorted(["traitchaotique"])
- }
- getTraitsEspeces() {
- return this.getItemSorted(["traitespece"])
- }
-
- /* -------------------------------------------- */
- getAspect() {
- return (this.system.balance.loi > this.system.balance.chaos) ? this.system.balance.loi : this.system.balance.chaos
- }
- getMarge() {
- return Math.abs(this.system.balance.loi - this.system.balance.chaos)
- }
- getAlignement() {
- return (this.system.balance.loi > this.system.balance.chaos) ? "loyal" : "chaotique"
- }
-
- /* -------------------------------------------- */
- getSkills() {
- let comp = []
- for (let item of this.items) {
- item = foundry.utils.duplicate(item)
- if (item.type == "competence") {
- item.system.attribut1total = item.system.niveau + (this.system.attributs[item.system.attribut1]?.value || 0)
- item.system.attribut2total = item.system.niveau + (this.system.attributs[item.system.attribut2]?.value || 0)
- item.system.attribut3total = item.system.niveau + (this.system.attributs[item.system.attribut3]?.value || 0)
- if (item.system.niveau == 0) {
- item.system.attribut1total -= 3
- item.system.attribut2total -= 3
- item.system.attribut3total -= 3
- }
- item.system.attribut1label = this.system.attributs[item.system.attribut1]?.label || ""
- item.system.attribut2label = this.system.attributs[item.system.attribut2]?.label || ""
- item.system.attribut3label = this.system.attributs[item.system.attribut3]?.label || ""
- comp.push(item)
- }
- }
- MournbladeCYD2Utility.sortArrayObjectsByName(comp)
- return comp
- }
-
- /* ----------------------- --------------------- */
- addMember(actorId) {
- let members = foundry.utils.duplicate(this.system.members)
- members.push({ id: actorId })
- this.update({ 'system.members': members })
- }
- async removeMember(actorId) {
- let members = this.system.members.filter(it => it.id != actorId)
- this.update({ 'system.members': members })
- }
-
- /* -------------------------------------------- */
- getDefenseBase() {
- return Math.max(this.system.attributs.tre.value, this.system.attributs.adr.value)
- }
-
- /* -------------------------------------------- */
- getVitesseBase() {
- return 5 + __vitesseBonus[this.system.attributs.adr.value]
- }
- /* -------------------------------------------- */
- getProtection() {
- let equipProtection = 0
- for (let armor of this.items) {
- if (armor.type == "protection" && armor.system.equipped) {
- equipProtection += Number(armor.system.protection)
- }
- }
- if (equipProtection < 4) {
- return 4 + equipProtection // Cas des boucliers + sans armure
- }
- return equipProtection // Uniquement la protection des armures + boucliers
- }
-
- /* -------------------------------------------- */
- getCombatValues() {
- if (this.type == "cellule") {
- return {
- initBase: 0,
- initTotal: 0,
- bonusDegats: 0,
- bonusDegatsTotal: 0,
- vitesseBase: 0,
- vitesseTotal: 0,
- defenseBase: 0,
- protection: 0,
- defenseTotal: 0
- }
- }
-
- let combat = {
- initBase: this.system.attributs.adr.value,
- initTotal: this.system.attributs.adr.value + this.system.combat.initbonus,
- bonusDegats: this.getBonusDegats(),
- bonusDegatsTotal: this.getBonusDegats() + this.system.combat.bonusdegats,
- vitesseBase: this.getVitesseBase(),
- vitesseTotal: this.getVitesseBase() + this.system.combat.vitessebonus,
- defenseBase: this.getDefenseBase(),
- protection: this.getProtection(),
- defenseTotal: this.getDefenseBase() + this.system.combat.defensebonus + this.getProtection() - this.getTotalAdversite() + (this.system.combat.defensetotale ? 3 : 0)
- }
- return combat
- }
-
- /* -------------------------------------------- */
- prepareBaseData() {
- }
-
- /* -------------------------------------------- */
- async prepareData() {
- super.prepareData();
- }
-
- /* -------------------------------------------- */
- prepareDerivedData() {
-
- if (this.type == 'personnage') {
- let talentBonus = this.getVigueurBonus()
- let vigueur = Math.floor((this.system.attributs.pui.value + this.system.attributs.tre.value) / 2) + talentBonus + this.system.sante.vigueurmodifier
- if (vigueur != this.system.sante.vigueur) {
- this.update({ 'system.sante.vigueur': vigueur })
- }
-
- let seuilPouvoirBonus = this.getSeuilPouvoirBonus()
- let seuilPouvoir = Math.floor((this.system.attributs.tre.value + this.system.attributs.cla.value) / 2) + seuilPouvoirBonus + this.system.ame.seuilpouvoirmodifier
- if (seuilPouvoir != this.system.ame.seuilpouvoir) {
- this.update({ 'system.ame.seuilpouvoir': seuilPouvoir })
- }
- }
- super.prepareDerivedData()
- }
-
- /* -------------------------------------------- */
- _preUpdate(changed, options, user) {
- if (changed?.system?.sante?.etat && changed?.system?.sante?.etat != this.system.sante.etat) {
- setTimeout(() => {
- this.processCombativite(changed.system.sante)
- }, 800)
- }
- if (changed?.system?.ame?.etat && changed?.system?.ame?.etat != this.system.ame.etat) {
- setTimeout(() => {
- this.processAme(changed.system.ame)
- }, 800)
- }
- super._preUpdate(changed, options, user);
- }
-
- /* -------------------------------------------- */
- _onUpdate(data, options, user) {
- super._onUpdate(data, options, user);
- }
- /* -------------------------------------------- */
- getItemById(id) {
- let item = this.items.find(item => item.id == id);
- if (item) {
- item = foundry.utils.duplicate(item)
- }
- return item;
- }
-
- /* -------------------------------------------- */
- async equipItem(itemId) {
- let item = this.items.find(item => item.id == itemId)
- if (item && item.system) {
- let update = { _id: item.id, "system.equipped": !item.system.equipped }
- await this.updateEmbeddedDocuments('Item', [update]); // Updates one EmbeddedEntity
- }
- }
-
- /* -------------------------------------------- */
- editItemField(itemId, itemType, itemField, dataType, value) {
- let item = this.items.find(item => item.id == itemId)
- if (item) {
- console.log("Item ", item, itemField, dataType, value)
- if (dataType.toLowerCase() == "number") {
- value = Number(value)
- } else {
- value = String(value)
- }
- let update = { _id: item.id, [`system.${itemField}`]: value };
- this.updateEmbeddedDocuments("Item", [update])
- }
- }
-
- /* -------------------------------------------- */
- checkAttribut(attribut, minLevel) {
- let attr = this.system.attributs.find(at => at.labelnorm == attribut.toLowerCase())
- if (attr && attr.value >= minLevel) {
- return { isValid: true, attr: foundry.utils.duplicate(attr) }
- }
- return { isValid: false }
- }
- /* -------------------------------------------- */
- checkAttributOrCompetenceLevel(compName, minLevel) {
- let comp = this.items.find(i => i.type == "competence" && i.name.toLowerCase() == compName.toLowerCase() && i.system.niveau >= minLevel)
- if (comp) {
- return { isValid: true, item: foundry.utils.duplicate(comp) }
- } else {
- for (let attrKey in this.system.attributs) {
- if (this.system.attributs[attrKey].label.toLowerCase() == compName.toLowerCase() && this.system.attributs[attrKey].value >= minLevel) {
- return { isValid: true, item: foundry.utils.duplicate(this.system.attributs[attrKey]) }
- }
- }
- }
- return { isValid: false, warningMessage: `Prérequis insuffisant : la compétence/attribut ${compName} doit être de niveau ${minLevel} au minimum` }
- }
- /* -------------------------------------------- */
- addCompetenceBonus(compName, bonus, baCost) {
- let comp = this.items.find(i => i.type == "competence" && i.name.toLowerCase() == compName.toLowerCase())
- if (comp) {
- comp = foundry.utils.duplicate(comp)
- comp.system.bonus = bonus
- comp.system.baCost = baCost
- return { isValid: true, item: comp }
- }
- return { isValid: false, warningMessage: `Compétence ${compName} non trouvée` }
- }
- /* -------------------------------------------- */
- checkIfCompetence(compName) {
- let comp = this.items.find(i => i.type == "competence" && i.name.toLowerCase() == compName.toLowerCase())
- if (comp) {
- return { isValid: true, item: comp }
- }
- return { isValid: false }
- }
- /* -------------------------------------------- */
- getVigueur() {
- return this.system.sante.vigueur
- }
-
- /* -------------------------------------------- */
- getVigueurBonus() {
- let talents = this.items.filter(item => item.type == "talent" && item.system.isautomated)
- let bonus = 0
- for (let talent of talents) {
- for (let auto of talent.system.automations) {
- if (auto.eventtype == "bonus-permanent" && auto.bonusname == "vigueur") {
- bonus += Number(auto.bonus || 0)
- }
- }
- }
- return bonus
- }
-
- /* -------------------------------------------- */
- getSeuilPouvoir() {
- return this.system.ame.seuilpouvoir
- }
-
- /* -------------------------------------------- */
- getSeuilPouvoirBonus() {
- let talents = this.items.filter(item => item.type == "talent" && item.system.isautomated)
- let bonus = 0
- for (let talent of talents) {
- for (let auto of talent.system.automations) {
- if (auto.eventtype == "bonus-permanent" && auto.bonusname == "seuilpouvoir") {
- bonus += Number(auto.bonus || 0)
- }
- }
- }
- return bonus
- }
-
- /* -------------------------------------------- */
- getAmeMax() {
- return Math.min(this.system.ame.max || this.system.ame.nbame, this.system.ame.nbame)
- }
-
- /* -------------------------------------------- */
- getBonneAventure() {
- return this.system.bonneaventure.actuelle
- }
- /* -------------------------------------------- */
- checkBonneAventure(cost) {
- return (this.system.bonneaventure.actuelle >= cost)
- }
- /* -------------------------------------------- */
- changeBonneAventure(value) {
- let newBA = this.system.bonneaventure.actuelle
- newBA += value
- this.update({ 'system.bonneaventure.actuelle': newBA })
- }
-
- /* -------------------------------------------- */
- getEclat() {
- return this.system.eclat.value
- }
-
- /* -------------------------------------------- */
- changeEclat(value) {
- let newE = this.system.eclat.value
- newE += value
- this.update({ 'system.eclat.value': newE })
- }
-
- /* -------------------------------------------- */
- compareName(a, b) {
- if (a.name < b.name) {
- return -1;
- }
- if (a.name > b.name) {
- return 1;
- }
- return 0;
- }
-
- /* -------------------------------------------- */
- getAttribute(attrKey) {
- return this.system.attributes[attrKey]
- }
-
- /* -------------------------------------------- */
- getBonusDegats() {
- return 0;
- }
-
- /* -------------------------------------------- */
- changeEtatCombativite(value) {
- if (value === "vaincu") {
- value = 200
- }
- let sante = foundry.utils.duplicate(this.system.sante)
- sante.etat += Number(value)
- sante.etat = Math.max(sante.etat, 0)
- sante.etat = Math.min(sante.etat, this.system.sante.nbcombativite)
- this.update({ 'system.sante': sante })
- if (sante.etat == this.system.sante.nbcombativite) {
- ChatMessage.create({ content: `${this.name} est vaincu !` })
- }
- // Duplicated ! this.processCombativite(sante)
- }
-
- /* -------------------------------------------- */
- changeEtatAme(value) {
- if (value === "brise") {
- value = 200
- }
- let ame = foundry.utils.duplicate(this.system.ame)
- ame.etat += Number(value)
- ame.etat = Math.max(ame.etat, 0)
- // L'état ne peut pas dépasser le maximum actuel d'âme
- let maxAme = Math.min(this.system.ame.max || this.system.ame.nbame, this.system.ame.nbame - 1)
- ame.etat = Math.min(ame.etat, maxAme)
- this.update({ 'system.ame': ame })
- if (ame.etat >= maxAme) {
- ChatMessage.create({ content: `${this.name} est brisé !` })
- }
- }
-
- /* -------------------------------------------- */
- processCombativite(sante) {
- sante = sante || foundry.utils.duplicate(this.system.sante)
- // Gestion des états affaibli et très affaibli
- if (sante.etat == this.system.sante.nbcombativite - 2 || sante.etat == this.system.sante.nbcombativite - 1) {
- if (sante.etat == this.system.sante.nbcombativite - 2 && this.items.find(item => item.type == "talent" && item.name.toLowerCase() == "encaissement")) {
- ChatMessage.create({ content: `${this.name} ne subit pas les 2 adversités rouge grâce à Encaissement. Pensez à les ajouter à la fin de la scène !` })
- } else if (sante.etat == this.system.sante.nbcombativite - 1 && this.items.find(item => item.type == "talent" && item.name.toLowerCase().includes("vaillant"))) {
- ChatMessage.create({ content: `${this.name} ne subit pas les 2 adversités rouge grâce à Vaillant. Pensez à les ajouter à la fin de la scène !` })
- } else {
- ChatMessage.create({ content: `${this.name} subit 2 adversités rouge !` })
- this.incDecAdversite("rouge", 2)
- }
- }
- }
-
- /* -------------------------------------------- */
- processAme(ame) {
- ame = ame || foundry.utils.duplicate(this.system.ame)
- let maxAme = Math.min(this.system.ame.max || this.system.ame.nbame, this.system.ame.nbame - 1)
- // Gestion des états Traumatisé, Très Traumatisé et Brisé en fonction du maximum actuel
- // Les seuils sont calculés par rapport au maximum d'âme actuel
- if (maxAme >= 2 && ame.etat >= maxAme - 2) {
- if (ame.etat == maxAme - 2) {
- ChatMessage.create({ content: `${this.name} est Traumatisé !` })
- } else if (ame.etat == maxAme - 1) {
- ChatMessage.create({ content: `${this.name} est Très Traumatisé !` })
- } else if (ame.etat >= maxAme) {
- ChatMessage.create({ content: `${this.name} est Brisé !` })
- }
- } else if (ame.etat >= maxAme) {
- ChatMessage.create({ content: `${this.name} est Brisé !` })
- }
- }
-
- /* -------------------------------------------- */
- async equipGear(equipmentId) {
- let item = this.items.find(item => item.id == equipmentId);
- if (item?.system?.data) {
- let update = { _id: item.id, "system.equipped": !item.system.equipped };
- await this.updateEmbeddedDocuments('Item', [update]); // Updates one EmbeddedEntity
- }
- }
-
- /* -------------------------------------------- */
- getSubActors() {
- let subActors = [];
- for (let id of this.system.subactors) {
- subActors.push(foundry.utils.duplicate(game.actors.get(id)));
- }
- return subActors;
- }
- /* -------------------------------------------- */
- async addSubActor(subActorId) {
- let subActors = foundry.utils.duplicate(this.system.subactors);
- subActors.push(subActorId);
- await this.update({ 'system.subactors': subActors });
- }
- /* -------------------------------------------- */
- async delSubActor(subActorId) {
- let newArray = [];
- for (let id of this.system.subactors) {
- if (id != subActorId) {
- newArray.push(id);
- }
- }
- await this.update({ 'system.subactors': newArray });
- }
-
- /* -------------------------------------------- */
- getTotalAdversite() {
- return this.system.adversite.bleue + this.system.adversite.rouge + this.system.adversite.noire
- }
-
- /* -------------------------------------------- */
- async incDecAdversite(adv, incDec = 0) {
- let adversite = foundry.utils.duplicate(this.system.adversite)
- adversite[adv] += Number(incDec)
- adversite[adv] = Math.max(adversite[adv], 0)
- adversite[adv] = Math.min(adversite[adv], 20)
- this.update({ 'system.adversite': adversite })
- }
- /* -------------------------------------------- */
- async incDecQuantity(objetId, incDec = 0) {
- let objetQ = this.items.get(objetId)
- if (objetQ) {
- let newQ = objetQ.system.quantite + incDec
- newQ = Math.max(newQ, 0)
- await this.updateEmbeddedDocuments('Item', [{ _id: objetQ.id, 'system.quantite': newQ }]); // pdates one EmbeddedEntity
- }
- }
-
- /* -------------------------------------------- */
- computeRichesse() {
- let valueSC = 0
- for (let monnaie of this.items) {
- if (monnaie.type == "monnaie") {
- valueSC += Number(monnaie.system.prixsc) * Number(monnaie.system.quantite)
- }
- }
- return MournbladeCYD2Utility.computeMonnaieDetails(valueSC)
- }
-
- /* -------------------------------------------- */
- computeValeurEquipement() {
- let valueSC = 0
- for (let equip of this.items) {
- if (equip.type == "equipement" || equip.type == "arme" || equip.type == "protection") {
- valueSC += Number(equip.system.prixsc) * Number(equip.system.quantite ?? 1)
- valueSC += (Number(equip.system.prixca) * Number(equip.system.quantite ?? 1)) * 20
- valueSC += (Number(equip.system.prixpo) * Number(equip.system.quantite ?? 1)) * 400
- }
- }
- return MournbladeCYD2Utility.computeMonnaieDetails(valueSC)
- }
-
- /* -------------------------------------------- */
- getCompetence(compId) {
- return this.items.get(compId)
- }
-
- /* -------------------------------------------- */
- async setPredilectionUsed(compId, predIdx) {
- let comp = this.items.get(compId)
- let pred = foundry.utils.duplicate(comp.system.predilections)
- pred[predIdx].used = true
- await this.updateEmbeddedDocuments('Item', [{ _id: compId, 'system.predilections': pred }])
- }
-
- /* -------------------------------------------- */
- getInitiativeScore() {
- let init = this.getFlag("world", "last-initiative")
- return init || -1
- }
-
- /* -------------------------------------------- */
- getBestAttackValue() {
- let attackList = this.items.filter(item => (item.type == "arme" || item.type == "talent") && item.system.equipped)
- let maxOff = 0
- let bestArme
- for (let arme of attackList) {
- if (arme.type == "arme") {
- arme = this.prepareArme(arme)
- }
- if (arme.system.totalOffensif > maxOff) {
- maxOff = arme.system.totalOffensif
- bestArme = foundry.utils.duplicate(arme)
- }
- }
- return bestArme
- }
-
- /* -------------------------------------------- */
- getBestDefenseValue() {
- let defenseList = this.items.filter(item => (item.type == "arme") && item.system.equipped)
- let maxDef = 0
- let bestArme
- for (let arme of defenseList) {
- if (arme.type == "arme") {
- arme = this.prepareArme(arme)
- }
- if (arme.system.totalDefensif > maxDef) {
- maxDef = arme.system.totalDefensif
- bestArme = foundry.utils.duplicate(arme)
- }
- }
- return bestArme
- }
-
- /* -------------------------------------------- */
- searchRelevantTalents(competence) {
- let talents = []
-
- for (let talent of this.items) {
- if (talent.type == "talent" && talent.system.isautomated && talent.system.automations.length > 0) {
- for (let auto of talent.system.automations) {
- if (auto.eventtype === "prepare-roll") {
- if (auto.competence.toLowerCase() == competence.name.toLowerCase()) {
- talent = foundry.utils.duplicate(talent)
- talent.system.bonus = auto.bonus
- talent.system.baCost = auto.baCost
- talents.push(talent)
- }
- }
- }
- }
- }
- return talents
- }
-
- /* -------------------------------------------- */
- buildListeAdversites() {
- return []
- }
-
- /* -------------------------------------------- */
- getCommonRollData(attrKey = undefined, compId = undefined, compName = undefined) {
- let rollData = MournbladeCYD2Utility.getBasicRollData()
- rollData.alias = this.name
- rollData.actorImg = this.img
- rollData.actorId = this.id
- rollData.tokenId = this.token?.id
- rollData.img = this.img
- rollData.attributs = MournbladeCYD2Utility.getAttributs()
- rollData.maitriseId = "none"
- rollData.nbEclat = this.system.eclat.value
- rollData.nbBA = this.system.bonneaventure.actuelle
- rollData.nbAdversites = this.getTotalAdversite()
- rollData.talents = []
- rollData.attrKey2 = "none"
- rollData.coupDevastateur = this.items.find(it => it.type == "talent" && it.name.toLowerCase() == "coup dévastateur" && !it.system.used)
- rollData.hasAmbidextre = this.items.find(it => it.type == "talent" && it.name.toLowerCase() == "ambidextre")
- rollData.hasFeinte = this.system.bonneaventure.actuelle > 0 && this.items.find(it => it.type == "talent" && it.name.toLowerCase() == "feinte")
- rollData.isMonte = this.system.combat.monte
- rollData.config = game.system.mournbladecyd2.config
-
- if (attrKey) {
- rollData.attrKey = attrKey
- if (attrKey != "tochoose") {
- rollData.actionImg = "systems/fvtt-mournblade-cyd2/assets/icons/" + this.system.attributs[attrKey].labelnorm + ".webp"
- rollData.attr = foundry.utils.duplicate(this.system.attributs[attrKey])
- }
- }
- if (compId) {
- rollData.competence = foundry.utils.duplicate(this.items.get(compId) || {})
- let maitrises = [{ key: "none", label: "Aucune" }]
- rollData.competence.system.predilections.forEach(function (item) {
- if (item.maitrise) {
- maitrises.push({ key: item.id, label: item.name });
- }
- })
- rollData.maitrises = maitrises // rollData.competence.system.predilections.filter(p => p.maitrise)
- rollData.actionImg = rollData.competence?.img
- rollData.talents = this.searchRelevantTalents(rollData.competence)
- }
- if (compName) {
- rollData.competence = foundry.utils.duplicate(this.items.find(item => item.name.toLowerCase() == compName.toLowerCase()) || {})
- rollData.actionImg = rollData.competence?.img
- }
- return rollData
- }
-
- /* -------------------------------------------- */
- async rollAttribut(attrKey, isInit = false) {
- let rollData = this.getCommonRollData(attrKey)
- rollData.multiplier = (isInit) ? 1 : 2
- rollData.isInit = isInit
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
-
- /* -------------------------------------------- */
- async rollCompetence(attrKey, compId) {
- let rollData = this.getCommonRollData(attrKey, compId)
- rollData.multiplier = 1 // Attr multiplier, always 1 in competence mode
- console.log("RollDatra", rollData)
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
-
- /* -------------------------------------------- */
- async rollArmeOffensif(armeId) {
- let arme = this.items.get(armeId)
- if (arme.type == "arme") {
- arme = this.prepareArme(arme)
- }
- let rollData = this.getCommonRollData(arme.system.attrKey, arme.system.competence._id)
- rollData.arme = arme
- MournbladeCYD2Utility.updateWithTarget(rollData)
- console.log("ARME!", rollData)
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
- /* -------------------------------------------- */
- async rollAssommer() {
- let rollData = this.getCommonRollData("pui", undefined, "Filouterie")
- rollData.assomer = true
- rollData.conditionsCommunes = true
- MournbladeCYD2Utility.updateWithTarget(rollData)
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
- /* -------------------------------------------- */
- async rollCoupBas() {
- let rollData = this.getCommonRollData("pui", undefined, "Mêlée")
- rollData.coupBas = true
- rollData.conditionsCommunes = true
- MournbladeCYD2Utility.updateWithTarget(rollData)
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
- /* -------------------------------------------- */
- async rollImmobiliser() {
- let rollData = this.getCommonRollData("pui", undefined, "Mêlée")
- rollData.immobiliser = true
- rollData.conditionsCommunes = true
- rollData.cibleconsciente = true
- MournbladeCYD2Utility.updateWithTarget(rollData)
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
- /* -------------------------------------------- */
- async rollRepousser() {
- let rollData = this.getCommonRollData("pui", undefined, "Mêlée")
- rollData.repousser = true
- rollData.conditionsCommunes = true
- rollData.cibleconsciente = true
- MournbladeCYD2Utility.updateWithTarget(rollData)
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
- /* -------------------------------------------- */
- async rollDesengager() {
- let rollData = this.getCommonRollData("adr", undefined, "Mouvements")
- rollData.desengager = true
- rollData.conditionsCommunes = true
- MournbladeCYD2Utility.updateWithTarget(rollData)
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
-
- /* -------------------------------------------- */
- async rollArmeDegats(armeId, targetVigueur = undefined, rollDataInput = undefined) {
- let arme = this.items.get(armeId)
- if (arme.type == "arme") {
- arme = this.prepareArme(arme)
- }
- console.log("DEGATS", arme, targetVigueur, rollDataInput)
- let roll
- let bonus = 0
- let bonus2 = 0
-
- if (rollDataInput?.applyCoupDevastateur) {
- bonus2 = Math.floor(this.system.attributs.pui.value / 2)
- let talent = this.items.find(item => item.type == "talent" && item.name.toLowerCase() == "coup dévastateur")
- this.updateEmbeddedDocuments('Item', [{ _id: talent.id, 'system.used': true }])
- }
-
- if (rollDataInput?.isHeroique) {
- if (rollDataInput?.attaqueCharge) {
- bonus = 5
- }
- if (rollDataInput?.chargeCavalerie) {
- bonus = 6
- }
- roll = await new Roll("2d10rr10+" + arme.system.totalDegats + "+" + bonus + "+" + bonus2).roll()
- } else {
- if (rollDataInput?.attaqueCharge) {
- bonus = 3
- }
- if (rollDataInput?.chargeCavalerie) {
- bonus = 4
- }
- roll = await new Roll("1d10+" + arme.system.totalDegats + "+" + bonus + "+" + bonus2).roll()
- }
- await MournbladeCYD2Utility.showDiceSoNice(roll, game.settings.get("core", "rollMode"));
- let nbEtatPerdus = 0
- if (targetVigueur) {
- nbEtatPerdus = Math.floor(roll.total / targetVigueur)
- }
- //console.log(roll)
- let rollData = {
- arme: arme,
- finalResult: roll.total,
- formula: roll.formula,
- alias: this.name,
- actorImg: this.img,
- actorId: this.id,
- defenderTokenId: rollDataInput?.defenderTokenId,
- actionImg: arme.img,
- targetVigueur: targetVigueur,
- nbEtatPerdus: nbEtatPerdus
- }
- MournbladeCYD2Utility.createChatWithRollMode(rollData.alias, {
- content: await renderTemplate(`systems/fvtt-mournblade-cyd2/templates/chat-degats-result.html`, rollData)
- })
-
- if (rollDataInput?.defenderTokenId && nbEtatPerdus) {
- MournbladeCYD2Utility.applyCombativite(rollDataInput, nbEtatPerdus)
- }
-
- }
-}
diff --git a/.history/modules/mournblade-cyd2-actor_20251026083504.js b/.history/modules/mournblade-cyd2-actor_20251026083504.js
deleted file mode 100644
index d2dabe2..0000000
--- a/.history/modules/mournblade-cyd2-actor_20251026083504.js
+++ /dev/null
@@ -1,893 +0,0 @@
-/* -------------------------------------------- */
-import { MournbladeCYD2Utility } from "./mournblade-cyd2-utility.js";
-import { MournbladeCYD2RollDialog } from "./mournblade-cyd2-roll-dialog.js";
-
-/* -------------------------------------------- */
-const __degatsBonus = [-2, -2, -1, -1, 0, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 8, 8, 9, 9, 10, 10]
-const __vitesseBonus = [-2, -2, -1, -1, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8]
-
-/* -------------------------------------------- */
-/**
- * Extend the base Actor entity by defining a custom roll data structure which is ideal for the Simple system.
- * @extends {Actor}
- */
-export class MournbladeCYD2Actor extends Actor {
-
- /* -------------------------------------------- */
- /**
- * Override the create() function to provide additional SoS functionality.
- *
- * This overrided create() function adds initial items
- * Namely: Basic skills, money,
- *
- * @param {Object} data Barebones actor data which this function adds onto.
- * @param {Object} options (Unused) Additional options which customize the creation workflow.
- *
- */
-
- static async create(data, options) {
-
- // Case of compendium global import
- if (data instanceof Array) {
- return super.create(data, options);
- }
- // If the created actor has items (only applicable to duplicated actors) bypass the new actor creation logic
- if (data.items) {
- let actor = super.create(data, options);
- return actor;
- }
-
- if (data.type == 'personnage') {
- const skills = await MournbladeCYD2Utility.loadCompendium("fvtt-mournblade-cyd2.skills")
- data.items = skills.map(i => i.toObject())
- }
- if (data.type == 'creature') {
- const skills = await MournbladeCYD2Utility.loadCompendium("fvtt-mournblade-cyd2.skills-creatures")
- data.items = skills.map(i => i.toObject())
- data.items.push({ name: "Arme naturelle 1", type: 'arme', img: "systems/fvtt-mournblade-cyd2/assets/icons/melee.webp", system: { typearme: "contact", bonusmaniementoff: 0, seuildefense: 0, degats: "0" } })
- data.items.push({ name: "Arme naturelle 2", type: 'arme', img: "systems/fvtt-mournblade-cyd2/assets/icons/melee.webp", system: { typearme: "contact", bonusmaniementoff: 0, seuildefense: 0, degats: "0" } })
- }
-
- return super.create(data, options);
- }
-
- /* -------------------------------------------- */
- getBonusDefenseFromTalents() {
- let talents = this.items.filter(item => item.type == "talent" && item.system.isautomated)
- let bonus = 0
- for (let talent of talents) {
- for (let auto of talent.system.automations) {
- if (auto.eventtype == "bonus-permanent" && auto.bonusname == "bonus-defensif") {
- bonus += Number(auto.bonus || 0)
- }
- }
- }
- return bonus
- }
-
- /* -------------------------------------------- */
- prepareArme(arme) {
- if (this.type == "cellule") {
- return arme
- }
-
- arme = foundry.utils.duplicate(arme)
- let combat = this.getCombatValues()
- if (arme.system.typearme == "contact" || arme.system.typearme == "contactjet") {
- let bonusDefense = this.getBonusDefenseFromTalents()
- arme.system.competence = foundry.utils.duplicate(this.items.find(item => item.type == "competence" && item.name.toLowerCase() == "mêlée"))
- arme.system.attrKey = "pui"
- arme.system.totalDegats = arme.system.degats + "+" + combat.bonusDegatsTotal
- arme.system.totalOffensif = this.system.attributs.pui.value + arme.system.competence.system.niveau + arme.system.bonusmaniementoff + (this.system.combat.monte ? 3 : 0)
- arme.system.totalDefensif = combat.defenseTotal + arme.system.competence.system.niveau + arme.system.seuildefense + bonusDefense + (this.system.combat.monte ? 3 : 0)
- console.log("Arme", arme.system.totalDefensif, combat, arme.system.competence.system.niveau, arme.system.seuildefense, bonusDefense)
- arme.system.isdefense = true
- arme.system.isMelee = true
- arme.system.isDistance = false
- }
- if (arme.system.typearme == "jet" || arme.system.typearme == "tir") {
- arme.system.competence = foundry.utils.duplicate(this.items.find(item => item.type == "competence" && item.name.toLowerCase() == "armes à distance"))
- arme.system.attrKey = "adr"
- arme.system.totalOffensif = this.system.attributs.adr.value + arme.system.competence.system.niveau + arme.system.bonusmaniementoff
- arme.system.totalDegats = arme.system.degats
- arme.system.isMelee = false
- arme.system.isDistance = true
- if (arme.system.isdefense) {
- arme.system.totalDefensif = combat.defenseTotal + arme.system.competence.system.niveau + arme.system.seuildefense
- }
- }
- return arme
- }
-
- /* -------------------------------------------- */
- getItemSorted(types) {
- let items = this.items.filter(item => types.includes(item.type)) || []
- MournbladeCYD2Utility.sortArrayObjectsByName(items)
- return items
- }
- getWeapons() {
- let armes = []
- for (let arme of this.items) {
- if (arme.type == "arme") {
- armes.push(this.prepareArme(arme))
- }
- }
- MournbladeCYD2Utility.sortArrayObjectsByName(armes)
- return armes
- }
- getMonnaies() {
- return this.getItemSorted(["monnaie"])
- }
- getEquipments() {
- return this.getItemSorted(["equipement"])
- }
- getArtefacts() {
- return this.getItemSorted(["artefact"])
- }
- getArmors() {
- return this.getItemSorted(["protection"])
- }
- getHistoriques() {
- return this.getItemSorted(["historique"])
- }
- getProfils() {
- return this.getItemSorted(["profil"])
- }
- getTalents() {
- return this.getItemSorted(["talent"])
- }
- getRessources() {
- return this.getItemSorted(["ressource"])
- }
- getContacts() {
- return this.getItemSorted(["contact"])
- }
- getMutations() {
- return this.getItemSorted(["mutation"])
- }
- getDons() {
- return this.getItemSorted(["don"])
- }
- getPactes() {
- return this.getItemSorted(["pacte"])
- }
- getTendances() {
- return this.getItemSorted(["tendance"])
- }
- getRunes() {
- return this.getItemSorted(["rune"])
- }
- getTraitsChaotiques() {
- return this.getItemSorted(["traitchaotique"])
- }
- getTraitsEspeces() {
- return this.getItemSorted(["traitespece"])
- }
-
- /* -------------------------------------------- */
- getAspect() {
- return (this.system.balance.loi > this.system.balance.chaos) ? this.system.balance.loi : this.system.balance.chaos
- }
- getMarge() {
- return Math.abs(this.system.balance.loi - this.system.balance.chaos)
- }
- getAlignement() {
- return (this.system.balance.loi > this.system.balance.chaos) ? "loyal" : "chaotique"
- }
-
- /* -------------------------------------------- */
- getSkills() {
- let comp = []
- for (let item of this.items) {
- item = foundry.utils.duplicate(item)
- if (item.type == "competence") {
- item.system.attribut1total = item.system.niveau + (this.system.attributs[item.system.attribut1]?.value || 0)
- item.system.attribut2total = item.system.niveau + (this.system.attributs[item.system.attribut2]?.value || 0)
- item.system.attribut3total = item.system.niveau + (this.system.attributs[item.system.attribut3]?.value || 0)
- if (item.system.niveau == 0) {
- item.system.attribut1total -= 3
- item.system.attribut2total -= 3
- item.system.attribut3total -= 3
- }
- item.system.attribut1label = this.system.attributs[item.system.attribut1]?.label || ""
- item.system.attribut2label = this.system.attributs[item.system.attribut2]?.label || ""
- item.system.attribut3label = this.system.attributs[item.system.attribut3]?.label || ""
- comp.push(item)
- }
- }
- MournbladeCYD2Utility.sortArrayObjectsByName(comp)
- return comp
- }
-
- /* ----------------------- --------------------- */
- addMember(actorId) {
- let members = foundry.utils.duplicate(this.system.members)
- members.push({ id: actorId })
- this.update({ 'system.members': members })
- }
- async removeMember(actorId) {
- let members = this.system.members.filter(it => it.id != actorId)
- this.update({ 'system.members': members })
- }
-
- /* -------------------------------------------- */
- getDefenseBase() {
- return Math.max(this.system.attributs.tre.value, this.system.attributs.adr.value)
- }
-
- /* -------------------------------------------- */
- getVitesseBase() {
- return 5 + __vitesseBonus[this.system.attributs.adr.value]
- }
- /* -------------------------------------------- */
- getProtection() {
- let equipProtection = 0
- for (let armor of this.items) {
- if (armor.type == "protection" && armor.system.equipped) {
- equipProtection += Number(armor.system.protection)
- }
- }
- if (equipProtection < 4) {
- return 4 + equipProtection // Cas des boucliers + sans armure
- }
- return equipProtection // Uniquement la protection des armures + boucliers
- }
-
- /* -------------------------------------------- */
- getCombatValues() {
- if (this.type == "cellule") {
- return {
- initBase: 0,
- initTotal: 0,
- bonusDegats: 0,
- bonusDegatsTotal: 0,
- vitesseBase: 0,
- vitesseTotal: 0,
- defenseBase: 0,
- protection: 0,
- defenseTotal: 0
- }
- }
-
- let combat = {
- initBase: this.system.attributs.adr.value,
- initTotal: this.system.attributs.adr.value + this.system.combat.initbonus,
- bonusDegats: this.getBonusDegats(),
- bonusDegatsTotal: this.getBonusDegats() + this.system.combat.bonusdegats,
- vitesseBase: this.getVitesseBase(),
- vitesseTotal: this.getVitesseBase() + this.system.combat.vitessebonus,
- defenseBase: this.getDefenseBase(),
- protection: this.getProtection(),
- defenseTotal: this.getDefenseBase() + this.system.combat.defensebonus + this.getProtection() - this.getTotalAdversite() + (this.system.combat.defensetotale ? 3 : 0)
- }
- return combat
- }
-
- /* -------------------------------------------- */
- prepareBaseData() {
- }
-
- /* -------------------------------------------- */
- async prepareData() {
- super.prepareData();
- }
-
- /* -------------------------------------------- */
- prepareDerivedData() {
-
- if (this.type == 'personnage') {
- let talentBonus = this.getVigueurBonus()
- let vigueur = Math.floor((this.system.attributs.pui.value + this.system.attributs.tre.value) / 2) + talentBonus + this.system.sante.vigueurmodifier
- if (vigueur != this.system.sante.vigueur) {
- this.update({ 'system.sante.vigueur': vigueur })
- }
-
- let seuilPouvoirBonus = this.getSeuilPouvoirBonus()
- let seuilPouvoir = Math.floor((this.system.attributs.tre.value + this.system.attributs.cla.value) / 2) + seuilPouvoirBonus + this.system.ame.seuilpouvoirmodifier
- if (seuilPouvoir != this.system.ame.seuilpouvoir) {
- this.update({ 'system.ame.seuilpouvoir': seuilPouvoir })
- }
- }
- super.prepareDerivedData()
- }
-
- /* -------------------------------------------- */
- _preUpdate(changed, options, user) {
- if (changed?.system?.sante?.etat && changed?.system?.sante?.etat != this.system.sante.etat) {
- setTimeout(() => {
- this.processCombativite(changed.system.sante)
- }, 800)
- }
- if (changed?.system?.ame?.etat && changed?.system?.ame?.etat != this.system.ame.etat) {
- setTimeout(() => {
- this.processAme(changed.system.ame)
- }, 800)
- }
- super._preUpdate(changed, options, user);
- }
-
- /* -------------------------------------------- */
- _onUpdate(data, options, user) {
- super._onUpdate(data, options, user);
- }
- /* -------------------------------------------- */
- getItemById(id) {
- let item = this.items.find(item => item.id == id);
- if (item) {
- item = foundry.utils.duplicate(item)
- }
- return item;
- }
-
- /* -------------------------------------------- */
- async equipItem(itemId) {
- let item = this.items.find(item => item.id == itemId)
- if (item && item.system) {
- let update = { _id: item.id, "system.equipped": !item.system.equipped }
- await this.updateEmbeddedDocuments('Item', [update]); // Updates one EmbeddedEntity
- }
- }
-
- /* -------------------------------------------- */
- editItemField(itemId, itemType, itemField, dataType, value) {
- let item = this.items.find(item => item.id == itemId)
- if (item) {
- console.log("Item ", item, itemField, dataType, value)
- if (dataType.toLowerCase() == "number") {
- value = Number(value)
- } else {
- value = String(value)
- }
- let update = { _id: item.id, [`system.${itemField}`]: value };
- this.updateEmbeddedDocuments("Item", [update])
- }
- }
-
- /* -------------------------------------------- */
- checkAttribut(attribut, minLevel) {
- let attr = this.system.attributs.find(at => at.labelnorm == attribut.toLowerCase())
- if (attr && attr.value >= minLevel) {
- return { isValid: true, attr: foundry.utils.duplicate(attr) }
- }
- return { isValid: false }
- }
- /* -------------------------------------------- */
- checkAttributOrCompetenceLevel(compName, minLevel) {
- let comp = this.items.find(i => i.type == "competence" && i.name.toLowerCase() == compName.toLowerCase() && i.system.niveau >= minLevel)
- if (comp) {
- return { isValid: true, item: foundry.utils.duplicate(comp) }
- } else {
- for (let attrKey in this.system.attributs) {
- if (this.system.attributs[attrKey].label.toLowerCase() == compName.toLowerCase() && this.system.attributs[attrKey].value >= minLevel) {
- return { isValid: true, item: foundry.utils.duplicate(this.system.attributs[attrKey]) }
- }
- }
- }
- return { isValid: false, warningMessage: `Prérequis insuffisant : la compétence/attribut ${compName} doit être de niveau ${minLevel} au minimum` }
- }
- /* -------------------------------------------- */
- addCompetenceBonus(compName, bonus, baCost) {
- let comp = this.items.find(i => i.type == "competence" && i.name.toLowerCase() == compName.toLowerCase())
- if (comp) {
- comp = foundry.utils.duplicate(comp)
- comp.system.bonus = bonus
- comp.system.baCost = baCost
- return { isValid: true, item: comp }
- }
- return { isValid: false, warningMessage: `Compétence ${compName} non trouvée` }
- }
- /* -------------------------------------------- */
- checkIfCompetence(compName) {
- let comp = this.items.find(i => i.type == "competence" && i.name.toLowerCase() == compName.toLowerCase())
- if (comp) {
- return { isValid: true, item: comp }
- }
- return { isValid: false }
- }
- /* -------------------------------------------- */
- getVigueur() {
- return this.system.sante.vigueur
- }
-
- /* -------------------------------------------- */
- getVigueurBonus() {
- let talents = this.items.filter(item => item.type == "talent" && item.system.isautomated)
- let bonus = 0
- for (let talent of talents) {
- for (let auto of talent.system.automations) {
- if (auto.eventtype == "bonus-permanent" && auto.bonusname == "vigueur") {
- bonus += Number(auto.bonus || 0)
- }
- }
- }
- return bonus
- }
-
- /* -------------------------------------------- */
- getSeuilPouvoir() {
- return this.system.ame.seuilpouvoir
- }
-
- /* -------------------------------------------- */
- getSeuilPouvoirBonus() {
- let talents = this.items.filter(item => item.type == "talent" && item.system.isautomated)
- let bonus = 0
- for (let talent of talents) {
- for (let auto of talent.system.automations) {
- if (auto.eventtype == "bonus-permanent" && auto.bonusname == "seuilpouvoir") {
- bonus += Number(auto.bonus || 0)
- }
- }
- }
- return bonus
- }
-
- /* -------------------------------------------- */
- getAmeMax() {
- return Math.min(this.system.ame.max || this.system.ame.nbame, this.system.ame.nbame)
- }
-
- /* -------------------------------------------- */
- getBonneAventure() {
- return this.system.bonneaventure.actuelle
- }
- /* -------------------------------------------- */
- checkBonneAventure(cost) {
- return (this.system.bonneaventure.actuelle >= cost)
- }
- /* -------------------------------------------- */
- changeBonneAventure(value) {
- let newBA = this.system.bonneaventure.actuelle
- newBA += value
- this.update({ 'system.bonneaventure.actuelle': newBA })
- }
-
- /* -------------------------------------------- */
- getEclat() {
- return this.system.eclat.value
- }
-
- /* -------------------------------------------- */
- changeEclat(value) {
- let newE = this.system.eclat.value
- newE += value
- this.update({ 'system.eclat.value': newE })
- }
-
- /* -------------------------------------------- */
- compareName(a, b) {
- if (a.name < b.name) {
- return -1;
- }
- if (a.name > b.name) {
- return 1;
- }
- return 0;
- }
-
- /* -------------------------------------------- */
- getAttribute(attrKey) {
- return this.system.attributes[attrKey]
- }
-
- /* -------------------------------------------- */
- getBonusDegats() {
- return 0;
- }
-
- /* -------------------------------------------- */
- changeEtatCombativite(value) {
- if (value === "vaincu") {
- value = 200
- }
- let sante = foundry.utils.duplicate(this.system.sante)
- sante.etat += Number(value)
- sante.etat = Math.max(sante.etat, 0)
- sante.etat = Math.min(sante.etat, this.system.sante.nbcombativite)
- this.update({ 'system.sante': sante })
- if (sante.etat == this.system.sante.nbcombativite) {
- ChatMessage.create({ content: `${this.name} est vaincu !` })
- }
- // Duplicated ! this.processCombativite(sante)
- }
-
- /* -------------------------------------------- */
- changeEtatAme(value) {
- if (value === "brise") {
- value = 200
- }
- let ame = foundry.utils.duplicate(this.system.ame)
- ame.etat += Number(value)
- ame.etat = Math.max(ame.etat, 0)
- // L'état ne peut pas dépasser le maximum actuel d'âme
- let maxAme = Math.min(this.system.ame.max || this.system.ame.nbame, this.system.ame.nbame - 1)
- ame.etat = Math.min(ame.etat, maxAme)
- this.update({ 'system.ame': ame })
- if (ame.etat >= maxAme) {
- ChatMessage.create({ content: `${this.name} est brisé !` })
- }
- }
-
- /* -------------------------------------------- */
- processCombativite(sante) {
- sante = sante || foundry.utils.duplicate(this.system.sante)
- // Gestion des états affaibli et très affaibli
- if (sante.etat == this.system.sante.nbcombativite - 2 || sante.etat == this.system.sante.nbcombativite - 1) {
- if (sante.etat == this.system.sante.nbcombativite - 2 && this.items.find(item => item.type == "talent" && item.name.toLowerCase() == "encaissement")) {
- ChatMessage.create({ content: `${this.name} ne subit pas les 2 adversités rouge grâce à Encaissement. Pensez à les ajouter à la fin de la scène !` })
- } else if (sante.etat == this.system.sante.nbcombativite - 1 && this.items.find(item => item.type == "talent" && item.name.toLowerCase().includes("vaillant"))) {
- ChatMessage.create({ content: `${this.name} ne subit pas les 2 adversités rouge grâce à Vaillant. Pensez à les ajouter à la fin de la scène !` })
- } else {
- ChatMessage.create({ content: `${this.name} subit 2 adversités rouge !` })
- this.incDecAdversite("rouge", 2)
- }
- }
- }
-
- /* -------------------------------------------- */
- processAme(ame) {
- ame = ame || foundry.utils.duplicate(this.system.ame)
- let maxAme = Math.min(this.system.ame.max || this.system.ame.nbame, this.system.ame.nbame - 1)
- // Gestion des états Traumatisé, Très Traumatisé et Brisé en fonction du maximum actuel
- // Les seuils sont calculés par rapport au maximum d'âme actuel
- if (maxAme >= 2 && ame.etat >= maxAme - 2) {
- if (ame.etat == maxAme - 2) {
- ChatMessage.create({ content: `${this.name} est Traumatisé !` })
- } else if (ame.etat == maxAme - 1) {
- ChatMessage.create({ content: `${this.name} est Très Traumatisé !` })
- } else if (ame.etat >= maxAme) {
- ChatMessage.create({ content: `${this.name} est Brisé !` })
- }
- } else if (ame.etat >= maxAme) {
- ChatMessage.create({ content: `${this.name} est Brisé !` })
- }
- }
-
- /* -------------------------------------------- */
- async equipGear(equipmentId) {
- let item = this.items.find(item => item.id == equipmentId);
- if (item?.system?.data) {
- let update = { _id: item.id, "system.equipped": !item.system.equipped };
- await this.updateEmbeddedDocuments('Item', [update]); // Updates one EmbeddedEntity
- }
- }
-
- /* -------------------------------------------- */
- getSubActors() {
- let subActors = [];
- for (let id of this.system.subactors) {
- subActors.push(foundry.utils.duplicate(game.actors.get(id)));
- }
- return subActors;
- }
- /* -------------------------------------------- */
- async addSubActor(subActorId) {
- let subActors = foundry.utils.duplicate(this.system.subactors);
- subActors.push(subActorId);
- await this.update({ 'system.subactors': subActors });
- }
- /* -------------------------------------------- */
- async delSubActor(subActorId) {
- let newArray = [];
- for (let id of this.system.subactors) {
- if (id != subActorId) {
- newArray.push(id);
- }
- }
- await this.update({ 'system.subactors': newArray });
- }
-
- /* -------------------------------------------- */
- getTotalAdversite() {
- return this.system.adversite.bleue + this.system.adversite.rouge + this.system.adversite.noire
- }
-
- /* -------------------------------------------- */
- async incDecAdversite(adv, incDec = 0) {
- let adversite = foundry.utils.duplicate(this.system.adversite)
- adversite[adv] += Number(incDec)
- adversite[adv] = Math.max(adversite[adv], 0)
- adversite[adv] = Math.min(adversite[adv], 20)
- this.update({ 'system.adversite': adversite })
- }
- /* -------------------------------------------- */
- async incDecQuantity(objetId, incDec = 0) {
- let objetQ = this.items.get(objetId)
- if (objetQ) {
- let newQ = objetQ.system.quantite + incDec
- newQ = Math.max(newQ, 0)
- await this.updateEmbeddedDocuments('Item', [{ _id: objetQ.id, 'system.quantite': newQ }]); // pdates one EmbeddedEntity
- }
- }
-
- /* -------------------------------------------- */
- computeRichesse() {
- let valueSC = 0
- for (let monnaie of this.items) {
- if (monnaie.type == "monnaie") {
- valueSC += Number(monnaie.system.prixsc) * Number(monnaie.system.quantite)
- }
- }
- return MournbladeCYD2Utility.computeMonnaieDetails(valueSC)
- }
-
- /* -------------------------------------------- */
- computeValeurEquipement() {
- let valueSC = 0
- for (let equip of this.items) {
- if (equip.type == "equipement" || equip.type == "arme" || equip.type == "protection") {
- valueSC += Number(equip.system.prixsc) * Number(equip.system.quantite ?? 1)
- valueSC += (Number(equip.system.prixca) * Number(equip.system.quantite ?? 1)) * 20
- valueSC += (Number(equip.system.prixpo) * Number(equip.system.quantite ?? 1)) * 400
- }
- }
- return MournbladeCYD2Utility.computeMonnaieDetails(valueSC)
- }
-
- /* -------------------------------------------- */
- getCompetence(compId) {
- return this.items.get(compId)
- }
-
- /* -------------------------------------------- */
- async setPredilectionUsed(compId, predIdx) {
- let comp = this.items.get(compId)
- let pred = foundry.utils.duplicate(comp.system.predilections)
- pred[predIdx].used = true
- await this.updateEmbeddedDocuments('Item', [{ _id: compId, 'system.predilections': pred }])
- }
-
- /* -------------------------------------------- */
- getInitiativeScore() {
- let init = this.getFlag("world", "last-initiative")
- return init || -1
- }
-
- /* -------------------------------------------- */
- getBestAttackValue() {
- let attackList = this.items.filter(item => (item.type == "arme" || item.type == "talent") && item.system.equipped)
- let maxOff = 0
- let bestArme
- for (let arme of attackList) {
- if (arme.type == "arme") {
- arme = this.prepareArme(arme)
- }
- if (arme.system.totalOffensif > maxOff) {
- maxOff = arme.system.totalOffensif
- bestArme = foundry.utils.duplicate(arme)
- }
- }
- return bestArme
- }
-
- /* -------------------------------------------- */
- getBestDefenseValue() {
- let defenseList = this.items.filter(item => (item.type == "arme") && item.system.equipped)
- let maxDef = 0
- let bestArme
- for (let arme of defenseList) {
- if (arme.type == "arme") {
- arme = this.prepareArme(arme)
- }
- if (arme.system.totalDefensif > maxDef) {
- maxDef = arme.system.totalDefensif
- bestArme = foundry.utils.duplicate(arme)
- }
- }
- return bestArme
- }
-
- /* -------------------------------------------- */
- searchRelevantTalents(competence) {
- let talents = []
-
- for (let talent of this.items) {
- if (talent.type == "talent" && talent.system.isautomated && talent.system.automations.length > 0) {
- for (let auto of talent.system.automations) {
- if (auto.eventtype === "prepare-roll") {
- if (auto.competence.toLowerCase() == competence.name.toLowerCase()) {
- talent = foundry.utils.duplicate(talent)
- talent.system.bonus = auto.bonus
- talent.system.baCost = auto.baCost
- talents.push(talent)
- }
- }
- }
- }
- }
- return talents
- }
-
- /* -------------------------------------------- */
- buildListeAdversites() {
- return []
- }
-
- /* -------------------------------------------- */
- getCommonRollData(attrKey = undefined, compId = undefined, compName = undefined) {
- let rollData = MournbladeCYD2Utility.getBasicRollData()
- rollData.alias = this.name
- rollData.actorImg = this.img
- rollData.actorId = this.id
- rollData.tokenId = this.token?.id
- rollData.img = this.img
- rollData.attributs = MournbladeCYD2Utility.getAttributs()
- rollData.maitriseId = "none"
- rollData.nbEclat = this.system.eclat.value
- rollData.nbBA = this.system.bonneaventure.actuelle
- rollData.nbAdversites = this.getTotalAdversite()
- rollData.talents = []
- rollData.attrKey2 = "none"
- rollData.coupDevastateur = this.items.find(it => it.type == "talent" && it.name.toLowerCase() == "coup dévastateur" && !it.system.used)
- rollData.hasAmbidextre = this.items.find(it => it.type == "talent" && it.name.toLowerCase() == "ambidextre")
- rollData.hasFeinte = this.system.bonneaventure.actuelle > 0 && this.items.find(it => it.type == "talent" && it.name.toLowerCase() == "feinte")
- rollData.isMonte = this.system.combat.monte
- rollData.config = game.system.mournbladecyd2.config
-
- if (attrKey) {
- rollData.attrKey = attrKey
- if (attrKey != "tochoose") {
- rollData.actionImg = "systems/fvtt-mournblade-cyd2/assets/icons/" + this.system.attributs[attrKey].labelnorm + ".webp"
- rollData.attr = foundry.utils.duplicate(this.system.attributs[attrKey])
- }
- }
- if (compId) {
- rollData.competence = foundry.utils.duplicate(this.items.get(compId) || {})
- let maitrises = [{ key: "none", label: "Aucune" }]
- rollData.competence.system.predilections.forEach(function (item) {
- if (item.maitrise) {
- maitrises.push({ key: item.id, label: item.name });
- }
- })
- rollData.maitrises = maitrises // rollData.competence.system.predilections.filter(p => p.maitrise)
- rollData.actionImg = rollData.competence?.img
- rollData.talents = this.searchRelevantTalents(rollData.competence)
- }
- if (compName) {
- rollData.competence = foundry.utils.duplicate(this.items.find(item => item.name.toLowerCase() == compName.toLowerCase()) || {})
- rollData.actionImg = rollData.competence?.img
- }
- return rollData
- }
-
- /* -------------------------------------------- */
- async rollAttribut(attrKey, isInit = false) {
- let rollData = this.getCommonRollData(attrKey)
- rollData.multiplier = (isInit) ? 1 : 2
- rollData.isInit = isInit
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
-
- /* -------------------------------------------- */
- async rollCompetence(attrKey, compId) {
- let rollData = this.getCommonRollData(attrKey, compId)
- rollData.multiplier = 1 // Attr multiplier, always 1 in competence mode
- console.log("RollDatra", rollData)
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
-
- /* -------------------------------------------- */
- async rollArmeOffensif(armeId) {
- let arme = this.items.get(armeId)
- if (arme.type == "arme") {
- arme = this.prepareArme(arme)
- }
- let rollData = this.getCommonRollData(arme.system.attrKey, arme.system.competence._id)
- rollData.arme = arme
- MournbladeCYD2Utility.updateWithTarget(rollData)
- console.log("ARME!", rollData)
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
- /* -------------------------------------------- */
- async rollAssommer() {
- let rollData = this.getCommonRollData("pui", undefined, "Filouterie")
- rollData.assomer = true
- rollData.conditionsCommunes = true
- MournbladeCYD2Utility.updateWithTarget(rollData)
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
- /* -------------------------------------------- */
- async rollCoupBas() {
- let rollData = this.getCommonRollData("pui", undefined, "Mêlée")
- rollData.coupBas = true
- rollData.conditionsCommunes = true
- MournbladeCYD2Utility.updateWithTarget(rollData)
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
- /* -------------------------------------------- */
- async rollImmobiliser() {
- let rollData = this.getCommonRollData("pui", undefined, "Mêlée")
- rollData.immobiliser = true
- rollData.conditionsCommunes = true
- rollData.cibleconsciente = true
- MournbladeCYD2Utility.updateWithTarget(rollData)
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
- /* -------------------------------------------- */
- async rollRepousser() {
- let rollData = this.getCommonRollData("pui", undefined, "Mêlée")
- rollData.repousser = true
- rollData.conditionsCommunes = true
- rollData.cibleconsciente = true
- MournbladeCYD2Utility.updateWithTarget(rollData)
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
- /* -------------------------------------------- */
- async rollDesengager() {
- let rollData = this.getCommonRollData("adr", undefined, "Mouvements")
- rollData.desengager = true
- rollData.conditionsCommunes = true
- MournbladeCYD2Utility.updateWithTarget(rollData)
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
-
- /* -------------------------------------------- */
- async rollArmeDegats(armeId, targetVigueur = undefined, rollDataInput = undefined) {
- let arme = this.items.get(armeId)
- if (arme.type == "arme") {
- arme = this.prepareArme(arme)
- }
- console.log("DEGATS", arme, targetVigueur, rollDataInput)
- let roll
- let bonus = 0
- let bonus2 = 0
-
- if (rollDataInput?.applyCoupDevastateur) {
- bonus2 = Math.floor(this.system.attributs.pui.value / 2)
- let talent = this.items.find(item => item.type == "talent" && item.name.toLowerCase() == "coup dévastateur")
- this.updateEmbeddedDocuments('Item', [{ _id: talent.id, 'system.used': true }])
- }
-
- if (rollDataInput?.isHeroique) {
- if (rollDataInput?.attaqueCharge) {
- bonus = 5
- }
- if (rollDataInput?.chargeCavalerie) {
- bonus = 6
- }
- roll = await new Roll("2d10rr10+" + arme.system.totalDegats + "+" + bonus + "+" + bonus2).roll()
- } else {
- if (rollDataInput?.attaqueCharge) {
- bonus = 3
- }
- if (rollDataInput?.chargeCavalerie) {
- bonus = 4
- }
- roll = await new Roll("1d10+" + arme.system.totalDegats + "+" + bonus + "+" + bonus2).roll()
- }
- await MournbladeCYD2Utility.showDiceSoNice(roll, game.settings.get("core", "rollMode"));
- let nbEtatPerdus = 0
- if (targetVigueur) {
- nbEtatPerdus = Math.floor(roll.total / targetVigueur)
- }
- //console.log(roll)
- let rollData = {
- arme: arme,
- finalResult: roll.total,
- formula: roll.formula,
- alias: this.name,
- actorImg: this.img,
- actorId: this.id,
- defenderTokenId: rollDataInput?.defenderTokenId,
- actionImg: arme.img,
- targetVigueur: targetVigueur,
- nbEtatPerdus: nbEtatPerdus
- }
- MournbladeCYD2Utility.createChatWithRollMode(rollData.alias, {
- content: await renderTemplate(`systems/fvtt-mournblade-cyd2/templates/chat-degats-result.html`, rollData)
- })
-
- if (rollDataInput?.defenderTokenId && nbEtatPerdus) {
- MournbladeCYD2Utility.applyCombativite(rollDataInput, nbEtatPerdus)
- }
-
- }
-}
diff --git a/.history/modules/mournblade-cyd2-actor_20251026083833.js b/.history/modules/mournblade-cyd2-actor_20251026083833.js
deleted file mode 100644
index 972b12a..0000000
--- a/.history/modules/mournblade-cyd2-actor_20251026083833.js
+++ /dev/null
@@ -1,904 +0,0 @@
-/* -------------------------------------------- */
-import { MournbladeCYD2Utility } from "./mournblade-cyd2-utility.js";
-import { MournbladeCYD2RollDialog } from "./mournblade-cyd2-roll-dialog.js";
-
-/* -------------------------------------------- */
-const __degatsBonus = [-2, -2, -1, -1, 0, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 8, 8, 9, 9, 10, 10]
-const __vitesseBonus = [-2, -2, -1, -1, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8]
-
-/* -------------------------------------------- */
-/**
- * Extend the base Actor entity by defining a custom roll data structure which is ideal for the Simple system.
- * @extends {Actor}
- */
-export class MournbladeCYD2Actor extends Actor {
-
- /* -------------------------------------------- */
- /**
- * Override the create() function to provide additional SoS functionality.
- *
- * This overrided create() function adds initial items
- * Namely: Basic skills, money,
- *
- * @param {Object} data Barebones actor data which this function adds onto.
- * @param {Object} options (Unused) Additional options which customize the creation workflow.
- *
- */
-
- static async create(data, options) {
-
- // Case of compendium global import
- if (data instanceof Array) {
- return super.create(data, options);
- }
- // If the created actor has items (only applicable to duplicated actors) bypass the new actor creation logic
- if (data.items) {
- let actor = super.create(data, options);
- return actor;
- }
-
- if (data.type == 'personnage') {
- const skills = await MournbladeCYD2Utility.loadCompendium("fvtt-mournblade-cyd2.skills")
- data.items = skills.map(i => i.toObject())
- }
- if (data.type == 'creature') {
- const skills = await MournbladeCYD2Utility.loadCompendium("fvtt-mournblade-cyd2.skills-creatures")
- data.items = skills.map(i => i.toObject())
- data.items.push({ name: "Arme naturelle 1", type: 'arme', img: "systems/fvtt-mournblade-cyd2/assets/icons/melee.webp", system: { typearme: "contact", bonusmaniementoff: 0, seuildefense: 0, degats: "0" } })
- data.items.push({ name: "Arme naturelle 2", type: 'arme', img: "systems/fvtt-mournblade-cyd2/assets/icons/melee.webp", system: { typearme: "contact", bonusmaniementoff: 0, seuildefense: 0, degats: "0" } })
- }
-
- return super.create(data, options);
- }
-
- /* -------------------------------------------- */
- getBonusDefenseFromTalents() {
- let talents = this.items.filter(item => item.type == "talent" && item.system.isautomated)
- let bonus = 0
- for (let talent of talents) {
- for (let auto of talent.system.automations) {
- if (auto.eventtype == "bonus-permanent" && auto.bonusname == "bonus-defensif") {
- bonus += Number(auto.bonus || 0)
- }
- }
- }
- return bonus
- }
-
- /* -------------------------------------------- */
- prepareArme(arme) {
- if (this.type == "cellule") {
- return arme
- }
-
- arme = foundry.utils.duplicate(arme)
- let combat = this.getCombatValues()
- if (arme.system.typearme == "contact" || arme.system.typearme == "contactjet") {
- let bonusDefense = this.getBonusDefenseFromTalents()
- arme.system.competence = foundry.utils.duplicate(this.items.find(item => item.type == "competence" && item.name.toLowerCase() == "mêlée"))
- arme.system.attrKey = "pui"
- arme.system.totalDegats = arme.system.degats + "+" + combat.bonusDegatsTotal
- arme.system.totalOffensif = this.system.attributs.pui.value + arme.system.competence.system.niveau + arme.system.bonusmaniementoff + (this.system.combat.monte ? 3 : 0)
- arme.system.totalDefensif = combat.defenseTotal + arme.system.competence.system.niveau + arme.system.seuildefense + bonusDefense + (this.system.combat.monte ? 3 : 0)
- console.log("Arme", arme.system.totalDefensif, combat, arme.system.competence.system.niveau, arme.system.seuildefense, bonusDefense)
- arme.system.isdefense = true
- arme.system.isMelee = true
- arme.system.isDistance = false
- }
- if (arme.system.typearme == "jet" || arme.system.typearme == "tir") {
- arme.system.competence = foundry.utils.duplicate(this.items.find(item => item.type == "competence" && item.name.toLowerCase() == "armes à distance"))
- arme.system.attrKey = "adr"
- arme.system.totalOffensif = this.system.attributs.adr.value + arme.system.competence.system.niveau + arme.system.bonusmaniementoff
- arme.system.totalDegats = arme.system.degats
- arme.system.isMelee = false
- arme.system.isDistance = true
- if (arme.system.isdefense) {
- arme.system.totalDefensif = combat.defenseTotal + arme.system.competence.system.niveau + arme.system.seuildefense
- }
- }
- return arme
- }
-
- /* -------------------------------------------- */
- getItemSorted(types) {
- let items = this.items.filter(item => types.includes(item.type)) || []
- MournbladeCYD2Utility.sortArrayObjectsByName(items)
- return items
- }
- getWeapons() {
- let armes = []
- for (let arme of this.items) {
- if (arme.type == "arme") {
- armes.push(this.prepareArme(arme))
- }
- }
- MournbladeCYD2Utility.sortArrayObjectsByName(armes)
- return armes
- }
- getMonnaies() {
- return this.getItemSorted(["monnaie"])
- }
- getEquipments() {
- return this.getItemSorted(["equipement"])
- }
- getArtefacts() {
- return this.getItemSorted(["artefact"])
- }
- getArmors() {
- return this.getItemSorted(["protection"])
- }
- getHistoriques() {
- return this.getItemSorted(["historique"])
- }
- getProfils() {
- return this.getItemSorted(["profil"])
- }
- getTalents() {
- return this.getItemSorted(["talent"])
- }
- getRessources() {
- return this.getItemSorted(["ressource"])
- }
- getContacts() {
- return this.getItemSorted(["contact"])
- }
- getMutations() {
- return this.getItemSorted(["mutation"])
- }
- getDons() {
- return this.getItemSorted(["don"])
- }
- getPactes() {
- return this.getItemSorted(["pacte"])
- }
- getTendances() {
- return this.getItemSorted(["tendance"])
- }
- getRunes() {
- return this.getItemSorted(["rune"])
- }
- getTraitsChaotiques() {
- return this.getItemSorted(["traitchaotique"])
- }
- getTraitsEspeces() {
- return this.getItemSorted(["traitespece"])
- }
-
- /* -------------------------------------------- */
- getAspect() {
- return (this.system.balance.loi > this.system.balance.chaos) ? this.system.balance.loi : this.system.balance.chaos
- }
- getMarge() {
- return Math.abs(this.system.balance.loi - this.system.balance.chaos)
- }
- getAlignement() {
- return (this.system.balance.loi > this.system.balance.chaos) ? "loyal" : "chaotique"
- }
-
- /* -------------------------------------------- */
- getSkills() {
- let comp = []
- for (let item of this.items) {
- item = foundry.utils.duplicate(item)
- if (item.type == "competence") {
- item.system.attribut1total = item.system.niveau + (this.system.attributs[item.system.attribut1]?.value || 0)
- item.system.attribut2total = item.system.niveau + (this.system.attributs[item.system.attribut2]?.value || 0)
- item.system.attribut3total = item.system.niveau + (this.system.attributs[item.system.attribut3]?.value || 0)
- if (item.system.niveau == 0) {
- item.system.attribut1total -= 3
- item.system.attribut2total -= 3
- item.system.attribut3total -= 3
- }
- item.system.attribut1label = this.system.attributs[item.system.attribut1]?.label || ""
- item.system.attribut2label = this.system.attributs[item.system.attribut2]?.label || ""
- item.system.attribut3label = this.system.attributs[item.system.attribut3]?.label || ""
- comp.push(item)
- }
- }
- MournbladeCYD2Utility.sortArrayObjectsByName(comp)
- return comp
- }
-
- /* ----------------------- --------------------- */
- addMember(actorId) {
- let members = foundry.utils.duplicate(this.system.members)
- members.push({ id: actorId })
- this.update({ 'system.members': members })
- }
- async removeMember(actorId) {
- let members = this.system.members.filter(it => it.id != actorId)
- this.update({ 'system.members': members })
- }
-
- /* -------------------------------------------- */
- getDefenseBase() {
- return Math.max(this.system.attributs.tre.value, this.system.attributs.adr.value)
- }
-
- /* -------------------------------------------- */
- getVitesseBase() {
- return 5 + __vitesseBonus[this.system.attributs.adr.value]
- }
- /* -------------------------------------------- */
- getProtection() {
- let equipProtection = 0
- for (let armor of this.items) {
- if (armor.type == "protection" && armor.system.equipped) {
- equipProtection += Number(armor.system.protection)
- }
- }
- if (equipProtection < 4) {
- return 4 + equipProtection // Cas des boucliers + sans armure
- }
- return equipProtection // Uniquement la protection des armures + boucliers
- }
-
- /* -------------------------------------------- */
- getCombatValues() {
- if (this.type == "cellule") {
- return {
- initBase: 0,
- initTotal: 0,
- bonusDegats: 0,
- bonusDegatsTotal: 0,
- vitesseBase: 0,
- vitesseTotal: 0,
- defenseBase: 0,
- protection: 0,
- defenseTotal: 0
- }
- }
-
- let combat = {
- initBase: this.system.attributs.adr.value,
- initTotal: this.system.attributs.adr.value + this.system.combat.initbonus,
- bonusDegats: this.getBonusDegats(),
- bonusDegatsTotal: this.getBonusDegats() + this.system.combat.bonusdegats,
- vitesseBase: this.getVitesseBase(),
- vitesseTotal: this.getVitesseBase() + this.system.combat.vitessebonus,
- defenseBase: this.getDefenseBase(),
- protection: this.getProtection(),
- defenseTotal: this.getDefenseBase() + this.system.combat.defensebonus + this.getProtection() - this.getTotalAdversite() + (this.system.combat.defensetotale ? 3 : 0)
- }
- return combat
- }
-
- /* -------------------------------------------- */
- prepareBaseData() {
- }
-
- /* -------------------------------------------- */
- async prepareData() {
- super.prepareData();
- }
-
- /* -------------------------------------------- */
- prepareDerivedData() {
-
- if (this.type == 'personnage') {
- let talentBonus = this.getVigueurBonus()
- let vigueur = Math.floor((this.system.attributs.pui.value + this.system.attributs.tre.value) / 2) + talentBonus + this.system.sante.vigueurmodifier
- if (vigueur != this.system.sante.vigueur) {
- this.update({ 'system.sante.vigueur': vigueur })
- }
-
- let seuilPouvoirBonus = this.getSeuilPouvoirBonus()
- let seuilPouvoir = Math.floor((this.system.attributs.tre.value + this.system.attributs.cla.value) / 2) + seuilPouvoirBonus + this.system.ame.seuilpouvoirmodifier
- if (seuilPouvoir != this.system.ame.seuilpouvoir) {
- this.update({ 'system.ame.seuilpouvoir': seuilPouvoir })
- }
- }
- super.prepareDerivedData()
- }
-
- /* -------------------------------------------- */
- _preUpdate(changed, options, user) {
- if (changed?.system?.sante?.etat && changed?.system?.sante?.etat != this.system.sante.etat) {
- setTimeout(() => {
- this.processCombativite(changed.system.sante)
- }, 800)
- }
- if (changed?.system?.ame?.etat && changed?.system?.ame?.etat != this.system.ame.etat) {
- // Limiter l'état d'Âme au maximum défini
- let maxAme = this.system.ame.max || this.system.ame.nbame
- if (changed.system.ame.etat > maxAme) {
- changed.system.ame.etat = maxAme
- }
- setTimeout(() => {
- this.processAme(changed.system.ame)
- }, 800)
- }
- // Si le max d'Âme change, ajuster l'état actuel si nécessaire
- if (changed?.system?.ame?.max && changed.system.ame.max != this.system.ame.max) {
- if (this.system.ame.etat > changed.system.ame.max) {
- changed.system.ame.etat = changed.system.ame.max
- }
- }
- super._preUpdate(changed, options, user);
- }
-
- /* -------------------------------------------- */
- _onUpdate(data, options, user) {
- super._onUpdate(data, options, user);
- }
- /* -------------------------------------------- */
- getItemById(id) {
- let item = this.items.find(item => item.id == id);
- if (item) {
- item = foundry.utils.duplicate(item)
- }
- return item;
- }
-
- /* -------------------------------------------- */
- async equipItem(itemId) {
- let item = this.items.find(item => item.id == itemId)
- if (item && item.system) {
- let update = { _id: item.id, "system.equipped": !item.system.equipped }
- await this.updateEmbeddedDocuments('Item', [update]); // Updates one EmbeddedEntity
- }
- }
-
- /* -------------------------------------------- */
- editItemField(itemId, itemType, itemField, dataType, value) {
- let item = this.items.find(item => item.id == itemId)
- if (item) {
- console.log("Item ", item, itemField, dataType, value)
- if (dataType.toLowerCase() == "number") {
- value = Number(value)
- } else {
- value = String(value)
- }
- let update = { _id: item.id, [`system.${itemField}`]: value };
- this.updateEmbeddedDocuments("Item", [update])
- }
- }
-
- /* -------------------------------------------- */
- checkAttribut(attribut, minLevel) {
- let attr = this.system.attributs.find(at => at.labelnorm == attribut.toLowerCase())
- if (attr && attr.value >= minLevel) {
- return { isValid: true, attr: foundry.utils.duplicate(attr) }
- }
- return { isValid: false }
- }
- /* -------------------------------------------- */
- checkAttributOrCompetenceLevel(compName, minLevel) {
- let comp = this.items.find(i => i.type == "competence" && i.name.toLowerCase() == compName.toLowerCase() && i.system.niveau >= minLevel)
- if (comp) {
- return { isValid: true, item: foundry.utils.duplicate(comp) }
- } else {
- for (let attrKey in this.system.attributs) {
- if (this.system.attributs[attrKey].label.toLowerCase() == compName.toLowerCase() && this.system.attributs[attrKey].value >= minLevel) {
- return { isValid: true, item: foundry.utils.duplicate(this.system.attributs[attrKey]) }
- }
- }
- }
- return { isValid: false, warningMessage: `Prérequis insuffisant : la compétence/attribut ${compName} doit être de niveau ${minLevel} au minimum` }
- }
- /* -------------------------------------------- */
- addCompetenceBonus(compName, bonus, baCost) {
- let comp = this.items.find(i => i.type == "competence" && i.name.toLowerCase() == compName.toLowerCase())
- if (comp) {
- comp = foundry.utils.duplicate(comp)
- comp.system.bonus = bonus
- comp.system.baCost = baCost
- return { isValid: true, item: comp }
- }
- return { isValid: false, warningMessage: `Compétence ${compName} non trouvée` }
- }
- /* -------------------------------------------- */
- checkIfCompetence(compName) {
- let comp = this.items.find(i => i.type == "competence" && i.name.toLowerCase() == compName.toLowerCase())
- if (comp) {
- return { isValid: true, item: comp }
- }
- return { isValid: false }
- }
- /* -------------------------------------------- */
- getVigueur() {
- return this.system.sante.vigueur
- }
-
- /* -------------------------------------------- */
- getVigueurBonus() {
- let talents = this.items.filter(item => item.type == "talent" && item.system.isautomated)
- let bonus = 0
- for (let talent of talents) {
- for (let auto of talent.system.automations) {
- if (auto.eventtype == "bonus-permanent" && auto.bonusname == "vigueur") {
- bonus += Number(auto.bonus || 0)
- }
- }
- }
- return bonus
- }
-
- /* -------------------------------------------- */
- getSeuilPouvoir() {
- return this.system.ame.seuilpouvoir
- }
-
- /* -------------------------------------------- */
- getSeuilPouvoirBonus() {
- let talents = this.items.filter(item => item.type == "talent" && item.system.isautomated)
- let bonus = 0
- for (let talent of talents) {
- for (let auto of talent.system.automations) {
- if (auto.eventtype == "bonus-permanent" && auto.bonusname == "seuilpouvoir") {
- bonus += Number(auto.bonus || 0)
- }
- }
- }
- return bonus
- }
-
- /* -------------------------------------------- */
- getAmeMax() {
- return Math.min(this.system.ame.max || this.system.ame.nbame, this.system.ame.nbame)
- }
-
- /* -------------------------------------------- */
- getBonneAventure() {
- return this.system.bonneaventure.actuelle
- }
- /* -------------------------------------------- */
- checkBonneAventure(cost) {
- return (this.system.bonneaventure.actuelle >= cost)
- }
- /* -------------------------------------------- */
- changeBonneAventure(value) {
- let newBA = this.system.bonneaventure.actuelle
- newBA += value
- this.update({ 'system.bonneaventure.actuelle': newBA })
- }
-
- /* -------------------------------------------- */
- getEclat() {
- return this.system.eclat.value
- }
-
- /* -------------------------------------------- */
- changeEclat(value) {
- let newE = this.system.eclat.value
- newE += value
- this.update({ 'system.eclat.value': newE })
- }
-
- /* -------------------------------------------- */
- compareName(a, b) {
- if (a.name < b.name) {
- return -1;
- }
- if (a.name > b.name) {
- return 1;
- }
- return 0;
- }
-
- /* -------------------------------------------- */
- getAttribute(attrKey) {
- return this.system.attributes[attrKey]
- }
-
- /* -------------------------------------------- */
- getBonusDegats() {
- return 0;
- }
-
- /* -------------------------------------------- */
- changeEtatCombativite(value) {
- if (value === "vaincu") {
- value = 200
- }
- let sante = foundry.utils.duplicate(this.system.sante)
- sante.etat += Number(value)
- sante.etat = Math.max(sante.etat, 0)
- sante.etat = Math.min(sante.etat, this.system.sante.nbcombativite)
- this.update({ 'system.sante': sante })
- if (sante.etat == this.system.sante.nbcombativite) {
- ChatMessage.create({ content: `${this.name} est vaincu !` })
- }
- // Duplicated ! this.processCombativite(sante)
- }
-
- /* -------------------------------------------- */
- changeEtatAme(value) {
- if (value === "brise") {
- value = 200
- }
- let ame = foundry.utils.duplicate(this.system.ame)
- ame.etat += Number(value)
- ame.etat = Math.max(ame.etat, 0)
- // L'état ne peut pas dépasser le maximum actuel d'âme
- let maxAme = Math.min(this.system.ame.max || this.system.ame.nbame, this.system.ame.nbame - 1)
- ame.etat = Math.min(ame.etat, maxAme)
- this.update({ 'system.ame': ame })
- if (ame.etat >= maxAme) {
- ChatMessage.create({ content: `${this.name} est brisé !` })
- }
- }
-
- /* -------------------------------------------- */
- processCombativite(sante) {
- sante = sante || foundry.utils.duplicate(this.system.sante)
- // Gestion des états affaibli et très affaibli
- if (sante.etat == this.system.sante.nbcombativite - 2 || sante.etat == this.system.sante.nbcombativite - 1) {
- if (sante.etat == this.system.sante.nbcombativite - 2 && this.items.find(item => item.type == "talent" && item.name.toLowerCase() == "encaissement")) {
- ChatMessage.create({ content: `${this.name} ne subit pas les 2 adversités rouge grâce à Encaissement. Pensez à les ajouter à la fin de la scène !` })
- } else if (sante.etat == this.system.sante.nbcombativite - 1 && this.items.find(item => item.type == "talent" && item.name.toLowerCase().includes("vaillant"))) {
- ChatMessage.create({ content: `${this.name} ne subit pas les 2 adversités rouge grâce à Vaillant. Pensez à les ajouter à la fin de la scène !` })
- } else {
- ChatMessage.create({ content: `${this.name} subit 2 adversités rouge !` })
- this.incDecAdversite("rouge", 2)
- }
- }
- }
-
- /* -------------------------------------------- */
- processAme(ame) {
- ame = ame || foundry.utils.duplicate(this.system.ame)
- let maxAme = Math.min(this.system.ame.max || this.system.ame.nbame, this.system.ame.nbame - 1)
- // Gestion des états Traumatisé, Très Traumatisé et Brisé en fonction du maximum actuel
- // Les seuils sont calculés par rapport au maximum d'âme actuel
- if (maxAme >= 2 && ame.etat >= maxAme - 2) {
- if (ame.etat == maxAme - 2) {
- ChatMessage.create({ content: `${this.name} est Traumatisé !` })
- } else if (ame.etat == maxAme - 1) {
- ChatMessage.create({ content: `${this.name} est Très Traumatisé !` })
- } else if (ame.etat >= maxAme) {
- ChatMessage.create({ content: `${this.name} est Brisé !` })
- }
- } else if (ame.etat >= maxAme) {
- ChatMessage.create({ content: `${this.name} est Brisé !` })
- }
- }
-
- /* -------------------------------------------- */
- async equipGear(equipmentId) {
- let item = this.items.find(item => item.id == equipmentId);
- if (item?.system?.data) {
- let update = { _id: item.id, "system.equipped": !item.system.equipped };
- await this.updateEmbeddedDocuments('Item', [update]); // Updates one EmbeddedEntity
- }
- }
-
- /* -------------------------------------------- */
- getSubActors() {
- let subActors = [];
- for (let id of this.system.subactors) {
- subActors.push(foundry.utils.duplicate(game.actors.get(id)));
- }
- return subActors;
- }
- /* -------------------------------------------- */
- async addSubActor(subActorId) {
- let subActors = foundry.utils.duplicate(this.system.subactors);
- subActors.push(subActorId);
- await this.update({ 'system.subactors': subActors });
- }
- /* -------------------------------------------- */
- async delSubActor(subActorId) {
- let newArray = [];
- for (let id of this.system.subactors) {
- if (id != subActorId) {
- newArray.push(id);
- }
- }
- await this.update({ 'system.subactors': newArray });
- }
-
- /* -------------------------------------------- */
- getTotalAdversite() {
- return this.system.adversite.bleue + this.system.adversite.rouge + this.system.adversite.noire
- }
-
- /* -------------------------------------------- */
- async incDecAdversite(adv, incDec = 0) {
- let adversite = foundry.utils.duplicate(this.system.adversite)
- adversite[adv] += Number(incDec)
- adversite[adv] = Math.max(adversite[adv], 0)
- adversite[adv] = Math.min(adversite[adv], 20)
- this.update({ 'system.adversite': adversite })
- }
- /* -------------------------------------------- */
- async incDecQuantity(objetId, incDec = 0) {
- let objetQ = this.items.get(objetId)
- if (objetQ) {
- let newQ = objetQ.system.quantite + incDec
- newQ = Math.max(newQ, 0)
- await this.updateEmbeddedDocuments('Item', [{ _id: objetQ.id, 'system.quantite': newQ }]); // pdates one EmbeddedEntity
- }
- }
-
- /* -------------------------------------------- */
- computeRichesse() {
- let valueSC = 0
- for (let monnaie of this.items) {
- if (monnaie.type == "monnaie") {
- valueSC += Number(monnaie.system.prixsc) * Number(monnaie.system.quantite)
- }
- }
- return MournbladeCYD2Utility.computeMonnaieDetails(valueSC)
- }
-
- /* -------------------------------------------- */
- computeValeurEquipement() {
- let valueSC = 0
- for (let equip of this.items) {
- if (equip.type == "equipement" || equip.type == "arme" || equip.type == "protection") {
- valueSC += Number(equip.system.prixsc) * Number(equip.system.quantite ?? 1)
- valueSC += (Number(equip.system.prixca) * Number(equip.system.quantite ?? 1)) * 20
- valueSC += (Number(equip.system.prixpo) * Number(equip.system.quantite ?? 1)) * 400
- }
- }
- return MournbladeCYD2Utility.computeMonnaieDetails(valueSC)
- }
-
- /* -------------------------------------------- */
- getCompetence(compId) {
- return this.items.get(compId)
- }
-
- /* -------------------------------------------- */
- async setPredilectionUsed(compId, predIdx) {
- let comp = this.items.get(compId)
- let pred = foundry.utils.duplicate(comp.system.predilections)
- pred[predIdx].used = true
- await this.updateEmbeddedDocuments('Item', [{ _id: compId, 'system.predilections': pred }])
- }
-
- /* -------------------------------------------- */
- getInitiativeScore() {
- let init = this.getFlag("world", "last-initiative")
- return init || -1
- }
-
- /* -------------------------------------------- */
- getBestAttackValue() {
- let attackList = this.items.filter(item => (item.type == "arme" || item.type == "talent") && item.system.equipped)
- let maxOff = 0
- let bestArme
- for (let arme of attackList) {
- if (arme.type == "arme") {
- arme = this.prepareArme(arme)
- }
- if (arme.system.totalOffensif > maxOff) {
- maxOff = arme.system.totalOffensif
- bestArme = foundry.utils.duplicate(arme)
- }
- }
- return bestArme
- }
-
- /* -------------------------------------------- */
- getBestDefenseValue() {
- let defenseList = this.items.filter(item => (item.type == "arme") && item.system.equipped)
- let maxDef = 0
- let bestArme
- for (let arme of defenseList) {
- if (arme.type == "arme") {
- arme = this.prepareArme(arme)
- }
- if (arme.system.totalDefensif > maxDef) {
- maxDef = arme.system.totalDefensif
- bestArme = foundry.utils.duplicate(arme)
- }
- }
- return bestArme
- }
-
- /* -------------------------------------------- */
- searchRelevantTalents(competence) {
- let talents = []
-
- for (let talent of this.items) {
- if (talent.type == "talent" && talent.system.isautomated && talent.system.automations.length > 0) {
- for (let auto of talent.system.automations) {
- if (auto.eventtype === "prepare-roll") {
- if (auto.competence.toLowerCase() == competence.name.toLowerCase()) {
- talent = foundry.utils.duplicate(talent)
- talent.system.bonus = auto.bonus
- talent.system.baCost = auto.baCost
- talents.push(talent)
- }
- }
- }
- }
- }
- return talents
- }
-
- /* -------------------------------------------- */
- buildListeAdversites() {
- return []
- }
-
- /* -------------------------------------------- */
- getCommonRollData(attrKey = undefined, compId = undefined, compName = undefined) {
- let rollData = MournbladeCYD2Utility.getBasicRollData()
- rollData.alias = this.name
- rollData.actorImg = this.img
- rollData.actorId = this.id
- rollData.tokenId = this.token?.id
- rollData.img = this.img
- rollData.attributs = MournbladeCYD2Utility.getAttributs()
- rollData.maitriseId = "none"
- rollData.nbEclat = this.system.eclat.value
- rollData.nbBA = this.system.bonneaventure.actuelle
- rollData.nbAdversites = this.getTotalAdversite()
- rollData.talents = []
- rollData.attrKey2 = "none"
- rollData.coupDevastateur = this.items.find(it => it.type == "talent" && it.name.toLowerCase() == "coup dévastateur" && !it.system.used)
- rollData.hasAmbidextre = this.items.find(it => it.type == "talent" && it.name.toLowerCase() == "ambidextre")
- rollData.hasFeinte = this.system.bonneaventure.actuelle > 0 && this.items.find(it => it.type == "talent" && it.name.toLowerCase() == "feinte")
- rollData.isMonte = this.system.combat.monte
- rollData.config = game.system.mournbladecyd2.config
-
- if (attrKey) {
- rollData.attrKey = attrKey
- if (attrKey != "tochoose") {
- rollData.actionImg = "systems/fvtt-mournblade-cyd2/assets/icons/" + this.system.attributs[attrKey].labelnorm + ".webp"
- rollData.attr = foundry.utils.duplicate(this.system.attributs[attrKey])
- }
- }
- if (compId) {
- rollData.competence = foundry.utils.duplicate(this.items.get(compId) || {})
- let maitrises = [{ key: "none", label: "Aucune" }]
- rollData.competence.system.predilections.forEach(function (item) {
- if (item.maitrise) {
- maitrises.push({ key: item.id, label: item.name });
- }
- })
- rollData.maitrises = maitrises // rollData.competence.system.predilections.filter(p => p.maitrise)
- rollData.actionImg = rollData.competence?.img
- rollData.talents = this.searchRelevantTalents(rollData.competence)
- }
- if (compName) {
- rollData.competence = foundry.utils.duplicate(this.items.find(item => item.name.toLowerCase() == compName.toLowerCase()) || {})
- rollData.actionImg = rollData.competence?.img
- }
- return rollData
- }
-
- /* -------------------------------------------- */
- async rollAttribut(attrKey, isInit = false) {
- let rollData = this.getCommonRollData(attrKey)
- rollData.multiplier = (isInit) ? 1 : 2
- rollData.isInit = isInit
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
-
- /* -------------------------------------------- */
- async rollCompetence(attrKey, compId) {
- let rollData = this.getCommonRollData(attrKey, compId)
- rollData.multiplier = 1 // Attr multiplier, always 1 in competence mode
- console.log("RollDatra", rollData)
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
-
- /* -------------------------------------------- */
- async rollArmeOffensif(armeId) {
- let arme = this.items.get(armeId)
- if (arme.type == "arme") {
- arme = this.prepareArme(arme)
- }
- let rollData = this.getCommonRollData(arme.system.attrKey, arme.system.competence._id)
- rollData.arme = arme
- MournbladeCYD2Utility.updateWithTarget(rollData)
- console.log("ARME!", rollData)
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
- /* -------------------------------------------- */
- async rollAssommer() {
- let rollData = this.getCommonRollData("pui", undefined, "Filouterie")
- rollData.assomer = true
- rollData.conditionsCommunes = true
- MournbladeCYD2Utility.updateWithTarget(rollData)
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
- /* -------------------------------------------- */
- async rollCoupBas() {
- let rollData = this.getCommonRollData("pui", undefined, "Mêlée")
- rollData.coupBas = true
- rollData.conditionsCommunes = true
- MournbladeCYD2Utility.updateWithTarget(rollData)
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
- /* -------------------------------------------- */
- async rollImmobiliser() {
- let rollData = this.getCommonRollData("pui", undefined, "Mêlée")
- rollData.immobiliser = true
- rollData.conditionsCommunes = true
- rollData.cibleconsciente = true
- MournbladeCYD2Utility.updateWithTarget(rollData)
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
- /* -------------------------------------------- */
- async rollRepousser() {
- let rollData = this.getCommonRollData("pui", undefined, "Mêlée")
- rollData.repousser = true
- rollData.conditionsCommunes = true
- rollData.cibleconsciente = true
- MournbladeCYD2Utility.updateWithTarget(rollData)
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
- /* -------------------------------------------- */
- async rollDesengager() {
- let rollData = this.getCommonRollData("adr", undefined, "Mouvements")
- rollData.desengager = true
- rollData.conditionsCommunes = true
- MournbladeCYD2Utility.updateWithTarget(rollData)
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
-
- /* -------------------------------------------- */
- async rollArmeDegats(armeId, targetVigueur = undefined, rollDataInput = undefined) {
- let arme = this.items.get(armeId)
- if (arme.type == "arme") {
- arme = this.prepareArme(arme)
- }
- console.log("DEGATS", arme, targetVigueur, rollDataInput)
- let roll
- let bonus = 0
- let bonus2 = 0
-
- if (rollDataInput?.applyCoupDevastateur) {
- bonus2 = Math.floor(this.system.attributs.pui.value / 2)
- let talent = this.items.find(item => item.type == "talent" && item.name.toLowerCase() == "coup dévastateur")
- this.updateEmbeddedDocuments('Item', [{ _id: talent.id, 'system.used': true }])
- }
-
- if (rollDataInput?.isHeroique) {
- if (rollDataInput?.attaqueCharge) {
- bonus = 5
- }
- if (rollDataInput?.chargeCavalerie) {
- bonus = 6
- }
- roll = await new Roll("2d10rr10+" + arme.system.totalDegats + "+" + bonus + "+" + bonus2).roll()
- } else {
- if (rollDataInput?.attaqueCharge) {
- bonus = 3
- }
- if (rollDataInput?.chargeCavalerie) {
- bonus = 4
- }
- roll = await new Roll("1d10+" + arme.system.totalDegats + "+" + bonus + "+" + bonus2).roll()
- }
- await MournbladeCYD2Utility.showDiceSoNice(roll, game.settings.get("core", "rollMode"));
- let nbEtatPerdus = 0
- if (targetVigueur) {
- nbEtatPerdus = Math.floor(roll.total / targetVigueur)
- }
- //console.log(roll)
- let rollData = {
- arme: arme,
- finalResult: roll.total,
- formula: roll.formula,
- alias: this.name,
- actorImg: this.img,
- actorId: this.id,
- defenderTokenId: rollDataInput?.defenderTokenId,
- actionImg: arme.img,
- targetVigueur: targetVigueur,
- nbEtatPerdus: nbEtatPerdus
- }
- MournbladeCYD2Utility.createChatWithRollMode(rollData.alias, {
- content: await renderTemplate(`systems/fvtt-mournblade-cyd2/templates/chat-degats-result.html`, rollData)
- })
-
- if (rollDataInput?.defenderTokenId && nbEtatPerdus) {
- MournbladeCYD2Utility.applyCombativite(rollDataInput, nbEtatPerdus)
- }
-
- }
-}
diff --git a/.history/modules/mournblade-cyd2-actor_20251026083905.js b/.history/modules/mournblade-cyd2-actor_20251026083905.js
deleted file mode 100644
index ebef197..0000000
--- a/.history/modules/mournblade-cyd2-actor_20251026083905.js
+++ /dev/null
@@ -1,904 +0,0 @@
-/* -------------------------------------------- */
-import { MournbladeCYD2Utility } from "./mournblade-cyd2-utility.js";
-import { MournbladeCYD2RollDialog } from "./mournblade-cyd2-roll-dialog.js";
-
-/* -------------------------------------------- */
-const __degatsBonus = [-2, -2, -1, -1, 0, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 8, 8, 9, 9, 10, 10]
-const __vitesseBonus = [-2, -2, -1, -1, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8]
-
-/* -------------------------------------------- */
-/**
- * Extend the base Actor entity by defining a custom roll data structure which is ideal for the Simple system.
- * @extends {Actor}
- */
-export class MournbladeCYD2Actor extends Actor {
-
- /* -------------------------------------------- */
- /**
- * Override the create() function to provide additional SoS functionality.
- *
- * This overrided create() function adds initial items
- * Namely: Basic skills, money,
- *
- * @param {Object} data Barebones actor data which this function adds onto.
- * @param {Object} options (Unused) Additional options which customize the creation workflow.
- *
- */
-
- static async create(data, options) {
-
- // Case of compendium global import
- if (data instanceof Array) {
- return super.create(data, options);
- }
- // If the created actor has items (only applicable to duplicated actors) bypass the new actor creation logic
- if (data.items) {
- let actor = super.create(data, options);
- return actor;
- }
-
- if (data.type == 'personnage') {
- const skills = await MournbladeCYD2Utility.loadCompendium("fvtt-mournblade-cyd2.skills")
- data.items = skills.map(i => i.toObject())
- }
- if (data.type == 'creature') {
- const skills = await MournbladeCYD2Utility.loadCompendium("fvtt-mournblade-cyd2.skills-creatures")
- data.items = skills.map(i => i.toObject())
- data.items.push({ name: "Arme naturelle 1", type: 'arme', img: "systems/fvtt-mournblade-cyd2/assets/icons/melee.webp", system: { typearme: "contact", bonusmaniementoff: 0, seuildefense: 0, degats: "0" } })
- data.items.push({ name: "Arme naturelle 2", type: 'arme', img: "systems/fvtt-mournblade-cyd2/assets/icons/melee.webp", system: { typearme: "contact", bonusmaniementoff: 0, seuildefense: 0, degats: "0" } })
- }
-
- return super.create(data, options);
- }
-
- /* -------------------------------------------- */
- getBonusDefenseFromTalents() {
- let talents = this.items.filter(item => item.type == "talent" && item.system.isautomated)
- let bonus = 0
- for (let talent of talents) {
- for (let auto of talent.system.automations) {
- if (auto.eventtype == "bonus-permanent" && auto.bonusname == "bonus-defensif") {
- bonus += Number(auto.bonus || 0)
- }
- }
- }
- return bonus
- }
-
- /* -------------------------------------------- */
- prepareArme(arme) {
- if (this.type == "cellule") {
- return arme
- }
-
- arme = foundry.utils.duplicate(arme)
- let combat = this.getCombatValues()
- if (arme.system.typearme == "contact" || arme.system.typearme == "contactjet") {
- let bonusDefense = this.getBonusDefenseFromTalents()
- arme.system.competence = foundry.utils.duplicate(this.items.find(item => item.type == "competence" && item.name.toLowerCase() == "mêlée"))
- arme.system.attrKey = "pui"
- arme.system.totalDegats = arme.system.degats + "+" + combat.bonusDegatsTotal
- arme.system.totalOffensif = this.system.attributs.pui.value + arme.system.competence.system.niveau + arme.system.bonusmaniementoff + (this.system.combat.monte ? 3 : 0)
- arme.system.totalDefensif = combat.defenseTotal + arme.system.competence.system.niveau + arme.system.seuildefense + bonusDefense + (this.system.combat.monte ? 3 : 0)
- console.log("Arme", arme.system.totalDefensif, combat, arme.system.competence.system.niveau, arme.system.seuildefense, bonusDefense)
- arme.system.isdefense = true
- arme.system.isMelee = true
- arme.system.isDistance = false
- }
- if (arme.system.typearme == "jet" || arme.system.typearme == "tir") {
- arme.system.competence = foundry.utils.duplicate(this.items.find(item => item.type == "competence" && item.name.toLowerCase() == "armes à distance"))
- arme.system.attrKey = "adr"
- arme.system.totalOffensif = this.system.attributs.adr.value + arme.system.competence.system.niveau + arme.system.bonusmaniementoff
- arme.system.totalDegats = arme.system.degats
- arme.system.isMelee = false
- arme.system.isDistance = true
- if (arme.system.isdefense) {
- arme.system.totalDefensif = combat.defenseTotal + arme.system.competence.system.niveau + arme.system.seuildefense
- }
- }
- return arme
- }
-
- /* -------------------------------------------- */
- getItemSorted(types) {
- let items = this.items.filter(item => types.includes(item.type)) || []
- MournbladeCYD2Utility.sortArrayObjectsByName(items)
- return items
- }
- getWeapons() {
- let armes = []
- for (let arme of this.items) {
- if (arme.type == "arme") {
- armes.push(this.prepareArme(arme))
- }
- }
- MournbladeCYD2Utility.sortArrayObjectsByName(armes)
- return armes
- }
- getMonnaies() {
- return this.getItemSorted(["monnaie"])
- }
- getEquipments() {
- return this.getItemSorted(["equipement"])
- }
- getArtefacts() {
- return this.getItemSorted(["artefact"])
- }
- getArmors() {
- return this.getItemSorted(["protection"])
- }
- getHistoriques() {
- return this.getItemSorted(["historique"])
- }
- getProfils() {
- return this.getItemSorted(["profil"])
- }
- getTalents() {
- return this.getItemSorted(["talent"])
- }
- getRessources() {
- return this.getItemSorted(["ressource"])
- }
- getContacts() {
- return this.getItemSorted(["contact"])
- }
- getMutations() {
- return this.getItemSorted(["mutation"])
- }
- getDons() {
- return this.getItemSorted(["don"])
- }
- getPactes() {
- return this.getItemSorted(["pacte"])
- }
- getTendances() {
- return this.getItemSorted(["tendance"])
- }
- getRunes() {
- return this.getItemSorted(["rune"])
- }
- getTraitsChaotiques() {
- return this.getItemSorted(["traitchaotique"])
- }
- getTraitsEspeces() {
- return this.getItemSorted(["traitespece"])
- }
-
- /* -------------------------------------------- */
- getAspect() {
- return (this.system.balance.loi > this.system.balance.chaos) ? this.system.balance.loi : this.system.balance.chaos
- }
- getMarge() {
- return Math.abs(this.system.balance.loi - this.system.balance.chaos)
- }
- getAlignement() {
- return (this.system.balance.loi > this.system.balance.chaos) ? "loyal" : "chaotique"
- }
-
- /* -------------------------------------------- */
- getSkills() {
- let comp = []
- for (let item of this.items) {
- item = foundry.utils.duplicate(item)
- if (item.type == "competence") {
- item.system.attribut1total = item.system.niveau + (this.system.attributs[item.system.attribut1]?.value || 0)
- item.system.attribut2total = item.system.niveau + (this.system.attributs[item.system.attribut2]?.value || 0)
- item.system.attribut3total = item.system.niveau + (this.system.attributs[item.system.attribut3]?.value || 0)
- if (item.system.niveau == 0) {
- item.system.attribut1total -= 3
- item.system.attribut2total -= 3
- item.system.attribut3total -= 3
- }
- item.system.attribut1label = this.system.attributs[item.system.attribut1]?.label || ""
- item.system.attribut2label = this.system.attributs[item.system.attribut2]?.label || ""
- item.system.attribut3label = this.system.attributs[item.system.attribut3]?.label || ""
- comp.push(item)
- }
- }
- MournbladeCYD2Utility.sortArrayObjectsByName(comp)
- return comp
- }
-
- /* ----------------------- --------------------- */
- addMember(actorId) {
- let members = foundry.utils.duplicate(this.system.members)
- members.push({ id: actorId })
- this.update({ 'system.members': members })
- }
- async removeMember(actorId) {
- let members = this.system.members.filter(it => it.id != actorId)
- this.update({ 'system.members': members })
- }
-
- /* -------------------------------------------- */
- getDefenseBase() {
- return Math.max(this.system.attributs.tre.value, this.system.attributs.adr.value)
- }
-
- /* -------------------------------------------- */
- getVitesseBase() {
- return 5 + __vitesseBonus[this.system.attributs.adr.value]
- }
- /* -------------------------------------------- */
- getProtection() {
- let equipProtection = 0
- for (let armor of this.items) {
- if (armor.type == "protection" && armor.system.equipped) {
- equipProtection += Number(armor.system.protection)
- }
- }
- if (equipProtection < 4) {
- return 4 + equipProtection // Cas des boucliers + sans armure
- }
- return equipProtection // Uniquement la protection des armures + boucliers
- }
-
- /* -------------------------------------------- */
- getCombatValues() {
- if (this.type == "cellule") {
- return {
- initBase: 0,
- initTotal: 0,
- bonusDegats: 0,
- bonusDegatsTotal: 0,
- vitesseBase: 0,
- vitesseTotal: 0,
- defenseBase: 0,
- protection: 0,
- defenseTotal: 0
- }
- }
-
- let combat = {
- initBase: this.system.attributs.adr.value,
- initTotal: this.system.attributs.adr.value + this.system.combat.initbonus,
- bonusDegats: this.getBonusDegats(),
- bonusDegatsTotal: this.getBonusDegats() + this.system.combat.bonusdegats,
- vitesseBase: this.getVitesseBase(),
- vitesseTotal: this.getVitesseBase() + this.system.combat.vitessebonus,
- defenseBase: this.getDefenseBase(),
- protection: this.getProtection(),
- defenseTotal: this.getDefenseBase() + this.system.combat.defensebonus + this.getProtection() - this.getTotalAdversite() + (this.system.combat.defensetotale ? 3 : 0)
- }
- return combat
- }
-
- /* -------------------------------------------- */
- prepareBaseData() {
- }
-
- /* -------------------------------------------- */
- async prepareData() {
- super.prepareData();
- }
-
- /* -------------------------------------------- */
- prepareDerivedData() {
-
- if (this.type == 'personnage') {
- let talentBonus = this.getVigueurBonus()
- let vigueur = Math.floor((this.system.attributs.pui.value + this.system.attributs.tre.value) / 2) + talentBonus + this.system.sante.vigueurmodifier
- if (vigueur != this.system.sante.vigueur) {
- this.update({ 'system.sante.vigueur': vigueur })
- }
-
- let seuilPouvoirBonus = this.getSeuilPouvoirBonus()
- let seuilPouvoir = Math.floor((this.system.attributs.tre.value + this.system.attributs.cla.value) / 2) + seuilPouvoirBonus + this.system.ame.seuilpouvoirmodifier
- if (seuilPouvoir != this.system.ame.seuilpouvoir) {
- this.update({ 'system.ame.seuilpouvoir': seuilPouvoir })
- }
- }
- super.prepareDerivedData()
- }
-
- /* -------------------------------------------- */
- _preUpdate(changed, options, user) {
- if (changed?.system?.sante?.etat && changed?.system?.sante?.etat != this.system.sante.etat) {
- setTimeout(() => {
- this.processCombativite(changed.system.sante)
- }, 800)
- }
- if (changed?.system?.ame?.etat && changed?.system?.ame?.etat != this.system.ame.etat) {
- // Limiter l'état d'Âme au maximum défini
- let maxAme = this.system.ame.max || this.system.ame.nbame
- if (changed.system.ame.etat > maxAme) {
- changed.system.ame.etat = maxAme
- }
- setTimeout(() => {
- this.processAme(changed.system.ame)
- }, 800)
- }
- // Si le max d'Âme change, ajuster l'état actuel si nécessaire
- if (changed?.system?.ame?.max && changed.system.ame.max != this.system.ame.max) {
- if (this.system.ame.etat > changed.system.ame.max) {
- changed.system.ame.etat = changed.system.ame.max
- }
- }
- super._preUpdate(changed, options, user);
- }
-
- /* -------------------------------------------- */
- _onUpdate(data, options, user) {
- super._onUpdate(data, options, user);
- }
- /* -------------------------------------------- */
- getItemById(id) {
- let item = this.items.find(item => item.id == id);
- if (item) {
- item = foundry.utils.duplicate(item)
- }
- return item;
- }
-
- /* -------------------------------------------- */
- async equipItem(itemId) {
- let item = this.items.find(item => item.id == itemId)
- if (item && item.system) {
- let update = { _id: item.id, "system.equipped": !item.system.equipped }
- await this.updateEmbeddedDocuments('Item', [update]); // Updates one EmbeddedEntity
- }
- }
-
- /* -------------------------------------------- */
- editItemField(itemId, itemType, itemField, dataType, value) {
- let item = this.items.find(item => item.id == itemId)
- if (item) {
- console.log("Item ", item, itemField, dataType, value)
- if (dataType.toLowerCase() == "number") {
- value = Number(value)
- } else {
- value = String(value)
- }
- let update = { _id: item.id, [`system.${itemField}`]: value };
- this.updateEmbeddedDocuments("Item", [update])
- }
- }
-
- /* -------------------------------------------- */
- checkAttribut(attribut, minLevel) {
- let attr = this.system.attributs.find(at => at.labelnorm == attribut.toLowerCase())
- if (attr && attr.value >= minLevel) {
- return { isValid: true, attr: foundry.utils.duplicate(attr) }
- }
- return { isValid: false }
- }
- /* -------------------------------------------- */
- checkAttributOrCompetenceLevel(compName, minLevel) {
- let comp = this.items.find(i => i.type == "competence" && i.name.toLowerCase() == compName.toLowerCase() && i.system.niveau >= minLevel)
- if (comp) {
- return { isValid: true, item: foundry.utils.duplicate(comp) }
- } else {
- for (let attrKey in this.system.attributs) {
- if (this.system.attributs[attrKey].label.toLowerCase() == compName.toLowerCase() && this.system.attributs[attrKey].value >= minLevel) {
- return { isValid: true, item: foundry.utils.duplicate(this.system.attributs[attrKey]) }
- }
- }
- }
- return { isValid: false, warningMessage: `Prérequis insuffisant : la compétence/attribut ${compName} doit être de niveau ${minLevel} au minimum` }
- }
- /* -------------------------------------------- */
- addCompetenceBonus(compName, bonus, baCost) {
- let comp = this.items.find(i => i.type == "competence" && i.name.toLowerCase() == compName.toLowerCase())
- if (comp) {
- comp = foundry.utils.duplicate(comp)
- comp.system.bonus = bonus
- comp.system.baCost = baCost
- return { isValid: true, item: comp }
- }
- return { isValid: false, warningMessage: `Compétence ${compName} non trouvée` }
- }
- /* -------------------------------------------- */
- checkIfCompetence(compName) {
- let comp = this.items.find(i => i.type == "competence" && i.name.toLowerCase() == compName.toLowerCase())
- if (comp) {
- return { isValid: true, item: comp }
- }
- return { isValid: false }
- }
- /* -------------------------------------------- */
- getVigueur() {
- return this.system.sante.vigueur
- }
-
- /* -------------------------------------------- */
- getVigueurBonus() {
- let talents = this.items.filter(item => item.type == "talent" && item.system.isautomated)
- let bonus = 0
- for (let talent of talents) {
- for (let auto of talent.system.automations) {
- if (auto.eventtype == "bonus-permanent" && auto.bonusname == "vigueur") {
- bonus += Number(auto.bonus || 0)
- }
- }
- }
- return bonus
- }
-
- /* -------------------------------------------- */
- getSeuilPouvoir() {
- return this.system.ame.seuilpouvoir
- }
-
- /* -------------------------------------------- */
- getSeuilPouvoirBonus() {
- let talents = this.items.filter(item => item.type == "talent" && item.system.isautomated)
- let bonus = 0
- for (let talent of talents) {
- for (let auto of talent.system.automations) {
- if (auto.eventtype == "bonus-permanent" && auto.bonusname == "seuilpouvoir") {
- bonus += Number(auto.bonus || 0)
- }
- }
- }
- return bonus
- }
-
- /* -------------------------------------------- */
- getAmeMax() {
- return Math.min(this.system.ame.max || this.system.ame.nbame, this.system.ame.nbame)
- }
-
- /* -------------------------------------------- */
- getBonneAventure() {
- return this.system.bonneaventure.actuelle
- }
- /* -------------------------------------------- */
- checkBonneAventure(cost) {
- return (this.system.bonneaventure.actuelle >= cost)
- }
- /* -------------------------------------------- */
- changeBonneAventure(value) {
- let newBA = this.system.bonneaventure.actuelle
- newBA += value
- this.update({ 'system.bonneaventure.actuelle': newBA })
- }
-
- /* -------------------------------------------- */
- getEclat() {
- return this.system.eclat.value
- }
-
- /* -------------------------------------------- */
- changeEclat(value) {
- let newE = this.system.eclat.value
- newE += value
- this.update({ 'system.eclat.value': newE })
- }
-
- /* -------------------------------------------- */
- compareName(a, b) {
- if (a.name < b.name) {
- return -1;
- }
- if (a.name > b.name) {
- return 1;
- }
- return 0;
- }
-
- /* -------------------------------------------- */
- getAttribute(attrKey) {
- return this.system.attributes[attrKey]
- }
-
- /* -------------------------------------------- */
- getBonusDegats() {
- return 0;
- }
-
- /* -------------------------------------------- */
- changeEtatCombativite(value) {
- if (value === "vaincu") {
- value = 200
- }
- let sante = foundry.utils.duplicate(this.system.sante)
- sante.etat += Number(value)
- sante.etat = Math.max(sante.etat, 0)
- sante.etat = Math.min(sante.etat, this.system.sante.nbcombativite)
- this.update({ 'system.sante': sante })
- if (sante.etat == this.system.sante.nbcombativite) {
- ChatMessage.create({ content: `${this.name} est vaincu !` })
- }
- // Duplicated ! this.processCombativite(sante)
- }
-
- /* -------------------------------------------- */
- changeEtatAme(value) {
- if (value === "brise") {
- value = 200
- }
- let ame = foundry.utils.duplicate(this.system.ame)
- ame.etat += Number(value)
- ame.etat = Math.max(ame.etat, 0)
- // L'état ne peut pas dépasser le maximum actuel d'âme
- let maxAme = this.system.ame.max || this.system.ame.nbame
- ame.etat = Math.min(ame.etat, maxAme)
- this.update({ 'system.ame': ame })
- if (ame.etat >= maxAme) {
- ChatMessage.create({ content: `${this.name} est brisé !` })
- }
- }
-
- /* -------------------------------------------- */
- processCombativite(sante) {
- sante = sante || foundry.utils.duplicate(this.system.sante)
- // Gestion des états affaibli et très affaibli
- if (sante.etat == this.system.sante.nbcombativite - 2 || sante.etat == this.system.sante.nbcombativite - 1) {
- if (sante.etat == this.system.sante.nbcombativite - 2 && this.items.find(item => item.type == "talent" && item.name.toLowerCase() == "encaissement")) {
- ChatMessage.create({ content: `${this.name} ne subit pas les 2 adversités rouge grâce à Encaissement. Pensez à les ajouter à la fin de la scène !` })
- } else if (sante.etat == this.system.sante.nbcombativite - 1 && this.items.find(item => item.type == "talent" && item.name.toLowerCase().includes("vaillant"))) {
- ChatMessage.create({ content: `${this.name} ne subit pas les 2 adversités rouge grâce à Vaillant. Pensez à les ajouter à la fin de la scène !` })
- } else {
- ChatMessage.create({ content: `${this.name} subit 2 adversités rouge !` })
- this.incDecAdversite("rouge", 2)
- }
- }
- }
-
- /* -------------------------------------------- */
- processAme(ame) {
- ame = ame || foundry.utils.duplicate(this.system.ame)
- let maxAme = Math.min(this.system.ame.max || this.system.ame.nbame, this.system.ame.nbame - 1)
- // Gestion des états Traumatisé, Très Traumatisé et Brisé en fonction du maximum actuel
- // Les seuils sont calculés par rapport au maximum d'âme actuel
- if (maxAme >= 2 && ame.etat >= maxAme - 2) {
- if (ame.etat == maxAme - 2) {
- ChatMessage.create({ content: `${this.name} est Traumatisé !` })
- } else if (ame.etat == maxAme - 1) {
- ChatMessage.create({ content: `${this.name} est Très Traumatisé !` })
- } else if (ame.etat >= maxAme) {
- ChatMessage.create({ content: `${this.name} est Brisé !` })
- }
- } else if (ame.etat >= maxAme) {
- ChatMessage.create({ content: `${this.name} est Brisé !` })
- }
- }
-
- /* -------------------------------------------- */
- async equipGear(equipmentId) {
- let item = this.items.find(item => item.id == equipmentId);
- if (item?.system?.data) {
- let update = { _id: item.id, "system.equipped": !item.system.equipped };
- await this.updateEmbeddedDocuments('Item', [update]); // Updates one EmbeddedEntity
- }
- }
-
- /* -------------------------------------------- */
- getSubActors() {
- let subActors = [];
- for (let id of this.system.subactors) {
- subActors.push(foundry.utils.duplicate(game.actors.get(id)));
- }
- return subActors;
- }
- /* -------------------------------------------- */
- async addSubActor(subActorId) {
- let subActors = foundry.utils.duplicate(this.system.subactors);
- subActors.push(subActorId);
- await this.update({ 'system.subactors': subActors });
- }
- /* -------------------------------------------- */
- async delSubActor(subActorId) {
- let newArray = [];
- for (let id of this.system.subactors) {
- if (id != subActorId) {
- newArray.push(id);
- }
- }
- await this.update({ 'system.subactors': newArray });
- }
-
- /* -------------------------------------------- */
- getTotalAdversite() {
- return this.system.adversite.bleue + this.system.adversite.rouge + this.system.adversite.noire
- }
-
- /* -------------------------------------------- */
- async incDecAdversite(adv, incDec = 0) {
- let adversite = foundry.utils.duplicate(this.system.adversite)
- adversite[adv] += Number(incDec)
- adversite[adv] = Math.max(adversite[adv], 0)
- adversite[adv] = Math.min(adversite[adv], 20)
- this.update({ 'system.adversite': adversite })
- }
- /* -------------------------------------------- */
- async incDecQuantity(objetId, incDec = 0) {
- let objetQ = this.items.get(objetId)
- if (objetQ) {
- let newQ = objetQ.system.quantite + incDec
- newQ = Math.max(newQ, 0)
- await this.updateEmbeddedDocuments('Item', [{ _id: objetQ.id, 'system.quantite': newQ }]); // pdates one EmbeddedEntity
- }
- }
-
- /* -------------------------------------------- */
- computeRichesse() {
- let valueSC = 0
- for (let monnaie of this.items) {
- if (monnaie.type == "monnaie") {
- valueSC += Number(monnaie.system.prixsc) * Number(monnaie.system.quantite)
- }
- }
- return MournbladeCYD2Utility.computeMonnaieDetails(valueSC)
- }
-
- /* -------------------------------------------- */
- computeValeurEquipement() {
- let valueSC = 0
- for (let equip of this.items) {
- if (equip.type == "equipement" || equip.type == "arme" || equip.type == "protection") {
- valueSC += Number(equip.system.prixsc) * Number(equip.system.quantite ?? 1)
- valueSC += (Number(equip.system.prixca) * Number(equip.system.quantite ?? 1)) * 20
- valueSC += (Number(equip.system.prixpo) * Number(equip.system.quantite ?? 1)) * 400
- }
- }
- return MournbladeCYD2Utility.computeMonnaieDetails(valueSC)
- }
-
- /* -------------------------------------------- */
- getCompetence(compId) {
- return this.items.get(compId)
- }
-
- /* -------------------------------------------- */
- async setPredilectionUsed(compId, predIdx) {
- let comp = this.items.get(compId)
- let pred = foundry.utils.duplicate(comp.system.predilections)
- pred[predIdx].used = true
- await this.updateEmbeddedDocuments('Item', [{ _id: compId, 'system.predilections': pred }])
- }
-
- /* -------------------------------------------- */
- getInitiativeScore() {
- let init = this.getFlag("world", "last-initiative")
- return init || -1
- }
-
- /* -------------------------------------------- */
- getBestAttackValue() {
- let attackList = this.items.filter(item => (item.type == "arme" || item.type == "talent") && item.system.equipped)
- let maxOff = 0
- let bestArme
- for (let arme of attackList) {
- if (arme.type == "arme") {
- arme = this.prepareArme(arme)
- }
- if (arme.system.totalOffensif > maxOff) {
- maxOff = arme.system.totalOffensif
- bestArme = foundry.utils.duplicate(arme)
- }
- }
- return bestArme
- }
-
- /* -------------------------------------------- */
- getBestDefenseValue() {
- let defenseList = this.items.filter(item => (item.type == "arme") && item.system.equipped)
- let maxDef = 0
- let bestArme
- for (let arme of defenseList) {
- if (arme.type == "arme") {
- arme = this.prepareArme(arme)
- }
- if (arme.system.totalDefensif > maxDef) {
- maxDef = arme.system.totalDefensif
- bestArme = foundry.utils.duplicate(arme)
- }
- }
- return bestArme
- }
-
- /* -------------------------------------------- */
- searchRelevantTalents(competence) {
- let talents = []
-
- for (let talent of this.items) {
- if (talent.type == "talent" && talent.system.isautomated && talent.system.automations.length > 0) {
- for (let auto of talent.system.automations) {
- if (auto.eventtype === "prepare-roll") {
- if (auto.competence.toLowerCase() == competence.name.toLowerCase()) {
- talent = foundry.utils.duplicate(talent)
- talent.system.bonus = auto.bonus
- talent.system.baCost = auto.baCost
- talents.push(talent)
- }
- }
- }
- }
- }
- return talents
- }
-
- /* -------------------------------------------- */
- buildListeAdversites() {
- return []
- }
-
- /* -------------------------------------------- */
- getCommonRollData(attrKey = undefined, compId = undefined, compName = undefined) {
- let rollData = MournbladeCYD2Utility.getBasicRollData()
- rollData.alias = this.name
- rollData.actorImg = this.img
- rollData.actorId = this.id
- rollData.tokenId = this.token?.id
- rollData.img = this.img
- rollData.attributs = MournbladeCYD2Utility.getAttributs()
- rollData.maitriseId = "none"
- rollData.nbEclat = this.system.eclat.value
- rollData.nbBA = this.system.bonneaventure.actuelle
- rollData.nbAdversites = this.getTotalAdversite()
- rollData.talents = []
- rollData.attrKey2 = "none"
- rollData.coupDevastateur = this.items.find(it => it.type == "talent" && it.name.toLowerCase() == "coup dévastateur" && !it.system.used)
- rollData.hasAmbidextre = this.items.find(it => it.type == "talent" && it.name.toLowerCase() == "ambidextre")
- rollData.hasFeinte = this.system.bonneaventure.actuelle > 0 && this.items.find(it => it.type == "talent" && it.name.toLowerCase() == "feinte")
- rollData.isMonte = this.system.combat.monte
- rollData.config = game.system.mournbladecyd2.config
-
- if (attrKey) {
- rollData.attrKey = attrKey
- if (attrKey != "tochoose") {
- rollData.actionImg = "systems/fvtt-mournblade-cyd2/assets/icons/" + this.system.attributs[attrKey].labelnorm + ".webp"
- rollData.attr = foundry.utils.duplicate(this.system.attributs[attrKey])
- }
- }
- if (compId) {
- rollData.competence = foundry.utils.duplicate(this.items.get(compId) || {})
- let maitrises = [{ key: "none", label: "Aucune" }]
- rollData.competence.system.predilections.forEach(function (item) {
- if (item.maitrise) {
- maitrises.push({ key: item.id, label: item.name });
- }
- })
- rollData.maitrises = maitrises // rollData.competence.system.predilections.filter(p => p.maitrise)
- rollData.actionImg = rollData.competence?.img
- rollData.talents = this.searchRelevantTalents(rollData.competence)
- }
- if (compName) {
- rollData.competence = foundry.utils.duplicate(this.items.find(item => item.name.toLowerCase() == compName.toLowerCase()) || {})
- rollData.actionImg = rollData.competence?.img
- }
- return rollData
- }
-
- /* -------------------------------------------- */
- async rollAttribut(attrKey, isInit = false) {
- let rollData = this.getCommonRollData(attrKey)
- rollData.multiplier = (isInit) ? 1 : 2
- rollData.isInit = isInit
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
-
- /* -------------------------------------------- */
- async rollCompetence(attrKey, compId) {
- let rollData = this.getCommonRollData(attrKey, compId)
- rollData.multiplier = 1 // Attr multiplier, always 1 in competence mode
- console.log("RollDatra", rollData)
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
-
- /* -------------------------------------------- */
- async rollArmeOffensif(armeId) {
- let arme = this.items.get(armeId)
- if (arme.type == "arme") {
- arme = this.prepareArme(arme)
- }
- let rollData = this.getCommonRollData(arme.system.attrKey, arme.system.competence._id)
- rollData.arme = arme
- MournbladeCYD2Utility.updateWithTarget(rollData)
- console.log("ARME!", rollData)
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
- /* -------------------------------------------- */
- async rollAssommer() {
- let rollData = this.getCommonRollData("pui", undefined, "Filouterie")
- rollData.assomer = true
- rollData.conditionsCommunes = true
- MournbladeCYD2Utility.updateWithTarget(rollData)
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
- /* -------------------------------------------- */
- async rollCoupBas() {
- let rollData = this.getCommonRollData("pui", undefined, "Mêlée")
- rollData.coupBas = true
- rollData.conditionsCommunes = true
- MournbladeCYD2Utility.updateWithTarget(rollData)
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
- /* -------------------------------------------- */
- async rollImmobiliser() {
- let rollData = this.getCommonRollData("pui", undefined, "Mêlée")
- rollData.immobiliser = true
- rollData.conditionsCommunes = true
- rollData.cibleconsciente = true
- MournbladeCYD2Utility.updateWithTarget(rollData)
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
- /* -------------------------------------------- */
- async rollRepousser() {
- let rollData = this.getCommonRollData("pui", undefined, "Mêlée")
- rollData.repousser = true
- rollData.conditionsCommunes = true
- rollData.cibleconsciente = true
- MournbladeCYD2Utility.updateWithTarget(rollData)
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
- /* -------------------------------------------- */
- async rollDesengager() {
- let rollData = this.getCommonRollData("adr", undefined, "Mouvements")
- rollData.desengager = true
- rollData.conditionsCommunes = true
- MournbladeCYD2Utility.updateWithTarget(rollData)
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
-
- /* -------------------------------------------- */
- async rollArmeDegats(armeId, targetVigueur = undefined, rollDataInput = undefined) {
- let arme = this.items.get(armeId)
- if (arme.type == "arme") {
- arme = this.prepareArme(arme)
- }
- console.log("DEGATS", arme, targetVigueur, rollDataInput)
- let roll
- let bonus = 0
- let bonus2 = 0
-
- if (rollDataInput?.applyCoupDevastateur) {
- bonus2 = Math.floor(this.system.attributs.pui.value / 2)
- let talent = this.items.find(item => item.type == "talent" && item.name.toLowerCase() == "coup dévastateur")
- this.updateEmbeddedDocuments('Item', [{ _id: talent.id, 'system.used': true }])
- }
-
- if (rollDataInput?.isHeroique) {
- if (rollDataInput?.attaqueCharge) {
- bonus = 5
- }
- if (rollDataInput?.chargeCavalerie) {
- bonus = 6
- }
- roll = await new Roll("2d10rr10+" + arme.system.totalDegats + "+" + bonus + "+" + bonus2).roll()
- } else {
- if (rollDataInput?.attaqueCharge) {
- bonus = 3
- }
- if (rollDataInput?.chargeCavalerie) {
- bonus = 4
- }
- roll = await new Roll("1d10+" + arme.system.totalDegats + "+" + bonus + "+" + bonus2).roll()
- }
- await MournbladeCYD2Utility.showDiceSoNice(roll, game.settings.get("core", "rollMode"));
- let nbEtatPerdus = 0
- if (targetVigueur) {
- nbEtatPerdus = Math.floor(roll.total / targetVigueur)
- }
- //console.log(roll)
- let rollData = {
- arme: arme,
- finalResult: roll.total,
- formula: roll.formula,
- alias: this.name,
- actorImg: this.img,
- actorId: this.id,
- defenderTokenId: rollDataInput?.defenderTokenId,
- actionImg: arme.img,
- targetVigueur: targetVigueur,
- nbEtatPerdus: nbEtatPerdus
- }
- MournbladeCYD2Utility.createChatWithRollMode(rollData.alias, {
- content: await renderTemplate(`systems/fvtt-mournblade-cyd2/templates/chat-degats-result.html`, rollData)
- })
-
- if (rollDataInput?.defenderTokenId && nbEtatPerdus) {
- MournbladeCYD2Utility.applyCombativite(rollDataInput, nbEtatPerdus)
- }
-
- }
-}
diff --git a/.history/modules/mournblade-cyd2-actor_20251026083918.js b/.history/modules/mournblade-cyd2-actor_20251026083918.js
deleted file mode 100644
index 2188fb5..0000000
--- a/.history/modules/mournblade-cyd2-actor_20251026083918.js
+++ /dev/null
@@ -1,904 +0,0 @@
-/* -------------------------------------------- */
-import { MournbladeCYD2Utility } from "./mournblade-cyd2-utility.js";
-import { MournbladeCYD2RollDialog } from "./mournblade-cyd2-roll-dialog.js";
-
-/* -------------------------------------------- */
-const __degatsBonus = [-2, -2, -1, -1, 0, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 8, 8, 9, 9, 10, 10]
-const __vitesseBonus = [-2, -2, -1, -1, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8]
-
-/* -------------------------------------------- */
-/**
- * Extend the base Actor entity by defining a custom roll data structure which is ideal for the Simple system.
- * @extends {Actor}
- */
-export class MournbladeCYD2Actor extends Actor {
-
- /* -------------------------------------------- */
- /**
- * Override the create() function to provide additional SoS functionality.
- *
- * This overrided create() function adds initial items
- * Namely: Basic skills, money,
- *
- * @param {Object} data Barebones actor data which this function adds onto.
- * @param {Object} options (Unused) Additional options which customize the creation workflow.
- *
- */
-
- static async create(data, options) {
-
- // Case of compendium global import
- if (data instanceof Array) {
- return super.create(data, options);
- }
- // If the created actor has items (only applicable to duplicated actors) bypass the new actor creation logic
- if (data.items) {
- let actor = super.create(data, options);
- return actor;
- }
-
- if (data.type == 'personnage') {
- const skills = await MournbladeCYD2Utility.loadCompendium("fvtt-mournblade-cyd2.skills")
- data.items = skills.map(i => i.toObject())
- }
- if (data.type == 'creature') {
- const skills = await MournbladeCYD2Utility.loadCompendium("fvtt-mournblade-cyd2.skills-creatures")
- data.items = skills.map(i => i.toObject())
- data.items.push({ name: "Arme naturelle 1", type: 'arme', img: "systems/fvtt-mournblade-cyd2/assets/icons/melee.webp", system: { typearme: "contact", bonusmaniementoff: 0, seuildefense: 0, degats: "0" } })
- data.items.push({ name: "Arme naturelle 2", type: 'arme', img: "systems/fvtt-mournblade-cyd2/assets/icons/melee.webp", system: { typearme: "contact", bonusmaniementoff: 0, seuildefense: 0, degats: "0" } })
- }
-
- return super.create(data, options);
- }
-
- /* -------------------------------------------- */
- getBonusDefenseFromTalents() {
- let talents = this.items.filter(item => item.type == "talent" && item.system.isautomated)
- let bonus = 0
- for (let talent of talents) {
- for (let auto of talent.system.automations) {
- if (auto.eventtype == "bonus-permanent" && auto.bonusname == "bonus-defensif") {
- bonus += Number(auto.bonus || 0)
- }
- }
- }
- return bonus
- }
-
- /* -------------------------------------------- */
- prepareArme(arme) {
- if (this.type == "cellule") {
- return arme
- }
-
- arme = foundry.utils.duplicate(arme)
- let combat = this.getCombatValues()
- if (arme.system.typearme == "contact" || arme.system.typearme == "contactjet") {
- let bonusDefense = this.getBonusDefenseFromTalents()
- arme.system.competence = foundry.utils.duplicate(this.items.find(item => item.type == "competence" && item.name.toLowerCase() == "mêlée"))
- arme.system.attrKey = "pui"
- arme.system.totalDegats = arme.system.degats + "+" + combat.bonusDegatsTotal
- arme.system.totalOffensif = this.system.attributs.pui.value + arme.system.competence.system.niveau + arme.system.bonusmaniementoff + (this.system.combat.monte ? 3 : 0)
- arme.system.totalDefensif = combat.defenseTotal + arme.system.competence.system.niveau + arme.system.seuildefense + bonusDefense + (this.system.combat.monte ? 3 : 0)
- console.log("Arme", arme.system.totalDefensif, combat, arme.system.competence.system.niveau, arme.system.seuildefense, bonusDefense)
- arme.system.isdefense = true
- arme.system.isMelee = true
- arme.system.isDistance = false
- }
- if (arme.system.typearme == "jet" || arme.system.typearme == "tir") {
- arme.system.competence = foundry.utils.duplicate(this.items.find(item => item.type == "competence" && item.name.toLowerCase() == "armes à distance"))
- arme.system.attrKey = "adr"
- arme.system.totalOffensif = this.system.attributs.adr.value + arme.system.competence.system.niveau + arme.system.bonusmaniementoff
- arme.system.totalDegats = arme.system.degats
- arme.system.isMelee = false
- arme.system.isDistance = true
- if (arme.system.isdefense) {
- arme.system.totalDefensif = combat.defenseTotal + arme.system.competence.system.niveau + arme.system.seuildefense
- }
- }
- return arme
- }
-
- /* -------------------------------------------- */
- getItemSorted(types) {
- let items = this.items.filter(item => types.includes(item.type)) || []
- MournbladeCYD2Utility.sortArrayObjectsByName(items)
- return items
- }
- getWeapons() {
- let armes = []
- for (let arme of this.items) {
- if (arme.type == "arme") {
- armes.push(this.prepareArme(arme))
- }
- }
- MournbladeCYD2Utility.sortArrayObjectsByName(armes)
- return armes
- }
- getMonnaies() {
- return this.getItemSorted(["monnaie"])
- }
- getEquipments() {
- return this.getItemSorted(["equipement"])
- }
- getArtefacts() {
- return this.getItemSorted(["artefact"])
- }
- getArmors() {
- return this.getItemSorted(["protection"])
- }
- getHistoriques() {
- return this.getItemSorted(["historique"])
- }
- getProfils() {
- return this.getItemSorted(["profil"])
- }
- getTalents() {
- return this.getItemSorted(["talent"])
- }
- getRessources() {
- return this.getItemSorted(["ressource"])
- }
- getContacts() {
- return this.getItemSorted(["contact"])
- }
- getMutations() {
- return this.getItemSorted(["mutation"])
- }
- getDons() {
- return this.getItemSorted(["don"])
- }
- getPactes() {
- return this.getItemSorted(["pacte"])
- }
- getTendances() {
- return this.getItemSorted(["tendance"])
- }
- getRunes() {
- return this.getItemSorted(["rune"])
- }
- getTraitsChaotiques() {
- return this.getItemSorted(["traitchaotique"])
- }
- getTraitsEspeces() {
- return this.getItemSorted(["traitespece"])
- }
-
- /* -------------------------------------------- */
- getAspect() {
- return (this.system.balance.loi > this.system.balance.chaos) ? this.system.balance.loi : this.system.balance.chaos
- }
- getMarge() {
- return Math.abs(this.system.balance.loi - this.system.balance.chaos)
- }
- getAlignement() {
- return (this.system.balance.loi > this.system.balance.chaos) ? "loyal" : "chaotique"
- }
-
- /* -------------------------------------------- */
- getSkills() {
- let comp = []
- for (let item of this.items) {
- item = foundry.utils.duplicate(item)
- if (item.type == "competence") {
- item.system.attribut1total = item.system.niveau + (this.system.attributs[item.system.attribut1]?.value || 0)
- item.system.attribut2total = item.system.niveau + (this.system.attributs[item.system.attribut2]?.value || 0)
- item.system.attribut3total = item.system.niveau + (this.system.attributs[item.system.attribut3]?.value || 0)
- if (item.system.niveau == 0) {
- item.system.attribut1total -= 3
- item.system.attribut2total -= 3
- item.system.attribut3total -= 3
- }
- item.system.attribut1label = this.system.attributs[item.system.attribut1]?.label || ""
- item.system.attribut2label = this.system.attributs[item.system.attribut2]?.label || ""
- item.system.attribut3label = this.system.attributs[item.system.attribut3]?.label || ""
- comp.push(item)
- }
- }
- MournbladeCYD2Utility.sortArrayObjectsByName(comp)
- return comp
- }
-
- /* ----------------------- --------------------- */
- addMember(actorId) {
- let members = foundry.utils.duplicate(this.system.members)
- members.push({ id: actorId })
- this.update({ 'system.members': members })
- }
- async removeMember(actorId) {
- let members = this.system.members.filter(it => it.id != actorId)
- this.update({ 'system.members': members })
- }
-
- /* -------------------------------------------- */
- getDefenseBase() {
- return Math.max(this.system.attributs.tre.value, this.system.attributs.adr.value)
- }
-
- /* -------------------------------------------- */
- getVitesseBase() {
- return 5 + __vitesseBonus[this.system.attributs.adr.value]
- }
- /* -------------------------------------------- */
- getProtection() {
- let equipProtection = 0
- for (let armor of this.items) {
- if (armor.type == "protection" && armor.system.equipped) {
- equipProtection += Number(armor.system.protection)
- }
- }
- if (equipProtection < 4) {
- return 4 + equipProtection // Cas des boucliers + sans armure
- }
- return equipProtection // Uniquement la protection des armures + boucliers
- }
-
- /* -------------------------------------------- */
- getCombatValues() {
- if (this.type == "cellule") {
- return {
- initBase: 0,
- initTotal: 0,
- bonusDegats: 0,
- bonusDegatsTotal: 0,
- vitesseBase: 0,
- vitesseTotal: 0,
- defenseBase: 0,
- protection: 0,
- defenseTotal: 0
- }
- }
-
- let combat = {
- initBase: this.system.attributs.adr.value,
- initTotal: this.system.attributs.adr.value + this.system.combat.initbonus,
- bonusDegats: this.getBonusDegats(),
- bonusDegatsTotal: this.getBonusDegats() + this.system.combat.bonusdegats,
- vitesseBase: this.getVitesseBase(),
- vitesseTotal: this.getVitesseBase() + this.system.combat.vitessebonus,
- defenseBase: this.getDefenseBase(),
- protection: this.getProtection(),
- defenseTotal: this.getDefenseBase() + this.system.combat.defensebonus + this.getProtection() - this.getTotalAdversite() + (this.system.combat.defensetotale ? 3 : 0)
- }
- return combat
- }
-
- /* -------------------------------------------- */
- prepareBaseData() {
- }
-
- /* -------------------------------------------- */
- async prepareData() {
- super.prepareData();
- }
-
- /* -------------------------------------------- */
- prepareDerivedData() {
-
- if (this.type == 'personnage') {
- let talentBonus = this.getVigueurBonus()
- let vigueur = Math.floor((this.system.attributs.pui.value + this.system.attributs.tre.value) / 2) + talentBonus + this.system.sante.vigueurmodifier
- if (vigueur != this.system.sante.vigueur) {
- this.update({ 'system.sante.vigueur': vigueur })
- }
-
- let seuilPouvoirBonus = this.getSeuilPouvoirBonus()
- let seuilPouvoir = Math.floor((this.system.attributs.tre.value + this.system.attributs.cla.value) / 2) + seuilPouvoirBonus + this.system.ame.seuilpouvoirmodifier
- if (seuilPouvoir != this.system.ame.seuilpouvoir) {
- this.update({ 'system.ame.seuilpouvoir': seuilPouvoir })
- }
- }
- super.prepareDerivedData()
- }
-
- /* -------------------------------------------- */
- _preUpdate(changed, options, user) {
- if (changed?.system?.sante?.etat && changed?.system?.sante?.etat != this.system.sante.etat) {
- setTimeout(() => {
- this.processCombativite(changed.system.sante)
- }, 800)
- }
- if (changed?.system?.ame?.etat && changed?.system?.ame?.etat != this.system.ame.etat) {
- // Limiter l'état d'Âme au maximum défini
- let maxAme = this.system.ame.max || this.system.ame.nbame
- if (changed.system.ame.etat > maxAme) {
- changed.system.ame.etat = maxAme
- }
- setTimeout(() => {
- this.processAme(changed.system.ame)
- }, 800)
- }
- // Si le max d'Âme change, ajuster l'état actuel si nécessaire
- if (changed?.system?.ame?.max && changed.system.ame.max != this.system.ame.max) {
- if (this.system.ame.etat > changed.system.ame.max) {
- changed.system.ame.etat = changed.system.ame.max
- }
- }
- super._preUpdate(changed, options, user);
- }
-
- /* -------------------------------------------- */
- _onUpdate(data, options, user) {
- super._onUpdate(data, options, user);
- }
- /* -------------------------------------------- */
- getItemById(id) {
- let item = this.items.find(item => item.id == id);
- if (item) {
- item = foundry.utils.duplicate(item)
- }
- return item;
- }
-
- /* -------------------------------------------- */
- async equipItem(itemId) {
- let item = this.items.find(item => item.id == itemId)
- if (item && item.system) {
- let update = { _id: item.id, "system.equipped": !item.system.equipped }
- await this.updateEmbeddedDocuments('Item', [update]); // Updates one EmbeddedEntity
- }
- }
-
- /* -------------------------------------------- */
- editItemField(itemId, itemType, itemField, dataType, value) {
- let item = this.items.find(item => item.id == itemId)
- if (item) {
- console.log("Item ", item, itemField, dataType, value)
- if (dataType.toLowerCase() == "number") {
- value = Number(value)
- } else {
- value = String(value)
- }
- let update = { _id: item.id, [`system.${itemField}`]: value };
- this.updateEmbeddedDocuments("Item", [update])
- }
- }
-
- /* -------------------------------------------- */
- checkAttribut(attribut, minLevel) {
- let attr = this.system.attributs.find(at => at.labelnorm == attribut.toLowerCase())
- if (attr && attr.value >= minLevel) {
- return { isValid: true, attr: foundry.utils.duplicate(attr) }
- }
- return { isValid: false }
- }
- /* -------------------------------------------- */
- checkAttributOrCompetenceLevel(compName, minLevel) {
- let comp = this.items.find(i => i.type == "competence" && i.name.toLowerCase() == compName.toLowerCase() && i.system.niveau >= minLevel)
- if (comp) {
- return { isValid: true, item: foundry.utils.duplicate(comp) }
- } else {
- for (let attrKey in this.system.attributs) {
- if (this.system.attributs[attrKey].label.toLowerCase() == compName.toLowerCase() && this.system.attributs[attrKey].value >= minLevel) {
- return { isValid: true, item: foundry.utils.duplicate(this.system.attributs[attrKey]) }
- }
- }
- }
- return { isValid: false, warningMessage: `Prérequis insuffisant : la compétence/attribut ${compName} doit être de niveau ${minLevel} au minimum` }
- }
- /* -------------------------------------------- */
- addCompetenceBonus(compName, bonus, baCost) {
- let comp = this.items.find(i => i.type == "competence" && i.name.toLowerCase() == compName.toLowerCase())
- if (comp) {
- comp = foundry.utils.duplicate(comp)
- comp.system.bonus = bonus
- comp.system.baCost = baCost
- return { isValid: true, item: comp }
- }
- return { isValid: false, warningMessage: `Compétence ${compName} non trouvée` }
- }
- /* -------------------------------------------- */
- checkIfCompetence(compName) {
- let comp = this.items.find(i => i.type == "competence" && i.name.toLowerCase() == compName.toLowerCase())
- if (comp) {
- return { isValid: true, item: comp }
- }
- return { isValid: false }
- }
- /* -------------------------------------------- */
- getVigueur() {
- return this.system.sante.vigueur
- }
-
- /* -------------------------------------------- */
- getVigueurBonus() {
- let talents = this.items.filter(item => item.type == "talent" && item.system.isautomated)
- let bonus = 0
- for (let talent of talents) {
- for (let auto of talent.system.automations) {
- if (auto.eventtype == "bonus-permanent" && auto.bonusname == "vigueur") {
- bonus += Number(auto.bonus || 0)
- }
- }
- }
- return bonus
- }
-
- /* -------------------------------------------- */
- getSeuilPouvoir() {
- return this.system.ame.seuilpouvoir
- }
-
- /* -------------------------------------------- */
- getSeuilPouvoirBonus() {
- let talents = this.items.filter(item => item.type == "talent" && item.system.isautomated)
- let bonus = 0
- for (let talent of talents) {
- for (let auto of talent.system.automations) {
- if (auto.eventtype == "bonus-permanent" && auto.bonusname == "seuilpouvoir") {
- bonus += Number(auto.bonus || 0)
- }
- }
- }
- return bonus
- }
-
- /* -------------------------------------------- */
- getAmeMax() {
- return Math.min(this.system.ame.max || this.system.ame.nbame, this.system.ame.nbame)
- }
-
- /* -------------------------------------------- */
- getBonneAventure() {
- return this.system.bonneaventure.actuelle
- }
- /* -------------------------------------------- */
- checkBonneAventure(cost) {
- return (this.system.bonneaventure.actuelle >= cost)
- }
- /* -------------------------------------------- */
- changeBonneAventure(value) {
- let newBA = this.system.bonneaventure.actuelle
- newBA += value
- this.update({ 'system.bonneaventure.actuelle': newBA })
- }
-
- /* -------------------------------------------- */
- getEclat() {
- return this.system.eclat.value
- }
-
- /* -------------------------------------------- */
- changeEclat(value) {
- let newE = this.system.eclat.value
- newE += value
- this.update({ 'system.eclat.value': newE })
- }
-
- /* -------------------------------------------- */
- compareName(a, b) {
- if (a.name < b.name) {
- return -1;
- }
- if (a.name > b.name) {
- return 1;
- }
- return 0;
- }
-
- /* -------------------------------------------- */
- getAttribute(attrKey) {
- return this.system.attributes[attrKey]
- }
-
- /* -------------------------------------------- */
- getBonusDegats() {
- return 0;
- }
-
- /* -------------------------------------------- */
- changeEtatCombativite(value) {
- if (value === "vaincu") {
- value = 200
- }
- let sante = foundry.utils.duplicate(this.system.sante)
- sante.etat += Number(value)
- sante.etat = Math.max(sante.etat, 0)
- sante.etat = Math.min(sante.etat, this.system.sante.nbcombativite)
- this.update({ 'system.sante': sante })
- if (sante.etat == this.system.sante.nbcombativite) {
- ChatMessage.create({ content: `${this.name} est vaincu !` })
- }
- // Duplicated ! this.processCombativite(sante)
- }
-
- /* -------------------------------------------- */
- changeEtatAme(value) {
- if (value === "brise") {
- value = 200
- }
- let ame = foundry.utils.duplicate(this.system.ame)
- ame.etat += Number(value)
- ame.etat = Math.max(ame.etat, 0)
- // L'état ne peut pas dépasser le maximum actuel d'âme
- let maxAme = this.system.ame.max || this.system.ame.nbame
- ame.etat = Math.min(ame.etat, maxAme)
- this.update({ 'system.ame': ame })
- if (ame.etat >= maxAme) {
- ChatMessage.create({ content: `${this.name} est brisé !` })
- }
- }
-
- /* -------------------------------------------- */
- processCombativite(sante) {
- sante = sante || foundry.utils.duplicate(this.system.sante)
- // Gestion des états affaibli et très affaibli
- if (sante.etat == this.system.sante.nbcombativite - 2 || sante.etat == this.system.sante.nbcombativite - 1) {
- if (sante.etat == this.system.sante.nbcombativite - 2 && this.items.find(item => item.type == "talent" && item.name.toLowerCase() == "encaissement")) {
- ChatMessage.create({ content: `${this.name} ne subit pas les 2 adversités rouge grâce à Encaissement. Pensez à les ajouter à la fin de la scène !` })
- } else if (sante.etat == this.system.sante.nbcombativite - 1 && this.items.find(item => item.type == "talent" && item.name.toLowerCase().includes("vaillant"))) {
- ChatMessage.create({ content: `${this.name} ne subit pas les 2 adversités rouge grâce à Vaillant. Pensez à les ajouter à la fin de la scène !` })
- } else {
- ChatMessage.create({ content: `${this.name} subit 2 adversités rouge !` })
- this.incDecAdversite("rouge", 2)
- }
- }
- }
-
- /* -------------------------------------------- */
- processAme(ame) {
- ame = ame || foundry.utils.duplicate(this.system.ame)
- let maxAme = this.system.ame.max || this.system.ame.nbame
- // Gestion des états Traumatisé, Très Traumatisé et Brisé en fonction du maximum actuel
- // Les seuils sont calculés par rapport au maximum d'âme actuel
- if (maxAme >= 3 && ame.etat >= maxAme - 2) {
- if (ame.etat == maxAme - 2) {
- ChatMessage.create({ content: `${this.name} est Traumatisé !` })
- } else if (ame.etat == maxAme - 1) {
- ChatMessage.create({ content: `${this.name} est Très Traumatisé !` })
- } else if (ame.etat >= maxAme) {
- ChatMessage.create({ content: `${this.name} est Brisé !` })
- }
- } else if (ame.etat >= maxAme) {
- ChatMessage.create({ content: `${this.name} est Brisé !` })
- }
- }
-
- /* -------------------------------------------- */
- async equipGear(equipmentId) {
- let item = this.items.find(item => item.id == equipmentId);
- if (item?.system?.data) {
- let update = { _id: item.id, "system.equipped": !item.system.equipped };
- await this.updateEmbeddedDocuments('Item', [update]); // Updates one EmbeddedEntity
- }
- }
-
- /* -------------------------------------------- */
- getSubActors() {
- let subActors = [];
- for (let id of this.system.subactors) {
- subActors.push(foundry.utils.duplicate(game.actors.get(id)));
- }
- return subActors;
- }
- /* -------------------------------------------- */
- async addSubActor(subActorId) {
- let subActors = foundry.utils.duplicate(this.system.subactors);
- subActors.push(subActorId);
- await this.update({ 'system.subactors': subActors });
- }
- /* -------------------------------------------- */
- async delSubActor(subActorId) {
- let newArray = [];
- for (let id of this.system.subactors) {
- if (id != subActorId) {
- newArray.push(id);
- }
- }
- await this.update({ 'system.subactors': newArray });
- }
-
- /* -------------------------------------------- */
- getTotalAdversite() {
- return this.system.adversite.bleue + this.system.adversite.rouge + this.system.adversite.noire
- }
-
- /* -------------------------------------------- */
- async incDecAdversite(adv, incDec = 0) {
- let adversite = foundry.utils.duplicate(this.system.adversite)
- adversite[adv] += Number(incDec)
- adversite[adv] = Math.max(adversite[adv], 0)
- adversite[adv] = Math.min(adversite[adv], 20)
- this.update({ 'system.adversite': adversite })
- }
- /* -------------------------------------------- */
- async incDecQuantity(objetId, incDec = 0) {
- let objetQ = this.items.get(objetId)
- if (objetQ) {
- let newQ = objetQ.system.quantite + incDec
- newQ = Math.max(newQ, 0)
- await this.updateEmbeddedDocuments('Item', [{ _id: objetQ.id, 'system.quantite': newQ }]); // pdates one EmbeddedEntity
- }
- }
-
- /* -------------------------------------------- */
- computeRichesse() {
- let valueSC = 0
- for (let monnaie of this.items) {
- if (monnaie.type == "monnaie") {
- valueSC += Number(monnaie.system.prixsc) * Number(monnaie.system.quantite)
- }
- }
- return MournbladeCYD2Utility.computeMonnaieDetails(valueSC)
- }
-
- /* -------------------------------------------- */
- computeValeurEquipement() {
- let valueSC = 0
- for (let equip of this.items) {
- if (equip.type == "equipement" || equip.type == "arme" || equip.type == "protection") {
- valueSC += Number(equip.system.prixsc) * Number(equip.system.quantite ?? 1)
- valueSC += (Number(equip.system.prixca) * Number(equip.system.quantite ?? 1)) * 20
- valueSC += (Number(equip.system.prixpo) * Number(equip.system.quantite ?? 1)) * 400
- }
- }
- return MournbladeCYD2Utility.computeMonnaieDetails(valueSC)
- }
-
- /* -------------------------------------------- */
- getCompetence(compId) {
- return this.items.get(compId)
- }
-
- /* -------------------------------------------- */
- async setPredilectionUsed(compId, predIdx) {
- let comp = this.items.get(compId)
- let pred = foundry.utils.duplicate(comp.system.predilections)
- pred[predIdx].used = true
- await this.updateEmbeddedDocuments('Item', [{ _id: compId, 'system.predilections': pred }])
- }
-
- /* -------------------------------------------- */
- getInitiativeScore() {
- let init = this.getFlag("world", "last-initiative")
- return init || -1
- }
-
- /* -------------------------------------------- */
- getBestAttackValue() {
- let attackList = this.items.filter(item => (item.type == "arme" || item.type == "talent") && item.system.equipped)
- let maxOff = 0
- let bestArme
- for (let arme of attackList) {
- if (arme.type == "arme") {
- arme = this.prepareArme(arme)
- }
- if (arme.system.totalOffensif > maxOff) {
- maxOff = arme.system.totalOffensif
- bestArme = foundry.utils.duplicate(arme)
- }
- }
- return bestArme
- }
-
- /* -------------------------------------------- */
- getBestDefenseValue() {
- let defenseList = this.items.filter(item => (item.type == "arme") && item.system.equipped)
- let maxDef = 0
- let bestArme
- for (let arme of defenseList) {
- if (arme.type == "arme") {
- arme = this.prepareArme(arme)
- }
- if (arme.system.totalDefensif > maxDef) {
- maxDef = arme.system.totalDefensif
- bestArme = foundry.utils.duplicate(arme)
- }
- }
- return bestArme
- }
-
- /* -------------------------------------------- */
- searchRelevantTalents(competence) {
- let talents = []
-
- for (let talent of this.items) {
- if (talent.type == "talent" && talent.system.isautomated && talent.system.automations.length > 0) {
- for (let auto of talent.system.automations) {
- if (auto.eventtype === "prepare-roll") {
- if (auto.competence.toLowerCase() == competence.name.toLowerCase()) {
- talent = foundry.utils.duplicate(talent)
- talent.system.bonus = auto.bonus
- talent.system.baCost = auto.baCost
- talents.push(talent)
- }
- }
- }
- }
- }
- return talents
- }
-
- /* -------------------------------------------- */
- buildListeAdversites() {
- return []
- }
-
- /* -------------------------------------------- */
- getCommonRollData(attrKey = undefined, compId = undefined, compName = undefined) {
- let rollData = MournbladeCYD2Utility.getBasicRollData()
- rollData.alias = this.name
- rollData.actorImg = this.img
- rollData.actorId = this.id
- rollData.tokenId = this.token?.id
- rollData.img = this.img
- rollData.attributs = MournbladeCYD2Utility.getAttributs()
- rollData.maitriseId = "none"
- rollData.nbEclat = this.system.eclat.value
- rollData.nbBA = this.system.bonneaventure.actuelle
- rollData.nbAdversites = this.getTotalAdversite()
- rollData.talents = []
- rollData.attrKey2 = "none"
- rollData.coupDevastateur = this.items.find(it => it.type == "talent" && it.name.toLowerCase() == "coup dévastateur" && !it.system.used)
- rollData.hasAmbidextre = this.items.find(it => it.type == "talent" && it.name.toLowerCase() == "ambidextre")
- rollData.hasFeinte = this.system.bonneaventure.actuelle > 0 && this.items.find(it => it.type == "talent" && it.name.toLowerCase() == "feinte")
- rollData.isMonte = this.system.combat.monte
- rollData.config = game.system.mournbladecyd2.config
-
- if (attrKey) {
- rollData.attrKey = attrKey
- if (attrKey != "tochoose") {
- rollData.actionImg = "systems/fvtt-mournblade-cyd2/assets/icons/" + this.system.attributs[attrKey].labelnorm + ".webp"
- rollData.attr = foundry.utils.duplicate(this.system.attributs[attrKey])
- }
- }
- if (compId) {
- rollData.competence = foundry.utils.duplicate(this.items.get(compId) || {})
- let maitrises = [{ key: "none", label: "Aucune" }]
- rollData.competence.system.predilections.forEach(function (item) {
- if (item.maitrise) {
- maitrises.push({ key: item.id, label: item.name });
- }
- })
- rollData.maitrises = maitrises // rollData.competence.system.predilections.filter(p => p.maitrise)
- rollData.actionImg = rollData.competence?.img
- rollData.talents = this.searchRelevantTalents(rollData.competence)
- }
- if (compName) {
- rollData.competence = foundry.utils.duplicate(this.items.find(item => item.name.toLowerCase() == compName.toLowerCase()) || {})
- rollData.actionImg = rollData.competence?.img
- }
- return rollData
- }
-
- /* -------------------------------------------- */
- async rollAttribut(attrKey, isInit = false) {
- let rollData = this.getCommonRollData(attrKey)
- rollData.multiplier = (isInit) ? 1 : 2
- rollData.isInit = isInit
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
-
- /* -------------------------------------------- */
- async rollCompetence(attrKey, compId) {
- let rollData = this.getCommonRollData(attrKey, compId)
- rollData.multiplier = 1 // Attr multiplier, always 1 in competence mode
- console.log("RollDatra", rollData)
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
-
- /* -------------------------------------------- */
- async rollArmeOffensif(armeId) {
- let arme = this.items.get(armeId)
- if (arme.type == "arme") {
- arme = this.prepareArme(arme)
- }
- let rollData = this.getCommonRollData(arme.system.attrKey, arme.system.competence._id)
- rollData.arme = arme
- MournbladeCYD2Utility.updateWithTarget(rollData)
- console.log("ARME!", rollData)
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
- /* -------------------------------------------- */
- async rollAssommer() {
- let rollData = this.getCommonRollData("pui", undefined, "Filouterie")
- rollData.assomer = true
- rollData.conditionsCommunes = true
- MournbladeCYD2Utility.updateWithTarget(rollData)
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
- /* -------------------------------------------- */
- async rollCoupBas() {
- let rollData = this.getCommonRollData("pui", undefined, "Mêlée")
- rollData.coupBas = true
- rollData.conditionsCommunes = true
- MournbladeCYD2Utility.updateWithTarget(rollData)
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
- /* -------------------------------------------- */
- async rollImmobiliser() {
- let rollData = this.getCommonRollData("pui", undefined, "Mêlée")
- rollData.immobiliser = true
- rollData.conditionsCommunes = true
- rollData.cibleconsciente = true
- MournbladeCYD2Utility.updateWithTarget(rollData)
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
- /* -------------------------------------------- */
- async rollRepousser() {
- let rollData = this.getCommonRollData("pui", undefined, "Mêlée")
- rollData.repousser = true
- rollData.conditionsCommunes = true
- rollData.cibleconsciente = true
- MournbladeCYD2Utility.updateWithTarget(rollData)
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
- /* -------------------------------------------- */
- async rollDesengager() {
- let rollData = this.getCommonRollData("adr", undefined, "Mouvements")
- rollData.desengager = true
- rollData.conditionsCommunes = true
- MournbladeCYD2Utility.updateWithTarget(rollData)
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
-
- /* -------------------------------------------- */
- async rollArmeDegats(armeId, targetVigueur = undefined, rollDataInput = undefined) {
- let arme = this.items.get(armeId)
- if (arme.type == "arme") {
- arme = this.prepareArme(arme)
- }
- console.log("DEGATS", arme, targetVigueur, rollDataInput)
- let roll
- let bonus = 0
- let bonus2 = 0
-
- if (rollDataInput?.applyCoupDevastateur) {
- bonus2 = Math.floor(this.system.attributs.pui.value / 2)
- let talent = this.items.find(item => item.type == "talent" && item.name.toLowerCase() == "coup dévastateur")
- this.updateEmbeddedDocuments('Item', [{ _id: talent.id, 'system.used': true }])
- }
-
- if (rollDataInput?.isHeroique) {
- if (rollDataInput?.attaqueCharge) {
- bonus = 5
- }
- if (rollDataInput?.chargeCavalerie) {
- bonus = 6
- }
- roll = await new Roll("2d10rr10+" + arme.system.totalDegats + "+" + bonus + "+" + bonus2).roll()
- } else {
- if (rollDataInput?.attaqueCharge) {
- bonus = 3
- }
- if (rollDataInput?.chargeCavalerie) {
- bonus = 4
- }
- roll = await new Roll("1d10+" + arme.system.totalDegats + "+" + bonus + "+" + bonus2).roll()
- }
- await MournbladeCYD2Utility.showDiceSoNice(roll, game.settings.get("core", "rollMode"));
- let nbEtatPerdus = 0
- if (targetVigueur) {
- nbEtatPerdus = Math.floor(roll.total / targetVigueur)
- }
- //console.log(roll)
- let rollData = {
- arme: arme,
- finalResult: roll.total,
- formula: roll.formula,
- alias: this.name,
- actorImg: this.img,
- actorId: this.id,
- defenderTokenId: rollDataInput?.defenderTokenId,
- actionImg: arme.img,
- targetVigueur: targetVigueur,
- nbEtatPerdus: nbEtatPerdus
- }
- MournbladeCYD2Utility.createChatWithRollMode(rollData.alias, {
- content: await renderTemplate(`systems/fvtt-mournblade-cyd2/templates/chat-degats-result.html`, rollData)
- })
-
- if (rollDataInput?.defenderTokenId && nbEtatPerdus) {
- MournbladeCYD2Utility.applyCombativite(rollDataInput, nbEtatPerdus)
- }
-
- }
-}
diff --git a/.history/modules/mournblade-cyd2-actor_20251026083937.js b/.history/modules/mournblade-cyd2-actor_20251026083937.js
deleted file mode 100644
index 2188fb5..0000000
--- a/.history/modules/mournblade-cyd2-actor_20251026083937.js
+++ /dev/null
@@ -1,904 +0,0 @@
-/* -------------------------------------------- */
-import { MournbladeCYD2Utility } from "./mournblade-cyd2-utility.js";
-import { MournbladeCYD2RollDialog } from "./mournblade-cyd2-roll-dialog.js";
-
-/* -------------------------------------------- */
-const __degatsBonus = [-2, -2, -1, -1, 0, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 8, 8, 9, 9, 10, 10]
-const __vitesseBonus = [-2, -2, -1, -1, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8]
-
-/* -------------------------------------------- */
-/**
- * Extend the base Actor entity by defining a custom roll data structure which is ideal for the Simple system.
- * @extends {Actor}
- */
-export class MournbladeCYD2Actor extends Actor {
-
- /* -------------------------------------------- */
- /**
- * Override the create() function to provide additional SoS functionality.
- *
- * This overrided create() function adds initial items
- * Namely: Basic skills, money,
- *
- * @param {Object} data Barebones actor data which this function adds onto.
- * @param {Object} options (Unused) Additional options which customize the creation workflow.
- *
- */
-
- static async create(data, options) {
-
- // Case of compendium global import
- if (data instanceof Array) {
- return super.create(data, options);
- }
- // If the created actor has items (only applicable to duplicated actors) bypass the new actor creation logic
- if (data.items) {
- let actor = super.create(data, options);
- return actor;
- }
-
- if (data.type == 'personnage') {
- const skills = await MournbladeCYD2Utility.loadCompendium("fvtt-mournblade-cyd2.skills")
- data.items = skills.map(i => i.toObject())
- }
- if (data.type == 'creature') {
- const skills = await MournbladeCYD2Utility.loadCompendium("fvtt-mournblade-cyd2.skills-creatures")
- data.items = skills.map(i => i.toObject())
- data.items.push({ name: "Arme naturelle 1", type: 'arme', img: "systems/fvtt-mournblade-cyd2/assets/icons/melee.webp", system: { typearme: "contact", bonusmaniementoff: 0, seuildefense: 0, degats: "0" } })
- data.items.push({ name: "Arme naturelle 2", type: 'arme', img: "systems/fvtt-mournblade-cyd2/assets/icons/melee.webp", system: { typearme: "contact", bonusmaniementoff: 0, seuildefense: 0, degats: "0" } })
- }
-
- return super.create(data, options);
- }
-
- /* -------------------------------------------- */
- getBonusDefenseFromTalents() {
- let talents = this.items.filter(item => item.type == "talent" && item.system.isautomated)
- let bonus = 0
- for (let talent of talents) {
- for (let auto of talent.system.automations) {
- if (auto.eventtype == "bonus-permanent" && auto.bonusname == "bonus-defensif") {
- bonus += Number(auto.bonus || 0)
- }
- }
- }
- return bonus
- }
-
- /* -------------------------------------------- */
- prepareArme(arme) {
- if (this.type == "cellule") {
- return arme
- }
-
- arme = foundry.utils.duplicate(arme)
- let combat = this.getCombatValues()
- if (arme.system.typearme == "contact" || arme.system.typearme == "contactjet") {
- let bonusDefense = this.getBonusDefenseFromTalents()
- arme.system.competence = foundry.utils.duplicate(this.items.find(item => item.type == "competence" && item.name.toLowerCase() == "mêlée"))
- arme.system.attrKey = "pui"
- arme.system.totalDegats = arme.system.degats + "+" + combat.bonusDegatsTotal
- arme.system.totalOffensif = this.system.attributs.pui.value + arme.system.competence.system.niveau + arme.system.bonusmaniementoff + (this.system.combat.monte ? 3 : 0)
- arme.system.totalDefensif = combat.defenseTotal + arme.system.competence.system.niveau + arme.system.seuildefense + bonusDefense + (this.system.combat.monte ? 3 : 0)
- console.log("Arme", arme.system.totalDefensif, combat, arme.system.competence.system.niveau, arme.system.seuildefense, bonusDefense)
- arme.system.isdefense = true
- arme.system.isMelee = true
- arme.system.isDistance = false
- }
- if (arme.system.typearme == "jet" || arme.system.typearme == "tir") {
- arme.system.competence = foundry.utils.duplicate(this.items.find(item => item.type == "competence" && item.name.toLowerCase() == "armes à distance"))
- arme.system.attrKey = "adr"
- arme.system.totalOffensif = this.system.attributs.adr.value + arme.system.competence.system.niveau + arme.system.bonusmaniementoff
- arme.system.totalDegats = arme.system.degats
- arme.system.isMelee = false
- arme.system.isDistance = true
- if (arme.system.isdefense) {
- arme.system.totalDefensif = combat.defenseTotal + arme.system.competence.system.niveau + arme.system.seuildefense
- }
- }
- return arme
- }
-
- /* -------------------------------------------- */
- getItemSorted(types) {
- let items = this.items.filter(item => types.includes(item.type)) || []
- MournbladeCYD2Utility.sortArrayObjectsByName(items)
- return items
- }
- getWeapons() {
- let armes = []
- for (let arme of this.items) {
- if (arme.type == "arme") {
- armes.push(this.prepareArme(arme))
- }
- }
- MournbladeCYD2Utility.sortArrayObjectsByName(armes)
- return armes
- }
- getMonnaies() {
- return this.getItemSorted(["monnaie"])
- }
- getEquipments() {
- return this.getItemSorted(["equipement"])
- }
- getArtefacts() {
- return this.getItemSorted(["artefact"])
- }
- getArmors() {
- return this.getItemSorted(["protection"])
- }
- getHistoriques() {
- return this.getItemSorted(["historique"])
- }
- getProfils() {
- return this.getItemSorted(["profil"])
- }
- getTalents() {
- return this.getItemSorted(["talent"])
- }
- getRessources() {
- return this.getItemSorted(["ressource"])
- }
- getContacts() {
- return this.getItemSorted(["contact"])
- }
- getMutations() {
- return this.getItemSorted(["mutation"])
- }
- getDons() {
- return this.getItemSorted(["don"])
- }
- getPactes() {
- return this.getItemSorted(["pacte"])
- }
- getTendances() {
- return this.getItemSorted(["tendance"])
- }
- getRunes() {
- return this.getItemSorted(["rune"])
- }
- getTraitsChaotiques() {
- return this.getItemSorted(["traitchaotique"])
- }
- getTraitsEspeces() {
- return this.getItemSorted(["traitespece"])
- }
-
- /* -------------------------------------------- */
- getAspect() {
- return (this.system.balance.loi > this.system.balance.chaos) ? this.system.balance.loi : this.system.balance.chaos
- }
- getMarge() {
- return Math.abs(this.system.balance.loi - this.system.balance.chaos)
- }
- getAlignement() {
- return (this.system.balance.loi > this.system.balance.chaos) ? "loyal" : "chaotique"
- }
-
- /* -------------------------------------------- */
- getSkills() {
- let comp = []
- for (let item of this.items) {
- item = foundry.utils.duplicate(item)
- if (item.type == "competence") {
- item.system.attribut1total = item.system.niveau + (this.system.attributs[item.system.attribut1]?.value || 0)
- item.system.attribut2total = item.system.niveau + (this.system.attributs[item.system.attribut2]?.value || 0)
- item.system.attribut3total = item.system.niveau + (this.system.attributs[item.system.attribut3]?.value || 0)
- if (item.system.niveau == 0) {
- item.system.attribut1total -= 3
- item.system.attribut2total -= 3
- item.system.attribut3total -= 3
- }
- item.system.attribut1label = this.system.attributs[item.system.attribut1]?.label || ""
- item.system.attribut2label = this.system.attributs[item.system.attribut2]?.label || ""
- item.system.attribut3label = this.system.attributs[item.system.attribut3]?.label || ""
- comp.push(item)
- }
- }
- MournbladeCYD2Utility.sortArrayObjectsByName(comp)
- return comp
- }
-
- /* ----------------------- --------------------- */
- addMember(actorId) {
- let members = foundry.utils.duplicate(this.system.members)
- members.push({ id: actorId })
- this.update({ 'system.members': members })
- }
- async removeMember(actorId) {
- let members = this.system.members.filter(it => it.id != actorId)
- this.update({ 'system.members': members })
- }
-
- /* -------------------------------------------- */
- getDefenseBase() {
- return Math.max(this.system.attributs.tre.value, this.system.attributs.adr.value)
- }
-
- /* -------------------------------------------- */
- getVitesseBase() {
- return 5 + __vitesseBonus[this.system.attributs.adr.value]
- }
- /* -------------------------------------------- */
- getProtection() {
- let equipProtection = 0
- for (let armor of this.items) {
- if (armor.type == "protection" && armor.system.equipped) {
- equipProtection += Number(armor.system.protection)
- }
- }
- if (equipProtection < 4) {
- return 4 + equipProtection // Cas des boucliers + sans armure
- }
- return equipProtection // Uniquement la protection des armures + boucliers
- }
-
- /* -------------------------------------------- */
- getCombatValues() {
- if (this.type == "cellule") {
- return {
- initBase: 0,
- initTotal: 0,
- bonusDegats: 0,
- bonusDegatsTotal: 0,
- vitesseBase: 0,
- vitesseTotal: 0,
- defenseBase: 0,
- protection: 0,
- defenseTotal: 0
- }
- }
-
- let combat = {
- initBase: this.system.attributs.adr.value,
- initTotal: this.system.attributs.adr.value + this.system.combat.initbonus,
- bonusDegats: this.getBonusDegats(),
- bonusDegatsTotal: this.getBonusDegats() + this.system.combat.bonusdegats,
- vitesseBase: this.getVitesseBase(),
- vitesseTotal: this.getVitesseBase() + this.system.combat.vitessebonus,
- defenseBase: this.getDefenseBase(),
- protection: this.getProtection(),
- defenseTotal: this.getDefenseBase() + this.system.combat.defensebonus + this.getProtection() - this.getTotalAdversite() + (this.system.combat.defensetotale ? 3 : 0)
- }
- return combat
- }
-
- /* -------------------------------------------- */
- prepareBaseData() {
- }
-
- /* -------------------------------------------- */
- async prepareData() {
- super.prepareData();
- }
-
- /* -------------------------------------------- */
- prepareDerivedData() {
-
- if (this.type == 'personnage') {
- let talentBonus = this.getVigueurBonus()
- let vigueur = Math.floor((this.system.attributs.pui.value + this.system.attributs.tre.value) / 2) + talentBonus + this.system.sante.vigueurmodifier
- if (vigueur != this.system.sante.vigueur) {
- this.update({ 'system.sante.vigueur': vigueur })
- }
-
- let seuilPouvoirBonus = this.getSeuilPouvoirBonus()
- let seuilPouvoir = Math.floor((this.system.attributs.tre.value + this.system.attributs.cla.value) / 2) + seuilPouvoirBonus + this.system.ame.seuilpouvoirmodifier
- if (seuilPouvoir != this.system.ame.seuilpouvoir) {
- this.update({ 'system.ame.seuilpouvoir': seuilPouvoir })
- }
- }
- super.prepareDerivedData()
- }
-
- /* -------------------------------------------- */
- _preUpdate(changed, options, user) {
- if (changed?.system?.sante?.etat && changed?.system?.sante?.etat != this.system.sante.etat) {
- setTimeout(() => {
- this.processCombativite(changed.system.sante)
- }, 800)
- }
- if (changed?.system?.ame?.etat && changed?.system?.ame?.etat != this.system.ame.etat) {
- // Limiter l'état d'Âme au maximum défini
- let maxAme = this.system.ame.max || this.system.ame.nbame
- if (changed.system.ame.etat > maxAme) {
- changed.system.ame.etat = maxAme
- }
- setTimeout(() => {
- this.processAme(changed.system.ame)
- }, 800)
- }
- // Si le max d'Âme change, ajuster l'état actuel si nécessaire
- if (changed?.system?.ame?.max && changed.system.ame.max != this.system.ame.max) {
- if (this.system.ame.etat > changed.system.ame.max) {
- changed.system.ame.etat = changed.system.ame.max
- }
- }
- super._preUpdate(changed, options, user);
- }
-
- /* -------------------------------------------- */
- _onUpdate(data, options, user) {
- super._onUpdate(data, options, user);
- }
- /* -------------------------------------------- */
- getItemById(id) {
- let item = this.items.find(item => item.id == id);
- if (item) {
- item = foundry.utils.duplicate(item)
- }
- return item;
- }
-
- /* -------------------------------------------- */
- async equipItem(itemId) {
- let item = this.items.find(item => item.id == itemId)
- if (item && item.system) {
- let update = { _id: item.id, "system.equipped": !item.system.equipped }
- await this.updateEmbeddedDocuments('Item', [update]); // Updates one EmbeddedEntity
- }
- }
-
- /* -------------------------------------------- */
- editItemField(itemId, itemType, itemField, dataType, value) {
- let item = this.items.find(item => item.id == itemId)
- if (item) {
- console.log("Item ", item, itemField, dataType, value)
- if (dataType.toLowerCase() == "number") {
- value = Number(value)
- } else {
- value = String(value)
- }
- let update = { _id: item.id, [`system.${itemField}`]: value };
- this.updateEmbeddedDocuments("Item", [update])
- }
- }
-
- /* -------------------------------------------- */
- checkAttribut(attribut, minLevel) {
- let attr = this.system.attributs.find(at => at.labelnorm == attribut.toLowerCase())
- if (attr && attr.value >= minLevel) {
- return { isValid: true, attr: foundry.utils.duplicate(attr) }
- }
- return { isValid: false }
- }
- /* -------------------------------------------- */
- checkAttributOrCompetenceLevel(compName, minLevel) {
- let comp = this.items.find(i => i.type == "competence" && i.name.toLowerCase() == compName.toLowerCase() && i.system.niveau >= minLevel)
- if (comp) {
- return { isValid: true, item: foundry.utils.duplicate(comp) }
- } else {
- for (let attrKey in this.system.attributs) {
- if (this.system.attributs[attrKey].label.toLowerCase() == compName.toLowerCase() && this.system.attributs[attrKey].value >= minLevel) {
- return { isValid: true, item: foundry.utils.duplicate(this.system.attributs[attrKey]) }
- }
- }
- }
- return { isValid: false, warningMessage: `Prérequis insuffisant : la compétence/attribut ${compName} doit être de niveau ${minLevel} au minimum` }
- }
- /* -------------------------------------------- */
- addCompetenceBonus(compName, bonus, baCost) {
- let comp = this.items.find(i => i.type == "competence" && i.name.toLowerCase() == compName.toLowerCase())
- if (comp) {
- comp = foundry.utils.duplicate(comp)
- comp.system.bonus = bonus
- comp.system.baCost = baCost
- return { isValid: true, item: comp }
- }
- return { isValid: false, warningMessage: `Compétence ${compName} non trouvée` }
- }
- /* -------------------------------------------- */
- checkIfCompetence(compName) {
- let comp = this.items.find(i => i.type == "competence" && i.name.toLowerCase() == compName.toLowerCase())
- if (comp) {
- return { isValid: true, item: comp }
- }
- return { isValid: false }
- }
- /* -------------------------------------------- */
- getVigueur() {
- return this.system.sante.vigueur
- }
-
- /* -------------------------------------------- */
- getVigueurBonus() {
- let talents = this.items.filter(item => item.type == "talent" && item.system.isautomated)
- let bonus = 0
- for (let talent of talents) {
- for (let auto of talent.system.automations) {
- if (auto.eventtype == "bonus-permanent" && auto.bonusname == "vigueur") {
- bonus += Number(auto.bonus || 0)
- }
- }
- }
- return bonus
- }
-
- /* -------------------------------------------- */
- getSeuilPouvoir() {
- return this.system.ame.seuilpouvoir
- }
-
- /* -------------------------------------------- */
- getSeuilPouvoirBonus() {
- let talents = this.items.filter(item => item.type == "talent" && item.system.isautomated)
- let bonus = 0
- for (let talent of talents) {
- for (let auto of talent.system.automations) {
- if (auto.eventtype == "bonus-permanent" && auto.bonusname == "seuilpouvoir") {
- bonus += Number(auto.bonus || 0)
- }
- }
- }
- return bonus
- }
-
- /* -------------------------------------------- */
- getAmeMax() {
- return Math.min(this.system.ame.max || this.system.ame.nbame, this.system.ame.nbame)
- }
-
- /* -------------------------------------------- */
- getBonneAventure() {
- return this.system.bonneaventure.actuelle
- }
- /* -------------------------------------------- */
- checkBonneAventure(cost) {
- return (this.system.bonneaventure.actuelle >= cost)
- }
- /* -------------------------------------------- */
- changeBonneAventure(value) {
- let newBA = this.system.bonneaventure.actuelle
- newBA += value
- this.update({ 'system.bonneaventure.actuelle': newBA })
- }
-
- /* -------------------------------------------- */
- getEclat() {
- return this.system.eclat.value
- }
-
- /* -------------------------------------------- */
- changeEclat(value) {
- let newE = this.system.eclat.value
- newE += value
- this.update({ 'system.eclat.value': newE })
- }
-
- /* -------------------------------------------- */
- compareName(a, b) {
- if (a.name < b.name) {
- return -1;
- }
- if (a.name > b.name) {
- return 1;
- }
- return 0;
- }
-
- /* -------------------------------------------- */
- getAttribute(attrKey) {
- return this.system.attributes[attrKey]
- }
-
- /* -------------------------------------------- */
- getBonusDegats() {
- return 0;
- }
-
- /* -------------------------------------------- */
- changeEtatCombativite(value) {
- if (value === "vaincu") {
- value = 200
- }
- let sante = foundry.utils.duplicate(this.system.sante)
- sante.etat += Number(value)
- sante.etat = Math.max(sante.etat, 0)
- sante.etat = Math.min(sante.etat, this.system.sante.nbcombativite)
- this.update({ 'system.sante': sante })
- if (sante.etat == this.system.sante.nbcombativite) {
- ChatMessage.create({ content: `${this.name} est vaincu !` })
- }
- // Duplicated ! this.processCombativite(sante)
- }
-
- /* -------------------------------------------- */
- changeEtatAme(value) {
- if (value === "brise") {
- value = 200
- }
- let ame = foundry.utils.duplicate(this.system.ame)
- ame.etat += Number(value)
- ame.etat = Math.max(ame.etat, 0)
- // L'état ne peut pas dépasser le maximum actuel d'âme
- let maxAme = this.system.ame.max || this.system.ame.nbame
- ame.etat = Math.min(ame.etat, maxAme)
- this.update({ 'system.ame': ame })
- if (ame.etat >= maxAme) {
- ChatMessage.create({ content: `${this.name} est brisé !` })
- }
- }
-
- /* -------------------------------------------- */
- processCombativite(sante) {
- sante = sante || foundry.utils.duplicate(this.system.sante)
- // Gestion des états affaibli et très affaibli
- if (sante.etat == this.system.sante.nbcombativite - 2 || sante.etat == this.system.sante.nbcombativite - 1) {
- if (sante.etat == this.system.sante.nbcombativite - 2 && this.items.find(item => item.type == "talent" && item.name.toLowerCase() == "encaissement")) {
- ChatMessage.create({ content: `${this.name} ne subit pas les 2 adversités rouge grâce à Encaissement. Pensez à les ajouter à la fin de la scène !` })
- } else if (sante.etat == this.system.sante.nbcombativite - 1 && this.items.find(item => item.type == "talent" && item.name.toLowerCase().includes("vaillant"))) {
- ChatMessage.create({ content: `${this.name} ne subit pas les 2 adversités rouge grâce à Vaillant. Pensez à les ajouter à la fin de la scène !` })
- } else {
- ChatMessage.create({ content: `${this.name} subit 2 adversités rouge !` })
- this.incDecAdversite("rouge", 2)
- }
- }
- }
-
- /* -------------------------------------------- */
- processAme(ame) {
- ame = ame || foundry.utils.duplicate(this.system.ame)
- let maxAme = this.system.ame.max || this.system.ame.nbame
- // Gestion des états Traumatisé, Très Traumatisé et Brisé en fonction du maximum actuel
- // Les seuils sont calculés par rapport au maximum d'âme actuel
- if (maxAme >= 3 && ame.etat >= maxAme - 2) {
- if (ame.etat == maxAme - 2) {
- ChatMessage.create({ content: `${this.name} est Traumatisé !` })
- } else if (ame.etat == maxAme - 1) {
- ChatMessage.create({ content: `${this.name} est Très Traumatisé !` })
- } else if (ame.etat >= maxAme) {
- ChatMessage.create({ content: `${this.name} est Brisé !` })
- }
- } else if (ame.etat >= maxAme) {
- ChatMessage.create({ content: `${this.name} est Brisé !` })
- }
- }
-
- /* -------------------------------------------- */
- async equipGear(equipmentId) {
- let item = this.items.find(item => item.id == equipmentId);
- if (item?.system?.data) {
- let update = { _id: item.id, "system.equipped": !item.system.equipped };
- await this.updateEmbeddedDocuments('Item', [update]); // Updates one EmbeddedEntity
- }
- }
-
- /* -------------------------------------------- */
- getSubActors() {
- let subActors = [];
- for (let id of this.system.subactors) {
- subActors.push(foundry.utils.duplicate(game.actors.get(id)));
- }
- return subActors;
- }
- /* -------------------------------------------- */
- async addSubActor(subActorId) {
- let subActors = foundry.utils.duplicate(this.system.subactors);
- subActors.push(subActorId);
- await this.update({ 'system.subactors': subActors });
- }
- /* -------------------------------------------- */
- async delSubActor(subActorId) {
- let newArray = [];
- for (let id of this.system.subactors) {
- if (id != subActorId) {
- newArray.push(id);
- }
- }
- await this.update({ 'system.subactors': newArray });
- }
-
- /* -------------------------------------------- */
- getTotalAdversite() {
- return this.system.adversite.bleue + this.system.adversite.rouge + this.system.adversite.noire
- }
-
- /* -------------------------------------------- */
- async incDecAdversite(adv, incDec = 0) {
- let adversite = foundry.utils.duplicate(this.system.adversite)
- adversite[adv] += Number(incDec)
- adversite[adv] = Math.max(adversite[adv], 0)
- adversite[adv] = Math.min(adversite[adv], 20)
- this.update({ 'system.adversite': adversite })
- }
- /* -------------------------------------------- */
- async incDecQuantity(objetId, incDec = 0) {
- let objetQ = this.items.get(objetId)
- if (objetQ) {
- let newQ = objetQ.system.quantite + incDec
- newQ = Math.max(newQ, 0)
- await this.updateEmbeddedDocuments('Item', [{ _id: objetQ.id, 'system.quantite': newQ }]); // pdates one EmbeddedEntity
- }
- }
-
- /* -------------------------------------------- */
- computeRichesse() {
- let valueSC = 0
- for (let monnaie of this.items) {
- if (monnaie.type == "monnaie") {
- valueSC += Number(monnaie.system.prixsc) * Number(monnaie.system.quantite)
- }
- }
- return MournbladeCYD2Utility.computeMonnaieDetails(valueSC)
- }
-
- /* -------------------------------------------- */
- computeValeurEquipement() {
- let valueSC = 0
- for (let equip of this.items) {
- if (equip.type == "equipement" || equip.type == "arme" || equip.type == "protection") {
- valueSC += Number(equip.system.prixsc) * Number(equip.system.quantite ?? 1)
- valueSC += (Number(equip.system.prixca) * Number(equip.system.quantite ?? 1)) * 20
- valueSC += (Number(equip.system.prixpo) * Number(equip.system.quantite ?? 1)) * 400
- }
- }
- return MournbladeCYD2Utility.computeMonnaieDetails(valueSC)
- }
-
- /* -------------------------------------------- */
- getCompetence(compId) {
- return this.items.get(compId)
- }
-
- /* -------------------------------------------- */
- async setPredilectionUsed(compId, predIdx) {
- let comp = this.items.get(compId)
- let pred = foundry.utils.duplicate(comp.system.predilections)
- pred[predIdx].used = true
- await this.updateEmbeddedDocuments('Item', [{ _id: compId, 'system.predilections': pred }])
- }
-
- /* -------------------------------------------- */
- getInitiativeScore() {
- let init = this.getFlag("world", "last-initiative")
- return init || -1
- }
-
- /* -------------------------------------------- */
- getBestAttackValue() {
- let attackList = this.items.filter(item => (item.type == "arme" || item.type == "talent") && item.system.equipped)
- let maxOff = 0
- let bestArme
- for (let arme of attackList) {
- if (arme.type == "arme") {
- arme = this.prepareArme(arme)
- }
- if (arme.system.totalOffensif > maxOff) {
- maxOff = arme.system.totalOffensif
- bestArme = foundry.utils.duplicate(arme)
- }
- }
- return bestArme
- }
-
- /* -------------------------------------------- */
- getBestDefenseValue() {
- let defenseList = this.items.filter(item => (item.type == "arme") && item.system.equipped)
- let maxDef = 0
- let bestArme
- for (let arme of defenseList) {
- if (arme.type == "arme") {
- arme = this.prepareArme(arme)
- }
- if (arme.system.totalDefensif > maxDef) {
- maxDef = arme.system.totalDefensif
- bestArme = foundry.utils.duplicate(arme)
- }
- }
- return bestArme
- }
-
- /* -------------------------------------------- */
- searchRelevantTalents(competence) {
- let talents = []
-
- for (let talent of this.items) {
- if (talent.type == "talent" && talent.system.isautomated && talent.system.automations.length > 0) {
- for (let auto of talent.system.automations) {
- if (auto.eventtype === "prepare-roll") {
- if (auto.competence.toLowerCase() == competence.name.toLowerCase()) {
- talent = foundry.utils.duplicate(talent)
- talent.system.bonus = auto.bonus
- talent.system.baCost = auto.baCost
- talents.push(talent)
- }
- }
- }
- }
- }
- return talents
- }
-
- /* -------------------------------------------- */
- buildListeAdversites() {
- return []
- }
-
- /* -------------------------------------------- */
- getCommonRollData(attrKey = undefined, compId = undefined, compName = undefined) {
- let rollData = MournbladeCYD2Utility.getBasicRollData()
- rollData.alias = this.name
- rollData.actorImg = this.img
- rollData.actorId = this.id
- rollData.tokenId = this.token?.id
- rollData.img = this.img
- rollData.attributs = MournbladeCYD2Utility.getAttributs()
- rollData.maitriseId = "none"
- rollData.nbEclat = this.system.eclat.value
- rollData.nbBA = this.system.bonneaventure.actuelle
- rollData.nbAdversites = this.getTotalAdversite()
- rollData.talents = []
- rollData.attrKey2 = "none"
- rollData.coupDevastateur = this.items.find(it => it.type == "talent" && it.name.toLowerCase() == "coup dévastateur" && !it.system.used)
- rollData.hasAmbidextre = this.items.find(it => it.type == "talent" && it.name.toLowerCase() == "ambidextre")
- rollData.hasFeinte = this.system.bonneaventure.actuelle > 0 && this.items.find(it => it.type == "talent" && it.name.toLowerCase() == "feinte")
- rollData.isMonte = this.system.combat.monte
- rollData.config = game.system.mournbladecyd2.config
-
- if (attrKey) {
- rollData.attrKey = attrKey
- if (attrKey != "tochoose") {
- rollData.actionImg = "systems/fvtt-mournblade-cyd2/assets/icons/" + this.system.attributs[attrKey].labelnorm + ".webp"
- rollData.attr = foundry.utils.duplicate(this.system.attributs[attrKey])
- }
- }
- if (compId) {
- rollData.competence = foundry.utils.duplicate(this.items.get(compId) || {})
- let maitrises = [{ key: "none", label: "Aucune" }]
- rollData.competence.system.predilections.forEach(function (item) {
- if (item.maitrise) {
- maitrises.push({ key: item.id, label: item.name });
- }
- })
- rollData.maitrises = maitrises // rollData.competence.system.predilections.filter(p => p.maitrise)
- rollData.actionImg = rollData.competence?.img
- rollData.talents = this.searchRelevantTalents(rollData.competence)
- }
- if (compName) {
- rollData.competence = foundry.utils.duplicate(this.items.find(item => item.name.toLowerCase() == compName.toLowerCase()) || {})
- rollData.actionImg = rollData.competence?.img
- }
- return rollData
- }
-
- /* -------------------------------------------- */
- async rollAttribut(attrKey, isInit = false) {
- let rollData = this.getCommonRollData(attrKey)
- rollData.multiplier = (isInit) ? 1 : 2
- rollData.isInit = isInit
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
-
- /* -------------------------------------------- */
- async rollCompetence(attrKey, compId) {
- let rollData = this.getCommonRollData(attrKey, compId)
- rollData.multiplier = 1 // Attr multiplier, always 1 in competence mode
- console.log("RollDatra", rollData)
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
-
- /* -------------------------------------------- */
- async rollArmeOffensif(armeId) {
- let arme = this.items.get(armeId)
- if (arme.type == "arme") {
- arme = this.prepareArme(arme)
- }
- let rollData = this.getCommonRollData(arme.system.attrKey, arme.system.competence._id)
- rollData.arme = arme
- MournbladeCYD2Utility.updateWithTarget(rollData)
- console.log("ARME!", rollData)
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
- /* -------------------------------------------- */
- async rollAssommer() {
- let rollData = this.getCommonRollData("pui", undefined, "Filouterie")
- rollData.assomer = true
- rollData.conditionsCommunes = true
- MournbladeCYD2Utility.updateWithTarget(rollData)
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
- /* -------------------------------------------- */
- async rollCoupBas() {
- let rollData = this.getCommonRollData("pui", undefined, "Mêlée")
- rollData.coupBas = true
- rollData.conditionsCommunes = true
- MournbladeCYD2Utility.updateWithTarget(rollData)
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
- /* -------------------------------------------- */
- async rollImmobiliser() {
- let rollData = this.getCommonRollData("pui", undefined, "Mêlée")
- rollData.immobiliser = true
- rollData.conditionsCommunes = true
- rollData.cibleconsciente = true
- MournbladeCYD2Utility.updateWithTarget(rollData)
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
- /* -------------------------------------------- */
- async rollRepousser() {
- let rollData = this.getCommonRollData("pui", undefined, "Mêlée")
- rollData.repousser = true
- rollData.conditionsCommunes = true
- rollData.cibleconsciente = true
- MournbladeCYD2Utility.updateWithTarget(rollData)
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
- /* -------------------------------------------- */
- async rollDesengager() {
- let rollData = this.getCommonRollData("adr", undefined, "Mouvements")
- rollData.desengager = true
- rollData.conditionsCommunes = true
- MournbladeCYD2Utility.updateWithTarget(rollData)
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
-
- /* -------------------------------------------- */
- async rollArmeDegats(armeId, targetVigueur = undefined, rollDataInput = undefined) {
- let arme = this.items.get(armeId)
- if (arme.type == "arme") {
- arme = this.prepareArme(arme)
- }
- console.log("DEGATS", arme, targetVigueur, rollDataInput)
- let roll
- let bonus = 0
- let bonus2 = 0
-
- if (rollDataInput?.applyCoupDevastateur) {
- bonus2 = Math.floor(this.system.attributs.pui.value / 2)
- let talent = this.items.find(item => item.type == "talent" && item.name.toLowerCase() == "coup dévastateur")
- this.updateEmbeddedDocuments('Item', [{ _id: talent.id, 'system.used': true }])
- }
-
- if (rollDataInput?.isHeroique) {
- if (rollDataInput?.attaqueCharge) {
- bonus = 5
- }
- if (rollDataInput?.chargeCavalerie) {
- bonus = 6
- }
- roll = await new Roll("2d10rr10+" + arme.system.totalDegats + "+" + bonus + "+" + bonus2).roll()
- } else {
- if (rollDataInput?.attaqueCharge) {
- bonus = 3
- }
- if (rollDataInput?.chargeCavalerie) {
- bonus = 4
- }
- roll = await new Roll("1d10+" + arme.system.totalDegats + "+" + bonus + "+" + bonus2).roll()
- }
- await MournbladeCYD2Utility.showDiceSoNice(roll, game.settings.get("core", "rollMode"));
- let nbEtatPerdus = 0
- if (targetVigueur) {
- nbEtatPerdus = Math.floor(roll.total / targetVigueur)
- }
- //console.log(roll)
- let rollData = {
- arme: arme,
- finalResult: roll.total,
- formula: roll.formula,
- alias: this.name,
- actorImg: this.img,
- actorId: this.id,
- defenderTokenId: rollDataInput?.defenderTokenId,
- actionImg: arme.img,
- targetVigueur: targetVigueur,
- nbEtatPerdus: nbEtatPerdus
- }
- MournbladeCYD2Utility.createChatWithRollMode(rollData.alias, {
- content: await renderTemplate(`systems/fvtt-mournblade-cyd2/templates/chat-degats-result.html`, rollData)
- })
-
- if (rollDataInput?.defenderTokenId && nbEtatPerdus) {
- MournbladeCYD2Utility.applyCombativite(rollDataInput, nbEtatPerdus)
- }
-
- }
-}
diff --git a/.history/modules/mournblade-cyd2-actor_20251026084242.js b/.history/modules/mournblade-cyd2-actor_20251026084242.js
deleted file mode 100644
index 53ac75e..0000000
--- a/.history/modules/mournblade-cyd2-actor_20251026084242.js
+++ /dev/null
@@ -1,908 +0,0 @@
-/* -------------------------------------------- */
-import { MournbladeCYD2Utility } from "./mournblade-cyd2-utility.js";
-import { MournbladeCYD2RollDialog } from "./mournblade-cyd2-roll-dialog.js";
-
-/* -------------------------------------------- */
-const __degatsBonus = [-2, -2, -1, -1, 0, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 8, 8, 9, 9, 10, 10]
-const __vitesseBonus = [-2, -2, -1, -1, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8]
-
-/* -------------------------------------------- */
-/**
- * Extend the base Actor entity by defining a custom roll data structure which is ideal for the Simple system.
- * @extends {Actor}
- */
-export class MournbladeCYD2Actor extends Actor {
-
- /* -------------------------------------------- */
- /**
- * Override the create() function to provide additional SoS functionality.
- *
- * This overrided create() function adds initial items
- * Namely: Basic skills, money,
- *
- * @param {Object} data Barebones actor data which this function adds onto.
- * @param {Object} options (Unused) Additional options which customize the creation workflow.
- *
- */
-
- static async create(data, options) {
-
- // Case of compendium global import
- if (data instanceof Array) {
- return super.create(data, options);
- }
- // If the created actor has items (only applicable to duplicated actors) bypass the new actor creation logic
- if (data.items) {
- let actor = super.create(data, options);
- return actor;
- }
-
- if (data.type == 'personnage') {
- const skills = await MournbladeCYD2Utility.loadCompendium("fvtt-mournblade-cyd2.skills")
- data.items = skills.map(i => i.toObject())
- }
- if (data.type == 'creature') {
- const skills = await MournbladeCYD2Utility.loadCompendium("fvtt-mournblade-cyd2.skills-creatures")
- data.items = skills.map(i => i.toObject())
- data.items.push({ name: "Arme naturelle 1", type: 'arme', img: "systems/fvtt-mournblade-cyd2/assets/icons/melee.webp", system: { typearme: "contact", bonusmaniementoff: 0, seuildefense: 0, degats: "0" } })
- data.items.push({ name: "Arme naturelle 2", type: 'arme', img: "systems/fvtt-mournblade-cyd2/assets/icons/melee.webp", system: { typearme: "contact", bonusmaniementoff: 0, seuildefense: 0, degats: "0" } })
- }
-
- return super.create(data, options);
- }
-
- /* -------------------------------------------- */
- getBonusDefenseFromTalents() {
- let talents = this.items.filter(item => item.type == "talent" && item.system.isautomated)
- let bonus = 0
- for (let talent of talents) {
- for (let auto of talent.system.automations) {
- if (auto.eventtype == "bonus-permanent" && auto.bonusname == "bonus-defensif") {
- bonus += Number(auto.bonus || 0)
- }
- }
- }
- return bonus
- }
-
- /* -------------------------------------------- */
- prepareArme(arme) {
- if (this.type == "cellule") {
- return arme
- }
-
- arme = foundry.utils.duplicate(arme)
- let combat = this.getCombatValues()
- if (arme.system.typearme == "contact" || arme.system.typearme == "contactjet") {
- let bonusDefense = this.getBonusDefenseFromTalents()
- arme.system.competence = foundry.utils.duplicate(this.items.find(item => item.type == "competence" && item.name.toLowerCase() == "mêlée"))
- arme.system.attrKey = "pui"
- arme.system.totalDegats = arme.system.degats + "+" + combat.bonusDegatsTotal
- arme.system.totalOffensif = this.system.attributs.pui.value + arme.system.competence.system.niveau + arme.system.bonusmaniementoff + (this.system.combat.monte ? 3 : 0)
- arme.system.totalDefensif = combat.defenseTotal + arme.system.competence.system.niveau + arme.system.seuildefense + bonusDefense + (this.system.combat.monte ? 3 : 0)
- console.log("Arme", arme.system.totalDefensif, combat, arme.system.competence.system.niveau, arme.system.seuildefense, bonusDefense)
- arme.system.isdefense = true
- arme.system.isMelee = true
- arme.system.isDistance = false
- }
- if (arme.system.typearme == "jet" || arme.system.typearme == "tir") {
- arme.system.competence = foundry.utils.duplicate(this.items.find(item => item.type == "competence" && item.name.toLowerCase() == "armes à distance"))
- arme.system.attrKey = "adr"
- arme.system.totalOffensif = this.system.attributs.adr.value + arme.system.competence.system.niveau + arme.system.bonusmaniementoff
- arme.system.totalDegats = arme.system.degats
- arme.system.isMelee = false
- arme.system.isDistance = true
- if (arme.system.isdefense) {
- arme.system.totalDefensif = combat.defenseTotal + arme.system.competence.system.niveau + arme.system.seuildefense
- }
- }
- return arme
- }
-
- /* -------------------------------------------- */
- getItemSorted(types) {
- let items = this.items.filter(item => types.includes(item.type)) || []
- MournbladeCYD2Utility.sortArrayObjectsByName(items)
- return items
- }
- getWeapons() {
- let armes = []
- for (let arme of this.items) {
- if (arme.type == "arme") {
- armes.push(this.prepareArme(arme))
- }
- }
- MournbladeCYD2Utility.sortArrayObjectsByName(armes)
- return armes
- }
- getMonnaies() {
- return this.getItemSorted(["monnaie"])
- }
- getEquipments() {
- return this.getItemSorted(["equipement"])
- }
- getArtefacts() {
- return this.getItemSorted(["artefact"])
- }
- getArmors() {
- return this.getItemSorted(["protection"])
- }
- getHistoriques() {
- return this.getItemSorted(["historique"])
- }
- getProfils() {
- return this.getItemSorted(["profil"])
- }
- getTalents() {
- return this.getItemSorted(["talent"])
- }
- getRessources() {
- return this.getItemSorted(["ressource"])
- }
- getContacts() {
- return this.getItemSorted(["contact"])
- }
- getMutations() {
- return this.getItemSorted(["mutation"])
- }
- getDons() {
- return this.getItemSorted(["don"])
- }
- getPactes() {
- return this.getItemSorted(["pacte"])
- }
- getTendances() {
- return this.getItemSorted(["tendance"])
- }
- getRunes() {
- return this.getItemSorted(["rune"])
- }
- getTraitsChaotiques() {
- return this.getItemSorted(["traitchaotique"])
- }
- getTraitsEspeces() {
- return this.getItemSorted(["traitespece"])
- }
-
- /* -------------------------------------------- */
- getAspect() {
- return (this.system.balance.loi > this.system.balance.chaos) ? this.system.balance.loi : this.system.balance.chaos
- }
- getMarge() {
- return Math.abs(this.system.balance.loi - this.system.balance.chaos)
- }
- getAlignement() {
- return (this.system.balance.loi > this.system.balance.chaos) ? "loyal" : "chaotique"
- }
-
- /* -------------------------------------------- */
- getSkills() {
- let comp = []
- for (let item of this.items) {
- item = foundry.utils.duplicate(item)
- if (item.type == "competence") {
- item.system.attribut1total = item.system.niveau + (this.system.attributs[item.system.attribut1]?.value || 0)
- item.system.attribut2total = item.system.niveau + (this.system.attributs[item.system.attribut2]?.value || 0)
- item.system.attribut3total = item.system.niveau + (this.system.attributs[item.system.attribut3]?.value || 0)
- if (item.system.niveau == 0) {
- item.system.attribut1total -= 3
- item.system.attribut2total -= 3
- item.system.attribut3total -= 3
- }
- item.system.attribut1label = this.system.attributs[item.system.attribut1]?.label || ""
- item.system.attribut2label = this.system.attributs[item.system.attribut2]?.label || ""
- item.system.attribut3label = this.system.attributs[item.system.attribut3]?.label || ""
- comp.push(item)
- }
- }
- MournbladeCYD2Utility.sortArrayObjectsByName(comp)
- return comp
- }
-
- /* ----------------------- --------------------- */
- addMember(actorId) {
- let members = foundry.utils.duplicate(this.system.members)
- members.push({ id: actorId })
- this.update({ 'system.members': members })
- }
- async removeMember(actorId) {
- let members = this.system.members.filter(it => it.id != actorId)
- this.update({ 'system.members': members })
- }
-
- /* -------------------------------------------- */
- getDefenseBase() {
- return Math.max(this.system.attributs.tre.value, this.system.attributs.adr.value)
- }
-
- /* -------------------------------------------- */
- getVitesseBase() {
- return 5 + __vitesseBonus[this.system.attributs.adr.value]
- }
- /* -------------------------------------------- */
- getProtection() {
- let equipProtection = 0
- for (let armor of this.items) {
- if (armor.type == "protection" && armor.system.equipped) {
- equipProtection += Number(armor.system.protection)
- }
- }
- if (equipProtection < 4) {
- return 4 + equipProtection // Cas des boucliers + sans armure
- }
- return equipProtection // Uniquement la protection des armures + boucliers
- }
-
- /* -------------------------------------------- */
- getCombatValues() {
- if (this.type == "cellule") {
- return {
- initBase: 0,
- initTotal: 0,
- bonusDegats: 0,
- bonusDegatsTotal: 0,
- vitesseBase: 0,
- vitesseTotal: 0,
- defenseBase: 0,
- protection: 0,
- defenseTotal: 0
- }
- }
-
- let combat = {
- initBase: this.system.attributs.adr.value,
- initTotal: this.system.attributs.adr.value + this.system.combat.initbonus,
- bonusDegats: this.getBonusDegats(),
- bonusDegatsTotal: this.getBonusDegats() + this.system.combat.bonusdegats,
- vitesseBase: this.getVitesseBase(),
- vitesseTotal: this.getVitesseBase() + this.system.combat.vitessebonus,
- defenseBase: this.getDefenseBase(),
- protection: this.getProtection(),
- defenseTotal: this.getDefenseBase() + this.system.combat.defensebonus + this.getProtection() - this.getTotalAdversite() + (this.system.combat.defensetotale ? 3 : 0)
- }
- return combat
- }
-
- /* -------------------------------------------- */
- prepareBaseData() {
- }
-
- /* -------------------------------------------- */
- async prepareData() {
- super.prepareData();
- }
-
- /* -------------------------------------------- */
- prepareDerivedData() {
-
- if (this.type == 'personnage') {
- let talentBonus = this.getVigueurBonus()
- let vigueur = Math.floor((this.system.attributs.pui.value + this.system.attributs.tre.value) / 2) + talentBonus + this.system.sante.vigueurmodifier
- if (vigueur != this.system.sante.vigueur) {
- this.update({ 'system.sante.vigueur': vigueur })
- }
-
- let seuilPouvoirBonus = this.getSeuilPouvoirBonus()
- let seuilPouvoir = Math.floor((this.system.attributs.tre.value + this.system.attributs.cla.value) / 2) + seuilPouvoirBonus + this.system.ame.seuilpouvoirmodifier
- if (seuilPouvoir != this.system.ame.seuilpouvoir) {
- this.update({ 'system.ame.seuilpouvoir': seuilPouvoir })
- }
- }
- super.prepareDerivedData()
- }
-
- /* -------------------------------------------- */
- _preUpdate(changed, options, user) {
- if (changed?.system?.sante?.etat && changed?.system?.sante?.etat != this.system.sante.etat) {
- setTimeout(() => {
- this.processCombativite(changed.system.sante)
- }, 800)
- }
- if (changed?.system?.ame?.etat && changed?.system?.ame?.etat != this.system.ame.etat) {
- // L'état d'Âme ne peut pas être inférieur au minimum (max dans le système)
- let minAme = this.system.ame.max !== undefined ? this.system.ame.max : 0
- if (changed.system.ame.etat < minAme) {
- changed.system.ame.etat = minAme
- }
- // L'état d'Âme ne peut pas dépasser nbame (Brisé)
- if (changed.system.ame.etat > this.system.ame.nbame) {
- changed.system.ame.etat = this.system.ame.nbame
- }
- setTimeout(() => {
- this.processAme(changed.system.ame)
- }, 800)
- }
- // Si le max d'Âme change, ajuster l'état actuel si nécessaire
- if (changed?.system?.ame?.max !== undefined && changed.system.ame.max != this.system.ame.max) {
- if (this.system.ame.etat < changed.system.ame.max) {
- changed.system.ame.etat = changed.system.ame.max
- }
- }
- super._preUpdate(changed, options, user);
- }
-
- /* -------------------------------------------- */
- _onUpdate(data, options, user) {
- super._onUpdate(data, options, user);
- }
- /* -------------------------------------------- */
- getItemById(id) {
- let item = this.items.find(item => item.id == id);
- if (item) {
- item = foundry.utils.duplicate(item)
- }
- return item;
- }
-
- /* -------------------------------------------- */
- async equipItem(itemId) {
- let item = this.items.find(item => item.id == itemId)
- if (item && item.system) {
- let update = { _id: item.id, "system.equipped": !item.system.equipped }
- await this.updateEmbeddedDocuments('Item', [update]); // Updates one EmbeddedEntity
- }
- }
-
- /* -------------------------------------------- */
- editItemField(itemId, itemType, itemField, dataType, value) {
- let item = this.items.find(item => item.id == itemId)
- if (item) {
- console.log("Item ", item, itemField, dataType, value)
- if (dataType.toLowerCase() == "number") {
- value = Number(value)
- } else {
- value = String(value)
- }
- let update = { _id: item.id, [`system.${itemField}`]: value };
- this.updateEmbeddedDocuments("Item", [update])
- }
- }
-
- /* -------------------------------------------- */
- checkAttribut(attribut, minLevel) {
- let attr = this.system.attributs.find(at => at.labelnorm == attribut.toLowerCase())
- if (attr && attr.value >= minLevel) {
- return { isValid: true, attr: foundry.utils.duplicate(attr) }
- }
- return { isValid: false }
- }
- /* -------------------------------------------- */
- checkAttributOrCompetenceLevel(compName, minLevel) {
- let comp = this.items.find(i => i.type == "competence" && i.name.toLowerCase() == compName.toLowerCase() && i.system.niveau >= minLevel)
- if (comp) {
- return { isValid: true, item: foundry.utils.duplicate(comp) }
- } else {
- for (let attrKey in this.system.attributs) {
- if (this.system.attributs[attrKey].label.toLowerCase() == compName.toLowerCase() && this.system.attributs[attrKey].value >= minLevel) {
- return { isValid: true, item: foundry.utils.duplicate(this.system.attributs[attrKey]) }
- }
- }
- }
- return { isValid: false, warningMessage: `Prérequis insuffisant : la compétence/attribut ${compName} doit être de niveau ${minLevel} au minimum` }
- }
- /* -------------------------------------------- */
- addCompetenceBonus(compName, bonus, baCost) {
- let comp = this.items.find(i => i.type == "competence" && i.name.toLowerCase() == compName.toLowerCase())
- if (comp) {
- comp = foundry.utils.duplicate(comp)
- comp.system.bonus = bonus
- comp.system.baCost = baCost
- return { isValid: true, item: comp }
- }
- return { isValid: false, warningMessage: `Compétence ${compName} non trouvée` }
- }
- /* -------------------------------------------- */
- checkIfCompetence(compName) {
- let comp = this.items.find(i => i.type == "competence" && i.name.toLowerCase() == compName.toLowerCase())
- if (comp) {
- return { isValid: true, item: comp }
- }
- return { isValid: false }
- }
- /* -------------------------------------------- */
- getVigueur() {
- return this.system.sante.vigueur
- }
-
- /* -------------------------------------------- */
- getVigueurBonus() {
- let talents = this.items.filter(item => item.type == "talent" && item.system.isautomated)
- let bonus = 0
- for (let talent of talents) {
- for (let auto of talent.system.automations) {
- if (auto.eventtype == "bonus-permanent" && auto.bonusname == "vigueur") {
- bonus += Number(auto.bonus || 0)
- }
- }
- }
- return bonus
- }
-
- /* -------------------------------------------- */
- getSeuilPouvoir() {
- return this.system.ame.seuilpouvoir
- }
-
- /* -------------------------------------------- */
- getSeuilPouvoirBonus() {
- let talents = this.items.filter(item => item.type == "talent" && item.system.isautomated)
- let bonus = 0
- for (let talent of talents) {
- for (let auto of talent.system.automations) {
- if (auto.eventtype == "bonus-permanent" && auto.bonusname == "seuilpouvoir") {
- bonus += Number(auto.bonus || 0)
- }
- }
- }
- return bonus
- }
-
- /* -------------------------------------------- */
- getAmeMax() {
- return Math.min(this.system.ame.max || this.system.ame.nbame, this.system.ame.nbame)
- }
-
- /* -------------------------------------------- */
- getBonneAventure() {
- return this.system.bonneaventure.actuelle
- }
- /* -------------------------------------------- */
- checkBonneAventure(cost) {
- return (this.system.bonneaventure.actuelle >= cost)
- }
- /* -------------------------------------------- */
- changeBonneAventure(value) {
- let newBA = this.system.bonneaventure.actuelle
- newBA += value
- this.update({ 'system.bonneaventure.actuelle': newBA })
- }
-
- /* -------------------------------------------- */
- getEclat() {
- return this.system.eclat.value
- }
-
- /* -------------------------------------------- */
- changeEclat(value) {
- let newE = this.system.eclat.value
- newE += value
- this.update({ 'system.eclat.value': newE })
- }
-
- /* -------------------------------------------- */
- compareName(a, b) {
- if (a.name < b.name) {
- return -1;
- }
- if (a.name > b.name) {
- return 1;
- }
- return 0;
- }
-
- /* -------------------------------------------- */
- getAttribute(attrKey) {
- return this.system.attributes[attrKey]
- }
-
- /* -------------------------------------------- */
- getBonusDegats() {
- return 0;
- }
-
- /* -------------------------------------------- */
- changeEtatCombativite(value) {
- if (value === "vaincu") {
- value = 200
- }
- let sante = foundry.utils.duplicate(this.system.sante)
- sante.etat += Number(value)
- sante.etat = Math.max(sante.etat, 0)
- sante.etat = Math.min(sante.etat, this.system.sante.nbcombativite)
- this.update({ 'system.sante': sante })
- if (sante.etat == this.system.sante.nbcombativite) {
- ChatMessage.create({ content: `${this.name} est vaincu !` })
- }
- // Duplicated ! this.processCombativite(sante)
- }
-
- /* -------------------------------------------- */
- changeEtatAme(value) {
- if (value === "brise") {
- value = 200
- }
- let ame = foundry.utils.duplicate(this.system.ame)
- ame.etat += Number(value)
- ame.etat = Math.max(ame.etat, 0)
- // L'état ne peut pas dépasser le maximum actuel d'âme
- let maxAme = this.system.ame.max || this.system.ame.nbame
- ame.etat = Math.min(ame.etat, maxAme)
- this.update({ 'system.ame': ame })
- if (ame.etat >= maxAme) {
- ChatMessage.create({ content: `${this.name} est brisé !` })
- }
- }
-
- /* -------------------------------------------- */
- processCombativite(sante) {
- sante = sante || foundry.utils.duplicate(this.system.sante)
- // Gestion des états affaibli et très affaibli
- if (sante.etat == this.system.sante.nbcombativite - 2 || sante.etat == this.system.sante.nbcombativite - 1) {
- if (sante.etat == this.system.sante.nbcombativite - 2 && this.items.find(item => item.type == "talent" && item.name.toLowerCase() == "encaissement")) {
- ChatMessage.create({ content: `${this.name} ne subit pas les 2 adversités rouge grâce à Encaissement. Pensez à les ajouter à la fin de la scène !` })
- } else if (sante.etat == this.system.sante.nbcombativite - 1 && this.items.find(item => item.type == "talent" && item.name.toLowerCase().includes("vaillant"))) {
- ChatMessage.create({ content: `${this.name} ne subit pas les 2 adversités rouge grâce à Vaillant. Pensez à les ajouter à la fin de la scène !` })
- } else {
- ChatMessage.create({ content: `${this.name} subit 2 adversités rouge !` })
- this.incDecAdversite("rouge", 2)
- }
- }
- }
-
- /* -------------------------------------------- */
- processAme(ame) {
- ame = ame || foundry.utils.duplicate(this.system.ame)
- let maxAme = this.system.ame.max || this.system.ame.nbame
- // Gestion des états Traumatisé, Très Traumatisé et Brisé en fonction du maximum actuel
- // Les seuils sont calculés par rapport au maximum d'âme actuel
- if (maxAme >= 3 && ame.etat >= maxAme - 2) {
- if (ame.etat == maxAme - 2) {
- ChatMessage.create({ content: `${this.name} est Traumatisé !` })
- } else if (ame.etat == maxAme - 1) {
- ChatMessage.create({ content: `${this.name} est Très Traumatisé !` })
- } else if (ame.etat >= maxAme) {
- ChatMessage.create({ content: `${this.name} est Brisé !` })
- }
- } else if (ame.etat >= maxAme) {
- ChatMessage.create({ content: `${this.name} est Brisé !` })
- }
- }
-
- /* -------------------------------------------- */
- async equipGear(equipmentId) {
- let item = this.items.find(item => item.id == equipmentId);
- if (item?.system?.data) {
- let update = { _id: item.id, "system.equipped": !item.system.equipped };
- await this.updateEmbeddedDocuments('Item', [update]); // Updates one EmbeddedEntity
- }
- }
-
- /* -------------------------------------------- */
- getSubActors() {
- let subActors = [];
- for (let id of this.system.subactors) {
- subActors.push(foundry.utils.duplicate(game.actors.get(id)));
- }
- return subActors;
- }
- /* -------------------------------------------- */
- async addSubActor(subActorId) {
- let subActors = foundry.utils.duplicate(this.system.subactors);
- subActors.push(subActorId);
- await this.update({ 'system.subactors': subActors });
- }
- /* -------------------------------------------- */
- async delSubActor(subActorId) {
- let newArray = [];
- for (let id of this.system.subactors) {
- if (id != subActorId) {
- newArray.push(id);
- }
- }
- await this.update({ 'system.subactors': newArray });
- }
-
- /* -------------------------------------------- */
- getTotalAdversite() {
- return this.system.adversite.bleue + this.system.adversite.rouge + this.system.adversite.noire
- }
-
- /* -------------------------------------------- */
- async incDecAdversite(adv, incDec = 0) {
- let adversite = foundry.utils.duplicate(this.system.adversite)
- adversite[adv] += Number(incDec)
- adversite[adv] = Math.max(adversite[adv], 0)
- adversite[adv] = Math.min(adversite[adv], 20)
- this.update({ 'system.adversite': adversite })
- }
- /* -------------------------------------------- */
- async incDecQuantity(objetId, incDec = 0) {
- let objetQ = this.items.get(objetId)
- if (objetQ) {
- let newQ = objetQ.system.quantite + incDec
- newQ = Math.max(newQ, 0)
- await this.updateEmbeddedDocuments('Item', [{ _id: objetQ.id, 'system.quantite': newQ }]); // pdates one EmbeddedEntity
- }
- }
-
- /* -------------------------------------------- */
- computeRichesse() {
- let valueSC = 0
- for (let monnaie of this.items) {
- if (monnaie.type == "monnaie") {
- valueSC += Number(monnaie.system.prixsc) * Number(monnaie.system.quantite)
- }
- }
- return MournbladeCYD2Utility.computeMonnaieDetails(valueSC)
- }
-
- /* -------------------------------------------- */
- computeValeurEquipement() {
- let valueSC = 0
- for (let equip of this.items) {
- if (equip.type == "equipement" || equip.type == "arme" || equip.type == "protection") {
- valueSC += Number(equip.system.prixsc) * Number(equip.system.quantite ?? 1)
- valueSC += (Number(equip.system.prixca) * Number(equip.system.quantite ?? 1)) * 20
- valueSC += (Number(equip.system.prixpo) * Number(equip.system.quantite ?? 1)) * 400
- }
- }
- return MournbladeCYD2Utility.computeMonnaieDetails(valueSC)
- }
-
- /* -------------------------------------------- */
- getCompetence(compId) {
- return this.items.get(compId)
- }
-
- /* -------------------------------------------- */
- async setPredilectionUsed(compId, predIdx) {
- let comp = this.items.get(compId)
- let pred = foundry.utils.duplicate(comp.system.predilections)
- pred[predIdx].used = true
- await this.updateEmbeddedDocuments('Item', [{ _id: compId, 'system.predilections': pred }])
- }
-
- /* -------------------------------------------- */
- getInitiativeScore() {
- let init = this.getFlag("world", "last-initiative")
- return init || -1
- }
-
- /* -------------------------------------------- */
- getBestAttackValue() {
- let attackList = this.items.filter(item => (item.type == "arme" || item.type == "talent") && item.system.equipped)
- let maxOff = 0
- let bestArme
- for (let arme of attackList) {
- if (arme.type == "arme") {
- arme = this.prepareArme(arme)
- }
- if (arme.system.totalOffensif > maxOff) {
- maxOff = arme.system.totalOffensif
- bestArme = foundry.utils.duplicate(arme)
- }
- }
- return bestArme
- }
-
- /* -------------------------------------------- */
- getBestDefenseValue() {
- let defenseList = this.items.filter(item => (item.type == "arme") && item.system.equipped)
- let maxDef = 0
- let bestArme
- for (let arme of defenseList) {
- if (arme.type == "arme") {
- arme = this.prepareArme(arme)
- }
- if (arme.system.totalDefensif > maxDef) {
- maxDef = arme.system.totalDefensif
- bestArme = foundry.utils.duplicate(arme)
- }
- }
- return bestArme
- }
-
- /* -------------------------------------------- */
- searchRelevantTalents(competence) {
- let talents = []
-
- for (let talent of this.items) {
- if (talent.type == "talent" && talent.system.isautomated && talent.system.automations.length > 0) {
- for (let auto of talent.system.automations) {
- if (auto.eventtype === "prepare-roll") {
- if (auto.competence.toLowerCase() == competence.name.toLowerCase()) {
- talent = foundry.utils.duplicate(talent)
- talent.system.bonus = auto.bonus
- talent.system.baCost = auto.baCost
- talents.push(talent)
- }
- }
- }
- }
- }
- return talents
- }
-
- /* -------------------------------------------- */
- buildListeAdversites() {
- return []
- }
-
- /* -------------------------------------------- */
- getCommonRollData(attrKey = undefined, compId = undefined, compName = undefined) {
- let rollData = MournbladeCYD2Utility.getBasicRollData()
- rollData.alias = this.name
- rollData.actorImg = this.img
- rollData.actorId = this.id
- rollData.tokenId = this.token?.id
- rollData.img = this.img
- rollData.attributs = MournbladeCYD2Utility.getAttributs()
- rollData.maitriseId = "none"
- rollData.nbEclat = this.system.eclat.value
- rollData.nbBA = this.system.bonneaventure.actuelle
- rollData.nbAdversites = this.getTotalAdversite()
- rollData.talents = []
- rollData.attrKey2 = "none"
- rollData.coupDevastateur = this.items.find(it => it.type == "talent" && it.name.toLowerCase() == "coup dévastateur" && !it.system.used)
- rollData.hasAmbidextre = this.items.find(it => it.type == "talent" && it.name.toLowerCase() == "ambidextre")
- rollData.hasFeinte = this.system.bonneaventure.actuelle > 0 && this.items.find(it => it.type == "talent" && it.name.toLowerCase() == "feinte")
- rollData.isMonte = this.system.combat.monte
- rollData.config = game.system.mournbladecyd2.config
-
- if (attrKey) {
- rollData.attrKey = attrKey
- if (attrKey != "tochoose") {
- rollData.actionImg = "systems/fvtt-mournblade-cyd2/assets/icons/" + this.system.attributs[attrKey].labelnorm + ".webp"
- rollData.attr = foundry.utils.duplicate(this.system.attributs[attrKey])
- }
- }
- if (compId) {
- rollData.competence = foundry.utils.duplicate(this.items.get(compId) || {})
- let maitrises = [{ key: "none", label: "Aucune" }]
- rollData.competence.system.predilections.forEach(function (item) {
- if (item.maitrise) {
- maitrises.push({ key: item.id, label: item.name });
- }
- })
- rollData.maitrises = maitrises // rollData.competence.system.predilections.filter(p => p.maitrise)
- rollData.actionImg = rollData.competence?.img
- rollData.talents = this.searchRelevantTalents(rollData.competence)
- }
- if (compName) {
- rollData.competence = foundry.utils.duplicate(this.items.find(item => item.name.toLowerCase() == compName.toLowerCase()) || {})
- rollData.actionImg = rollData.competence?.img
- }
- return rollData
- }
-
- /* -------------------------------------------- */
- async rollAttribut(attrKey, isInit = false) {
- let rollData = this.getCommonRollData(attrKey)
- rollData.multiplier = (isInit) ? 1 : 2
- rollData.isInit = isInit
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
-
- /* -------------------------------------------- */
- async rollCompetence(attrKey, compId) {
- let rollData = this.getCommonRollData(attrKey, compId)
- rollData.multiplier = 1 // Attr multiplier, always 1 in competence mode
- console.log("RollDatra", rollData)
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
-
- /* -------------------------------------------- */
- async rollArmeOffensif(armeId) {
- let arme = this.items.get(armeId)
- if (arme.type == "arme") {
- arme = this.prepareArme(arme)
- }
- let rollData = this.getCommonRollData(arme.system.attrKey, arme.system.competence._id)
- rollData.arme = arme
- MournbladeCYD2Utility.updateWithTarget(rollData)
- console.log("ARME!", rollData)
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
- /* -------------------------------------------- */
- async rollAssommer() {
- let rollData = this.getCommonRollData("pui", undefined, "Filouterie")
- rollData.assomer = true
- rollData.conditionsCommunes = true
- MournbladeCYD2Utility.updateWithTarget(rollData)
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
- /* -------------------------------------------- */
- async rollCoupBas() {
- let rollData = this.getCommonRollData("pui", undefined, "Mêlée")
- rollData.coupBas = true
- rollData.conditionsCommunes = true
- MournbladeCYD2Utility.updateWithTarget(rollData)
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
- /* -------------------------------------------- */
- async rollImmobiliser() {
- let rollData = this.getCommonRollData("pui", undefined, "Mêlée")
- rollData.immobiliser = true
- rollData.conditionsCommunes = true
- rollData.cibleconsciente = true
- MournbladeCYD2Utility.updateWithTarget(rollData)
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
- /* -------------------------------------------- */
- async rollRepousser() {
- let rollData = this.getCommonRollData("pui", undefined, "Mêlée")
- rollData.repousser = true
- rollData.conditionsCommunes = true
- rollData.cibleconsciente = true
- MournbladeCYD2Utility.updateWithTarget(rollData)
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
- /* -------------------------------------------- */
- async rollDesengager() {
- let rollData = this.getCommonRollData("adr", undefined, "Mouvements")
- rollData.desengager = true
- rollData.conditionsCommunes = true
- MournbladeCYD2Utility.updateWithTarget(rollData)
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
-
- /* -------------------------------------------- */
- async rollArmeDegats(armeId, targetVigueur = undefined, rollDataInput = undefined) {
- let arme = this.items.get(armeId)
- if (arme.type == "arme") {
- arme = this.prepareArme(arme)
- }
- console.log("DEGATS", arme, targetVigueur, rollDataInput)
- let roll
- let bonus = 0
- let bonus2 = 0
-
- if (rollDataInput?.applyCoupDevastateur) {
- bonus2 = Math.floor(this.system.attributs.pui.value / 2)
- let talent = this.items.find(item => item.type == "talent" && item.name.toLowerCase() == "coup dévastateur")
- this.updateEmbeddedDocuments('Item', [{ _id: talent.id, 'system.used': true }])
- }
-
- if (rollDataInput?.isHeroique) {
- if (rollDataInput?.attaqueCharge) {
- bonus = 5
- }
- if (rollDataInput?.chargeCavalerie) {
- bonus = 6
- }
- roll = await new Roll("2d10rr10+" + arme.system.totalDegats + "+" + bonus + "+" + bonus2).roll()
- } else {
- if (rollDataInput?.attaqueCharge) {
- bonus = 3
- }
- if (rollDataInput?.chargeCavalerie) {
- bonus = 4
- }
- roll = await new Roll("1d10+" + arme.system.totalDegats + "+" + bonus + "+" + bonus2).roll()
- }
- await MournbladeCYD2Utility.showDiceSoNice(roll, game.settings.get("core", "rollMode"));
- let nbEtatPerdus = 0
- if (targetVigueur) {
- nbEtatPerdus = Math.floor(roll.total / targetVigueur)
- }
- //console.log(roll)
- let rollData = {
- arme: arme,
- finalResult: roll.total,
- formula: roll.formula,
- alias: this.name,
- actorImg: this.img,
- actorId: this.id,
- defenderTokenId: rollDataInput?.defenderTokenId,
- actionImg: arme.img,
- targetVigueur: targetVigueur,
- nbEtatPerdus: nbEtatPerdus
- }
- MournbladeCYD2Utility.createChatWithRollMode(rollData.alias, {
- content: await renderTemplate(`systems/fvtt-mournblade-cyd2/templates/chat-degats-result.html`, rollData)
- })
-
- if (rollDataInput?.defenderTokenId && nbEtatPerdus) {
- MournbladeCYD2Utility.applyCombativite(rollDataInput, nbEtatPerdus)
- }
-
- }
-}
diff --git a/.history/modules/mournblade-cyd2-actor_20251026084254.js b/.history/modules/mournblade-cyd2-actor_20251026084254.js
deleted file mode 100644
index e8feba3..0000000
--- a/.history/modules/mournblade-cyd2-actor_20251026084254.js
+++ /dev/null
@@ -1,909 +0,0 @@
-/* -------------------------------------------- */
-import { MournbladeCYD2Utility } from "./mournblade-cyd2-utility.js";
-import { MournbladeCYD2RollDialog } from "./mournblade-cyd2-roll-dialog.js";
-
-/* -------------------------------------------- */
-const __degatsBonus = [-2, -2, -1, -1, 0, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 8, 8, 9, 9, 10, 10]
-const __vitesseBonus = [-2, -2, -1, -1, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8]
-
-/* -------------------------------------------- */
-/**
- * Extend the base Actor entity by defining a custom roll data structure which is ideal for the Simple system.
- * @extends {Actor}
- */
-export class MournbladeCYD2Actor extends Actor {
-
- /* -------------------------------------------- */
- /**
- * Override the create() function to provide additional SoS functionality.
- *
- * This overrided create() function adds initial items
- * Namely: Basic skills, money,
- *
- * @param {Object} data Barebones actor data which this function adds onto.
- * @param {Object} options (Unused) Additional options which customize the creation workflow.
- *
- */
-
- static async create(data, options) {
-
- // Case of compendium global import
- if (data instanceof Array) {
- return super.create(data, options);
- }
- // If the created actor has items (only applicable to duplicated actors) bypass the new actor creation logic
- if (data.items) {
- let actor = super.create(data, options);
- return actor;
- }
-
- if (data.type == 'personnage') {
- const skills = await MournbladeCYD2Utility.loadCompendium("fvtt-mournblade-cyd2.skills")
- data.items = skills.map(i => i.toObject())
- }
- if (data.type == 'creature') {
- const skills = await MournbladeCYD2Utility.loadCompendium("fvtt-mournblade-cyd2.skills-creatures")
- data.items = skills.map(i => i.toObject())
- data.items.push({ name: "Arme naturelle 1", type: 'arme', img: "systems/fvtt-mournblade-cyd2/assets/icons/melee.webp", system: { typearme: "contact", bonusmaniementoff: 0, seuildefense: 0, degats: "0" } })
- data.items.push({ name: "Arme naturelle 2", type: 'arme', img: "systems/fvtt-mournblade-cyd2/assets/icons/melee.webp", system: { typearme: "contact", bonusmaniementoff: 0, seuildefense: 0, degats: "0" } })
- }
-
- return super.create(data, options);
- }
-
- /* -------------------------------------------- */
- getBonusDefenseFromTalents() {
- let talents = this.items.filter(item => item.type == "talent" && item.system.isautomated)
- let bonus = 0
- for (let talent of talents) {
- for (let auto of talent.system.automations) {
- if (auto.eventtype == "bonus-permanent" && auto.bonusname == "bonus-defensif") {
- bonus += Number(auto.bonus || 0)
- }
- }
- }
- return bonus
- }
-
- /* -------------------------------------------- */
- prepareArme(arme) {
- if (this.type == "cellule") {
- return arme
- }
-
- arme = foundry.utils.duplicate(arme)
- let combat = this.getCombatValues()
- if (arme.system.typearme == "contact" || arme.system.typearme == "contactjet") {
- let bonusDefense = this.getBonusDefenseFromTalents()
- arme.system.competence = foundry.utils.duplicate(this.items.find(item => item.type == "competence" && item.name.toLowerCase() == "mêlée"))
- arme.system.attrKey = "pui"
- arme.system.totalDegats = arme.system.degats + "+" + combat.bonusDegatsTotal
- arme.system.totalOffensif = this.system.attributs.pui.value + arme.system.competence.system.niveau + arme.system.bonusmaniementoff + (this.system.combat.monte ? 3 : 0)
- arme.system.totalDefensif = combat.defenseTotal + arme.system.competence.system.niveau + arme.system.seuildefense + bonusDefense + (this.system.combat.monte ? 3 : 0)
- console.log("Arme", arme.system.totalDefensif, combat, arme.system.competence.system.niveau, arme.system.seuildefense, bonusDefense)
- arme.system.isdefense = true
- arme.system.isMelee = true
- arme.system.isDistance = false
- }
- if (arme.system.typearme == "jet" || arme.system.typearme == "tir") {
- arme.system.competence = foundry.utils.duplicate(this.items.find(item => item.type == "competence" && item.name.toLowerCase() == "armes à distance"))
- arme.system.attrKey = "adr"
- arme.system.totalOffensif = this.system.attributs.adr.value + arme.system.competence.system.niveau + arme.system.bonusmaniementoff
- arme.system.totalDegats = arme.system.degats
- arme.system.isMelee = false
- arme.system.isDistance = true
- if (arme.system.isdefense) {
- arme.system.totalDefensif = combat.defenseTotal + arme.system.competence.system.niveau + arme.system.seuildefense
- }
- }
- return arme
- }
-
- /* -------------------------------------------- */
- getItemSorted(types) {
- let items = this.items.filter(item => types.includes(item.type)) || []
- MournbladeCYD2Utility.sortArrayObjectsByName(items)
- return items
- }
- getWeapons() {
- let armes = []
- for (let arme of this.items) {
- if (arme.type == "arme") {
- armes.push(this.prepareArme(arme))
- }
- }
- MournbladeCYD2Utility.sortArrayObjectsByName(armes)
- return armes
- }
- getMonnaies() {
- return this.getItemSorted(["monnaie"])
- }
- getEquipments() {
- return this.getItemSorted(["equipement"])
- }
- getArtefacts() {
- return this.getItemSorted(["artefact"])
- }
- getArmors() {
- return this.getItemSorted(["protection"])
- }
- getHistoriques() {
- return this.getItemSorted(["historique"])
- }
- getProfils() {
- return this.getItemSorted(["profil"])
- }
- getTalents() {
- return this.getItemSorted(["talent"])
- }
- getRessources() {
- return this.getItemSorted(["ressource"])
- }
- getContacts() {
- return this.getItemSorted(["contact"])
- }
- getMutations() {
- return this.getItemSorted(["mutation"])
- }
- getDons() {
- return this.getItemSorted(["don"])
- }
- getPactes() {
- return this.getItemSorted(["pacte"])
- }
- getTendances() {
- return this.getItemSorted(["tendance"])
- }
- getRunes() {
- return this.getItemSorted(["rune"])
- }
- getTraitsChaotiques() {
- return this.getItemSorted(["traitchaotique"])
- }
- getTraitsEspeces() {
- return this.getItemSorted(["traitespece"])
- }
-
- /* -------------------------------------------- */
- getAspect() {
- return (this.system.balance.loi > this.system.balance.chaos) ? this.system.balance.loi : this.system.balance.chaos
- }
- getMarge() {
- return Math.abs(this.system.balance.loi - this.system.balance.chaos)
- }
- getAlignement() {
- return (this.system.balance.loi > this.system.balance.chaos) ? "loyal" : "chaotique"
- }
-
- /* -------------------------------------------- */
- getSkills() {
- let comp = []
- for (let item of this.items) {
- item = foundry.utils.duplicate(item)
- if (item.type == "competence") {
- item.system.attribut1total = item.system.niveau + (this.system.attributs[item.system.attribut1]?.value || 0)
- item.system.attribut2total = item.system.niveau + (this.system.attributs[item.system.attribut2]?.value || 0)
- item.system.attribut3total = item.system.niveau + (this.system.attributs[item.system.attribut3]?.value || 0)
- if (item.system.niveau == 0) {
- item.system.attribut1total -= 3
- item.system.attribut2total -= 3
- item.system.attribut3total -= 3
- }
- item.system.attribut1label = this.system.attributs[item.system.attribut1]?.label || ""
- item.system.attribut2label = this.system.attributs[item.system.attribut2]?.label || ""
- item.system.attribut3label = this.system.attributs[item.system.attribut3]?.label || ""
- comp.push(item)
- }
- }
- MournbladeCYD2Utility.sortArrayObjectsByName(comp)
- return comp
- }
-
- /* ----------------------- --------------------- */
- addMember(actorId) {
- let members = foundry.utils.duplicate(this.system.members)
- members.push({ id: actorId })
- this.update({ 'system.members': members })
- }
- async removeMember(actorId) {
- let members = this.system.members.filter(it => it.id != actorId)
- this.update({ 'system.members': members })
- }
-
- /* -------------------------------------------- */
- getDefenseBase() {
- return Math.max(this.system.attributs.tre.value, this.system.attributs.adr.value)
- }
-
- /* -------------------------------------------- */
- getVitesseBase() {
- return 5 + __vitesseBonus[this.system.attributs.adr.value]
- }
- /* -------------------------------------------- */
- getProtection() {
- let equipProtection = 0
- for (let armor of this.items) {
- if (armor.type == "protection" && armor.system.equipped) {
- equipProtection += Number(armor.system.protection)
- }
- }
- if (equipProtection < 4) {
- return 4 + equipProtection // Cas des boucliers + sans armure
- }
- return equipProtection // Uniquement la protection des armures + boucliers
- }
-
- /* -------------------------------------------- */
- getCombatValues() {
- if (this.type == "cellule") {
- return {
- initBase: 0,
- initTotal: 0,
- bonusDegats: 0,
- bonusDegatsTotal: 0,
- vitesseBase: 0,
- vitesseTotal: 0,
- defenseBase: 0,
- protection: 0,
- defenseTotal: 0
- }
- }
-
- let combat = {
- initBase: this.system.attributs.adr.value,
- initTotal: this.system.attributs.adr.value + this.system.combat.initbonus,
- bonusDegats: this.getBonusDegats(),
- bonusDegatsTotal: this.getBonusDegats() + this.system.combat.bonusdegats,
- vitesseBase: this.getVitesseBase(),
- vitesseTotal: this.getVitesseBase() + this.system.combat.vitessebonus,
- defenseBase: this.getDefenseBase(),
- protection: this.getProtection(),
- defenseTotal: this.getDefenseBase() + this.system.combat.defensebonus + this.getProtection() - this.getTotalAdversite() + (this.system.combat.defensetotale ? 3 : 0)
- }
- return combat
- }
-
- /* -------------------------------------------- */
- prepareBaseData() {
- }
-
- /* -------------------------------------------- */
- async prepareData() {
- super.prepareData();
- }
-
- /* -------------------------------------------- */
- prepareDerivedData() {
-
- if (this.type == 'personnage') {
- let talentBonus = this.getVigueurBonus()
- let vigueur = Math.floor((this.system.attributs.pui.value + this.system.attributs.tre.value) / 2) + talentBonus + this.system.sante.vigueurmodifier
- if (vigueur != this.system.sante.vigueur) {
- this.update({ 'system.sante.vigueur': vigueur })
- }
-
- let seuilPouvoirBonus = this.getSeuilPouvoirBonus()
- let seuilPouvoir = Math.floor((this.system.attributs.tre.value + this.system.attributs.cla.value) / 2) + seuilPouvoirBonus + this.system.ame.seuilpouvoirmodifier
- if (seuilPouvoir != this.system.ame.seuilpouvoir) {
- this.update({ 'system.ame.seuilpouvoir': seuilPouvoir })
- }
- }
- super.prepareDerivedData()
- }
-
- /* -------------------------------------------- */
- _preUpdate(changed, options, user) {
- if (changed?.system?.sante?.etat && changed?.system?.sante?.etat != this.system.sante.etat) {
- setTimeout(() => {
- this.processCombativite(changed.system.sante)
- }, 800)
- }
- if (changed?.system?.ame?.etat && changed?.system?.ame?.etat != this.system.ame.etat) {
- // L'état d'Âme ne peut pas être inférieur au minimum (max dans le système)
- let minAme = this.system.ame.max !== undefined ? this.system.ame.max : 0
- if (changed.system.ame.etat < minAme) {
- changed.system.ame.etat = minAme
- }
- // L'état d'Âme ne peut pas dépasser nbame (Brisé)
- if (changed.system.ame.etat > this.system.ame.nbame) {
- changed.system.ame.etat = this.system.ame.nbame
- }
- setTimeout(() => {
- this.processAme(changed.system.ame)
- }, 800)
- }
- // Si le max d'Âme change, ajuster l'état actuel si nécessaire
- if (changed?.system?.ame?.max !== undefined && changed.system.ame.max != this.system.ame.max) {
- if (this.system.ame.etat < changed.system.ame.max) {
- changed.system.ame.etat = changed.system.ame.max
- }
- }
- super._preUpdate(changed, options, user);
- }
-
- /* -------------------------------------------- */
- _onUpdate(data, options, user) {
- super._onUpdate(data, options, user);
- }
- /* -------------------------------------------- */
- getItemById(id) {
- let item = this.items.find(item => item.id == id);
- if (item) {
- item = foundry.utils.duplicate(item)
- }
- return item;
- }
-
- /* -------------------------------------------- */
- async equipItem(itemId) {
- let item = this.items.find(item => item.id == itemId)
- if (item && item.system) {
- let update = { _id: item.id, "system.equipped": !item.system.equipped }
- await this.updateEmbeddedDocuments('Item', [update]); // Updates one EmbeddedEntity
- }
- }
-
- /* -------------------------------------------- */
- editItemField(itemId, itemType, itemField, dataType, value) {
- let item = this.items.find(item => item.id == itemId)
- if (item) {
- console.log("Item ", item, itemField, dataType, value)
- if (dataType.toLowerCase() == "number") {
- value = Number(value)
- } else {
- value = String(value)
- }
- let update = { _id: item.id, [`system.${itemField}`]: value };
- this.updateEmbeddedDocuments("Item", [update])
- }
- }
-
- /* -------------------------------------------- */
- checkAttribut(attribut, minLevel) {
- let attr = this.system.attributs.find(at => at.labelnorm == attribut.toLowerCase())
- if (attr && attr.value >= minLevel) {
- return { isValid: true, attr: foundry.utils.duplicate(attr) }
- }
- return { isValid: false }
- }
- /* -------------------------------------------- */
- checkAttributOrCompetenceLevel(compName, minLevel) {
- let comp = this.items.find(i => i.type == "competence" && i.name.toLowerCase() == compName.toLowerCase() && i.system.niveau >= minLevel)
- if (comp) {
- return { isValid: true, item: foundry.utils.duplicate(comp) }
- } else {
- for (let attrKey in this.system.attributs) {
- if (this.system.attributs[attrKey].label.toLowerCase() == compName.toLowerCase() && this.system.attributs[attrKey].value >= minLevel) {
- return { isValid: true, item: foundry.utils.duplicate(this.system.attributs[attrKey]) }
- }
- }
- }
- return { isValid: false, warningMessage: `Prérequis insuffisant : la compétence/attribut ${compName} doit être de niveau ${minLevel} au minimum` }
- }
- /* -------------------------------------------- */
- addCompetenceBonus(compName, bonus, baCost) {
- let comp = this.items.find(i => i.type == "competence" && i.name.toLowerCase() == compName.toLowerCase())
- if (comp) {
- comp = foundry.utils.duplicate(comp)
- comp.system.bonus = bonus
- comp.system.baCost = baCost
- return { isValid: true, item: comp }
- }
- return { isValid: false, warningMessage: `Compétence ${compName} non trouvée` }
- }
- /* -------------------------------------------- */
- checkIfCompetence(compName) {
- let comp = this.items.find(i => i.type == "competence" && i.name.toLowerCase() == compName.toLowerCase())
- if (comp) {
- return { isValid: true, item: comp }
- }
- return { isValid: false }
- }
- /* -------------------------------------------- */
- getVigueur() {
- return this.system.sante.vigueur
- }
-
- /* -------------------------------------------- */
- getVigueurBonus() {
- let talents = this.items.filter(item => item.type == "talent" && item.system.isautomated)
- let bonus = 0
- for (let talent of talents) {
- for (let auto of talent.system.automations) {
- if (auto.eventtype == "bonus-permanent" && auto.bonusname == "vigueur") {
- bonus += Number(auto.bonus || 0)
- }
- }
- }
- return bonus
- }
-
- /* -------------------------------------------- */
- getSeuilPouvoir() {
- return this.system.ame.seuilpouvoir
- }
-
- /* -------------------------------------------- */
- getSeuilPouvoirBonus() {
- let talents = this.items.filter(item => item.type == "talent" && item.system.isautomated)
- let bonus = 0
- for (let talent of talents) {
- for (let auto of talent.system.automations) {
- if (auto.eventtype == "bonus-permanent" && auto.bonusname == "seuilpouvoir") {
- bonus += Number(auto.bonus || 0)
- }
- }
- }
- return bonus
- }
-
- /* -------------------------------------------- */
- getAmeMax() {
- return Math.min(this.system.ame.max || this.system.ame.nbame, this.system.ame.nbame)
- }
-
- /* -------------------------------------------- */
- getBonneAventure() {
- return this.system.bonneaventure.actuelle
- }
- /* -------------------------------------------- */
- checkBonneAventure(cost) {
- return (this.system.bonneaventure.actuelle >= cost)
- }
- /* -------------------------------------------- */
- changeBonneAventure(value) {
- let newBA = this.system.bonneaventure.actuelle
- newBA += value
- this.update({ 'system.bonneaventure.actuelle': newBA })
- }
-
- /* -------------------------------------------- */
- getEclat() {
- return this.system.eclat.value
- }
-
- /* -------------------------------------------- */
- changeEclat(value) {
- let newE = this.system.eclat.value
- newE += value
- this.update({ 'system.eclat.value': newE })
- }
-
- /* -------------------------------------------- */
- compareName(a, b) {
- if (a.name < b.name) {
- return -1;
- }
- if (a.name > b.name) {
- return 1;
- }
- return 0;
- }
-
- /* -------------------------------------------- */
- getAttribute(attrKey) {
- return this.system.attributes[attrKey]
- }
-
- /* -------------------------------------------- */
- getBonusDegats() {
- return 0;
- }
-
- /* -------------------------------------------- */
- changeEtatCombativite(value) {
- if (value === "vaincu") {
- value = 200
- }
- let sante = foundry.utils.duplicate(this.system.sante)
- sante.etat += Number(value)
- sante.etat = Math.max(sante.etat, 0)
- sante.etat = Math.min(sante.etat, this.system.sante.nbcombativite)
- this.update({ 'system.sante': sante })
- if (sante.etat == this.system.sante.nbcombativite) {
- ChatMessage.create({ content: `${this.name} est vaincu !` })
- }
- // Duplicated ! this.processCombativite(sante)
- }
-
- /* -------------------------------------------- */
- changeEtatAme(value) {
- if (value === "brise") {
- value = 200
- }
- let ame = foundry.utils.duplicate(this.system.ame)
- ame.etat += Number(value)
- // L'état ne peut pas être inférieur au minimum (max dans le système)
- let minAme = this.system.ame.max !== undefined ? this.system.ame.max : 0
- ame.etat = Math.max(ame.etat, minAme)
- // L'état ne peut pas dépasser nbame (Brisé)
- ame.etat = Math.min(ame.etat, this.system.ame.nbame)
- this.update({ 'system.ame': ame })
- if (ame.etat >= this.system.ame.nbame) {
- ChatMessage.create({ content: `${this.name} est brisé !` })
- }
- }
-
- /* -------------------------------------------- */
- processCombativite(sante) {
- sante = sante || foundry.utils.duplicate(this.system.sante)
- // Gestion des états affaibli et très affaibli
- if (sante.etat == this.system.sante.nbcombativite - 2 || sante.etat == this.system.sante.nbcombativite - 1) {
- if (sante.etat == this.system.sante.nbcombativite - 2 && this.items.find(item => item.type == "talent" && item.name.toLowerCase() == "encaissement")) {
- ChatMessage.create({ content: `${this.name} ne subit pas les 2 adversités rouge grâce à Encaissement. Pensez à les ajouter à la fin de la scène !` })
- } else if (sante.etat == this.system.sante.nbcombativite - 1 && this.items.find(item => item.type == "talent" && item.name.toLowerCase().includes("vaillant"))) {
- ChatMessage.create({ content: `${this.name} ne subit pas les 2 adversités rouge grâce à Vaillant. Pensez à les ajouter à la fin de la scène !` })
- } else {
- ChatMessage.create({ content: `${this.name} subit 2 adversités rouge !` })
- this.incDecAdversite("rouge", 2)
- }
- }
- }
-
- /* -------------------------------------------- */
- processAme(ame) {
- ame = ame || foundry.utils.duplicate(this.system.ame)
- let maxAme = this.system.ame.max || this.system.ame.nbame
- // Gestion des états Traumatisé, Très Traumatisé et Brisé en fonction du maximum actuel
- // Les seuils sont calculés par rapport au maximum d'âme actuel
- if (maxAme >= 3 && ame.etat >= maxAme - 2) {
- if (ame.etat == maxAme - 2) {
- ChatMessage.create({ content: `${this.name} est Traumatisé !` })
- } else if (ame.etat == maxAme - 1) {
- ChatMessage.create({ content: `${this.name} est Très Traumatisé !` })
- } else if (ame.etat >= maxAme) {
- ChatMessage.create({ content: `${this.name} est Brisé !` })
- }
- } else if (ame.etat >= maxAme) {
- ChatMessage.create({ content: `${this.name} est Brisé !` })
- }
- }
-
- /* -------------------------------------------- */
- async equipGear(equipmentId) {
- let item = this.items.find(item => item.id == equipmentId);
- if (item?.system?.data) {
- let update = { _id: item.id, "system.equipped": !item.system.equipped };
- await this.updateEmbeddedDocuments('Item', [update]); // Updates one EmbeddedEntity
- }
- }
-
- /* -------------------------------------------- */
- getSubActors() {
- let subActors = [];
- for (let id of this.system.subactors) {
- subActors.push(foundry.utils.duplicate(game.actors.get(id)));
- }
- return subActors;
- }
- /* -------------------------------------------- */
- async addSubActor(subActorId) {
- let subActors = foundry.utils.duplicate(this.system.subactors);
- subActors.push(subActorId);
- await this.update({ 'system.subactors': subActors });
- }
- /* -------------------------------------------- */
- async delSubActor(subActorId) {
- let newArray = [];
- for (let id of this.system.subactors) {
- if (id != subActorId) {
- newArray.push(id);
- }
- }
- await this.update({ 'system.subactors': newArray });
- }
-
- /* -------------------------------------------- */
- getTotalAdversite() {
- return this.system.adversite.bleue + this.system.adversite.rouge + this.system.adversite.noire
- }
-
- /* -------------------------------------------- */
- async incDecAdversite(adv, incDec = 0) {
- let adversite = foundry.utils.duplicate(this.system.adversite)
- adversite[adv] += Number(incDec)
- adversite[adv] = Math.max(adversite[adv], 0)
- adversite[adv] = Math.min(adversite[adv], 20)
- this.update({ 'system.adversite': adversite })
- }
- /* -------------------------------------------- */
- async incDecQuantity(objetId, incDec = 0) {
- let objetQ = this.items.get(objetId)
- if (objetQ) {
- let newQ = objetQ.system.quantite + incDec
- newQ = Math.max(newQ, 0)
- await this.updateEmbeddedDocuments('Item', [{ _id: objetQ.id, 'system.quantite': newQ }]); // pdates one EmbeddedEntity
- }
- }
-
- /* -------------------------------------------- */
- computeRichesse() {
- let valueSC = 0
- for (let monnaie of this.items) {
- if (monnaie.type == "monnaie") {
- valueSC += Number(monnaie.system.prixsc) * Number(monnaie.system.quantite)
- }
- }
- return MournbladeCYD2Utility.computeMonnaieDetails(valueSC)
- }
-
- /* -------------------------------------------- */
- computeValeurEquipement() {
- let valueSC = 0
- for (let equip of this.items) {
- if (equip.type == "equipement" || equip.type == "arme" || equip.type == "protection") {
- valueSC += Number(equip.system.prixsc) * Number(equip.system.quantite ?? 1)
- valueSC += (Number(equip.system.prixca) * Number(equip.system.quantite ?? 1)) * 20
- valueSC += (Number(equip.system.prixpo) * Number(equip.system.quantite ?? 1)) * 400
- }
- }
- return MournbladeCYD2Utility.computeMonnaieDetails(valueSC)
- }
-
- /* -------------------------------------------- */
- getCompetence(compId) {
- return this.items.get(compId)
- }
-
- /* -------------------------------------------- */
- async setPredilectionUsed(compId, predIdx) {
- let comp = this.items.get(compId)
- let pred = foundry.utils.duplicate(comp.system.predilections)
- pred[predIdx].used = true
- await this.updateEmbeddedDocuments('Item', [{ _id: compId, 'system.predilections': pred }])
- }
-
- /* -------------------------------------------- */
- getInitiativeScore() {
- let init = this.getFlag("world", "last-initiative")
- return init || -1
- }
-
- /* -------------------------------------------- */
- getBestAttackValue() {
- let attackList = this.items.filter(item => (item.type == "arme" || item.type == "talent") && item.system.equipped)
- let maxOff = 0
- let bestArme
- for (let arme of attackList) {
- if (arme.type == "arme") {
- arme = this.prepareArme(arme)
- }
- if (arme.system.totalOffensif > maxOff) {
- maxOff = arme.system.totalOffensif
- bestArme = foundry.utils.duplicate(arme)
- }
- }
- return bestArme
- }
-
- /* -------------------------------------------- */
- getBestDefenseValue() {
- let defenseList = this.items.filter(item => (item.type == "arme") && item.system.equipped)
- let maxDef = 0
- let bestArme
- for (let arme of defenseList) {
- if (arme.type == "arme") {
- arme = this.prepareArme(arme)
- }
- if (arme.system.totalDefensif > maxDef) {
- maxDef = arme.system.totalDefensif
- bestArme = foundry.utils.duplicate(arme)
- }
- }
- return bestArme
- }
-
- /* -------------------------------------------- */
- searchRelevantTalents(competence) {
- let talents = []
-
- for (let talent of this.items) {
- if (talent.type == "talent" && talent.system.isautomated && talent.system.automations.length > 0) {
- for (let auto of talent.system.automations) {
- if (auto.eventtype === "prepare-roll") {
- if (auto.competence.toLowerCase() == competence.name.toLowerCase()) {
- talent = foundry.utils.duplicate(talent)
- talent.system.bonus = auto.bonus
- talent.system.baCost = auto.baCost
- talents.push(talent)
- }
- }
- }
- }
- }
- return talents
- }
-
- /* -------------------------------------------- */
- buildListeAdversites() {
- return []
- }
-
- /* -------------------------------------------- */
- getCommonRollData(attrKey = undefined, compId = undefined, compName = undefined) {
- let rollData = MournbladeCYD2Utility.getBasicRollData()
- rollData.alias = this.name
- rollData.actorImg = this.img
- rollData.actorId = this.id
- rollData.tokenId = this.token?.id
- rollData.img = this.img
- rollData.attributs = MournbladeCYD2Utility.getAttributs()
- rollData.maitriseId = "none"
- rollData.nbEclat = this.system.eclat.value
- rollData.nbBA = this.system.bonneaventure.actuelle
- rollData.nbAdversites = this.getTotalAdversite()
- rollData.talents = []
- rollData.attrKey2 = "none"
- rollData.coupDevastateur = this.items.find(it => it.type == "talent" && it.name.toLowerCase() == "coup dévastateur" && !it.system.used)
- rollData.hasAmbidextre = this.items.find(it => it.type == "talent" && it.name.toLowerCase() == "ambidextre")
- rollData.hasFeinte = this.system.bonneaventure.actuelle > 0 && this.items.find(it => it.type == "talent" && it.name.toLowerCase() == "feinte")
- rollData.isMonte = this.system.combat.monte
- rollData.config = game.system.mournbladecyd2.config
-
- if (attrKey) {
- rollData.attrKey = attrKey
- if (attrKey != "tochoose") {
- rollData.actionImg = "systems/fvtt-mournblade-cyd2/assets/icons/" + this.system.attributs[attrKey].labelnorm + ".webp"
- rollData.attr = foundry.utils.duplicate(this.system.attributs[attrKey])
- }
- }
- if (compId) {
- rollData.competence = foundry.utils.duplicate(this.items.get(compId) || {})
- let maitrises = [{ key: "none", label: "Aucune" }]
- rollData.competence.system.predilections.forEach(function (item) {
- if (item.maitrise) {
- maitrises.push({ key: item.id, label: item.name });
- }
- })
- rollData.maitrises = maitrises // rollData.competence.system.predilections.filter(p => p.maitrise)
- rollData.actionImg = rollData.competence?.img
- rollData.talents = this.searchRelevantTalents(rollData.competence)
- }
- if (compName) {
- rollData.competence = foundry.utils.duplicate(this.items.find(item => item.name.toLowerCase() == compName.toLowerCase()) || {})
- rollData.actionImg = rollData.competence?.img
- }
- return rollData
- }
-
- /* -------------------------------------------- */
- async rollAttribut(attrKey, isInit = false) {
- let rollData = this.getCommonRollData(attrKey)
- rollData.multiplier = (isInit) ? 1 : 2
- rollData.isInit = isInit
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
-
- /* -------------------------------------------- */
- async rollCompetence(attrKey, compId) {
- let rollData = this.getCommonRollData(attrKey, compId)
- rollData.multiplier = 1 // Attr multiplier, always 1 in competence mode
- console.log("RollDatra", rollData)
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
-
- /* -------------------------------------------- */
- async rollArmeOffensif(armeId) {
- let arme = this.items.get(armeId)
- if (arme.type == "arme") {
- arme = this.prepareArme(arme)
- }
- let rollData = this.getCommonRollData(arme.system.attrKey, arme.system.competence._id)
- rollData.arme = arme
- MournbladeCYD2Utility.updateWithTarget(rollData)
- console.log("ARME!", rollData)
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
- /* -------------------------------------------- */
- async rollAssommer() {
- let rollData = this.getCommonRollData("pui", undefined, "Filouterie")
- rollData.assomer = true
- rollData.conditionsCommunes = true
- MournbladeCYD2Utility.updateWithTarget(rollData)
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
- /* -------------------------------------------- */
- async rollCoupBas() {
- let rollData = this.getCommonRollData("pui", undefined, "Mêlée")
- rollData.coupBas = true
- rollData.conditionsCommunes = true
- MournbladeCYD2Utility.updateWithTarget(rollData)
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
- /* -------------------------------------------- */
- async rollImmobiliser() {
- let rollData = this.getCommonRollData("pui", undefined, "Mêlée")
- rollData.immobiliser = true
- rollData.conditionsCommunes = true
- rollData.cibleconsciente = true
- MournbladeCYD2Utility.updateWithTarget(rollData)
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
- /* -------------------------------------------- */
- async rollRepousser() {
- let rollData = this.getCommonRollData("pui", undefined, "Mêlée")
- rollData.repousser = true
- rollData.conditionsCommunes = true
- rollData.cibleconsciente = true
- MournbladeCYD2Utility.updateWithTarget(rollData)
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
- /* -------------------------------------------- */
- async rollDesengager() {
- let rollData = this.getCommonRollData("adr", undefined, "Mouvements")
- rollData.desengager = true
- rollData.conditionsCommunes = true
- MournbladeCYD2Utility.updateWithTarget(rollData)
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
-
- /* -------------------------------------------- */
- async rollArmeDegats(armeId, targetVigueur = undefined, rollDataInput = undefined) {
- let arme = this.items.get(armeId)
- if (arme.type == "arme") {
- arme = this.prepareArme(arme)
- }
- console.log("DEGATS", arme, targetVigueur, rollDataInput)
- let roll
- let bonus = 0
- let bonus2 = 0
-
- if (rollDataInput?.applyCoupDevastateur) {
- bonus2 = Math.floor(this.system.attributs.pui.value / 2)
- let talent = this.items.find(item => item.type == "talent" && item.name.toLowerCase() == "coup dévastateur")
- this.updateEmbeddedDocuments('Item', [{ _id: talent.id, 'system.used': true }])
- }
-
- if (rollDataInput?.isHeroique) {
- if (rollDataInput?.attaqueCharge) {
- bonus = 5
- }
- if (rollDataInput?.chargeCavalerie) {
- bonus = 6
- }
- roll = await new Roll("2d10rr10+" + arme.system.totalDegats + "+" + bonus + "+" + bonus2).roll()
- } else {
- if (rollDataInput?.attaqueCharge) {
- bonus = 3
- }
- if (rollDataInput?.chargeCavalerie) {
- bonus = 4
- }
- roll = await new Roll("1d10+" + arme.system.totalDegats + "+" + bonus + "+" + bonus2).roll()
- }
- await MournbladeCYD2Utility.showDiceSoNice(roll, game.settings.get("core", "rollMode"));
- let nbEtatPerdus = 0
- if (targetVigueur) {
- nbEtatPerdus = Math.floor(roll.total / targetVigueur)
- }
- //console.log(roll)
- let rollData = {
- arme: arme,
- finalResult: roll.total,
- formula: roll.formula,
- alias: this.name,
- actorImg: this.img,
- actorId: this.id,
- defenderTokenId: rollDataInput?.defenderTokenId,
- actionImg: arme.img,
- targetVigueur: targetVigueur,
- nbEtatPerdus: nbEtatPerdus
- }
- MournbladeCYD2Utility.createChatWithRollMode(rollData.alias, {
- content: await renderTemplate(`systems/fvtt-mournblade-cyd2/templates/chat-degats-result.html`, rollData)
- })
-
- if (rollDataInput?.defenderTokenId && nbEtatPerdus) {
- MournbladeCYD2Utility.applyCombativite(rollDataInput, nbEtatPerdus)
- }
-
- }
-}
diff --git a/.history/modules/mournblade-cyd2-actor_20251026084306.js b/.history/modules/mournblade-cyd2-actor_20251026084306.js
deleted file mode 100644
index 16df549..0000000
--- a/.history/modules/mournblade-cyd2-actor_20251026084306.js
+++ /dev/null
@@ -1,907 +0,0 @@
-/* -------------------------------------------- */
-import { MournbladeCYD2Utility } from "./mournblade-cyd2-utility.js";
-import { MournbladeCYD2RollDialog } from "./mournblade-cyd2-roll-dialog.js";
-
-/* -------------------------------------------- */
-const __degatsBonus = [-2, -2, -1, -1, 0, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 8, 8, 9, 9, 10, 10]
-const __vitesseBonus = [-2, -2, -1, -1, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8]
-
-/* -------------------------------------------- */
-/**
- * Extend the base Actor entity by defining a custom roll data structure which is ideal for the Simple system.
- * @extends {Actor}
- */
-export class MournbladeCYD2Actor extends Actor {
-
- /* -------------------------------------------- */
- /**
- * Override the create() function to provide additional SoS functionality.
- *
- * This overrided create() function adds initial items
- * Namely: Basic skills, money,
- *
- * @param {Object} data Barebones actor data which this function adds onto.
- * @param {Object} options (Unused) Additional options which customize the creation workflow.
- *
- */
-
- static async create(data, options) {
-
- // Case of compendium global import
- if (data instanceof Array) {
- return super.create(data, options);
- }
- // If the created actor has items (only applicable to duplicated actors) bypass the new actor creation logic
- if (data.items) {
- let actor = super.create(data, options);
- return actor;
- }
-
- if (data.type == 'personnage') {
- const skills = await MournbladeCYD2Utility.loadCompendium("fvtt-mournblade-cyd2.skills")
- data.items = skills.map(i => i.toObject())
- }
- if (data.type == 'creature') {
- const skills = await MournbladeCYD2Utility.loadCompendium("fvtt-mournblade-cyd2.skills-creatures")
- data.items = skills.map(i => i.toObject())
- data.items.push({ name: "Arme naturelle 1", type: 'arme', img: "systems/fvtt-mournblade-cyd2/assets/icons/melee.webp", system: { typearme: "contact", bonusmaniementoff: 0, seuildefense: 0, degats: "0" } })
- data.items.push({ name: "Arme naturelle 2", type: 'arme', img: "systems/fvtt-mournblade-cyd2/assets/icons/melee.webp", system: { typearme: "contact", bonusmaniementoff: 0, seuildefense: 0, degats: "0" } })
- }
-
- return super.create(data, options);
- }
-
- /* -------------------------------------------- */
- getBonusDefenseFromTalents() {
- let talents = this.items.filter(item => item.type == "talent" && item.system.isautomated)
- let bonus = 0
- for (let talent of talents) {
- for (let auto of talent.system.automations) {
- if (auto.eventtype == "bonus-permanent" && auto.bonusname == "bonus-defensif") {
- bonus += Number(auto.bonus || 0)
- }
- }
- }
- return bonus
- }
-
- /* -------------------------------------------- */
- prepareArme(arme) {
- if (this.type == "cellule") {
- return arme
- }
-
- arme = foundry.utils.duplicate(arme)
- let combat = this.getCombatValues()
- if (arme.system.typearme == "contact" || arme.system.typearme == "contactjet") {
- let bonusDefense = this.getBonusDefenseFromTalents()
- arme.system.competence = foundry.utils.duplicate(this.items.find(item => item.type == "competence" && item.name.toLowerCase() == "mêlée"))
- arme.system.attrKey = "pui"
- arme.system.totalDegats = arme.system.degats + "+" + combat.bonusDegatsTotal
- arme.system.totalOffensif = this.system.attributs.pui.value + arme.system.competence.system.niveau + arme.system.bonusmaniementoff + (this.system.combat.monte ? 3 : 0)
- arme.system.totalDefensif = combat.defenseTotal + arme.system.competence.system.niveau + arme.system.seuildefense + bonusDefense + (this.system.combat.monte ? 3 : 0)
- console.log("Arme", arme.system.totalDefensif, combat, arme.system.competence.system.niveau, arme.system.seuildefense, bonusDefense)
- arme.system.isdefense = true
- arme.system.isMelee = true
- arme.system.isDistance = false
- }
- if (arme.system.typearme == "jet" || arme.system.typearme == "tir") {
- arme.system.competence = foundry.utils.duplicate(this.items.find(item => item.type == "competence" && item.name.toLowerCase() == "armes à distance"))
- arme.system.attrKey = "adr"
- arme.system.totalOffensif = this.system.attributs.adr.value + arme.system.competence.system.niveau + arme.system.bonusmaniementoff
- arme.system.totalDegats = arme.system.degats
- arme.system.isMelee = false
- arme.system.isDistance = true
- if (arme.system.isdefense) {
- arme.system.totalDefensif = combat.defenseTotal + arme.system.competence.system.niveau + arme.system.seuildefense
- }
- }
- return arme
- }
-
- /* -------------------------------------------- */
- getItemSorted(types) {
- let items = this.items.filter(item => types.includes(item.type)) || []
- MournbladeCYD2Utility.sortArrayObjectsByName(items)
- return items
- }
- getWeapons() {
- let armes = []
- for (let arme of this.items) {
- if (arme.type == "arme") {
- armes.push(this.prepareArme(arme))
- }
- }
- MournbladeCYD2Utility.sortArrayObjectsByName(armes)
- return armes
- }
- getMonnaies() {
- return this.getItemSorted(["monnaie"])
- }
- getEquipments() {
- return this.getItemSorted(["equipement"])
- }
- getArtefacts() {
- return this.getItemSorted(["artefact"])
- }
- getArmors() {
- return this.getItemSorted(["protection"])
- }
- getHistoriques() {
- return this.getItemSorted(["historique"])
- }
- getProfils() {
- return this.getItemSorted(["profil"])
- }
- getTalents() {
- return this.getItemSorted(["talent"])
- }
- getRessources() {
- return this.getItemSorted(["ressource"])
- }
- getContacts() {
- return this.getItemSorted(["contact"])
- }
- getMutations() {
- return this.getItemSorted(["mutation"])
- }
- getDons() {
- return this.getItemSorted(["don"])
- }
- getPactes() {
- return this.getItemSorted(["pacte"])
- }
- getTendances() {
- return this.getItemSorted(["tendance"])
- }
- getRunes() {
- return this.getItemSorted(["rune"])
- }
- getTraitsChaotiques() {
- return this.getItemSorted(["traitchaotique"])
- }
- getTraitsEspeces() {
- return this.getItemSorted(["traitespece"])
- }
-
- /* -------------------------------------------- */
- getAspect() {
- return (this.system.balance.loi > this.system.balance.chaos) ? this.system.balance.loi : this.system.balance.chaos
- }
- getMarge() {
- return Math.abs(this.system.balance.loi - this.system.balance.chaos)
- }
- getAlignement() {
- return (this.system.balance.loi > this.system.balance.chaos) ? "loyal" : "chaotique"
- }
-
- /* -------------------------------------------- */
- getSkills() {
- let comp = []
- for (let item of this.items) {
- item = foundry.utils.duplicate(item)
- if (item.type == "competence") {
- item.system.attribut1total = item.system.niveau + (this.system.attributs[item.system.attribut1]?.value || 0)
- item.system.attribut2total = item.system.niveau + (this.system.attributs[item.system.attribut2]?.value || 0)
- item.system.attribut3total = item.system.niveau + (this.system.attributs[item.system.attribut3]?.value || 0)
- if (item.system.niveau == 0) {
- item.system.attribut1total -= 3
- item.system.attribut2total -= 3
- item.system.attribut3total -= 3
- }
- item.system.attribut1label = this.system.attributs[item.system.attribut1]?.label || ""
- item.system.attribut2label = this.system.attributs[item.system.attribut2]?.label || ""
- item.system.attribut3label = this.system.attributs[item.system.attribut3]?.label || ""
- comp.push(item)
- }
- }
- MournbladeCYD2Utility.sortArrayObjectsByName(comp)
- return comp
- }
-
- /* ----------------------- --------------------- */
- addMember(actorId) {
- let members = foundry.utils.duplicate(this.system.members)
- members.push({ id: actorId })
- this.update({ 'system.members': members })
- }
- async removeMember(actorId) {
- let members = this.system.members.filter(it => it.id != actorId)
- this.update({ 'system.members': members })
- }
-
- /* -------------------------------------------- */
- getDefenseBase() {
- return Math.max(this.system.attributs.tre.value, this.system.attributs.adr.value)
- }
-
- /* -------------------------------------------- */
- getVitesseBase() {
- return 5 + __vitesseBonus[this.system.attributs.adr.value]
- }
- /* -------------------------------------------- */
- getProtection() {
- let equipProtection = 0
- for (let armor of this.items) {
- if (armor.type == "protection" && armor.system.equipped) {
- equipProtection += Number(armor.system.protection)
- }
- }
- if (equipProtection < 4) {
- return 4 + equipProtection // Cas des boucliers + sans armure
- }
- return equipProtection // Uniquement la protection des armures + boucliers
- }
-
- /* -------------------------------------------- */
- getCombatValues() {
- if (this.type == "cellule") {
- return {
- initBase: 0,
- initTotal: 0,
- bonusDegats: 0,
- bonusDegatsTotal: 0,
- vitesseBase: 0,
- vitesseTotal: 0,
- defenseBase: 0,
- protection: 0,
- defenseTotal: 0
- }
- }
-
- let combat = {
- initBase: this.system.attributs.adr.value,
- initTotal: this.system.attributs.adr.value + this.system.combat.initbonus,
- bonusDegats: this.getBonusDegats(),
- bonusDegatsTotal: this.getBonusDegats() + this.system.combat.bonusdegats,
- vitesseBase: this.getVitesseBase(),
- vitesseTotal: this.getVitesseBase() + this.system.combat.vitessebonus,
- defenseBase: this.getDefenseBase(),
- protection: this.getProtection(),
- defenseTotal: this.getDefenseBase() + this.system.combat.defensebonus + this.getProtection() - this.getTotalAdversite() + (this.system.combat.defensetotale ? 3 : 0)
- }
- return combat
- }
-
- /* -------------------------------------------- */
- prepareBaseData() {
- }
-
- /* -------------------------------------------- */
- async prepareData() {
- super.prepareData();
- }
-
- /* -------------------------------------------- */
- prepareDerivedData() {
-
- if (this.type == 'personnage') {
- let talentBonus = this.getVigueurBonus()
- let vigueur = Math.floor((this.system.attributs.pui.value + this.system.attributs.tre.value) / 2) + talentBonus + this.system.sante.vigueurmodifier
- if (vigueur != this.system.sante.vigueur) {
- this.update({ 'system.sante.vigueur': vigueur })
- }
-
- let seuilPouvoirBonus = this.getSeuilPouvoirBonus()
- let seuilPouvoir = Math.floor((this.system.attributs.tre.value + this.system.attributs.cla.value) / 2) + seuilPouvoirBonus + this.system.ame.seuilpouvoirmodifier
- if (seuilPouvoir != this.system.ame.seuilpouvoir) {
- this.update({ 'system.ame.seuilpouvoir': seuilPouvoir })
- }
- }
- super.prepareDerivedData()
- }
-
- /* -------------------------------------------- */
- _preUpdate(changed, options, user) {
- if (changed?.system?.sante?.etat && changed?.system?.sante?.etat != this.system.sante.etat) {
- setTimeout(() => {
- this.processCombativite(changed.system.sante)
- }, 800)
- }
- if (changed?.system?.ame?.etat && changed?.system?.ame?.etat != this.system.ame.etat) {
- // L'état d'Âme ne peut pas être inférieur au minimum (max dans le système)
- let minAme = this.system.ame.max !== undefined ? this.system.ame.max : 0
- if (changed.system.ame.etat < minAme) {
- changed.system.ame.etat = minAme
- }
- // L'état d'Âme ne peut pas dépasser nbame (Brisé)
- if (changed.system.ame.etat > this.system.ame.nbame) {
- changed.system.ame.etat = this.system.ame.nbame
- }
- setTimeout(() => {
- this.processAme(changed.system.ame)
- }, 800)
- }
- // Si le max d'Âme change, ajuster l'état actuel si nécessaire
- if (changed?.system?.ame?.max !== undefined && changed.system.ame.max != this.system.ame.max) {
- if (this.system.ame.etat < changed.system.ame.max) {
- changed.system.ame.etat = changed.system.ame.max
- }
- }
- super._preUpdate(changed, options, user);
- }
-
- /* -------------------------------------------- */
- _onUpdate(data, options, user) {
- super._onUpdate(data, options, user);
- }
- /* -------------------------------------------- */
- getItemById(id) {
- let item = this.items.find(item => item.id == id);
- if (item) {
- item = foundry.utils.duplicate(item)
- }
- return item;
- }
-
- /* -------------------------------------------- */
- async equipItem(itemId) {
- let item = this.items.find(item => item.id == itemId)
- if (item && item.system) {
- let update = { _id: item.id, "system.equipped": !item.system.equipped }
- await this.updateEmbeddedDocuments('Item', [update]); // Updates one EmbeddedEntity
- }
- }
-
- /* -------------------------------------------- */
- editItemField(itemId, itemType, itemField, dataType, value) {
- let item = this.items.find(item => item.id == itemId)
- if (item) {
- console.log("Item ", item, itemField, dataType, value)
- if (dataType.toLowerCase() == "number") {
- value = Number(value)
- } else {
- value = String(value)
- }
- let update = { _id: item.id, [`system.${itemField}`]: value };
- this.updateEmbeddedDocuments("Item", [update])
- }
- }
-
- /* -------------------------------------------- */
- checkAttribut(attribut, minLevel) {
- let attr = this.system.attributs.find(at => at.labelnorm == attribut.toLowerCase())
- if (attr && attr.value >= minLevel) {
- return { isValid: true, attr: foundry.utils.duplicate(attr) }
- }
- return { isValid: false }
- }
- /* -------------------------------------------- */
- checkAttributOrCompetenceLevel(compName, minLevel) {
- let comp = this.items.find(i => i.type == "competence" && i.name.toLowerCase() == compName.toLowerCase() && i.system.niveau >= minLevel)
- if (comp) {
- return { isValid: true, item: foundry.utils.duplicate(comp) }
- } else {
- for (let attrKey in this.system.attributs) {
- if (this.system.attributs[attrKey].label.toLowerCase() == compName.toLowerCase() && this.system.attributs[attrKey].value >= minLevel) {
- return { isValid: true, item: foundry.utils.duplicate(this.system.attributs[attrKey]) }
- }
- }
- }
- return { isValid: false, warningMessage: `Prérequis insuffisant : la compétence/attribut ${compName} doit être de niveau ${minLevel} au minimum` }
- }
- /* -------------------------------------------- */
- addCompetenceBonus(compName, bonus, baCost) {
- let comp = this.items.find(i => i.type == "competence" && i.name.toLowerCase() == compName.toLowerCase())
- if (comp) {
- comp = foundry.utils.duplicate(comp)
- comp.system.bonus = bonus
- comp.system.baCost = baCost
- return { isValid: true, item: comp }
- }
- return { isValid: false, warningMessage: `Compétence ${compName} non trouvée` }
- }
- /* -------------------------------------------- */
- checkIfCompetence(compName) {
- let comp = this.items.find(i => i.type == "competence" && i.name.toLowerCase() == compName.toLowerCase())
- if (comp) {
- return { isValid: true, item: comp }
- }
- return { isValid: false }
- }
- /* -------------------------------------------- */
- getVigueur() {
- return this.system.sante.vigueur
- }
-
- /* -------------------------------------------- */
- getVigueurBonus() {
- let talents = this.items.filter(item => item.type == "talent" && item.system.isautomated)
- let bonus = 0
- for (let talent of talents) {
- for (let auto of talent.system.automations) {
- if (auto.eventtype == "bonus-permanent" && auto.bonusname == "vigueur") {
- bonus += Number(auto.bonus || 0)
- }
- }
- }
- return bonus
- }
-
- /* -------------------------------------------- */
- getSeuilPouvoir() {
- return this.system.ame.seuilpouvoir
- }
-
- /* -------------------------------------------- */
- getSeuilPouvoirBonus() {
- let talents = this.items.filter(item => item.type == "talent" && item.system.isautomated)
- let bonus = 0
- for (let talent of talents) {
- for (let auto of talent.system.automations) {
- if (auto.eventtype == "bonus-permanent" && auto.bonusname == "seuilpouvoir") {
- bonus += Number(auto.bonus || 0)
- }
- }
- }
- return bonus
- }
-
- /* -------------------------------------------- */
- getAmeMax() {
- return Math.min(this.system.ame.max || this.system.ame.nbame, this.system.ame.nbame)
- }
-
- /* -------------------------------------------- */
- getBonneAventure() {
- return this.system.bonneaventure.actuelle
- }
- /* -------------------------------------------- */
- checkBonneAventure(cost) {
- return (this.system.bonneaventure.actuelle >= cost)
- }
- /* -------------------------------------------- */
- changeBonneAventure(value) {
- let newBA = this.system.bonneaventure.actuelle
- newBA += value
- this.update({ 'system.bonneaventure.actuelle': newBA })
- }
-
- /* -------------------------------------------- */
- getEclat() {
- return this.system.eclat.value
- }
-
- /* -------------------------------------------- */
- changeEclat(value) {
- let newE = this.system.eclat.value
- newE += value
- this.update({ 'system.eclat.value': newE })
- }
-
- /* -------------------------------------------- */
- compareName(a, b) {
- if (a.name < b.name) {
- return -1;
- }
- if (a.name > b.name) {
- return 1;
- }
- return 0;
- }
-
- /* -------------------------------------------- */
- getAttribute(attrKey) {
- return this.system.attributes[attrKey]
- }
-
- /* -------------------------------------------- */
- getBonusDegats() {
- return 0;
- }
-
- /* -------------------------------------------- */
- changeEtatCombativite(value) {
- if (value === "vaincu") {
- value = 200
- }
- let sante = foundry.utils.duplicate(this.system.sante)
- sante.etat += Number(value)
- sante.etat = Math.max(sante.etat, 0)
- sante.etat = Math.min(sante.etat, this.system.sante.nbcombativite)
- this.update({ 'system.sante': sante })
- if (sante.etat == this.system.sante.nbcombativite) {
- ChatMessage.create({ content: `${this.name} est vaincu !` })
- }
- // Duplicated ! this.processCombativite(sante)
- }
-
- /* -------------------------------------------- */
- changeEtatAme(value) {
- if (value === "brise") {
- value = 200
- }
- let ame = foundry.utils.duplicate(this.system.ame)
- ame.etat += Number(value)
- // L'état ne peut pas être inférieur au minimum (max dans le système)
- let minAme = this.system.ame.max !== undefined ? this.system.ame.max : 0
- ame.etat = Math.max(ame.etat, minAme)
- // L'état ne peut pas dépasser nbame (Brisé)
- ame.etat = Math.min(ame.etat, this.system.ame.nbame)
- this.update({ 'system.ame': ame })
- if (ame.etat >= this.system.ame.nbame) {
- ChatMessage.create({ content: `${this.name} est brisé !` })
- }
- }
-
- /* -------------------------------------------- */
- processCombativite(sante) {
- sante = sante || foundry.utils.duplicate(this.system.sante)
- // Gestion des états affaibli et très affaibli
- if (sante.etat == this.system.sante.nbcombativite - 2 || sante.etat == this.system.sante.nbcombativite - 1) {
- if (sante.etat == this.system.sante.nbcombativite - 2 && this.items.find(item => item.type == "talent" && item.name.toLowerCase() == "encaissement")) {
- ChatMessage.create({ content: `${this.name} ne subit pas les 2 adversités rouge grâce à Encaissement. Pensez à les ajouter à la fin de la scène !` })
- } else if (sante.etat == this.system.sante.nbcombativite - 1 && this.items.find(item => item.type == "talent" && item.name.toLowerCase().includes("vaillant"))) {
- ChatMessage.create({ content: `${this.name} ne subit pas les 2 adversités rouge grâce à Vaillant. Pensez à les ajouter à la fin de la scène !` })
- } else {
- ChatMessage.create({ content: `${this.name} subit 2 adversités rouge !` })
- this.incDecAdversite("rouge", 2)
- }
- }
- }
-
- /* -------------------------------------------- */
- processAme(ame) {
- ame = ame || foundry.utils.duplicate(this.system.ame)
- let traumatiseValue = this.system.ame.nbame - 2
- let tresTraumatiseValue = this.system.ame.nbame - 1
- let briseValue = this.system.ame.nbame
-
- // Gestion des états Traumatisé, Très Traumatisé et Brisé
- if (ame.etat == traumatiseValue) {
- ChatMessage.create({ content: `${this.name} est Traumatisé !` })
- } else if (ame.etat == tresTraumatiseValue) {
- ChatMessage.create({ content: `${this.name} est Très Traumatisé !` })
- } else if (ame.etat >= briseValue) {
- ChatMessage.create({ content: `${this.name} est Brisé !` })
- }
- }
-
- /* -------------------------------------------- */
- async equipGear(equipmentId) {
- let item = this.items.find(item => item.id == equipmentId);
- if (item?.system?.data) {
- let update = { _id: item.id, "system.equipped": !item.system.equipped };
- await this.updateEmbeddedDocuments('Item', [update]); // Updates one EmbeddedEntity
- }
- }
-
- /* -------------------------------------------- */
- getSubActors() {
- let subActors = [];
- for (let id of this.system.subactors) {
- subActors.push(foundry.utils.duplicate(game.actors.get(id)));
- }
- return subActors;
- }
- /* -------------------------------------------- */
- async addSubActor(subActorId) {
- let subActors = foundry.utils.duplicate(this.system.subactors);
- subActors.push(subActorId);
- await this.update({ 'system.subactors': subActors });
- }
- /* -------------------------------------------- */
- async delSubActor(subActorId) {
- let newArray = [];
- for (let id of this.system.subactors) {
- if (id != subActorId) {
- newArray.push(id);
- }
- }
- await this.update({ 'system.subactors': newArray });
- }
-
- /* -------------------------------------------- */
- getTotalAdversite() {
- return this.system.adversite.bleue + this.system.adversite.rouge + this.system.adversite.noire
- }
-
- /* -------------------------------------------- */
- async incDecAdversite(adv, incDec = 0) {
- let adversite = foundry.utils.duplicate(this.system.adversite)
- adversite[adv] += Number(incDec)
- adversite[adv] = Math.max(adversite[adv], 0)
- adversite[adv] = Math.min(adversite[adv], 20)
- this.update({ 'system.adversite': adversite })
- }
- /* -------------------------------------------- */
- async incDecQuantity(objetId, incDec = 0) {
- let objetQ = this.items.get(objetId)
- if (objetQ) {
- let newQ = objetQ.system.quantite + incDec
- newQ = Math.max(newQ, 0)
- await this.updateEmbeddedDocuments('Item', [{ _id: objetQ.id, 'system.quantite': newQ }]); // pdates one EmbeddedEntity
- }
- }
-
- /* -------------------------------------------- */
- computeRichesse() {
- let valueSC = 0
- for (let monnaie of this.items) {
- if (monnaie.type == "monnaie") {
- valueSC += Number(monnaie.system.prixsc) * Number(monnaie.system.quantite)
- }
- }
- return MournbladeCYD2Utility.computeMonnaieDetails(valueSC)
- }
-
- /* -------------------------------------------- */
- computeValeurEquipement() {
- let valueSC = 0
- for (let equip of this.items) {
- if (equip.type == "equipement" || equip.type == "arme" || equip.type == "protection") {
- valueSC += Number(equip.system.prixsc) * Number(equip.system.quantite ?? 1)
- valueSC += (Number(equip.system.prixca) * Number(equip.system.quantite ?? 1)) * 20
- valueSC += (Number(equip.system.prixpo) * Number(equip.system.quantite ?? 1)) * 400
- }
- }
- return MournbladeCYD2Utility.computeMonnaieDetails(valueSC)
- }
-
- /* -------------------------------------------- */
- getCompetence(compId) {
- return this.items.get(compId)
- }
-
- /* -------------------------------------------- */
- async setPredilectionUsed(compId, predIdx) {
- let comp = this.items.get(compId)
- let pred = foundry.utils.duplicate(comp.system.predilections)
- pred[predIdx].used = true
- await this.updateEmbeddedDocuments('Item', [{ _id: compId, 'system.predilections': pred }])
- }
-
- /* -------------------------------------------- */
- getInitiativeScore() {
- let init = this.getFlag("world", "last-initiative")
- return init || -1
- }
-
- /* -------------------------------------------- */
- getBestAttackValue() {
- let attackList = this.items.filter(item => (item.type == "arme" || item.type == "talent") && item.system.equipped)
- let maxOff = 0
- let bestArme
- for (let arme of attackList) {
- if (arme.type == "arme") {
- arme = this.prepareArme(arme)
- }
- if (arme.system.totalOffensif > maxOff) {
- maxOff = arme.system.totalOffensif
- bestArme = foundry.utils.duplicate(arme)
- }
- }
- return bestArme
- }
-
- /* -------------------------------------------- */
- getBestDefenseValue() {
- let defenseList = this.items.filter(item => (item.type == "arme") && item.system.equipped)
- let maxDef = 0
- let bestArme
- for (let arme of defenseList) {
- if (arme.type == "arme") {
- arme = this.prepareArme(arme)
- }
- if (arme.system.totalDefensif > maxDef) {
- maxDef = arme.system.totalDefensif
- bestArme = foundry.utils.duplicate(arme)
- }
- }
- return bestArme
- }
-
- /* -------------------------------------------- */
- searchRelevantTalents(competence) {
- let talents = []
-
- for (let talent of this.items) {
- if (talent.type == "talent" && talent.system.isautomated && talent.system.automations.length > 0) {
- for (let auto of talent.system.automations) {
- if (auto.eventtype === "prepare-roll") {
- if (auto.competence.toLowerCase() == competence.name.toLowerCase()) {
- talent = foundry.utils.duplicate(talent)
- talent.system.bonus = auto.bonus
- talent.system.baCost = auto.baCost
- talents.push(talent)
- }
- }
- }
- }
- }
- return talents
- }
-
- /* -------------------------------------------- */
- buildListeAdversites() {
- return []
- }
-
- /* -------------------------------------------- */
- getCommonRollData(attrKey = undefined, compId = undefined, compName = undefined) {
- let rollData = MournbladeCYD2Utility.getBasicRollData()
- rollData.alias = this.name
- rollData.actorImg = this.img
- rollData.actorId = this.id
- rollData.tokenId = this.token?.id
- rollData.img = this.img
- rollData.attributs = MournbladeCYD2Utility.getAttributs()
- rollData.maitriseId = "none"
- rollData.nbEclat = this.system.eclat.value
- rollData.nbBA = this.system.bonneaventure.actuelle
- rollData.nbAdversites = this.getTotalAdversite()
- rollData.talents = []
- rollData.attrKey2 = "none"
- rollData.coupDevastateur = this.items.find(it => it.type == "talent" && it.name.toLowerCase() == "coup dévastateur" && !it.system.used)
- rollData.hasAmbidextre = this.items.find(it => it.type == "talent" && it.name.toLowerCase() == "ambidextre")
- rollData.hasFeinte = this.system.bonneaventure.actuelle > 0 && this.items.find(it => it.type == "talent" && it.name.toLowerCase() == "feinte")
- rollData.isMonte = this.system.combat.monte
- rollData.config = game.system.mournbladecyd2.config
-
- if (attrKey) {
- rollData.attrKey = attrKey
- if (attrKey != "tochoose") {
- rollData.actionImg = "systems/fvtt-mournblade-cyd2/assets/icons/" + this.system.attributs[attrKey].labelnorm + ".webp"
- rollData.attr = foundry.utils.duplicate(this.system.attributs[attrKey])
- }
- }
- if (compId) {
- rollData.competence = foundry.utils.duplicate(this.items.get(compId) || {})
- let maitrises = [{ key: "none", label: "Aucune" }]
- rollData.competence.system.predilections.forEach(function (item) {
- if (item.maitrise) {
- maitrises.push({ key: item.id, label: item.name });
- }
- })
- rollData.maitrises = maitrises // rollData.competence.system.predilections.filter(p => p.maitrise)
- rollData.actionImg = rollData.competence?.img
- rollData.talents = this.searchRelevantTalents(rollData.competence)
- }
- if (compName) {
- rollData.competence = foundry.utils.duplicate(this.items.find(item => item.name.toLowerCase() == compName.toLowerCase()) || {})
- rollData.actionImg = rollData.competence?.img
- }
- return rollData
- }
-
- /* -------------------------------------------- */
- async rollAttribut(attrKey, isInit = false) {
- let rollData = this.getCommonRollData(attrKey)
- rollData.multiplier = (isInit) ? 1 : 2
- rollData.isInit = isInit
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
-
- /* -------------------------------------------- */
- async rollCompetence(attrKey, compId) {
- let rollData = this.getCommonRollData(attrKey, compId)
- rollData.multiplier = 1 // Attr multiplier, always 1 in competence mode
- console.log("RollDatra", rollData)
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
-
- /* -------------------------------------------- */
- async rollArmeOffensif(armeId) {
- let arme = this.items.get(armeId)
- if (arme.type == "arme") {
- arme = this.prepareArme(arme)
- }
- let rollData = this.getCommonRollData(arme.system.attrKey, arme.system.competence._id)
- rollData.arme = arme
- MournbladeCYD2Utility.updateWithTarget(rollData)
- console.log("ARME!", rollData)
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
- /* -------------------------------------------- */
- async rollAssommer() {
- let rollData = this.getCommonRollData("pui", undefined, "Filouterie")
- rollData.assomer = true
- rollData.conditionsCommunes = true
- MournbladeCYD2Utility.updateWithTarget(rollData)
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
- /* -------------------------------------------- */
- async rollCoupBas() {
- let rollData = this.getCommonRollData("pui", undefined, "Mêlée")
- rollData.coupBas = true
- rollData.conditionsCommunes = true
- MournbladeCYD2Utility.updateWithTarget(rollData)
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
- /* -------------------------------------------- */
- async rollImmobiliser() {
- let rollData = this.getCommonRollData("pui", undefined, "Mêlée")
- rollData.immobiliser = true
- rollData.conditionsCommunes = true
- rollData.cibleconsciente = true
- MournbladeCYD2Utility.updateWithTarget(rollData)
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
- /* -------------------------------------------- */
- async rollRepousser() {
- let rollData = this.getCommonRollData("pui", undefined, "Mêlée")
- rollData.repousser = true
- rollData.conditionsCommunes = true
- rollData.cibleconsciente = true
- MournbladeCYD2Utility.updateWithTarget(rollData)
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
- /* -------------------------------------------- */
- async rollDesengager() {
- let rollData = this.getCommonRollData("adr", undefined, "Mouvements")
- rollData.desengager = true
- rollData.conditionsCommunes = true
- MournbladeCYD2Utility.updateWithTarget(rollData)
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
-
- /* -------------------------------------------- */
- async rollArmeDegats(armeId, targetVigueur = undefined, rollDataInput = undefined) {
- let arme = this.items.get(armeId)
- if (arme.type == "arme") {
- arme = this.prepareArme(arme)
- }
- console.log("DEGATS", arme, targetVigueur, rollDataInput)
- let roll
- let bonus = 0
- let bonus2 = 0
-
- if (rollDataInput?.applyCoupDevastateur) {
- bonus2 = Math.floor(this.system.attributs.pui.value / 2)
- let talent = this.items.find(item => item.type == "talent" && item.name.toLowerCase() == "coup dévastateur")
- this.updateEmbeddedDocuments('Item', [{ _id: talent.id, 'system.used': true }])
- }
-
- if (rollDataInput?.isHeroique) {
- if (rollDataInput?.attaqueCharge) {
- bonus = 5
- }
- if (rollDataInput?.chargeCavalerie) {
- bonus = 6
- }
- roll = await new Roll("2d10rr10+" + arme.system.totalDegats + "+" + bonus + "+" + bonus2).roll()
- } else {
- if (rollDataInput?.attaqueCharge) {
- bonus = 3
- }
- if (rollDataInput?.chargeCavalerie) {
- bonus = 4
- }
- roll = await new Roll("1d10+" + arme.system.totalDegats + "+" + bonus + "+" + bonus2).roll()
- }
- await MournbladeCYD2Utility.showDiceSoNice(roll, game.settings.get("core", "rollMode"));
- let nbEtatPerdus = 0
- if (targetVigueur) {
- nbEtatPerdus = Math.floor(roll.total / targetVigueur)
- }
- //console.log(roll)
- let rollData = {
- arme: arme,
- finalResult: roll.total,
- formula: roll.formula,
- alias: this.name,
- actorImg: this.img,
- actorId: this.id,
- defenderTokenId: rollDataInput?.defenderTokenId,
- actionImg: arme.img,
- targetVigueur: targetVigueur,
- nbEtatPerdus: nbEtatPerdus
- }
- MournbladeCYD2Utility.createChatWithRollMode(rollData.alias, {
- content: await renderTemplate(`systems/fvtt-mournblade-cyd2/templates/chat-degats-result.html`, rollData)
- })
-
- if (rollDataInput?.defenderTokenId && nbEtatPerdus) {
- MournbladeCYD2Utility.applyCombativite(rollDataInput, nbEtatPerdus)
- }
-
- }
-}
diff --git a/.history/modules/mournblade-cyd2-actor_20251026084418.js b/.history/modules/mournblade-cyd2-actor_20251026084418.js
deleted file mode 100644
index d0baf54..0000000
--- a/.history/modules/mournblade-cyd2-actor_20251026084418.js
+++ /dev/null
@@ -1,907 +0,0 @@
-/* -------------------------------------------- */
-import { MournbladeCYD2Utility } from "./mournblade-cyd2-utility.js";
-import { MournbladeCYD2RollDialog } from "./mournblade-cyd2-roll-dialog.js";
-
-/* -------------------------------------------- */
-const __degatsBonus = [-2, -2, -1, -1, 0, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 8, 8, 9, 9, 10, 10]
-const __vitesseBonus = [-2, -2, -1, -1, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8]
-
-/* -------------------------------------------- */
-/**
- * Extend the base Actor entity by defining a custom roll data structure which is ideal for the Simple system.
- * @extends {Actor}
- */
-export class MournbladeCYD2Actor extends Actor {
-
- /* -------------------------------------------- */
- /**
- * Override the create() function to provide additional SoS functionality.
- *
- * This overrided create() function adds initial items
- * Namely: Basic skills, money,
- *
- * @param {Object} data Barebones actor data which this function adds onto.
- * @param {Object} options (Unused) Additional options which customize the creation workflow.
- *
- */
-
- static async create(data, options) {
-
- // Case of compendium global import
- if (data instanceof Array) {
- return super.create(data, options);
- }
- // If the created actor has items (only applicable to duplicated actors) bypass the new actor creation logic
- if (data.items) {
- let actor = super.create(data, options);
- return actor;
- }
-
- if (data.type == 'personnage') {
- const skills = await MournbladeCYD2Utility.loadCompendium("fvtt-mournblade-cyd2.skills")
- data.items = skills.map(i => i.toObject())
- }
- if (data.type == 'creature') {
- const skills = await MournbladeCYD2Utility.loadCompendium("fvtt-mournblade-cyd2.skills-creatures")
- data.items = skills.map(i => i.toObject())
- data.items.push({ name: "Arme naturelle 1", type: 'arme', img: "systems/fvtt-mournblade-cyd2/assets/icons/melee.webp", system: { typearme: "contact", bonusmaniementoff: 0, seuildefense: 0, degats: "0" } })
- data.items.push({ name: "Arme naturelle 2", type: 'arme', img: "systems/fvtt-mournblade-cyd2/assets/icons/melee.webp", system: { typearme: "contact", bonusmaniementoff: 0, seuildefense: 0, degats: "0" } })
- }
-
- return super.create(data, options);
- }
-
- /* -------------------------------------------- */
- getBonusDefenseFromTalents() {
- let talents = this.items.filter(item => item.type == "talent" && item.system.isautomated)
- let bonus = 0
- for (let talent of talents) {
- for (let auto of talent.system.automations) {
- if (auto.eventtype == "bonus-permanent" && auto.bonusname == "bonus-defensif") {
- bonus += Number(auto.bonus || 0)
- }
- }
- }
- return bonus
- }
-
- /* -------------------------------------------- */
- prepareArme(arme) {
- if (this.type == "cellule") {
- return arme
- }
-
- arme = foundry.utils.duplicate(arme)
- let combat = this.getCombatValues()
- if (arme.system.typearme == "contact" || arme.system.typearme == "contactjet") {
- let bonusDefense = this.getBonusDefenseFromTalents()
- arme.system.competence = foundry.utils.duplicate(this.items.find(item => item.type == "competence" && item.name.toLowerCase() == "mêlée"))
- arme.system.attrKey = "pui"
- arme.system.totalDegats = arme.system.degats + "+" + combat.bonusDegatsTotal
- arme.system.totalOffensif = this.system.attributs.pui.value + arme.system.competence.system.niveau + arme.system.bonusmaniementoff + (this.system.combat.monte ? 3 : 0)
- arme.system.totalDefensif = combat.defenseTotal + arme.system.competence.system.niveau + arme.system.seuildefense + bonusDefense + (this.system.combat.monte ? 3 : 0)
- console.log("Arme", arme.system.totalDefensif, combat, arme.system.competence.system.niveau, arme.system.seuildefense, bonusDefense)
- arme.system.isdefense = true
- arme.system.isMelee = true
- arme.system.isDistance = false
- }
- if (arme.system.typearme == "jet" || arme.system.typearme == "tir") {
- arme.system.competence = foundry.utils.duplicate(this.items.find(item => item.type == "competence" && item.name.toLowerCase() == "armes à distance"))
- arme.system.attrKey = "adr"
- arme.system.totalOffensif = this.system.attributs.adr.value + arme.system.competence.system.niveau + arme.system.bonusmaniementoff
- arme.system.totalDegats = arme.system.degats
- arme.system.isMelee = false
- arme.system.isDistance = true
- if (arme.system.isdefense) {
- arme.system.totalDefensif = combat.defenseTotal + arme.system.competence.system.niveau + arme.system.seuildefense
- }
- }
- return arme
- }
-
- /* -------------------------------------------- */
- getItemSorted(types) {
- let items = this.items.filter(item => types.includes(item.type)) || []
- MournbladeCYD2Utility.sortArrayObjectsByName(items)
- return items
- }
- getWeapons() {
- let armes = []
- for (let arme of this.items) {
- if (arme.type == "arme") {
- armes.push(this.prepareArme(arme))
- }
- }
- MournbladeCYD2Utility.sortArrayObjectsByName(armes)
- return armes
- }
- getMonnaies() {
- return this.getItemSorted(["monnaie"])
- }
- getEquipments() {
- return this.getItemSorted(["equipement"])
- }
- getArtefacts() {
- return this.getItemSorted(["artefact"])
- }
- getArmors() {
- return this.getItemSorted(["protection"])
- }
- getHistoriques() {
- return this.getItemSorted(["historique"])
- }
- getProfils() {
- return this.getItemSorted(["profil"])
- }
- getTalents() {
- return this.getItemSorted(["talent"])
- }
- getRessources() {
- return this.getItemSorted(["ressource"])
- }
- getContacts() {
- return this.getItemSorted(["contact"])
- }
- getMutations() {
- return this.getItemSorted(["mutation"])
- }
- getDons() {
- return this.getItemSorted(["don"])
- }
- getPactes() {
- return this.getItemSorted(["pacte"])
- }
- getTendances() {
- return this.getItemSorted(["tendance"])
- }
- getRunes() {
- return this.getItemSorted(["rune"])
- }
- getTraitsChaotiques() {
- return this.getItemSorted(["traitchaotique"])
- }
- getTraitsEspeces() {
- return this.getItemSorted(["traitespece"])
- }
-
- /* -------------------------------------------- */
- getAspect() {
- return (this.system.balance.loi > this.system.balance.chaos) ? this.system.balance.loi : this.system.balance.chaos
- }
- getMarge() {
- return Math.abs(this.system.balance.loi - this.system.balance.chaos)
- }
- getAlignement() {
- return (this.system.balance.loi > this.system.balance.chaos) ? "loyal" : "chaotique"
- }
-
- /* -------------------------------------------- */
- getSkills() {
- let comp = []
- for (let item of this.items) {
- item = foundry.utils.duplicate(item)
- if (item.type == "competence") {
- item.system.attribut1total = item.system.niveau + (this.system.attributs[item.system.attribut1]?.value || 0)
- item.system.attribut2total = item.system.niveau + (this.system.attributs[item.system.attribut2]?.value || 0)
- item.system.attribut3total = item.system.niveau + (this.system.attributs[item.system.attribut3]?.value || 0)
- if (item.system.niveau == 0) {
- item.system.attribut1total -= 3
- item.system.attribut2total -= 3
- item.system.attribut3total -= 3
- }
- item.system.attribut1label = this.system.attributs[item.system.attribut1]?.label || ""
- item.system.attribut2label = this.system.attributs[item.system.attribut2]?.label || ""
- item.system.attribut3label = this.system.attributs[item.system.attribut3]?.label || ""
- comp.push(item)
- }
- }
- MournbladeCYD2Utility.sortArrayObjectsByName(comp)
- return comp
- }
-
- /* ----------------------- --------------------- */
- addMember(actorId) {
- let members = foundry.utils.duplicate(this.system.members)
- members.push({ id: actorId })
- this.update({ 'system.members': members })
- }
- async removeMember(actorId) {
- let members = this.system.members.filter(it => it.id != actorId)
- this.update({ 'system.members': members })
- }
-
- /* -------------------------------------------- */
- getDefenseBase() {
- return Math.max(this.system.attributs.tre.value, this.system.attributs.adr.value)
- }
-
- /* -------------------------------------------- */
- getVitesseBase() {
- return 5 + __vitesseBonus[this.system.attributs.adr.value]
- }
- /* -------------------------------------------- */
- getProtection() {
- let equipProtection = 0
- for (let armor of this.items) {
- if (armor.type == "protection" && armor.system.equipped) {
- equipProtection += Number(armor.system.protection)
- }
- }
- if (equipProtection < 4) {
- return 4 + equipProtection // Cas des boucliers + sans armure
- }
- return equipProtection // Uniquement la protection des armures + boucliers
- }
-
- /* -------------------------------------------- */
- getCombatValues() {
- if (this.type == "cellule") {
- return {
- initBase: 0,
- initTotal: 0,
- bonusDegats: 0,
- bonusDegatsTotal: 0,
- vitesseBase: 0,
- vitesseTotal: 0,
- defenseBase: 0,
- protection: 0,
- defenseTotal: 0
- }
- }
-
- let combat = {
- initBase: this.system.attributs.adr.value,
- initTotal: this.system.attributs.adr.value + this.system.combat.initbonus,
- bonusDegats: this.getBonusDegats(),
- bonusDegatsTotal: this.getBonusDegats() + this.system.combat.bonusdegats,
- vitesseBase: this.getVitesseBase(),
- vitesseTotal: this.getVitesseBase() + this.system.combat.vitessebonus,
- defenseBase: this.getDefenseBase(),
- protection: this.getProtection(),
- defenseTotal: this.getDefenseBase() + this.system.combat.defensebonus + this.getProtection() - this.getTotalAdversite() + (this.system.combat.defensetotale ? 3 : 0)
- }
- return combat
- }
-
- /* -------------------------------------------- */
- prepareBaseData() {
- }
-
- /* -------------------------------------------- */
- async prepareData() {
- super.prepareData();
- }
-
- /* -------------------------------------------- */
- prepareDerivedData() {
-
- if (this.type == 'personnage') {
- let talentBonus = this.getVigueurBonus()
- let vigueur = Math.floor((this.system.attributs.pui.value + this.system.attributs.tre.value) / 2) + talentBonus + this.system.sante.vigueurmodifier
- if (vigueur != this.system.sante.vigueur) {
- this.update({ 'system.sante.vigueur': vigueur })
- }
-
- let seuilPouvoirBonus = this.getSeuilPouvoirBonus()
- let seuilPouvoir = Math.floor((this.system.attributs.tre.value + this.system.attributs.cla.value) / 2) + seuilPouvoirBonus + this.system.ame.seuilpouvoirmodifier
- if (seuilPouvoir != this.system.ame.seuilpouvoir) {
- this.update({ 'system.ame.seuilpouvoir': seuilPouvoir })
- }
- }
- super.prepareDerivedData()
- }
-
- /* -------------------------------------------- */
- _preUpdate(changed, options, user) {
- if (changed?.system?.sante?.etat && changed?.system?.sante?.etat != this.system.sante.etat) {
- setTimeout(() => {
- this.processCombativite(changed.system.sante)
- }, 800)
- }
- if (changed?.system?.ame?.etat && changed?.system?.ame?.etat != this.system.ame.etat) {
- // L'état d'Âme ne peut pas être inférieur au minimum (max dans le système)
- let minAme = this.system.ame.max !== undefined ? this.system.ame.max : 0
- if (changed.system.ame.etat < minAme) {
- changed.system.ame.etat = minAme
- }
- // L'état d'Âme ne peut pas dépasser nbame (Brisé)
- if (changed.system.ame.etat > this.system.ame.nbame) {
- changed.system.ame.etat = this.system.ame.nbame
- }
- setTimeout(() => {
- this.processAme(changed.system.ame)
- }, 800)
- }
- // Si le max d'Âme change, ajuster l'état actuel si nécessaire
- if (changed?.system?.ame?.max !== undefined && changed.system.ame.max != this.system.ame.max) {
- if (this.system.ame.etat < changed.system.ame.max) {
- changed.system.ame.etat = changed.system.ame.max
- }
- }
- super._preUpdate(changed, options, user);
- }
-
- /* -------------------------------------------- */
- _onUpdate(data, options, user) {
- super._onUpdate(data, options, user);
- }
- /* -------------------------------------------- */
- getItemById(id) {
- let item = this.items.find(item => item.id == id);
- if (item) {
- item = foundry.utils.duplicate(item)
- }
- return item;
- }
-
- /* -------------------------------------------- */
- async equipItem(itemId) {
- let item = this.items.find(item => item.id == itemId)
- if (item && item.system) {
- let update = { _id: item.id, "system.equipped": !item.system.equipped }
- await this.updateEmbeddedDocuments('Item', [update]); // Updates one EmbeddedEntity
- }
- }
-
- /* -------------------------------------------- */
- editItemField(itemId, itemType, itemField, dataType, value) {
- let item = this.items.find(item => item.id == itemId)
- if (item) {
- console.log("Item ", item, itemField, dataType, value)
- if (dataType.toLowerCase() == "number") {
- value = Number(value)
- } else {
- value = String(value)
- }
- let update = { _id: item.id, [`system.${itemField}`]: value };
- this.updateEmbeddedDocuments("Item", [update])
- }
- }
-
- /* -------------------------------------------- */
- checkAttribut(attribut, minLevel) {
- let attr = this.system.attributs.find(at => at.labelnorm == attribut.toLowerCase())
- if (attr && attr.value >= minLevel) {
- return { isValid: true, attr: foundry.utils.duplicate(attr) }
- }
- return { isValid: false }
- }
- /* -------------------------------------------- */
- checkAttributOrCompetenceLevel(compName, minLevel) {
- let comp = this.items.find(i => i.type == "competence" && i.name.toLowerCase() == compName.toLowerCase() && i.system.niveau >= minLevel)
- if (comp) {
- return { isValid: true, item: foundry.utils.duplicate(comp) }
- } else {
- for (let attrKey in this.system.attributs) {
- if (this.system.attributs[attrKey].label.toLowerCase() == compName.toLowerCase() && this.system.attributs[attrKey].value >= minLevel) {
- return { isValid: true, item: foundry.utils.duplicate(this.system.attributs[attrKey]) }
- }
- }
- }
- return { isValid: false, warningMessage: `Prérequis insuffisant : la compétence/attribut ${compName} doit être de niveau ${minLevel} au minimum` }
- }
- /* -------------------------------------------- */
- addCompetenceBonus(compName, bonus, baCost) {
- let comp = this.items.find(i => i.type == "competence" && i.name.toLowerCase() == compName.toLowerCase())
- if (comp) {
- comp = foundry.utils.duplicate(comp)
- comp.system.bonus = bonus
- comp.system.baCost = baCost
- return { isValid: true, item: comp }
- }
- return { isValid: false, warningMessage: `Compétence ${compName} non trouvée` }
- }
- /* -------------------------------------------- */
- checkIfCompetence(compName) {
- let comp = this.items.find(i => i.type == "competence" && i.name.toLowerCase() == compName.toLowerCase())
- if (comp) {
- return { isValid: true, item: comp }
- }
- return { isValid: false }
- }
- /* -------------------------------------------- */
- getVigueur() {
- return this.system.sante.vigueur
- }
-
- /* -------------------------------------------- */
- getVigueurBonus() {
- let talents = this.items.filter(item => item.type == "talent" && item.system.isautomated)
- let bonus = 0
- for (let talent of talents) {
- for (let auto of talent.system.automations) {
- if (auto.eventtype == "bonus-permanent" && auto.bonusname == "vigueur") {
- bonus += Number(auto.bonus || 0)
- }
- }
- }
- return bonus
- }
-
- /* -------------------------------------------- */
- getSeuilPouvoir() {
- return this.system.ame.seuilpouvoir
- }
-
- /* -------------------------------------------- */
- getSeuilPouvoirBonus() {
- let talents = this.items.filter(item => item.type == "talent" && item.system.isautomated)
- let bonus = 0
- for (let talent of talents) {
- for (let auto of talent.system.automations) {
- if (auto.eventtype == "bonus-permanent" && auto.bonusname == "seuilpouvoir") {
- bonus += Number(auto.bonus || 0)
- }
- }
- }
- return bonus
- }
-
- /* -------------------------------------------- */
- getAmeMax() {
- return Math.min(this.system.ame.max || this.system.ame.nbame, this.system.ame.nbame)
- }
-
- /* -------------------------------------------- */
- getBonneAventure() {
- return this.system.bonneaventure.actuelle
- }
- /* -------------------------------------------- */
- checkBonneAventure(cost) {
- return (this.system.bonneaventure.actuelle >= cost)
- }
- /* -------------------------------------------- */
- changeBonneAventure(value) {
- let newBA = this.system.bonneaventure.actuelle
- newBA += value
- this.update({ 'system.bonneaventure.actuelle': newBA })
- }
-
- /* -------------------------------------------- */
- getEclat() {
- return this.system.eclat.value
- }
-
- /* -------------------------------------------- */
- changeEclat(value) {
- let newE = this.system.eclat.value
- newE += value
- this.update({ 'system.eclat.value': newE })
- }
-
- /* -------------------------------------------- */
- compareName(a, b) {
- if (a.name < b.name) {
- return -1;
- }
- if (a.name > b.name) {
- return 1;
- }
- return 0;
- }
-
- /* -------------------------------------------- */
- getAttribute(attrKey) {
- return this.system.attributes[attrKey]
- }
-
- /* -------------------------------------------- */
- getBonusDegats() {
- return 0;
- }
-
- /* -------------------------------------------- */
- changeEtatCombativite(value) {
- if (value === "vaincu") {
- value = 200
- }
- let sante = foundry.utils.duplicate(this.system.sante)
- sante.etat += Number(value)
- sante.etat = Math.max(sante.etat, 0)
- sante.etat = Math.min(sante.etat, this.system.sante.nbcombativite)
- this.update({ 'system.sante': sante })
- if (sante.etat == this.system.sante.nbcombativite) {
- ChatMessage.create({ content: `${this.name} est vaincu !` })
- }
- // Duplicated ! this.processCombativite(sante)
- }
-
- /* -------------------------------------------- */
- changeEtatAme(value) {
- if (value === "brise") {
- value = 200
- }
- let ame = foundry.utils.duplicate(this.system.ame)
- ame.etat += Number(value)
- // L'état ne peut pas être inférieur au minimum (max dans le système)
- let minAme = this.system.ame.max !== undefined ? this.system.ame.max : 0
- ame.etat = Math.max(ame.etat, minAme)
- // L'état ne peut pas dépasser nbame (Brisé)
- ame.etat = Math.min(ame.etat, this.system.ame.nbame)
- this.update({ 'system.ame': ame })
- if (ame.etat >= this.system.ame.nbame) {
- ChatMessage.create({ content: `${this.name} est brisé !` })
- }
- }
-
- /* -------------------------------------------- */
- processCombativite(sante) {
- sante = sante || foundry.utils.duplicate(this.system.sante)
- // Gestion des états affaibli et très affaibli
- if (sante.etat == this.system.sante.nbcombativite - 2 || sante.etat == this.system.sante.nbcombativite - 1) {
- if (sante.etat == this.system.sante.nbcombativite - 2 && this.items.find(item => item.type == "talent" && item.name.toLowerCase() == "encaissement")) {
- ChatMessage.create({ content: `${this.name} ne subit pas les 2 adversités rouge grâce à Encaissement. Pensez à les ajouter à la fin de la scène !` })
- } else if (sante.etat == this.system.sante.nbcombativite - 1 && this.items.find(item => item.type == "talent" && item.name.toLowerCase().includes("vaillant"))) {
- ChatMessage.create({ content: `${this.name} ne subit pas les 2 adversités rouge grâce à Vaillant. Pensez à les ajouter à la fin de la scène !` })
- } else {
- ChatMessage.create({ content: `${this.name} subit 2 adversités rouge !` })
- this.incDecAdversite("rouge", 2)
- }
- }
- }
-
- /* -------------------------------------------- */
- processAme(ame) {
- ame = ame || foundry.utils.duplicate(this.system.ame)
- let traumatiseValue = this.system.ame.nbame - 2
- let tresTraumatiseValue = this.system.ame.nbame - 1
- let briseValue = this.system.ame.nbame
-
- // Gestion des états Traumatisé, Très Traumatisé et Brisé
- if (ame.etat == traumatiseValue) {
- ChatMessage.create({ content: `${this.name} est Traumatisé !` })
- } else if (ame.etat == tresTraumatiseValue) {
- ChatMessage.create({ content: `${this.name} est Très Traumatisé !` })
- } else if (ame.etat >= briseValue) {
- ChatMessage.create({ content: `${this.name} est Brisé !` })
- }
- }
-
- /* -------------------------------------------- */
- async equipGear(equipmentId) {
- let item = this.items.find(item => item.id == equipmentId);
- if (item?.system?.data) {
- let update = { _id: item.id, "system.equipped": !item.system.equipped };
- await this.updateEmbeddedDocuments('Item', [update]); // Updates one EmbeddedEntity
- }
- }
-
- /* -------------------------------------------- */
- getSubActors() {
- let subActors = [];
- for (let id of this.system.subactors) {
- subActors.push(foundry.utils.duplicate(game.actors.get(id)));
- }
- return subActors;
- }
- /* -------------------------------------------- */
- async addSubActor(subActorId) {
- let subActors = foundry.utils.duplicate(this.system.subactors);
- subActors.push(subActorId);
- await this.update({ 'system.subactors': subActors });
- }
- /* -------------------------------------------- */
- async delSubActor(subActorId) {
- let newArray = [];
- for (let id of this.system.subactors) {
- if (id != subActorId) {
- newArray.push(id);
- }
- }
- await this.update({ 'system.subactors': newArray });
- }
-
- /* -------------------------------------------- */
- getTotalAdversite() {
- return this.system.adversite.bleue + this.system.adversite.rouge + this.system.adversite.noire
- }
-
- /* -------------------------------------------- */
- async incDecAdversite(adv, incDec = 0) {
- let adversite = foundry.utils.duplicate(this.system.adversite)
- adversite[adv] += Number(incDec)
- adversite[adv] = Math.max(adversite[adv], 0)
- adversite[adv] = Math.min(adversite[adv], 20)
- this.update({ 'system.adversite': adversite })
- }
- /* -------------------------------------------- */
- async incDecQuantity(objetId, incDec = 0) {
- let objetQ = this.items.get(objetId)
- if (objetQ) {
- let newQ = objetQ.system.quantite + incDec
- newQ = Math.max(newQ, 0)
- await this.updateEmbeddedDocuments('Item', [{ _id: objetQ.id, 'system.quantite': newQ }]); // pdates one EmbeddedEntity
- }
- }
-
- /* -------------------------------------------- */
- computeRichesse() {
- let valueSC = 0
- for (let monnaie of this.items) {
- if (monnaie.type == "monnaie") {
- valueSC += Number(monnaie.system.prixsc) * Number(monnaie.system.quantite)
- }
- }
- return MournbladeCYD2Utility.computeMonnaieDetails(valueSC)
- }
-
- /* -------------------------------------------- */
- computeValeurEquipement() {
- let valueSC = 0
- for (let equip of this.items) {
- if (equip.type == "equipement" || equip.type == "arme" || equip.type == "protection") {
- valueSC += Number(equip.system.prixsc) * Number(equip.system.quantite ?? 1)
- valueSC += (Number(equip.system.prixca) * Number(equip.system.quantite ?? 1)) * 20
- valueSC += (Number(equip.system.prixpo) * Number(equip.system.quantite ?? 1)) * 400
- }
- }
- return MournbladeCYD2Utility.computeMonnaieDetails(valueSC)
- }
-
- /* -------------------------------------------- */
- getCompetence(compId) {
- return this.items.get(compId)
- }
-
- /* -------------------------------------------- */
- async setPredilectionUsed(compId, predIdx) {
- let comp = this.items.get(compId)
- let pred = foundry.utils.duplicate(comp.system.predilections)
- pred[predIdx].used = true
- await this.updateEmbeddedDocuments('Item', [{ _id: compId, 'system.predilections': pred }])
- }
-
- /* -------------------------------------------- */
- getInitiativeScore() {
- let init = this.getFlag("world", "last-initiative")
- return init || -1
- }
-
- /* -------------------------------------------- */
- getBestAttackValue() {
- let attackList = this.items.filter(item => (item.type == "arme" || item.type == "talent") && item.system.equipped)
- let maxOff = 0
- let bestArme
- for (let arme of attackList) {
- if (arme.type == "arme") {
- arme = this.prepareArme(arme)
- }
- if (arme.system.totalOffensif > maxOff) {
- maxOff = arme.system.totalOffensif
- bestArme = foundry.utils.duplicate(arme)
- }
- }
- return bestArme
- }
-
- /* -------------------------------------------- */
- getBestDefenseValue() {
- let defenseList = this.items.filter(item => (item.type == "arme") && item.system.equipped)
- let maxDef = 0
- let bestArme
- for (let arme of defenseList) {
- if (arme.type == "arme") {
- arme = this.prepareArme(arme)
- }
- if (arme.system.totalDefensif > maxDef) {
- maxDef = arme.system.totalDefensif
- bestArme = foundry.utils.duplicate(arme)
- }
- }
- return bestArme
- }
-
- /* -------------------------------------------- */
- searchRelevantTalents(competence) {
- let talents = []
-
- for (let talent of this.items) {
- if (talent.type == "talent" && talent.system.isautomated && talent.system.automations.length > 0) {
- for (let auto of talent.system.automations) {
- if (auto.eventtype === "prepare-roll") {
- if (auto.competence.toLowerCase() == competence.name.toLowerCase()) {
- talent = foundry.utils.duplicate(talent)
- talent.system.bonus = auto.bonus
- talent.system.baCost = auto.baCost
- talents.push(talent)
- }
- }
- }
- }
- }
- return talents
- }
-
- /* -------------------------------------------- */
- buildListeAdversites() {
- return []
- }
-
- /* -------------------------------------------- */
- getCommonRollData(attrKey = undefined, compId = undefined, compName = undefined) {
- let rollData = MournbladeCYD2Utility.getBasicRollData()
- rollData.alias = this.name
- rollData.actorImg = this.img
- rollData.actorId = this.id
- rollData.tokenId = this.token?.id
- rollData.img = this.img
- rollData.attributs = MournbladeCYD2Utility.getAttributs()
- rollData.maitriseId = "none"
- rollData.nbEclat = this.system.eclat.value
- rollData.nbBA = this.system.bonneaventure.actuelle
- rollData.nbAdversites = this.getTotalAdversite()
- rollData.talents = []
- rollData.attrKey2 = "none"
- rollData.coupDevastateur = this.items.find(it => it.type == "talent" && it.name.toLowerCase() == "coup dévastateur" && !it.system.used)
- rollData.hasAmbidextre = this.items.find(it => it.type == "talent" && it.name.toLowerCase() == "ambidextre")
- rollData.hasFeinte = this.system.bonneaventure.actuelle > 0 && this.items.find(it => it.type == "talent" && it.name.toLowerCase() == "feinte")
- rollData.isMonte = this.system.combat.monte
- rollData.config = game.system.mournbladecyd2.config
-
- if (attrKey) {
- rollData.attrKey = attrKey
- if (attrKey != "tochoose") {
- rollData.actionImg = "systems/fvtt-mournblade-cyd2/assets/icons/" + this.system.attributs[attrKey].labelnorm + ".webp"
- rollData.attr = foundry.utils.duplicate(this.system.attributs[attrKey])
- }
- }
- if (compId) {
- rollData.competence = foundry.utils.duplicate(this.items.get(compId) || {})
- let maitrises = [{ key: "none", label: "Aucune" }]
- rollData.competence.system.predilections.forEach(function (item) {
- if (item.maitrise) {
- maitrises.push({ key: item.id, label: item.name });
- }
- })
- rollData.maitrises = maitrises // rollData.competence.system.predilections.filter(p => p.maitrise)
- rollData.actionImg = rollData.competence?.img
- rollData.talents = this.searchRelevantTalents(rollData.competence)
- }
- if (compName) {
- rollData.competence = foundry.utils.duplicate(this.items.find(item => item.name.toLowerCase() == compName.toLowerCase()) || {})
- rollData.actionImg = rollData.competence?.img
- }
- return rollData
- }
-
- /* -------------------------------------------- */
- async rollAttribut(attrKey, isInit = false) {
- let rollData = this.getCommonRollData(attrKey)
- rollData.multiplier = (isInit) ? 1 : 2
- rollData.isInit = isInit
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
-
- /* -------------------------------------------- */
- async rollCompetence(attrKey, compId) {
- let rollData = this.getCommonRollData(attrKey, compId)
- rollData.multiplier = 1 // Attr multiplier, always 1 in competence mode
- console.log("RollDatra", rollData)
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
-
- /* -------------------------------------------- */
- async rollArmeOffensif(armeId) {
- let arme = this.items.get(armeId)
- if (arme.type == "arme") {
- arme = this.prepareArme(arme)
- }
- let rollData = this.getCommonRollData(arme.system.attrKey, arme.system.competence._id)
- rollData.arme = arme
- MournbladeCYD2Utility.updateWithTarget(rollData)
- console.log("ARME!", rollData)
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
- /* -------------------------------------------- */
- async rollAssommer() {
- let rollData = this.getCommonRollData("pui", undefined, "Filouterie")
- rollData.assomer = true
- rollData.conditionsCommunes = true
- MournbladeCYD2Utility.updateWithTarget(rollData)
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
- /* -------------------------------------------- */
- async rollCoupBas() {
- let rollData = this.getCommonRollData("pui", undefined, "Mêlée")
- rollData.coupBas = true
- rollData.conditionsCommunes = true
- MournbladeCYD2Utility.updateWithTarget(rollData)
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
- /* -------------------------------------------- */
- async rollImmobiliser() {
- let rollData = this.getCommonRollData("pui", undefined, "Mêlée")
- rollData.immobiliser = true
- rollData.conditionsCommunes = true
- rollData.cibleconsciente = true
- MournbladeCYD2Utility.updateWithTarget(rollData)
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
- /* -------------------------------------------- */
- async rollRepousser() {
- let rollData = this.getCommonRollData("pui", undefined, "Mêlée")
- rollData.repousser = true
- rollData.conditionsCommunes = true
- rollData.cibleconsciente = true
- MournbladeCYD2Utility.updateWithTarget(rollData)
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
- /* -------------------------------------------- */
- async rollDesengager() {
- let rollData = this.getCommonRollData("adr", undefined, "Mouvements")
- rollData.desengager = true
- rollData.conditionsCommunes = true
- MournbladeCYD2Utility.updateWithTarget(rollData)
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
-
- /* -------------------------------------------- */
- async rollArmeDegats(armeId, targetVigueur = undefined, rollDataInput = undefined) {
- let arme = this.items.get(armeId)
- if (arme.type == "arme") {
- arme = this.prepareArme(arme)
- }
- console.log("DEGATS", arme, targetVigueur, rollDataInput)
- let roll
- let bonus = 0
- let bonus2 = 0
-
- if (rollDataInput?.applyCoupDevastateur) {
- bonus2 = Math.floor(this.system.attributs.pui.value / 2)
- let talent = this.items.find(item => item.type == "talent" && item.name.toLowerCase() == "coup dévastateur")
- this.updateEmbeddedDocuments('Item', [{ _id: talent.id, 'system.used': true }])
- }
-
- if (rollDataInput?.isHeroique) {
- if (rollDataInput?.attaqueCharge) {
- bonus = 5
- }
- if (rollDataInput?.chargeCavalerie) {
- bonus = 6
- }
- roll = await new Roll("2d10rr10+" + arme.system.totalDegats + "+" + bonus + "+" + bonus2).roll()
- } else {
- if (rollDataInput?.attaqueCharge) {
- bonus = 3
- }
- if (rollDataInput?.chargeCavalerie) {
- bonus = 4
- }
- roll = await new Roll("1d10+" + arme.system.totalDegats + "+" + bonus + "+" + bonus2).roll()
- }
- await MournbladeCYD2Utility.showDiceSoNice(roll, game.settings.get("core", "rollMode"));
- let nbEtatPerdus = 0
- if (targetVigueur) {
- nbEtatPerdus = Math.floor(roll.total / targetVigueur)
- }
- //console.log(roll)
- let rollData = {
- arme: arme,
- finalResult: roll.total,
- formula: roll.formula,
- alias: this.name,
- actorImg: this.img,
- actorId: this.id,
- defenderTokenId: rollDataInput?.defenderTokenId,
- actionImg: arme.img,
- targetVigueur: targetVigueur,
- nbEtatPerdus: nbEtatPerdus
- }
- MournbladeCYD2Utility.createChatWithRollMode(rollData.alias, {
- content: await renderTemplate(`systems/fvtt-mournblade-cyd2/templates/chat-degats-result.html`, rollData)
- })
-
- if (rollDataInput?.defenderTokenId && nbEtatPerdus) {
- MournbladeCYD2Utility.applyCombativite(rollDataInput, nbEtatPerdus)
- }
-
- }
-}
diff --git a/.history/modules/mournblade-cyd2-actor_20251026084727.js b/.history/modules/mournblade-cyd2-actor_20251026084727.js
deleted file mode 100644
index b0b3dc0..0000000
--- a/.history/modules/mournblade-cyd2-actor_20251026084727.js
+++ /dev/null
@@ -1,908 +0,0 @@
-/* -------------------------------------------- */
-import { MournbladeCYD2Utility } from "./mournblade-cyd2-utility.js";
-import { MournbladeCYD2RollDialog } from "./mournblade-cyd2-roll-dialog.js";
-
-/* -------------------------------------------- */
-const __degatsBonus = [-2, -2, -1, -1, 0, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 8, 8, 9, 9, 10, 10]
-const __vitesseBonus = [-2, -2, -1, -1, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8]
-
-/* -------------------------------------------- */
-/**
- * Extend the base Actor entity by defining a custom roll data structure which is ideal for the Simple system.
- * @extends {Actor}
- */
-export class MournbladeCYD2Actor extends Actor {
-
- /* -------------------------------------------- */
- /**
- * Override the create() function to provide additional SoS functionality.
- *
- * This overrided create() function adds initial items
- * Namely: Basic skills, money,
- *
- * @param {Object} data Barebones actor data which this function adds onto.
- * @param {Object} options (Unused) Additional options which customize the creation workflow.
- *
- */
-
- static async create(data, options) {
-
- // Case of compendium global import
- if (data instanceof Array) {
- return super.create(data, options);
- }
- // If the created actor has items (only applicable to duplicated actors) bypass the new actor creation logic
- if (data.items) {
- let actor = super.create(data, options);
- return actor;
- }
-
- if (data.type == 'personnage') {
- const skills = await MournbladeCYD2Utility.loadCompendium("fvtt-mournblade-cyd2.skills")
- data.items = skills.map(i => i.toObject())
- }
- if (data.type == 'creature') {
- const skills = await MournbladeCYD2Utility.loadCompendium("fvtt-mournblade-cyd2.skills-creatures")
- data.items = skills.map(i => i.toObject())
- data.items.push({ name: "Arme naturelle 1", type: 'arme', img: "systems/fvtt-mournblade-cyd2/assets/icons/melee.webp", system: { typearme: "contact", bonusmaniementoff: 0, seuildefense: 0, degats: "0" } })
- data.items.push({ name: "Arme naturelle 2", type: 'arme', img: "systems/fvtt-mournblade-cyd2/assets/icons/melee.webp", system: { typearme: "contact", bonusmaniementoff: 0, seuildefense: 0, degats: "0" } })
- }
-
- return super.create(data, options);
- }
-
- /* -------------------------------------------- */
- getBonusDefenseFromTalents() {
- let talents = this.items.filter(item => item.type == "talent" && item.system.isautomated)
- let bonus = 0
- for (let talent of talents) {
- for (let auto of talent.system.automations) {
- if (auto.eventtype == "bonus-permanent" && auto.bonusname == "bonus-defensif") {
- bonus += Number(auto.bonus || 0)
- }
- }
- }
- return bonus
- }
-
- /* -------------------------------------------- */
- prepareArme(arme) {
- if (this.type == "cellule") {
- return arme
- }
-
- arme = foundry.utils.duplicate(arme)
- let combat = this.getCombatValues()
- if (arme.system.typearme == "contact" || arme.system.typearme == "contactjet") {
- let bonusDefense = this.getBonusDefenseFromTalents()
- arme.system.competence = foundry.utils.duplicate(this.items.find(item => item.type == "competence" && item.name.toLowerCase() == "mêlée"))
- arme.system.attrKey = "pui"
- arme.system.totalDegats = arme.system.degats + "+" + combat.bonusDegatsTotal
- arme.system.totalOffensif = this.system.attributs.pui.value + arme.system.competence.system.niveau + arme.system.bonusmaniementoff + (this.system.combat.monte ? 3 : 0)
- arme.system.totalDefensif = combat.defenseTotal + arme.system.competence.system.niveau + arme.system.seuildefense + bonusDefense + (this.system.combat.monte ? 3 : 0)
- console.log("Arme", arme.system.totalDefensif, combat, arme.system.competence.system.niveau, arme.system.seuildefense, bonusDefense)
- arme.system.isdefense = true
- arme.system.isMelee = true
- arme.system.isDistance = false
- }
- if (arme.system.typearme == "jet" || arme.system.typearme == "tir") {
- arme.system.competence = foundry.utils.duplicate(this.items.find(item => item.type == "competence" && item.name.toLowerCase() == "armes à distance"))
- arme.system.attrKey = "adr"
- arme.system.totalOffensif = this.system.attributs.adr.value + arme.system.competence.system.niveau + arme.system.bonusmaniementoff
- arme.system.totalDegats = arme.system.degats
- arme.system.isMelee = false
- arme.system.isDistance = true
- if (arme.system.isdefense) {
- arme.system.totalDefensif = combat.defenseTotal + arme.system.competence.system.niveau + arme.system.seuildefense
- }
- }
- return arme
- }
-
- /* -------------------------------------------- */
- getItemSorted(types) {
- let items = this.items.filter(item => types.includes(item.type)) || []
- MournbladeCYD2Utility.sortArrayObjectsByName(items)
- return items
- }
- getWeapons() {
- let armes = []
- for (let arme of this.items) {
- if (arme.type == "arme") {
- armes.push(this.prepareArme(arme))
- }
- }
- MournbladeCYD2Utility.sortArrayObjectsByName(armes)
- return armes
- }
- getMonnaies() {
- return this.getItemSorted(["monnaie"])
- }
- getEquipments() {
- return this.getItemSorted(["equipement"])
- }
- getArtefacts() {
- return this.getItemSorted(["artefact"])
- }
- getArmors() {
- return this.getItemSorted(["protection"])
- }
- getHistoriques() {
- return this.getItemSorted(["historique"])
- }
- getProfils() {
- return this.getItemSorted(["profil"])
- }
- getTalents() {
- return this.getItemSorted(["talent"])
- }
- getRessources() {
- return this.getItemSorted(["ressource"])
- }
- getContacts() {
- return this.getItemSorted(["contact"])
- }
- getMutations() {
- return this.getItemSorted(["mutation"])
- }
- getDons() {
- return this.getItemSorted(["don"])
- }
- getPactes() {
- return this.getItemSorted(["pacte"])
- }
- getTendances() {
- return this.getItemSorted(["tendance"])
- }
- getRunes() {
- return this.getItemSorted(["rune"])
- }
- getTraitsChaotiques() {
- return this.getItemSorted(["traitchaotique"])
- }
- getTraitsEspeces() {
- return this.getItemSorted(["traitespece"])
- }
-
- /* -------------------------------------------- */
- getAspect() {
- return (this.system.balance.loi > this.system.balance.chaos) ? this.system.balance.loi : this.system.balance.chaos
- }
- getMarge() {
- return Math.abs(this.system.balance.loi - this.system.balance.chaos)
- }
- getAlignement() {
- return (this.system.balance.loi > this.system.balance.chaos) ? "loyal" : "chaotique"
- }
-
- /* -------------------------------------------- */
- getSkills() {
- let comp = []
- for (let item of this.items) {
- item = foundry.utils.duplicate(item)
- if (item.type == "competence") {
- item.system.attribut1total = item.system.niveau + (this.system.attributs[item.system.attribut1]?.value || 0)
- item.system.attribut2total = item.system.niveau + (this.system.attributs[item.system.attribut2]?.value || 0)
- item.system.attribut3total = item.system.niveau + (this.system.attributs[item.system.attribut3]?.value || 0)
- if (item.system.niveau == 0) {
- item.system.attribut1total -= 3
- item.system.attribut2total -= 3
- item.system.attribut3total -= 3
- }
- item.system.attribut1label = this.system.attributs[item.system.attribut1]?.label || ""
- item.system.attribut2label = this.system.attributs[item.system.attribut2]?.label || ""
- item.system.attribut3label = this.system.attributs[item.system.attribut3]?.label || ""
- comp.push(item)
- }
- }
- MournbladeCYD2Utility.sortArrayObjectsByName(comp)
- return comp
- }
-
- /* ----------------------- --------------------- */
- addMember(actorId) {
- let members = foundry.utils.duplicate(this.system.members)
- members.push({ id: actorId })
- this.update({ 'system.members': members })
- }
- async removeMember(actorId) {
- let members = this.system.members.filter(it => it.id != actorId)
- this.update({ 'system.members': members })
- }
-
- /* -------------------------------------------- */
- getDefenseBase() {
- return Math.max(this.system.attributs.tre.value, this.system.attributs.adr.value)
- }
-
- /* -------------------------------------------- */
- getVitesseBase() {
- return 5 + __vitesseBonus[this.system.attributs.adr.value]
- }
- /* -------------------------------------------- */
- getProtection() {
- let equipProtection = 0
- for (let armor of this.items) {
- if (armor.type == "protection" && armor.system.equipped) {
- equipProtection += Number(armor.system.protection)
- }
- }
- if (equipProtection < 4) {
- return 4 + equipProtection // Cas des boucliers + sans armure
- }
- return equipProtection // Uniquement la protection des armures + boucliers
- }
-
- /* -------------------------------------------- */
- getCombatValues() {
- if (this.type == "cellule") {
- return {
- initBase: 0,
- initTotal: 0,
- bonusDegats: 0,
- bonusDegatsTotal: 0,
- vitesseBase: 0,
- vitesseTotal: 0,
- defenseBase: 0,
- protection: 0,
- defenseTotal: 0
- }
- }
-
- let combat = {
- initBase: this.system.attributs.adr.value,
- initTotal: this.system.attributs.adr.value + this.system.combat.initbonus,
- bonusDegats: this.getBonusDegats(),
- bonusDegatsTotal: this.getBonusDegats() + this.system.combat.bonusdegats,
- vitesseBase: this.getVitesseBase(),
- vitesseTotal: this.getVitesseBase() + this.system.combat.vitessebonus,
- defenseBase: this.getDefenseBase(),
- protection: this.getProtection(),
- defenseTotal: this.getDefenseBase() + this.system.combat.defensebonus + this.getProtection() - this.getTotalAdversite() + (this.system.combat.defensetotale ? 3 : 0)
- }
- return combat
- }
-
- /* -------------------------------------------- */
- prepareBaseData() {
- }
-
- /* -------------------------------------------- */
- async prepareData() {
- super.prepareData();
- }
-
- /* -------------------------------------------- */
- prepareDerivedData() {
-
- if (this.type == 'personnage') {
- let talentBonus = this.getVigueurBonus()
- let vigueur = Math.floor((this.system.attributs.pui.value + this.system.attributs.tre.value) / 2) + talentBonus + this.system.sante.vigueurmodifier
- if (vigueur != this.system.sante.vigueur) {
- this.update({ 'system.sante.vigueur': vigueur })
- }
-
- let seuilPouvoirBonus = this.getSeuilPouvoirBonus()
- let seuilPouvoir = Math.floor((this.system.attributs.tre.value + this.system.attributs.cla.value) / 2) + seuilPouvoirBonus + this.system.ame.seuilpouvoirmodifier
- if (seuilPouvoir != this.system.ame.seuilpouvoir) {
- this.update({ 'system.ame.seuilpouvoir': seuilPouvoir })
- }
- }
- super.prepareDerivedData()
- }
-
- /* -------------------------------------------- */
- _preUpdate(changed, options, user) {
- if (changed?.system?.sante?.etat && changed?.system?.sante?.etat != this.system.sante.etat) {
- setTimeout(() => {
- this.processCombativite(changed.system.sante)
- }, 800)
- }
- if (changed?.system?.ame?.etat && changed?.system?.ame?.etat != this.system.ame.etat) {
- // L'état d'Âme ne peut pas être inférieur au minimum (max dans le système)
- let minAme = this.system.ame.max !== undefined ? this.system.ame.max : 0
- if (changed.system.ame.etat < minAme) {
- changed.system.ame.etat = minAme
- }
- // L'état d'Âme ne peut pas dépasser nbame (Brisé)
- if (changed.system.ame.etat > this.system.ame.nbame) {
- changed.system.ame.etat = this.system.ame.nbame
- }
- setTimeout(() => {
- this.processAme(changed.system.ame)
- }, 800)
- }
- // Si le max d'Âme change, ajuster l'état actuel si nécessaire
- if (changed?.system?.ame?.max !== undefined && changed.system.ame.max != this.system.ame.max) {
- if (this.system.ame.etat < changed.system.ame.max) {
- changed.system.ame.etat = changed.system.ame.max
- }
- }
- super._preUpdate(changed, options, user);
- }
-
- /* -------------------------------------------- */
- _onUpdate(data, options, user) {
- super._onUpdate(data, options, user);
- }
- /* -------------------------------------------- */
- getItemById(id) {
- let item = this.items.find(item => item.id == id);
- if (item) {
- item = foundry.utils.duplicate(item)
- }
- return item;
- }
-
- /* -------------------------------------------- */
- async equipItem(itemId) {
- let item = this.items.find(item => item.id == itemId)
- if (item && item.system) {
- let update = { _id: item.id, "system.equipped": !item.system.equipped }
- await this.updateEmbeddedDocuments('Item', [update]); // Updates one EmbeddedEntity
- }
- }
-
- /* -------------------------------------------- */
- editItemField(itemId, itemType, itemField, dataType, value) {
- let item = this.items.find(item => item.id == itemId)
- if (item) {
- console.log("Item ", item, itemField, dataType, value)
- if (dataType.toLowerCase() == "number") {
- value = Number(value)
- } else {
- value = String(value)
- }
- let update = { _id: item.id, [`system.${itemField}`]: value };
- this.updateEmbeddedDocuments("Item", [update])
- }
- }
-
- /* -------------------------------------------- */
- checkAttribut(attribut, minLevel) {
- let attr = this.system.attributs.find(at => at.labelnorm == attribut.toLowerCase())
- if (attr && attr.value >= minLevel) {
- return { isValid: true, attr: foundry.utils.duplicate(attr) }
- }
- return { isValid: false }
- }
- /* -------------------------------------------- */
- checkAttributOrCompetenceLevel(compName, minLevel) {
- let comp = this.items.find(i => i.type == "competence" && i.name.toLowerCase() == compName.toLowerCase() && i.system.niveau >= minLevel)
- if (comp) {
- return { isValid: true, item: foundry.utils.duplicate(comp) }
- } else {
- for (let attrKey in this.system.attributs) {
- if (this.system.attributs[attrKey].label.toLowerCase() == compName.toLowerCase() && this.system.attributs[attrKey].value >= minLevel) {
- return { isValid: true, item: foundry.utils.duplicate(this.system.attributs[attrKey]) }
- }
- }
- }
- return { isValid: false, warningMessage: `Prérequis insuffisant : la compétence/attribut ${compName} doit être de niveau ${minLevel} au minimum` }
- }
- /* -------------------------------------------- */
- addCompetenceBonus(compName, bonus, baCost) {
- let comp = this.items.find(i => i.type == "competence" && i.name.toLowerCase() == compName.toLowerCase())
- if (comp) {
- comp = foundry.utils.duplicate(comp)
- comp.system.bonus = bonus
- comp.system.baCost = baCost
- return { isValid: true, item: comp }
- }
- return { isValid: false, warningMessage: `Compétence ${compName} non trouvée` }
- }
- /* -------------------------------------------- */
- checkIfCompetence(compName) {
- let comp = this.items.find(i => i.type == "competence" && i.name.toLowerCase() == compName.toLowerCase())
- if (comp) {
- return { isValid: true, item: comp }
- }
- return { isValid: false }
- }
- /* -------------------------------------------- */
- getVigueur() {
- return this.system.sante.vigueur
- }
-
- /* -------------------------------------------- */
- getVigueurBonus() {
- let talents = this.items.filter(item => item.type == "talent" && item.system.isautomated)
- let bonus = 0
- for (let talent of talents) {
- for (let auto of talent.system.automations) {
- if (auto.eventtype == "bonus-permanent" && auto.bonusname == "vigueur") {
- bonus += Number(auto.bonus || 0)
- }
- }
- }
- return bonus
- }
-
- /* -------------------------------------------- */
- getSeuilPouvoir() {
- return this.system.ame.seuilpouvoir
- }
-
- /* -------------------------------------------- */
- getSeuilPouvoirBonus() {
- let talents = this.items.filter(item => item.type == "talent" && item.system.isautomated)
- let bonus = 0
- for (let talent of talents) {
- for (let auto of talent.system.automations) {
- if (auto.eventtype == "bonus-permanent" && auto.bonusname == "seuilpouvoir") {
- bonus += Number(auto.bonus || 0)
- }
- }
- }
- return bonus
- }
-
- /* -------------------------------------------- */
- getAmeMax() {
- // Utiliser une vérification stricte car 0 (Serein) est une valeur valide
- return this.system.ame.max !== undefined ? this.system.ame.max : this.system.ame.nbame
- }
-
- /* -------------------------------------------- */
- getBonneAventure() {
- return this.system.bonneaventure.actuelle
- }
- /* -------------------------------------------- */
- checkBonneAventure(cost) {
- return (this.system.bonneaventure.actuelle >= cost)
- }
- /* -------------------------------------------- */
- changeBonneAventure(value) {
- let newBA = this.system.bonneaventure.actuelle
- newBA += value
- this.update({ 'system.bonneaventure.actuelle': newBA })
- }
-
- /* -------------------------------------------- */
- getEclat() {
- return this.system.eclat.value
- }
-
- /* -------------------------------------------- */
- changeEclat(value) {
- let newE = this.system.eclat.value
- newE += value
- this.update({ 'system.eclat.value': newE })
- }
-
- /* -------------------------------------------- */
- compareName(a, b) {
- if (a.name < b.name) {
- return -1;
- }
- if (a.name > b.name) {
- return 1;
- }
- return 0;
- }
-
- /* -------------------------------------------- */
- getAttribute(attrKey) {
- return this.system.attributes[attrKey]
- }
-
- /* -------------------------------------------- */
- getBonusDegats() {
- return 0;
- }
-
- /* -------------------------------------------- */
- changeEtatCombativite(value) {
- if (value === "vaincu") {
- value = 200
- }
- let sante = foundry.utils.duplicate(this.system.sante)
- sante.etat += Number(value)
- sante.etat = Math.max(sante.etat, 0)
- sante.etat = Math.min(sante.etat, this.system.sante.nbcombativite)
- this.update({ 'system.sante': sante })
- if (sante.etat == this.system.sante.nbcombativite) {
- ChatMessage.create({ content: `${this.name} est vaincu !` })
- }
- // Duplicated ! this.processCombativite(sante)
- }
-
- /* -------------------------------------------- */
- changeEtatAme(value) {
- if (value === "brise") {
- value = 200
- }
- let ame = foundry.utils.duplicate(this.system.ame)
- ame.etat += Number(value)
- // L'état ne peut pas être inférieur au minimum (max dans le système)
- let minAme = this.system.ame.max !== undefined ? this.system.ame.max : 0
- ame.etat = Math.max(ame.etat, minAme)
- // L'état ne peut pas dépasser nbame (Brisé)
- ame.etat = Math.min(ame.etat, this.system.ame.nbame)
- this.update({ 'system.ame': ame })
- if (ame.etat >= this.system.ame.nbame) {
- ChatMessage.create({ content: `${this.name} est brisé !` })
- }
- }
-
- /* -------------------------------------------- */
- processCombativite(sante) {
- sante = sante || foundry.utils.duplicate(this.system.sante)
- // Gestion des états affaibli et très affaibli
- if (sante.etat == this.system.sante.nbcombativite - 2 || sante.etat == this.system.sante.nbcombativite - 1) {
- if (sante.etat == this.system.sante.nbcombativite - 2 && this.items.find(item => item.type == "talent" && item.name.toLowerCase() == "encaissement")) {
- ChatMessage.create({ content: `${this.name} ne subit pas les 2 adversités rouge grâce à Encaissement. Pensez à les ajouter à la fin de la scène !` })
- } else if (sante.etat == this.system.sante.nbcombativite - 1 && this.items.find(item => item.type == "talent" && item.name.toLowerCase().includes("vaillant"))) {
- ChatMessage.create({ content: `${this.name} ne subit pas les 2 adversités rouge grâce à Vaillant. Pensez à les ajouter à la fin de la scène !` })
- } else {
- ChatMessage.create({ content: `${this.name} subit 2 adversités rouge !` })
- this.incDecAdversite("rouge", 2)
- }
- }
- }
-
- /* -------------------------------------------- */
- processAme(ame) {
- ame = ame || foundry.utils.duplicate(this.system.ame)
- let traumatiseValue = this.system.ame.nbame - 2
- let tresTraumatiseValue = this.system.ame.nbame - 1
- let briseValue = this.system.ame.nbame
-
- // Gestion des états Traumatisé, Très Traumatisé et Brisé
- if (ame.etat == traumatiseValue) {
- ChatMessage.create({ content: `${this.name} est Traumatisé !` })
- } else if (ame.etat == tresTraumatiseValue) {
- ChatMessage.create({ content: `${this.name} est Très Traumatisé !` })
- } else if (ame.etat >= briseValue) {
- ChatMessage.create({ content: `${this.name} est Brisé !` })
- }
- }
-
- /* -------------------------------------------- */
- async equipGear(equipmentId) {
- let item = this.items.find(item => item.id == equipmentId);
- if (item?.system?.data) {
- let update = { _id: item.id, "system.equipped": !item.system.equipped };
- await this.updateEmbeddedDocuments('Item', [update]); // Updates one EmbeddedEntity
- }
- }
-
- /* -------------------------------------------- */
- getSubActors() {
- let subActors = [];
- for (let id of this.system.subactors) {
- subActors.push(foundry.utils.duplicate(game.actors.get(id)));
- }
- return subActors;
- }
- /* -------------------------------------------- */
- async addSubActor(subActorId) {
- let subActors = foundry.utils.duplicate(this.system.subactors);
- subActors.push(subActorId);
- await this.update({ 'system.subactors': subActors });
- }
- /* -------------------------------------------- */
- async delSubActor(subActorId) {
- let newArray = [];
- for (let id of this.system.subactors) {
- if (id != subActorId) {
- newArray.push(id);
- }
- }
- await this.update({ 'system.subactors': newArray });
- }
-
- /* -------------------------------------------- */
- getTotalAdversite() {
- return this.system.adversite.bleue + this.system.adversite.rouge + this.system.adversite.noire
- }
-
- /* -------------------------------------------- */
- async incDecAdversite(adv, incDec = 0) {
- let adversite = foundry.utils.duplicate(this.system.adversite)
- adversite[adv] += Number(incDec)
- adversite[adv] = Math.max(adversite[adv], 0)
- adversite[adv] = Math.min(adversite[adv], 20)
- this.update({ 'system.adversite': adversite })
- }
- /* -------------------------------------------- */
- async incDecQuantity(objetId, incDec = 0) {
- let objetQ = this.items.get(objetId)
- if (objetQ) {
- let newQ = objetQ.system.quantite + incDec
- newQ = Math.max(newQ, 0)
- await this.updateEmbeddedDocuments('Item', [{ _id: objetQ.id, 'system.quantite': newQ }]); // pdates one EmbeddedEntity
- }
- }
-
- /* -------------------------------------------- */
- computeRichesse() {
- let valueSC = 0
- for (let monnaie of this.items) {
- if (monnaie.type == "monnaie") {
- valueSC += Number(monnaie.system.prixsc) * Number(monnaie.system.quantite)
- }
- }
- return MournbladeCYD2Utility.computeMonnaieDetails(valueSC)
- }
-
- /* -------------------------------------------- */
- computeValeurEquipement() {
- let valueSC = 0
- for (let equip of this.items) {
- if (equip.type == "equipement" || equip.type == "arme" || equip.type == "protection") {
- valueSC += Number(equip.system.prixsc) * Number(equip.system.quantite ?? 1)
- valueSC += (Number(equip.system.prixca) * Number(equip.system.quantite ?? 1)) * 20
- valueSC += (Number(equip.system.prixpo) * Number(equip.system.quantite ?? 1)) * 400
- }
- }
- return MournbladeCYD2Utility.computeMonnaieDetails(valueSC)
- }
-
- /* -------------------------------------------- */
- getCompetence(compId) {
- return this.items.get(compId)
- }
-
- /* -------------------------------------------- */
- async setPredilectionUsed(compId, predIdx) {
- let comp = this.items.get(compId)
- let pred = foundry.utils.duplicate(comp.system.predilections)
- pred[predIdx].used = true
- await this.updateEmbeddedDocuments('Item', [{ _id: compId, 'system.predilections': pred }])
- }
-
- /* -------------------------------------------- */
- getInitiativeScore() {
- let init = this.getFlag("world", "last-initiative")
- return init || -1
- }
-
- /* -------------------------------------------- */
- getBestAttackValue() {
- let attackList = this.items.filter(item => (item.type == "arme" || item.type == "talent") && item.system.equipped)
- let maxOff = 0
- let bestArme
- for (let arme of attackList) {
- if (arme.type == "arme") {
- arme = this.prepareArme(arme)
- }
- if (arme.system.totalOffensif > maxOff) {
- maxOff = arme.system.totalOffensif
- bestArme = foundry.utils.duplicate(arme)
- }
- }
- return bestArme
- }
-
- /* -------------------------------------------- */
- getBestDefenseValue() {
- let defenseList = this.items.filter(item => (item.type == "arme") && item.system.equipped)
- let maxDef = 0
- let bestArme
- for (let arme of defenseList) {
- if (arme.type == "arme") {
- arme = this.prepareArme(arme)
- }
- if (arme.system.totalDefensif > maxDef) {
- maxDef = arme.system.totalDefensif
- bestArme = foundry.utils.duplicate(arme)
- }
- }
- return bestArme
- }
-
- /* -------------------------------------------- */
- searchRelevantTalents(competence) {
- let talents = []
-
- for (let talent of this.items) {
- if (talent.type == "talent" && talent.system.isautomated && talent.system.automations.length > 0) {
- for (let auto of talent.system.automations) {
- if (auto.eventtype === "prepare-roll") {
- if (auto.competence.toLowerCase() == competence.name.toLowerCase()) {
- talent = foundry.utils.duplicate(talent)
- talent.system.bonus = auto.bonus
- talent.system.baCost = auto.baCost
- talents.push(talent)
- }
- }
- }
- }
- }
- return talents
- }
-
- /* -------------------------------------------- */
- buildListeAdversites() {
- return []
- }
-
- /* -------------------------------------------- */
- getCommonRollData(attrKey = undefined, compId = undefined, compName = undefined) {
- let rollData = MournbladeCYD2Utility.getBasicRollData()
- rollData.alias = this.name
- rollData.actorImg = this.img
- rollData.actorId = this.id
- rollData.tokenId = this.token?.id
- rollData.img = this.img
- rollData.attributs = MournbladeCYD2Utility.getAttributs()
- rollData.maitriseId = "none"
- rollData.nbEclat = this.system.eclat.value
- rollData.nbBA = this.system.bonneaventure.actuelle
- rollData.nbAdversites = this.getTotalAdversite()
- rollData.talents = []
- rollData.attrKey2 = "none"
- rollData.coupDevastateur = this.items.find(it => it.type == "talent" && it.name.toLowerCase() == "coup dévastateur" && !it.system.used)
- rollData.hasAmbidextre = this.items.find(it => it.type == "talent" && it.name.toLowerCase() == "ambidextre")
- rollData.hasFeinte = this.system.bonneaventure.actuelle > 0 && this.items.find(it => it.type == "talent" && it.name.toLowerCase() == "feinte")
- rollData.isMonte = this.system.combat.monte
- rollData.config = game.system.mournbladecyd2.config
-
- if (attrKey) {
- rollData.attrKey = attrKey
- if (attrKey != "tochoose") {
- rollData.actionImg = "systems/fvtt-mournblade-cyd2/assets/icons/" + this.system.attributs[attrKey].labelnorm + ".webp"
- rollData.attr = foundry.utils.duplicate(this.system.attributs[attrKey])
- }
- }
- if (compId) {
- rollData.competence = foundry.utils.duplicate(this.items.get(compId) || {})
- let maitrises = [{ key: "none", label: "Aucune" }]
- rollData.competence.system.predilections.forEach(function (item) {
- if (item.maitrise) {
- maitrises.push({ key: item.id, label: item.name });
- }
- })
- rollData.maitrises = maitrises // rollData.competence.system.predilections.filter(p => p.maitrise)
- rollData.actionImg = rollData.competence?.img
- rollData.talents = this.searchRelevantTalents(rollData.competence)
- }
- if (compName) {
- rollData.competence = foundry.utils.duplicate(this.items.find(item => item.name.toLowerCase() == compName.toLowerCase()) || {})
- rollData.actionImg = rollData.competence?.img
- }
- return rollData
- }
-
- /* -------------------------------------------- */
- async rollAttribut(attrKey, isInit = false) {
- let rollData = this.getCommonRollData(attrKey)
- rollData.multiplier = (isInit) ? 1 : 2
- rollData.isInit = isInit
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
-
- /* -------------------------------------------- */
- async rollCompetence(attrKey, compId) {
- let rollData = this.getCommonRollData(attrKey, compId)
- rollData.multiplier = 1 // Attr multiplier, always 1 in competence mode
- console.log("RollDatra", rollData)
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
-
- /* -------------------------------------------- */
- async rollArmeOffensif(armeId) {
- let arme = this.items.get(armeId)
- if (arme.type == "arme") {
- arme = this.prepareArme(arme)
- }
- let rollData = this.getCommonRollData(arme.system.attrKey, arme.system.competence._id)
- rollData.arme = arme
- MournbladeCYD2Utility.updateWithTarget(rollData)
- console.log("ARME!", rollData)
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
- /* -------------------------------------------- */
- async rollAssommer() {
- let rollData = this.getCommonRollData("pui", undefined, "Filouterie")
- rollData.assomer = true
- rollData.conditionsCommunes = true
- MournbladeCYD2Utility.updateWithTarget(rollData)
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
- /* -------------------------------------------- */
- async rollCoupBas() {
- let rollData = this.getCommonRollData("pui", undefined, "Mêlée")
- rollData.coupBas = true
- rollData.conditionsCommunes = true
- MournbladeCYD2Utility.updateWithTarget(rollData)
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
- /* -------------------------------------------- */
- async rollImmobiliser() {
- let rollData = this.getCommonRollData("pui", undefined, "Mêlée")
- rollData.immobiliser = true
- rollData.conditionsCommunes = true
- rollData.cibleconsciente = true
- MournbladeCYD2Utility.updateWithTarget(rollData)
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
- /* -------------------------------------------- */
- async rollRepousser() {
- let rollData = this.getCommonRollData("pui", undefined, "Mêlée")
- rollData.repousser = true
- rollData.conditionsCommunes = true
- rollData.cibleconsciente = true
- MournbladeCYD2Utility.updateWithTarget(rollData)
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
- /* -------------------------------------------- */
- async rollDesengager() {
- let rollData = this.getCommonRollData("adr", undefined, "Mouvements")
- rollData.desengager = true
- rollData.conditionsCommunes = true
- MournbladeCYD2Utility.updateWithTarget(rollData)
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
-
- /* -------------------------------------------- */
- async rollArmeDegats(armeId, targetVigueur = undefined, rollDataInput = undefined) {
- let arme = this.items.get(armeId)
- if (arme.type == "arme") {
- arme = this.prepareArme(arme)
- }
- console.log("DEGATS", arme, targetVigueur, rollDataInput)
- let roll
- let bonus = 0
- let bonus2 = 0
-
- if (rollDataInput?.applyCoupDevastateur) {
- bonus2 = Math.floor(this.system.attributs.pui.value / 2)
- let talent = this.items.find(item => item.type == "talent" && item.name.toLowerCase() == "coup dévastateur")
- this.updateEmbeddedDocuments('Item', [{ _id: talent.id, 'system.used': true }])
- }
-
- if (rollDataInput?.isHeroique) {
- if (rollDataInput?.attaqueCharge) {
- bonus = 5
- }
- if (rollDataInput?.chargeCavalerie) {
- bonus = 6
- }
- roll = await new Roll("2d10rr10+" + arme.system.totalDegats + "+" + bonus + "+" + bonus2).roll()
- } else {
- if (rollDataInput?.attaqueCharge) {
- bonus = 3
- }
- if (rollDataInput?.chargeCavalerie) {
- bonus = 4
- }
- roll = await new Roll("1d10+" + arme.system.totalDegats + "+" + bonus + "+" + bonus2).roll()
- }
- await MournbladeCYD2Utility.showDiceSoNice(roll, game.settings.get("core", "rollMode"));
- let nbEtatPerdus = 0
- if (targetVigueur) {
- nbEtatPerdus = Math.floor(roll.total / targetVigueur)
- }
- //console.log(roll)
- let rollData = {
- arme: arme,
- finalResult: roll.total,
- formula: roll.formula,
- alias: this.name,
- actorImg: this.img,
- actorId: this.id,
- defenderTokenId: rollDataInput?.defenderTokenId,
- actionImg: arme.img,
- targetVigueur: targetVigueur,
- nbEtatPerdus: nbEtatPerdus
- }
- MournbladeCYD2Utility.createChatWithRollMode(rollData.alias, {
- content: await renderTemplate(`systems/fvtt-mournblade-cyd2/templates/chat-degats-result.html`, rollData)
- })
-
- if (rollDataInput?.defenderTokenId && nbEtatPerdus) {
- MournbladeCYD2Utility.applyCombativite(rollDataInput, nbEtatPerdus)
- }
-
- }
-}
diff --git a/.history/modules/mournblade-cyd2-actor_20251026084815.js b/.history/modules/mournblade-cyd2-actor_20251026084815.js
deleted file mode 100644
index b0b3dc0..0000000
--- a/.history/modules/mournblade-cyd2-actor_20251026084815.js
+++ /dev/null
@@ -1,908 +0,0 @@
-/* -------------------------------------------- */
-import { MournbladeCYD2Utility } from "./mournblade-cyd2-utility.js";
-import { MournbladeCYD2RollDialog } from "./mournblade-cyd2-roll-dialog.js";
-
-/* -------------------------------------------- */
-const __degatsBonus = [-2, -2, -1, -1, 0, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 8, 8, 9, 9, 10, 10]
-const __vitesseBonus = [-2, -2, -1, -1, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8]
-
-/* -------------------------------------------- */
-/**
- * Extend the base Actor entity by defining a custom roll data structure which is ideal for the Simple system.
- * @extends {Actor}
- */
-export class MournbladeCYD2Actor extends Actor {
-
- /* -------------------------------------------- */
- /**
- * Override the create() function to provide additional SoS functionality.
- *
- * This overrided create() function adds initial items
- * Namely: Basic skills, money,
- *
- * @param {Object} data Barebones actor data which this function adds onto.
- * @param {Object} options (Unused) Additional options which customize the creation workflow.
- *
- */
-
- static async create(data, options) {
-
- // Case of compendium global import
- if (data instanceof Array) {
- return super.create(data, options);
- }
- // If the created actor has items (only applicable to duplicated actors) bypass the new actor creation logic
- if (data.items) {
- let actor = super.create(data, options);
- return actor;
- }
-
- if (data.type == 'personnage') {
- const skills = await MournbladeCYD2Utility.loadCompendium("fvtt-mournblade-cyd2.skills")
- data.items = skills.map(i => i.toObject())
- }
- if (data.type == 'creature') {
- const skills = await MournbladeCYD2Utility.loadCompendium("fvtt-mournblade-cyd2.skills-creatures")
- data.items = skills.map(i => i.toObject())
- data.items.push({ name: "Arme naturelle 1", type: 'arme', img: "systems/fvtt-mournblade-cyd2/assets/icons/melee.webp", system: { typearme: "contact", bonusmaniementoff: 0, seuildefense: 0, degats: "0" } })
- data.items.push({ name: "Arme naturelle 2", type: 'arme', img: "systems/fvtt-mournblade-cyd2/assets/icons/melee.webp", system: { typearme: "contact", bonusmaniementoff: 0, seuildefense: 0, degats: "0" } })
- }
-
- return super.create(data, options);
- }
-
- /* -------------------------------------------- */
- getBonusDefenseFromTalents() {
- let talents = this.items.filter(item => item.type == "talent" && item.system.isautomated)
- let bonus = 0
- for (let talent of talents) {
- for (let auto of talent.system.automations) {
- if (auto.eventtype == "bonus-permanent" && auto.bonusname == "bonus-defensif") {
- bonus += Number(auto.bonus || 0)
- }
- }
- }
- return bonus
- }
-
- /* -------------------------------------------- */
- prepareArme(arme) {
- if (this.type == "cellule") {
- return arme
- }
-
- arme = foundry.utils.duplicate(arme)
- let combat = this.getCombatValues()
- if (arme.system.typearme == "contact" || arme.system.typearme == "contactjet") {
- let bonusDefense = this.getBonusDefenseFromTalents()
- arme.system.competence = foundry.utils.duplicate(this.items.find(item => item.type == "competence" && item.name.toLowerCase() == "mêlée"))
- arme.system.attrKey = "pui"
- arme.system.totalDegats = arme.system.degats + "+" + combat.bonusDegatsTotal
- arme.system.totalOffensif = this.system.attributs.pui.value + arme.system.competence.system.niveau + arme.system.bonusmaniementoff + (this.system.combat.monte ? 3 : 0)
- arme.system.totalDefensif = combat.defenseTotal + arme.system.competence.system.niveau + arme.system.seuildefense + bonusDefense + (this.system.combat.monte ? 3 : 0)
- console.log("Arme", arme.system.totalDefensif, combat, arme.system.competence.system.niveau, arme.system.seuildefense, bonusDefense)
- arme.system.isdefense = true
- arme.system.isMelee = true
- arme.system.isDistance = false
- }
- if (arme.system.typearme == "jet" || arme.system.typearme == "tir") {
- arme.system.competence = foundry.utils.duplicate(this.items.find(item => item.type == "competence" && item.name.toLowerCase() == "armes à distance"))
- arme.system.attrKey = "adr"
- arme.system.totalOffensif = this.system.attributs.adr.value + arme.system.competence.system.niveau + arme.system.bonusmaniementoff
- arme.system.totalDegats = arme.system.degats
- arme.system.isMelee = false
- arme.system.isDistance = true
- if (arme.system.isdefense) {
- arme.system.totalDefensif = combat.defenseTotal + arme.system.competence.system.niveau + arme.system.seuildefense
- }
- }
- return arme
- }
-
- /* -------------------------------------------- */
- getItemSorted(types) {
- let items = this.items.filter(item => types.includes(item.type)) || []
- MournbladeCYD2Utility.sortArrayObjectsByName(items)
- return items
- }
- getWeapons() {
- let armes = []
- for (let arme of this.items) {
- if (arme.type == "arme") {
- armes.push(this.prepareArme(arme))
- }
- }
- MournbladeCYD2Utility.sortArrayObjectsByName(armes)
- return armes
- }
- getMonnaies() {
- return this.getItemSorted(["monnaie"])
- }
- getEquipments() {
- return this.getItemSorted(["equipement"])
- }
- getArtefacts() {
- return this.getItemSorted(["artefact"])
- }
- getArmors() {
- return this.getItemSorted(["protection"])
- }
- getHistoriques() {
- return this.getItemSorted(["historique"])
- }
- getProfils() {
- return this.getItemSorted(["profil"])
- }
- getTalents() {
- return this.getItemSorted(["talent"])
- }
- getRessources() {
- return this.getItemSorted(["ressource"])
- }
- getContacts() {
- return this.getItemSorted(["contact"])
- }
- getMutations() {
- return this.getItemSorted(["mutation"])
- }
- getDons() {
- return this.getItemSorted(["don"])
- }
- getPactes() {
- return this.getItemSorted(["pacte"])
- }
- getTendances() {
- return this.getItemSorted(["tendance"])
- }
- getRunes() {
- return this.getItemSorted(["rune"])
- }
- getTraitsChaotiques() {
- return this.getItemSorted(["traitchaotique"])
- }
- getTraitsEspeces() {
- return this.getItemSorted(["traitespece"])
- }
-
- /* -------------------------------------------- */
- getAspect() {
- return (this.system.balance.loi > this.system.balance.chaos) ? this.system.balance.loi : this.system.balance.chaos
- }
- getMarge() {
- return Math.abs(this.system.balance.loi - this.system.balance.chaos)
- }
- getAlignement() {
- return (this.system.balance.loi > this.system.balance.chaos) ? "loyal" : "chaotique"
- }
-
- /* -------------------------------------------- */
- getSkills() {
- let comp = []
- for (let item of this.items) {
- item = foundry.utils.duplicate(item)
- if (item.type == "competence") {
- item.system.attribut1total = item.system.niveau + (this.system.attributs[item.system.attribut1]?.value || 0)
- item.system.attribut2total = item.system.niveau + (this.system.attributs[item.system.attribut2]?.value || 0)
- item.system.attribut3total = item.system.niveau + (this.system.attributs[item.system.attribut3]?.value || 0)
- if (item.system.niveau == 0) {
- item.system.attribut1total -= 3
- item.system.attribut2total -= 3
- item.system.attribut3total -= 3
- }
- item.system.attribut1label = this.system.attributs[item.system.attribut1]?.label || ""
- item.system.attribut2label = this.system.attributs[item.system.attribut2]?.label || ""
- item.system.attribut3label = this.system.attributs[item.system.attribut3]?.label || ""
- comp.push(item)
- }
- }
- MournbladeCYD2Utility.sortArrayObjectsByName(comp)
- return comp
- }
-
- /* ----------------------- --------------------- */
- addMember(actorId) {
- let members = foundry.utils.duplicate(this.system.members)
- members.push({ id: actorId })
- this.update({ 'system.members': members })
- }
- async removeMember(actorId) {
- let members = this.system.members.filter(it => it.id != actorId)
- this.update({ 'system.members': members })
- }
-
- /* -------------------------------------------- */
- getDefenseBase() {
- return Math.max(this.system.attributs.tre.value, this.system.attributs.adr.value)
- }
-
- /* -------------------------------------------- */
- getVitesseBase() {
- return 5 + __vitesseBonus[this.system.attributs.adr.value]
- }
- /* -------------------------------------------- */
- getProtection() {
- let equipProtection = 0
- for (let armor of this.items) {
- if (armor.type == "protection" && armor.system.equipped) {
- equipProtection += Number(armor.system.protection)
- }
- }
- if (equipProtection < 4) {
- return 4 + equipProtection // Cas des boucliers + sans armure
- }
- return equipProtection // Uniquement la protection des armures + boucliers
- }
-
- /* -------------------------------------------- */
- getCombatValues() {
- if (this.type == "cellule") {
- return {
- initBase: 0,
- initTotal: 0,
- bonusDegats: 0,
- bonusDegatsTotal: 0,
- vitesseBase: 0,
- vitesseTotal: 0,
- defenseBase: 0,
- protection: 0,
- defenseTotal: 0
- }
- }
-
- let combat = {
- initBase: this.system.attributs.adr.value,
- initTotal: this.system.attributs.adr.value + this.system.combat.initbonus,
- bonusDegats: this.getBonusDegats(),
- bonusDegatsTotal: this.getBonusDegats() + this.system.combat.bonusdegats,
- vitesseBase: this.getVitesseBase(),
- vitesseTotal: this.getVitesseBase() + this.system.combat.vitessebonus,
- defenseBase: this.getDefenseBase(),
- protection: this.getProtection(),
- defenseTotal: this.getDefenseBase() + this.system.combat.defensebonus + this.getProtection() - this.getTotalAdversite() + (this.system.combat.defensetotale ? 3 : 0)
- }
- return combat
- }
-
- /* -------------------------------------------- */
- prepareBaseData() {
- }
-
- /* -------------------------------------------- */
- async prepareData() {
- super.prepareData();
- }
-
- /* -------------------------------------------- */
- prepareDerivedData() {
-
- if (this.type == 'personnage') {
- let talentBonus = this.getVigueurBonus()
- let vigueur = Math.floor((this.system.attributs.pui.value + this.system.attributs.tre.value) / 2) + talentBonus + this.system.sante.vigueurmodifier
- if (vigueur != this.system.sante.vigueur) {
- this.update({ 'system.sante.vigueur': vigueur })
- }
-
- let seuilPouvoirBonus = this.getSeuilPouvoirBonus()
- let seuilPouvoir = Math.floor((this.system.attributs.tre.value + this.system.attributs.cla.value) / 2) + seuilPouvoirBonus + this.system.ame.seuilpouvoirmodifier
- if (seuilPouvoir != this.system.ame.seuilpouvoir) {
- this.update({ 'system.ame.seuilpouvoir': seuilPouvoir })
- }
- }
- super.prepareDerivedData()
- }
-
- /* -------------------------------------------- */
- _preUpdate(changed, options, user) {
- if (changed?.system?.sante?.etat && changed?.system?.sante?.etat != this.system.sante.etat) {
- setTimeout(() => {
- this.processCombativite(changed.system.sante)
- }, 800)
- }
- if (changed?.system?.ame?.etat && changed?.system?.ame?.etat != this.system.ame.etat) {
- // L'état d'Âme ne peut pas être inférieur au minimum (max dans le système)
- let minAme = this.system.ame.max !== undefined ? this.system.ame.max : 0
- if (changed.system.ame.etat < minAme) {
- changed.system.ame.etat = minAme
- }
- // L'état d'Âme ne peut pas dépasser nbame (Brisé)
- if (changed.system.ame.etat > this.system.ame.nbame) {
- changed.system.ame.etat = this.system.ame.nbame
- }
- setTimeout(() => {
- this.processAme(changed.system.ame)
- }, 800)
- }
- // Si le max d'Âme change, ajuster l'état actuel si nécessaire
- if (changed?.system?.ame?.max !== undefined && changed.system.ame.max != this.system.ame.max) {
- if (this.system.ame.etat < changed.system.ame.max) {
- changed.system.ame.etat = changed.system.ame.max
- }
- }
- super._preUpdate(changed, options, user);
- }
-
- /* -------------------------------------------- */
- _onUpdate(data, options, user) {
- super._onUpdate(data, options, user);
- }
- /* -------------------------------------------- */
- getItemById(id) {
- let item = this.items.find(item => item.id == id);
- if (item) {
- item = foundry.utils.duplicate(item)
- }
- return item;
- }
-
- /* -------------------------------------------- */
- async equipItem(itemId) {
- let item = this.items.find(item => item.id == itemId)
- if (item && item.system) {
- let update = { _id: item.id, "system.equipped": !item.system.equipped }
- await this.updateEmbeddedDocuments('Item', [update]); // Updates one EmbeddedEntity
- }
- }
-
- /* -------------------------------------------- */
- editItemField(itemId, itemType, itemField, dataType, value) {
- let item = this.items.find(item => item.id == itemId)
- if (item) {
- console.log("Item ", item, itemField, dataType, value)
- if (dataType.toLowerCase() == "number") {
- value = Number(value)
- } else {
- value = String(value)
- }
- let update = { _id: item.id, [`system.${itemField}`]: value };
- this.updateEmbeddedDocuments("Item", [update])
- }
- }
-
- /* -------------------------------------------- */
- checkAttribut(attribut, minLevel) {
- let attr = this.system.attributs.find(at => at.labelnorm == attribut.toLowerCase())
- if (attr && attr.value >= minLevel) {
- return { isValid: true, attr: foundry.utils.duplicate(attr) }
- }
- return { isValid: false }
- }
- /* -------------------------------------------- */
- checkAttributOrCompetenceLevel(compName, minLevel) {
- let comp = this.items.find(i => i.type == "competence" && i.name.toLowerCase() == compName.toLowerCase() && i.system.niveau >= minLevel)
- if (comp) {
- return { isValid: true, item: foundry.utils.duplicate(comp) }
- } else {
- for (let attrKey in this.system.attributs) {
- if (this.system.attributs[attrKey].label.toLowerCase() == compName.toLowerCase() && this.system.attributs[attrKey].value >= minLevel) {
- return { isValid: true, item: foundry.utils.duplicate(this.system.attributs[attrKey]) }
- }
- }
- }
- return { isValid: false, warningMessage: `Prérequis insuffisant : la compétence/attribut ${compName} doit être de niveau ${minLevel} au minimum` }
- }
- /* -------------------------------------------- */
- addCompetenceBonus(compName, bonus, baCost) {
- let comp = this.items.find(i => i.type == "competence" && i.name.toLowerCase() == compName.toLowerCase())
- if (comp) {
- comp = foundry.utils.duplicate(comp)
- comp.system.bonus = bonus
- comp.system.baCost = baCost
- return { isValid: true, item: comp }
- }
- return { isValid: false, warningMessage: `Compétence ${compName} non trouvée` }
- }
- /* -------------------------------------------- */
- checkIfCompetence(compName) {
- let comp = this.items.find(i => i.type == "competence" && i.name.toLowerCase() == compName.toLowerCase())
- if (comp) {
- return { isValid: true, item: comp }
- }
- return { isValid: false }
- }
- /* -------------------------------------------- */
- getVigueur() {
- return this.system.sante.vigueur
- }
-
- /* -------------------------------------------- */
- getVigueurBonus() {
- let talents = this.items.filter(item => item.type == "talent" && item.system.isautomated)
- let bonus = 0
- for (let talent of talents) {
- for (let auto of talent.system.automations) {
- if (auto.eventtype == "bonus-permanent" && auto.bonusname == "vigueur") {
- bonus += Number(auto.bonus || 0)
- }
- }
- }
- return bonus
- }
-
- /* -------------------------------------------- */
- getSeuilPouvoir() {
- return this.system.ame.seuilpouvoir
- }
-
- /* -------------------------------------------- */
- getSeuilPouvoirBonus() {
- let talents = this.items.filter(item => item.type == "talent" && item.system.isautomated)
- let bonus = 0
- for (let talent of talents) {
- for (let auto of talent.system.automations) {
- if (auto.eventtype == "bonus-permanent" && auto.bonusname == "seuilpouvoir") {
- bonus += Number(auto.bonus || 0)
- }
- }
- }
- return bonus
- }
-
- /* -------------------------------------------- */
- getAmeMax() {
- // Utiliser une vérification stricte car 0 (Serein) est une valeur valide
- return this.system.ame.max !== undefined ? this.system.ame.max : this.system.ame.nbame
- }
-
- /* -------------------------------------------- */
- getBonneAventure() {
- return this.system.bonneaventure.actuelle
- }
- /* -------------------------------------------- */
- checkBonneAventure(cost) {
- return (this.system.bonneaventure.actuelle >= cost)
- }
- /* -------------------------------------------- */
- changeBonneAventure(value) {
- let newBA = this.system.bonneaventure.actuelle
- newBA += value
- this.update({ 'system.bonneaventure.actuelle': newBA })
- }
-
- /* -------------------------------------------- */
- getEclat() {
- return this.system.eclat.value
- }
-
- /* -------------------------------------------- */
- changeEclat(value) {
- let newE = this.system.eclat.value
- newE += value
- this.update({ 'system.eclat.value': newE })
- }
-
- /* -------------------------------------------- */
- compareName(a, b) {
- if (a.name < b.name) {
- return -1;
- }
- if (a.name > b.name) {
- return 1;
- }
- return 0;
- }
-
- /* -------------------------------------------- */
- getAttribute(attrKey) {
- return this.system.attributes[attrKey]
- }
-
- /* -------------------------------------------- */
- getBonusDegats() {
- return 0;
- }
-
- /* -------------------------------------------- */
- changeEtatCombativite(value) {
- if (value === "vaincu") {
- value = 200
- }
- let sante = foundry.utils.duplicate(this.system.sante)
- sante.etat += Number(value)
- sante.etat = Math.max(sante.etat, 0)
- sante.etat = Math.min(sante.etat, this.system.sante.nbcombativite)
- this.update({ 'system.sante': sante })
- if (sante.etat == this.system.sante.nbcombativite) {
- ChatMessage.create({ content: `${this.name} est vaincu !` })
- }
- // Duplicated ! this.processCombativite(sante)
- }
-
- /* -------------------------------------------- */
- changeEtatAme(value) {
- if (value === "brise") {
- value = 200
- }
- let ame = foundry.utils.duplicate(this.system.ame)
- ame.etat += Number(value)
- // L'état ne peut pas être inférieur au minimum (max dans le système)
- let minAme = this.system.ame.max !== undefined ? this.system.ame.max : 0
- ame.etat = Math.max(ame.etat, minAme)
- // L'état ne peut pas dépasser nbame (Brisé)
- ame.etat = Math.min(ame.etat, this.system.ame.nbame)
- this.update({ 'system.ame': ame })
- if (ame.etat >= this.system.ame.nbame) {
- ChatMessage.create({ content: `${this.name} est brisé !` })
- }
- }
-
- /* -------------------------------------------- */
- processCombativite(sante) {
- sante = sante || foundry.utils.duplicate(this.system.sante)
- // Gestion des états affaibli et très affaibli
- if (sante.etat == this.system.sante.nbcombativite - 2 || sante.etat == this.system.sante.nbcombativite - 1) {
- if (sante.etat == this.system.sante.nbcombativite - 2 && this.items.find(item => item.type == "talent" && item.name.toLowerCase() == "encaissement")) {
- ChatMessage.create({ content: `${this.name} ne subit pas les 2 adversités rouge grâce à Encaissement. Pensez à les ajouter à la fin de la scène !` })
- } else if (sante.etat == this.system.sante.nbcombativite - 1 && this.items.find(item => item.type == "talent" && item.name.toLowerCase().includes("vaillant"))) {
- ChatMessage.create({ content: `${this.name} ne subit pas les 2 adversités rouge grâce à Vaillant. Pensez à les ajouter à la fin de la scène !` })
- } else {
- ChatMessage.create({ content: `${this.name} subit 2 adversités rouge !` })
- this.incDecAdversite("rouge", 2)
- }
- }
- }
-
- /* -------------------------------------------- */
- processAme(ame) {
- ame = ame || foundry.utils.duplicate(this.system.ame)
- let traumatiseValue = this.system.ame.nbame - 2
- let tresTraumatiseValue = this.system.ame.nbame - 1
- let briseValue = this.system.ame.nbame
-
- // Gestion des états Traumatisé, Très Traumatisé et Brisé
- if (ame.etat == traumatiseValue) {
- ChatMessage.create({ content: `${this.name} est Traumatisé !` })
- } else if (ame.etat == tresTraumatiseValue) {
- ChatMessage.create({ content: `${this.name} est Très Traumatisé !` })
- } else if (ame.etat >= briseValue) {
- ChatMessage.create({ content: `${this.name} est Brisé !` })
- }
- }
-
- /* -------------------------------------------- */
- async equipGear(equipmentId) {
- let item = this.items.find(item => item.id == equipmentId);
- if (item?.system?.data) {
- let update = { _id: item.id, "system.equipped": !item.system.equipped };
- await this.updateEmbeddedDocuments('Item', [update]); // Updates one EmbeddedEntity
- }
- }
-
- /* -------------------------------------------- */
- getSubActors() {
- let subActors = [];
- for (let id of this.system.subactors) {
- subActors.push(foundry.utils.duplicate(game.actors.get(id)));
- }
- return subActors;
- }
- /* -------------------------------------------- */
- async addSubActor(subActorId) {
- let subActors = foundry.utils.duplicate(this.system.subactors);
- subActors.push(subActorId);
- await this.update({ 'system.subactors': subActors });
- }
- /* -------------------------------------------- */
- async delSubActor(subActorId) {
- let newArray = [];
- for (let id of this.system.subactors) {
- if (id != subActorId) {
- newArray.push(id);
- }
- }
- await this.update({ 'system.subactors': newArray });
- }
-
- /* -------------------------------------------- */
- getTotalAdversite() {
- return this.system.adversite.bleue + this.system.adversite.rouge + this.system.adversite.noire
- }
-
- /* -------------------------------------------- */
- async incDecAdversite(adv, incDec = 0) {
- let adversite = foundry.utils.duplicate(this.system.adversite)
- adversite[adv] += Number(incDec)
- adversite[adv] = Math.max(adversite[adv], 0)
- adversite[adv] = Math.min(adversite[adv], 20)
- this.update({ 'system.adversite': adversite })
- }
- /* -------------------------------------------- */
- async incDecQuantity(objetId, incDec = 0) {
- let objetQ = this.items.get(objetId)
- if (objetQ) {
- let newQ = objetQ.system.quantite + incDec
- newQ = Math.max(newQ, 0)
- await this.updateEmbeddedDocuments('Item', [{ _id: objetQ.id, 'system.quantite': newQ }]); // pdates one EmbeddedEntity
- }
- }
-
- /* -------------------------------------------- */
- computeRichesse() {
- let valueSC = 0
- for (let monnaie of this.items) {
- if (monnaie.type == "monnaie") {
- valueSC += Number(monnaie.system.prixsc) * Number(monnaie.system.quantite)
- }
- }
- return MournbladeCYD2Utility.computeMonnaieDetails(valueSC)
- }
-
- /* -------------------------------------------- */
- computeValeurEquipement() {
- let valueSC = 0
- for (let equip of this.items) {
- if (equip.type == "equipement" || equip.type == "arme" || equip.type == "protection") {
- valueSC += Number(equip.system.prixsc) * Number(equip.system.quantite ?? 1)
- valueSC += (Number(equip.system.prixca) * Number(equip.system.quantite ?? 1)) * 20
- valueSC += (Number(equip.system.prixpo) * Number(equip.system.quantite ?? 1)) * 400
- }
- }
- return MournbladeCYD2Utility.computeMonnaieDetails(valueSC)
- }
-
- /* -------------------------------------------- */
- getCompetence(compId) {
- return this.items.get(compId)
- }
-
- /* -------------------------------------------- */
- async setPredilectionUsed(compId, predIdx) {
- let comp = this.items.get(compId)
- let pred = foundry.utils.duplicate(comp.system.predilections)
- pred[predIdx].used = true
- await this.updateEmbeddedDocuments('Item', [{ _id: compId, 'system.predilections': pred }])
- }
-
- /* -------------------------------------------- */
- getInitiativeScore() {
- let init = this.getFlag("world", "last-initiative")
- return init || -1
- }
-
- /* -------------------------------------------- */
- getBestAttackValue() {
- let attackList = this.items.filter(item => (item.type == "arme" || item.type == "talent") && item.system.equipped)
- let maxOff = 0
- let bestArme
- for (let arme of attackList) {
- if (arme.type == "arme") {
- arme = this.prepareArme(arme)
- }
- if (arme.system.totalOffensif > maxOff) {
- maxOff = arme.system.totalOffensif
- bestArme = foundry.utils.duplicate(arme)
- }
- }
- return bestArme
- }
-
- /* -------------------------------------------- */
- getBestDefenseValue() {
- let defenseList = this.items.filter(item => (item.type == "arme") && item.system.equipped)
- let maxDef = 0
- let bestArme
- for (let arme of defenseList) {
- if (arme.type == "arme") {
- arme = this.prepareArme(arme)
- }
- if (arme.system.totalDefensif > maxDef) {
- maxDef = arme.system.totalDefensif
- bestArme = foundry.utils.duplicate(arme)
- }
- }
- return bestArme
- }
-
- /* -------------------------------------------- */
- searchRelevantTalents(competence) {
- let talents = []
-
- for (let talent of this.items) {
- if (talent.type == "talent" && talent.system.isautomated && talent.system.automations.length > 0) {
- for (let auto of talent.system.automations) {
- if (auto.eventtype === "prepare-roll") {
- if (auto.competence.toLowerCase() == competence.name.toLowerCase()) {
- talent = foundry.utils.duplicate(talent)
- talent.system.bonus = auto.bonus
- talent.system.baCost = auto.baCost
- talents.push(talent)
- }
- }
- }
- }
- }
- return talents
- }
-
- /* -------------------------------------------- */
- buildListeAdversites() {
- return []
- }
-
- /* -------------------------------------------- */
- getCommonRollData(attrKey = undefined, compId = undefined, compName = undefined) {
- let rollData = MournbladeCYD2Utility.getBasicRollData()
- rollData.alias = this.name
- rollData.actorImg = this.img
- rollData.actorId = this.id
- rollData.tokenId = this.token?.id
- rollData.img = this.img
- rollData.attributs = MournbladeCYD2Utility.getAttributs()
- rollData.maitriseId = "none"
- rollData.nbEclat = this.system.eclat.value
- rollData.nbBA = this.system.bonneaventure.actuelle
- rollData.nbAdversites = this.getTotalAdversite()
- rollData.talents = []
- rollData.attrKey2 = "none"
- rollData.coupDevastateur = this.items.find(it => it.type == "talent" && it.name.toLowerCase() == "coup dévastateur" && !it.system.used)
- rollData.hasAmbidextre = this.items.find(it => it.type == "talent" && it.name.toLowerCase() == "ambidextre")
- rollData.hasFeinte = this.system.bonneaventure.actuelle > 0 && this.items.find(it => it.type == "talent" && it.name.toLowerCase() == "feinte")
- rollData.isMonte = this.system.combat.monte
- rollData.config = game.system.mournbladecyd2.config
-
- if (attrKey) {
- rollData.attrKey = attrKey
- if (attrKey != "tochoose") {
- rollData.actionImg = "systems/fvtt-mournblade-cyd2/assets/icons/" + this.system.attributs[attrKey].labelnorm + ".webp"
- rollData.attr = foundry.utils.duplicate(this.system.attributs[attrKey])
- }
- }
- if (compId) {
- rollData.competence = foundry.utils.duplicate(this.items.get(compId) || {})
- let maitrises = [{ key: "none", label: "Aucune" }]
- rollData.competence.system.predilections.forEach(function (item) {
- if (item.maitrise) {
- maitrises.push({ key: item.id, label: item.name });
- }
- })
- rollData.maitrises = maitrises // rollData.competence.system.predilections.filter(p => p.maitrise)
- rollData.actionImg = rollData.competence?.img
- rollData.talents = this.searchRelevantTalents(rollData.competence)
- }
- if (compName) {
- rollData.competence = foundry.utils.duplicate(this.items.find(item => item.name.toLowerCase() == compName.toLowerCase()) || {})
- rollData.actionImg = rollData.competence?.img
- }
- return rollData
- }
-
- /* -------------------------------------------- */
- async rollAttribut(attrKey, isInit = false) {
- let rollData = this.getCommonRollData(attrKey)
- rollData.multiplier = (isInit) ? 1 : 2
- rollData.isInit = isInit
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
-
- /* -------------------------------------------- */
- async rollCompetence(attrKey, compId) {
- let rollData = this.getCommonRollData(attrKey, compId)
- rollData.multiplier = 1 // Attr multiplier, always 1 in competence mode
- console.log("RollDatra", rollData)
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
-
- /* -------------------------------------------- */
- async rollArmeOffensif(armeId) {
- let arme = this.items.get(armeId)
- if (arme.type == "arme") {
- arme = this.prepareArme(arme)
- }
- let rollData = this.getCommonRollData(arme.system.attrKey, arme.system.competence._id)
- rollData.arme = arme
- MournbladeCYD2Utility.updateWithTarget(rollData)
- console.log("ARME!", rollData)
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
- /* -------------------------------------------- */
- async rollAssommer() {
- let rollData = this.getCommonRollData("pui", undefined, "Filouterie")
- rollData.assomer = true
- rollData.conditionsCommunes = true
- MournbladeCYD2Utility.updateWithTarget(rollData)
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
- /* -------------------------------------------- */
- async rollCoupBas() {
- let rollData = this.getCommonRollData("pui", undefined, "Mêlée")
- rollData.coupBas = true
- rollData.conditionsCommunes = true
- MournbladeCYD2Utility.updateWithTarget(rollData)
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
- /* -------------------------------------------- */
- async rollImmobiliser() {
- let rollData = this.getCommonRollData("pui", undefined, "Mêlée")
- rollData.immobiliser = true
- rollData.conditionsCommunes = true
- rollData.cibleconsciente = true
- MournbladeCYD2Utility.updateWithTarget(rollData)
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
- /* -------------------------------------------- */
- async rollRepousser() {
- let rollData = this.getCommonRollData("pui", undefined, "Mêlée")
- rollData.repousser = true
- rollData.conditionsCommunes = true
- rollData.cibleconsciente = true
- MournbladeCYD2Utility.updateWithTarget(rollData)
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
- /* -------------------------------------------- */
- async rollDesengager() {
- let rollData = this.getCommonRollData("adr", undefined, "Mouvements")
- rollData.desengager = true
- rollData.conditionsCommunes = true
- MournbladeCYD2Utility.updateWithTarget(rollData)
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
-
- /* -------------------------------------------- */
- async rollArmeDegats(armeId, targetVigueur = undefined, rollDataInput = undefined) {
- let arme = this.items.get(armeId)
- if (arme.type == "arme") {
- arme = this.prepareArme(arme)
- }
- console.log("DEGATS", arme, targetVigueur, rollDataInput)
- let roll
- let bonus = 0
- let bonus2 = 0
-
- if (rollDataInput?.applyCoupDevastateur) {
- bonus2 = Math.floor(this.system.attributs.pui.value / 2)
- let talent = this.items.find(item => item.type == "talent" && item.name.toLowerCase() == "coup dévastateur")
- this.updateEmbeddedDocuments('Item', [{ _id: talent.id, 'system.used': true }])
- }
-
- if (rollDataInput?.isHeroique) {
- if (rollDataInput?.attaqueCharge) {
- bonus = 5
- }
- if (rollDataInput?.chargeCavalerie) {
- bonus = 6
- }
- roll = await new Roll("2d10rr10+" + arme.system.totalDegats + "+" + bonus + "+" + bonus2).roll()
- } else {
- if (rollDataInput?.attaqueCharge) {
- bonus = 3
- }
- if (rollDataInput?.chargeCavalerie) {
- bonus = 4
- }
- roll = await new Roll("1d10+" + arme.system.totalDegats + "+" + bonus + "+" + bonus2).roll()
- }
- await MournbladeCYD2Utility.showDiceSoNice(roll, game.settings.get("core", "rollMode"));
- let nbEtatPerdus = 0
- if (targetVigueur) {
- nbEtatPerdus = Math.floor(roll.total / targetVigueur)
- }
- //console.log(roll)
- let rollData = {
- arme: arme,
- finalResult: roll.total,
- formula: roll.formula,
- alias: this.name,
- actorImg: this.img,
- actorId: this.id,
- defenderTokenId: rollDataInput?.defenderTokenId,
- actionImg: arme.img,
- targetVigueur: targetVigueur,
- nbEtatPerdus: nbEtatPerdus
- }
- MournbladeCYD2Utility.createChatWithRollMode(rollData.alias, {
- content: await renderTemplate(`systems/fvtt-mournblade-cyd2/templates/chat-degats-result.html`, rollData)
- })
-
- if (rollDataInput?.defenderTokenId && nbEtatPerdus) {
- MournbladeCYD2Utility.applyCombativite(rollDataInput, nbEtatPerdus)
- }
-
- }
-}
diff --git a/.history/modules/mournblade-cyd2-actor_20251026095752.js b/.history/modules/mournblade-cyd2-actor_20251026095752.js
deleted file mode 100644
index 3660760..0000000
--- a/.history/modules/mournblade-cyd2-actor_20251026095752.js
+++ /dev/null
@@ -1,904 +0,0 @@
-/* -------------------------------------------- */
-import { MournbladeCYD2Utility } from "./mournblade-cyd2-utility.js";
-import { MournbladeCYD2RollDialog } from "./mournblade-cyd2-roll-dialog.js";
-
-/* -------------------------------------------- */
-const __degatsBonus = [-2, -2, -1, -1, 0, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 8, 8, 9, 9, 10, 10]
-const __vitesseBonus = [-2, -2, -1, -1, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8]
-
-/* -------------------------------------------- */
-/**
- * Extend the base Actor entity by defining a custom roll data structure which is ideal for the Simple system.
- * @extends {Actor}
- */
-export class MournbladeCYD2Actor extends Actor {
-
- /* -------------------------------------------- */
- /**
- * Override the create() function to provide additional SoS functionality.
- *
- * This overrided create() function adds initial items
- * Namely: Basic skills, money,
- *
- * @param {Object} data Barebones actor data which this function adds onto.
- * @param {Object} options (Unused) Additional options which customize the creation workflow.
- *
- */
-
- static async create(data, options) {
-
- // Case of compendium global import
- if (data instanceof Array) {
- return super.create(data, options);
- }
- // If the created actor has items (only applicable to duplicated actors) bypass the new actor creation logic
- if (data.items) {
- let actor = super.create(data, options);
- return actor;
- }
-
- if (data.type == 'personnage') {
- const skills = await MournbladeCYD2Utility.loadCompendium("fvtt-mournblade-cyd2.skills")
- data.items = skills.map(i => i.toObject())
- }
- if (data.type == 'creature') {
- const skills = await MournbladeCYD2Utility.loadCompendium("fvtt-mournblade-cyd2.skills-creatures")
- data.items = skills.map(i => i.toObject())
- data.items.push({ name: "Arme naturelle 1", type: 'arme', img: "systems/fvtt-mournblade-cyd2/assets/icons/melee.webp", system: { typearme: "contact", bonusmaniementoff: 0, seuildefense: 0, degats: "0" } })
- data.items.push({ name: "Arme naturelle 2", type: 'arme', img: "systems/fvtt-mournblade-cyd2/assets/icons/melee.webp", system: { typearme: "contact", bonusmaniementoff: 0, seuildefense: 0, degats: "0" } })
- }
-
- return super.create(data, options);
- }
-
- /* -------------------------------------------- */
- getBonusDefenseFromTalents() {
- let talents = this.items.filter(item => item.type == "talent" && item.system.isautomated)
- let bonus = 0
- for (let talent of talents) {
- for (let auto of talent.system.automations) {
- if (auto.eventtype == "bonus-permanent" && auto.bonusname == "bonus-defensif") {
- bonus += Number(auto.bonus || 0)
- }
- }
- }
- return bonus
- }
-
- /* -------------------------------------------- */
- prepareArme(arme) {
- arme = foundry.utils.duplicate(arme)
- let combat = this.getCombatValues()
- if (arme.system.typearme == "contact" || arme.system.typearme == "contactjet") {
- let bonusDefense = this.getBonusDefenseFromTalents()
- arme.system.competence = foundry.utils.duplicate(this.items.find(item => item.type == "competence" && item.name.toLowerCase() == "mêlée"))
- arme.system.attrKey = "pui"
- arme.system.totalDegats = arme.system.degats + "+" + combat.bonusDegatsTotal
- arme.system.totalOffensif = this.system.attributs.pui.value + arme.system.competence.system.niveau + arme.system.bonusmaniementoff + (this.system.combat.monte ? 3 : 0)
- arme.system.totalDefensif = combat.defenseTotal + arme.system.competence.system.niveau + arme.system.seuildefense + bonusDefense + (this.system.combat.monte ? 3 : 0)
- console.log("Arme", arme.system.totalDefensif, combat, arme.system.competence.system.niveau, arme.system.seuildefense, bonusDefense)
- arme.system.isdefense = true
- arme.system.isMelee = true
- arme.system.isDistance = false
- }
- if (arme.system.typearme == "jet" || arme.system.typearme == "tir") {
- arme.system.competence = foundry.utils.duplicate(this.items.find(item => item.type == "competence" && item.name.toLowerCase() == "armes à distance"))
- arme.system.attrKey = "adr"
- arme.system.totalOffensif = this.system.attributs.adr.value + arme.system.competence.system.niveau + arme.system.bonusmaniementoff
- arme.system.totalDegats = arme.system.degats
- arme.system.isMelee = false
- arme.system.isDistance = true
- if (arme.system.isdefense) {
- arme.system.totalDefensif = combat.defenseTotal + arme.system.competence.system.niveau + arme.system.seuildefense
- }
- }
- return arme
- }
-
- /* -------------------------------------------- */
- getItemSorted(types) {
- let items = this.items.filter(item => types.includes(item.type)) || []
- MournbladeCYD2Utility.sortArrayObjectsByName(items)
- return items
- }
- getWeapons() {
- let armes = []
- for (let arme of this.items) {
- if (arme.type == "arme") {
- armes.push(this.prepareArme(arme))
- }
- }
- MournbladeCYD2Utility.sortArrayObjectsByName(armes)
- return armes
- }
- getMonnaies() {
- return this.getItemSorted(["monnaie"])
- }
- getEquipments() {
- return this.getItemSorted(["equipement"])
- }
- getArtefacts() {
- return this.getItemSorted(["artefact"])
- }
- getArmors() {
- return this.getItemSorted(["protection"])
- }
- getHistoriques() {
- return this.getItemSorted(["historique"])
- }
- getProfils() {
- return this.getItemSorted(["profil"])
- }
- getTalents() {
- return this.getItemSorted(["talent"])
- }
- getRessources() {
- return this.getItemSorted(["ressource"])
- }
- getContacts() {
- return this.getItemSorted(["contact"])
- }
- getMutations() {
- return this.getItemSorted(["mutation"])
- }
- getDons() {
- return this.getItemSorted(["don"])
- }
- getPactes() {
- return this.getItemSorted(["pacte"])
- }
- getTendances() {
- return this.getItemSorted(["tendance"])
- }
- getRunes() {
- return this.getItemSorted(["rune"])
- }
- getTraitsChaotiques() {
- return this.getItemSorted(["traitchaotique"])
- }
- getTraitsEspeces() {
- return this.getItemSorted(["traitespece"])
- }
-
- /* -------------------------------------------- */
- getAspect() {
- return (this.system.balance.loi > this.system.balance.chaos) ? this.system.balance.loi : this.system.balance.chaos
- }
- getMarge() {
- return Math.abs(this.system.balance.loi - this.system.balance.chaos)
- }
- getAlignement() {
- return (this.system.balance.loi > this.system.balance.chaos) ? "loyal" : "chaotique"
- }
-
- /* -------------------------------------------- */
- getSkills() {
- let comp = []
- for (let item of this.items) {
- item = foundry.utils.duplicate(item)
- if (item.type == "competence") {
- item.system.attribut1total = item.system.niveau + (this.system.attributs[item.system.attribut1]?.value || 0)
- item.system.attribut2total = item.system.niveau + (this.system.attributs[item.system.attribut2]?.value || 0)
- item.system.attribut3total = item.system.niveau + (this.system.attributs[item.system.attribut3]?.value || 0)
- if (item.system.niveau == 0) {
- item.system.attribut1total -= 3
- item.system.attribut2total -= 3
- item.system.attribut3total -= 3
- }
- item.system.attribut1label = this.system.attributs[item.system.attribut1]?.label || ""
- item.system.attribut2label = this.system.attributs[item.system.attribut2]?.label || ""
- item.system.attribut3label = this.system.attributs[item.system.attribut3]?.label || ""
- comp.push(item)
- }
- }
- MournbladeCYD2Utility.sortArrayObjectsByName(comp)
- return comp
- }
-
- /* ----------------------- --------------------- */
- addMember(actorId) {
- let members = foundry.utils.duplicate(this.system.members)
- members.push({ id: actorId })
- this.update({ 'system.members': members })
- }
- async removeMember(actorId) {
- let members = this.system.members.filter(it => it.id != actorId)
- this.update({ 'system.members': members })
- }
-
- /* -------------------------------------------- */
- getDefenseBase() {
- return Math.max(this.system.attributs.tre.value, this.system.attributs.adr.value)
- }
-
- /* -------------------------------------------- */
- getVitesseBase() {
- return 5 + __vitesseBonus[this.system.attributs.adr.value]
- }
- /* -------------------------------------------- */
- getProtection() {
- let equipProtection = 0
- for (let armor of this.items) {
- if (armor.type == "protection" && armor.system.equipped) {
- equipProtection += Number(armor.system.protection)
- }
- }
- if (equipProtection < 4) {
- return 4 + equipProtection // Cas des boucliers + sans armure
- }
- return equipProtection // Uniquement la protection des armures + boucliers
- }
-
- /* -------------------------------------------- */
- getCombatValues() {
- if (this.type == "cellule") {
- return {
- initBase: 0,
- initTotal: 0,
- bonusDegats: 0,
- bonusDegatsTotal: 0,
- vitesseBase: 0,
- vitesseTotal: 0,
- defenseBase: 0,
- protection: 0,
- defenseTotal: 0
- }
- }
-
- let combat = {
- initBase: this.system.attributs.adr.value,
- initTotal: this.system.attributs.adr.value + this.system.combat.initbonus,
- bonusDegats: this.getBonusDegats(),
- bonusDegatsTotal: this.getBonusDegats() + this.system.combat.bonusdegats,
- vitesseBase: this.getVitesseBase(),
- vitesseTotal: this.getVitesseBase() + this.system.combat.vitessebonus,
- defenseBase: this.getDefenseBase(),
- protection: this.getProtection(),
- defenseTotal: this.getDefenseBase() + this.system.combat.defensebonus + this.getProtection() - this.getTotalAdversite() + (this.system.combat.defensetotale ? 3 : 0)
- }
- return combat
- }
-
- /* -------------------------------------------- */
- prepareBaseData() {
- }
-
- /* -------------------------------------------- */
- async prepareData() {
- super.prepareData();
- }
-
- /* -------------------------------------------- */
- prepareDerivedData() {
-
- if (this.type == 'personnage') {
- let talentBonus = this.getVigueurBonus()
- let vigueur = Math.floor((this.system.attributs.pui.value + this.system.attributs.tre.value) / 2) + talentBonus + this.system.sante.vigueurmodifier
- if (vigueur != this.system.sante.vigueur) {
- this.update({ 'system.sante.vigueur': vigueur })
- }
-
- let seuilPouvoirBonus = this.getSeuilPouvoirBonus()
- let seuilPouvoir = Math.floor((this.system.attributs.tre.value + this.system.attributs.cla.value) / 2) + seuilPouvoirBonus + this.system.ame.seuilpouvoirmodifier
- if (seuilPouvoir != this.system.ame.seuilpouvoir) {
- this.update({ 'system.ame.seuilpouvoir': seuilPouvoir })
- }
- }
- super.prepareDerivedData()
- }
-
- /* -------------------------------------------- */
- _preUpdate(changed, options, user) {
- if (changed?.system?.sante?.etat && changed?.system?.sante?.etat != this.system.sante.etat) {
- setTimeout(() => {
- this.processCombativite(changed.system.sante)
- }, 800)
- }
- if (changed?.system?.ame?.etat && changed?.system?.ame?.etat != this.system.ame.etat) {
- // L'état d'Âme ne peut pas être inférieur au minimum (max dans le système)
- let minAme = this.system.ame.max !== undefined ? this.system.ame.max : 0
- if (changed.system.ame.etat < minAme) {
- changed.system.ame.etat = minAme
- }
- // L'état d'Âme ne peut pas dépasser nbame (Brisé)
- if (changed.system.ame.etat > this.system.ame.nbame) {
- changed.system.ame.etat = this.system.ame.nbame
- }
- setTimeout(() => {
- this.processAme(changed.system.ame)
- }, 800)
- }
- // Si le max d'Âme change, ajuster l'état actuel si nécessaire
- if (changed?.system?.ame?.max !== undefined && changed.system.ame.max != this.system.ame.max) {
- if (this.system.ame.etat < changed.system.ame.max) {
- changed.system.ame.etat = changed.system.ame.max
- }
- }
- super._preUpdate(changed, options, user);
- }
-
- /* -------------------------------------------- */
- _onUpdate(data, options, user) {
- super._onUpdate(data, options, user);
- }
- /* -------------------------------------------- */
- getItemById(id) {
- let item = this.items.find(item => item.id == id);
- if (item) {
- item = foundry.utils.duplicate(item)
- }
- return item;
- }
-
- /* -------------------------------------------- */
- async equipItem(itemId) {
- let item = this.items.find(item => item.id == itemId)
- if (item && item.system) {
- let update = { _id: item.id, "system.equipped": !item.system.equipped }
- await this.updateEmbeddedDocuments('Item', [update]); // Updates one EmbeddedEntity
- }
- }
-
- /* -------------------------------------------- */
- editItemField(itemId, itemType, itemField, dataType, value) {
- let item = this.items.find(item => item.id == itemId)
- if (item) {
- console.log("Item ", item, itemField, dataType, value)
- if (dataType.toLowerCase() == "number") {
- value = Number(value)
- } else {
- value = String(value)
- }
- let update = { _id: item.id, [`system.${itemField}`]: value };
- this.updateEmbeddedDocuments("Item", [update])
- }
- }
-
- /* -------------------------------------------- */
- checkAttribut(attribut, minLevel) {
- let attr = this.system.attributs.find(at => at.labelnorm == attribut.toLowerCase())
- if (attr && attr.value >= minLevel) {
- return { isValid: true, attr: foundry.utils.duplicate(attr) }
- }
- return { isValid: false }
- }
- /* -------------------------------------------- */
- checkAttributOrCompetenceLevel(compName, minLevel) {
- let comp = this.items.find(i => i.type == "competence" && i.name.toLowerCase() == compName.toLowerCase() && i.system.niveau >= minLevel)
- if (comp) {
- return { isValid: true, item: foundry.utils.duplicate(comp) }
- } else {
- for (let attrKey in this.system.attributs) {
- if (this.system.attributs[attrKey].label.toLowerCase() == compName.toLowerCase() && this.system.attributs[attrKey].value >= minLevel) {
- return { isValid: true, item: foundry.utils.duplicate(this.system.attributs[attrKey]) }
- }
- }
- }
- return { isValid: false, warningMessage: `Prérequis insuffisant : la compétence/attribut ${compName} doit être de niveau ${minLevel} au minimum` }
- }
- /* -------------------------------------------- */
- addCompetenceBonus(compName, bonus, baCost) {
- let comp = this.items.find(i => i.type == "competence" && i.name.toLowerCase() == compName.toLowerCase())
- if (comp) {
- comp = foundry.utils.duplicate(comp)
- comp.system.bonus = bonus
- comp.system.baCost = baCost
- return { isValid: true, item: comp }
- }
- return { isValid: false, warningMessage: `Compétence ${compName} non trouvée` }
- }
- /* -------------------------------------------- */
- checkIfCompetence(compName) {
- let comp = this.items.find(i => i.type == "competence" && i.name.toLowerCase() == compName.toLowerCase())
- if (comp) {
- return { isValid: true, item: comp }
- }
- return { isValid: false }
- }
- /* -------------------------------------------- */
- getVigueur() {
- return this.system.sante.vigueur
- }
-
- /* -------------------------------------------- */
- getVigueurBonus() {
- let talents = this.items.filter(item => item.type == "talent" && item.system.isautomated)
- let bonus = 0
- for (let talent of talents) {
- for (let auto of talent.system.automations) {
- if (auto.eventtype == "bonus-permanent" && auto.bonusname == "vigueur") {
- bonus += Number(auto.bonus || 0)
- }
- }
- }
- return bonus
- }
-
- /* -------------------------------------------- */
- getSeuilPouvoir() {
- return this.system.ame.seuilpouvoir
- }
-
- /* -------------------------------------------- */
- getSeuilPouvoirBonus() {
- let talents = this.items.filter(item => item.type == "talent" && item.system.isautomated)
- let bonus = 0
- for (let talent of talents) {
- for (let auto of talent.system.automations) {
- if (auto.eventtype == "bonus-permanent" && auto.bonusname == "seuilpouvoir") {
- bonus += Number(auto.bonus || 0)
- }
- }
- }
- return bonus
- }
-
- /* -------------------------------------------- */
- getAmeMax() {
- // Utiliser une vérification stricte car 0 (Serein) est une valeur valide
- return this.system.ame.max !== undefined ? this.system.ame.max : this.system.ame.nbame
- }
-
- /* -------------------------------------------- */
- getBonneAventure() {
- return this.system.bonneaventure.actuelle
- }
- /* -------------------------------------------- */
- checkBonneAventure(cost) {
- return (this.system.bonneaventure.actuelle >= cost)
- }
- /* -------------------------------------------- */
- changeBonneAventure(value) {
- let newBA = this.system.bonneaventure.actuelle
- newBA += value
- this.update({ 'system.bonneaventure.actuelle': newBA })
- }
-
- /* -------------------------------------------- */
- getEclat() {
- return this.system.eclat.value
- }
-
- /* -------------------------------------------- */
- changeEclat(value) {
- let newE = this.system.eclat.value
- newE += value
- this.update({ 'system.eclat.value': newE })
- }
-
- /* -------------------------------------------- */
- compareName(a, b) {
- if (a.name < b.name) {
- return -1;
- }
- if (a.name > b.name) {
- return 1;
- }
- return 0;
- }
-
- /* -------------------------------------------- */
- getAttribute(attrKey) {
- return this.system.attributes[attrKey]
- }
-
- /* -------------------------------------------- */
- getBonusDegats() {
- return 0;
- }
-
- /* -------------------------------------------- */
- changeEtatCombativite(value) {
- if (value === "vaincu") {
- value = 200
- }
- let sante = foundry.utils.duplicate(this.system.sante)
- sante.etat += Number(value)
- sante.etat = Math.max(sante.etat, 0)
- sante.etat = Math.min(sante.etat, this.system.sante.nbcombativite)
- this.update({ 'system.sante': sante })
- if (sante.etat == this.system.sante.nbcombativite) {
- ChatMessage.create({ content: `${this.name} est vaincu !` })
- }
- // Duplicated ! this.processCombativite(sante)
- }
-
- /* -------------------------------------------- */
- changeEtatAme(value) {
- if (value === "brise") {
- value = 200
- }
- let ame = foundry.utils.duplicate(this.system.ame)
- ame.etat += Number(value)
- // L'état ne peut pas être inférieur au minimum (max dans le système)
- let minAme = this.system.ame.max !== undefined ? this.system.ame.max : 0
- ame.etat = Math.max(ame.etat, minAme)
- // L'état ne peut pas dépasser nbame (Brisé)
- ame.etat = Math.min(ame.etat, this.system.ame.nbame)
- this.update({ 'system.ame': ame })
- if (ame.etat >= this.system.ame.nbame) {
- ChatMessage.create({ content: `${this.name} est brisé !` })
- }
- }
-
- /* -------------------------------------------- */
- processCombativite(sante) {
- sante = sante || foundry.utils.duplicate(this.system.sante)
- // Gestion des états affaibli et très affaibli
- if (sante.etat == this.system.sante.nbcombativite - 2 || sante.etat == this.system.sante.nbcombativite - 1) {
- if (sante.etat == this.system.sante.nbcombativite - 2 && this.items.find(item => item.type == "talent" && item.name.toLowerCase() == "encaissement")) {
- ChatMessage.create({ content: `${this.name} ne subit pas les 2 adversités rouge grâce à Encaissement. Pensez à les ajouter à la fin de la scène !` })
- } else if (sante.etat == this.system.sante.nbcombativite - 1 && this.items.find(item => item.type == "talent" && item.name.toLowerCase().includes("vaillant"))) {
- ChatMessage.create({ content: `${this.name} ne subit pas les 2 adversités rouge grâce à Vaillant. Pensez à les ajouter à la fin de la scène !` })
- } else {
- ChatMessage.create({ content: `${this.name} subit 2 adversités rouge !` })
- this.incDecAdversite("rouge", 2)
- }
- }
- }
-
- /* -------------------------------------------- */
- processAme(ame) {
- ame = ame || foundry.utils.duplicate(this.system.ame)
- let traumatiseValue = this.system.ame.nbame - 2
- let tresTraumatiseValue = this.system.ame.nbame - 1
- let briseValue = this.system.ame.nbame
-
- // Gestion des états Traumatisé, Très Traumatisé et Brisé
- if (ame.etat == traumatiseValue) {
- ChatMessage.create({ content: `${this.name} est Traumatisé !` })
- } else if (ame.etat == tresTraumatiseValue) {
- ChatMessage.create({ content: `${this.name} est Très Traumatisé !` })
- } else if (ame.etat >= briseValue) {
- ChatMessage.create({ content: `${this.name} est Brisé !` })
- }
- }
-
- /* -------------------------------------------- */
- async equipGear(equipmentId) {
- let item = this.items.find(item => item.id == equipmentId);
- if (item?.system?.data) {
- let update = { _id: item.id, "system.equipped": !item.system.equipped };
- await this.updateEmbeddedDocuments('Item', [update]); // Updates one EmbeddedEntity
- }
- }
-
- /* -------------------------------------------- */
- getSubActors() {
- let subActors = [];
- for (let id of this.system.subactors) {
- subActors.push(foundry.utils.duplicate(game.actors.get(id)));
- }
- return subActors;
- }
- /* -------------------------------------------- */
- async addSubActor(subActorId) {
- let subActors = foundry.utils.duplicate(this.system.subactors);
- subActors.push(subActorId);
- await this.update({ 'system.subactors': subActors });
- }
- /* -------------------------------------------- */
- async delSubActor(subActorId) {
- let newArray = [];
- for (let id of this.system.subactors) {
- if (id != subActorId) {
- newArray.push(id);
- }
- }
- await this.update({ 'system.subactors': newArray });
- }
-
- /* -------------------------------------------- */
- getTotalAdversite() {
- return this.system.adversite.bleue + this.system.adversite.rouge + this.system.adversite.noire
- }
-
- /* -------------------------------------------- */
- async incDecAdversite(adv, incDec = 0) {
- let adversite = foundry.utils.duplicate(this.system.adversite)
- adversite[adv] += Number(incDec)
- adversite[adv] = Math.max(adversite[adv], 0)
- adversite[adv] = Math.min(adversite[adv], 20)
- this.update({ 'system.adversite': adversite })
- }
- /* -------------------------------------------- */
- async incDecQuantity(objetId, incDec = 0) {
- let objetQ = this.items.get(objetId)
- if (objetQ) {
- let newQ = objetQ.system.quantite + incDec
- newQ = Math.max(newQ, 0)
- await this.updateEmbeddedDocuments('Item', [{ _id: objetQ.id, 'system.quantite': newQ }]); // pdates one EmbeddedEntity
- }
- }
-
- /* -------------------------------------------- */
- computeRichesse() {
- let valueSC = 0
- for (let monnaie of this.items) {
- if (monnaie.type == "monnaie") {
- valueSC += Number(monnaie.system.prixsc) * Number(monnaie.system.quantite)
- }
- }
- return MournbladeCYD2Utility.computeMonnaieDetails(valueSC)
- }
-
- /* -------------------------------------------- */
- computeValeurEquipement() {
- let valueSC = 0
- for (let equip of this.items) {
- if (equip.type == "equipement" || equip.type == "arme" || equip.type == "protection") {
- valueSC += Number(equip.system.prixsc) * Number(equip.system.quantite ?? 1)
- valueSC += (Number(equip.system.prixca) * Number(equip.system.quantite ?? 1)) * 20
- valueSC += (Number(equip.system.prixpo) * Number(equip.system.quantite ?? 1)) * 400
- }
- }
- return MournbladeCYD2Utility.computeMonnaieDetails(valueSC)
- }
-
- /* -------------------------------------------- */
- getCompetence(compId) {
- return this.items.get(compId)
- }
-
- /* -------------------------------------------- */
- async setPredilectionUsed(compId, predIdx) {
- let comp = this.items.get(compId)
- let pred = foundry.utils.duplicate(comp.system.predilections)
- pred[predIdx].used = true
- await this.updateEmbeddedDocuments('Item', [{ _id: compId, 'system.predilections': pred }])
- }
-
- /* -------------------------------------------- */
- getInitiativeScore() {
- let init = this.getFlag("world", "last-initiative")
- return init || -1
- }
-
- /* -------------------------------------------- */
- getBestAttackValue() {
- let attackList = this.items.filter(item => (item.type == "arme" || item.type == "talent") && item.system.equipped)
- let maxOff = 0
- let bestArme
- for (let arme of attackList) {
- if (arme.type == "arme") {
- arme = this.prepareArme(arme)
- }
- if (arme.system.totalOffensif > maxOff) {
- maxOff = arme.system.totalOffensif
- bestArme = foundry.utils.duplicate(arme)
- }
- }
- return bestArme
- }
-
- /* -------------------------------------------- */
- getBestDefenseValue() {
- let defenseList = this.items.filter(item => (item.type == "arme") && item.system.equipped)
- let maxDef = 0
- let bestArme
- for (let arme of defenseList) {
- if (arme.type == "arme") {
- arme = this.prepareArme(arme)
- }
- if (arme.system.totalDefensif > maxDef) {
- maxDef = arme.system.totalDefensif
- bestArme = foundry.utils.duplicate(arme)
- }
- }
- return bestArme
- }
-
- /* -------------------------------------------- */
- searchRelevantTalents(competence) {
- let talents = []
-
- for (let talent of this.items) {
- if (talent.type == "talent" && talent.system.isautomated && talent.system.automations.length > 0) {
- for (let auto of talent.system.automations) {
- if (auto.eventtype === "prepare-roll") {
- if (auto.competence.toLowerCase() == competence.name.toLowerCase()) {
- talent = foundry.utils.duplicate(talent)
- talent.system.bonus = auto.bonus
- talent.system.baCost = auto.baCost
- talents.push(talent)
- }
- }
- }
- }
- }
- return talents
- }
-
- /* -------------------------------------------- */
- buildListeAdversites() {
- return []
- }
-
- /* -------------------------------------------- */
- getCommonRollData(attrKey = undefined, compId = undefined, compName = undefined) {
- let rollData = MournbladeCYD2Utility.getBasicRollData()
- rollData.alias = this.name
- rollData.actorImg = this.img
- rollData.actorId = this.id
- rollData.tokenId = this.token?.id
- rollData.img = this.img
- rollData.attributs = MournbladeCYD2Utility.getAttributs()
- rollData.maitriseId = "none"
- rollData.nbEclat = this.system.eclat.value
- rollData.nbBA = this.system.bonneaventure.actuelle
- rollData.nbAdversites = this.getTotalAdversite()
- rollData.talents = []
- rollData.attrKey2 = "none"
- rollData.coupDevastateur = this.items.find(it => it.type == "talent" && it.name.toLowerCase() == "coup dévastateur" && !it.system.used)
- rollData.hasAmbidextre = this.items.find(it => it.type == "talent" && it.name.toLowerCase() == "ambidextre")
- rollData.hasFeinte = this.system.bonneaventure.actuelle > 0 && this.items.find(it => it.type == "talent" && it.name.toLowerCase() == "feinte")
- rollData.isMonte = this.system.combat.monte
- rollData.config = game.system.mournbladecyd2.config
-
- if (attrKey) {
- rollData.attrKey = attrKey
- if (attrKey != "tochoose") {
- rollData.actionImg = "systems/fvtt-mournblade-cyd2/assets/icons/" + this.system.attributs[attrKey].labelnorm + ".webp"
- rollData.attr = foundry.utils.duplicate(this.system.attributs[attrKey])
- }
- }
- if (compId) {
- rollData.competence = foundry.utils.duplicate(this.items.get(compId) || {})
- let maitrises = [{ key: "none", label: "Aucune" }]
- rollData.competence.system.predilections.forEach(function (item) {
- if (item.maitrise) {
- maitrises.push({ key: item.id, label: item.name });
- }
- })
- rollData.maitrises = maitrises // rollData.competence.system.predilections.filter(p => p.maitrise)
- rollData.actionImg = rollData.competence?.img
- rollData.talents = this.searchRelevantTalents(rollData.competence)
- }
- if (compName) {
- rollData.competence = foundry.utils.duplicate(this.items.find(item => item.name.toLowerCase() == compName.toLowerCase()) || {})
- rollData.actionImg = rollData.competence?.img
- }
- return rollData
- }
-
- /* -------------------------------------------- */
- async rollAttribut(attrKey, isInit = false) {
- let rollData = this.getCommonRollData(attrKey)
- rollData.multiplier = (isInit) ? 1 : 2
- rollData.isInit = isInit
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
-
- /* -------------------------------------------- */
- async rollCompetence(attrKey, compId) {
- let rollData = this.getCommonRollData(attrKey, compId)
- rollData.multiplier = 1 // Attr multiplier, always 1 in competence mode
- console.log("RollDatra", rollData)
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
-
- /* -------------------------------------------- */
- async rollArmeOffensif(armeId) {
- let arme = this.items.get(armeId)
- if (arme.type == "arme") {
- arme = this.prepareArme(arme)
- }
- let rollData = this.getCommonRollData(arme.system.attrKey, arme.system.competence._id)
- rollData.arme = arme
- MournbladeCYD2Utility.updateWithTarget(rollData)
- console.log("ARME!", rollData)
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
- /* -------------------------------------------- */
- async rollAssommer() {
- let rollData = this.getCommonRollData("pui", undefined, "Filouterie")
- rollData.assomer = true
- rollData.conditionsCommunes = true
- MournbladeCYD2Utility.updateWithTarget(rollData)
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
- /* -------------------------------------------- */
- async rollCoupBas() {
- let rollData = this.getCommonRollData("pui", undefined, "Mêlée")
- rollData.coupBas = true
- rollData.conditionsCommunes = true
- MournbladeCYD2Utility.updateWithTarget(rollData)
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
- /* -------------------------------------------- */
- async rollImmobiliser() {
- let rollData = this.getCommonRollData("pui", undefined, "Mêlée")
- rollData.immobiliser = true
- rollData.conditionsCommunes = true
- rollData.cibleconsciente = true
- MournbladeCYD2Utility.updateWithTarget(rollData)
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
- /* -------------------------------------------- */
- async rollRepousser() {
- let rollData = this.getCommonRollData("pui", undefined, "Mêlée")
- rollData.repousser = true
- rollData.conditionsCommunes = true
- rollData.cibleconsciente = true
- MournbladeCYD2Utility.updateWithTarget(rollData)
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
- /* -------------------------------------------- */
- async rollDesengager() {
- let rollData = this.getCommonRollData("adr", undefined, "Mouvements")
- rollData.desengager = true
- rollData.conditionsCommunes = true
- MournbladeCYD2Utility.updateWithTarget(rollData)
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
-
- /* -------------------------------------------- */
- async rollArmeDegats(armeId, targetVigueur = undefined, rollDataInput = undefined) {
- let arme = this.items.get(armeId)
- if (arme.type == "arme") {
- arme = this.prepareArme(arme)
- }
- console.log("DEGATS", arme, targetVigueur, rollDataInput)
- let roll
- let bonus = 0
- let bonus2 = 0
-
- if (rollDataInput?.applyCoupDevastateur) {
- bonus2 = Math.floor(this.system.attributs.pui.value / 2)
- let talent = this.items.find(item => item.type == "talent" && item.name.toLowerCase() == "coup dévastateur")
- this.updateEmbeddedDocuments('Item', [{ _id: talent.id, 'system.used': true }])
- }
-
- if (rollDataInput?.isHeroique) {
- if (rollDataInput?.attaqueCharge) {
- bonus = 5
- }
- if (rollDataInput?.chargeCavalerie) {
- bonus = 6
- }
- roll = await new Roll("2d10rr10+" + arme.system.totalDegats + "+" + bonus + "+" + bonus2).roll()
- } else {
- if (rollDataInput?.attaqueCharge) {
- bonus = 3
- }
- if (rollDataInput?.chargeCavalerie) {
- bonus = 4
- }
- roll = await new Roll("1d10+" + arme.system.totalDegats + "+" + bonus + "+" + bonus2).roll()
- }
- await MournbladeCYD2Utility.showDiceSoNice(roll, game.settings.get("core", "rollMode"));
- let nbEtatPerdus = 0
- if (targetVigueur) {
- nbEtatPerdus = Math.floor(roll.total / targetVigueur)
- }
- //console.log(roll)
- let rollData = {
- arme: arme,
- finalResult: roll.total,
- formula: roll.formula,
- alias: this.name,
- actorImg: this.img,
- actorId: this.id,
- defenderTokenId: rollDataInput?.defenderTokenId,
- actionImg: arme.img,
- targetVigueur: targetVigueur,
- nbEtatPerdus: nbEtatPerdus
- }
- MournbladeCYD2Utility.createChatWithRollMode(rollData.alias, {
- content: await renderTemplate(`systems/fvtt-mournblade-cyd2/templates/chat-degats-result.html`, rollData)
- })
-
- if (rollDataInput?.defenderTokenId && nbEtatPerdus) {
- MournbladeCYD2Utility.applyCombativite(rollDataInput, nbEtatPerdus)
- }
-
- }
-}
diff --git a/.history/modules/mournblade-cyd2-actor_20251026095804.js b/.history/modules/mournblade-cyd2-actor_20251026095804.js
deleted file mode 100644
index ab7746f..0000000
--- a/.history/modules/mournblade-cyd2-actor_20251026095804.js
+++ /dev/null
@@ -1,890 +0,0 @@
-/* -------------------------------------------- */
-import { MournbladeCYD2Utility } from "./mournblade-cyd2-utility.js";
-import { MournbladeCYD2RollDialog } from "./mournblade-cyd2-roll-dialog.js";
-
-/* -------------------------------------------- */
-const __degatsBonus = [-2, -2, -1, -1, 0, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 8, 8, 9, 9, 10, 10]
-const __vitesseBonus = [-2, -2, -1, -1, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8]
-
-/* -------------------------------------------- */
-/**
- * Extend the base Actor entity by defining a custom roll data structure which is ideal for the Simple system.
- * @extends {Actor}
- */
-export class MournbladeCYD2Actor extends Actor {
-
- /* -------------------------------------------- */
- /**
- * Override the create() function to provide additional SoS functionality.
- *
- * This overrided create() function adds initial items
- * Namely: Basic skills, money,
- *
- * @param {Object} data Barebones actor data which this function adds onto.
- * @param {Object} options (Unused) Additional options which customize the creation workflow.
- *
- */
-
- static async create(data, options) {
-
- // Case of compendium global import
- if (data instanceof Array) {
- return super.create(data, options);
- }
- // If the created actor has items (only applicable to duplicated actors) bypass the new actor creation logic
- if (data.items) {
- let actor = super.create(data, options);
- return actor;
- }
-
- if (data.type == 'personnage') {
- const skills = await MournbladeCYD2Utility.loadCompendium("fvtt-mournblade-cyd2.skills")
- data.items = skills.map(i => i.toObject())
- }
- if (data.type == 'creature') {
- const skills = await MournbladeCYD2Utility.loadCompendium("fvtt-mournblade-cyd2.skills-creatures")
- data.items = skills.map(i => i.toObject())
- data.items.push({ name: "Arme naturelle 1", type: 'arme', img: "systems/fvtt-mournblade-cyd2/assets/icons/melee.webp", system: { typearme: "contact", bonusmaniementoff: 0, seuildefense: 0, degats: "0" } })
- data.items.push({ name: "Arme naturelle 2", type: 'arme', img: "systems/fvtt-mournblade-cyd2/assets/icons/melee.webp", system: { typearme: "contact", bonusmaniementoff: 0, seuildefense: 0, degats: "0" } })
- }
-
- return super.create(data, options);
- }
-
- /* -------------------------------------------- */
- getBonusDefenseFromTalents() {
- let talents = this.items.filter(item => item.type == "talent" && item.system.isautomated)
- let bonus = 0
- for (let talent of talents) {
- for (let auto of talent.system.automations) {
- if (auto.eventtype == "bonus-permanent" && auto.bonusname == "bonus-defensif") {
- bonus += Number(auto.bonus || 0)
- }
- }
- }
- return bonus
- }
-
- /* -------------------------------------------- */
- prepareArme(arme) {
- arme = foundry.utils.duplicate(arme)
- let combat = this.getCombatValues()
- if (arme.system.typearme == "contact" || arme.system.typearme == "contactjet") {
- let bonusDefense = this.getBonusDefenseFromTalents()
- arme.system.competence = foundry.utils.duplicate(this.items.find(item => item.type == "competence" && item.name.toLowerCase() == "mêlée"))
- arme.system.attrKey = "pui"
- arme.system.totalDegats = arme.system.degats + "+" + combat.bonusDegatsTotal
- arme.system.totalOffensif = this.system.attributs.pui.value + arme.system.competence.system.niveau + arme.system.bonusmaniementoff + (this.system.combat.monte ? 3 : 0)
- arme.system.totalDefensif = combat.defenseTotal + arme.system.competence.system.niveau + arme.system.seuildefense + bonusDefense + (this.system.combat.monte ? 3 : 0)
- console.log("Arme", arme.system.totalDefensif, combat, arme.system.competence.system.niveau, arme.system.seuildefense, bonusDefense)
- arme.system.isdefense = true
- arme.system.isMelee = true
- arme.system.isDistance = false
- }
- if (arme.system.typearme == "jet" || arme.system.typearme == "tir") {
- arme.system.competence = foundry.utils.duplicate(this.items.find(item => item.type == "competence" && item.name.toLowerCase() == "armes à distance"))
- arme.system.attrKey = "adr"
- arme.system.totalOffensif = this.system.attributs.adr.value + arme.system.competence.system.niveau + arme.system.bonusmaniementoff
- arme.system.totalDegats = arme.system.degats
- arme.system.isMelee = false
- arme.system.isDistance = true
- if (arme.system.isdefense) {
- arme.system.totalDefensif = combat.defenseTotal + arme.system.competence.system.niveau + arme.system.seuildefense
- }
- }
- return arme
- }
-
- /* -------------------------------------------- */
- getItemSorted(types) {
- let items = this.items.filter(item => types.includes(item.type)) || []
- MournbladeCYD2Utility.sortArrayObjectsByName(items)
- return items
- }
- getWeapons() {
- let armes = []
- for (let arme of this.items) {
- if (arme.type == "arme") {
- armes.push(this.prepareArme(arme))
- }
- }
- MournbladeCYD2Utility.sortArrayObjectsByName(armes)
- return armes
- }
- getMonnaies() {
- return this.getItemSorted(["monnaie"])
- }
- getEquipments() {
- return this.getItemSorted(["equipement"])
- }
- getArtefacts() {
- return this.getItemSorted(["artefact"])
- }
- getArmors() {
- return this.getItemSorted(["protection"])
- }
- getHistoriques() {
- return this.getItemSorted(["historique"])
- }
- getProfils() {
- return this.getItemSorted(["profil"])
- }
- getTalents() {
- return this.getItemSorted(["talent"])
- }
- getRessources() {
- return this.getItemSorted(["ressource"])
- }
- getContacts() {
- return this.getItemSorted(["contact"])
- }
- getMutations() {
- return this.getItemSorted(["mutation"])
- }
- getDons() {
- return this.getItemSorted(["don"])
- }
- getPactes() {
- return this.getItemSorted(["pacte"])
- }
- getTendances() {
- return this.getItemSorted(["tendance"])
- }
- getRunes() {
- return this.getItemSorted(["rune"])
- }
- getTraitsChaotiques() {
- return this.getItemSorted(["traitchaotique"])
- }
- getTraitsEspeces() {
- return this.getItemSorted(["traitespece"])
- }
-
- /* -------------------------------------------- */
- getAspect() {
- return (this.system.balance.loi > this.system.balance.chaos) ? this.system.balance.loi : this.system.balance.chaos
- }
- getMarge() {
- return Math.abs(this.system.balance.loi - this.system.balance.chaos)
- }
- getAlignement() {
- return (this.system.balance.loi > this.system.balance.chaos) ? "loyal" : "chaotique"
- }
-
- /* -------------------------------------------- */
- getSkills() {
- let comp = []
- for (let item of this.items) {
- item = foundry.utils.duplicate(item)
- if (item.type == "competence") {
- item.system.attribut1total = item.system.niveau + (this.system.attributs[item.system.attribut1]?.value || 0)
- item.system.attribut2total = item.system.niveau + (this.system.attributs[item.system.attribut2]?.value || 0)
- item.system.attribut3total = item.system.niveau + (this.system.attributs[item.system.attribut3]?.value || 0)
- if (item.system.niveau == 0) {
- item.system.attribut1total -= 3
- item.system.attribut2total -= 3
- item.system.attribut3total -= 3
- }
- item.system.attribut1label = this.system.attributs[item.system.attribut1]?.label || ""
- item.system.attribut2label = this.system.attributs[item.system.attribut2]?.label || ""
- item.system.attribut3label = this.system.attributs[item.system.attribut3]?.label || ""
- comp.push(item)
- }
- }
- MournbladeCYD2Utility.sortArrayObjectsByName(comp)
- return comp
- }
-
- /* ----------------------- --------------------- */
- addMember(actorId) {
- let members = foundry.utils.duplicate(this.system.members)
- members.push({ id: actorId })
- this.update({ 'system.members': members })
- }
- async removeMember(actorId) {
- let members = this.system.members.filter(it => it.id != actorId)
- this.update({ 'system.members': members })
- }
-
- /* -------------------------------------------- */
- getDefenseBase() {
- return Math.max(this.system.attributs.tre.value, this.system.attributs.adr.value)
- }
-
- /* -------------------------------------------- */
- getVitesseBase() {
- return 5 + __vitesseBonus[this.system.attributs.adr.value]
- }
- /* -------------------------------------------- */
- getProtection() {
- let equipProtection = 0
- for (let armor of this.items) {
- if (armor.type == "protection" && armor.system.equipped) {
- equipProtection += Number(armor.system.protection)
- }
- }
- if (equipProtection < 4) {
- return 4 + equipProtection // Cas des boucliers + sans armure
- }
- return equipProtection // Uniquement la protection des armures + boucliers
- }
-
- /* -------------------------------------------- */
- getCombatValues() {
- let combat = {
- initBase: this.system.attributs.adr.value,
- initTotal: this.system.attributs.adr.value + this.system.combat.initbonus,
- bonusDegats: this.getBonusDegats(),
- bonusDegatsTotal: this.getBonusDegats() + this.system.combat.bonusdegats,
- vitesseBase: this.getVitesseBase(),
- vitesseTotal: this.getVitesseBase() + this.system.combat.vitessebonus,
- defenseBase: this.getDefenseBase(),
- protection: this.getProtection(),
- defenseTotal: this.getDefenseBase() + this.system.combat.defensebonus + this.getProtection() - this.getTotalAdversite() + (this.system.combat.defensetotale ? 3 : 0)
- }
- return combat
- }
-
- /* -------------------------------------------- */
- prepareBaseData() {
- }
-
- /* -------------------------------------------- */
- async prepareData() {
- super.prepareData();
- }
-
- /* -------------------------------------------- */
- prepareDerivedData() {
-
- if (this.type == 'personnage') {
- let talentBonus = this.getVigueurBonus()
- let vigueur = Math.floor((this.system.attributs.pui.value + this.system.attributs.tre.value) / 2) + talentBonus + this.system.sante.vigueurmodifier
- if (vigueur != this.system.sante.vigueur) {
- this.update({ 'system.sante.vigueur': vigueur })
- }
-
- let seuilPouvoirBonus = this.getSeuilPouvoirBonus()
- let seuilPouvoir = Math.floor((this.system.attributs.tre.value + this.system.attributs.cla.value) / 2) + seuilPouvoirBonus + this.system.ame.seuilpouvoirmodifier
- if (seuilPouvoir != this.system.ame.seuilpouvoir) {
- this.update({ 'system.ame.seuilpouvoir': seuilPouvoir })
- }
- }
- super.prepareDerivedData()
- }
-
- /* -------------------------------------------- */
- _preUpdate(changed, options, user) {
- if (changed?.system?.sante?.etat && changed?.system?.sante?.etat != this.system.sante.etat) {
- setTimeout(() => {
- this.processCombativite(changed.system.sante)
- }, 800)
- }
- if (changed?.system?.ame?.etat && changed?.system?.ame?.etat != this.system.ame.etat) {
- // L'état d'Âme ne peut pas être inférieur au minimum (max dans le système)
- let minAme = this.system.ame.max !== undefined ? this.system.ame.max : 0
- if (changed.system.ame.etat < minAme) {
- changed.system.ame.etat = minAme
- }
- // L'état d'Âme ne peut pas dépasser nbame (Brisé)
- if (changed.system.ame.etat > this.system.ame.nbame) {
- changed.system.ame.etat = this.system.ame.nbame
- }
- setTimeout(() => {
- this.processAme(changed.system.ame)
- }, 800)
- }
- // Si le max d'Âme change, ajuster l'état actuel si nécessaire
- if (changed?.system?.ame?.max !== undefined && changed.system.ame.max != this.system.ame.max) {
- if (this.system.ame.etat < changed.system.ame.max) {
- changed.system.ame.etat = changed.system.ame.max
- }
- }
- super._preUpdate(changed, options, user);
- }
-
- /* -------------------------------------------- */
- _onUpdate(data, options, user) {
- super._onUpdate(data, options, user);
- }
- /* -------------------------------------------- */
- getItemById(id) {
- let item = this.items.find(item => item.id == id);
- if (item) {
- item = foundry.utils.duplicate(item)
- }
- return item;
- }
-
- /* -------------------------------------------- */
- async equipItem(itemId) {
- let item = this.items.find(item => item.id == itemId)
- if (item && item.system) {
- let update = { _id: item.id, "system.equipped": !item.system.equipped }
- await this.updateEmbeddedDocuments('Item', [update]); // Updates one EmbeddedEntity
- }
- }
-
- /* -------------------------------------------- */
- editItemField(itemId, itemType, itemField, dataType, value) {
- let item = this.items.find(item => item.id == itemId)
- if (item) {
- console.log("Item ", item, itemField, dataType, value)
- if (dataType.toLowerCase() == "number") {
- value = Number(value)
- } else {
- value = String(value)
- }
- let update = { _id: item.id, [`system.${itemField}`]: value };
- this.updateEmbeddedDocuments("Item", [update])
- }
- }
-
- /* -------------------------------------------- */
- checkAttribut(attribut, minLevel) {
- let attr = this.system.attributs.find(at => at.labelnorm == attribut.toLowerCase())
- if (attr && attr.value >= minLevel) {
- return { isValid: true, attr: foundry.utils.duplicate(attr) }
- }
- return { isValid: false }
- }
- /* -------------------------------------------- */
- checkAttributOrCompetenceLevel(compName, minLevel) {
- let comp = this.items.find(i => i.type == "competence" && i.name.toLowerCase() == compName.toLowerCase() && i.system.niveau >= minLevel)
- if (comp) {
- return { isValid: true, item: foundry.utils.duplicate(comp) }
- } else {
- for (let attrKey in this.system.attributs) {
- if (this.system.attributs[attrKey].label.toLowerCase() == compName.toLowerCase() && this.system.attributs[attrKey].value >= minLevel) {
- return { isValid: true, item: foundry.utils.duplicate(this.system.attributs[attrKey]) }
- }
- }
- }
- return { isValid: false, warningMessage: `Prérequis insuffisant : la compétence/attribut ${compName} doit être de niveau ${minLevel} au minimum` }
- }
- /* -------------------------------------------- */
- addCompetenceBonus(compName, bonus, baCost) {
- let comp = this.items.find(i => i.type == "competence" && i.name.toLowerCase() == compName.toLowerCase())
- if (comp) {
- comp = foundry.utils.duplicate(comp)
- comp.system.bonus = bonus
- comp.system.baCost = baCost
- return { isValid: true, item: comp }
- }
- return { isValid: false, warningMessage: `Compétence ${compName} non trouvée` }
- }
- /* -------------------------------------------- */
- checkIfCompetence(compName) {
- let comp = this.items.find(i => i.type == "competence" && i.name.toLowerCase() == compName.toLowerCase())
- if (comp) {
- return { isValid: true, item: comp }
- }
- return { isValid: false }
- }
- /* -------------------------------------------- */
- getVigueur() {
- return this.system.sante.vigueur
- }
-
- /* -------------------------------------------- */
- getVigueurBonus() {
- let talents = this.items.filter(item => item.type == "talent" && item.system.isautomated)
- let bonus = 0
- for (let talent of talents) {
- for (let auto of talent.system.automations) {
- if (auto.eventtype == "bonus-permanent" && auto.bonusname == "vigueur") {
- bonus += Number(auto.bonus || 0)
- }
- }
- }
- return bonus
- }
-
- /* -------------------------------------------- */
- getSeuilPouvoir() {
- return this.system.ame.seuilpouvoir
- }
-
- /* -------------------------------------------- */
- getSeuilPouvoirBonus() {
- let talents = this.items.filter(item => item.type == "talent" && item.system.isautomated)
- let bonus = 0
- for (let talent of talents) {
- for (let auto of talent.system.automations) {
- if (auto.eventtype == "bonus-permanent" && auto.bonusname == "seuilpouvoir") {
- bonus += Number(auto.bonus || 0)
- }
- }
- }
- return bonus
- }
-
- /* -------------------------------------------- */
- getAmeMax() {
- // Utiliser une vérification stricte car 0 (Serein) est une valeur valide
- return this.system.ame.max !== undefined ? this.system.ame.max : this.system.ame.nbame
- }
-
- /* -------------------------------------------- */
- getBonneAventure() {
- return this.system.bonneaventure.actuelle
- }
- /* -------------------------------------------- */
- checkBonneAventure(cost) {
- return (this.system.bonneaventure.actuelle >= cost)
- }
- /* -------------------------------------------- */
- changeBonneAventure(value) {
- let newBA = this.system.bonneaventure.actuelle
- newBA += value
- this.update({ 'system.bonneaventure.actuelle': newBA })
- }
-
- /* -------------------------------------------- */
- getEclat() {
- return this.system.eclat.value
- }
-
- /* -------------------------------------------- */
- changeEclat(value) {
- let newE = this.system.eclat.value
- newE += value
- this.update({ 'system.eclat.value': newE })
- }
-
- /* -------------------------------------------- */
- compareName(a, b) {
- if (a.name < b.name) {
- return -1;
- }
- if (a.name > b.name) {
- return 1;
- }
- return 0;
- }
-
- /* -------------------------------------------- */
- getAttribute(attrKey) {
- return this.system.attributes[attrKey]
- }
-
- /* -------------------------------------------- */
- getBonusDegats() {
- return 0;
- }
-
- /* -------------------------------------------- */
- changeEtatCombativite(value) {
- if (value === "vaincu") {
- value = 200
- }
- let sante = foundry.utils.duplicate(this.system.sante)
- sante.etat += Number(value)
- sante.etat = Math.max(sante.etat, 0)
- sante.etat = Math.min(sante.etat, this.system.sante.nbcombativite)
- this.update({ 'system.sante': sante })
- if (sante.etat == this.system.sante.nbcombativite) {
- ChatMessage.create({ content: `${this.name} est vaincu !` })
- }
- // Duplicated ! this.processCombativite(sante)
- }
-
- /* -------------------------------------------- */
- changeEtatAme(value) {
- if (value === "brise") {
- value = 200
- }
- let ame = foundry.utils.duplicate(this.system.ame)
- ame.etat += Number(value)
- // L'état ne peut pas être inférieur au minimum (max dans le système)
- let minAme = this.system.ame.max !== undefined ? this.system.ame.max : 0
- ame.etat = Math.max(ame.etat, minAme)
- // L'état ne peut pas dépasser nbame (Brisé)
- ame.etat = Math.min(ame.etat, this.system.ame.nbame)
- this.update({ 'system.ame': ame })
- if (ame.etat >= this.system.ame.nbame) {
- ChatMessage.create({ content: `${this.name} est brisé !` })
- }
- }
-
- /* -------------------------------------------- */
- processCombativite(sante) {
- sante = sante || foundry.utils.duplicate(this.system.sante)
- // Gestion des états affaibli et très affaibli
- if (sante.etat == this.system.sante.nbcombativite - 2 || sante.etat == this.system.sante.nbcombativite - 1) {
- if (sante.etat == this.system.sante.nbcombativite - 2 && this.items.find(item => item.type == "talent" && item.name.toLowerCase() == "encaissement")) {
- ChatMessage.create({ content: `${this.name} ne subit pas les 2 adversités rouge grâce à Encaissement. Pensez à les ajouter à la fin de la scène !` })
- } else if (sante.etat == this.system.sante.nbcombativite - 1 && this.items.find(item => item.type == "talent" && item.name.toLowerCase().includes("vaillant"))) {
- ChatMessage.create({ content: `${this.name} ne subit pas les 2 adversités rouge grâce à Vaillant. Pensez à les ajouter à la fin de la scène !` })
- } else {
- ChatMessage.create({ content: `${this.name} subit 2 adversités rouge !` })
- this.incDecAdversite("rouge", 2)
- }
- }
- }
-
- /* -------------------------------------------- */
- processAme(ame) {
- ame = ame || foundry.utils.duplicate(this.system.ame)
- let traumatiseValue = this.system.ame.nbame - 2
- let tresTraumatiseValue = this.system.ame.nbame - 1
- let briseValue = this.system.ame.nbame
-
- // Gestion des états Traumatisé, Très Traumatisé et Brisé
- if (ame.etat == traumatiseValue) {
- ChatMessage.create({ content: `${this.name} est Traumatisé !` })
- } else if (ame.etat == tresTraumatiseValue) {
- ChatMessage.create({ content: `${this.name} est Très Traumatisé !` })
- } else if (ame.etat >= briseValue) {
- ChatMessage.create({ content: `${this.name} est Brisé !` })
- }
- }
-
- /* -------------------------------------------- */
- async equipGear(equipmentId) {
- let item = this.items.find(item => item.id == equipmentId);
- if (item?.system?.data) {
- let update = { _id: item.id, "system.equipped": !item.system.equipped };
- await this.updateEmbeddedDocuments('Item', [update]); // Updates one EmbeddedEntity
- }
- }
-
- /* -------------------------------------------- */
- getSubActors() {
- let subActors = [];
- for (let id of this.system.subactors) {
- subActors.push(foundry.utils.duplicate(game.actors.get(id)));
- }
- return subActors;
- }
- /* -------------------------------------------- */
- async addSubActor(subActorId) {
- let subActors = foundry.utils.duplicate(this.system.subactors);
- subActors.push(subActorId);
- await this.update({ 'system.subactors': subActors });
- }
- /* -------------------------------------------- */
- async delSubActor(subActorId) {
- let newArray = [];
- for (let id of this.system.subactors) {
- if (id != subActorId) {
- newArray.push(id);
- }
- }
- await this.update({ 'system.subactors': newArray });
- }
-
- /* -------------------------------------------- */
- getTotalAdversite() {
- return this.system.adversite.bleue + this.system.adversite.rouge + this.system.adversite.noire
- }
-
- /* -------------------------------------------- */
- async incDecAdversite(adv, incDec = 0) {
- let adversite = foundry.utils.duplicate(this.system.adversite)
- adversite[adv] += Number(incDec)
- adversite[adv] = Math.max(adversite[adv], 0)
- adversite[adv] = Math.min(adversite[adv], 20)
- this.update({ 'system.adversite': adversite })
- }
- /* -------------------------------------------- */
- async incDecQuantity(objetId, incDec = 0) {
- let objetQ = this.items.get(objetId)
- if (objetQ) {
- let newQ = objetQ.system.quantite + incDec
- newQ = Math.max(newQ, 0)
- await this.updateEmbeddedDocuments('Item', [{ _id: objetQ.id, 'system.quantite': newQ }]); // pdates one EmbeddedEntity
- }
- }
-
- /* -------------------------------------------- */
- computeRichesse() {
- let valueSC = 0
- for (let monnaie of this.items) {
- if (monnaie.type == "monnaie") {
- valueSC += Number(monnaie.system.prixsc) * Number(monnaie.system.quantite)
- }
- }
- return MournbladeCYD2Utility.computeMonnaieDetails(valueSC)
- }
-
- /* -------------------------------------------- */
- computeValeurEquipement() {
- let valueSC = 0
- for (let equip of this.items) {
- if (equip.type == "equipement" || equip.type == "arme" || equip.type == "protection") {
- valueSC += Number(equip.system.prixsc) * Number(equip.system.quantite ?? 1)
- valueSC += (Number(equip.system.prixca) * Number(equip.system.quantite ?? 1)) * 20
- valueSC += (Number(equip.system.prixpo) * Number(equip.system.quantite ?? 1)) * 400
- }
- }
- return MournbladeCYD2Utility.computeMonnaieDetails(valueSC)
- }
-
- /* -------------------------------------------- */
- getCompetence(compId) {
- return this.items.get(compId)
- }
-
- /* -------------------------------------------- */
- async setPredilectionUsed(compId, predIdx) {
- let comp = this.items.get(compId)
- let pred = foundry.utils.duplicate(comp.system.predilections)
- pred[predIdx].used = true
- await this.updateEmbeddedDocuments('Item', [{ _id: compId, 'system.predilections': pred }])
- }
-
- /* -------------------------------------------- */
- getInitiativeScore() {
- let init = this.getFlag("world", "last-initiative")
- return init || -1
- }
-
- /* -------------------------------------------- */
- getBestAttackValue() {
- let attackList = this.items.filter(item => (item.type == "arme" || item.type == "talent") && item.system.equipped)
- let maxOff = 0
- let bestArme
- for (let arme of attackList) {
- if (arme.type == "arme") {
- arme = this.prepareArme(arme)
- }
- if (arme.system.totalOffensif > maxOff) {
- maxOff = arme.system.totalOffensif
- bestArme = foundry.utils.duplicate(arme)
- }
- }
- return bestArme
- }
-
- /* -------------------------------------------- */
- getBestDefenseValue() {
- let defenseList = this.items.filter(item => (item.type == "arme") && item.system.equipped)
- let maxDef = 0
- let bestArme
- for (let arme of defenseList) {
- if (arme.type == "arme") {
- arme = this.prepareArme(arme)
- }
- if (arme.system.totalDefensif > maxDef) {
- maxDef = arme.system.totalDefensif
- bestArme = foundry.utils.duplicate(arme)
- }
- }
- return bestArme
- }
-
- /* -------------------------------------------- */
- searchRelevantTalents(competence) {
- let talents = []
-
- for (let talent of this.items) {
- if (talent.type == "talent" && talent.system.isautomated && talent.system.automations.length > 0) {
- for (let auto of talent.system.automations) {
- if (auto.eventtype === "prepare-roll") {
- if (auto.competence.toLowerCase() == competence.name.toLowerCase()) {
- talent = foundry.utils.duplicate(talent)
- talent.system.bonus = auto.bonus
- talent.system.baCost = auto.baCost
- talents.push(talent)
- }
- }
- }
- }
- }
- return talents
- }
-
- /* -------------------------------------------- */
- buildListeAdversites() {
- return []
- }
-
- /* -------------------------------------------- */
- getCommonRollData(attrKey = undefined, compId = undefined, compName = undefined) {
- let rollData = MournbladeCYD2Utility.getBasicRollData()
- rollData.alias = this.name
- rollData.actorImg = this.img
- rollData.actorId = this.id
- rollData.tokenId = this.token?.id
- rollData.img = this.img
- rollData.attributs = MournbladeCYD2Utility.getAttributs()
- rollData.maitriseId = "none"
- rollData.nbEclat = this.system.eclat.value
- rollData.nbBA = this.system.bonneaventure.actuelle
- rollData.nbAdversites = this.getTotalAdversite()
- rollData.talents = []
- rollData.attrKey2 = "none"
- rollData.coupDevastateur = this.items.find(it => it.type == "talent" && it.name.toLowerCase() == "coup dévastateur" && !it.system.used)
- rollData.hasAmbidextre = this.items.find(it => it.type == "talent" && it.name.toLowerCase() == "ambidextre")
- rollData.hasFeinte = this.system.bonneaventure.actuelle > 0 && this.items.find(it => it.type == "talent" && it.name.toLowerCase() == "feinte")
- rollData.isMonte = this.system.combat.monte
- rollData.config = game.system.mournbladecyd2.config
-
- if (attrKey) {
- rollData.attrKey = attrKey
- if (attrKey != "tochoose") {
- rollData.actionImg = "systems/fvtt-mournblade-cyd2/assets/icons/" + this.system.attributs[attrKey].labelnorm + ".webp"
- rollData.attr = foundry.utils.duplicate(this.system.attributs[attrKey])
- }
- }
- if (compId) {
- rollData.competence = foundry.utils.duplicate(this.items.get(compId) || {})
- let maitrises = [{ key: "none", label: "Aucune" }]
- rollData.competence.system.predilections.forEach(function (item) {
- if (item.maitrise) {
- maitrises.push({ key: item.id, label: item.name });
- }
- })
- rollData.maitrises = maitrises // rollData.competence.system.predilections.filter(p => p.maitrise)
- rollData.actionImg = rollData.competence?.img
- rollData.talents = this.searchRelevantTalents(rollData.competence)
- }
- if (compName) {
- rollData.competence = foundry.utils.duplicate(this.items.find(item => item.name.toLowerCase() == compName.toLowerCase()) || {})
- rollData.actionImg = rollData.competence?.img
- }
- return rollData
- }
-
- /* -------------------------------------------- */
- async rollAttribut(attrKey, isInit = false) {
- let rollData = this.getCommonRollData(attrKey)
- rollData.multiplier = (isInit) ? 1 : 2
- rollData.isInit = isInit
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
-
- /* -------------------------------------------- */
- async rollCompetence(attrKey, compId) {
- let rollData = this.getCommonRollData(attrKey, compId)
- rollData.multiplier = 1 // Attr multiplier, always 1 in competence mode
- console.log("RollDatra", rollData)
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
-
- /* -------------------------------------------- */
- async rollArmeOffensif(armeId) {
- let arme = this.items.get(armeId)
- if (arme.type == "arme") {
- arme = this.prepareArme(arme)
- }
- let rollData = this.getCommonRollData(arme.system.attrKey, arme.system.competence._id)
- rollData.arme = arme
- MournbladeCYD2Utility.updateWithTarget(rollData)
- console.log("ARME!", rollData)
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
- /* -------------------------------------------- */
- async rollAssommer() {
- let rollData = this.getCommonRollData("pui", undefined, "Filouterie")
- rollData.assomer = true
- rollData.conditionsCommunes = true
- MournbladeCYD2Utility.updateWithTarget(rollData)
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
- /* -------------------------------------------- */
- async rollCoupBas() {
- let rollData = this.getCommonRollData("pui", undefined, "Mêlée")
- rollData.coupBas = true
- rollData.conditionsCommunes = true
- MournbladeCYD2Utility.updateWithTarget(rollData)
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
- /* -------------------------------------------- */
- async rollImmobiliser() {
- let rollData = this.getCommonRollData("pui", undefined, "Mêlée")
- rollData.immobiliser = true
- rollData.conditionsCommunes = true
- rollData.cibleconsciente = true
- MournbladeCYD2Utility.updateWithTarget(rollData)
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
- /* -------------------------------------------- */
- async rollRepousser() {
- let rollData = this.getCommonRollData("pui", undefined, "Mêlée")
- rollData.repousser = true
- rollData.conditionsCommunes = true
- rollData.cibleconsciente = true
- MournbladeCYD2Utility.updateWithTarget(rollData)
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
- /* -------------------------------------------- */
- async rollDesengager() {
- let rollData = this.getCommonRollData("adr", undefined, "Mouvements")
- rollData.desengager = true
- rollData.conditionsCommunes = true
- MournbladeCYD2Utility.updateWithTarget(rollData)
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
-
- /* -------------------------------------------- */
- async rollArmeDegats(armeId, targetVigueur = undefined, rollDataInput = undefined) {
- let arme = this.items.get(armeId)
- if (arme.type == "arme") {
- arme = this.prepareArme(arme)
- }
- console.log("DEGATS", arme, targetVigueur, rollDataInput)
- let roll
- let bonus = 0
- let bonus2 = 0
-
- if (rollDataInput?.applyCoupDevastateur) {
- bonus2 = Math.floor(this.system.attributs.pui.value / 2)
- let talent = this.items.find(item => item.type == "talent" && item.name.toLowerCase() == "coup dévastateur")
- this.updateEmbeddedDocuments('Item', [{ _id: talent.id, 'system.used': true }])
- }
-
- if (rollDataInput?.isHeroique) {
- if (rollDataInput?.attaqueCharge) {
- bonus = 5
- }
- if (rollDataInput?.chargeCavalerie) {
- bonus = 6
- }
- roll = await new Roll("2d10rr10+" + arme.system.totalDegats + "+" + bonus + "+" + bonus2).roll()
- } else {
- if (rollDataInput?.attaqueCharge) {
- bonus = 3
- }
- if (rollDataInput?.chargeCavalerie) {
- bonus = 4
- }
- roll = await new Roll("1d10+" + arme.system.totalDegats + "+" + bonus + "+" + bonus2).roll()
- }
- await MournbladeCYD2Utility.showDiceSoNice(roll, game.settings.get("core", "rollMode"));
- let nbEtatPerdus = 0
- if (targetVigueur) {
- nbEtatPerdus = Math.floor(roll.total / targetVigueur)
- }
- //console.log(roll)
- let rollData = {
- arme: arme,
- finalResult: roll.total,
- formula: roll.formula,
- alias: this.name,
- actorImg: this.img,
- actorId: this.id,
- defenderTokenId: rollDataInput?.defenderTokenId,
- actionImg: arme.img,
- targetVigueur: targetVigueur,
- nbEtatPerdus: nbEtatPerdus
- }
- MournbladeCYD2Utility.createChatWithRollMode(rollData.alias, {
- content: await renderTemplate(`systems/fvtt-mournblade-cyd2/templates/chat-degats-result.html`, rollData)
- })
-
- if (rollDataInput?.defenderTokenId && nbEtatPerdus) {
- MournbladeCYD2Utility.applyCombativite(rollDataInput, nbEtatPerdus)
- }
-
- }
-}
diff --git a/.history/modules/mournblade-cyd2-actor_20251026100139.js b/.history/modules/mournblade-cyd2-actor_20251026100139.js
deleted file mode 100644
index ab7746f..0000000
--- a/.history/modules/mournblade-cyd2-actor_20251026100139.js
+++ /dev/null
@@ -1,890 +0,0 @@
-/* -------------------------------------------- */
-import { MournbladeCYD2Utility } from "./mournblade-cyd2-utility.js";
-import { MournbladeCYD2RollDialog } from "./mournblade-cyd2-roll-dialog.js";
-
-/* -------------------------------------------- */
-const __degatsBonus = [-2, -2, -1, -1, 0, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 8, 8, 9, 9, 10, 10]
-const __vitesseBonus = [-2, -2, -1, -1, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8]
-
-/* -------------------------------------------- */
-/**
- * Extend the base Actor entity by defining a custom roll data structure which is ideal for the Simple system.
- * @extends {Actor}
- */
-export class MournbladeCYD2Actor extends Actor {
-
- /* -------------------------------------------- */
- /**
- * Override the create() function to provide additional SoS functionality.
- *
- * This overrided create() function adds initial items
- * Namely: Basic skills, money,
- *
- * @param {Object} data Barebones actor data which this function adds onto.
- * @param {Object} options (Unused) Additional options which customize the creation workflow.
- *
- */
-
- static async create(data, options) {
-
- // Case of compendium global import
- if (data instanceof Array) {
- return super.create(data, options);
- }
- // If the created actor has items (only applicable to duplicated actors) bypass the new actor creation logic
- if (data.items) {
- let actor = super.create(data, options);
- return actor;
- }
-
- if (data.type == 'personnage') {
- const skills = await MournbladeCYD2Utility.loadCompendium("fvtt-mournblade-cyd2.skills")
- data.items = skills.map(i => i.toObject())
- }
- if (data.type == 'creature') {
- const skills = await MournbladeCYD2Utility.loadCompendium("fvtt-mournblade-cyd2.skills-creatures")
- data.items = skills.map(i => i.toObject())
- data.items.push({ name: "Arme naturelle 1", type: 'arme', img: "systems/fvtt-mournblade-cyd2/assets/icons/melee.webp", system: { typearme: "contact", bonusmaniementoff: 0, seuildefense: 0, degats: "0" } })
- data.items.push({ name: "Arme naturelle 2", type: 'arme', img: "systems/fvtt-mournblade-cyd2/assets/icons/melee.webp", system: { typearme: "contact", bonusmaniementoff: 0, seuildefense: 0, degats: "0" } })
- }
-
- return super.create(data, options);
- }
-
- /* -------------------------------------------- */
- getBonusDefenseFromTalents() {
- let talents = this.items.filter(item => item.type == "talent" && item.system.isautomated)
- let bonus = 0
- for (let talent of talents) {
- for (let auto of talent.system.automations) {
- if (auto.eventtype == "bonus-permanent" && auto.bonusname == "bonus-defensif") {
- bonus += Number(auto.bonus || 0)
- }
- }
- }
- return bonus
- }
-
- /* -------------------------------------------- */
- prepareArme(arme) {
- arme = foundry.utils.duplicate(arme)
- let combat = this.getCombatValues()
- if (arme.system.typearme == "contact" || arme.system.typearme == "contactjet") {
- let bonusDefense = this.getBonusDefenseFromTalents()
- arme.system.competence = foundry.utils.duplicate(this.items.find(item => item.type == "competence" && item.name.toLowerCase() == "mêlée"))
- arme.system.attrKey = "pui"
- arme.system.totalDegats = arme.system.degats + "+" + combat.bonusDegatsTotal
- arme.system.totalOffensif = this.system.attributs.pui.value + arme.system.competence.system.niveau + arme.system.bonusmaniementoff + (this.system.combat.monte ? 3 : 0)
- arme.system.totalDefensif = combat.defenseTotal + arme.system.competence.system.niveau + arme.system.seuildefense + bonusDefense + (this.system.combat.monte ? 3 : 0)
- console.log("Arme", arme.system.totalDefensif, combat, arme.system.competence.system.niveau, arme.system.seuildefense, bonusDefense)
- arme.system.isdefense = true
- arme.system.isMelee = true
- arme.system.isDistance = false
- }
- if (arme.system.typearme == "jet" || arme.system.typearme == "tir") {
- arme.system.competence = foundry.utils.duplicate(this.items.find(item => item.type == "competence" && item.name.toLowerCase() == "armes à distance"))
- arme.system.attrKey = "adr"
- arme.system.totalOffensif = this.system.attributs.adr.value + arme.system.competence.system.niveau + arme.system.bonusmaniementoff
- arme.system.totalDegats = arme.system.degats
- arme.system.isMelee = false
- arme.system.isDistance = true
- if (arme.system.isdefense) {
- arme.system.totalDefensif = combat.defenseTotal + arme.system.competence.system.niveau + arme.system.seuildefense
- }
- }
- return arme
- }
-
- /* -------------------------------------------- */
- getItemSorted(types) {
- let items = this.items.filter(item => types.includes(item.type)) || []
- MournbladeCYD2Utility.sortArrayObjectsByName(items)
- return items
- }
- getWeapons() {
- let armes = []
- for (let arme of this.items) {
- if (arme.type == "arme") {
- armes.push(this.prepareArme(arme))
- }
- }
- MournbladeCYD2Utility.sortArrayObjectsByName(armes)
- return armes
- }
- getMonnaies() {
- return this.getItemSorted(["monnaie"])
- }
- getEquipments() {
- return this.getItemSorted(["equipement"])
- }
- getArtefacts() {
- return this.getItemSorted(["artefact"])
- }
- getArmors() {
- return this.getItemSorted(["protection"])
- }
- getHistoriques() {
- return this.getItemSorted(["historique"])
- }
- getProfils() {
- return this.getItemSorted(["profil"])
- }
- getTalents() {
- return this.getItemSorted(["talent"])
- }
- getRessources() {
- return this.getItemSorted(["ressource"])
- }
- getContacts() {
- return this.getItemSorted(["contact"])
- }
- getMutations() {
- return this.getItemSorted(["mutation"])
- }
- getDons() {
- return this.getItemSorted(["don"])
- }
- getPactes() {
- return this.getItemSorted(["pacte"])
- }
- getTendances() {
- return this.getItemSorted(["tendance"])
- }
- getRunes() {
- return this.getItemSorted(["rune"])
- }
- getTraitsChaotiques() {
- return this.getItemSorted(["traitchaotique"])
- }
- getTraitsEspeces() {
- return this.getItemSorted(["traitespece"])
- }
-
- /* -------------------------------------------- */
- getAspect() {
- return (this.system.balance.loi > this.system.balance.chaos) ? this.system.balance.loi : this.system.balance.chaos
- }
- getMarge() {
- return Math.abs(this.system.balance.loi - this.system.balance.chaos)
- }
- getAlignement() {
- return (this.system.balance.loi > this.system.balance.chaos) ? "loyal" : "chaotique"
- }
-
- /* -------------------------------------------- */
- getSkills() {
- let comp = []
- for (let item of this.items) {
- item = foundry.utils.duplicate(item)
- if (item.type == "competence") {
- item.system.attribut1total = item.system.niveau + (this.system.attributs[item.system.attribut1]?.value || 0)
- item.system.attribut2total = item.system.niveau + (this.system.attributs[item.system.attribut2]?.value || 0)
- item.system.attribut3total = item.system.niveau + (this.system.attributs[item.system.attribut3]?.value || 0)
- if (item.system.niveau == 0) {
- item.system.attribut1total -= 3
- item.system.attribut2total -= 3
- item.system.attribut3total -= 3
- }
- item.system.attribut1label = this.system.attributs[item.system.attribut1]?.label || ""
- item.system.attribut2label = this.system.attributs[item.system.attribut2]?.label || ""
- item.system.attribut3label = this.system.attributs[item.system.attribut3]?.label || ""
- comp.push(item)
- }
- }
- MournbladeCYD2Utility.sortArrayObjectsByName(comp)
- return comp
- }
-
- /* ----------------------- --------------------- */
- addMember(actorId) {
- let members = foundry.utils.duplicate(this.system.members)
- members.push({ id: actorId })
- this.update({ 'system.members': members })
- }
- async removeMember(actorId) {
- let members = this.system.members.filter(it => it.id != actorId)
- this.update({ 'system.members': members })
- }
-
- /* -------------------------------------------- */
- getDefenseBase() {
- return Math.max(this.system.attributs.tre.value, this.system.attributs.adr.value)
- }
-
- /* -------------------------------------------- */
- getVitesseBase() {
- return 5 + __vitesseBonus[this.system.attributs.adr.value]
- }
- /* -------------------------------------------- */
- getProtection() {
- let equipProtection = 0
- for (let armor of this.items) {
- if (armor.type == "protection" && armor.system.equipped) {
- equipProtection += Number(armor.system.protection)
- }
- }
- if (equipProtection < 4) {
- return 4 + equipProtection // Cas des boucliers + sans armure
- }
- return equipProtection // Uniquement la protection des armures + boucliers
- }
-
- /* -------------------------------------------- */
- getCombatValues() {
- let combat = {
- initBase: this.system.attributs.adr.value,
- initTotal: this.system.attributs.adr.value + this.system.combat.initbonus,
- bonusDegats: this.getBonusDegats(),
- bonusDegatsTotal: this.getBonusDegats() + this.system.combat.bonusdegats,
- vitesseBase: this.getVitesseBase(),
- vitesseTotal: this.getVitesseBase() + this.system.combat.vitessebonus,
- defenseBase: this.getDefenseBase(),
- protection: this.getProtection(),
- defenseTotal: this.getDefenseBase() + this.system.combat.defensebonus + this.getProtection() - this.getTotalAdversite() + (this.system.combat.defensetotale ? 3 : 0)
- }
- return combat
- }
-
- /* -------------------------------------------- */
- prepareBaseData() {
- }
-
- /* -------------------------------------------- */
- async prepareData() {
- super.prepareData();
- }
-
- /* -------------------------------------------- */
- prepareDerivedData() {
-
- if (this.type == 'personnage') {
- let talentBonus = this.getVigueurBonus()
- let vigueur = Math.floor((this.system.attributs.pui.value + this.system.attributs.tre.value) / 2) + talentBonus + this.system.sante.vigueurmodifier
- if (vigueur != this.system.sante.vigueur) {
- this.update({ 'system.sante.vigueur': vigueur })
- }
-
- let seuilPouvoirBonus = this.getSeuilPouvoirBonus()
- let seuilPouvoir = Math.floor((this.system.attributs.tre.value + this.system.attributs.cla.value) / 2) + seuilPouvoirBonus + this.system.ame.seuilpouvoirmodifier
- if (seuilPouvoir != this.system.ame.seuilpouvoir) {
- this.update({ 'system.ame.seuilpouvoir': seuilPouvoir })
- }
- }
- super.prepareDerivedData()
- }
-
- /* -------------------------------------------- */
- _preUpdate(changed, options, user) {
- if (changed?.system?.sante?.etat && changed?.system?.sante?.etat != this.system.sante.etat) {
- setTimeout(() => {
- this.processCombativite(changed.system.sante)
- }, 800)
- }
- if (changed?.system?.ame?.etat && changed?.system?.ame?.etat != this.system.ame.etat) {
- // L'état d'Âme ne peut pas être inférieur au minimum (max dans le système)
- let minAme = this.system.ame.max !== undefined ? this.system.ame.max : 0
- if (changed.system.ame.etat < minAme) {
- changed.system.ame.etat = minAme
- }
- // L'état d'Âme ne peut pas dépasser nbame (Brisé)
- if (changed.system.ame.etat > this.system.ame.nbame) {
- changed.system.ame.etat = this.system.ame.nbame
- }
- setTimeout(() => {
- this.processAme(changed.system.ame)
- }, 800)
- }
- // Si le max d'Âme change, ajuster l'état actuel si nécessaire
- if (changed?.system?.ame?.max !== undefined && changed.system.ame.max != this.system.ame.max) {
- if (this.system.ame.etat < changed.system.ame.max) {
- changed.system.ame.etat = changed.system.ame.max
- }
- }
- super._preUpdate(changed, options, user);
- }
-
- /* -------------------------------------------- */
- _onUpdate(data, options, user) {
- super._onUpdate(data, options, user);
- }
- /* -------------------------------------------- */
- getItemById(id) {
- let item = this.items.find(item => item.id == id);
- if (item) {
- item = foundry.utils.duplicate(item)
- }
- return item;
- }
-
- /* -------------------------------------------- */
- async equipItem(itemId) {
- let item = this.items.find(item => item.id == itemId)
- if (item && item.system) {
- let update = { _id: item.id, "system.equipped": !item.system.equipped }
- await this.updateEmbeddedDocuments('Item', [update]); // Updates one EmbeddedEntity
- }
- }
-
- /* -------------------------------------------- */
- editItemField(itemId, itemType, itemField, dataType, value) {
- let item = this.items.find(item => item.id == itemId)
- if (item) {
- console.log("Item ", item, itemField, dataType, value)
- if (dataType.toLowerCase() == "number") {
- value = Number(value)
- } else {
- value = String(value)
- }
- let update = { _id: item.id, [`system.${itemField}`]: value };
- this.updateEmbeddedDocuments("Item", [update])
- }
- }
-
- /* -------------------------------------------- */
- checkAttribut(attribut, minLevel) {
- let attr = this.system.attributs.find(at => at.labelnorm == attribut.toLowerCase())
- if (attr && attr.value >= minLevel) {
- return { isValid: true, attr: foundry.utils.duplicate(attr) }
- }
- return { isValid: false }
- }
- /* -------------------------------------------- */
- checkAttributOrCompetenceLevel(compName, minLevel) {
- let comp = this.items.find(i => i.type == "competence" && i.name.toLowerCase() == compName.toLowerCase() && i.system.niveau >= minLevel)
- if (comp) {
- return { isValid: true, item: foundry.utils.duplicate(comp) }
- } else {
- for (let attrKey in this.system.attributs) {
- if (this.system.attributs[attrKey].label.toLowerCase() == compName.toLowerCase() && this.system.attributs[attrKey].value >= minLevel) {
- return { isValid: true, item: foundry.utils.duplicate(this.system.attributs[attrKey]) }
- }
- }
- }
- return { isValid: false, warningMessage: `Prérequis insuffisant : la compétence/attribut ${compName} doit être de niveau ${minLevel} au minimum` }
- }
- /* -------------------------------------------- */
- addCompetenceBonus(compName, bonus, baCost) {
- let comp = this.items.find(i => i.type == "competence" && i.name.toLowerCase() == compName.toLowerCase())
- if (comp) {
- comp = foundry.utils.duplicate(comp)
- comp.system.bonus = bonus
- comp.system.baCost = baCost
- return { isValid: true, item: comp }
- }
- return { isValid: false, warningMessage: `Compétence ${compName} non trouvée` }
- }
- /* -------------------------------------------- */
- checkIfCompetence(compName) {
- let comp = this.items.find(i => i.type == "competence" && i.name.toLowerCase() == compName.toLowerCase())
- if (comp) {
- return { isValid: true, item: comp }
- }
- return { isValid: false }
- }
- /* -------------------------------------------- */
- getVigueur() {
- return this.system.sante.vigueur
- }
-
- /* -------------------------------------------- */
- getVigueurBonus() {
- let talents = this.items.filter(item => item.type == "talent" && item.system.isautomated)
- let bonus = 0
- for (let talent of talents) {
- for (let auto of talent.system.automations) {
- if (auto.eventtype == "bonus-permanent" && auto.bonusname == "vigueur") {
- bonus += Number(auto.bonus || 0)
- }
- }
- }
- return bonus
- }
-
- /* -------------------------------------------- */
- getSeuilPouvoir() {
- return this.system.ame.seuilpouvoir
- }
-
- /* -------------------------------------------- */
- getSeuilPouvoirBonus() {
- let talents = this.items.filter(item => item.type == "talent" && item.system.isautomated)
- let bonus = 0
- for (let talent of talents) {
- for (let auto of talent.system.automations) {
- if (auto.eventtype == "bonus-permanent" && auto.bonusname == "seuilpouvoir") {
- bonus += Number(auto.bonus || 0)
- }
- }
- }
- return bonus
- }
-
- /* -------------------------------------------- */
- getAmeMax() {
- // Utiliser une vérification stricte car 0 (Serein) est une valeur valide
- return this.system.ame.max !== undefined ? this.system.ame.max : this.system.ame.nbame
- }
-
- /* -------------------------------------------- */
- getBonneAventure() {
- return this.system.bonneaventure.actuelle
- }
- /* -------------------------------------------- */
- checkBonneAventure(cost) {
- return (this.system.bonneaventure.actuelle >= cost)
- }
- /* -------------------------------------------- */
- changeBonneAventure(value) {
- let newBA = this.system.bonneaventure.actuelle
- newBA += value
- this.update({ 'system.bonneaventure.actuelle': newBA })
- }
-
- /* -------------------------------------------- */
- getEclat() {
- return this.system.eclat.value
- }
-
- /* -------------------------------------------- */
- changeEclat(value) {
- let newE = this.system.eclat.value
- newE += value
- this.update({ 'system.eclat.value': newE })
- }
-
- /* -------------------------------------------- */
- compareName(a, b) {
- if (a.name < b.name) {
- return -1;
- }
- if (a.name > b.name) {
- return 1;
- }
- return 0;
- }
-
- /* -------------------------------------------- */
- getAttribute(attrKey) {
- return this.system.attributes[attrKey]
- }
-
- /* -------------------------------------------- */
- getBonusDegats() {
- return 0;
- }
-
- /* -------------------------------------------- */
- changeEtatCombativite(value) {
- if (value === "vaincu") {
- value = 200
- }
- let sante = foundry.utils.duplicate(this.system.sante)
- sante.etat += Number(value)
- sante.etat = Math.max(sante.etat, 0)
- sante.etat = Math.min(sante.etat, this.system.sante.nbcombativite)
- this.update({ 'system.sante': sante })
- if (sante.etat == this.system.sante.nbcombativite) {
- ChatMessage.create({ content: `${this.name} est vaincu !` })
- }
- // Duplicated ! this.processCombativite(sante)
- }
-
- /* -------------------------------------------- */
- changeEtatAme(value) {
- if (value === "brise") {
- value = 200
- }
- let ame = foundry.utils.duplicate(this.system.ame)
- ame.etat += Number(value)
- // L'état ne peut pas être inférieur au minimum (max dans le système)
- let minAme = this.system.ame.max !== undefined ? this.system.ame.max : 0
- ame.etat = Math.max(ame.etat, minAme)
- // L'état ne peut pas dépasser nbame (Brisé)
- ame.etat = Math.min(ame.etat, this.system.ame.nbame)
- this.update({ 'system.ame': ame })
- if (ame.etat >= this.system.ame.nbame) {
- ChatMessage.create({ content: `${this.name} est brisé !` })
- }
- }
-
- /* -------------------------------------------- */
- processCombativite(sante) {
- sante = sante || foundry.utils.duplicate(this.system.sante)
- // Gestion des états affaibli et très affaibli
- if (sante.etat == this.system.sante.nbcombativite - 2 || sante.etat == this.system.sante.nbcombativite - 1) {
- if (sante.etat == this.system.sante.nbcombativite - 2 && this.items.find(item => item.type == "talent" && item.name.toLowerCase() == "encaissement")) {
- ChatMessage.create({ content: `${this.name} ne subit pas les 2 adversités rouge grâce à Encaissement. Pensez à les ajouter à la fin de la scène !` })
- } else if (sante.etat == this.system.sante.nbcombativite - 1 && this.items.find(item => item.type == "talent" && item.name.toLowerCase().includes("vaillant"))) {
- ChatMessage.create({ content: `${this.name} ne subit pas les 2 adversités rouge grâce à Vaillant. Pensez à les ajouter à la fin de la scène !` })
- } else {
- ChatMessage.create({ content: `${this.name} subit 2 adversités rouge !` })
- this.incDecAdversite("rouge", 2)
- }
- }
- }
-
- /* -------------------------------------------- */
- processAme(ame) {
- ame = ame || foundry.utils.duplicate(this.system.ame)
- let traumatiseValue = this.system.ame.nbame - 2
- let tresTraumatiseValue = this.system.ame.nbame - 1
- let briseValue = this.system.ame.nbame
-
- // Gestion des états Traumatisé, Très Traumatisé et Brisé
- if (ame.etat == traumatiseValue) {
- ChatMessage.create({ content: `${this.name} est Traumatisé !` })
- } else if (ame.etat == tresTraumatiseValue) {
- ChatMessage.create({ content: `${this.name} est Très Traumatisé !` })
- } else if (ame.etat >= briseValue) {
- ChatMessage.create({ content: `${this.name} est Brisé !` })
- }
- }
-
- /* -------------------------------------------- */
- async equipGear(equipmentId) {
- let item = this.items.find(item => item.id == equipmentId);
- if (item?.system?.data) {
- let update = { _id: item.id, "system.equipped": !item.system.equipped };
- await this.updateEmbeddedDocuments('Item', [update]); // Updates one EmbeddedEntity
- }
- }
-
- /* -------------------------------------------- */
- getSubActors() {
- let subActors = [];
- for (let id of this.system.subactors) {
- subActors.push(foundry.utils.duplicate(game.actors.get(id)));
- }
- return subActors;
- }
- /* -------------------------------------------- */
- async addSubActor(subActorId) {
- let subActors = foundry.utils.duplicate(this.system.subactors);
- subActors.push(subActorId);
- await this.update({ 'system.subactors': subActors });
- }
- /* -------------------------------------------- */
- async delSubActor(subActorId) {
- let newArray = [];
- for (let id of this.system.subactors) {
- if (id != subActorId) {
- newArray.push(id);
- }
- }
- await this.update({ 'system.subactors': newArray });
- }
-
- /* -------------------------------------------- */
- getTotalAdversite() {
- return this.system.adversite.bleue + this.system.adversite.rouge + this.system.adversite.noire
- }
-
- /* -------------------------------------------- */
- async incDecAdversite(adv, incDec = 0) {
- let adversite = foundry.utils.duplicate(this.system.adversite)
- adversite[adv] += Number(incDec)
- adversite[adv] = Math.max(adversite[adv], 0)
- adversite[adv] = Math.min(adversite[adv], 20)
- this.update({ 'system.adversite': adversite })
- }
- /* -------------------------------------------- */
- async incDecQuantity(objetId, incDec = 0) {
- let objetQ = this.items.get(objetId)
- if (objetQ) {
- let newQ = objetQ.system.quantite + incDec
- newQ = Math.max(newQ, 0)
- await this.updateEmbeddedDocuments('Item', [{ _id: objetQ.id, 'system.quantite': newQ }]); // pdates one EmbeddedEntity
- }
- }
-
- /* -------------------------------------------- */
- computeRichesse() {
- let valueSC = 0
- for (let monnaie of this.items) {
- if (monnaie.type == "monnaie") {
- valueSC += Number(monnaie.system.prixsc) * Number(monnaie.system.quantite)
- }
- }
- return MournbladeCYD2Utility.computeMonnaieDetails(valueSC)
- }
-
- /* -------------------------------------------- */
- computeValeurEquipement() {
- let valueSC = 0
- for (let equip of this.items) {
- if (equip.type == "equipement" || equip.type == "arme" || equip.type == "protection") {
- valueSC += Number(equip.system.prixsc) * Number(equip.system.quantite ?? 1)
- valueSC += (Number(equip.system.prixca) * Number(equip.system.quantite ?? 1)) * 20
- valueSC += (Number(equip.system.prixpo) * Number(equip.system.quantite ?? 1)) * 400
- }
- }
- return MournbladeCYD2Utility.computeMonnaieDetails(valueSC)
- }
-
- /* -------------------------------------------- */
- getCompetence(compId) {
- return this.items.get(compId)
- }
-
- /* -------------------------------------------- */
- async setPredilectionUsed(compId, predIdx) {
- let comp = this.items.get(compId)
- let pred = foundry.utils.duplicate(comp.system.predilections)
- pred[predIdx].used = true
- await this.updateEmbeddedDocuments('Item', [{ _id: compId, 'system.predilections': pred }])
- }
-
- /* -------------------------------------------- */
- getInitiativeScore() {
- let init = this.getFlag("world", "last-initiative")
- return init || -1
- }
-
- /* -------------------------------------------- */
- getBestAttackValue() {
- let attackList = this.items.filter(item => (item.type == "arme" || item.type == "talent") && item.system.equipped)
- let maxOff = 0
- let bestArme
- for (let arme of attackList) {
- if (arme.type == "arme") {
- arme = this.prepareArme(arme)
- }
- if (arme.system.totalOffensif > maxOff) {
- maxOff = arme.system.totalOffensif
- bestArme = foundry.utils.duplicate(arme)
- }
- }
- return bestArme
- }
-
- /* -------------------------------------------- */
- getBestDefenseValue() {
- let defenseList = this.items.filter(item => (item.type == "arme") && item.system.equipped)
- let maxDef = 0
- let bestArme
- for (let arme of defenseList) {
- if (arme.type == "arme") {
- arme = this.prepareArme(arme)
- }
- if (arme.system.totalDefensif > maxDef) {
- maxDef = arme.system.totalDefensif
- bestArme = foundry.utils.duplicate(arme)
- }
- }
- return bestArme
- }
-
- /* -------------------------------------------- */
- searchRelevantTalents(competence) {
- let talents = []
-
- for (let talent of this.items) {
- if (talent.type == "talent" && talent.system.isautomated && talent.system.automations.length > 0) {
- for (let auto of talent.system.automations) {
- if (auto.eventtype === "prepare-roll") {
- if (auto.competence.toLowerCase() == competence.name.toLowerCase()) {
- talent = foundry.utils.duplicate(talent)
- talent.system.bonus = auto.bonus
- talent.system.baCost = auto.baCost
- talents.push(talent)
- }
- }
- }
- }
- }
- return talents
- }
-
- /* -------------------------------------------- */
- buildListeAdversites() {
- return []
- }
-
- /* -------------------------------------------- */
- getCommonRollData(attrKey = undefined, compId = undefined, compName = undefined) {
- let rollData = MournbladeCYD2Utility.getBasicRollData()
- rollData.alias = this.name
- rollData.actorImg = this.img
- rollData.actorId = this.id
- rollData.tokenId = this.token?.id
- rollData.img = this.img
- rollData.attributs = MournbladeCYD2Utility.getAttributs()
- rollData.maitriseId = "none"
- rollData.nbEclat = this.system.eclat.value
- rollData.nbBA = this.system.bonneaventure.actuelle
- rollData.nbAdversites = this.getTotalAdversite()
- rollData.talents = []
- rollData.attrKey2 = "none"
- rollData.coupDevastateur = this.items.find(it => it.type == "talent" && it.name.toLowerCase() == "coup dévastateur" && !it.system.used)
- rollData.hasAmbidextre = this.items.find(it => it.type == "talent" && it.name.toLowerCase() == "ambidextre")
- rollData.hasFeinte = this.system.bonneaventure.actuelle > 0 && this.items.find(it => it.type == "talent" && it.name.toLowerCase() == "feinte")
- rollData.isMonte = this.system.combat.monte
- rollData.config = game.system.mournbladecyd2.config
-
- if (attrKey) {
- rollData.attrKey = attrKey
- if (attrKey != "tochoose") {
- rollData.actionImg = "systems/fvtt-mournblade-cyd2/assets/icons/" + this.system.attributs[attrKey].labelnorm + ".webp"
- rollData.attr = foundry.utils.duplicate(this.system.attributs[attrKey])
- }
- }
- if (compId) {
- rollData.competence = foundry.utils.duplicate(this.items.get(compId) || {})
- let maitrises = [{ key: "none", label: "Aucune" }]
- rollData.competence.system.predilections.forEach(function (item) {
- if (item.maitrise) {
- maitrises.push({ key: item.id, label: item.name });
- }
- })
- rollData.maitrises = maitrises // rollData.competence.system.predilections.filter(p => p.maitrise)
- rollData.actionImg = rollData.competence?.img
- rollData.talents = this.searchRelevantTalents(rollData.competence)
- }
- if (compName) {
- rollData.competence = foundry.utils.duplicate(this.items.find(item => item.name.toLowerCase() == compName.toLowerCase()) || {})
- rollData.actionImg = rollData.competence?.img
- }
- return rollData
- }
-
- /* -------------------------------------------- */
- async rollAttribut(attrKey, isInit = false) {
- let rollData = this.getCommonRollData(attrKey)
- rollData.multiplier = (isInit) ? 1 : 2
- rollData.isInit = isInit
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
-
- /* -------------------------------------------- */
- async rollCompetence(attrKey, compId) {
- let rollData = this.getCommonRollData(attrKey, compId)
- rollData.multiplier = 1 // Attr multiplier, always 1 in competence mode
- console.log("RollDatra", rollData)
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
-
- /* -------------------------------------------- */
- async rollArmeOffensif(armeId) {
- let arme = this.items.get(armeId)
- if (arme.type == "arme") {
- arme = this.prepareArme(arme)
- }
- let rollData = this.getCommonRollData(arme.system.attrKey, arme.system.competence._id)
- rollData.arme = arme
- MournbladeCYD2Utility.updateWithTarget(rollData)
- console.log("ARME!", rollData)
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
- /* -------------------------------------------- */
- async rollAssommer() {
- let rollData = this.getCommonRollData("pui", undefined, "Filouterie")
- rollData.assomer = true
- rollData.conditionsCommunes = true
- MournbladeCYD2Utility.updateWithTarget(rollData)
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
- /* -------------------------------------------- */
- async rollCoupBas() {
- let rollData = this.getCommonRollData("pui", undefined, "Mêlée")
- rollData.coupBas = true
- rollData.conditionsCommunes = true
- MournbladeCYD2Utility.updateWithTarget(rollData)
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
- /* -------------------------------------------- */
- async rollImmobiliser() {
- let rollData = this.getCommonRollData("pui", undefined, "Mêlée")
- rollData.immobiliser = true
- rollData.conditionsCommunes = true
- rollData.cibleconsciente = true
- MournbladeCYD2Utility.updateWithTarget(rollData)
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
- /* -------------------------------------------- */
- async rollRepousser() {
- let rollData = this.getCommonRollData("pui", undefined, "Mêlée")
- rollData.repousser = true
- rollData.conditionsCommunes = true
- rollData.cibleconsciente = true
- MournbladeCYD2Utility.updateWithTarget(rollData)
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
- /* -------------------------------------------- */
- async rollDesengager() {
- let rollData = this.getCommonRollData("adr", undefined, "Mouvements")
- rollData.desengager = true
- rollData.conditionsCommunes = true
- MournbladeCYD2Utility.updateWithTarget(rollData)
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
-
- /* -------------------------------------------- */
- async rollArmeDegats(armeId, targetVigueur = undefined, rollDataInput = undefined) {
- let arme = this.items.get(armeId)
- if (arme.type == "arme") {
- arme = this.prepareArme(arme)
- }
- console.log("DEGATS", arme, targetVigueur, rollDataInput)
- let roll
- let bonus = 0
- let bonus2 = 0
-
- if (rollDataInput?.applyCoupDevastateur) {
- bonus2 = Math.floor(this.system.attributs.pui.value / 2)
- let talent = this.items.find(item => item.type == "talent" && item.name.toLowerCase() == "coup dévastateur")
- this.updateEmbeddedDocuments('Item', [{ _id: talent.id, 'system.used': true }])
- }
-
- if (rollDataInput?.isHeroique) {
- if (rollDataInput?.attaqueCharge) {
- bonus = 5
- }
- if (rollDataInput?.chargeCavalerie) {
- bonus = 6
- }
- roll = await new Roll("2d10rr10+" + arme.system.totalDegats + "+" + bonus + "+" + bonus2).roll()
- } else {
- if (rollDataInput?.attaqueCharge) {
- bonus = 3
- }
- if (rollDataInput?.chargeCavalerie) {
- bonus = 4
- }
- roll = await new Roll("1d10+" + arme.system.totalDegats + "+" + bonus + "+" + bonus2).roll()
- }
- await MournbladeCYD2Utility.showDiceSoNice(roll, game.settings.get("core", "rollMode"));
- let nbEtatPerdus = 0
- if (targetVigueur) {
- nbEtatPerdus = Math.floor(roll.total / targetVigueur)
- }
- //console.log(roll)
- let rollData = {
- arme: arme,
- finalResult: roll.total,
- formula: roll.formula,
- alias: this.name,
- actorImg: this.img,
- actorId: this.id,
- defenderTokenId: rollDataInput?.defenderTokenId,
- actionImg: arme.img,
- targetVigueur: targetVigueur,
- nbEtatPerdus: nbEtatPerdus
- }
- MournbladeCYD2Utility.createChatWithRollMode(rollData.alias, {
- content: await renderTemplate(`systems/fvtt-mournblade-cyd2/templates/chat-degats-result.html`, rollData)
- })
-
- if (rollDataInput?.defenderTokenId && nbEtatPerdus) {
- MournbladeCYD2Utility.applyCombativite(rollDataInput, nbEtatPerdus)
- }
-
- }
-}
diff --git a/.history/modules/mournblade-cyd2-actor_20251026100634.js b/.history/modules/mournblade-cyd2-actor_20251026100634.js
deleted file mode 100644
index a2c5c87..0000000
--- a/.history/modules/mournblade-cyd2-actor_20251026100634.js
+++ /dev/null
@@ -1,895 +0,0 @@
-/* -------------------------------------------- */
-import { MournbladeCYD2Utility } from "./mournblade-cyd2-utility.js";
-import { MournbladeCYD2RollDialog } from "./mournblade-cyd2-roll-dialog.js";
-
-/* -------------------------------------------- */
-const __degatsBonus = [-2, -2, -1, -1, 0, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 8, 8, 9, 9, 10, 10]
-const __vitesseBonus = [-2, -2, -1, -1, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8]
-
-/* -------------------------------------------- */
-/**
- * Extend the base Actor entity by defining a custom roll data structure which is ideal for the Simple system.
- * @extends {Actor}
- */
-export class MournbladeCYD2Actor extends Actor {
-
- /* -------------------------------------------- */
- /**
- * Override the create() function to provide additional SoS functionality.
- *
- * This overrided create() function adds initial items
- * Namely: Basic skills, money,
- *
- * @param {Object} data Barebones actor data which this function adds onto.
- * @param {Object} options (Unused) Additional options which customize the creation workflow.
- *
- */
-
- static async create(data, options) {
-
- // Case of compendium global import
- if (data instanceof Array) {
- return super.create(data, options);
- }
- // If the created actor has items (only applicable to duplicated actors) bypass the new actor creation logic
- if (data.items) {
- let actor = super.create(data, options);
- return actor;
- }
-
- if (data.type == 'personnage') {
- const skills = await MournbladeCYD2Utility.loadCompendium("fvtt-mournblade-cyd2.skills")
- data.items = skills.map(i => i.toObject())
- }
- if (data.type == 'creature') {
- const skills = await MournbladeCYD2Utility.loadCompendium("fvtt-mournblade-cyd2.skills-creatures")
- data.items = skills.map(i => i.toObject())
- data.items.push({ name: "Arme naturelle 1", type: 'arme', img: "systems/fvtt-mournblade-cyd2/assets/icons/melee.webp", system: { typearme: "contact", bonusmaniementoff: 0, seuildefense: 0, degats: "0" } })
- data.items.push({ name: "Arme naturelle 2", type: 'arme', img: "systems/fvtt-mournblade-cyd2/assets/icons/melee.webp", system: { typearme: "contact", bonusmaniementoff: 0, seuildefense: 0, degats: "0" } })
- }
-
- return super.create(data, options);
- }
-
- /* -------------------------------------------- */
- getBonusDefenseFromTalents() {
- let talents = this.items.filter(item => item.type == "talent" && item.system.isautomated)
- let bonus = 0
- for (let talent of talents) {
- for (let auto of talent.system.automations) {
- if (auto.eventtype == "bonus-permanent" && auto.bonusname == "bonus-defensif") {
- bonus += Number(auto.bonus || 0)
- }
- }
- }
- return bonus
- }
-
- /* -------------------------------------------- */
- prepareArme(arme) {
- arme = foundry.utils.duplicate(arme)
- let combat = this.getCombatValues()
- if (arme.system.typearme == "contact" || arme.system.typearme == "contactjet") {
- let bonusDefense = this.getBonusDefenseFromTalents()
- arme.system.competence = foundry.utils.duplicate(this.items.find(item => item.type == "competence" && item.name.toLowerCase() == "mêlée"))
- arme.system.attrKey = "pui"
- arme.system.totalDegats = arme.system.degats + "+" + combat.bonusDegatsTotal
- arme.system.totalOffensif = this.system.attributs.pui.value + arme.system.competence.system.niveau + arme.system.bonusmaniementoff + (this.system.combat.monte ? 3 : 0)
- arme.system.totalDefensif = combat.defenseTotal + arme.system.competence.system.niveau + arme.system.seuildefense + bonusDefense + (this.system.combat.monte ? 3 : 0)
- console.log("Arme", arme.system.totalDefensif, combat, arme.system.competence.system.niveau, arme.system.seuildefense, bonusDefense)
- arme.system.isdefense = true
- arme.system.isMelee = true
- arme.system.isDistance = false
- }
- if (arme.system.typearme == "jet" || arme.system.typearme == "tir") {
- arme.system.competence = foundry.utils.duplicate(this.items.find(item => item.type == "competence" && item.name.toLowerCase() == "armes à distance"))
- arme.system.attrKey = "adr"
- arme.system.totalOffensif = this.system.attributs.adr.value + arme.system.competence.system.niveau + arme.system.bonusmaniementoff
- arme.system.totalDegats = arme.system.degats
- arme.system.isMelee = false
- arme.system.isDistance = true
- if (arme.system.isdefense) {
- arme.system.totalDefensif = combat.defenseTotal + arme.system.competence.system.niveau + arme.system.seuildefense
- }
- }
- return arme
- }
-
- /* -------------------------------------------- */
- getItemSorted(types) {
- let items = this.items.filter(item => types.includes(item.type)) || []
- MournbladeCYD2Utility.sortArrayObjectsByName(items)
- return items
- }
- getWeapons() {
- let armes = []
- for (let arme of this.items) {
- if (arme.type == "arme") {
- armes.push(this.prepareArme(arme))
- }
- }
- MournbladeCYD2Utility.sortArrayObjectsByName(armes)
- return armes
- }
- getMonnaies() {
- return this.getItemSorted(["monnaie"])
- }
- getEquipments() {
- return this.getItemSorted(["equipement"])
- }
- getArtefacts() {
- return this.getItemSorted(["artefact"])
- }
- getArmors() {
- return this.getItemSorted(["protection"])
- }
- getHistoriques() {
- return this.getItemSorted(["historique"])
- }
- getProfils() {
- return this.getItemSorted(["profil"])
- }
- getTalents() {
- return this.getItemSorted(["talent"])
- }
- getRessources() {
- return this.getItemSorted(["ressource"])
- }
- getContacts() {
- return this.getItemSorted(["contact"])
- }
- getMutations() {
- return this.getItemSorted(["mutation"])
- }
- getDons() {
- return this.getItemSorted(["don"])
- }
- getPactes() {
- return this.getItemSorted(["pacte"])
- }
- getTendances() {
- return this.getItemSorted(["tendance"])
- }
- getRunes() {
- return this.getItemSorted(["rune"])
- }
- getTraitsChaotiques() {
- return this.getItemSorted(["traitchaotique"])
- }
- getTraitsEspeces() {
- return this.getItemSorted(["traitespece"])
- }
-
- /* -------------------------------------------- */
- getAspect() {
- return (this.system.balance.loi > this.system.balance.chaos) ? this.system.balance.loi : this.system.balance.chaos
- }
- getMarge() {
- return Math.abs(this.system.balance.loi - this.system.balance.chaos)
- }
- getAlignement() {
- return (this.system.balance.loi > this.system.balance.chaos) ? "loyal" : "chaotique"
- }
-
- /* -------------------------------------------- */
- getSkills() {
- let comp = []
- for (let item of this.items) {
- item = foundry.utils.duplicate(item)
- if (item.type == "competence") {
- item.system.attribut1total = item.system.niveau + (this.system.attributs[item.system.attribut1]?.value || 0)
- item.system.attribut2total = item.system.niveau + (this.system.attributs[item.system.attribut2]?.value || 0)
- item.system.attribut3total = item.system.niveau + (this.system.attributs[item.system.attribut3]?.value || 0)
- if (item.system.niveau == 0) {
- item.system.attribut1total -= 3
- item.system.attribut2total -= 3
- item.system.attribut3total -= 3
- }
- item.system.attribut1label = this.system.attributs[item.system.attribut1]?.label || ""
- item.system.attribut2label = this.system.attributs[item.system.attribut2]?.label || ""
- item.system.attribut3label = this.system.attributs[item.system.attribut3]?.label || ""
- comp.push(item)
- }
- }
- MournbladeCYD2Utility.sortArrayObjectsByName(comp)
- return comp
- }
-
- /* ----------------------- --------------------- */
- addMember(actorId) {
- let members = foundry.utils.duplicate(this.system.members)
- members.push({ id: actorId })
- this.update({ 'system.members': members })
- }
- async removeMember(actorId) {
- let members = this.system.members.filter(it => it.id != actorId)
- this.update({ 'system.members': members })
- }
-
- /* -------------------------------------------- */
- getDefenseBase() {
- return Math.max(this.system.attributs.tre.value, this.system.attributs.adr.value)
- }
-
- /* -------------------------------------------- */
- getVitesseBase() {
- return 5 + __vitesseBonus[this.system.attributs.adr.value]
- }
- /* -------------------------------------------- */
- getProtection() {
- let equipProtection = 0
- for (let armor of this.items) {
- if (armor.type == "protection" && armor.system.equipped) {
- equipProtection += Number(armor.system.protection)
- }
- }
- if (equipProtection < 4) {
- return 4 + equipProtection // Cas des boucliers + sans armure
- }
- return equipProtection // Uniquement la protection des armures + boucliers
- }
-
- /* -------------------------------------------- */
- getCombatValues() {
- let combat = {
- initBase: this.system.attributs.adr.value,
- initTotal: this.system.attributs.adr.value + this.system.combat.initbonus,
- bonusDegats: this.getBonusDegats(),
- bonusDegatsTotal: this.getBonusDegats() + this.system.combat.bonusdegats,
- vitesseBase: this.getVitesseBase(),
- vitesseTotal: this.getVitesseBase() + this.system.combat.vitessebonus,
- defenseBase: this.getDefenseBase(),
- protection: this.getProtection(),
- defenseTotal: this.getDefenseBase() + this.system.combat.defensebonus + this.getProtection() - this.getTotalAdversite() + (this.system.combat.defensetotale ? 3 : 0)
- }
- return combat
- }
-
- /* -------------------------------------------- */
- prepareBaseData() {
- }
-
- /* -------------------------------------------- */
- async prepareData() {
- super.prepareData();
- }
-
- /* -------------------------------------------- */
- prepareDerivedData() {
-
- if (this.type == 'personnage') {
- let talentBonus = this.getVigueurBonus()
- let vigueur = Math.floor((this.system.attributs.pui.value + this.system.attributs.tre.value) / 2) + talentBonus + this.system.sante.vigueurmodifier
- if (vigueur != this.system.sante.vigueur) {
- this.update({ 'system.sante.vigueur': vigueur })
- }
-
- let seuilPouvoirBonus = this.getSeuilPouvoirBonus()
- let seuilPouvoir = Math.floor((this.system.attributs.tre.value + this.system.attributs.cla.value) / 2) + seuilPouvoirBonus + this.system.ame.seuilpouvoirmodifier
- if (seuilPouvoir != this.system.ame.seuilpouvoir) {
- this.update({ 'system.ame.seuilpouvoir': seuilPouvoir })
- }
- }
- super.prepareDerivedData()
- }
-
- /* -------------------------------------------- */
- _preUpdate(changed, options, user) {
- if (changed?.system?.sante?.etat && changed?.system?.sante?.etat != this.system.sante.etat) {
- setTimeout(() => {
- this.processCombativite(changed.system.sante)
- }, 800)
- }
- if (changed?.system?.ame?.etat && changed?.system?.ame?.etat != this.system.ame.etat) {
- // L'état d'Âme ne peut pas être inférieur au minimum (max dans le système)
- let minAme = this.system.ame.max !== undefined ? this.system.ame.max : 0
- if (changed.system.ame.etat < minAme) {
- changed.system.ame.etat = minAme
- }
- // L'état d'Âme ne peut pas dépasser nbame (Brisé)
- if (changed.system.ame.etat > this.system.ame.nbame) {
- changed.system.ame.etat = this.system.ame.nbame
- }
- setTimeout(() => {
- this.processAme(changed.system.ame)
- }, 800)
- }
- // Si le max d'Âme change, ajuster l'état actuel si nécessaire
- if (changed?.system?.ame?.max !== undefined && changed.system.ame.max != this.system.ame.max) {
- if (this.system.ame.etat < changed.system.ame.max) {
- changed.system.ame.etat = changed.system.ame.max
- }
- }
- super._preUpdate(changed, options, user);
- }
-
- /* -------------------------------------------- */
- _onUpdate(data, options, user) {
- super._onUpdate(data, options, user);
- }
- /* -------------------------------------------- */
- getItemById(id) {
- let item = this.items.find(item => item.id == id);
- if (item) {
- item = foundry.utils.duplicate(item)
- }
- return item;
- }
-
- /* -------------------------------------------- */
- async equipItem(itemId) {
- let item = this.items.find(item => item.id == itemId)
- if (item && item.system) {
- let update = { _id: item.id, "system.equipped": !item.system.equipped }
- await this.updateEmbeddedDocuments('Item', [update]); // Updates one EmbeddedEntity
- }
- }
-
- /* -------------------------------------------- */
- editItemField(itemId, itemType, itemField, dataType, value) {
- let item = this.items.find(item => item.id == itemId)
- if (item) {
- console.log("Item ", item, itemField, dataType, value)
- if (dataType.toLowerCase() == "number") {
- value = Number(value)
- } else {
- value = String(value)
- }
- let update = { _id: item.id, [`system.${itemField}`]: value };
- this.updateEmbeddedDocuments("Item", [update])
- }
- }
-
- /* -------------------------------------------- */
- checkAttribut(attribut, minLevel) {
- let attr = this.system.attributs.find(at => at.labelnorm == attribut.toLowerCase())
- if (attr && attr.value >= minLevel) {
- return { isValid: true, attr: foundry.utils.duplicate(attr) }
- }
- return { isValid: false }
- }
- /* -------------------------------------------- */
- checkAttributOrCompetenceLevel(compName, minLevel) {
- let comp = this.items.find(i => i.type == "competence" && i.name.toLowerCase() == compName.toLowerCase() && i.system.niveau >= minLevel)
- if (comp) {
- return { isValid: true, item: foundry.utils.duplicate(comp) }
- } else {
- for (let attrKey in this.system.attributs) {
- if (this.system.attributs[attrKey].label.toLowerCase() == compName.toLowerCase() && this.system.attributs[attrKey].value >= minLevel) {
- return { isValid: true, item: foundry.utils.duplicate(this.system.attributs[attrKey]) }
- }
- }
- }
- return { isValid: false, warningMessage: `Prérequis insuffisant : la compétence/attribut ${compName} doit être de niveau ${minLevel} au minimum` }
- }
- /* -------------------------------------------- */
- addCompetenceBonus(compName, bonus, baCost) {
- let comp = this.items.find(i => i.type == "competence" && i.name.toLowerCase() == compName.toLowerCase())
- if (comp) {
- comp = foundry.utils.duplicate(comp)
- comp.system.bonus = bonus
- comp.system.baCost = baCost
- return { isValid: true, item: comp }
- }
- return { isValid: false, warningMessage: `Compétence ${compName} non trouvée` }
- }
- /* -------------------------------------------- */
- checkIfCompetence(compName) {
- let comp = this.items.find(i => i.type == "competence" && i.name.toLowerCase() == compName.toLowerCase())
- if (comp) {
- return { isValid: true, item: comp }
- }
- return { isValid: false }
- }
- /* -------------------------------------------- */
- getVigueur() {
- return this.system.sante.vigueur
- }
-
- /* -------------------------------------------- */
- getVigueurBonus() {
- let talents = this.items.filter(item => item.type == "talent" && item.system.isautomated)
- let bonus = 0
- for (let talent of talents) {
- for (let auto of talent.system.automations) {
- if (auto.eventtype == "bonus-permanent" && auto.bonusname == "vigueur") {
- bonus += Number(auto.bonus || 0)
- }
- }
- }
- return bonus
- }
-
- /* -------------------------------------------- */
- getSeuilPouvoir() {
- return this.system.ame.seuilpouvoir
- }
-
- /* -------------------------------------------- */
- getSeuilPouvoirBonus() {
- let talents = this.items.filter(item => item.type == "talent" && item.system.isautomated)
- let bonus = 0
- for (let talent of talents) {
- for (let auto of talent.system.automations) {
- if (auto.eventtype == "bonus-permanent" && auto.bonusname == "seuilpouvoir") {
- bonus += Number(auto.bonus || 0)
- }
- }
- }
- return bonus
- }
-
- /* -------------------------------------------- */
- getAmeMax() {
- // Utiliser une vérification stricte car 0 (Serein) est une valeur valide
- return this.system.ame.max !== undefined ? this.system.ame.max : this.system.ame.nbame
- }
-
- /* -------------------------------------------- */
- getBonneAventure() {
- return this.system.bonneaventure.actuelle
- }
- /* -------------------------------------------- */
- checkBonneAventure(cost) {
- return (this.system.bonneaventure.actuelle >= cost)
- }
- /* -------------------------------------------- */
- changeBonneAventure(value) {
- let newBA = this.system.bonneaventure.actuelle
- newBA += value
- this.update({ 'system.bonneaventure.actuelle': newBA })
- }
-
- /* -------------------------------------------- */
- getEclat() {
- return this.system.eclat.value
- }
-
- /* -------------------------------------------- */
- changeEclat(value) {
- let newE = this.system.eclat.value
- newE += value
- this.update({ 'system.eclat.value': newE })
- }
-
- /* -------------------------------------------- */
- compareName(a, b) {
- if (a.name < b.name) {
- return -1;
- }
- if (a.name > b.name) {
- return 1;
- }
- return 0;
- }
-
- /* -------------------------------------------- */
- getAttribute(attrKey) {
- return this.system.attributes[attrKey]
- }
-
- /* -------------------------------------------- */
- getBonusDegats() {
- return 0;
- }
-
- /* -------------------------------------------- */
- changeEtatCombativite(value) {
- if (value === "vaincu") {
- value = 200
- }
- let sante = foundry.utils.duplicate(this.system.sante)
- sante.etat += Number(value)
- sante.etat = Math.max(sante.etat, 0)
- sante.etat = Math.min(sante.etat, this.system.sante.nbcombativite)
- this.update({ 'system.sante': sante })
- if (sante.etat == this.system.sante.nbcombativite) {
- ChatMessage.create({ content: `${this.name} est vaincu !` })
- }
- // Duplicated ! this.processCombativite(sante)
- }
-
- /* -------------------------------------------- */
- changeEtatAme(value) {
- if (value === "brise") {
- value = 200
- }
- let ame = foundry.utils.duplicate(this.system.ame)
- ame.etat += Number(value)
- // L'état ne peut pas être inférieur au minimum (max dans le système)
- let minAme = this.system.ame.max !== undefined ? this.system.ame.max : 0
- ame.etat = Math.max(ame.etat, minAme)
- // L'état ne peut pas dépasser nbame (Brisé)
- ame.etat = Math.min(ame.etat, this.system.ame.nbame)
- this.update({ 'system.ame': ame })
- if (ame.etat >= this.system.ame.nbame) {
- ChatMessage.create({ content: `${this.name} est brisé !` })
- }
- }
-
- /* -------------------------------------------- */
- processCombativite(sante) {
- sante = sante || foundry.utils.duplicate(this.system.sante)
- // Gestion des états affaibli et très affaibli
- if (sante.etat == this.system.sante.nbcombativite - 2 || sante.etat == this.system.sante.nbcombativite - 1) {
- if (sante.etat == this.system.sante.nbcombativite - 2 && this.items.find(item => item.type == "talent" && item.name.toLowerCase() == "encaissement")) {
- ChatMessage.create({ content: `${this.name} ne subit pas les 2 adversités rouge grâce à Encaissement. Pensez à les ajouter à la fin de la scène !` })
- } else if (sante.etat == this.system.sante.nbcombativite - 1 && this.items.find(item => item.type == "talent" && item.name.toLowerCase().includes("vaillant"))) {
- ChatMessage.create({ content: `${this.name} ne subit pas les 2 adversités rouge grâce à Vaillant. Pensez à les ajouter à la fin de la scène !` })
- } else {
- ChatMessage.create({ content: `${this.name} subit 2 adversités rouge !` })
- this.incDecAdversite("rouge", 2)
- }
- }
- }
-
- /* -------------------------------------------- */
- processAme(ame) {
- ame = ame || foundry.utils.duplicate(this.system.ame)
- let traumatiseValue = this.system.ame.nbame - 2
- let tresTraumatiseValue = this.system.ame.nbame - 1
- let briseValue = this.system.ame.nbame
-
- // Gestion des états Traumatisé, Très Traumatisé et Brisé
- if (ame.etat == traumatiseValue) {
- ChatMessage.create({ content: `${this.name} est Traumatisé et subit 1 adversité bleue et 1 adversité noire !` })
- this.incDecAdversite("bleue", 1)
- this.incDecAdversite("noire", 1)
- } else if (ame.etat == tresTraumatiseValue) {
- ChatMessage.create({ content: `${this.name} est Très Traumatisé et subit 1 adversité bleue et 1 adversité noire !` })
- this.incDecAdversite("bleue", 1)
- this.incDecAdversite("noire", 1)
- } else if (ame.etat >= briseValue) {
- ChatMessage.create({ content: `${this.name} est Brisé et subit 1 adversité noire !` })
- this.incDecAdversite("noire", 1)
- }
- }
-
- /* -------------------------------------------- */
- async equipGear(equipmentId) {
- let item = this.items.find(item => item.id == equipmentId);
- if (item?.system?.data) {
- let update = { _id: item.id, "system.equipped": !item.system.equipped };
- await this.updateEmbeddedDocuments('Item', [update]); // Updates one EmbeddedEntity
- }
- }
-
- /* -------------------------------------------- */
- getSubActors() {
- let subActors = [];
- for (let id of this.system.subactors) {
- subActors.push(foundry.utils.duplicate(game.actors.get(id)));
- }
- return subActors;
- }
- /* -------------------------------------------- */
- async addSubActor(subActorId) {
- let subActors = foundry.utils.duplicate(this.system.subactors);
- subActors.push(subActorId);
- await this.update({ 'system.subactors': subActors });
- }
- /* -------------------------------------------- */
- async delSubActor(subActorId) {
- let newArray = [];
- for (let id of this.system.subactors) {
- if (id != subActorId) {
- newArray.push(id);
- }
- }
- await this.update({ 'system.subactors': newArray });
- }
-
- /* -------------------------------------------- */
- getTotalAdversite() {
- return this.system.adversite.bleue + this.system.adversite.rouge + this.system.adversite.noire
- }
-
- /* -------------------------------------------- */
- async incDecAdversite(adv, incDec = 0) {
- let adversite = foundry.utils.duplicate(this.system.adversite)
- adversite[adv] += Number(incDec)
- adversite[adv] = Math.max(adversite[adv], 0)
- adversite[adv] = Math.min(adversite[adv], 20)
- this.update({ 'system.adversite': adversite })
- }
- /* -------------------------------------------- */
- async incDecQuantity(objetId, incDec = 0) {
- let objetQ = this.items.get(objetId)
- if (objetQ) {
- let newQ = objetQ.system.quantite + incDec
- newQ = Math.max(newQ, 0)
- await this.updateEmbeddedDocuments('Item', [{ _id: objetQ.id, 'system.quantite': newQ }]); // pdates one EmbeddedEntity
- }
- }
-
- /* -------------------------------------------- */
- computeRichesse() {
- let valueSC = 0
- for (let monnaie of this.items) {
- if (monnaie.type == "monnaie") {
- valueSC += Number(monnaie.system.prixsc) * Number(monnaie.system.quantite)
- }
- }
- return MournbladeCYD2Utility.computeMonnaieDetails(valueSC)
- }
-
- /* -------------------------------------------- */
- computeValeurEquipement() {
- let valueSC = 0
- for (let equip of this.items) {
- if (equip.type == "equipement" || equip.type == "arme" || equip.type == "protection") {
- valueSC += Number(equip.system.prixsc) * Number(equip.system.quantite ?? 1)
- valueSC += (Number(equip.system.prixca) * Number(equip.system.quantite ?? 1)) * 20
- valueSC += (Number(equip.system.prixpo) * Number(equip.system.quantite ?? 1)) * 400
- }
- }
- return MournbladeCYD2Utility.computeMonnaieDetails(valueSC)
- }
-
- /* -------------------------------------------- */
- getCompetence(compId) {
- return this.items.get(compId)
- }
-
- /* -------------------------------------------- */
- async setPredilectionUsed(compId, predIdx) {
- let comp = this.items.get(compId)
- let pred = foundry.utils.duplicate(comp.system.predilections)
- pred[predIdx].used = true
- await this.updateEmbeddedDocuments('Item', [{ _id: compId, 'system.predilections': pred }])
- }
-
- /* -------------------------------------------- */
- getInitiativeScore() {
- let init = this.getFlag("world", "last-initiative")
- return init || -1
- }
-
- /* -------------------------------------------- */
- getBestAttackValue() {
- let attackList = this.items.filter(item => (item.type == "arme" || item.type == "talent") && item.system.equipped)
- let maxOff = 0
- let bestArme
- for (let arme of attackList) {
- if (arme.type == "arme") {
- arme = this.prepareArme(arme)
- }
- if (arme.system.totalOffensif > maxOff) {
- maxOff = arme.system.totalOffensif
- bestArme = foundry.utils.duplicate(arme)
- }
- }
- return bestArme
- }
-
- /* -------------------------------------------- */
- getBestDefenseValue() {
- let defenseList = this.items.filter(item => (item.type == "arme") && item.system.equipped)
- let maxDef = 0
- let bestArme
- for (let arme of defenseList) {
- if (arme.type == "arme") {
- arme = this.prepareArme(arme)
- }
- if (arme.system.totalDefensif > maxDef) {
- maxDef = arme.system.totalDefensif
- bestArme = foundry.utils.duplicate(arme)
- }
- }
- return bestArme
- }
-
- /* -------------------------------------------- */
- searchRelevantTalents(competence) {
- let talents = []
-
- for (let talent of this.items) {
- if (talent.type == "talent" && talent.system.isautomated && talent.system.automations.length > 0) {
- for (let auto of talent.system.automations) {
- if (auto.eventtype === "prepare-roll") {
- if (auto.competence.toLowerCase() == competence.name.toLowerCase()) {
- talent = foundry.utils.duplicate(talent)
- talent.system.bonus = auto.bonus
- talent.system.baCost = auto.baCost
- talents.push(talent)
- }
- }
- }
- }
- }
- return talents
- }
-
- /* -------------------------------------------- */
- buildListeAdversites() {
- return []
- }
-
- /* -------------------------------------------- */
- getCommonRollData(attrKey = undefined, compId = undefined, compName = undefined) {
- let rollData = MournbladeCYD2Utility.getBasicRollData()
- rollData.alias = this.name
- rollData.actorImg = this.img
- rollData.actorId = this.id
- rollData.tokenId = this.token?.id
- rollData.img = this.img
- rollData.attributs = MournbladeCYD2Utility.getAttributs()
- rollData.maitriseId = "none"
- rollData.nbEclat = this.system.eclat.value
- rollData.nbBA = this.system.bonneaventure.actuelle
- rollData.nbAdversites = this.getTotalAdversite()
- rollData.talents = []
- rollData.attrKey2 = "none"
- rollData.coupDevastateur = this.items.find(it => it.type == "talent" && it.name.toLowerCase() == "coup dévastateur" && !it.system.used)
- rollData.hasAmbidextre = this.items.find(it => it.type == "talent" && it.name.toLowerCase() == "ambidextre")
- rollData.hasFeinte = this.system.bonneaventure.actuelle > 0 && this.items.find(it => it.type == "talent" && it.name.toLowerCase() == "feinte")
- rollData.isMonte = this.system.combat.monte
- rollData.config = game.system.mournbladecyd2.config
-
- if (attrKey) {
- rollData.attrKey = attrKey
- if (attrKey != "tochoose") {
- rollData.actionImg = "systems/fvtt-mournblade-cyd2/assets/icons/" + this.system.attributs[attrKey].labelnorm + ".webp"
- rollData.attr = foundry.utils.duplicate(this.system.attributs[attrKey])
- }
- }
- if (compId) {
- rollData.competence = foundry.utils.duplicate(this.items.get(compId) || {})
- let maitrises = [{ key: "none", label: "Aucune" }]
- rollData.competence.system.predilections.forEach(function (item) {
- if (item.maitrise) {
- maitrises.push({ key: item.id, label: item.name });
- }
- })
- rollData.maitrises = maitrises // rollData.competence.system.predilections.filter(p => p.maitrise)
- rollData.actionImg = rollData.competence?.img
- rollData.talents = this.searchRelevantTalents(rollData.competence)
- }
- if (compName) {
- rollData.competence = foundry.utils.duplicate(this.items.find(item => item.name.toLowerCase() == compName.toLowerCase()) || {})
- rollData.actionImg = rollData.competence?.img
- }
- return rollData
- }
-
- /* -------------------------------------------- */
- async rollAttribut(attrKey, isInit = false) {
- let rollData = this.getCommonRollData(attrKey)
- rollData.multiplier = (isInit) ? 1 : 2
- rollData.isInit = isInit
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
-
- /* -------------------------------------------- */
- async rollCompetence(attrKey, compId) {
- let rollData = this.getCommonRollData(attrKey, compId)
- rollData.multiplier = 1 // Attr multiplier, always 1 in competence mode
- console.log("RollDatra", rollData)
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
-
- /* -------------------------------------------- */
- async rollArmeOffensif(armeId) {
- let arme = this.items.get(armeId)
- if (arme.type == "arme") {
- arme = this.prepareArme(arme)
- }
- let rollData = this.getCommonRollData(arme.system.attrKey, arme.system.competence._id)
- rollData.arme = arme
- MournbladeCYD2Utility.updateWithTarget(rollData)
- console.log("ARME!", rollData)
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
- /* -------------------------------------------- */
- async rollAssommer() {
- let rollData = this.getCommonRollData("pui", undefined, "Filouterie")
- rollData.assomer = true
- rollData.conditionsCommunes = true
- MournbladeCYD2Utility.updateWithTarget(rollData)
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
- /* -------------------------------------------- */
- async rollCoupBas() {
- let rollData = this.getCommonRollData("pui", undefined, "Mêlée")
- rollData.coupBas = true
- rollData.conditionsCommunes = true
- MournbladeCYD2Utility.updateWithTarget(rollData)
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
- /* -------------------------------------------- */
- async rollImmobiliser() {
- let rollData = this.getCommonRollData("pui", undefined, "Mêlée")
- rollData.immobiliser = true
- rollData.conditionsCommunes = true
- rollData.cibleconsciente = true
- MournbladeCYD2Utility.updateWithTarget(rollData)
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
- /* -------------------------------------------- */
- async rollRepousser() {
- let rollData = this.getCommonRollData("pui", undefined, "Mêlée")
- rollData.repousser = true
- rollData.conditionsCommunes = true
- rollData.cibleconsciente = true
- MournbladeCYD2Utility.updateWithTarget(rollData)
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
- /* -------------------------------------------- */
- async rollDesengager() {
- let rollData = this.getCommonRollData("adr", undefined, "Mouvements")
- rollData.desengager = true
- rollData.conditionsCommunes = true
- MournbladeCYD2Utility.updateWithTarget(rollData)
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
-
- /* -------------------------------------------- */
- async rollArmeDegats(armeId, targetVigueur = undefined, rollDataInput = undefined) {
- let arme = this.items.get(armeId)
- if (arme.type == "arme") {
- arme = this.prepareArme(arme)
- }
- console.log("DEGATS", arme, targetVigueur, rollDataInput)
- let roll
- let bonus = 0
- let bonus2 = 0
-
- if (rollDataInput?.applyCoupDevastateur) {
- bonus2 = Math.floor(this.system.attributs.pui.value / 2)
- let talent = this.items.find(item => item.type == "talent" && item.name.toLowerCase() == "coup dévastateur")
- this.updateEmbeddedDocuments('Item', [{ _id: talent.id, 'system.used': true }])
- }
-
- if (rollDataInput?.isHeroique) {
- if (rollDataInput?.attaqueCharge) {
- bonus = 5
- }
- if (rollDataInput?.chargeCavalerie) {
- bonus = 6
- }
- roll = await new Roll("2d10rr10+" + arme.system.totalDegats + "+" + bonus + "+" + bonus2).roll()
- } else {
- if (rollDataInput?.attaqueCharge) {
- bonus = 3
- }
- if (rollDataInput?.chargeCavalerie) {
- bonus = 4
- }
- roll = await new Roll("1d10+" + arme.system.totalDegats + "+" + bonus + "+" + bonus2).roll()
- }
- await MournbladeCYD2Utility.showDiceSoNice(roll, game.settings.get("core", "rollMode"));
- let nbEtatPerdus = 0
- if (targetVigueur) {
- nbEtatPerdus = Math.floor(roll.total / targetVigueur)
- }
- //console.log(roll)
- let rollData = {
- arme: arme,
- finalResult: roll.total,
- formula: roll.formula,
- alias: this.name,
- actorImg: this.img,
- actorId: this.id,
- defenderTokenId: rollDataInput?.defenderTokenId,
- actionImg: arme.img,
- targetVigueur: targetVigueur,
- nbEtatPerdus: nbEtatPerdus
- }
- MournbladeCYD2Utility.createChatWithRollMode(rollData.alias, {
- content: await renderTemplate(`systems/fvtt-mournblade-cyd2/templates/chat-degats-result.html`, rollData)
- })
-
- if (rollDataInput?.defenderTokenId && nbEtatPerdus) {
- MournbladeCYD2Utility.applyCombativite(rollDataInput, nbEtatPerdus)
- }
-
- }
-}
diff --git a/.history/modules/mournblade-cyd2-actor_20251026100656.js b/.history/modules/mournblade-cyd2-actor_20251026100656.js
deleted file mode 100644
index a2c5c87..0000000
--- a/.history/modules/mournblade-cyd2-actor_20251026100656.js
+++ /dev/null
@@ -1,895 +0,0 @@
-/* -------------------------------------------- */
-import { MournbladeCYD2Utility } from "./mournblade-cyd2-utility.js";
-import { MournbladeCYD2RollDialog } from "./mournblade-cyd2-roll-dialog.js";
-
-/* -------------------------------------------- */
-const __degatsBonus = [-2, -2, -1, -1, 0, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 8, 8, 9, 9, 10, 10]
-const __vitesseBonus = [-2, -2, -1, -1, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8]
-
-/* -------------------------------------------- */
-/**
- * Extend the base Actor entity by defining a custom roll data structure which is ideal for the Simple system.
- * @extends {Actor}
- */
-export class MournbladeCYD2Actor extends Actor {
-
- /* -------------------------------------------- */
- /**
- * Override the create() function to provide additional SoS functionality.
- *
- * This overrided create() function adds initial items
- * Namely: Basic skills, money,
- *
- * @param {Object} data Barebones actor data which this function adds onto.
- * @param {Object} options (Unused) Additional options which customize the creation workflow.
- *
- */
-
- static async create(data, options) {
-
- // Case of compendium global import
- if (data instanceof Array) {
- return super.create(data, options);
- }
- // If the created actor has items (only applicable to duplicated actors) bypass the new actor creation logic
- if (data.items) {
- let actor = super.create(data, options);
- return actor;
- }
-
- if (data.type == 'personnage') {
- const skills = await MournbladeCYD2Utility.loadCompendium("fvtt-mournblade-cyd2.skills")
- data.items = skills.map(i => i.toObject())
- }
- if (data.type == 'creature') {
- const skills = await MournbladeCYD2Utility.loadCompendium("fvtt-mournblade-cyd2.skills-creatures")
- data.items = skills.map(i => i.toObject())
- data.items.push({ name: "Arme naturelle 1", type: 'arme', img: "systems/fvtt-mournblade-cyd2/assets/icons/melee.webp", system: { typearme: "contact", bonusmaniementoff: 0, seuildefense: 0, degats: "0" } })
- data.items.push({ name: "Arme naturelle 2", type: 'arme', img: "systems/fvtt-mournblade-cyd2/assets/icons/melee.webp", system: { typearme: "contact", bonusmaniementoff: 0, seuildefense: 0, degats: "0" } })
- }
-
- return super.create(data, options);
- }
-
- /* -------------------------------------------- */
- getBonusDefenseFromTalents() {
- let talents = this.items.filter(item => item.type == "talent" && item.system.isautomated)
- let bonus = 0
- for (let talent of talents) {
- for (let auto of talent.system.automations) {
- if (auto.eventtype == "bonus-permanent" && auto.bonusname == "bonus-defensif") {
- bonus += Number(auto.bonus || 0)
- }
- }
- }
- return bonus
- }
-
- /* -------------------------------------------- */
- prepareArme(arme) {
- arme = foundry.utils.duplicate(arme)
- let combat = this.getCombatValues()
- if (arme.system.typearme == "contact" || arme.system.typearme == "contactjet") {
- let bonusDefense = this.getBonusDefenseFromTalents()
- arme.system.competence = foundry.utils.duplicate(this.items.find(item => item.type == "competence" && item.name.toLowerCase() == "mêlée"))
- arme.system.attrKey = "pui"
- arme.system.totalDegats = arme.system.degats + "+" + combat.bonusDegatsTotal
- arme.system.totalOffensif = this.system.attributs.pui.value + arme.system.competence.system.niveau + arme.system.bonusmaniementoff + (this.system.combat.monte ? 3 : 0)
- arme.system.totalDefensif = combat.defenseTotal + arme.system.competence.system.niveau + arme.system.seuildefense + bonusDefense + (this.system.combat.monte ? 3 : 0)
- console.log("Arme", arme.system.totalDefensif, combat, arme.system.competence.system.niveau, arme.system.seuildefense, bonusDefense)
- arme.system.isdefense = true
- arme.system.isMelee = true
- arme.system.isDistance = false
- }
- if (arme.system.typearme == "jet" || arme.system.typearme == "tir") {
- arme.system.competence = foundry.utils.duplicate(this.items.find(item => item.type == "competence" && item.name.toLowerCase() == "armes à distance"))
- arme.system.attrKey = "adr"
- arme.system.totalOffensif = this.system.attributs.adr.value + arme.system.competence.system.niveau + arme.system.bonusmaniementoff
- arme.system.totalDegats = arme.system.degats
- arme.system.isMelee = false
- arme.system.isDistance = true
- if (arme.system.isdefense) {
- arme.system.totalDefensif = combat.defenseTotal + arme.system.competence.system.niveau + arme.system.seuildefense
- }
- }
- return arme
- }
-
- /* -------------------------------------------- */
- getItemSorted(types) {
- let items = this.items.filter(item => types.includes(item.type)) || []
- MournbladeCYD2Utility.sortArrayObjectsByName(items)
- return items
- }
- getWeapons() {
- let armes = []
- for (let arme of this.items) {
- if (arme.type == "arme") {
- armes.push(this.prepareArme(arme))
- }
- }
- MournbladeCYD2Utility.sortArrayObjectsByName(armes)
- return armes
- }
- getMonnaies() {
- return this.getItemSorted(["monnaie"])
- }
- getEquipments() {
- return this.getItemSorted(["equipement"])
- }
- getArtefacts() {
- return this.getItemSorted(["artefact"])
- }
- getArmors() {
- return this.getItemSorted(["protection"])
- }
- getHistoriques() {
- return this.getItemSorted(["historique"])
- }
- getProfils() {
- return this.getItemSorted(["profil"])
- }
- getTalents() {
- return this.getItemSorted(["talent"])
- }
- getRessources() {
- return this.getItemSorted(["ressource"])
- }
- getContacts() {
- return this.getItemSorted(["contact"])
- }
- getMutations() {
- return this.getItemSorted(["mutation"])
- }
- getDons() {
- return this.getItemSorted(["don"])
- }
- getPactes() {
- return this.getItemSorted(["pacte"])
- }
- getTendances() {
- return this.getItemSorted(["tendance"])
- }
- getRunes() {
- return this.getItemSorted(["rune"])
- }
- getTraitsChaotiques() {
- return this.getItemSorted(["traitchaotique"])
- }
- getTraitsEspeces() {
- return this.getItemSorted(["traitespece"])
- }
-
- /* -------------------------------------------- */
- getAspect() {
- return (this.system.balance.loi > this.system.balance.chaos) ? this.system.balance.loi : this.system.balance.chaos
- }
- getMarge() {
- return Math.abs(this.system.balance.loi - this.system.balance.chaos)
- }
- getAlignement() {
- return (this.system.balance.loi > this.system.balance.chaos) ? "loyal" : "chaotique"
- }
-
- /* -------------------------------------------- */
- getSkills() {
- let comp = []
- for (let item of this.items) {
- item = foundry.utils.duplicate(item)
- if (item.type == "competence") {
- item.system.attribut1total = item.system.niveau + (this.system.attributs[item.system.attribut1]?.value || 0)
- item.system.attribut2total = item.system.niveau + (this.system.attributs[item.system.attribut2]?.value || 0)
- item.system.attribut3total = item.system.niveau + (this.system.attributs[item.system.attribut3]?.value || 0)
- if (item.system.niveau == 0) {
- item.system.attribut1total -= 3
- item.system.attribut2total -= 3
- item.system.attribut3total -= 3
- }
- item.system.attribut1label = this.system.attributs[item.system.attribut1]?.label || ""
- item.system.attribut2label = this.system.attributs[item.system.attribut2]?.label || ""
- item.system.attribut3label = this.system.attributs[item.system.attribut3]?.label || ""
- comp.push(item)
- }
- }
- MournbladeCYD2Utility.sortArrayObjectsByName(comp)
- return comp
- }
-
- /* ----------------------- --------------------- */
- addMember(actorId) {
- let members = foundry.utils.duplicate(this.system.members)
- members.push({ id: actorId })
- this.update({ 'system.members': members })
- }
- async removeMember(actorId) {
- let members = this.system.members.filter(it => it.id != actorId)
- this.update({ 'system.members': members })
- }
-
- /* -------------------------------------------- */
- getDefenseBase() {
- return Math.max(this.system.attributs.tre.value, this.system.attributs.adr.value)
- }
-
- /* -------------------------------------------- */
- getVitesseBase() {
- return 5 + __vitesseBonus[this.system.attributs.adr.value]
- }
- /* -------------------------------------------- */
- getProtection() {
- let equipProtection = 0
- for (let armor of this.items) {
- if (armor.type == "protection" && armor.system.equipped) {
- equipProtection += Number(armor.system.protection)
- }
- }
- if (equipProtection < 4) {
- return 4 + equipProtection // Cas des boucliers + sans armure
- }
- return equipProtection // Uniquement la protection des armures + boucliers
- }
-
- /* -------------------------------------------- */
- getCombatValues() {
- let combat = {
- initBase: this.system.attributs.adr.value,
- initTotal: this.system.attributs.adr.value + this.system.combat.initbonus,
- bonusDegats: this.getBonusDegats(),
- bonusDegatsTotal: this.getBonusDegats() + this.system.combat.bonusdegats,
- vitesseBase: this.getVitesseBase(),
- vitesseTotal: this.getVitesseBase() + this.system.combat.vitessebonus,
- defenseBase: this.getDefenseBase(),
- protection: this.getProtection(),
- defenseTotal: this.getDefenseBase() + this.system.combat.defensebonus + this.getProtection() - this.getTotalAdversite() + (this.system.combat.defensetotale ? 3 : 0)
- }
- return combat
- }
-
- /* -------------------------------------------- */
- prepareBaseData() {
- }
-
- /* -------------------------------------------- */
- async prepareData() {
- super.prepareData();
- }
-
- /* -------------------------------------------- */
- prepareDerivedData() {
-
- if (this.type == 'personnage') {
- let talentBonus = this.getVigueurBonus()
- let vigueur = Math.floor((this.system.attributs.pui.value + this.system.attributs.tre.value) / 2) + talentBonus + this.system.sante.vigueurmodifier
- if (vigueur != this.system.sante.vigueur) {
- this.update({ 'system.sante.vigueur': vigueur })
- }
-
- let seuilPouvoirBonus = this.getSeuilPouvoirBonus()
- let seuilPouvoir = Math.floor((this.system.attributs.tre.value + this.system.attributs.cla.value) / 2) + seuilPouvoirBonus + this.system.ame.seuilpouvoirmodifier
- if (seuilPouvoir != this.system.ame.seuilpouvoir) {
- this.update({ 'system.ame.seuilpouvoir': seuilPouvoir })
- }
- }
- super.prepareDerivedData()
- }
-
- /* -------------------------------------------- */
- _preUpdate(changed, options, user) {
- if (changed?.system?.sante?.etat && changed?.system?.sante?.etat != this.system.sante.etat) {
- setTimeout(() => {
- this.processCombativite(changed.system.sante)
- }, 800)
- }
- if (changed?.system?.ame?.etat && changed?.system?.ame?.etat != this.system.ame.etat) {
- // L'état d'Âme ne peut pas être inférieur au minimum (max dans le système)
- let minAme = this.system.ame.max !== undefined ? this.system.ame.max : 0
- if (changed.system.ame.etat < minAme) {
- changed.system.ame.etat = minAme
- }
- // L'état d'Âme ne peut pas dépasser nbame (Brisé)
- if (changed.system.ame.etat > this.system.ame.nbame) {
- changed.system.ame.etat = this.system.ame.nbame
- }
- setTimeout(() => {
- this.processAme(changed.system.ame)
- }, 800)
- }
- // Si le max d'Âme change, ajuster l'état actuel si nécessaire
- if (changed?.system?.ame?.max !== undefined && changed.system.ame.max != this.system.ame.max) {
- if (this.system.ame.etat < changed.system.ame.max) {
- changed.system.ame.etat = changed.system.ame.max
- }
- }
- super._preUpdate(changed, options, user);
- }
-
- /* -------------------------------------------- */
- _onUpdate(data, options, user) {
- super._onUpdate(data, options, user);
- }
- /* -------------------------------------------- */
- getItemById(id) {
- let item = this.items.find(item => item.id == id);
- if (item) {
- item = foundry.utils.duplicate(item)
- }
- return item;
- }
-
- /* -------------------------------------------- */
- async equipItem(itemId) {
- let item = this.items.find(item => item.id == itemId)
- if (item && item.system) {
- let update = { _id: item.id, "system.equipped": !item.system.equipped }
- await this.updateEmbeddedDocuments('Item', [update]); // Updates one EmbeddedEntity
- }
- }
-
- /* -------------------------------------------- */
- editItemField(itemId, itemType, itemField, dataType, value) {
- let item = this.items.find(item => item.id == itemId)
- if (item) {
- console.log("Item ", item, itemField, dataType, value)
- if (dataType.toLowerCase() == "number") {
- value = Number(value)
- } else {
- value = String(value)
- }
- let update = { _id: item.id, [`system.${itemField}`]: value };
- this.updateEmbeddedDocuments("Item", [update])
- }
- }
-
- /* -------------------------------------------- */
- checkAttribut(attribut, minLevel) {
- let attr = this.system.attributs.find(at => at.labelnorm == attribut.toLowerCase())
- if (attr && attr.value >= minLevel) {
- return { isValid: true, attr: foundry.utils.duplicate(attr) }
- }
- return { isValid: false }
- }
- /* -------------------------------------------- */
- checkAttributOrCompetenceLevel(compName, minLevel) {
- let comp = this.items.find(i => i.type == "competence" && i.name.toLowerCase() == compName.toLowerCase() && i.system.niveau >= minLevel)
- if (comp) {
- return { isValid: true, item: foundry.utils.duplicate(comp) }
- } else {
- for (let attrKey in this.system.attributs) {
- if (this.system.attributs[attrKey].label.toLowerCase() == compName.toLowerCase() && this.system.attributs[attrKey].value >= minLevel) {
- return { isValid: true, item: foundry.utils.duplicate(this.system.attributs[attrKey]) }
- }
- }
- }
- return { isValid: false, warningMessage: `Prérequis insuffisant : la compétence/attribut ${compName} doit être de niveau ${minLevel} au minimum` }
- }
- /* -------------------------------------------- */
- addCompetenceBonus(compName, bonus, baCost) {
- let comp = this.items.find(i => i.type == "competence" && i.name.toLowerCase() == compName.toLowerCase())
- if (comp) {
- comp = foundry.utils.duplicate(comp)
- comp.system.bonus = bonus
- comp.system.baCost = baCost
- return { isValid: true, item: comp }
- }
- return { isValid: false, warningMessage: `Compétence ${compName} non trouvée` }
- }
- /* -------------------------------------------- */
- checkIfCompetence(compName) {
- let comp = this.items.find(i => i.type == "competence" && i.name.toLowerCase() == compName.toLowerCase())
- if (comp) {
- return { isValid: true, item: comp }
- }
- return { isValid: false }
- }
- /* -------------------------------------------- */
- getVigueur() {
- return this.system.sante.vigueur
- }
-
- /* -------------------------------------------- */
- getVigueurBonus() {
- let talents = this.items.filter(item => item.type == "talent" && item.system.isautomated)
- let bonus = 0
- for (let talent of talents) {
- for (let auto of talent.system.automations) {
- if (auto.eventtype == "bonus-permanent" && auto.bonusname == "vigueur") {
- bonus += Number(auto.bonus || 0)
- }
- }
- }
- return bonus
- }
-
- /* -------------------------------------------- */
- getSeuilPouvoir() {
- return this.system.ame.seuilpouvoir
- }
-
- /* -------------------------------------------- */
- getSeuilPouvoirBonus() {
- let talents = this.items.filter(item => item.type == "talent" && item.system.isautomated)
- let bonus = 0
- for (let talent of talents) {
- for (let auto of talent.system.automations) {
- if (auto.eventtype == "bonus-permanent" && auto.bonusname == "seuilpouvoir") {
- bonus += Number(auto.bonus || 0)
- }
- }
- }
- return bonus
- }
-
- /* -------------------------------------------- */
- getAmeMax() {
- // Utiliser une vérification stricte car 0 (Serein) est une valeur valide
- return this.system.ame.max !== undefined ? this.system.ame.max : this.system.ame.nbame
- }
-
- /* -------------------------------------------- */
- getBonneAventure() {
- return this.system.bonneaventure.actuelle
- }
- /* -------------------------------------------- */
- checkBonneAventure(cost) {
- return (this.system.bonneaventure.actuelle >= cost)
- }
- /* -------------------------------------------- */
- changeBonneAventure(value) {
- let newBA = this.system.bonneaventure.actuelle
- newBA += value
- this.update({ 'system.bonneaventure.actuelle': newBA })
- }
-
- /* -------------------------------------------- */
- getEclat() {
- return this.system.eclat.value
- }
-
- /* -------------------------------------------- */
- changeEclat(value) {
- let newE = this.system.eclat.value
- newE += value
- this.update({ 'system.eclat.value': newE })
- }
-
- /* -------------------------------------------- */
- compareName(a, b) {
- if (a.name < b.name) {
- return -1;
- }
- if (a.name > b.name) {
- return 1;
- }
- return 0;
- }
-
- /* -------------------------------------------- */
- getAttribute(attrKey) {
- return this.system.attributes[attrKey]
- }
-
- /* -------------------------------------------- */
- getBonusDegats() {
- return 0;
- }
-
- /* -------------------------------------------- */
- changeEtatCombativite(value) {
- if (value === "vaincu") {
- value = 200
- }
- let sante = foundry.utils.duplicate(this.system.sante)
- sante.etat += Number(value)
- sante.etat = Math.max(sante.etat, 0)
- sante.etat = Math.min(sante.etat, this.system.sante.nbcombativite)
- this.update({ 'system.sante': sante })
- if (sante.etat == this.system.sante.nbcombativite) {
- ChatMessage.create({ content: `${this.name} est vaincu !` })
- }
- // Duplicated ! this.processCombativite(sante)
- }
-
- /* -------------------------------------------- */
- changeEtatAme(value) {
- if (value === "brise") {
- value = 200
- }
- let ame = foundry.utils.duplicate(this.system.ame)
- ame.etat += Number(value)
- // L'état ne peut pas être inférieur au minimum (max dans le système)
- let minAme = this.system.ame.max !== undefined ? this.system.ame.max : 0
- ame.etat = Math.max(ame.etat, minAme)
- // L'état ne peut pas dépasser nbame (Brisé)
- ame.etat = Math.min(ame.etat, this.system.ame.nbame)
- this.update({ 'system.ame': ame })
- if (ame.etat >= this.system.ame.nbame) {
- ChatMessage.create({ content: `${this.name} est brisé !` })
- }
- }
-
- /* -------------------------------------------- */
- processCombativite(sante) {
- sante = sante || foundry.utils.duplicate(this.system.sante)
- // Gestion des états affaibli et très affaibli
- if (sante.etat == this.system.sante.nbcombativite - 2 || sante.etat == this.system.sante.nbcombativite - 1) {
- if (sante.etat == this.system.sante.nbcombativite - 2 && this.items.find(item => item.type == "talent" && item.name.toLowerCase() == "encaissement")) {
- ChatMessage.create({ content: `${this.name} ne subit pas les 2 adversités rouge grâce à Encaissement. Pensez à les ajouter à la fin de la scène !` })
- } else if (sante.etat == this.system.sante.nbcombativite - 1 && this.items.find(item => item.type == "talent" && item.name.toLowerCase().includes("vaillant"))) {
- ChatMessage.create({ content: `${this.name} ne subit pas les 2 adversités rouge grâce à Vaillant. Pensez à les ajouter à la fin de la scène !` })
- } else {
- ChatMessage.create({ content: `${this.name} subit 2 adversités rouge !` })
- this.incDecAdversite("rouge", 2)
- }
- }
- }
-
- /* -------------------------------------------- */
- processAme(ame) {
- ame = ame || foundry.utils.duplicate(this.system.ame)
- let traumatiseValue = this.system.ame.nbame - 2
- let tresTraumatiseValue = this.system.ame.nbame - 1
- let briseValue = this.system.ame.nbame
-
- // Gestion des états Traumatisé, Très Traumatisé et Brisé
- if (ame.etat == traumatiseValue) {
- ChatMessage.create({ content: `${this.name} est Traumatisé et subit 1 adversité bleue et 1 adversité noire !` })
- this.incDecAdversite("bleue", 1)
- this.incDecAdversite("noire", 1)
- } else if (ame.etat == tresTraumatiseValue) {
- ChatMessage.create({ content: `${this.name} est Très Traumatisé et subit 1 adversité bleue et 1 adversité noire !` })
- this.incDecAdversite("bleue", 1)
- this.incDecAdversite("noire", 1)
- } else if (ame.etat >= briseValue) {
- ChatMessage.create({ content: `${this.name} est Brisé et subit 1 adversité noire !` })
- this.incDecAdversite("noire", 1)
- }
- }
-
- /* -------------------------------------------- */
- async equipGear(equipmentId) {
- let item = this.items.find(item => item.id == equipmentId);
- if (item?.system?.data) {
- let update = { _id: item.id, "system.equipped": !item.system.equipped };
- await this.updateEmbeddedDocuments('Item', [update]); // Updates one EmbeddedEntity
- }
- }
-
- /* -------------------------------------------- */
- getSubActors() {
- let subActors = [];
- for (let id of this.system.subactors) {
- subActors.push(foundry.utils.duplicate(game.actors.get(id)));
- }
- return subActors;
- }
- /* -------------------------------------------- */
- async addSubActor(subActorId) {
- let subActors = foundry.utils.duplicate(this.system.subactors);
- subActors.push(subActorId);
- await this.update({ 'system.subactors': subActors });
- }
- /* -------------------------------------------- */
- async delSubActor(subActorId) {
- let newArray = [];
- for (let id of this.system.subactors) {
- if (id != subActorId) {
- newArray.push(id);
- }
- }
- await this.update({ 'system.subactors': newArray });
- }
-
- /* -------------------------------------------- */
- getTotalAdversite() {
- return this.system.adversite.bleue + this.system.adversite.rouge + this.system.adversite.noire
- }
-
- /* -------------------------------------------- */
- async incDecAdversite(adv, incDec = 0) {
- let adversite = foundry.utils.duplicate(this.system.adversite)
- adversite[adv] += Number(incDec)
- adversite[adv] = Math.max(adversite[adv], 0)
- adversite[adv] = Math.min(adversite[adv], 20)
- this.update({ 'system.adversite': adversite })
- }
- /* -------------------------------------------- */
- async incDecQuantity(objetId, incDec = 0) {
- let objetQ = this.items.get(objetId)
- if (objetQ) {
- let newQ = objetQ.system.quantite + incDec
- newQ = Math.max(newQ, 0)
- await this.updateEmbeddedDocuments('Item', [{ _id: objetQ.id, 'system.quantite': newQ }]); // pdates one EmbeddedEntity
- }
- }
-
- /* -------------------------------------------- */
- computeRichesse() {
- let valueSC = 0
- for (let monnaie of this.items) {
- if (monnaie.type == "monnaie") {
- valueSC += Number(monnaie.system.prixsc) * Number(monnaie.system.quantite)
- }
- }
- return MournbladeCYD2Utility.computeMonnaieDetails(valueSC)
- }
-
- /* -------------------------------------------- */
- computeValeurEquipement() {
- let valueSC = 0
- for (let equip of this.items) {
- if (equip.type == "equipement" || equip.type == "arme" || equip.type == "protection") {
- valueSC += Number(equip.system.prixsc) * Number(equip.system.quantite ?? 1)
- valueSC += (Number(equip.system.prixca) * Number(equip.system.quantite ?? 1)) * 20
- valueSC += (Number(equip.system.prixpo) * Number(equip.system.quantite ?? 1)) * 400
- }
- }
- return MournbladeCYD2Utility.computeMonnaieDetails(valueSC)
- }
-
- /* -------------------------------------------- */
- getCompetence(compId) {
- return this.items.get(compId)
- }
-
- /* -------------------------------------------- */
- async setPredilectionUsed(compId, predIdx) {
- let comp = this.items.get(compId)
- let pred = foundry.utils.duplicate(comp.system.predilections)
- pred[predIdx].used = true
- await this.updateEmbeddedDocuments('Item', [{ _id: compId, 'system.predilections': pred }])
- }
-
- /* -------------------------------------------- */
- getInitiativeScore() {
- let init = this.getFlag("world", "last-initiative")
- return init || -1
- }
-
- /* -------------------------------------------- */
- getBestAttackValue() {
- let attackList = this.items.filter(item => (item.type == "arme" || item.type == "talent") && item.system.equipped)
- let maxOff = 0
- let bestArme
- for (let arme of attackList) {
- if (arme.type == "arme") {
- arme = this.prepareArme(arme)
- }
- if (arme.system.totalOffensif > maxOff) {
- maxOff = arme.system.totalOffensif
- bestArme = foundry.utils.duplicate(arme)
- }
- }
- return bestArme
- }
-
- /* -------------------------------------------- */
- getBestDefenseValue() {
- let defenseList = this.items.filter(item => (item.type == "arme") && item.system.equipped)
- let maxDef = 0
- let bestArme
- for (let arme of defenseList) {
- if (arme.type == "arme") {
- arme = this.prepareArme(arme)
- }
- if (arme.system.totalDefensif > maxDef) {
- maxDef = arme.system.totalDefensif
- bestArme = foundry.utils.duplicate(arme)
- }
- }
- return bestArme
- }
-
- /* -------------------------------------------- */
- searchRelevantTalents(competence) {
- let talents = []
-
- for (let talent of this.items) {
- if (talent.type == "talent" && talent.system.isautomated && talent.system.automations.length > 0) {
- for (let auto of talent.system.automations) {
- if (auto.eventtype === "prepare-roll") {
- if (auto.competence.toLowerCase() == competence.name.toLowerCase()) {
- talent = foundry.utils.duplicate(talent)
- talent.system.bonus = auto.bonus
- talent.system.baCost = auto.baCost
- talents.push(talent)
- }
- }
- }
- }
- }
- return talents
- }
-
- /* -------------------------------------------- */
- buildListeAdversites() {
- return []
- }
-
- /* -------------------------------------------- */
- getCommonRollData(attrKey = undefined, compId = undefined, compName = undefined) {
- let rollData = MournbladeCYD2Utility.getBasicRollData()
- rollData.alias = this.name
- rollData.actorImg = this.img
- rollData.actorId = this.id
- rollData.tokenId = this.token?.id
- rollData.img = this.img
- rollData.attributs = MournbladeCYD2Utility.getAttributs()
- rollData.maitriseId = "none"
- rollData.nbEclat = this.system.eclat.value
- rollData.nbBA = this.system.bonneaventure.actuelle
- rollData.nbAdversites = this.getTotalAdversite()
- rollData.talents = []
- rollData.attrKey2 = "none"
- rollData.coupDevastateur = this.items.find(it => it.type == "talent" && it.name.toLowerCase() == "coup dévastateur" && !it.system.used)
- rollData.hasAmbidextre = this.items.find(it => it.type == "talent" && it.name.toLowerCase() == "ambidextre")
- rollData.hasFeinte = this.system.bonneaventure.actuelle > 0 && this.items.find(it => it.type == "talent" && it.name.toLowerCase() == "feinte")
- rollData.isMonte = this.system.combat.monte
- rollData.config = game.system.mournbladecyd2.config
-
- if (attrKey) {
- rollData.attrKey = attrKey
- if (attrKey != "tochoose") {
- rollData.actionImg = "systems/fvtt-mournblade-cyd2/assets/icons/" + this.system.attributs[attrKey].labelnorm + ".webp"
- rollData.attr = foundry.utils.duplicate(this.system.attributs[attrKey])
- }
- }
- if (compId) {
- rollData.competence = foundry.utils.duplicate(this.items.get(compId) || {})
- let maitrises = [{ key: "none", label: "Aucune" }]
- rollData.competence.system.predilections.forEach(function (item) {
- if (item.maitrise) {
- maitrises.push({ key: item.id, label: item.name });
- }
- })
- rollData.maitrises = maitrises // rollData.competence.system.predilections.filter(p => p.maitrise)
- rollData.actionImg = rollData.competence?.img
- rollData.talents = this.searchRelevantTalents(rollData.competence)
- }
- if (compName) {
- rollData.competence = foundry.utils.duplicate(this.items.find(item => item.name.toLowerCase() == compName.toLowerCase()) || {})
- rollData.actionImg = rollData.competence?.img
- }
- return rollData
- }
-
- /* -------------------------------------------- */
- async rollAttribut(attrKey, isInit = false) {
- let rollData = this.getCommonRollData(attrKey)
- rollData.multiplier = (isInit) ? 1 : 2
- rollData.isInit = isInit
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
-
- /* -------------------------------------------- */
- async rollCompetence(attrKey, compId) {
- let rollData = this.getCommonRollData(attrKey, compId)
- rollData.multiplier = 1 // Attr multiplier, always 1 in competence mode
- console.log("RollDatra", rollData)
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
-
- /* -------------------------------------------- */
- async rollArmeOffensif(armeId) {
- let arme = this.items.get(armeId)
- if (arme.type == "arme") {
- arme = this.prepareArme(arme)
- }
- let rollData = this.getCommonRollData(arme.system.attrKey, arme.system.competence._id)
- rollData.arme = arme
- MournbladeCYD2Utility.updateWithTarget(rollData)
- console.log("ARME!", rollData)
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
- /* -------------------------------------------- */
- async rollAssommer() {
- let rollData = this.getCommonRollData("pui", undefined, "Filouterie")
- rollData.assomer = true
- rollData.conditionsCommunes = true
- MournbladeCYD2Utility.updateWithTarget(rollData)
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
- /* -------------------------------------------- */
- async rollCoupBas() {
- let rollData = this.getCommonRollData("pui", undefined, "Mêlée")
- rollData.coupBas = true
- rollData.conditionsCommunes = true
- MournbladeCYD2Utility.updateWithTarget(rollData)
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
- /* -------------------------------------------- */
- async rollImmobiliser() {
- let rollData = this.getCommonRollData("pui", undefined, "Mêlée")
- rollData.immobiliser = true
- rollData.conditionsCommunes = true
- rollData.cibleconsciente = true
- MournbladeCYD2Utility.updateWithTarget(rollData)
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
- /* -------------------------------------------- */
- async rollRepousser() {
- let rollData = this.getCommonRollData("pui", undefined, "Mêlée")
- rollData.repousser = true
- rollData.conditionsCommunes = true
- rollData.cibleconsciente = true
- MournbladeCYD2Utility.updateWithTarget(rollData)
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
- /* -------------------------------------------- */
- async rollDesengager() {
- let rollData = this.getCommonRollData("adr", undefined, "Mouvements")
- rollData.desengager = true
- rollData.conditionsCommunes = true
- MournbladeCYD2Utility.updateWithTarget(rollData)
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
-
- /* -------------------------------------------- */
- async rollArmeDegats(armeId, targetVigueur = undefined, rollDataInput = undefined) {
- let arme = this.items.get(armeId)
- if (arme.type == "arme") {
- arme = this.prepareArme(arme)
- }
- console.log("DEGATS", arme, targetVigueur, rollDataInput)
- let roll
- let bonus = 0
- let bonus2 = 0
-
- if (rollDataInput?.applyCoupDevastateur) {
- bonus2 = Math.floor(this.system.attributs.pui.value / 2)
- let talent = this.items.find(item => item.type == "talent" && item.name.toLowerCase() == "coup dévastateur")
- this.updateEmbeddedDocuments('Item', [{ _id: talent.id, 'system.used': true }])
- }
-
- if (rollDataInput?.isHeroique) {
- if (rollDataInput?.attaqueCharge) {
- bonus = 5
- }
- if (rollDataInput?.chargeCavalerie) {
- bonus = 6
- }
- roll = await new Roll("2d10rr10+" + arme.system.totalDegats + "+" + bonus + "+" + bonus2).roll()
- } else {
- if (rollDataInput?.attaqueCharge) {
- bonus = 3
- }
- if (rollDataInput?.chargeCavalerie) {
- bonus = 4
- }
- roll = await new Roll("1d10+" + arme.system.totalDegats + "+" + bonus + "+" + bonus2).roll()
- }
- await MournbladeCYD2Utility.showDiceSoNice(roll, game.settings.get("core", "rollMode"));
- let nbEtatPerdus = 0
- if (targetVigueur) {
- nbEtatPerdus = Math.floor(roll.total / targetVigueur)
- }
- //console.log(roll)
- let rollData = {
- arme: arme,
- finalResult: roll.total,
- formula: roll.formula,
- alias: this.name,
- actorImg: this.img,
- actorId: this.id,
- defenderTokenId: rollDataInput?.defenderTokenId,
- actionImg: arme.img,
- targetVigueur: targetVigueur,
- nbEtatPerdus: nbEtatPerdus
- }
- MournbladeCYD2Utility.createChatWithRollMode(rollData.alias, {
- content: await renderTemplate(`systems/fvtt-mournblade-cyd2/templates/chat-degats-result.html`, rollData)
- })
-
- if (rollDataInput?.defenderTokenId && nbEtatPerdus) {
- MournbladeCYD2Utility.applyCombativite(rollDataInput, nbEtatPerdus)
- }
-
- }
-}
diff --git a/.history/modules/mournblade-cyd2-actor_20251026103947.js b/.history/modules/mournblade-cyd2-actor_20251026103947.js
deleted file mode 100644
index f7301cf..0000000
--- a/.history/modules/mournblade-cyd2-actor_20251026103947.js
+++ /dev/null
@@ -1,896 +0,0 @@
-/* -------------------------------------------- */
-import { MournbladeCYD2Utility } from "./mournblade-cyd2-utility.js";
-import { MournbladeCYD2RollDialog } from "./mournblade-cyd2-roll-dialog.js";
-
-/* -------------------------------------------- */
-const __degatsBonus = [-2, -2, -1, -1, 0, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 8, 8, 9, 9, 10, 10]
-const __vitesseBonus = [-2, -2, -1, -1, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8]
-
-/* -------------------------------------------- */
-/**
- * Extend the base Actor entity by defining a custom roll data structure which is ideal for the Simple system.
- * @extends {Actor}
- */
-export class MournbladeCYD2Actor extends Actor {
-
- /* -------------------------------------------- */
- /**
- * Override the create() function to provide additional SoS functionality.
- *
- * This overrided create() function adds initial items
- * Namely: Basic skills, money,
- *
- * @param {Object} data Barebones actor data which this function adds onto.
- * @param {Object} options (Unused) Additional options which customize the creation workflow.
- *
- */
-
- static async create(data, options) {
-
- // Case of compendium global import
- if (data instanceof Array) {
- return super.create(data, options);
- }
- // If the created actor has items (only applicable to duplicated actors) bypass the new actor creation logic
- if (data.items) {
- let actor = super.create(data, options);
- return actor;
- }
-
- if (data.type == 'personnage') {
- cons
- const skills = await MournbladeCYD2Utility.loadCompendium("fvtt-mournblade-cyd2.skills")
- data.items = skills.map(i => i.toObject())
- }
- if (data.type == 'creature') {
- const skills = await MournbladeCYD2Utility.loadCompendium("fvtt-mournblade-cyd2.skills-creatures")
- data.items = skills.map(i => i.toObject())
- data.items.push({ name: "Arme naturelle 1", type: 'arme', img: "systems/fvtt-mournblade-cyd2/assets/icons/melee.webp", system: { typearme: "contact", bonusmaniementoff: 0, seuildefense: 0, degats: "0" } })
- data.items.push({ name: "Arme naturelle 2", type: 'arme', img: "systems/fvtt-mournblade-cyd2/assets/icons/melee.webp", system: { typearme: "contact", bonusmaniementoff: 0, seuildefense: 0, degats: "0" } })
- }
-
- return super.create(data, options);
- }
-
- /* -------------------------------------------- */
- getBonusDefenseFromTalents() {
- let talents = this.items.filter(item => item.type == "talent" && item.system.isautomated)
- let bonus = 0
- for (let talent of talents) {
- for (let auto of talent.system.automations) {
- if (auto.eventtype == "bonus-permanent" && auto.bonusname == "bonus-defensif") {
- bonus += Number(auto.bonus || 0)
- }
- }
- }
- return bonus
- }
-
- /* -------------------------------------------- */
- prepareArme(arme) {
- arme = foundry.utils.duplicate(arme)
- let combat = this.getCombatValues()
- if (arme.system.typearme == "contact" || arme.system.typearme == "contactjet") {
- let bonusDefense = this.getBonusDefenseFromTalents()
- arme.system.competence = foundry.utils.duplicate(this.items.find(item => item.type == "competence" && item.name.toLowerCase() == "mêlée"))
- arme.system.attrKey = "pui"
- arme.system.totalDegats = arme.system.degats + "+" + combat.bonusDegatsTotal
- arme.system.totalOffensif = this.system.attributs.pui.value + arme.system.competence.system.niveau + arme.system.bonusmaniementoff + (this.system.combat.monte ? 3 : 0)
- arme.system.totalDefensif = combat.defenseTotal + arme.system.competence.system.niveau + arme.system.seuildefense + bonusDefense + (this.system.combat.monte ? 3 : 0)
- console.log("Arme", arme.system.totalDefensif, combat, arme.system.competence.system.niveau, arme.system.seuildefense, bonusDefense)
- arme.system.isdefense = true
- arme.system.isMelee = true
- arme.system.isDistance = false
- }
- if (arme.system.typearme == "jet" || arme.system.typearme == "tir") {
- arme.system.competence = foundry.utils.duplicate(this.items.find(item => item.type == "competence" && item.name.toLowerCase() == "armes à distance"))
- arme.system.attrKey = "adr"
- arme.system.totalOffensif = this.system.attributs.adr.value + arme.system.competence.system.niveau + arme.system.bonusmaniementoff
- arme.system.totalDegats = arme.system.degats
- arme.system.isMelee = false
- arme.system.isDistance = true
- if (arme.system.isdefense) {
- arme.system.totalDefensif = combat.defenseTotal + arme.system.competence.system.niveau + arme.system.seuildefense
- }
- }
- return arme
- }
-
- /* -------------------------------------------- */
- getItemSorted(types) {
- let items = this.items.filter(item => types.includes(item.type)) || []
- MournbladeCYD2Utility.sortArrayObjectsByName(items)
- return items
- }
- getWeapons() {
- let armes = []
- for (let arme of this.items) {
- if (arme.type == "arme") {
- armes.push(this.prepareArme(arme))
- }
- }
- MournbladeCYD2Utility.sortArrayObjectsByName(armes)
- return armes
- }
- getMonnaies() {
- return this.getItemSorted(["monnaie"])
- }
- getEquipments() {
- return this.getItemSorted(["equipement"])
- }
- getArtefacts() {
- return this.getItemSorted(["artefact"])
- }
- getArmors() {
- return this.getItemSorted(["protection"])
- }
- getHistoriques() {
- return this.getItemSorted(["historique"])
- }
- getProfils() {
- return this.getItemSorted(["profil"])
- }
- getTalents() {
- return this.getItemSorted(["talent"])
- }
- getRessources() {
- return this.getItemSorted(["ressource"])
- }
- getContacts() {
- return this.getItemSorted(["contact"])
- }
- getMutations() {
- return this.getItemSorted(["mutation"])
- }
- getDons() {
- return this.getItemSorted(["don"])
- }
- getPactes() {
- return this.getItemSorted(["pacte"])
- }
- getTendances() {
- return this.getItemSorted(["tendance"])
- }
- getRunes() {
- return this.getItemSorted(["rune"])
- }
- getTraitsChaotiques() {
- return this.getItemSorted(["traitchaotique"])
- }
- getTraitsEspeces() {
- return this.getItemSorted(["traitespece"])
- }
-
- /* -------------------------------------------- */
- getAspect() {
- return (this.system.balance.loi > this.system.balance.chaos) ? this.system.balance.loi : this.system.balance.chaos
- }
- getMarge() {
- return Math.abs(this.system.balance.loi - this.system.balance.chaos)
- }
- getAlignement() {
- return (this.system.balance.loi > this.system.balance.chaos) ? "loyal" : "chaotique"
- }
-
- /* -------------------------------------------- */
- getSkills() {
- let comp = []
- for (let item of this.items) {
- item = foundry.utils.duplicate(item)
- if (item.type == "competence") {
- item.system.attribut1total = item.system.niveau + (this.system.attributs[item.system.attribut1]?.value || 0)
- item.system.attribut2total = item.system.niveau + (this.system.attributs[item.system.attribut2]?.value || 0)
- item.system.attribut3total = item.system.niveau + (this.system.attributs[item.system.attribut3]?.value || 0)
- if (item.system.niveau == 0) {
- item.system.attribut1total -= 3
- item.system.attribut2total -= 3
- item.system.attribut3total -= 3
- }
- item.system.attribut1label = this.system.attributs[item.system.attribut1]?.label || ""
- item.system.attribut2label = this.system.attributs[item.system.attribut2]?.label || ""
- item.system.attribut3label = this.system.attributs[item.system.attribut3]?.label || ""
- comp.push(item)
- }
- }
- MournbladeCYD2Utility.sortArrayObjectsByName(comp)
- return comp
- }
-
- /* ----------------------- --------------------- */
- addMember(actorId) {
- let members = foundry.utils.duplicate(this.system.members)
- members.push({ id: actorId })
- this.update({ 'system.members': members })
- }
- async removeMember(actorId) {
- let members = this.system.members.filter(it => it.id != actorId)
- this.update({ 'system.members': members })
- }
-
- /* -------------------------------------------- */
- getDefenseBase() {
- return Math.max(this.system.attributs.tre.value, this.system.attributs.adr.value)
- }
-
- /* -------------------------------------------- */
- getVitesseBase() {
- return 5 + __vitesseBonus[this.system.attributs.adr.value]
- }
- /* -------------------------------------------- */
- getProtection() {
- let equipProtection = 0
- for (let armor of this.items) {
- if (armor.type == "protection" && armor.system.equipped) {
- equipProtection += Number(armor.system.protection)
- }
- }
- if (equipProtection < 4) {
- return 4 + equipProtection // Cas des boucliers + sans armure
- }
- return equipProtection // Uniquement la protection des armures + boucliers
- }
-
- /* -------------------------------------------- */
- getCombatValues() {
- let combat = {
- initBase: this.system.attributs.adr.value,
- initTotal: this.system.attributs.adr.value + this.system.combat.initbonus,
- bonusDegats: this.getBonusDegats(),
- bonusDegatsTotal: this.getBonusDegats() + this.system.combat.bonusdegats,
- vitesseBase: this.getVitesseBase(),
- vitesseTotal: this.getVitesseBase() + this.system.combat.vitessebonus,
- defenseBase: this.getDefenseBase(),
- protection: this.getProtection(),
- defenseTotal: this.getDefenseBase() + this.system.combat.defensebonus + this.getProtection() - this.getTotalAdversite() + (this.system.combat.defensetotale ? 3 : 0)
- }
- return combat
- }
-
- /* -------------------------------------------- */
- prepareBaseData() {
- }
-
- /* -------------------------------------------- */
- async prepareData() {
- super.prepareData();
- }
-
- /* -------------------------------------------- */
- prepareDerivedData() {
-
- if (this.type == 'personnage') {
- let talentBonus = this.getVigueurBonus()
- let vigueur = Math.floor((this.system.attributs.pui.value + this.system.attributs.tre.value) / 2) + talentBonus + this.system.sante.vigueurmodifier
- if (vigueur != this.system.sante.vigueur) {
- this.update({ 'system.sante.vigueur': vigueur })
- }
-
- let seuilPouvoirBonus = this.getSeuilPouvoirBonus()
- let seuilPouvoir = Math.floor((this.system.attributs.tre.value + this.system.attributs.cla.value) / 2) + seuilPouvoirBonus + this.system.ame.seuilpouvoirmodifier
- if (seuilPouvoir != this.system.ame.seuilpouvoir) {
- this.update({ 'system.ame.seuilpouvoir': seuilPouvoir })
- }
- }
- super.prepareDerivedData()
- }
-
- /* -------------------------------------------- */
- _preUpdate(changed, options, user) {
- if (changed?.system?.sante?.etat && changed?.system?.sante?.etat != this.system.sante.etat) {
- setTimeout(() => {
- this.processCombativite(changed.system.sante)
- }, 800)
- }
- if (changed?.system?.ame?.etat && changed?.system?.ame?.etat != this.system.ame.etat) {
- // L'état d'Âme ne peut pas être inférieur au minimum (max dans le système)
- let minAme = this.system.ame.max !== undefined ? this.system.ame.max : 0
- if (changed.system.ame.etat < minAme) {
- changed.system.ame.etat = minAme
- }
- // L'état d'Âme ne peut pas dépasser nbame (Brisé)
- if (changed.system.ame.etat > this.system.ame.nbame) {
- changed.system.ame.etat = this.system.ame.nbame
- }
- setTimeout(() => {
- this.processAme(changed.system.ame)
- }, 800)
- }
- // Si le max d'Âme change, ajuster l'état actuel si nécessaire
- if (changed?.system?.ame?.max !== undefined && changed.system.ame.max != this.system.ame.max) {
- if (this.system.ame.etat < changed.system.ame.max) {
- changed.system.ame.etat = changed.system.ame.max
- }
- }
- super._preUpdate(changed, options, user);
- }
-
- /* -------------------------------------------- */
- _onUpdate(data, options, user) {
- super._onUpdate(data, options, user);
- }
- /* -------------------------------------------- */
- getItemById(id) {
- let item = this.items.find(item => item.id == id);
- if (item) {
- item = foundry.utils.duplicate(item)
- }
- return item;
- }
-
- /* -------------------------------------------- */
- async equipItem(itemId) {
- let item = this.items.find(item => item.id == itemId)
- if (item && item.system) {
- let update = { _id: item.id, "system.equipped": !item.system.equipped }
- await this.updateEmbeddedDocuments('Item', [update]); // Updates one EmbeddedEntity
- }
- }
-
- /* -------------------------------------------- */
- editItemField(itemId, itemType, itemField, dataType, value) {
- let item = this.items.find(item => item.id == itemId)
- if (item) {
- console.log("Item ", item, itemField, dataType, value)
- if (dataType.toLowerCase() == "number") {
- value = Number(value)
- } else {
- value = String(value)
- }
- let update = { _id: item.id, [`system.${itemField}`]: value };
- this.updateEmbeddedDocuments("Item", [update])
- }
- }
-
- /* -------------------------------------------- */
- checkAttribut(attribut, minLevel) {
- let attr = this.system.attributs.find(at => at.labelnorm == attribut.toLowerCase())
- if (attr && attr.value >= minLevel) {
- return { isValid: true, attr: foundry.utils.duplicate(attr) }
- }
- return { isValid: false }
- }
- /* -------------------------------------------- */
- checkAttributOrCompetenceLevel(compName, minLevel) {
- let comp = this.items.find(i => i.type == "competence" && i.name.toLowerCase() == compName.toLowerCase() && i.system.niveau >= minLevel)
- if (comp) {
- return { isValid: true, item: foundry.utils.duplicate(comp) }
- } else {
- for (let attrKey in this.system.attributs) {
- if (this.system.attributs[attrKey].label.toLowerCase() == compName.toLowerCase() && this.system.attributs[attrKey].value >= minLevel) {
- return { isValid: true, item: foundry.utils.duplicate(this.system.attributs[attrKey]) }
- }
- }
- }
- return { isValid: false, warningMessage: `Prérequis insuffisant : la compétence/attribut ${compName} doit être de niveau ${minLevel} au minimum` }
- }
- /* -------------------------------------------- */
- addCompetenceBonus(compName, bonus, baCost) {
- let comp = this.items.find(i => i.type == "competence" && i.name.toLowerCase() == compName.toLowerCase())
- if (comp) {
- comp = foundry.utils.duplicate(comp)
- comp.system.bonus = bonus
- comp.system.baCost = baCost
- return { isValid: true, item: comp }
- }
- return { isValid: false, warningMessage: `Compétence ${compName} non trouvée` }
- }
- /* -------------------------------------------- */
- checkIfCompetence(compName) {
- let comp = this.items.find(i => i.type == "competence" && i.name.toLowerCase() == compName.toLowerCase())
- if (comp) {
- return { isValid: true, item: comp }
- }
- return { isValid: false }
- }
- /* -------------------------------------------- */
- getVigueur() {
- return this.system.sante.vigueur
- }
-
- /* -------------------------------------------- */
- getVigueurBonus() {
- let talents = this.items.filter(item => item.type == "talent" && item.system.isautomated)
- let bonus = 0
- for (let talent of talents) {
- for (let auto of talent.system.automations) {
- if (auto.eventtype == "bonus-permanent" && auto.bonusname == "vigueur") {
- bonus += Number(auto.bonus || 0)
- }
- }
- }
- return bonus
- }
-
- /* -------------------------------------------- */
- getSeuilPouvoir() {
- return this.system.ame.seuilpouvoir
- }
-
- /* -------------------------------------------- */
- getSeuilPouvoirBonus() {
- let talents = this.items.filter(item => item.type == "talent" && item.system.isautomated)
- let bonus = 0
- for (let talent of talents) {
- for (let auto of talent.system.automations) {
- if (auto.eventtype == "bonus-permanent" && auto.bonusname == "seuilpouvoir") {
- bonus += Number(auto.bonus || 0)
- }
- }
- }
- return bonus
- }
-
- /* -------------------------------------------- */
- getAmeMax() {
- // Utiliser une vérification stricte car 0 (Serein) est une valeur valide
- return this.system.ame.max !== undefined ? this.system.ame.max : this.system.ame.nbame
- }
-
- /* -------------------------------------------- */
- getBonneAventure() {
- return this.system.bonneaventure.actuelle
- }
- /* -------------------------------------------- */
- checkBonneAventure(cost) {
- return (this.system.bonneaventure.actuelle >= cost)
- }
- /* -------------------------------------------- */
- changeBonneAventure(value) {
- let newBA = this.system.bonneaventure.actuelle
- newBA += value
- this.update({ 'system.bonneaventure.actuelle': newBA })
- }
-
- /* -------------------------------------------- */
- getEclat() {
- return this.system.eclat.value
- }
-
- /* -------------------------------------------- */
- changeEclat(value) {
- let newE = this.system.eclat.value
- newE += value
- this.update({ 'system.eclat.value': newE })
- }
-
- /* -------------------------------------------- */
- compareName(a, b) {
- if (a.name < b.name) {
- return -1;
- }
- if (a.name > b.name) {
- return 1;
- }
- return 0;
- }
-
- /* -------------------------------------------- */
- getAttribute(attrKey) {
- return this.system.attributes[attrKey]
- }
-
- /* -------------------------------------------- */
- getBonusDegats() {
- return 0;
- }
-
- /* -------------------------------------------- */
- changeEtatCombativite(value) {
- if (value === "vaincu") {
- value = 200
- }
- let sante = foundry.utils.duplicate(this.system.sante)
- sante.etat += Number(value)
- sante.etat = Math.max(sante.etat, 0)
- sante.etat = Math.min(sante.etat, this.system.sante.nbcombativite)
- this.update({ 'system.sante': sante })
- if (sante.etat == this.system.sante.nbcombativite) {
- ChatMessage.create({ content: `${this.name} est vaincu !` })
- }
- // Duplicated ! this.processCombativite(sante)
- }
-
- /* -------------------------------------------- */
- changeEtatAme(value) {
- if (value === "brise") {
- value = 200
- }
- let ame = foundry.utils.duplicate(this.system.ame)
- ame.etat += Number(value)
- // L'état ne peut pas être inférieur au minimum (max dans le système)
- let minAme = this.system.ame.max !== undefined ? this.system.ame.max : 0
- ame.etat = Math.max(ame.etat, minAme)
- // L'état ne peut pas dépasser nbame (Brisé)
- ame.etat = Math.min(ame.etat, this.system.ame.nbame)
- this.update({ 'system.ame': ame })
- if (ame.etat >= this.system.ame.nbame) {
- ChatMessage.create({ content: `${this.name} est brisé !` })
- }
- }
-
- /* -------------------------------------------- */
- processCombativite(sante) {
- sante = sante || foundry.utils.duplicate(this.system.sante)
- // Gestion des états affaibli et très affaibli
- if (sante.etat == this.system.sante.nbcombativite - 2 || sante.etat == this.system.sante.nbcombativite - 1) {
- if (sante.etat == this.system.sante.nbcombativite - 2 && this.items.find(item => item.type == "talent" && item.name.toLowerCase() == "encaissement")) {
- ChatMessage.create({ content: `${this.name} ne subit pas les 2 adversités rouge grâce à Encaissement. Pensez à les ajouter à la fin de la scène !` })
- } else if (sante.etat == this.system.sante.nbcombativite - 1 && this.items.find(item => item.type == "talent" && item.name.toLowerCase().includes("vaillant"))) {
- ChatMessage.create({ content: `${this.name} ne subit pas les 2 adversités rouge grâce à Vaillant. Pensez à les ajouter à la fin de la scène !` })
- } else {
- ChatMessage.create({ content: `${this.name} subit 2 adversités rouge !` })
- this.incDecAdversite("rouge", 2)
- }
- }
- }
-
- /* -------------------------------------------- */
- processAme(ame) {
- ame = ame || foundry.utils.duplicate(this.system.ame)
- let traumatiseValue = this.system.ame.nbame - 2
- let tresTraumatiseValue = this.system.ame.nbame - 1
- let briseValue = this.system.ame.nbame
-
- // Gestion des états Traumatisé, Très Traumatisé et Brisé
- if (ame.etat == traumatiseValue) {
- ChatMessage.create({ content: `${this.name} est Traumatisé et subit 1 adversité bleue et 1 adversité noire !` })
- this.incDecAdversite("bleue", 1)
- this.incDecAdversite("noire", 1)
- } else if (ame.etat == tresTraumatiseValue) {
- ChatMessage.create({ content: `${this.name} est Très Traumatisé et subit 1 adversité bleue et 1 adversité noire !` })
- this.incDecAdversite("bleue", 1)
- this.incDecAdversite("noire", 1)
- } else if (ame.etat >= briseValue) {
- ChatMessage.create({ content: `${this.name} est Brisé et subit 1 adversité noire !` })
- this.incDecAdversite("noire", 1)
- }
- }
-
- /* -------------------------------------------- */
- async equipGear(equipmentId) {
- let item = this.items.find(item => item.id == equipmentId);
- if (item?.system?.data) {
- let update = { _id: item.id, "system.equipped": !item.system.equipped };
- await this.updateEmbeddedDocuments('Item', [update]); // Updates one EmbeddedEntity
- }
- }
-
- /* -------------------------------------------- */
- getSubActors() {
- let subActors = [];
- for (let id of this.system.subactors) {
- subActors.push(foundry.utils.duplicate(game.actors.get(id)));
- }
- return subActors;
- }
- /* -------------------------------------------- */
- async addSubActor(subActorId) {
- let subActors = foundry.utils.duplicate(this.system.subactors);
- subActors.push(subActorId);
- await this.update({ 'system.subactors': subActors });
- }
- /* -------------------------------------------- */
- async delSubActor(subActorId) {
- let newArray = [];
- for (let id of this.system.subactors) {
- if (id != subActorId) {
- newArray.push(id);
- }
- }
- await this.update({ 'system.subactors': newArray });
- }
-
- /* -------------------------------------------- */
- getTotalAdversite() {
- return this.system.adversite.bleue + this.system.adversite.rouge + this.system.adversite.noire
- }
-
- /* -------------------------------------------- */
- async incDecAdversite(adv, incDec = 0) {
- let adversite = foundry.utils.duplicate(this.system.adversite)
- adversite[adv] += Number(incDec)
- adversite[adv] = Math.max(adversite[adv], 0)
- adversite[adv] = Math.min(adversite[adv], 20)
- this.update({ 'system.adversite': adversite })
- }
- /* -------------------------------------------- */
- async incDecQuantity(objetId, incDec = 0) {
- let objetQ = this.items.get(objetId)
- if (objetQ) {
- let newQ = objetQ.system.quantite + incDec
- newQ = Math.max(newQ, 0)
- await this.updateEmbeddedDocuments('Item', [{ _id: objetQ.id, 'system.quantite': newQ }]); // pdates one EmbeddedEntity
- }
- }
-
- /* -------------------------------------------- */
- computeRichesse() {
- let valueSC = 0
- for (let monnaie of this.items) {
- if (monnaie.type == "monnaie") {
- valueSC += Number(monnaie.system.prixsc) * Number(monnaie.system.quantite)
- }
- }
- return MournbladeCYD2Utility.computeMonnaieDetails(valueSC)
- }
-
- /* -------------------------------------------- */
- computeValeurEquipement() {
- let valueSC = 0
- for (let equip of this.items) {
- if (equip.type == "equipement" || equip.type == "arme" || equip.type == "protection") {
- valueSC += Number(equip.system.prixsc) * Number(equip.system.quantite ?? 1)
- valueSC += (Number(equip.system.prixca) * Number(equip.system.quantite ?? 1)) * 20
- valueSC += (Number(equip.system.prixpo) * Number(equip.system.quantite ?? 1)) * 400
- }
- }
- return MournbladeCYD2Utility.computeMonnaieDetails(valueSC)
- }
-
- /* -------------------------------------------- */
- getCompetence(compId) {
- return this.items.get(compId)
- }
-
- /* -------------------------------------------- */
- async setPredilectionUsed(compId, predIdx) {
- let comp = this.items.get(compId)
- let pred = foundry.utils.duplicate(comp.system.predilections)
- pred[predIdx].used = true
- await this.updateEmbeddedDocuments('Item', [{ _id: compId, 'system.predilections': pred }])
- }
-
- /* -------------------------------------------- */
- getInitiativeScore() {
- let init = this.getFlag("world", "last-initiative")
- return init || -1
- }
-
- /* -------------------------------------------- */
- getBestAttackValue() {
- let attackList = this.items.filter(item => (item.type == "arme" || item.type == "talent") && item.system.equipped)
- let maxOff = 0
- let bestArme
- for (let arme of attackList) {
- if (arme.type == "arme") {
- arme = this.prepareArme(arme)
- }
- if (arme.system.totalOffensif > maxOff) {
- maxOff = arme.system.totalOffensif
- bestArme = foundry.utils.duplicate(arme)
- }
- }
- return bestArme
- }
-
- /* -------------------------------------------- */
- getBestDefenseValue() {
- let defenseList = this.items.filter(item => (item.type == "arme") && item.system.equipped)
- let maxDef = 0
- let bestArme
- for (let arme of defenseList) {
- if (arme.type == "arme") {
- arme = this.prepareArme(arme)
- }
- if (arme.system.totalDefensif > maxDef) {
- maxDef = arme.system.totalDefensif
- bestArme = foundry.utils.duplicate(arme)
- }
- }
- return bestArme
- }
-
- /* -------------------------------------------- */
- searchRelevantTalents(competence) {
- let talents = []
-
- for (let talent of this.items) {
- if (talent.type == "talent" && talent.system.isautomated && talent.system.automations.length > 0) {
- for (let auto of talent.system.automations) {
- if (auto.eventtype === "prepare-roll") {
- if (auto.competence.toLowerCase() == competence.name.toLowerCase()) {
- talent = foundry.utils.duplicate(talent)
- talent.system.bonus = auto.bonus
- talent.system.baCost = auto.baCost
- talents.push(talent)
- }
- }
- }
- }
- }
- return talents
- }
-
- /* -------------------------------------------- */
- buildListeAdversites() {
- return []
- }
-
- /* -------------------------------------------- */
- getCommonRollData(attrKey = undefined, compId = undefined, compName = undefined) {
- let rollData = MournbladeCYD2Utility.getBasicRollData()
- rollData.alias = this.name
- rollData.actorImg = this.img
- rollData.actorId = this.id
- rollData.tokenId = this.token?.id
- rollData.img = this.img
- rollData.attributs = MournbladeCYD2Utility.getAttributs()
- rollData.maitriseId = "none"
- rollData.nbEclat = this.system.eclat.value
- rollData.nbBA = this.system.bonneaventure.actuelle
- rollData.nbAdversites = this.getTotalAdversite()
- rollData.talents = []
- rollData.attrKey2 = "none"
- rollData.coupDevastateur = this.items.find(it => it.type == "talent" && it.name.toLowerCase() == "coup dévastateur" && !it.system.used)
- rollData.hasAmbidextre = this.items.find(it => it.type == "talent" && it.name.toLowerCase() == "ambidextre")
- rollData.hasFeinte = this.system.bonneaventure.actuelle > 0 && this.items.find(it => it.type == "talent" && it.name.toLowerCase() == "feinte")
- rollData.isMonte = this.system.combat.monte
- rollData.config = game.system.mournbladecyd2.config
-
- if (attrKey) {
- rollData.attrKey = attrKey
- if (attrKey != "tochoose") {
- rollData.actionImg = "systems/fvtt-mournblade-cyd2/assets/icons/" + this.system.attributs[attrKey].labelnorm + ".webp"
- rollData.attr = foundry.utils.duplicate(this.system.attributs[attrKey])
- }
- }
- if (compId) {
- rollData.competence = foundry.utils.duplicate(this.items.get(compId) || {})
- let maitrises = [{ key: "none", label: "Aucune" }]
- rollData.competence.system.predilections.forEach(function (item) {
- if (item.maitrise) {
- maitrises.push({ key: item.id, label: item.name });
- }
- })
- rollData.maitrises = maitrises // rollData.competence.system.predilections.filter(p => p.maitrise)
- rollData.actionImg = rollData.competence?.img
- rollData.talents = this.searchRelevantTalents(rollData.competence)
- }
- if (compName) {
- rollData.competence = foundry.utils.duplicate(this.items.find(item => item.name.toLowerCase() == compName.toLowerCase()) || {})
- rollData.actionImg = rollData.competence?.img
- }
- return rollData
- }
-
- /* -------------------------------------------- */
- async rollAttribut(attrKey, isInit = false) {
- let rollData = this.getCommonRollData(attrKey)
- rollData.multiplier = (isInit) ? 1 : 2
- rollData.isInit = isInit
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
-
- /* -------------------------------------------- */
- async rollCompetence(attrKey, compId) {
- let rollData = this.getCommonRollData(attrKey, compId)
- rollData.multiplier = 1 // Attr multiplier, always 1 in competence mode
- console.log("RollDatra", rollData)
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
-
- /* -------------------------------------------- */
- async rollArmeOffensif(armeId) {
- let arme = this.items.get(armeId)
- if (arme.type == "arme") {
- arme = this.prepareArme(arme)
- }
- let rollData = this.getCommonRollData(arme.system.attrKey, arme.system.competence._id)
- rollData.arme = arme
- MournbladeCYD2Utility.updateWithTarget(rollData)
- console.log("ARME!", rollData)
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
- /* -------------------------------------------- */
- async rollAssommer() {
- let rollData = this.getCommonRollData("pui", undefined, "Filouterie")
- rollData.assomer = true
- rollData.conditionsCommunes = true
- MournbladeCYD2Utility.updateWithTarget(rollData)
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
- /* -------------------------------------------- */
- async rollCoupBas() {
- let rollData = this.getCommonRollData("pui", undefined, "Mêlée")
- rollData.coupBas = true
- rollData.conditionsCommunes = true
- MournbladeCYD2Utility.updateWithTarget(rollData)
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
- /* -------------------------------------------- */
- async rollImmobiliser() {
- let rollData = this.getCommonRollData("pui", undefined, "Mêlée")
- rollData.immobiliser = true
- rollData.conditionsCommunes = true
- rollData.cibleconsciente = true
- MournbladeCYD2Utility.updateWithTarget(rollData)
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
- /* -------------------------------------------- */
- async rollRepousser() {
- let rollData = this.getCommonRollData("pui", undefined, "Mêlée")
- rollData.repousser = true
- rollData.conditionsCommunes = true
- rollData.cibleconsciente = true
- MournbladeCYD2Utility.updateWithTarget(rollData)
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
- /* -------------------------------------------- */
- async rollDesengager() {
- let rollData = this.getCommonRollData("adr", undefined, "Mouvements")
- rollData.desengager = true
- rollData.conditionsCommunes = true
- MournbladeCYD2Utility.updateWithTarget(rollData)
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
-
- /* -------------------------------------------- */
- async rollArmeDegats(armeId, targetVigueur = undefined, rollDataInput = undefined) {
- let arme = this.items.get(armeId)
- if (arme.type == "arme") {
- arme = this.prepareArme(arme)
- }
- console.log("DEGATS", arme, targetVigueur, rollDataInput)
- let roll
- let bonus = 0
- let bonus2 = 0
-
- if (rollDataInput?.applyCoupDevastateur) {
- bonus2 = Math.floor(this.system.attributs.pui.value / 2)
- let talent = this.items.find(item => item.type == "talent" && item.name.toLowerCase() == "coup dévastateur")
- this.updateEmbeddedDocuments('Item', [{ _id: talent.id, 'system.used': true }])
- }
-
- if (rollDataInput?.isHeroique) {
- if (rollDataInput?.attaqueCharge) {
- bonus = 5
- }
- if (rollDataInput?.chargeCavalerie) {
- bonus = 6
- }
- roll = await new Roll("2d10rr10+" + arme.system.totalDegats + "+" + bonus + "+" + bonus2).roll()
- } else {
- if (rollDataInput?.attaqueCharge) {
- bonus = 3
- }
- if (rollDataInput?.chargeCavalerie) {
- bonus = 4
- }
- roll = await new Roll("1d10+" + arme.system.totalDegats + "+" + bonus + "+" + bonus2).roll()
- }
- await MournbladeCYD2Utility.showDiceSoNice(roll, game.settings.get("core", "rollMode"));
- let nbEtatPerdus = 0
- if (targetVigueur) {
- nbEtatPerdus = Math.floor(roll.total / targetVigueur)
- }
- //console.log(roll)
- let rollData = {
- arme: arme,
- finalResult: roll.total,
- formula: roll.formula,
- alias: this.name,
- actorImg: this.img,
- actorId: this.id,
- defenderTokenId: rollDataInput?.defenderTokenId,
- actionImg: arme.img,
- targetVigueur: targetVigueur,
- nbEtatPerdus: nbEtatPerdus
- }
- MournbladeCYD2Utility.createChatWithRollMode(rollData.alias, {
- content: await renderTemplate(`systems/fvtt-mournblade-cyd2/templates/chat-degats-result.html`, rollData)
- })
-
- if (rollDataInput?.defenderTokenId && nbEtatPerdus) {
- MournbladeCYD2Utility.applyCombativite(rollDataInput, nbEtatPerdus)
- }
-
- }
-}
diff --git a/.history/modules/mournblade-cyd2-actor_20251026132457.js b/.history/modules/mournblade-cyd2-actor_20251026132457.js
deleted file mode 100644
index 0520df0..0000000
--- a/.history/modules/mournblade-cyd2-actor_20251026132457.js
+++ /dev/null
@@ -1,893 +0,0 @@
-/* -------------------------------------------- */
-import { MournbladeCYD2Utility } from "./mournblade-cyd2-utility.js";
-import { MournbladeCYD2RollDialog } from "./mournblade-cyd2-roll-dialog.js";
-
-/* -------------------------------------------- */
-const __degatsBonus = [-2, -2, -1, -1, 0, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 8, 8, 9, 9, 10, 10]
-const __vitesseBonus = [-2, -2, -1, -1, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8]
-
-/* -------------------------------------------- */
-/**
- * Extend the base Actor entity by defining a custom roll data structure which is ideal for the Simple system.
- * @extends {Actor}
- */
-export class MournbladeCYD2Actor extends Actor {
-
- /* -------------------------------------------- */
- /**
- * Override the create() function to provide additional SoS functionality.
- *
- * This overrided create() function adds initial items
- * Namely: Basic skills, money,
- *
- * @param {Object} data Barebones actor data which this function adds onto.
- * @param {Object} options (Unused) Additional options which customize the creation workflow.
- *
- */
-
- static async create(data, options) {
-
- // Case of compendium global import
- if (data instanceof Array) {
- return super.create(data, options);
- }
- // If the created actor has items (only applicable to duplicated actors) bypass the new actor creation logic
- if (data.items) {
- let actor = super.create(data, options);
- return actor;
- }
-
- if (data.type == 'personnage') {
- console.log("Loading skills for personnage")
- const skills = await MournbladeCYD2Utility.loadCompendium("fvtt-mournblade-cyd2.skills")
- data.items = skills.map(i => i.toObject())
- }
- if (data.type == 'creature') {
- const skills = await MournbladeCYD2Utility.loadCompendium("fvtt-mournblade-cyd2.skills-creatures")
- data.items = skills.map(i => i.toObject())
- data.items.push({ name: "Arme naturelle 1", type: 'arme', img: "systems/fvtt-mournblade-cyd2/assets/icons/melee.webp", system: { typearme: "contact", bonusmaniementoff: 0, seuildefense: 0, degats: "0" } })
- data.items.push({ name: "Arme naturelle 2", type: 'arme', img: "systems/fvtt-mournblade-cyd2/assets/icons/melee.webp", system: { typearme: "contact", bonusmaniementoff: 0, seuildefense: 0, degats: "0" } })
- }
-
- return super.create(data, options);
- }
-
- /* -------------------------------------------- */
- getBonusDefenseFromTalents() {
- let talents = this.items.filter(item => item.type == "talent" && item.system.isautomated)
- let bonus = 0
- for (let talent of talents) {
- for (let auto of talent.system.automations) {
- if (auto.eventtype == "bonus-permanent" && auto.bonusname == "bonus-defensif") {
- bonus += Number(auto.bonus || 0)
- }
- }
- }
- return bonus
- }
-
- /* -------------------------------------------- */
- prepareArme(arme) {
- arme = foundry.utils.duplicate(arme)
- let combat = this.getCombatValues()
- if (arme.system.typearme == "contact" || arme.system.typearme == "contactjet") {
- let bonusDefense = this.getBonusDefenseFromTalents()
- arme.system.competence = foundry.utils.duplicate(this.items.find(item => item.type == "competence" && item.name.toLowerCase() == "mêlée"))
- arme.system.attrKey = "pui"
- arme.system.totalDegats = arme.system.degats + "+" + combat.bonusDegatsTotal
- arme.system.totalOffensif = this.system.attributs.pui.value + arme.system.competence.system.niveau + arme.system.bonusmaniementoff + (this.system.combat.monte ? 3 : 0)
- arme.system.totalDefensif = combat.defenseTotal + arme.system.competence.system.niveau + arme.system.seuildefense + bonusDefense + (this.system.combat.monte ? 3 : 0)
- console.log("Arme", arme.system.totalDefensif, combat, arme.system.competence.system.niveau, arme.system.seuildefense, bonusDefense)
- arme.system.isdefense = true
- arme.system.isMelee = true
- arme.system.isDistance = false
- }
- if (arme.system.typearme == "jet" || arme.system.typearme == "tir") {
- arme.system.competence = foundry.utils.duplicate(this.items.find(item => item.type == "competence" && item.name.toLowerCase() == "armes à distance"))
- arme.system.attrKey = "adr"
- arme.system.totalOffensif = this.system.attributs.adr.value + arme.system.competence.system.niveau + arme.system.bonusmaniementoff
- arme.system.totalDegats = arme.system.degats
- arme.system.isMelee = false
- arme.system.isDistance = true
- if (arme.system.isdefense) {
- arme.system.totalDefensif = combat.defenseTotal + arme.system.competence.system.niveau + arme.system.seuildefense
- }
- }
- return arme
- }
-
- /* -------------------------------------------- */
- getItemSorted(types) {
- let items = this.items.filter(item => types.includes(item.type)) || []
- MournbladeCYD2Utility.sortArrayObjectsByName(items)
- return items
- }
- getWeapons() {
- let armes = []
- for (let arme of this.items) {
- if (arme.type == "arme") {
- armes.push(this.prepareArme(arme))
- }
- }
- MournbladeCYD2Utility.sortArrayObjectsByName(armes)
- return armes
- }
- getMonnaies() {
- return this.getItemSorted(["monnaie"])
- }
- getEquipments() {
- return this.getItemSorted(["equipement"])
- }
- getArmors() {
- return this.getItemSorted(["protection"])
- }
- getHistoriques() {
- return this.getItemSorted(["historique"])
- }
- getProfils() {
- return this.getItemSorted(["profil"])
- }
- getTalents() {
- return this.getItemSorted(["talent"])
- }
- getRessources() {
- return this.getItemSorted(["ressource"])
- }
- getContacts() {
- return this.getItemSorted(["contact"])
- }
- getMutations() {
- return this.getItemSorted(["mutation"])
- }
- getDons() {
- return this.getItemSorted(["don"])
- }
- getPactes() {
- return this.getItemSorted(["pacte"])
- }
- getTendances() {
- return this.getItemSorted(["tendance"])
- }
- getRunes() {
- return this.getItemSorted(["rune"])
- }
- getTraitsChaotiques() {
- return this.getItemSorted(["traitchaotique"])
- }
- getTraitsEspeces() {
- return this.getItemSorted(["traitespece"])
- }
-
- /* -------------------------------------------- */
- getAspect() {
- return (this.system.balance.loi > this.system.balance.chaos) ? this.system.balance.loi : this.system.balance.chaos
- }
- getMarge() {
- return Math.abs(this.system.balance.loi - this.system.balance.chaos)
- }
- getAlignement() {
- return (this.system.balance.loi > this.system.balance.chaos) ? "loyal" : "chaotique"
- }
-
- /* -------------------------------------------- */
- getSkills() {
- let comp = []
- for (let item of this.items) {
- item = foundry.utils.duplicate(item)
- if (item.type == "competence") {
- item.system.attribut1total = item.system.niveau + (this.system.attributs[item.system.attribut1]?.value || 0)
- item.system.attribut2total = item.system.niveau + (this.system.attributs[item.system.attribut2]?.value || 0)
- item.system.attribut3total = item.system.niveau + (this.system.attributs[item.system.attribut3]?.value || 0)
- if (item.system.niveau == 0) {
- item.system.attribut1total -= 3
- item.system.attribut2total -= 3
- item.system.attribut3total -= 3
- }
- item.system.attribut1label = this.system.attributs[item.system.attribut1]?.label || ""
- item.system.attribut2label = this.system.attributs[item.system.attribut2]?.label || ""
- item.system.attribut3label = this.system.attributs[item.system.attribut3]?.label || ""
- comp.push(item)
- }
- }
- MournbladeCYD2Utility.sortArrayObjectsByName(comp)
- return comp
- }
-
- /* ----------------------- --------------------- */
- addMember(actorId) {
- let members = foundry.utils.duplicate(this.system.members)
- members.push({ id: actorId })
- this.update({ 'system.members': members })
- }
- async removeMember(actorId) {
- let members = this.system.members.filter(it => it.id != actorId)
- this.update({ 'system.members': members })
- }
-
- /* -------------------------------------------- */
- getDefenseBase() {
- return Math.max(this.system.attributs.tre.value, this.system.attributs.adr.value)
- }
-
- /* -------------------------------------------- */
- getVitesseBase() {
- return 5 + __vitesseBonus[this.system.attributs.adr.value]
- }
- /* -------------------------------------------- */
- getProtection() {
- let equipProtection = 0
- for (let armor of this.items) {
- if (armor.type == "protection" && armor.system.equipped) {
- equipProtection += Number(armor.system.protection)
- }
- }
- if (equipProtection < 4) {
- return 4 + equipProtection // Cas des boucliers + sans armure
- }
- return equipProtection // Uniquement la protection des armures + boucliers
- }
-
- /* -------------------------------------------- */
- getCombatValues() {
- let combat = {
- initBase: this.system.attributs.adr.value,
- initTotal: this.system.attributs.adr.value + this.system.combat.initbonus,
- bonusDegats: this.getBonusDegats(),
- bonusDegatsTotal: this.getBonusDegats() + this.system.combat.bonusdegats,
- vitesseBase: this.getVitesseBase(),
- vitesseTotal: this.getVitesseBase() + this.system.combat.vitessebonus,
- defenseBase: this.getDefenseBase(),
- protection: this.getProtection(),
- defenseTotal: this.getDefenseBase() + this.system.combat.defensebonus + this.getProtection() - this.getTotalAdversite() + (this.system.combat.defensetotale ? 3 : 0)
- }
- return combat
- }
-
- /* -------------------------------------------- */
- prepareBaseData() {
- }
-
- /* -------------------------------------------- */
- async prepareData() {
- super.prepareData();
- }
-
- /* -------------------------------------------- */
- prepareDerivedData() {
-
- if (this.type == 'personnage') {
- let talentBonus = this.getVigueurBonus()
- let vigueur = Math.floor((this.system.attributs.pui.value + this.system.attributs.tre.value) / 2) + talentBonus + this.system.sante.vigueurmodifier
- if (vigueur != this.system.sante.vigueur) {
- this.update({ 'system.sante.vigueur': vigueur })
- }
-
- let seuilPouvoirBonus = this.getSeuilPouvoirBonus()
- let seuilPouvoir = Math.floor((this.system.attributs.tre.value + this.system.attributs.cla.value) / 2) + seuilPouvoirBonus + this.system.ame.seuilpouvoirmodifier
- if (seuilPouvoir != this.system.ame.seuilpouvoir) {
- this.update({ 'system.ame.seuilpouvoir': seuilPouvoir })
- }
- }
- super.prepareDerivedData()
- }
-
- /* -------------------------------------------- */
- _preUpdate(changed, options, user) {
- if (changed?.system?.sante?.etat && changed?.system?.sante?.etat != this.system.sante.etat) {
- setTimeout(() => {
- this.processCombativite(changed.system.sante)
- }, 800)
- }
- if (changed?.system?.ame?.etat && changed?.system?.ame?.etat != this.system.ame.etat) {
- // L'état d'Âme ne peut pas être inférieur au minimum (max dans le système)
- let minAme = this.system.ame.max !== undefined ? this.system.ame.max : 0
- if (changed.system.ame.etat < minAme) {
- changed.system.ame.etat = minAme
- }
- // L'état d'Âme ne peut pas dépasser nbame (Brisé)
- if (changed.system.ame.etat > this.system.ame.nbame) {
- changed.system.ame.etat = this.system.ame.nbame
- }
- setTimeout(() => {
- this.processAme(changed.system.ame)
- }, 800)
- }
- // Si le max d'Âme change, ajuster l'état actuel si nécessaire
- if (changed?.system?.ame?.max !== undefined && changed.system.ame.max != this.system.ame.max) {
- if (this.system.ame.etat < changed.system.ame.max) {
- changed.system.ame.etat = changed.system.ame.max
- }
- }
- super._preUpdate(changed, options, user);
- }
-
- /* -------------------------------------------- */
- _onUpdate(data, options, user) {
- super._onUpdate(data, options, user);
- }
- /* -------------------------------------------- */
- getItemById(id) {
- let item = this.items.find(item => item.id == id);
- if (item) {
- item = foundry.utils.duplicate(item)
- }
- return item;
- }
-
- /* -------------------------------------------- */
- async equipItem(itemId) {
- let item = this.items.find(item => item.id == itemId)
- if (item && item.system) {
- let update = { _id: item.id, "system.equipped": !item.system.equipped }
- await this.updateEmbeddedDocuments('Item', [update]); // Updates one EmbeddedEntity
- }
- }
-
- /* -------------------------------------------- */
- editItemField(itemId, itemType, itemField, dataType, value) {
- let item = this.items.find(item => item.id == itemId)
- if (item) {
- console.log("Item ", item, itemField, dataType, value)
- if (dataType.toLowerCase() == "number") {
- value = Number(value)
- } else {
- value = String(value)
- }
- let update = { _id: item.id, [`system.${itemField}`]: value };
- this.updateEmbeddedDocuments("Item", [update])
- }
- }
-
- /* -------------------------------------------- */
- checkAttribut(attribut, minLevel) {
- let attr = this.system.attributs.find(at => at.labelnorm == attribut.toLowerCase())
- if (attr && attr.value >= minLevel) {
- return { isValid: true, attr: foundry.utils.duplicate(attr) }
- }
- return { isValid: false }
- }
- /* -------------------------------------------- */
- checkAttributOrCompetenceLevel(compName, minLevel) {
- let comp = this.items.find(i => i.type == "competence" && i.name.toLowerCase() == compName.toLowerCase() && i.system.niveau >= minLevel)
- if (comp) {
- return { isValid: true, item: foundry.utils.duplicate(comp) }
- } else {
- for (let attrKey in this.system.attributs) {
- if (this.system.attributs[attrKey].label.toLowerCase() == compName.toLowerCase() && this.system.attributs[attrKey].value >= minLevel) {
- return { isValid: true, item: foundry.utils.duplicate(this.system.attributs[attrKey]) }
- }
- }
- }
- return { isValid: false, warningMessage: `Prérequis insuffisant : la compétence/attribut ${compName} doit être de niveau ${minLevel} au minimum` }
- }
- /* -------------------------------------------- */
- addCompetenceBonus(compName, bonus, baCost) {
- let comp = this.items.find(i => i.type == "competence" && i.name.toLowerCase() == compName.toLowerCase())
- if (comp) {
- comp = foundry.utils.duplicate(comp)
- comp.system.bonus = bonus
- comp.system.baCost = baCost
- return { isValid: true, item: comp }
- }
- return { isValid: false, warningMessage: `Compétence ${compName} non trouvée` }
- }
- /* -------------------------------------------- */
- checkIfCompetence(compName) {
- let comp = this.items.find(i => i.type == "competence" && i.name.toLowerCase() == compName.toLowerCase())
- if (comp) {
- return { isValid: true, item: comp }
- }
- return { isValid: false }
- }
- /* -------------------------------------------- */
- getVigueur() {
- return this.system.sante.vigueur
- }
-
- /* -------------------------------------------- */
- getVigueurBonus() {
- let talents = this.items.filter(item => item.type == "talent" && item.system.isautomated)
- let bonus = 0
- for (let talent of talents) {
- for (let auto of talent.system.automations) {
- if (auto.eventtype == "bonus-permanent" && auto.bonusname == "vigueur") {
- bonus += Number(auto.bonus || 0)
- }
- }
- }
- return bonus
- }
-
- /* -------------------------------------------- */
- getSeuilPouvoir() {
- return this.system.ame.seuilpouvoir
- }
-
- /* -------------------------------------------- */
- getSeuilPouvoirBonus() {
- let talents = this.items.filter(item => item.type == "talent" && item.system.isautomated)
- let bonus = 0
- for (let talent of talents) {
- for (let auto of talent.system.automations) {
- if (auto.eventtype == "bonus-permanent" && auto.bonusname == "seuilpouvoir") {
- bonus += Number(auto.bonus || 0)
- }
- }
- }
- return bonus
- }
-
- /* -------------------------------------------- */
- getAmeMax() {
- // Utiliser une vérification stricte car 0 (Serein) est une valeur valide
- return this.system.ame.max !== undefined ? this.system.ame.max : this.system.ame.nbame
- }
-
- /* -------------------------------------------- */
- getBonneAventure() {
- return this.system.bonneaventure.actuelle
- }
- /* -------------------------------------------- */
- checkBonneAventure(cost) {
- return (this.system.bonneaventure.actuelle >= cost)
- }
- /* -------------------------------------------- */
- changeBonneAventure(value) {
- let newBA = this.system.bonneaventure.actuelle
- newBA += value
- this.update({ 'system.bonneaventure.actuelle': newBA })
- }
-
- /* -------------------------------------------- */
- getEclat() {
- return this.system.eclat.value
- }
-
- /* -------------------------------------------- */
- changeEclat(value) {
- let newE = this.system.eclat.value
- newE += value
- this.update({ 'system.eclat.value': newE })
- }
-
- /* -------------------------------------------- */
- compareName(a, b) {
- if (a.name < b.name) {
- return -1;
- }
- if (a.name > b.name) {
- return 1;
- }
- return 0;
- }
-
- /* -------------------------------------------- */
- getAttribute(attrKey) {
- return this.system.attributes[attrKey]
- }
-
- /* -------------------------------------------- */
- getBonusDegats() {
- return 0;
- }
-
- /* -------------------------------------------- */
- changeEtatCombativite(value) {
- if (value === "vaincu") {
- value = 200
- }
- let sante = foundry.utils.duplicate(this.system.sante)
- sante.etat += Number(value)
- sante.etat = Math.max(sante.etat, 0)
- sante.etat = Math.min(sante.etat, this.system.sante.nbcombativite)
- this.update({ 'system.sante': sante })
- if (sante.etat == this.system.sante.nbcombativite) {
- ChatMessage.create({ content: `${this.name} est vaincu !` })
- }
- // Duplicated ! this.processCombativite(sante)
- }
-
- /* -------------------------------------------- */
- changeEtatAme(value) {
- if (value === "brise") {
- value = 200
- }
- let ame = foundry.utils.duplicate(this.system.ame)
- ame.etat += Number(value)
- // L'état ne peut pas être inférieur au minimum (max dans le système)
- let minAme = this.system.ame.max !== undefined ? this.system.ame.max : 0
- ame.etat = Math.max(ame.etat, minAme)
- // L'état ne peut pas dépasser nbame (Brisé)
- ame.etat = Math.min(ame.etat, this.system.ame.nbame)
- this.update({ 'system.ame': ame })
- if (ame.etat >= this.system.ame.nbame) {
- ChatMessage.create({ content: `${this.name} est brisé !` })
- }
- }
-
- /* -------------------------------------------- */
- processCombativite(sante) {
- sante = sante || foundry.utils.duplicate(this.system.sante)
- // Gestion des états affaibli et très affaibli
- if (sante.etat == this.system.sante.nbcombativite - 2 || sante.etat == this.system.sante.nbcombativite - 1) {
- if (sante.etat == this.system.sante.nbcombativite - 2 && this.items.find(item => item.type == "talent" && item.name.toLowerCase() == "encaissement")) {
- ChatMessage.create({ content: `${this.name} ne subit pas les 2 adversités rouge grâce à Encaissement. Pensez à les ajouter à la fin de la scène !` })
- } else if (sante.etat == this.system.sante.nbcombativite - 1 && this.items.find(item => item.type == "talent" && item.name.toLowerCase().includes("vaillant"))) {
- ChatMessage.create({ content: `${this.name} ne subit pas les 2 adversités rouge grâce à Vaillant. Pensez à les ajouter à la fin de la scène !` })
- } else {
- ChatMessage.create({ content: `${this.name} subit 2 adversités rouge !` })
- this.incDecAdversite("rouge", 2)
- }
- }
- }
-
- /* -------------------------------------------- */
- processAme(ame) {
- ame = ame || foundry.utils.duplicate(this.system.ame)
- let traumatiseValue = this.system.ame.nbame - 2
- let tresTraumatiseValue = this.system.ame.nbame - 1
- let briseValue = this.system.ame.nbame
-
- // Gestion des états Traumatisé, Très Traumatisé et Brisé
- if (ame.etat == traumatiseValue) {
- ChatMessage.create({ content: `${this.name} est Traumatisé et subit 1 adversité bleue et 1 adversité noire !` })
- this.incDecAdversite("bleue", 1)
- this.incDecAdversite("noire", 1)
- } else if (ame.etat == tresTraumatiseValue) {
- ChatMessage.create({ content: `${this.name} est Très Traumatisé et subit 1 adversité bleue et 1 adversité noire !` })
- this.incDecAdversite("bleue", 1)
- this.incDecAdversite("noire", 1)
- } else if (ame.etat >= briseValue) {
- ChatMessage.create({ content: `${this.name} est Brisé et subit 1 adversité noire !` })
- this.incDecAdversite("noire", 1)
- }
- }
-
- /* -------------------------------------------- */
- async equipGear(equipmentId) {
- let item = this.items.find(item => item.id == equipmentId);
- if (item?.system?.data) {
- let update = { _id: item.id, "system.equipped": !item.system.equipped };
- await this.updateEmbeddedDocuments('Item', [update]); // Updates one EmbeddedEntity
- }
- }
-
- /* -------------------------------------------- */
- getSubActors() {
- let subActors = [];
- for (let id of this.system.subactors) {
- subActors.push(foundry.utils.duplicate(game.actors.get(id)));
- }
- return subActors;
- }
- /* -------------------------------------------- */
- async addSubActor(subActorId) {
- let subActors = foundry.utils.duplicate(this.system.subactors);
- subActors.push(subActorId);
- await this.update({ 'system.subactors': subActors });
- }
- /* -------------------------------------------- */
- async delSubActor(subActorId) {
- let newArray = [];
- for (let id of this.system.subactors) {
- if (id != subActorId) {
- newArray.push(id);
- }
- }
- await this.update({ 'system.subactors': newArray });
- }
-
- /* -------------------------------------------- */
- getTotalAdversite() {
- return this.system.adversite.bleue + this.system.adversite.rouge + this.system.adversite.noire
- }
-
- /* -------------------------------------------- */
- async incDecAdversite(adv, incDec = 0) {
- let adversite = foundry.utils.duplicate(this.system.adversite)
- adversite[adv] += Number(incDec)
- adversite[adv] = Math.max(adversite[adv], 0)
- adversite[adv] = Math.min(adversite[adv], 20)
- this.update({ 'system.adversite': adversite })
- }
- /* -------------------------------------------- */
- async incDecQuantity(objetId, incDec = 0) {
- let objetQ = this.items.get(objetId)
- if (objetQ) {
- let newQ = objetQ.system.quantite + incDec
- newQ = Math.max(newQ, 0)
- await this.updateEmbeddedDocuments('Item', [{ _id: objetQ.id, 'system.quantite': newQ }]); // pdates one EmbeddedEntity
- }
- }
-
- /* -------------------------------------------- */
- computeRichesse() {
- let valueSC = 0
- for (let monnaie of this.items) {
- if (monnaie.type == "monnaie") {
- valueSC += Number(monnaie.system.prixsc) * Number(monnaie.system.quantite)
- }
- }
- return MournbladeCYD2Utility.computeMonnaieDetails(valueSC)
- }
-
- /* -------------------------------------------- */
- computeValeurEquipement() {
- let valueSC = 0
- for (let equip of this.items) {
- if (equip.type == "equipement" || equip.type == "arme" || equip.type == "protection") {
- valueSC += Number(equip.system.prixsc) * Number(equip.system.quantite ?? 1)
- valueSC += (Number(equip.system.prixca) * Number(equip.system.quantite ?? 1)) * 20
- valueSC += (Number(equip.system.prixpo) * Number(equip.system.quantite ?? 1)) * 400
- }
- }
- return MournbladeCYD2Utility.computeMonnaieDetails(valueSC)
- }
-
- /* -------------------------------------------- */
- getCompetence(compId) {
- return this.items.get(compId)
- }
-
- /* -------------------------------------------- */
- async setPredilectionUsed(compId, predIdx) {
- let comp = this.items.get(compId)
- let pred = foundry.utils.duplicate(comp.system.predilections)
- pred[predIdx].used = true
- await this.updateEmbeddedDocuments('Item', [{ _id: compId, 'system.predilections': pred }])
- }
-
- /* -------------------------------------------- */
- getInitiativeScore() {
- let init = this.getFlag("world", "last-initiative")
- return init || -1
- }
-
- /* -------------------------------------------- */
- getBestAttackValue() {
- let attackList = this.items.filter(item => (item.type == "arme" || item.type == "talent") && item.system.equipped)
- let maxOff = 0
- let bestArme
- for (let arme of attackList) {
- if (arme.type == "arme") {
- arme = this.prepareArme(arme)
- }
- if (arme.system.totalOffensif > maxOff) {
- maxOff = arme.system.totalOffensif
- bestArme = foundry.utils.duplicate(arme)
- }
- }
- return bestArme
- }
-
- /* -------------------------------------------- */
- getBestDefenseValue() {
- let defenseList = this.items.filter(item => (item.type == "arme") && item.system.equipped)
- let maxDef = 0
- let bestArme
- for (let arme of defenseList) {
- if (arme.type == "arme") {
- arme = this.prepareArme(arme)
- }
- if (arme.system.totalDefensif > maxDef) {
- maxDef = arme.system.totalDefensif
- bestArme = foundry.utils.duplicate(arme)
- }
- }
- return bestArme
- }
-
- /* -------------------------------------------- */
- searchRelevantTalents(competence) {
- let talents = []
-
- for (let talent of this.items) {
- if (talent.type == "talent" && talent.system.isautomated && talent.system.automations.length > 0) {
- for (let auto of talent.system.automations) {
- if (auto.eventtype === "prepare-roll") {
- if (auto.competence.toLowerCase() == competence.name.toLowerCase()) {
- talent = foundry.utils.duplicate(talent)
- talent.system.bonus = auto.bonus
- talent.system.baCost = auto.baCost
- talents.push(talent)
- }
- }
- }
- }
- }
- return talents
- }
-
- /* -------------------------------------------- */
- buildListeAdversites() {
- return []
- }
-
- /* -------------------------------------------- */
- getCommonRollData(attrKey = undefined, compId = undefined, compName = undefined) {
- let rollData = MournbladeCYD2Utility.getBasicRollData()
- rollData.alias = this.name
- rollData.actorImg = this.img
- rollData.actorId = this.id
- rollData.tokenId = this.token?.id
- rollData.img = this.img
- rollData.attributs = MournbladeCYD2Utility.getAttributs()
- rollData.maitriseId = "none"
- rollData.nbEclat = this.system.eclat.value
- rollData.nbBA = this.system.bonneaventure.actuelle
- rollData.nbAdversites = this.getTotalAdversite()
- rollData.talents = []
- rollData.attrKey2 = "none"
- rollData.coupDevastateur = this.items.find(it => it.type == "talent" && it.name.toLowerCase() == "coup dévastateur" && !it.system.used)
- rollData.hasAmbidextre = this.items.find(it => it.type == "talent" && it.name.toLowerCase() == "ambidextre")
- rollData.hasFeinte = this.system.bonneaventure.actuelle > 0 && this.items.find(it => it.type == "talent" && it.name.toLowerCase() == "feinte")
- rollData.isMonte = this.system.combat.monte
- rollData.config = game.system.mournbladecyd2.config
-
- if (attrKey) {
- rollData.attrKey = attrKey
- if (attrKey != "tochoose") {
- rollData.actionImg = "systems/fvtt-mournblade-cyd2/assets/icons/" + this.system.attributs[attrKey].labelnorm + ".webp"
- rollData.attr = foundry.utils.duplicate(this.system.attributs[attrKey])
- }
- }
- if (compId) {
- rollData.competence = foundry.utils.duplicate(this.items.get(compId) || {})
- let maitrises = [{ key: "none", label: "Aucune" }]
- rollData.competence.system.predilections.forEach(function (item) {
- if (item.maitrise) {
- maitrises.push({ key: item.id, label: item.name });
- }
- })
- rollData.maitrises = maitrises // rollData.competence.system.predilections.filter(p => p.maitrise)
- rollData.actionImg = rollData.competence?.img
- rollData.talents = this.searchRelevantTalents(rollData.competence)
- }
- if (compName) {
- rollData.competence = foundry.utils.duplicate(this.items.find(item => item.name.toLowerCase() == compName.toLowerCase()) || {})
- rollData.actionImg = rollData.competence?.img
- }
- return rollData
- }
-
- /* -------------------------------------------- */
- async rollAttribut(attrKey, isInit = false) {
- let rollData = this.getCommonRollData(attrKey)
- rollData.multiplier = (isInit) ? 1 : 2
- rollData.isInit = isInit
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
-
- /* -------------------------------------------- */
- async rollCompetence(attrKey, compId) {
- let rollData = this.getCommonRollData(attrKey, compId)
- rollData.multiplier = 1 // Attr multiplier, always 1 in competence mode
- console.log("RollDatra", rollData)
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
-
- /* -------------------------------------------- */
- async rollArmeOffensif(armeId) {
- let arme = this.items.get(armeId)
- if (arme.type == "arme") {
- arme = this.prepareArme(arme)
- }
- let rollData = this.getCommonRollData(arme.system.attrKey, arme.system.competence._id)
- rollData.arme = arme
- MournbladeCYD2Utility.updateWithTarget(rollData)
- console.log("ARME!", rollData)
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
- /* -------------------------------------------- */
- async rollAssommer() {
- let rollData = this.getCommonRollData("pui", undefined, "Filouterie")
- rollData.assomer = true
- rollData.conditionsCommunes = true
- MournbladeCYD2Utility.updateWithTarget(rollData)
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
- /* -------------------------------------------- */
- async rollCoupBas() {
- let rollData = this.getCommonRollData("pui", undefined, "Mêlée")
- rollData.coupBas = true
- rollData.conditionsCommunes = true
- MournbladeCYD2Utility.updateWithTarget(rollData)
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
- /* -------------------------------------------- */
- async rollImmobiliser() {
- let rollData = this.getCommonRollData("pui", undefined, "Mêlée")
- rollData.immobiliser = true
- rollData.conditionsCommunes = true
- rollData.cibleconsciente = true
- MournbladeCYD2Utility.updateWithTarget(rollData)
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
- /* -------------------------------------------- */
- async rollRepousser() {
- let rollData = this.getCommonRollData("pui", undefined, "Mêlée")
- rollData.repousser = true
- rollData.conditionsCommunes = true
- rollData.cibleconsciente = true
- MournbladeCYD2Utility.updateWithTarget(rollData)
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
- /* -------------------------------------------- */
- async rollDesengager() {
- let rollData = this.getCommonRollData("adr", undefined, "Mouvements")
- rollData.desengager = true
- rollData.conditionsCommunes = true
- MournbladeCYD2Utility.updateWithTarget(rollData)
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
-
- /* -------------------------------------------- */
- async rollArmeDegats(armeId, targetVigueur = undefined, rollDataInput = undefined) {
- let arme = this.items.get(armeId)
- if (arme.type == "arme") {
- arme = this.prepareArme(arme)
- }
- console.log("DEGATS", arme, targetVigueur, rollDataInput)
- let roll
- let bonus = 0
- let bonus2 = 0
-
- if (rollDataInput?.applyCoupDevastateur) {
- bonus2 = Math.floor(this.system.attributs.pui.value / 2)
- let talent = this.items.find(item => item.type == "talent" && item.name.toLowerCase() == "coup dévastateur")
- this.updateEmbeddedDocuments('Item', [{ _id: talent.id, 'system.used': true }])
- }
-
- if (rollDataInput?.isHeroique) {
- if (rollDataInput?.attaqueCharge) {
- bonus = 5
- }
- if (rollDataInput?.chargeCavalerie) {
- bonus = 6
- }
- roll = await new Roll("2d10rr10+" + arme.system.totalDegats + "+" + bonus + "+" + bonus2).roll()
- } else {
- if (rollDataInput?.attaqueCharge) {
- bonus = 3
- }
- if (rollDataInput?.chargeCavalerie) {
- bonus = 4
- }
- roll = await new Roll("1d10+" + arme.system.totalDegats + "+" + bonus + "+" + bonus2).roll()
- }
- await MournbladeCYD2Utility.showDiceSoNice(roll, game.settings.get("core", "rollMode"));
- let nbEtatPerdus = 0
- if (targetVigueur) {
- nbEtatPerdus = Math.floor(roll.total / targetVigueur)
- }
- //console.log(roll)
- let rollData = {
- arme: arme,
- finalResult: roll.total,
- formula: roll.formula,
- alias: this.name,
- actorImg: this.img,
- actorId: this.id,
- defenderTokenId: rollDataInput?.defenderTokenId,
- actionImg: arme.img,
- targetVigueur: targetVigueur,
- nbEtatPerdus: nbEtatPerdus
- }
- MournbladeCYD2Utility.createChatWithRollMode(rollData.alias, {
- content: await renderTemplate(`systems/fvtt-mournblade-cyd2/templates/chat-degats-result.html`, rollData)
- })
-
- if (rollDataInput?.defenderTokenId && nbEtatPerdus) {
- MournbladeCYD2Utility.applyCombativite(rollDataInput, nbEtatPerdus)
- }
-
- }
-}
diff --git a/.history/modules/mournblade-cyd2-actor_20251026132651.js b/.history/modules/mournblade-cyd2-actor_20251026132651.js
deleted file mode 100644
index d1f46ec..0000000
--- a/.history/modules/mournblade-cyd2-actor_20251026132651.js
+++ /dev/null
@@ -1,890 +0,0 @@
-/* -------------------------------------------- */
-import { MournbladeCYD2Utility } from "./mournblade-cyd2-utility.js";
-import { MournbladeCYD2RollDialog } from "./mournblade-cyd2-roll-dialog.js";
-
-/* -------------------------------------------- */
-const __degatsBonus = [-2, -2, -1, -1, 0, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 8, 8, 9, 9, 10, 10]
-const __vitesseBonus = [-2, -2, -1, -1, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8]
-
-/* -------------------------------------------- */
-/**
- * Extend the base Actor entity by defining a custom roll data structure which is ideal for the Simple system.
- * @extends {Actor}
- */
-export class MournbladeCYD2Actor extends Actor {
-
- /* -------------------------------------------- */
- /**
- * Override the create() function to provide additional SoS functionality.
- *
- * This overrided create() function adds initial items
- * Namely: Basic skills, money,
- *
- * @param {Object} data Barebones actor data which this function adds onto.
- * @param {Object} options (Unused) Additional options which customize the creation workflow.
- *
- */
-
- static async create(data, options) {
-
- // Case of compendium global import
- if (data instanceof Array) {
- return super.create(data, options);
- }
- // If the created actor has items (only applicable to duplicated actors) bypass the new actor creation logic
- if (data.items) {
- let actor = super.create(data, options);
- return actor;
- }
-
- if (data.type == 'personnage') {
- console.log("Loading skills for personnage")
- const skills = await MournbladeCYD2Utility.loadCompendium("fvtt-mournblade-cyd2.skills")
- data.items = skills.map(i => i.toObject())
- }
- if (data.type == 'creature') {
- const skills = await MournbladeCYD2Utility.loadCompendium("fvtt-mournblade-cyd2.skills-creatures")
- data.items = skills.map(i => i.toObject())
- data.items.push({ name: "Arme naturelle 1", type: 'arme', img: "systems/fvtt-mournblade-cyd2/assets/icons/melee.webp", system: { typearme: "contact", bonusmaniementoff: 0, seuildefense: 0, degats: "0" } })
- data.items.push({ name: "Arme naturelle 2", type: 'arme', img: "systems/fvtt-mournblade-cyd2/assets/icons/melee.webp", system: { typearme: "contact", bonusmaniementoff: 0, seuildefense: 0, degats: "0" } })
- }
-
- return super.create(data, options);
- }
-
- /* -------------------------------------------- */
- getBonusDefenseFromTalents() {
- let talents = this.items.filter(item => item.type == "talent" && item.system.isautomated)
- let bonus = 0
- for (let talent of talents) {
- for (let auto of talent.system.automations) {
- if (auto.eventtype == "bonus-permanent" && auto.bonusname == "bonus-defensif") {
- bonus += Number(auto.bonus || 0)
- }
- }
- }
- return bonus
- }
-
- /* -------------------------------------------- */
- prepareArme(arme) {
- arme = foundry.utils.duplicate(arme)
- let combat = this.getCombatValues()
- if (arme.system.typearme == "contact" || arme.system.typearme == "contactjet") {
- let bonusDefense = this.getBonusDefenseFromTalents()
- arme.system.competence = foundry.utils.duplicate(this.items.find(item => item.type == "competence" && item.name.toLowerCase() == "mêlée"))
- arme.system.attrKey = "pui"
- arme.system.totalDegats = arme.system.degats + "+" + combat.bonusDegatsTotal
- arme.system.totalOffensif = this.system.attributs.pui.value + arme.system.competence.system.niveau + arme.system.bonusmaniementoff + (this.system.combat.monte ? 3 : 0)
- arme.system.totalDefensif = combat.defenseTotal + arme.system.competence.system.niveau + arme.system.seuildefense + bonusDefense + (this.system.combat.monte ? 3 : 0)
- console.log("Arme", arme.system.totalDefensif, combat, arme.system.competence.system.niveau, arme.system.seuildefense, bonusDefense)
- arme.system.isdefense = true
- arme.system.isMelee = true
- arme.system.isDistance = false
- }
- if (arme.system.typearme == "jet" || arme.system.typearme == "tir") {
- arme.system.competence = foundry.utils.duplicate(this.items.find(item => item.type == "competence" && item.name.toLowerCase() == "armes à distance"))
- arme.system.attrKey = "adr"
- arme.system.totalOffensif = this.system.attributs.adr.value + arme.system.competence.system.niveau + arme.system.bonusmaniementoff
- arme.system.totalDegats = arme.system.degats
- arme.system.isMelee = false
- arme.system.isDistance = true
- if (arme.system.isdefense) {
- arme.system.totalDefensif = combat.defenseTotal + arme.system.competence.system.niveau + arme.system.seuildefense
- }
- }
- return arme
- }
-
- /* -------------------------------------------- */
- getItemSorted(types) {
- let items = this.items.filter(item => types.includes(item.type)) || []
- MournbladeCYD2Utility.sortArrayObjectsByName(items)
- return items
- }
- getWeapons() {
- let armes = []
- for (let arme of this.items) {
- if (arme.type == "arme") {
- armes.push(this.prepareArme(arme))
- }
- }
- MournbladeCYD2Utility.sortArrayObjectsByName(armes)
- return armes
- }
- getMonnaies() {
- return this.getItemSorted(["monnaie"])
- }
- getEquipments() {
- return this.getItemSorted(["equipement"])
- }
- getArmors() {
- return this.getItemSorted(["protection"])
- }
- getHistoriques() {
- return this.getItemSorted(["historique"])
- }
- getProfils() {
- return this.getItemSorted(["profil"])
- }
- getTalents() {
- return this.getItemSorted(["talent"])
- }
- getRessources() {
- return this.getItemSorted(["ressource"])
- }
- getContacts() {
- return this.getItemSorted(["contact"])
- }
- getDons() {
- return this.getItemSorted(["don"])
- }
- getPactes() {
- return this.getItemSorted(["pacte"])
- }
- getTendances() {
- return this.getItemSorted(["tendance"])
- }
- getRunes() {
- return this.getItemSorted(["rune"])
- }
- getTraitsChaotiques() {
- return this.getItemSorted(["traitchaotique"])
- }
- getTraitsEspeces() {
- return this.getItemSorted(["traitespece"])
- }
-
- /* -------------------------------------------- */
- getAspect() {
- return (this.system.balance.loi > this.system.balance.chaos) ? this.system.balance.loi : this.system.balance.chaos
- }
- getMarge() {
- return Math.abs(this.system.balance.loi - this.system.balance.chaos)
- }
- getAlignement() {
- return (this.system.balance.loi > this.system.balance.chaos) ? "loyal" : "chaotique"
- }
-
- /* -------------------------------------------- */
- getSkills() {
- let comp = []
- for (let item of this.items) {
- item = foundry.utils.duplicate(item)
- if (item.type == "competence") {
- item.system.attribut1total = item.system.niveau + (this.system.attributs[item.system.attribut1]?.value || 0)
- item.system.attribut2total = item.system.niveau + (this.system.attributs[item.system.attribut2]?.value || 0)
- item.system.attribut3total = item.system.niveau + (this.system.attributs[item.system.attribut3]?.value || 0)
- if (item.system.niveau == 0) {
- item.system.attribut1total -= 3
- item.system.attribut2total -= 3
- item.system.attribut3total -= 3
- }
- item.system.attribut1label = this.system.attributs[item.system.attribut1]?.label || ""
- item.system.attribut2label = this.system.attributs[item.system.attribut2]?.label || ""
- item.system.attribut3label = this.system.attributs[item.system.attribut3]?.label || ""
- comp.push(item)
- }
- }
- MournbladeCYD2Utility.sortArrayObjectsByName(comp)
- return comp
- }
-
- /* ----------------------- --------------------- */
- addMember(actorId) {
- let members = foundry.utils.duplicate(this.system.members)
- members.push({ id: actorId })
- this.update({ 'system.members': members })
- }
- async removeMember(actorId) {
- let members = this.system.members.filter(it => it.id != actorId)
- this.update({ 'system.members': members })
- }
-
- /* -------------------------------------------- */
- getDefenseBase() {
- return Math.max(this.system.attributs.tre.value, this.system.attributs.adr.value)
- }
-
- /* -------------------------------------------- */
- getVitesseBase() {
- return 5 + __vitesseBonus[this.system.attributs.adr.value]
- }
- /* -------------------------------------------- */
- getProtection() {
- let equipProtection = 0
- for (let armor of this.items) {
- if (armor.type == "protection" && armor.system.equipped) {
- equipProtection += Number(armor.system.protection)
- }
- }
- if (equipProtection < 4) {
- return 4 + equipProtection // Cas des boucliers + sans armure
- }
- return equipProtection // Uniquement la protection des armures + boucliers
- }
-
- /* -------------------------------------------- */
- getCombatValues() {
- let combat = {
- initBase: this.system.attributs.adr.value,
- initTotal: this.system.attributs.adr.value + this.system.combat.initbonus,
- bonusDegats: this.getBonusDegats(),
- bonusDegatsTotal: this.getBonusDegats() + this.system.combat.bonusdegats,
- vitesseBase: this.getVitesseBase(),
- vitesseTotal: this.getVitesseBase() + this.system.combat.vitessebonus,
- defenseBase: this.getDefenseBase(),
- protection: this.getProtection(),
- defenseTotal: this.getDefenseBase() + this.system.combat.defensebonus + this.getProtection() - this.getTotalAdversite() + (this.system.combat.defensetotale ? 3 : 0)
- }
- return combat
- }
-
- /* -------------------------------------------- */
- prepareBaseData() {
- }
-
- /* -------------------------------------------- */
- async prepareData() {
- super.prepareData();
- }
-
- /* -------------------------------------------- */
- prepareDerivedData() {
-
- if (this.type == 'personnage') {
- let talentBonus = this.getVigueurBonus()
- let vigueur = Math.floor((this.system.attributs.pui.value + this.system.attributs.tre.value) / 2) + talentBonus + this.system.sante.vigueurmodifier
- if (vigueur != this.system.sante.vigueur) {
- this.update({ 'system.sante.vigueur': vigueur })
- }
-
- let seuilPouvoirBonus = this.getSeuilPouvoirBonus()
- let seuilPouvoir = Math.floor((this.system.attributs.tre.value + this.system.attributs.cla.value) / 2) + seuilPouvoirBonus + this.system.ame.seuilpouvoirmodifier
- if (seuilPouvoir != this.system.ame.seuilpouvoir) {
- this.update({ 'system.ame.seuilpouvoir': seuilPouvoir })
- }
- }
- super.prepareDerivedData()
- }
-
- /* -------------------------------------------- */
- _preUpdate(changed, options, user) {
- if (changed?.system?.sante?.etat && changed?.system?.sante?.etat != this.system.sante.etat) {
- setTimeout(() => {
- this.processCombativite(changed.system.sante)
- }, 800)
- }
- if (changed?.system?.ame?.etat && changed?.system?.ame?.etat != this.system.ame.etat) {
- // L'état d'Âme ne peut pas être inférieur au minimum (max dans le système)
- let minAme = this.system.ame.max !== undefined ? this.system.ame.max : 0
- if (changed.system.ame.etat < minAme) {
- changed.system.ame.etat = minAme
- }
- // L'état d'Âme ne peut pas dépasser nbame (Brisé)
- if (changed.system.ame.etat > this.system.ame.nbame) {
- changed.system.ame.etat = this.system.ame.nbame
- }
- setTimeout(() => {
- this.processAme(changed.system.ame)
- }, 800)
- }
- // Si le max d'Âme change, ajuster l'état actuel si nécessaire
- if (changed?.system?.ame?.max !== undefined && changed.system.ame.max != this.system.ame.max) {
- if (this.system.ame.etat < changed.system.ame.max) {
- changed.system.ame.etat = changed.system.ame.max
- }
- }
- super._preUpdate(changed, options, user);
- }
-
- /* -------------------------------------------- */
- _onUpdate(data, options, user) {
- super._onUpdate(data, options, user);
- }
- /* -------------------------------------------- */
- getItemById(id) {
- let item = this.items.find(item => item.id == id);
- if (item) {
- item = foundry.utils.duplicate(item)
- }
- return item;
- }
-
- /* -------------------------------------------- */
- async equipItem(itemId) {
- let item = this.items.find(item => item.id == itemId)
- if (item && item.system) {
- let update = { _id: item.id, "system.equipped": !item.system.equipped }
- await this.updateEmbeddedDocuments('Item', [update]); // Updates one EmbeddedEntity
- }
- }
-
- /* -------------------------------------------- */
- editItemField(itemId, itemType, itemField, dataType, value) {
- let item = this.items.find(item => item.id == itemId)
- if (item) {
- console.log("Item ", item, itemField, dataType, value)
- if (dataType.toLowerCase() == "number") {
- value = Number(value)
- } else {
- value = String(value)
- }
- let update = { _id: item.id, [`system.${itemField}`]: value };
- this.updateEmbeddedDocuments("Item", [update])
- }
- }
-
- /* -------------------------------------------- */
- checkAttribut(attribut, minLevel) {
- let attr = this.system.attributs.find(at => at.labelnorm == attribut.toLowerCase())
- if (attr && attr.value >= minLevel) {
- return { isValid: true, attr: foundry.utils.duplicate(attr) }
- }
- return { isValid: false }
- }
- /* -------------------------------------------- */
- checkAttributOrCompetenceLevel(compName, minLevel) {
- let comp = this.items.find(i => i.type == "competence" && i.name.toLowerCase() == compName.toLowerCase() && i.system.niveau >= minLevel)
- if (comp) {
- return { isValid: true, item: foundry.utils.duplicate(comp) }
- } else {
- for (let attrKey in this.system.attributs) {
- if (this.system.attributs[attrKey].label.toLowerCase() == compName.toLowerCase() && this.system.attributs[attrKey].value >= minLevel) {
- return { isValid: true, item: foundry.utils.duplicate(this.system.attributs[attrKey]) }
- }
- }
- }
- return { isValid: false, warningMessage: `Prérequis insuffisant : la compétence/attribut ${compName} doit être de niveau ${minLevel} au minimum` }
- }
- /* -------------------------------------------- */
- addCompetenceBonus(compName, bonus, baCost) {
- let comp = this.items.find(i => i.type == "competence" && i.name.toLowerCase() == compName.toLowerCase())
- if (comp) {
- comp = foundry.utils.duplicate(comp)
- comp.system.bonus = bonus
- comp.system.baCost = baCost
- return { isValid: true, item: comp }
- }
- return { isValid: false, warningMessage: `Compétence ${compName} non trouvée` }
- }
- /* -------------------------------------------- */
- checkIfCompetence(compName) {
- let comp = this.items.find(i => i.type == "competence" && i.name.toLowerCase() == compName.toLowerCase())
- if (comp) {
- return { isValid: true, item: comp }
- }
- return { isValid: false }
- }
- /* -------------------------------------------- */
- getVigueur() {
- return this.system.sante.vigueur
- }
-
- /* -------------------------------------------- */
- getVigueurBonus() {
- let talents = this.items.filter(item => item.type == "talent" && item.system.isautomated)
- let bonus = 0
- for (let talent of talents) {
- for (let auto of talent.system.automations) {
- if (auto.eventtype == "bonus-permanent" && auto.bonusname == "vigueur") {
- bonus += Number(auto.bonus || 0)
- }
- }
- }
- return bonus
- }
-
- /* -------------------------------------------- */
- getSeuilPouvoir() {
- return this.system.ame.seuilpouvoir
- }
-
- /* -------------------------------------------- */
- getSeuilPouvoirBonus() {
- let talents = this.items.filter(item => item.type == "talent" && item.system.isautomated)
- let bonus = 0
- for (let talent of talents) {
- for (let auto of talent.system.automations) {
- if (auto.eventtype == "bonus-permanent" && auto.bonusname == "seuilpouvoir") {
- bonus += Number(auto.bonus || 0)
- }
- }
- }
- return bonus
- }
-
- /* -------------------------------------------- */
- getAmeMax() {
- // Utiliser une vérification stricte car 0 (Serein) est une valeur valide
- return this.system.ame.max !== undefined ? this.system.ame.max : this.system.ame.nbame
- }
-
- /* -------------------------------------------- */
- getBonneAventure() {
- return this.system.bonneaventure.actuelle
- }
- /* -------------------------------------------- */
- checkBonneAventure(cost) {
- return (this.system.bonneaventure.actuelle >= cost)
- }
- /* -------------------------------------------- */
- changeBonneAventure(value) {
- let newBA = this.system.bonneaventure.actuelle
- newBA += value
- this.update({ 'system.bonneaventure.actuelle': newBA })
- }
-
- /* -------------------------------------------- */
- getEclat() {
- return this.system.eclat.value
- }
-
- /* -------------------------------------------- */
- changeEclat(value) {
- let newE = this.system.eclat.value
- newE += value
- this.update({ 'system.eclat.value': newE })
- }
-
- /* -------------------------------------------- */
- compareName(a, b) {
- if (a.name < b.name) {
- return -1;
- }
- if (a.name > b.name) {
- return 1;
- }
- return 0;
- }
-
- /* -------------------------------------------- */
- getAttribute(attrKey) {
- return this.system.attributes[attrKey]
- }
-
- /* -------------------------------------------- */
- getBonusDegats() {
- return 0;
- }
-
- /* -------------------------------------------- */
- changeEtatCombativite(value) {
- if (value === "vaincu") {
- value = 200
- }
- let sante = foundry.utils.duplicate(this.system.sante)
- sante.etat += Number(value)
- sante.etat = Math.max(sante.etat, 0)
- sante.etat = Math.min(sante.etat, this.system.sante.nbcombativite)
- this.update({ 'system.sante': sante })
- if (sante.etat == this.system.sante.nbcombativite) {
- ChatMessage.create({ content: `${this.name} est vaincu !` })
- }
- // Duplicated ! this.processCombativite(sante)
- }
-
- /* -------------------------------------------- */
- changeEtatAme(value) {
- if (value === "brise") {
- value = 200
- }
- let ame = foundry.utils.duplicate(this.system.ame)
- ame.etat += Number(value)
- // L'état ne peut pas être inférieur au minimum (max dans le système)
- let minAme = this.system.ame.max !== undefined ? this.system.ame.max : 0
- ame.etat = Math.max(ame.etat, minAme)
- // L'état ne peut pas dépasser nbame (Brisé)
- ame.etat = Math.min(ame.etat, this.system.ame.nbame)
- this.update({ 'system.ame': ame })
- if (ame.etat >= this.system.ame.nbame) {
- ChatMessage.create({ content: `${this.name} est brisé !` })
- }
- }
-
- /* -------------------------------------------- */
- processCombativite(sante) {
- sante = sante || foundry.utils.duplicate(this.system.sante)
- // Gestion des états affaibli et très affaibli
- if (sante.etat == this.system.sante.nbcombativite - 2 || sante.etat == this.system.sante.nbcombativite - 1) {
- if (sante.etat == this.system.sante.nbcombativite - 2 && this.items.find(item => item.type == "talent" && item.name.toLowerCase() == "encaissement")) {
- ChatMessage.create({ content: `${this.name} ne subit pas les 2 adversités rouge grâce à Encaissement. Pensez à les ajouter à la fin de la scène !` })
- } else if (sante.etat == this.system.sante.nbcombativite - 1 && this.items.find(item => item.type == "talent" && item.name.toLowerCase().includes("vaillant"))) {
- ChatMessage.create({ content: `${this.name} ne subit pas les 2 adversités rouge grâce à Vaillant. Pensez à les ajouter à la fin de la scène !` })
- } else {
- ChatMessage.create({ content: `${this.name} subit 2 adversités rouge !` })
- this.incDecAdversite("rouge", 2)
- }
- }
- }
-
- /* -------------------------------------------- */
- processAme(ame) {
- ame = ame || foundry.utils.duplicate(this.system.ame)
- let traumatiseValue = this.system.ame.nbame - 2
- let tresTraumatiseValue = this.system.ame.nbame - 1
- let briseValue = this.system.ame.nbame
-
- // Gestion des états Traumatisé, Très Traumatisé et Brisé
- if (ame.etat == traumatiseValue) {
- ChatMessage.create({ content: `${this.name} est Traumatisé et subit 1 adversité bleue et 1 adversité noire !` })
- this.incDecAdversite("bleue", 1)
- this.incDecAdversite("noire", 1)
- } else if (ame.etat == tresTraumatiseValue) {
- ChatMessage.create({ content: `${this.name} est Très Traumatisé et subit 1 adversité bleue et 1 adversité noire !` })
- this.incDecAdversite("bleue", 1)
- this.incDecAdversite("noire", 1)
- } else if (ame.etat >= briseValue) {
- ChatMessage.create({ content: `${this.name} est Brisé et subit 1 adversité noire !` })
- this.incDecAdversite("noire", 1)
- }
- }
-
- /* -------------------------------------------- */
- async equipGear(equipmentId) {
- let item = this.items.find(item => item.id == equipmentId);
- if (item?.system?.data) {
- let update = { _id: item.id, "system.equipped": !item.system.equipped };
- await this.updateEmbeddedDocuments('Item', [update]); // Updates one EmbeddedEntity
- }
- }
-
- /* -------------------------------------------- */
- getSubActors() {
- let subActors = [];
- for (let id of this.system.subactors) {
- subActors.push(foundry.utils.duplicate(game.actors.get(id)));
- }
- return subActors;
- }
- /* -------------------------------------------- */
- async addSubActor(subActorId) {
- let subActors = foundry.utils.duplicate(this.system.subactors);
- subActors.push(subActorId);
- await this.update({ 'system.subactors': subActors });
- }
- /* -------------------------------------------- */
- async delSubActor(subActorId) {
- let newArray = [];
- for (let id of this.system.subactors) {
- if (id != subActorId) {
- newArray.push(id);
- }
- }
- await this.update({ 'system.subactors': newArray });
- }
-
- /* -------------------------------------------- */
- getTotalAdversite() {
- return this.system.adversite.bleue + this.system.adversite.rouge + this.system.adversite.noire
- }
-
- /* -------------------------------------------- */
- async incDecAdversite(adv, incDec = 0) {
- let adversite = foundry.utils.duplicate(this.system.adversite)
- adversite[adv] += Number(incDec)
- adversite[adv] = Math.max(adversite[adv], 0)
- adversite[adv] = Math.min(adversite[adv], 20)
- this.update({ 'system.adversite': adversite })
- }
- /* -------------------------------------------- */
- async incDecQuantity(objetId, incDec = 0) {
- let objetQ = this.items.get(objetId)
- if (objetQ) {
- let newQ = objetQ.system.quantite + incDec
- newQ = Math.max(newQ, 0)
- await this.updateEmbeddedDocuments('Item', [{ _id: objetQ.id, 'system.quantite': newQ }]); // pdates one EmbeddedEntity
- }
- }
-
- /* -------------------------------------------- */
- computeRichesse() {
- let valueSC = 0
- for (let monnaie of this.items) {
- if (monnaie.type == "monnaie") {
- valueSC += Number(monnaie.system.prixsc) * Number(monnaie.system.quantite)
- }
- }
- return MournbladeCYD2Utility.computeMonnaieDetails(valueSC)
- }
-
- /* -------------------------------------------- */
- computeValeurEquipement() {
- let valueSC = 0
- for (let equip of this.items) {
- if (equip.type == "equipement" || equip.type == "arme" || equip.type == "protection") {
- valueSC += Number(equip.system.prixsc) * Number(equip.system.quantite ?? 1)
- valueSC += (Number(equip.system.prixca) * Number(equip.system.quantite ?? 1)) * 20
- valueSC += (Number(equip.system.prixpo) * Number(equip.system.quantite ?? 1)) * 400
- }
- }
- return MournbladeCYD2Utility.computeMonnaieDetails(valueSC)
- }
-
- /* -------------------------------------------- */
- getCompetence(compId) {
- return this.items.get(compId)
- }
-
- /* -------------------------------------------- */
- async setPredilectionUsed(compId, predIdx) {
- let comp = this.items.get(compId)
- let pred = foundry.utils.duplicate(comp.system.predilections)
- pred[predIdx].used = true
- await this.updateEmbeddedDocuments('Item', [{ _id: compId, 'system.predilections': pred }])
- }
-
- /* -------------------------------------------- */
- getInitiativeScore() {
- let init = this.getFlag("world", "last-initiative")
- return init || -1
- }
-
- /* -------------------------------------------- */
- getBestAttackValue() {
- let attackList = this.items.filter(item => (item.type == "arme" || item.type == "talent") && item.system.equipped)
- let maxOff = 0
- let bestArme
- for (let arme of attackList) {
- if (arme.type == "arme") {
- arme = this.prepareArme(arme)
- }
- if (arme.system.totalOffensif > maxOff) {
- maxOff = arme.system.totalOffensif
- bestArme = foundry.utils.duplicate(arme)
- }
- }
- return bestArme
- }
-
- /* -------------------------------------------- */
- getBestDefenseValue() {
- let defenseList = this.items.filter(item => (item.type == "arme") && item.system.equipped)
- let maxDef = 0
- let bestArme
- for (let arme of defenseList) {
- if (arme.type == "arme") {
- arme = this.prepareArme(arme)
- }
- if (arme.system.totalDefensif > maxDef) {
- maxDef = arme.system.totalDefensif
- bestArme = foundry.utils.duplicate(arme)
- }
- }
- return bestArme
- }
-
- /* -------------------------------------------- */
- searchRelevantTalents(competence) {
- let talents = []
-
- for (let talent of this.items) {
- if (talent.type == "talent" && talent.system.isautomated && talent.system.automations.length > 0) {
- for (let auto of talent.system.automations) {
- if (auto.eventtype === "prepare-roll") {
- if (auto.competence.toLowerCase() == competence.name.toLowerCase()) {
- talent = foundry.utils.duplicate(talent)
- talent.system.bonus = auto.bonus
- talent.system.baCost = auto.baCost
- talents.push(talent)
- }
- }
- }
- }
- }
- return talents
- }
-
- /* -------------------------------------------- */
- buildListeAdversites() {
- return []
- }
-
- /* -------------------------------------------- */
- getCommonRollData(attrKey = undefined, compId = undefined, compName = undefined) {
- let rollData = MournbladeCYD2Utility.getBasicRollData()
- rollData.alias = this.name
- rollData.actorImg = this.img
- rollData.actorId = this.id
- rollData.tokenId = this.token?.id
- rollData.img = this.img
- rollData.attributs = MournbladeCYD2Utility.getAttributs()
- rollData.maitriseId = "none"
- rollData.nbEclat = this.system.eclat.value
- rollData.nbBA = this.system.bonneaventure.actuelle
- rollData.nbAdversites = this.getTotalAdversite()
- rollData.talents = []
- rollData.attrKey2 = "none"
- rollData.coupDevastateur = this.items.find(it => it.type == "talent" && it.name.toLowerCase() == "coup dévastateur" && !it.system.used)
- rollData.hasAmbidextre = this.items.find(it => it.type == "talent" && it.name.toLowerCase() == "ambidextre")
- rollData.hasFeinte = this.system.bonneaventure.actuelle > 0 && this.items.find(it => it.type == "talent" && it.name.toLowerCase() == "feinte")
- rollData.isMonte = this.system.combat.monte
- rollData.config = game.system.mournbladecyd2.config
-
- if (attrKey) {
- rollData.attrKey = attrKey
- if (attrKey != "tochoose") {
- rollData.actionImg = "systems/fvtt-mournblade-cyd2/assets/icons/" + this.system.attributs[attrKey].labelnorm + ".webp"
- rollData.attr = foundry.utils.duplicate(this.system.attributs[attrKey])
- }
- }
- if (compId) {
- rollData.competence = foundry.utils.duplicate(this.items.get(compId) || {})
- let maitrises = [{ key: "none", label: "Aucune" }]
- rollData.competence.system.predilections.forEach(function (item) {
- if (item.maitrise) {
- maitrises.push({ key: item.id, label: item.name });
- }
- })
- rollData.maitrises = maitrises // rollData.competence.system.predilections.filter(p => p.maitrise)
- rollData.actionImg = rollData.competence?.img
- rollData.talents = this.searchRelevantTalents(rollData.competence)
- }
- if (compName) {
- rollData.competence = foundry.utils.duplicate(this.items.find(item => item.name.toLowerCase() == compName.toLowerCase()) || {})
- rollData.actionImg = rollData.competence?.img
- }
- return rollData
- }
-
- /* -------------------------------------------- */
- async rollAttribut(attrKey, isInit = false) {
- let rollData = this.getCommonRollData(attrKey)
- rollData.multiplier = (isInit) ? 1 : 2
- rollData.isInit = isInit
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
-
- /* -------------------------------------------- */
- async rollCompetence(attrKey, compId) {
- let rollData = this.getCommonRollData(attrKey, compId)
- rollData.multiplier = 1 // Attr multiplier, always 1 in competence mode
- console.log("RollDatra", rollData)
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
-
- /* -------------------------------------------- */
- async rollArmeOffensif(armeId) {
- let arme = this.items.get(armeId)
- if (arme.type == "arme") {
- arme = this.prepareArme(arme)
- }
- let rollData = this.getCommonRollData(arme.system.attrKey, arme.system.competence._id)
- rollData.arme = arme
- MournbladeCYD2Utility.updateWithTarget(rollData)
- console.log("ARME!", rollData)
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
- /* -------------------------------------------- */
- async rollAssommer() {
- let rollData = this.getCommonRollData("pui", undefined, "Filouterie")
- rollData.assomer = true
- rollData.conditionsCommunes = true
- MournbladeCYD2Utility.updateWithTarget(rollData)
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
- /* -------------------------------------------- */
- async rollCoupBas() {
- let rollData = this.getCommonRollData("pui", undefined, "Mêlée")
- rollData.coupBas = true
- rollData.conditionsCommunes = true
- MournbladeCYD2Utility.updateWithTarget(rollData)
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
- /* -------------------------------------------- */
- async rollImmobiliser() {
- let rollData = this.getCommonRollData("pui", undefined, "Mêlée")
- rollData.immobiliser = true
- rollData.conditionsCommunes = true
- rollData.cibleconsciente = true
- MournbladeCYD2Utility.updateWithTarget(rollData)
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
- /* -------------------------------------------- */
- async rollRepousser() {
- let rollData = this.getCommonRollData("pui", undefined, "Mêlée")
- rollData.repousser = true
- rollData.conditionsCommunes = true
- rollData.cibleconsciente = true
- MournbladeCYD2Utility.updateWithTarget(rollData)
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
- /* -------------------------------------------- */
- async rollDesengager() {
- let rollData = this.getCommonRollData("adr", undefined, "Mouvements")
- rollData.desengager = true
- rollData.conditionsCommunes = true
- MournbladeCYD2Utility.updateWithTarget(rollData)
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
-
- /* -------------------------------------------- */
- async rollArmeDegats(armeId, targetVigueur = undefined, rollDataInput = undefined) {
- let arme = this.items.get(armeId)
- if (arme.type == "arme") {
- arme = this.prepareArme(arme)
- }
- console.log("DEGATS", arme, targetVigueur, rollDataInput)
- let roll
- let bonus = 0
- let bonus2 = 0
-
- if (rollDataInput?.applyCoupDevastateur) {
- bonus2 = Math.floor(this.system.attributs.pui.value / 2)
- let talent = this.items.find(item => item.type == "talent" && item.name.toLowerCase() == "coup dévastateur")
- this.updateEmbeddedDocuments('Item', [{ _id: talent.id, 'system.used': true }])
- }
-
- if (rollDataInput?.isHeroique) {
- if (rollDataInput?.attaqueCharge) {
- bonus = 5
- }
- if (rollDataInput?.chargeCavalerie) {
- bonus = 6
- }
- roll = await new Roll("2d10rr10+" + arme.system.totalDegats + "+" + bonus + "+" + bonus2).roll()
- } else {
- if (rollDataInput?.attaqueCharge) {
- bonus = 3
- }
- if (rollDataInput?.chargeCavalerie) {
- bonus = 4
- }
- roll = await new Roll("1d10+" + arme.system.totalDegats + "+" + bonus + "+" + bonus2).roll()
- }
- await MournbladeCYD2Utility.showDiceSoNice(roll, game.settings.get("core", "rollMode"));
- let nbEtatPerdus = 0
- if (targetVigueur) {
- nbEtatPerdus = Math.floor(roll.total / targetVigueur)
- }
- //console.log(roll)
- let rollData = {
- arme: arme,
- finalResult: roll.total,
- formula: roll.formula,
- alias: this.name,
- actorImg: this.img,
- actorId: this.id,
- defenderTokenId: rollDataInput?.defenderTokenId,
- actionImg: arme.img,
- targetVigueur: targetVigueur,
- nbEtatPerdus: nbEtatPerdus
- }
- MournbladeCYD2Utility.createChatWithRollMode(rollData.alias, {
- content: await renderTemplate(`systems/fvtt-mournblade-cyd2/templates/chat-degats-result.html`, rollData)
- })
-
- if (rollDataInput?.defenderTokenId && nbEtatPerdus) {
- MournbladeCYD2Utility.applyCombativite(rollDataInput, nbEtatPerdus)
- }
-
- }
-}
diff --git a/.history/modules/mournblade-cyd2-actor_20251026132939.js b/.history/modules/mournblade-cyd2-actor_20251026132939.js
deleted file mode 100644
index d1f46ec..0000000
--- a/.history/modules/mournblade-cyd2-actor_20251026132939.js
+++ /dev/null
@@ -1,890 +0,0 @@
-/* -------------------------------------------- */
-import { MournbladeCYD2Utility } from "./mournblade-cyd2-utility.js";
-import { MournbladeCYD2RollDialog } from "./mournblade-cyd2-roll-dialog.js";
-
-/* -------------------------------------------- */
-const __degatsBonus = [-2, -2, -1, -1, 0, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 8, 8, 9, 9, 10, 10]
-const __vitesseBonus = [-2, -2, -1, -1, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8]
-
-/* -------------------------------------------- */
-/**
- * Extend the base Actor entity by defining a custom roll data structure which is ideal for the Simple system.
- * @extends {Actor}
- */
-export class MournbladeCYD2Actor extends Actor {
-
- /* -------------------------------------------- */
- /**
- * Override the create() function to provide additional SoS functionality.
- *
- * This overrided create() function adds initial items
- * Namely: Basic skills, money,
- *
- * @param {Object} data Barebones actor data which this function adds onto.
- * @param {Object} options (Unused) Additional options which customize the creation workflow.
- *
- */
-
- static async create(data, options) {
-
- // Case of compendium global import
- if (data instanceof Array) {
- return super.create(data, options);
- }
- // If the created actor has items (only applicable to duplicated actors) bypass the new actor creation logic
- if (data.items) {
- let actor = super.create(data, options);
- return actor;
- }
-
- if (data.type == 'personnage') {
- console.log("Loading skills for personnage")
- const skills = await MournbladeCYD2Utility.loadCompendium("fvtt-mournblade-cyd2.skills")
- data.items = skills.map(i => i.toObject())
- }
- if (data.type == 'creature') {
- const skills = await MournbladeCYD2Utility.loadCompendium("fvtt-mournblade-cyd2.skills-creatures")
- data.items = skills.map(i => i.toObject())
- data.items.push({ name: "Arme naturelle 1", type: 'arme', img: "systems/fvtt-mournblade-cyd2/assets/icons/melee.webp", system: { typearme: "contact", bonusmaniementoff: 0, seuildefense: 0, degats: "0" } })
- data.items.push({ name: "Arme naturelle 2", type: 'arme', img: "systems/fvtt-mournblade-cyd2/assets/icons/melee.webp", system: { typearme: "contact", bonusmaniementoff: 0, seuildefense: 0, degats: "0" } })
- }
-
- return super.create(data, options);
- }
-
- /* -------------------------------------------- */
- getBonusDefenseFromTalents() {
- let talents = this.items.filter(item => item.type == "talent" && item.system.isautomated)
- let bonus = 0
- for (let talent of talents) {
- for (let auto of talent.system.automations) {
- if (auto.eventtype == "bonus-permanent" && auto.bonusname == "bonus-defensif") {
- bonus += Number(auto.bonus || 0)
- }
- }
- }
- return bonus
- }
-
- /* -------------------------------------------- */
- prepareArme(arme) {
- arme = foundry.utils.duplicate(arme)
- let combat = this.getCombatValues()
- if (arme.system.typearme == "contact" || arme.system.typearme == "contactjet") {
- let bonusDefense = this.getBonusDefenseFromTalents()
- arme.system.competence = foundry.utils.duplicate(this.items.find(item => item.type == "competence" && item.name.toLowerCase() == "mêlée"))
- arme.system.attrKey = "pui"
- arme.system.totalDegats = arme.system.degats + "+" + combat.bonusDegatsTotal
- arme.system.totalOffensif = this.system.attributs.pui.value + arme.system.competence.system.niveau + arme.system.bonusmaniementoff + (this.system.combat.monte ? 3 : 0)
- arme.system.totalDefensif = combat.defenseTotal + arme.system.competence.system.niveau + arme.system.seuildefense + bonusDefense + (this.system.combat.monte ? 3 : 0)
- console.log("Arme", arme.system.totalDefensif, combat, arme.system.competence.system.niveau, arme.system.seuildefense, bonusDefense)
- arme.system.isdefense = true
- arme.system.isMelee = true
- arme.system.isDistance = false
- }
- if (arme.system.typearme == "jet" || arme.system.typearme == "tir") {
- arme.system.competence = foundry.utils.duplicate(this.items.find(item => item.type == "competence" && item.name.toLowerCase() == "armes à distance"))
- arme.system.attrKey = "adr"
- arme.system.totalOffensif = this.system.attributs.adr.value + arme.system.competence.system.niveau + arme.system.bonusmaniementoff
- arme.system.totalDegats = arme.system.degats
- arme.system.isMelee = false
- arme.system.isDistance = true
- if (arme.system.isdefense) {
- arme.system.totalDefensif = combat.defenseTotal + arme.system.competence.system.niveau + arme.system.seuildefense
- }
- }
- return arme
- }
-
- /* -------------------------------------------- */
- getItemSorted(types) {
- let items = this.items.filter(item => types.includes(item.type)) || []
- MournbladeCYD2Utility.sortArrayObjectsByName(items)
- return items
- }
- getWeapons() {
- let armes = []
- for (let arme of this.items) {
- if (arme.type == "arme") {
- armes.push(this.prepareArme(arme))
- }
- }
- MournbladeCYD2Utility.sortArrayObjectsByName(armes)
- return armes
- }
- getMonnaies() {
- return this.getItemSorted(["monnaie"])
- }
- getEquipments() {
- return this.getItemSorted(["equipement"])
- }
- getArmors() {
- return this.getItemSorted(["protection"])
- }
- getHistoriques() {
- return this.getItemSorted(["historique"])
- }
- getProfils() {
- return this.getItemSorted(["profil"])
- }
- getTalents() {
- return this.getItemSorted(["talent"])
- }
- getRessources() {
- return this.getItemSorted(["ressource"])
- }
- getContacts() {
- return this.getItemSorted(["contact"])
- }
- getDons() {
- return this.getItemSorted(["don"])
- }
- getPactes() {
- return this.getItemSorted(["pacte"])
- }
- getTendances() {
- return this.getItemSorted(["tendance"])
- }
- getRunes() {
- return this.getItemSorted(["rune"])
- }
- getTraitsChaotiques() {
- return this.getItemSorted(["traitchaotique"])
- }
- getTraitsEspeces() {
- return this.getItemSorted(["traitespece"])
- }
-
- /* -------------------------------------------- */
- getAspect() {
- return (this.system.balance.loi > this.system.balance.chaos) ? this.system.balance.loi : this.system.balance.chaos
- }
- getMarge() {
- return Math.abs(this.system.balance.loi - this.system.balance.chaos)
- }
- getAlignement() {
- return (this.system.balance.loi > this.system.balance.chaos) ? "loyal" : "chaotique"
- }
-
- /* -------------------------------------------- */
- getSkills() {
- let comp = []
- for (let item of this.items) {
- item = foundry.utils.duplicate(item)
- if (item.type == "competence") {
- item.system.attribut1total = item.system.niveau + (this.system.attributs[item.system.attribut1]?.value || 0)
- item.system.attribut2total = item.system.niveau + (this.system.attributs[item.system.attribut2]?.value || 0)
- item.system.attribut3total = item.system.niveau + (this.system.attributs[item.system.attribut3]?.value || 0)
- if (item.system.niveau == 0) {
- item.system.attribut1total -= 3
- item.system.attribut2total -= 3
- item.system.attribut3total -= 3
- }
- item.system.attribut1label = this.system.attributs[item.system.attribut1]?.label || ""
- item.system.attribut2label = this.system.attributs[item.system.attribut2]?.label || ""
- item.system.attribut3label = this.system.attributs[item.system.attribut3]?.label || ""
- comp.push(item)
- }
- }
- MournbladeCYD2Utility.sortArrayObjectsByName(comp)
- return comp
- }
-
- /* ----------------------- --------------------- */
- addMember(actorId) {
- let members = foundry.utils.duplicate(this.system.members)
- members.push({ id: actorId })
- this.update({ 'system.members': members })
- }
- async removeMember(actorId) {
- let members = this.system.members.filter(it => it.id != actorId)
- this.update({ 'system.members': members })
- }
-
- /* -------------------------------------------- */
- getDefenseBase() {
- return Math.max(this.system.attributs.tre.value, this.system.attributs.adr.value)
- }
-
- /* -------------------------------------------- */
- getVitesseBase() {
- return 5 + __vitesseBonus[this.system.attributs.adr.value]
- }
- /* -------------------------------------------- */
- getProtection() {
- let equipProtection = 0
- for (let armor of this.items) {
- if (armor.type == "protection" && armor.system.equipped) {
- equipProtection += Number(armor.system.protection)
- }
- }
- if (equipProtection < 4) {
- return 4 + equipProtection // Cas des boucliers + sans armure
- }
- return equipProtection // Uniquement la protection des armures + boucliers
- }
-
- /* -------------------------------------------- */
- getCombatValues() {
- let combat = {
- initBase: this.system.attributs.adr.value,
- initTotal: this.system.attributs.adr.value + this.system.combat.initbonus,
- bonusDegats: this.getBonusDegats(),
- bonusDegatsTotal: this.getBonusDegats() + this.system.combat.bonusdegats,
- vitesseBase: this.getVitesseBase(),
- vitesseTotal: this.getVitesseBase() + this.system.combat.vitessebonus,
- defenseBase: this.getDefenseBase(),
- protection: this.getProtection(),
- defenseTotal: this.getDefenseBase() + this.system.combat.defensebonus + this.getProtection() - this.getTotalAdversite() + (this.system.combat.defensetotale ? 3 : 0)
- }
- return combat
- }
-
- /* -------------------------------------------- */
- prepareBaseData() {
- }
-
- /* -------------------------------------------- */
- async prepareData() {
- super.prepareData();
- }
-
- /* -------------------------------------------- */
- prepareDerivedData() {
-
- if (this.type == 'personnage') {
- let talentBonus = this.getVigueurBonus()
- let vigueur = Math.floor((this.system.attributs.pui.value + this.system.attributs.tre.value) / 2) + talentBonus + this.system.sante.vigueurmodifier
- if (vigueur != this.system.sante.vigueur) {
- this.update({ 'system.sante.vigueur': vigueur })
- }
-
- let seuilPouvoirBonus = this.getSeuilPouvoirBonus()
- let seuilPouvoir = Math.floor((this.system.attributs.tre.value + this.system.attributs.cla.value) / 2) + seuilPouvoirBonus + this.system.ame.seuilpouvoirmodifier
- if (seuilPouvoir != this.system.ame.seuilpouvoir) {
- this.update({ 'system.ame.seuilpouvoir': seuilPouvoir })
- }
- }
- super.prepareDerivedData()
- }
-
- /* -------------------------------------------- */
- _preUpdate(changed, options, user) {
- if (changed?.system?.sante?.etat && changed?.system?.sante?.etat != this.system.sante.etat) {
- setTimeout(() => {
- this.processCombativite(changed.system.sante)
- }, 800)
- }
- if (changed?.system?.ame?.etat && changed?.system?.ame?.etat != this.system.ame.etat) {
- // L'état d'Âme ne peut pas être inférieur au minimum (max dans le système)
- let minAme = this.system.ame.max !== undefined ? this.system.ame.max : 0
- if (changed.system.ame.etat < minAme) {
- changed.system.ame.etat = minAme
- }
- // L'état d'Âme ne peut pas dépasser nbame (Brisé)
- if (changed.system.ame.etat > this.system.ame.nbame) {
- changed.system.ame.etat = this.system.ame.nbame
- }
- setTimeout(() => {
- this.processAme(changed.system.ame)
- }, 800)
- }
- // Si le max d'Âme change, ajuster l'état actuel si nécessaire
- if (changed?.system?.ame?.max !== undefined && changed.system.ame.max != this.system.ame.max) {
- if (this.system.ame.etat < changed.system.ame.max) {
- changed.system.ame.etat = changed.system.ame.max
- }
- }
- super._preUpdate(changed, options, user);
- }
-
- /* -------------------------------------------- */
- _onUpdate(data, options, user) {
- super._onUpdate(data, options, user);
- }
- /* -------------------------------------------- */
- getItemById(id) {
- let item = this.items.find(item => item.id == id);
- if (item) {
- item = foundry.utils.duplicate(item)
- }
- return item;
- }
-
- /* -------------------------------------------- */
- async equipItem(itemId) {
- let item = this.items.find(item => item.id == itemId)
- if (item && item.system) {
- let update = { _id: item.id, "system.equipped": !item.system.equipped }
- await this.updateEmbeddedDocuments('Item', [update]); // Updates one EmbeddedEntity
- }
- }
-
- /* -------------------------------------------- */
- editItemField(itemId, itemType, itemField, dataType, value) {
- let item = this.items.find(item => item.id == itemId)
- if (item) {
- console.log("Item ", item, itemField, dataType, value)
- if (dataType.toLowerCase() == "number") {
- value = Number(value)
- } else {
- value = String(value)
- }
- let update = { _id: item.id, [`system.${itemField}`]: value };
- this.updateEmbeddedDocuments("Item", [update])
- }
- }
-
- /* -------------------------------------------- */
- checkAttribut(attribut, minLevel) {
- let attr = this.system.attributs.find(at => at.labelnorm == attribut.toLowerCase())
- if (attr && attr.value >= minLevel) {
- return { isValid: true, attr: foundry.utils.duplicate(attr) }
- }
- return { isValid: false }
- }
- /* -------------------------------------------- */
- checkAttributOrCompetenceLevel(compName, minLevel) {
- let comp = this.items.find(i => i.type == "competence" && i.name.toLowerCase() == compName.toLowerCase() && i.system.niveau >= minLevel)
- if (comp) {
- return { isValid: true, item: foundry.utils.duplicate(comp) }
- } else {
- for (let attrKey in this.system.attributs) {
- if (this.system.attributs[attrKey].label.toLowerCase() == compName.toLowerCase() && this.system.attributs[attrKey].value >= minLevel) {
- return { isValid: true, item: foundry.utils.duplicate(this.system.attributs[attrKey]) }
- }
- }
- }
- return { isValid: false, warningMessage: `Prérequis insuffisant : la compétence/attribut ${compName} doit être de niveau ${minLevel} au minimum` }
- }
- /* -------------------------------------------- */
- addCompetenceBonus(compName, bonus, baCost) {
- let comp = this.items.find(i => i.type == "competence" && i.name.toLowerCase() == compName.toLowerCase())
- if (comp) {
- comp = foundry.utils.duplicate(comp)
- comp.system.bonus = bonus
- comp.system.baCost = baCost
- return { isValid: true, item: comp }
- }
- return { isValid: false, warningMessage: `Compétence ${compName} non trouvée` }
- }
- /* -------------------------------------------- */
- checkIfCompetence(compName) {
- let comp = this.items.find(i => i.type == "competence" && i.name.toLowerCase() == compName.toLowerCase())
- if (comp) {
- return { isValid: true, item: comp }
- }
- return { isValid: false }
- }
- /* -------------------------------------------- */
- getVigueur() {
- return this.system.sante.vigueur
- }
-
- /* -------------------------------------------- */
- getVigueurBonus() {
- let talents = this.items.filter(item => item.type == "talent" && item.system.isautomated)
- let bonus = 0
- for (let talent of talents) {
- for (let auto of talent.system.automations) {
- if (auto.eventtype == "bonus-permanent" && auto.bonusname == "vigueur") {
- bonus += Number(auto.bonus || 0)
- }
- }
- }
- return bonus
- }
-
- /* -------------------------------------------- */
- getSeuilPouvoir() {
- return this.system.ame.seuilpouvoir
- }
-
- /* -------------------------------------------- */
- getSeuilPouvoirBonus() {
- let talents = this.items.filter(item => item.type == "talent" && item.system.isautomated)
- let bonus = 0
- for (let talent of talents) {
- for (let auto of talent.system.automations) {
- if (auto.eventtype == "bonus-permanent" && auto.bonusname == "seuilpouvoir") {
- bonus += Number(auto.bonus || 0)
- }
- }
- }
- return bonus
- }
-
- /* -------------------------------------------- */
- getAmeMax() {
- // Utiliser une vérification stricte car 0 (Serein) est une valeur valide
- return this.system.ame.max !== undefined ? this.system.ame.max : this.system.ame.nbame
- }
-
- /* -------------------------------------------- */
- getBonneAventure() {
- return this.system.bonneaventure.actuelle
- }
- /* -------------------------------------------- */
- checkBonneAventure(cost) {
- return (this.system.bonneaventure.actuelle >= cost)
- }
- /* -------------------------------------------- */
- changeBonneAventure(value) {
- let newBA = this.system.bonneaventure.actuelle
- newBA += value
- this.update({ 'system.bonneaventure.actuelle': newBA })
- }
-
- /* -------------------------------------------- */
- getEclat() {
- return this.system.eclat.value
- }
-
- /* -------------------------------------------- */
- changeEclat(value) {
- let newE = this.system.eclat.value
- newE += value
- this.update({ 'system.eclat.value': newE })
- }
-
- /* -------------------------------------------- */
- compareName(a, b) {
- if (a.name < b.name) {
- return -1;
- }
- if (a.name > b.name) {
- return 1;
- }
- return 0;
- }
-
- /* -------------------------------------------- */
- getAttribute(attrKey) {
- return this.system.attributes[attrKey]
- }
-
- /* -------------------------------------------- */
- getBonusDegats() {
- return 0;
- }
-
- /* -------------------------------------------- */
- changeEtatCombativite(value) {
- if (value === "vaincu") {
- value = 200
- }
- let sante = foundry.utils.duplicate(this.system.sante)
- sante.etat += Number(value)
- sante.etat = Math.max(sante.etat, 0)
- sante.etat = Math.min(sante.etat, this.system.sante.nbcombativite)
- this.update({ 'system.sante': sante })
- if (sante.etat == this.system.sante.nbcombativite) {
- ChatMessage.create({ content: `${this.name} est vaincu !` })
- }
- // Duplicated ! this.processCombativite(sante)
- }
-
- /* -------------------------------------------- */
- changeEtatAme(value) {
- if (value === "brise") {
- value = 200
- }
- let ame = foundry.utils.duplicate(this.system.ame)
- ame.etat += Number(value)
- // L'état ne peut pas être inférieur au minimum (max dans le système)
- let minAme = this.system.ame.max !== undefined ? this.system.ame.max : 0
- ame.etat = Math.max(ame.etat, minAme)
- // L'état ne peut pas dépasser nbame (Brisé)
- ame.etat = Math.min(ame.etat, this.system.ame.nbame)
- this.update({ 'system.ame': ame })
- if (ame.etat >= this.system.ame.nbame) {
- ChatMessage.create({ content: `${this.name} est brisé !` })
- }
- }
-
- /* -------------------------------------------- */
- processCombativite(sante) {
- sante = sante || foundry.utils.duplicate(this.system.sante)
- // Gestion des états affaibli et très affaibli
- if (sante.etat == this.system.sante.nbcombativite - 2 || sante.etat == this.system.sante.nbcombativite - 1) {
- if (sante.etat == this.system.sante.nbcombativite - 2 && this.items.find(item => item.type == "talent" && item.name.toLowerCase() == "encaissement")) {
- ChatMessage.create({ content: `${this.name} ne subit pas les 2 adversités rouge grâce à Encaissement. Pensez à les ajouter à la fin de la scène !` })
- } else if (sante.etat == this.system.sante.nbcombativite - 1 && this.items.find(item => item.type == "talent" && item.name.toLowerCase().includes("vaillant"))) {
- ChatMessage.create({ content: `${this.name} ne subit pas les 2 adversités rouge grâce à Vaillant. Pensez à les ajouter à la fin de la scène !` })
- } else {
- ChatMessage.create({ content: `${this.name} subit 2 adversités rouge !` })
- this.incDecAdversite("rouge", 2)
- }
- }
- }
-
- /* -------------------------------------------- */
- processAme(ame) {
- ame = ame || foundry.utils.duplicate(this.system.ame)
- let traumatiseValue = this.system.ame.nbame - 2
- let tresTraumatiseValue = this.system.ame.nbame - 1
- let briseValue = this.system.ame.nbame
-
- // Gestion des états Traumatisé, Très Traumatisé et Brisé
- if (ame.etat == traumatiseValue) {
- ChatMessage.create({ content: `${this.name} est Traumatisé et subit 1 adversité bleue et 1 adversité noire !` })
- this.incDecAdversite("bleue", 1)
- this.incDecAdversite("noire", 1)
- } else if (ame.etat == tresTraumatiseValue) {
- ChatMessage.create({ content: `${this.name} est Très Traumatisé et subit 1 adversité bleue et 1 adversité noire !` })
- this.incDecAdversite("bleue", 1)
- this.incDecAdversite("noire", 1)
- } else if (ame.etat >= briseValue) {
- ChatMessage.create({ content: `${this.name} est Brisé et subit 1 adversité noire !` })
- this.incDecAdversite("noire", 1)
- }
- }
-
- /* -------------------------------------------- */
- async equipGear(equipmentId) {
- let item = this.items.find(item => item.id == equipmentId);
- if (item?.system?.data) {
- let update = { _id: item.id, "system.equipped": !item.system.equipped };
- await this.updateEmbeddedDocuments('Item', [update]); // Updates one EmbeddedEntity
- }
- }
-
- /* -------------------------------------------- */
- getSubActors() {
- let subActors = [];
- for (let id of this.system.subactors) {
- subActors.push(foundry.utils.duplicate(game.actors.get(id)));
- }
- return subActors;
- }
- /* -------------------------------------------- */
- async addSubActor(subActorId) {
- let subActors = foundry.utils.duplicate(this.system.subactors);
- subActors.push(subActorId);
- await this.update({ 'system.subactors': subActors });
- }
- /* -------------------------------------------- */
- async delSubActor(subActorId) {
- let newArray = [];
- for (let id of this.system.subactors) {
- if (id != subActorId) {
- newArray.push(id);
- }
- }
- await this.update({ 'system.subactors': newArray });
- }
-
- /* -------------------------------------------- */
- getTotalAdversite() {
- return this.system.adversite.bleue + this.system.adversite.rouge + this.system.adversite.noire
- }
-
- /* -------------------------------------------- */
- async incDecAdversite(adv, incDec = 0) {
- let adversite = foundry.utils.duplicate(this.system.adversite)
- adversite[adv] += Number(incDec)
- adversite[adv] = Math.max(adversite[adv], 0)
- adversite[adv] = Math.min(adversite[adv], 20)
- this.update({ 'system.adversite': adversite })
- }
- /* -------------------------------------------- */
- async incDecQuantity(objetId, incDec = 0) {
- let objetQ = this.items.get(objetId)
- if (objetQ) {
- let newQ = objetQ.system.quantite + incDec
- newQ = Math.max(newQ, 0)
- await this.updateEmbeddedDocuments('Item', [{ _id: objetQ.id, 'system.quantite': newQ }]); // pdates one EmbeddedEntity
- }
- }
-
- /* -------------------------------------------- */
- computeRichesse() {
- let valueSC = 0
- for (let monnaie of this.items) {
- if (monnaie.type == "monnaie") {
- valueSC += Number(monnaie.system.prixsc) * Number(monnaie.system.quantite)
- }
- }
- return MournbladeCYD2Utility.computeMonnaieDetails(valueSC)
- }
-
- /* -------------------------------------------- */
- computeValeurEquipement() {
- let valueSC = 0
- for (let equip of this.items) {
- if (equip.type == "equipement" || equip.type == "arme" || equip.type == "protection") {
- valueSC += Number(equip.system.prixsc) * Number(equip.system.quantite ?? 1)
- valueSC += (Number(equip.system.prixca) * Number(equip.system.quantite ?? 1)) * 20
- valueSC += (Number(equip.system.prixpo) * Number(equip.system.quantite ?? 1)) * 400
- }
- }
- return MournbladeCYD2Utility.computeMonnaieDetails(valueSC)
- }
-
- /* -------------------------------------------- */
- getCompetence(compId) {
- return this.items.get(compId)
- }
-
- /* -------------------------------------------- */
- async setPredilectionUsed(compId, predIdx) {
- let comp = this.items.get(compId)
- let pred = foundry.utils.duplicate(comp.system.predilections)
- pred[predIdx].used = true
- await this.updateEmbeddedDocuments('Item', [{ _id: compId, 'system.predilections': pred }])
- }
-
- /* -------------------------------------------- */
- getInitiativeScore() {
- let init = this.getFlag("world", "last-initiative")
- return init || -1
- }
-
- /* -------------------------------------------- */
- getBestAttackValue() {
- let attackList = this.items.filter(item => (item.type == "arme" || item.type == "talent") && item.system.equipped)
- let maxOff = 0
- let bestArme
- for (let arme of attackList) {
- if (arme.type == "arme") {
- arme = this.prepareArme(arme)
- }
- if (arme.system.totalOffensif > maxOff) {
- maxOff = arme.system.totalOffensif
- bestArme = foundry.utils.duplicate(arme)
- }
- }
- return bestArme
- }
-
- /* -------------------------------------------- */
- getBestDefenseValue() {
- let defenseList = this.items.filter(item => (item.type == "arme") && item.system.equipped)
- let maxDef = 0
- let bestArme
- for (let arme of defenseList) {
- if (arme.type == "arme") {
- arme = this.prepareArme(arme)
- }
- if (arme.system.totalDefensif > maxDef) {
- maxDef = arme.system.totalDefensif
- bestArme = foundry.utils.duplicate(arme)
- }
- }
- return bestArme
- }
-
- /* -------------------------------------------- */
- searchRelevantTalents(competence) {
- let talents = []
-
- for (let talent of this.items) {
- if (talent.type == "talent" && talent.system.isautomated && talent.system.automations.length > 0) {
- for (let auto of talent.system.automations) {
- if (auto.eventtype === "prepare-roll") {
- if (auto.competence.toLowerCase() == competence.name.toLowerCase()) {
- talent = foundry.utils.duplicate(talent)
- talent.system.bonus = auto.bonus
- talent.system.baCost = auto.baCost
- talents.push(talent)
- }
- }
- }
- }
- }
- return talents
- }
-
- /* -------------------------------------------- */
- buildListeAdversites() {
- return []
- }
-
- /* -------------------------------------------- */
- getCommonRollData(attrKey = undefined, compId = undefined, compName = undefined) {
- let rollData = MournbladeCYD2Utility.getBasicRollData()
- rollData.alias = this.name
- rollData.actorImg = this.img
- rollData.actorId = this.id
- rollData.tokenId = this.token?.id
- rollData.img = this.img
- rollData.attributs = MournbladeCYD2Utility.getAttributs()
- rollData.maitriseId = "none"
- rollData.nbEclat = this.system.eclat.value
- rollData.nbBA = this.system.bonneaventure.actuelle
- rollData.nbAdversites = this.getTotalAdversite()
- rollData.talents = []
- rollData.attrKey2 = "none"
- rollData.coupDevastateur = this.items.find(it => it.type == "talent" && it.name.toLowerCase() == "coup dévastateur" && !it.system.used)
- rollData.hasAmbidextre = this.items.find(it => it.type == "talent" && it.name.toLowerCase() == "ambidextre")
- rollData.hasFeinte = this.system.bonneaventure.actuelle > 0 && this.items.find(it => it.type == "talent" && it.name.toLowerCase() == "feinte")
- rollData.isMonte = this.system.combat.monte
- rollData.config = game.system.mournbladecyd2.config
-
- if (attrKey) {
- rollData.attrKey = attrKey
- if (attrKey != "tochoose") {
- rollData.actionImg = "systems/fvtt-mournblade-cyd2/assets/icons/" + this.system.attributs[attrKey].labelnorm + ".webp"
- rollData.attr = foundry.utils.duplicate(this.system.attributs[attrKey])
- }
- }
- if (compId) {
- rollData.competence = foundry.utils.duplicate(this.items.get(compId) || {})
- let maitrises = [{ key: "none", label: "Aucune" }]
- rollData.competence.system.predilections.forEach(function (item) {
- if (item.maitrise) {
- maitrises.push({ key: item.id, label: item.name });
- }
- })
- rollData.maitrises = maitrises // rollData.competence.system.predilections.filter(p => p.maitrise)
- rollData.actionImg = rollData.competence?.img
- rollData.talents = this.searchRelevantTalents(rollData.competence)
- }
- if (compName) {
- rollData.competence = foundry.utils.duplicate(this.items.find(item => item.name.toLowerCase() == compName.toLowerCase()) || {})
- rollData.actionImg = rollData.competence?.img
- }
- return rollData
- }
-
- /* -------------------------------------------- */
- async rollAttribut(attrKey, isInit = false) {
- let rollData = this.getCommonRollData(attrKey)
- rollData.multiplier = (isInit) ? 1 : 2
- rollData.isInit = isInit
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
-
- /* -------------------------------------------- */
- async rollCompetence(attrKey, compId) {
- let rollData = this.getCommonRollData(attrKey, compId)
- rollData.multiplier = 1 // Attr multiplier, always 1 in competence mode
- console.log("RollDatra", rollData)
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
-
- /* -------------------------------------------- */
- async rollArmeOffensif(armeId) {
- let arme = this.items.get(armeId)
- if (arme.type == "arme") {
- arme = this.prepareArme(arme)
- }
- let rollData = this.getCommonRollData(arme.system.attrKey, arme.system.competence._id)
- rollData.arme = arme
- MournbladeCYD2Utility.updateWithTarget(rollData)
- console.log("ARME!", rollData)
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
- /* -------------------------------------------- */
- async rollAssommer() {
- let rollData = this.getCommonRollData("pui", undefined, "Filouterie")
- rollData.assomer = true
- rollData.conditionsCommunes = true
- MournbladeCYD2Utility.updateWithTarget(rollData)
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
- /* -------------------------------------------- */
- async rollCoupBas() {
- let rollData = this.getCommonRollData("pui", undefined, "Mêlée")
- rollData.coupBas = true
- rollData.conditionsCommunes = true
- MournbladeCYD2Utility.updateWithTarget(rollData)
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
- /* -------------------------------------------- */
- async rollImmobiliser() {
- let rollData = this.getCommonRollData("pui", undefined, "Mêlée")
- rollData.immobiliser = true
- rollData.conditionsCommunes = true
- rollData.cibleconsciente = true
- MournbladeCYD2Utility.updateWithTarget(rollData)
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
- /* -------------------------------------------- */
- async rollRepousser() {
- let rollData = this.getCommonRollData("pui", undefined, "Mêlée")
- rollData.repousser = true
- rollData.conditionsCommunes = true
- rollData.cibleconsciente = true
- MournbladeCYD2Utility.updateWithTarget(rollData)
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
- /* -------------------------------------------- */
- async rollDesengager() {
- let rollData = this.getCommonRollData("adr", undefined, "Mouvements")
- rollData.desengager = true
- rollData.conditionsCommunes = true
- MournbladeCYD2Utility.updateWithTarget(rollData)
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
-
- /* -------------------------------------------- */
- async rollArmeDegats(armeId, targetVigueur = undefined, rollDataInput = undefined) {
- let arme = this.items.get(armeId)
- if (arme.type == "arme") {
- arme = this.prepareArme(arme)
- }
- console.log("DEGATS", arme, targetVigueur, rollDataInput)
- let roll
- let bonus = 0
- let bonus2 = 0
-
- if (rollDataInput?.applyCoupDevastateur) {
- bonus2 = Math.floor(this.system.attributs.pui.value / 2)
- let talent = this.items.find(item => item.type == "talent" && item.name.toLowerCase() == "coup dévastateur")
- this.updateEmbeddedDocuments('Item', [{ _id: talent.id, 'system.used': true }])
- }
-
- if (rollDataInput?.isHeroique) {
- if (rollDataInput?.attaqueCharge) {
- bonus = 5
- }
- if (rollDataInput?.chargeCavalerie) {
- bonus = 6
- }
- roll = await new Roll("2d10rr10+" + arme.system.totalDegats + "+" + bonus + "+" + bonus2).roll()
- } else {
- if (rollDataInput?.attaqueCharge) {
- bonus = 3
- }
- if (rollDataInput?.chargeCavalerie) {
- bonus = 4
- }
- roll = await new Roll("1d10+" + arme.system.totalDegats + "+" + bonus + "+" + bonus2).roll()
- }
- await MournbladeCYD2Utility.showDiceSoNice(roll, game.settings.get("core", "rollMode"));
- let nbEtatPerdus = 0
- if (targetVigueur) {
- nbEtatPerdus = Math.floor(roll.total / targetVigueur)
- }
- //console.log(roll)
- let rollData = {
- arme: arme,
- finalResult: roll.total,
- formula: roll.formula,
- alias: this.name,
- actorImg: this.img,
- actorId: this.id,
- defenderTokenId: rollDataInput?.defenderTokenId,
- actionImg: arme.img,
- targetVigueur: targetVigueur,
- nbEtatPerdus: nbEtatPerdus
- }
- MournbladeCYD2Utility.createChatWithRollMode(rollData.alias, {
- content: await renderTemplate(`systems/fvtt-mournblade-cyd2/templates/chat-degats-result.html`, rollData)
- })
-
- if (rollDataInput?.defenderTokenId && nbEtatPerdus) {
- MournbladeCYD2Utility.applyCombativite(rollDataInput, nbEtatPerdus)
- }
-
- }
-}
diff --git a/.history/modules/mournblade-cyd2-actor_20251026133228.js b/.history/modules/mournblade-cyd2-actor_20251026133228.js
deleted file mode 100644
index 6a5a8a8..0000000
--- a/.history/modules/mournblade-cyd2-actor_20251026133228.js
+++ /dev/null
@@ -1,887 +0,0 @@
-/* -------------------------------------------- */
-import { MournbladeCYD2Utility } from "./mournblade-cyd2-utility.js";
-import { MournbladeCYD2RollDialog } from "./mournblade-cyd2-roll-dialog.js";
-
-/* -------------------------------------------- */
-const __degatsBonus = [-2, -2, -1, -1, 0, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 8, 8, 9, 9, 10, 10]
-const __vitesseBonus = [-2, -2, -1, -1, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8]
-
-/* -------------------------------------------- */
-/**
- * Extend the base Actor entity by defining a custom roll data structure which is ideal for the Simple system.
- * @extends {Actor}
- */
-export class MournbladeCYD2Actor extends Actor {
-
- /* -------------------------------------------- */
- /**
- * Override the create() function to provide additional SoS functionality.
- *
- * This overrided create() function adds initial items
- * Namely: Basic skills, money,
- *
- * @param {Object} data Barebones actor data which this function adds onto.
- * @param {Object} options (Unused) Additional options which customize the creation workflow.
- *
- */
-
- static async create(data, options) {
-
- // Case of compendium global import
- if (data instanceof Array) {
- return super.create(data, options);
- }
- // If the created actor has items (only applicable to duplicated actors) bypass the new actor creation logic
- if (data.items) {
- let actor = super.create(data, options);
- return actor;
- }
-
- if (data.type == 'personnage') {
- console.log("Loading skills for personnage")
- const skills = await MournbladeCYD2Utility.loadCompendium("fvtt-mournblade-cyd2.skills")
- data.items = skills.map(i => i.toObject())
- }
- if (data.type == 'creature') {
- const skills = await MournbladeCYD2Utility.loadCompendium("fvtt-mournblade-cyd2.skills-creatures")
- data.items = skills.map(i => i.toObject())
- data.items.push({ name: "Arme naturelle 1", type: 'arme', img: "systems/fvtt-mournblade-cyd2/assets/icons/melee.webp", system: { typearme: "contact", bonusmaniementoff: 0, seuildefense: 0, degats: "0" } })
- data.items.push({ name: "Arme naturelle 2", type: 'arme', img: "systems/fvtt-mournblade-cyd2/assets/icons/melee.webp", system: { typearme: "contact", bonusmaniementoff: 0, seuildefense: 0, degats: "0" } })
- }
-
- return super.create(data, options);
- }
-
- /* -------------------------------------------- */
- getBonusDefenseFromTalents() {
- let talents = this.items.filter(item => item.type == "talent" && item.system.isautomated)
- let bonus = 0
- for (let talent of talents) {
- for (let auto of talent.system.automations) {
- if (auto.eventtype == "bonus-permanent" && auto.bonusname == "bonus-defensif") {
- bonus += Number(auto.bonus || 0)
- }
- }
- }
- return bonus
- }
-
- /* -------------------------------------------- */
- prepareArme(arme) {
- arme = foundry.utils.duplicate(arme)
- let combat = this.getCombatValues()
- if (arme.system.typearme == "contact" || arme.system.typearme == "contactjet") {
- let bonusDefense = this.getBonusDefenseFromTalents()
- arme.system.competence = foundry.utils.duplicate(this.items.find(item => item.type == "competence" && item.name.toLowerCase() == "mêlée"))
- arme.system.attrKey = "pui"
- arme.system.totalDegats = arme.system.degats + "+" + combat.bonusDegatsTotal
- arme.system.totalOffensif = this.system.attributs.pui.value + arme.system.competence.system.niveau + arme.system.bonusmaniementoff + (this.system.combat.monte ? 3 : 0)
- arme.system.totalDefensif = combat.defenseTotal + arme.system.competence.system.niveau + arme.system.seuildefense + bonusDefense + (this.system.combat.monte ? 3 : 0)
- console.log("Arme", arme.system.totalDefensif, combat, arme.system.competence.system.niveau, arme.system.seuildefense, bonusDefense)
- arme.system.isdefense = true
- arme.system.isMelee = true
- arme.system.isDistance = false
- }
- if (arme.system.typearme == "jet" || arme.system.typearme == "tir") {
- arme.system.competence = foundry.utils.duplicate(this.items.find(item => item.type == "competence" && item.name.toLowerCase() == "armes à distance"))
- arme.system.attrKey = "adr"
- arme.system.totalOffensif = this.system.attributs.adr.value + arme.system.competence.system.niveau + arme.system.bonusmaniementoff
- arme.system.totalDegats = arme.system.degats
- arme.system.isMelee = false
- arme.system.isDistance = true
- if (arme.system.isdefense) {
- arme.system.totalDefensif = combat.defenseTotal + arme.system.competence.system.niveau + arme.system.seuildefense
- }
- }
- return arme
- }
-
- /* -------------------------------------------- */
- getItemSorted(types) {
- let items = this.items.filter(item => types.includes(item.type)) || []
- MournbladeCYD2Utility.sortArrayObjectsByName(items)
- return items
- }
- getWeapons() {
- let armes = []
- for (let arme of this.items) {
- if (arme.type == "arme") {
- armes.push(this.prepareArme(arme))
- }
- }
- MournbladeCYD2Utility.sortArrayObjectsByName(armes)
- return armes
- }
- getMonnaies() {
- return this.getItemSorted(["monnaie"])
- }
- getEquipments() {
- return this.getItemSorted(["equipement"])
- }
- getArmors() {
- return this.getItemSorted(["protection"])
- }
- getHistoriques() {
- return this.getItemSorted(["historique"])
- }
- getProfils() {
- return this.getItemSorted(["profil"])
- }
- getTalents() {
- return this.getItemSorted(["talent"])
- }
- getRessources() {
- return this.getItemSorted(["ressource"])
- }
- getDons() {
- return this.getItemSorted(["don"])
- }
- getPactes() {
- return this.getItemSorted(["pacte"])
- }
- getTendances() {
- return this.getItemSorted(["tendance"])
- }
- getRunes() {
- return this.getItemSorted(["rune"])
- }
- getTraitsChaotiques() {
- return this.getItemSorted(["traitchaotique"])
- }
- getTraitsEspeces() {
- return this.getItemSorted(["traitespece"])
- }
-
- /* -------------------------------------------- */
- getAspect() {
- return (this.system.balance.loi > this.system.balance.chaos) ? this.system.balance.loi : this.system.balance.chaos
- }
- getMarge() {
- return Math.abs(this.system.balance.loi - this.system.balance.chaos)
- }
- getAlignement() {
- return (this.system.balance.loi > this.system.balance.chaos) ? "loyal" : "chaotique"
- }
-
- /* -------------------------------------------- */
- getSkills() {
- let comp = []
- for (let item of this.items) {
- item = foundry.utils.duplicate(item)
- if (item.type == "competence") {
- item.system.attribut1total = item.system.niveau + (this.system.attributs[item.system.attribut1]?.value || 0)
- item.system.attribut2total = item.system.niveau + (this.system.attributs[item.system.attribut2]?.value || 0)
- item.system.attribut3total = item.system.niveau + (this.system.attributs[item.system.attribut3]?.value || 0)
- if (item.system.niveau == 0) {
- item.system.attribut1total -= 3
- item.system.attribut2total -= 3
- item.system.attribut3total -= 3
- }
- item.system.attribut1label = this.system.attributs[item.system.attribut1]?.label || ""
- item.system.attribut2label = this.system.attributs[item.system.attribut2]?.label || ""
- item.system.attribut3label = this.system.attributs[item.system.attribut3]?.label || ""
- comp.push(item)
- }
- }
- MournbladeCYD2Utility.sortArrayObjectsByName(comp)
- return comp
- }
-
- /* ----------------------- --------------------- */
- addMember(actorId) {
- let members = foundry.utils.duplicate(this.system.members)
- members.push({ id: actorId })
- this.update({ 'system.members': members })
- }
- async removeMember(actorId) {
- let members = this.system.members.filter(it => it.id != actorId)
- this.update({ 'system.members': members })
- }
-
- /* -------------------------------------------- */
- getDefenseBase() {
- return Math.max(this.system.attributs.tre.value, this.system.attributs.adr.value)
- }
-
- /* -------------------------------------------- */
- getVitesseBase() {
- return 5 + __vitesseBonus[this.system.attributs.adr.value]
- }
- /* -------------------------------------------- */
- getProtection() {
- let equipProtection = 0
- for (let armor of this.items) {
- if (armor.type == "protection" && armor.system.equipped) {
- equipProtection += Number(armor.system.protection)
- }
- }
- if (equipProtection < 4) {
- return 4 + equipProtection // Cas des boucliers + sans armure
- }
- return equipProtection // Uniquement la protection des armures + boucliers
- }
-
- /* -------------------------------------------- */
- getCombatValues() {
- let combat = {
- initBase: this.system.attributs.adr.value,
- initTotal: this.system.attributs.adr.value + this.system.combat.initbonus,
- bonusDegats: this.getBonusDegats(),
- bonusDegatsTotal: this.getBonusDegats() + this.system.combat.bonusdegats,
- vitesseBase: this.getVitesseBase(),
- vitesseTotal: this.getVitesseBase() + this.system.combat.vitessebonus,
- defenseBase: this.getDefenseBase(),
- protection: this.getProtection(),
- defenseTotal: this.getDefenseBase() + this.system.combat.defensebonus + this.getProtection() - this.getTotalAdversite() + (this.system.combat.defensetotale ? 3 : 0)
- }
- return combat
- }
-
- /* -------------------------------------------- */
- prepareBaseData() {
- }
-
- /* -------------------------------------------- */
- async prepareData() {
- super.prepareData();
- }
-
- /* -------------------------------------------- */
- prepareDerivedData() {
-
- if (this.type == 'personnage') {
- let talentBonus = this.getVigueurBonus()
- let vigueur = Math.floor((this.system.attributs.pui.value + this.system.attributs.tre.value) / 2) + talentBonus + this.system.sante.vigueurmodifier
- if (vigueur != this.system.sante.vigueur) {
- this.update({ 'system.sante.vigueur': vigueur })
- }
-
- let seuilPouvoirBonus = this.getSeuilPouvoirBonus()
- let seuilPouvoir = Math.floor((this.system.attributs.tre.value + this.system.attributs.cla.value) / 2) + seuilPouvoirBonus + this.system.ame.seuilpouvoirmodifier
- if (seuilPouvoir != this.system.ame.seuilpouvoir) {
- this.update({ 'system.ame.seuilpouvoir': seuilPouvoir })
- }
- }
- super.prepareDerivedData()
- }
-
- /* -------------------------------------------- */
- _preUpdate(changed, options, user) {
- if (changed?.system?.sante?.etat && changed?.system?.sante?.etat != this.system.sante.etat) {
- setTimeout(() => {
- this.processCombativite(changed.system.sante)
- }, 800)
- }
- if (changed?.system?.ame?.etat && changed?.system?.ame?.etat != this.system.ame.etat) {
- // L'état d'Âme ne peut pas être inférieur au minimum (max dans le système)
- let minAme = this.system.ame.max !== undefined ? this.system.ame.max : 0
- if (changed.system.ame.etat < minAme) {
- changed.system.ame.etat = minAme
- }
- // L'état d'Âme ne peut pas dépasser nbame (Brisé)
- if (changed.system.ame.etat > this.system.ame.nbame) {
- changed.system.ame.etat = this.system.ame.nbame
- }
- setTimeout(() => {
- this.processAme(changed.system.ame)
- }, 800)
- }
- // Si le max d'Âme change, ajuster l'état actuel si nécessaire
- if (changed?.system?.ame?.max !== undefined && changed.system.ame.max != this.system.ame.max) {
- if (this.system.ame.etat < changed.system.ame.max) {
- changed.system.ame.etat = changed.system.ame.max
- }
- }
- super._preUpdate(changed, options, user);
- }
-
- /* -------------------------------------------- */
- _onUpdate(data, options, user) {
- super._onUpdate(data, options, user);
- }
- /* -------------------------------------------- */
- getItemById(id) {
- let item = this.items.find(item => item.id == id);
- if (item) {
- item = foundry.utils.duplicate(item)
- }
- return item;
- }
-
- /* -------------------------------------------- */
- async equipItem(itemId) {
- let item = this.items.find(item => item.id == itemId)
- if (item && item.system) {
- let update = { _id: item.id, "system.equipped": !item.system.equipped }
- await this.updateEmbeddedDocuments('Item', [update]); // Updates one EmbeddedEntity
- }
- }
-
- /* -------------------------------------------- */
- editItemField(itemId, itemType, itemField, dataType, value) {
- let item = this.items.find(item => item.id == itemId)
- if (item) {
- console.log("Item ", item, itemField, dataType, value)
- if (dataType.toLowerCase() == "number") {
- value = Number(value)
- } else {
- value = String(value)
- }
- let update = { _id: item.id, [`system.${itemField}`]: value };
- this.updateEmbeddedDocuments("Item", [update])
- }
- }
-
- /* -------------------------------------------- */
- checkAttribut(attribut, minLevel) {
- let attr = this.system.attributs.find(at => at.labelnorm == attribut.toLowerCase())
- if (attr && attr.value >= minLevel) {
- return { isValid: true, attr: foundry.utils.duplicate(attr) }
- }
- return { isValid: false }
- }
- /* -------------------------------------------- */
- checkAttributOrCompetenceLevel(compName, minLevel) {
- let comp = this.items.find(i => i.type == "competence" && i.name.toLowerCase() == compName.toLowerCase() && i.system.niveau >= minLevel)
- if (comp) {
- return { isValid: true, item: foundry.utils.duplicate(comp) }
- } else {
- for (let attrKey in this.system.attributs) {
- if (this.system.attributs[attrKey].label.toLowerCase() == compName.toLowerCase() && this.system.attributs[attrKey].value >= minLevel) {
- return { isValid: true, item: foundry.utils.duplicate(this.system.attributs[attrKey]) }
- }
- }
- }
- return { isValid: false, warningMessage: `Prérequis insuffisant : la compétence/attribut ${compName} doit être de niveau ${minLevel} au minimum` }
- }
- /* -------------------------------------------- */
- addCompetenceBonus(compName, bonus, baCost) {
- let comp = this.items.find(i => i.type == "competence" && i.name.toLowerCase() == compName.toLowerCase())
- if (comp) {
- comp = foundry.utils.duplicate(comp)
- comp.system.bonus = bonus
- comp.system.baCost = baCost
- return { isValid: true, item: comp }
- }
- return { isValid: false, warningMessage: `Compétence ${compName} non trouvée` }
- }
- /* -------------------------------------------- */
- checkIfCompetence(compName) {
- let comp = this.items.find(i => i.type == "competence" && i.name.toLowerCase() == compName.toLowerCase())
- if (comp) {
- return { isValid: true, item: comp }
- }
- return { isValid: false }
- }
- /* -------------------------------------------- */
- getVigueur() {
- return this.system.sante.vigueur
- }
-
- /* -------------------------------------------- */
- getVigueurBonus() {
- let talents = this.items.filter(item => item.type == "talent" && item.system.isautomated)
- let bonus = 0
- for (let talent of talents) {
- for (let auto of talent.system.automations) {
- if (auto.eventtype == "bonus-permanent" && auto.bonusname == "vigueur") {
- bonus += Number(auto.bonus || 0)
- }
- }
- }
- return bonus
- }
-
- /* -------------------------------------------- */
- getSeuilPouvoir() {
- return this.system.ame.seuilpouvoir
- }
-
- /* -------------------------------------------- */
- getSeuilPouvoirBonus() {
- let talents = this.items.filter(item => item.type == "talent" && item.system.isautomated)
- let bonus = 0
- for (let talent of talents) {
- for (let auto of talent.system.automations) {
- if (auto.eventtype == "bonus-permanent" && auto.bonusname == "seuilpouvoir") {
- bonus += Number(auto.bonus || 0)
- }
- }
- }
- return bonus
- }
-
- /* -------------------------------------------- */
- getAmeMax() {
- // Utiliser une vérification stricte car 0 (Serein) est une valeur valide
- return this.system.ame.max !== undefined ? this.system.ame.max : this.system.ame.nbame
- }
-
- /* -------------------------------------------- */
- getBonneAventure() {
- return this.system.bonneaventure.actuelle
- }
- /* -------------------------------------------- */
- checkBonneAventure(cost) {
- return (this.system.bonneaventure.actuelle >= cost)
- }
- /* -------------------------------------------- */
- changeBonneAventure(value) {
- let newBA = this.system.bonneaventure.actuelle
- newBA += value
- this.update({ 'system.bonneaventure.actuelle': newBA })
- }
-
- /* -------------------------------------------- */
- getEclat() {
- return this.system.eclat.value
- }
-
- /* -------------------------------------------- */
- changeEclat(value) {
- let newE = this.system.eclat.value
- newE += value
- this.update({ 'system.eclat.value': newE })
- }
-
- /* -------------------------------------------- */
- compareName(a, b) {
- if (a.name < b.name) {
- return -1;
- }
- if (a.name > b.name) {
- return 1;
- }
- return 0;
- }
-
- /* -------------------------------------------- */
- getAttribute(attrKey) {
- return this.system.attributes[attrKey]
- }
-
- /* -------------------------------------------- */
- getBonusDegats() {
- return 0;
- }
-
- /* -------------------------------------------- */
- changeEtatCombativite(value) {
- if (value === "vaincu") {
- value = 200
- }
- let sante = foundry.utils.duplicate(this.system.sante)
- sante.etat += Number(value)
- sante.etat = Math.max(sante.etat, 0)
- sante.etat = Math.min(sante.etat, this.system.sante.nbcombativite)
- this.update({ 'system.sante': sante })
- if (sante.etat == this.system.sante.nbcombativite) {
- ChatMessage.create({ content: `${this.name} est vaincu !` })
- }
- // Duplicated ! this.processCombativite(sante)
- }
-
- /* -------------------------------------------- */
- changeEtatAme(value) {
- if (value === "brise") {
- value = 200
- }
- let ame = foundry.utils.duplicate(this.system.ame)
- ame.etat += Number(value)
- // L'état ne peut pas être inférieur au minimum (max dans le système)
- let minAme = this.system.ame.max !== undefined ? this.system.ame.max : 0
- ame.etat = Math.max(ame.etat, minAme)
- // L'état ne peut pas dépasser nbame (Brisé)
- ame.etat = Math.min(ame.etat, this.system.ame.nbame)
- this.update({ 'system.ame': ame })
- if (ame.etat >= this.system.ame.nbame) {
- ChatMessage.create({ content: `${this.name} est brisé !` })
- }
- }
-
- /* -------------------------------------------- */
- processCombativite(sante) {
- sante = sante || foundry.utils.duplicate(this.system.sante)
- // Gestion des états affaibli et très affaibli
- if (sante.etat == this.system.sante.nbcombativite - 2 || sante.etat == this.system.sante.nbcombativite - 1) {
- if (sante.etat == this.system.sante.nbcombativite - 2 && this.items.find(item => item.type == "talent" && item.name.toLowerCase() == "encaissement")) {
- ChatMessage.create({ content: `${this.name} ne subit pas les 2 adversités rouge grâce à Encaissement. Pensez à les ajouter à la fin de la scène !` })
- } else if (sante.etat == this.system.sante.nbcombativite - 1 && this.items.find(item => item.type == "talent" && item.name.toLowerCase().includes("vaillant"))) {
- ChatMessage.create({ content: `${this.name} ne subit pas les 2 adversités rouge grâce à Vaillant. Pensez à les ajouter à la fin de la scène !` })
- } else {
- ChatMessage.create({ content: `${this.name} subit 2 adversités rouge !` })
- this.incDecAdversite("rouge", 2)
- }
- }
- }
-
- /* -------------------------------------------- */
- processAme(ame) {
- ame = ame || foundry.utils.duplicate(this.system.ame)
- let traumatiseValue = this.system.ame.nbame - 2
- let tresTraumatiseValue = this.system.ame.nbame - 1
- let briseValue = this.system.ame.nbame
-
- // Gestion des états Traumatisé, Très Traumatisé et Brisé
- if (ame.etat == traumatiseValue) {
- ChatMessage.create({ content: `${this.name} est Traumatisé et subit 1 adversité bleue et 1 adversité noire !` })
- this.incDecAdversite("bleue", 1)
- this.incDecAdversite("noire", 1)
- } else if (ame.etat == tresTraumatiseValue) {
- ChatMessage.create({ content: `${this.name} est Très Traumatisé et subit 1 adversité bleue et 1 adversité noire !` })
- this.incDecAdversite("bleue", 1)
- this.incDecAdversite("noire", 1)
- } else if (ame.etat >= briseValue) {
- ChatMessage.create({ content: `${this.name} est Brisé et subit 1 adversité noire !` })
- this.incDecAdversite("noire", 1)
- }
- }
-
- /* -------------------------------------------- */
- async equipGear(equipmentId) {
- let item = this.items.find(item => item.id == equipmentId);
- if (item?.system?.data) {
- let update = { _id: item.id, "system.equipped": !item.system.equipped };
- await this.updateEmbeddedDocuments('Item', [update]); // Updates one EmbeddedEntity
- }
- }
-
- /* -------------------------------------------- */
- getSubActors() {
- let subActors = [];
- for (let id of this.system.subactors) {
- subActors.push(foundry.utils.duplicate(game.actors.get(id)));
- }
- return subActors;
- }
- /* -------------------------------------------- */
- async addSubActor(subActorId) {
- let subActors = foundry.utils.duplicate(this.system.subactors);
- subActors.push(subActorId);
- await this.update({ 'system.subactors': subActors });
- }
- /* -------------------------------------------- */
- async delSubActor(subActorId) {
- let newArray = [];
- for (let id of this.system.subactors) {
- if (id != subActorId) {
- newArray.push(id);
- }
- }
- await this.update({ 'system.subactors': newArray });
- }
-
- /* -------------------------------------------- */
- getTotalAdversite() {
- return this.system.adversite.bleue + this.system.adversite.rouge + this.system.adversite.noire
- }
-
- /* -------------------------------------------- */
- async incDecAdversite(adv, incDec = 0) {
- let adversite = foundry.utils.duplicate(this.system.adversite)
- adversite[adv] += Number(incDec)
- adversite[adv] = Math.max(adversite[adv], 0)
- adversite[adv] = Math.min(adversite[adv], 20)
- this.update({ 'system.adversite': adversite })
- }
- /* -------------------------------------------- */
- async incDecQuantity(objetId, incDec = 0) {
- let objetQ = this.items.get(objetId)
- if (objetQ) {
- let newQ = objetQ.system.quantite + incDec
- newQ = Math.max(newQ, 0)
- await this.updateEmbeddedDocuments('Item', [{ _id: objetQ.id, 'system.quantite': newQ }]); // pdates one EmbeddedEntity
- }
- }
-
- /* -------------------------------------------- */
- computeRichesse() {
- let valueSC = 0
- for (let monnaie of this.items) {
- if (monnaie.type == "monnaie") {
- valueSC += Number(monnaie.system.prixsc) * Number(monnaie.system.quantite)
- }
- }
- return MournbladeCYD2Utility.computeMonnaieDetails(valueSC)
- }
-
- /* -------------------------------------------- */
- computeValeurEquipement() {
- let valueSC = 0
- for (let equip of this.items) {
- if (equip.type == "equipement" || equip.type == "arme" || equip.type == "protection") {
- valueSC += Number(equip.system.prixsc) * Number(equip.system.quantite ?? 1)
- valueSC += (Number(equip.system.prixca) * Number(equip.system.quantite ?? 1)) * 20
- valueSC += (Number(equip.system.prixpo) * Number(equip.system.quantite ?? 1)) * 400
- }
- }
- return MournbladeCYD2Utility.computeMonnaieDetails(valueSC)
- }
-
- /* -------------------------------------------- */
- getCompetence(compId) {
- return this.items.get(compId)
- }
-
- /* -------------------------------------------- */
- async setPredilectionUsed(compId, predIdx) {
- let comp = this.items.get(compId)
- let pred = foundry.utils.duplicate(comp.system.predilections)
- pred[predIdx].used = true
- await this.updateEmbeddedDocuments('Item', [{ _id: compId, 'system.predilections': pred }])
- }
-
- /* -------------------------------------------- */
- getInitiativeScore() {
- let init = this.getFlag("world", "last-initiative")
- return init || -1
- }
-
- /* -------------------------------------------- */
- getBestAttackValue() {
- let attackList = this.items.filter(item => (item.type == "arme" || item.type == "talent") && item.system.equipped)
- let maxOff = 0
- let bestArme
- for (let arme of attackList) {
- if (arme.type == "arme") {
- arme = this.prepareArme(arme)
- }
- if (arme.system.totalOffensif > maxOff) {
- maxOff = arme.system.totalOffensif
- bestArme = foundry.utils.duplicate(arme)
- }
- }
- return bestArme
- }
-
- /* -------------------------------------------- */
- getBestDefenseValue() {
- let defenseList = this.items.filter(item => (item.type == "arme") && item.system.equipped)
- let maxDef = 0
- let bestArme
- for (let arme of defenseList) {
- if (arme.type == "arme") {
- arme = this.prepareArme(arme)
- }
- if (arme.system.totalDefensif > maxDef) {
- maxDef = arme.system.totalDefensif
- bestArme = foundry.utils.duplicate(arme)
- }
- }
- return bestArme
- }
-
- /* -------------------------------------------- */
- searchRelevantTalents(competence) {
- let talents = []
-
- for (let talent of this.items) {
- if (talent.type == "talent" && talent.system.isautomated && talent.system.automations.length > 0) {
- for (let auto of talent.system.automations) {
- if (auto.eventtype === "prepare-roll") {
- if (auto.competence.toLowerCase() == competence.name.toLowerCase()) {
- talent = foundry.utils.duplicate(talent)
- talent.system.bonus = auto.bonus
- talent.system.baCost = auto.baCost
- talents.push(talent)
- }
- }
- }
- }
- }
- return talents
- }
-
- /* -------------------------------------------- */
- buildListeAdversites() {
- return []
- }
-
- /* -------------------------------------------- */
- getCommonRollData(attrKey = undefined, compId = undefined, compName = undefined) {
- let rollData = MournbladeCYD2Utility.getBasicRollData()
- rollData.alias = this.name
- rollData.actorImg = this.img
- rollData.actorId = this.id
- rollData.tokenId = this.token?.id
- rollData.img = this.img
- rollData.attributs = MournbladeCYD2Utility.getAttributs()
- rollData.maitriseId = "none"
- rollData.nbEclat = this.system.eclat.value
- rollData.nbBA = this.system.bonneaventure.actuelle
- rollData.nbAdversites = this.getTotalAdversite()
- rollData.talents = []
- rollData.attrKey2 = "none"
- rollData.coupDevastateur = this.items.find(it => it.type == "talent" && it.name.toLowerCase() == "coup dévastateur" && !it.system.used)
- rollData.hasAmbidextre = this.items.find(it => it.type == "talent" && it.name.toLowerCase() == "ambidextre")
- rollData.hasFeinte = this.system.bonneaventure.actuelle > 0 && this.items.find(it => it.type == "talent" && it.name.toLowerCase() == "feinte")
- rollData.isMonte = this.system.combat.monte
- rollData.config = game.system.mournbladecyd2.config
-
- if (attrKey) {
- rollData.attrKey = attrKey
- if (attrKey != "tochoose") {
- rollData.actionImg = "systems/fvtt-mournblade-cyd2/assets/icons/" + this.system.attributs[attrKey].labelnorm + ".webp"
- rollData.attr = foundry.utils.duplicate(this.system.attributs[attrKey])
- }
- }
- if (compId) {
- rollData.competence = foundry.utils.duplicate(this.items.get(compId) || {})
- let maitrises = [{ key: "none", label: "Aucune" }]
- rollData.competence.system.predilections.forEach(function (item) {
- if (item.maitrise) {
- maitrises.push({ key: item.id, label: item.name });
- }
- })
- rollData.maitrises = maitrises // rollData.competence.system.predilections.filter(p => p.maitrise)
- rollData.actionImg = rollData.competence?.img
- rollData.talents = this.searchRelevantTalents(rollData.competence)
- }
- if (compName) {
- rollData.competence = foundry.utils.duplicate(this.items.find(item => item.name.toLowerCase() == compName.toLowerCase()) || {})
- rollData.actionImg = rollData.competence?.img
- }
- return rollData
- }
-
- /* -------------------------------------------- */
- async rollAttribut(attrKey, isInit = false) {
- let rollData = this.getCommonRollData(attrKey)
- rollData.multiplier = (isInit) ? 1 : 2
- rollData.isInit = isInit
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
-
- /* -------------------------------------------- */
- async rollCompetence(attrKey, compId) {
- let rollData = this.getCommonRollData(attrKey, compId)
- rollData.multiplier = 1 // Attr multiplier, always 1 in competence mode
- console.log("RollDatra", rollData)
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
-
- /* -------------------------------------------- */
- async rollArmeOffensif(armeId) {
- let arme = this.items.get(armeId)
- if (arme.type == "arme") {
- arme = this.prepareArme(arme)
- }
- let rollData = this.getCommonRollData(arme.system.attrKey, arme.system.competence._id)
- rollData.arme = arme
- MournbladeCYD2Utility.updateWithTarget(rollData)
- console.log("ARME!", rollData)
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
- /* -------------------------------------------- */
- async rollAssommer() {
- let rollData = this.getCommonRollData("pui", undefined, "Filouterie")
- rollData.assomer = true
- rollData.conditionsCommunes = true
- MournbladeCYD2Utility.updateWithTarget(rollData)
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
- /* -------------------------------------------- */
- async rollCoupBas() {
- let rollData = this.getCommonRollData("pui", undefined, "Mêlée")
- rollData.coupBas = true
- rollData.conditionsCommunes = true
- MournbladeCYD2Utility.updateWithTarget(rollData)
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
- /* -------------------------------------------- */
- async rollImmobiliser() {
- let rollData = this.getCommonRollData("pui", undefined, "Mêlée")
- rollData.immobiliser = true
- rollData.conditionsCommunes = true
- rollData.cibleconsciente = true
- MournbladeCYD2Utility.updateWithTarget(rollData)
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
- /* -------------------------------------------- */
- async rollRepousser() {
- let rollData = this.getCommonRollData("pui", undefined, "Mêlée")
- rollData.repousser = true
- rollData.conditionsCommunes = true
- rollData.cibleconsciente = true
- MournbladeCYD2Utility.updateWithTarget(rollData)
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
- /* -------------------------------------------- */
- async rollDesengager() {
- let rollData = this.getCommonRollData("adr", undefined, "Mouvements")
- rollData.desengager = true
- rollData.conditionsCommunes = true
- MournbladeCYD2Utility.updateWithTarget(rollData)
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
-
- /* -------------------------------------------- */
- async rollArmeDegats(armeId, targetVigueur = undefined, rollDataInput = undefined) {
- let arme = this.items.get(armeId)
- if (arme.type == "arme") {
- arme = this.prepareArme(arme)
- }
- console.log("DEGATS", arme, targetVigueur, rollDataInput)
- let roll
- let bonus = 0
- let bonus2 = 0
-
- if (rollDataInput?.applyCoupDevastateur) {
- bonus2 = Math.floor(this.system.attributs.pui.value / 2)
- let talent = this.items.find(item => item.type == "talent" && item.name.toLowerCase() == "coup dévastateur")
- this.updateEmbeddedDocuments('Item', [{ _id: talent.id, 'system.used': true }])
- }
-
- if (rollDataInput?.isHeroique) {
- if (rollDataInput?.attaqueCharge) {
- bonus = 5
- }
- if (rollDataInput?.chargeCavalerie) {
- bonus = 6
- }
- roll = await new Roll("2d10rr10+" + arme.system.totalDegats + "+" + bonus + "+" + bonus2).roll()
- } else {
- if (rollDataInput?.attaqueCharge) {
- bonus = 3
- }
- if (rollDataInput?.chargeCavalerie) {
- bonus = 4
- }
- roll = await new Roll("1d10+" + arme.system.totalDegats + "+" + bonus + "+" + bonus2).roll()
- }
- await MournbladeCYD2Utility.showDiceSoNice(roll, game.settings.get("core", "rollMode"));
- let nbEtatPerdus = 0
- if (targetVigueur) {
- nbEtatPerdus = Math.floor(roll.total / targetVigueur)
- }
- //console.log(roll)
- let rollData = {
- arme: arme,
- finalResult: roll.total,
- formula: roll.formula,
- alias: this.name,
- actorImg: this.img,
- actorId: this.id,
- defenderTokenId: rollDataInput?.defenderTokenId,
- actionImg: arme.img,
- targetVigueur: targetVigueur,
- nbEtatPerdus: nbEtatPerdus
- }
- MournbladeCYD2Utility.createChatWithRollMode(rollData.alias, {
- content: await renderTemplate(`systems/fvtt-mournblade-cyd2/templates/chat-degats-result.html`, rollData)
- })
-
- if (rollDataInput?.defenderTokenId && nbEtatPerdus) {
- MournbladeCYD2Utility.applyCombativite(rollDataInput, nbEtatPerdus)
- }
-
- }
-}
diff --git a/.history/modules/mournblade-cyd2-actor_20251026133244.js b/.history/modules/mournblade-cyd2-actor_20251026133244.js
deleted file mode 100644
index 6a5a8a8..0000000
--- a/.history/modules/mournblade-cyd2-actor_20251026133244.js
+++ /dev/null
@@ -1,887 +0,0 @@
-/* -------------------------------------------- */
-import { MournbladeCYD2Utility } from "./mournblade-cyd2-utility.js";
-import { MournbladeCYD2RollDialog } from "./mournblade-cyd2-roll-dialog.js";
-
-/* -------------------------------------------- */
-const __degatsBonus = [-2, -2, -1, -1, 0, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 8, 8, 9, 9, 10, 10]
-const __vitesseBonus = [-2, -2, -1, -1, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8]
-
-/* -------------------------------------------- */
-/**
- * Extend the base Actor entity by defining a custom roll data structure which is ideal for the Simple system.
- * @extends {Actor}
- */
-export class MournbladeCYD2Actor extends Actor {
-
- /* -------------------------------------------- */
- /**
- * Override the create() function to provide additional SoS functionality.
- *
- * This overrided create() function adds initial items
- * Namely: Basic skills, money,
- *
- * @param {Object} data Barebones actor data which this function adds onto.
- * @param {Object} options (Unused) Additional options which customize the creation workflow.
- *
- */
-
- static async create(data, options) {
-
- // Case of compendium global import
- if (data instanceof Array) {
- return super.create(data, options);
- }
- // If the created actor has items (only applicable to duplicated actors) bypass the new actor creation logic
- if (data.items) {
- let actor = super.create(data, options);
- return actor;
- }
-
- if (data.type == 'personnage') {
- console.log("Loading skills for personnage")
- const skills = await MournbladeCYD2Utility.loadCompendium("fvtt-mournblade-cyd2.skills")
- data.items = skills.map(i => i.toObject())
- }
- if (data.type == 'creature') {
- const skills = await MournbladeCYD2Utility.loadCompendium("fvtt-mournblade-cyd2.skills-creatures")
- data.items = skills.map(i => i.toObject())
- data.items.push({ name: "Arme naturelle 1", type: 'arme', img: "systems/fvtt-mournblade-cyd2/assets/icons/melee.webp", system: { typearme: "contact", bonusmaniementoff: 0, seuildefense: 0, degats: "0" } })
- data.items.push({ name: "Arme naturelle 2", type: 'arme', img: "systems/fvtt-mournblade-cyd2/assets/icons/melee.webp", system: { typearme: "contact", bonusmaniementoff: 0, seuildefense: 0, degats: "0" } })
- }
-
- return super.create(data, options);
- }
-
- /* -------------------------------------------- */
- getBonusDefenseFromTalents() {
- let talents = this.items.filter(item => item.type == "talent" && item.system.isautomated)
- let bonus = 0
- for (let talent of talents) {
- for (let auto of talent.system.automations) {
- if (auto.eventtype == "bonus-permanent" && auto.bonusname == "bonus-defensif") {
- bonus += Number(auto.bonus || 0)
- }
- }
- }
- return bonus
- }
-
- /* -------------------------------------------- */
- prepareArme(arme) {
- arme = foundry.utils.duplicate(arme)
- let combat = this.getCombatValues()
- if (arme.system.typearme == "contact" || arme.system.typearme == "contactjet") {
- let bonusDefense = this.getBonusDefenseFromTalents()
- arme.system.competence = foundry.utils.duplicate(this.items.find(item => item.type == "competence" && item.name.toLowerCase() == "mêlée"))
- arme.system.attrKey = "pui"
- arme.system.totalDegats = arme.system.degats + "+" + combat.bonusDegatsTotal
- arme.system.totalOffensif = this.system.attributs.pui.value + arme.system.competence.system.niveau + arme.system.bonusmaniementoff + (this.system.combat.monte ? 3 : 0)
- arme.system.totalDefensif = combat.defenseTotal + arme.system.competence.system.niveau + arme.system.seuildefense + bonusDefense + (this.system.combat.monte ? 3 : 0)
- console.log("Arme", arme.system.totalDefensif, combat, arme.system.competence.system.niveau, arme.system.seuildefense, bonusDefense)
- arme.system.isdefense = true
- arme.system.isMelee = true
- arme.system.isDistance = false
- }
- if (arme.system.typearme == "jet" || arme.system.typearme == "tir") {
- arme.system.competence = foundry.utils.duplicate(this.items.find(item => item.type == "competence" && item.name.toLowerCase() == "armes à distance"))
- arme.system.attrKey = "adr"
- arme.system.totalOffensif = this.system.attributs.adr.value + arme.system.competence.system.niveau + arme.system.bonusmaniementoff
- arme.system.totalDegats = arme.system.degats
- arme.system.isMelee = false
- arme.system.isDistance = true
- if (arme.system.isdefense) {
- arme.system.totalDefensif = combat.defenseTotal + arme.system.competence.system.niveau + arme.system.seuildefense
- }
- }
- return arme
- }
-
- /* -------------------------------------------- */
- getItemSorted(types) {
- let items = this.items.filter(item => types.includes(item.type)) || []
- MournbladeCYD2Utility.sortArrayObjectsByName(items)
- return items
- }
- getWeapons() {
- let armes = []
- for (let arme of this.items) {
- if (arme.type == "arme") {
- armes.push(this.prepareArme(arme))
- }
- }
- MournbladeCYD2Utility.sortArrayObjectsByName(armes)
- return armes
- }
- getMonnaies() {
- return this.getItemSorted(["monnaie"])
- }
- getEquipments() {
- return this.getItemSorted(["equipement"])
- }
- getArmors() {
- return this.getItemSorted(["protection"])
- }
- getHistoriques() {
- return this.getItemSorted(["historique"])
- }
- getProfils() {
- return this.getItemSorted(["profil"])
- }
- getTalents() {
- return this.getItemSorted(["talent"])
- }
- getRessources() {
- return this.getItemSorted(["ressource"])
- }
- getDons() {
- return this.getItemSorted(["don"])
- }
- getPactes() {
- return this.getItemSorted(["pacte"])
- }
- getTendances() {
- return this.getItemSorted(["tendance"])
- }
- getRunes() {
- return this.getItemSorted(["rune"])
- }
- getTraitsChaotiques() {
- return this.getItemSorted(["traitchaotique"])
- }
- getTraitsEspeces() {
- return this.getItemSorted(["traitespece"])
- }
-
- /* -------------------------------------------- */
- getAspect() {
- return (this.system.balance.loi > this.system.balance.chaos) ? this.system.balance.loi : this.system.balance.chaos
- }
- getMarge() {
- return Math.abs(this.system.balance.loi - this.system.balance.chaos)
- }
- getAlignement() {
- return (this.system.balance.loi > this.system.balance.chaos) ? "loyal" : "chaotique"
- }
-
- /* -------------------------------------------- */
- getSkills() {
- let comp = []
- for (let item of this.items) {
- item = foundry.utils.duplicate(item)
- if (item.type == "competence") {
- item.system.attribut1total = item.system.niveau + (this.system.attributs[item.system.attribut1]?.value || 0)
- item.system.attribut2total = item.system.niveau + (this.system.attributs[item.system.attribut2]?.value || 0)
- item.system.attribut3total = item.system.niveau + (this.system.attributs[item.system.attribut3]?.value || 0)
- if (item.system.niveau == 0) {
- item.system.attribut1total -= 3
- item.system.attribut2total -= 3
- item.system.attribut3total -= 3
- }
- item.system.attribut1label = this.system.attributs[item.system.attribut1]?.label || ""
- item.system.attribut2label = this.system.attributs[item.system.attribut2]?.label || ""
- item.system.attribut3label = this.system.attributs[item.system.attribut3]?.label || ""
- comp.push(item)
- }
- }
- MournbladeCYD2Utility.sortArrayObjectsByName(comp)
- return comp
- }
-
- /* ----------------------- --------------------- */
- addMember(actorId) {
- let members = foundry.utils.duplicate(this.system.members)
- members.push({ id: actorId })
- this.update({ 'system.members': members })
- }
- async removeMember(actorId) {
- let members = this.system.members.filter(it => it.id != actorId)
- this.update({ 'system.members': members })
- }
-
- /* -------------------------------------------- */
- getDefenseBase() {
- return Math.max(this.system.attributs.tre.value, this.system.attributs.adr.value)
- }
-
- /* -------------------------------------------- */
- getVitesseBase() {
- return 5 + __vitesseBonus[this.system.attributs.adr.value]
- }
- /* -------------------------------------------- */
- getProtection() {
- let equipProtection = 0
- for (let armor of this.items) {
- if (armor.type == "protection" && armor.system.equipped) {
- equipProtection += Number(armor.system.protection)
- }
- }
- if (equipProtection < 4) {
- return 4 + equipProtection // Cas des boucliers + sans armure
- }
- return equipProtection // Uniquement la protection des armures + boucliers
- }
-
- /* -------------------------------------------- */
- getCombatValues() {
- let combat = {
- initBase: this.system.attributs.adr.value,
- initTotal: this.system.attributs.adr.value + this.system.combat.initbonus,
- bonusDegats: this.getBonusDegats(),
- bonusDegatsTotal: this.getBonusDegats() + this.system.combat.bonusdegats,
- vitesseBase: this.getVitesseBase(),
- vitesseTotal: this.getVitesseBase() + this.system.combat.vitessebonus,
- defenseBase: this.getDefenseBase(),
- protection: this.getProtection(),
- defenseTotal: this.getDefenseBase() + this.system.combat.defensebonus + this.getProtection() - this.getTotalAdversite() + (this.system.combat.defensetotale ? 3 : 0)
- }
- return combat
- }
-
- /* -------------------------------------------- */
- prepareBaseData() {
- }
-
- /* -------------------------------------------- */
- async prepareData() {
- super.prepareData();
- }
-
- /* -------------------------------------------- */
- prepareDerivedData() {
-
- if (this.type == 'personnage') {
- let talentBonus = this.getVigueurBonus()
- let vigueur = Math.floor((this.system.attributs.pui.value + this.system.attributs.tre.value) / 2) + talentBonus + this.system.sante.vigueurmodifier
- if (vigueur != this.system.sante.vigueur) {
- this.update({ 'system.sante.vigueur': vigueur })
- }
-
- let seuilPouvoirBonus = this.getSeuilPouvoirBonus()
- let seuilPouvoir = Math.floor((this.system.attributs.tre.value + this.system.attributs.cla.value) / 2) + seuilPouvoirBonus + this.system.ame.seuilpouvoirmodifier
- if (seuilPouvoir != this.system.ame.seuilpouvoir) {
- this.update({ 'system.ame.seuilpouvoir': seuilPouvoir })
- }
- }
- super.prepareDerivedData()
- }
-
- /* -------------------------------------------- */
- _preUpdate(changed, options, user) {
- if (changed?.system?.sante?.etat && changed?.system?.sante?.etat != this.system.sante.etat) {
- setTimeout(() => {
- this.processCombativite(changed.system.sante)
- }, 800)
- }
- if (changed?.system?.ame?.etat && changed?.system?.ame?.etat != this.system.ame.etat) {
- // L'état d'Âme ne peut pas être inférieur au minimum (max dans le système)
- let minAme = this.system.ame.max !== undefined ? this.system.ame.max : 0
- if (changed.system.ame.etat < minAme) {
- changed.system.ame.etat = minAme
- }
- // L'état d'Âme ne peut pas dépasser nbame (Brisé)
- if (changed.system.ame.etat > this.system.ame.nbame) {
- changed.system.ame.etat = this.system.ame.nbame
- }
- setTimeout(() => {
- this.processAme(changed.system.ame)
- }, 800)
- }
- // Si le max d'Âme change, ajuster l'état actuel si nécessaire
- if (changed?.system?.ame?.max !== undefined && changed.system.ame.max != this.system.ame.max) {
- if (this.system.ame.etat < changed.system.ame.max) {
- changed.system.ame.etat = changed.system.ame.max
- }
- }
- super._preUpdate(changed, options, user);
- }
-
- /* -------------------------------------------- */
- _onUpdate(data, options, user) {
- super._onUpdate(data, options, user);
- }
- /* -------------------------------------------- */
- getItemById(id) {
- let item = this.items.find(item => item.id == id);
- if (item) {
- item = foundry.utils.duplicate(item)
- }
- return item;
- }
-
- /* -------------------------------------------- */
- async equipItem(itemId) {
- let item = this.items.find(item => item.id == itemId)
- if (item && item.system) {
- let update = { _id: item.id, "system.equipped": !item.system.equipped }
- await this.updateEmbeddedDocuments('Item', [update]); // Updates one EmbeddedEntity
- }
- }
-
- /* -------------------------------------------- */
- editItemField(itemId, itemType, itemField, dataType, value) {
- let item = this.items.find(item => item.id == itemId)
- if (item) {
- console.log("Item ", item, itemField, dataType, value)
- if (dataType.toLowerCase() == "number") {
- value = Number(value)
- } else {
- value = String(value)
- }
- let update = { _id: item.id, [`system.${itemField}`]: value };
- this.updateEmbeddedDocuments("Item", [update])
- }
- }
-
- /* -------------------------------------------- */
- checkAttribut(attribut, minLevel) {
- let attr = this.system.attributs.find(at => at.labelnorm == attribut.toLowerCase())
- if (attr && attr.value >= minLevel) {
- return { isValid: true, attr: foundry.utils.duplicate(attr) }
- }
- return { isValid: false }
- }
- /* -------------------------------------------- */
- checkAttributOrCompetenceLevel(compName, minLevel) {
- let comp = this.items.find(i => i.type == "competence" && i.name.toLowerCase() == compName.toLowerCase() && i.system.niveau >= minLevel)
- if (comp) {
- return { isValid: true, item: foundry.utils.duplicate(comp) }
- } else {
- for (let attrKey in this.system.attributs) {
- if (this.system.attributs[attrKey].label.toLowerCase() == compName.toLowerCase() && this.system.attributs[attrKey].value >= minLevel) {
- return { isValid: true, item: foundry.utils.duplicate(this.system.attributs[attrKey]) }
- }
- }
- }
- return { isValid: false, warningMessage: `Prérequis insuffisant : la compétence/attribut ${compName} doit être de niveau ${minLevel} au minimum` }
- }
- /* -------------------------------------------- */
- addCompetenceBonus(compName, bonus, baCost) {
- let comp = this.items.find(i => i.type == "competence" && i.name.toLowerCase() == compName.toLowerCase())
- if (comp) {
- comp = foundry.utils.duplicate(comp)
- comp.system.bonus = bonus
- comp.system.baCost = baCost
- return { isValid: true, item: comp }
- }
- return { isValid: false, warningMessage: `Compétence ${compName} non trouvée` }
- }
- /* -------------------------------------------- */
- checkIfCompetence(compName) {
- let comp = this.items.find(i => i.type == "competence" && i.name.toLowerCase() == compName.toLowerCase())
- if (comp) {
- return { isValid: true, item: comp }
- }
- return { isValid: false }
- }
- /* -------------------------------------------- */
- getVigueur() {
- return this.system.sante.vigueur
- }
-
- /* -------------------------------------------- */
- getVigueurBonus() {
- let talents = this.items.filter(item => item.type == "talent" && item.system.isautomated)
- let bonus = 0
- for (let talent of talents) {
- for (let auto of talent.system.automations) {
- if (auto.eventtype == "bonus-permanent" && auto.bonusname == "vigueur") {
- bonus += Number(auto.bonus || 0)
- }
- }
- }
- return bonus
- }
-
- /* -------------------------------------------- */
- getSeuilPouvoir() {
- return this.system.ame.seuilpouvoir
- }
-
- /* -------------------------------------------- */
- getSeuilPouvoirBonus() {
- let talents = this.items.filter(item => item.type == "talent" && item.system.isautomated)
- let bonus = 0
- for (let talent of talents) {
- for (let auto of talent.system.automations) {
- if (auto.eventtype == "bonus-permanent" && auto.bonusname == "seuilpouvoir") {
- bonus += Number(auto.bonus || 0)
- }
- }
- }
- return bonus
- }
-
- /* -------------------------------------------- */
- getAmeMax() {
- // Utiliser une vérification stricte car 0 (Serein) est une valeur valide
- return this.system.ame.max !== undefined ? this.system.ame.max : this.system.ame.nbame
- }
-
- /* -------------------------------------------- */
- getBonneAventure() {
- return this.system.bonneaventure.actuelle
- }
- /* -------------------------------------------- */
- checkBonneAventure(cost) {
- return (this.system.bonneaventure.actuelle >= cost)
- }
- /* -------------------------------------------- */
- changeBonneAventure(value) {
- let newBA = this.system.bonneaventure.actuelle
- newBA += value
- this.update({ 'system.bonneaventure.actuelle': newBA })
- }
-
- /* -------------------------------------------- */
- getEclat() {
- return this.system.eclat.value
- }
-
- /* -------------------------------------------- */
- changeEclat(value) {
- let newE = this.system.eclat.value
- newE += value
- this.update({ 'system.eclat.value': newE })
- }
-
- /* -------------------------------------------- */
- compareName(a, b) {
- if (a.name < b.name) {
- return -1;
- }
- if (a.name > b.name) {
- return 1;
- }
- return 0;
- }
-
- /* -------------------------------------------- */
- getAttribute(attrKey) {
- return this.system.attributes[attrKey]
- }
-
- /* -------------------------------------------- */
- getBonusDegats() {
- return 0;
- }
-
- /* -------------------------------------------- */
- changeEtatCombativite(value) {
- if (value === "vaincu") {
- value = 200
- }
- let sante = foundry.utils.duplicate(this.system.sante)
- sante.etat += Number(value)
- sante.etat = Math.max(sante.etat, 0)
- sante.etat = Math.min(sante.etat, this.system.sante.nbcombativite)
- this.update({ 'system.sante': sante })
- if (sante.etat == this.system.sante.nbcombativite) {
- ChatMessage.create({ content: `${this.name} est vaincu !` })
- }
- // Duplicated ! this.processCombativite(sante)
- }
-
- /* -------------------------------------------- */
- changeEtatAme(value) {
- if (value === "brise") {
- value = 200
- }
- let ame = foundry.utils.duplicate(this.system.ame)
- ame.etat += Number(value)
- // L'état ne peut pas être inférieur au minimum (max dans le système)
- let minAme = this.system.ame.max !== undefined ? this.system.ame.max : 0
- ame.etat = Math.max(ame.etat, minAme)
- // L'état ne peut pas dépasser nbame (Brisé)
- ame.etat = Math.min(ame.etat, this.system.ame.nbame)
- this.update({ 'system.ame': ame })
- if (ame.etat >= this.system.ame.nbame) {
- ChatMessage.create({ content: `${this.name} est brisé !` })
- }
- }
-
- /* -------------------------------------------- */
- processCombativite(sante) {
- sante = sante || foundry.utils.duplicate(this.system.sante)
- // Gestion des états affaibli et très affaibli
- if (sante.etat == this.system.sante.nbcombativite - 2 || sante.etat == this.system.sante.nbcombativite - 1) {
- if (sante.etat == this.system.sante.nbcombativite - 2 && this.items.find(item => item.type == "talent" && item.name.toLowerCase() == "encaissement")) {
- ChatMessage.create({ content: `${this.name} ne subit pas les 2 adversités rouge grâce à Encaissement. Pensez à les ajouter à la fin de la scène !` })
- } else if (sante.etat == this.system.sante.nbcombativite - 1 && this.items.find(item => item.type == "talent" && item.name.toLowerCase().includes("vaillant"))) {
- ChatMessage.create({ content: `${this.name} ne subit pas les 2 adversités rouge grâce à Vaillant. Pensez à les ajouter à la fin de la scène !` })
- } else {
- ChatMessage.create({ content: `${this.name} subit 2 adversités rouge !` })
- this.incDecAdversite("rouge", 2)
- }
- }
- }
-
- /* -------------------------------------------- */
- processAme(ame) {
- ame = ame || foundry.utils.duplicate(this.system.ame)
- let traumatiseValue = this.system.ame.nbame - 2
- let tresTraumatiseValue = this.system.ame.nbame - 1
- let briseValue = this.system.ame.nbame
-
- // Gestion des états Traumatisé, Très Traumatisé et Brisé
- if (ame.etat == traumatiseValue) {
- ChatMessage.create({ content: `${this.name} est Traumatisé et subit 1 adversité bleue et 1 adversité noire !` })
- this.incDecAdversite("bleue", 1)
- this.incDecAdversite("noire", 1)
- } else if (ame.etat == tresTraumatiseValue) {
- ChatMessage.create({ content: `${this.name} est Très Traumatisé et subit 1 adversité bleue et 1 adversité noire !` })
- this.incDecAdversite("bleue", 1)
- this.incDecAdversite("noire", 1)
- } else if (ame.etat >= briseValue) {
- ChatMessage.create({ content: `${this.name} est Brisé et subit 1 adversité noire !` })
- this.incDecAdversite("noire", 1)
- }
- }
-
- /* -------------------------------------------- */
- async equipGear(equipmentId) {
- let item = this.items.find(item => item.id == equipmentId);
- if (item?.system?.data) {
- let update = { _id: item.id, "system.equipped": !item.system.equipped };
- await this.updateEmbeddedDocuments('Item', [update]); // Updates one EmbeddedEntity
- }
- }
-
- /* -------------------------------------------- */
- getSubActors() {
- let subActors = [];
- for (let id of this.system.subactors) {
- subActors.push(foundry.utils.duplicate(game.actors.get(id)));
- }
- return subActors;
- }
- /* -------------------------------------------- */
- async addSubActor(subActorId) {
- let subActors = foundry.utils.duplicate(this.system.subactors);
- subActors.push(subActorId);
- await this.update({ 'system.subactors': subActors });
- }
- /* -------------------------------------------- */
- async delSubActor(subActorId) {
- let newArray = [];
- for (let id of this.system.subactors) {
- if (id != subActorId) {
- newArray.push(id);
- }
- }
- await this.update({ 'system.subactors': newArray });
- }
-
- /* -------------------------------------------- */
- getTotalAdversite() {
- return this.system.adversite.bleue + this.system.adversite.rouge + this.system.adversite.noire
- }
-
- /* -------------------------------------------- */
- async incDecAdversite(adv, incDec = 0) {
- let adversite = foundry.utils.duplicate(this.system.adversite)
- adversite[adv] += Number(incDec)
- adversite[adv] = Math.max(adversite[adv], 0)
- adversite[adv] = Math.min(adversite[adv], 20)
- this.update({ 'system.adversite': adversite })
- }
- /* -------------------------------------------- */
- async incDecQuantity(objetId, incDec = 0) {
- let objetQ = this.items.get(objetId)
- if (objetQ) {
- let newQ = objetQ.system.quantite + incDec
- newQ = Math.max(newQ, 0)
- await this.updateEmbeddedDocuments('Item', [{ _id: objetQ.id, 'system.quantite': newQ }]); // pdates one EmbeddedEntity
- }
- }
-
- /* -------------------------------------------- */
- computeRichesse() {
- let valueSC = 0
- for (let monnaie of this.items) {
- if (monnaie.type == "monnaie") {
- valueSC += Number(monnaie.system.prixsc) * Number(monnaie.system.quantite)
- }
- }
- return MournbladeCYD2Utility.computeMonnaieDetails(valueSC)
- }
-
- /* -------------------------------------------- */
- computeValeurEquipement() {
- let valueSC = 0
- for (let equip of this.items) {
- if (equip.type == "equipement" || equip.type == "arme" || equip.type == "protection") {
- valueSC += Number(equip.system.prixsc) * Number(equip.system.quantite ?? 1)
- valueSC += (Number(equip.system.prixca) * Number(equip.system.quantite ?? 1)) * 20
- valueSC += (Number(equip.system.prixpo) * Number(equip.system.quantite ?? 1)) * 400
- }
- }
- return MournbladeCYD2Utility.computeMonnaieDetails(valueSC)
- }
-
- /* -------------------------------------------- */
- getCompetence(compId) {
- return this.items.get(compId)
- }
-
- /* -------------------------------------------- */
- async setPredilectionUsed(compId, predIdx) {
- let comp = this.items.get(compId)
- let pred = foundry.utils.duplicate(comp.system.predilections)
- pred[predIdx].used = true
- await this.updateEmbeddedDocuments('Item', [{ _id: compId, 'system.predilections': pred }])
- }
-
- /* -------------------------------------------- */
- getInitiativeScore() {
- let init = this.getFlag("world", "last-initiative")
- return init || -1
- }
-
- /* -------------------------------------------- */
- getBestAttackValue() {
- let attackList = this.items.filter(item => (item.type == "arme" || item.type == "talent") && item.system.equipped)
- let maxOff = 0
- let bestArme
- for (let arme of attackList) {
- if (arme.type == "arme") {
- arme = this.prepareArme(arme)
- }
- if (arme.system.totalOffensif > maxOff) {
- maxOff = arme.system.totalOffensif
- bestArme = foundry.utils.duplicate(arme)
- }
- }
- return bestArme
- }
-
- /* -------------------------------------------- */
- getBestDefenseValue() {
- let defenseList = this.items.filter(item => (item.type == "arme") && item.system.equipped)
- let maxDef = 0
- let bestArme
- for (let arme of defenseList) {
- if (arme.type == "arme") {
- arme = this.prepareArme(arme)
- }
- if (arme.system.totalDefensif > maxDef) {
- maxDef = arme.system.totalDefensif
- bestArme = foundry.utils.duplicate(arme)
- }
- }
- return bestArme
- }
-
- /* -------------------------------------------- */
- searchRelevantTalents(competence) {
- let talents = []
-
- for (let talent of this.items) {
- if (talent.type == "talent" && talent.system.isautomated && talent.system.automations.length > 0) {
- for (let auto of talent.system.automations) {
- if (auto.eventtype === "prepare-roll") {
- if (auto.competence.toLowerCase() == competence.name.toLowerCase()) {
- talent = foundry.utils.duplicate(talent)
- talent.system.bonus = auto.bonus
- talent.system.baCost = auto.baCost
- talents.push(talent)
- }
- }
- }
- }
- }
- return talents
- }
-
- /* -------------------------------------------- */
- buildListeAdversites() {
- return []
- }
-
- /* -------------------------------------------- */
- getCommonRollData(attrKey = undefined, compId = undefined, compName = undefined) {
- let rollData = MournbladeCYD2Utility.getBasicRollData()
- rollData.alias = this.name
- rollData.actorImg = this.img
- rollData.actorId = this.id
- rollData.tokenId = this.token?.id
- rollData.img = this.img
- rollData.attributs = MournbladeCYD2Utility.getAttributs()
- rollData.maitriseId = "none"
- rollData.nbEclat = this.system.eclat.value
- rollData.nbBA = this.system.bonneaventure.actuelle
- rollData.nbAdversites = this.getTotalAdversite()
- rollData.talents = []
- rollData.attrKey2 = "none"
- rollData.coupDevastateur = this.items.find(it => it.type == "talent" && it.name.toLowerCase() == "coup dévastateur" && !it.system.used)
- rollData.hasAmbidextre = this.items.find(it => it.type == "talent" && it.name.toLowerCase() == "ambidextre")
- rollData.hasFeinte = this.system.bonneaventure.actuelle > 0 && this.items.find(it => it.type == "talent" && it.name.toLowerCase() == "feinte")
- rollData.isMonte = this.system.combat.monte
- rollData.config = game.system.mournbladecyd2.config
-
- if (attrKey) {
- rollData.attrKey = attrKey
- if (attrKey != "tochoose") {
- rollData.actionImg = "systems/fvtt-mournblade-cyd2/assets/icons/" + this.system.attributs[attrKey].labelnorm + ".webp"
- rollData.attr = foundry.utils.duplicate(this.system.attributs[attrKey])
- }
- }
- if (compId) {
- rollData.competence = foundry.utils.duplicate(this.items.get(compId) || {})
- let maitrises = [{ key: "none", label: "Aucune" }]
- rollData.competence.system.predilections.forEach(function (item) {
- if (item.maitrise) {
- maitrises.push({ key: item.id, label: item.name });
- }
- })
- rollData.maitrises = maitrises // rollData.competence.system.predilections.filter(p => p.maitrise)
- rollData.actionImg = rollData.competence?.img
- rollData.talents = this.searchRelevantTalents(rollData.competence)
- }
- if (compName) {
- rollData.competence = foundry.utils.duplicate(this.items.find(item => item.name.toLowerCase() == compName.toLowerCase()) || {})
- rollData.actionImg = rollData.competence?.img
- }
- return rollData
- }
-
- /* -------------------------------------------- */
- async rollAttribut(attrKey, isInit = false) {
- let rollData = this.getCommonRollData(attrKey)
- rollData.multiplier = (isInit) ? 1 : 2
- rollData.isInit = isInit
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
-
- /* -------------------------------------------- */
- async rollCompetence(attrKey, compId) {
- let rollData = this.getCommonRollData(attrKey, compId)
- rollData.multiplier = 1 // Attr multiplier, always 1 in competence mode
- console.log("RollDatra", rollData)
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
-
- /* -------------------------------------------- */
- async rollArmeOffensif(armeId) {
- let arme = this.items.get(armeId)
- if (arme.type == "arme") {
- arme = this.prepareArme(arme)
- }
- let rollData = this.getCommonRollData(arme.system.attrKey, arme.system.competence._id)
- rollData.arme = arme
- MournbladeCYD2Utility.updateWithTarget(rollData)
- console.log("ARME!", rollData)
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
- /* -------------------------------------------- */
- async rollAssommer() {
- let rollData = this.getCommonRollData("pui", undefined, "Filouterie")
- rollData.assomer = true
- rollData.conditionsCommunes = true
- MournbladeCYD2Utility.updateWithTarget(rollData)
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
- /* -------------------------------------------- */
- async rollCoupBas() {
- let rollData = this.getCommonRollData("pui", undefined, "Mêlée")
- rollData.coupBas = true
- rollData.conditionsCommunes = true
- MournbladeCYD2Utility.updateWithTarget(rollData)
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
- /* -------------------------------------------- */
- async rollImmobiliser() {
- let rollData = this.getCommonRollData("pui", undefined, "Mêlée")
- rollData.immobiliser = true
- rollData.conditionsCommunes = true
- rollData.cibleconsciente = true
- MournbladeCYD2Utility.updateWithTarget(rollData)
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
- /* -------------------------------------------- */
- async rollRepousser() {
- let rollData = this.getCommonRollData("pui", undefined, "Mêlée")
- rollData.repousser = true
- rollData.conditionsCommunes = true
- rollData.cibleconsciente = true
- MournbladeCYD2Utility.updateWithTarget(rollData)
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
- /* -------------------------------------------- */
- async rollDesengager() {
- let rollData = this.getCommonRollData("adr", undefined, "Mouvements")
- rollData.desengager = true
- rollData.conditionsCommunes = true
- MournbladeCYD2Utility.updateWithTarget(rollData)
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
- }
-
- /* -------------------------------------------- */
- async rollArmeDegats(armeId, targetVigueur = undefined, rollDataInput = undefined) {
- let arme = this.items.get(armeId)
- if (arme.type == "arme") {
- arme = this.prepareArme(arme)
- }
- console.log("DEGATS", arme, targetVigueur, rollDataInput)
- let roll
- let bonus = 0
- let bonus2 = 0
-
- if (rollDataInput?.applyCoupDevastateur) {
- bonus2 = Math.floor(this.system.attributs.pui.value / 2)
- let talent = this.items.find(item => item.type == "talent" && item.name.toLowerCase() == "coup dévastateur")
- this.updateEmbeddedDocuments('Item', [{ _id: talent.id, 'system.used': true }])
- }
-
- if (rollDataInput?.isHeroique) {
- if (rollDataInput?.attaqueCharge) {
- bonus = 5
- }
- if (rollDataInput?.chargeCavalerie) {
- bonus = 6
- }
- roll = await new Roll("2d10rr10+" + arme.system.totalDegats + "+" + bonus + "+" + bonus2).roll()
- } else {
- if (rollDataInput?.attaqueCharge) {
- bonus = 3
- }
- if (rollDataInput?.chargeCavalerie) {
- bonus = 4
- }
- roll = await new Roll("1d10+" + arme.system.totalDegats + "+" + bonus + "+" + bonus2).roll()
- }
- await MournbladeCYD2Utility.showDiceSoNice(roll, game.settings.get("core", "rollMode"));
- let nbEtatPerdus = 0
- if (targetVigueur) {
- nbEtatPerdus = Math.floor(roll.total / targetVigueur)
- }
- //console.log(roll)
- let rollData = {
- arme: arme,
- finalResult: roll.total,
- formula: roll.formula,
- alias: this.name,
- actorImg: this.img,
- actorId: this.id,
- defenderTokenId: rollDataInput?.defenderTokenId,
- actionImg: arme.img,
- targetVigueur: targetVigueur,
- nbEtatPerdus: nbEtatPerdus
- }
- MournbladeCYD2Utility.createChatWithRollMode(rollData.alias, {
- content: await renderTemplate(`systems/fvtt-mournblade-cyd2/templates/chat-degats-result.html`, rollData)
- })
-
- if (rollDataInput?.defenderTokenId && nbEtatPerdus) {
- MournbladeCYD2Utility.applyCombativite(rollDataInput, nbEtatPerdus)
- }
-
- }
-}
diff --git a/.history/modules/mournblade-cyd2-actor_20251026132127.js b/.history/modules/mournblade-cyd2-actor_20260402224326.js
similarity index 90%
rename from .history/modules/mournblade-cyd2-actor_20251026132127.js
rename to .history/modules/mournblade-cyd2-actor_20260402224326.js
index 0520df0..33b6479 100644
--- a/.history/modules/mournblade-cyd2-actor_20251026132127.js
+++ b/.history/modules/mournblade-cyd2-actor_20260402224326.js
@@ -1,6 +1,6 @@
/* -------------------------------------------- */
import { MournbladeCYD2Utility } from "./mournblade-cyd2-utility.js";
-import { MournbladeCYD2RollDialog } from "./mournblade-cyd2-roll-dialog.js";
+import { MournbladeCYD2RollDialog } from "./applications/mournblade-cyd2-roll-dialog.mjs";
/* -------------------------------------------- */
const __degatsBonus = [-2, -2, -1, -1, 0, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 8, 8, 9, 9, 10, 10]
@@ -39,14 +39,14 @@ export class MournbladeCYD2Actor extends Actor {
if (data.type == 'personnage') {
console.log("Loading skills for personnage")
- const skills = await MournbladeCYD2Utility.loadCompendium("fvtt-mournblade-cyd2.skills")
+ const skills = await MournbladeCYD2Utility.loadCompendium("fvtt-mournblade-cyd-2-0.skills")
data.items = skills.map(i => i.toObject())
}
if (data.type == 'creature') {
- const skills = await MournbladeCYD2Utility.loadCompendium("fvtt-mournblade-cyd2.skills-creatures")
+ const skills = await MournbladeCYD2Utility.loadCompendium("fvtt-mournblade-cyd-2-0.skills-creatures")
data.items = skills.map(i => i.toObject())
- data.items.push({ name: "Arme naturelle 1", type: 'arme', img: "systems/fvtt-mournblade-cyd2/assets/icons/melee.webp", system: { typearme: "contact", bonusmaniementoff: 0, seuildefense: 0, degats: "0" } })
- data.items.push({ name: "Arme naturelle 2", type: 'arme', img: "systems/fvtt-mournblade-cyd2/assets/icons/melee.webp", system: { typearme: "contact", bonusmaniementoff: 0, seuildefense: 0, degats: "0" } })
+ data.items.push({ name: "Arme naturelle 1", type: 'arme', img: "systems/fvtt-mournblade-cyd-2-0/assets/icons/melee.webp", system: { typearme: "contact", bonusmaniementoff: 0, seuildefense: 0, degats: "0" } })
+ data.items.push({ name: "Arme naturelle 2", type: 'arme', img: "systems/fvtt-mournblade-cyd-2-0/assets/icons/melee.webp", system: { typearme: "contact", bonusmaniementoff: 0, seuildefense: 0, degats: "0" } })
}
return super.create(data, options);
@@ -133,12 +133,6 @@ export class MournbladeCYD2Actor extends Actor {
getRessources() {
return this.getItemSorted(["ressource"])
}
- getContacts() {
- return this.getItemSorted(["contact"])
- }
- getMutations() {
- return this.getItemSorted(["mutation"])
- }
getDons() {
return this.getItemSorted(["don"])
}
@@ -151,6 +145,12 @@ export class MournbladeCYD2Actor extends Actor {
getRunes() {
return this.getItemSorted(["rune"])
}
+ getRuneEffects() {
+ return this.getItemSorted(["runeeffect"])
+ }
+ getProfil() {
+ return this.getProfils()[0] ?? null
+ }
getTraitsChaotiques() {
return this.getItemSorted(["traitchaotique"])
}
@@ -226,6 +226,9 @@ export class MournbladeCYD2Actor extends Actor {
}
return equipProtection // Uniquement la protection des armures + boucliers
}
+ getProtectionTotal() {
+ return this.getProtection()
+ }
/* -------------------------------------------- */
getCombatValues() {
@@ -243,9 +246,6 @@ export class MournbladeCYD2Actor extends Actor {
return combat
}
- /* -------------------------------------------- */
- prepareBaseData() {
- }
/* -------------------------------------------- */
async prepareData() {
@@ -273,12 +273,13 @@ export class MournbladeCYD2Actor extends Actor {
/* -------------------------------------------- */
_preUpdate(changed, options, user) {
- if (changed?.system?.sante?.etat && changed?.system?.sante?.etat != this.system.sante.etat) {
+ if (changed?.system?.sante?.etat !== undefined && changed.system.sante.etat != this.system.sante.etat) {
+ const oldEtat = this.system.sante.etat
setTimeout(() => {
- this.processCombativite(changed.system.sante)
+ this.processCombativite(changed.system.sante, oldEtat)
}, 800)
}
- if (changed?.system?.ame?.etat && changed?.system?.ame?.etat != this.system.ame.etat) {
+ if (changed?.system?.ame?.etat !== undefined && changed.system.ame.etat != this.system.ame.etat) {
// L'état d'Âme ne peut pas être inférieur au minimum (max dans le système)
let minAme = this.system.ame.max !== undefined ? this.system.ame.max : 0
if (changed.system.ame.etat < minAme) {
@@ -288,8 +289,9 @@ export class MournbladeCYD2Actor extends Actor {
if (changed.system.ame.etat > this.system.ame.nbame) {
changed.system.ame.etat = this.system.ame.nbame
}
+ const oldEtat = this.system.ame.etat
setTimeout(() => {
- this.processAme(changed.system.ame)
+ this.processAme(changed.system.ame, oldEtat)
}, 800)
}
// Si le max d'Âme change, ajuster l'état actuel si nécessaire
@@ -506,38 +508,57 @@ export class MournbladeCYD2Actor extends Actor {
}
/* -------------------------------------------- */
- processCombativite(sante) {
+ processCombativite(sante, oldEtat = undefined) {
sante = sante || foundry.utils.duplicate(this.system.sante)
- // Gestion des états affaibli et très affaibli
- if (sante.etat == this.system.sante.nbcombativite - 2 || sante.etat == this.system.sante.nbcombativite - 1) {
- if (sante.etat == this.system.sante.nbcombativite - 2 && this.items.find(item => item.type == "talent" && item.name.toLowerCase() == "encaissement")) {
- ChatMessage.create({ content: `${this.name} ne subit pas les 2 adversités rouge grâce à Encaissement. Pensez à les ajouter à la fin de la scène !` })
- } else if (sante.etat == this.system.sante.nbcombativite - 1 && this.items.find(item => item.type == "talent" && item.name.toLowerCase().includes("vaillant"))) {
- ChatMessage.create({ content: `${this.name} ne subit pas les 2 adversités rouge grâce à Vaillant. Pensez à les ajouter à la fin de la scène !` })
+ const affaibli = this.system.sante.nbcombativite - 2
+ const tresAffaibli = this.system.sante.nbcombativite - 1
+ // oldEtat permet de détecter les sauts qui franchissent Affaibli ou Très Affaibli
+ // sans y atterrir exactement (ex: 0 → 5 doit déclencher les deux seuils)
+ const prev = oldEtat !== undefined ? oldEtat : sante.etat
+ const curr = sante.etat
+
+ const passedAffaibli = curr >= affaibli && prev < affaibli
+ const passedTresAffaibli = curr >= tresAffaibli && prev < tresAffaibli
+
+ if (passedAffaibli) {
+ if (this.items.find(item => item.type == "talent" && item.name.toLowerCase() == "encaissement")) {
+ ChatMessage.create({ content: `${this.name} ne subit pas les 2 adversités rouge (Affaibli) grâce à Encaissement. Pensez à les ajouter à la fin de la scène !` })
} else {
- ChatMessage.create({ content: `${this.name} subit 2 adversités rouge !` })
+ ChatMessage.create({ content: `${this.name} est Affaibli et subit 2 adversités rouge !` })
+ this.incDecAdversite("rouge", 2)
+ }
+ }
+ if (passedTresAffaibli) {
+ if (this.items.find(item => item.type == "talent" && item.name.toLowerCase().includes("vaillant"))) {
+ ChatMessage.create({ content: `${this.name} ne subit pas les 2 adversités rouge (Très Affaibli) grâce à Vaillant. Pensez à les ajouter à la fin de la scène !` })
+ } else {
+ ChatMessage.create({ content: `${this.name} est Très Affaibli et subit 2 adversités rouge supplémentaires !` })
this.incDecAdversite("rouge", 2)
}
}
}
/* -------------------------------------------- */
- processAme(ame) {
+ processAme(ame, oldEtat = undefined) {
ame = ame || foundry.utils.duplicate(this.system.ame)
- let traumatiseValue = this.system.ame.nbame - 2
- let tresTraumatiseValue = this.system.ame.nbame - 1
- let briseValue = this.system.ame.nbame
+ const traumatiseValue = this.system.ame.nbame - 2
+ const tresTraumatiseValue = this.system.ame.nbame - 1
+ const briseValue = this.system.ame.nbame
+ const prev = oldEtat !== undefined ? oldEtat : ame.etat
+ const curr = ame.etat
- // Gestion des états Traumatisé, Très Traumatisé et Brisé
- if (ame.etat == traumatiseValue) {
+ // Déclencher pour chaque seuil franchi ou atteint, même en cas de saut
+ if (curr >= traumatiseValue && prev < traumatiseValue) {
ChatMessage.create({ content: `${this.name} est Traumatisé et subit 1 adversité bleue et 1 adversité noire !` })
this.incDecAdversite("bleue", 1)
this.incDecAdversite("noire", 1)
- } else if (ame.etat == tresTraumatiseValue) {
+ }
+ if (curr >= tresTraumatiseValue && prev < tresTraumatiseValue) {
ChatMessage.create({ content: `${this.name} est Très Traumatisé et subit 1 adversité bleue et 1 adversité noire !` })
this.incDecAdversite("bleue", 1)
this.incDecAdversite("noire", 1)
- } else if (ame.etat >= briseValue) {
+ }
+ if (curr >= briseValue && prev < briseValue) {
ChatMessage.create({ content: `${this.name} est Brisé et subit 1 adversité noire !` })
this.incDecAdversite("noire", 1)
}
@@ -727,7 +748,7 @@ export class MournbladeCYD2Actor extends Actor {
if (attrKey) {
rollData.attrKey = attrKey
if (attrKey != "tochoose") {
- rollData.actionImg = "systems/fvtt-mournblade-cyd2/assets/icons/" + this.system.attributs[attrKey].labelnorm + ".webp"
+ rollData.actionImg = "systems/fvtt-mournblade-cyd-2-0/assets/icons/" + this.system.attributs[attrKey].labelnorm + ".webp"
rollData.attr = foundry.utils.duplicate(this.system.attributs[attrKey])
}
}
@@ -864,6 +885,8 @@ export class MournbladeCYD2Actor extends Actor {
roll = await new Roll("1d10+" + arme.system.totalDegats + "+" + bonus + "+" + bonus2).roll()
}
await MournbladeCYD2Utility.showDiceSoNice(roll, game.settings.get("core", "rollMode"));
+ // CYD 2.0: états SUPPLÉMENTAIRES au-delà du -1 automatique à la réussite.
+ // Math.floor(total/SV) = 0 ( i.toObject())
}
if (data.type == 'creature') {
- const skills = await MournbladeCYD2Utility.loadCompendium("fvtt-mournblade-cyd2.skills-creatures")
+ const skills = await MournbladeCYD2Utility.loadCompendium("fvtt-mournblade-cyd-2-0.skills-creatures")
data.items = skills.map(i => i.toObject())
- data.items.push({ name: "Arme naturelle 1", type: 'arme', img: "systems/fvtt-mournblade-cyd2/assets/icons/melee.webp", system: { typearme: "contact", bonusmaniementoff: 0, seuildefense: 0, degats: "0" } })
- data.items.push({ name: "Arme naturelle 2", type: 'arme', img: "systems/fvtt-mournblade-cyd2/assets/icons/melee.webp", system: { typearme: "contact", bonusmaniementoff: 0, seuildefense: 0, degats: "0" } })
+ data.items.push({ name: "Arme naturelle 1", type: 'arme', img: "systems/fvtt-mournblade-cyd-2-0/assets/icons/melee.webp", system: { typearme: "contact", bonusmaniementoff: 0, seuildefense: 0, degats: "0" } })
+ data.items.push({ name: "Arme naturelle 2", type: 'arme', img: "systems/fvtt-mournblade-cyd-2-0/assets/icons/melee.webp", system: { typearme: "contact", bonusmaniementoff: 0, seuildefense: 0, degats: "0" } })
}
return super.create(data, options);
@@ -118,9 +118,6 @@ export class MournbladeCYD2Actor extends Actor {
getEquipments() {
return this.getItemSorted(["equipement"])
}
- getArtefacts() {
- return this.getItemSorted(["artefact"])
- }
getArmors() {
return this.getItemSorted(["protection"])
}
@@ -136,12 +133,6 @@ export class MournbladeCYD2Actor extends Actor {
getRessources() {
return this.getItemSorted(["ressource"])
}
- getContacts() {
- return this.getItemSorted(["contact"])
- }
- getMutations() {
- return this.getItemSorted(["mutation"])
- }
getDons() {
return this.getItemSorted(["don"])
}
@@ -154,6 +145,12 @@ export class MournbladeCYD2Actor extends Actor {
getRunes() {
return this.getItemSorted(["rune"])
}
+ getRuneEffects() {
+ return this.getItemSorted(["runeeffect"])
+ }
+ getProfil() {
+ return this.getProfils()[0] ?? null
+ }
getTraitsChaotiques() {
return this.getItemSorted(["traitchaotique"])
}
@@ -229,6 +226,9 @@ export class MournbladeCYD2Actor extends Actor {
}
return equipProtection // Uniquement la protection des armures + boucliers
}
+ getProtectionTotal() {
+ return this.getProtection()
+ }
/* -------------------------------------------- */
getCombatValues() {
@@ -246,9 +246,6 @@ export class MournbladeCYD2Actor extends Actor {
return combat
}
- /* -------------------------------------------- */
- prepareBaseData() {
- }
/* -------------------------------------------- */
async prepareData() {
@@ -276,12 +273,13 @@ export class MournbladeCYD2Actor extends Actor {
/* -------------------------------------------- */
_preUpdate(changed, options, user) {
- if (changed?.system?.sante?.etat && changed?.system?.sante?.etat != this.system.sante.etat) {
+ if (changed?.system?.sante?.etat !== undefined && changed.system.sante.etat != this.system.sante.etat) {
+ const oldEtat = this.system.sante.etat
setTimeout(() => {
- this.processCombativite(changed.system.sante)
+ this.processCombativite(changed.system.sante, oldEtat)
}, 800)
}
- if (changed?.system?.ame?.etat && changed?.system?.ame?.etat != this.system.ame.etat) {
+ if (changed?.system?.ame?.etat !== undefined && changed.system.ame.etat != this.system.ame.etat) {
// L'état d'Âme ne peut pas être inférieur au minimum (max dans le système)
let minAme = this.system.ame.max !== undefined ? this.system.ame.max : 0
if (changed.system.ame.etat < minAme) {
@@ -291,8 +289,9 @@ export class MournbladeCYD2Actor extends Actor {
if (changed.system.ame.etat > this.system.ame.nbame) {
changed.system.ame.etat = this.system.ame.nbame
}
+ const oldEtat = this.system.ame.etat
setTimeout(() => {
- this.processAme(changed.system.ame)
+ this.processAme(changed.system.ame, oldEtat)
}, 800)
}
// Si le max d'Âme change, ajuster l'état actuel si nécessaire
@@ -509,38 +508,57 @@ export class MournbladeCYD2Actor extends Actor {
}
/* -------------------------------------------- */
- processCombativite(sante) {
+ processCombativite(sante, oldEtat = undefined) {
sante = sante || foundry.utils.duplicate(this.system.sante)
- // Gestion des états affaibli et très affaibli
- if (sante.etat == this.system.sante.nbcombativite - 2 || sante.etat == this.system.sante.nbcombativite - 1) {
- if (sante.etat == this.system.sante.nbcombativite - 2 && this.items.find(item => item.type == "talent" && item.name.toLowerCase() == "encaissement")) {
- ChatMessage.create({ content: `${this.name} ne subit pas les 2 adversités rouge grâce à Encaissement. Pensez à les ajouter à la fin de la scène !` })
- } else if (sante.etat == this.system.sante.nbcombativite - 1 && this.items.find(item => item.type == "talent" && item.name.toLowerCase().includes("vaillant"))) {
- ChatMessage.create({ content: `${this.name} ne subit pas les 2 adversités rouge grâce à Vaillant. Pensez à les ajouter à la fin de la scène !` })
+ const affaibli = this.system.sante.nbcombativite - 2
+ const tresAffaibli = this.system.sante.nbcombativite - 1
+ // oldEtat permet de détecter les sauts qui franchissent Affaibli ou Très Affaibli
+ // sans y atterrir exactement (ex: 0 → 5 doit déclencher les deux seuils)
+ const prev = oldEtat !== undefined ? oldEtat : sante.etat
+ const curr = sante.etat
+
+ const passedAffaibli = curr >= affaibli && prev < affaibli
+ const passedTresAffaibli = curr >= tresAffaibli && prev < tresAffaibli
+
+ if (passedAffaibli) {
+ if (this.items.find(item => item.type == "talent" && item.name.toLowerCase() == "encaissement")) {
+ ChatMessage.create({ content: `${this.name} ne subit pas les 2 adversités rouge (Affaibli) grâce à Encaissement. Pensez à les ajouter à la fin de la scène !` })
} else {
- ChatMessage.create({ content: `${this.name} subit 2 adversités rouge !` })
+ ChatMessage.create({ content: `${this.name} est Affaibli et subit 2 adversités rouge !` })
+ this.incDecAdversite("rouge", 2)
+ }
+ }
+ if (passedTresAffaibli) {
+ if (this.items.find(item => item.type == "talent" && item.name.toLowerCase().includes("vaillant"))) {
+ ChatMessage.create({ content: `${this.name} ne subit pas les 2 adversités rouge (Très Affaibli) grâce à Vaillant. Pensez à les ajouter à la fin de la scène !` })
+ } else {
+ ChatMessage.create({ content: `${this.name} est Très Affaibli et subit 2 adversités rouge supplémentaires !` })
this.incDecAdversite("rouge", 2)
}
}
}
/* -------------------------------------------- */
- processAme(ame) {
+ processAme(ame, oldEtat = undefined) {
ame = ame || foundry.utils.duplicate(this.system.ame)
- let traumatiseValue = this.system.ame.nbame - 2
- let tresTraumatiseValue = this.system.ame.nbame - 1
- let briseValue = this.system.ame.nbame
+ const traumatiseValue = this.system.ame.nbame - 2
+ const tresTraumatiseValue = this.system.ame.nbame - 1
+ const briseValue = this.system.ame.nbame
+ const prev = oldEtat !== undefined ? oldEtat : ame.etat
+ const curr = ame.etat
- // Gestion des états Traumatisé, Très Traumatisé et Brisé
- if (ame.etat == traumatiseValue) {
+ // Déclencher pour chaque seuil franchi ou atteint, même en cas de saut
+ if (curr >= traumatiseValue && prev < traumatiseValue) {
ChatMessage.create({ content: `${this.name} est Traumatisé et subit 1 adversité bleue et 1 adversité noire !` })
this.incDecAdversite("bleue", 1)
this.incDecAdversite("noire", 1)
- } else if (ame.etat == tresTraumatiseValue) {
+ }
+ if (curr >= tresTraumatiseValue && prev < tresTraumatiseValue) {
ChatMessage.create({ content: `${this.name} est Très Traumatisé et subit 1 adversité bleue et 1 adversité noire !` })
this.incDecAdversite("bleue", 1)
this.incDecAdversite("noire", 1)
- } else if (ame.etat >= briseValue) {
+ }
+ if (curr >= briseValue && prev < briseValue) {
ChatMessage.create({ content: `${this.name} est Brisé et subit 1 adversité noire !` })
this.incDecAdversite("noire", 1)
}
@@ -730,7 +748,7 @@ export class MournbladeCYD2Actor extends Actor {
if (attrKey) {
rollData.attrKey = attrKey
if (attrKey != "tochoose") {
- rollData.actionImg = "systems/fvtt-mournblade-cyd2/assets/icons/" + this.system.attributs[attrKey].labelnorm + ".webp"
+ rollData.actionImg = "systems/fvtt-mournblade-cyd-2-0/assets/icons/" + this.system.attributs[attrKey].labelnorm + ".webp"
rollData.attr = foundry.utils.duplicate(this.system.attributs[attrKey])
}
}
@@ -867,6 +885,8 @@ export class MournbladeCYD2Actor extends Actor {
roll = await new Roll("1d10+" + arme.system.totalDegats + "+" + bonus + "+" + bonus2).roll()
}
await MournbladeCYD2Utility.showDiceSoNice(roll, game.settings.get("core", "rollMode"));
+ // CYD 2.0: états SUPPLÉMENTAIRES au-delà du -1 automatique à la réussite.
+ // Math.floor(total/SV) = 0 ( section {
- height: 100%;
display: flex;
flex-direction: column;
flex: 1;
@@ -176,6 +160,26 @@
}
.header-fields {
+ // Force single-line stat rows — prevent Foundry's .flexrow wrap and h4 margins from breaking layout
+ .item.flexrow {
+ flex-wrap: nowrap !important;
+ align-items: center !important;
+
+ h4 {
+ margin: 0 !important;
+ padding-top: 0 !important;
+ }
+ }
+
+ h4.item-name-label.competence-name,
+ .item-name-label.competence-name,
+ label.item-name-label.competence-name {
+ color: #1a1008 !important;
+ text-shadow: none !important;
+ font-weight: bold !important;
+ background: none !important;
+ }
+
h4.item-name-label.competence-name {
font-size: 0.75rem;
padding-top: 3px;
@@ -197,6 +201,25 @@
font-size: 0.8rem;
}
}
+
+ .sheet-mode-toggle {
+ background: transparent;
+ border: none;
+ color: #fff;
+ padding: 2px 6px;
+ cursor: pointer;
+ font-size: 0.75rem;
+ transition: all 0.2s ease;
+ margin-left: 8px;
+ height: auto;
+ line-height: 1.2;
+ text-shadow: 1px 1px 2px rgba(0, 0, 0, 0.8);
+
+ &:hover {
+ color: #ffd700;
+ text-shadow: 0 0 8px rgba(255, 215, 0, 0.8);
+ }
+ }
}
// Sheet navigation tabs
@@ -689,7 +712,7 @@
}
/* ==================== Creature Sheet Specific Styles ==================== */
-.fvtt-mournblade.actor.creature-sheet {
+.fvtt-mournblade-cyd-2-0.actor.creature-sheet {
// Variant background pour creatures - teinte légèrement différente
.background-sheet-header-creature {
@@ -745,7 +768,7 @@
// PNJ Sheet - Orange/Copper theme for visual distinction
-.fvtt-mournblade.actor.pnj-sheet {
+.fvtt-mournblade-cyd-2-0.actor.pnj-sheet {
// Variant background pour PNJs - teinte orange/cuivre
.background-sheet-header-creature {
diff --git a/less/item-styles.less b/less/item-styles.less
index 6568dff..a9f4c2a 100644
--- a/less/item-styles.less
+++ b/less/item-styles.less
@@ -1,7 +1,7 @@
/* ==================== Item Sheet Styles ==================== */
/* Item header with image and name */
-.fvtt-mournblade.item {
+.fvtt-mournblade-cyd-2-0.item {
/* Background pour toute la fiche d'item */
background: url("../assets/ui/pc_sheet_bg.webp") repeat;
display: flex;
diff --git a/less/simple-converted.less b/less/simple-converted.less
index 9643c3f..511ad68 100644
--- a/less/simple-converted.less
+++ b/less/simple-converted.less
@@ -82,7 +82,7 @@
/* For nav and title */
.window-app input,
- .fvtt-mournblade .item-form,
+ .fvtt-mournblade-cyd-2-0 .item-form,
.sheet header.sheet-header .flex-group-center.flex-compteurs,
.sheet header.sheet-header .flex-group-center.flex-fatigue,
select,
@@ -244,7 +244,7 @@
/* Styles limited to foundryvtt-vadentis sheets */
- .fvtt-mournblade .sheet-header {
+ .fvtt-mournblade-cyd-2-0 .sheet-header {
-webkit-box-flex: 0;
-ms-flex: 0 0 210px;
flex: 0 0 210px;
@@ -264,15 +264,16 @@
margin-bottom: 10px;
}
- .fvtt-mournblade .sheet-header .profile-img {
+ .fvtt-mournblade-cyd-2-0 .sheet-header .profile-img {
-webkit-box-flex: 0;
- -ms-flex: 0 0 128px;
- flex: 0 0 128px;
- height: 128px;
- width: 128px;
+ -ms-flex: 0 0 80px;
+ flex: 0 0 80px;
+ height: 80px;
+ width: 80px;
margin-right: 10px;
object-fit: cover;
object-position: 50% 0;
+ cursor: pointer;
}
.button-img {
@@ -305,13 +306,13 @@
vertical-align: bottom;
}
- .fvtt-mournblade .sheet-header .header-fields {
+ .fvtt-mournblade-cyd-2-0 .sheet-header .header-fields {
-webkit-box-flex: 1;
-ms-flex: 1;
flex: 1;
}
- .fvtt-mournblade .sheet-header h1.charname {
+ .fvtt-mournblade-cyd-2-0 .sheet-header h1.charname {
height: 50px;
padding: 0px;
margin: 5px 0;
@@ -321,7 +322,7 @@
font-family: "CentaurMT";
}
- .fvtt-mournblade .sheet-header h1.charname input {
+ .fvtt-mournblade-cyd-2-0 .sheet-header h1.charname input {
width: 100%;
height: 100%;
margin: 0;
@@ -331,19 +332,19 @@
text-align: left;
}
- .fvtt-mournblade .sheet-tabs {
+ .fvtt-mournblade-cyd-2-0 .sheet-tabs {
-webkit-box-flex: 0;
-ms-flex: 0;
flex: 0;
}
- .fvtt-mournblade .sheet-body,
- .fvtt-mournblade .sheet-body .tab {
+ .fvtt-mournblade-cyd-2-0 .sheet-body,
+ .fvtt-mournblade-cyd-2-0 .sheet-body .tab {
height: auto;
font-size: 0.9rem;
}
- .fvtt-mournblade .sheet-body .tab .editor {
+ .fvtt-mournblade-cyd-2-0 .sheet-body .tab .editor {
height: 100%;
font-size: 0.9rem;
}
@@ -372,70 +373,83 @@
padding: 0 3px;
}
- .fvtt-mournblade .tox .tox-editor-container {
+ .fvtt-mournblade-cyd-2-0 .tox .tox-editor-container {
background: #fff;
}
- .fvtt-mournblade .tox .tox-edit-area {
+ .fvtt-mournblade-cyd-2-0 .tox .tox-edit-area {
padding: 0 8px;
}
- .fvtt-mournblade .resource-label {
+ .fvtt-mournblade-cyd-2-0 .resource-label {
font-weight: bold;
text-transform: uppercase;
}
- .fvtt-mournblade .tabs {
+ .fvtt-mournblade-cyd-2-0 .tabs {
height: 40px;
border-top: 1px solid #AAA;
border-bottom: 1px solid #AAA;
color: #000000;
}
- .fvtt-mournblade .tabs .item {
- line-height: 40px;
- font-weight: bold;
+ .fvtt-mournblade-cyd-2-0 nav.sheet-tabs {
+ justify-content: flex-start !important;
+ gap: 0 !important;
+ padding: 0 !important;
}
- .fvtt-mournblade .tabs .item.active {
+ .fvtt-mournblade-cyd-2-0 .tabs .item {
+ line-height: 40px;
+ font-size: 10px;
+ font-weight: bold;
+ white-space: nowrap;
+ overflow: hidden;
+ text-overflow: ellipsis;
+ flex: 1 1 0;
+ text-align: center;
+ padding: 0 4px;
+ }
+
+ .fvtt-mournblade-cyd-2-0 .tabs .item.active {
text-decoration: underline;
text-shadow: none;
}
- .fvtt-mournblade .items-list {
+ .fvtt-mournblade-cyd-2-0 .items-list {
list-style: none;
margin: 1px 0;
padding: 0;
overflow-y: auto;
}
- .fvtt-mournblade .items-list .item-header {
+ .fvtt-mournblade-cyd-2-0 .items-list .item-header {
font-weight: bold;
}
- .fvtt-mournblade .items-list .item {
+ .fvtt-mournblade-cyd-2-0 .items-list .item {
height: 30px;
line-height: 24px;
padding: 1px 0;
border-bottom: 1px solid #BBB;
}
- .fvtt-mournblade .items-list .item .item-image {
+ .fvtt-mournblade-cyd-2-0 .items-list .item .item-image {
-webkit-box-flex: 0;
-ms-flex: 0 0 24px;
flex: 0 0 24px;
margin-right: 5px;
}
- .fvtt-mournblade .items-list .item img {
+ .fvtt-mournblade-cyd-2-0 .items-list .item img {
display: block;
}
- .fvtt-mournblade .items-list .item-name {
+ .fvtt-mournblade-cyd-2-0 .items-list .item-name {
margin: 0;
}
- .fvtt-mournblade .items-list .item-controls {
+ .fvtt-mournblade-cyd-2-0 .items-list .item-controls {
-webkit-box-flex: 0;
-ms-flex: 0 0 86px;
flex: 0 0 86px;
@@ -1532,7 +1546,7 @@
.item-field-label-long {
flex-grow: 1;
- max-width: 8rem;
+ max-width: 10rem;
min-width: 8rem;
}
diff --git a/modules/applications/mournblade-cyd2-roll-dialog.mjs b/modules/applications/mournblade-cyd2-roll-dialog.mjs
index d4fc750..100571a 100644
--- a/modules/applications/mournblade-cyd2-roll-dialog.mjs
+++ b/modules/applications/mournblade-cyd2-roll-dialog.mjs
@@ -16,15 +16,12 @@ export class MournbladeCYD2RollDialog {
difficulte: String(rollData.difficulte || 0),
img: actor.img,
name: actor.name,
- config: game.system.mournbladecyd2.config
+ config: game.system.mournbladecyd2.config,
+ attributs: game.system.mournbladecyd2.config.attributs,
};
- if (rollData.attrKey === "tochoose") {
- context.selectableAttributes = actor.system.attributs;
- }
-
const content = await foundry.applications.handlebars.renderTemplate(
- "systems/fvtt-mournblade-cyd2/templates/roll-dialog-generic.hbs",
+ "systems/fvtt-mournblade-cyd-2-0/templates/roll-dialog-generic.hbs",
context
);
diff --git a/modules/applications/sheets/base-actor-sheet.mjs b/modules/applications/sheets/base-actor-sheet.mjs
index 76c2154..656b57d 100644
--- a/modules/applications/sheets/base-actor-sheet.mjs
+++ b/modules/applications/sheets/base-actor-sheet.mjs
@@ -16,10 +16,10 @@ export default class MournbladeCYD2ActorSheetV2 extends HandlebarsApplicationMix
/** @override */
static DEFAULT_OPTIONS = {
- classes: ["fvtt-mournblade-cyd2", "sheet", "actor"],
+ classes: ["fvtt-mournblade-cyd-2-0", "sheet", "actor"],
position: {
- width: 640,
- height: 720,
+ width: 750,
+ height: 820,
},
form: {
submitOnChange: true,
@@ -44,6 +44,7 @@ export default class MournbladeCYD2ActorSheetV2 extends HandlebarsApplicationMix
createItem: MournbladeCYD2ActorSheetV2.#onCreateItem,
equipItem: MournbladeCYD2ActorSheetV2.#onEquipItem,
modifyQuantity: MournbladeCYD2ActorSheetV2.#onModifyQuantity,
+ modifyAdversite: MournbladeCYD2ActorSheetV2.#onModifyAdversite,
modifySante: MournbladeCYD2ActorSheetV2.#onModifySante,
modifyAme: MournbladeCYD2ActorSheetV2.#onModifyAme,
rollAttribut: MournbladeCYD2ActorSheetV2.#onRollAttribut,
@@ -53,7 +54,11 @@ export default class MournbladeCYD2ActorSheetV2 extends HandlebarsApplicationMix
rollArmeSpecial: MournbladeCYD2ActorSheetV2.#onRollArmeSpecial,
rollArmeDegats: MournbladeCYD2ActorSheetV2.#onRollArmeDegats,
rollAssommer: MournbladeCYD2ActorSheetV2.#onRollAssommer,
+ rollCoupBas: MournbladeCYD2ActorSheetV2.#onRollCoupBas,
rollImmobiliser: MournbladeCYD2ActorSheetV2.#onRollImmobiliser,
+ rollRepousser: MournbladeCYD2ActorSheetV2.#onRollRepousser,
+ rollDesengager: MournbladeCYD2ActorSheetV2.#onRollDesengager,
+ rollInitiative: MournbladeCYD2ActorSheetV2.#onRollInitiative,
rollFuir: MournbladeCYD2ActorSheetV2.#onRollFuir,
},
};
@@ -226,6 +231,15 @@ export default class MournbladeCYD2ActorSheetV2 extends HandlebarsApplicationMix
}
}
+ static async #onModifyAdversite(event, target) {
+ const li = target.closest('[data-adversite]');
+ const adversiteKey = li?.dataset.adversite;
+ if (!adversiteKey) return;
+ const value = Number.parseInt(target.dataset.adversiteValue);
+ const current = this.document.system.adversite[adversiteKey] || 0;
+ await this.document.update({ [`system.adversite.${adversiteKey}`]: Math.max(0, current + value) });
+ }
+
static async #onModifySante(event, target) {
const type = target.dataset.type;
const value = Number.parseInt(target.dataset.value);
@@ -254,25 +268,44 @@ export default class MournbladeCYD2ActorSheetV2 extends HandlebarsApplicationMix
}
static async #onRollArmeOffensif(event, target) {
- await this.document.rollArmeOffensif(target.dataset.armeId);
+ const li = target.closest('[data-item-id]');
+ await this.document.rollArmeOffensif(target.dataset.armeId ?? li?.dataset.itemId);
}
static async #onRollArmeSpecial(event, target) {
- await this.document.rollArmeSpecial(target.dataset.armeId);
+ const li = target.closest('[data-item-id]');
+ await this.document.rollArmeSpecial(target.dataset.armeId ?? li?.dataset.itemId);
}
static async #onRollArmeDegats(event, target) {
- await this.document.rollArmeDegats(target.dataset.armeId);
+ const li = target.closest('[data-item-id]');
+ await this.document.rollArmeDegats(target.dataset.armeId ?? li?.dataset.itemId);
}
static async #onRollAssommer(event, target) {
await this.document.rollAssomer();
}
+ static async #onRollCoupBas(event, target) {
+ await this.document.rollCoupBas();
+ }
+
static async #onRollImmobiliser(event, target) {
await this.document.rollImmobiliser();
}
+ static async #onRollRepousser(event, target) {
+ await this.document.rollRepousser();
+ }
+
+ static async #onRollDesengager(event, target) {
+ await this.document.rollDesengager();
+ }
+
+ static async #onRollInitiative(event, target) {
+ await this.document.rollAttribut("adr", true);
+ }
+
static async #onRollFuir(event, target) {
await this.document.rollFuir();
}
diff --git a/modules/applications/sheets/base-item-sheet.mjs b/modules/applications/sheets/base-item-sheet.mjs
index f3f264b..6a4b705 100644
--- a/modules/applications/sheets/base-item-sheet.mjs
+++ b/modules/applications/sheets/base-item-sheet.mjs
@@ -13,7 +13,7 @@ export default class MournbladeCYD2ItemSheetV2 extends HandlebarsApplicationMixi
/** @override */
static DEFAULT_OPTIONS = {
- classes: ["fvtt-mournblade-cyd2", "item"],
+ classes: ["fvtt-mournblade-cyd-2-0", "item"],
position: {
width: 620,
height: 600,
@@ -107,7 +107,24 @@ export default class MournbladeCYD2ItemSheetV2 extends HandlebarsApplicationMixi
}
static async #onPostItem(event) {
- await this.document.toChat?.();
+ event.preventDefault();
+ const item = this.document;
+ const chatData = foundry.utils.duplicate(item);
+ if (item.actor) {
+ chatData.actor = { id: item.actor.id };
+ }
+ if (chatData.img?.includes("/blank.png")) {
+ chatData.img = null;
+ }
+ chatData.jsondata = JSON.stringify({
+ compendium: "postedItem",
+ payload: chatData,
+ });
+ const html = await foundry.applications.handlebars.renderTemplate(
+ "systems/fvtt-mournblade-cyd-2-0/templates/post-item.hbs",
+ chatData
+ );
+ ChatMessage.create({ user: game.user.id, content: html });
}
static async #onAddPredilection(event) {
diff --git a/modules/applications/sheets/mournblade-cyd2-arme-sheet.mjs b/modules/applications/sheets/mournblade-cyd2-arme-sheet.mjs
index abbee8e..c7f4b9a 100644
--- a/modules/applications/sheets/mournblade-cyd2-arme-sheet.mjs
+++ b/modules/applications/sheets/mournblade-cyd2-arme-sheet.mjs
@@ -15,7 +15,7 @@ export default class MournbladeCYD2ArmeSheet extends MournbladeCYD2ItemSheetV2 {
/** @override */
static PARTS = {
main: {
- template: "systems/fvtt-mournblade-cyd2/templates/item-arme-sheet.hbs",
+ template: "systems/fvtt-mournblade-cyd-2-0/templates/item-arme-sheet.hbs",
},
};
diff --git a/modules/applications/sheets/mournblade-cyd2-competence-sheet.mjs b/modules/applications/sheets/mournblade-cyd2-competence-sheet.mjs
index 3d7d343..3dcbd5c 100644
--- a/modules/applications/sheets/mournblade-cyd2-competence-sheet.mjs
+++ b/modules/applications/sheets/mournblade-cyd2-competence-sheet.mjs
@@ -15,7 +15,7 @@ export default class MournbladeCYD2CompetenceSheet extends MournbladeCYD2ItemShe
/** @override */
static PARTS = {
main: {
- template: "systems/fvtt-mournblade-cyd2/templates/item-competence-sheet.hbs",
+ template: "systems/fvtt-mournblade-cyd-2-0/templates/item-competence-sheet.hbs",
},
};
diff --git a/modules/applications/sheets/mournblade-cyd2-creature-sheet.mjs b/modules/applications/sheets/mournblade-cyd2-creature-sheet.mjs
index 22a442a..dd86406 100644
--- a/modules/applications/sheets/mournblade-cyd2-creature-sheet.mjs
+++ b/modules/applications/sheets/mournblade-cyd2-creature-sheet.mjs
@@ -1,4 +1,5 @@
import MournbladeCYD2ActorSheetV2 from "./base-actor-sheet.mjs";
+import { MournbladeCYD2Utility } from "../../mournblade-cyd2-utility.js";
export default class MournbladeCYD2CreatureSheet extends MournbladeCYD2ActorSheetV2 {
@@ -15,7 +16,7 @@ export default class MournbladeCYD2CreatureSheet extends MournbladeCYD2ActorShee
/** @override */
static PARTS = {
sheet: {
- template: "systems/fvtt-mournblade-cyd2/templates/creature-sheet.hbs",
+ template: "systems/fvtt-mournblade-cyd-2-0/templates/creature-sheet.hbs",
},
};
@@ -28,6 +29,7 @@ export default class MournbladeCYD2CreatureSheet extends MournbladeCYD2ActorShee
const actor = this.document;
context.skills = actor.getSkills?.() ?? [];
+ context.combativiteList = MournbladeCYD2Utility.getCombativiteList(actor.system.sante?.nbcombativite || 0);
context.armes = foundry.utils.duplicate(actor.getWeapons?.() ?? []);
context.protections = foundry.utils.duplicate(actor.getArmors?.() ?? []);
context.runes = foundry.utils.duplicate(actor.getRunes?.() ?? []);
diff --git a/modules/applications/sheets/mournblade-cyd2-don-sheet.mjs b/modules/applications/sheets/mournblade-cyd2-don-sheet.mjs
index 1f954ba..1786c80 100644
--- a/modules/applications/sheets/mournblade-cyd2-don-sheet.mjs
+++ b/modules/applications/sheets/mournblade-cyd2-don-sheet.mjs
@@ -15,7 +15,7 @@ export default class MournbladeCYD2DonSheet extends MournbladeCYD2ItemSheetV2 {
/** @override */
static PARTS = {
main: {
- template: "systems/fvtt-mournblade-cyd2/templates/item-don-sheet.hbs",
+ template: "systems/fvtt-mournblade-cyd-2-0/templates/item-don-sheet.hbs",
},
};
diff --git a/modules/applications/sheets/mournblade-cyd2-equipement-sheet.mjs b/modules/applications/sheets/mournblade-cyd2-equipement-sheet.mjs
index e6f04f7..2133837 100644
--- a/modules/applications/sheets/mournblade-cyd2-equipement-sheet.mjs
+++ b/modules/applications/sheets/mournblade-cyd2-equipement-sheet.mjs
@@ -15,7 +15,7 @@ export default class MournbladeCYD2EquipementSheet extends MournbladeCYD2ItemShe
/** @override */
static PARTS = {
main: {
- template: "systems/fvtt-mournblade-cyd2/templates/item-equipement-sheet.hbs",
+ template: "systems/fvtt-mournblade-cyd-2-0/templates/item-equipement-sheet.hbs",
},
};
diff --git a/modules/applications/sheets/mournblade-cyd2-historique-sheet.mjs b/modules/applications/sheets/mournblade-cyd2-historique-sheet.mjs
index 3cd8d39..4e38865 100644
--- a/modules/applications/sheets/mournblade-cyd2-historique-sheet.mjs
+++ b/modules/applications/sheets/mournblade-cyd2-historique-sheet.mjs
@@ -15,7 +15,7 @@ export default class MournbladeCYD2HistoriqueSheet extends MournbladeCYD2ItemShe
/** @override */
static PARTS = {
main: {
- template: "systems/fvtt-mournblade-cyd2/templates/item-historique-sheet.hbs",
+ template: "systems/fvtt-mournblade-cyd-2-0/templates/item-historique-sheet.hbs",
},
};
diff --git a/modules/applications/sheets/mournblade-cyd2-monnaie-sheet.mjs b/modules/applications/sheets/mournblade-cyd2-monnaie-sheet.mjs
index b1d0d9e..73af19c 100644
--- a/modules/applications/sheets/mournblade-cyd2-monnaie-sheet.mjs
+++ b/modules/applications/sheets/mournblade-cyd2-monnaie-sheet.mjs
@@ -15,7 +15,7 @@ export default class MournbladeCYD2MonnaieSheet extends MournbladeCYD2ItemSheetV
/** @override */
static PARTS = {
main: {
- template: "systems/fvtt-mournblade-cyd2/templates/item-monnaie-sheet.hbs",
+ template: "systems/fvtt-mournblade-cyd-2-0/templates/item-monnaie-sheet.hbs",
},
};
diff --git a/modules/applications/sheets/mournblade-cyd2-pacte-sheet.mjs b/modules/applications/sheets/mournblade-cyd2-pacte-sheet.mjs
index 07707b0..181f087 100644
--- a/modules/applications/sheets/mournblade-cyd2-pacte-sheet.mjs
+++ b/modules/applications/sheets/mournblade-cyd2-pacte-sheet.mjs
@@ -15,7 +15,7 @@ export default class MournbladeCYD2PacteSheet extends MournbladeCYD2ItemSheetV2
/** @override */
static PARTS = {
main: {
- template: "systems/fvtt-mournblade-cyd2/templates/item-pacte-sheet.hbs",
+ template: "systems/fvtt-mournblade-cyd-2-0/templates/item-pacte-sheet.hbs",
},
};
diff --git a/modules/applications/sheets/mournblade-cyd2-personnage-sheet.mjs b/modules/applications/sheets/mournblade-cyd2-personnage-sheet.mjs
index 38144a0..06e5019 100644
--- a/modules/applications/sheets/mournblade-cyd2-personnage-sheet.mjs
+++ b/modules/applications/sheets/mournblade-cyd2-personnage-sheet.mjs
@@ -1,4 +1,5 @@
import MournbladeCYD2ActorSheetV2 from "./base-actor-sheet.mjs";
+import { MournbladeCYD2Utility } from "../../mournblade-cyd2-utility.js";
export default class MournbladeCYD2PersonnageSheet extends MournbladeCYD2ActorSheetV2 {
@@ -15,7 +16,7 @@ export default class MournbladeCYD2PersonnageSheet extends MournbladeCYD2ActorSh
/** @override */
static PARTS = {
sheet: {
- template: "systems/fvtt-mournblade-cyd2/templates/actor-sheet.hbs",
+ template: "systems/fvtt-mournblade-cyd-2-0/templates/actor-sheet.hbs",
},
};
@@ -27,6 +28,10 @@ export default class MournbladeCYD2PersonnageSheet extends MournbladeCYD2ActorSh
const context = await super._prepareContext();
const actor = this.document;
+ context.combativiteList = MournbladeCYD2Utility.getCombativiteList(actor.system.sante.nbcombativite);
+ context.ameList = MournbladeCYD2Utility.getAmeList(actor.system.ame.nbame, actor.getAmeMax?.() ?? 0);
+ context.ameMaxList = MournbladeCYD2Utility.getAmeMaxList(actor.system.ame.nbame);
+
context.skills = actor.getSkills?.() ?? [];
context.armes = foundry.utils.duplicate(actor.getWeapons?.() ?? []);
context.protections = foundry.utils.duplicate(actor.getArmors?.() ?? []);
diff --git a/modules/applications/sheets/mournblade-cyd2-profil-sheet.mjs b/modules/applications/sheets/mournblade-cyd2-profil-sheet.mjs
index 4b94ce5..eace14a 100644
--- a/modules/applications/sheets/mournblade-cyd2-profil-sheet.mjs
+++ b/modules/applications/sheets/mournblade-cyd2-profil-sheet.mjs
@@ -15,7 +15,7 @@ export default class MournbladeCYD2ProfilSheet extends MournbladeCYD2ItemSheetV2
/** @override */
static PARTS = {
main: {
- template: "systems/fvtt-mournblade-cyd2/templates/item-profil-sheet.hbs",
+ template: "systems/fvtt-mournblade-cyd-2-0/templates/item-profil-sheet.hbs",
},
};
diff --git a/modules/applications/sheets/mournblade-cyd2-protection-sheet.mjs b/modules/applications/sheets/mournblade-cyd2-protection-sheet.mjs
index 343fe13..d8c9f15 100644
--- a/modules/applications/sheets/mournblade-cyd2-protection-sheet.mjs
+++ b/modules/applications/sheets/mournblade-cyd2-protection-sheet.mjs
@@ -15,7 +15,7 @@ export default class MournbladeCYD2ProtectionSheet extends MournbladeCYD2ItemShe
/** @override */
static PARTS = {
main: {
- template: "systems/fvtt-mournblade-cyd2/templates/item-protection-sheet.hbs",
+ template: "systems/fvtt-mournblade-cyd-2-0/templates/item-protection-sheet.hbs",
},
};
diff --git a/modules/applications/sheets/mournblade-cyd2-ressource-sheet.mjs b/modules/applications/sheets/mournblade-cyd2-ressource-sheet.mjs
index ade6e82..213b138 100644
--- a/modules/applications/sheets/mournblade-cyd2-ressource-sheet.mjs
+++ b/modules/applications/sheets/mournblade-cyd2-ressource-sheet.mjs
@@ -15,7 +15,7 @@ export default class MournbladeCYD2RessourceSheet extends MournbladeCYD2ItemShee
/** @override */
static PARTS = {
main: {
- template: "systems/fvtt-mournblade-cyd2/templates/item-ressource-sheet.hbs",
+ template: "systems/fvtt-mournblade-cyd-2-0/templates/item-ressource-sheet.hbs",
},
};
diff --git a/modules/applications/sheets/mournblade-cyd2-rune-sheet.mjs b/modules/applications/sheets/mournblade-cyd2-rune-sheet.mjs
index 568375b..8a7de57 100644
--- a/modules/applications/sheets/mournblade-cyd2-rune-sheet.mjs
+++ b/modules/applications/sheets/mournblade-cyd2-rune-sheet.mjs
@@ -15,7 +15,7 @@ export default class MournbladeCYD2RuneSheet extends MournbladeCYD2ItemSheetV2 {
/** @override */
static PARTS = {
main: {
- template: "systems/fvtt-mournblade-cyd2/templates/item-rune-sheet.hbs",
+ template: "systems/fvtt-mournblade-cyd-2-0/templates/item-rune-sheet.hbs",
},
};
diff --git a/modules/applications/sheets/mournblade-cyd2-runeeffect-sheet.mjs b/modules/applications/sheets/mournblade-cyd2-runeeffect-sheet.mjs
index 2a2f22f..5f1cdd0 100644
--- a/modules/applications/sheets/mournblade-cyd2-runeeffect-sheet.mjs
+++ b/modules/applications/sheets/mournblade-cyd2-runeeffect-sheet.mjs
@@ -15,7 +15,7 @@ export default class MournbladeCYD2RuneEffectSheet extends MournbladeCYD2ItemShe
/** @override */
static PARTS = {
main: {
- template: "systems/fvtt-mournblade-cyd2/templates/item-runeeffect-sheet.hbs",
+ template: "systems/fvtt-mournblade-cyd-2-0/templates/item-runeeffect-sheet.hbs",
},
};
diff --git a/modules/applications/sheets/mournblade-cyd2-talent-sheet.mjs b/modules/applications/sheets/mournblade-cyd2-talent-sheet.mjs
index 4fe8265..38ef8ed 100644
--- a/modules/applications/sheets/mournblade-cyd2-talent-sheet.mjs
+++ b/modules/applications/sheets/mournblade-cyd2-talent-sheet.mjs
@@ -15,7 +15,7 @@ export default class MournbladeCYD2TalentSheet extends MournbladeCYD2ItemSheetV2
/** @override */
static PARTS = {
main: {
- template: "systems/fvtt-mournblade-cyd2/templates/item-talent-sheet.hbs",
+ template: "systems/fvtt-mournblade-cyd-2-0/templates/item-talent-sheet.hbs",
},
};
diff --git a/modules/applications/sheets/mournblade-cyd2-tendance-sheet.mjs b/modules/applications/sheets/mournblade-cyd2-tendance-sheet.mjs
index bc31582..df766d9 100644
--- a/modules/applications/sheets/mournblade-cyd2-tendance-sheet.mjs
+++ b/modules/applications/sheets/mournblade-cyd2-tendance-sheet.mjs
@@ -15,7 +15,7 @@ export default class MournbladeCYD2TendanceSheet extends MournbladeCYD2ItemSheet
/** @override */
static PARTS = {
main: {
- template: "systems/fvtt-mournblade-cyd2/templates/item-tendance-sheet.hbs",
+ template: "systems/fvtt-mournblade-cyd-2-0/templates/item-tendance-sheet.hbs",
},
};
diff --git a/modules/applications/sheets/mournblade-cyd2-traitchaotique-sheet.mjs b/modules/applications/sheets/mournblade-cyd2-traitchaotique-sheet.mjs
index 4ab322e..7c93c90 100644
--- a/modules/applications/sheets/mournblade-cyd2-traitchaotique-sheet.mjs
+++ b/modules/applications/sheets/mournblade-cyd2-traitchaotique-sheet.mjs
@@ -15,7 +15,7 @@ export default class MournbladeCYD2TraitChaotiqueSheet extends MournbladeCYD2Ite
/** @override */
static PARTS = {
main: {
- template: "systems/fvtt-mournblade-cyd2/templates/item-traitchaotique-sheet.hbs",
+ template: "systems/fvtt-mournblade-cyd-2-0/templates/item-traitchaotique-sheet.hbs",
},
};
diff --git a/modules/applications/sheets/mournblade-cyd2-traitespece-sheet.mjs b/modules/applications/sheets/mournblade-cyd2-traitespece-sheet.mjs
index d0d967d..4b5ec09 100644
--- a/modules/applications/sheets/mournblade-cyd2-traitespece-sheet.mjs
+++ b/modules/applications/sheets/mournblade-cyd2-traitespece-sheet.mjs
@@ -15,7 +15,7 @@ export default class MournbladeCYD2TraitEspeceSheet extends MournbladeCYD2ItemSh
/** @override */
static PARTS = {
main: {
- template: "systems/fvtt-mournblade-cyd2/templates/item-traitespece-sheet.hbs",
+ template: "systems/fvtt-mournblade-cyd-2-0/templates/item-traitespece-sheet.hbs",
},
};
diff --git a/modules/macro-replace-images.js b/modules/macro-replace-images.js
index 6cfc9ec..3236ed4 100644
--- a/modules/macro-replace-images.js
+++ b/modules/macro-replace-images.js
@@ -1,6 +1,6 @@
/**
* Macro pour remplacer les chemins d'images dans les compendiums
- * Remplace "fvtt-hawkmoon-cyd" par "fvtt-mournblade-cyd2" dans tous les champs 'img'
+ * Remplace "fvtt-hawkmoon-cyd" par "fvtt-mournblade-cyd-2-0" dans tous les champs 'img'
*/
(async () => {
@@ -10,7 +10,7 @@
content: `Cette macro va :
- Déverrouiller tous les compendiums
- - Remplacer "fvtt-hawkmoon-cyd" par "fvtt-mournblade-cyd2" dans tous les champs 'img'
+ - Remplacer "fvtt-hawkmoon-cyd" par "fvtt-mournblade-cyd-2-0" dans tous les champs 'img'
- Reverrouiller les compendiums
Voulez-vous continuer ?
`,
@@ -49,14 +49,14 @@
// Vérifier le champ img principal
if (doc.img && doc.img.includes("fvtt-hawkmoon-cyd")) {
- updateData.img = doc.img.replace(/fvtt-hawkmoon-cyd/g, "fvtt-mournblade-cyd2");
+ updateData.img = doc.img.replace(/fvtt-hawkmoon-cyd/g, "fvtt-mournblade-cyd-2-0");
needsUpdate = true;
}
// Pour les acteurs, vérifier aussi prototypeToken.texture.src
if (doc.documentName === "Actor" && doc.prototypeToken?.texture?.src) {
if (doc.prototypeToken.texture.src.includes("fvtt-hawkmoon-cyd")) {
- updateData["prototypeToken.texture.src"] = doc.prototypeToken.texture.src.replace(/fvtt-hawkmoon-cyd/g, "fvtt-mournblade-cyd2");
+ updateData["prototypeToken.texture.src"] = doc.prototypeToken.texture.src.replace(/fvtt-hawkmoon-cyd/g, "fvtt-mournblade-cyd-2-0");
needsUpdate = true;
}
}
@@ -74,7 +74,7 @@
// Pour les scènes, vérifier background.src et les tokens
if (doc.documentName === "Scene") {
if (doc.background?.src && doc.background.src.includes("fvtt-hawkmoon-cyd")) {
- updateData["background.src"] = doc.background.src.replace(/fvtt-hawkmoon-cyd/g, "fvtt-mournblade-cyd2");
+ updateData["background.src"] = doc.background.src.replace(/fvtt-hawkmoon-cyd/g, "fvtt-mournblade-cyd-2-0");
needsUpdate = true;
}
}
diff --git a/modules/mournblade-cyd2-actor-sheet.js b/modules/mournblade-cyd2-actor-sheet.js
index f4385fc..296bd32 100644
--- a/modules/mournblade-cyd2-actor-sheet.js
+++ b/modules/mournblade-cyd2-actor-sheet.js
@@ -13,8 +13,8 @@ export class MournbladeCYD2ActorSheet extends foundry.appv1.sheets.ActorSheet {
static get defaultOptions() {
return foundry.utils.mergeObject(super.defaultOptions, {
- classes: ["fvtt-mournblade-cyd2", "sheet", "actor"],
- template: "systems/fvtt-mournblade-cyd2/templates/actor-sheet.hbs",
+ classes: ["fvtt-mournblade-cyd-2-0", "sheet", "actor"],
+ template: "systems/fvtt-mournblade-cyd-2-0/templates/actor-sheet.hbs",
width: 640,
height: 720,
tabs: [{ navSelector: ".sheet-tabs", contentSelector: ".sheet-body", initial: "stats" }],
diff --git a/modules/mournblade-cyd2-actor.js b/modules/mournblade-cyd2-actor.js
index 2bf1453..78247ca 100644
--- a/modules/mournblade-cyd2-actor.js
+++ b/modules/mournblade-cyd2-actor.js
@@ -39,14 +39,14 @@ export class MournbladeCYD2Actor extends Actor {
if (data.type == 'personnage') {
console.log("Loading skills for personnage")
- const skills = await MournbladeCYD2Utility.loadCompendium("fvtt-mournblade-cyd2.skills")
+ const skills = await MournbladeCYD2Utility.loadCompendium("fvtt-mournblade-cyd-2-0.skills")
data.items = skills.map(i => i.toObject())
}
if (data.type == 'creature') {
- const skills = await MournbladeCYD2Utility.loadCompendium("fvtt-mournblade-cyd2.skills-creatures")
+ const skills = await MournbladeCYD2Utility.loadCompendium("fvtt-mournblade-cyd-2-0.skills-creatures")
data.items = skills.map(i => i.toObject())
- data.items.push({ name: "Arme naturelle 1", type: 'arme', img: "systems/fvtt-mournblade-cyd2/assets/icons/melee.webp", system: { typearme: "contact", bonusmaniementoff: 0, seuildefense: 0, degats: "0" } })
- data.items.push({ name: "Arme naturelle 2", type: 'arme', img: "systems/fvtt-mournblade-cyd2/assets/icons/melee.webp", system: { typearme: "contact", bonusmaniementoff: 0, seuildefense: 0, degats: "0" } })
+ data.items.push({ name: "Arme naturelle 1", type: 'arme', img: "systems/fvtt-mournblade-cyd-2-0/assets/icons/melee.webp", system: { typearme: "contact", bonusmaniementoff: 0, seuildefense: 0, degats: "0" } })
+ data.items.push({ name: "Arme naturelle 2", type: 'arme', img: "systems/fvtt-mournblade-cyd-2-0/assets/icons/melee.webp", system: { typearme: "contact", bonusmaniementoff: 0, seuildefense: 0, degats: "0" } })
}
return super.create(data, options);
@@ -246,9 +246,6 @@ export class MournbladeCYD2Actor extends Actor {
return combat
}
- /* -------------------------------------------- */
- prepareBaseData() {
- }
/* -------------------------------------------- */
async prepareData() {
@@ -751,7 +748,7 @@ export class MournbladeCYD2Actor extends Actor {
if (attrKey) {
rollData.attrKey = attrKey
if (attrKey != "tochoose") {
- rollData.actionImg = "systems/fvtt-mournblade-cyd2/assets/icons/" + this.system.attributs[attrKey].labelnorm + ".webp"
+ rollData.actionImg = "systems/fvtt-mournblade-cyd-2-0/assets/icons/" + this.system.attributs[attrKey].labelnorm + ".webp"
rollData.attr = foundry.utils.duplicate(this.system.attributs[attrKey])
}
}
@@ -779,8 +776,7 @@ export class MournbladeCYD2Actor extends Actor {
let rollData = this.getCommonRollData(attrKey)
rollData.multiplier = (isInit) ? 1 : 2
rollData.isInit = isInit
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
+ await MournbladeCYD2RollDialog.create(this, rollData)
}
/* -------------------------------------------- */
@@ -788,8 +784,7 @@ export class MournbladeCYD2Actor extends Actor {
let rollData = this.getCommonRollData(attrKey, compId)
rollData.multiplier = 1 // Attr multiplier, always 1 in competence mode
console.log("RollDatra", rollData)
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
+ await MournbladeCYD2RollDialog.create(this, rollData)
}
/* -------------------------------------------- */
@@ -802,8 +797,7 @@ export class MournbladeCYD2Actor extends Actor {
rollData.arme = arme
MournbladeCYD2Utility.updateWithTarget(rollData)
console.log("ARME!", rollData)
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
+ await MournbladeCYD2RollDialog.create(this, rollData)
}
/* -------------------------------------------- */
async rollAssommer() {
@@ -811,8 +805,7 @@ export class MournbladeCYD2Actor extends Actor {
rollData.assomer = true
rollData.conditionsCommunes = true
MournbladeCYD2Utility.updateWithTarget(rollData)
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
+ await MournbladeCYD2RollDialog.create(this, rollData)
}
/* -------------------------------------------- */
async rollCoupBas() {
@@ -820,8 +813,7 @@ export class MournbladeCYD2Actor extends Actor {
rollData.coupBas = true
rollData.conditionsCommunes = true
MournbladeCYD2Utility.updateWithTarget(rollData)
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
+ await MournbladeCYD2RollDialog.create(this, rollData)
}
/* -------------------------------------------- */
async rollImmobiliser() {
@@ -830,8 +822,7 @@ export class MournbladeCYD2Actor extends Actor {
rollData.conditionsCommunes = true
rollData.cibleconsciente = true
MournbladeCYD2Utility.updateWithTarget(rollData)
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
+ await MournbladeCYD2RollDialog.create(this, rollData)
}
/* -------------------------------------------- */
async rollRepousser() {
@@ -840,8 +831,7 @@ export class MournbladeCYD2Actor extends Actor {
rollData.conditionsCommunes = true
rollData.cibleconsciente = true
MournbladeCYD2Utility.updateWithTarget(rollData)
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
+ await MournbladeCYD2RollDialog.create(this, rollData)
}
/* -------------------------------------------- */
async rollDesengager() {
@@ -849,8 +839,7 @@ export class MournbladeCYD2Actor extends Actor {
rollData.desengager = true
rollData.conditionsCommunes = true
MournbladeCYD2Utility.updateWithTarget(rollData)
- let rollDialog = await MournbladeCYD2RollDialog.create(this, rollData)
- rollDialog.render(true)
+ await MournbladeCYD2RollDialog.create(this, rollData)
}
/* -------------------------------------------- */
@@ -908,7 +897,7 @@ export class MournbladeCYD2Actor extends Actor {
nbEtatPerdus: nbEtatPerdus
}
MournbladeCYD2Utility.createChatWithRollMode(rollData.alias, {
- content: await renderTemplate(`systems/fvtt-mournblade-cyd2/templates/chat-degats-result.hbs`, rollData)
+ content: await renderTemplate(`systems/fvtt-mournblade-cyd-2-0/templates/chat-degats-result.hbs`, rollData)
})
if (rollDataInput?.defenderTokenId && nbEtatPerdus) {
diff --git a/modules/mournblade-cyd2-config.js b/modules/mournblade-cyd2-config.js
index ff95f8b..e62a721 100644
--- a/modules/mournblade-cyd2-config.js
+++ b/modules/mournblade-cyd2-config.js
@@ -1,4 +1,11 @@
export const MOURNBLADECYD2_CONFIG = {
+ attributs: {
+ adr: "Adresse",
+ pui: "Puissance",
+ cla: "Clairvoyance",
+ pre: "Présence",
+ tre: "Trempe"
+ },
allegeanceOptions: {
tous: 'Tous',
chaos: 'Chaos',
diff --git a/modules/mournblade-cyd2-creature-sheet.js b/modules/mournblade-cyd2-creature-sheet.js
index 8edcd5e..e3fcd2d 100644
--- a/modules/mournblade-cyd2-creature-sheet.js
+++ b/modules/mournblade-cyd2-creature-sheet.js
@@ -14,8 +14,8 @@ export class MournbladeCYD2CreatureSheet extends MournbladeCYD2ActorSheet {
static get defaultOptions() {
return foundry.utils.mergeObject(super.defaultOptions, {
- classes: ["fvtt-mournblade-cyd2", "sheet", "actor"],
- template: "systems/fvtt-mournblade-cyd2/templates/creature-sheet.hbs",
+ classes: ["fvtt-mournblade-cyd-2-0", "sheet", "actor"],
+ template: "systems/fvtt-mournblade-cyd-2-0/templates/creature-sheet.hbs",
width: 640,
height: 720,
tabs: [{ navSelector: ".sheet-tabs", contentSelector: ".sheet-body", initial: "stats" }],
diff --git a/modules/mournblade-cyd2-hud.js b/modules/mournblade-cyd2-hud.js
index 815203b..a7c6bf4 100644
--- a/modules/mournblade-cyd2-hud.js
+++ b/modules/mournblade-cyd2-hud.js
@@ -24,7 +24,7 @@ export class MournbladeCYD2TokenHud {
const controlIconActions = $(html).find('.control-icon[data-action=combat]');
// initiative
- await MournbladeCYD2TokenHud._configureSubMenu(controlIconActions, 'systems/fvtt-mournblade-cyd2/templates/hud-adversites.hbs', hudData,
+ await MournbladeCYD2TokenHud._configureSubMenu(controlIconActions, 'systems/fvtt-mournblade-cyd-2-0/templates/hud-adversites.hbs', hudData,
(event) => {
let adversite = event.currentTarget.attributes['data-action-index'].value
let value = Number(event.currentTarget.attributes['data-action-value'].value)
diff --git a/modules/mournblade-cyd2-item-sheet.js b/modules/mournblade-cyd2-item-sheet.js
index 59071f2..b60967b 100644
--- a/modules/mournblade-cyd2-item-sheet.js
+++ b/modules/mournblade-cyd2-item-sheet.js
@@ -10,8 +10,8 @@ export class MournbladeCYD2ItemSheet extends foundry.appv1.sheets.ItemSheet {
static get defaultOptions() {
return foundry.utils.mergeObject(super.defaultOptions, {
- classes: ["fvtt-mournblade-cyd2", "sheet", "item"],
- template: "systems/fvtt-mournblade-cyd2/templates/item-sheet.hbs",
+ classes: ["fvtt-mournblade-cyd-2-0", "sheet", "item"],
+ template: "systems/fvtt-mournblade-cyd-2-0/templates/item-sheet.hbs",
dragDrop: [{ dragSelector: null, dropSelector: null }],
width: 620,
height: 550,
@@ -105,7 +105,7 @@ export class MournbladeCYD2ItemSheet extends foundry.appv1.sheets.ItemSheet {
payload: chatData,
});
- renderTemplate('systems/fvtt-mournblade-cyd2/templates/post-item.hbs', chatData).then(html => {
+ renderTemplate('systems/fvtt-mournblade-cyd-2-0/templates/post-item.hbs', chatData).then(html => {
let chatOptions = MournbladeCYD2Utility.chatDataSetup(html);
ChatMessage.create(chatOptions)
});
@@ -217,7 +217,7 @@ export class MournbladeCYD2ItemSheet extends foundry.appv1.sheets.ItemSheet {
/* -------------------------------------------- */
get template() {
let type = this.item.type;
- return `systems/fvtt-mournblade-cyd2/templates/item-${type}-sheet.hbs`;
+ return `systems/fvtt-mournblade-cyd-2-0/templates/item-${type}-sheet.hbs`;
}
/* -------------------------------------------- */
diff --git a/modules/mournblade-cyd2-item.js b/modules/mournblade-cyd2-item.js
index 97fab6d..537fd5b 100644
--- a/modules/mournblade-cyd2-item.js
+++ b/modules/mournblade-cyd2-item.js
@@ -1,22 +1,22 @@
import { MournbladeCYD2Utility } from "./mournblade-cyd2-utility.js";
export const defaultItemImg = {
- competence: "systems/fvtt-mournblade-cyd2/assets/icons/competence.webp",
- arme: "systems/fvtt-mournblade-cyd2/assets/icons/melee.webp",
- equipement: "systems/fvtt-mournblade-cyd2/assets/icons/equipement.webp",
- monnaie: "systems/fvtt-mournblade-cyd2/assets/icons/monnaie.webp",
- predilection: "systems/fvtt-mournblade-cyd2/assets/icons/predilection.webp",
- protection: "systems/fvtt-mournblade-cyd2/assets/icons/protection.webp",
- talent: "systems/fvtt-mournblade-cyd2/assets/icons/talent.webp",
- historique: "systems/fvtt-mournblade-cyd2/assets/icons/historique.webp",
- profil: "systems/fvtt-mournblade-cyd2/assets/icons/profil.webp",
- ressource: "systems/fvtt-mournblade-cyd2/assets/icons/ressources.webp",
- traitchaotique: "systems/fvtt-mournblade-cyd2/assets/icons/traitchaotique.webp",
- traitespece: "systems/fvtt-mournblade-cyd2/assets/icons/traitespece.webp",
- don: "systems/fvtt-mournblade-cyd2/assets/icons/don.webp",
- pacte: "systems/fvtt-mournblade-cyd2/assets/icons/pacte.webp",
- rune: "systems/fvtt-mournblade-cyd2/assets/icons/rune.webp",
- tendance: "systems/fvtt-mournblade-cyd2/assets/icons/tendance.webp",
+ competence: "systems/fvtt-mournblade-cyd-2-0/assets/icons/competence.webp",
+ arme: "systems/fvtt-mournblade-cyd-2-0/assets/icons/melee.webp",
+ equipement: "systems/fvtt-mournblade-cyd-2-0/assets/icons/equipement.webp",
+ monnaie: "systems/fvtt-mournblade-cyd-2-0/assets/icons/monnaie.webp",
+ predilection: "systems/fvtt-mournblade-cyd-2-0/assets/icons/predilection.webp",
+ protection: "systems/fvtt-mournblade-cyd-2-0/assets/icons/protection.webp",
+ talent: "systems/fvtt-mournblade-cyd-2-0/assets/icons/talent.webp",
+ historique: "systems/fvtt-mournblade-cyd-2-0/assets/icons/historique.webp",
+ profil: "systems/fvtt-mournblade-cyd-2-0/assets/icons/profil.webp",
+ ressource: "systems/fvtt-mournblade-cyd-2-0/assets/icons/ressources.webp",
+ traitchaotique: "systems/fvtt-mournblade-cyd-2-0/assets/icons/traitchaotique.webp",
+ traitespece: "systems/fvtt-mournblade-cyd-2-0/assets/icons/traitespece.webp",
+ don: "systems/fvtt-mournblade-cyd-2-0/assets/icons/don.webp",
+ pacte: "systems/fvtt-mournblade-cyd-2-0/assets/icons/pacte.webp",
+ rune: "systems/fvtt-mournblade-cyd-2-0/assets/icons/rune.webp",
+ tendance: "systems/fvtt-mournblade-cyd-2-0/assets/icons/tendance.webp",
}
/**
diff --git a/modules/mournblade-cyd2-main.js b/modules/mournblade-cyd2-main.js
index b604f07..920a1c2 100644
--- a/modules/mournblade-cyd2-main.js
+++ b/modules/mournblade-cyd2-main.js
@@ -40,7 +40,7 @@ Hooks.once("init", async function () {
};
/* -------------------------------------------- */
- game.socket.on("system.fvtt-mournblade-cyd2", data => {
+ game.socket.on("system.fvtt-mournblade-cyd-2-0", data => {
MournbladeCYD2Utility.onSocketMesssage(data)
});
@@ -79,26 +79,26 @@ Hooks.once("init", async function () {
// Register sheet application classes (AppV2)
foundry.documents.collections.Actors.unregisterSheet("core", foundry.appv1.sheets.ActorSheet);
- foundry.documents.collections.Actors.registerSheet("fvtt-mournblade-cyd2", sheets.MournbladeCYD2PersonnageSheet, { types: ["personnage"], makeDefault: true });
- foundry.documents.collections.Actors.registerSheet("fvtt-mournblade-cyd2", sheets.MournbladeCYD2CreatureSheet, { types: ["creature"], makeDefault: true });
+ foundry.documents.collections.Actors.registerSheet("fvtt-mournblade-cyd-2-0", sheets.MournbladeCYD2PersonnageSheet, { types: ["personnage"], makeDefault: true });
+ foundry.documents.collections.Actors.registerSheet("fvtt-mournblade-cyd-2-0", sheets.MournbladeCYD2CreatureSheet, { types: ["creature"], makeDefault: true });
foundry.documents.collections.Items.unregisterSheet("core", foundry.appv1.sheets.ItemSheet);
- foundry.documents.collections.Items.registerSheet("fvtt-mournblade-cyd2", sheets.MournbladeCYD2CompetenceSheet, { types: ["competence"], makeDefault: true });
- foundry.documents.collections.Items.registerSheet("fvtt-mournblade-cyd2", sheets.MournbladeCYD2TalentSheet, { types: ["talent"], makeDefault: true });
- foundry.documents.collections.Items.registerSheet("fvtt-mournblade-cyd2", sheets.MournbladeCYD2HistoriqueSheet, { types: ["historique"], makeDefault: true });
- foundry.documents.collections.Items.registerSheet("fvtt-mournblade-cyd2", sheets.MournbladeCYD2ProfilSheet, { types: ["profil"], makeDefault: true });
- foundry.documents.collections.Items.registerSheet("fvtt-mournblade-cyd2", sheets.MournbladeCYD2ArmeSheet, { types: ["arme"], makeDefault: true });
- foundry.documents.collections.Items.registerSheet("fvtt-mournblade-cyd2", sheets.MournbladeCYD2ProtectionSheet, { types: ["protection"], makeDefault: true });
- foundry.documents.collections.Items.registerSheet("fvtt-mournblade-cyd2", sheets.MournbladeCYD2MonnaieSheet, { types: ["monnaie"], makeDefault: true });
- foundry.documents.collections.Items.registerSheet("fvtt-mournblade-cyd2", sheets.MournbladeCYD2EquipementSheet, { types: ["equipement"], makeDefault: true });
- foundry.documents.collections.Items.registerSheet("fvtt-mournblade-cyd2", sheets.MournbladeCYD2RessourceSheet, { types: ["ressource"], makeDefault: true });
- foundry.documents.collections.Items.registerSheet("fvtt-mournblade-cyd2", sheets.MournbladeCYD2DonSheet, { types: ["don"], makeDefault: true });
- foundry.documents.collections.Items.registerSheet("fvtt-mournblade-cyd2", sheets.MournbladeCYD2PacteSheet, { types: ["pacte"], makeDefault: true });
- foundry.documents.collections.Items.registerSheet("fvtt-mournblade-cyd2", sheets.MournbladeCYD2RuneSheet, { types: ["rune"], makeDefault: true });
- foundry.documents.collections.Items.registerSheet("fvtt-mournblade-cyd2", sheets.MournbladeCYD2RuneEffectSheet, { types: ["runeeffect"], makeDefault: true });
- foundry.documents.collections.Items.registerSheet("fvtt-mournblade-cyd2", sheets.MournbladeCYD2TendanceSheet, { types: ["tendance"], makeDefault: true });
- foundry.documents.collections.Items.registerSheet("fvtt-mournblade-cyd2", sheets.MournbladeCYD2TraitChaotiqueSheet, { types: ["traitchaotique"], makeDefault: true });
- foundry.documents.collections.Items.registerSheet("fvtt-mournblade-cyd2", sheets.MournbladeCYD2TraitEspeceSheet, { types: ["traitespece"], makeDefault: true });
+ foundry.documents.collections.Items.registerSheet("fvtt-mournblade-cyd-2-0", sheets.MournbladeCYD2CompetenceSheet, { types: ["competence"], makeDefault: true });
+ foundry.documents.collections.Items.registerSheet("fvtt-mournblade-cyd-2-0", sheets.MournbladeCYD2TalentSheet, { types: ["talent"], makeDefault: true });
+ foundry.documents.collections.Items.registerSheet("fvtt-mournblade-cyd-2-0", sheets.MournbladeCYD2HistoriqueSheet, { types: ["historique"], makeDefault: true });
+ foundry.documents.collections.Items.registerSheet("fvtt-mournblade-cyd-2-0", sheets.MournbladeCYD2ProfilSheet, { types: ["profil"], makeDefault: true });
+ foundry.documents.collections.Items.registerSheet("fvtt-mournblade-cyd-2-0", sheets.MournbladeCYD2ArmeSheet, { types: ["arme"], makeDefault: true });
+ foundry.documents.collections.Items.registerSheet("fvtt-mournblade-cyd-2-0", sheets.MournbladeCYD2ProtectionSheet, { types: ["protection"], makeDefault: true });
+ foundry.documents.collections.Items.registerSheet("fvtt-mournblade-cyd-2-0", sheets.MournbladeCYD2MonnaieSheet, { types: ["monnaie"], makeDefault: true });
+ foundry.documents.collections.Items.registerSheet("fvtt-mournblade-cyd-2-0", sheets.MournbladeCYD2EquipementSheet, { types: ["equipement"], makeDefault: true });
+ foundry.documents.collections.Items.registerSheet("fvtt-mournblade-cyd-2-0", sheets.MournbladeCYD2RessourceSheet, { types: ["ressource"], makeDefault: true });
+ foundry.documents.collections.Items.registerSheet("fvtt-mournblade-cyd-2-0", sheets.MournbladeCYD2DonSheet, { types: ["don"], makeDefault: true });
+ foundry.documents.collections.Items.registerSheet("fvtt-mournblade-cyd-2-0", sheets.MournbladeCYD2PacteSheet, { types: ["pacte"], makeDefault: true });
+ foundry.documents.collections.Items.registerSheet("fvtt-mournblade-cyd-2-0", sheets.MournbladeCYD2RuneSheet, { types: ["rune"], makeDefault: true });
+ foundry.documents.collections.Items.registerSheet("fvtt-mournblade-cyd-2-0", sheets.MournbladeCYD2RuneEffectSheet, { types: ["runeeffect"], makeDefault: true });
+ foundry.documents.collections.Items.registerSheet("fvtt-mournblade-cyd-2-0", sheets.MournbladeCYD2TendanceSheet, { types: ["tendance"], makeDefault: true });
+ foundry.documents.collections.Items.registerSheet("fvtt-mournblade-cyd-2-0", sheets.MournbladeCYD2TraitChaotiqueSheet, { types: ["traitchaotique"], makeDefault: true });
+ foundry.documents.collections.Items.registerSheet("fvtt-mournblade-cyd-2-0", sheets.MournbladeCYD2TraitEspeceSheet, { types: ["traitespece"], makeDefault: true });
MournbladeCYD2Utility.init()
MournbladeCYD2Automation.init()
@@ -123,7 +123,7 @@ function welcomeMessage() {
async function importDefaultScene() {
let exists = game.scenes.find(j => j.name == "Accueil");
if (!exists) {
- const scenes = await MournbladeCYD2Utility.loadCompendium("fvtt-mournblade-cyd2.scenes")
+ const scenes = await MournbladeCYD2Utility.loadCompendium("fvtt-mournblade-cyd-2-0.scenes")
let newDocuments = scenes.filter(i => i.name == "Accueil");
if (newDocuments) {
await game.scenes.documentClass.create(newDocuments);
diff --git a/modules/mournblade-cyd2-roll-dialog.js b/modules/mournblade-cyd2-roll-dialog.js
index 6ac2d72..10015c5 100644
--- a/modules/mournblade-cyd2-roll-dialog.js
+++ b/modules/mournblade-cyd2-roll-dialog.js
@@ -6,7 +6,7 @@ export class MournbladeCYD2RollDialog extends Dialog {
static async create(actor, rollData ) {
let options = { classes: ["MournbladeCYD2Dialog"], width: 320, height: 'fit-content', 'z-index': 99999 };
- let html = await foundry.applications.handlebars.renderTemplate('systems/fvtt-mournblade-cyd2/templates/roll-dialog-generic.hbs', rollData);
+ let html = await foundry.applications.handlebars.renderTemplate('systems/fvtt-mournblade-cyd-2-0/templates/roll-dialog-generic.hbs', rollData);
return new MournbladeCYD2RollDialog(actor, rollData, html, options );
}
diff --git a/modules/mournblade-cyd2-utility.js b/modules/mournblade-cyd2-utility.js
index cf232c0..d3ae838 100644
--- a/modules/mournblade-cyd2-utility.js
+++ b/modules/mournblade-cyd2-utility.js
@@ -47,7 +47,7 @@ export class MournbladeCYD2Utility {
return parseInt(a) * parseInt(b);
})
- game.settings.register("fvtt-mournblade-cyd2", "mournblade-cyd2-pause-logo", {
+ game.settings.register("fvtt-mournblade-cyd-2-0", "mournblade-cyd2-pause-logo", {
name: "Logo de pause",
scope: "world",
config: true,
@@ -60,6 +60,10 @@ export class MournbladeCYD2Utility {
},
})
+ // Initialise les listes de sélection dès le hook init (avant le rendu des fiches)
+ game.system.mournbladecyd2.config.listeNiveauSkill = this.createDirectOptionList(0, 10)
+ game.system.mournbladecyd2.config.listeNiveauCreature = this.createDirectOptionList(0, 35)
+
}
/* -------------------------------------------- */
@@ -102,16 +106,13 @@ export class MournbladeCYD2Utility {
/* -------------------------------------------- */
static async ready() {
- const skills = await MournbladeCYD2Utility.loadCompendium("fvtt-mournblade-cyd2.skills")
+ const skills = await MournbladeCYD2Utility.loadCompendium("fvtt-mournblade-cyd-2-0.skills")
this.skills = skills.map(i => i.toObject())
// Setup pause logo
- let logoPause = "systems/fvtt-mournblade-cyd2/assets/logos/" + game.settings.get("fvtt-mournblade-cyd2", "mournblade-cyd2-pause-logo") + ".webp"
+ let logoPause = "systems/fvtt-mournblade-cyd-2-0/assets/logos/" + game.settings.get("fvtt-mournblade-cyd-2-0", "mournblade-cyd2-pause-logo") + ".webp"
let logoImg = document.querySelector('#pause').children[0]
logoImg.setAttribute('style', `content: url(${logoPause})`)
-
- game.system.mournbladecyd2.config.listeNiveauSkill = this.createDirectOptionList(0, 10)
- game.system.mournbladecyd2.config.listeNiveauCreature = this.createDirectOptionList(0, 35)
}
/* -------------------------------------------- */
@@ -182,13 +183,13 @@ export class MournbladeCYD2Utility {
static async preloadHandlebarsTemplates() {
const templatePaths = [
- 'systems/fvtt-mournblade-cyd2/templates/editor-notes-gm.hbs',
- 'systems/fvtt-mournblade-cyd2/templates/partial-item-header.hbs',
- 'systems/fvtt-mournblade-cyd2/templates/partial-item-description.hbs',
- 'systems/fvtt-mournblade-cyd2/templates/partial-item-nav.hbs',
- 'systems/fvtt-mournblade-cyd2/templates/partial-item-prix.hbs',
- 'systems/fvtt-mournblade-cyd2/templates/partial-automation.hbs',
- 'systems/fvtt-mournblade-cyd2/templates/hud-adversites.hbs',
+ 'systems/fvtt-mournblade-cyd-2-0/templates/editor-notes-gm.hbs',
+ 'systems/fvtt-mournblade-cyd-2-0/templates/partial-item-header.hbs',
+ 'systems/fvtt-mournblade-cyd-2-0/templates/partial-item-description.hbs',
+ 'systems/fvtt-mournblade-cyd-2-0/templates/partial-item-nav.hbs',
+ 'systems/fvtt-mournblade-cyd-2-0/templates/partial-item-prix.hbs',
+ 'systems/fvtt-mournblade-cyd-2-0/templates/partial-automation.hbs',
+ 'systems/fvtt-mournblade-cyd-2-0/templates/hud-adversites.hbs',
]
return foundry.applications.handlebars.loadTemplates(templatePaths);
}
@@ -372,7 +373,7 @@ export class MournbladeCYD2Utility {
let defender = game.canvas.tokens.get(rollData.defenderTokenId).actor
defender.changeEtatCombativite(value)
} else {
- game.socket.emit("system.fvtt-mournblade-cyd2", { msg: "msg_apply_combativite", data: { defenderTokenId: rollData.defenderTokenId, value } });
+ game.socket.emit("system.fvtt-mournblade-cyd-2-0", { msg: "msg_apply_combativite", data: { defenderTokenId: rollData.defenderTokenId, value } });
}
}
/* -------------------------------------------- */
@@ -383,7 +384,7 @@ export class MournbladeCYD2Utility {
rollData.attrKey = "adr"
}
if (!rollData.attr) {
- rollData.actionImg = "systems/fvtt-mournblade-cyd2/assets/icons/" + actor.system.attributs[rollData.attrKey].labelnorm + ".webp"
+ rollData.actionImg = "systems/fvtt-mournblade-cyd-2-0/assets/icons/" + actor.system.attributs[rollData.attrKey].labelnorm + ".webp"
rollData.attr = foundry.utils.duplicate(actor.system.attributs[rollData.attrKey])
}
if (rollData.attrKey2 != "none") {
@@ -503,7 +504,7 @@ export class MournbladeCYD2Utility {
}
this.createChatWithRollMode(rollData.alias, {
- content: await foundry.applications.handlebars.renderTemplate(`systems/fvtt-mournblade-cyd2/templates/chat-generic-result.hbs`, rollData)
+ content: await foundry.applications.handlebars.renderTemplate(`systems/fvtt-mournblade-cyd-2-0/templates/chat-generic-result.hbs`, rollData)
}, rollData)
if ((rollData.coupBas || rollData.arme) && rollData.isSuccess && rollData.defenderTokenId) {
@@ -610,7 +611,7 @@ export class MournbladeCYD2Utility {
this.computeResultQuality(rollData)
this.createChatWithRollMode(rollData.alias, {
- content: await foundry.applications.handlebars.renderTemplate(`systems/fvtt-mournblade-cyd2/templates/chat-generic-result.hbs`, rollData)
+ content: await foundry.applications.handlebars.renderTemplate(`systems/fvtt-mournblade-cyd-2-0/templates/chat-generic-result.hbs`, rollData)
}, rollData)
}
@@ -641,7 +642,7 @@ export class MournbladeCYD2Utility {
chatGM.whisper = this.getUsers(user => user.isGM);
chatGM.content = "Blinde message of " + game.user.name + "
" + chatOptions.content;
console.log("blindMessageToGM", chatGM);
- game.socket.emit("system.fvtt-mournblade-cyd2", { msg: "msg_gm_chat_message", data: chatGM });
+ game.socket.emit("system.fvtt-mournblade-cyd-2-0", { msg: "msg_gm_chat_message", data: chatGM });
}
/* -------------------------------------------- */
diff --git a/package.json b/package.json
index d688130..5e8ad67 100644
--- a/package.json
+++ b/package.json
@@ -1,5 +1,5 @@
{
- "name": "fvtt-mournblade-cyd2",
+ "name": "fvtt-mournblade-cyd-2-0",
"version": "2.0.0",
"description": "Mournblade CYD 2.0 RPG for FoundryVTT - French",
"scripts": {
diff --git a/packs/aides-de-jeu/000378.log b/packs/aides-de-jeu/000385.log
similarity index 100%
rename from packs/aides-de-jeu/000378.log
rename to packs/aides-de-jeu/000385.log
diff --git a/packs/aides-de-jeu/CURRENT b/packs/aides-de-jeu/CURRENT
index 561f1eb..70d8a3a 100644
--- a/packs/aides-de-jeu/CURRENT
+++ b/packs/aides-de-jeu/CURRENT
@@ -1 +1 @@
-MANIFEST-000376
+MANIFEST-000384
diff --git a/packs/aides-de-jeu/LOG b/packs/aides-de-jeu/LOG
index afe3f5c..06ea44c 100644
--- a/packs/aides-de-jeu/LOG
+++ b/packs/aides-de-jeu/LOG
@@ -1,8 +1,3 @@
-2025/10/26-14:44:35.773579 7f05877fe6c0 Recovering log #374
-2025/10/26-14:44:35.783336 7f05877fe6c0 Delete type=3 #372
-2025/10/26-14:44:35.783390 7f05877fe6c0 Delete type=0 #374
-2025/10/26-14:44:53.282449 7f0586bff6c0 Level-0 table #379: started
-2025/10/26-14:44:53.282474 7f0586bff6c0 Level-0 table #379: 0 bytes OK
-2025/10/26-14:44:53.288360 7f0586bff6c0 Delete type=0 #377
-2025/10/26-14:44:53.308451 7f0586bff6c0 Manual compaction at level-0 from '!journal!gVybbv17TFY8o3Y4' @ 72057594037927935 : 1 .. '!journal.pages!gVybbv17TFY8o3Y4.fQidyqfF1TbsZKHM' @ 0 : 0; will stop at (end)
-2025/10/26-14:44:53.308507 7f0586bff6c0 Manual compaction at level-1 from '!journal!gVybbv17TFY8o3Y4' @ 72057594037927935 : 1 .. '!journal.pages!gVybbv17TFY8o3Y4.fQidyqfF1TbsZKHM' @ 0 : 0; will stop at (end)
+2026/04/02-22:42:22.886542 7feec8bfd6c0 Recovering log #382
+2026/04/02-22:42:22.897444 7feec8bfd6c0 Delete type=3 #380
+2026/04/02-22:42:22.897515 7feec8bfd6c0 Delete type=0 #382
diff --git a/packs/aides-de-jeu/LOG.old b/packs/aides-de-jeu/LOG.old
index cbbd66e..88fa664 100644
--- a/packs/aides-de-jeu/LOG.old
+++ b/packs/aides-de-jeu/LOG.old
@@ -1,8 +1,8 @@
-2025/10/26-14:17:34.089807 7f058c9f96c0 Recovering log #370
-2025/10/26-14:17:34.150991 7f058c9f96c0 Delete type=3 #368
-2025/10/26-14:17:34.151050 7f058c9f96c0 Delete type=0 #370
-2025/10/26-14:43:50.641754 7f0586bff6c0 Level-0 table #375: started
-2025/10/26-14:43:50.641778 7f0586bff6c0 Level-0 table #375: 0 bytes OK
-2025/10/26-14:43:50.648553 7f0586bff6c0 Delete type=0 #373
-2025/10/26-14:43:50.648712 7f0586bff6c0 Manual compaction at level-0 from '!journal!gVybbv17TFY8o3Y4' @ 72057594037927935 : 1 .. '!journal.pages!gVybbv17TFY8o3Y4.fQidyqfF1TbsZKHM' @ 0 : 0; will stop at (end)
-2025/10/26-14:43:50.648735 7f0586bff6c0 Manual compaction at level-1 from '!journal!gVybbv17TFY8o3Y4' @ 72057594037927935 : 1 .. '!journal.pages!gVybbv17TFY8o3Y4.fQidyqfF1TbsZKHM' @ 0 : 0; will stop at (end)
+2026/04/02-22:23:11.995579 7feec93fe6c0 Recovering log #378
+2026/04/02-22:23:12.005529 7feec93fe6c0 Delete type=3 #376
+2026/04/02-22:23:12.005581 7feec93fe6c0 Delete type=0 #378
+2026/04/02-22:41:03.722884 7feeb37fe6c0 Level-0 table #383: started
+2026/04/02-22:41:03.722902 7feeb37fe6c0 Level-0 table #383: 0 bytes OK
+2026/04/02-22:41:03.728999 7feeb37fe6c0 Delete type=0 #381
+2026/04/02-22:41:03.736041 7feeb37fe6c0 Manual compaction at level-0 from '!journal!gVybbv17TFY8o3Y4' @ 72057594037927935 : 1 .. '!journal.pages!gVybbv17TFY8o3Y4.fQidyqfF1TbsZKHM' @ 0 : 0; will stop at (end)
+2026/04/02-22:41:03.745674 7feeb37fe6c0 Manual compaction at level-1 from '!journal!gVybbv17TFY8o3Y4' @ 72057594037927935 : 1 .. '!journal.pages!gVybbv17TFY8o3Y4.fQidyqfF1TbsZKHM' @ 0 : 0; will stop at (end)
diff --git a/packs/aides-de-jeu/MANIFEST-000376 b/packs/aides-de-jeu/MANIFEST-000384
similarity index 84%
rename from packs/aides-de-jeu/MANIFEST-000376
rename to packs/aides-de-jeu/MANIFEST-000384
index 6da865b..3e50fce 100644
Binary files a/packs/aides-de-jeu/MANIFEST-000376 and b/packs/aides-de-jeu/MANIFEST-000384 differ
diff --git a/packs/armes/000375.log b/packs/armes/000382.log
similarity index 100%
rename from packs/armes/000375.log
rename to packs/armes/000382.log
diff --git a/packs/armes/CURRENT b/packs/armes/CURRENT
index 1ca0e83..9a9c819 100644
--- a/packs/armes/CURRENT
+++ b/packs/armes/CURRENT
@@ -1 +1 @@
-MANIFEST-000373
+MANIFEST-000381
diff --git a/packs/armes/LOG b/packs/armes/LOG
index c369281..7cc49ea 100644
--- a/packs/armes/LOG
+++ b/packs/armes/LOG
@@ -1,9 +1,3 @@
-2025/10/26-14:44:35.634587 7f05877fe6c0 Recovering log #371
-2025/10/26-14:44:35.644088 7f05877fe6c0 Delete type=3 #367
-2025/10/26-14:44:35.644144 7f05877fe6c0 Delete type=3 #252
-2025/10/26-14:44:35.644177 7f05877fe6c0 Delete type=0 #371
-2025/10/26-14:44:53.218055 7f0586bff6c0 Level-0 table #376: started
-2025/10/26-14:44:53.218081 7f0586bff6c0 Level-0 table #376: 0 bytes OK
-2025/10/26-14:44:53.224298 7f0586bff6c0 Delete type=0 #374
-2025/10/26-14:44:53.231605 7f0586bff6c0 Manual compaction at level-0 from '!items!0swiE8k5zfUIqmXu' @ 72057594037927935 : 1 .. '!items!wv5EiePmPTpqFutt' @ 0 : 0; will stop at (end)
-2025/10/26-14:44:53.231650 7f0586bff6c0 Manual compaction at level-1 from '!items!0swiE8k5zfUIqmXu' @ 72057594037927935 : 1 .. '!items!wv5EiePmPTpqFutt' @ 0 : 0; will stop at (end)
+2026/04/02-22:42:22.751579 7feeb3fff6c0 Recovering log #379
+2026/04/02-22:42:22.761248 7feeb3fff6c0 Delete type=3 #377
+2026/04/02-22:42:22.761291 7feeb3fff6c0 Delete type=0 #379
diff --git a/packs/armes/LOG.old b/packs/armes/LOG.old
index 36e80d3..1c1ad4e 100644
--- a/packs/armes/LOG.old
+++ b/packs/armes/LOG.old
@@ -1,11 +1,8 @@
-2025/10/26-14:17:33.329160 7f0587fff6c0 Recovering log #250
-2025/10/26-14:17:33.329199 7f0587fff6c0 Recovering log #369
-2025/10/26-14:17:33.500980 7f0587fff6c0 Delete type=2 #352
-2025/10/26-14:17:33.501082 7f0587fff6c0 Delete type=0 #369
-2025/10/26-14:17:33.501136 7f0587fff6c0 Delete type=3 #248
-2025/10/26-14:17:33.501178 7f0587fff6c0 Delete type=0 #250
-2025/10/26-14:43:50.551774 7f0586bff6c0 Level-0 table #372: started
-2025/10/26-14:43:50.551804 7f0586bff6c0 Level-0 table #372: 0 bytes OK
-2025/10/26-14:43:50.557801 7f0586bff6c0 Delete type=0 #370
-2025/10/26-14:43:50.570810 7f0586bff6c0 Manual compaction at level-0 from '!items!0swiE8k5zfUIqmXu' @ 72057594037927935 : 1 .. '!items!wv5EiePmPTpqFutt' @ 0 : 0; will stop at (end)
-2025/10/26-14:43:50.570851 7f0586bff6c0 Manual compaction at level-1 from '!items!0swiE8k5zfUIqmXu' @ 72057594037927935 : 1 .. '!items!wv5EiePmPTpqFutt' @ 0 : 0; will stop at (end)
+2026/04/02-22:23:11.844533 7feec8bfd6c0 Recovering log #375
+2026/04/02-22:23:11.854182 7feec8bfd6c0 Delete type=3 #373
+2026/04/02-22:23:11.854243 7feec8bfd6c0 Delete type=0 #375
+2026/04/02-22:41:03.650062 7feeb37fe6c0 Level-0 table #380: started
+2026/04/02-22:41:03.650092 7feeb37fe6c0 Level-0 table #380: 0 bytes OK
+2026/04/02-22:41:03.656009 7feeb37fe6c0 Delete type=0 #378
+2026/04/02-22:41:03.656115 7feeb37fe6c0 Manual compaction at level-0 from '!items!0swiE8k5zfUIqmXu' @ 72057594037927935 : 1 .. '!items!wv5EiePmPTpqFutt' @ 0 : 0; will stop at (end)
+2026/04/02-22:41:03.656130 7feeb37fe6c0 Manual compaction at level-1 from '!items!0swiE8k5zfUIqmXu' @ 72057594037927935 : 1 .. '!items!wv5EiePmPTpqFutt' @ 0 : 0; will stop at (end)
diff --git a/packs/armes/MANIFEST-000373 b/packs/armes/MANIFEST-000381
similarity index 73%
rename from packs/armes/MANIFEST-000373
rename to packs/armes/MANIFEST-000381
index db0b7de..7c1b4d5 100644
Binary files a/packs/armes/MANIFEST-000373 and b/packs/armes/MANIFEST-000381 differ
diff --git a/packs/dons/000257.log b/packs/dons/000264.log
similarity index 100%
rename from packs/dons/000257.log
rename to packs/dons/000264.log
diff --git a/packs/dons/CURRENT b/packs/dons/CURRENT
index 380474a..45bcdf0 100644
--- a/packs/dons/CURRENT
+++ b/packs/dons/CURRENT
@@ -1 +1 @@
-MANIFEST-000255
+MANIFEST-000263
diff --git a/packs/dons/LOG b/packs/dons/LOG
index 17a7306..378062e 100644
--- a/packs/dons/LOG
+++ b/packs/dons/LOG
@@ -1,8 +1,3 @@
-2025/10/26-14:44:35.670450 7f05877fe6c0 Recovering log #253
-2025/10/26-14:44:35.680591 7f05877fe6c0 Delete type=3 #251
-2025/10/26-14:44:35.680668 7f05877fe6c0 Delete type=0 #253
-2025/10/26-14:44:53.250029 7f0586bff6c0 Level-0 table #258: started
-2025/10/26-14:44:53.250057 7f0586bff6c0 Level-0 table #258: 0 bytes OK
-2025/10/26-14:44:53.256904 7f0586bff6c0 Delete type=0 #256
-2025/10/26-14:44:53.257116 7f0586bff6c0 Manual compaction at level-0 from '!items!5dGXNiL3WN4cAk7X' @ 72057594037927935 : 1 .. '!items!zzz9JrtWjELdoAfK' @ 0 : 0; will stop at (end)
-2025/10/26-14:44:53.257149 7f0586bff6c0 Manual compaction at level-1 from '!items!5dGXNiL3WN4cAk7X' @ 72057594037927935 : 1 .. '!items!zzz9JrtWjELdoAfK' @ 0 : 0; will stop at (end)
+2026/04/02-22:42:22.787186 7feec8bfd6c0 Recovering log #261
+2026/04/02-22:42:22.797121 7feec8bfd6c0 Delete type=3 #259
+2026/04/02-22:42:22.797203 7feec8bfd6c0 Delete type=0 #261
diff --git a/packs/dons/LOG.old b/packs/dons/LOG.old
index 513843c..e8a18e4 100644
--- a/packs/dons/LOG.old
+++ b/packs/dons/LOG.old
@@ -1,8 +1,8 @@
-2025/10/26-14:17:33.616386 7f05877fe6c0 Recovering log #249
-2025/10/26-14:17:33.676039 7f05877fe6c0 Delete type=3 #247
-2025/10/26-14:17:33.676103 7f05877fe6c0 Delete type=0 #249
-2025/10/26-14:43:50.589531 7f0586bff6c0 Level-0 table #254: started
-2025/10/26-14:43:50.589558 7f0586bff6c0 Level-0 table #254: 0 bytes OK
-2025/10/26-14:43:50.595890 7f0586bff6c0 Delete type=0 #252
-2025/10/26-14:43:50.596069 7f0586bff6c0 Manual compaction at level-0 from '!items!5dGXNiL3WN4cAk7X' @ 72057594037927935 : 1 .. '!items!zzz9JrtWjELdoAfK' @ 0 : 0; will stop at (end)
-2025/10/26-14:43:50.596098 7f0586bff6c0 Manual compaction at level-1 from '!items!5dGXNiL3WN4cAk7X' @ 72057594037927935 : 1 .. '!items!zzz9JrtWjELdoAfK' @ 0 : 0; will stop at (end)
+2026/04/02-22:23:11.881302 7feec93fe6c0 Recovering log #257
+2026/04/02-22:23:11.891971 7feec93fe6c0 Delete type=3 #255
+2026/04/02-22:23:11.892014 7feec93fe6c0 Delete type=0 #257
+2026/04/02-22:41:03.662117 7feeb37fe6c0 Level-0 table #262: started
+2026/04/02-22:41:03.662146 7feeb37fe6c0 Level-0 table #262: 0 bytes OK
+2026/04/02-22:41:03.668307 7feeb37fe6c0 Delete type=0 #260
+2026/04/02-22:41:03.680730 7feeb37fe6c0 Manual compaction at level-0 from '!items!5dGXNiL3WN4cAk7X' @ 72057594037927935 : 1 .. '!items!zzz9JrtWjELdoAfK' @ 0 : 0; will stop at (end)
+2026/04/02-22:41:03.680782 7feeb37fe6c0 Manual compaction at level-1 from '!items!5dGXNiL3WN4cAk7X' @ 72057594037927935 : 1 .. '!items!zzz9JrtWjELdoAfK' @ 0 : 0; will stop at (end)
diff --git a/packs/dons/MANIFEST-000255 b/packs/dons/MANIFEST-000263
similarity index 73%
rename from packs/dons/MANIFEST-000255
rename to packs/dons/MANIFEST-000263
index 54b14e5..8f4504f 100644
Binary files a/packs/dons/MANIFEST-000255 and b/packs/dons/MANIFEST-000263 differ
diff --git a/packs/equipement/000257.log b/packs/equipement/000264.log
similarity index 100%
rename from packs/equipement/000257.log
rename to packs/equipement/000264.log
diff --git a/packs/equipement/CURRENT b/packs/equipement/CURRENT
index 380474a..45bcdf0 100644
--- a/packs/equipement/CURRENT
+++ b/packs/equipement/CURRENT
@@ -1 +1 @@
-MANIFEST-000255
+MANIFEST-000263
diff --git a/packs/equipement/LOG b/packs/equipement/LOG
index a4bbeb1..fb93e61 100644
--- a/packs/equipement/LOG
+++ b/packs/equipement/LOG
@@ -1,8 +1,3 @@
-2025/10/26-14:44:35.658462 7f058d1fa6c0 Recovering log #253
-2025/10/26-14:44:35.668414 7f058d1fa6c0 Delete type=3 #251
-2025/10/26-14:44:35.668489 7f058d1fa6c0 Delete type=0 #253
-2025/10/26-14:44:53.237798 7f0586bff6c0 Level-0 table #258: started
-2025/10/26-14:44:53.237817 7f0586bff6c0 Level-0 table #258: 0 bytes OK
-2025/10/26-14:44:53.243746 7f0586bff6c0 Delete type=0 #256
-2025/10/26-14:44:53.257084 7f0586bff6c0 Manual compaction at level-0 from '!items!1cZd2hlTV9tykDED' @ 72057594037927935 : 1 .. '!items!y47dBO3Mf5Pn7tOd' @ 0 : 0; will stop at (end)
-2025/10/26-14:44:53.257137 7f0586bff6c0 Manual compaction at level-1 from '!items!1cZd2hlTV9tykDED' @ 72057594037927935 : 1 .. '!items!y47dBO3Mf5Pn7tOd' @ 0 : 0; will stop at (end)
+2026/04/02-22:42:22.774883 7feec93fe6c0 Recovering log #261
+2026/04/02-22:42:22.785249 7feec93fe6c0 Delete type=3 #259
+2026/04/02-22:42:22.785297 7feec93fe6c0 Delete type=0 #261
diff --git a/packs/equipement/LOG.old b/packs/equipement/LOG.old
index 999519c..99f5923 100644
--- a/packs/equipement/LOG.old
+++ b/packs/equipement/LOG.old
@@ -1,8 +1,8 @@
-2025/10/26-14:17:33.560253 7f058d1fa6c0 Recovering log #249
-2025/10/26-14:17:33.613553 7f058d1fa6c0 Delete type=3 #247
-2025/10/26-14:17:33.613627 7f058d1fa6c0 Delete type=0 #249
-2025/10/26-14:43:50.577372 7f0586bff6c0 Level-0 table #254: started
-2025/10/26-14:43:50.577440 7f0586bff6c0 Level-0 table #254: 0 bytes OK
-2025/10/26-14:43:50.583481 7f0586bff6c0 Delete type=0 #252
-2025/10/26-14:43:50.596035 7f0586bff6c0 Manual compaction at level-0 from '!items!1cZd2hlTV9tykDED' @ 72057594037927935 : 1 .. '!items!y47dBO3Mf5Pn7tOd' @ 0 : 0; will stop at (end)
-2025/10/26-14:43:50.596079 7f0586bff6c0 Manual compaction at level-1 from '!items!1cZd2hlTV9tykDED' @ 72057594037927935 : 1 .. '!items!y47dBO3Mf5Pn7tOd' @ 0 : 0; will stop at (end)
+2026/04/02-22:23:11.869572 7feec8bfd6c0 Recovering log #257
+2026/04/02-22:23:11.878854 7feec8bfd6c0 Delete type=3 #255
+2026/04/02-22:23:11.878924 7feec8bfd6c0 Delete type=0 #257
+2026/04/02-22:41:03.674670 7feeb37fe6c0 Level-0 table #262: started
+2026/04/02-22:41:03.674691 7feeb37fe6c0 Level-0 table #262: 0 bytes OK
+2026/04/02-22:41:03.680561 7feeb37fe6c0 Delete type=0 #260
+2026/04/02-22:41:03.680749 7feeb37fe6c0 Manual compaction at level-0 from '!items!1cZd2hlTV9tykDED' @ 72057594037927935 : 1 .. '!items!y47dBO3Mf5Pn7tOd' @ 0 : 0; will stop at (end)
+2026/04/02-22:41:03.680776 7feeb37fe6c0 Manual compaction at level-1 from '!items!1cZd2hlTV9tykDED' @ 72057594037927935 : 1 .. '!items!y47dBO3Mf5Pn7tOd' @ 0 : 0; will stop at (end)
diff --git a/packs/equipement/MANIFEST-000255 b/packs/equipement/MANIFEST-000263
similarity index 73%
rename from packs/equipement/MANIFEST-000255
rename to packs/equipement/MANIFEST-000263
index f41db3d..10c3971 100644
Binary files a/packs/equipement/MANIFEST-000255 and b/packs/equipement/MANIFEST-000263 differ
diff --git a/packs/historiques/000377.log b/packs/historiques/000384.log
similarity index 100%
rename from packs/historiques/000377.log
rename to packs/historiques/000384.log
diff --git a/packs/historiques/CURRENT b/packs/historiques/CURRENT
index 741abc7..25e3b7f 100644
--- a/packs/historiques/CURRENT
+++ b/packs/historiques/CURRENT
@@ -1 +1 @@
-MANIFEST-000375
+MANIFEST-000383
diff --git a/packs/historiques/LOG b/packs/historiques/LOG
index 705a706..78973e4 100644
--- a/packs/historiques/LOG
+++ b/packs/historiques/LOG
@@ -1,8 +1,3 @@
-2025/10/26-14:44:35.622083 7f0587fff6c0 Recovering log #373
-2025/10/26-14:44:35.632124 7f0587fff6c0 Delete type=3 #371
-2025/10/26-14:44:35.632194 7f0587fff6c0 Delete type=0 #373
-2025/10/26-14:44:53.205925 7f0586bff6c0 Level-0 table #378: started
-2025/10/26-14:44:53.205967 7f0586bff6c0 Level-0 table #378: 0 bytes OK
-2025/10/26-14:44:53.211891 7f0586bff6c0 Delete type=0 #376
-2025/10/26-14:44:53.231573 7f0586bff6c0 Manual compaction at level-0 from '!items!15foLG7y3LUXNzkK' @ 72057594037927935 : 1 .. '!items!z1HtkvazCGHut7cz' @ 0 : 0; will stop at (end)
-2025/10/26-14:44:53.231629 7f0586bff6c0 Manual compaction at level-1 from '!items!15foLG7y3LUXNzkK' @ 72057594037927935 : 1 .. '!items!z1HtkvazCGHut7cz' @ 0 : 0; will stop at (end)
+2026/04/02-22:42:22.739027 7feec8bfd6c0 Recovering log #381
+2026/04/02-22:42:22.749357 7feec8bfd6c0 Delete type=3 #379
+2026/04/02-22:42:22.749468 7feec8bfd6c0 Delete type=0 #381
diff --git a/packs/historiques/LOG.old b/packs/historiques/LOG.old
index 59724bb..7cbab3d 100644
--- a/packs/historiques/LOG.old
+++ b/packs/historiques/LOG.old
@@ -1,8 +1,8 @@
-2025/10/26-14:17:33.238795 7f058d1fa6c0 Recovering log #369
-2025/10/26-14:17:33.326213 7f058d1fa6c0 Delete type=3 #367
-2025/10/26-14:17:33.326289 7f058d1fa6c0 Delete type=0 #369
-2025/10/26-14:43:50.557940 7f0586bff6c0 Level-0 table #374: started
-2025/10/26-14:43:50.557971 7f0586bff6c0 Level-0 table #374: 0 bytes OK
-2025/10/26-14:43:50.563944 7f0586bff6c0 Delete type=0 #372
-2025/10/26-14:43:50.570822 7f0586bff6c0 Manual compaction at level-0 from '!items!15foLG7y3LUXNzkK' @ 72057594037927935 : 1 .. '!items!z1HtkvazCGHut7cz' @ 0 : 0; will stop at (end)
-2025/10/26-14:43:50.570858 7f0586bff6c0 Manual compaction at level-1 from '!items!15foLG7y3LUXNzkK' @ 72057594037927935 : 1 .. '!items!z1HtkvazCGHut7cz' @ 0 : 0; will stop at (end)
+2026/04/02-22:23:11.832014 7feec93fe6c0 Recovering log #377
+2026/04/02-22:23:11.841719 7feec93fe6c0 Delete type=3 #375
+2026/04/02-22:23:11.841777 7feec93fe6c0 Delete type=0 #377
+2026/04/02-22:41:03.636791 7feeb37fe6c0 Level-0 table #382: started
+2026/04/02-22:41:03.636818 7feeb37fe6c0 Level-0 table #382: 0 bytes OK
+2026/04/02-22:41:03.642955 7feeb37fe6c0 Delete type=0 #380
+2026/04/02-22:41:03.656101 7feeb37fe6c0 Manual compaction at level-0 from '!items!15foLG7y3LUXNzkK' @ 72057594037927935 : 1 .. '!items!z1HtkvazCGHut7cz' @ 0 : 0; will stop at (end)
+2026/04/02-22:41:03.656120 7feeb37fe6c0 Manual compaction at level-1 from '!items!15foLG7y3LUXNzkK' @ 72057594037927935 : 1 .. '!items!z1HtkvazCGHut7cz' @ 0 : 0; will stop at (end)
diff --git a/packs/historiques/MANIFEST-000375 b/packs/historiques/MANIFEST-000383
similarity index 72%
rename from packs/historiques/MANIFEST-000375
rename to packs/historiques/MANIFEST-000383
index 1edf243..a81aac4 100644
Binary files a/packs/historiques/MANIFEST-000375 and b/packs/historiques/MANIFEST-000383 differ
diff --git a/packs/profils/000377.log b/packs/profils/000384.log
similarity index 100%
rename from packs/profils/000377.log
rename to packs/profils/000384.log
diff --git a/packs/profils/CURRENT b/packs/profils/CURRENT
index 741abc7..25e3b7f 100644
--- a/packs/profils/CURRENT
+++ b/packs/profils/CURRENT
@@ -1 +1 @@
-MANIFEST-000375
+MANIFEST-000383
diff --git a/packs/profils/LOG b/packs/profils/LOG
index 8b05353..fefd735 100644
--- a/packs/profils/LOG
+++ b/packs/profils/LOG
@@ -1,8 +1,3 @@
-2025/10/26-14:44:35.721136 7f058c9f96c0 Recovering log #373
-2025/10/26-14:44:35.731166 7f058c9f96c0 Delete type=3 #371
-2025/10/26-14:44:35.731245 7f058c9f96c0 Delete type=0 #373
-2025/10/26-14:44:53.263565 7f0586bff6c0 Level-0 table #378: started
-2025/10/26-14:44:53.263592 7f0586bff6c0 Level-0 table #378: 0 bytes OK
-2025/10/26-14:44:53.269403 7f0586bff6c0 Delete type=0 #376
-2025/10/26-14:44:53.282273 7f0586bff6c0 Manual compaction at level-0 from '!items!26mRstKhCJoXkhu1' @ 72057594037927935 : 1 .. '!items!tFQqcxmkS3MT6ASE' @ 0 : 0; will stop at (end)
-2025/10/26-14:44:53.282328 7f0586bff6c0 Manual compaction at level-1 from '!items!26mRstKhCJoXkhu1' @ 72057594037927935 : 1 .. '!items!tFQqcxmkS3MT6ASE' @ 0 : 0; will stop at (end)
+2026/04/02-22:42:22.835807 7feec8bfd6c0 Recovering log #381
+2026/04/02-22:42:22.845258 7feec8bfd6c0 Delete type=3 #379
+2026/04/02-22:42:22.845300 7feec8bfd6c0 Delete type=0 #381
diff --git a/packs/profils/LOG.old b/packs/profils/LOG.old
index 74bce7e..b7a6f82 100644
--- a/packs/profils/LOG.old
+++ b/packs/profils/LOG.old
@@ -1,8 +1,8 @@
-2025/10/26-14:17:33.844186 7f058d1fa6c0 Recovering log #369
-2025/10/26-14:17:33.904254 7f058d1fa6c0 Delete type=3 #367
-2025/10/26-14:17:33.904322 7f058d1fa6c0 Delete type=0 #369
-2025/10/26-14:43:50.615369 7f0586bff6c0 Level-0 table #374: started
-2025/10/26-14:43:50.615397 7f0586bff6c0 Level-0 table #374: 0 bytes OK
-2025/10/26-14:43:50.621407 7f0586bff6c0 Delete type=0 #372
-2025/10/26-14:43:50.621524 7f0586bff6c0 Manual compaction at level-0 from '!items!26mRstKhCJoXkhu1' @ 72057594037927935 : 1 .. '!items!tFQqcxmkS3MT6ASE' @ 0 : 0; will stop at (end)
-2025/10/26-14:43:50.621543 7f0586bff6c0 Manual compaction at level-1 from '!items!26mRstKhCJoXkhu1' @ 72057594037927935 : 1 .. '!items!tFQqcxmkS3MT6ASE' @ 0 : 0; will stop at (end)
+2026/04/02-22:23:11.945566 7feec93fe6c0 Recovering log #377
+2026/04/02-22:23:11.954859 7feec93fe6c0 Delete type=3 #375
+2026/04/02-22:23:11.954911 7feec93fe6c0 Delete type=0 #377
+2026/04/02-22:41:03.686833 7feeb37fe6c0 Level-0 table #382: started
+2026/04/02-22:41:03.686856 7feeb37fe6c0 Level-0 table #382: 0 bytes OK
+2026/04/02-22:41:03.693649 7feeb37fe6c0 Delete type=0 #380
+2026/04/02-22:41:03.706286 7feeb37fe6c0 Manual compaction at level-0 from '!items!26mRstKhCJoXkhu1' @ 72057594037927935 : 1 .. '!items!tFQqcxmkS3MT6ASE' @ 0 : 0; will stop at (end)
+2026/04/02-22:41:03.706323 7feeb37fe6c0 Manual compaction at level-1 from '!items!26mRstKhCJoXkhu1' @ 72057594037927935 : 1 .. '!items!tFQqcxmkS3MT6ASE' @ 0 : 0; will stop at (end)
diff --git a/packs/profils/MANIFEST-000375 b/packs/profils/MANIFEST-000383
similarity index 73%
rename from packs/profils/MANIFEST-000375
rename to packs/profils/MANIFEST-000383
index f0543c8..16c85f2 100644
Binary files a/packs/profils/MANIFEST-000375 and b/packs/profils/MANIFEST-000383 differ
diff --git a/packs/protections/000257.log b/packs/protections/000264.log
similarity index 100%
rename from packs/protections/000257.log
rename to packs/protections/000264.log
diff --git a/packs/protections/CURRENT b/packs/protections/CURRENT
index 380474a..45bcdf0 100644
--- a/packs/protections/CURRENT
+++ b/packs/protections/CURRENT
@@ -1 +1 @@
-MANIFEST-000255
+MANIFEST-000263
diff --git a/packs/protections/LOG b/packs/protections/LOG
index 954f888..9ac80e5 100644
--- a/packs/protections/LOG
+++ b/packs/protections/LOG
@@ -1,8 +1,3 @@
-2025/10/26-14:44:35.646347 7f058c9f96c0 Recovering log #253
-2025/10/26-14:44:35.656365 7f058c9f96c0 Delete type=3 #251
-2025/10/26-14:44:35.656455 7f058c9f96c0 Delete type=0 #253
-2025/10/26-14:44:53.231745 7f0586bff6c0 Level-0 table #258: started
-2025/10/26-14:44:53.231785 7f0586bff6c0 Level-0 table #258: 0 bytes OK
-2025/10/26-14:44:53.237694 7f0586bff6c0 Delete type=0 #256
-2025/10/26-14:44:53.257064 7f0586bff6c0 Manual compaction at level-0 from '!items!2hD1DQVeCIQIXFU7' @ 72057594037927935 : 1 .. '!items!veoS6Gtzj6Dq087V' @ 0 : 0; will stop at (end)
-2025/10/26-14:44:53.257127 7f0586bff6c0 Manual compaction at level-1 from '!items!2hD1DQVeCIQIXFU7' @ 72057594037927935 : 1 .. '!items!veoS6Gtzj6Dq087V' @ 0 : 0; will stop at (end)
+2026/04/02-22:42:22.763267 7feec9bff6c0 Recovering log #261
+2026/04/02-22:42:22.772907 7feec9bff6c0 Delete type=3 #259
+2026/04/02-22:42:22.772976 7feec9bff6c0 Delete type=0 #261
diff --git a/packs/protections/LOG.old b/packs/protections/LOG.old
index 16616da..7250dea 100644
--- a/packs/protections/LOG.old
+++ b/packs/protections/LOG.old
@@ -1,8 +1,8 @@
-2025/10/26-14:17:33.504597 7f058c9f96c0 Recovering log #249
-2025/10/26-14:17:33.557486 7f058c9f96c0 Delete type=3 #247
-2025/10/26-14:17:33.557559 7f058c9f96c0 Delete type=0 #249
-2025/10/26-14:43:50.570973 7f0586bff6c0 Level-0 table #254: started
-2025/10/26-14:43:50.571024 7f0586bff6c0 Level-0 table #254: 0 bytes OK
-2025/10/26-14:43:50.577238 7f0586bff6c0 Delete type=0 #252
-2025/10/26-14:43:50.596020 7f0586bff6c0 Manual compaction at level-0 from '!items!2hD1DQVeCIQIXFU7' @ 72057594037927935 : 1 .. '!items!veoS6Gtzj6Dq087V' @ 0 : 0; will stop at (end)
-2025/10/26-14:43:50.596059 7f0586bff6c0 Manual compaction at level-1 from '!items!2hD1DQVeCIQIXFU7' @ 72057594037927935 : 1 .. '!items!veoS6Gtzj6Dq087V' @ 0 : 0; will stop at (end)
+2026/04/02-22:23:11.856417 7feec93fe6c0 Recovering log #257
+2026/04/02-22:23:11.867162 7feec93fe6c0 Delete type=3 #255
+2026/04/02-22:23:11.867225 7feec93fe6c0 Delete type=0 #257
+2026/04/02-22:41:03.656206 7feeb37fe6c0 Level-0 table #262: started
+2026/04/02-22:41:03.656226 7feeb37fe6c0 Level-0 table #262: 0 bytes OK
+2026/04/02-22:41:03.662021 7feeb37fe6c0 Delete type=0 #260
+2026/04/02-22:41:03.680712 7feeb37fe6c0 Manual compaction at level-0 from '!items!2hD1DQVeCIQIXFU7' @ 72057594037927935 : 1 .. '!items!veoS6Gtzj6Dq087V' @ 0 : 0; will stop at (end)
+2026/04/02-22:41:03.680794 7feeb37fe6c0 Manual compaction at level-1 from '!items!2hD1DQVeCIQIXFU7' @ 72057594037927935 : 1 .. '!items!veoS6Gtzj6Dq087V' @ 0 : 0; will stop at (end)
diff --git a/packs/protections/MANIFEST-000255 b/packs/protections/MANIFEST-000263
similarity index 73%
rename from packs/protections/MANIFEST-000255
rename to packs/protections/MANIFEST-000263
index c2b44d9..b4ac06a 100644
Binary files a/packs/protections/MANIFEST-000255 and b/packs/protections/MANIFEST-000263 differ
diff --git a/packs/runes/000257.log b/packs/runes/000264.log
similarity index 100%
rename from packs/runes/000257.log
rename to packs/runes/000264.log
diff --git a/packs/runes/CURRENT b/packs/runes/CURRENT
index 380474a..45bcdf0 100644
--- a/packs/runes/CURRENT
+++ b/packs/runes/CURRENT
@@ -1 +1 @@
-MANIFEST-000255
+MANIFEST-000263
diff --git a/packs/runes/LOG b/packs/runes/LOG
index 969738a..c7a90df 100644
--- a/packs/runes/LOG
+++ b/packs/runes/LOG
@@ -1,8 +1,3 @@
-2025/10/26-14:44:35.708614 7f05877fe6c0 Recovering log #253
-2025/10/26-14:44:35.719212 7f05877fe6c0 Delete type=3 #251
-2025/10/26-14:44:35.719271 7f05877fe6c0 Delete type=0 #253
-2025/10/26-14:44:53.257366 7f0586bff6c0 Level-0 table #258: started
-2025/10/26-14:44:53.257411 7f0586bff6c0 Level-0 table #258: 0 bytes OK
-2025/10/26-14:44:53.263459 7f0586bff6c0 Delete type=0 #256
-2025/10/26-14:44:53.282260 7f0586bff6c0 Manual compaction at level-0 from '!items!1JqWbEkHUoKXbsgn' @ 72057594037927935 : 1 .. '!items!xnCf2xIPzdsUoBTy' @ 0 : 0; will stop at (end)
-2025/10/26-14:44:53.282308 7f0586bff6c0 Manual compaction at level-1 from '!items!1JqWbEkHUoKXbsgn' @ 72057594037927935 : 1 .. '!items!xnCf2xIPzdsUoBTy' @ 0 : 0; will stop at (end)
+2026/04/02-22:42:22.823423 7feeb3fff6c0 Recovering log #261
+2026/04/02-22:42:22.833361 7feeb3fff6c0 Delete type=3 #259
+2026/04/02-22:42:22.833424 7feeb3fff6c0 Delete type=0 #261
diff --git a/packs/runes/LOG.old b/packs/runes/LOG.old
index 861a736..72b5d4a 100644
--- a/packs/runes/LOG.old
+++ b/packs/runes/LOG.old
@@ -1,8 +1,8 @@
-2025/10/26-14:17:33.790087 7f05877fe6c0 Recovering log #249
-2025/10/26-14:17:33.841786 7f05877fe6c0 Delete type=3 #247
-2025/10/26-14:17:33.841849 7f05877fe6c0 Delete type=0 #249
-2025/10/26-14:43:50.602350 7f0586bff6c0 Level-0 table #254: started
-2025/10/26-14:43:50.602383 7f0586bff6c0 Level-0 table #254: 0 bytes OK
-2025/10/26-14:43:50.608645 7f0586bff6c0 Delete type=0 #252
-2025/10/26-14:43:50.621507 7f0586bff6c0 Manual compaction at level-0 from '!items!1JqWbEkHUoKXbsgn' @ 72057594037927935 : 1 .. '!items!xnCf2xIPzdsUoBTy' @ 0 : 0; will stop at (end)
-2025/10/26-14:43:50.621536 7f0586bff6c0 Manual compaction at level-1 from '!items!1JqWbEkHUoKXbsgn' @ 72057594037927935 : 1 .. '!items!xnCf2xIPzdsUoBTy' @ 0 : 0; will stop at (end)
+2026/04/02-22:23:11.918116 7feeb3fff6c0 Recovering log #257
+2026/04/02-22:23:11.928729 7feeb3fff6c0 Delete type=3 #255
+2026/04/02-22:23:11.928772 7feeb3fff6c0 Delete type=0 #257
+2026/04/02-22:41:03.680892 7feeb37fe6c0 Level-0 table #262: started
+2026/04/02-22:41:03.680922 7feeb37fe6c0 Level-0 table #262: 0 bytes OK
+2026/04/02-22:41:03.686757 7feeb37fe6c0 Delete type=0 #260
+2026/04/02-22:41:03.706277 7feeb37fe6c0 Manual compaction at level-0 from '!items!1JqWbEkHUoKXbsgn' @ 72057594037927935 : 1 .. '!items!xnCf2xIPzdsUoBTy' @ 0 : 0; will stop at (end)
+2026/04/02-22:41:03.706313 7feeb37fe6c0 Manual compaction at level-1 from '!items!1JqWbEkHUoKXbsgn' @ 72057594037927935 : 1 .. '!items!xnCf2xIPzdsUoBTy' @ 0 : 0; will stop at (end)
diff --git a/packs/runes/MANIFEST-000255 b/packs/runes/MANIFEST-000263
similarity index 72%
rename from packs/runes/MANIFEST-000255
rename to packs/runes/MANIFEST-000263
index 70e07dd..8703f99 100644
Binary files a/packs/runes/MANIFEST-000255 and b/packs/runes/MANIFEST-000263 differ
diff --git a/packs/scenes/000200.ldb b/packs/scenes/000200.ldb
deleted file mode 100644
index acba567..0000000
Binary files a/packs/scenes/000200.ldb and /dev/null differ
diff --git a/packs/scenes/000223.ldb b/packs/scenes/000223.ldb
new file mode 100644
index 0000000..a4d14b9
Binary files /dev/null and b/packs/scenes/000223.ldb differ
diff --git a/packs/scenes/000217.log b/packs/scenes/000225.log
similarity index 100%
rename from packs/scenes/000217.log
rename to packs/scenes/000225.log
diff --git a/packs/scenes/CURRENT b/packs/scenes/CURRENT
index 68076bd..4d5019e 100644
--- a/packs/scenes/CURRENT
+++ b/packs/scenes/CURRENT
@@ -1 +1 @@
-MANIFEST-000215
+MANIFEST-000224
diff --git a/packs/scenes/LOG b/packs/scenes/LOG
index cec6dab..1e3d339 100644
--- a/packs/scenes/LOG
+++ b/packs/scenes/LOG
@@ -1,8 +1,3 @@
-2025/10/26-14:44:35.760670 7f058d1fa6c0 Recovering log #213
-2025/10/26-14:44:35.770100 7f058d1fa6c0 Delete type=3 #211
-2025/10/26-14:44:35.770150 7f058d1fa6c0 Delete type=0 #213
-2025/10/26-14:44:53.294614 7f0586bff6c0 Level-0 table #218: started
-2025/10/26-14:44:53.294640 7f0586bff6c0 Level-0 table #218: 0 bytes OK
-2025/10/26-14:44:53.302067 7f0586bff6c0 Delete type=0 #216
-2025/10/26-14:44:53.308488 7f0586bff6c0 Manual compaction at level-0 from '!scenes!mfosNsLsHN5Pf4TO' @ 72057594037927935 : 1 .. '!scenes!mfosNsLsHN5Pf4TO' @ 0 : 0; will stop at (end)
-2025/10/26-14:44:53.308516 7f0586bff6c0 Manual compaction at level-1 from '!scenes!mfosNsLsHN5Pf4TO' @ 72057594037927935 : 1 .. '!scenes!mfosNsLsHN5Pf4TO' @ 0 : 0; will stop at (end)
+2026/04/02-22:42:22.872560 7feec93fe6c0 Recovering log #221
+2026/04/02-22:42:22.882205 7feec93fe6c0 Delete type=3 #219
+2026/04/02-22:42:22.882248 7feec93fe6c0 Delete type=0 #221
diff --git a/packs/scenes/LOG.old b/packs/scenes/LOG.old
index 7080410..a1901bd 100644
--- a/packs/scenes/LOG.old
+++ b/packs/scenes/LOG.old
@@ -1,8 +1,15 @@
-2025/10/26-14:17:34.026248 7f058d1fa6c0 Recovering log #209
-2025/10/26-14:17:34.085478 7f058d1fa6c0 Delete type=3 #207
-2025/10/26-14:17:34.085544 7f058d1fa6c0 Delete type=0 #209
-2025/10/26-14:43:50.635471 7f0586bff6c0 Level-0 table #214: started
-2025/10/26-14:43:50.635508 7f0586bff6c0 Level-0 table #214: 0 bytes OK
-2025/10/26-14:43:50.641648 7f0586bff6c0 Delete type=0 #212
-2025/10/26-14:43:50.648703 7f0586bff6c0 Manual compaction at level-0 from '!scenes!mfosNsLsHN5Pf4TO' @ 72057594037927935 : 1 .. '!scenes!mfosNsLsHN5Pf4TO' @ 0 : 0; will stop at (end)
-2025/10/26-14:43:50.648748 7f0586bff6c0 Manual compaction at level-1 from '!scenes!mfosNsLsHN5Pf4TO' @ 72057594037927935 : 1 .. '!scenes!mfosNsLsHN5Pf4TO' @ 0 : 0; will stop at (end)
+2026/04/02-22:23:11.983507 7feeb3fff6c0 Recovering log #217
+2026/04/02-22:23:11.992802 7feeb3fff6c0 Delete type=3 #215
+2026/04/02-22:23:11.992847 7feeb3fff6c0 Delete type=0 #217
+2026/04/02-22:41:03.713063 7feeb37fe6c0 Level-0 table #222: started
+2026/04/02-22:41:03.716879 7feeb37fe6c0 Level-0 table #222: 1619 bytes OK
+2026/04/02-22:41:03.722798 7feeb37fe6c0 Delete type=0 #220
+2026/04/02-22:41:03.736032 7feeb37fe6c0 Manual compaction at level-0 from '!scenes!mfosNsLsHN5Pf4TO' @ 72057594037927935 : 1 .. '!scenes.levels!mfosNsLsHN5Pf4TO.defaultLevel0000' @ 0 : 0; will stop at (end)
+2026/04/02-22:41:03.736071 7feeb37fe6c0 Manual compaction at level-1 from '!scenes!mfosNsLsHN5Pf4TO' @ 72057594037927935 : 1 .. '!scenes.levels!mfosNsLsHN5Pf4TO.defaultLevel0000' @ 0 : 0; will stop at '!scenes.levels!mfosNsLsHN5Pf4TO.defaultLevel0000' @ 102 : 1
+2026/04/02-22:41:03.736077 7feeb37fe6c0 Compacting 1@1 + 1@2 files
+2026/04/02-22:41:03.739208 7feeb37fe6c0 Generated table #223@1: 2 keys, 1619 bytes
+2026/04/02-22:41:03.739222 7feeb37fe6c0 Compacted 1@1 + 1@2 files => 1619 bytes
+2026/04/02-22:41:03.745387 7feeb37fe6c0 compacted to: files[ 0 0 1 0 0 0 0 ]
+2026/04/02-22:41:03.745489 7feeb37fe6c0 Delete type=2 #200
+2026/04/02-22:41:03.745601 7feeb37fe6c0 Delete type=2 #222
+2026/04/02-22:41:03.758550 7feeb37fe6c0 Manual compaction at level-1 from '!scenes.levels!mfosNsLsHN5Pf4TO.defaultLevel0000' @ 102 : 1 .. '!scenes.levels!mfosNsLsHN5Pf4TO.defaultLevel0000' @ 0 : 0; will stop at (end)
diff --git a/packs/scenes/MANIFEST-000215 b/packs/scenes/MANIFEST-000215
deleted file mode 100644
index b202611..0000000
Binary files a/packs/scenes/MANIFEST-000215 and /dev/null differ
diff --git a/packs/scenes/MANIFEST-000224 b/packs/scenes/MANIFEST-000224
new file mode 100644
index 0000000..b8acdd6
Binary files /dev/null and b/packs/scenes/MANIFEST-000224 differ
diff --git a/packs/skills-creatures/000165.log b/packs/skills-creatures/000172.log
similarity index 100%
rename from packs/skills-creatures/000165.log
rename to packs/skills-creatures/000172.log
diff --git a/packs/skills-creatures/CURRENT b/packs/skills-creatures/CURRENT
index abf5eb3..91e41f4 100644
--- a/packs/skills-creatures/CURRENT
+++ b/packs/skills-creatures/CURRENT
@@ -1 +1 @@
-MANIFEST-000163
+MANIFEST-000171
diff --git a/packs/skills-creatures/LOG b/packs/skills-creatures/LOG
index 0f43ce8..774594e 100644
--- a/packs/skills-creatures/LOG
+++ b/packs/skills-creatures/LOG
@@ -1,8 +1,3 @@
-2025/10/26-14:44:35.609943 7f058c9f96c0 Recovering log #161
-2025/10/26-14:44:35.620061 7f058c9f96c0 Delete type=3 #159
-2025/10/26-14:44:35.620112 7f058c9f96c0 Delete type=0 #161
-2025/10/26-14:44:53.224450 7f0586bff6c0 Level-0 table #166: started
-2025/10/26-14:44:53.224482 7f0586bff6c0 Level-0 table #166: 0 bytes OK
-2025/10/26-14:44:53.231453 7f0586bff6c0 Delete type=0 #164
-2025/10/26-14:44:53.231618 7f0586bff6c0 Manual compaction at level-0 from '!items!6bmjc4MUduGs9s6n' @ 72057594037927935 : 1 .. '!items!t692JcsGHG4YJIlM' @ 0 : 0; will stop at (end)
-2025/10/26-14:44:53.231660 7f0586bff6c0 Manual compaction at level-1 from '!items!6bmjc4MUduGs9s6n' @ 72057594037927935 : 1 .. '!items!t692JcsGHG4YJIlM' @ 0 : 0; will stop at (end)
+2026/04/02-22:42:22.727378 7feeb3fff6c0 Recovering log #169
+2026/04/02-22:42:22.736950 7feeb3fff6c0 Delete type=3 #167
+2026/04/02-22:42:22.737015 7feeb3fff6c0 Delete type=0 #169
diff --git a/packs/skills-creatures/LOG.old b/packs/skills-creatures/LOG.old
index e59df36..e567db4 100644
--- a/packs/skills-creatures/LOG.old
+++ b/packs/skills-creatures/LOG.old
@@ -1,8 +1,8 @@
-2025/10/26-14:17:33.157252 7f05877fe6c0 Recovering log #157
-2025/10/26-14:17:33.236823 7f05877fe6c0 Delete type=3 #155
-2025/10/26-14:17:33.236895 7f05877fe6c0 Delete type=0 #157
-2025/10/26-14:43:50.544974 7f0586bff6c0 Level-0 table #162: started
-2025/10/26-14:43:50.545049 7f0586bff6c0 Level-0 table #162: 0 bytes OK
-2025/10/26-14:43:50.551670 7f0586bff6c0 Delete type=0 #160
-2025/10/26-14:43:50.570795 7f0586bff6c0 Manual compaction at level-0 from '!items!6bmjc4MUduGs9s6n' @ 72057594037927935 : 1 .. '!items!t692JcsGHG4YJIlM' @ 0 : 0; will stop at (end)
-2025/10/26-14:43:50.570842 7f0586bff6c0 Manual compaction at level-1 from '!items!6bmjc4MUduGs9s6n' @ 72057594037927935 : 1 .. '!items!t692JcsGHG4YJIlM' @ 0 : 0; will stop at (end)
+2026/04/02-22:23:11.820127 7feeb3fff6c0 Recovering log #165
+2026/04/02-22:23:11.829802 7feeb3fff6c0 Delete type=3 #163
+2026/04/02-22:23:11.829871 7feeb3fff6c0 Delete type=0 #165
+2026/04/02-22:41:03.643069 7feeb37fe6c0 Level-0 table #170: started
+2026/04/02-22:41:03.643094 7feeb37fe6c0 Level-0 table #170: 0 bytes OK
+2026/04/02-22:41:03.649929 7feeb37fe6c0 Delete type=0 #168
+2026/04/02-22:41:03.656108 7feeb37fe6c0 Manual compaction at level-0 from '!items!6bmjc4MUduGs9s6n' @ 72057594037927935 : 1 .. '!items!t692JcsGHG4YJIlM' @ 0 : 0; will stop at (end)
+2026/04/02-22:41:03.656141 7feeb37fe6c0 Manual compaction at level-1 from '!items!6bmjc4MUduGs9s6n' @ 72057594037927935 : 1 .. '!items!t692JcsGHG4YJIlM' @ 0 : 0; will stop at (end)
diff --git a/packs/skills-creatures/MANIFEST-000163 b/packs/skills-creatures/MANIFEST-000171
similarity index 73%
rename from packs/skills-creatures/MANIFEST-000163
rename to packs/skills-creatures/MANIFEST-000171
index 4c7eb17..2997f77 100644
Binary files a/packs/skills-creatures/MANIFEST-000163 and b/packs/skills-creatures/MANIFEST-000171 differ
diff --git a/packs/skills/000257.log b/packs/skills/000264.log
similarity index 100%
rename from packs/skills/000257.log
rename to packs/skills/000264.log
diff --git a/packs/skills/CURRENT b/packs/skills/CURRENT
index 380474a..45bcdf0 100644
--- a/packs/skills/CURRENT
+++ b/packs/skills/CURRENT
@@ -1 +1 @@
-MANIFEST-000255
+MANIFEST-000263
diff --git a/packs/skills/LOG b/packs/skills/LOG
index 8981689..3289dc9 100644
--- a/packs/skills/LOG
+++ b/packs/skills/LOG
@@ -1,8 +1,3 @@
-2025/10/26-14:44:35.598401 7f05877fe6c0 Recovering log #253
-2025/10/26-14:44:35.607893 7f05877fe6c0 Delete type=3 #251
-2025/10/26-14:44:35.607941 7f05877fe6c0 Delete type=0 #253
-2025/10/26-14:44:53.212036 7f0586bff6c0 Level-0 table #258: started
-2025/10/26-14:44:53.212073 7f0586bff6c0 Level-0 table #258: 0 bytes OK
-2025/10/26-14:44:53.217965 7f0586bff6c0 Delete type=0 #256
-2025/10/26-14:44:53.231590 7f0586bff6c0 Manual compaction at level-0 from '!items!0LlzDyCurJedqeyG' @ 72057594037927935 : 1 .. '!items!tq6mEgXog7h4VyWk' @ 0 : 0; will stop at (end)
-2025/10/26-14:44:53.231639 7f0586bff6c0 Manual compaction at level-1 from '!items!0LlzDyCurJedqeyG' @ 72057594037927935 : 1 .. '!items!tq6mEgXog7h4VyWk' @ 0 : 0; will stop at (end)
+2026/04/02-22:42:22.715339 7feec8bfd6c0 Recovering log #261
+2026/04/02-22:42:22.725110 7feec8bfd6c0 Delete type=3 #259
+2026/04/02-22:42:22.725152 7feec8bfd6c0 Delete type=0 #261
diff --git a/packs/skills/LOG.old b/packs/skills/LOG.old
index c168e39..bd64a57 100644
--- a/packs/skills/LOG.old
+++ b/packs/skills/LOG.old
@@ -1,8 +1,8 @@
-2025/10/26-14:17:33.083511 7f058c9f96c0 Recovering log #249
-2025/10/26-14:17:33.155121 7f058c9f96c0 Delete type=3 #247
-2025/10/26-14:17:33.155197 7f058c9f96c0 Delete type=0 #249
-2025/10/26-14:43:50.564078 7f0586bff6c0 Level-0 table #254: started
-2025/10/26-14:43:50.564116 7f0586bff6c0 Level-0 table #254: 0 bytes OK
-2025/10/26-14:43:50.570661 7f0586bff6c0 Delete type=0 #252
-2025/10/26-14:43:50.570833 7f0586bff6c0 Manual compaction at level-0 from '!items!0LlzDyCurJedqeyG' @ 72057594037927935 : 1 .. '!items!tq6mEgXog7h4VyWk' @ 0 : 0; will stop at (end)
-2025/10/26-14:43:50.570867 7f0586bff6c0 Manual compaction at level-1 from '!items!0LlzDyCurJedqeyG' @ 72057594037927935 : 1 .. '!items!tq6mEgXog7h4VyWk' @ 0 : 0; will stop at (end)
+2026/04/02-22:23:11.808380 7feec9bff6c0 Recovering log #257
+2026/04/02-22:23:11.817785 7feec9bff6c0 Delete type=3 #255
+2026/04/02-22:23:11.817833 7feec9bff6c0 Delete type=0 #257
+2026/04/02-22:41:03.630634 7feeb37fe6c0 Level-0 table #262: started
+2026/04/02-22:41:03.630678 7feeb37fe6c0 Level-0 table #262: 0 bytes OK
+2026/04/02-22:41:03.636689 7feeb37fe6c0 Delete type=0 #260
+2026/04/02-22:41:03.656092 7feeb37fe6c0 Manual compaction at level-0 from '!items!0LlzDyCurJedqeyG' @ 72057594037927935 : 1 .. '!items!tq6mEgXog7h4VyWk' @ 0 : 0; will stop at (end)
+2026/04/02-22:41:03.656125 7feeb37fe6c0 Manual compaction at level-1 from '!items!0LlzDyCurJedqeyG' @ 72057594037927935 : 1 .. '!items!tq6mEgXog7h4VyWk' @ 0 : 0; will stop at (end)
diff --git a/packs/skills/MANIFEST-000255 b/packs/skills/MANIFEST-000263
similarity index 73%
rename from packs/skills/MANIFEST-000255
rename to packs/skills/MANIFEST-000263
index d136a35..09afeba 100644
Binary files a/packs/skills/MANIFEST-000255 and b/packs/skills/MANIFEST-000263 differ
diff --git a/packs/tables/000372.log b/packs/tables/000379.log
similarity index 100%
rename from packs/tables/000372.log
rename to packs/tables/000379.log
diff --git a/packs/tables/CURRENT b/packs/tables/CURRENT
index 460ff32..5a3fb87 100644
--- a/packs/tables/CURRENT
+++ b/packs/tables/CURRENT
@@ -1 +1 @@
-MANIFEST-000370
+MANIFEST-000378
diff --git a/packs/tables/LOG b/packs/tables/LOG
index 432afa0..12f9ee8 100644
--- a/packs/tables/LOG
+++ b/packs/tables/LOG
@@ -1,7 +1,3 @@
-2025/10/26-14:44:35.747136 7f05877fe6c0 Recovering log #368
-2025/10/26-14:44:35.758006 7f05877fe6c0 Delete type=3 #366
-2025/10/26-14:44:35.758071 7f05877fe6c0 Delete type=0 #368
-2025/10/26-14:44:53.288438 7f0586bff6c0 Level-0 table #373: started
-2025/10/26-14:44:53.288457 7f0586bff6c0 Level-0 table #373: 0 bytes OK
-2025/10/26-14:44:53.294493 7f0586bff6c0 Delete type=0 #371
-2025/10/26-14:44:53.308473 7f0586bff6c0 Manual compaction at level-0 from 'undefined' @ 72057594037927935 : 1 .. 'undefined' @ 0 : 0; will stop at (end)
+2026/04/02-22:42:22.860656 7feec9bff6c0 Recovering log #376
+2026/04/02-22:42:22.870238 7feec9bff6c0 Delete type=3 #374
+2026/04/02-22:42:22.870287 7feec9bff6c0 Delete type=0 #376
diff --git a/packs/tables/LOG.old b/packs/tables/LOG.old
index 8e00e3e..105acfb 100644
--- a/packs/tables/LOG.old
+++ b/packs/tables/LOG.old
@@ -1,7 +1,7 @@
-2025/10/26-14:17:33.964490 7f0587fff6c0 Recovering log #364
-2025/10/26-14:17:34.023594 7f0587fff6c0 Delete type=3 #362
-2025/10/26-14:17:34.023664 7f0587fff6c0 Delete type=0 #364
-2025/10/26-14:43:50.621643 7f0586bff6c0 Level-0 table #369: started
-2025/10/26-14:43:50.621665 7f0586bff6c0 Level-0 table #369: 0 bytes OK
-2025/10/26-14:43:50.628955 7f0586bff6c0 Delete type=0 #367
-2025/10/26-14:43:50.648683 7f0586bff6c0 Manual compaction at level-0 from 'undefined' @ 72057594037927935 : 1 .. 'undefined' @ 0 : 0; will stop at (end)
+2026/04/02-22:23:11.970070 7feec93fe6c0 Recovering log #372
+2026/04/02-22:23:11.980922 7feec93fe6c0 Delete type=3 #370
+2026/04/02-22:23:11.980982 7feec93fe6c0 Delete type=0 #372
+2026/04/02-22:41:03.706419 7feeb37fe6c0 Level-0 table #377: started
+2026/04/02-22:41:03.706450 7feeb37fe6c0 Level-0 table #377: 0 bytes OK
+2026/04/02-22:41:03.712908 7feeb37fe6c0 Delete type=0 #375
+2026/04/02-22:41:03.736020 7feeb37fe6c0 Manual compaction at level-0 from 'undefined' @ 72057594037927935 : 1 .. 'undefined' @ 0 : 0; will stop at (end)
diff --git a/packs/tables/MANIFEST-000370 b/packs/tables/MANIFEST-000370
deleted file mode 100644
index 446ee38..0000000
Binary files a/packs/tables/MANIFEST-000370 and /dev/null differ
diff --git a/packs/tables/MANIFEST-000378 b/packs/tables/MANIFEST-000378
new file mode 100644
index 0000000..b3c08e1
Binary files /dev/null and b/packs/tables/MANIFEST-000378 differ
diff --git a/packs/talents/000378.log b/packs/talents/000385.log
similarity index 100%
rename from packs/talents/000378.log
rename to packs/talents/000385.log
diff --git a/packs/talents/CURRENT b/packs/talents/CURRENT
index 561f1eb..70d8a3a 100644
--- a/packs/talents/CURRENT
+++ b/packs/talents/CURRENT
@@ -1 +1 @@
-MANIFEST-000376
+MANIFEST-000384
diff --git a/packs/talents/LOG b/packs/talents/LOG
index abd66f1..b27b28d 100644
--- a/packs/talents/LOG
+++ b/packs/talents/LOG
@@ -1,8 +1,3 @@
-2025/10/26-14:44:35.733973 7f0587fff6c0 Recovering log #374
-2025/10/26-14:44:35.744053 7f0587fff6c0 Delete type=3 #372
-2025/10/26-14:44:35.744110 7f0587fff6c0 Delete type=0 #374
-2025/10/26-14:44:53.269501 7f0586bff6c0 Level-0 table #379: started
-2025/10/26-14:44:53.269524 7f0586bff6c0 Level-0 table #379: 0 bytes OK
-2025/10/26-14:44:53.275723 7f0586bff6c0 Delete type=0 #377
-2025/10/26-14:44:53.282286 7f0586bff6c0 Manual compaction at level-0 from '!items!07bq0fsbn653i81y' @ 72057594037927935 : 1 .. '!items!zKvlDHBalR4UdwUx' @ 0 : 0; will stop at (end)
-2025/10/26-14:44:53.282318 7f0586bff6c0 Manual compaction at level-1 from '!items!07bq0fsbn653i81y' @ 72057594037927935 : 1 .. '!items!zKvlDHBalR4UdwUx' @ 0 : 0; will stop at (end)
+2026/04/02-22:42:22.847185 7feec93fe6c0 Recovering log #382
+2026/04/02-22:42:22.858002 7feec93fe6c0 Delete type=3 #380
+2026/04/02-22:42:22.858062 7feec93fe6c0 Delete type=0 #382
diff --git a/packs/talents/LOG.old b/packs/talents/LOG.old
index 8338fe9..1895c2d 100644
--- a/packs/talents/LOG.old
+++ b/packs/talents/LOG.old
@@ -1,8 +1,8 @@
-2025/10/26-14:17:33.906646 7f058c9f96c0 Recovering log #370
-2025/10/26-14:17:33.961055 7f058c9f96c0 Delete type=3 #368
-2025/10/26-14:17:33.961113 7f058c9f96c0 Delete type=0 #370
-2025/10/26-14:43:50.608740 7f0586bff6c0 Level-0 table #375: started
-2025/10/26-14:43:50.608767 7f0586bff6c0 Level-0 table #375: 0 bytes OK
-2025/10/26-14:43:50.615235 7f0586bff6c0 Delete type=0 #373
-2025/10/26-14:43:50.621516 7f0586bff6c0 Manual compaction at level-0 from '!items!07bq0fsbn653i81y' @ 72057594037927935 : 1 .. '!items!zKvlDHBalR4UdwUx' @ 0 : 0; will stop at (end)
-2025/10/26-14:43:50.621549 7f0586bff6c0 Manual compaction at level-1 from '!items!07bq0fsbn653i81y' @ 72057594037927935 : 1 .. '!items!zKvlDHBalR4UdwUx' @ 0 : 0; will stop at (end)
+2026/04/02-22:23:11.957088 7feeb3fff6c0 Recovering log #378
+2026/04/02-22:23:11.966998 7feeb3fff6c0 Delete type=3 #376
+2026/04/02-22:23:11.967052 7feeb3fff6c0 Delete type=0 #378
+2026/04/02-22:41:03.700257 7feeb37fe6c0 Level-0 table #383: started
+2026/04/02-22:41:03.700299 7feeb37fe6c0 Level-0 table #383: 0 bytes OK
+2026/04/02-22:41:03.706198 7feeb37fe6c0 Delete type=0 #381
+2026/04/02-22:41:03.706300 7feeb37fe6c0 Manual compaction at level-0 from '!items!07bq0fsbn653i81y' @ 72057594037927935 : 1 .. '!items!zKvlDHBalR4UdwUx' @ 0 : 0; will stop at (end)
+2026/04/02-22:41:03.706318 7feeb37fe6c0 Manual compaction at level-1 from '!items!07bq0fsbn653i81y' @ 72057594037927935 : 1 .. '!items!zKvlDHBalR4UdwUx' @ 0 : 0; will stop at (end)
diff --git a/packs/talents/MANIFEST-000376 b/packs/talents/MANIFEST-000384
similarity index 72%
rename from packs/talents/MANIFEST-000376
rename to packs/talents/MANIFEST-000384
index 959140d..0e94d11 100644
Binary files a/packs/talents/MANIFEST-000376 and b/packs/talents/MANIFEST-000384 differ
diff --git a/packs/tendances/000257.log b/packs/tendances/000264.log
similarity index 100%
rename from packs/tendances/000257.log
rename to packs/tendances/000264.log
diff --git a/packs/tendances/CURRENT b/packs/tendances/CURRENT
index 380474a..45bcdf0 100644
--- a/packs/tendances/CURRENT
+++ b/packs/tendances/CURRENT
@@ -1 +1 @@
-MANIFEST-000255
+MANIFEST-000263
diff --git a/packs/tendances/LOG b/packs/tendances/LOG
index 9e1d44d..d497faf 100644
--- a/packs/tendances/LOG
+++ b/packs/tendances/LOG
@@ -1,8 +1,3 @@
-2025/10/26-14:44:35.683164 7f058c9f96c0 Recovering log #253
-2025/10/26-14:44:35.694143 7f058c9f96c0 Delete type=3 #251
-2025/10/26-14:44:35.694192 7f058c9f96c0 Delete type=0 #253
-2025/10/26-14:44:53.243853 7f0586bff6c0 Level-0 table #258: started
-2025/10/26-14:44:53.243873 7f0586bff6c0 Level-0 table #258: 0 bytes OK
-2025/10/26-14:44:53.249962 7f0586bff6c0 Delete type=0 #256
-2025/10/26-14:44:53.257101 7f0586bff6c0 Manual compaction at level-0 from '!items!0CYP1JpZu9mst5tK' @ 72057594037927935 : 1 .. '!items!zhPPsmTtLv7cyNHJ' @ 0 : 0; will stop at (end)
-2025/10/26-14:44:53.257159 7f0586bff6c0 Manual compaction at level-1 from '!items!0CYP1JpZu9mst5tK' @ 72057594037927935 : 1 .. '!items!zhPPsmTtLv7cyNHJ' @ 0 : 0; will stop at (end)
+2026/04/02-22:42:22.799253 7feec93fe6c0 Recovering log #261
+2026/04/02-22:42:22.808694 7feec93fe6c0 Delete type=3 #259
+2026/04/02-22:42:22.808753 7feec93fe6c0 Delete type=0 #261
diff --git a/packs/tendances/LOG.old b/packs/tendances/LOG.old
index ef3a534..e750811 100644
--- a/packs/tendances/LOG.old
+++ b/packs/tendances/LOG.old
@@ -1,8 +1,8 @@
-2025/10/26-14:17:33.678678 7f0587fff6c0 Recovering log #249
-2025/10/26-14:17:33.731346 7f0587fff6c0 Delete type=3 #247
-2025/10/26-14:17:33.731455 7f0587fff6c0 Delete type=0 #249
-2025/10/26-14:43:50.583563 7f0586bff6c0 Level-0 table #254: started
-2025/10/26-14:43:50.583591 7f0586bff6c0 Level-0 table #254: 0 bytes OK
-2025/10/26-14:43:50.589444 7f0586bff6c0 Delete type=0 #252
-2025/10/26-14:43:50.596047 7f0586bff6c0 Manual compaction at level-0 from '!items!0CYP1JpZu9mst5tK' @ 72057594037927935 : 1 .. '!items!zhPPsmTtLv7cyNHJ' @ 0 : 0; will stop at (end)
-2025/10/26-14:43:50.596088 7f0586bff6c0 Manual compaction at level-1 from '!items!0CYP1JpZu9mst5tK' @ 72057594037927935 : 1 .. '!items!zhPPsmTtLv7cyNHJ' @ 0 : 0; will stop at (end)
+2026/04/02-22:23:11.894124 7feeb3fff6c0 Recovering log #257
+2026/04/02-22:23:11.903854 7feeb3fff6c0 Delete type=3 #255
+2026/04/02-22:23:11.903907 7feeb3fff6c0 Delete type=0 #257
+2026/04/02-22:41:03.668376 7feeb37fe6c0 Level-0 table #262: started
+2026/04/02-22:41:03.668395 7feeb37fe6c0 Level-0 table #262: 0 bytes OK
+2026/04/02-22:41:03.674598 7feeb37fe6c0 Delete type=0 #260
+2026/04/02-22:41:03.680742 7feeb37fe6c0 Manual compaction at level-0 from '!items!0CYP1JpZu9mst5tK' @ 72057594037927935 : 1 .. '!items!zhPPsmTtLv7cyNHJ' @ 0 : 0; will stop at (end)
+2026/04/02-22:41:03.680788 7feeb37fe6c0 Manual compaction at level-1 from '!items!0CYP1JpZu9mst5tK' @ 72057594037927935 : 1 .. '!items!zhPPsmTtLv7cyNHJ' @ 0 : 0; will stop at (end)
diff --git a/packs/tendances/MANIFEST-000255 b/packs/tendances/MANIFEST-000263
similarity index 72%
rename from packs/tendances/MANIFEST-000255
rename to packs/tendances/MANIFEST-000263
index 518b685..b4e54bc 100644
Binary files a/packs/tendances/MANIFEST-000255 and b/packs/tendances/MANIFEST-000263 differ
diff --git a/packs/traits-chaotiques/000257.log b/packs/traits-chaotiques/000264.log
similarity index 100%
rename from packs/traits-chaotiques/000257.log
rename to packs/traits-chaotiques/000264.log
diff --git a/packs/traits-chaotiques/CURRENT b/packs/traits-chaotiques/CURRENT
index 380474a..45bcdf0 100644
--- a/packs/traits-chaotiques/CURRENT
+++ b/packs/traits-chaotiques/CURRENT
@@ -1 +1 @@
-MANIFEST-000255
+MANIFEST-000263
diff --git a/packs/traits-chaotiques/LOG b/packs/traits-chaotiques/LOG
index 34e6f8e..a36a23a 100644
--- a/packs/traits-chaotiques/LOG
+++ b/packs/traits-chaotiques/LOG
@@ -1,8 +1,3 @@
-2025/10/26-14:44:35.696475 7f058d1fa6c0 Recovering log #253
-2025/10/26-14:44:35.706242 7f058d1fa6c0 Delete type=3 #251
-2025/10/26-14:44:35.706313 7f058d1fa6c0 Delete type=0 #253
-2025/10/26-14:44:53.275829 7f0586bff6c0 Level-0 table #258: started
-2025/10/26-14:44:53.275850 7f0586bff6c0 Level-0 table #258: 0 bytes OK
-2025/10/26-14:44:53.282151 7f0586bff6c0 Delete type=0 #256
-2025/10/26-14:44:53.282297 7f0586bff6c0 Manual compaction at level-0 from '!items!3J0HKjcVtBT39BiR' @ 72057594037927935 : 1 .. '!items!zeOtWz6oscp8Su5l' @ 0 : 0; will stop at (end)
-2025/10/26-14:44:53.282339 7f0586bff6c0 Manual compaction at level-1 from '!items!3J0HKjcVtBT39BiR' @ 72057594037927935 : 1 .. '!items!zeOtWz6oscp8Su5l' @ 0 : 0; will stop at (end)
+2026/04/02-22:42:22.810618 7feec8bfd6c0 Recovering log #261
+2026/04/02-22:42:22.821256 7feec8bfd6c0 Delete type=3 #259
+2026/04/02-22:42:22.821311 7feec8bfd6c0 Delete type=0 #261
diff --git a/packs/traits-chaotiques/LOG.old b/packs/traits-chaotiques/LOG.old
index afe7964..a64c2ca 100644
--- a/packs/traits-chaotiques/LOG.old
+++ b/packs/traits-chaotiques/LOG.old
@@ -1,8 +1,8 @@
-2025/10/26-14:17:33.734638 7f058c9f96c0 Recovering log #249
-2025/10/26-14:17:33.787813 7f058c9f96c0 Delete type=3 #247
-2025/10/26-14:17:33.787886 7f058c9f96c0 Delete type=0 #249
-2025/10/26-14:43:50.596168 7f0586bff6c0 Level-0 table #254: started
-2025/10/26-14:43:50.596199 7f0586bff6c0 Level-0 table #254: 0 bytes OK
-2025/10/26-14:43:50.602232 7f0586bff6c0 Delete type=0 #252
-2025/10/26-14:43:50.621497 7f0586bff6c0 Manual compaction at level-0 from '!items!3J0HKjcVtBT39BiR' @ 72057594037927935 : 1 .. '!items!zeOtWz6oscp8Su5l' @ 0 : 0; will stop at (end)
-2025/10/26-14:43:50.621530 7f0586bff6c0 Manual compaction at level-1 from '!items!3J0HKjcVtBT39BiR' @ 72057594037927935 : 1 .. '!items!zeOtWz6oscp8Su5l' @ 0 : 0; will stop at (end)
+2026/04/02-22:23:11.906122 7feec93fe6c0 Recovering log #257
+2026/04/02-22:23:11.916026 7feec93fe6c0 Delete type=3 #255
+2026/04/02-22:23:11.916071 7feec93fe6c0 Delete type=0 #257
+2026/04/02-22:41:03.693733 7feeb37fe6c0 Level-0 table #262: started
+2026/04/02-22:41:03.693757 7feeb37fe6c0 Level-0 table #262: 0 bytes OK
+2026/04/02-22:41:03.700114 7feeb37fe6c0 Delete type=0 #260
+2026/04/02-22:41:03.706293 7feeb37fe6c0 Manual compaction at level-0 from '!items!3J0HKjcVtBT39BiR' @ 72057594037927935 : 1 .. '!items!zeOtWz6oscp8Su5l' @ 0 : 0; will stop at (end)
+2026/04/02-22:41:03.706328 7feeb37fe6c0 Manual compaction at level-1 from '!items!3J0HKjcVtBT39BiR' @ 72057594037927935 : 1 .. '!items!zeOtWz6oscp8Su5l' @ 0 : 0; will stop at (end)
diff --git a/packs/traits-chaotiques/MANIFEST-000255 b/packs/traits-chaotiques/MANIFEST-000263
similarity index 73%
rename from packs/traits-chaotiques/MANIFEST-000255
rename to packs/traits-chaotiques/MANIFEST-000263
index ea46fd0..ead50ba 100644
Binary files a/packs/traits-chaotiques/MANIFEST-000255 and b/packs/traits-chaotiques/MANIFEST-000263 differ
diff --git a/styles/mournblade-cyd2.css b/styles/mournblade-cyd2.css
index 232dc90..e44349a 100644
--- a/styles/mournblade-cyd2.css
+++ b/styles/mournblade-cyd2.css
@@ -67,7 +67,7 @@
}
/* For nav and title */
.window-app input,
-.fvtt-mournblade .item-form,
+.fvtt-mournblade-cyd-2-0 .item-form,
.sheet header.sheet-header .flex-group-center.flex-compteurs,
.sheet header.sheet-header .flex-group-center.flex-fatigue,
select,
@@ -202,7 +202,7 @@ table {
flex: 'flex-shrink';
}
/* Styles limited to foundryvtt-vadentis sheets */
-.fvtt-mournblade .sheet-header {
+.fvtt-mournblade-cyd-2-0 .sheet-header {
-webkit-box-flex: 0;
-ms-flex: 0 0 210px;
flex: 0 0 210px;
@@ -221,15 +221,16 @@ table {
justify-content: flex-start;
margin-bottom: 10px;
}
-.fvtt-mournblade .sheet-header .profile-img {
+.fvtt-mournblade-cyd-2-0 .sheet-header .profile-img {
-webkit-box-flex: 0;
- -ms-flex: 0 0 128px;
- flex: 0 0 128px;
- height: 128px;
- width: 128px;
+ -ms-flex: 0 0 80px;
+ flex: 0 0 80px;
+ height: 80px;
+ width: 80px;
margin-right: 10px;
object-fit: cover;
object-position: 50% 0;
+ cursor: pointer;
}
.button-img {
vertical-align: baseline;
@@ -257,12 +258,12 @@ table {
border: 0;
vertical-align: bottom;
}
-.fvtt-mournblade .sheet-header .header-fields {
+.fvtt-mournblade-cyd-2-0 .sheet-header .header-fields {
-webkit-box-flex: 1;
-ms-flex: 1;
flex: 1;
}
-.fvtt-mournblade .sheet-header h1.charname {
+.fvtt-mournblade-cyd-2-0 .sheet-header h1.charname {
height: 50px;
padding: 0px;
margin: 5px 0;
@@ -271,7 +272,7 @@ table {
font-size: 2rem;
font-family: "CentaurMT";
}
-.fvtt-mournblade .sheet-header h1.charname input {
+.fvtt-mournblade-cyd-2-0 .sheet-header h1.charname input {
width: 100%;
height: 100%;
margin: 0;
@@ -280,17 +281,17 @@ table {
font-size: 2rem;
text-align: left;
}
-.fvtt-mournblade .sheet-tabs {
+.fvtt-mournblade-cyd-2-0 .sheet-tabs {
-webkit-box-flex: 0;
-ms-flex: 0;
flex: 0;
}
-.fvtt-mournblade .sheet-body,
-.fvtt-mournblade .sheet-body .tab {
+.fvtt-mournblade-cyd-2-0 .sheet-body,
+.fvtt-mournblade-cyd-2-0 .sheet-body .tab {
height: auto;
font-size: 0.9rem;
}
-.fvtt-mournblade .sheet-body .tab .editor {
+.fvtt-mournblade-cyd-2-0 .sheet-body .tab .editor {
height: 100%;
font-size: 0.9rem;
}
@@ -314,58 +315,70 @@ table {
height: 120px;
padding: 0 3px;
}
-.fvtt-mournblade .tox .tox-editor-container {
+.fvtt-mournblade-cyd-2-0 .tox .tox-editor-container {
background: #fff;
}
-.fvtt-mournblade .tox .tox-edit-area {
+.fvtt-mournblade-cyd-2-0 .tox .tox-edit-area {
padding: 0 8px;
}
-.fvtt-mournblade .resource-label {
+.fvtt-mournblade-cyd-2-0 .resource-label {
font-weight: bold;
text-transform: uppercase;
}
-.fvtt-mournblade .tabs {
+.fvtt-mournblade-cyd-2-0 .tabs {
height: 40px;
border-top: 1px solid #AAA;
border-bottom: 1px solid #AAA;
color: #000000;
}
-.fvtt-mournblade .tabs .item {
- line-height: 40px;
- font-weight: bold;
+.fvtt-mournblade-cyd-2-0 nav.sheet-tabs {
+ justify-content: flex-start !important;
+ gap: 0 !important;
+ padding: 0 !important;
}
-.fvtt-mournblade .tabs .item.active {
+.fvtt-mournblade-cyd-2-0 .tabs .item {
+ line-height: 40px;
+ font-size: 10px;
+ font-weight: bold;
+ white-space: nowrap;
+ overflow: hidden;
+ text-overflow: ellipsis;
+ flex: 1 1 0;
+ text-align: center;
+ padding: 0 4px;
+}
+.fvtt-mournblade-cyd-2-0 .tabs .item.active {
text-decoration: underline;
text-shadow: none;
}
-.fvtt-mournblade .items-list {
+.fvtt-mournblade-cyd-2-0 .items-list {
list-style: none;
margin: 1px 0;
padding: 0;
overflow-y: auto;
}
-.fvtt-mournblade .items-list .item-header {
+.fvtt-mournblade-cyd-2-0 .items-list .item-header {
font-weight: bold;
}
-.fvtt-mournblade .items-list .item {
+.fvtt-mournblade-cyd-2-0 .items-list .item {
height: 30px;
line-height: 24px;
padding: 1px 0;
border-bottom: 1px solid #BBB;
}
-.fvtt-mournblade .items-list .item .item-image {
+.fvtt-mournblade-cyd-2-0 .items-list .item .item-image {
-webkit-box-flex: 0;
-ms-flex: 0 0 24px;
flex: 0 0 24px;
margin-right: 5px;
}
-.fvtt-mournblade .items-list .item img {
+.fvtt-mournblade-cyd-2-0 .items-list .item img {
display: block;
}
-.fvtt-mournblade .items-list .item-name {
+.fvtt-mournblade-cyd-2-0 .items-list .item-name {
margin: 0;
}
-.fvtt-mournblade .items-list .item-controls {
+.fvtt-mournblade-cyd-2-0 .items-list .item-controls {
-webkit-box-flex: 0;
-ms-flex: 0 0 86px;
flex: 0 0 86px;
@@ -1296,7 +1309,7 @@ li {
}
.item-field-label-long {
flex-grow: 1;
- max-width: 8rem;
+ max-width: 10rem;
min-width: 8rem;
}
.item-control-end {
@@ -2117,7 +2130,7 @@ li {
}
/* ==================== Item Sheet Styles ==================== */
/* Item header with image and name */
-.fvtt-mournblade.item {
+.fvtt-mournblade-cyd-2-0.item {
/* Background pour toute la fiche d'item */
background: url("../assets/ui/pc_sheet_bg.webp") repeat;
display: flex;
@@ -2136,11 +2149,11 @@ li {
/* Field labels */
/* Editor fields */
}
-.fvtt-mournblade.item .window-content {
+.fvtt-mournblade-cyd-2-0.item .window-content {
padding: 0;
margin: 0;
}
-.fvtt-mournblade.item section {
+.fvtt-mournblade-cyd-2-0.item section {
background: url("../assets/ui/pc_sheet_bg.webp") repeat-y;
color: black;
display: flex;
@@ -2150,15 +2163,15 @@ li {
padding: 0;
margin: 0;
}
-.fvtt-mournblade.item input:disabled,
-.fvtt-mournblade.item select:disabled {
+.fvtt-mournblade-cyd-2-0.item input:disabled,
+.fvtt-mournblade-cyd-2-0.item select:disabled {
color: #000000;
opacity: 0.8;
background-color: rgba(255, 255, 255, 0.5);
}
-.fvtt-mournblade.item input[type="text"],
-.fvtt-mournblade.item input[type="number"],
-.fvtt-mournblade.item select {
+.fvtt-mournblade-cyd-2-0.item input[type="text"],
+.fvtt-mournblade-cyd-2-0.item input[type="number"],
+.fvtt-mournblade-cyd-2-0.item select {
color: #000000;
background-color: rgba(255, 255, 255, 0.7);
border: 1px solid #999999;
@@ -2167,22 +2180,22 @@ li {
font-family: "CentaurMT", serif;
font-size: 0.85rem;
}
-.fvtt-mournblade.item textarea {
+.fvtt-mournblade-cyd-2-0.item textarea {
margin: 0;
padding: 2px 4px;
}
-.fvtt-mournblade.item input[type="checkbox"] {
+.fvtt-mournblade-cyd-2-0.item input[type="checkbox"] {
width: auto;
height: auto;
margin: 0 4px;
align-self: center;
}
-.fvtt-mournblade.item .header {
+.fvtt-mournblade-cyd-2-0.item .header {
flex: 0 0 auto;
border-bottom: 1px solid #999;
margin: 0;
}
-.fvtt-mournblade.item .sheet-header {
+.fvtt-mournblade-cyd-2-0.item .sheet-header {
display: flex;
flex-direction: row;
align-items: center;
@@ -2191,7 +2204,7 @@ li {
background: url("../assets/ui/pc_sheet_bg.webp") repeat;
flex: 0 0 auto;
}
-.fvtt-mournblade.item .item-sheet-img {
+.fvtt-mournblade-cyd-2-0.item .item-sheet-img {
flex: 0 0 64px;
width: 64px;
height: 64px;
@@ -2200,52 +2213,52 @@ li {
border-radius: 4px;
cursor: pointer;
}
-.fvtt-mournblade.item .item-sheet-img:hover {
+.fvtt-mournblade-cyd-2-0.item .item-sheet-img:hover {
box-shadow: 0 0 8px rgba(255, 102, 0, 0.8);
}
-.fvtt-mournblade.item .header-fields {
+.fvtt-mournblade-cyd-2-0.item .header-fields {
flex: 1;
display: flex;
flex-direction: column;
gap: 0.25rem;
}
-.fvtt-mournblade.item .header-actions {
+.fvtt-mournblade-cyd-2-0.item .header-actions {
flex: 0 0 auto;
display: flex;
align-items: center;
gap: 0.5rem;
}
-.fvtt-mournblade.item .header-actions button {
+.fvtt-mournblade-cyd-2-0.item .header-actions button {
background: rgba(0, 0, 0, 0.1);
border: 1px solid #999;
padding: 0.25rem 0.5rem;
cursor: pointer;
font-family: "CentaurMT", serif;
}
-.fvtt-mournblade.item .header-actions button:hover {
+.fvtt-mournblade-cyd-2-0.item .header-actions button:hover {
background: rgba(255, 102, 0, 0.2);
box-shadow: 0 0 5px rgba(255, 102, 0, 0.5);
}
-.fvtt-mournblade.item .header-actions .chat-card-button {
+.fvtt-mournblade-cyd-2-0.item .header-actions .chat-card-button {
background: linear-gradient(to bottom, #21374afc 5%, #152833ab 100%);
border: 2px ridge #846109;
color: #d4b5a8;
padding: 0.3rem 0.5rem;
transition: all 0.2s ease;
}
-.fvtt-mournblade.item .header-actions .chat-card-button i {
+.fvtt-mournblade-cyd-2-0.item .header-actions .chat-card-button i {
font-size: 0.9rem;
}
-.fvtt-mournblade.item .header-actions .chat-card-button:hover {
+.fvtt-mournblade-cyd-2-0.item .header-actions .chat-card-button:hover {
background: linear-gradient(to bottom, #800000 5%, #3e0101 100%);
color: #ffffff;
box-shadow: 0 0 8px rgba(128, 0, 0, 0.6);
}
-.fvtt-mournblade.item .header-actions .chat-card-button:active {
+.fvtt-mournblade-cyd-2-0.item .header-actions .chat-card-button:active {
position: relative;
top: 1px;
}
-.fvtt-mournblade.item .sheet-header h1.charname {
+.fvtt-mournblade-cyd-2-0.item .sheet-header h1.charname {
height: 50px;
padding: 0;
margin: 5px 0;
@@ -2254,7 +2267,7 @@ li {
font-size: 2rem;
font-family: "CentaurMT";
}
-.fvtt-mournblade.item .sheet-header h1.charname input {
+.fvtt-mournblade-cyd-2-0.item .sheet-header h1.charname input {
width: 100%;
height: 100%;
margin: 0;
@@ -2264,10 +2277,10 @@ li {
text-align: left;
border: 0 none;
}
-.fvtt-mournblade.item .sheet-header h1.charname input:focus {
+.fvtt-mournblade-cyd-2-0.item .sheet-header h1.charname input:focus {
outline: 1px solid #ff6600;
}
-.fvtt-mournblade.item nav.tabs {
+.fvtt-mournblade-cyd-2-0.item nav.tabs {
display: flex;
border-bottom: 1px solid #7a7971;
margin: 0;
@@ -2275,7 +2288,7 @@ li {
background-color: #1c1c1c;
flex: 0 0 auto;
}
-.fvtt-mournblade.item nav.tabs a.item {
+.fvtt-mournblade-cyd-2-0.item nav.tabs a.item {
padding: 6px 12px;
color: #d4af37;
text-decoration: none;
@@ -2284,32 +2297,32 @@ li {
margin-right: 4px;
transition: all 0.2s;
}
-.fvtt-mournblade.item nav.tabs a.item i {
+.fvtt-mournblade-cyd-2-0.item nav.tabs a.item i {
display: none;
}
-.fvtt-mournblade.item nav.tabs a.item:hover {
+.fvtt-mournblade-cyd-2-0.item nav.tabs a.item:hover {
background-color: rgba(212, 175, 55, 0.1);
}
-.fvtt-mournblade.item nav.tabs a.item.active {
+.fvtt-mournblade-cyd-2-0.item nav.tabs a.item.active {
background-color: #2a2a2a;
border-bottom-color: #d4af37;
color: #f5f5f5;
}
-.fvtt-mournblade.item .tab {
+.fvtt-mournblade-cyd-2-0.item .tab {
display: none;
padding: 4px 8px;
overflow-y: auto;
flex: 1 1 auto;
}
-.fvtt-mournblade.item .tab.active {
+.fvtt-mournblade-cyd-2-0.item .tab.active {
display: block;
}
-.fvtt-mournblade.item .item-list {
+.fvtt-mournblade-cyd-2-0.item .item-list {
list-style: none;
margin: 0;
padding: 0;
}
-.fvtt-mournblade.item .item-list li.item {
+.fvtt-mournblade-cyd-2-0.item .item-list li.item {
display: flex;
align-items: center;
margin-bottom: 2px;
@@ -2317,13 +2330,13 @@ li {
min-height: 24px;
border-bottom: none;
}
-.fvtt-mournblade.item .item-list li.item.flexrow {
+.fvtt-mournblade-cyd-2-0.item .item-list li.item.flexrow {
display: flex;
flex-direction: row;
align-items: center;
gap: 4px;
}
-.fvtt-mournblade.item .generic-label {
+.fvtt-mournblade-cyd-2-0.item .generic-label {
display: inline-block;
white-space: nowrap;
font-weight: 700;
@@ -2333,51 +2346,51 @@ li {
margin: 0;
padding: 0 4px 0 0;
}
-.fvtt-mournblade.item .item-field-label-short {
+.fvtt-mournblade-cyd-2-0.item .item-field-label-short {
flex: 0 0 60px;
max-width: 60px;
}
-.fvtt-mournblade.item .item-field-label-medium {
+.fvtt-mournblade-cyd-2-0.item .item-field-label-medium {
flex: 0 0 100px;
max-width: 100px;
}
-.fvtt-mournblade.item .item-field-label-long {
+.fvtt-mournblade-cyd-2-0.item .item-field-label-long {
flex: 1;
min-width: 150px;
}
-.fvtt-mournblade.item .item-field-label-long1 {
+.fvtt-mournblade-cyd-2-0.item .item-field-label-long1 {
flex: 1;
min-width: 200px;
}
-.fvtt-mournblade.item .item-field-label-long2 {
+.fvtt-mournblade-cyd-2-0.item .item-field-label-long2 {
flex: 1;
min-width: 250px;
max-width: 250px;
}
-.fvtt-mournblade.item .item-field-label-long3 {
+.fvtt-mournblade-cyd-2-0.item .item-field-label-long3 {
flex: 1;
min-width: 350px;
max-width: 350px;
}
-.fvtt-mournblade.item .numeric-input {
+.fvtt-mournblade-cyd-2-0.item .numeric-input {
text-align: center;
width: 60px;
}
-.fvtt-mournblade.item .editor {
+.fvtt-mournblade-cyd-2-0.item .editor {
height: 300px;
border: 1px solid #999;
background: rgba(255, 255, 255, 0.9);
}
-.fvtt-mournblade.item .editor .editor-content {
+.fvtt-mournblade-cyd-2-0.item .editor .editor-content {
height: 100%;
padding: 0.5rem;
color: #000;
}
/* ==================== Actor Sheet Styles ==================== */
-.fvtt-mournblade.actor {
+.fvtt-mournblade-cyd-2-0.actor {
background: url("../assets/ui/pc_sheet_bg.webp") repeat;
}
-.fvtt-mournblade.actor .window-content {
+.fvtt-mournblade-cyd-2-0.actor .window-content {
height: 100%;
padding: 0;
margin: 0;
@@ -2385,45 +2398,30 @@ li {
flex-direction: column;
overflow: hidden;
}
-.fvtt-mournblade.actor form,
-.fvtt-mournblade.actor .sheet-form-layout {
- height: 100%;
- background: url("../assets/ui/pc_sheet_bg.webp") repeat-y;
- color: black;
- display: flex;
- flex-direction: column;
- flex: 1;
- min-height: 0;
- overflow: hidden;
- padding: 0;
- margin: 0;
-}
-.fvtt-mournblade.actor form > section,
-.fvtt-mournblade.actor .sheet-form-layout > section {
- height: 100%;
+.fvtt-mournblade-cyd-2-0.actor .window-content > section {
display: flex;
flex-direction: column;
flex: 1;
min-height: 0;
overflow: hidden;
}
-.fvtt-mournblade.actor .sheet-header {
+.fvtt-mournblade-cyd-2-0.actor .sheet-header {
background: url("../assets/ui/pc_sheet_bg.webp") repeat;
padding: 0.5rem;
margin: 0;
flex: 0 0 auto !important;
overflow: visible !important;
}
-.fvtt-mournblade.actor .sheet-header .background-sheet-header {
+.fvtt-mournblade-cyd-2-0.actor .sheet-header .background-sheet-header {
background: transparent;
}
-.fvtt-mournblade.actor .sheet-header .header-main-content {
+.fvtt-mournblade-cyd-2-0.actor .sheet-header .header-main-content {
flex: 1;
display: flex;
flex-direction: column;
gap: 0.5rem;
}
-.fvtt-mournblade.actor .sheet-header .header-stats-grid {
+.fvtt-mournblade-cyd-2-0.actor .sheet-header .header-stats-grid {
display: grid;
grid-template-columns: 2fr 1fr 1fr;
gap: 0.75rem;
@@ -2432,7 +2430,7 @@ li {
border: 2px solid rgba(139, 69, 19, 0.5);
border-radius: 4px;
}
-.fvtt-mournblade.actor .sheet-header .stat-group {
+.fvtt-mournblade-cyd-2-0.actor .sheet-header .stat-group {
display: flex;
flex-direction: column;
gap: 0.3rem;
@@ -2441,11 +2439,11 @@ li {
border: 1px solid rgba(139, 69, 19, 0.4);
border-radius: 3px;
}
-.fvtt-mournblade.actor .sheet-header .stat-group.stat-group-health {
+.fvtt-mournblade-cyd-2-0.actor .sheet-header .stat-group.stat-group-health {
border-left: 3px solid rgba(200, 0, 0, 0.6);
background: rgba(40, 0, 0, 0.15);
}
-.fvtt-mournblade.actor .sheet-header .stat-title {
+.fvtt-mournblade-cyd-2-0.actor .sheet-header .stat-title {
font-size: 0.75rem;
font-weight: bold;
color: #f5e6d3;
@@ -2457,14 +2455,14 @@ li {
font-family: "CentaurMT", serif;
text-shadow: 1px 1px 2px rgba(0, 0, 0, 0.8);
}
-.fvtt-mournblade.actor .sheet-header .stat-values {
+.fvtt-mournblade-cyd-2-0.actor .sheet-header .stat-values {
display: flex;
flex-direction: row;
gap: 0.5rem;
flex-wrap: wrap;
justify-content: center;
}
-.fvtt-mournblade.actor .sheet-header .stat-item {
+.fvtt-mournblade-cyd-2-0.actor .sheet-header .stat-item {
display: flex;
flex-direction: column;
gap: 0.2rem;
@@ -2472,14 +2470,14 @@ li {
flex: 1;
min-width: 0;
}
-.fvtt-mournblade.actor .sheet-header .stat-label {
+.fvtt-mournblade-cyd-2-0.actor .sheet-header .stat-label {
font-size: 0.7rem;
color: #d4c5b0;
margin: 0;
font-weight: 600;
text-shadow: 1px 1px 1px rgba(0, 0, 0, 0.7);
}
-.fvtt-mournblade.actor .sheet-header .stat-value {
+.fvtt-mournblade-cyd-2-0.actor .sheet-header .stat-value {
font-size: 0.85rem;
font-weight: bold;
color: #fff;
@@ -2492,7 +2490,7 @@ li {
text-shadow: 1px 1px 2px rgba(0, 0, 0, 0.9);
width: 100%;
}
-.fvtt-mournblade.actor .sheet-header .stat-input {
+.fvtt-mournblade-cyd-2-0.actor .sheet-header .stat-input {
font-size: 0.8rem;
font-weight: 600;
padding: 0.25rem 0.4rem;
@@ -2507,98 +2505,131 @@ li {
text-shadow: 1px 1px 2px rgba(0, 0, 0, 0.9);
box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.3);
}
-.fvtt-mournblade.actor .sheet-header .stat-input.stat-input-single {
+.fvtt-mournblade-cyd-2-0.actor .sheet-header .stat-input.stat-input-single {
min-width: 3.5rem;
}
-.fvtt-mournblade.actor .sheet-header .stat-input.stat-input-damage {
+.fvtt-mournblade-cyd-2-0.actor .sheet-header .stat-input.stat-input-damage {
border-color: rgba(200, 0, 0, 0.8);
background: rgba(80, 0, 0, 0.5);
}
-.fvtt-mournblade.actor .sheet-header .stat-input:hover {
+.fvtt-mournblade-cyd-2-0.actor .sheet-header .stat-input:hover {
background: rgba(60, 45, 30, 0.8);
border-color: rgba(255, 102, 0, 0.6);
}
-.fvtt-mournblade.actor .sheet-header .stat-input:focus {
+.fvtt-mournblade-cyd-2-0.actor .sheet-header .stat-input:focus {
outline: none;
border-color: #ff6600;
box-shadow: 0 0 6px rgba(255, 102, 0, 0.5), inset 0 1px 3px rgba(0, 0, 0, 0.3);
background: rgba(70, 50, 35, 0.9);
}
-.fvtt-mournblade.actor .sheet-header .header-fields h4.item-name-label.competence-name {
+.fvtt-mournblade-cyd-2-0.actor .sheet-header .header-fields .item.flexrow {
+ flex-wrap: nowrap !important;
+ align-items: center !important;
+}
+.fvtt-mournblade-cyd-2-0.actor .sheet-header .header-fields .item.flexrow h4 {
+ margin: 0 !important;
+ padding-top: 0 !important;
+}
+.fvtt-mournblade-cyd-2-0.actor .sheet-header .header-fields h4.item-name-label.competence-name,
+.fvtt-mournblade-cyd-2-0.actor .sheet-header .header-fields .item-name-label.competence-name,
+.fvtt-mournblade-cyd-2-0.actor .sheet-header .header-fields label.item-name-label.competence-name {
+ color: #1a1008 !important;
+ text-shadow: none !important;
+ font-weight: bold !important;
+ background: none !important;
+}
+.fvtt-mournblade-cyd-2-0.actor .sheet-header .header-fields h4.item-name-label.competence-name {
font-size: 0.75rem;
padding-top: 3px;
}
-.fvtt-mournblade.actor .sheet-header .header-fields .item-name-label.competence-name {
+.fvtt-mournblade-cyd-2-0.actor .sheet-header .header-fields .item-name-label.competence-name {
font-size: 0.75rem;
}
-.fvtt-mournblade.actor .sheet-header .header-fields label.item-name-label.competence-name {
+.fvtt-mournblade-cyd-2-0.actor .sheet-header .header-fields label.item-name-label.competence-name {
font-size: 0.7rem;
}
-.fvtt-mournblade.actor .sheet-header .header-fields .item-field-label-short {
+.fvtt-mournblade-cyd-2-0.actor .sheet-header .header-fields .item-field-label-short {
font-size: 0.8rem;
}
-.fvtt-mournblade.actor .sheet-header .header-fields .status-small-label {
+.fvtt-mournblade-cyd-2-0.actor .sheet-header .header-fields .status-small-label {
font-size: 0.8rem;
}
-.fvtt-mournblade.actor .sheet-tabs {
+.fvtt-mournblade-cyd-2-0.actor .sheet-header .sheet-mode-toggle {
+ background: transparent;
+ border: none;
+ color: #fff;
+ padding: 2px 6px;
+ cursor: pointer;
+ font-size: 0.75rem;
+ transition: all 0.2s ease;
+ margin-left: 8px;
+ height: auto;
+ line-height: 1.2;
+ text-shadow: 1px 1px 2px rgba(0, 0, 0, 0.8);
+}
+.fvtt-mournblade-cyd-2-0.actor .sheet-header .sheet-mode-toggle:hover {
+ color: #ffd700;
+ text-shadow: 0 0 8px rgba(255, 215, 0, 0.8);
+}
+.fvtt-mournblade-cyd-2-0.actor .sheet-tabs {
margin: 0;
padding: 0 0.5rem;
flex: 0 0 auto !important;
}
-.fvtt-mournblade.actor .sheet-body {
+.fvtt-mournblade-cyd-2-0.actor .sheet-body {
margin: 0;
padding: 0.5rem;
flex: 1 !important;
min-height: 0 !important;
overflow-y: auto !important;
}
-.fvtt-mournblade.actor .sheet-body .tab {
+.fvtt-mournblade-cyd-2-0.actor .sheet-body .tab {
padding: 0;
height: auto !important;
}
-.fvtt-mournblade.actor .sheet-body .tab:not(.active) {
+.fvtt-mournblade-cyd-2-0.actor .sheet-body .tab:not(.active) {
display: none;
}
-.fvtt-mournblade.actor .sheet-body .tab .grid,
-.fvtt-mournblade.actor .sheet-body .tab .grid-2col {
+.fvtt-mournblade-cyd-2-0.actor .sheet-body .tab .grid,
+.fvtt-mournblade-cyd-2-0.actor .sheet-body .tab .grid-2col {
height: auto;
overflow: visible;
}
-.fvtt-mournblade.actor .sheet-body .tab .sheet-box {
+.fvtt-mournblade-cyd-2-0.actor .sheet-body .tab .sheet-box {
height: auto;
}
-.fvtt-mournblade.actor .sheet-body .compact-list {
+.fvtt-mournblade-cyd-2-0.actor .sheet-body .compact-list {
list-style: none;
margin: 0;
padding: 0;
}
-.fvtt-mournblade.actor .sheet-body .compact-list li.item {
+.fvtt-mournblade-cyd-2-0.actor .sheet-body .compact-list li.item {
padding: 0.2rem 0.4rem;
margin-bottom: 0.15rem;
background: rgba(0, 0, 0, 0.1);
border: 1px solid rgba(139, 69, 19, 0.3);
border-radius: 3px;
}
-.fvtt-mournblade.actor .sheet-body .compact-list li.item:hover {
+.fvtt-mournblade-cyd-2-0.actor .sheet-body .compact-list li.item:hover {
background: rgba(0, 0, 0, 0.15);
}
-.fvtt-mournblade.actor .sheet-body .compact-list li.item.items-title-bg {
+.fvtt-mournblade-cyd-2-0.actor .sheet-body .compact-list li.item.items-title-bg {
background: rgba(0, 0, 0, 0.3);
border-color: rgba(139, 69, 19, 0.5);
font-weight: 600;
margin-bottom: 0.3rem;
}
-.fvtt-mournblade.actor .sheet-body .compact-list li.item.items-title-bg .item-name-label-header {
+.fvtt-mournblade-cyd-2-0.actor .sheet-body .compact-list li.item.items-title-bg .item-name-label-header {
color: #f5e6d3;
text-shadow: 1px 1px 1px rgba(0, 0, 0, 0.7);
}
-.fvtt-mournblade.actor .sheet-body .item-controls {
+.fvtt-mournblade-cyd-2-0.actor .sheet-body .item-controls {
display: flex;
align-items: center;
gap: 0.3rem;
justify-content: flex-end;
}
-.fvtt-mournblade.actor .sheet-body .item-controls .item-control {
+.fvtt-mournblade-cyd-2-0.actor .sheet-body .item-controls .item-control {
display: inline-flex;
align-items: center;
justify-content: center;
@@ -2610,70 +2641,70 @@ li {
border-radius: 3px;
transition: all 0.2s;
}
-.fvtt-mournblade.actor .sheet-body .item-controls .item-control:hover {
+.fvtt-mournblade-cyd-2-0.actor .sheet-body .item-controls .item-control:hover {
color: #2a1a0a;
background: rgba(139, 69, 19, 0.2);
transform: scale(1.1);
}
-.fvtt-mournblade.actor .sheet-body .item-controls .item-control i {
+.fvtt-mournblade-cyd-2-0.actor .sheet-body .item-controls .item-control i {
font-size: 0.85rem;
}
-.fvtt-mournblade.actor .sheet-body .item-controls .item-control.item-edit {
+.fvtt-mournblade-cyd-2-0.actor .sheet-body .item-controls .item-control.item-edit {
color: #4a7c59;
}
-.fvtt-mournblade.actor .sheet-body .item-controls .item-control.item-edit:hover {
+.fvtt-mournblade-cyd-2-0.actor .sheet-body .item-controls .item-control.item-edit:hover {
color: #2d5a3a;
background: rgba(74, 124, 89, 0.2);
}
-.fvtt-mournblade.actor .sheet-body .item-controls .item-control.item-delete {
+.fvtt-mournblade-cyd-2-0.actor .sheet-body .item-controls .item-control.item-delete {
color: #a04040;
}
-.fvtt-mournblade.actor .sheet-body .item-controls .item-control.item-delete:hover {
+.fvtt-mournblade-cyd-2-0.actor .sheet-body .item-controls .item-control.item-delete:hover {
color: #802020;
background: rgba(160, 64, 64, 0.2);
}
-.fvtt-mournblade.actor .sheet-body .item-controls .item-control.item-equip {
+.fvtt-mournblade-cyd-2-0.actor .sheet-body .item-controls .item-control.item-equip {
color: #6b5b3a;
}
-.fvtt-mournblade.actor .sheet-body .item-controls .item-control.item-equip:hover {
+.fvtt-mournblade-cyd-2-0.actor .sheet-body .item-controls .item-control.item-equip:hover {
color: #4a3a1a;
background: rgba(107, 91, 58, 0.2);
}
-.fvtt-mournblade.actor .sheet-body .item-controls .item-control.item-equip i.fa-circle {
+.fvtt-mournblade-cyd-2-0.actor .sheet-body .item-controls .item-control.item-equip i.fa-circle {
color: #4a7c59;
}
-.fvtt-mournblade.actor .sheet-body .item-controls .item-control.item-equip i.fa-genderless {
+.fvtt-mournblade-cyd-2-0.actor .sheet-body .item-controls .item-control.item-equip i.fa-genderless {
color: #8a6a4a;
}
-.fvtt-mournblade.actor .sheet-body .item-controls .item-control.item-add {
+.fvtt-mournblade-cyd-2-0.actor .sheet-body .item-controls .item-control.item-add {
color: #4a7c59;
}
-.fvtt-mournblade.actor .sheet-body .item-controls .item-control.item-add:hover {
+.fvtt-mournblade-cyd-2-0.actor .sheet-body .item-controls .item-control.item-add:hover {
color: #2d5a3a;
background: rgba(74, 124, 89, 0.2);
}
-.fvtt-mournblade.actor .sheet-body .item-controls-fixed {
+.fvtt-mournblade-cyd-2-0.actor .sheet-body .item-controls-fixed {
min-width: 3.2rem;
max-width: 3.2rem;
}
-.fvtt-mournblade.actor .sheet-body h4,
-.fvtt-mournblade.actor .sheet-body h3,
-.fvtt-mournblade.actor .sheet-body label,
-.fvtt-mournblade.actor .sheet-body span.item-name-label,
-.fvtt-mournblade.actor .sheet-body span.competence-name,
-.fvtt-mournblade.actor .sheet-body .label-name,
-.fvtt-mournblade.actor .sheet-body .generic-label,
-.fvtt-mournblade.actor .sheet-body .item-field-label-short,
-.fvtt-mournblade.actor .sheet-body .item-field-label-medium,
-.fvtt-mournblade.actor .sheet-body .item-field-label-long,
-.fvtt-mournblade.actor .sheet-body .short-label,
-.fvtt-mournblade.actor .sheet-body .items-title-text {
+.fvtt-mournblade-cyd-2-0.actor .sheet-body h4,
+.fvtt-mournblade-cyd-2-0.actor .sheet-body h3,
+.fvtt-mournblade-cyd-2-0.actor .sheet-body label,
+.fvtt-mournblade-cyd-2-0.actor .sheet-body span.item-name-label,
+.fvtt-mournblade-cyd-2-0.actor .sheet-body span.competence-name,
+.fvtt-mournblade-cyd-2-0.actor .sheet-body .label-name,
+.fvtt-mournblade-cyd-2-0.actor .sheet-body .generic-label,
+.fvtt-mournblade-cyd-2-0.actor .sheet-body .item-field-label-short,
+.fvtt-mournblade-cyd-2-0.actor .sheet-body .item-field-label-medium,
+.fvtt-mournblade-cyd-2-0.actor .sheet-body .item-field-label-long,
+.fvtt-mournblade-cyd-2-0.actor .sheet-body .short-label,
+.fvtt-mournblade-cyd-2-0.actor .sheet-body .items-title-text {
color: #3a2a1a !important;
text-shadow: 0px 0px 1px rgba(255, 255, 255, 0.3);
}
-.fvtt-mournblade.actor .sheet-body input[type="text"],
-.fvtt-mournblade.actor .sheet-body input[type="number"],
-.fvtt-mournblade.actor .sheet-body select {
+.fvtt-mournblade-cyd-2-0.actor .sheet-body input[type="text"],
+.fvtt-mournblade-cyd-2-0.actor .sheet-body input[type="number"],
+.fvtt-mournblade-cyd-2-0.actor .sheet-body select {
color: #2a1a0a;
background: rgba(255, 250, 240, 0.8);
border: 1px solid rgba(139, 69, 19, 0.5);
@@ -2681,24 +2712,24 @@ li {
padding: 0.15rem 0.3rem;
line-height: 1.2;
}
-.fvtt-mournblade.actor .sheet-body input[type="text"]:focus,
-.fvtt-mournblade.actor .sheet-body input[type="number"]:focus,
-.fvtt-mournblade.actor .sheet-body select:focus {
+.fvtt-mournblade-cyd-2-0.actor .sheet-body input[type="text"]:focus,
+.fvtt-mournblade-cyd-2-0.actor .sheet-body input[type="number"]:focus,
+.fvtt-mournblade-cyd-2-0.actor .sheet-body select:focus {
background: rgba(255, 255, 245, 0.95);
border-color: rgba(139, 69, 19, 0.8);
}
-.fvtt-mournblade.actor .sheet-body h3,
-.fvtt-mournblade.actor .sheet-body h4 {
+.fvtt-mournblade-cyd-2-0.actor .sheet-body h3,
+.fvtt-mournblade-cyd-2-0.actor .sheet-body h4 {
font-weight: bold;
color: #2a1a0a !important;
}
-.fvtt-mournblade.actor .sheet-body h4.item-name-label.competence-name {
+.fvtt-mournblade-cyd-2-0.actor .sheet-body h4.item-name-label.competence-name {
font-size: 0.85rem;
margin-top: 0.2rem;
margin-bottom: 0.3rem;
padding-top: 0;
}
-.fvtt-mournblade.actor .sheet-body .section-grid {
+.fvtt-mournblade-cyd-2-0.actor .sheet-body .section-grid {
display: flex;
flex-direction: column;
gap: 0.2rem;
@@ -2708,7 +2739,7 @@ li {
border: 2px solid rgba(139, 69, 19, 0.5);
border-radius: 4px;
}
-.fvtt-mournblade.actor .sheet-body .section-grid .section-title {
+.fvtt-mournblade-cyd-2-0.actor .sheet-body .section-grid .section-title {
font-size: 0.85rem;
font-weight: bold;
color: #f5e6d3;
@@ -2721,7 +2752,7 @@ li {
border-radius: 2px;
text-shadow: 1px 1px 2px rgba(0, 0, 0, 0.9);
}
-.fvtt-mournblade.actor .sheet-body .section-grid .grid-row {
+.fvtt-mournblade-cyd-2-0.actor .sheet-body .section-grid .grid-row {
display: grid;
grid-template-columns: 1fr 1fr;
align-items: center;
@@ -2731,50 +2762,50 @@ li {
border: 1px solid rgba(139, 69, 19, 0.4);
border-radius: 3px;
}
-.fvtt-mournblade.actor .sheet-body .section-grid .grid-row input {
+.fvtt-mournblade-cyd-2-0.actor .sheet-body .section-grid .grid-row input {
width: 60px;
min-width: 60px;
}
-.fvtt-mournblade.actor .sheet-body .section-grid .grid-row.attr-row {
+.fvtt-mournblade-cyd-2-0.actor .sheet-body .section-grid .grid-row.attr-row {
grid-template-columns: 40px 1fr auto;
gap: 0.5rem;
}
-.fvtt-mournblade.actor .sheet-body .section-grid .grid-row.attr-row .item-name-img {
+.fvtt-mournblade-cyd-2-0.actor .sheet-body .section-grid .grid-row.attr-row .item-name-img {
width: 32px;
height: 32px;
border-radius: 3px;
border: 1px solid rgba(139, 69, 19, 0.5);
}
-.fvtt-mournblade.actor .sheet-body .section-grid .grid-row.attr-row .label-name {
+.fvtt-mournblade-cyd-2-0.actor .sheet-body .section-grid .grid-row.attr-row .label-name {
display: flex;
align-items: center;
}
-.fvtt-mournblade.actor .sheet-body .section-grid .grid-row.attr-row .label-name a {
+.fvtt-mournblade-cyd-2-0.actor .sheet-body .section-grid .grid-row.attr-row .label-name a {
color: #f5e6d3;
text-shadow: 1px 1px 1px rgba(0, 0, 0, 0.7);
font-weight: 600;
cursor: pointer;
}
-.fvtt-mournblade.actor .sheet-body .section-grid .grid-row.attr-row .label-name a:hover {
+.fvtt-mournblade-cyd-2-0.actor .sheet-body .section-grid .grid-row.attr-row .label-name a:hover {
color: #fff;
text-shadow: 0 0 4px rgba(255, 200, 100, 0.8);
}
-.fvtt-mournblade.actor .sheet-body .section-grid .grid-row.attr-row select {
+.fvtt-mournblade-cyd-2-0.actor .sheet-body .section-grid .grid-row.attr-row select {
width: 80px;
}
-.fvtt-mournblade.actor .sheet-body .section-grid .grid-row .label-name {
+.fvtt-mournblade-cyd-2-0.actor .sheet-body .section-grid .grid-row .label-name {
font-weight: 600;
font-size: 0.9rem;
color: #d4c5b0;
text-shadow: 1px 1px 1px rgba(0, 0, 0, 0.7);
}
-.fvtt-mournblade.actor .sheet-body .section-grid .grid-row .stat-label {
+.fvtt-mournblade-cyd-2-0.actor .sheet-body .section-grid .grid-row .stat-label {
font-weight: 600;
font-size: 0.9rem;
color: #d4c5b0;
text-shadow: 1px 1px 1px rgba(0, 0, 0, 0.7);
}
-.fvtt-mournblade.actor .sheet-body .section-grid .grid-row .value-display {
+.fvtt-mournblade-cyd-2-0.actor .sheet-body .section-grid .grid-row .value-display {
text-align: center;
font-weight: bold;
font-size: 1rem;
@@ -2785,7 +2816,7 @@ li {
border: 1px solid rgba(139, 69, 19, 0.6);
text-shadow: 1px 1px 2px rgba(0, 0, 0, 0.9);
}
-.fvtt-mournblade.actor .sheet-body .section-grid .grid-row .malus-value {
+.fvtt-mournblade-cyd-2-0.actor .sheet-body .section-grid .grid-row .malus-value {
text-align: center;
font-weight: bold;
font-size: 1rem;
@@ -2796,20 +2827,20 @@ li {
border: 1px solid rgba(200, 50, 50, 0.6);
text-shadow: 1px 1px 2px rgba(0, 0, 0, 0.9);
}
-.fvtt-mournblade.actor .sheet-body .section-grid .grid-row.damage-row {
+.fvtt-mournblade-cyd-2-0.actor .sheet-body .section-grid .grid-row.damage-row {
grid-template-columns: 120px 1fr;
}
-.fvtt-mournblade.actor .sheet-body .section-grid .grid-row.damage-row .damage-label {
+.fvtt-mournblade-cyd-2-0.actor .sheet-body .section-grid .grid-row.damage-row .damage-label {
font-size: 0.95rem;
font-weight: 600;
}
-.fvtt-mournblade.actor .sheet-body .section-grid .grid-row.damage-row .damage-controls {
+.fvtt-mournblade-cyd-2-0.actor .sheet-body .section-grid .grid-row.damage-row .damage-controls {
display: flex;
align-items: center;
justify-content: center;
gap: 0.4rem;
}
-.fvtt-mournblade.actor .sheet-body .section-grid .grid-row.damage-row .damage-controls input {
+.fvtt-mournblade-cyd-2-0.actor .sheet-body .section-grid .grid-row.damage-row .damage-controls input {
width: 60px;
min-width: 60px;
flex-shrink: 0;
@@ -2817,7 +2848,7 @@ li {
font-size: 1.1rem;
font-weight: bold;
}
-.fvtt-mournblade.actor .sheet-body .section-grid .grid-row.damage-row .damage-controls .plus-minus-button {
+.fvtt-mournblade-cyd-2-0.actor .sheet-body .section-grid .grid-row.damage-row .damage-controls .plus-minus-button {
width: 30px;
height: 30px;
display: flex;
@@ -2832,51 +2863,51 @@ li {
cursor: pointer;
transition: all 0.15s;
}
-.fvtt-mournblade.actor .sheet-body .section-grid .grid-row.damage-row .damage-controls .plus-minus-button:hover {
+.fvtt-mournblade-cyd-2-0.actor .sheet-body .section-grid .grid-row.damage-row .damage-controls .plus-minus-button:hover {
background: linear-gradient(to bottom, rgba(230, 200, 160, 0.95), rgba(200, 170, 130, 0.95));
border-color: rgba(139, 69, 19, 0.8);
transform: scale(1.08);
}
-.fvtt-mournblade.actor .sheet-body .section-grid .grid-row.damage-row .damage-controls .plus-minus-button:active {
+.fvtt-mournblade-cyd-2-0.actor .sheet-body .section-grid .grid-row.damage-row .damage-controls .plus-minus-button:active {
transform: scale(0.95);
}
-.fvtt-mournblade.actor .sheet-body .section-grid .grid-row.soul-consumed-row {
+.fvtt-mournblade-cyd-2-0.actor .sheet-body .section-grid .grid-row.soul-consumed-row {
grid-template-columns: 120px 1fr;
}
-.fvtt-mournblade.actor .sheet-body .section-grid .grid-row.soul-malus-row {
+.fvtt-mournblade-cyd-2-0.actor .sheet-body .section-grid .grid-row.soul-malus-row {
grid-template-columns: 90px 1fr;
gap: 0.4rem;
}
-.fvtt-mournblade.actor .sheet-body .section-grid .grid-row.soul-malus-row .label-name {
+.fvtt-mournblade-cyd-2-0.actor .sheet-body .section-grid .grid-row.soul-malus-row .label-name {
font-size: 0.85rem;
}
-.fvtt-mournblade.actor .sheet-body .section-grid .grid-row.soul-malus-row .malus-value {
+.fvtt-mournblade-cyd-2-0.actor .sheet-body .section-grid .grid-row.soul-malus-row .malus-value {
font-size: 0.9rem;
padding: 0.2rem 0.3rem;
}
-.fvtt-mournblade.actor .sheet-body .section-grid .grid-row.malus-row {
+.fvtt-mournblade-cyd-2-0.actor .sheet-body .section-grid .grid-row.malus-row {
grid-template-columns: 55px 60px 75px 50px;
gap: 0.3rem;
}
-.fvtt-mournblade.actor .sheet-body .section-grid .grid-row.malus-row .label-name {
+.fvtt-mournblade-cyd-2-0.actor .sheet-body .section-grid .grid-row.malus-row .label-name {
font-size: 0.85rem;
}
-.fvtt-mournblade.actor .sheet-body .section-grid .grid-row.malus-row input {
+.fvtt-mournblade-cyd-2-0.actor .sheet-body .section-grid .grid-row.malus-row input {
width: 100%;
min-width: unset;
}
-.fvtt-mournblade.actor .sheet-body .section-grid .grid-row.malus-row .malus-value {
+.fvtt-mournblade-cyd-2-0.actor .sheet-body .section-grid .grid-row.malus-row .malus-value {
font-size: 0.9rem;
padding: 0.2rem 0.3rem;
}
-.fvtt-mournblade.actor .sheet-body .section-grid.combat-grid .grid-row.combat-stat {
+.fvtt-mournblade-cyd-2-0.actor .sheet-body .section-grid.combat-grid .grid-row.combat-stat {
grid-template-columns: 85px 50px 60px 55px;
gap: 0.4rem;
}
-.fvtt-mournblade.actor .sheet-body .section-grid.combat-grid .grid-row.combat-stat .stat-label {
+.fvtt-mournblade-cyd-2-0.actor .sheet-body .section-grid.combat-grid .grid-row.combat-stat .stat-label {
font-size: 0.85rem;
}
-.fvtt-mournblade.actor .sheet-body .section-grid.combat-grid .grid-row.combat-stat .stat-base {
+.fvtt-mournblade-cyd-2-0.actor .sheet-body .section-grid.combat-grid .grid-row.combat-stat .stat-base {
text-align: center;
font-weight: bold;
font-size: 0.85rem;
@@ -2887,12 +2918,12 @@ li {
border: 1px solid rgba(139, 69, 19, 0.6);
text-shadow: 1px 1px 2px rgba(0, 0, 0, 0.9);
}
-.fvtt-mournblade.actor .sheet-body .section-grid.combat-grid .grid-row.combat-stat input {
+.fvtt-mournblade-cyd-2-0.actor .sheet-body .section-grid.combat-grid .grid-row.combat-stat input {
width: 50px;
min-width: 50px;
text-align: center;
}
-.fvtt-mournblade.actor .sheet-body .section-grid.combat-grid .grid-row.combat-stat .stat-total {
+.fvtt-mournblade-cyd-2-0.actor .sheet-body .section-grid.combat-grid .grid-row.combat-stat .stat-total {
text-align: center;
font-weight: bold;
font-size: 0.85rem;
@@ -2903,10 +2934,10 @@ li {
border: 1px solid rgba(139, 69, 19, 0.6);
text-shadow: 1px 1px 2px rgba(0, 0, 0, 0.9);
}
-.fvtt-mournblade.actor .sheet-body .section-grid.combat-grid .grid-row.protection-row {
+.fvtt-mournblade-cyd-2-0.actor .sheet-body .section-grid.combat-grid .grid-row.protection-row {
grid-template-columns: 1fr 1fr;
}
-.fvtt-mournblade.actor .sheet-body .section-grid.combat-grid .grid-row.protection-row .protection-value {
+.fvtt-mournblade-cyd-2-0.actor .sheet-body .section-grid.combat-grid .grid-row.protection-row .protection-value {
text-align: center;
font-weight: bold;
font-size: 1.2rem;
@@ -2917,56 +2948,56 @@ li {
border: 1px solid rgba(139, 69, 19, 0.6);
text-shadow: 1px 1px 2px rgba(0, 0, 0, 0.9);
}
-.fvtt-mournblade.actor .sheet-body .action-buttons {
+.fvtt-mournblade-cyd-2-0.actor .sheet-body .action-buttons {
display: flex;
flex-direction: column;
gap: 0.3rem;
padding: 0.3rem 0;
}
-.fvtt-mournblade.actor .sheet-body .action-buttons button {
+.fvtt-mournblade-cyd-2-0.actor .sheet-body .action-buttons button {
margin: 0;
}
-.fvtt-mournblade.actor .sheet-body .action-buttons-row {
+.fvtt-mournblade-cyd-2-0.actor .sheet-body .action-buttons-row {
display: flex;
flex-direction: row;
align-items: center;
gap: 0.5rem;
padding: 0.3rem 0;
}
-.fvtt-mournblade.actor .sheet-body .action-buttons-row button {
+.fvtt-mournblade-cyd-2-0.actor .sheet-body .action-buttons-row button {
margin: 0;
flex: 1;
}
-.fvtt-mournblade.actor .sheet-body .action-buttons-row .mounted-checkbox {
+.fvtt-mournblade-cyd-2-0.actor .sheet-body .action-buttons-row .mounted-checkbox {
display: flex;
align-items: center;
gap: 0.4rem;
padding: 0.3rem 0.6rem;
white-space: nowrap;
}
-.fvtt-mournblade.actor .sheet-body .action-buttons-row .mounted-checkbox label {
+.fvtt-mournblade-cyd-2-0.actor .sheet-body .action-buttons-row .mounted-checkbox label {
margin: 0;
font-size: 0.9rem;
}
-.fvtt-mournblade.actor .sheet-body .action-buttons-row .mounted-checkbox input[type="checkbox"] {
+.fvtt-mournblade-cyd-2-0.actor .sheet-body .action-buttons-row .mounted-checkbox input[type="checkbox"] {
margin: 0;
cursor: pointer;
}
/* ==================== Creature Sheet Specific Styles ==================== */
-.fvtt-mournblade.actor.creature-sheet .background-sheet-header-creature {
+.fvtt-mournblade-cyd-2-0.actor.creature-sheet .background-sheet-header-creature {
background: linear-gradient(135deg, rgba(0, 60, 0, 0.15) 0%, rgba(20, 80, 20, 0.1) 100%);
border: 2px solid rgba(34, 139, 34, 0.5);
border-radius: 4px;
padding: 0;
}
-.fvtt-mournblade.actor.creature-sheet .sheet-box.color-bg-archetype {
+.fvtt-mournblade-cyd-2-0.actor.creature-sheet .sheet-box.color-bg-archetype {
background: linear-gradient(135deg, rgba(0, 40, 0, 0.08) 0%, rgba(20, 60, 20, 0.05) 100%);
}
-.fvtt-mournblade.actor.creature-sheet .sheet-header {
+.fvtt-mournblade-cyd-2-0.actor.creature-sheet .sheet-header {
flex: 0 0 auto !important;
padding: 0;
}
-.fvtt-mournblade.actor.creature-sheet .profile-img {
+.fvtt-mournblade-cyd-2-0.actor.creature-sheet .profile-img {
width: 80px;
height: 80px;
border-radius: 8px;
@@ -2975,32 +3006,32 @@ li {
cursor: pointer;
flex-shrink: 0;
}
-.fvtt-mournblade.actor.creature-sheet nav.tabs .item.active {
+.fvtt-mournblade-cyd-2-0.actor.creature-sheet nav.tabs .item.active {
border-bottom-color: rgba(34, 139, 34, 0.8);
color: #228b22;
}
-.fvtt-mournblade.actor.creature-sheet .section-title {
+.fvtt-mournblade-cyd-2-0.actor.creature-sheet .section-title {
color: #1a5a1a;
border-bottom-color: rgba(34, 139, 34, 0.3);
}
-.fvtt-mournblade.actor.creature-sheet .items-title-bg {
+.fvtt-mournblade-cyd-2-0.actor.creature-sheet .items-title-bg {
background: linear-gradient(135deg, rgba(0, 60, 0, 0.15) 0%, rgba(20, 80, 20, 0.1) 100%);
border-bottom: 1px solid rgba(34, 139, 34, 0.3);
}
-.fvtt-mournblade.actor.pnj-sheet .background-sheet-header-creature {
+.fvtt-mournblade-cyd-2-0.actor.pnj-sheet .background-sheet-header-creature {
background: linear-gradient(135deg, rgba(80, 40, 0, 0.15) 0%, rgba(100, 50, 0, 0.1) 100%);
border: 2px solid rgba(205, 127, 50, 0.5);
border-radius: 4px;
padding: 0;
}
-.fvtt-mournblade.actor.pnj-sheet .sheet-box.color-bg-archetype {
+.fvtt-mournblade-cyd-2-0.actor.pnj-sheet .sheet-box.color-bg-archetype {
background: linear-gradient(135deg, rgba(60, 30, 0, 0.08) 0%, rgba(80, 40, 0, 0.05) 100%);
}
-.fvtt-mournblade.actor.pnj-sheet .sheet-header {
+.fvtt-mournblade-cyd-2-0.actor.pnj-sheet .sheet-header {
flex: 0 0 auto !important;
padding: 0;
}
-.fvtt-mournblade.actor.pnj-sheet .profile-img {
+.fvtt-mournblade-cyd-2-0.actor.pnj-sheet .profile-img {
width: 80px;
height: 80px;
border-radius: 8px;
@@ -3009,15 +3040,15 @@ li {
cursor: pointer;
flex-shrink: 0;
}
-.fvtt-mournblade.actor.pnj-sheet nav.tabs .item.active {
+.fvtt-mournblade-cyd-2-0.actor.pnj-sheet nav.tabs .item.active {
border-bottom-color: rgba(205, 127, 50, 0.8);
color: #cd7f32;
}
-.fvtt-mournblade.actor.pnj-sheet .section-title {
+.fvtt-mournblade-cyd-2-0.actor.pnj-sheet .section-title {
color: #b8734d;
border-bottom-color: rgba(205, 127, 50, 0.3);
}
-.fvtt-mournblade.actor.pnj-sheet .items-title-bg {
+.fvtt-mournblade-cyd-2-0.actor.pnj-sheet .items-title-bg {
background: linear-gradient(135deg, rgba(80, 40, 0, 0.15) 0%, rgba(100, 50, 0, 0.1) 100%);
border-bottom: 1px solid rgba(205, 127, 50, 0.3);
}
diff --git a/styles/simple.css b/styles/simple.css
index 3f8c471..b3a5a0f 100644
--- a/styles/simple.css
+++ b/styles/simple.css
@@ -110,7 +110,7 @@
/* For nav and title */
.window-app input,
- .fvtt-mournblade-cyd2 .item-form,
+ .fvtt-mournblade-cyd-2-0 .item-form,
.sheet header.sheet-header .flex-group-center.flex-compteurs,
.sheet header.sheet-header .flex-group-center.flex-fatigue,
select,
@@ -122,15 +122,15 @@
font-size: 0.8rem;
}
- .fvtt-mournblade-cyd2 .sheet-header input,
- .fvtt-mournblade-cyd2 .sheet-header select {
+ .fvtt-mournblade-cyd-2-0 .sheet-header input,
+ .fvtt-mournblade-cyd-2-0 .sheet-header select {
color: black;
min-width: 3rem;
max-width: 3rem;
text-align: center;
}
- .fvtt-mournblade-cyd2 .sheet-header .liste-etat {
+ .fvtt-mournblade-cyd-2-0 .sheet-header .liste-etat {
min-width: 6rem;
max-width: 6rem;
}
@@ -288,7 +288,7 @@
/* Styles limited to foundryvtt-vadentis sheets */
- .fvtt-mournblade-cyd2 .sheet-header {
+ .fvtt-mournblade-cyd-2-0 .sheet-header {
-webkit-box-flex: 0;
-ms-flex: 0 0 210px;
flex: 0 0 210px;
@@ -318,7 +318,7 @@
width: 100%;
}
- .fvtt-mournblade-cyd2 .sheet-header .profile-img {
+ .fvtt-mournblade-cyd-2-0 .sheet-header .profile-img {
-webkit-box-flex: 0;
-ms-flex: 0 0 128px;
flex: 0 0 128px;
@@ -359,13 +359,13 @@
vertical-align: bottom;
}
- .fvtt-mournblade-cyd2 .sheet-header .header-fields {
+ .fvtt-mournblade-cyd-2-0 .sheet-header .header-fields {
-webkit-box-flex: 1;
-ms-flex: 1;
flex: 1;
}
- .fvtt-mournblade-cyd2 .sheet-header h1.charname {
+ .fvtt-mournblade-cyd-2-0 .sheet-header h1.charname {
height: 50px;
padding: 0px;
margin: 5px 0;
@@ -375,7 +375,7 @@
font-family: "CentaurMT";
}
- .fvtt-mournblade-cyd2 .sheet-header h1.charname input {
+ .fvtt-mournblade-cyd-2-0 .sheet-header h1.charname input {
width: 100%;
height: 100%;
margin: 0;
@@ -386,22 +386,22 @@
text-align: left;
}
- .fvtt-mournblade-cyd2 .sheet-tabs {
+ .fvtt-mournblade-cyd-2-0 .sheet-tabs {
-webkit-box-flex: 0;
-ms-flex: 0;
flex: 0;
}
- .fvtt-mournblade-cyd2 .sheet-body,
- .fvtt-mournblade-cyd2 .sheet-body .tab,
- .fvtt-mournblade-cyd2 .sheet-body .tab .editor {
+ .fvtt-mournblade-cyd-2-0 .sheet-body,
+ .fvtt-mournblade-cyd-2-0 .sheet-body .tab,
+ .fvtt-mournblade-cyd-2-0 .sheet-body .tab .editor {
height: 100%;
font-size: 0.8rem;
color: rgba(0, 0, 0, 0.9)
}
- .fvtt-mournblade-cyd2 .sheet-body input,
- .fvtt-mournblade-cyd2 .sheet-body select {
+ .fvtt-mournblade-cyd-2-0 .sheet-body input,
+ .fvtt-mournblade-cyd-2-0 .sheet-body select {
color: rgba(0, 0, 0, 0.9)
}
@@ -423,70 +423,70 @@
padding: 0 3px;
}
- .fvtt-mournblade-cyd2 .tox .tox-editor-container {
+ .fvtt-mournblade-cyd-2-0 .tox .tox-editor-container {
background: #fff;
}
- .fvtt-mournblade-cyd2 .tox .tox-edit-area {
+ .fvtt-mournblade-cyd-2-0 .tox .tox-edit-area {
padding: 0 8px;
}
- .fvtt-mournblade-cyd2 .resource-label {
+ .fvtt-mournblade-cyd-2-0 .resource-label {
font-weight: bold;
text-transform: uppercase;
}
- .fvtt-mournblade-cyd2 .tabs {
+ .fvtt-mournblade-cyd-2-0 .tabs {
height: 40px;
border-top: 1px solid #AAA;
border-bottom: 1px solid #AAA;
color: #000000;
}
- .fvtt-mournblade-cyd2 .tabs .item {
+ .fvtt-mournblade-cyd-2-0 .tabs .item {
/*line-height: 40px;*/
font-weight: bold;
}
- .fvtt-mournblade-cyd2 .tabs .item.active {
+ .fvtt-mournblade-cyd-2-0 .tabs .item.active {
text-decoration: underline;
text-shadow: none;
}
- .fvtt-mournblade-cyd2 .items-list {
+ .fvtt-mournblade-cyd-2-0 .items-list {
list-style: none;
margin: 1px 0;
padding: 0;
overflow-y: auto;
}
- .fvtt-mournblade-cyd2 .items-list .item-header {
+ .fvtt-mournblade-cyd-2-0 .items-list .item-header {
font-weight: bold;
}
- .fvtt-mournblade-cyd2 .items-list .item {
+ .fvtt-mournblade-cyd-2-0 .items-list .item {
height: 30px;
line-height: 24px;
padding: 1px 0;
border-bottom: 1px solid #BBB;
}
- .fvtt-mournblade-cyd2 .items-list .item .item-image {
+ .fvtt-mournblade-cyd-2-0 .items-list .item .item-image {
-webkit-box-flex: 0;
-ms-flex: 0 0 24px;
flex: 0 0 24px;
margin-right: 5px;
}
- .fvtt-mournblade-cyd2 .items-list .item img {
+ .fvtt-mournblade-cyd-2-0 .items-list .item img {
display: block;
}
- .fvtt-mournblade-cyd2 .items-list .item-name {
+ .fvtt-mournblade-cyd-2-0 .items-list .item-name {
margin: 0;
}
- .fvtt-mournblade-cyd2 .items-list .item-controls {
+ .fvtt-mournblade-cyd-2-0 .items-list .item-controls {
-webkit-box-flex: 0;
-ms-flex: 0 0 86px;
flex: 0 0 86px;
diff --git a/system.json b/system.json
index e969eea..9ff08ab 100644
--- a/system.json
+++ b/system.json
@@ -26,6 +26,40 @@
"flags": {}
}
],
+ "documentTypes": {
+ "Actor": {
+ "personnage": {
+ "htmlFields": ["biodata.description", "biodata.notes", "biodata.gmnotes"]
+ },
+ "creature": {
+ "htmlFields": ["biodata.description", "biodata.notes", "biodata.gmnotes"]
+ }
+ },
+ "Item": {
+ "competence": { "htmlFields": ["description"] },
+ "talent": { "htmlFields": ["description"] },
+ "historique": { "htmlFields": ["description"] },
+ "profil": { "htmlFields": ["description"] },
+ "arme": { "htmlFields": ["description"] },
+ "protection": { "htmlFields": ["description"] },
+ "monnaie": { "htmlFields": ["description"] },
+ "equipement": { "htmlFields": ["description"] },
+ "ressource": { "htmlFields": ["description"] },
+ "don": { "htmlFields": ["description"] },
+ "pacte": { "htmlFields": ["description"] },
+ "rune": { "htmlFields": ["description"] },
+ "runeeffect": { "htmlFields": ["description"] },
+ "tendance": { "htmlFields": ["description"] },
+ "traitchaotique": { "htmlFields": ["description"] },
+ "traitespece": { "htmlFields": ["description"] }
+ }
+ },
+ "flags": {
+ "hotReload": {
+ "extensions": ["css", "hbs", "json"],
+ "paths": ["styles", "templates", "lang/fr.json"]
+ }
+ },
"packFolders": [
{
"name": "MournbladeCYD2",
diff --git a/templates/actor-sheet.hbs b/templates/actor-sheet.hbs
index 8ce5bdb..a8bed8d 100644
--- a/templates/actor-sheet.hbs
+++ b/templates/actor-sheet.hbs
@@ -1,12 +1,12 @@
-