bol/module/actor/actor.js

1125 lines
38 KiB
JavaScript
Raw Normal View History

2023-06-23 08:37:50 +02:00
import { BoLDefaultRoll, BoLRoll } from "../controllers/bol-rolls.js";
2022-02-18 22:15:46 +01:00
import { BoLUtility } from "../system/bol-utility.js";
2022-01-16 22:06:49 +01:00
2021-07-08 10:12:12 +02:00
/**
* Extend the base Actor entity by defining a custom roll data structure which is ideal for the Simple system.
* @extends {Actor}
*/
export class BoLActor extends Actor {
2022-03-21 23:21:05 +01:00
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;
}
2024-11-02 18:29:22 +01:00
if (data.type == 'encounter') {
data.system = { resources: { hero : { max : 0, value: 0 } } }
}
if (data.type == 'horde') {
let weapon = {
name: game.i18n.localize("BOL.ui.hordeAttack"), type: "item",
img: "ui/icons/attaque_melee.webp",
system: foundry.utils.duplicate(game.bol.config.defaultNaturalWeapon)
}
weapon.system.properties.attackModifiers = 1
weapon.system.properties.damage = "1d6M"
2024-09-12 22:43:09 +02:00
data.items = [weapon]
data.img = "systems/bol/ui/icons/icon-horde-token.webp"
data.prototypeToken = { texture: "systems/bol/ui/icons/icon-horde-token.webp" }
}
return super.create(data, options);
}
2021-07-08 10:12:12 +02:00
/** @override */
prepareData() {
2022-02-23 20:39:58 +01:00
2022-07-01 15:48:54 +02:00
if (this.type === 'character') {
2022-07-01 16:30:21 +02:00
this.chartype = 'player'
this.villainy = false
2022-01-08 23:28:16 +01:00
}
2022-07-01 15:48:54 +02:00
if (this.type === 'encounter') {
2022-07-01 16:30:21 +02:00
this.chartype = 'tough'
this.villainy = true
2021-11-01 22:23:43 +01:00
}
2024-11-02 18:29:22 +01:00
if (this.type === 'creature') {
this.villainy = true
}
if (this.type == "horde") {
let weapon = this.items.find(i => i.type === "item" && i.system.subtype === "weapon")
// Check if the horde attack is inline with the hordesize
if (weapon?.system?.properties?.attackModifiers != this.system.hordesize) {
this.updateEmbeddedDocuments('Item', [{ _id: weapon.id, 'system.properties.attackModifiers': this.system.hordesize }])
}
}
2022-07-01 16:30:21 +02:00
super.prepareData()
}
/* -------------------------------------------- */
async _onCreateOperation(documents, operation, user) {
await super._onCreateOperation(documents, operation, user);
}
/* -------------------------------------------- */
getTokenSizeFromHordeSize(hordeSize) {
hordeSize = hordeSize || this.system.hordesize
// If size > 50 then max is 50
let size = Math.min(hordeSize, 20)
// Compute the size of the token from 1 to 5
let tokenSize = Math.max((size / 4), 1) // Never below 1
return tokenSize
}
2022-07-01 16:30:21 +02:00
2023-08-26 19:00:25 +02:00
/* -------------------------------------------- */
async _preCreate(data, options, user) {
await super._preCreate(data, options, user);
// Configure prototype token settings
const prototypeToken = {};
2024-09-12 22:43:09 +02:00
if (this.type === "character") {
Object.assign(prototypeToken, {
sight: { enabled: true }, actorLink: true, disposition: CONST.TOKEN_DISPOSITIONS.FRIENDLY
});
this.updateSource({ prototypeToken });
}
2023-08-26 19:00:25 +02:00
}
2023-04-04 13:41:22 +02:00
/* -------------------------------------------- */
isHeroAdversary() {
if (this.type === 'character') {
return true
}
return (this.type === 'encounter' && this.chartype == "adversary")
2023-04-04 13:41:22 +02:00
}
2022-07-01 16:30:21 +02:00
/* -------------------------------------------- */
getCharType() {
if (this.type === 'character') {
2022-12-23 23:24:09 +01:00
return "player"
2022-07-01 16:30:21 +02:00
}
2022-08-31 22:46:19 +02:00
return this.system.chartype
2022-07-01 16:30:21 +02:00
}
2022-07-01 16:30:21 +02:00
/* -------------------------------------------- */
getVillainy() {
2024-11-02 18:29:22 +01:00
return ( (this.type === 'encounter' && this.chartype == "adversary") || this.chartype == "creature")
}
isUndead() {
return (this.type == "encounter" && this.system.isundead)
2021-07-08 10:12:12 +02:00
}
2023-05-01 18:50:32 +02:00
/* -------------------------------------------- */
getInitiativeMalus() {
2023-09-16 09:40:08 +02:00
if (this.type === 'encounter' && (this.chartype == "adversary" || this.chartype == "tough")) {
2023-05-01 18:50:32 +02:00
return this.system.aptitudes.init.value
}
return 0
}
2022-11-29 15:23:05 +01:00
/* -------------------------------------------- */
getBougette() {
2023-03-18 10:24:30 +01:00
if (this.type == "character") {
let b = foundry.utils.duplicate(this.system.bougette)
2023-03-18 10:24:30 +01:00
b.label = game.i18n.localize(game.bol.config.bougetteState[String(this.system.bougette.value)])
b.diceImg = "icons/dice/" + game.bol.config.bougetteDice[String(this.system.bougette.value)] + "black.svg"
2022-12-04 13:48:37 +01:00
return b
}
return undefined
2022-11-29 15:23:05 +01:00
}
2022-12-04 13:48:37 +01:00
2022-11-29 15:23:05 +01:00
/* -------------------------------------------- */
async rollBougette() {
2023-03-18 10:24:30 +01:00
if (this.type == "character") {
let attribute = foundry.utils.duplicate(this.system.attributes.vigor)
2023-03-18 10:24:30 +01:00
let rollData = BoLRoll.getCommonRollData(this, "bougette", attribute, undefined)
2022-12-04 13:48:37 +01:00
rollData.formula = game.bol.config.bougetteDice[String(this.system.bougette.value)]
let r = new BoLDefaultRoll(rollData)
r.roll()
}
2022-11-29 15:23:05 +01:00
}
2022-12-04 13:48:37 +01:00
2022-11-29 15:23:05 +01:00
/* -------------------------------------------- */
decBougette() {
2023-03-18 10:24:30 +01:00
if (this.type == "character") {
let bougette = foundry.utils.duplicate(this.system.bougette)
2023-03-18 10:24:30 +01:00
bougette.value = Math.max(Number(bougette.value) - 1, 0)
this.update({ 'system.bougette': bougette })
2022-12-04 13:48:37 +01:00
}
2022-11-29 15:23:05 +01:00
}
2023-03-18 10:24:30 +01:00
2022-01-03 00:09:27 +01:00
/* -------------------------------------------- */
2022-03-21 23:21:05 +01:00
updateResourcesData() {
if (this.type == 'character') {
2022-07-01 15:48:54 +02:00
let newVitality = 10 + this.system.attributes.vigor.value + this.system.resources.hp.bonus
if (this.system.resources.hp.max != newVitality) {
2023-04-06 20:15:04 +02:00
let actor = this
2023-09-16 09:40:08 +02:00
setTimeout(function () { actor.update({ 'system.resources.hp.max': newVitality }) }, 800)
2022-01-08 23:28:16 +01:00
}
2022-07-01 15:48:54 +02:00
let newPower = 10 + this.system.attributes.mind.value + this.system.resources.power.bonus
if (this.system.resources.power.max != newPower) {
2023-04-06 20:15:04 +02:00
let actor = this
2023-09-16 09:40:08 +02:00
setTimeout(function () { actor.update({ 'system.resources.power.max': newPower }) }, 800)
2022-01-08 23:28:16 +01:00
}
2021-11-01 22:23:43 +01:00
}
}
2021-12-29 19:15:06 +01:00
/* -------------------------------------------- */
2022-01-03 00:09:27 +01:00
prepareDerivedData() {
if (this.type == "vehicle") {
} else {
super.prepareDerivedData()
2023-04-06 20:15:04 +02:00
if (this.id) {
this.updateResourcesData()
2023-09-16 09:40:08 +02:00
this.manageHealthState()
2023-04-06 20:15:04 +02:00
}
}
2021-12-29 19:15:06 +01:00
}
2022-01-03 00:09:27 +01:00
2021-11-01 00:28:42 +01:00
/* -------------------------------------------- */
2021-11-08 14:40:29 +01:00
get details() {
2022-07-01 15:48:54 +02:00
return this.system.details
2021-11-01 00:28:42 +01:00
}
2023-09-16 09:40:08 +02:00
addEffectModifiers(myList, dataPath) {
2023-04-06 20:15:04 +02:00
for (let attr of myList) {
attr.numModifier = 0
attr.diceModifier = ""
2023-09-16 09:40:08 +02:00
let effects = this.items.filter(i => i.type === "feature" && i.system.subtype === "boleffect" && i.system.properties.identifier == dataPath + attr.key)
2023-04-06 20:15:04 +02:00
for (let effect of effects) {
2023-09-16 09:40:08 +02:00
if (Number(effect.system.properties.modifier)) {
2023-04-06 20:15:04 +02:00
attr.numModifier += Number(effect.system.properties.modifier)
} else {
2023-09-16 09:40:08 +02:00
attr.diceModifier += "+" + effect.system.properties.modifier
2023-04-06 20:15:04 +02:00
}
}
}
}
2021-11-08 14:40:29 +01:00
get attributes() {
let attrList = foundry.utils.duplicate(Object.values(this.system.attributes))
2023-04-06 20:15:04 +02:00
this.addEffectModifiers(attrList, "system.attributes.")
return attrList
2021-11-08 14:40:29 +01:00
}
get aptitudes() {
2023-04-06 20:15:04 +02:00
let aptList = Object.values(this.system.aptitudes)
this.addEffectModifiers(aptList, "system.aptitudes.")
return aptList
2021-11-08 14:40:29 +01:00
}
2022-03-10 21:39:12 +01:00
/* -------------------------------------------- */
2022-03-21 23:21:05 +01:00
clearRoundModifiers() { // Process data/items that are finished at end of a round
2022-03-10 21:39:12 +01:00
let foList = this.fightoptions
2022-03-21 23:21:05 +01:00
for (let fo of foList) {
2022-07-01 15:48:54 +02:00
if (fo.system.properties.used) {
this.updateEmbeddedDocuments("Item", [{ _id: fo._id, 'system.properties.used': false }])
2022-03-10 21:39:12 +01:00
}
}
}
2022-03-10 21:05:53 +01:00
/* -------------------------------------------- */
2021-12-25 23:26:27 +01:00
get defenseValue() {
2022-03-10 21:05:53 +01:00
let defMod = 0
let fo = this.getActiveFightOption()
2022-07-01 15:48:54 +02:00
if (fo && fo.system.properties.fightoptiontype == "intrepid") {
2022-03-10 21:05:53 +01:00
defMod += -2
}
2022-07-01 15:48:54 +02:00
if (fo && fo.system.properties.fightoptiontype == "fulldefense") {
2022-03-10 21:05:53 +01:00
defMod += 2
}
2022-07-01 15:48:54 +02:00
if (fo && fo.system.properties.fightoptiontype == "twoweaponsdef" && !fo.system.properties.used) {
2022-03-10 21:05:53 +01:00
defMod += 1
2022-07-01 15:48:54 +02:00
this.updateEmbeddedDocuments("Item", [{ _id: fo._id, 'system.properties.used': true }])
2022-03-10 21:05:53 +01:00
}
2022-07-01 15:48:54 +02:00
if (fo && fo.system.properties.fightoptiontype == "defense") {
2022-03-10 21:05:53 +01:00
defMod += 1
}
2022-07-01 15:48:54 +02:00
if (fo && fo.system.properties.fightoptiontype == "attack") {
2022-03-10 21:05:53 +01:00
defMod += -1
}
// Apply defense effects
for (let i of this.items) {
2023-03-18 10:24:30 +01:00
if (i.type === "feature" && i.system.subtype === "boleffect" && i.system.properties.identifier.includes("aptitudes.def")) {
defMod += Number(i.system.properties.modifier)
}
}
console.log("Defense : ", defMod)
2022-07-01 15:48:54 +02:00
return this.system.aptitudes.def.value + defMod
2021-12-25 23:26:27 +01:00
}
2022-03-10 21:05:53 +01:00
/* -------------------------------------------- */
2022-03-21 23:21:05 +01:00
getActiveFightOption() {
2022-07-01 15:48:54 +02:00
let it = this.items.find(i => i.type === "feature" && i.system.subtype === "fightoption" && i.system.properties.activated)
2022-03-10 21:05:53 +01:00
if (it) {
return foundry.utils.duplicate(it)
2022-03-10 21:05:53 +01:00
}
return undefined
}
2022-03-20 23:17:52 +01:00
2024-01-12 18:42:12 +01:00
/* -------------------------------------------- */
addXPLog(type, name, cost, value) {
let xplog = {
name: "XP : " + game.i18n.localize(type), type: "feature",
2024-01-12 18:42:12 +01:00
img: "icons/magic/symbols/chevron-elipse-circle-blue.webp",
system: {
subtype: "xplog", properties: {
xptype: type,
xpdate: new Date().toLocaleDateString(),
xpname: name,
xpcost: cost,
xpvalue: value
}
}
}
this.createEmbeddedDocuments('Item', [xplog])
}
2022-03-20 23:17:52 +01:00
/* -------------------------------------------- */
2022-03-21 23:21:05 +01:00
incAttributeXP(key) {
let attr = foundry.utils.duplicate(this.system.attributes[key])
2022-03-20 23:17:52 +01:00
if (attr) {
2022-03-21 23:21:05 +01:00
let nextXP = (attr.value == -1) ? 2 : attr.value + (attr.value + 1)
let xp = foundry.utils.duplicate(this.system.xp)
2022-03-21 23:21:05 +01:00
if (xp.total - xp.spent >= nextXP) {
2022-03-20 23:17:52 +01:00
attr.value += 1
xp.spent += nextXP
2022-07-01 15:48:54 +02:00
this.update({ [`system.attributes.${key}`]: attr, [`system.xp`]: xp })
2024-01-12 18:42:12 +01:00
this.addXPLog("attribute", key, nextXP, attr.value)
2022-03-20 23:17:52 +01:00
} else {
ui.notifications.warn("Pas assez de points d'expérience !")
}
}
}
/* -------------------------------------------- */
2022-03-21 23:21:05 +01:00
incAptitudeXP(key) {
let apt = foundry.utils.duplicate(this.system.aptitudes[key])
2022-03-20 23:17:52 +01:00
if (apt) {
let nextXP = (apt.value == -1) ? 1 : apt.value + 2
let xp = foundry.utils.duplicate(this.system.xp)
2022-03-21 23:21:05 +01:00
if (xp.total - xp.spent >= nextXP) {
2022-03-20 23:17:52 +01:00
apt.value += 1
xp.spent += nextXP
2022-07-01 15:48:54 +02:00
this.update({ [`system.aptitudes.${key}`]: apt, [`system.xp`]: xp })
2024-01-12 18:42:12 +01:00
this.addXPLog("aptitude", key, nextXP, apt.value)
2022-03-20 23:17:52 +01:00
} else {
ui.notifications.warn("Pas assez de points d'expérience !")
}
}
}
/* -------------------------------------------- */
2022-03-21 23:21:05 +01:00
incCareerXP(itemId) {
2022-07-01 15:48:54 +02:00
let career = this.items.get(itemId)
2022-03-20 23:17:52 +01:00
if (career) {
career = foundry.utils.duplicate(career)
2022-07-01 15:48:54 +02:00
let nextXP = career.system.rank + 1
let xp = foundry.utils.duplicate(this.system.xp)
2022-03-21 23:21:05 +01:00
if (xp.total - xp.spent >= nextXP) {
2022-03-20 23:17:52 +01:00
xp.spent += nextXP
2022-07-01 15:48:54 +02:00
this.update({ [`system.xp`]: xp })
this.updateEmbeddedDocuments('Item', [{ _id: career._id, 'system.rank': career.system.rank + 1 }])
this.addXPLog("career", career.name, nextXP, career.system.rank + 1)
2022-03-20 23:17:52 +01:00
} else {
ui.notifications.warn("Pas assez de points d'expérience !")
}
}
}
2022-03-10 21:05:53 +01:00
/* -------------------------------------------- */
2022-03-21 23:21:05 +01:00
async toggleFightOption(itemId) {
2022-07-01 15:48:54 +02:00
let fightOption = this.items.get(itemId)
2022-03-10 21:05:53 +01:00
let state
let updates = []
2022-03-21 23:21:05 +01:00
if (fightOption) {
fightOption = foundry.utils.duplicate(fightOption)
2022-07-01 15:48:54 +02:00
if (fightOption.system.properties.activated) {
2022-03-10 21:05:53 +01:00
state = false
} else {
state = true
}
2022-07-01 15:48:54 +02:00
updates.push({ _id: fightOption._id, 'system.properties.activated': state }) // Update the selected one
2022-03-10 21:05:53 +01:00
await this.updateEmbeddedDocuments("Item", updates) // Apply all changes
// Then notify
ChatMessage.create({
alias: this.name,
whisper: BoLUtility.getWhisperRecipientsAndGMs(this.name),
2022-03-21 23:21:05 +01:00
content: await renderTemplate('systems/bol/templates/chat/chat-activate-fight-option.hbs', { name: this.name, img: fightOption.img, foName: fightOption.name, state: state })
2022-03-10 21:05:53 +01:00
})
}
}
/*-------------------------------------------- */
2022-03-10 21:05:53 +01:00
get armorMalusValue() { // used for Fight Options
2022-03-21 23:21:05 +01:00
for (let armor of this.armors) {
2023-04-06 20:15:04 +02:00
if (armor.system.properties.armorQuality?.includes("light")) {
2022-03-10 21:05:53 +01:00
return 1
}
2023-04-06 20:15:04 +02:00
if (armor.system.properties.armorQuality?.includes("medium")) {
2022-03-10 21:05:53 +01:00
return 2
}
2023-04-06 20:15:04 +02:00
if (armor.system.properties.armorQuality?.includes("heavy")) {
2022-03-10 21:05:53 +01:00
return 3
}
}
return 0
}
2021-11-08 14:40:29 +01:00
get resources() {
2022-07-01 15:48:54 +02:00
return Object.values(this.system.resources)
2021-11-08 14:40:29 +01:00
}
2022-11-23 21:34:51 +01:00
get boleffects() {
return this.items.filter(i => i.type === "feature" && i.system.subtype === "boleffect")
}
2024-01-12 18:42:12 +01:00
get xplog() {
return this.items.filter(i => i.type === "feature" && i.system.subtype === "xplog")
}
2022-12-23 23:24:09 +01:00
get horoscopes() {
return this.items.filter(i => i.type === "feature" && i.system.subtype === "horoscope")
}
2021-11-08 14:40:29 +01:00
get boons() {
return foundry.utils.duplicate(this.items.filter(i => i.type === "feature" && i.system.subtype === "boon") || []);
2021-11-08 14:40:29 +01:00
}
get flaws() {
return foundry.utils.duplicate(this.items.filter(i => i.type === "feature" && i.system.subtype === "flaw") || []);
2021-11-08 14:40:29 +01:00
}
get careers() {
return foundry.utils.duplicate(this.items.filter(i => i.type === "feature" && i.system.subtype === "career") || [])
2021-11-08 14:40:29 +01:00
}
get origins() {
2022-07-01 15:48:54 +02:00
return this.items.filter(i => i.type === "feature" && i.system.subtype === "origin");
2021-11-08 14:40:29 +01:00
}
get races() {
2022-07-01 15:48:54 +02:00
return this.items.filter(i => i.type === "feature" && i.system.subtype === "race");
2021-11-08 14:40:29 +01:00
}
get languages() {
2022-07-01 15:48:54 +02:00
return this.items.filter(i => i.type === "feature" && i.system.subtype === "language")
2022-03-10 21:05:53 +01:00
}
get fightoptions() {
2022-07-01 15:48:54 +02:00
return this.items.filter(i => i.type === "feature" && i.system.subtype === "fightoption")
2021-11-08 14:40:29 +01:00
}
2022-05-23 18:38:51 +02:00
get godsfaith() {
2022-07-01 15:48:54 +02:00
return this.items.filter(i => i.type === "feature" && i.system.subtype === "godsfaith")
2022-05-23 18:38:51 +02:00
}
2021-11-08 14:40:29 +01:00
get features() {
2022-07-01 15:48:54 +02:00
return this.items.filter(i => i.type === "feature")
2021-11-08 14:40:29 +01:00
}
get equipment() {
2022-07-01 15:48:54 +02:00
return this.items.filter(i => i.type === "item")
2021-11-08 14:40:29 +01:00
}
2022-04-10 16:38:09 +02:00
get equipmentCreature() {
return this.items.filter(i => i.type === "item" && i.system.category === "equipment" && ((i.system.subtype === "weapon" && i.system.properties.natural === true) || (i.system.subtype === "armor")))
2022-04-10 16:38:09 +02:00
}
2021-11-08 14:40:29 +01:00
get armors() {
2022-07-01 15:48:54 +02:00
return this.items.filter(i => i.type === "item" && i.system.category === "equipment" && i.system.subtype === "armor");
2021-11-08 14:40:29 +01:00
}
get helms() {
2022-07-01 15:48:54 +02:00
return this.items.filter(i => i.type === "item" && i.system.category === "equipment" && i.system.subtype === "helm");
2021-11-08 14:40:29 +01:00
}
get shields() {
2022-07-01 15:48:54 +02:00
return this.items.filter(i => i.type === "item" && i.system.category === "equipment" && i.system.subtype === "shield");
}
get vehicleWeapons() {
return this.items.filter(i => i.type === "item" && i.system.category === "vehicleweapon")
}
get weapons() {
return this.items.filter(i => i.type === "item" && i.system.category === "equipment" && i.system.subtype === "weapon")
2021-11-08 14:40:29 +01:00
}
get protections() {
return this.armors.concat(this.helms).concat(this.shields)
2021-11-08 14:40:29 +01:00
}
2022-01-23 09:25:09 +01:00
get spells() {
2022-07-01 15:48:54 +02:00
return this.items.filter(i => i.type === "item" && i.system.category === "spell");
2022-01-23 09:25:09 +01:00
}
get alchemy() {
2022-07-01 15:48:54 +02:00
return this.items.filter(i => i.type === "item" && i.system.category === "alchemy");
2022-01-23 09:25:09 +01:00
}
2021-11-08 14:40:29 +01:00
get melee() {
2022-07-01 15:48:54 +02:00
return this.weapons.filter(i => i.system.properties.melee === true);
2021-11-08 14:40:29 +01:00
}
2022-04-10 16:38:09 +02:00
get natural() {
2022-07-01 15:48:54 +02:00
return this.weapons.filter(i => i.system.properties.natural === true);
2022-04-10 16:38:09 +02:00
}
2021-11-08 14:40:29 +01:00
get ranged() {
2022-07-01 15:48:54 +02:00
return this.weapons.filter(i => i.system.properties.ranged === true);
}
get containers() {
2022-07-01 15:48:54 +02:00
return this.items.filter(i => i.type === "item" && i.system.category === "equipment" && i.system.subtype === "container");
2021-11-08 14:40:29 +01:00
}
get treasure() {
2022-07-01 15:48:54 +02:00
return this.items.filter(i => i.type === "item" && i.system.category === "equipment" && i.system.subtype === "currency");
}
get vehicles() {
2022-07-01 15:48:54 +02:00
return this.items.filter(i => i.type === "item" && i.system.category === "vehicle");
}
get ammos() {
2022-07-01 15:48:54 +02:00
return this.items.filter(i => i.type === "item" && i.system.category === "equipment" && i.system.subtype === "ammunition");
}
get misc() {
2022-07-01 15:48:54 +02:00
return this.items.filter(i => i.type === "item" && i.system.category === "equipment" && (i.system.subtype === "other" || i.system.subtype === "container" || i.system.subtype === "scroll" || i.system.subtype === "jewel"));
}
2022-03-21 23:21:05 +01:00
2022-02-18 21:58:53 +01:00
get bonusBoons() {
2022-07-07 13:33:31 +02:00
let boons = this.items.filter(i => i.type === "feature" && i.system.subtype === "boon" && i.system.properties.isbonusdice)
return foundry.utils.duplicate(boons || [])
2022-02-18 21:58:53 +01:00
}
get malusFlaws() {
return foundry.utils.duplicate(this.items.filter(i => i.type === "feature" && i.system.subtype === "flaw" && i.system.properties.ismalusdice) || []);
2022-02-18 21:58:53 +01:00
}
2022-03-21 23:21:05 +01:00
isSorcerer() {
return (this.careers.find(item => item.system.properties.sorcerer))
2022-01-23 09:25:09 +01:00
}
2022-03-21 23:21:05 +01:00
isAlchemist() {
2024-02-22 18:29:04 +01:00
return (this.careers.find(item => item.system.properties.alchemist))
2022-01-23 09:25:09 +01:00
}
2022-12-23 23:24:09 +01:00
isAstrologer() {
2024-02-22 18:29:04 +01:00
return (this.careers.find(item => item.system.properties.astrologer))
2022-12-23 23:24:09 +01:00
}
2022-03-21 23:21:05 +01:00
isPriest() {
2024-02-22 18:29:04 +01:00
return (this.careers.find(item => item.system.properties.priest))
2022-01-23 09:25:09 +01:00
}
/*-------------------------------------------- */
getPPCostArmor() {
let armors = this.armors
let ppCostArmor = 0
for (let armor of armors) {
2022-07-01 15:48:54 +02:00
if (armor.system.worn) {
ppCostArmor += Number(armor.system.properties.modifiers.powercost) || 0
}
}
return ppCostArmor
}
/*-------------------------------------------- */
getDamageAttributeValue(attrDamage) {
let attrDamageValue = 0
if (attrDamage.includes("vigor")) {
2022-11-25 20:47:28 +01:00
attrDamageValue = this.system.attributes.vigor.value
if (attrDamage.includes("half")) {
attrDamageValue = Math.floor(attrDamageValue / 2)
}
// Apply vigor effects
for (let i of this.items) {
2023-03-18 10:24:30 +01:00
if (i.type === "feature" && i.system.subtype === "boleffect" && i.system.properties.identifier.includes("vigor")) {
attrDamageValue += Number(i.system.properties.modifier)
}
}
}
return attrDamageValue
}
/*-------------------------------------------- */
getArmorAgiMalus() {
let malusAgi = 0
2022-03-27 22:56:43 +02:00
for (let armor of this.protections) {
2022-07-01 15:48:54 +02:00
if (armor.system.worn) {
malusAgi += Number(armor.system.properties.modifiers.agility) || 0
}
}
return malusAgi
}
/*-------------------------------------------- */
getArmorInitMalus() {
let malusInit = 0
2022-03-27 22:56:43 +02:00
for (let armor of this.protections) {
2022-07-01 15:48:54 +02:00
if (armor.system.worn) {
malusInit += Number(armor.system.properties.modifiers.init) || 0
}
}
return malusInit
}
/*-------------------------------------------- */
2022-03-21 23:21:05 +01:00
spendPowerPoint(ppCost) {
2022-07-01 15:48:54 +02:00
let newPP = this.system.resources.power.value - ppCost
2022-03-21 23:21:05 +01:00
newPP = (newPP < 0) ? 0 : newPP
2022-08-31 22:24:56 +02:00
this.update({ 'system.resources.power.value': newPP })
2022-06-11 20:56:35 +02:00
return newPP
2022-01-23 09:25:09 +01:00
}
/*-------------------------------------------- */
2022-03-21 23:21:05 +01:00
resetAlchemyStatus(alchemyId) {
2022-07-01 15:48:54 +02:00
let alchemy = this.items.get(alchemyId)
2022-01-23 09:25:09 +01:00
if (alchemy) {
2022-08-31 22:24:56 +02:00
this.updateEmbeddedDocuments('Item', [{ _id: alchemy.id, 'system.properties.pccurrent': 0 }])
2022-01-23 09:25:09 +01:00
}
}
2023-03-18 10:24:30 +01:00
2022-12-23 23:24:09 +01:00
/*-------------------------------------------- */
spentAstrologyPoints(points) {
let astrology = foundry.utils.duplicate(this.system.resources.astrologypoints)
2022-12-23 23:24:09 +01:00
astrology.value -= points
2023-03-18 10:24:30 +01:00
astrology.value = Math.max(astrology.value, 0)
this.update({ 'system.resources.astrologypoints': astrology })
2022-12-23 23:24:09 +01:00
}
/*-------------------------------------------- */
getHoroscopesBonus() {
2023-03-18 10:24:30 +01:00
let astro = this.items.filter(it => it.type == "feature" && it.system.subtype == "horoscope" && !it.system.properties.ishoroscopemajor
&& it.system.properties.horoscopeanswer == "favorable")
2022-12-23 23:24:09 +01:00
return astro
}
/*-------------------------------------------- */
getHoroscopesMalus() {
2023-03-18 10:24:30 +01:00
let astro = this.items.filter(it => it.type == "feature" && it.system.subtype == "horoscope" && !it.system.properties.ishoroscopemajor
&& it.system.properties.horoscopeanswer == "unfavorable")
2022-12-23 23:24:09 +01:00
return astro
}
/*-------------------------------------------- */
manageHoroscope(rollData) {
//Spent points
this.spentAstrologyPoints(rollData.astrologyPointsCost)
2023-03-18 10:24:30 +01:00
if (rollData.horoscopeType == "minor") {
let horoscope = {
name: "SITUATION A SPECIFIER", type: "feature",
2022-12-23 23:24:09 +01:00
img: "icons/magic/perception/eye-ringed-glow-angry-large-red.webp",
2023-03-18 10:24:30 +01:00
system: {
subtype: "horoscope", properties: {
ishoroscopemajor: false,
horoscopeanswer: (rollData.isSuccess) ? "favorable" : "unfavorable",
rank: rollData.careerBonus
}
2022-12-23 23:24:09 +01:00
}
}
this.createEmbeddedDocuments('Item', [horoscope])
}
2023-03-18 10:24:30 +01:00
if (rollData.horoscopeType == "major") {
2023-04-29 21:48:51 +02:00
let actorHoroscope = this
2023-09-16 09:40:08 +02:00
if (rollData.targetId) {
2023-04-29 21:48:51 +02:00
let token = game.scenes.current.tokens.get(rollData.targetId)
2023-09-16 09:40:08 +02:00
actorHoroscope = token.actor
2023-04-29 21:48:51 +02:00
}
2023-03-18 10:24:30 +01:00
if (rollData.isSuccess) {
2023-04-29 21:48:51 +02:00
actorHoroscope.addHeroPoints(1)
2022-12-23 23:24:09 +01:00
} else {
2023-04-29 21:48:51 +02:00
actorHoroscope.subHeroPoints(1)
2023-03-18 10:24:30 +01:00
}
2023-09-16 09:40:08 +02:00
rollData.horoscopeName = actorHoroscope.name
2022-12-23 23:24:09 +01:00
}
2023-03-18 10:24:30 +01:00
if (rollData.horoscopeType == "majorgroup") {
let rID = foundry.utils.randomID(16)
let horoscopes = foundry.utils.duplicate(game.settings.get("bol", "horoscope-group"))
2022-12-23 23:24:09 +01:00
horoscopes[rID] = {
2022-12-25 18:00:42 +01:00
id: rID,
2022-12-23 23:24:09 +01:00
name: game.i18n.localize("BOL.ui.groupHoroscope") + this.name,
maxDice: rollData.careerBonus,
availableDice: rollData.careerBonus,
2023-03-18 10:24:30 +01:00
type: (rollData.isSuccess) ? "bonus" : "malus"
2022-12-23 23:24:09 +01:00
}
2022-12-25 18:00:42 +01:00
game.settings.set("bol", "horoscope-group", horoscopes)
2022-12-23 23:24:09 +01:00
}
}
2022-12-25 18:00:42 +01:00
/*-------------------------------------------- */
getAstrologyPoints() {
return this.system.resources.astrologypoints.value
}
2022-12-23 23:24:09 +01:00
/*-------------------------------------------- */
2023-03-18 10:24:30 +01:00
removeHoroscopeMinor(rollData) {
2022-12-23 23:24:09 +01:00
let toDel = []
2023-03-18 10:24:30 +01:00
for (let horo of rollData.selectedHoroscope) {
toDel.push(horo._id)
2022-12-23 23:24:09 +01:00
}
if (toDel.length > 0) {
this.deleteEmbeddedDocuments('Item', toDel)
}
}
2022-01-23 09:25:09 +01:00
/*-------------------------------------------- */
2022-03-21 23:21:05 +01:00
async spendAlchemyPoint(alchemyId, pcCost) {
2022-07-01 15:48:54 +02:00
let alchemy = this.items.get(alchemyId)
2022-01-23 09:25:09 +01:00
if (alchemy) {
2024-02-22 18:29:04 +01:00
pcCost = Number(pcCost) || 0
2022-07-01 15:48:54 +02:00
if (this.system.resources.alchemypoints.value >= pcCost) {
let newPC = this.system.resources.alchemypoints.value - pcCost
2022-03-21 23:21:05 +01:00
newPC = (newPC < 0) ? 0 : newPC
this.update({ 'data.resources.alchemypoints.value': newPC })
2022-07-01 15:48:54 +02:00
newPC = alchemy.system.properties.pccurrent + pcCost
2022-08-31 22:24:56 +02:00
await this.updateEmbeddedDocuments('Item', [{ _id: alchemy.id, 'system.properties.pccurrent': newPC }])
2022-01-23 09:25:09 +01:00
} else {
2023-03-18 10:24:30 +01:00
ui.notifications.warn(game.i18n.localize("BOL.ui.nomorealchemypoints"))
2022-01-23 09:25:09 +01:00
}
}
2022-03-21 23:21:05 +01:00
}
2022-12-23 23:24:09 +01:00
/*-------------------------------------------- */
getAstrologerBonus() {
2024-02-22 18:29:04 +01:00
let astrologer = this.careers.find(item => item.system.properties.astrologer)
2022-12-23 23:24:09 +01:00
if (astrologer) {
return astrologer.system.rank
}
return 0;
}
2022-06-11 10:21:18 +02:00
/*-------------------------------------------- */
2022-01-23 09:25:09 +01:00
getAlchemistBonus() {
2024-02-22 18:29:04 +01:00
let sorcerer = this.careers.find(item => item.system.properties.alchemist)
2022-01-23 09:25:09 +01:00
if (sorcerer) {
2022-07-01 15:48:54 +02:00
return sorcerer.system.rank
2022-01-23 09:25:09 +01:00
}
return 0;
}
2022-06-11 10:21:18 +02:00
/*-------------------------------------------- */
2022-01-23 09:25:09 +01:00
getSorcererBonus() {
let sorcerer = this.careers.find(item => item.system.properties.sorcerer)
2022-01-23 09:25:09 +01:00
if (sorcerer) {
2022-07-01 15:48:54 +02:00
return sorcerer.system.rank
2022-01-23 09:25:09 +01:00
}
return 0;
}
2022-06-11 10:21:18 +02:00
/*-------------------------------------------- */
2022-03-21 23:21:05 +01:00
heroReroll() {
2023-09-16 09:40:08 +02:00
if (this.type == 'character' || this.system.villainy == 'adversary') {
2022-07-01 15:48:54 +02:00
return this.system.resources.hero.value > 0;
2022-01-09 13:23:20 +01:00
}
return false
}
2023-09-16 09:40:08 +02:00
/*-------------------------------------------- */
getHeroPoints() {
if (this.type == 'character' || this.system.villainy == 'adversary') {
return this.system.resources.hero.value
}
return 0
}
/*-------------------------------------------- */
2022-01-08 23:28:16 +01:00
getResourcesFromType() {
let resources = {};
if (this.type == 'encounter') {
2022-07-01 15:48:54 +02:00
resources['hp'] = this.system.resources.hp;
if (this.system.chartype != 'base') {
2022-07-01 15:48:54 +02:00
resources['faith'] = this.system.resources.faith
resources['power'] = this.system.resources.power
2022-01-08 23:28:16 +01:00
}
2024-11-02 18:29:22 +01:00
if (this.system.chartype == 'adversary' || this.system.chartype == 'creature') {
resources['hero'] = foundry.utils.duplicate(this.system.resources.hero)
2022-01-08 23:28:16 +01:00
resources['hero'].label = "BOL.resources.villainy"
}
} else {
2022-07-01 15:48:54 +02:00
resources = this.system.resources;
2022-01-08 23:28:16 +01:00
}
return resources
}
2022-03-21 23:21:05 +01:00
buildFeatures() {
2021-11-08 14:40:29 +01:00
return {
"careers": {
"label": "BOL.featureCategory.careers",
"ranked": true,
"items": this.careers
},
"origins": {
"label": "BOL.featureCategory.origins",
"ranked": false,
"items": this.origins
},
"races": {
"label": "BOL.featureCategory.races",
"ranked": false,
"items": this.races
},
"boons": {
"label": "BOL.featureCategory.boons",
"ranked": false,
"items": this.boons
},
"flaws": {
"label": "BOL.featureCategory.flaws",
"ranked": false,
"items": this.flaws
},
"languages": {
"label": "BOL.featureCategory.languages",
"ranked": false,
"items": this.languages
2022-03-10 21:05:53 +01:00
},
"fightoptions": {
"label": "BOL.featureCategory.fightoptions",
"ranked": false,
"items": this.fightoptions
2022-05-23 18:38:51 +02:00
},
"godsfaith": {
"label": "BOL.featureSubtypes.gods",
"ranked": false,
"items": this.godsfaith
2022-11-23 21:34:51 +01:00
},
"boleffects": {
"label": "BOL.featureSubtypes.effects",
"ranked": false,
"items": this.boleffects
2021-11-08 14:40:29 +01:00
}
2022-03-10 21:05:53 +01:00
}
2021-11-08 14:40:29 +01:00
}
2022-03-21 23:21:05 +01:00
buildCombat() {
2021-11-08 14:40:29 +01:00
return {
2022-03-21 23:21:05 +01:00
"melee": {
"label": "BOL.combatCategory.melee",
"weapon": true,
"protection": false,
"blocking": false,
"ranged": false,
2022-03-10 21:05:53 +01:00
"options": false,
2022-03-21 23:21:05 +01:00
"items": this.melee
2021-11-08 14:40:29 +01:00
},
2022-09-02 16:08:56 +02:00
"natural": {
"label": "BOL.combatCategory.natural",
"weapon": true,
"protection": false,
"blocking": false,
"ranged": false,
"options": false,
"items": this.natural
},
2022-03-21 23:21:05 +01:00
"ranged": {
"label": "BOL.combatCategory.ranged",
"weapon": true,
"protection": false,
"blocking": false,
"ranged": true,
2022-03-10 21:05:53 +01:00
"options": false,
2022-03-21 23:21:05 +01:00
"items": this.ranged
2021-11-08 14:40:29 +01:00
},
2022-03-21 23:21:05 +01:00
"protections": {
"label": "BOL.combatCategory.protections",
"weapon": false,
"protection": true,
"blocking": false,
"ranged": false,
2022-03-10 21:05:53 +01:00
"options": false,
2022-03-21 23:21:05 +01:00
"items": this.protections
2021-11-08 14:40:29 +01:00
},
2022-03-21 23:21:05 +01:00
"shields": {
"label": "BOL.combatCategory.shields",
"weapon": false,
"protection": false,
"blocking": true,
"ranged": false,
2022-03-10 21:05:53 +01:00
"options": false,
2022-03-21 23:21:05 +01:00
"items": this.shields
2022-03-10 21:05:53 +01:00
},
2022-03-21 23:21:05 +01:00
"fightoptions": {
"label": "BOL.combatCategory.fightOptions",
"weapon": false,
"protection": false,
"blocking": false,
"ranged": false,
2022-03-10 21:05:53 +01:00
"options": true,
2022-03-21 23:21:05 +01:00
"items": this.fightoptions
2021-11-08 14:40:29 +01:00
}
2022-03-10 21:05:53 +01:00
}
2021-11-01 00:28:42 +01:00
}
2021-12-29 19:15:06 +01:00
2022-04-10 16:38:09 +02:00
2022-03-21 23:21:05 +01:00
/*-------------------------------------------- */
buildRollList() {
let rolls = []
2022-07-01 15:48:54 +02:00
for (let key in this.system.attributes) {
let attr = this.system.attributes[key]
rolls.push({ key: key, value: attr.value, name: attr.label, type: "attribute" })
2022-03-21 23:21:05 +01:00
}
2022-07-01 15:48:54 +02:00
for (let key in this.system.aptitudes) {
if (key != "def") {
2022-07-01 15:48:54 +02:00
let apt = this.system.aptitudes[key]
rolls.push({ key: key, value: apt.value, name: apt.label, type: "aptitude" })
2022-03-21 23:21:05 +01:00
}
}
return rolls
}
/*-------------------------------------------- */
buildListeActions() {
2023-06-23 08:37:50 +02:00
return this.melee.concat(this.ranged).concat(this.natural).concat(this.fightoptions)
2022-03-21 23:21:05 +01:00
}
2021-12-29 19:15:06 +01:00
/*-------------------------------------------- */
2022-02-18 22:15:46 +01:00
async manageHealthState() {
2022-03-21 23:21:05 +01:00
let hpID = "lastHP" + this.id
let lastHP = await this.getFlag("world", hpID)
if (lastHP != this.system.resources.hp.value && game.user.isGM) { // Only GM sends this
2022-07-01 15:48:54 +02:00
await this.setFlag("world", hpID, this.system.resources.hp.value)
let prone = this.effects.find(ef => ef.name == game.i18n.localize("EFFECT.StatusProne"))
let dead = this.effects.find(ef => ef.name == game.i18n.localize("EFFECT.StatusDead"))
2022-07-01 15:48:54 +02:00
if (this.system.resources.hp.value <= 0) {
2023-03-18 10:24:30 +01:00
if (!prone) {
await this.createEmbeddedDocuments("ActiveEffect", [
{ name: game.i18n.localize('EFFECT.StatusProne'), icon: 'icons/svg/falling.svg', statuses: 'prone' }
])
}
2023-03-18 10:24:30 +01:00
if (this.system.resources.hp.value < -5 && !dead) {
await this.createEmbeddedDocuments("ActiveEffect", [
{ name: game.i18n.localize('EFFECT.StatusDead'), icon: 'icons/svg/skull.svg', statuses: 'dead' }
])
}
2022-02-20 10:12:25 +01:00
ChatMessage.create({
alias: this.name,
whisper: BoLUtility.getWhisperRecipientsAndGMs(this.name),
2023-04-04 13:41:22 +02:00
content: await renderTemplate('systems/bol/templates/chat/chat-vitality-zero.hbs', { name: this.name, img: this.img, hp: this.system.resources.hp.value, isHeroAdversary: this.isHeroAdversary() })
2022-02-20 10:12:25 +01:00
})
} else {
2023-03-18 10:24:30 +01:00
if (prone) {
await this.deleteEmbeddedDocuments("ActiveEffect", [prone.id])
}
2023-03-18 10:24:30 +01:00
if (dead) {
await this.deleteEmbeddedDocuments("ActiveEffect", [dead.id])
}
2022-02-20 10:12:25 +01:00
}
2021-12-29 19:15:06 +01:00
}
}
2022-01-16 22:53:41 +01:00
/*-------------------------------------------- */
2022-12-02 13:15:48 +01:00
async registerInit(rollData) {
2022-11-30 20:58:27 +01:00
rollData.actor = undefined // Cleanup if present
2022-12-02 13:15:48 +01:00
await this.setFlag("world", "last-initiative", rollData)
2022-01-16 22:53:41 +01:00
}
2023-03-18 10:24:30 +01:00
/*-------------------------------------------- */
storeVitaliteCombat() {
this.setFlag("world", "vitalite-before-combat", foundry.utils.duplicate(this.system.resources.hp))
2023-03-18 10:24:30 +01:00
}
/*-------------------------------------------- */
async displayRecuperation() {
let previousHP = this.getFlag("world", "vitalite-before-combat")
let lossHP = previousHP.value - this.system.resources.hp.value
2023-03-18 13:51:46 +01:00
//console.log(">>>>> RECUP INFO", previousHP, this.system.resources.hp.value)
2023-03-18 10:24:30 +01:00
if (previousHP && lossHP > 0 && this.system.resources.hp.value > 0) {
let msg = await ChatMessage.create({
alias: this.name,
whisper: BoLUtility.getWhisperRecipientsAndGMs(this.name),
content: await renderTemplate('systems/bol/templates/chat/chat-recup-information.hbs', {
name: this.name,
2023-04-29 21:48:51 +02:00
img: this.img,
2023-03-18 10:24:30 +01:00
actorId: this.id,
lossHP: lossHP,
2023-03-18 13:51:46 +01:00
recupHP: Math.ceil(lossHP / 2)
2023-03-18 10:24:30 +01:00
})
})
}
this.unsetFlag("world", "vitalite-before-combat")
}
/*-------------------------------------------- */
async applyRecuperation(recupHP) {
let hp = foundry.utils.duplicate(this.system.resources.hp)
2023-04-29 21:48:51 +02:00
//console.log("RECUP !!!!", hp, recupHP)
hp.value += Number(recupHP)
2023-03-18 10:24:30 +01:00
hp.value = Math.min(hp.value, hp.max)
this.update({ 'system.resources.hp': hp })
let msg = await ChatMessage.create({
alias: this.name,
whisper: BoLUtility.getWhisperRecipientsAndGMs(this.name),
2023-09-16 09:40:08 +02:00
content: game.i18n.format("BOL.chat.inforecup", { name: this.name, recupHP: recupHP })
2023-03-18 10:24:30 +01:00
})
}
2022-01-16 22:53:41 +01:00
/*-------------------------------------------- */
2022-12-23 16:38:41 +01:00
clearInitiative() {
2023-03-18 10:24:30 +01:00
this.unsetFlag("world", "last-initiative")
2022-12-23 16:38:41 +01:00
}
2023-01-04 09:57:13 +01:00
/*-------------------------------------------- */
getSize() {
if (this.system.details.size.length > 0 && game.bol.config.creatureSize[this.system.details.size]) {
return game.bol.config.creatureSize[this.system.details.size].order
}
return game.bol.config.creatureSize["medium"].order // Medium size per default
}
2023-04-06 20:15:04 +02:00
/*-------------------------------------------- */
checkNumeric(myObject) {
2023-09-16 09:40:08 +02:00
if (myObject) {
2023-04-06 20:15:04 +02:00
for (let key in myObject) {
2024-02-22 18:29:04 +01:00
if (myObject[key].value === null || isNaN(myObject[key].value)) {
2023-04-06 20:15:04 +02:00
myObject[key].value = 0
}
}
}
}
/*-------------------------------------------- */
_preUpdate(data, options, userId) {
if (data.system?.attributes) {
this.checkNumeric(data.system.attributes)
}
if (data.system?.aptitudes) {
this.checkNumeric(data.system.aptitudes)
}
if (data.system?.resources) {
this.checkNumeric(data.system.resources)
}
// Apply changes in Horde size to Token width/height
2024-09-12 22:43:09 +02:00
if (this.type == "horde") {
if (data?.system?.hordesize) { // If horde size is changed}
let newHP = data.system.hordesize * this.system.hordebasehp
if (newHP != this.system.resources.hp.value) {
data.system.resources = { hp: { value: newHP, max: newHP } } // Update HP
}
let tokenSize = this.getTokenSizeFromHordeSize(data?.system?.hordesize)
2024-09-12 22:43:09 +02:00
if (this.isToken && (tokenSize !== this.token.width)) {
this.token.update({ width: tokenSize, height: tokenSize })
2024-09-12 22:43:09 +02:00
} else {
if (tokenSize && (tokenSize !== this.prototypeToken.width)) {
if (!foundry.utils.hasProperty(data, "prototypeToken.width")) {
data.prototypeToken ||= {};
data.prototypeToken.height = tokenSize;
data.prototypeToken.width = tokenSize;
}
}
}
}
if (data?.system?.hordebasehp) {
let newHP = this.system.hordesize * data.system.hordebasehp
if (newHP != this.system.resources.hp.value) {
2024-09-12 22:43:09 +02:00
data.system.resources = { hp: { value: newHP, max: newHP } }
}
}
}
2023-04-06 20:15:04 +02:00
super._preUpdate(data, options, userId)
}
2023-01-04 09:57:13 +01:00
2022-12-23 16:38:41 +01:00
/*-------------------------------------------- */
2024-02-22 18:29:04 +01:00
getInitiativeRank(rollData = undefined, isCombat = false, combatData = undefined) {
2022-12-01 23:57:33 +01:00
let fvttInit = 4 // Pietaille par defaut
2023-03-18 10:24:30 +01:00
if (this.type == 'character') {
2022-12-01 23:57:33 +01:00
fvttInit = 5
2023-04-06 20:15:04 +02:00
if (!rollData) {
2023-03-18 10:24:30 +01:00
if (isCombat) {
2023-09-16 09:40:08 +02:00
if (game.user.isGM) {
2023-05-01 18:50:32 +02:00
if (this.hasPlayerOwner) {
game.socket.emit("system.bol", { name: "msg_request_init_roll", data: { actorId: this.id, combatData } })
} else {
BoLRoll.aptitudeCheck(this, "init", undefined, combatData);
}
2023-04-06 20:15:04 +02:00
}
2022-12-23 16:38:41 +01:00
}
2022-12-01 23:57:33 +01:00
} else {
if (rollData.isLegendary) {
fvttInit = 10
} else if (rollData.isCritical) {
fvttInit = 9
2023-03-18 10:24:30 +01:00
} else if (rollData.isSuccess) {
2022-12-01 23:57:33 +01:00
fvttInit = 8
} else if (rollData.isFumble) {
fvttInit = 3
2023-03-18 10:24:30 +01:00
}
2022-11-30 20:58:27 +01:00
}
2022-12-01 23:57:33 +01:00
}
2023-03-18 10:24:30 +01:00
if (this.getCharType() == 'adversary') {
2022-12-01 23:57:33 +01:00
fvttInit = 7
2023-03-18 10:24:30 +01:00
}
if (this.getCharType() == 'tough') {
2022-12-01 23:57:33 +01:00
fvttInit = 6
2022-11-30 20:58:27 +01:00
}
2023-03-18 10:24:30 +01:00
if (this.getCharType() == 'creature') {
2023-01-04 09:57:13 +01:00
let mySize = this.getSize()
let sizeSmall = game.bol.config.creatureSize["small"].order
let sizeMedium = game.bol.config.creatureSize["medium"].order
2023-03-18 10:24:30 +01:00
if (mySize >= sizeSmall && mySize <= sizeMedium) {
2023-01-04 09:57:13 +01:00
fvttInit = 6
}
2023-03-18 10:24:30 +01:00
if (mySize > sizeMedium) {
2023-01-04 09:57:13 +01:00
fvttInit = 7
}
}
2022-11-30 20:58:27 +01:00
return fvttInit
2022-01-16 22:53:41 +01:00
}
2023-03-18 10:24:30 +01:00
2021-12-29 19:15:06 +01:00
/*-------------------------------------------- */
2022-03-21 23:21:05 +01:00
async subHeroPoints(nb) {
2022-07-01 15:48:54 +02:00
let newHeroP = this.system.resources.hero.value - nb;
2022-03-21 23:21:05 +01:00
newHeroP = (newHeroP < 0) ? 0 : newHeroP;
2022-07-01 15:48:54 +02:00
await this.update({ 'system.resources.hero.value': newHeroP });
2021-12-29 19:15:06 +01:00
}
2022-12-23 23:24:09 +01:00
/*-------------------------------------------- */
async addHeroPoints(nb) {
let newHeroP = this.system.resources.hero.value + nb;
newHeroP = (newHeroP < 0) ? 0 : newHeroP;
await this.update({ 'system.resources.hero.value': newHeroP });
}
2021-12-29 19:15:06 +01:00
2023-03-18 13:51:46 +01:00
/*-------------------------------------------- */
incDecResources(target, value) {
let newValue = this.system.resources[target].value + value
2023-09-16 09:40:08 +02:00
this.update({ [`system.resources.${target}.value`]: newValue })
2023-03-18 13:51:46 +01:00
}
2021-12-29 19:15:06 +01:00
/*-------------------------------------------- */
2022-03-21 23:21:05 +01:00
async sufferDamage(damage) {
let updates = {}
2022-07-01 15:48:54 +02:00
let newHP = this.system.resources.hp.value - damage
updates['system.resources.hp.value'] = newHP
if (this.type == "horde") {
let newSize = Math.ceil(newHP / this.system.hordebasehp)
updates['system.hordesize'] = newSize
}
await this.update(updates)
2021-12-29 19:15:06 +01:00
}
/* -------------------------------------------- */
2022-03-21 23:21:05 +01:00
getArmorFormula() {
2022-07-01 15:48:54 +02:00
let protectWorn = this.protections.filter(item => item.system.worn)
2021-12-29 19:15:06 +01:00
let formula = ""
for (let protect of protectWorn) {
2022-07-01 15:48:54 +02:00
if (protect.system.subtype == 'helm') {
2022-03-21 23:21:05 +01:00
formula += "+1"
2022-07-01 15:48:54 +02:00
} else if (protect.system.subtype == 'armor') {
2022-03-21 23:21:05 +01:00
if (BoLUtility.getRollArmor()) {
2022-07-01 15:48:54 +02:00
if (!protect.system.properties.soak.formula || protect.system.properties.soak.formula == "") {
2023-03-18 10:24:30 +01:00
ui.notifications.warn(game.i18n.localize("BOL.ui.armornoformula", protect.name))
2022-03-21 23:21:05 +01:00
} else {
formula += "+" + " max(" + protect.system.properties.soak.formula + ",0)"
2022-02-23 20:39:58 +01:00
}
2022-03-21 23:21:05 +01:00
} else {
2022-07-01 15:48:54 +02:00
if (protect.system.properties.soak.value == undefined) {
2023-03-18 10:24:30 +01:00
ui.notifications.warn(game.i18n.localize("BOL.ui.armornoformula", protect.name))
2022-03-21 23:21:05 +01:00
} else {
2022-07-01 15:48:54 +02:00
formula += "+ " + protect.system.properties.soak.value
2022-02-23 20:39:58 +01:00
}
}
2021-12-29 19:15:06 +01:00
}
}
console.log("Protect Formula", formula)
2022-03-21 23:21:05 +01:00
return (formula == "") ? "0" : formula;
2021-12-29 19:15:06 +01:00
}
2022-01-16 22:06:49 +01:00
/* -------------------------------------------- */
2024-09-12 22:43:09 +02:00
async rollProtection(itemId) {
let armor = foundry.utils.duplicate(this.items.get(itemId))
2022-03-21 23:21:05 +01:00
if (armor) {
let armorFormula = "max(" + armor.system.properties.soak.formula + ", 0)"
2022-01-16 22:06:49 +01:00
let rollArmor = new Roll(armorFormula)
2024-09-12 22:43:09 +02:00
await rollArmor.roll()
rollArmor.toMessage()
2022-01-16 22:06:49 +01:00
}
}
/* -------------------------------------------- */
2022-03-21 23:21:05 +01:00
rollWeaponDamage(itemId) {
let weapon = foundry.utils.duplicate(this.items.get(itemId))
2022-03-21 23:21:05 +01:00
if (weapon) {
let r = new BoLDefaultRoll({ id: foundry.utils.randomID(16), isSuccess: true, mode: "weapon", weapon: weapon, actorId: this.id, actor: this })
2022-01-16 22:06:49 +01:00
r.setSuccess(true)
2022-02-02 09:35:32 +01:00
r.rollDamage()
2022-01-16 22:06:49 +01:00
}
}
2021-11-01 00:28:42 +01:00
/* -------------------------------------------- */
toggleEquipItem(item) {
2022-07-01 15:48:54 +02:00
const equipable = item.system.properties.equipable;
2022-03-21 23:21:05 +01:00
if (equipable) {
let itemData = foundry.utils.duplicate(item);
2022-07-01 15:48:54 +02:00
itemData.system.worn = !itemData.system.worn;
return item.update(itemData);
}
}
2021-07-08 10:12:12 +02:00
}