powers v2 part 1

This commit is contained in:
Mike Bloy 2024-04-29 00:04:14 -05:00
parent b4089e4b71
commit 9333be95fd
4 changed files with 250 additions and 104 deletions

View File

@ -12,17 +12,19 @@ export default [
languageOptions: { languageOptions: {
globals: { globals: {
...globals.browser, ...globals.browser,
ActiveEffect: true, ActiveEffect: false,
ChatMessage: true, ChatMessage: false,
ColorAdjustmentsSamplerShader: true, ColorAdjustmentsSamplerShader: false,
CONFIG: true, CONFIG: false,
foundry: true, deepClone: false,
game: true, foundry: false,
Hooks: true, game: false,
socketlib: true, Hooks: false,
ui: true, randomID: false,
VisionMode: true, socketlib: false,
warpgate: true, ui: false,
VisionMode: false,
warpgate: false,
} }
} }
}, },

225
scripts/allPowers.js Normal file
View File

@ -0,0 +1,225 @@
import { moduleName, log } from './globals.js'
class PowerEffect {
constructor (token, targets) {
this.source = token
this.targets = targets
this.data = {}
}
static async applyActiveEffects (token, effectDocuments) {
const mutation = {
embedded: { ActiveEffect: {} }
}
const mutateOptions = {
permanent: true,
description: effectDocuments[effectDocuments.length - 1]?.name
}
for (const effectDocument of effectDocuments) {
mutation.embedded.ActiveEffect[effectDocument.name] = effectDocument
}
await warpgate.mutate(token.document, mutation, {}, mutateOptions)
}
static async getStatus (label, name, favorite = true) {
const effect = deepClone(
CONFIG.statusEffects.find(se => se.label === label))
effect.name = ('name' in effect ? effect.name : effect.label)
if (!('flags' in effect)) {
effect.flags = {}
}
if (favorite) {
if (!('swade' in effect.flags)) {
effect.flags.swade = {}
}
effect.flags.swade.favorite = true
}
effect.flags.core = { statusId: effect.id }
return effect
}
static createEffectDocument (icon, name, changes = null) {
if (changes === null) {
changes = []
}
return {
icon,
name,
changes,
description: `<p>From <strong>${this.source.name}</strong> casting <em>${this.name}</em></p>`,
flags: {
[moduleName]: {
powerEffect: true
}, swade: {
favorite: true,
expiration: CONFIG.SWADE.CONST.STATUS_EFFECT_EXPIRATION.EndOfTurnPrompt
}
}
}
}
get name () { return 'Unknown Power' }
get icon () { return 'icons/magic/symbols/question-stone-yellow.webp' }
get duration () { return 5 }
get basePowerPoints () { return 0 }
get powerPoints () { return this.basePowerPoints }
get modifiers () {
return [
{ name: 'Glow',
id: 'glow',
value: 1,
advanced: false,
effect: true,
icon: 'icons/magic/light/orb-shadow-blue.webp',
changes: [ { key: '@Skill{Stealth}[system.die.modifier', value: -2,
priority: 0, mode: foundry.CONST.ACTIVE_EFFECT_MODES.ADD } ]
},
{ name: 'Shroud',
id: 'shroud',
value: 1,
advanced: false,
effect: true,
icon: 'icons/magic/perception/shadow-stealth-eyes-purple.webp',
changes: [ { key: '@Skill{Stealth}[system.die.modifier', value: 1,
priority: 0, mode: foundry.CONST.ACTIVE_EFFECT_MODES.ADD } ]
},
{ name: 'Hinder',
id: 'hinder',
value: 1,
advanced: false,
effect: true,
icon: 'icons/magic/control/debuff-chains-shackle-movement-red.webp',
changes: [ { key: 'system.stats.speed.value', value: -2,
priority: 0, mode: foundry.CONST.ACTIVE_EFFECT_MODES.ADD } ]
},
{ name: 'Hurry',
id: 'hurry',
value: 1,
advanced: false,
effect: true,
icon: 'icons/skills/movement/feet-winged-sandals-tan.webp',
changes: [ { key: 'system.stats.speed.value', value: 2,
priority: 0, mode: foundry.CONST.ACTIVE_EFFECT_MODES.ADD } ]
},
]
}
get menuData () {
return {
inputs: this.menuInputs,
buttons: this.menuButtons,
}
}
get menuInputs () {
const data = [
{ type: 'header', label: `${this.name} Effect` },
{ type: 'info', label: `Apply ${this.name} Effect` },
]
if (this.targets.length > 0) {
data.push({
type: 'info',
label: `<strong>Targets:</strong> ${this.targets.map(t => t.name).join(',')}`
})
}
for (const mod of this.modifiers) {
data.push({
type: 'checkbox',
label: (
`${mod.advanced ? '⭐ ' : ''}${mod.name} ` +
`(${mod.value >= 0 ? '+' : ''}${mod.value}`
),
})
}
return data
}
get menuButtons () {
const data = [
{ label: 'Apply', value: 'apply' },
{ label: 'Apply with Raise', value: 'raise' },
{ label: 'Cancel', value: 'cancel' }
]
return data
}
get menuOptions () {
return {
title: `${this.name} Effect`,
defaultButton: 'Cancel',
options: {}
}
}
async powerEffect () {
const { buttons, inputs } = await warpgate.menu(
this.menuData, this.menuOptions
)
if (buttons && buttons !== 'cancel') {
this.data.button = buttons
this.data.values = inputs
await this.parseValues()
await this.apply()
await this.sideEffects()
}
}
async parseValues () {
log(this.data.values)
log(this.data.choice)
this.data.rawValues = deepClone(this.data.values)
this.data.raise = this.data.button === 'raise'
for (let i = 0; i < 3; i++) {
this.data.values.shift()
}
this.data.mods = new Set()
for (const mod of this.modifiers) {
const modEnabled = this.data.values.shift()
if (modEnabled) {
this.data.mods.add(mod.id)
}
}
}
modifierEffects (helperId) {
const docs = []
for (const mod of this.modifiers) {
if (this.data.mods.has(mod.id) && mod.effect) {
const doc = this.createEffectDocument(mod.icon, mod.name, mod.changes)
doc.flags[moduleName].helperId = helperId
docs.push(doc)
}
}
return docs
}
async apply () {
}
async sideEffects () {
}
}
class ActiveEffectPower extends PowerEffect {
async secondaryDocuments (helperId) {
const secondaryDocs = this.modiferEffects(helperId)
return secondaryDocs
}
async apply () {
const helperId = randomID()
const secondaryDocs = this.secondaryDocuments(helperId)
const primaryDocument = this.primaryDocument(helperId)
}
}
class BurrowEffect extends ActiveEffectPower {
get name () { return 'Burrow' }
get duration () { return 5 }
get icon () { return 'icons/magic/earth/projectile-stone-landslide.webp' }
}
export const PowerClasses = {
burrow: BurrowEffect
}

