Skip to content

Commit

Permalink
Merge pull request #148 from juanferrer/master
Browse files Browse the repository at this point in the history
Attack message normalisation
  • Loading branch information
ClipplerBlood committed Dec 21, 2023
2 parents 52906e2 + 8b69424 commit 5ae1fae
Show file tree
Hide file tree
Showing 26 changed files with 213 additions and 158 deletions.
5 changes: 2 additions & 3 deletions src/module/active-effects/afflictions.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ export class DLAfflictions {
const isBlocked = actor.system.maluses.autoFail[actionType]?.[actionAttribute] > 0
if (isBlocked) {
// TODO: more precise message? Currently it picks the first message
let msg = actor.getEmbeddedCollection('ActiveEffect').find(effect => Boolean(effect.flags?.warningMessage))
let msg = Array.from(actor.allApplicableEffects()).find(effect => Boolean(effect.flags?.warningMessage))
?.flags.warningMessage
msg = msg ?? game.i18n.localize(`DL.AutoFail${actionType.capitalize()}s`)
ui.notifications.error(msg)
Expand All @@ -42,8 +42,7 @@ export class DLAfflictions {

static async clearAfflictions(actor) {
if (!actor) return
const afflictions = actor
.getEmbeddedCollection('ActiveEffect')
const afflictions = Array.from(actor.allApplicableEffects())
.filter(e => e.statuses.size > 0)
.map(e => e._id)
await actor.deleteEmbeddedDocuments('ActiveEffect', afflictions)
Expand Down
15 changes: 10 additions & 5 deletions src/module/active-effects/effects.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,16 @@
* @param {MouseEvent} event The left-click event on the effect control
* @param {Actor|Item} owner The owning entity which manages this effect
*/
import { DemonlordActor } from "../actor/actor";
import {calcEffectRemainingRounds, calcEffectRemainingSeconds, calcEffectRemainingTurn} from "../combat/combat";
import { DemonlordItem } from "../item/item";
import {i18n} from "../utils/utils";

export async function onManageActiveEffect(event, owner) {
event.preventDefault()
const a = event.currentTarget
const li = a.closest('li')
const effect = li.dataset.effectId ? owner.effects.get(li.dataset.effectId) : null
const effect = li.dataset.effectId ? (owner instanceof DemonlordActor ? Array.from(owner.allApplicableEffects()).find(e => e._id === li.dataset.effectId) : owner.effects.get(li.dataset.effectId)) : null
const isCharacter = owner.type === 'character'
switch (a.dataset.action) {
case 'create':
Expand Down Expand Up @@ -43,34 +45,37 @@ export async function onManageActiveEffect(event, owner) {
* @param {Integer} showControls What controls to show
* @return {object} Data for rendering
*/
export function prepareActiveEffectCategories(effects, showCreateButtons = false, showControls = 3) {
export function prepareActiveEffectCategories(effects, showCreateButtons = false, ownerIsItem = false) {
// Define effect header categories
let categories = {
temporary: {
type: 'temporary',
name: 'Temporary Effects',
showCreateButtons: showCreateButtons,
showControls: showControls,
showControls: 3,
effects: [],
},
passive: {
type: 'passive',
name: 'Passive Effects',
showCreateButtons: showCreateButtons,
showControls: showControls,
showControls: 3,
effects: [],
},
inactive: {
type: 'inactive',
name: 'Inactive Effects',
showCreateButtons: showCreateButtons,
showControls: showControls,
showControls: 3,
effects: [],
},
}

// Iterate over active effects, classifying them into categories.
for (let e of effects) {
// First thing, set notEditable flag on effects that come from items where !ownerIsItem
e.flags.notDeletable = e.flags.notDeletable ?? (e.parent instanceof DemonlordItem && !ownerIsItem)

// Also set the 'remaining time' in seconds or rounds depending on if in combat
if (e.isTemporary && (e.duration.seconds || e.duration.rounds || e.duration.turns)) {
if (game.combat) {
Expand Down
3 changes: 2 additions & 1 deletion src/module/active-effects/item-effects.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { DemonlordActor } from '../actor/actor'
import { plusify } from '../utils/utils'

export const addEffect = (key, value, priority) => ({
Expand Down Expand Up @@ -52,7 +53,7 @@ const falsyChangeFilter = change => Boolean(change.value)

export class DLActiveEffects {
static async removeEffectsByOrigin(doc, originID) {
const toDel = doc.getEmbeddedCollection('ActiveEffect').filter(effect => effect.data?.origin?.includes(originID))
const toDel = (doc instanceof DemonlordActor ? Array.from(doc.allApplicableEffects()) : doc.effects).filter(effect => effect?.origin?.includes(originID))

const promises = []
for await (const e of toDel) {
Expand Down
84 changes: 62 additions & 22 deletions src/module/actor/actor.js
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ export class DemonlordActor extends Actor {

// We can reapply some active effects if we know they happened
// We're copying what it's done in applyActiveEffects
const effectChanges = this.effects.reduce((changes, e) => {
const effectChanges = Array.from(this.allApplicableEffects()).reduce((changes, e) => {
if (e.disabled || e.isSuppressed) return changes
return changes.concat(e.changes.map(c => {
c = foundry.utils.duplicate(c)
Expand Down Expand Up @@ -191,23 +191,63 @@ export class DemonlordActor extends Actor {
if (result !== null) this.overrides[change.key] = result
}

// WIP: Adjust size here
// for (let change of effectChanges.filter(e => e.key.includes("size"))) {
// let size = change.value
// let newSize = 0
// Adjust size here
const originalSize = this._source.system.characteristics.size
let modifiedSize = 0
let newSize = "1"
if (originalSize.includes("/")) {
const [numerator, denominator] = originalSize.split("/")
modifiedSize = parseInt(numerator) / parseInt(denominator)
} else {
modifiedSize = parseInt(originalSize)
}
for (let change of effectChanges.filter(e => e.key.includes("size"))) {
let sizeMod = 0

if (change.value.includes("/")) {
const [numerator, denominator] = change.value.split("/")
sizeMod = parseInt(numerator) / parseInt(denominator)
} else {
sizeMod = parseInt(change.value)
}

// if (size.includes("/")) {
// const [numerator, denominator] = size.split("/")
// newSize = parseInt(numerator) / parseInt(denominator)
// } else {
// newSize = parseInt(size)
// }
switch (change.mode) {
case 0: // CUSTOM
break
case 1: // MULTIPLY
modifiedSize *= sizeMod
break
case 2: // ADD
modifiedSize += sizeMod
break
case 3: // DOWNGRADE
modifiedSize = Math.min(modifiedSize, sizeMod)
break
case 4: // UPGRADE
modifiedSize = Math.max(modifiedSize, sizeMod)
break
case 5: // OVERRIDE
modifiedSize = sizeMod
break
}

// change.value = newSize.toString()
// Calculate string if fraction
if (modifiedSize >= 1) {
newSize = Math.floor(modifiedSize).toString()
} else if (modifiedSize >= 0.5) {
newSize = "1/2";
} else if (modifiedSize >= 0.25) {
newSize = "1/4";
} else if (modifiedSize >= 0.125) {
newSize = "1/8";
} else if (modifiedSize >= 0.0625) {
newSize = "1/16";
} else if (modifiedSize >= 0.03125) {
newSize = "1/32";
}
}

// const result = change.effect.apply(this, change)
// if (result !== null) this.overrides[change.key] = result
// }
this.system.characteristics.size = newSize
}

/* -------------------------------------------- */
Expand Down Expand Up @@ -720,14 +760,14 @@ export class DemonlordActor extends Actor {
let uses = talent.system.uses?.value || 0
const usesmax = talent.system.uses?.max || 0
if (usesmax > 0 && uses < usesmax)
return await talent.update({'data.uses.value': ++uses, 'data.addtonextroll': setActive}, {parent: this})
return await talent.update({'system.uses.value': ++uses, 'system.addtonextroll': setActive}, {parent: this})
}

async deactivateTalent(talent, decrement = 0, onlyTemporary = false) {
if (onlyTemporary && !talent.system.uses?.max) return
let uses = talent.system.uses?.value || 0
uses = Math.max(0, uses - decrement)
return await talent.update({'data.uses.value': uses, 'data.addtonextroll': false}, {parent: this})
return await talent.update({'system.uses.value': uses, 'system.addtonextroll': false}, {parent: this})
}

/* -------------------------------------------- */
Expand All @@ -736,15 +776,15 @@ export class DemonlordActor extends Actor {
await Promise.all(game.user.targets.map(async target => {
const currentDamage = parseInt(target.actor.system.characteristics.health.value)
await target?.actor.update({
'data.characteristics.health.value': currentDamage + damage,
'system.characteristics.health.value': currentDamage + damage,
})
}))
}

async restActor() {
// Reset talent and spell uses
const talentData = this.items.filter(i => i.type === 'talent').map(t => ({_id: t.id, 'data.uses.value': 0}))
const spellData = this.items.filter(i => i.type === 'spell').map(s => ({_id: s.id, 'data.castings.value': 0}))
const talentData = this.items.filter(i => i.type === 'talent').map(t => ({_id: t.id, 'system.uses.value': 0}))
const spellData = this.items.filter(i => i.type === 'spell').map(s => ({_id: s.id, 'system.castings.value': 0}))

await this.updateEmbeddedDocuments('Item', [...talentData, ...spellData])
await this.applyHealing(true)
Expand Down Expand Up @@ -786,7 +826,7 @@ export class DemonlordActor extends Actor {
}

return this.update({
'data.characteristics.health.value': newHp
'system.characteristics.health.value': newHp
})
}

Expand All @@ -801,7 +841,7 @@ export class DemonlordActor extends Actor {
const rank = s.system.rank
const currentMax = s.system.castings.max
const newMax = CONFIG.DL.spelluses[power]?.[rank] ?? 0
if (currentMax !== newMax) diff.push({_id: s.id, 'data.castings.max': newMax})
if (currentMax !== newMax) diff.push({_id: s.id, 'system.castings.max': newMax})
})
if (diff.length > 0) return await this.updateEmbeddedDocuments('Item', diff)
}
Expand Down
10 changes: 5 additions & 5 deletions src/module/actor/sheets/base-actor-sheet.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ export default class DLBaseActorSheet extends ActorSheet {
actor: this.actor,
system: this.actor.system,
effects: true,
generalEffects: prepareActiveEffectCategories(this.actor.effects, true),
generalEffects: prepareActiveEffectCategories(Array.from(this.actor.allApplicableEffects()), true),
effectsOverview: buildOverview(this.actor),
flags: this.actor.flags,
}
Expand Down Expand Up @@ -60,7 +60,7 @@ export default class DLBaseActorSheet extends ActorSheet {
const actorData = sheetData.actor

const actorHasChangeBool = (actor, key) => {
return actor.getEmbeddedCollection('ActiveEffect').filter(e => !e.disabled && e.changes.filter(c => c.key === key && c.value === '1').length > 0).length > 0
return Array.from(actor.allApplicableEffects()).filter(e => !e.disabled && e.changes.filter(c => c.key === key && c.value === '1').length > 0).length > 0
}

const noAttacks = actorHasChangeBool(actorData, 'system.maluses.noAttacks')
Expand Down Expand Up @@ -242,7 +242,7 @@ export default class DLBaseActorSheet extends ActorSheet {
}
if (['action', 'afflictions', 'damage'].includes(div.dataset.type)) {
const type = capitalize(div.dataset.type)
const k = 'data.afflictionsTab.hideAction' + type
const k = 'system.afflictionsTab.hideAction' + type
const v = !this.actor.system.afflictionsTab[`hide${type}`]
await this.actor.update({[k]: v})
}
Expand Down Expand Up @@ -279,7 +279,7 @@ export default class DLBaseActorSheet extends ActorSheet {
const _itemwear = async (ev, bool) => {
const id = $(ev.currentTarget).closest('[data-item-id]').data('itemId')
const item = this.actor.items.get(id)
await item.update({'data.wear': bool}, {parent: this.actor})
await item.update({'system.wear': bool}, {parent: this.actor})
}
html.find('.item-wear').click(async ev => await _itemwear(ev, false))
html.find('.item-wearoff').click(async ev => await _itemwear(ev, true))
Expand Down Expand Up @@ -314,7 +314,7 @@ export default class DLBaseActorSheet extends ActorSheet {
const usesmax = +item.system.castings.max
if (ev.button == 0) uses = uses < usesmax ? uses + 1 : 0
else if (ev.button == 2) uses = uses > 0 ? uses - 1 : 0
await item.update({'data.castings.value': uses}, {parent: this.actor})
await item.update({'system.castings.value': uses}, {parent: this.actor})
})

// Rollable Attributes
Expand Down
22 changes: 11 additions & 11 deletions src/module/actor/sheets/character-sheet.js
Original file line number Diff line number Diff line change
Expand Up @@ -41,29 +41,29 @@ export default class DLCharacterSheet extends DLBaseActorSheet {

// Effects categories
data.ancestryEffects = prepareActiveEffectCategories(
this.actor.effects.filter(effect => effect.flags?.sourceType === 'ancestry'),
Array.from(this.actor.allApplicableEffects()).filter(effect => effect.flags?.sourceType === 'ancestry'),
)
delete data.ancestryEffects.temporary

data.pathEffects = prepareActiveEffectCategories(
this.actor.effects.filter(effect => effect.flags?.sourceType === 'path'),
Array.from(this.actor.allApplicableEffects()).filter(effect => effect.flags?.sourceType === 'path'),
)
delete data.pathEffects.temporary

data.talentEffects = prepareActiveEffectCategories(
this.actor.effects.filter(effect => effect.flags?.sourceType === 'talent'),
Array.from(this.actor.allApplicableEffects()).filter(effect => effect.flags?.sourceType === 'talent'),
)
data.spellEffects = prepareActiveEffectCategories(
this.actor.effects.filter(effect => effect.flags?.sourceType === 'spell'),
Array.from(this.actor.allApplicableEffects()).filter(effect => effect.flags?.sourceType === 'spell'),
)
data.itemEffects = prepareActiveEffectCategories(
this.actor.effects.filter(effect => ['armor', 'weapon', 'item'].indexOf(effect.flags?.sourceType) >= 0),
Array.from(this.actor.allApplicableEffects()).filter(effect => ['armor', 'weapon', 'item'].indexOf(effect.flags?.sourceType) >= 0),
)
data.itemEffects = prepareActiveEffectCategories(
this.actor.effects.filter(effect => effect.flags?.sourceType === 'creaturerole'),
Array.from(this.actor.allApplicableEffects()).filter(effect => effect.flags?.sourceType === 'creaturerole'),
)
data.itemEffects = prepareActiveEffectCategories(
this.actor.effects.filter(effect => effect.flags?.sourceType === 'relic'),
Array.from(this.actor.allApplicableEffects()).filter(effect => effect.flags?.sourceType === 'relic'),
)
this.prepareItems(data)
return data
Expand Down Expand Up @@ -179,7 +179,7 @@ export default class DLCharacterSheet extends DLBaseActorSheet {

await actor
.update({
'data.characteristics.editbar': actor.system.characteristics.editbar,
'system.characteristics.editbar': actor.system.characteristics.editbar,
})
.then(_ => this.render())
})
Expand All @@ -202,7 +202,7 @@ export default class DLCharacterSheet extends DLBaseActorSheet {
if (value <= 0) value = 0
else value--
}
await this.actor.update({ 'data.characteristics.insanity.value': value }).then(_ => this.render())
await this.actor.update({ 'system.characteristics.insanity.value': value }).then(_ => this.render())
})

// Corruption bar click
Expand All @@ -216,7 +216,7 @@ export default class DLCharacterSheet extends DLBaseActorSheet {
if (value <= 0) value = 0
else value--
}
await this.actor.update({ 'data.characteristics.corruption.value': value }).then(_ => this.render())
await this.actor.update({ 'system.characteristics.corruption.value': value }).then(_ => this.render())
})

// Health bar fill
Expand Down Expand Up @@ -281,7 +281,7 @@ export default class DLCharacterSheet extends DLBaseActorSheet {
html
.find('.religion-edit')
.click(async _ =>
await this.actor.update({ 'data.religion.edit': !this.actor.system.religion.edit }).then(() => this.render()),
await this.actor.update({ 'system.religion.edit': !this.actor.system.religion.edit }).then(() => this.render()),
)

// Ammo uses
Expand Down
2 changes: 1 addition & 1 deletion src/module/actor/sheets/creature-sheet.js
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ export default class DLCreatureSheet extends DLBaseActorSheet {
const actorData = sheetData.actor

const actorHasChangeBool = (actor, key) => {
return actor.getEmbeddedCollection('ActiveEffect').filter(e => !e.disabled && e.changes.filter(c => c.key === key && c.value === '1').length > 0).length > 0
return Array.from(actor.allApplicableEffects()).filter(e => !e.disabled && e.changes.filter(c => c.key === key && c.value === '1').length > 0).length > 0
}

const noSpecialAttacks = actorHasChangeBool(actorData, 'system.maluses.noSpecialAttacks')
Expand Down
Loading

0 comments on commit 5ae1fae

Please sign in to comment.