/* -------------------------------------------- */ import { PegasusUtility } from "./pegasus-utility.js"; import { PegasusRollDialog } from "./pegasus-roll-dialog.js"; /* -------------------------------------------- */ const coverBonusTable = { "nocover": 0, "lightcover": 2, "heavycover": 4, "entrenchedcover": 6 }; /* -------------------------------------------- */ /* -------------------------------------------- */ /** * Extend the base Actor entity by defining a custom roll data structure which is ideal for the Simple system. * @extends {Actor} */ export class PegasusActor 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 == 'character') { const skills = await PegasusUtility.loadCompendium("fvtt-weapons-of-the-gods.skills"); data.items = skills.map(i => i.toObject()); } if (data.type == 'npc') { } return super.create(data, options); } /* -------------------------------------------- */ prepareBaseData() { } /* -------------------------------------------- */ async prepareData() { super.prepareData(); } /* -------------------------------------------- */ prepareDerivedData() { if (this.type == 'character') { let h = 0; let updates = []; for (let key in this.data.data.statistics) { let attr = this.data.data.statistics[key]; } if (updates.length > 0) { this.update(updates); } this.computeNRGHealth(); } super.prepareDerivedData(); } /* -------------------------------------------- */ _preUpdate(changed, options, user) { super._preUpdate(changed, options, user); } /* -------------------------------------------- */ getActivePerks() { let perks = this.data.items.filter(item => item.type == 'perk' && item.data.data.active); return perks; } /* -------------------------------------------- */ getAbilities() { let ab = this.data.items.filter(item => item.type == 'ability'); return ab; } /* -------------------------------------------- */ getPerks() { let comp = this.data.items.filter(item => item.type == 'perk'); return comp; } /* -------------------------------------------- */ getEffects() { let comp = this.data.items.filter(item => item.type == 'effect'); return comp; } /* -------------------------------------------- */ getPowers() { let comp = this.data.items.filter(item => item.type == 'power'); return comp; } /* -------------------------------------------- */ getMoneys() { let comp = this.data.items.filter(item => item.type == 'money'); return comp; } /* -------------------------------------------- */ getArmors() { let comp = duplicate(this.data.items.filter(item => item.type == 'armor') || []); return comp; } /* -------------------------------------------- */ getShields() { let comp = this.data.items.filter(item => item.type == 'shield'); return comp; } getRace() { let race = this.data.items.filter(item => item.type == 'race'); return race[0] ?? []; } getRole() { let role = this.data.items.filter(item => item.type == 'role'); return role[0] ?? []; } /* -------------------------------------------- */ checkAndPrepareArmor(armor) { armor.data.resistanceDice = PegasusUtility.getDiceFromLevel(armor.data.resistance); } /* -------------------------------------------- */ checkAndPrepareArmors(armors) { for (let item of armors) { this.checkAndPrepareArmor(item); } return armors; } /* -------------------------------------------- */ checkAndPrepareWeapon(weapon) { weapon.data.damageDice = PegasusUtility.getDiceFromLevel(weapon.data.damage); } /* -------------------------------------------- */ checkAndPrepareWeapons(weapons) { for (let item of weapons) { this.checkAndPrepareWeapon(item); } return weapons; } /* -------------------------------------------- */ getWeapons() { let comp = duplicate(this.data.items.filter(item => item.type == 'weapon') || []); return comp; } /* -------------------------------------------- */ getItemById(id) { let item = this.data.items.find(item => item.id == id); if (item) { item = duplicate(item) if (item.type == 'specialisation') { item.data.dice = PegasusUtility.getDiceFromLevel(item.data.level); } } return item; } /* -------------------------------------------- */ getSpecs() { let comp = duplicate(this.data.items.filter(item => item.type == 'specialisation') || []); for (let c of comp) { c.data.dice = PegasusUtility.getDiceFromLevel(c.data.level); } return comp; } /* -------------------------------------------- */ getRelevantSpec(statKey) { let comp = duplicate(this.data.items.filter(item => item.type == 'specialisation' && item.data.data.statistic == statKey) || []); for (let c of comp) { c.data.dice = PegasusUtility.getDiceFromLevel(c.data.level); } return comp; } /* -------------------------------------------- */ async activatePerk(perkId) { let item = this.data.items.find(item => item.id == perkId); if (item && item.data.data) { let update = { _id: item.id, "data.active": !item.data.data.active }; await this.updateEmbeddedDocuments('Item', [update]); // Updates one EmbeddedEntity } } /* -------------------------------------------- */ async activatePower(itemId) { let item = this.data.items.find(item => item.id == itemId); if (item && item.data.data) { let update = { _id: item.id, "data.activated": !item.data.data.activated }; await this.updateEmbeddedDocuments('Item', [update]); // Updates one EmbeddedEntity } } /* -------------------------------------------- */ async equipItem(itemId) { let item = this.data.items.find(item => item.id == itemId); if (item && item.data.data) { let update = { _id: item.id, "data.equipped": !item.data.data.equipped }; await this.updateEmbeddedDocuments('Item', [update]); // Updates one EmbeddedEntity } } /* -------------------------------------------- */ compareName(a, b) { if (a.name < b.name) { return -1; } if (a.name > b.name) { return 1; } return 0; } /* ------------------------------------------- */ getEquipments() { return this.data.items.filter(item => item.type == 'shield' || item.type == 'armor' || item.type == "weapon" || item.type == "equipment"); } /* ------------------------------------------- */ getEquipmentsOnly() { return duplicate( this.data.items.filter(item => item.type == "equipment") || [] ) } /* -------------------------------------------- */ getActiveEffects(matching = it => true) { let array = Array.from(this.getEmbeddedCollection("ActiveEffect").values()); return Array.from(this.getEmbeddedCollection("ActiveEffect").values()).filter(it => matching(it)); } /* -------------------------------------------- */ getEffectByLabel(label) { return this.getActiveEffects().find(it => it.data.label == label); } /* -------------------------------------------- */ getEffectById(id) { return this.getActiveEffects().find(it => it.id == id); } /* -------------------------------------------- */ getAttribute(attrKey) { return this.data.data.attributes[attrKey]; } /* -------------------------------------------- */ async preprocessItem( event, item, onDrop = false) { if ( item.data.type == 'race') { this.applyRace(item.data) } else if ( item.data.type == 'ability') { this.applyAbility(item.data, [], true) if ( !onDrop) { await this.createEmbeddedDocuments('Item', [item.data] ) } } else { if ( !onDrop) { await this.createEmbeddedDocuments('Item', [item.data] ) } } } /* -------------------------------------------- */ async equipGear(equipmentId) { let item = this.data.items.find(item => item.id == equipmentId); if (item && item.data.data) { let update = { _id: item.id, "data.equipped": !item.data.data.equipped }; await this.updateEmbeddedDocuments('Item', [update]); // Updates one EmbeddedEntity } } /* -------------------------------------------- */ getInitiativeScore( combatId, combatantId) { if (this.type == 'character') { this.rollMR(true, combatId, combatantId) } console.log("Init required !!!!") return -1; } /* -------------------------------------------- */ getSubActors() { let subActors = []; for (let id of this.data.data.subactors) { subActors.push(duplicate(game.actors.get(id))); } return subActors; } /* -------------------------------------------- */ async addSubActor(subActorId) { let subActors = duplicate(this.data.data.subactors); subActors.push(subActorId); await this.update({ 'data.subactors': subActors }); } /* -------------------------------------------- */ async delSubActor(subActorId) { let newArray = []; for (let id of this.data.data.subactors) { if (id != subActorId) { newArray.push(id); } } await this.update({ 'data.subactors': newArray }); } /* -------------------------------------------- */ syncRoll(rollData) { let linkedRollId = PegasusUtility.getDefenseState(this.id); if (linkedRollId) { rollData.linkedRollId = linkedRollId; } this.lastRollId = rollData.rollId; PegasusUtility.saveRollData(rollData); } /* -------------------------------------------- */ getStat(statKey) { let stat if (statKey == 'mr') { stat = duplicate(this.data.data.mr); } else { stat = duplicate(this.data.data.statistics[statKey]); } stat.dice = PegasusUtility.getDiceFromLevel(stat.value); return stat; } /* -------------------------------------------- */ getOneSpec(specId) { let spec = this.data.items.find(item => item.type == 'specialisation' && item.id == specId); if (spec) { spec = duplicate(spec); spec.data.dice = PegasusUtility.getDiceFromLevel(spec.data.level); } return spec; } /* -------------------------------------------- */ async perkEffectUsed( itemId) { let effect = this.items.get(itemId) if (effect) { PegasusUtility.createChatWithRollMode(effect.name, { content: await renderTemplate(`systems/fvtt-pegasus-rpg/templates/chat-effect-used.html`, effect.data) }); this.deleteEmbeddedDocuments('Item', [ effect.id] ) } } /* -------------------------------------------- */ async updatePerkStatus(itemId, status) { let item = this.items.get(itemId) if (item) { if (item.data.data.status == status) return;// Ensure we are really changing the status let updateOK = true if ( status == "ready") { let effects = [] for( let item of this.data.items) { if ( item.type == "effect" && item.data.data.perkId == itemId) { effects.push( item.id) } } if ( effects.length) { await this.deleteEmbeddedDocuments('Item', effects ) } if ( item.data.data.features.nrgcost.flag ) { let nrg = duplicate(this.data.data.nrg) nrg.activated -= item.data.data.features.nrgcost.value this.update( {'data.nrg': nrg } ) } if (item.data.data.features.bonushealth.flag) { let health = duplicate(this.data.data.secondary.health) health.bonus -= item.data.data.features.bonushealth.value this.update( {'data.secondary.health': health } ) } if (item.data.data.features.bonusdelirium.flag) { let delirium = duplicate(this.data.data.delirium.delirium) delirium.bonus -= item.data.data.features.bonusdelirium.value this.update( {'data.secondary.delirium': delirium } ) } if (item.data.data.features.bonusnrg.flag) { let nrg = duplicate(this.data.data.nrg) nrg.mod -= item.data.data.features.bonusnrg.value this.update( {'data.nrg': nrg } ) } } if ( status == "activated") { // Add effects linked to the perk let effects = [] for( let effect of item.data.data.effectsgained) { effect.data.perkId = itemId // Link to the perk, in order to dynamically remove them effect.data.isUsed = false // Flag to indicate removal when used in a roll window effects.push( effect ) } if ( effects.length) { await this.createEmbeddedDocuments('Item', effects ) } // Manage additional flags if ( item.data.data.features.nrgcost.flag ) { if (this.data.data.nrg.value >= item.data.data.features.nrgcost.value) { let nrg = duplicate(this.data.data.nrg) nrg.activated += item.data.data.features.nrgcost.value nrg.value -= item.data.data.features.nrgcost.value this.update( {'data.nrg': nrg } ) } else { updateOK = false ui.notifications.warn("Not enough NRG to activate the Perk " + item.name) } } if (item.data.data.features.bonushealth.flag) { let health = duplicate(this.data.data.secondary.health) health.bonus += item.data.data.features.bonushealth.value this.update( {'data.secondary.health': health } ) } if (item.data.data.features.bonusdelirium.flag) { let delirium = duplicate(this.data.data.delirium.delirium) delirium.bonus += item.data.data.features.bonusdelirium.value this.update( {'data.secondary.delirium': delirium } ) } if (item.data.data.features.bonusnrg.flag) { let nrg = duplicate(this.data.data.nrg) nrg.mod += item.data.data.features.bonusnrg.value this.update( {'data.nrg': nrg } ) } } if (updateOK) { this.updateEmbeddedDocuments('Item', [{ _id: item.id, 'data.status': status }]) } } } /* -------------------------------------------- */ async deleteAllItemsByType(itemType) { let items = this.data.items.filter(item => item.type == itemType); await this.deleteEmbeddedDocuments('Item', items); } /* -------------------------------------------- */ async addItemWithoutDuplicate(newItem) { let item = this.data.items.find(item => item.type == newItem.type && item.name.toLowerCase() == newItem.name.toLowerCase()) if (!item) { await this.createEmbeddedDocuments('Item', [newItem]); } } /* -------------------------------------------- */ async computeNRGHealth() { if ( this.isToken ) return if (this.isOwner || game.user.isGM) { let updates = {} let phyDiceValue = PegasusUtility.getDiceValue(this.data.data.statistics.phy.value) + this.data.data.secondary.health.bonus + this.data.data.statistics.phy.mod; if (phyDiceValue != this.data.data.secondary.health.max) { updates['data.secondary.health.max'] = phyDiceValue updates['data.secondary.health.value'] = phyDiceValue } let mndDiceValue = PegasusUtility.getDiceValue(this.data.data.statistics.mnd.value) + this.data.data.secondary.delirium.bonus + this.data.data.statistics.mnd.mod; if (mndDiceValue != this.data.data.secondary.delirium.max) { updates['data.secondary.delirium.max'] = mndDiceValue updates['data.secondary.delirium.value'] = mndDiceValue } let stlDiceValue = PegasusUtility.getDiceValue(this.data.data.statistics.stl.value) + this.data.data.secondary.stealthhealth.bonus + this.data.data.statistics.stl.mod; if (stlDiceValue != this.data.data.secondary.stealthhealth.max) { updates['data.secondary.stealthhealth.max'] = stlDiceValue updates['data.secondary.stealthhealth.value'] = stlDiceValue } let socDiceValue = PegasusUtility.getDiceValue(this.data.data.statistics.soc.value) + this.data.data.secondary.socialhealth.bonus + this.data.data.statistics.soc.mod; if (socDiceValue != this.data.data.secondary.socialhealth.max) { updates['data.secondary.socialhealth.max'] = socDiceValue updates['data.secondary.socialhealth.value'] = socDiceValue } let nrgValue = PegasusUtility.getDiceValue(this.data.data.statistics.foc.value) + this.data.data.nrg.mod + this.data.data.statistics.foc.mod; if (nrgValue != this.data.data.nrg.max) { updates['data.nrg.max'] = nrgValue updates['data.nrg.value'] = nrgValue } nrgValue = PegasusUtility.getDiceValue(this.data.data.statistics.foc.value) + this.data.data.statistics.foc.mod; if (nrgValue != this.data.data.combat.stunthreshold) { updates['data.combat.stunthreshold'] = nrgValue } let momentum = this.data.data.statistics.foc.value + this.data.data.statistics.foc.mod if (momentum != this.data.data.momentum.max) { updates['data.momentum.value'] = 0 updates['data.momentum.max'] = momentum } let mrLevel = (this.data.data.statistics.agi.value + this.data.data.statistics.str.value) - this.data.data.statistics.phy.value mrLevel = (mrLevel < 1) ? 1 : mrLevel; if (mrLevel != this.data.data.mr.value) { updates['data.mr.value'] = mrLevel } let race = this.getRace() if (race && race.name && (race.name != this.data.data.biodata.racename)) { updates['data.biodata.racename'] = race.name } let role = this.getRole() if (role && role.name && (role.name != this.data.data.biodata.rolename)) { updates['data.biodata.rolename'] = role.name } //console.log("UPD", updates, this.data.data.biodata) await this.update(updates) } // Update current hindrance level let hindrance = this.data.data.combat.hindrancedice if ( this.data.data.secondary.health.value < 0) { hindrance += Math.abs(this.data.data.secondary.health.value) } if ( this.data.data.secondary.delirium.value < 0) { hindrance += Math.abs(this.data.data.secondary.delirium.value) } this.data.data.combat.hindrancedice = hindrance } /* -------------------------------------------- */ async modStat(key, inc = 1) { let stat = duplicate(this.data.data.statistics[key]) stat.mod += parseInt(inc) await this.update({ [`data.statistics.${key}`]: stat }) } /* -------------------------------------------- */ async valueStat(key, inc = 1) { key = key.toLowerCase() let stat = duplicate(this.data.data.statistics[key]) stat.value += parseInt(inc) await this.update({ [`data.statistics.${key}`]: stat }) } /* -------------------------------------------- */ async addIncSpec(spec, inc = 1) { console.log("Using spec : ", spec, inc) let specExist = this.data.items.find(item => item.type == 'specialisation' && item.name.toLowerCase() == spec.name.toLowerCase()) if (specExist) { specExist = duplicate(specExist) specExist.data.level += inc; let update = { _id: specExist._id, "data.level": specExist.data.level }; await this.updateEmbeddedDocuments('Item', [update]); } else { spec.data.level += inc; await this.createEmbeddedDocuments('Item', [spec]); } } /* -------------------------------------------- */ async incDecQuantity(objetId, incDec = 0) { let objetQ = this.data.items.get(objetId) if (objetQ) { let newQ = objetQ.data.data.quantity + incDec; const updated = await this.updateEmbeddedDocuments('Item', [{ _id: objetQ.id, 'data.quantity': newQ }]); // pdates one EmbeddedEntity } } /* -------------------------------------------- */ async applyAbility(ability, updates = [], directUpdate = false) { // manage stat bonus if (ability.data.affectedstat != "notapplicable") { let stat = duplicate(this.data.data.statistics[ability.data.affectedstat]) stat.mod += Number(ability.data.statmodifier) updates[`data.statistics.${ability.data.affectedstat}`] = stat } // manage status bonus if (ability.data.statusaffected != "notapplicable") { if ( ability.data.statusaffected == 'nrg' ) { let nrg = duplicate( this.data.data.nrg) nrg.mod += Number(ability.data.statusmodifier) updates[`data.nrg`] = nrg } if ( ability.data.statusaffected == 'health' ) { let health = duplicate( this.data.data.secondary.health) health.bonus += Number(ability.data.statusmodifier) updates[`data.secondary.health`] = health } if ( ability.data.statusaffected == 'delirium' ) { let delirium = duplicate( this.data.data.secondary.delirium) delirium.bonus += Number(ability.data.statusmodifier) updates[`data.secondary.delirium`] = delirium } } if ( directUpdate ) { await this.update(updates) } let newItems = [] if (ability.data.effectsgained) { for (let effect of ability.data.effectsgained) { newItems.push(effect); } } if (ability.data.powersgained) { for (let power of ability.data.powersgained) { newItems.push(power); } } if (ability.data.specialisations) { for (let spec of ability.data.specialisations) { newItems.push(spec); } } if (ability.data.attackgained) { for (let weapon of ability.data.attackgained) { newItems.push(weapon); } } if (ability.data.armorgained) { for (let armor of ability.data.armorgained) { newItems.push(armor); } } await this.createEmbeddedDocuments('Item', newItems) } /* -------------------------------------------- */ async applyRace(race) { let updates = { 'data.biodata.racename': race.name } let newItems = [] await this.deleteAllItemsByType('race') newItems.push(race); for (let ability of race.data.abilities) { newItems.push(ability) this.applyAbility(ability, updates) } if (race.data.perksgained) { for (let power of race.data.perks) { newItems.push(power); } } await this.update(updates) await this.createEmbeddedDocuments('Item', newItems) console.log("Updates", updates, newItems) console.log("Updated actor", this) } /* -------------------------------------------- */ getIncreaseStatValue(updates, statKey) { let stat = duplicate(this.data.data.statistics[statKey]) stat.value += 1; updates[`data.statistics.${statKey}`] = stat } /* -------------------------------------------- */ async applyRole(role) { console.log("ROLE", role) let updates = { 'data.biodata.rolename': role.name } let newItems = [] await this.deleteAllItemsByType('role') newItems.push(role); this.getIncreaseStatValue(updates, role.data.statincrease1) this.getIncreaseStatValue(updates, role.data.statincrease2) //newItems = newItems.concat(duplicate(role.data.specialisationsplus1)) newItems = newItems.concat(duplicate(role.data.specialperk)) await this.update(updates) await this.createEmbeddedDocuments('Item', newItems) } /* -------------------------------------------- */ addHindrancesList( effectsList ) { if (this.data.data.combat.stunlevel > 0) { effectsList.push( { label: "Stun Hindrance", type: "hindrance", applied: false, value: this.data.data.combat.stunlevel } ) } if (this.data.data.combat.hindrancedice > 0) { effectsList.push( { label: "Health/Delirium Hindrance", type: "hindrance", applied: false, value: this.data.data.combat.hindrancedice } ) } let effects = this.data.items.filter( item => item.type == 'effect' ) for( let effect of effects) { effect = duplicate(effect) if (effect.data.hindrance) { effectsList.push( { label: effect.name, type: "effect", applied: false, effect: effect, value: effect.data.effectlevel } ) } } } /* -------------------------------------------- */ /* ROLL SECTION /* -------------------------------------------- */ /* -------------------------------------------- */ addEffects( rollData) { let effects = this.data.items.filter( item => item.type == 'effect' ) for( let effect of effects) { effect = duplicate(effect) if ( !effect.data.hindrance && effect.data.stataffected != "notapplicable" && effect.data.stataffected != "special") { rollData.effectsList.push( { label: effect.name, type: "effect", applied: false, effect: effect, value: effect.data.effectlevel } ) } } } /* -------------------------------------------- */ addArmorsShields( rollData, statKey = "none", useShield = false) { if (statKey == 'phy') { let armors = this.getArmors() for (let armor of armors) { rollData.armorsList.push( {label: `Armor ${armor.name}`, type: "other", applied: false, value: armor.data.resistance } ) } } if (useShield ) { let shields = this.data.items.filter(item => item.type == "shield" && item.data.data.equipped) for (let sh of shields) { rollData.armorsList.push( {label: `Shield ${sh.name}`, type: "other", applied: false, value: sh.data.data.level } ) } } } addWeapons(rollData, statKey) { let weapons = this.getWeapons() for (let weapon of weapons) { if (weapon.data.equipped && weapon.data.statistic == statKey) { rollData.weaponsList.push( {label: `Attack ${weapon.name}`, type: "attack", applied: false, weapon: weapon, value: 0 } ) } if (weapon.data.equipped && weapon.data.enhanced && weapon.data.enhancedstat == statKey) { rollData.weaponsList.push( {label: `Enhanced Attack ${weapon.name}`, type: "enhanced", applied: false, weapon: weapon, value: weapon.data.enhancedlevel } ) } if (weapon.data.equipped && weapon.data.damagestatistic == statKey) { rollData.weaponsList.push( {label: `Damage ${weapon.name}`, type: "damage", applied: false, weapon: weapon, value: weapon.data.damage } ) } } } addEquipments(rollData, statKey) { let equipments = this.getEquipmentsOnly() for (let equip of equipments) { if (equip.data.equipped && equip.data.stataffected == statKey) { rollData.equipmentsList.push( {label: `Item ${equip.name}`, type: "item", applied: false, equip: equip, value: equip.data.level } ) } } } /* -------------------------------------------- */ getCommonRollData(statKey = undefined, useShield = false) { let rollData = PegasusUtility.getBasicRollData() rollData.alias = this.name rollData.actorImg = this.img rollData.actorId = this.id rollData.img = this.img rollData.activePerks = duplicate(this.getActivePerks()) if ( statKey) { rollData.statKey = statKey rollData.stat = this.getStat(statKey) rollData.statDicesLevel = rollData.stat.value rollData.statMod = rollData.stat.mod rollData.specList = this.getRelevantSpec(statKey) rollData.selectedSpec = "0" } this.addEffects( rollData) this.addArmorsShields(rollData, statKey, useShield) this.addWeapons(rollData, statKey, useShield) this.addEquipments(rollData, statKey) return rollData } /* -------------------------------------------- */ async startRoll(rollData) { this.syncRoll(rollData); console.log("ROLL DATA", rollData) let rollDialog = await PegasusRollDialog.create(this, rollData); console.log(rollDialog); rollDialog.render(true); } /* -------------------------------------------- */ rollPool(statKey, useShield = false) { let stat = this.getStat(statKey); if (stat) { let rollData = this.getCommonRollData(statKey, useShield) rollData.mode = "stat" this.startRoll(rollData) } else { ui.notifications.warn("Statistic not found !"); } } /* -------------------------------------------- */ rollUnarmedAttack() { let stat = this.getStat('com'); if (stat) { let rollData = this.getCommonRollData(statKey) rollData.mode = "stat" rollData.title = `Unarmed Attack`; rollData.damages = this.getStat('str'); this.startRoll(rollData); } else { ui.notifications.warn("Statistic not found !"); } } /*-------------------------------------------- */ rollStat(statKey) { let stat = this.getStat(statKey); if (stat) { let rollData = this.getCommonRollData(statKey) rollData.mode = "stat" rollData.title = `Stat ${stat.label}`; this.startRoll(rollData) } else { ui.notifications.warn("Statistic not found !"); } } /* -------------------------------------------- */ async rollSpec(specId) { let spec = this.getOneSpec(specId) if (spec) { let rollData = this.getCommonRollData(spec.data.statistic) rollData.mode = "spec" rollData.title = `Spec. : ${spec.name} ` rollData.specList = [ spec ] rollData.selectedSpec = spec._id rollData.specDicesLevel = spec.data.level this.startRoll(rollData) } else { ui.notifications.warn("Specialisation not found !"); } } /* -------------------------------------------- */ async rollMR( isInit = false, combatId = 0, combatantId = 0) { let mr = duplicate(this.data.data.mr) if (mr) { mr.dice = PegasusUtility.getDiceFromLevel(mr.value); let rollData = this.getCommonRollData("mr") rollData.mode = "MR" rollData.isInit = isInit rollData.combatId = combatId rollData.combatantId = combatantId this.startRoll(rollData); } else { ui.notifications.warn("MR not found !"); } } /* -------------------------------------------- */ async rollArmor(armorId) { let armor = this.data.items.get(armorId) if (armor) { let rollData = this.getCommonRollData(armor.data.statistic) armor = duplicate(armor); this.checkAndPrepareArmor(armor); rollData.mode = "armor" rollData.armor = armor rollData.title = `Armor : ${armor.name}` rollData.isResistance = true; rollData.otherDicesLevel = armor.data.resistance this.startRoll(rollData); } else { ui.notifications.warn("Armor not found !", weaponId); } } /* -------------------------------------------- */ async rollPower(powerId) { let power = this.data.items.get(powerId) if (power) { power = duplicate(power) let rollData = this.getCommonRollData(power.data.statistic) rollData.mode = "power" rollData.power = power rollData.title = `Power : ${power.name}` this.startRoll(rollData); } else { ui.notifications.warn("Power not found !", powerId); } } }