View File

@ -3,6 +3,7 @@ import { requestTokenRoll } from './helpers.js'
import { preDamageRollModifiers, preTraitRollModifiers } from './rollHelpers.js' import { preDamageRollModifiers, preTraitRollModifiers } from './rollHelpers.js'
import { shapeChangeOnDismiss } from './powerEffects.js' import { shapeChangeOnDismiss } from './powerEffects.js'
import { log, module } from './globals.js' import { log, module } from './globals.js'
import { powerEffectManagementHook } from './powers.js'
function _checkModule (name) { function _checkModule (name) {
if (!game.modules.get(name)?.active && game.user.isGM) { if (!game.modules.get(name)?.active && game.user.isGM) {
@ -91,6 +92,7 @@ Hooks.on('init', () => {
Hooks.on('swadePreRollAttribute', preTraitRollModifiers) Hooks.on('swadePreRollAttribute', preTraitRollModifiers)
Hooks.on('swadePreRollSkill', preTraitRollModifiers) Hooks.on('swadePreRollSkill', preTraitRollModifiers)
Hooks.on('swadeRollDamage', preDamageRollModifiers) Hooks.on('swadeRollDamage', preDamageRollModifiers)
Hooks.on('deleteActiveEffect', powerEffectManagementHook)
Hooks.on('ready', () => { Hooks.on('ready', () => {
_checkModule('warpgate') _checkModule('warpgate')

View File

@ -1,3 +1,12 @@
import { PowerClasses } from './allPowers.js'
export async function powerEffectManagementHook(effect, data, userId) {
console.log('Power Effect Management')
console.log(effect)
console.log(data)
console.log(userId)
}
export async function powers (options = {}) { export async function powers (options = {}) {
const token = 'token' in options ? options.token : null const token = 'token' in options ? options.token : null
if (token === undefined || token === null) { if (token === undefined || token === null) {
@ -10,102 +19,10 @@ export async function powers (options = {}) {
const swid = options?.name || item?.system.swid || null const swid = options?.name || item?.system.swid || null
if (swid in PowerClasses) { if (swid in PowerClasses) {
const runner = new PowerClasses[name](token, targets) const runner = new PowerClasses[swid](token, targets)
runner.powerEffect() runner.powerEffect()
return return
} }
ui.notifications.error(`No power effect found for ${name}`) ui.notifications.error(`No power effect found for ${name}`)
} }
const PowerClasses = {
'burrow': BurrowEffect
}
class PowerEffect {
constructor (token, targets) {
this.source = token
this.targets = targets
this.modifiers = [
{name: 'Glow', id: 'glow', value: 1, advanced: false},
{name: 'Shroud', id: 'shroud', value: 1, advanced: false},
{name: 'Hinder', id: 'hinder', value: 1, advanced: false},
{name: 'Hurry', id: 'hurry', value: 1, advanced: false},
]
}
get name () { return 'Unknown Power' }
get icon () { return 'icons/magic/symbols/question-stone-yellow.webp' }
get duration () { return 5 }
get menuData () {
return {
inputs: this.menuInputs,
buttons: this.menuButtons,
}
}
get menuInputs () {
const data = [
{ type: 'header', label: `${this.name} Effect` },
{ type: 'info', label: `Apply ${this.name} Effect` },
]
if (this.targets.length > 0) {
data.push({
type: 'info',
label: `<strong>Targets:</strong> ${this.targets.map(t => t.name).join(',')}`
})
}
for (const mod of this.modifiers) {
data.push({
type: 'checkbox',
label: (
`${mod.advanced ? '⭐ ' : ''}${mod.name} ` +
`(${mod.value >= 0 ? '+' : ''}${mod.value}`
),
})
}
data.push({ type: 'header', label: '---------------' })
return data
}
get menuButtons () {
const data = [
{ label: 'Apply', value: 'apply' },
{ label: 'Apply with Raise', value: 'raise' },
{ label: 'Cancel', value: 'cancel' }
]
return data
}
get menuOptions () {
return {
title: `${this.name} Effect`,
defaultButton: 'Cancel',
options: {}
}
}
async powerEffect () {
const { buttons, inputs } = await warpgate.menu(
this.menuData, this.menuOptions
)
this.choice = buttons
this.values = inputs
if (this.choice && this.choice !== 'cancel') {
await this.parseValues()
await this.apply()
}
}
async parseValues () {
}
async applyResult () {
}
}
class BurrowEffect extends PowerEffect {
get name () { return 'Burrow' }
get duration () { return 5 }
get icon () { return 'icons/magic/earth/projectile-stone-landslide.webp' }
}