First actor sheet
This commit is contained in:
		| @@ -13,10 +13,10 @@ export class Hero6ActorSheet extends ActorSheet { | ||||
|  | ||||
|     return mergeObject(super.defaultOptions, { | ||||
|       classes: ["fvtt-hero-system-6", "sheet", "actor"], | ||||
|       template: "systems/fvtt-hero-system-6/templates/actor-sheet.hbs", | ||||
|       template: "systems/fvtt-hero-system-6/templates/actors/actor-sheet.hbs", | ||||
|       width: 960, | ||||
|       height: 720, | ||||
|       tabs: [{ navSelector: ".sheet-tabs", contentSelector: ".sheet-body", initial: "skills" }], | ||||
|       tabs: [{ navSelector: ".sheet-tabs", contentSelector: ".sheet-body", initial: "main" }], | ||||
|       dragDrop: [{ dragSelector: ".item-list .item", dropSelector: null }], | ||||
|       editScore: true | ||||
|     }); | ||||
| @@ -24,8 +24,7 @@ export class Hero6ActorSheet extends ActorSheet { | ||||
|  | ||||
|   /* -------------------------------------------- */ | ||||
|   async getData() { | ||||
|     const objectData = this.object.system | ||||
|     let actorData = duplicate(objectData) | ||||
|     const objectData = duplicate(this.object.system) | ||||
|  | ||||
|     let formData = { | ||||
|       title: this.title, | ||||
| @@ -35,24 +34,21 @@ export class Hero6ActorSheet extends ActorSheet { | ||||
|       name: this.actor.name, | ||||
|       editable: this.isEditable, | ||||
|       cssClass: this.isEditable ? "editable" : "locked", | ||||
|       data: actorData, | ||||
|       system: objectData, | ||||
|       characteristics: this.actor.prepareCharac(), | ||||
|       limited: this.object.limited, | ||||
|       skills: this.actor.getSkills( ), | ||||
|       weapons: this.actor.checkAndPrepareEquipments( duplicate(this.actor.getWeapons()) ), | ||||
|       armors: this.actor.checkAndPrepareEquipments( duplicate(this.actor.getArmors())), | ||||
|       shields: this.actor.checkAndPrepareEquipments( duplicate(this.actor.getShields())), | ||||
|       spells: this.actor.checkAndPrepareEquipments( duplicate(this.actor.getLore())), | ||||
|       equipments: this.actor.checkAndPrepareEquipments(duplicate(this.actor.getEquipmentsOnly()) ), | ||||
|       equippedWeapons: this.actor.checkAndPrepareEquipments(duplicate(this.actor.getEquippedWeapons()) ), | ||||
|       equippedArmor: this.actor.getEquippedArmor(), | ||||
|       equippedShield: this.actor.getEquippedShield(), | ||||
|       feats: duplicate(this.actor.getFeats()), | ||||
|       subActors: duplicate(this.actor.getSubActors()), | ||||
|       race: duplicate(this.actor.getRace()), | ||||
|       moneys: duplicate(this.actor.getMoneys()), | ||||
|       encCapacity: this.actor.getEncumbranceCapacity(), | ||||
|       saveRolls: this.actor.getSaveRoll(), | ||||
|       conditions: this.actor.getConditions(), | ||||
|       description: await TextEditor.enrichHTML(this.object.system.biodata.description, {async: true}), | ||||
|       notes: await TextEditor.enrichHTML(this.object.system.biodata.notes, {async: true}), | ||||
|       containersTree: this.actor.containersTree, | ||||
| @@ -139,37 +135,17 @@ export class Hero6ActorSheet extends ActorSheet { | ||||
|       this.actor.incDecAmmo( li.data("item-id"), +1 ) | ||||
|     } ); | ||||
|              | ||||
|     html.find('.roll-ability').click((event) => { | ||||
|       const abilityKey = $(event.currentTarget).data("ability-key"); | ||||
|       this.actor.rollAbility(abilityKey); | ||||
|     html.find('.roll-charac').click((event) => { | ||||
|       const characKey = $(event.currentTarget).data("charac-key"); | ||||
|       this.actor.rollCharac(characKey); | ||||
|     }); | ||||
|     html.find('.roll-skill').click((event) => { | ||||
|       const li = $(event.currentTarget).parents(".item") | ||||
|       const skillId = li.data("item-id") | ||||
|       this.actor.rollSkill(skillId) | ||||
|     });     | ||||
|  | ||||
|     html.find('.roll-weapon').click((event) => { | ||||
|       const li = $(event.currentTarget).parents(".item"); | ||||
|       const skillId = li.data("item-id") | ||||
|       this.actor.rollWeapon(skillId) | ||||
|     }); | ||||
|     html.find('.roll-armor-die').click((event) => { | ||||
|       this.actor.rollArmorDie() | ||||
|     }); | ||||
|     html.find('.roll-shield-die').click((event) => { | ||||
|       this.actor.rollShieldDie() | ||||
|     }); | ||||
|     html.find('.roll-target-die').click((event) => { | ||||
|       this.actor.rollDefenseRanged() | ||||
|     }); | ||||
|      | ||||
|     html.find('.roll-save').click((event) => { | ||||
|       const saveKey = $(event.currentTarget).data("save-key") | ||||
|       this.actor.rollSave(saveKey) | ||||
|     }); | ||||
|      | ||||
|      | ||||
|     | ||||
|     html.find('.lock-unlock-sheet').click((event) => { | ||||
|       this.options.editScore = !this.options.editScore; | ||||
|       this.render(true); | ||||
|   | ||||
| @@ -64,28 +64,8 @@ export class Hero6Actor extends Actor { | ||||
|   /* -------------------------------------------- */ | ||||
|   computeHitPoints() { | ||||
|     if (this.type == "character") { | ||||
|       let hp = duplicate(this.system.secondary.hp) | ||||
|       let max = (this.system.abilities.str.value + this.system.abilities.con.value) * 6 | ||||
|       if (max != hp.max || hp.value > max) { | ||||
|         hp.max = max | ||||
|         hp.value = max // Init case | ||||
|         this.update({ 'system.secondary.hp': hp }) | ||||
|       } | ||||
|     } | ||||
|   } | ||||
|   /* -------------------------------------------- */ | ||||
|   computeEffortPoints() { | ||||
|     if (this.type == "character") { | ||||
|       let effort = duplicate(this.system.secondary.effort) | ||||
|       let max = (this.system.abilities.con.value + this.system.abilities.int.value) * 6 | ||||
|       if (max != effort.max || effort.value > max) { | ||||
|         effort.max = max | ||||
|         effort.value = max // Init case | ||||
|         this.update({ 'system.secondary.effort': effort }) | ||||
|       } | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   /* -------------------------------------------- */ | ||||
|   prepareDerivedData() { | ||||
|  | ||||
| @@ -93,7 +73,6 @@ export class Hero6Actor extends Actor { | ||||
|       this.system.encCapacity = this.getEncumbranceCapacity() | ||||
|       this.buildContainerTree() | ||||
|       this.computeHitPoints() | ||||
|       this.computeEffortPoints() | ||||
|     } | ||||
|  | ||||
|     super.prepareDerivedData(); | ||||
| @@ -116,29 +95,6 @@ export class Hero6Actor extends Actor { | ||||
|     Hero6Utility.sortArrayObjectsByName(comp) | ||||
|     return comp; | ||||
|   } | ||||
|   /* -------------------------------------------- */ | ||||
|   getFeats() { | ||||
|     let comp = duplicate(this.items.filter(item => item.type == 'feat') || []); | ||||
|     Hero6Utility.sortArrayObjectsByName(comp) | ||||
|     return comp; | ||||
|   } | ||||
|   /* -------------------------------------------- */ | ||||
|   getFeatsWithDie() { | ||||
|     let comp = duplicate(this.items.filter(item => item.type == 'feat' && item.system.isfeatdie) || []); | ||||
|     Hero6Utility.sortArrayObjectsByName(comp) | ||||
|     return comp; | ||||
|   } | ||||
|   getFeatsWithSL() { | ||||
|     let comp = duplicate(this.items.filter(item => item.type == 'feat' && item.system.issl) || []); | ||||
|     Hero6Utility.sortArrayObjectsByName(comp) | ||||
|     return comp; | ||||
|   } | ||||
|   /* -------------------------------------------- */ | ||||
|   getLore() { | ||||
|     let comp = duplicate(this.items.filter(item => item.type == 'spell') || []); | ||||
|     Hero6Utility.sortArrayObjectsByName(comp) | ||||
|     return comp; | ||||
|   } | ||||
|   getEquippedWeapons() { | ||||
|     let comp = duplicate(this.items.filter(item => item.type == 'weapon' && item.system.equipped) || []); | ||||
|     Hero6Utility.sortArrayObjectsByName(comp) | ||||
| @@ -211,20 +167,10 @@ export class Hero6Actor extends Actor { | ||||
|   /* -------------------------------------------- */ | ||||
|   getSkills() { | ||||
|     let comp = duplicate(this.items.filter(item => item.type == 'skill') || []) | ||||
|     for (let skill of comp) { | ||||
|       Hero6Utility.updateSkill(skill) | ||||
|     } | ||||
|     Hero6Utility.sortArrayObjectsByName(comp) | ||||
|     return comp | ||||
|   } | ||||
|  | ||||
|   /* -------------------------------------------- */ | ||||
|   getRelevantAbility(statKey) { | ||||
|     let comp = duplicate(this.items.filter(item => item.type == 'skill' && item.system.ability == ability) || []); | ||||
|     return comp; | ||||
|   } | ||||
|  | ||||
|  | ||||
|   /* -------------------------------------------- */ | ||||
|   async equipItem(itemId) { | ||||
|     let item = this.items.find(item => item.id == itemId) | ||||
| @@ -268,27 +214,6 @@ export class Hero6Actor extends Actor { | ||||
|     return duplicate(this.items.filter(item => item.type == "equipment") || []) | ||||
|   } | ||||
|  | ||||
|   /* ------------------------------------------- */ | ||||
|   getSaveRoll() { | ||||
|     return { | ||||
|       reflex: { | ||||
|         "label": "Reflex Save", | ||||
|         "img": "systems/fvtt-hero-system-6/images/icons/saves/reflex_save.webp", | ||||
|         "value": this.system.abilities.agi.value + this.system.abilities.wit.value | ||||
|       }, | ||||
|       fortitude: { | ||||
|         "label": "Fortitude Save", | ||||
|         "img": "systems/fvtt-hero-system-6/images/icons/saves/fortitude_save.webp", | ||||
|         "value": this.system.abilities.str.value + this.system.abilities.con.value | ||||
|       }, | ||||
|       willpower: { | ||||
|         "label": "Willpower Save", | ||||
|         "img": "systems/fvtt-hero-system-6/images/icons/saves/will_save.webp", | ||||
|         "value": this.system.abilities.int.value + this.system.abilities.cha.value | ||||
|       } | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   /* ------------------------------------------- */ | ||||
|   async buildContainerTree() { | ||||
|     let equipments = duplicate(this.items.filter(item => item.type == "equipment") || []) | ||||
| @@ -332,15 +257,6 @@ export class Hero6Actor extends Actor { | ||||
|  | ||||
|   } | ||||
|  | ||||
|   /* -------------------------------------------- */ | ||||
|   async rollArmor(rollData) { | ||||
|     let armor = this.getEquippedArmor() | ||||
|     if (armor) { | ||||
|  | ||||
|     } | ||||
|     return { armor: "none" } | ||||
|   } | ||||
|  | ||||
|   /* -------------------------------------------- */ | ||||
|   async incDecHP(formula) { | ||||
|     let dmgRoll = new Roll(formula+"[dark-starsorange]").roll({ async: false }) | ||||
| @@ -351,11 +267,6 @@ export class Hero6Actor extends Actor { | ||||
|     return Number(dmgRoll.total) | ||||
|   } | ||||
|  | ||||
|   /* -------------------------------------------- */ | ||||
|   getAbility(abilKey) { | ||||
|     return this.system.abilities[abilKey]; | ||||
|   } | ||||
|  | ||||
|   /* -------------------------------------------- */ | ||||
|   async addObjectToContainer(itemId, containerId) { | ||||
|     let container = this.items.find(item => item.id == containerId && item.system.iscontainer) | ||||
| @@ -429,9 +340,16 @@ export class Hero6Actor extends Actor { | ||||
|   } | ||||
|  | ||||
|   /* -------------------------------------------- */ | ||||
|   syncRoll(rollData) { | ||||
|     this.lastRollId = rollData.rollId; | ||||
|     Hero6Utility.saveRollData(rollData); | ||||
|   prepareCharacValues( charac) { | ||||
|     charac.total = charac.base+charac.value | ||||
|     charac.roll = 9 + Math.floor((charac.base+charac.value)/5) | ||||
|   } | ||||
|   prepareCharac() { | ||||
|     let characs = duplicate(this.system.characteristics) | ||||
|     for(let key in characs) { | ||||
|       this.prepareCharacValues( characs[key]) | ||||
|     } | ||||
|     return characs | ||||
|   } | ||||
|  | ||||
|   /* -------------------------------------------- */ | ||||
| @@ -457,31 +375,6 @@ export class Hero6Actor extends Actor { | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   /* -------------------------------------------- */ | ||||
|   async incrementSkillExp(skillId, inc) { | ||||
|     let skill = this.items.get(skillId) | ||||
|     if (skill) { | ||||
|       await this.updateEmbeddedDocuments('Item', [{ _id: skill.id, 'system.exp': skill.system.exp + inc }]) | ||||
|       let chatData = { | ||||
|         user: game.user.id, | ||||
|         rollMode: game.settings.get("core", "rollMode"), | ||||
|         whisper: [game.user.id].concat(ChatMessage.getWhisperRecipients('GM')), | ||||
|         content: `<div>${this.name} has gained 1 exp in the skill ${skill.name} (exp = ${skill.system.exp})</div` | ||||
|       } | ||||
|       ChatMessage.create(chatData) | ||||
|       if (skill.system.exp >= 25) { | ||||
|         await this.updateEmbeddedDocuments('Item', [{ _id: skill.id, 'system.exp': 0, 'system.explevel': skill.system.explevel + 1 }]) | ||||
|         let chatData = { | ||||
|           user: game.user.id, | ||||
|           rollMode: game.settings.get("core", "rollMode"), | ||||
|           whisper: [game.user.id].concat(ChatMessage.getWhisperRecipients('GM')), | ||||
|           content: `<div>${this.name} has gained 1 exp SL in the skill ${skill.name} (new exp SL :  ${skill.system.explevel}) !</div` | ||||
|         } | ||||
|         ChatMessage.create(chatData) | ||||
|       } | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   /* -------------------------------------------- */ | ||||
|   async incDecQuantity(objetId, incDec = 0) { | ||||
|     let objetQ = this.items.get(objetId) | ||||
| @@ -504,61 +397,16 @@ export class Hero6Actor extends Actor { | ||||
|   } | ||||
|  | ||||
|   /* -------------------------------------------- */ | ||||
|   isForcedAdvantage() { | ||||
|     return this.items.find(cond => cond.type == "condition" && cond.system.advantage) | ||||
|   } | ||||
|   isForcedDisadvantage() { | ||||
|     return this.items.find(cond => cond.type == "condition" && cond.system.disadvantage) | ||||
|   } | ||||
|   isForcedRollAdvantage() { | ||||
|     return this.items.find(cond => cond.type == "condition" && cond.system.rolladvantage) | ||||
|   } | ||||
|   isForcedRollDisadvantage() { | ||||
|     return this.items.find(cond => cond.type == "condition" && cond.system.rolldisadvantage) | ||||
|   } | ||||
|   isNoAdvantage() { | ||||
|     return this.items.find(cond => cond.type == "condition" && cond.system.noadvantage) | ||||
|   } | ||||
|   isNoAction() { | ||||
|     return this.items.find(cond => cond.type == "condition" && cond.system.noaction) | ||||
|   } | ||||
|   isAttackDisadvantage() { | ||||
|     return this.items.find(cond => cond.type == "condition" && cond.system.attackdisadvantage) | ||||
|   } | ||||
|   isDefenseDisadvantage() { | ||||
|     return this.items.find(cond => cond.type == "condition" && cond.system.defensedisadvantage) | ||||
|   } | ||||
|   isAttackerAdvantage() { | ||||
|     return this.items.find(cond => cond.type == "condition" && cond.system.targetadvantage) | ||||
|   } | ||||
|  | ||||
|   /* -------------------------------------------- */ | ||||
|   getCommonRollData(abilityKey = undefined) { | ||||
|     let noAction = this.isNoAction() | ||||
|     if (noAction) { | ||||
|       ui.notifications.warn("You can't do any actions du to the condition : " + noAction.name) | ||||
|       return | ||||
|     } | ||||
|  | ||||
|   getCommonRollData(chKey = undefined) { | ||||
|     let rollData = Hero6Utility.getBasicRollData() | ||||
|     rollData.alias = this.name | ||||
|     rollData.actorImg = this.img | ||||
|     rollData.actorId = this.id | ||||
|     rollData.img = this.img | ||||
|     rollData.featsDie = this.getFeatsWithDie() | ||||
|     rollData.featsSL = this.getFeatsWithSL() | ||||
|     rollData.armors = this.getArmors() | ||||
|     rollData.conditions = this.getConditions() | ||||
|     rollData.featDieName = "none" | ||||
|     rollData.featSLName = "none" | ||||
|     rollData.rollAdvantage = "none" | ||||
|     rollData.advantage = "none" | ||||
|     rollData.disadvantage = "none" | ||||
|     rollData.forceAdvantage = this.isForcedAdvantage() | ||||
|     rollData.forceDisadvantage = this.isForcedDisadvantage() | ||||
|     rollData.forceRollAdvantage = this.isForcedRollAdvantage() | ||||
|     rollData.forceRollDisadvantage = this.isForcedRollDisadvantage() | ||||
|     rollData.noAdvantage = this.isNoAdvantage() | ||||
|     if (chKey) { | ||||
|       rollData.charac = duplicate(this.system.characteristics[chKey]) | ||||
|       this.prepareCharacValues(rollData.charac) | ||||
|     } | ||||
|     if (rollData.defenderTokenId) { | ||||
|       let defenderToken = game.canvas.tokens.get(rollData.defenderTokenId) | ||||
|       let defender = defenderToken.actor | ||||
| @@ -581,26 +429,20 @@ export class Hero6Actor extends Actor { | ||||
|         rollData.advantageFromTarget = true | ||||
|       } | ||||
|     } | ||||
|  | ||||
|     if (abilityKey) { | ||||
|       rollData.ability = this.getAbility(abilityKey) | ||||
|       rollData.selectedKill = undefined | ||||
|     } | ||||
|  | ||||
|     console.log("ROLLDATA", rollData) | ||||
|  | ||||
|     return rollData | ||||
|   } | ||||
|  | ||||
|   /* -------------------------------------------- */ | ||||
|   rollAbility(abilityKey) { | ||||
|     let rollData = this.getCommonRollData(abilityKey) | ||||
|     rollData.mode = "ability" | ||||
|   rollCharac(chKey) { | ||||
|     let rollData = this.getCommonRollData(chKey) | ||||
|     rollData.mode = "charac" | ||||
|     if (rollData.target) { | ||||
|       ui.notifications.warn("You are targetting a token with a skill : please use a Weapon instead.") | ||||
|       return | ||||
|     } | ||||
|     Hero6Utility.rollHero6(rollData) | ||||
|     this.startRoll(rollData) | ||||
|   } | ||||
|  | ||||
|   /* -------------------------------------------- */ | ||||
| @@ -655,152 +497,8 @@ export class Hero6Actor extends Actor { | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   /* -------------------------------------------- */ | ||||
|   rollDefenseMelee(attackRollData) { | ||||
|     let weapon = this.items.get(attackRollData.defenseWeaponId) | ||||
|     if (weapon) { | ||||
|       weapon = duplicate(weapon) | ||||
|       let skill = this.items.find(item => item.name.toLowerCase() == weapon.system.skill.toLowerCase()) | ||||
|       if (skill) { | ||||
|         skill = duplicate(skill) | ||||
|         Hero6Utility.updateSkill(skill) | ||||
|         let abilityKey = skill.system.ability | ||||
|         let rollData = this.getCommonRollData(abilityKey) | ||||
|         rollData.defenderTokenId = undefined // Cleanup | ||||
|         rollData.mode = "weapondefense" | ||||
|         rollData.shield = this.getEquippedShield() | ||||
|         rollData.attackRollData = duplicate(attackRollData) | ||||
|         rollData.skill = skill | ||||
|         rollData.weapon = weapon | ||||
|         rollData.img = weapon.img | ||||
|         if (!rollData.forceDisadvantage) { // This is an attack, check if disadvantaged | ||||
|           rollData.forceDisadvantage = this.isDefenseDisadvantage() | ||||
|         } | ||||
|  | ||||
|         this.startRoll(rollData) | ||||
|       } else { | ||||
|         ui.notifications.warn("Unable to find the relevant skill for weapon " + weapon.name) | ||||
|       } | ||||
|     } else { | ||||
|       ui.notifications.warn("Weapon not found ! ") | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   /* -------------------------------------------- */ | ||||
|   rollDefenseRanged(attackRollData) { | ||||
|     let rollData = this.getCommonRollData() | ||||
|     rollData.defenderTokenId = undefined // Cleanup | ||||
|     rollData.mode = "rangeddefense" | ||||
|     if ( attackRollData) { | ||||
|       rollData.attackRollData = duplicate(attackRollData) | ||||
|       rollData.effectiveRange = Hero6Utility.getWeaponRange(attackRollData.weapon) | ||||
|       rollData.tokensDistance = attackRollData.tokensDistance // QoL copy | ||||
|     } | ||||
|     rollData.sizeDice = Hero6Utility.getSizeDice(this.system.biodata.size) | ||||
|     rollData.distanceBonusDice = 0 //Math.max(0, Math.floor((rollData.tokensDistance - rollData.effectiveRange) + 0.5)) | ||||
|     rollData.hasCover = "none" | ||||
|     rollData.situational = "none" | ||||
|     rollData.useshield = false | ||||
|     rollData.shield = this.getEquippedShield() | ||||
|     this.startRoll(rollData) | ||||
|   } | ||||
|  | ||||
|   /* -------------------------------------------- */ | ||||
|   rollShieldDie() { | ||||
|     let shield = this.getEquippedShield() | ||||
|     if (shield) { | ||||
|       shield = duplicate(shield) | ||||
|       let rollData = this.getCommonRollData() | ||||
|       rollData.mode = "shield" | ||||
|       rollData.shield = shield | ||||
|       rollData.useshield = true | ||||
|       rollData.img = shield.img | ||||
|       this.startRoll(rollData) | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   /* -------------------------------------------- */ | ||||
|   async rollArmorDie(rollData = undefined) { | ||||
|     let armor = this.getEquippedArmor() | ||||
|     if (armor) { | ||||
|       armor = duplicate(armor) | ||||
|       let reduce = 0 | ||||
|       let multiply = 1 | ||||
|       let disadvantage = false | ||||
|       let advantage = false | ||||
|       let messages = ["Armor applied"] | ||||
|  | ||||
|       if (rollData) { | ||||
|         if (Hero6Utility.isArmorLight(armor) && Hero6Utility.isWeaponPenetrating(rollData.attackRollData.weapon)) { | ||||
|           return { armorIgnored: true, nbSuccess: 0, messages: ["Armor ignored : Penetrating weapons ignore Light Armors."] } | ||||
|         } | ||||
|         if (Hero6Utility.isWeaponPenetrating(rollData.attackRollData.weapon)) { | ||||
|           messages.push("Armor reduced by 1 (Penetrating weapon)") | ||||
|           reduce = 1 | ||||
|         } | ||||
|         if (Hero6Utility.isWeaponLight(rollData.attackRollData.weapon)) { | ||||
|           messages.push("Armor with advantage (Light weapon)") | ||||
|           advantage = true | ||||
|         } | ||||
|         if (Hero6Utility.isWeaponHeavy(rollData.attackRollData.weapon)) { | ||||
|           messages.push("Armor with disadvantage (Heavy weapon)") | ||||
|           disadvantage = true | ||||
|         } | ||||
|         if (Hero6Utility.isWeaponHack(rollData.attackRollData.weapon)) { | ||||
|           messages.push("Armor reduced by 1 (Hack weapon)") | ||||
|           reduce = 1 | ||||
|         } | ||||
|         if (Hero6Utility.isWeaponUndamaging(rollData.attackRollData.weapon)) { | ||||
|           messages.push("Armor multiplied by 2 (Undamaging weapon)") | ||||
|           multiply = 2 | ||||
|         } | ||||
|       } | ||||
|       let diceColor = armor.system.absorprionroll | ||||
|       let armorResult = await Hero6Utility.getRollTableFromDiceColor(diceColor, false) | ||||
|       console.log("Armor log", armorResult) | ||||
|       let armorValue = Math.max(0, (Number(armorResult.text) + reduce) * multiply) | ||||
|       if (advantage || disadvantage) { | ||||
|         let armorResult2 = await Hero6Utility.getRollTableFromDiceColor(diceColor, false) | ||||
|         let armorValue2 = Math.max(0, (Number(armorResult2.text) + reduce) * multiply) | ||||
|         if (advantage) { | ||||
|           armorValue = (armorValue2 > armorValue) ? armorValue2 : armorValue | ||||
|           messages.push(`Armor advantage - Roll 1 = ${armorValue} - Roll 2 = ${armorValue2}`) | ||||
|         } | ||||
|         if (disadvantage) { | ||||
|           armorValue = (armorValue2 < armorValue) ? armorValue2 : armorValue | ||||
|           messages.push(`Armor disadvantage - Roll 1 = ${armorValue} - Roll 2 = ${armorValue2}`) | ||||
|         } | ||||
|       } | ||||
|       armorResult.armorValue = armorValue | ||||
|       if (!rollData) { | ||||
|         ChatMessage.create({ content: "Armor result : " + armorValue }) | ||||
|       } | ||||
|       messages.push("Armor result : " + armorValue) | ||||
|       return { armorIgnored: false, nbSuccess: armorValue, rawArmor: armorResult.text, messages: messages } | ||||
|     } | ||||
|     return { armorIgnored: true, nbSuccess: 0, messages: ["No armor equipped."] } | ||||
|   } | ||||
|  | ||||
|   /* -------------------------------------------- */ | ||||
|   rollSave(saveKey) { | ||||
|     let saves = this.getSaveRoll() | ||||
|     let save = saves[saveKey] | ||||
|     if (save) { | ||||
|       save = duplicate(save) | ||||
|       let rollData = this.getCommonRollData() | ||||
|       rollData.mode = "save" | ||||
|       rollData.save = save | ||||
|       if (rollData.target) { | ||||
|         ui.notifications.warn("You are targetting a token with a save roll - Not authorized.") | ||||
|         return | ||||
|       } | ||||
|       this.startRoll(rollData) | ||||
|     } | ||||
|  | ||||
|   } | ||||
|   /* -------------------------------------------- */ | ||||
|   async startRoll(rollData) { | ||||
|     this.syncRoll(rollData) | ||||
|     let rollDialog = await Hero6RollDialog.create(this, rollData) | ||||
|     rollDialog.render(true) | ||||
|   } | ||||
|   | ||||
| @@ -5,8 +5,8 @@ export class Hero6RollDialog extends Dialog { | ||||
|   /* -------------------------------------------- */ | ||||
|   static async create(actor, rollData) { | ||||
|  | ||||
|     let options = { classes: ["Hero6Dialog"], width: 540, height: 340, 'z-index': 99999 }; | ||||
|     let html = await renderTemplate('systems/fvtt-hero-system-6/templates/roll-dialog-generic.hbs', rollData); | ||||
|     let options = { classes: ["Hero6Dialog"], width: 460, height: 'fit-content', 'z-index': 99999 }; | ||||
|     let html = await renderTemplate('systems/fvtt-hero-system-6/templates/apps/roll-dialog-generic.hbs', rollData); | ||||
|  | ||||
|     return new Hero6RollDialog(actor, rollData, html, options); | ||||
|   } | ||||
| @@ -44,7 +44,7 @@ export class Hero6RollDialog extends Dialog { | ||||
|  | ||||
|   /* -------------------------------------------- */ | ||||
|   async refreshDialog() { | ||||
|     const content = await renderTemplate("systems/fvtt-hero-system-6/templates/roll-dialog-generic.hbs", this.rollData) | ||||
|     const content = await renderTemplate("systems/fvtt-hero-system-6/templates/apps/roll-dialog-generic.hbs", this.rollData) | ||||
|     this.data.content = content | ||||
|     this.render(true) | ||||
|   } | ||||
| @@ -76,8 +76,8 @@ export class Hero6RollDialog extends Dialog { | ||||
|     html.find('#situational').change((event) => { | ||||
|       this.rollData.situational = event.currentTarget.value | ||||
|     }) | ||||
|     html.find('#distanceBonusDice').change((event) => { | ||||
|       this.rollData.distanceBonusDice = Number(event.currentTarget.value) | ||||
|     html.find('#bonusMalus').change((event) => { | ||||
|       this.rollData.bonusMalus = Number(event.currentTarget.value) | ||||
|     }) | ||||
|      | ||||
|   } | ||||
|   | ||||
| @@ -24,7 +24,10 @@ export class Hero6Utility { | ||||
|       return array.includes(val); | ||||
|     }) | ||||
|     Handlebars.registerHelper('upper', function (text) { | ||||
|       return text.toUpperCase(); | ||||
|       if (text) {  | ||||
|         return text.toUpperCase(); | ||||
|       } | ||||
|       return text | ||||
|     }) | ||||
|     Handlebars.registerHelper('lower', function (text) { | ||||
|       return text.toLowerCase() | ||||
| @@ -150,7 +153,7 @@ export class Hero6Utility { | ||||
|     const templatePaths = [ | ||||
|       'systems/fvtt-hero-system-6/templates/partials/editor-notes-gm.hbs', | ||||
|       'systems/fvtt-hero-system-6/templates/partials/partial-roll-select.hbs', | ||||
|       'systems/fvtt-hero-system-6/templates/partials/partial-actor-ability-block.hbs', | ||||
|       'systems/fvtt-hero-system-6/templates/partials/partial-actor-characteristic-block.hbs', | ||||
|       'systems/fvtt-hero-system-6/templates/partials/partial-actor-status.hbs', | ||||
|       'systems/fvtt-hero-system-6/templates/partials/partial-options-abilities.hbs', | ||||
|       'systems/fvtt-hero-system-6/templates/partials/partial-item-nav.hbs', | ||||
| @@ -293,93 +296,10 @@ export class Hero6Utility { | ||||
|     let actor = game.actors.get(rollData.actorId) | ||||
|  | ||||
|     // ability/save/size => 0 | ||||
|     let diceFormula | ||||
|     let startFormula = "0d6cs>=5[blue]" | ||||
|     if (rollData.ability) { | ||||
|       startFormula = String(rollData.ability.value) + "d6cs>=5[blue]" | ||||
|     } | ||||
|     if (rollData.save) { | ||||
|       startFormula = String(rollData.save.value) + "d6cs>=5[blue]" | ||||
|     } | ||||
|     if (rollData.sizeDice) { | ||||
|       let nb = rollData.sizeDice.nb + rollData.distanceBonusDice + this.getDiceFromCover(rollData.hasCover) + this.getDiceFromSituational(rollData.situational) | ||||
|       startFormula = String(nb) + String(rollData.sizeDice.dice) + "cs>=5[blue]" | ||||
|     } | ||||
|     diceFormula = startFormula | ||||
|  | ||||
|     // skill => 2 | ||||
|     // feat => 4 | ||||
|     // bonus => 6 | ||||
|     if (rollData.skill) { | ||||
|       let level = rollData.skill.system.level | ||||
|       if (rollData.skill.system.issl2) { | ||||
|         rollData.hasSLBonus = true | ||||
|         level += 2 | ||||
|         if (level > 7) { level = 7 } | ||||
|       } | ||||
|       rollData.skill.system.skilldice = __skillLevel2Dice[level] | ||||
|       diceFormula += "+" + String(rollData.skill.system.skilldice) + "cs>=5[black]" | ||||
|  | ||||
|       if (rollData.skill.system.skilltype == "complex" && rollData.skill.system.level == 0) { | ||||
|         rollData.complexSkillDisadvantage = true | ||||
|         rollData.rollAdvantage = "roll-disadvantage" | ||||
|       } | ||||
|  | ||||
|       if (rollData.skill.system.isfeatdie) { | ||||
|         rollData.hasFeatDie = true | ||||
|         diceFormula += "+ 1d10cs>=5[hero6-purple]" | ||||
|       } else { | ||||
|         diceFormula += `+ 0d10cs>=5[hero6-purple]` | ||||
|       } | ||||
|       if (rollData.skill.system.bonusdice != "none") { | ||||
|         rollData.hasBonusDice = rollData.skill.system.bonusdice | ||||
|         diceFormula += `+ ${rollData.hasBonusDice}cs>=5[black]` | ||||
|       } else { | ||||
|         diceFormula += `+ 0d6cs>=5[black]` | ||||
|       } | ||||
|     } else { | ||||
|       diceFormula += `+ 0d8cs=>5 + 0d10cs>=5 + 0d6cs>=5` | ||||
|     } | ||||
|  | ||||
|     // advantage => 8 | ||||
|     let advFormula = "+ 0d8cs>=5" | ||||
|     if (rollData.advantage == "advantage1" || rollData.forceAdvantage) { | ||||
|       advFormula = "+ 1d8cs>=5[hero6-darkgreen]" | ||||
|     } | ||||
|     if (rollData.advantage == "advantage2") { | ||||
|       advFormula = "+ 2d8cs>=5[hero6-darkgreen]" | ||||
|     } | ||||
|     diceFormula += advFormula | ||||
|  | ||||
|     // disadvantage => 10 | ||||
|     let disFormula = "- 0d8cs>=5" | ||||
|     if (rollData.disadvantage == "disadvantage1" || rollData.forceDisadvantage) { | ||||
|       disFormula = "- 1d8cs>=5[red]" | ||||
|     } | ||||
|     if (rollData.disadvantage == "disadvantage2") { | ||||
|       disFormula = "- 2d8cs>=5[red]" | ||||
|     } | ||||
|     diceFormula += disFormula | ||||
|  | ||||
|     // armor => 12 | ||||
|     let skillArmorPenalty = 0 | ||||
|     for (let armor of rollData.armors) { | ||||
|       if (armor.system.equipped) { | ||||
|         skillArmorPenalty += armor.system.skillpenalty | ||||
|       } | ||||
|     } | ||||
|     if (rollData.skill && rollData.skill.system.armorpenalty && skillArmorPenalty > 0) { | ||||
|       rollData.skillArmorPenalty = skillArmorPenalty | ||||
|       diceFormula += `- ${skillArmorPenalty}d8cs>=5` | ||||
|     } else { | ||||
|       diceFormula += `- 0d8cs>=5` | ||||
|     } | ||||
|  | ||||
|     // shield => 14 | ||||
|     if (rollData.useshield && rollData.shield) { | ||||
|       diceFormula += "+ 1" + String(rollData.shield.system.shielddie) + "cs>=5[yellow]" | ||||
|     } else { | ||||
|       diceFormula += " + 0d6cs>=5" | ||||
|     let diceFormula = "3d6+" + rollData.bonusMalus | ||||
|     let target = 10 | ||||
|     if (rollData.charac) { | ||||
|       target = rollData.charac.roll | ||||
|     } | ||||
|  | ||||
|     // Performs roll | ||||
| @@ -389,74 +309,27 @@ export class Hero6Utility { | ||||
|       myRoll = new Roll(diceFormula).roll({ async: false }) | ||||
|       await this.showDiceSoNice(myRoll, game.settings.get("core", "rollMode")) | ||||
|     } | ||||
|     rollData.rollOrder = 0 | ||||
|     rollData.roll = myRoll | ||||
|     rollData.nbSuccess = myRoll.total | ||||
|  | ||||
|     if (rollData.rollAdvantage == "none" && rollData.forceRollAdvantage) { | ||||
|       rollData.rollAdvantage = "roll-advantage" | ||||
|     rollData.target = target | ||||
|     rollData.diceFormula = diceFormula | ||||
|     rollData.result = myRoll.total | ||||
|     rollData.isSuccess = false | ||||
|     if (rollData.result <= target) { | ||||
|       rollData.isSuccess = true | ||||
|     } | ||||
|     if (rollData.rollAdvantage == "none" && rollData.forceRollDisadvantage) { | ||||
|       rollData.rollAdvantage = "roll-disadvantage" | ||||
|     if ( myRoll.terms[0].total == 3) { // Always a success | ||||
|       rollData.isSuccess = true | ||||
|     } | ||||
|     if (rollData.rollAdvantage != "none") { | ||||
|  | ||||
|       rollData.rollOrder = 1 | ||||
|       rollData.rollType = (rollData.rollAdvantage == "roll-advantage") ? "Advantage" : "Disadvantage" | ||||
|       this.createChatWithRollMode(rollData.alias, { | ||||
|         content: await renderTemplate(`systems/fvtt-hero-system-6/templates/chat-generic-result.hbs`, rollData) | ||||
|       }) | ||||
|  | ||||
|       rollData.rollOrder = 2 | ||||
|       let myRoll2 = new Roll(diceFormula).roll({ async: false }) | ||||
|       await this.showDiceSoNice(myRoll2, game.settings.get("core", "rollMode")) | ||||
|  | ||||
|       rollData.roll = myRoll2 // Tmp switch to display the proper results | ||||
|       rollData.nbSuccess = myRoll2.total | ||||
|       this.createChatWithRollMode(rollData.alias, { | ||||
|         content: await renderTemplate(`systems/fvtt-hero-system-6/templates/chat-generic-result.hbs`, rollData) | ||||
|       }) | ||||
|       rollData.roll = myRoll // Revert the tmp switch | ||||
|       rollData.nbSuccess = myRoll.total | ||||
|  | ||||
|       if (rollData.rollAdvantage == "roll-advantage") { | ||||
|         if (myRoll2.total > rollData.nbSuccess) { | ||||
|           hasChanged = true | ||||
|           rollData.roll = myRoll2 | ||||
|           rollData.nbSuccess = myRoll2.total | ||||
|         } | ||||
|       } else { | ||||
|         if (myRoll2.total < rollData.nbSuccess) { | ||||
|           rollData.roll = myRoll2 | ||||
|           rollData.nbSuccess = myRoll2.total | ||||
|         } | ||||
|       } | ||||
|       rollData.rollOrder = 3 | ||||
|     } | ||||
|     rollData.nbSuccess = Math.max(0, rollData.nbSuccess) | ||||
|  | ||||
|     rollData.isFirstRollAdvantage = false | ||||
|     // Manage exp | ||||
|     if (rollData.skill && rollData.skill.system.level > 0) { | ||||
|       let nbSkillSuccess = rollData.roll.terms[2].total | ||||
|       if (nbSkillSuccess == 0 || nbSkillSuccess == rollData.skill.system.level) { | ||||
|         actor.incrementSkillExp(rollData.skill.id, 1) | ||||
|       } | ||||
|     if ( myRoll.terms[0].total == 18) { // Always a failure | ||||
|       rollData.isSuccess = false | ||||
|     } | ||||
|  | ||||
|     this.saveRollData(rollData) | ||||
|     actor.lastRoll = rollData | ||||
|  | ||||
|     this.createChatWithRollMode(rollData.alias, { | ||||
|       content: await renderTemplate(`systems/fvtt-hero-system-6/templates/chat-generic-result.hbs`, rollData) | ||||
|     let msg = await this.createChatWithRollMode(rollData.alias, { | ||||
|       content: await renderTemplate(`systems/fvtt-hero-system-6/templates/chat/chat-generic-result.hbs`, rollData) | ||||
|     }) | ||||
|     msg.setFlag("world", "rolldata", rollData) | ||||
|     console.log("Rolldata result", rollData) | ||||
|  | ||||
|     // Message response | ||||
|     this.displayDefenseMessage(rollData) | ||||
|  | ||||
|     // Manage defense result | ||||
|     this.processAttackDefense(rollData) | ||||
|   } | ||||
|  | ||||
|   /* -------------------------------------------- */ | ||||
| @@ -532,7 +405,7 @@ export class Hero6Utility { | ||||
|   } | ||||
|  | ||||
|   /* -------------------------------------------- */ | ||||
|   static createChatMessage(name, rollMode, chatOptions) { | ||||
|   static async createChatMessage(name, rollMode, chatOptions) { | ||||
|     switch (rollMode) { | ||||
|       case "blindroll": // GM only | ||||
|         if (!game.user.isGM) { | ||||
| @@ -550,7 +423,7 @@ export class Hero6Utility { | ||||
|         break; | ||||
|     } | ||||
|     chatOptions.alias = chatOptions.alias || name; | ||||
|     ChatMessage.create(chatOptions); | ||||
|     return await ChatMessage.create(chatOptions); | ||||
|   } | ||||
|  | ||||
|   /* -------------------------------------------- */ | ||||
| @@ -558,7 +431,7 @@ export class Hero6Utility { | ||||
|     let rollData = { | ||||
|       rollId: randomID(16), | ||||
|       rollMode: game.settings.get("core", "rollMode"), | ||||
|       advantage: "none" | ||||
|       bonusMalus: 0 | ||||
|     } | ||||
|     Hero6Utility.updateWithTarget(rollData) | ||||
|     return rollData | ||||
| @@ -573,8 +446,8 @@ export class Hero6Utility { | ||||
|   } | ||||
|  | ||||
|   /* -------------------------------------------- */ | ||||
|   static createChatWithRollMode(name, chatOptions) { | ||||
|     this.createChatMessage(name, game.settings.get("core", "rollMode"), chatOptions) | ||||
|   static async createChatWithRollMode(name, chatOptions) { | ||||
|     return await this.createChatMessage(name, game.settings.get("core", "rollMode"), chatOptions) | ||||
|   } | ||||
|  | ||||
|   /* -------------------------------------------- */ | ||||
|   | ||||
		Reference in New Issue
	
	Block a user