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-28 20:04:04 +02:00
"ranged-dmg" : "Ranged Damage" , "defence" : "Defence" , "dmg-res" : "Damage Resistance" , "power-dmg" : "Power Damage"
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" },
2022-09-27 16:45:07 +02:00
{ modules : [ "vehiclehull" , "mobilitymodule" ] , itemfield : "man" , field : "man" , additionnal1 : "turningarc45" } ,
2022-10-07 16:51:03 +02:00
{ modules : [ "powercoremodule" ] , field : "pc" , itemfield : "pc" } ,
2022-09-21 16:54:34 +02:00
{ 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-27 16:45:07 +02:00
const _ _LocationsArmour = [ "front" , "rear" , "bottom" , "left" , "right" , "bottom" ]
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-27 16:45:07 +02:00
const _ _isVehicle = {
vehiclehull : 1 , powercoremodule : 1 , mobilitymodule : 1 , combatmodule : 1 ,
propulsionmodule : 1 , vehiclemodule : 1 , vehicleweaponmodule : 1 , effect : 1 , cargo : 1
}
const _ _isVehicleCargo = { cargo : 1 }
2022-09-25 09:26:12 +02:00
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 ( )
2022-09-27 20:31:01 +02:00
this . updatePPP ( )
2022-09-28 16:43:28 +02:00
this . updateSize ( )
2021-12-02 07:38:59 +01:00
}
2022-09-16 17:36:58 +02:00
if ( this . type == 'vehicle' ) {
2022-10-05 21:14:15 +02:00
this . computeVehicleStats ( )
2022-09-16 17:36:58 +02:00
}
2022-10-05 21:14:15 +02:00
super . prepareDerivedData ( )
2021-12-02 07:38:59 +01:00
}
/* -------------------------------------------- */
_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 ;
}
/* -------------------------------------------- */
2022-09-28 13:43:36 +02:00
getPerks ( ) {
2022-09-27 20:31:01 +02:00
let comp = duplicate ( this . items . filter ( item => item . type == 'perk' ) || [ ] )
for ( let perk of comp ) {
if ( perk . system . features . range . flag ) {
2022-09-28 13:43:36 +02:00
perk . rangeText = PegasusUtility . getRangeText ( perk . system . features . range . value )
2022-09-27 20:31:01 +02:00
}
}
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 ;
}
2022-09-26 18:42:13 +02:00
getCargos ( ) {
let comp = this . items . filter ( item => item . type == 'cargo' ) ;
return comp ;
}
2022-09-08 21:26:45 +02:00
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-10-07 10:48:44 +02:00
getVehicleWeaponModules ( activated = false ) {
let comp = [ ]
if ( activated ) {
comp = this . items . filter ( item => item . type == 'vehicleweaponmodule' && item . system . activated )
} else {
comp = this . items . filter ( item => item . type == 'vehicleweaponmodule' )
}
2022-09-08 21:26:45 +02:00
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-10-03 10:01:41 +02:00
/* -------------------------------------------- */
getRoleLevel ( ) {
let role = this . items . find ( item => item . type == 'role' )
2022-10-05 09:40:34 +02:00
if ( role ) {
2022-10-03 10:01:41 +02:00
console . log ( "Role" , role )
return role . system . rolelevel
}
return 0
}
/* -------------------------------------------- */
isTactician ( ) {
let role = this . items . find ( item => item . type == 'role' )
return role && role . system . perksrole == "tactician"
}
hasTacticianBonus ( ) {
2022-10-05 09:40:34 +02:00
let effect = this . items . find ( item => item . name . toLowerCase ( ) . includes ( "tactician bonus dice" ) )
2022-10-03 10:01:41 +02:00
return effect
}
async addTacticianEffect ( name , level ) {
let effect = duplicate ( _ _bonusEffect )
effect . name = ` ${ name } Tactician Bonus Dice `
2022-10-05 09:40:34 +02:00
effect . system . effectlevel = level
2022-10-03 17:17:28 +02:00
effect . system . stataffected = "mr"
2022-10-03 10:01:41 +02:00
effect . system . bonusdice = true
await this . createEmbeddedDocuments ( 'Item' , [ effect ] )
2022-10-05 21:14:15 +02:00
ChatMessage . create ( {
content : ` Tactician Bonus Dice has been added to ${ this . name } ( ${ level } ) ` ,
whisper : ChatMessage . getWhisperRecipients ( 'GM' )
} )
2022-10-03 10:01:41 +02:00
}
async removeTacticianEffect ( ) {
2022-10-05 21:14:15 +02:00
let effect = this . items . find ( item => item . name . toLowerCase ( ) . includes ( "tactician bonus dice" ) )
if ( effect ) {
await this . deleteEmbeddedDocuments ( 'Item' , [ effect . id ] )
ChatMessage . create ( { content : ` Tactician Bonus Dice has been removed to ${ this . name } ` , whisper : ChatMessage . getWhisperRecipients ( 'GM' ) } )
}
2022-10-03 10:01:41 +02:00
}
2022-10-05 21:14:15 +02:00
/* -------------------------------------------- */
isEnhancer ( ) {
let role = this . items . find ( item => item . type == 'role' )
return role && role . system . perksrole == "enhancer"
}
hasEnhancerBonus ( ) {
let effect = this . items . find ( item => item . name . toLowerCase ( ) . includes ( "enhancer bonus dice" ) )
return effect
}
2022-10-05 09:40:34 +02:00
async addEnhancerEffect ( name , level ) {
2022-10-05 21:14:15 +02:00
let effect = duplicate ( _ _bonusEffect )
effect . name = ` ${ name } Enhancer Bonus Dice ALL `
effect . system . effectlevel = level
effect . system . stataffected = "all"
effect . system . bonusdice = true
await this . createEmbeddedDocuments ( 'Item' , [ effect ] )
ChatMessage . create ( { content : ` Enhancer Bonus Dice has been added to ${ this . name } ( ${ level } ) ` , whisper : ChatMessage . getWhisperRecipients ( 'GM' ) } )
}
2022-10-03 10:01:41 +02:00
async removeEnhancerEffect ( ) {
2022-10-05 21:14:15 +02:00
let effect = this . items . find ( item => item . name . toLowerCase ( ) . includes ( "enhancer bonus dice" ) )
if ( effect ) {
await this . deleteEmbeddedDocuments ( 'Item' , [ effect . id ] )
ChatMessage . create ( { content : ` Enhancer Bonus Dice has been removed to ${ this . name } ` , whisper : ChatMessage . getWhisperRecipients ( 'GM' ) } )
}
2022-10-03 10:01:41 +02:00
}
2022-10-05 21:14:15 +02:00
/* -------------------------------------------- */
isAgitator ( ) {
let role = this . items . find ( item => item . type == 'role' )
return role && role . system . perksrole == "agitator"
2022-10-03 10:01:41 +02:00
}
2022-10-05 21:14:15 +02:00
hasAgitatorHindrance ( ) {
let effect = this . items . find ( item => item . name . toLowerCase ( ) . includes ( "hindered by agitator" ) )
return effect
2022-01-14 18:20:15 +01:00
}
2022-10-05 21:14:15 +02:00
async addAgitatorHindrance ( name , level ) {
let effect = duplicate ( _ _bonusEffect )
effect . name = ` Hindered by Agitator ${ name } `
effect . system . effectlevel = level
effect . system . stataffected = "all"
effect . system . genre = "negative"
effect . system . hindrance = true
await this . createEmbeddedDocuments ( 'Item' , [ effect ] )
ChatMessage . create ( { content : ` Agitator Hindrance has been added to ${ this . name } ( ${ level } ) ` , whisper : ChatMessage . getWhisperRecipients ( 'GM' ) } )
2022-10-05 10:00:30 +02:00
}
2022-10-05 21:14:15 +02:00
async removeAgitatorHindrance ( ) {
let effect = this . items . find ( item => item . name . toLowerCase ( ) . includes ( "hindered by agitator" ) )
if ( effect ) {
await this . deleteEmbeddedDocuments ( 'Item' , [ effect . id ] )
ChatMessage . create ( { content : ` Agitator Hindrance has been removed to ${ this . name } ` , whisper : ChatMessage . getWhisperRecipients ( 'GM' ) } )
}
2022-10-05 10:00:30 +02:00
}
2022-10-05 21:14:15 +02:00
/* -------------------------------------------- */
checkAndPrepareEquipment ( item ) {
if ( item . system . resistance ) {
item . system . resistanceDice = PegasusUtility . getDiceFromLevel ( item . system . resistance )
}
2022-10-06 17:47:56 +02:00
if ( item . system . idr && Number ( item . system . idr ) > 0 ) {
2022-10-05 21:14:15 +02:00
item . system . idrDice = PegasusUtility . getDiceFromLevel ( item . system . idr )
}
if ( item . system . damage ) {
item . system . damageDice = PegasusUtility . getDiceFromLevel ( item . system . damage )
}
if ( item . system . level ) {
item . system . levelDice = PegasusUtility . getDiceFromLevel ( item . system . level )
}
2021-12-02 07:38:59 +01:00
}
2022-10-05 21:14:15 +02:00
/* -------------------------------------------- */
checkAndPrepareEquipments ( listItem ) {
for ( let item of listItem ) {
this . checkAndPrepareEquipment ( item )
}
return listItem
2021-12-02 07:38:59 +01:00
}
2022-10-05 10:00:30 +02:00
2022-10-05 21:14:15 +02:00
/* -------------------------------------------- */
getWeapons ( ) {
let comp = duplicate ( this . items . filter ( item => item . type == 'weapon' ) || [ ] ) ;
return comp ;
}
/* -------------------------------------------- */
getItemById ( id ) {
let item = this . items . find ( item => item . id == id ) ;
if ( item ) {
item = duplicate ( item )
if ( item . type == 'specialisation' ) {
item . system . dice = PegasusUtility . getDiceFromLevel ( item . system . level ) ;
}
2022-01-11 23:35:23 +01:00
}
2022-10-05 21:14:15 +02:00
return item ;
2022-01-11 23:35:23 +01:00
}
2021-12-02 07:38:59 +01:00
2022-10-05 21:14:15 +02:00
/* -------------------------------------------- */
getSpecs ( ) {
let comp = duplicate ( this . items . filter ( item => item . type == 'specialisation' ) || [ ] ) ;
for ( let c of comp ) {
c . system . dice = PegasusUtility . getDiceFromLevel ( c . system . level ) ;
}
return comp ;
2021-12-02 07:38:59 +01:00
}
2022-02-10 21:58:19 +01:00
/* -------------------------------------------- */
async manageWorstFear ( flag ) {
2022-10-05 21:14:15 +02:00
if ( flag ) {
let effect = await PegasusUtility . getEffectFromCompendium ( "Worst Fear" )
effect . system . worstfear = true
this . createEmbeddedDocuments ( 'Item' , [ effect ] )
} else {
let effect = this . items . find ( item => item . type == "effect" && item . system . worstfear )
if ( effect ) {
this . deleteEmbeddedDocuments ( 'Item' , [ effect . id ] )
}
2022-02-10 21:58:19 +01:00
}
}
/* -------------------------------------------- */
async manageDesires ( flag ) {
2022-10-05 21:14:15 +02:00
if ( flag ) {
let effect = await PegasusUtility . getEffectFromCompendium ( "Desire" )
//console.log("EFFECT", effect)
effect . system . desires = true
this . createEmbeddedDocuments ( 'Item' , [ effect ] )
} else {
let effect = this . items . find ( item => item . type == "effect" && item . system . desires )
if ( effect ) {
this . deleteEmbeddedDocuments ( 'Item' , [ effect . id ] )
}
2022-02-10 21:58:19 +01:00
}
}
2022-10-05 21:14:15 +02:00
/* -------------------------------------------- */
getRelevantSpec ( statKey ) {
let comp = duplicate ( this . items . filter ( item => item . type == 'specialisation' && item . system . statistic == statKey ) || [ ] ) ;
for ( let c of comp ) {
c . system . dice = PegasusUtility . getDiceFromLevel ( c . system . level ) ;
}
return comp ;
2022-01-11 23:35:23 +01:00
}
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-10-05 21:14:15 +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 } ;
await this . updateEmbeddedDocuments ( 'Item' , [ update ] ) ; // Updates one EmbeddedEntity
}
2021-12-03 18:31:43 +01:00
}
2022-01-25 09:14:32 +01:00
2022-07-19 00:18:46 +02:00
/* -------------------------------------------- */
async activateViceOrVirtue ( itemId ) {
2022-10-05 21:14:15 +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
2022-10-05 21:14:15 +02:00
let effects = [ ]
for ( let effect of item . system . effectsgained ) {
effect . system . powerId = itemId // Link to the perk, in order to dynamically remove them
effects . push ( effect )
}
if ( effects . length ) {
await this . createEmbeddedDocuments ( 'Item' , effects )
}
} else {
let toRem = [ ]
for ( let item of this . items ) {
if ( item . type == 'effect' && item . system . powerId == itemId ) {
toRem . push ( item . id )
}
}
if ( toRem . length ) {
await this . deleteEmbeddedDocuments ( 'Item' , toRem )
2022-07-19 00:18:46 +02:00
}
}
2022-10-05 21:14:15 +02:00
let update = { _id : item . id , "data.activated" : ! item . system . activated }
await this . updateEmbeddedDocuments ( 'Item' , [ update ] ) // Updates one EmbeddedEntity
2022-07-19 00:18:46 +02:00
}
}
2022-09-28 13:43:36 +02:00
2022-10-05 21:14:15 +02:00
/* -------------------------------------------- */
updatePPP ( ) {
let ppp = 0
for ( let power of this . items ) {
if ( power . type == "power" ) {
ppp += Number ( power . system . powerlevelcost )
}
2022-09-27 20:31:01 +02:00
}
2022-10-05 21:14:15 +02:00
if ( ppp != this . system . ppp . spentPPP ) {
this . update ( { 'system.ppp.spentPPP' : ppp } )
2022-09-28 16:43:28 +02:00
}
}
2022-10-05 21:14:15 +02:00
/* -------------------------------------------- */
updateSize ( ) {
let sizeBonus = 0
for ( let effect of this . items ) {
if ( effect . type == "effect" && effect . system . effectlevel > 0 && effect . system . affectsize ) {
sizeBonus += effect . system . effectlevel
}
}
if ( sizeBonus != this . system . biodata . sizebonus ) {
this . update ( { 'system.biodata.sizebonus' : sizeBonus } )
}
2022-10-05 10:00:30 +02:00
}
2022-07-19 00:18:46 +02:00
2022-01-16 16:12:15 +01:00
/* -------------------------------------------- */
async activatePower ( itemId ) {
2022-10-05 21:14:15 +02:00
let item = this . items . find ( item => item . id == itemId )
if ( item && item . system ) {
2022-02-10 21:58:19 +01:00
2022-10-05 21:14:15 +02:00
let nrg = duplicate ( this . system . nrg )
if ( ! item . system . activated ) { // Current value
2022-02-13 21:58:19 +01:00
2022-10-05 21:14:15 +02:00
if ( item . system . costspent > nrg . value || item . system . costspent > nrg . max ) {
return ui . notifications . warn ( "Not enough NRG to activate the Power " + item . name )
}
2022-08-28 18:51:52 +02:00
2022-10-05 21:14:15 +02:00
nrg . activated += item . system . costspent
nrg . value -= item . system . costspent
nrg . max -= item . system . costspent
await this . update ( { 'system.nrg' : nrg } )
2022-02-10 21:58:19 +01:00
2022-10-05 21:14:15 +02:00
let effects = [ ]
for ( let effect of item . system . effectsgained ) {
effect . system . powerId = itemId // Link to the perk, in order to dynamically remove them
effects . push ( effect )
}
if ( effects . length ) {
await this . createEmbeddedDocuments ( 'Item' , effects )
}
if ( item . system . activatedtext . length > 0 ) {
ChatMessage . create ( { content : ` Power ${ item . name } activated : ${ item . system . activatedtext } ` } )
}
} else {
nrg . activated -= item . system . costspent
nrg . max += item . system . costspent
await this . update ( { 'system.nrg' : nrg } )
let toRem = [ ]
for ( let item of this . items ) {
if ( item . type == 'effect' && item . system . powerId == itemId ) {
toRem . push ( item . id )
}
}
if ( toRem . length ) {
await this . deleteEmbeddedDocuments ( 'Item' , toRem )
}
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-10-05 21:14:15 +02:00
let update = { _id : item . id , "data.activated" : ! item . system . activated }
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-10-05 21:14:15 +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 } ;
await this . updateEmbeddedDocuments ( 'Item' , [ update ] ) ; // Updates one EmbeddedEntity
}
2021-12-02 07:38:59 +01:00
}
2022-10-05 21:14:15 +02:00
/* -------------------------------------------- */
compareName ( a , b ) {
if ( a . name < b . name ) {
return - 1 ;
}
if ( a . name > b . name ) {
return 1 ;
}
return 0 ;
2022-10-05 10:00:30 +02:00
}
2022-10-05 21:14:15 +02:00
/* ------------------------------------------- */
getEquipments ( ) {
return this . items . filter ( item => item . type == 'shield' || item . type == 'armor' || item . type == "weapon" || item . type == "equipment" ) ;
2022-01-28 17:27:01 +01:00
}
2022-10-05 21:14:15 +02:00
/* ------------------------------------------- */
getEquipmentsOnly ( ) {
return duplicate ( this . items . filter ( item => item . type == "equipment" ) || [ ] )
2022-10-05 10:00:30 +02:00
}
2022-01-14 14:49:16 +01:00
2022-10-05 21:14:15 +02:00
/* ------------------------------------------- */
computeThreatLevel ( ) {
let tl = 0
for ( let key of statThreatLevel ) { // Init with concerned stats
tl += PegasusUtility . getDiceValue ( this . system . statistics [ key ] . value )
}
let powers = duplicate ( this . getPowers ( ) || [ ] )
if ( powers . length > 0 ) { // Then add some mental ones of powers
tl += PegasusUtility . getDiceValue ( this . system . statistics . foc . value )
tl += PegasusUtility . getDiceValue ( this . system . statistics . mnd . value )
}
tl += PegasusUtility . getDiceValue ( this . system . mr . value )
let specThreat = this . items . filter ( it => it . type == "specialisation" && it . system . isthreatlevel ) || [ ]
for ( let spec of specThreat ) {
tl += PegasusUtility . getDiceValue ( spec . system . level )
}
tl += this . system . nrg . absolutemax + this . system . secondary . health . max + this . system . secondary . delirium . max
tl += this . getPerks ( ) . length * 5
let weapons = this . getWeapons ( )
for ( let weapon of weapons ) {
tl += PegasusUtility . getDiceValue ( weapon . system . damage )
}
let armors = this . getArmors ( )
for ( let armor of armors ) {
tl += PegasusUtility . getDiceValue ( armor . system . resistance )
}
let shields = duplicate ( this . getShields ( ) )
for ( let shield of shields ) {
tl += PegasusUtility . getDiceValue ( shield . system . level )
}
let abilities = duplicate ( this . getAbilities ( ) )
for ( let ability of abilities ) {
tl += ability . system . threatlevel
}
let equipments = this . getEquipmentsOnly ( )
for ( let equip of equipments ) {
tl += equip . system . threatlevel
}
if ( tl != this . system . biodata . threatlevel ) {
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-10-05 21:14:15 +02:00
let equipments = duplicate ( this . items . filter ( item => item . type == "equipment" ) || [ ] )
for ( let equip1 of equipments ) {
if ( equip1 . system . iscontainer ) {
equip1 . system . contents = [ ]
equip1 . system . contentsEnc = 0
for ( let equip2 of equipments ) {
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-10-05 21:14:15 +02:00
// Compute whole enc
let enc = 0
for ( let item of equipments ) {
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
}
}
}
for ( let item of this . items ) { // Process items/shields/armors
if ( ( item . type == "weapon" || item . type == "shield" || item . type == "armor" ) && item . system . equipped ) {
2022-09-04 09:58:51 +02:00
let q = item . system . quantity ? ? 1
enc += q * item . system . weight
2022-03-07 16:00:53 +01:00
}
}
2022-03-06 20:07:41 +01:00
2022-10-05 21:14:15 +02:00
// Store local values
this . encCurrent = enc
this . containersTree = equipments . filter ( item => item . system . containerid == "" ) // Returns the root of equipements without container
2022-10-05 10:00:30 +02:00
2022-10-05 21:14:15 +02:00
// Manages slow effect
let overCapacity = Math . floor ( this . encCurrent / this . getEncumbranceCapacity ( ) )
this . encHindrance = Math . floor ( this . encCurrent / this . getEncumbranceCapacity ( ) )
//console.log("Capacity", overCapacity, this.encCurrent / this.getEncumbranceCapacity() )
let effect = this . items . find ( item => item . type == "effect" && item . system . slow )
if ( overCapacity >= 4 ) {
if ( ! effect ) {
effect = await PegasusUtility . getEffectFromCompendium ( "Slowed" )
effect . system . slow = true
this . createEmbeddedDocuments ( 'Item' , [ effect ] )
}
} else {
if ( effect ) {
this . deleteEmbeddedDocuments ( 'Item' , [ effect . id ] )
}
}
}
2022-10-05 10:00:30 +02:00
2022-10-05 21:14:15 +02:00
/* -------------------------------------------- */
modifyStun ( incDec ) {
let combat = duplicate ( this . system . combat )
combat . stunlevel += incDec
if ( combat . stunlevel >= 0 ) {
this . update ( { 'system.combat' : combat } )
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" )
2022-08-14 15:27:54 +02:00
}
2022-10-05 21:14:15 +02:00
let stunAbove = combat . stunlevel - combat . stunthreshold
if ( stunAbove > 0 ) {
ChatMessage . create ( { content : ` ${ this . name } Stun threshold has been exceeded. ` } )
}
if ( incDec > 0 && stunAbove > 0 ) {
let delirium = duplicate ( this . system . secondary . delirium )
delirium . value -= incDec
this . update ( { 'system.secondary.delirium' : delirium } )
2022-07-10 10:22:04 +02:00
}
}
2022-10-05 21:14:15 +02:00
/* -------------------------------------------- */
modifyMomentum ( incDec ) {
let momentum = duplicate ( this . system . momentum )
momentum . value += incDec
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 ) {
2022-10-05 21:14:15 +02:00
chatData . content = ` <div> ${ this . name } has gained a Momentum</div `
2022-07-10 10:22:04 +02:00
} else {
2022-10-05 21:14:15 +02:00
chatData . content = ` <div> ${ this . name } has used a Momentum</div `
2022-07-20 23:53:37 +02:00
}
ChatMessage . create ( chatData )
2022-10-05 21:14:15 +02:00
if ( incDec < 0 && momentum . value >= 0 ) {
PegasusUtility . showMomentumDialog ( this . id )
}
2022-03-06 20:07:41 +01:00
}
2022-10-05 21:14:15 +02:00
/* -------------------------------------------- */
getActiveEffects ( matching = it => true ) {
let array = Array . from ( this . getEmbeddedCollection ( "ActiveEffect" ) . values ( ) ) ;
return Array . from ( this . getEmbeddedCollection ( "ActiveEffect" ) . values ( ) ) . filter ( it => matching ( it ) ) ;
2021-12-02 07:38:59 +01:00
}
2022-10-05 21:14:15 +02:00
/* -------------------------------------------- */
getEffectByLabel ( label ) {
return this . getActiveEffects ( ) . find ( it => it . system . label == label ) ;
2021-12-02 07:38:59 +01:00
}
2022-10-05 21:14:15 +02:00
/* -------------------------------------------- */
getEffectById ( id ) {
return this . getActiveEffects ( ) . find ( it => it . id == id ) ;
2021-12-02 07:38:59 +01:00
}
2022-10-05 10:00:30 +02:00
2022-10-05 21:14:15 +02:00
/* -------------------------------------------- */
getAttribute ( attrKey ) {
return this . system . attributes [ attrKey ] ;
}
2022-01-30 09:44:37 +01:00
2022-03-06 20:07:41 +01:00
/* -------------------------------------------- */
2022-11-11 08:47:48 +01:00
async addObjectToContainer ( object , containerId ) {
2022-10-05 21:14:15 +02:00
let container = this . items . find ( item => item . id == containerId && item . system . iscontainer )
2022-11-11 08:47:48 +01:00
console . log ( "Adding container: " , container , object )
2022-10-05 21:14:15 +02:00
if ( container ) {
2022-11-11 08:47:48 +01:00
if ( object . system ? . iscontainer ) {
2022-10-05 21:14:15 +02:00
ui . notifications . warn ( "Only 1 level of container allowed" )
return
}
let alreadyInside = this . items . filter ( item => item . system . containerid && item . system . containerid == containerId ) ;
if ( alreadyInside . length >= container . system . containercapacity ) {
ui . notifications . warn ( "Container is already full !" )
return
} else {
2022-11-11 08:47:48 +01:00
this . updateEmbeddedDocuments ( "Item" , [ { _id : object . id , 'system.containerid' : containerId } ] )
2022-10-05 21:14:15 +02:00
}
} else if ( object && object . system . containerid ) { // remove from container
2022-11-11 08:47:48 +01:00
this . updateEmbeddedDocuments ( "Item" , [ { _id : object . id , 'system.containerid' : "" } ] )
2022-03-06 20:07:41 +01:00
}
}
2022-11-11 08:47:48 +01:00
2022-10-05 21:14:15 +02:00
/* -------------------------------------------- */
checkVirtue ( virtue ) {
let vices = this . getVices ( )
for ( let vice of vices ) {
let nonVirtues = vice . system . unavailablevirtue
for ( let blockedVirtue of nonVirtues ) {
if ( blockedVirtue . name . toLowerCase ( ) == virtue . name . toLowerCase ( ) ) {
return false
}
2022-07-19 20:51:48 +02:00
}
}
2022-10-05 21:14:15 +02:00
return true
2022-07-19 20:51:48 +02:00
}
2022-10-05 21:14:15 +02:00
/* -------------------------------------------- */
checkVice ( vice ) {
let virtues = this . getVirtues ( )
for ( let virtue of virtues ) {
let nonVices = virtue . system . unavailablevice
for ( let blockedVice of nonVices ) {
if ( blockedVice . name . toLowerCase ( ) == vice . name . toLowerCase ( ) ) {
return false
}
2022-07-19 20:51:48 +02:00
}
}
2022-10-05 21:14:15 +02:00
return true
2022-07-19 20:51:48 +02:00
}
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-10-05 21:14:15 +02:00
console . log ( "Pre-process" , item )
2022-11-11 08:47:48 +01:00
if ( ! item ) {
return
}
2022-10-05 21:14:15 +02:00
if ( item . type != "effect" && _ _isVehicle [ item . type ] ) {
ui . notifications . warn ( "You can't drop Vehicles item over a character sheet." )
2022-10-05 10:00:30 +02:00
return
}
2022-10-05 21:14:15 +02:00
// Pre-filter effects
if ( item . type == 'effect' ) {
if ( this . checkMentalDisruption ( ) && item . system . type == "mental" && item . system . genre == "positive" ) {
ChatMessage . create ( { content : "Effects of this type cannot be applied while Disruption is applied, Use a Soft Action to remove Disruption" } )
return
}
if ( this . checkPhysicalDisruption ( ) && item . system . type == "physical" && item . system . genre == "positive" ) {
ChatMessage . create ( { content : "Effects of this type cannot be applied while Disruption is applied, Use a Soft Action to remove Disruption" } )
return
}
if ( this . checkMentalImmunity ( ) && item . system . type == "mental" && item . system . genre == "negative" ) {
ChatMessage . create ( { content : "Effects of this type cannot be applied while Immunity is applied" } )
return
}
if ( this . checkPhysicalImmunity ( ) && item . system . type == "physical" && item . system . genre == "negative" ) {
ChatMessage . create ( { content : "Effects of this type cannot be applied while Immunity is applied" } )
return
}
2022-10-06 13:17:42 +02:00
if ( item . system . droptext && item . system . droptext . length > 0 ) {
ChatMessage . create ( { content : ` Effect ${ item . name } message : ${ item . system . droptext } ` } )
2022-10-06 12:38:31 +02:00
}
2022-08-14 15:27:54 +02:00
}
2022-10-05 21:14:15 +02:00
if ( item . type == 'race' ) {
this . applyRace ( item )
} else if ( item . type == 'role' ) {
this . applyRole ( item )
} else if ( item . type == 'ability' ) {
this . applyAbility ( item , [ ] , true )
if ( ! onDrop ) {
await this . createEmbeddedDocuments ( 'Item' , [ item ] )
}
} else {
if ( ! onDrop ) {
await this . createEmbeddedDocuments ( 'Item' , [ item ] )
}
2022-01-30 09:44:37 +01:00
}
2022-10-05 21:14:15 +02:00
// Check virtue/vice validity
if ( item . type == "virtue" ) {
if ( ! this . checkVirtue ( item ) ) {
ui . notifications . info ( "Virtue is not allowed due to Vice." )
return false
}
2022-07-19 20:51:48 +02:00
}
2022-10-05 21:14:15 +02:00
if ( item . type == "vice" ) {
if ( ! this . checkVice ( item ) ) {
ui . notifications . info ( "Vice is not allowed due to Virtue." )
return false
}
2022-07-19 20:51:48 +02:00
}
2022-10-05 21:14:15 +02:00
if ( item . type == "power" && item . system . purchasedtext . length > 0 ) {
ChatMessage . create ( { content : ` Power ${ item . name } puchased : ${ item . system . purchasedtext } ` } )
2022-08-28 18:51:52 +02:00
}
2022-10-05 21:14:15 +02:00
let dropID = $ ( event . target ) . parents ( ".item" ) . attr ( "data-item-id" ) // Only relevant if container drop
2022-11-11 08:47:48 +01:00
this . addObjectToContainer ( item , dropID )
2022-10-05 21:14:15 +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-10-05 21:14:15 +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 } ;
await this . updateEmbeddedDocuments ( 'Item' , [ update ] ) ; // Updates one EmbeddedEntity
}
2022-10-05 10:00:30 +02:00
}
2022-10-05 21:14:15 +02:00
/* -------------------------------------------- */
getInitiativeScore ( combatId , combatantId ) {
if ( this . type == 'character' ) {
this . rollMR ( true , combatId , combatantId )
}
if ( this . type == 'vehicle' ) {
this . rollMR ( true , combatId , combatantId )
}
console . log ( "Init required !!!!" )
return - 1 ;
2021-12-02 07:38:59 +01:00
}
2022-10-05 21:14:15 +02:00
/* -------------------------------------------- */
getSubActors ( ) {
let subActors = [ ] ;
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
}
2022-10-05 21:14:15 +02:00
return subActors ;
2021-12-02 07:38:59 +01:00
}
/* -------------------------------------------- */
2022-01-14 14:49:16 +01:00
async addSubActor ( subActorId ) {
2022-10-05 21:14:15 +02:00
let subActors = duplicate ( this . system . subactors || [ ] ) ;
subActors . push ( subActorId ) ;
await this . update ( { 'system.subactors' : subActors } ) ;
}
2022-09-25 15:13:59 +02:00
2021-12-02 07:38:59 +01:00
/* -------------------------------------------- */
2022-01-14 14:49:16 +01:00
async delSubActor ( subActorId ) {
2022-10-05 21:14:15 +02:00
let newArray = [ ] ;
for ( let id of this . system . subactors ) {
if ( id != subActorId ) {
newArray . push ( id ) ;
}
2021-12-02 07:38:59 +01:00
}
2022-10-05 21:14:15 +02:00
await this . update ( { 'system.subactors' : newArray } ) ;
2021-12-02 07:38:59 +01:00
}
2022-10-05 21:14:15 +02:00
/* -------------------------------------------- */
syncRoll ( rollData ) {
let linkedRollId = PegasusUtility . getDefenseState ( this . id ) ;
if ( linkedRollId ) {
rollData . linkedRollId = linkedRollId ;
}
this . lastRollId = rollData . rollId ;
PegasusUtility . saveRollData ( rollData ) ;
2021-12-02 20:18:21 +01:00
}
2021-12-02 07:38:59 +01:00
2022-10-05 21:14:15 +02:00
/* -------------------------------------------- */
getStat ( statKey ) {
let stat
if ( this . type == "character" && statKey == 'mr' ) {
2022-10-06 12:22:29 +02:00
stat = duplicate ( this . system . mr )
2022-10-05 21:14:15 +02:00
} else {
2022-10-06 12:22:29 +02:00
stat = duplicate ( this . system . statistics [ statKey ] )
2022-10-05 21:14:15 +02:00
}
2022-10-06 13:17:42 +02:00
if ( stat . currentlevel ) {
2022-10-06 12:22:29 +02:00
stat . dice = PegasusUtility . getDiceFromLevel ( stat . currentlevel )
} else {
stat . dice = PegasusUtility . getDiceFromLevel ( stat . value || stat . level )
}
return stat
2021-12-02 20:18:21 +01:00
}
2022-10-05 21:14:15 +02:00
/* -------------------------------------------- */
getOneSpec ( specId ) {
let spec = this . items . find ( item => item . type == 'specialisation' && item . id == specId )
if ( spec ) {
spec = duplicate ( spec ) ;
spec . system . dice = PegasusUtility . getDiceFromLevel ( spec . system . level ) ;
2022-02-10 21:58:19 +01:00
}
2022-10-05 21:14:15 +02:00
return spec ;
2022-02-10 21:58:19 +01:00
}
2022-10-05 21:14:15 +02:00
/* -------------------------------------------- */
specPowerActivate ( specId ) {
let spec = this . getOneSpec ( specId )
if ( spec ) {
let powers = [ ]
for ( let power of spec . system . powers ) {
if ( power . data ) {
power . system = power . data
}
power . system . specId = specId
powers . push ( power )
}
if ( powers . length > 0 ) {
this . createEmbeddedDocuments ( 'Item' , powers )
}
this . updateEmbeddedDocuments ( 'Item' , [ { _id : specId , 'system.powersactivated' : true } ] )
2022-02-10 21:58:19 +01:00
}
}
2022-10-05 21:14:15 +02:00
/* -------------------------------------------- */
specPowerDeactivate ( specId ) {
let toRem = [ ]
for ( let power of this . items ) {
if ( power . type == "power" && power . system . specId && power . system . specId == specId ) {
toRem . push ( power . id )
}
2022-10-05 10:00:30 +02:00
}
2022-10-05 21:14:15 +02:00
if ( toRem . length > 0 ) {
this . deleteEmbeddedDocuments ( 'Item' , toRem )
2022-02-16 17:43:51 +01:00
}
2022-10-05 21:14:15 +02:00
this . updateEmbeddedDocuments ( 'Item' , [ { _id : specId , 'system.powersactivated' : false } ] )
2022-02-16 17:43:51 +01:00
}
2022-10-05 21:14:15 +02:00
/* -------------------------------------------- */
equipActivate ( itemId ) {
let item = this . items . get ( itemId )
if ( item ) {
let effects = [ ]
for ( let effect of item . system . effects ) {
effect . system . itemId = itemId // Keep link
effects . push ( effect )
}
if ( effects . length > 0 ) {
this . createEmbeddedDocuments ( 'Item' , effects )
}
this . updateEmbeddedDocuments ( 'Item' , [ { _id : itemId , 'system.activated' : true } ] )
2022-02-16 17:43:51 +01:00
}
}
2022-10-05 21:14:15 +02:00
/* -------------------------------------------- */
equipDeactivate ( itemId ) {
let toRem = [ ]
for ( let item of this . items ) {
if ( item . system . itemId && item . system . itemId == itemId ) {
toRem . push ( item . id )
}
}
if ( toRem . length > 0 ) {
this . deleteEmbeddedDocuments ( 'Item' , toRem )
}
this . updateEmbeddedDocuments ( 'Item' , [ { _id : itemId , 'system.activated' : false } ] )
2022-10-05 10:00:30 +02:00
}
2022-02-16 17:43:51 +01:00
2022-02-10 21:58:19 +01:00
/* -------------------------------------------- */
async perkEffectUsed ( itemId ) {
2022-10-05 21:14:15 +02: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 19:03:09 +01:00
2022-10-05 21:14:15 +02:00
this . deleteEmbeddedDocuments ( 'Item' , [ effect . id ] )
}
2022-02-10 21:58:19 +01:00
}
2022-10-05 21:14:15 +02:00
/* -------------------------------------------- */
disableWeaverPerk ( perk ) {
if ( perk . system . isweaver ) {
for ( let spec of this . items ) {
if ( spec . type == 'specialisation' && spec . system . ispowergroup ) {
this . specPowerDeactivate ( spec . id )
}
2022-02-10 21:58:19 +01:00
}
}
}
2022-10-05 21:14:15 +02:00
/* -------------------------------------------- */
enableWeaverPerk ( perk ) {
if ( perk . system . isweaver ) {
for ( let spec of this . items ) {
if ( spec . type == 'specialisation' && spec . system . ispowergroup ) {
this . specPowerActivate ( spec . id )
}
2022-02-10 21:58:19 +01:00
}
2022-02-10 19:03:09 +01:00
}
}
2022-02-13 21:58:19 +01:00
/* -------------------------------------------- */
async cleanPerkEffects ( itemId ) {
2022-10-05 21:14:15 +02:00
let effects = [ ]
for ( let item of this . items ) {
if ( item . type == "effect" && item . system . perkId == itemId ) {
effects . push ( item . id )
}
}
if ( effects . length > 0 ) {
console . log ( "DELET!!!!" , effects , this )
await this . deleteEmbeddedDocuments ( 'Item' , effects )
2022-02-13 21:58:19 +01:00
}
}
/* -------------------------------------------- */
async updatePerkUsed ( itemId , index , checked ) {
2022-10-05 21:14:15 +02:00
let item = this . items . get ( itemId )
if ( item && index ) {
let key = "data.used" + index
await this . updateEmbeddedDocuments ( 'Item' , [ { _id : itemId , [ ` ${ key } ` ] : checked } ] )
item = this . items . get ( itemId ) // Refresh
if ( item . system . nbuse == "next1action" && item . system . used1 ) {
this . cleanPerkEffects ( itemId )
}
if ( item . system . nbuse == "next2action" && item . system . used1 && item . system . used2 ) {
this . cleanPerkEffects ( itemId )
}
if ( item . system . nbuse == "next3action" && item . system . used1 && item . system . used2 && item . system . used3 ) {
this . cleanPerkEffects ( itemId )
}
2022-02-13 21:58:19 +01:00
}
}
/* -------------------------------------------- */
async updatePowerSpentCost ( itemId , value ) {
2022-10-05 21:14:15 +02:00
let item = this . items . get ( itemId )
if ( item && value ) {
value = Number ( value ) || 0
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-10-05 21:14:15 +02:00
if ( this . getTraumaState ( ) == "severetrauma" ) {
for ( let perk of this . items ) {
if ( perk . type == "perk" ) {
this . cleanPerkEffects ( perk . id )
this . updateEmbeddedDocuments ( 'Item' , [ { _id : perk . id , 'system.status' : "ready" , 'system.used1' : false , 'system.used2' : false , 'system.used3' : false } ] )
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-10-05 21:14:15 +02:00
/* -------------------------------------------- */
incDecNRG ( value ) {
if ( this . type == "character" ) {
let nrg = duplicate ( this . system . nrg )
nrg . value += value
if ( nrg . value >= 0 && nrg . value <= nrg . max ) {
this . update ( { 'system.nrg' : nrg } )
}
} else {
let pc = duplicate ( this . system . statistics . pc )
pc . curnrg += value
if ( pc . curnrg >= 0 && pc . curnrg <= pc . maxnrg ) {
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-10-05 21:14:15 +02:00
let item = this . items . get ( itemId )
if ( item ) {
if ( item . system . status == status ) return ; // Ensure we are really changing the status
if ( this . checkNoPerksAllowed ( ) ) {
await this . updateEmbeddedDocuments ( 'Item' , [ { _id : item . id , 'system.status' : "ready" } ] )
ChatMessage . create ( { content : "No perks activation allowed due to effect !" } )
return
}
2022-10-05 10:00:30 +02:00
2022-10-05 21:14:15 +02:00
// Severe Trauma management
if ( this . getTraumaState ( ) == "severetrauma" ) {
if ( ! this . severeTraumaMessage ) {
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-10-05 21:14:15 +02:00
this . updateEmbeddedDocuments ( 'Item' , [ { _id : itemId , 'system.status' : "ready" , 'system.used1' : false , 'system.used2' : false , 'system.used3' : false } ] )
return
2022-10-05 10:00:30 +02:00
}
2022-10-05 21:14:15 +02:00
let updateOK = true
if ( status == "ready" ) {
await this . cleanPerkEffects ( itemId )
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-10-05 21:14:15 +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 } )
}
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 } )
}
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 } )
}
this . disableWeaverPerk ( item )
PegasusUtility . createChatWithRollMode ( item . name , {
content : await renderTemplate ( ` systems/fvtt-pegasus-rpg/templates/chat-perk-ready.html ` , { name : this . name , perk : duplicate ( item ) } )
} )
2022-10-05 10:00:30 +02:00
}
2022-10-05 21:14:15 +02:00
if ( status == "activated" ) {
// Add effects linked to the perk
let effects = [ ]
for ( let effect of item . system . effectsgained ) {
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
effects . push ( effect )
}
if ( effects . length ) {
await this . createEmbeddedDocuments ( 'Item' , effects )
}
// Manage additional flags
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 } )
} else {
updateOK = false
ui . notifications . warn ( "Not enough NRG to activate the Perk " + item . name )
}
}
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 } )
}
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 } )
}
if ( item . system . features . bonusnrg . flag ) {
2022-09-04 09:58:51 +02:00
let nrg = duplicate ( this . system . nrg )
2022-10-05 21:14:15 +02:00
nrg . value += Number ( item . system . features . bonusnrg . value ) || 0
nrg . max += Number ( item . system . features . bonusnrg . value ) || 0
2022-09-04 09:58:51 +02:00
await this . update ( { 'system.nrg' : nrg } )
2022-02-10 19:03:09 +01:00
}
2022-10-05 21:14:15 +02:00
PegasusUtility . createChatWithRollMode ( item . name , {
content : await renderTemplate ( ` systems/fvtt-pegasus-rpg/templates/chat-perk-activated.html ` , { name : this . name , perk : duplicate ( item ) } )
} )
this . enableWeaverPerk ( item )
2022-02-10 19:03:09 +01:00
}
2022-10-05 21:14:15 +02:00
if ( updateOK ) {
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-10-05 21:14:15 +02:00
let items = this . items . filter ( item => item . type == itemType ) ;
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-10-05 21:14:15 +02:00
let item = this . items . find ( item => item . type == newItem . type && item . name . toLowerCase ( ) == newItem . name . toLowerCase ( ) )
if ( ! item ) {
await this . createEmbeddedDocuments ( 'Item' , [ newItem ] ) ;
}
2022-01-08 10:49:08 +01:00
}
2022-10-05 21:14:15 +02:00
/* -------------------------------------------- */
getTraumaState ( ) {
this . traumaState = "none"
2022-09-25 09:26:12 +02:00
if ( this . type == "character" ) {
2022-10-05 21:14:15 +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
}
}
2022-10-05 21:14:15 +02:00
return this . traumaState
2022-07-10 10:22:04 +02:00
}
2022-10-05 21:14:15 +02:00
/* -------------------------------------------- */
getLevelRemaining ( ) {
return this . system . biodata ? . currentlevelremaining || 0
}
/* -------------------------------------------- */
modifyHeroLevelRemaining ( incDec ) {
let biodata = duplicate ( this . system . biodata )
biodata . currentlevelremaining = Math . max ( biodata . currentlevelremaining + incDec , 0 )
this . update ( { "system.biodata" : biodata } )
ChatMessage . create ( { content : ` ${ this . name } has used a Hero Level to reroll ! ` } )
return biodata . currentlevelremaining
}
2022-08-24 20:24:22 +02:00
2022-10-05 21:14:15 +02:00
/* -------------------------------------------- */
checkIgnoreHealth ( ) {
for ( let effect of this . items ) {
if ( effect . type == "effect" && effect . system . ignorehealthpenalty ) {
return true
}
2022-08-14 15:27:54 +02:00
}
2022-10-05 21:14:15 +02:00
return false
2022-08-14 15:27:54 +02:00
}
2022-10-05 21:14:15 +02:00
/* -------------------------------------------- */
checkMentalDisruption ( ) {
for ( let effect of this . items ) {
if ( effect . type == "effect" && effect . system . mentaldisruption ) {
return true
}
2022-08-14 15:27:54 +02:00
}
2022-10-05 21:14:15 +02:00
return false
2022-08-14 15:27:54 +02:00
}
2022-10-05 21:14:15 +02:00
/* -------------------------------------------- */
checkPhysicalDisruption ( ) {
for ( let effect of this . items ) {
if ( effect . type == "effect" && effect . system . physicaldisruption ) {
return true
}
2022-08-14 15:27:54 +02:00
}
2022-10-05 21:14:15 +02:00
return false
2022-08-14 15:27:54 +02:00
}
2022-10-05 21:14:15 +02:00
/* -------------------------------------------- */
checkMentalImmunity ( ) {
for ( let effect of this . items ) {
if ( effect . type == "effect" && effect . system . mentalimmunity ) {
return true
}
2022-08-14 15:27:54 +02:00
}
2022-10-05 21:14:15 +02:00
return false
2022-08-14 15:27:54 +02:00
}
2022-10-05 21:14:15 +02:00
/* -------------------------------------------- */
checkPhysicalImmunity ( ) {
for ( let effect of this . items ) {
if ( effect . type == "effect" && effect . system . physicalimmunity ) {
return true
}
2022-08-14 15:27:54 +02:00
}
2022-10-05 21:14:15 +02:00
return false
2022-08-14 15:27:54 +02:00
}
2022-10-05 21:14:15 +02:00
/* -------------------------------------------- */
checkNoBonusDice ( ) {
for ( let effect of this . items ) {
if ( effect . type == "effect" && effect . system . nobonusdice ) {
return true
}
2022-08-14 15:27:54 +02:00
}
2022-10-05 21:14:15 +02:00
return false
2022-08-14 15:27:54 +02:00
}
2022-10-05 21:14:15 +02:00
/* -------------------------------------------- */
checkNoPerksAllowed ( ) {
for ( let effect of this . items ) {
if ( effect . type == "effect" && effect . system . noperksallowed ) {
return true
}
2022-08-14 15:27:54 +02:00
}
2022-10-05 21:14:15 +02:00
return false
2022-08-14 15:27:54 +02:00
}
2022-10-05 21:14:15 +02:00
/* -------------------------------------------- */
checkIfPossible ( ) {
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-10-05 21:14:15 +02:00
if ( this . isOwner || game . user . isGM ) {
let updates = { }
2022-11-11 08:47:48 +01:00
let phyDiceValue = PegasusUtility . getDiceValue ( this . system . statistics . phy . value ) + this . system . secondary . health . bonus + this . system . statistics . phy . mod + PegasusUtility . getDiceValue ( this . system . statistics . phy . bonuseffect ) ;
2022-10-05 21:14:15 +02:00
if ( phyDiceValue != this . system . secondary . health . max ) {
updates [ 'system.secondary.health.max' ] = phyDiceValue
}
if ( this . computeValue ) {
updates [ 'system.secondary.health.value' ] = phyDiceValue
}
2022-11-11 08:47:48 +01:00
let mndDiceValue = PegasusUtility . getDiceValue ( this . system . statistics . mnd . value ) + this . system . secondary . delirium . bonus + this . system . statistics . mnd . mod + PegasusUtility . getDiceValue ( this . system . statistics . mnd . bonuseffect ) ;
2022-10-05 21:14:15 +02:00
if ( mndDiceValue != this . system . secondary . delirium . max ) {
updates [ 'system.secondary.delirium.max' ] = mndDiceValue
}
if ( this . computeValue ) {
updates [ 'system.secondary.delirium.value' ] = mndDiceValue
}
2022-11-11 08:47:48 +01:00
let stlDiceValue = PegasusUtility . getDiceValue ( this . system . statistics . stl . value ) + this . system . secondary . stealthhealth . bonus + this . system . statistics . stl . mod + PegasusUtility . getDiceValue ( this . system . statistics . stl . bonuseffect ) ;
2022-10-05 21:14:15 +02:00
if ( stlDiceValue != this . system . secondary . stealthhealth . max ) {
updates [ 'system.secondary.stealthhealth.max' ] = stlDiceValue
}
if ( this . computeValue ) {
updates [ 'system.secondary.stealthhealth.value' ] = stlDiceValue
}
2022-01-25 09:14:32 +01:00
2022-11-11 08:47:48 +01:00
let socDiceValue = PegasusUtility . getDiceValue ( this . system . statistics . soc . value ) + this . system . secondary . socialhealth . bonus + this . system . statistics . soc . mod + PegasusUtility . getDiceValue ( this . system . statistics . soc . bonuseffect ) ;
2022-10-05 21:14:15 +02:00
if ( socDiceValue != this . system . secondary . socialhealth . max ) {
updates [ 'system.secondary.socialhealth.max' ] = socDiceValue
}
if ( this . computeValue ) {
updates [ 'system.secondary.socialhealth.value' ] = socDiceValue
}
2022-07-28 18:45:04 +02:00
2022-11-11 08:47:48 +01:00
let nrgValue = PegasusUtility . getDiceValue ( this . system . statistics . foc . value ) + this . system . nrg . mod + this . system . statistics . foc . mod + PegasusUtility . getDiceValue ( this . system . statistics . foc . bonuseffect )
2022-10-05 21:14:15 +02:00
if ( nrgValue != this . system . nrg . absolutemax ) {
updates [ 'system.nrg.absolutemax' ] = nrgValue
}
if ( this . computeValue ) {
updates [ 'system.nrg.max' ] = nrgValue
updates [ 'system.nrg.value' ] = nrgValue
}
2022-02-16 14:13:16 +01:00
2022-10-05 21:14:15 +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 ) {
updates [ 'system.combat.stunthreshold' ] = stunth
}
2022-01-25 09:14:32 +01:00
2022-10-05 21:14:15 +02:00
let momentum = this . system . statistics . foc . value + this . system . statistics . foc . mod
if ( momentum != this . system . momentum . max ) {
updates [ 'system.momentum.value' ] = 0
updates [ 'system.momentum.max' ] = momentum
}
2022-01-25 09:14:32 +01:00
2022-10-05 21:14:15 +02:00
let mrLevel = ( this . system . statistics . agi . value + this . system . statistics . str . value ) - this . system . statistics . phy . value
mrLevel = ( mrLevel < 1 ) ? 1 : mrLevel ;
if ( mrLevel != this . system . mr . value ) {
updates [ 'system.mr.value' ] = mrLevel
}
2022-01-19 21:25:59 +01:00
2022-10-05 21:14:15 +02:00
let moralitythreshold = - ( Number ( PegasusUtility . getDiceValue ( this . system . statistics . foc . value ) ) + Number ( this . system . statistics . foc . mod ) )
if ( moralitythreshold != this . system . biodata . moralitythreshold ) {
updates [ 'system.biodata.moralitythreshold' ] = moralitythreshold
2022-07-21 22:52:17 +02:00
}
2022-10-05 21:14:15 +02:00
if ( ! this . isToken ) {
if ( this . warnMorality != this . system . biodata . morality && this . system . biodata . morality < 0 ) {
console . log ( "CHAR" , this )
ChatMessage . create ( { content : "WARNING: Your character is dangerously close to becoming corrupted and defeated. Start on a path of redemption!" } )
}
if ( this . warnMorality != this . system . biodata . morality ) {
this . warnMorality = this . system . biodata . morality
}
2022-07-21 22:52:17 +02:00
}
2022-08-24 20:24:22 +02:00
2022-10-05 21:14:15 +02:00
let race = this . getRace ( )
if ( race && race . name && ( race . name != this . system . biodata . racename ) ) {
updates [ 'system.biodata.racename' ] = race . name
}
let role = this . getRole ( )
if ( role && role . name && ( role . name != this . system . biodata . rolename ) ) {
updates [ 'system.biodata.rolename' ] = role . name
}
if ( Object . entries ( updates ) . length > 0 ) {
await this . update ( updates )
}
this . computeThreatLevel ( )
}
if ( this . isOwner || game . user . isGM ) {
// Update current hindrance level
let hindrance = this . system . combat . hindrancedice
if ( ! this . checkIgnoreHealth ( ) ) {
if ( this . system . secondary . health . value < 0 ) {
if ( this . system . secondary . health . value < - Math . floor ( ( this . system . secondary . health . max + 1 ) / 2 ) ) { // Severe wounded
hindrance += 3
} else {
hindrance += 1
}
}
}
this . system . combat . hindrancedice = hindrance
this . getTraumaState ( )
this . cleanupPerksIfTrauma ( )
this . parseStatEffects ( )
this . parseStatusEffects ( )
2022-09-28 16:27:16 +02:00
}
}
2022-10-05 21:14:15 +02:00
/* -------------------------------------------- */
parseStatEffects ( ) {
if ( this . system . biodata . noautobonus ) { // If we are in "no-bonus mode
return
}
2022-10-07 17:50:28 +02:00
let effectsPlus = this . items . filter ( effect => effect . type == "effect" && effect . system . genre == "positive" && effect . system . statdice )
let effectsMinus = this . items . filter ( effect => effect . type == "effect" && effect . system . genre == "negative" && effect . system . reducedicevalue )
2022-10-05 21:14:15 +02:00
for ( let statKey in this . system . statistics ) {
let stat = duplicate ( this . system . statistics [ statKey ] )
let bonus = 0
2022-10-07 17:50:28 +02:00
for ( let effect of effectsPlus ) {
2022-10-05 21:14:15 +02:00
if ( effect . system . stataffected == statKey ) {
bonus += Number ( effect . system . effectlevel )
2022-09-28 16:27:16 +02:00
}
}
2022-10-07 17:50:28 +02:00
for ( let effect of effectsMinus ) {
if ( effect . system . stataffected == statKey ) {
bonus -= Number ( effect . system . effectlevel )
}
}
2022-10-05 21:14:15 +02:00
if ( bonus != stat . bonuseffect ) {
stat . bonuseffect = bonus
2022-10-07 17:50:28 +02:00
if ( stat . bonuseffect + stat . value < 1 ) {
stat . value = 1
stat . bonuseffect = 0
}
2022-10-05 21:14:15 +02:00
this . update ( { [ ` system.statistics. ${ statKey } ` ] : stat } )
}
2022-02-10 15:53:42 +01:00
}
2022-01-08 10:49:08 +01:00
}
2022-10-05 21:14:15 +02:00
/* -------------------------------------------- */
parseStatusEffects ( ) {
if ( this . system . biodata . noautobonus ) { // If we are in "no-bonus mode
return
2022-09-30 13:44:59 +02:00
}
2022-10-05 21:14:15 +02:00
let effects = this . items . filter ( effect => effect . type == "effect" && effect . system . affectstatus && ( Number ( effect . system . effectlevel ) > 0 ) )
for ( let statusKey in this . system . secondary ) {
let status = duplicate ( this . system . secondary [ statusKey ] )
let bonus = 0
for ( let effect of effects ) {
if ( effect . system . affectedstatus && effect . system . affectedstatus == statusKey ) {
bonus += Number ( effect . system . effectlevel )
}
}
if ( bonus != status . bonus ) {
status . bonus = bonus
this . update ( { [ ` system.secondary. ${ statusKey } ` ] : status } )
}
2022-10-05 10:00:30 +02:00
}
2022-09-30 13:44:59 +02:00
2022-10-05 21:14:15 +02:00
let nrg = duplicate ( this . system . nrg )
2022-09-30 13:44:59 +02:00
let bonus = 0
2022-10-03 10:01:41 +02:00
for ( let effect of effects ) {
2022-10-05 21:14:15 +02:00
if ( effect . system . affectedstatus && effect . system . affectedstatus == "nrg" ) {
2022-09-30 13:44:59 +02:00
bonus += Number ( effect . system . effectlevel )
}
}
2022-10-05 21:14:15 +02:00
if ( bonus != nrg . mod ) {
nrg . mod = bonus
this . update ( { [ ` system.nrg ` ] : nrg } )
2022-09-30 13:44:59 +02:00
}
2022-10-05 10:00:30 +02:00
}
2022-01-07 20:40:40 +01:00
/* -------------------------------------------- */
2022-01-14 14:49:16 +01:00
async modStat ( key , inc = 1 ) {
2022-10-05 21:14:15 +02:00
let stat = duplicate ( this . system . statistics [ key ] )
stat . mod += parseInt ( inc )
await this . update ( { [ ` data.statistics. ${ key } ` ] : stat } )
}
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-10-05 21:14:15 +02:00
key = key . toLowerCase ( )
let stat = duplicate ( this . system . statistics [ key ] )
stat . value += parseInt ( inc )
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-10-05 21:14:15 +02:00
console . log ( "Using spec : " , spec , inc )
let specExist = this . items . find ( item => item . type == 'specialisation' && item . name . toLowerCase ( ) == spec . name . toLowerCase ( ) )
if ( specExist ) {
specExist = duplicate ( specExist )
specExist . system . level += inc ;
let update = { _id : specExist . _id , "data.level" : specExist . system . level } ;
await this . updateEmbeddedDocuments ( 'Item' , [ update ] ) ;
} else {
spec . system . level += inc ;
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-10-05 21:14:15 +02:00
let objetQ = this . items . get ( objetId )
if ( objetQ ) {
let newQ = objetQ . system . quantity + incDec
if ( newQ >= 0 ) {
const updated = await this . updateEmbeddedDocuments ( 'Item' , [ { _id : objetQ . id , 'system.quantity' : newQ } ] ) // pdates one EmbeddedEntity
}
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-10-05 21:14:15 +02:00
let objetQ = this . items . get ( objetId )
if ( objetQ ) {
let newQ = objetQ . system . ammocurrent + incDec ;
if ( newQ >= 0 && newQ <= objetQ . system . ammomax ) {
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 ) {
2022-10-05 21:14:15 +02:00
// manage stat bonus
if ( ability . system . affectedstat != "notapplicable" ) {
let stat = duplicate ( this . system . statistics [ ability . system . affectedstat ] )
stat . mod += Number ( ability . system . statmodifier )
updates [ ` system.statistics. ${ ability . system . affectedstat } ` ] = stat
}
// manage status bonus
if ( ability . system . statusaffected != "notapplicable" ) {
if ( ability . system . statusaffected == 'nrg' ) {
let nrg = duplicate ( this . system . nrg )
nrg . mod += Number ( ability . system . statusmodifier )
updates [ ` system.nrg ` ] = nrg
}
if ( ability . system . statusaffected == 'health' ) {
let health = duplicate ( this . system . secondary . health )
health . bonus += Number ( ability . system . statusmodifier )
updates [ ` system.secondary.health ` ] = health
}
if ( ability . system . statusaffected == 'delirium' ) {
let delirium = duplicate ( this . system . secondary . delirium )
delirium . bonus += Number ( ability . system . statusmodifier )
updates [ ` system.secondary.delirium ` ] = delirium
}
2022-02-10 15:53:42 +01:00
}
2022-10-05 21:14:15 +02:00
if ( directUpdate ) {
await this . update ( updates )
2022-02-10 15:53:42 +01:00
}
2022-10-05 21:14:15 +02:00
let newItems = [ ]
if ( ability . system . effectsgained ) {
for ( let effect of ability . system . effectsgained ) {
if ( ! effect . system ) effect . system = effect . data
newItems . push ( effect ) ;
}
2022-02-10 15:53:42 +01:00
}
2022-10-05 21:14:15 +02:00
if ( ability . system . powersgained ) {
for ( let power of ability . system . powersgained ) {
if ( ! power . system ) power . system = power . data
newItems . push ( power ) ;
}
2022-01-14 14:49:16 +01:00
}
2022-10-05 21:14:15 +02:00
if ( ability . system . specialisations ) {
for ( let spec of ability . system . specialisations ) {
if ( ! spec . system ) spec . system = spec . data
newItems . push ( spec ) ;
}
2022-02-10 15:53:42 +01:00
}
2022-10-05 21:14:15 +02:00
if ( ability . system . attackgained ) {
for ( let weapon of ability . system . attackgained ) {
if ( ! weapon . system ) weapon . system = weapon . data
newItems . push ( weapon ) ;
}
2022-10-05 10:00:30 +02:00
}
2022-10-05 21:14:15 +02:00
if ( ability . system . armorgained ) {
for ( let armor of ability . system . armorgained ) {
if ( ! armor . system ) armor . system = armor . data
newItems . push ( armor ) ;
}
2022-02-10 21:58:19 +01:00
}
2022-10-05 21:14:15 +02:00
console . log ( "Ability : adding" , newItems )
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-10-05 21:14:15 +02:00
let updates = { 'system.biodata.racename' : race . name }
let newItems = [ ]
await this . deleteAllItemsByType ( 'race' )
newItems . push ( race ) ;
console . log ( "DROPPED RACE" , race )
for ( let ability of race . system . abilities ) {
if ( ! ability . system ) ability . system = ability . data
newItems . push ( ability )
this . applyAbility ( ability , updates )
}
if ( race . system . perksgained ) {
for ( let power of race . system . perks ) {
if ( ! power . system ) power . system = power . data
newItems . push ( power ) ;
}
2022-10-05 10:00:30 +02:00
}
2022-01-07 20:40:40 +01:00
2022-10-05 21:14:15 +02:00
await this . update ( updates )
await this . createEmbeddedDocuments ( 'Item' , newItems )
console . log ( "Updates" , updates , newItems )
console . log ( "Updated actor" , this )
}
2022-10-05 10:00:30 +02:00
2022-10-05 21:14:15 +02:00
/* -------------------------------------------- */
getIncreaseStatValue ( updates , statKey ) {
let stat = duplicate ( this . system . statistics [ statKey ] )
stat . value += 1 ;
updates [ ` data.statistics. ${ statKey } ` ] = stat
}
2022-10-05 10:00:30 +02:00
2022-01-07 20:40:40 +01:00
/* -------------------------------------------- */
2022-01-14 14:49:16 +01:00
async applyRole ( role ) {
2022-10-05 21:14:15 +02:00
console . log ( "ROLE" , role )
2022-01-07 20:40:40 +01:00
2022-10-05 21:14:15 +02:00
let updates = { 'system.biodata.rolename' : role . name }
let newItems = [ ]
await this . deleteAllItemsByType ( 'role' )
newItems . push ( role )
2022-01-07 20:40:40 +01:00
2022-10-05 21:14:15 +02:00
this . getIncreaseStatValue ( updates , role . system . statincrease1 )
this . getIncreaseStatValue ( updates , role . system . statincrease2 )
2022-03-16 15:08:34 +01:00
2022-10-05 21:14:15 +02:00
if ( role . system . specialability . length > 0 ) {
//console.log("Adding ability", role.system.specialability)
newItems = newItems . concat ( duplicate ( role . system . specialability ) ) // Add new ability
this . applyAbility ( role . system . specialability [ 0 ] , newItems )
}
await this . update ( updates )
await this . createEmbeddedDocuments ( 'Item' , newItems )
2022-10-05 10:00:30 +02:00
2022-10-05 21:14:15 +02:00
}
2022-01-14 14:49:16 +01:00
2022-01-28 10:05:54 +01:00
2022-10-05 21:14:15 +02:00
/* -------------------------------------------- */
addHindrancesList ( effectsList ) {
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-01-28 10:05:54 +01:00
}
}
2022-10-05 21:14:15 +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-10-05 10:00:30 +02:00
}
}
2022-01-28 10:05:54 +01:00
2022-10-05 21:14:15 +02:00
/* -------------------------------------------- */
/ * R O L L S E C T I O N
/* -------------------------------------------- */
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-10-05 21:14:15 +02:00
} else {
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-10-05 21:14:15 +02:00
/* -------------------------------------------- */
addEffects ( rollData , isInit = false , isPower = false , isPowerDmg = false ) {
let effects = this . items . filter ( item => item . type == 'effect' )
for ( let effect of effects ) {
effect = duplicate ( effect )
2022-10-07 17:45:53 +02:00
if ( ! effect . system . hindrance && ! effect . system . statdice && ! effect . system . reducedicevalue
2022-10-05 21:14:15 +02:00
&& ( 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
}
this . pushEffect ( rollData , effect )
}
if ( isPower && effect . system . stataffected == "powerroll" ) {
this . pushEffect ( rollData , effect )
}
if ( isPowerDmg && effect . system . stataffected == "powerdmgroll" ) {
this . pushEffect ( rollData , effect )
2022-08-24 20:24:22 +02:00
}
2022-02-10 15:53:42 +01:00
2022-01-28 11:41:19 +01:00
}
2022-01-28 10:05:54 +01:00
}
2022-10-05 21:14:15 +02:00
/* -------------------------------------------- */
addArmorsShields ( rollData , statKey = "none" , useShield = false , subKey = undefined ) {
if ( statKey == 'phy' && subKey == "dmg-res" ) {
let armors = this . getArmors ( )
for ( let armor of armors ) {
rollData . armorsList . push ( { label : ` Armor ${ armor . name } ` , type : "armor" , applied : false , value : armor . system . resistance } )
}
2022-01-28 17:27:01 +01:00
}
2022-10-05 21:14:15 +02:00
if ( useShield ) {
let shields = this . items . filter ( item => item . type == "shield" && item . system . equipped )
for ( let sh of shields ) {
rollData . armorsList . push ( { label : ` Shield ${ sh . name } ` , type : "shield" , applied : false , value : sh . system . level } )
2022-01-28 17:27:01 +01:00
}
}
}
2022-10-05 21:14:15 +02:00
addWeapons ( rollData , statKey ) {
let weapons = this . getWeapons ( )
for ( let weapon of weapons ) {
if ( weapon . system . equipped && weapon . system . statistic == statKey ) {
rollData . weaponsList . push ( { label : ` Attack ${ weapon . name } ` , type : "attack" , applied : false , weapon : weapon , value : 0 , damageDice : PegasusUtility . getDiceFromLevel ( 0 ) } )
}
if ( weapon . system . equipped && weapon . system . canbethrown && statKey == "agi" ) {
rollData . weaponsList . push ( { label : ` Attack ${ weapon . name } ` , type : "attack" , applied : false , weapon : weapon , value : 0 , damageDice : PegasusUtility . getDiceFromLevel ( 0 ) } )
}
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-09-21 16:54:34 +02:00
}
2022-10-05 21:14:15 +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-09-28 16:27:16 +02:00
}
2022-10-05 21:14:15 +02:00
}
}
addEquipments ( rollData , statKey ) {
let equipments = this . getEquipmentsOnly ( )
for ( let equip of equipments ) {
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-10-05 10:00:30 +02:00
}
2022-10-05 21:14:15 +02:00
}
}
addVehicleWeapons ( rollData , vehicle ) {
if ( vehicle ) {
2022-10-07 10:48:44 +02:00
let modules = vehicle . items . filter ( item => item . type == "vehicleweaponmodule" && item . system . activated )
2022-10-05 21:14:15 +02:00
if ( modules && modules . length > 0 ) {
for ( let module of modules ) {
rollData . vehicleWeapons . push ( { label : ` Weapon ${ module . name } ` , type : "item" , applied : false , weapon : module , value : module . system . damagedicevalue } )
2022-09-25 09:26:12 +02:00
}
2022-09-21 16:54:34 +02:00
}
2022-10-05 10:00:30 +02:00
}
2022-10-05 21:14:15 +02:00
}
2022-09-25 09:26:12 +02:00
2022-10-06 13:17:42 +02:00
/* -------------------------------------------- */
processVehicleTargetMessage ( rollData ) {
if ( rollData . defenderTokenId ) {
let vehicle = game . canvas . tokens . get ( rollData . defenderTokenId ) . actor
if ( vehicle . type == "vehicle" ) {
if ( rollData . subKey == "defence" && vehicle . system . statistics . ad . currentspeed == "crawling" ) {
ChatMessage . create ( { content : ` ${ vehicle . name } is moving at Crawling speed : add a D8 to your Attack Dice Pool against this Vehicle ` } )
}
if ( rollData . subKey == "defence" && vehicle . system . statistics . ad . currentspeed == "slow" ) {
ChatMessage . create ( { content : ` ${ vehicle . name } is moving at Slow speed : add a D4 to your Attack Dice Pool against this Vehicle ` } )
}
}
if ( this . type == "vehicle" && rollData . statKey == "man" && this . system . statistics . ad . currentspeed == "fast" ) {
2022-10-06 20:35:23 +02:00
ChatMessage . create ( { content : ` ${ this . name } is moving at Fast speed : anyone using the vehicles MAN Dice Pool suffers a D8 Hindrance which is added to the Difficulty Dice Pool against this Vehicle ` } )
2022-10-06 13:17:42 +02:00
}
if ( this . type == "vehicle" && rollData . statKey == "man" && this . system . statistics . ad . currentspeed == "extfast" ) {
2022-10-06 20:35:23 +02:00
ChatMessage . create ( { content : ` ${ this . name } is moving at Extremely Fast speed : anyone using the vehicles MAN Dice Pool suffers a D12 Hindrance which is added to the Difficulty Dice Pool against this Vehicle ` } )
2022-10-06 13:17:42 +02:00
}
2022-10-06 20:35:23 +02:00
if ( rollData . subKey == "defence" && rollData . vehicle && rollData . vehicle . system . statistics . ad . currentspeed == "crawling" ) {
ChatMessage . create ( { content : ` ${ this . name } is moving at Crawling speed : add a D8 to your Attack Dice Pool against this Vehicle ` } )
}
if ( rollData . subKey == "defence" && rollData . vehicle && rollData . vehicle . system . statistics . ad . currentspeed == "slow" ) {
ChatMessage . create ( { content : ` ${ this . name } is moving at Slow speed : add a D4 to your Attack Dice Pool against this Vehicle ` } )
}
}
2022-10-06 13:17:42 +02:00
}
2022-10-05 21:14:15 +02:00
/* -------------------------------------------- */
getCommonRollData ( statKey = undefined , useShield = false , isInit = false , isPower = false , subKey = "" , vehicle = undefined ) {
let rollData = PegasusUtility . getBasicRollData ( isInit )
rollData . alias = this . name
rollData . actorImg = this . img
rollData . actorId = this . id
rollData . img = this . img
rollData . traumaState = this . getTraumaState ( )
rollData . levelRemaining = this . getLevelRemaining ( )
rollData . activePerks = duplicate ( this . getActivePerks ( ) )
rollData . diceList = PegasusUtility . getDiceList ( )
rollData . noBonusDice = this . checkNoBonusDice ( )
rollData . dicePool = [ ]
rollData . subKey = subKey
if ( subKey == "melee-dmg" || subKey == "ranged-dmg" || subKey == "power-dmg" ) {
rollData . isDamage = true
2022-02-10 21:58:19 +01:00
}
2022-01-28 10:05:54 +01:00
2022-10-05 21:14:15 +02:00
if ( statKey ) {
rollData . statKey = statKey
rollData . stat = this . getStat ( statKey )
if ( rollData . stat . value != undefined ) {
rollData . stat . level = rollData . stat . value // Normalize
2022-10-06 12:22:29 +02:00
rollData . statDicesLevel = rollData . stat . level + rollData . stat . bonuseffect
}
if ( rollData . stat . currentlevel ) {
rollData . stat . level = rollData . stat . currentlevel
rollData . statDicesLevel = rollData . stat . currentlevel
2022-10-05 21:14:15 +02:00
}
rollData . statMod = rollData . stat . mod
if ( vehicle ) {
rollData . vehicle = duplicate ( vehicle )
if ( subKey == "melee-dmg" ) {
if ( vehicle . isVehicleFullStop ( ) ) {
ui . notifications . warn ( "MR not added to Melee Damage due to Full Stop." )
} else {
rollData . statVehicle = vehicle . system . statistics . mr
rollData . vehicleKey = "mr"
}
this . addVehicleWeapons ( rollData , vehicle )
}
if ( subKey == "ranged-atk" ) {
rollData . statVehicle = vehicle . system . statistics . fc
rollData . vehicleKey = "fc"
}
if ( subKey == "ranged-dmg" ) {
this . addVehicleWeapons ( rollData , vehicle )
}
if ( subKey == "defence" ) {
if ( vehicle . isVehicleFullStop ( ) ) {
ui . notifications . warn ( "MAN not added to Defense due to Full Stop." )
} else {
rollData . statVehicle = vehicle . system . statistics . man
rollData . vehicleKey = "man"
}
vehicle . addVehicleShields ( rollData )
}
vehicle . addEffects ( rollData , false , false , false )
}
rollData . specList = this . getRelevantSpec ( statKey )
rollData . selectedSpec = "0"
if ( statKey . toLowerCase ( ) == "mr" ) {
rollData . img = "systems/fvtt-pegasus-rpg/images/icons/MR.webp"
} else {
let abbrev = rollData . stat . abbrev . toUpperCase ( )
rollData . img = ` systems/fvtt-pegasus-rpg/images/icons/ ${ abbrev } .webp `
}
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-10-05 09:58:07 +02:00
}
2022-10-05 10:00:30 +02:00
}
2022-10-05 21:14:15 +02:00
if ( statKey == "mr" ) {
if ( this . type == "character" ) {
rollData . mrVehicle = PegasusUtility . checkIsVehicleCrew ( this . id )
if ( rollData . mrVehicle ) {
rollData . effectsList . push ( {
label : ` Vehicle ${ rollData . mrVehicle . name } MR Bonus ` ,
type : "effect" , applied : false , isdynamic : true , value : rollData . mrVehicle . system . statistics . mr . currentlevel
} )
}
}
if ( this . type == "vehicle" ) {
for ( let member of this . system . crew ) {
let actor = game . actors . get ( member . id )
let specList = actor . getRelevantSpec ( "mr" )
rollData . effectsList . push ( {
label : ` Crew ${ actor . name } MR Bonus ` ,
type : "effect" , applied : false , isdynamic : true , value : actor . system . mr . value + actor . system . mr . bonuseffect , specList : specList
} )
}
2022-10-05 09:58:07 +02:00
}
}
2022-10-05 21:14:15 +02:00
this . processSizeBonus ( rollData )
this . addEffects ( rollData , isInit , isPower , subKey == "power-dmg" )
this . addArmorsShields ( rollData , statKey , useShield , subKey )
this . addWeapons ( rollData , statKey , useShield )
this . addEquipments ( rollData , statKey )
2022-10-06 13:17:42 +02:00
this . processVehicleTargetMessage ( rollData )
2022-10-05 21:14:15 +02:00
console . log ( "ROLLDATA" , rollData )
2022-02-10 21:58:19 +01:00
2022-10-05 21:14:15 +02:00
return rollData
}
2022-01-28 10:05:54 +01:00
2022-10-05 21:14:15 +02:00
/* -------------------------------------------- */
processSizeBonus ( rollData ) {
if ( rollData . defenderTokenId ) {
2022-10-06 12:48:58 +02:00
let diffSize = 0
2022-10-06 13:17:42 +02:00
if ( this . type == "character" ) {
this . system . biodata . sizenum = this . system . biodata ? . sizenum ? ? 0
this . system . biodata . sizebonus = this . system . biodata ? . sizebonus ? ? 0
2022-10-06 12:48:58 +02:00
diffSize = rollData . defenderSize - this . system . biodata . sizenum + this . system . biodata . sizebonus
} else {
diffSize = rollData . defenderSize - this . system . statistics . hr . size
}
2022-10-05 21:14:15 +02:00
//console.log("Diffsize", diffSize)
if ( rollData . subKey == "melee-atk" || rollData . subKey == "ranged-atk" ) {
if ( diffSize > 0 ) {
rollData . effectsList . push ( { label : "Size Bonus" , type : "effect" , applied : false , isdynamic : true , value : diffSize } )
}
2022-10-03 10:01:41 +02:00
}
2022-10-05 21:14:15 +02:00
if ( rollData . subKey == "dmg-res" ) {
if ( diffSize < 0 ) {
rollData . effectsList . push ( { label : "Size Bonus" , type : "effect" , applied : false , isdynamic : true , value : Math . abs ( diffSize ) } )
}
2022-09-28 20:04:04 +02:00
}
2022-10-05 21:14:15 +02:00
if ( rollData . subKey == "defence" ) {
if ( diffSize > 0 ) {
rollData . effectsList . push ( { label : "Size Bonus" , type : "effect" , applied : false , isdynamic : true , value : Math . abs ( diffSize ) } )
}
2022-09-28 20:04:04 +02:00
}
2022-10-05 21:14:15 +02:00
if ( rollData . subKey == "melee-dmg" || rollData . subKey == "ranged-dmg" || rollData . subKey == "power-dmg" ) {
if ( diffSize < 0 ) {
rollData . effectsList . push ( { label : "Size Bonus" , type : "effect" , applied : false , isdynamic : true , value : Math . abs ( diffSize ) } )
}
2022-10-03 10:01:41 +02:00
}
2022-09-28 20:04:04 +02:00
}
}
2022-10-05 21:14:15 +02:00
/* -------------------------------------------- */
getLevelRemainingList ( ) {
let options = [ ]
for ( let i = 0 ; i <= this . system . biodata . maxlevelremaining ; i ++ ) {
options . push ( ` <option value=" ${ i } "> ${ i } </option> ` )
}
return options . join ( "\n" )
2022-07-13 22:47:07 +02:00
}
2022-10-05 21:14:15 +02:00
/* -------------------------------------------- */
getMaxLevelRemainingList ( ) {
let options = [ ]
for ( let i = 0 ; i <= 12 ; i ++ ) {
options . push ( ` <option value=" ${ i } "> ${ i } </option> ` )
}
return options . join ( "\n" )
2022-07-26 22:58:33 +02:00
}
2022-01-28 10:05:54 +01:00
/* -------------------------------------------- */
async startRoll ( rollData ) {
2022-10-05 21:14:15 +02:00
this . syncRoll ( rollData ) ;
//console.log("ROLL DATA", rollData)
let rollDialog = await PegasusRollDialog . create ( this , rollData )
console . log ( rollDialog )
rollDialog . render ( true ) ;
}
2022-01-28 10:05:54 +01:00
2022-10-05 21:14:15 +02:00
/* -------------------------------------------- */
powerDmgRoll ( itemId ) {
let power = this . items . get ( itemId )
if ( power ) {
power = duplicate ( power )
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-10-05 21:14:15 +02:00
/* -------------------------------------------- */
rollPool ( statKey , useShield = false , subKey = "none" , vehicle = undefined ) {
let stat = this . getStat ( statKey )
if ( stat ) {
let rollData = this . getCommonRollData ( statKey , useShield , false , false , subKey , vehicle )
rollData . mode = "stat"
rollData . subKey = subKey
let def = stat . label
if ( subKey ) {
def = _ _subkey2title [ subKey ]
}
rollData . title = ` Roll : ${ def } `
rollData . img = "icons/dice/d12black.svg"
this . startRoll ( rollData )
} else {
ui . notifications . warn ( "Statistic not found !" ) ;
2022-01-28 10:05:54 +01:00
}
}
2022-10-05 21:14:15 +02:00
/* -------------------------------------------- */
rollUnarmedAttack ( ) {
let stat = this . getStat ( 'com' )
if ( stat ) {
let rollData = this . getCommonRollData ( statKey )
rollData . mode = "stat"
rollData . title = ` Unarmed Attack ` ;
rollData . damages = this . getStat ( 'str' ) ;
this . startRoll ( rollData ) ;
} else {
ui . notifications . warn ( "Statistic not found !" ) ;
}
2022-01-28 10:05:54 +01:00
}
2022-10-05 21:14:15 +02:00
/*-------------------------------------------- */
rollStat ( statKey ) {
2022-10-06 12:22:29 +02:00
let stat = this . getStat ( statKey )
2022-10-05 21:14:15 +02:00
if ( stat ) {
let rollData = this . getCommonRollData ( statKey )
rollData . mode = "stat"
rollData . title = ` Stat ${ stat . label } ` ;
2021-12-02 07:38:59 +01:00
2022-10-05 21:14:15 +02:00
this . startRoll ( rollData )
} else {
ui . notifications . warn ( "Statistic not found !" ) ;
}
2022-01-28 10:05:54 +01:00
}
2021-12-02 07:38:59 +01:00
2022-01-28 10:05:54 +01:00
/* -------------------------------------------- */
async rollSpec ( specId ) {
2022-10-05 21:14:15 +02:00
let spec = this . getOneSpec ( specId )
if ( spec ) {
let rollData = this . getCommonRollData ( spec . system . statistic )
rollData . mode = "spec"
rollData . title = ` Spec. : ${ spec . name } `
rollData . specList = [ spec ]
rollData . selectedSpec = spec . _id
rollData . specName = spec . name
rollData . img = spec . img
rollData . specDicesLevel = spec . system . level
PegasusUtility . updateSpecDicePool ( rollData )
this . startRoll ( rollData )
} else {
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-10-03 10:01:41 +02:00
2022-10-05 21:14:15 +02:00
let mr = duplicate ( ( this . type == "vehicle" ) ? this . system . statistics . mr : this . system . mr )
if ( mr ) {
mr . dice = PegasusUtility . getDiceFromLevel ( mr . value ) ;
2022-01-28 10:05:54 +01:00
2022-10-05 21:14:15 +02:00
let rollData = this . getCommonRollData ( "mr" , false , isInit )
rollData . mode = "MR"
rollData . img = "systems/fvtt-pegasus-rpg/images/icons/MR.webp"
rollData . isInit = isInit
rollData . combatId = combatId
rollData . combatantId = combatantId
console . log ( "MR ROLL" , rollData )
if ( isInit ) {
rollData . title = "MR / Initiative"
}
this . startRoll ( rollData ) ;
} else {
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-10-05 21:14:15 +02:00
let armor = this . items . get ( armorId )
2022-01-14 18:20:15 +01:00
2022-10-05 21:14:15 +02:00
if ( armor ) {
let rollData = this . getCommonRollData ( armor . system . statistic )
2022-01-14 18:20:15 +01:00
2022-10-05 21:14:15 +02:00
armor = duplicate ( armor ) ;
this . checkAndPrepareEquipment ( armor ) ;
2022-01-14 18:20:15 +01:00
2022-10-05 21:14:15 +02:00
rollData . mode = "armor"
rollData . armor = armor
rollData . title = ` Armor : ${ armor . name } `
rollData . isResistance = true ;
rollData . img = armor . img
rollData . damageDiceLevel = armor . system . resistance
2022-01-14 18:20:15 +01:00
2022-10-05 21:14:15 +02:00
this . startRoll ( rollData ) ;
} else {
ui . notifications . warn ( "Armor not found !" , weaponId ) ;
}
2022-01-14 18:20:15 +01:00
}
2022-01-14 14:49:16 +01:00
2022-01-14 18:20:15 +01:00
/* -------------------------------------------- */
async rollPower ( powerId ) {
2022-10-05 21:14:15 +02:00
let power = this . items . get ( powerId )
2022-01-14 18:20:15 +01:00
2022-10-05 21:14:15 +02:00
if ( power ) {
power = duplicate ( power )
let rollData = this . getCommonRollData ( power . system . statistic , false , false , true )
2022-01-14 18:20:15 +01:00
2022-10-05 21:14:15 +02:00
rollData . mode = "power"
rollData . power = power
rollData . title = ` Power : ${ power . name } `
rollData . img = power . img
2022-03-06 20:07:41 +01:00
2022-10-05 21:14:15 +02:00
this . startRoll ( rollData ) ;
} else {
ui . notifications . warn ( "Power not found !" , powerId ) ;
}
2022-01-14 18:20:15 +01:00
}
2022-09-09 08:33:28 +02:00
/* -------------------------------------------- */
/* VEHICLE STUFF */
2022-09-25 15:13:59 +02:00
async manageCurrentSpeed ( speed ) {
2022-10-05 21:14:15 +02:00
// Delete any previous effect
let effect = this . items . find ( effect => effect . system . isspeed != undefined )
if ( effect ) {
await this . deleteEmbeddedDocuments ( "Item" , [ effect . id ] )
}
2022-09-09 08:33:28 +02:00
2022-10-05 21:14:15 +02:00
if ( speed == "fullstop" ) {
this . update ( { 'system.secondary.moverange' : "nomovement" } )
}
if ( speed == "crawling" ) {
await this . update ( { 'system.secondary.moverange' : "threatzone" } )
await this . manageVehicleSpeedBonus ( "crawling" , "Crawling MAN Bonus" , "man" , 3 )
}
if ( speed == "slow" ) {
await this . update ( { 'system.secondary.moverange' : "close" } )
await this . manageVehicleSpeedBonus ( "slow" , "Slow MAN Bonus" , "man" , 1 )
}
if ( speed == "average" ) {
await this . update ( { 'system.secondary.moverange' : "medium" } )
await this . manageVehicleSpeedBonus ( "average" , "Avoid attack Bonus" , "all" , 1 )
}
if ( speed == "fast" ) {
await this . update ( { 'system.secondary.moverange' : "long" } )
await this . manageVehicleSpeedBonus ( "fast" , "Avoid attack Bonus" , "all" , 3 )
}
if ( speed == "extfast" ) {
await this . update ( { 'system.secondary.moverange' : "extreme" } )
await this . manageVehicleSpeedBonus ( "extfast" , "Avoid attack Bonus" , "all" , 5 )
}
2022-10-05 10:00:30 +02:00
}
2022-10-05 21:14:15 +02:00
/* -------------------------------------------- */
modifyVehicleStun ( incDec ) {
let stun = this . system . stun . value + incDec
this . update ( { 'system.stun.value' : stun } )
}
2022-10-05 10:00:30 +02:00
2022-10-05 21:14:15 +02:00
/* -------------------------------------------- */
addTopSpeedBonus ( topspeed , bonus ) {
let num = _ _speed2Num [ topspeed ] + Number ( bonus )
num = Math . max ( 0 , num )
num = Math . min ( num , _ _num2speed . length - 1 )
return _ _num2speed [ num ]
}
2022-09-16 17:36:58 +02:00
2022-09-25 09:26:12 +02:00
/* -------------------------------------------- */
2022-09-25 15:13:59 +02:00
async manageVehicleSpeedBonus ( speed , name , stat , level ) {
2022-10-05 21:14:15 +02:00
let effect = duplicate ( _ _bonusEffect )
effect . id = randomID ( 16 )
effect . name = name
effect . system . stataffected = stat
effect . system . effectlevel = level
effect . system . isspeed = speed
await this . createEmbeddedDocuments ( "Item" , [ effect ] )
}
/* -------------------------------------------- */
processVehicleStatEffects ( ) {
2022-10-07 17:45:53 +02:00
let effectsPlus = this . items . filter ( effect => effect . type == "effect" && effect . system . genre == "positive" && effect . system . statdice )
let effectsMinus = this . items . filter ( effect => effect . type == "effect" && effect . system . genre == "negative" && effect . system . reducedicevalue )
2022-10-05 21:14:15 +02:00
for ( let statKey in this . system . statistics ) {
let stat = duplicate ( this . system . statistics [ statKey ] )
2022-10-07 17:50:28 +02:00
let bonus = 0
2022-10-07 17:45:53 +02:00
for ( let effect of effectsPlus ) {
2022-10-05 21:14:15 +02:00
if ( effect . system . stataffected == statKey ) {
bonus += Number ( effect . system . effectlevel )
}
}
2022-10-07 17:45:53 +02:00
for ( let effect of effectsMinus ) {
if ( effect . system . stataffected == statKey ) {
bonus -= Number ( effect . system . effectlevel )
}
}
2022-10-05 21:14:15 +02:00
if ( bonus != stat . bonuseffect ) {
stat . bonuseffect = bonus
2022-10-07 17:50:28 +02:00
if ( stat . bonuseffect + stat . level < 1 ) {
stat . level = 1
stat . bonuseffect = 0
}
2022-10-07 17:45:53 +02:00
if ( stat . currentlevel > stat . bonuseffect + stat . level ) {
stat . currentlevel = stat . bonuseffect + stat . level
}
2022-10-05 21:14:15 +02:00
this . update ( { [ ` system.statistics. ${ statKey } ` ] : stat } )
2022-10-07 17:45:53 +02:00
}
2022-10-05 21:14:15 +02:00
}
}
2022-10-06 13:17:42 +02:00
2022-09-16 17:36:58 +02:00
/* -------------------------------------------- */
async computeVehicleStats ( ) {
2022-10-05 21:14:15 +02:00
if ( this . type == "vehicle" ) {
2022-09-16 17:36:58 +02:00
2022-10-05 21:14:15 +02:00
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 ) )
2022-09-16 17:36:58 +02:00
}
2022-10-05 21:14:15 +02:00
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)
if ( statDef . subfield ) {
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])
this . update ( { [ ` system.statistics. ${ statDef . field } . ${ statDef . subfield } ` ] : sum } )
2022-10-05 10:00:30 +02:00
}
2022-10-05 21:14:15 +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 } )
if ( statDef . additionnal1 ) {
if ( sum != Number ( this . system . statistics [ statDef . field ] [ statDef . additionnal1 ] ) ) {
this . update ( { [ ` system.statistics. ${ statDef . field } . ${ statDef . additionnal1 } ` ] : sum } )
}
}
if ( statDef . additionnal2 ) {
if ( sum != Number ( this . system . statistics [ statDef . field ] [ statDef . additionnal2 ] ) ) {
this . update ( { [ ` system.statistics. ${ statDef . field } . ${ statDef . additionnal2 } ` ] : sum } )
}
2022-09-25 09:26:12 +02:00
}
2022-09-16 17:36:58 +02:00
}
}
}
2022-10-05 21:14:15 +02:00
// Top speed management
let mobility = this . items . find ( item => item . type == "mobilitymodule" )
let arcs = duplicate ( this . system . arcs )
if ( mobility ) {
let propulsion = this . items . find ( item => item . type == "propulsionmodule" )
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
arcs . reararc . topspeed = mobility . system . ts _r
} else {
arcs . frontarc . topspeed = "fullstop"
arcs . rightarc . topspeed = "fullstop"
arcs . leftarc . topspeed = "fullstop"
arcs . toparc . topspeed = "fullstop"
arcs . bottomarc . topspeed = "fullstop"
arcs . reararc . topspeed = "fullstop"
}
for ( let key in this . system . arcs ) {
if ( this . system . arcs [ key ] . topspeed != arcs [ key ] . topspeed ) {
this . update ( { 'system.arcs' : arcs } )
}
2022-09-16 17:36:58 +02:00
}
2022-09-25 09:26:12 +02:00
2022-10-05 21:14:15 +02:00
// VMS management
let hull = this . items . find ( item => item . type == "vehiclehull" )
let modules = duplicate ( this . system . modules )
if ( hull ) {
modules . totalvms = Number ( hull . system . vms )
} else {
modules . totalvms = 0
}
let spaceList = this . items . filter ( item => item . type == "vehiclemodule" ) || [ ]
spaceList = spaceList . concat ( this . items . filter ( item => item . type == "vehicleweaponmodule" ) || [ ] )
let space = 0
if ( spaceList && spaceList . length > 0 ) {
space = spaceList . reduce ( ( value , item2 ) => value + Number ( item2 . system . space ) , 0 )
}
modules . vmsused = space
if ( modules . totalvms != this . system . modules . totalvms || modules . usedvms != this . system . modules . vmsused ) {
this . update ( { 'system.modules' : modules } )
}
if ( modules . vmsused > modules . totalvms ) {
ui . notifications . warn ( "Warning! No more space available in cargo !!" )
}
2022-09-16 17:36:58 +02:00
2022-10-05 21:14:15 +02:00
// Destroyed
if ( this . system . statistics . hr . currentlevel == 0 ) {
ChatMessage . create ( { content : ` The vehicle ${ this . name } has been destroyed ! ` } )
}
this . processVehicleArmorShields ( )
this . processVehicleStatEffects ( )
2022-09-16 17:36:58 +02:00
}
}
2022-10-05 21:14:15 +02:00
/* -------------------------------------------- */
getTotalCost ( ) {
let sumCost = 0
for ( let item of this . items ) {
if ( _ _isVehicle [ item . type ] ) {
if ( item . system . cost ) {
sumCost += Number ( item . system . cost )
}
2022-09-18 17:30:15 +02:00
}
}
2022-10-05 21:14:15 +02:00
return sumCost
2022-09-18 17:30:15 +02:00
}
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-10-05 21:14:15 +02:00
if ( item . type != "effect" && ! _ _isVehicle [ item . type ] ) {
ui . notifications . warn ( "You can't drop Character items over a vehicle sheet." )
return
}
2022-09-18 17:30:15 +02:00
2022-10-06 13:17:42 +02:00
if ( item . type == "effect" && item . system . droptext && item . system . droptext . length > 0 ) {
ChatMessage . create ( { content : ` Effect ${ item . name } message : ${ item . system . droptext } ` } )
2022-10-06 12:38:31 +02:00
}
2022-10-05 21:14:15 +02:00
//console.log(">>>>> item", item.type, __isVehicleUnique[item.type])
if ( _ _isVehicleUnique [ item . type ] ) {
let toDelList = [ ]
for ( let toDel of this . items ) {
if ( toDel . type == item . type ) {
toDelList . push ( toDel . id )
}
}
//console.log("TODEL : ", toDelList)
if ( toDelList . length > 0 ) {
await this . deleteEmbeddedDocuments ( 'Item' , toDelList )
2022-09-16 17:36:58 +02:00
}
}
2022-10-05 21:14:15 +02:00
// Check size
if ( item . type == "vehiclemodule" || item . type == "vehicleweaponmodule" ) {
item . system . space = item . system ? . space || 0
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. ` } )
return false
}
2022-09-18 17:30:15 +02:00
}
2022-10-07 16:51:03 +02:00
// NRG max management
if ( item . type == "powercoremodule" ) {
if ( this . system . statistics . pc . maxnrg != item . system . nrg ) {
this . update ( { 'system.statistics.pc.maxnrg' : item . system . nrg } )
}
}
2022-10-05 21:14:15 +02:00
// Cargo management
if ( _ _isVehicleCargo [ item . type ] ) {
let capacity = this . getCurrentCargoCapacity ( )
if ( item . type == "cargo" ) {
capacity += Number ( item . system . capacity )
} else {
let q = item . system . quantity || 1
capacity += Number ( q ) * Number ( item . system . weight )
}
console . log ( "capa" , capacity , this . system . cargo . cargocapacity )
if ( capacity > this . system . cargo . cargocapacity ) {
ui . notifications . warn ( "Your cargo capacity is already full, unable to add this content : " + item . name )
return false
}
2022-09-26 18:42:13 +02:00
}
2022-10-05 21:14:15 +02:00
return true
2022-09-16 17:36:58 +02:00
}
2022-10-05 21:14:15 +02:00
/* -------------------------------------------- */
getCrewList ( ) {
let crew = [ ]
for ( let actorDef of this . system . crew ) {
let actor = game . actors . get ( actorDef . id )
if ( actor ) {
crew . push ( { name : actor . name , img : actor . img , id : actor . id } )
}
2022-09-21 16:54:34 +02:00
}
2022-10-05 21:14:15 +02:00
return crew
2022-09-21 16:54:34 +02:00
}
2022-10-05 21:14:15 +02:00
addCrew ( actorId ) {
if ( this . system . crew . length >= this . system . crewmax ) {
ui . notifications . warn ( "Vehicle crew is already full." )
return
2022-09-25 15:13:59 +02:00
}
2022-10-05 21:14:15 +02:00
let crewList = duplicate ( this . system . crew . filter ( actorDef => actorDef . id != actorId ) || [ ] )
crewList . push ( { id : actorId } )
this . update ( { 'system.crew' : crewList } )
2022-10-05 09:40:34 +02:00
}
2022-10-05 21:14:15 +02:00
delCrew ( actorId ) {
let crewList = duplicate ( this . system . crew . filter ( actorDef => actorDef . id != actorId ) || [ ] )
this . update ( { 'system.crew' : crewList } )
}
inCrew ( actorId ) {
return this . system . crew . find ( member => member . id == actorId )
2022-09-25 09:26:12 +02:00
}
2022-10-05 21:14:15 +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"
}
2022-09-25 09:26:12 +02:00
2022-10-05 21:14:15 +02:00
/* -------------------------------------------- */
isValidActor ( ) {
// Find relevant actor
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-25 09:26:12 +02:00
}
2022-10-05 21:14:15 +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
2022-10-05 21:14:15 +02:00
}
2022-09-25 09:26:12 +02:00
}
2022-10-05 21:14:15 +02:00
/* -------------------------------------------- */
rollPoolFromVehicle ( statKey , useShield = false , subKey = "none" ) {
let actor = this . isValidActor ( )
if ( actor ) {
actor . rollPool ( statKey , useShield , subKey , this )
}
2022-09-25 09:26:12 +02:00
}
2022-10-05 21:14:15 +02:00
/* -------------------------------------------- */
addVehicleShields ( rollData ) {
for ( let arcKey in this . system . arcs ) {
let arc = this . system . arcs [ arcKey ]
if ( arc . shieldlevel > 0 ) {
rollData . vehicleShieldList . push ( { label : ` ${ arc . label } Shield ` , type : "vehicleshield" , applied : false , value : arc . shieldlevel } )
}
2022-09-27 16:56:59 +02:00
}
}
2022-10-05 21:14:15 +02:00
/* -------------------------------------------- */
addVehicleArmors ( rollData ) {
for ( let arcKey in this . system . arcs ) {
let arc = this . system . arcs [ arcKey ]
if ( arc . armourlevel > 0 ) {
rollData . vehicleShieldList . push ( { label : ` ${ arc . label } Armor ` , type : "vehicleshield" , applied : false , value : arc . armourlevel } )
}
2022-09-25 09:26:12 +02:00
}
}
2022-10-05 10:00:30 +02:00
2022-10-05 21:14:15 +02:00
/* -------------------------------------------- */
rollVehicleDamageResistance ( ) {
let actor = this . isValidActor ( )
if ( actor ) {
let stat = this . getStat ( "hr" )
let rollData = this . getCommonRollData ( "hr" )
rollData . vehicle = duplicate ( this )
rollData . isVehicleStun = true
rollData . mode = "stat"
rollData . title = ` Stat ${ stat . label } `
this . addVehicleArmors ( rollData )
this . startRoll ( rollData )
}
2022-10-05 10:00:30 +02:00
}
2022-09-25 09:26:12 +02:00
2022-10-06 19:04:53 +02:00
/* -------------------------------------------- */
async addVehicleModuleEffects ( mod ) {
let effects = [ ]
for ( let effect of mod . system . effects ) {
if ( ! effect . system ) {
effect . system = effect . data
}
effect . system . effectId = mod . id // Link to the perk, in order to dynamically remove them
effects . push ( effect )
}
if ( effects . length ) {
await this . createEmbeddedDocuments ( 'Item' , effects )
}
}
/* -------------------------------------------- */
async removeVehicleModuleEffects ( mod ) {
let toRem = [ ]
for ( let item of this . items ) {
if ( item . type == 'effect' && item . system . effectId == mod . id ) {
toRem . push ( item . id )
}
}
console . log ( "TODEL" , toRem )
if ( toRem . length ) {
await this . deleteEmbeddedDocuments ( 'Item' , toRem )
}
}
2022-09-25 09:26:12 +02:00
/* -------------------------------------------- */
2022-09-28 13:43:36 +02:00
async activateVehicleModule ( itemId ) {
2022-10-05 21:14:15 +02:00
let mod = this . items . get ( itemId )
if ( mod ) {
if ( mod . system . nrg && mod . system . nrg > 0 ) {
let pc = duplicate ( this . system . statistics . pc )
if ( ! mod . system . activated ) { // Previous state was non activated -> activated now
if ( mod . system . nrg > pc . curnrg ) {
ChatMessage . create ( { content : ` The Vehicle ${ this . name } does not have enough Energy to Activate this module at this time. ` } )
return
}
await this . updateEmbeddedDocuments ( 'Item' , [ { _id : mod . id , 'system.activated' : ! mod . system . activated } ] )
pc . actnrg += Number ( mod . system . nrg )
pc . maxnrg -= Number ( mod . system . nrg )
pc . curnrg -= Number ( mod . system . nrg )
this . update ( { 'system.statistics.pc' : pc } )
2022-10-06 19:04:53 +02:00
this . addVehicleModuleEffects ( mod )
2022-10-05 21:14:15 +02:00
} else { // Now deactivated
pc . actnrg -= Number ( mod . system . nrg )
pc . maxnrg += Number ( mod . system . nrg )
this . update ( { 'system.statistics.pc' : pc } )
await this . updateEmbeddedDocuments ( 'Item' , [ { _id : mod . id , 'system.activated' : ! mod . system . activated } ] )
2022-10-06 19:04:53 +02:00
this . removeVehicleModuleEffects ( mod )
2022-09-27 14:16:11 +02:00
}
2022-10-05 21:14:15 +02:00
} else {
2022-10-06 19:04:53 +02:00
if ( mod . system . activated ) {
this . removeVehicleModuleEffects ( mod )
} else {
this . addVehicleModuleEffects ( mod )
}
2022-09-28 13:43:36 +02:00
await this . updateEmbeddedDocuments ( 'Item' , [ { _id : mod . id , 'system.activated' : ! mod . system . activated } ] )
}
}
2022-09-28 13:48:50 +02:00
2022-10-05 21:14:15 +02:00
this . processVehicleArmorShields ( )
}
2022-10-05 10:00:30 +02:00
2022-10-05 21:14:15 +02:00
/* -------------------------------------------- */
processVehicleArmorShields ( ) {
// Shield management
let shieldsList = this . items . filter ( item => item . type == "vehiclemodule" && item . system . category == "shield" && item . system . activated ) || [ ]
2022-09-28 13:43:36 +02:00
let level = 0
2022-10-05 21:14:15 +02:00
for ( let armour of shieldsList ) {
if ( armour . system . shielddicevalue > 0 ) {
level += Number ( armour . system . shielddicevalue )
2022-09-27 14:16:11 +02:00
}
2022-09-21 16:54:34 +02:00
}
2022-10-05 21:14:15 +02:00
let shift = 500
for ( let loc of _ _LocationsArmour ) {
let arcKey = loc + "arc"
let arc = duplicate ( this . system . arcs [ arcKey ] )
2022-10-06 18:48:45 +02:00
if ( level != Number ( arc . maxshieldlevel ) ) {
let lvChanged = level - arc . maxshieldlevel
arc . maxshieldlevel = level
arc . shieldlevel += lvChanged
if ( arc . shieldlevel <= 0 || arc . shieldlevel > level ) {
arc . shieldlevel = level
}
2022-10-05 21:14:15 +02:00
setTimeout ( shift , this . update ( { [ ` system.arcs. ${ arcKey } ` ] : arc } ) )
shift += 200
}
2022-09-28 13:48:50 +02:00
}
2022-09-26 20:57:55 +02:00
2022-10-05 21:14:15 +02:00
// Armour management
let armorsList = this . items . filter ( item => item . type == "vehiclemodule" && item . system . category == "armor" && item . system . activated ) || [ ]
for ( let loc of _ _LocationsArmour ) {
let arcKey = loc + "arc"
let arc = duplicate ( this . system . arcs [ arcKey ] )
let level = 0
for ( let armour of armorsList ) {
if ( armour . system . location == loc && armour . system . armourdicevalue > 0 ) {
level += Number ( armour . system . armourdicevalue )
}
}
2022-10-06 18:48:45 +02:00
if ( level != Number ( arc . maxarmourlevel ) ) {
let lvChanged = level - arc . maxarmourlevel
arc . maxarmourlevel = level
arc . armourlevel += lvChanged
if ( arc . armourlevel <= 0 || arc . armourlevel > arc . maxarmourlevel ) {
arc . armourlevel = level
}
2022-10-05 21:14:15 +02:00
setTimeout ( 500 , this . update ( { [ ` system.arcs. ${ arcKey } ` ] : arc } ) )
}
2022-10-05 10:00:30 +02:00
}
2022-10-05 21:14:15 +02:00
}
/* -------------------------------------------- */
updateMaxNrg ( currentLevel ) {
2022-10-06 20:18:51 +02:00
this . update ( { 'system.statistics.pc.maxnrg' : Number ( PegasusUtility . getDiceValue ( currentLevel ) ) } )
2022-10-05 21:14:15 +02:00
}
/* -------------------------------------------- */
setTurningArc ( currentLevel ) {
this . update ( { 'system.statistics.man.turningarc45' : Number ( currentLevel ) } )
}
/* -------------------------------------------- */
getCurrentCargoCapacity ( ) {
let capacity = 0
for ( let cargo of this . items ) {
if ( cargo . type == "equipment" || cargo . type == "weapon" || cargo . type == "armor" || cargo . type == "money" || cargo . type == "shield" ) {
let q = cargo . system . quantity || 1
capacity += Number ( q ) * Number ( cargo . system . weight )
}
if ( cargo . type == "cargo" ) {
capacity += Number ( cargo . system . capacity )
}
2022-09-25 15:48:11 +02:00
}
2022-10-05 21:14:15 +02:00
return capacity
2022-09-25 15:48:11 +02:00
}
2022-09-27 16:45:07 +02:00
2021-12-02 07:38:59 +01:00
}