additional power refinement

This commit is contained in:
Mike Bloy 2024-04-30 23:01:42 -05:00
parent 2aa7af28a5
commit 592d0c5406
3 changed files with 83 additions and 31 deletions

View File

@ -13,11 +13,13 @@ export default [
globals: { globals: {
...globals.browser, ...globals.browser,
ActiveEffect: false, ActiveEffect: false,
canvas: false,
ChatMessage: false, ChatMessage: false,
ColorAdjustmentsSamplerShader: false, ColorAdjustmentsSamplerShader: false,
CONFIG: false, CONFIG: false,
deepClone: false, deepClone: false,
foundry: false, foundry: false,
fromUuid: false,
game: false, game: false,
Hooks: false, Hooks: false,
randomID: false, randomID: false,

View File

@ -1,4 +1,6 @@
import { moduleName, log } from './globals.js' import { moduleName } from './globals.js'
const MAINTAIN_ICON = 'icons/magic/symbols/runes-star-blue.webp'
class PowerEffect { class PowerEffect {
constructor (token, targets) { constructor (token, targets) {
@ -26,7 +28,9 @@ class PowerEffect {
createEffectDocument (icon, name, changes = null) { createEffectDocument (icon, name, changes = null) {
if (changes === null) { if (changes === null) {
changes = [] changes = [
{ key: 'flags.swade-mb-helpers.hasPower', value: 1,
priority: 0, mode: foundry.CONST.ACTIVE_EFFECT_MODES.OVERRIDE } ]
} }
return { return {
icon, icon,
@ -46,6 +50,21 @@ class PowerEffect {
} }
} }
async applyActiveEffects (token, effectDocuments) {
const mutation = {
embedded: { ActiveEffect: {} }
}
const mutateOptions = {
permanent: true,
description: `${this.source.name} applying ${effectDocuments[effectDocuments.length - 1]?.name} to ${token.name}`
}
for (const effectDocument of effectDocuments) {
mutation.embedded.ActiveEffect[effectDocument.name] = effectDocument
}
await warpgate.mutate(token.document, mutation, {}, mutateOptions)
}
get name () { return 'Unknown Power' } get name () { return 'Unknown Power' }
get icon () { return 'icons/magic/symbols/question-stone-yellow.webp' } get icon () { return 'icons/magic/symbols/question-stone-yellow.webp' }
get duration () { return 5 } get duration () { return 5 }
@ -57,7 +76,7 @@ class PowerEffect {
{ name: 'Glow', { name: 'Glow',
id: 'glow', id: 'glow',
value: 1, value: 1,
advanced: false, epic: false,
effect: true, effect: true,
icon: 'icons/magic/light/orb-shadow-blue.webp', icon: 'icons/magic/light/orb-shadow-blue.webp',
changes: [ { key: '@Skill{Stealth}[system.die.modifier]', value: -2, changes: [ { key: '@Skill{Stealth}[system.die.modifier]', value: -2,
@ -66,7 +85,7 @@ class PowerEffect {
{ name: 'Shroud', { name: 'Shroud',
id: 'shroud', id: 'shroud',
value: 1, value: 1,
advanced: false, epic: false,
effect: true, effect: true,
icon: 'icons/magic/perception/shadow-stealth-eyes-purple.webp', icon: 'icons/magic/perception/shadow-stealth-eyes-purple.webp',
changes: [ { key: '@Skill{Stealth}[system.die.modifier]', value: 1, changes: [ { key: '@Skill{Stealth}[system.die.modifier]', value: 1,
@ -75,7 +94,7 @@ class PowerEffect {
{ name: 'Hinder', { name: 'Hinder',
id: 'hinder', id: 'hinder',
value: 1, value: 1,
advanced: false, epic: false,
effect: true, effect: true,
icon: 'icons/magic/control/debuff-chains-shackle-movement-red.webp', icon: 'icons/magic/control/debuff-chains-shackle-movement-red.webp',
changes: [ { key: 'system.stats.speed.value', value: -2, changes: [ { key: 'system.stats.speed.value', value: -2,
@ -84,7 +103,7 @@ class PowerEffect {
{ name: 'Hurry', { name: 'Hurry',
id: 'hurry', id: 'hurry',
value: 1, value: 1,
advanced: false, epic: false,
effect: true, effect: true,
icon: 'icons/skills/movement/feet-winged-sandals-tan.webp', icon: 'icons/skills/movement/feet-winged-sandals-tan.webp',
changes: [ { key: 'system.stats.speed.value', value: 2, changes: [ { key: 'system.stats.speed.value', value: 2,
@ -115,7 +134,7 @@ class PowerEffect {
data.push({ data.push({
type: 'checkbox', type: 'checkbox',
label: ( label: (
`${mod.advanced ? '⭐ ' : ''}${mod.name} ` + `${mod.epic ? '⭐ ' : ''}${mod.name} ` +
`(${mod.value >= 0 ? '+' : ''}${mod.value})` `(${mod.value >= 0 ? '+' : ''}${mod.value})`
), ),
}) })
@ -168,7 +187,7 @@ class PowerEffect {
} }
} }
async createSecondaryEffects () { async createSecondaryEffects (maintId) {
const docs = [] const docs = []
for (const mod of this.modifiers) { for (const mod of this.modifiers) {
if (this.data.mods.has(mod.id) && mod.effect) { if (this.data.mods.has(mod.id) && mod.effect) {
@ -178,6 +197,9 @@ class PowerEffect {
// turn // turn
doc.duration.rounds = 1 doc.duration.rounds = 1
doc.flags.swade.expiration = CONFIG.SWADE.CONST.STATUS_EFFECT_EXPIRATION.StartOfTurnAuto doc.flags.swade.expiration = CONFIG.SWADE.CONST.STATUS_EFFECT_EXPIRATION.StartOfTurnAuto
} else {
doc.duration.seconds = 594
doc.flags[moduleName].maintId = maintId
} }
docs.push(doc) docs.push(doc)
} }
@ -185,48 +207,51 @@ class PowerEffect {
return docs return docs
} }
async createPrimaryEffect () { async createPrimaryEffect (maintId) {
const doc = this.createEffectDocument(this.icon, this.name, []) const doc = this.createEffectDocument(this.icon, this.name, [])
doc.flags[moduleName].maintId = maintId
doc.duration.seconds = 594
return doc return doc
} }
async createMaintainEffect () { async createMaintainEffect (maintId) {
const doc = this.createEffectDocument( const doc = this.createEffectDocument(
this.icon, `Maintaining ${this.name}`, []) MAINTAIN_ICON, `Maintaining ${this.name}`, [])
doc.duration.rounds = this.duration doc.duration.rounds = this.duration
doc.flags.swade.expiration = CONFIG.SWADE.CONST.STATUS_EFFECT_EXPIRATION.StartOfTurnPrompt doc.flags.swade.expiration = CONFIG.SWADE.CONST.STATUS_EFFECT_EXPIRATION.StartOfTurnPrompt
doc.flags.swade.loseTurnOnHold = true doc.flags.swade.loseTurnOnHold = true
doc.flags[moduleName].maintainingId = maintId
doc.flags[moduleName].targetIds = this.targets.map(t => t.id)
return doc return doc
} }
// eslint-disable-next-line no-unused-vars
async secondaryDocsForTarget(docs, target) { async secondaryDocsForTarget(docs, target) {
return deepClone(docs) return deepClone(docs)
} }
async primaryDocForTarget(doc, ids, target) { // eslint-disable-next-line no-unused-vars
async primaryDocForTarget(doc, target) {
const newDoc = deepClone(doc) const newDoc = deepClone(doc)
newDoc.flags[moduleName].secondaryDocIds = deepClone(ids)
return newDoc return newDoc
} }
async apply () { async apply () {
const secondaryDocs = await this.createSecondaryEffects() const maintId = randomID()
const primaryDoc = await this.createPrimaryEffect() const secondaryDocs = await this.createSecondaryEffects(maintId)
const maintainDoc = await this.createMaintainEffect() const primaryDoc = await this.createPrimaryEffect(maintId)
const primaryIds = [] const maintainDoc = await this.createMaintainEffect(maintId)
for (const target of this.targets) { for (const target of this.targets) {
const created = await target.actor.createEmbeddedDocuments( const targetDocs = await this.secondaryDocsForTarget(secondaryDocs, target)
'ActiveEffect', await this.secondaryDocsForTarget(secondaryDocs, target))
const createdIds = created.map(c => c.uuid)
if (this.duration > 0 || this.usePrimaryEffect) { if (this.duration > 0 || this.usePrimaryEffect) {
const pCreated = await target.actor.createEmbeddedDocuments( targetDocs.push(await this.primaryDocForTarget(primaryDoc, target))
'ActiveEffect', [await this.primaryDocForTarget(primaryDoc, createdIds, target)]) }
primaryIds.push(pCreated[0].uuid) if (targetDocs.length > 0) {
await this.applyActiveEffects(target, targetDocs)
} }
} }
if (this.duration > 0) { if (this.duration > 0) {
maintainDoc.flags[moduleName].secondaryDocIds = deepClone(primaryIds) await this.applyActiveEffects(this.source, [maintainDoc])
await this.source.actor.createEmbeddedDocuments('ActiveEffect', [maintainDoc])
} }
} }

View File

@ -1,12 +1,37 @@
import { log, moduleName } from './globals.js' import { moduleName } from './globals.js'
import { PowerClasses } from './allPowers.js' import { PowerClasses } from './allPowers.js'
export async function powerEffectManagementHook(effect, data, userId) { export async function powerEffectManagementHook(effect, data, userId) {
log('ids:', effect.getFlag(moduleName, 'secondaryDocIds')) if (game.user.id !== userId) {
log('Power Effect Management') return
log('effect:', effect) }
log('data:', data) const maintId = effect.getFlag(moduleName, 'maintainingId')
log('userId:', userId) if (!maintId) {
return
}
const mutateOptions = {
permanent: true,
comparisonKeys: {
ActiveEffect: 'id'
}
}
const targetIds = effect.getFlag(moduleName, 'targetIds') || []
for (const targetId of targetIds) {
const mutation = {
embedded: { ActiveEffect: {} }
}
const target = canvas.tokens.get(targetId)
if (!target) {
continue
}
const effects = target.actor.effects.filter(
e => e.getFlag(moduleName, 'maintId') === maintId)
for (const effect of effects) {
mutation.embedded.ActiveEffect[effect.id] = warpgate.CONST.DELETE
}
mutateOptions.description = `${effect.parent.name} is no longer ${effect.name} on ${target.name}`
await warpgate.mutate(target.document, mutation, {}, mutateOptions)
}
} }
export async function powers (options = {}) { export async function powers (options = {}) {