fvtt-pegasus-rpg/modules/pegasus-actor.js

2158 lines
77 KiB
JavaScript
Raw Normal View History

2021-12-02 07:38:59 +01:00
/* -------------------------------------------- */
import { PegasusUtility } from "./pegasus-utility.js";
import { PegasusRollDialog } from "./pegasus-roll-dialog.js";
/* -------------------------------------------- */
2022-01-14 14:49:16 +01:00
const coverBonusTable = { "nocover": 0, "lightcover": 2, "heavycover": 4, "entrenchedcover": 6 };
2022-07-10 10:22:04 +02:00
const statThreatLevel = ["agi", "str", "phy", "com", "def", "per"]
2022-07-19 20:51:48 +02:00
const __subkey2title = {
"melee-dmg": "Melee Damage", "melee-atk": "Melee Attack", "ranged-atk": "Ranged Attack",
2022-09-25 09:26:12 +02:00
"ranged-dmg": "Ranged Damage", "defence": "Defence", "dmg-res": "Damare Resistance"
2022-07-19 20:51:48 +02:00
}
2022-09-16 17:36:58 +02:00
const __statBuild = [
{ modules: ["vehiclehull"], field: "hr", itemfield: "hr" },
{ modules: ["vehiclehull", "vehiclemodule"], field: "hr", itemfield: "size", subfield: "size" },
//{ modules: ["vehiclehull"], field: "pc", itemfield: "vms", subfield: "avgnrg" },
//{ modules: ["powercoremodule"], field: "pc", itemfield: "nrg", subfield: "avgnrg" },
{ modules: ["vehiclehull", "mobilitymodule"], itemfield: "man", field: "man" },
2022-09-21 16:54:34 +02:00
{ modules: ["powercoremodule"], field: "pc", itemfield: "pc", additionnal1: "curnrg", additionnal2: "maxnrg" },
{ modules: ["mobilitymodule"], field: "mr", itemfield: "mr" },
{ modules: ["propulsionmodule"], field: "ad", itemfield: "ad" },
{ modules: ["combatmodule"], field: "fc", itemfield: "fc" },
2022-09-16 17:36:58 +02:00
]
2022-09-25 09:26:12 +02:00
const __isVehicleUnique = { vehiclehull: 1, powercoremodule: 1, mobilitymodule: 1, propulsionmodule: 1, combatmodule: 1 }
2022-09-16 17:36:58 +02:00
const __speed2Num = { fullstop: 0, crawling: 1, slow: 2, average: 3, fast: 4, extfast: 5 }
const __num2speed = ["fullstop", "crawling", "slow", "average", "fast", "extfast"]
2022-09-25 09:26:12 +02:00
const __isVehicle = { vehiclehull: 1, powercoremodule: 1, mobilitymodule: 1, combatmodule: 1, propulsionmodule: 1, vehiclemodule: 1, vehicleweaponmodule: 1, effect: 1 }
const __bonusEffect = {
name: "Crawling MAN Bonus", type: "effect", img: "systems/fvtt-pegasus-rpg/images/icons/icon_effect.webp",
system: {
type: "physical",
genre: "positive",
effectlevel: 3,
reducedicevalue: false,
stataffected: "man",
specaffected: [],
statdice: false,
bonusdice: true,
weapondamage: false,
hindrance: false,
resistedby: "notapplicable",
recoveryroll: false,
recoveryrollstat: "",
recoveryrollspec: [],
effectstatlevel: false,
effectstat: "",
oneuse: false,
ignorehealthpenalty: false,
isthispossible: "",
mentaldisruption: false,
physicaldisruption: false,
mentalimmunity: false,
physicalimmunity: false,
nobonusdice: false,
noperksallowed: false,
description: "",
otherdice: false
}
}
2021-12-02 07:38:59 +01:00
/* -------------------------------------------- */
/**
* 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;
}
2022-01-14 14:49:16 +01:00
if (data.type == 'character') {
2021-12-02 07:38:59 +01:00
}
2022-01-14 14:49:16 +01:00
if (data.type == 'npc') {
2021-12-02 07:38:59 +01:00
}
2022-08-28 18:51:52 +02:00
2021-12-02 07:38:59 +01:00
return super.create(data, options);
}
2022-01-14 14:49:16 +01:00
2021-12-02 07:38:59 +01:00
/* -------------------------------------------- */
prepareBaseData() {
}
/* -------------------------------------------- */
async prepareData() {
super.prepareData();
}
/* -------------------------------------------- */
prepareDerivedData() {
2022-08-28 18:51:52 +02:00
if (!this.traumaState) {
this.traumaState = "none"
}
2021-12-02 07:38:59 +01:00
if (this.type == 'character') {
2022-01-11 23:35:23 +01:00
this.computeNRGHealth();
2022-09-04 09:58:51 +02:00
this.system.encCapacity = this.getEncumbranceCapacity()
2022-03-06 20:07:41 +01:00
this.buildContainerTree()
2021-12-02 07:38:59 +01:00
}
2022-09-16 17:36:58 +02:00
if (this.type == 'vehicle') {
this.computeVehicleStats();
}
2021-12-02 07:38:59 +01:00
super.prepareDerivedData();
}
/* -------------------------------------------- */
_preUpdate(changed, options, user) {
super._preUpdate(changed, options, user);
}
2022-03-06 20:07:41 +01:00
/* -------------------------------------------- */
getEncumbranceCapacity() {
2022-09-04 09:58:51 +02:00
return this.system.statistics.str.value * 25
2022-03-06 20:07:41 +01:00
}
2021-12-03 18:31:43 +01:00
/* -------------------------------------------- */
getActivePerks() {
2022-09-04 09:58:51 +02:00
let perks = this.items.filter(item => item.type == 'perk' && item.system.active);
2021-12-03 18:31:43 +01:00
return perks;
2022-01-14 14:49:16 +01:00
}
2021-12-02 07:38:59 +01:00
/* -------------------------------------------- */
2022-01-06 18:22:05 +01:00
getAbilities() {
2022-09-04 09:58:51 +02:00
let ab = this.items.filter(item => item.type == 'ability');
2022-01-06 18:22:05 +01:00
return ab;
}
/* -------------------------------------------- */
2021-12-02 07:38:59 +01:00
getPerks() {
2022-09-04 09:58:51 +02:00
let comp = this.items.filter(item => item.type == 'perk');
2021-12-02 07:38:59 +01:00
return comp;
}
/* -------------------------------------------- */
2022-01-12 16:25:55 +01:00
getEffects() {
2022-09-04 09:58:51 +02:00
let comp = this.items.filter(item => item.type == 'effect');
2022-01-12 16:25:55 +01:00
return comp;
}
2022-09-08 21:26:45 +02:00
/* -------------------------------------------- */
getCombatModules() {
let comp = this.items.filter(item => item.type == 'combatmodule');
return comp;
}
/* -------------------------------------------- */
getVehicleHull() {
let comp = this.items.filter(item => item.type == 'vehiclehull');
return comp;
}
/* -------------------------------------------- */
getPowercoreModules() {
let comp = this.items.filter(item => item.type == 'powercoremodule');
return comp;
}
/* -------------------------------------------- */
getMobilityModules() {
let comp = this.items.filter(item => item.type == 'mobilitymodule');
return comp;
}
/* -------------------------------------------- */
getPropulsionModules() {
let comp = this.items.filter(item => item.type == 'propulsionmodule');
return comp;
}
/* -------------------------------------------- */
2022-09-09 08:33:28 +02:00
getVehicleModules() {
2022-09-08 21:26:45 +02:00
let comp = this.items.filter(item => item.type == 'vehiclemodule');
return comp;
}
/* -------------------------------------------- */
2022-09-09 08:33:28 +02:00
getVehicleWeaponModules() {
2022-09-08 21:26:45 +02:00
let comp = this.items.filter(item => item.type == 'vehicleweaponmodule');
return comp;
}
2022-01-12 16:25:55 +01:00
/* -------------------------------------------- */
2021-12-02 07:38:59 +01:00
getPowers() {
2022-09-04 09:58:51 +02:00
let comp = this.items.filter(item => item.type == 'power');
2021-12-02 07:38:59 +01:00
return comp;
}
/* -------------------------------------------- */
2022-01-22 21:49:34 +01:00
getMoneys() {
2022-09-04 09:58:51 +02:00
let comp = this.items.filter(item => item.type == 'money');
2022-01-22 21:49:34 +01:00
return comp;
}
/* -------------------------------------------- */
2022-07-19 00:18:46 +02:00
getVirtues() {
2022-09-04 09:58:51 +02:00
let comp = this.items.filter(item => item.type == 'virtue');
2022-07-19 00:18:46 +02:00
return comp;
}
/* -------------------------------------------- */
getVices() {
2022-09-04 09:58:51 +02:00
let comp = this.items.filter(item => item.type == 'vice');
2022-07-19 00:18:46 +02:00
return comp;
}
/* -------------------------------------------- */
2021-12-02 07:38:59 +01:00
getArmors() {
2022-09-04 09:58:51 +02:00
let comp = duplicate(this.items.filter(item => item.type == 'armor') || []);
2021-12-02 07:38:59 +01:00
return comp;
}
/* -------------------------------------------- */
getShields() {
2022-09-04 09:58:51 +02:00
let comp = this.items.filter(item => item.type == 'shield')
2021-12-02 07:38:59 +01:00
return comp;
2022-01-14 14:49:16 +01:00
}
2022-01-08 18:28:01 +01:00
getRace() {
2022-09-04 09:58:51 +02:00
let race = this.items.filter(item => item.type == 'race')
2022-01-14 14:49:16 +01:00
return race[0] ?? [];
2022-01-08 18:28:01 +01:00
}
getRole() {
2022-09-04 09:58:51 +02:00
let role = this.items.filter(item => item.type == 'role')
2022-01-14 14:49:16 +01:00
return role[0] ?? [];
2021-12-02 07:38:59 +01:00
}
2022-01-14 18:20:15 +01:00
/* -------------------------------------------- */
2022-03-09 18:12:40 +01:00
checkAndPrepareEquipment(item) {
2022-09-04 09:58:51 +02:00
if (item.system.resistance) {
item.system.resistanceDice = PegasusUtility.getDiceFromLevel(item.system.resistance)
2022-03-09 18:12:40 +01:00
}
2022-09-04 09:58:51 +02:00
if (item.system.idr) {
item.system.idrDice = PegasusUtility.getDiceFromLevel(item.system.idr)
2022-03-09 18:12:40 +01:00
}
2022-09-04 09:58:51 +02:00
if (item.system.damage) {
item.system.damageDice = PegasusUtility.getDiceFromLevel(item.system.damage)
2022-03-09 18:12:40 +01:00
}
2022-09-04 09:58:51 +02:00
if (item.system.level) {
item.system.levelDice = PegasusUtility.getDiceFromLevel(item.system.level)
2022-01-14 18:20:15 +01:00
}
}
2022-01-14 14:49:16 +01:00
2021-12-02 07:38:59 +01:00
/* -------------------------------------------- */
2022-03-09 18:12:40 +01:00
checkAndPrepareEquipments(listItem) {
for (let item of listItem) {
this.checkAndPrepareEquipment(item)
2021-12-02 07:38:59 +01:00
}
2022-03-09 18:12:40 +01:00
return listItem
2021-12-02 07:38:59 +01:00
}
/* -------------------------------------------- */
getWeapons() {
2022-09-04 09:58:51 +02:00
let comp = duplicate(this.items.filter(item => item.type == 'weapon') || []);
2021-12-02 07:38:59 +01:00
return comp;
}
2022-01-11 23:35:23 +01:00
/* -------------------------------------------- */
2022-01-14 14:49:16 +01:00
getItemById(id) {
2022-09-04 09:58:51 +02:00
let item = this.items.find(item => item.id == id);
2022-01-14 14:49:16 +01:00
if (item) {
2022-01-11 23:35:23 +01:00
item = duplicate(item)
if (item.type == 'specialisation') {
2022-09-04 09:58:51 +02:00
item.system.dice = PegasusUtility.getDiceFromLevel(item.system.level);
2022-01-11 23:35:23 +01:00
}
}
2022-01-14 14:49:16 +01:00
return item;
2022-01-11 23:35:23 +01:00
}
2021-12-02 07:38:59 +01:00
/* -------------------------------------------- */
getSpecs() {
2022-09-04 09:58:51 +02:00
let comp = duplicate(this.items.filter(item => item.type == 'specialisation') || []);
2021-12-02 20:18:21 +01:00
for (let c of comp) {
2022-09-04 09:58:51 +02:00
c.system.dice = PegasusUtility.getDiceFromLevel(c.system.level);
2021-12-02 20:18:21 +01:00
}
2021-12-02 07:38:59 +01:00
return comp;
}
2022-02-10 21:58:19 +01:00
/* -------------------------------------------- */
async manageWorstFear(flag) {
if (flag) {
2022-02-13 21:58:19 +01:00
let effect = await PegasusUtility.getEffectFromCompendium("Worst Fear")
2022-09-04 09:58:51 +02:00
effect.system.worstfear = true
2022-02-13 21:58:19 +01:00
this.createEmbeddedDocuments('Item', [effect])
2022-02-10 21:58:19 +01:00
} else {
2022-09-04 09:58:51 +02:00
let effect = this.items.find(item => item.type == "effect" && item.system.worstfear)
2022-02-10 21:58:19 +01:00
if (effect) {
2022-02-13 21:58:19 +01:00
this.deleteEmbeddedDocuments('Item', [effect.id])
2022-02-10 21:58:19 +01:00
}
}
}
/* -------------------------------------------- */
async manageDesires(flag) {
if (flag) {
2022-09-05 11:32:21 +02:00
let effect = await PegasusUtility.getEffectFromCompendium("Desire")
//console.log("EFFECT", effect)
2022-09-04 09:58:51 +02:00
effect.system.desires = true
2022-02-13 21:58:19 +01:00
this.createEmbeddedDocuments('Item', [effect])
2022-02-10 21:58:19 +01:00
} else {
2022-09-04 09:58:51 +02:00
let effect = this.items.find(item => item.type == "effect" && item.system.desires)
2022-02-10 21:58:19 +01:00
if (effect) {
2022-02-13 21:58:19 +01:00
this.deleteEmbeddedDocuments('Item', [effect.id])
2022-02-10 21:58:19 +01:00
}
}
}
2022-01-11 23:35:23 +01:00
/* -------------------------------------------- */
2022-01-14 14:49:16 +01:00
getRelevantSpec(statKey) {
2022-09-04 09:58:51 +02:00
let comp = duplicate(this.items.filter(item => item.type == 'specialisation' && item.system.statistic == statKey) || []);
2022-01-11 23:35:23 +01:00
for (let c of comp) {
2022-09-04 09:58:51 +02:00
c.system.dice = PegasusUtility.getDiceFromLevel(c.system.level);
2022-01-11 23:35:23 +01:00
}
return comp;
}
2022-01-14 14:49:16 +01:00
2021-12-03 18:31:43 +01:00
/* -------------------------------------------- */
2022-01-14 14:49:16 +01:00
async activatePerk(perkId) {
2022-09-04 09:58:51 +02:00
let item = this.items.find(item => item.id == perkId);
if (item && item.system) {
let update = { _id: item.id, "data.active": !item.system.active };
2021-12-03 18:31:43 +01:00
await this.updateEmbeddedDocuments('Item', [update]); // Updates one EmbeddedEntity
}
}
2022-01-25 09:14:32 +01:00
2022-07-19 00:18:46 +02:00
/* -------------------------------------------- */
async activateViceOrVirtue(itemId) {
2022-09-04 09:58:51 +02:00
let item = this.items.find(item => item.id == itemId)
if (item && item.system) {
let nrg = duplicate(this.system.nrg)
if (!item.system.activated) { // Current value
2022-07-19 00:18:46 +02:00
let effects = []
2022-09-04 09:58:51 +02:00
for (let effect of item.system.effectsgained) {
effect.system.powerId = itemId // Link to the perk, in order to dynamically remove them
2022-07-19 00:18:46 +02:00
effects.push(effect)
}
if (effects.length) {
await this.createEmbeddedDocuments('Item', effects)
}
} else {
let toRem = []
2022-09-04 09:58:51 +02:00
for (let item of this.items) {
if (item.type == 'effect' && item.system.powerId == itemId) {
2022-07-19 00:18:46 +02:00
toRem.push(item.id)
}
}
if (toRem.length) {
await this.deleteEmbeddedDocuments('Item', toRem)
}
}
2022-09-04 09:58:51 +02:00
let update = { _id: item.id, "data.activated": !item.system.activated }
2022-07-19 00:18:46 +02:00
await this.updateEmbeddedDocuments('Item', [update]) // Updates one EmbeddedEntity
}
}
2022-01-16 16:12:15 +01:00
/* -------------------------------------------- */
async activatePower(itemId) {
2022-09-04 09:58:51 +02:00
let item = this.items.find(item => item.id == itemId)
if (item && item.system) {
2022-02-10 21:58:19 +01:00
2022-09-04 09:58:51 +02:00
let nrg = duplicate(this.system.nrg)
if (!item.system.activated) { // Current value
2022-02-13 21:58:19 +01:00
2022-09-04 09:58:51 +02:00
if (item.system.costspent > nrg.value || item.system.costspent > nrg.max) {
2022-02-13 21:58:19 +01:00
return ui.notifications.warn("Not enough NRG to activate the Power " + item.name)
2022-02-10 21:58:19 +01:00
}
2022-08-28 18:51:52 +02:00
2022-09-04 09:58:51 +02:00
nrg.activated += item.system.costspent
nrg.value -= item.system.costspent
nrg.max -= item.system.costspent
2022-09-25 09:26:12 +02:00
await this.update({ 'system.nrg': nrg })
2022-02-10 21:58:19 +01:00
let effects = []
2022-09-04 09:58:51 +02:00
for (let effect of item.system.effectsgained) {
effect.system.powerId = itemId // Link to the perk, in order to dynamically remove them
2022-02-10 21:58:19 +01:00
effects.push(effect)
}
if (effects.length) {
await this.createEmbeddedDocuments('Item', effects)
}
2022-09-04 09:58:51 +02:00
if (item.system.activatedtext.length > 0) {
ChatMessage.create({ content: `Power ${item.name} activated : ${item.system.activatedtext}` })
2022-08-28 18:51:52 +02:00
}
2022-02-10 21:58:19 +01:00
} else {
2022-09-04 09:58:51 +02:00
nrg.activated -= item.system.costspent
nrg.max += item.system.costspent
2022-09-25 09:26:12 +02:00
await this.update({ 'system.nrg': nrg })
2022-02-10 21:58:19 +01:00
let toRem = []
2022-09-04 09:58:51 +02:00
for (let item of this.items) {
if (item.type == 'effect' && item.system.powerId == itemId) {
2022-02-13 21:58:19 +01:00
toRem.push(item.id)
2022-02-10 21:58:19 +01:00
}
}
if (toRem.length) {
await this.deleteEmbeddedDocuments('Item', toRem)
}
2022-09-04 09:58:51 +02:00
if (item.system.deactivatedtext.length > 0) {
ChatMessage.create({ content: `Power ${item.name} deactivated : ${item.system.deactivatedtext}` })
2022-08-28 18:51:52 +02:00
}
2022-02-13 21:58:19 +01:00
}
2022-09-04 09:58:51 +02:00
let update = { _id: item.id, "data.activated": !item.system.activated }
2022-02-10 21:58:19 +01:00
await this.updateEmbeddedDocuments('Item', [update]) // Updates one EmbeddedEntity
2022-01-16 16:12:15 +01:00
}
}
2021-12-03 18:31:43 +01:00
2021-12-02 07:38:59 +01:00
/* -------------------------------------------- */
2022-01-14 14:49:16 +01:00
async equipItem(itemId) {
2022-09-04 09:58:51 +02:00
let item = this.items.find(item => item.id == itemId);
if (item && item.system) {
let update = { _id: item.id, "data.equipped": !item.system.equipped };
2021-12-02 07:38:59 +01:00
await this.updateEmbeddedDocuments('Item', [update]); // Updates one EmbeddedEntity
}
}
/* -------------------------------------------- */
2022-01-14 14:49:16 +01:00
compareName(a, b) {
if (a.name < b.name) {
2021-12-02 07:38:59 +01:00
return -1;
}
2022-01-14 14:49:16 +01:00
if (a.name > b.name) {
2021-12-02 07:38:59 +01:00
return 1;
}
return 0;
}
/* ------------------------------------------- */
getEquipments() {
2022-09-04 09:58:51 +02:00
return this.items.filter(item => item.type == 'shield' || item.type == 'armor' || item.type == "weapon" || item.type == "equipment");
2021-12-02 07:38:59 +01:00
}
2022-01-28 17:27:01 +01:00
/* ------------------------------------------- */
getEquipmentsOnly() {
2022-09-04 09:58:51 +02:00
return duplicate(this.items.filter(item => item.type == "equipment") || [])
2022-01-28 17:27:01 +01:00
}
2022-01-14 14:49:16 +01:00
2022-03-12 16:35:32 +01:00
/* ------------------------------------------- */
computeThreatLevel() {
let tl = 0
2022-07-10 10:22:04 +02:00
for (let key of statThreatLevel) { // Init with concerned stats
2022-09-04 09:58:51 +02:00
tl += PegasusUtility.getDiceValue(this.system.statistics[key].value)
2022-03-12 16:35:32 +01:00
}
2022-07-10 10:22:04 +02:00
let powers = duplicate(this.getPowers() || [])
if (powers.length > 0) { // Then add some mental ones of powers
2022-09-04 09:58:51 +02:00
tl += PegasusUtility.getDiceValue(this.system.statistics.foc.value)
tl += PegasusUtility.getDiceValue(this.system.statistics.mnd.value)
2022-03-12 16:35:32 +01:00
}
2022-09-04 09:58:51 +02:00
tl += PegasusUtility.getDiceValue(this.system.mr.value)
let specThreat = this.items.filter(it => it.type == "specialisation" && it.system.isthreatlevel) || []
2022-03-12 16:35:32 +01:00
for (let spec of specThreat) {
2022-09-04 09:58:51 +02:00
tl += PegasusUtility.getDiceValue(spec.system.level)
2022-03-12 16:35:32 +01:00
}
2022-09-04 09:58:51 +02:00
tl += this.system.nrg.absolutemax + this.system.secondary.health.max + this.system.secondary.delirium.max
2022-03-12 16:35:32 +01:00
tl += this.getPerks().length * 5
let weapons = this.getWeapons()
2022-07-10 10:22:04 +02:00
for (let weapon of weapons) {
2022-09-04 09:58:51 +02:00
tl += PegasusUtility.getDiceValue(weapon.system.damage)
2022-03-12 16:35:32 +01:00
}
let armors = this.getArmors()
2022-07-10 10:22:04 +02:00
for (let armor of armors) {
2022-09-04 09:58:51 +02:00
tl += PegasusUtility.getDiceValue(armor.system.resistance)
2022-03-12 16:35:32 +01:00
}
2022-03-14 20:54:13 +01:00
let shields = duplicate(this.getShields())
2022-07-10 10:22:04 +02:00
for (let shield of shields) {
2022-09-04 09:58:51 +02:00
tl += PegasusUtility.getDiceValue(shield.system.level)
2022-03-12 16:35:32 +01:00
}
2022-03-14 14:09:26 +01:00
let abilities = duplicate(this.getAbilities())
for (let ability of abilities) {
2022-09-04 09:58:51 +02:00
tl += ability.system.threatlevel
2022-03-14 14:09:26 +01:00
}
2022-03-12 16:35:32 +01:00
let equipments = this.getEquipmentsOnly()
for (let equip of equipments) {
2022-09-04 09:58:51 +02:00
tl += equip.system.threatlevel
2022-03-12 16:35:32 +01:00
}
2022-09-04 09:58:51 +02:00
if (tl != this.system.biodata.threatlevel) {
2022-09-25 09:26:12 +02:00
this.update({ 'system.biodata.threatlevel': tl })
2022-03-12 16:35:32 +01:00
}
}
2022-03-06 20:07:41 +01:00
/* ------------------------------------------- */
async buildContainerTree() {
2022-09-04 09:58:51 +02:00
let equipments = duplicate(this.items.filter(item => item.type == "equipment") || [])
2022-03-06 20:07:41 +01:00
for (let equip1 of equipments) {
2022-09-04 09:58:51 +02:00
if (equip1.system.iscontainer) {
equip1.system.contents = []
equip1.system.contentsEnc = 0
2022-03-06 20:07:41 +01:00
for (let equip2 of equipments) {
2022-09-04 09:58:51 +02:00
if (equip1._id != equip2._id && equip2.system.containerid == equip1._id) {
equip1.system.contents.push(equip2)
let q = equip2.system.quantity ?? 1
equip1.system.contentsEnc += q * equip2.system.weight
2022-03-06 20:07:41 +01:00
}
}
}
}
2022-03-07 16:00:53 +01:00
// Compute whole enc
2022-03-06 20:07:41 +01:00
let enc = 0
2022-03-07 16:00:53 +01:00
for (let item of equipments) {
2022-09-04 09:58:51 +02:00
item.system.idrDice = PegasusUtility.getDiceFromLevel(Number(item.system.idr))
if (item.system.equipped) {
if (item.system.iscontainer) {
enc += item.system.contentsEnc
} else if (item.system.containerid == "") {
let q = item.system.quantity ?? 1
enc += q * item.system.weight
2022-03-06 20:07:41 +01:00
}
}
}
2022-09-04 09:58:51 +02:00
for (let item of this.items) { // Process items/shields/armors
if ((item.type == "weapon" || item.type == "shield" || item.type == "armor") && item.system.equipped) {
let q = item.system.quantity ?? 1
enc += q * item.system.weight
2022-03-07 16:00:53 +01:00
}
}
// Store local values
2022-03-06 20:07:41 +01:00
this.encCurrent = enc
2022-09-04 09:58:51 +02:00
this.containersTree = equipments.filter(item => item.system.containerid == "") // Returns the root of equipements without container
2022-03-06 20:07:41 +01:00
// Manages slow effect
2022-03-07 16:00:53 +01:00
let overCapacity = Math.floor(this.encCurrent / this.getEncumbranceCapacity())
this.encHindrance = Math.floor(this.encCurrent / this.getEncumbranceCapacity())
2022-03-06 20:07:41 +01:00
//console.log("Capacity", overCapacity, this.encCurrent / this.getEncumbranceCapacity() )
2022-09-04 09:58:51 +02:00
let effect = this.items.find(item => item.type == "effect" && item.system.slow)
2022-03-07 16:00:53 +01:00
if (overCapacity >= 4) {
if (!effect) {
2022-03-06 20:07:41 +01:00
effect = await PegasusUtility.getEffectFromCompendium("Slowed")
2022-09-04 09:58:51 +02:00
effect.system.slow = true
2022-03-06 20:07:41 +01:00
this.createEmbeddedDocuments('Item', [effect])
}
} else {
if (effect) {
this.deleteEmbeddedDocuments('Item', [effect.id])
}
}
}
2022-07-10 10:22:04 +02:00
/* -------------------------------------------- */
modifyStun(incDec) {
2022-09-04 09:58:51 +02:00
let combat = duplicate(this.system.combat)
2022-07-10 10:22:04 +02:00
combat.stunlevel += incDec
if (combat.stunlevel >= 0) {
2022-09-25 09:26:12 +02:00
this.update({ 'system.combat': combat })
2022-07-10 10:22:04 +02:00
let chatData = {
user: game.user.id,
rollMode: game.settings.get("core", "rollMode"),
whisper: [game.user.id].concat(ChatMessage.getWhisperRecipients('GM'))
}
if (incDec > 0) {
chatData.content = `<div>${this.name} suffered a Stun level.</div`
} else {
chatData.content = `<div>${this.name} recovered a Stun level.</div`
}
ChatMessage.create(chatData)
} else {
ui.notifications.warn("Stun level cannot go below 0")
}
let stunAbove = combat.stunlevel - combat.stunthreshold
2022-08-14 15:27:54 +02:00
if (stunAbove > 0) {
2022-08-24 20:24:22 +02:00
ChatMessage.create({ content: `${this.name} Stun threshold has been exceeded.` })
2022-08-14 15:27:54 +02:00
}
2022-07-10 10:22:04 +02:00
if (incDec > 0 && stunAbove > 0) {
2022-09-04 09:58:51 +02:00
let delirium = duplicate(this.system.secondary.delirium)
2022-07-10 10:22:04 +02:00
delirium.value -= incDec
2022-09-25 09:26:12 +02:00
this.update({ 'system.secondary.delirium': delirium })
2022-07-10 10:22:04 +02:00
}
}
2022-03-06 20:07:41 +01:00
/* -------------------------------------------- */
2022-03-07 16:00:53 +01:00
modifyMomentum(incDec) {
2022-09-04 09:58:51 +02:00
let momentum = duplicate(this.system.momentum)
2022-03-06 20:07:41 +01:00
momentum.value += incDec
2022-09-25 09:26:12 +02:00
this.update({ 'system.momentum': momentum })
2022-07-20 23:53:37 +02:00
let chatData = {
user: game.user.id,
rollMode: game.settings.get("core", "rollMode"),
whisper: [game.user.id].concat(ChatMessage.getWhisperRecipients('GM'))
}
if (incDec > 0) {
chatData.content = `<div>${this.name} has gained a Momentum</div`
2022-07-10 10:22:04 +02:00
} else {
2022-07-20 23:53:37 +02:00
chatData.content = `<div>${this.name} has used a Momentum</div`
}
ChatMessage.create(chatData)
if (incDec < 0 && momentum.value >= 0) {
PegasusUtility.showMomentumDialog(this.id)
2022-03-06 20:07:41 +01:00
}
}
2022-03-07 16:00:53 +01:00
2021-12-02 07:38:59 +01:00
/* -------------------------------------------- */
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) {
2022-09-04 09:58:51 +02:00
return this.getActiveEffects().find(it => it.system.label == label);
2021-12-02 07:38:59 +01:00
}
/* -------------------------------------------- */
getEffectById(id) {
return this.getActiveEffects().find(it => it.id == id);
}
/* -------------------------------------------- */
2022-01-14 14:49:16 +01:00
getAttribute(attrKey) {
2022-09-04 09:58:51 +02:00
return this.system.attributes[attrKey];
2021-12-02 07:38:59 +01:00
}
2022-01-30 09:44:37 +01:00
2022-03-06 20:07:41 +01:00
/* -------------------------------------------- */
2022-03-07 16:00:53 +01:00
async addObjectToContainer(itemId, containerId) {
2022-09-04 09:58:51 +02:00
let container = this.items.find(item => item.id == containerId && item.system.iscontainer)
let object = this.items.find(item => item.id == itemId)
2022-03-07 16:00:53 +01:00
if (container) {
2022-09-04 09:58:51 +02:00
if (object.system.iscontainer) {
2022-03-06 20:07:41 +01:00
ui.notifications.warn("Only 1 level of container allowed")
return
}
2022-09-04 09:58:51 +02:00
let alreadyInside = this.items.filter(item => item.system.containerid && item.system.containerid == containerId);
if (alreadyInside.length >= container.system.containercapacity) {
2022-03-06 20:07:41 +01:00
ui.notifications.warn("Container is already full !")
return
2022-03-07 16:00:53 +01:00
} else {
2022-09-25 09:26:12 +02:00
await this.updateEmbeddedDocuments("Item", [{ _id: object.id, 'system.containerid': containerId }])
2022-03-06 20:07:41 +01:00
}
2022-09-04 09:58:51 +02:00
} else if (object && object.system.containerid) { // remove from container
2022-03-06 20:07:41 +01:00
console.log("Removeing: ", object)
2022-09-25 09:26:12 +02:00
await this.updateEmbeddedDocuments("Item", [{ _id: object.id, 'system.containerid': "" }]);
2022-03-06 20:07:41 +01:00
}
}
2022-07-19 20:51:48 +02:00
/* -------------------------------------------- */
2022-07-20 23:53:37 +02:00
checkVirtue(virtue) {
2022-07-19 20:51:48 +02:00
let vices = this.getVices()
for (let vice of vices) {
2022-09-04 09:58:51 +02:00
let nonVirtues = vice.system.unavailablevirtue
2022-07-19 20:51:48 +02:00
for (let blockedVirtue of nonVirtues) {
if (blockedVirtue.name.toLowerCase() == virtue.name.toLowerCase()) {
return false
2022-07-20 23:53:37 +02:00
}
2022-07-19 20:51:48 +02:00
}
}
return true
}
/* -------------------------------------------- */
2022-07-20 23:53:37 +02:00
checkVice(vice) {
2022-07-19 20:51:48 +02:00
let virtues = this.getVirtues()
for (let virtue of virtues) {
2022-09-04 09:58:51 +02:00
let nonVices = virtue.system.unavailablevice
2022-07-19 20:51:48 +02:00
for (let blockedVice of nonVices) {
if (blockedVice.name.toLowerCase() == vice.name.toLowerCase()) {
return false
2022-07-20 23:53:37 +02:00
}
2022-07-19 20:51:48 +02:00
}
}
return true
}
2022-03-06 20:07:41 +01:00
2021-12-02 07:38:59 +01:00
/* -------------------------------------------- */
2022-02-10 21:58:19 +01:00
async preprocessItem(event, item, onDrop = false) {
2022-08-14 15:27:54 +02:00
2022-09-25 09:26:12 +02:00
console.log("Pre-process", item)
if (item.type != "effect" && __isVehicle[item.type]) {
2022-09-18 17:30:15 +02:00
ui.notifications.warn("You can't drop Vehicles item over a character sheet.")
return
}
2022-09-16 17:36:58 +02:00
2022-08-14 15:27:54 +02:00
// Pre-filter effects
2022-09-04 09:58:51 +02:00
if (item.type == 'effect') {
if (this.checkMentalDisruption() && item.system.type == "mental" && item.system.genre == "positive") {
2022-08-24 20:24:22 +02:00
ChatMessage.create({ content: "Effects of this type cannot be applied while Disruption is applied, Use a Soft Action to remove Disruption" })
2022-08-14 15:27:54 +02:00
return
}
2022-09-04 09:58:51 +02:00
if (this.checkPhysicalDisruption() && item.system.type == "physical" && item.system.genre == "positive") {
2022-08-24 20:24:22 +02:00
ChatMessage.create({ content: "Effects of this type cannot be applied while Disruption is applied, Use a Soft Action to remove Disruption" })
2022-08-14 15:27:54 +02:00
return
}
2022-09-04 09:58:51 +02:00
if (this.checkMentalImmunity() && item.system.type == "mental" && item.system.genre == "negative") {
2022-08-24 20:24:22 +02:00
ChatMessage.create({ content: "Effects of this type cannot be applied while Immunity is applied" })
2022-08-14 15:27:54 +02:00
return
}
2022-09-04 09:58:51 +02:00
if (this.checkPhysicalImmunity() && item.system.type == "physical" && item.system.genre == "negative") {
2022-08-24 20:24:22 +02:00
ChatMessage.create({ content: "Effects of this type cannot be applied while Immunity is applied" })
2022-08-14 15:27:54 +02:00
return
}
}
2022-09-18 17:30:15 +02:00
2022-09-04 09:58:51 +02:00
if (item.type == 'race') {
2022-09-25 09:26:12 +02:00
this.applyRace(item)
2022-09-04 09:58:51 +02:00
} else if (item.type == 'role') {
2022-09-25 09:26:12 +02:00
this.applyRole(item)
2022-09-04 09:58:51 +02:00
} else if (item.type == 'ability') {
2022-09-25 09:26:12 +02:00
this.applyAbility(item, [], true)
2022-02-10 21:58:19 +01:00
if (!onDrop) {
2022-09-04 09:58:51 +02:00
await this.createEmbeddedDocuments('Item', [item])
2022-02-10 15:53:42 +01:00
}
2022-01-30 09:44:37 +01:00
} else {
2022-02-10 21:58:19 +01:00
if (!onDrop) {
2022-09-04 09:58:51 +02:00
await this.createEmbeddedDocuments('Item', [item])
2022-01-30 09:44:37 +01:00
}
}
2022-07-19 20:51:48 +02:00
// Check virtue/vice validity
2022-09-04 09:58:51 +02:00
if (item.type == "virtue") {
2022-07-20 23:53:37 +02:00
if (!this.checkVirtue(item)) {
2022-07-19 20:51:48 +02:00
ui.notifications.info("Virtue is not allowed due to Vice.")
return false
2022-07-20 23:53:37 +02:00
}
2022-07-19 20:51:48 +02:00
}
2022-09-04 09:58:51 +02:00
if (item.type == "vice") {
2022-07-20 23:53:37 +02:00
if (!this.checkVice(item)) {
2022-07-19 20:51:48 +02:00
ui.notifications.info("Vice is not allowed due to Virtue.")
return false
2022-07-20 23:53:37 +02:00
}
2022-07-19 20:51:48 +02:00
}
2022-09-09 08:33:28 +02:00
if (item.type == "power" && item.system.purchasedtext.length > 0) {
2022-09-04 09:58:51 +02:00
ChatMessage.create({ content: `Power ${item.name} puchased : ${item.system.purchasedtext}` })
2022-08-28 18:51:52 +02:00
}
2022-03-06 20:07:41 +01:00
let dropID = $(event.target).parents(".item").attr("data-item-id") // Only relevant if container drop
let objectID = item.id || item._id
2022-03-07 16:00:53 +01:00
this.addObjectToContainer(objectID, dropID)
2022-07-19 20:51:48 +02:00
return true
2022-01-30 09:44:37 +01:00
}
2021-12-02 07:38:59 +01:00
2022-01-30 09:44:37 +01:00
/* -------------------------------------------- */
2022-01-14 14:49:16 +01:00
async equipGear(equipmentId) {
2022-09-04 09:58:51 +02:00
let item = this.items.find(item => item.id == equipmentId);
if (item && item.system) {
let update = { _id: item.id, "data.equipped": !item.system.equipped };
2021-12-02 07:38:59 +01:00
await this.updateEmbeddedDocuments('Item', [update]); // Updates one EmbeddedEntity
}
}
/* -------------------------------------------- */
2022-02-10 21:58:19 +01:00
getInitiativeScore(combatId, combatantId) {
2022-01-14 14:49:16 +01:00
if (this.type == 'character') {
2022-01-28 10:05:54 +01:00
this.rollMR(true, combatId, combatantId)
2022-01-14 14:49:16 +01:00
}
2022-01-28 10:05:54 +01:00
console.log("Init required !!!!")
return -1;
2021-12-02 07:38:59 +01:00
}
/* -------------------------------------------- */
getSubActors() {
let subActors = [];
2022-09-25 14:51:43 +02:00
if (this.system.subactors) {
for (let id of this.system.subactors) {
subActors.push(duplicate(game.actors.get(id)))
}
2021-12-02 07:38:59 +01:00
}
return subActors;
}
/* -------------------------------------------- */
2022-01-14 14:49:16 +01:00
async addSubActor(subActorId) {
2022-09-25 14:51:43 +02:00
let subActors = duplicate(this.system.subactors || []);
2022-01-14 14:49:16 +01:00
subActors.push(subActorId);
2022-09-25 09:26:12 +02:00
await this.update({ 'system.subactors': subActors });
2021-12-02 07:38:59 +01:00
}
2022-09-25 14:51:43 +02:00
2021-12-02 07:38:59 +01:00
/* -------------------------------------------- */
2022-01-14 14:49:16 +01:00
async delSubActor(subActorId) {
2021-12-02 07:38:59 +01:00
let newArray = [];
2022-09-04 09:58:51 +02:00
for (let id of this.system.subactors) {
2022-01-14 14:49:16 +01:00
if (id != subActorId) {
newArray.push(id);
2021-12-02 07:38:59 +01:00
}
}
2022-09-25 09:26:12 +02:00
await this.update({ 'system.subactors': newArray });
2021-12-02 07:38:59 +01:00
}
/* -------------------------------------------- */
2022-01-14 14:49:16 +01:00
syncRoll(rollData) {
2021-12-02 20:18:21 +01:00
let linkedRollId = PegasusUtility.getDefenseState(this.id);
2022-01-14 14:49:16 +01:00
if (linkedRollId) {
2021-12-02 07:38:59 +01:00
rollData.linkedRollId = linkedRollId;
}
this.lastRollId = rollData.rollId;
2022-01-14 14:49:16 +01:00
PegasusUtility.saveRollData(rollData);
2021-12-02 20:18:21 +01:00
}
/* -------------------------------------------- */
2022-01-14 14:49:16 +01:00
getStat(statKey) {
2022-01-12 16:25:55 +01:00
let stat
2022-09-21 16:54:34 +02:00
if (this.type == "character" && statKey == 'mr') {
2022-09-04 09:58:51 +02:00
stat = duplicate(this.system.mr);
2022-01-12 16:25:55 +01:00
} else {
2022-09-04 09:58:51 +02:00
stat = duplicate(this.system.statistics[statKey]);
2022-01-12 16:25:55 +01:00
}
2022-09-21 16:54:34 +02:00
stat.dice = PegasusUtility.getDiceFromLevel(stat.value || stat.level);
2021-12-02 20:18:21 +01:00
return stat;
2021-12-02 07:38:59 +01:00
}
/* -------------------------------------------- */
2022-01-14 14:49:16 +01:00
getOneSpec(specId) {
2022-09-04 09:58:51 +02:00
let spec = this.items.find(item => item.type == 'specialisation' && item.id == specId)
2021-12-02 20:18:21 +01:00
if (spec) {
spec = duplicate(spec);
2022-09-04 09:58:51 +02:00
spec.system.dice = PegasusUtility.getDiceFromLevel(spec.system.level);
2021-12-02 20:18:21 +01:00
}
return spec;
}
2022-01-12 16:25:55 +01:00
/* -------------------------------------------- */
2022-02-10 21:58:19 +01:00
specPowerActivate(specId) {
let spec = this.getOneSpec(specId)
if (spec) {
let powers = []
2022-09-04 09:58:51 +02:00
for (let power of spec.system.powers) {
2022-09-09 08:33:28 +02:00
if (power.data) {
power.system = power.data
2022-09-04 09:58:51 +02:00
}
power.system.specId = specId
2022-02-10 21:58:19 +01:00
powers.push(power)
}
if (powers.length > 0) {
this.createEmbeddedDocuments('Item', powers)
}
2022-09-25 09:26:12 +02:00
this.updateEmbeddedDocuments('Item', [{ _id: specId, 'system.powersactivated': true }])
2022-02-10 21:58:19 +01:00
}
}
/* -------------------------------------------- */
specPowerDeactivate(specId) {
let toRem = []
2022-09-04 09:58:51 +02:00
for (let power of this.items) {
if (power.type == "power" && power.system.specId && power.system.specId == specId) {
2022-02-10 21:58:19 +01:00
toRem.push(power.id)
}
}
if (toRem.length > 0) {
this.deleteEmbeddedDocuments('Item', toRem)
}
2022-09-25 09:26:12 +02:00
this.updateEmbeddedDocuments('Item', [{ _id: specId, 'system.powersactivated': false }])
2022-02-10 21:58:19 +01:00
}
2022-02-16 17:43:51 +01:00
/* -------------------------------------------- */
equipActivate(itemId) {
let item = this.items.get(itemId)
if (item) {
let effects = []
2022-09-04 09:58:51 +02:00
for (let effect of item.system.effects) {
effect.system.itemId = itemId // Keep link
2022-02-16 17:43:51 +01:00
effects.push(effect)
}
if (effects.length > 0) {
2022-03-07 16:00:53 +01:00
this.createEmbeddedDocuments('Item', effects)
2022-02-16 17:43:51 +01:00
}
2022-09-25 09:26:12 +02:00
this.updateEmbeddedDocuments('Item', [{ _id: itemId, 'system.activated': true }])
2022-02-16 17:43:51 +01:00
}
}
/* -------------------------------------------- */
equipDeactivate(itemId) {
let toRem = []
2022-09-04 09:58:51 +02:00
for (let item of this.items) {
if (item.system.itemId && item.system.itemId == itemId) {
2022-02-16 17:43:51 +01:00
toRem.push(item.id)
}
}
if (toRem.length > 0) {
this.deleteEmbeddedDocuments('Item', toRem)
}
2022-09-25 09:26:12 +02:00
this.updateEmbeddedDocuments('Item', [{ _id: itemId, 'system.activated': false }])
2022-02-16 17:43:51 +01:00
}
2022-02-10 21:58:19 +01:00
/* -------------------------------------------- */
async perkEffectUsed(itemId) {
2022-02-10 19:03:09 +01:00
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)
});
2022-02-10 21:58:19 +01:00
this.deleteEmbeddedDocuments('Item', [effect.id])
}
}
/* -------------------------------------------- */
disableWeaverPerk(perk) {
2022-09-04 09:58:51 +02:00
if (perk.system.isweaver) {
for (let spec of this.items) {
if (spec.type == 'specialisation' && spec.system.ispowergroup) {
2022-02-10 21:58:19 +01:00
this.specPowerDeactivate(spec.id)
}
}
}
}
/* -------------------------------------------- */
enableWeaverPerk(perk) {
2022-09-04 09:58:51 +02:00
if (perk.system.isweaver) {
for (let spec of this.items) {
if (spec.type == 'specialisation' && spec.system.ispowergroup) {
2022-02-10 21:58:19 +01:00
this.specPowerActivate(spec.id)
}
}
2022-02-10 19:03:09 +01:00
}
}
2022-02-13 21:58:19 +01:00
/* -------------------------------------------- */
async cleanPerkEffects(itemId) {
let effects = []
2022-09-04 09:58:51 +02:00
for (let item of this.items) {
if (item.type == "effect" && item.system.perkId == itemId) {
2022-02-13 21:58:19 +01:00
effects.push(item.id)
}
}
2022-02-16 12:14:34 +01:00
if (effects.length > 0) {
2022-02-16 14:13:16 +01:00
console.log("DELET!!!!", effects, this)
2022-02-13 21:58:19 +01:00
await this.deleteEmbeddedDocuments('Item', effects)
}
}
/* -------------------------------------------- */
async updatePerkUsed(itemId, index, checked) {
let item = this.items.get(itemId)
if (item && index) {
let key = "data.used" + index
2022-02-16 14:13:16 +01:00
await this.updateEmbeddedDocuments('Item', [{ _id: itemId, [`${key}`]: checked }])
2022-02-13 21:58:19 +01:00
item = this.items.get(itemId) // Refresh
2022-09-04 09:58:51 +02:00
if (item.system.nbuse == "next1action" && item.system.used1) {
2022-02-13 21:58:19 +01:00
this.cleanPerkEffects(itemId)
}
2022-09-04 09:58:51 +02:00
if (item.system.nbuse == "next2action" && item.system.used1 && item.system.used2) {
2022-02-13 21:58:19 +01:00
this.cleanPerkEffects(itemId)
}
2022-09-04 09:58:51 +02:00
if (item.system.nbuse == "next3action" && item.system.used1 && item.system.used2 && item.system.used3) {
2022-02-13 21:58:19 +01:00
this.cleanPerkEffects(itemId)
}
}
}
/* -------------------------------------------- */
async updatePowerSpentCost(itemId, value) {
let item = this.items.get(itemId)
if (item && value) {
value = Number(value) || 0
2022-09-25 09:26:12 +02:00
await this.updateEmbeddedDocuments('Item', [{ _id: itemId, 'system.costspent': value }])
2022-02-13 21:58:19 +01:00
}
}
2022-07-20 23:53:37 +02:00
/* -------------------------------------------- */
async cleanupPerksIfTrauma() {
2022-07-28 18:45:04 +02:00
if (this.getTraumaState() == "severetrauma") {
2022-09-04 09:58:51 +02:00
for (let perk of this.items) {
2022-07-20 23:53:37 +02:00
if (perk.type == "perk") {
this.cleanPerkEffects(perk.id)
2022-09-25 09:26:12 +02:00
this.updateEmbeddedDocuments('Item', [{ _id: perk.id, 'system.status': "ready", 'system.used1': false, 'system.used2': false, 'system.used3': false }])
2022-07-28 18:45:04 +02:00
ChatMessage.create({ content: `Perk ${perk.name} has been deactivated due to Severe Trauma state !` })
2022-07-20 23:53:37 +02:00
}
}
}
}
2022-07-28 18:45:04 +02:00
2022-07-26 22:38:04 +02:00
/* -------------------------------------------- */
2022-07-28 18:45:04 +02:00
incDecNRG(value) {
2022-09-16 17:36:58 +02:00
if (this.type == "character") {
let nrg = duplicate(this.system.nrg)
nrg.value += value
if (nrg.value >= 0 && nrg.value <= nrg.max) {
2022-09-25 09:26:12 +02:00
this.update({ 'system.nrg': nrg })
2022-09-16 17:36:58 +02:00
}
} else {
let pc = duplicate(this.system.statistics.pc)
pc.curnrg += value
2022-09-21 16:54:34 +02:00
if (pc.curnrg >= 0 && pc.curnrg <= pc.maxnrg) {
2022-09-16 17:36:58 +02:00
this.update({ 'system.statistics.pc': pc })
}
2022-07-26 22:38:04 +02:00
}
}
2022-02-10 19:03:09 +01:00
/* -------------------------------------------- */
async updatePerkStatus(itemId, status) {
2022-01-14 14:49:16 +01:00
let item = this.items.get(itemId)
2022-01-12 16:25:55 +01:00
if (item) {
2022-02-10 19:03:09 +01:00
2022-09-04 09:58:51 +02:00
if (item.system.status == status) return;// Ensure we are really changing the status
2022-08-24 20:24:22 +02:00
if (this.checkNoPerksAllowed()) {
2022-09-04 09:58:51 +02:00
await this.updateEmbeddedDocuments('Item', [{ _id: item.id, 'system.status': "ready" }])
2022-08-24 20:24:22 +02:00
ChatMessage.create({ content: "No perks activation allowed due to effect !" })
2022-08-14 15:27:54 +02:00
return
}
2022-02-10 21:58:19 +01:00
2022-07-10 10:22:04 +02:00
// Severe Trauma management
if (this.getTraumaState() == "severetrauma") {
2022-08-24 20:24:22 +02:00
if (!this.severeTraumaMessage) {
2022-07-30 22:44:44 +02:00
let chatData = {
user: game.user.id,
rollMode: game.settings.get("core", "rollMode"),
whisper: [game.user.id].concat(ChatMessage.getWhisperRecipients('GM'))
}
chatData.content = `<div>${this.name} is suffering from Severe Trauma and cannot use Perks at this time.</div`
ChatMessage.create(chatData)
this.severeTraumaMessage = true
2022-07-10 10:22:04 +02:00
}
2022-09-04 09:58:51 +02:00
this.updateEmbeddedDocuments('Item', [{ _id: itemId, 'system.status': "ready", 'system.used1': false, 'system.used2': false, 'system.used3': false }])
2022-07-10 10:22:04 +02:00
return
}
2022-02-10 19:03:09 +01:00
let updateOK = true
2022-02-10 21:58:19 +01:00
if (status == "ready") {
2022-02-16 14:13:16 +01:00
await this.cleanPerkEffects(itemId)
2022-09-04 09:58:51 +02:00
await this.updateEmbeddedDocuments('Item', [{ _id: itemId, 'system.used1': false, 'system.used2': false, 'system.used3': false }])
if (item.system.features.nrgcost.flag) {
let nrg = duplicate(this.system.nrg)
nrg.activated -= item.system.features.nrgcost.value
nrg.max += item.system.features.nrgcost.value
await this.update({ 'system.nrg': nrg })
2022-02-10 19:03:09 +01:00
}
2022-09-04 09:58:51 +02:00
if (item.system.features.bonushealth.flag) {
let health = duplicate(this.system.secondary.health)
health.value -= Number(item.system.features.bonushealth.value) || 0
health.max -= Number(item.system.features.bonushealth.value) || 0
await this.update({ 'system.secondary.health': health })
2022-02-10 19:03:09 +01:00
}
2022-09-04 09:58:51 +02:00
if (item.system.features.bonusdelirium.flag) {
let delirium = duplicate(this.system.secondary.delirium)
delirium.value -= Number(item.system.features.bonusdelirium.value) || 0
delirium.max -= Number(item.system.features.bonusdelirium.value) || 0
await this.update({ 'system.secondary.delirium': delirium })
2022-02-10 19:03:09 +01:00
}
2022-09-04 09:58:51 +02:00
if (item.system.features.bonusnrg.flag) {
let nrg = duplicate(this.system.nrg)
nrg.value -= Number(item.system.features.bonusnrg.value) || 0
nrg.max -= Number(item.system.features.bonusnrg.value) || 0
await this.update({ 'system.nrg': nrg })
2022-02-10 19:03:09 +01:00
}
2022-02-10 21:58:19 +01:00
this.disableWeaverPerk(item)
2022-02-16 17:43:51 +01:00
PegasusUtility.createChatWithRollMode(item.name, {
2022-08-16 21:21:37 +02:00
content: await renderTemplate(`systems/fvtt-pegasus-rpg/templates/chat-perk-ready.html`, { name: this.name, perk: duplicate(item) })
2022-07-26 22:38:04 +02:00
})
2022-02-10 19:03:09 +01:00
}
2022-02-10 21:58:19 +01:00
if (status == "activated") {
2022-02-10 19:03:09 +01:00
// Add effects linked to the perk
let effects = []
2022-09-09 08:33:28 +02:00
for (let effect of item.system.effectsgained) {
2022-09-04 09:58:51 +02:00
if (effect.data) {
effect.system = effect.data
}
effect.system.perkId = itemId // Link to the perk, in order to dynamically remove them
effect.system.isUsed = false // Flag to indicate removal when used in a roll window
2022-02-10 21:58:19 +01:00
effects.push(effect)
2022-02-10 19:03:09 +01:00
}
2022-02-10 21:58:19 +01:00
if (effects.length) {
await this.createEmbeddedDocuments('Item', effects)
2022-02-10 19:03:09 +01:00
}
// Manage additional flags
2022-09-04 09:58:51 +02:00
if (item.system.features.nrgcost.flag) {
if ((this.system.nrg.value >= item.system.features.nrgcost.value) && (this.system.nrg.max >= item.system.features.nrgcost.value)) {
let nrg = duplicate(this.system.nrg)
nrg.activated += item.system.features.nrgcost.value
nrg.value -= item.system.features.nrgcost.value
nrg.max -= item.system.features.nrgcost.value
await this.update({ 'system.nrg': nrg })
2022-02-10 19:03:09 +01:00
} else {
updateOK = false
ui.notifications.warn("Not enough NRG to activate the Perk " + item.name)
}
}
2022-09-04 09:58:51 +02:00
if (item.system.features.bonushealth.flag) {
let health = duplicate(this.system.secondary.health)
health.value += Number(item.system.features.bonushealth.value) || 0
health.max += Number(item.system.features.bonushealth.value) || 0
await this.update({ 'system.secondary.health': health })
2022-02-10 19:03:09 +01:00
}
2022-09-04 09:58:51 +02:00
if (item.system.features.bonusdelirium.flag) {
let delirium = duplicate(this.system.secondary.delirium)
delirium.value += Number(item.system.features.bonusdelirium.value) || 0
delirium.max += Number(item.system.features.bonusdelirium.value) || 0
await this.update({ 'system.secondary.delirium': delirium })
2022-02-10 19:03:09 +01:00
}
2022-09-04 09:58:51 +02:00
if (item.system.features.bonusnrg.flag) {
let nrg = duplicate(this.system.nrg)
nrg.value += Number(item.system.features.bonusnrg.value) || 0
nrg.max += Number(item.system.features.bonusnrg.value) || 0
await this.update({ 'system.nrg': nrg })
2022-02-10 19:03:09 +01:00
}
2022-07-26 22:38:04 +02:00
PegasusUtility.createChatWithRollMode(item.name, {
2022-08-16 21:21:37 +02:00
content: await renderTemplate(`systems/fvtt-pegasus-rpg/templates/chat-perk-activated.html`, { name: this.name, perk: duplicate(item) })
2022-07-26 22:38:04 +02:00
})
2022-02-10 21:58:19 +01:00
this.enableWeaverPerk(item)
2022-02-10 19:03:09 +01:00
}
if (updateOK) {
2022-09-04 09:58:51 +02:00
await this.updateEmbeddedDocuments('Item', [{ _id: item.id, 'system.status': status }])
2022-02-10 19:03:09 +01:00
}
2022-01-12 16:25:55 +01:00
}
}
2021-12-02 07:38:59 +01:00
/* -------------------------------------------- */
2022-01-14 14:49:16 +01:00
async deleteAllItemsByType(itemType) {
2022-09-04 09:58:51 +02:00
let items = this.items.filter(item => item.type == itemType);
2022-01-14 14:49:16 +01:00
await this.deleteEmbeddedDocuments('Item', items);
2022-01-07 20:40:40 +01:00
}
2022-01-08 10:49:08 +01:00
/* -------------------------------------------- */
2022-01-14 14:49:16 +01:00
async addItemWithoutDuplicate(newItem) {
2022-09-04 09:58:51 +02:00
let item = this.items.find(item => item.type == newItem.type && item.name.toLowerCase() == newItem.name.toLowerCase())
2022-01-14 14:49:16 +01:00
if (!item) {
await this.createEmbeddedDocuments('Item', [newItem]);
2022-01-08 10:49:08 +01:00
}
}
2022-07-10 10:22:04 +02:00
/* -------------------------------------------- */
getTraumaState() {
this.traumaState = "none"
2022-09-25 09:26:12 +02:00
if (this.type == "character") {
2022-09-21 16:54:34 +02:00
let negDelirium = -Math.floor((this.system.secondary.delirium.max + 1) / 2)
if (this.type == "character") {
if (this.system.secondary.delirium.value <= 0 && this.system.secondary.delirium.value >= negDelirium) {
this.traumaState = "trauma"
}
if (this.system.secondary.delirium.value < negDelirium) {
this.traumaState = "severetrauma"
}
2022-07-10 10:22:04 +02:00
}
}
return this.traumaState
}
2022-07-13 22:47:07 +02:00
/* -------------------------------------------- */
getLevelRemaining() {
2022-09-04 09:58:51 +02:00
return this.system.biodata.currentlevelremaining
2022-07-13 22:47:07 +02:00
}
/* -------------------------------------------- */
2022-07-19 00:18:46 +02:00
modifyHeroLevelRemaining(incDec) {
2022-09-04 09:58:51 +02:00
let biodata = duplicate(this.system.biodata)
2022-07-19 00:18:46 +02:00
biodata.currentlevelremaining = Math.max(biodata.currentlevelremaining + incDec, 0)
2022-09-25 14:45:02 +02:00
this.update({ "system.biodata": biodata })
2022-07-19 21:56:59 +02:00
ChatMessage.create({ content: `${this.name} has used a Hero Level to reroll !` })
2022-07-13 22:47:07 +02:00
return biodata.currentlevelremaining
}
2022-08-24 20:24:22 +02:00
2022-08-14 15:27:54 +02:00
/* -------------------------------------------- */
checkIgnoreHealth() {
2022-09-04 09:58:51 +02:00
for (let effect of this.items) {
if (effect.type == "effect" && effect.system.ignorehealthpenalty) {
2022-08-14 15:27:54 +02:00
return true
}
}
return false
}
/* -------------------------------------------- */
checkMentalDisruption() {
2022-09-04 09:58:51 +02:00
for (let effect of this.items) {
if (effect.type == "effect" && effect.system.mentaldisruption) {
2022-08-14 15:27:54 +02:00
return true
}
}
return false
}
/* -------------------------------------------- */
checkPhysicalDisruption() {
2022-09-04 09:58:51 +02:00
for (let effect of this.items) {
if (effect.type == "effect" && effect.system.physicaldisruption) {
2022-08-14 15:27:54 +02:00
return true
}
}
return false
}
/* -------------------------------------------- */
checkMentalImmunity() {
2022-09-04 09:58:51 +02:00
for (let effect of this.items) {
if (effect.type == "effect" && effect.system.mentalimmunity) {
2022-08-14 15:27:54 +02:00
return true
}
}
return false
}
/* -------------------------------------------- */
checkPhysicalImmunity() {
2022-09-04 09:58:51 +02:00
for (let effect of this.items) {
if (effect.type == "effect" && effect.system.physicalimmunity) {
2022-08-14 15:27:54 +02:00
return true
}
}
return false
}
/* -------------------------------------------- */
checkNoBonusDice() {
2022-09-04 09:58:51 +02:00
for (let effect of this.items) {
if (effect.type == "effect" && effect.system.nobonusdice) {
2022-08-14 15:27:54 +02:00
return true
}
}
return false
}
/* -------------------------------------------- */
checkNoPerksAllowed() {
2022-09-04 09:58:51 +02:00
for (let effect of this.items) {
if (effect.type == "effect" && effect.system.noperksallowed) {
2022-08-14 15:27:54 +02:00
return true
}
}
return false
}
/* -------------------------------------------- */
checkIfPossible() {
2022-09-04 09:58:51 +02:00
for (let effect of this.items) {
if (effect.type == "effect" && effect.system.isthispossible.length > 0) {
ChatMessage.create({ content: effect.system.isthispossible })
2022-08-14 15:27:54 +02:00
}
}
}
2022-08-24 20:24:22 +02:00
2022-09-16 17:36:58 +02:00
2022-01-08 10:49:08 +01:00
/* -------------------------------------------- */
2022-02-16 14:13:16 +01:00
async computeNRGHealth() {
2022-09-16 17:36:58 +02:00
2022-01-25 09:14:32 +01:00
if (this.isOwner || game.user.isGM) {
2022-01-19 21:25:59 +01:00
let updates = {}
2022-09-04 09:58:51 +02:00
let phyDiceValue = PegasusUtility.getDiceValue(this.system.statistics.phy.value) + this.system.secondary.health.bonus + this.system.statistics.phy.mod;
if (phyDiceValue != this.system.secondary.health.max) {
2022-09-25 09:26:12 +02:00
updates['system.secondary.health.max'] = phyDiceValue
2022-02-16 14:13:16 +01:00
}
if (this.computeValue) {
2022-09-25 09:26:12 +02:00
updates['system.secondary.health.value'] = phyDiceValue
2022-01-19 21:25:59 +01:00
}
2022-09-04 09:58:51 +02:00
let mndDiceValue = PegasusUtility.getDiceValue(this.system.statistics.mnd.value) + this.system.secondary.delirium.bonus + this.system.statistics.mnd.mod;
if (mndDiceValue != this.system.secondary.delirium.max) {
2022-09-25 09:26:12 +02:00
updates['system.secondary.delirium.max'] = mndDiceValue
2022-02-16 14:13:16 +01:00
}
if (this.computeValue) {
2022-09-25 09:26:12 +02:00
updates['system.secondary.delirium.value'] = mndDiceValue
2022-01-19 21:25:59 +01:00
}
2022-09-04 09:58:51 +02:00
let stlDiceValue = PegasusUtility.getDiceValue(this.system.statistics.stl.value) + this.system.secondary.stealthhealth.bonus + this.system.statistics.stl.mod;
if (stlDiceValue != this.system.secondary.stealthhealth.max) {
2022-09-25 09:26:12 +02:00
updates['system.secondary.stealthhealth.max'] = stlDiceValue
2022-02-16 14:13:16 +01:00
}
if (this.computeValue) {
2022-09-25 09:26:12 +02:00
updates['system.secondary.stealthhealth.value'] = stlDiceValue
2022-01-19 21:25:59 +01:00
}
2022-01-25 09:14:32 +01:00
2022-09-04 09:58:51 +02:00
let socDiceValue = PegasusUtility.getDiceValue(this.system.statistics.soc.value) + this.system.secondary.socialhealth.bonus + this.system.statistics.soc.mod;
if (socDiceValue != this.system.secondary.socialhealth.max) {
2022-09-25 09:26:12 +02:00
updates['system.secondary.socialhealth.max'] = socDiceValue
2022-02-16 14:13:16 +01:00
}
if (this.computeValue) {
2022-09-25 09:26:12 +02:00
updates['system.secondary.socialhealth.value'] = socDiceValue
2022-01-19 21:25:59 +01:00
}
2022-07-28 18:45:04 +02:00
2022-09-04 09:58:51 +02:00
let nrgValue = PegasusUtility.getDiceValue(this.system.statistics.foc.value) + this.system.nrg.mod + this.system.statistics.foc.mod
if (nrgValue != this.system.nrg.absolutemax) {
2022-09-25 09:26:12 +02:00
updates['system.nrg.absolutemax'] = nrgValue
2022-01-19 21:25:59 +01:00
}
2022-02-16 14:13:16 +01:00
if (this.computeValue) {
2022-09-25 09:26:12 +02:00
updates['system.nrg.max'] = nrgValue
updates['system.nrg.value'] = nrgValue
2022-02-16 14:13:16 +01:00
}
2022-09-04 09:58:51 +02:00
let stunth = PegasusUtility.getDiceValue(this.system.statistics.phy.value) + PegasusUtility.getDiceValue(this.system.statistics.mnd.value) + PegasusUtility.getDiceValue(this.system.statistics.foc.value)
+ this.system.statistics.mnd.mod + this.system.statistics.phy.mod + this.system.statistics.foc.mod
if (stunth != this.system.combat.stunthreshold) {
2022-09-25 09:26:12 +02:00
updates['system.combat.stunthreshold'] = stunth
2022-01-19 21:25:59 +01:00
}
2022-01-25 09:14:32 +01:00
2022-09-04 09:58:51 +02:00
let momentum = this.system.statistics.foc.value + this.system.statistics.foc.mod
if (momentum != this.system.momentum.max) {
2022-09-25 09:26:12 +02:00
updates['system.momentum.value'] = 0
updates['system.momentum.max'] = momentum
2022-01-25 09:14:32 +01:00
}
2022-09-04 09:58:51 +02:00
let mrLevel = (this.system.statistics.agi.value + this.system.statistics.str.value) - this.system.statistics.phy.value
2022-01-25 09:14:32 +01:00
mrLevel = (mrLevel < 1) ? 1 : mrLevel;
2022-09-04 09:58:51 +02:00
if (mrLevel != this.system.mr.value) {
2022-09-25 09:26:12 +02:00
updates['system.mr.value'] = mrLevel
2022-01-19 21:25:59 +01:00
}
2022-09-04 09:58:51 +02:00
let moralitythreshold = - (Number(PegasusUtility.getDiceValue(this.system.statistics.foc.value)) + Number(this.system.statistics.foc.mod))
if (moralitythreshold != this.system.biodata.moralitythreshold) {
2022-09-25 09:26:12 +02:00
updates['system.biodata.moralitythreshold'] = moralitythreshold
2022-07-21 22:52:17 +02:00
}
2022-08-24 20:24:22 +02:00
if (!this.isToken) {
2022-09-04 09:58:51 +02:00
if (this.warnMorality != this.system.biodata.morality && this.system.biodata.morality < 0) {
2022-07-30 22:44:44 +02:00
console.log("CHAR", this)
ChatMessage.create({ content: "WARNING: Your character is dangerously close to becoming corrupted and defeated. Start on a path of redemption!" })
}
2022-09-04 09:58:51 +02:00
if (this.warnMorality != this.system.biodata.morality) {
this.warnMorality = this.system.biodata.morality
2022-07-30 22:44:44 +02:00
}
2022-07-21 22:52:17 +02:00
}
2022-08-24 20:24:22 +02:00
2022-01-19 21:25:59 +01:00
let race = this.getRace()
2022-09-04 09:58:51 +02:00
if (race && race.name && (race.name != this.system.biodata.racename)) {
2022-09-25 09:26:12 +02:00
updates['system.biodata.racename'] = race.name
2022-01-19 21:25:59 +01:00
}
let role = this.getRole()
2022-09-04 09:58:51 +02:00
if (role && role.name && (role.name != this.system.biodata.rolename)) {
2022-09-25 09:26:12 +02:00
updates['system.biodata.rolename'] = role.name
2022-01-19 21:25:59 +01:00
}
2022-07-28 18:45:04 +02:00
if (Object.entries(updates).length > 0) {
await this.update(updates)
}
2022-08-14 15:27:54 +02:00
this.computeThreatLevel()
2022-01-19 21:25:59 +01:00
}
2022-02-10 15:53:42 +01:00
2022-02-16 14:13:16 +01:00
if (this.isOwner || game.user.isGM) {
// Update current hindrance level
2022-09-04 09:58:51 +02:00
let hindrance = this.system.combat.hindrancedice
2022-08-24 20:24:22 +02:00
if (!this.checkIgnoreHealth()) {
2022-09-04 09:58:51 +02:00
if (this.system.secondary.health.value < 0) {
if (this.system.secondary.health.value < -Math.floor((this.system.secondary.health.max + 1) / 2)) { // Severe wounded
2022-08-14 15:27:54 +02:00
hindrance += 3
} else {
hindrance += 1
}
2022-07-10 10:22:04 +02:00
}
2022-02-16 14:13:16 +01:00
}
2022-09-04 09:58:51 +02:00
this.system.combat.hindrancedice = hindrance
2022-07-10 10:22:04 +02:00
this.getTraumaState()
2022-07-20 23:53:37 +02:00
this.cleanupPerksIfTrauma()
2022-02-10 15:53:42 +01:00
}
2022-01-08 10:49:08 +01:00
}
2022-01-07 20:40:40 +01:00
/* -------------------------------------------- */
2022-01-14 14:49:16 +01:00
async modStat(key, inc = 1) {
2022-09-04 09:58:51 +02:00
let stat = duplicate(this.system.statistics[key])
2022-01-07 20:40:40 +01:00
stat.mod += parseInt(inc)
2022-01-14 14:49:16 +01:00
await this.update({ [`data.statistics.${key}`]: stat })
2022-01-07 20:40:40 +01:00
}
2022-01-14 14:49:16 +01:00
2022-01-08 10:49:08 +01:00
/* -------------------------------------------- */
2022-01-14 14:49:16 +01:00
async valueStat(key, inc = 1) {
2022-01-08 10:49:08 +01:00
key = key.toLowerCase()
2022-09-04 09:58:51 +02:00
let stat = duplicate(this.system.statistics[key])
2022-01-08 10:49:08 +01:00
stat.value += parseInt(inc)
2022-01-14 14:49:16 +01:00
await this.update({ [`data.statistics.${key}`]: stat })
2022-01-08 10:49:08 +01:00
}
/* -------------------------------------------- */
2022-01-14 14:49:16 +01:00
async addIncSpec(spec, inc = 1) {
2022-01-08 10:49:08 +01:00
console.log("Using spec : ", spec, inc)
2022-09-04 09:58:51 +02:00
let specExist = this.items.find(item => item.type == 'specialisation' && item.name.toLowerCase() == spec.name.toLowerCase())
2022-01-08 10:49:08 +01:00
if (specExist) {
specExist = duplicate(specExist)
2022-09-04 09:58:51 +02:00
specExist.system.level += inc;
let update = { _id: specExist._id, "data.level": specExist.system.level };
2022-01-14 14:49:16 +01:00
await this.updateEmbeddedDocuments('Item', [update]);
2022-01-08 10:49:08 +01:00
} else {
2022-09-04 09:58:51 +02:00
spec.system.level += inc;
2022-01-14 14:49:16 +01:00
await this.createEmbeddedDocuments('Item', [spec]);
2022-01-08 10:49:08 +01:00
}
}
2022-01-28 10:05:54 +01:00
/* -------------------------------------------- */
async incDecQuantity(objetId, incDec = 0) {
2022-09-04 09:58:51 +02:00
let objetQ = this.items.get(objetId)
2022-01-28 10:05:54 +01:00
if (objetQ) {
2022-09-04 09:58:51 +02:00
let newQ = objetQ.system.quantity + incDec
2022-03-12 16:35:32 +01:00
if (newQ >= 0) {
2022-09-25 09:26:12 +02:00
const updated = await this.updateEmbeddedDocuments('Item', [{ _id: objetQ.id, 'system.quantity': newQ }]) // pdates one EmbeddedEntity
2022-03-12 16:35:32 +01:00
}
2022-01-25 10:37:28 +01:00
}
2022-01-28 10:05:54 +01:00
}
2022-03-09 18:12:40 +01:00
/* -------------------------------------------- */
async incDecAmmo(objetId, incDec = 0) {
2022-09-04 09:58:51 +02:00
let objetQ = this.items.get(objetId)
2022-03-09 18:12:40 +01:00
if (objetQ) {
2022-09-04 09:58:51 +02:00
let newQ = objetQ.system.ammocurrent + incDec;
if (newQ >= 0 && newQ <= objetQ.system.ammomax) {
2022-09-25 09:26:12 +02:00
const updated = await this.updateEmbeddedDocuments('Item', [{ _id: objetQ.id, 'system.ammocurrent': newQ }]); // pdates one EmbeddedEntity
2022-03-09 18:12:40 +01:00
}
}
}
2022-01-28 10:05:54 +01:00
2022-01-11 23:35:23 +01:00
/* -------------------------------------------- */
2022-02-10 15:53:42 +01:00
async applyAbility(ability, updates = [], directUpdate = false) {
// manage stat bonus
2022-09-04 09:58:51 +02:00
if (ability.system.affectedstat != "notapplicable") {
let stat = duplicate(this.system.statistics[ability.system.affectedstat])
stat.mod += Number(ability.system.statmodifier)
2022-09-05 11:32:21 +02:00
updates[`system.statistics.${ability.system.affectedstat}`] = stat
2022-02-10 15:53:42 +01:00
}
// manage status bonus
2022-09-04 09:58:51 +02:00
if (ability.system.statusaffected != "notapplicable") {
if (ability.system.statusaffected == 'nrg') {
let nrg = duplicate(this.system.nrg)
nrg.mod += Number(ability.system.statusmodifier)
2022-09-05 11:32:21 +02:00
updates[`system.nrg`] = nrg
2022-02-10 15:53:42 +01:00
}
2022-09-04 09:58:51 +02:00
if (ability.system.statusaffected == 'health') {
let health = duplicate(this.system.secondary.health)
health.bonus += Number(ability.system.statusmodifier)
2022-09-05 11:32:21 +02:00
updates[`system.secondary.health`] = health
2022-02-10 15:53:42 +01:00
}
2022-09-04 09:58:51 +02:00
if (ability.system.statusaffected == 'delirium') {
let delirium = duplicate(this.system.secondary.delirium)
delirium.bonus += Number(ability.system.statusmodifier)
2022-09-05 11:32:21 +02:00
updates[`system.secondary.delirium`] = delirium
2022-02-10 15:53:42 +01:00
}
}
2022-02-10 21:58:19 +01:00
if (directUpdate) {
2022-02-10 15:53:42 +01:00
await this.update(updates)
}
let newItems = []
2022-09-04 09:58:51 +02:00
if (ability.system.effectsgained) {
for (let effect of ability.system.effectsgained) {
if (!effect.system) effect.system = effect.data
2022-02-10 15:53:42 +01:00
newItems.push(effect);
}
}
2022-09-04 09:58:51 +02:00
if (ability.system.powersgained) {
for (let power of ability.system.powersgained) {
if (!power.system) power.system = power.data
2022-02-10 15:53:42 +01:00
newItems.push(power);
}
}
2022-09-04 09:58:51 +02:00
if (ability.system.specialisations) {
for (let spec of ability.system.specialisations) {
if (!spec.system) spec.system = spec.data
2022-02-10 15:53:42 +01:00
newItems.push(spec);
2022-01-30 09:44:37 +01:00
}
2022-01-14 14:49:16 +01:00
}
2022-09-04 09:58:51 +02:00
if (ability.system.attackgained) {
for (let weapon of ability.system.attackgained) {
if (!weapon.system) weapon.system = weapon.data
2022-02-10 15:53:42 +01:00
newItems.push(weapon);
}
}
2022-09-04 09:58:51 +02:00
if (ability.system.armorgained) {
for (let armor of ability.system.armorgained) {
if (!armor.system) armor.system = armor.data
2022-02-10 15:53:42 +01:00
newItems.push(armor);
}
2022-02-10 21:58:19 +01:00
}
2022-03-16 15:08:34 +01:00
console.log("Ability : adding", newItems)
2022-02-10 15:53:42 +01:00
await this.createEmbeddedDocuments('Item', newItems)
2022-01-11 23:35:23 +01:00
}
2022-02-10 15:53:42 +01:00
2022-01-06 18:22:05 +01:00
/* -------------------------------------------- */
2022-01-14 14:49:16 +01:00
async applyRace(race) {
2022-09-25 09:26:12 +02:00
let updates = { 'system.biodata.racename': race.name }
2022-01-06 18:22:05 +01:00
let newItems = []
2022-01-14 14:49:16 +01:00
await this.deleteAllItemsByType('race')
2022-01-06 18:22:05 +01:00
newItems.push(race);
2022-09-25 09:26:12 +02:00
console.log("DROPPED RACE", race)
2022-09-04 09:58:51 +02:00
for (let ability of race.system.abilities) {
if (!ability.system) ability.system = ability.data
2022-01-30 09:44:37 +01:00
newItems.push(ability)
2022-01-14 14:49:16 +01:00
this.applyAbility(ability, updates)
2022-01-11 23:35:23 +01:00
}
2022-09-04 09:58:51 +02:00
if (race.system.perksgained) {
for (let power of race.system.perks) {
if (!power.system) power.system = power.data
2022-01-11 23:35:23 +01:00
newItems.push(power);
2022-01-08 18:28:01 +01:00
}
2022-01-11 23:35:23 +01:00
}
2022-01-14 14:49:16 +01:00
await this.update(updates)
2022-01-06 18:22:05 +01:00
await this.createEmbeddedDocuments('Item', newItems)
console.log("Updates", updates, newItems)
console.log("Updated actor", this)
}
/* -------------------------------------------- */
2022-01-14 14:49:16 +01:00
getIncreaseStatValue(updates, statKey) {
2022-09-04 09:58:51 +02:00
let stat = duplicate(this.system.statistics[statKey])
2022-01-07 20:40:40 +01:00
stat.value += 1;
updates[`data.statistics.${statKey}`] = stat
}
/* -------------------------------------------- */
2022-01-14 14:49:16 +01:00
async applyRole(role) {
2022-01-06 18:22:05 +01:00
console.log("ROLE", role)
2022-01-07 20:40:40 +01:00
2022-09-25 09:26:12 +02:00
let updates = { 'system.biodata.rolename': role.name }
2022-01-07 20:40:40 +01:00
let newItems = []
2022-01-14 14:49:16 +01:00
await this.deleteAllItemsByType('role')
2022-03-16 11:12:14 +01:00
newItems.push(role)
2022-01-07 20:40:40 +01:00
2022-09-04 09:58:51 +02:00
this.getIncreaseStatValue(updates, role.system.statincrease1)
this.getIncreaseStatValue(updates, role.system.statincrease2)
2022-01-07 20:40:40 +01:00
2022-09-04 09:58:51 +02:00
if (role.system.specialability.length > 0) {
//console.log("Adding ability", role.system.specialability)
2022-09-04 09:58:51 +02:00
newItems = newItems.concat(duplicate(role.system.specialability)) // Add new ability
this.applyAbility(role.system.specialability[0], newItems)
2022-03-16 15:08:34 +01:00
}
2022-01-14 14:49:16 +01:00
await this.update(updates)
2022-01-07 20:40:40 +01:00
await this.createEmbeddedDocuments('Item', newItems)
2022-03-16 15:08:34 +01:00
2022-01-06 18:22:05 +01:00
}
2022-01-14 14:49:16 +01:00
2022-01-28 10:05:54 +01:00
/* -------------------------------------------- */
2022-02-10 21:58:19 +01:00
addHindrancesList(effectsList) {
2022-09-25 09:26:12 +02:00
if (this.type == "character") {
if (this.system.combat.stunlevel > 0) {
effectsList.push({ label: "Stun Hindrance", type: "hindrance", foreign: true, actorId: this.id, applied: false, value: 2 })
}
if (this.system.combat.hindrancedice > 0) {
effectsList.push({ label: "Wounds Hindrance", type: "hindrance", foreign: true, actorId: this.id, applied: false, value: this.system.combat.hindrancedice })
}
let overCapacity = Math.floor(this.encCurrent / this.getEncumbranceCapacity())
if (overCapacity > 0) {
effectsList.push({ label: "Encumbrance Hindrance", type: "hindrance", foreign: true, actorId: this.id, applied: false, value: overCapacity })
}
if (this.system.biodata.morality <= 0) {
effectsList.push({ label: "Morality Hindrance", type: "hindrance", foreign: true, actorId: this.id, applied: false, value: 3 })
}
let effects = this.items.filter(item => item.type == 'effect')
for (let effect of effects) {
effect = duplicate(effect)
if (effect.system.hindrance) {
effectsList.push({ label: effect.name, type: "effect", foreign: true, actorId: this.id, applied: false, effect: effect, value: effect.system.effectlevel })
}
}
2022-07-21 22:52:17 +02:00
}
2022-09-25 09:26:12 +02:00
if (this.type == "vehicle") {
if (this.system.stun.value > 0) {
effectsList.push({ label: "Stun Hindrance", type: "hindrance", foreign: true, actorId: this.id, applied: false, value: 2 })
}
if (this.isVehicleCrawling()) {
effectsList.push({ label: "Crawling Hindrance", type: "hindrance", foreign: true, actorId: this.id, applied: false, value: 3 })
}
if (this.isVehicleSlow()) {
effectsList.push({ label: "Slow Hindrance", type: "hindrance", foreign: true, actorId: this.id, applied: false, value: 1 })
}
if (this.isVehicleAverage()) {
effectsList.push({ label: "Average Hindrance", type: "hindrance", foreign: true, actorId: this.id, applied: false, value: 1 })
}
if (this.isVehicleFast()) {
effectsList.push({ label: "Fast Hindrance", type: "hindrance", foreign: true, actorId: this.id, applied: false, value: 3 })
}
if (this.isVehicleExFast()) {
effectsList.push({ label: "Ext. Fast Hindrance", type: "hindrance", foreign: true, actorId: this.id, applied: false, value: 5 })
2022-01-28 10:05:54 +01:00
}
}
}
/* -------------------------------------------- */
/* ROLL SECTION
/* -------------------------------------------- */
2022-08-24 20:24:22 +02:00
pushEffect(rollData, effect) {
if (this.getTraumaState() == "none" && !this.checkNoBonusDice()) {
2022-09-04 09:58:51 +02:00
rollData.effectsList.push({ label: effect.name, type: "effect", applied: false, effect: effect, value: effect.system.effectlevel })
2022-08-24 20:24:22 +02:00
} else {
2022-09-04 09:58:51 +02:00
if (!effect.system.bonusdice) { // Do not push bonus dice effect when TraumaState is activated
rollData.effectsList.push({ label: effect.name, type: "effect", applied: false, effect: effect, value: effect.system.effectlevel })
2022-08-24 20:24:22 +02:00
}
}
}
2022-01-28 10:05:54 +01:00
/* -------------------------------------------- */
2022-08-24 20:24:22 +02:00
addEffects(rollData, isInit = false, isPower = false, isPowerDmg = false) {
2022-09-04 09:58:51 +02:00
let effects = this.items.filter(item => item.type == 'effect')
2022-02-10 21:58:19 +01:00
for (let effect of effects) {
2022-01-28 10:05:54 +01:00
effect = duplicate(effect)
2022-09-04 09:58:51 +02:00
if (!effect.system.hindrance
&& (effect.system.stataffected != "notapplicable" || effect.system.specaffected.length > 0)
&& effect.system.stataffected != "special"
&& effect.system.stataffected != "powerroll"
&& effect.system.stataffected != "powerdmgroll") {
if (effect.system.effectstatlevel) {
effect.system.effectlevel = this.system.statistics[effect.system.effectstat].value
2022-02-16 14:13:16 +01:00
}
2022-08-24 20:24:22 +02:00
this.pushEffect(rollData, effect)
}
2022-09-04 09:58:51 +02:00
if (isPower && effect.system.stataffected == "powerroll") {
2022-08-24 20:24:22 +02:00
this.pushEffect(rollData, effect)
2022-01-14 14:49:16 +01:00
}
2022-09-04 09:58:51 +02:00
if (isPowerDmg && effect.system.stataffected == "powerdmgroll") {
2022-08-24 20:24:22 +02:00
this.pushEffect(rollData, effect)
}
2022-08-28 18:51:52 +02:00
2022-01-28 10:05:54 +01:00
}
}
2022-02-10 15:53:42 +01:00
2022-01-28 10:05:54 +01:00
/* -------------------------------------------- */
2022-02-10 21:58:19 +01:00
addArmorsShields(rollData, statKey = "none", useShield = false) {
2022-01-28 15:23:14 +01:00
if (statKey == 'phy') {
let armors = this.getArmors()
for (let armor of armors) {
2022-09-04 09:58:51 +02:00
rollData.armorsList.push({ label: `Armor ${armor.name}`, type: "armor", applied: false, value: armor.system.resistance })
2022-01-28 15:23:14 +01:00
}
2022-01-28 10:05:54 +01:00
}
2022-02-10 21:58:19 +01:00
if (useShield) {
2022-09-04 09:58:51 +02:00
let shields = this.items.filter(item => item.type == "shield" && item.system.equipped)
2022-01-28 15:23:14 +01:00
for (let sh of shields) {
2022-09-04 09:58:51 +02:00
rollData.armorsList.push({ label: `Shield ${sh.name}`, type: "shield", applied: false, value: sh.system.level })
2022-01-28 15:23:14 +01:00
}
2022-01-28 11:41:19 +01:00
}
2022-01-28 10:05:54 +01:00
}
2022-01-28 17:27:01 +01:00
addWeapons(rollData, statKey) {
2022-02-10 21:58:19 +01:00
let weapons = this.getWeapons()
2022-01-28 17:27:01 +01:00
for (let weapon of weapons) {
2022-09-04 09:58:51 +02:00
if (weapon.system.equipped && weapon.system.statistic == statKey) {
2022-07-19 20:51:48 +02:00
rollData.weaponsList.push({ label: `Attack ${weapon.name}`, type: "attack", applied: false, weapon: weapon, value: 0, damageDice: PegasusUtility.getDiceFromLevel(0) })
2022-01-28 17:27:01 +01:00
}
2022-09-04 09:58:51 +02:00
if (weapon.system.equipped && weapon.system.canbethrown && statKey == "agi") {
2022-08-24 20:24:22 +02:00
rollData.weaponsList.push({ label: `Attack ${weapon.name}`, type: "attack", applied: false, weapon: weapon, value: 0, damageDice: PegasusUtility.getDiceFromLevel(0) })
}
2022-09-04 09:58:51 +02:00
if (weapon.system.equipped && weapon.system.enhanced && weapon.system.enhancedstat == statKey) {
rollData.weaponsList.push({ label: `Enhanced Attack ${weapon.name}`, type: "enhanced", applied: false, weapon: weapon, value: weapon.system.enhancedlevel, damageDice: PegasusUtility.getDiceFromLevel(weapon.system.enhancedlevel) })
2022-01-28 18:15:28 +01:00
}
2022-09-04 09:58:51 +02:00
if (weapon.system.equipped && weapon.system.damagestatistic == statKey) {
rollData.weaponsList.push({ label: `Damage ${weapon.name}`, type: "damage", applied: false, weapon: weapon, value: weapon.system.damage, damageDice: PegasusUtility.getDiceFromLevel(weapon.system.damage) })
2022-01-28 17:27:01 +01:00
}
}
}
addEquipments(rollData, statKey) {
2022-02-10 21:58:19 +01:00
let equipments = this.getEquipmentsOnly()
2022-01-28 17:27:01 +01:00
for (let equip of equipments) {
2022-09-04 09:58:51 +02:00
if (equip.system.equipped && equip.system.stataffected == statKey) {
rollData.equipmentsList.push({ label: `Item ${equip.name}`, type: "item", applied: false, equip: equip, value: equip.system.level })
2022-01-28 17:27:01 +01:00
}
}
}
2022-09-21 16:54:34 +02:00
addVehicleWeapons(rollData, vehicle) {
if (vehicle) {
let modules = vehicle.items.filter(vehicle => vehicle.type == "vehicleweaponmodule")
if (modules && modules.length > 0) {
2022-09-25 09:26:12 +02:00
for (let module of modules) {
rollData.vehicleWeapons.push({ label: `Weapon ${module.name}`, type: "item", applied: false, weapon: module, value: module.system.damagedicevalue })
2022-09-21 16:54:34 +02:00
}
}
}
}
2022-01-28 10:05:54 +01:00
/* -------------------------------------------- */
2022-09-25 09:26:12 +02:00
getCommonRollData(statKey = undefined, useShield = false, isInit = false, isPower = false, subKey = "", vehicle = undefined) {
2022-07-20 23:53:37 +02:00
let rollData = PegasusUtility.getBasicRollData(isInit)
2022-01-28 10:05:54 +01:00
rollData.alias = this.name
rollData.actorImg = this.img
rollData.actorId = this.id
rollData.img = this.img
2022-07-10 10:22:04 +02:00
rollData.traumaState = this.getTraumaState()
2022-07-13 22:47:07 +02:00
rollData.levelRemaining = this.getLevelRemaining()
2022-01-28 10:05:54 +01:00
rollData.activePerks = duplicate(this.getActivePerks())
2022-07-10 10:22:04 +02:00
rollData.diceList = PegasusUtility.getDiceList()
2022-08-14 15:27:54 +02:00
rollData.noBonusDice = this.checkNoBonusDice()
2022-07-10 10:22:04 +02:00
rollData.dicePool = []
2022-09-21 16:54:34 +02:00
if (subKey == "melee-dmg" || subKey == "ranged-dmg" || subKey == "power-dmg") {
rollData.isDamage = true
}
2022-02-10 21:58:19 +01:00
if (statKey) {
2022-01-28 10:05:54 +01:00
rollData.statKey = statKey
rollData.stat = this.getStat(statKey)
2022-09-25 09:26:12 +02:00
rollData.statDicesLevel = rollData.stat.value || rollData.stat.level
2022-02-10 21:58:19 +01:00
rollData.statMod = rollData.stat.mod
2022-09-25 09:26:12 +02:00
if (vehicle) {
2022-09-21 16:54:34 +02:00
rollData.vehicle = duplicate(vehicle)
if (subKey == "melee-dmg") {
2022-09-25 09:26:12 +02:00
if (vehicle.isVehicleFullStop()) {
ui.notifications.warn("MR not added to Melee Damage due to Full Stop.")
} else {
rollData.statVehicle = vehicle.system.statistics.mr
}
2022-09-21 16:54:34 +02:00
this.addVehicleWeapons(rollData, vehicle)
}
if (subKey == "ranged-atk") {
rollData.statVehicle = vehicle.system.statistics.fc
}
if (subKey == "ranged-dmg") {
this.addVehicleWeapons(rollData, vehicle)
}
if (subKey == "defense") {
2022-09-25 09:26:12 +02:00
if (vehicle.isVehicleFullStop()) {
ui.notifications.warn("MAN not added to Defense due to Full Stop.")
} else {
rollData.statVehicle = vehicle.system.statistics.man
}
}
//this.addVehiculeHindrances(rollData.effectsList, vehicle)
//this.addVehicleBonus(rollData, vehicle)
2022-09-21 16:54:34 +02:00
}
2022-09-25 09:26:12 +02:00
2022-01-28 10:05:54 +01:00
rollData.specList = this.getRelevantSpec(statKey)
rollData.selectedSpec = "0"
2022-03-09 18:12:40 +01:00
if (statKey.toLowerCase() == "mr") {
rollData.img = "systems/fvtt-pegasus-rpg/images/icons/MR.webp"
} else {
2022-07-10 10:22:04 +02:00
rollData.img = `systems/fvtt-pegasus-rpg/images/icons/${rollData.stat.abbrev}.webp`
2022-03-09 18:12:40 +01:00
}
2022-09-25 09:26:12 +02:00
rollData.dicePool = rollData.dicePool.concat(PegasusUtility.buildDicePool("stat", rollData.statDicesLevel, rollData.stat.mod))
if (rollData.statVehicle) {
rollData.dicePool = rollData.dicePool.concat(PegasusUtility.buildDicePool("statvehicle", rollData.statVehicle.currentlevel, 0))
2022-07-28 18:45:04 +02:00
}
2022-02-10 21:58:19 +01:00
}
2022-01-28 10:05:54 +01:00
2022-09-25 09:26:12 +02:00
this.addEffects(rollData, isInit, isPower, subKey == "power-dmg")
2022-01-28 15:23:14 +01:00
this.addArmorsShields(rollData, statKey, useShield)
2022-01-28 17:27:01 +01:00
this.addWeapons(rollData, statKey, useShield)
this.addEquipments(rollData, statKey)
2022-07-19 00:18:46 +02:00
console.log("ROLLDATA", rollData)
2022-02-10 21:58:19 +01:00
2022-01-28 10:05:54 +01:00
return rollData
}
2022-07-13 22:47:07 +02:00
/* -------------------------------------------- */
2022-07-19 00:18:46 +02:00
getLevelRemainingList() {
2022-07-13 22:47:07 +02:00
let options = []
2022-09-04 09:58:51 +02:00
for (let i = 0; i <= this.system.biodata.maxlevelremaining; i++) {
2022-07-19 00:18:46 +02:00
options.push(`<option value="${i}">${i}</option>`)
2022-07-13 22:47:07 +02:00
}
return options.join("\n")
}
2022-07-26 22:58:33 +02:00
/* -------------------------------------------- */
getMaxLevelRemainingList() {
let options = []
for (let i = 0; i <= 12; i++) {
options.push(`<option value="${i}">${i}</option>`)
}
return options.join("\n")
}
2022-01-28 10:05:54 +01:00
/* -------------------------------------------- */
async startRoll(rollData) {
this.syncRoll(rollData);
2022-02-16 14:13:16 +01:00
//console.log("ROLL DATA", rollData)
2022-07-19 00:18:46 +02:00
let rollDialog = await PegasusRollDialog.create(this, rollData)
console.log(rollDialog)
2022-01-28 10:05:54 +01:00
rollDialog.render(true);
}
2022-02-25 14:53:19 +01:00
/* -------------------------------------------- */
2022-03-07 16:00:53 +01:00
powerDmgRoll(itemId) {
2022-09-04 09:58:51 +02:00
let power = this.items.get(itemId)
2022-03-07 16:00:53 +01:00
if (power) {
2022-02-25 14:53:19 +01:00
power = duplicate(power)
2022-09-04 09:58:51 +02:00
this.rollPool(power.system.dmgstatistic, false, "power-dmg")
2022-02-25 14:53:19 +01:00
}
}
2022-03-07 16:00:53 +01:00
2022-01-28 10:05:54 +01:00
/* -------------------------------------------- */
2022-09-21 16:54:34 +02:00
rollPool(statKey, useShield = false, subKey = "none", vehicle = undefined) {
2022-02-25 14:53:19 +01:00
let stat = this.getStat(statKey)
2022-01-28 10:05:54 +01:00
if (stat) {
2022-09-21 16:54:34 +02:00
let rollData = this.getCommonRollData(statKey, useShield, false, false, subKey, vehicle)
2022-01-28 10:05:54 +01:00
rollData.mode = "stat"
2022-07-10 10:22:04 +02:00
rollData.subKey = subKey
2022-07-19 20:51:48 +02:00
let def = stat.label
if (subKey) {
def = __subkey2title[subKey]
}
2022-09-25 09:26:12 +02:00
rollData.title = `Roll : ${def} `
2022-03-09 18:12:40 +01:00
rollData.img = "icons/dice/d12black.svg"
2022-01-28 10:05:54 +01:00
this.startRoll(rollData)
} else {
ui.notifications.warn("Statistic not found !");
}
}
/* -------------------------------------------- */
rollUnarmedAttack() {
2022-02-25 14:53:19 +01:00
let stat = this.getStat('com')
2022-01-28 10:05:54 +01:00
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}`;
2021-12-02 07:38:59 +01:00
2022-01-28 10:05:54 +01:00
this.startRoll(rollData)
} else {
ui.notifications.warn("Statistic not found !");
}
}
2021-12-02 07:38:59 +01:00
2022-01-28 10:05:54 +01:00
/* -------------------------------------------- */
async rollSpec(specId) {
let spec = this.getOneSpec(specId)
if (spec) {
2022-09-04 09:58:51 +02:00
let rollData = this.getCommonRollData(spec.system.statistic)
2022-01-28 10:05:54 +01:00
rollData.mode = "spec"
rollData.title = `Spec. : ${spec.name} `
2022-02-10 21:58:19 +01:00
rollData.specList = [spec]
2022-01-28 11:41:19 +01:00
rollData.selectedSpec = spec._id
2022-02-16 12:14:34 +01:00
rollData.specName = spec.name
2022-03-06 20:07:41 +01:00
rollData.img = spec.img
2022-09-04 09:58:51 +02:00
rollData.specDicesLevel = spec.system.level
2022-07-13 22:47:07 +02:00
PegasusUtility.updateSpecDicePool(rollData)
2022-01-28 10:05:54 +01:00
this.startRoll(rollData)
2022-01-14 14:49:16 +01:00
} else {
2022-01-28 10:05:54 +01:00
ui.notifications.warn("Specialisation not found !");
2022-01-14 14:49:16 +01:00
}
}
2022-01-14 18:20:15 +01:00
2022-01-14 14:49:16 +01:00
/* -------------------------------------------- */
2022-02-10 21:58:19 +01:00
async rollMR(isInit = false, combatId = 0, combatantId = 0) {
2022-09-04 09:58:51 +02:00
let mr = duplicate(this.system.mr)
2022-01-28 10:05:54 +01:00
if (mr) {
mr.dice = PegasusUtility.getDiceFromLevel(mr.value);
2022-07-20 23:53:37 +02:00
let rollData = this.getCommonRollData("mr", false, isInit)
2022-01-28 10:05:54 +01:00
rollData.mode = "MR"
2022-03-09 18:12:40 +01:00
rollData.img = "systems/fvtt-pegasus-rpg/images/icons/MR.webp"
2022-01-28 10:05:54 +01:00
rollData.isInit = isInit
rollData.combatId = combatId
rollData.combatantId = combatantId
2022-03-09 18:12:40 +01:00
console.log("MR ROLL", rollData)
2022-07-10 10:22:04 +02:00
if (isInit) {
rollData.title = "MR / Initiative"
}
2022-01-28 10:05:54 +01:00
this.startRoll(rollData);
2022-01-14 14:49:16 +01:00
} else {
2022-01-28 10:05:54 +01:00
ui.notifications.warn("MR not found !");
2022-01-14 14:49:16 +01:00
}
}
2022-01-28 10:05:54 +01:00
2022-01-14 18:20:15 +01:00
/* -------------------------------------------- */
async rollArmor(armorId) {
2022-09-04 09:58:51 +02:00
let armor = this.items.get(armorId)
2022-01-14 18:20:15 +01:00
if (armor) {
2022-09-04 09:58:51 +02:00
let rollData = this.getCommonRollData(armor.system.statistic)
2022-01-14 18:20:15 +01:00
armor = duplicate(armor);
2022-03-09 18:12:40 +01:00
this.checkAndPrepareEquipment(armor);
2022-01-14 18:20:15 +01:00
rollData.mode = "armor"
rollData.armor = armor
rollData.title = `Armor : ${armor.name}`
rollData.isResistance = true;
2022-03-06 20:07:41 +01:00
rollData.img = armor.img
2022-09-04 09:58:51 +02:00
rollData.damageDiceLevel = armor.system.resistance
2022-01-14 18:20:15 +01:00
this.startRoll(rollData);
} else {
ui.notifications.warn("Armor not found !", weaponId);
}
}
2022-01-14 14:49:16 +01:00
2022-01-14 18:20:15 +01:00
/* -------------------------------------------- */
async rollPower(powerId) {
2022-09-04 09:58:51 +02:00
let power = this.items.get(powerId)
2022-01-14 18:20:15 +01:00
if (power) {
2022-01-28 10:05:54 +01:00
power = duplicate(power)
2022-09-21 16:54:34 +02:00
let rollData = this.getCommonRollData(power.system.statistic, false, false, true)
2022-01-14 18:20:15 +01:00
rollData.mode = "power"
rollData.power = power
rollData.title = `Power : ${power.name}`
2022-03-06 20:07:41 +01:00
rollData.img = power.img
2022-01-14 18:20:15 +01:00
this.startRoll(rollData);
} else {
ui.notifications.warn("Power not found !", powerId);
}
}
2022-09-09 08:33:28 +02:00
/* -------------------------------------------- */
/* VEHICLE STUFF */
manageCurrentSpeed(speed) {
if (speed == "fullstop") {
this.update({ 'system.secondary.moverange': "nomovement" })
}
if (speed == "crawling") {
this.update({ 'system.secondary.moverange': "threatzone" })
}
if (speed == "slow") {
this.update({ 'system.secondary.moverange': "close" })
}
if (speed == "average") {
this.update({ 'system.secondary.moverange': "medium" })
}
if (speed == "fast") {
this.update({ 'system.secondary.moverange': "long" })
}
if (speed == "extfast") {
this.update({ 'system.secondary.moverange': "extreme" })
}
}
/* -------------------------------------------- */
modifyVehicleStun(incDec) {
let stun = this.system.stun.value + incDec
this.update({ 'stun.value': stun })
}
2022-09-16 17:36:58 +02:00
/* -------------------------------------------- */
2022-09-25 09:26:12 +02:00
addTopSpeedBonus(topspeed, bonus) {
2022-09-16 17:36:58 +02:00
let num = __speed2Num[topspeed] + Number(bonus)
num = Math.max(0, num)
2022-09-25 09:26:12 +02:00
num = Math.min(num, __num2speed.length - 1)
2022-09-16 17:36:58 +02:00
return __num2speed[num]
}
2022-09-25 09:26:12 +02:00
/* -------------------------------------------- */
manageVehicleSpeedBonus(speed, name, stat, level) {
if (this.system.statistics.ad.currentspeed == speed) {
if (!this.items.find(effect => effect.system.isspeed == speed)) {
let effect = duplicate(__bonusEffect)
effect.name = name
effect.system.stataffected = stat
effect.system.effectlevel = level
effect.system.isspeed = speed
this.createEmbeddedDocuments("Item", [effect])
}
} else {
let effect = this.items.find(effect => effect.system.isspeed == speed)
if (effect) {
this.deleteEmbeddedDocuments("Item", [effect.id])
}
}
}
2022-09-16 17:36:58 +02:00
/* -------------------------------------------- */
async computeVehicleStats() {
if (this.type == "vehicle") {
for (let statDef of __statBuild) {
let sum = 0
let list = []
for (let moduleType of statDef.modules) {
list = list.concat(this.items.filter(item => item.type == moduleType))
}
if (list && list.length > 0) {
sum = list.reduce((value, item2) => value + Number(item2.system[statDef.itemfield]), 0)
}
//console.log("Processing", statDef.field, this.system.statistics[statDef.field].level, list, sum)
2022-09-25 09:26:12 +02:00
if (statDef.subfield) {
2022-09-16 17:36:58 +02:00
if (sum != Number(this.system.statistics[statDef.field][statDef.subfield])) {
//console.log("Update", statDef.field, statDef.subfield, sum, this.system.statistics[statDef.field][statDef.subfield])
2022-09-25 09:26:12 +02:00
this.update({ [`system.statistics.${statDef.field}.${statDef.subfield}`]: sum })
2022-09-16 17:36:58 +02:00
}
} else {
if (sum != Number(this.system.statistics[statDef.field].level)) {
this.update({ [`system.statistics.${statDef.field}.level`]: sum, [`system.statistics.${statDef.field}.currentlevel`]: sum })
2022-09-21 16:54:34 +02:00
if (statDef.additionnal1) {
if (sum != Number(this.system.statistics[statDef.field][statDef.additionnal1])) {
2022-09-25 09:26:12 +02:00
this.update({ [`system.statistics.${statDef.field}.${statDef.additionnal1}`]: sum })
2022-09-21 16:54:34 +02:00
}
}
if (statDef.additionnal2) {
if (sum != Number(this.system.statistics[statDef.field][statDef.additionnal2])) {
2022-09-25 09:26:12 +02:00
this.update({ [`system.statistics.${statDef.field}.${statDef.additionnal2}`]: sum })
2022-09-21 16:54:34 +02:00
}
2022-09-25 09:26:12 +02:00
}
2022-09-16 17:36:58 +02:00
}
}
}
// Top speed management
2022-09-25 09:26:12 +02:00
let mobility = this.items.find(item => item.type == "mobilitymodule")
2022-09-16 17:36:58 +02:00
let arcs = duplicate(this.system.arcs)
if (mobility) {
2022-09-25 09:26:12 +02:00
let propulsion = this.items.find(item => item.type == "propulsionmodule")
2022-09-16 17:36:58 +02:00
let bonus = (propulsion) ? propulsion.system.topspeed : 0
arcs.frontarc.topspeed = this.addTopSpeedBonus(mobility.system.ts_f, bonus)
arcs.rightarc.topspeed = mobility.system.ts_s
arcs.leftarc.topspeed = mobility.system.ts_s
arcs.toparc.topspeed = mobility.system.ts_s
arcs.bottomarc.topspeed = mobility.system.ts_s
2022-09-25 09:26:12 +02:00
arcs.reararc.topspeed = mobility.system.ts_r
} else {
2022-09-16 17:36:58 +02:00
arcs.frontarc.topspeed = "fullstop"
arcs.rightarc.topspeed = "fullstop"
arcs.leftarc.topspeed = "fullstop"
arcs.toparc.topspeed = "fullstop"
arcs.bottomarc.topspeed = "fullstop"
arcs.reararc.topspeed = "fullstop"
}
2022-09-25 09:26:12 +02:00
for (let key in this.system.arcs) {
2022-09-16 17:36:58 +02:00
if (this.system.arcs[key].topspeed != arcs[key].topspeed) {
2022-09-25 09:26:12 +02:00
this.update({ 'system.arcs': arcs })
2022-09-16 17:36:58 +02:00
}
}
2022-09-25 09:26:12 +02:00
2022-09-16 17:36:58 +02:00
// VMS management
2022-09-25 09:26:12 +02:00
let hull = this.items.find(item => item.type == "vehiclehull")
2022-09-16 17:36:58 +02:00
let modules = duplicate(this.system.modules)
2022-09-25 09:26:12 +02:00
if (hull) {
2022-09-16 17:36:58 +02:00
modules.totalvms = Number(hull.system.vms)
} else {
modules.totalvms = 0
2022-09-25 09:26:12 +02:00
}
2022-09-16 17:36:58 +02:00
let spaceList = this.items.filter(item => item.type == "vehiclemodule") || []
spaceList = spaceList.concat(this.items.filter(item => item.type == "vehicleweaponmodule") || [])
let space = 0
2022-09-25 09:26:12 +02:00
if (spaceList && spaceList.length > 0) {
space = spaceList.reduce((value, item2) => value + Number(item2.system.space), 0)
2022-09-16 17:36:58 +02:00
}
modules.usedvms = space
2022-09-25 09:26:12 +02:00
if (modules.totalvms != this.system.modules.totalvms || modules.usedvms != this.system.modules.usedvms) {
this.update({ 'system.modules': modules })
2022-09-16 17:36:58 +02:00
}
2022-09-25 09:26:12 +02:00
if (modules.usedvms > modules.totalvms) {
2022-09-16 17:36:58 +02:00
ui.notifications.warn("Warning! No more space available in cargo !!")
}
}
2022-09-25 09:26:12 +02:00
// Speed effect management
this.manageVehicleSpeedBonus("crawling", "Crawling MAN Bonus", "man", 3)
this.manageVehicleSpeedBonus("slow", "Slow MAN Bonus", "man", 1)
this.manageVehicleSpeedBonus("average", "Avoid attack Bonus", "all", 1)
this.manageVehicleSpeedBonus("fast", "Avoid attack Bonus", "all", 3)
this.manageVehicleSpeedBonus("extfast", "Avoid attack Bonus", "all", 5)
2022-09-16 17:36:58 +02:00
}
2022-09-18 17:30:15 +02:00
/* -------------------------------------------- */
2022-09-25 09:26:12 +02:00
getTotalCost() {
2022-09-18 17:30:15 +02:00
let sumCost = 0
2022-09-25 09:26:12 +02:00
for (let item of this.items) {
if (__isVehicle[item.type]) {
2022-09-18 17:30:15 +02:00
if (item.system.cost) {
sumCost += Number(item.system.cost)
}
}
}
return sumCost
}
2022-09-25 09:26:12 +02:00
2022-09-16 17:36:58 +02:00
/* -------------------------------------------- */
async preprocessItemVehicle(event, item, onDrop = false) {
2022-09-18 17:30:15 +02:00
2022-09-25 09:26:12 +02:00
if (item.type != "effect" && !__isVehicle[item.type]) {
2022-09-18 17:30:15 +02:00
ui.notifications.warn("You can't drop Character items over a vehicle sheet.")
return
}
2022-09-16 17:36:58 +02:00
//console.log(">>>>> item", item.type, __isVehicleUnique[item.type])
2022-09-25 09:26:12 +02:00
if (__isVehicleUnique[item.type]) {
2022-09-16 17:36:58 +02:00
let toDelList = []
for (let toDel of this.items) {
2022-09-25 09:26:12 +02:00
if (toDel.type == item.type) {
toDelList.push(toDel.id)
2022-09-16 17:36:58 +02:00
}
}
//console.log("TODEL : ", toDelList)
2022-09-25 09:26:12 +02:00
if (toDelList.length > 0) {
2022-09-16 17:36:58 +02:00
await this.deleteEmbeddedDocuments('Item', toDelList)
}
}
2022-09-18 17:30:15 +02:00
// Check size
if (item.type == "vehiclemodule" || item.type == "vehicleweaponmodule") {
2022-09-21 16:54:34 +02:00
item.system.space = item.system.space || 0
2022-09-25 09:26:12 +02:00
if (this.system.modules.usedvms + Number(item.system.space) > this.system.modules.totalvms) {
ChatMessage.create({ content: `No more room available to host module ${item.name}. Module is not added to the vehicle.` })
2022-09-18 17:30:15 +02:00
return false
}
}
2022-09-16 17:36:58 +02:00
return true
}
2022-09-21 16:54:34 +02:00
/* -------------------------------------------- */
2022-09-25 09:26:12 +02:00
getCrewList() {
2022-09-21 16:54:34 +02:00
let crew = []
for (let actorDef of this.system.crew) {
let actor = game.actors.get(actorDef.id)
2022-09-25 09:26:12 +02:00
if (actor) {
crew.push({ name: actor.name, img: actor.img, id: actor.id })
2022-09-21 16:54:34 +02:00
}
}
return crew
}
/* -------------------------------------------- */
2022-09-25 09:26:12 +02:00
addCrew(actorId) {
2022-09-25 14:45:02 +02:00
if ( this.system.crew.length >= this.system.crewmax) {
ui.notifications.warn("Vehicle crew is already full.")
return
}
2022-09-25 09:26:12 +02:00
let crewList = duplicate(this.system.crew.filter(actorDef => actorDef.id != actorId) || [])
crewList.push({ id: actorId })
this.update({ 'system.crew': crewList })
2022-09-21 16:54:34 +02:00
}
2022-09-21 16:58:02 +02:00
/* -------------------------------------------- */
delCrew(actorId) {
2022-09-25 09:26:12 +02:00
let crewList = duplicate(this.system.crew.filter(actorDef => actorDef.id != actorId) || [])
this.update({ 'system.crew': crewList })
2022-09-21 16:58:02 +02:00
}
2022-09-25 09:26:12 +02:00
2022-09-21 16:54:34 +02:00
/* -------------------------------------------- */
2022-09-25 09:26:12 +02:00
isVehicleFullStop() {
return this.system.statistics.ad.currentspeed == "fullstop"
}
isVehicleCrawling() {
return this.system.statistics.ad.currentspeed == "crawling"
}
isVehicleSlow() {
return this.system.statistics.ad.currentspeed == "slow"
}
isVehicleAverage() {
return this.system.statistics.ad.currentspeed == "average"
}
isVehicleFast() {
return this.system.statistics.ad.currentspeed == "fast"
}
isVehicleExFast() {
return this.system.statistics.ad.currentspeed == "extfast"
}
/* -------------------------------------------- */
isValidActor() {
2022-09-21 16:54:34 +02:00
// Find relevant actor
2022-09-25 09:26:12 +02:00
let actor
for (let actorDef of this.system.crew) {
let actorTest = game.actors.get(actorDef.id)
if (actorTest.testUserPermission(game.user, "OWNER")) {
return actorTest
2022-09-21 16:54:34 +02:00
}
}
if (!actor) {
ui.notifications.warn("You do no own any actors in the crew of this vehicle.")
return
2022-09-25 09:26:12 +02:00
}
}
/* -------------------------------------------- */
rollPoolFromVehicle(statKey, useShield = false, subKey = "none") {
let actor = this.isValidActor()
if (actor) {
actor.rollPool(statKey, useShield, subKey, this)
}
}
/* -------------------------------------------- */
addVehicleShields(rollData) {
let shields = this.items.filter( shield => shield.type == "vehiclemodule" && shield.system.activated && shield.system.shielddicevalue > 0) || []
for (let shield of shields) {
rollData.vehicleShieldList.push({ label: `${shield.name} (${shield.system.arccoverage})`, type: "vehicleshield", applied: false, value: shield.system.shielddicevalue })
}
}
/* -------------------------------------------- */
rollVehicleDamageResistance() {
let actor = this.isValidActor()
if (actor) {
let stat = this.getStat("hr")
let rollData = this.getCommonRollData("hr")
rollData.mode = "stat"
rollData.title = `Stat ${stat.label}`;
this.addVehicleShields(rollData)
this.startRoll(rollData)
}
}
/* -------------------------------------------- */
activateVehicleModule(itemId) {
let mod = this.items.get(itemId)
if (mod) {
this.updateEmbeddedDocuments('Item', [{ _id: mod.id, 'system.activated': !mod.system.activated }])
2022-09-21 16:54:34 +02:00
}
}
2021-12-02 07:38:59 +01:00
}