/* globals warpgate */ import { moduleName } from '../globals.js'; import { PowerEffect } from './basePowers.js'; import { ArcaneProtectionEffect } from './arcaneProtection.js'; import { BanishEffect } from './banish.js'; import { BarrierEffect } from './barrier.js'; import { BeastFriendEffect } from './beastFriend.js'; import { BlastEffect } from './blast.js'; import { BlindEffect } from './blind.js'; import { BoltEffect } from './bolt.js'; import { BurrowEffect } from './burrow.js'; import { BoostLowerTraitEffect } from './boostLowerTrait.js'; import { BurstEffect } from './burst.js'; import { ConfusionEffect } from './confusion.js'; import { CurseEffect } from './curse.js'; import { DamageFieldEffect } from './damageField.js'; import { DarksightEffect } from './darksight.js'; import { DeflectionEffect } from './deflection.js'; import { DetectConcealArcanaEffect } from './detectConcealArcana.js'; class DisguiseEffect extends PowerEffect { get name() { return 'Disguise'; } get icon() { return 'icons/equipment/head/mask-carved-wood-white.webp'; } get duration() { return 100; } get basePowerPoints() { return 2; } get isTargeted() { return true; } get hasAdditionalRecipients() { return true; } get additionalRecipientCost() { return 1; } get modifiers() { return [...super.modifiers, { name: 'Size', value: 1, id: 'size', epic: false, effect: false }]; } get description() { const size = this.data.mods.has('size') ? 'of the same size as' : 'within two sizes of'; return ( super.description + `

Assume the appearance of another person ${size} the recipient. Anyone who has cause to doubt the disguise may make a Notice roll at ${this.data.raise ? -4 : -4} as a free action to see through the disguise.

` ); } } const PowerClasses = { 'arcane-protection': ArcaneProtectionEffect, banish: BanishEffect, barrier: BarrierEffect, 'beast-friend': BeastFriendEffect, blast: BlastEffect, blind: BlindEffect, bolt: BoltEffect, 'boostlower-trait': BoostLowerTraitEffect, 'boost-lower-trait': BoostLowerTraitEffect, 'boost-trait': BoostLowerTraitEffect, burrow: BurrowEffect, burst: BurstEffect, 'conceal-arcana': DetectConcealArcanaEffect, confusion: ConfusionEffect, curse: CurseEffect, 'damage-field': DamageFieldEffect, darksight: DarksightEffect, deflection: DeflectionEffect, 'detect-arcana': DetectConcealArcanaEffect, 'detect-conceal-arcana': DetectConcealArcanaEffect, 'detectconceal-arcana': DetectConcealArcanaEffect, disguise: DisguiseEffect, 'lower-trait': BoostLowerTraitEffect, }; /* ---------------------------------------------------------------- */ export async function powerEffectManagementHook(effect, data, userId) { if (game.user.id !== userId) { return; } const maintId = effect.getFlag(moduleName, 'maintainingId'); 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 efct of effects) { mutation.embedded.ActiveEffect[efct.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 = {}) { const token = 'token' in options ? options.token : null; if (token === undefined || token === null) { ui.notifications.error('Please select one token to be the caster'); return; } const targets = 'targets' in options ? Array.from(options.targets) : []; const item = 'item' in options ? options.item : null; const swid = options?.name || item?.system.swid || null; if (swid in PowerClasses) { const runner = new PowerClasses[swid](token, targets); runner.render(); return; } ui.notifications.error(`No power effect found for ${swid}`); }