working summon
This commit is contained in:
parent
d7c30e3990
commit
19c1e697db
@ -1,9 +1,10 @@
|
||||
import { helpers } from './helpers.js'
|
||||
import { shim, log } from './shim.js'
|
||||
import { powerEffects } from './powerEffects.js'
|
||||
|
||||
export class api {
|
||||
static registerFunctions () {
|
||||
console.log('SWADE MB Helpers initialized')
|
||||
log('SWADE MB Helpers initialized')
|
||||
api.globals()
|
||||
}
|
||||
|
||||
@ -11,11 +12,11 @@ export class api {
|
||||
globalThis.swadeMBHelpers = {
|
||||
DEBUG: true,
|
||||
powerEffects,
|
||||
createEffectDocument: helpers.createEffectDocument,
|
||||
createEffectDocument: shim.createEffectDocument,
|
||||
createMutationWithEffect: helpers.createMutationWithEffect,
|
||||
defaultMutationOptions: helpers.defaultMutationOptions,
|
||||
getActorFolderByPath: helpers.getActorFolderByPath,
|
||||
getActorsInFolder: helpers.getActorsInFolder,
|
||||
getActorFolderByPath: shim.getActorFolderByPath,
|
||||
getActorsInFolder: shim.getActorsInFolder,
|
||||
runOnTargetOrSelectedTokens: helpers.runOnTargetOrSelectedTokens
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { CONST, shim } from './shim.js'
|
||||
import { CONST, log, shim } from './shim.js'
|
||||
|
||||
class PowerEffect {
|
||||
constructor (token, targets) {
|
||||
@ -40,7 +40,12 @@ class PowerEffect {
|
||||
}
|
||||
|
||||
async powerEffect () {
|
||||
this.prepMenu()
|
||||
try {
|
||||
await this.prepMenu()
|
||||
} catch (e) {
|
||||
log('Error preparing menu for power effect: ' + e.toString())
|
||||
return
|
||||
}
|
||||
const { buttons, inputs } = await shim.warpgateMenu(
|
||||
this.menuData, this.menuOptions)
|
||||
this.buttons = buttons
|
||||
@ -518,6 +523,132 @@ class SmiteEffect extends TargetedPowerEffect {
|
||||
}
|
||||
}
|
||||
|
||||
class SummonEffect extends PowerEffect {
|
||||
ICON = 'icons/magic/symbols/runes-triangle-blue.webp'
|
||||
|
||||
get actorFolder () {
|
||||
return 'Summonables'
|
||||
}
|
||||
|
||||
get name () {
|
||||
return 'Summon Creature'
|
||||
}
|
||||
|
||||
get durationRounds () {
|
||||
return 5
|
||||
}
|
||||
|
||||
async prepFolders () {
|
||||
const folders = []
|
||||
const folderNames = [
|
||||
this.actorFolder,
|
||||
`${this.actorFolder} - Default`,
|
||||
`${this.actorFolder}/Default`,
|
||||
`${this.actorFolder} - ${this.token.name}`,
|
||||
`${this.actorFolder} - ${this.token.actor.name}`,
|
||||
`${this.actorFolder}/${this.token.name}`,
|
||||
`${this.actorFolder}/${this.token.actor.name}`
|
||||
]
|
||||
for (const folderName of folderNames) {
|
||||
const folder = shim.getActorFolderByPath(folderName)
|
||||
if (folder) {
|
||||
log(`Found actor folder ${folderName}`)
|
||||
folders.push(folder)
|
||||
}
|
||||
}
|
||||
if (folders.length > 1) {
|
||||
folders.shift()
|
||||
}
|
||||
return folders
|
||||
}
|
||||
|
||||
async prepActors () {
|
||||
const folders = await this.prepFolders()
|
||||
const actors = {}
|
||||
for (const folder of folders) {
|
||||
const folderActors = shim.getActorsInFolder(folder)
|
||||
for (const key in folderActors) {
|
||||
actors[key] = folderActors[key]
|
||||
}
|
||||
}
|
||||
return actors
|
||||
}
|
||||
|
||||
async prepMenu () {
|
||||
this.menuData.inputs[1].label = `${this.token.name} is summoning...`
|
||||
const actors = await this.prepActors()
|
||||
if (Object.keys(actors).length < 1) {
|
||||
shim.notifications.error('No summonables found')
|
||||
throw new Error('No summonables found')
|
||||
}
|
||||
|
||||
function actorData (key) {
|
||||
return {
|
||||
value: actors[key].id,
|
||||
html: key
|
||||
}
|
||||
}
|
||||
|
||||
this.menuData.inputs.push({
|
||||
type: 'select',
|
||||
label: 'Creature to summon',
|
||||
options: Object.keys(actors).filter(
|
||||
k => !k.includes('_template')).sort().map(actorData)
|
||||
})
|
||||
this.menuData.inputs.push({
|
||||
type: 'number',
|
||||
label: 'Number to spawn (+half base cost per)',
|
||||
options: 1
|
||||
})
|
||||
}
|
||||
|
||||
async prepResult () {
|
||||
this.raise = (this.buttons === 'raise')
|
||||
this.actorId = (this.inputs[this.inputIndex])
|
||||
this.number = (this.inputs[this.inputIndex + 1])
|
||||
this.actor = shim.actors.get(this.actorId)
|
||||
this.icon = this.actor.prototypeToken.texture.src
|
||||
this.protoDoc = await this.actor.getTokenDocument()
|
||||
this.spawnOptions = {
|
||||
controllingActor: this.token.actor,
|
||||
duplicates: this.number,
|
||||
crosshairs: {
|
||||
icon: this.icon,
|
||||
label: `Summon ${this.actor.name}`,
|
||||
drawOutline: true,
|
||||
rememberControlled: true
|
||||
}
|
||||
}
|
||||
this.spawnMutation = {
|
||||
actor: {
|
||||
name: `${this.token.name}'s ${this.actor.name}`
|
||||
},
|
||||
token: {
|
||||
actorLink: false,
|
||||
name: `${this.token.name}'s ${this.protoDoc.name}`
|
||||
},
|
||||
embedded: { ActiveEffect: {} }
|
||||
}
|
||||
for (const effectDocument of this.effectDocs) {
|
||||
this.spawnMutation.embedded.ActiveEffect[effectDocument.name] = effectDocument
|
||||
}
|
||||
}
|
||||
|
||||
async applyResult () {
|
||||
await shim.warpgateSpawn(this.protoDoc, this.spawnMutation, {}, this.spawnOptions)
|
||||
}
|
||||
}
|
||||
|
||||
class SummonAllyEffect extends SummonEffect {
|
||||
get name () {
|
||||
return 'Summon Ally'
|
||||
}
|
||||
|
||||
get actorFolder () {
|
||||
return `${super.actorFolder}/Summon Ally`
|
||||
}
|
||||
}
|
||||
|
||||
const PowerClasses = {
|
||||
blind: BlindEffect,
|
||||
'boost/lower trait': BoostLowerTraitEffect,
|
||||
@ -529,7 +660,8 @@ const PowerClasses = {
|
||||
invisibility: InvisibilityEffect,
|
||||
'lower trait': BoostLowerTraitEffect,
|
||||
protection: ProtectionEffect,
|
||||
smite: SmiteEffect
|
||||
smite: SmiteEffect,
|
||||
'summon ally': SummonAllyEffect
|
||||
}
|
||||
|
||||
export async function powerEffects (options = {}) {
|
||||
|
||||
@ -24,6 +24,10 @@ export class shim {
|
||||
return game.user
|
||||
}
|
||||
|
||||
static get actors () {
|
||||
return game.actors
|
||||
}
|
||||
|
||||
static getStatus (label, name, favorite = true) {
|
||||
const effect = JSON.parse(JSON.stringify(
|
||||
CONFIG.statusEffects.find(se => se.label === label)))
|
||||
@ -76,6 +80,53 @@ export class shim {
|
||||
static warpgateMenu (menuData, menuOptions) {
|
||||
return warpgate.menu(menuData, menuOptions)
|
||||
}
|
||||
|
||||
static warpgateSpawn (...args) {
|
||||
return warpgate.spawn(...args)
|
||||
}
|
||||
|
||||
static getActorFolderByPath (path) {
|
||||
const names = path.split('/')
|
||||
if (names[0] === '') {
|
||||
names.shift()
|
||||
}
|
||||
let name = names.shift()
|
||||
let folder = shim.folders.filter(
|
||||
f => f.type === 'Actor' && !f.folder
|
||||
).find(f => f.name === name)
|
||||
if (!folder) { return undefined }
|
||||
while (names.length > 0) {
|
||||
name = names.shift()
|
||||
folder = folder.children.find(c => c.folder.name === name)
|
||||
if (!folder) { return undefined }
|
||||
folder = folder.folder
|
||||
}
|
||||
return folder
|
||||
}
|
||||
|
||||
static getActorsInFolder (inFolder) {
|
||||
const prefixStack = ['']
|
||||
const actors = {}
|
||||
const folderStack = [inFolder]
|
||||
while (folderStack.length > 0) {
|
||||
const prefix = prefixStack.shift()
|
||||
const folder = folderStack.shift()
|
||||
for (const actor of folder.contents) {
|
||||
if (shim.user.isGM ||
|
||||
actor.testUserPermission(
|
||||
shim.user, CONST.FOUNDRY.DOCUMENT_OWNERSHIP_LEVELS.OBSERVER)
|
||||
) {
|
||||
actors[`${prefix}${actor.name}`] = actor
|
||||
}
|
||||
}
|
||||
for (const child of folder.children) {
|
||||
const newPrefix = `${prefix}${child.folder.name} | `
|
||||
prefixStack.push(newPrefix)
|
||||
folderStack.push(child.folder)
|
||||
}
|
||||
}
|
||||
return actors
|
||||
}
|
||||
}
|
||||
|
||||
export function log (...args) {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user