base powers feature complete
This commit is contained in:
parent
c679304ae2
commit
d99d0c0728
@ -2,7 +2,7 @@ import { moduleName } from './globals.js'
|
|||||||
|
|
||||||
const MAINTAIN_ICON = 'icons/magic/symbols/runes-star-blue.webp'
|
const MAINTAIN_ICON = 'icons/magic/symbols/runes-star-blue.webp'
|
||||||
|
|
||||||
class PowerEffect {
|
export class PowerEffect {
|
||||||
constructor (token, targets) {
|
constructor (token, targets) {
|
||||||
this.source = token
|
this.source = token
|
||||||
this.targets = targets
|
this.targets = targets
|
||||||
@ -70,47 +70,44 @@ class PowerEffect {
|
|||||||
get basePowerPoints () { return 0 }
|
get basePowerPoints () { return 0 }
|
||||||
get usePrimaryEffect () { return true }
|
get usePrimaryEffect () { return true }
|
||||||
get hasAdditionalRecipients () { return false }
|
get hasAdditionalRecipients () { return false }
|
||||||
|
get isDamaging () { return false }
|
||||||
get additionalRecipientCost () { return 0 }
|
get additionalRecipientCost () { return 0 }
|
||||||
get isTargeted () { return false }
|
get isTargeted () { return false }
|
||||||
get modifiers () {
|
get modifiers () {
|
||||||
return [
|
const mods = []
|
||||||
{ name: 'Glow',
|
mods.push({ name: 'Adaptable Caster', id: 'adaptable',
|
||||||
id: 'glow',
|
value: 1, epic: false, effect: false })
|
||||||
value: 1,
|
mods.push({ name: 'Fatigue', id: 'fatigue', value: 2, epic: false, effect: false })
|
||||||
epic: false,
|
mods.push({ name: 'Glow', id: 'glow', value: 1,
|
||||||
effect: true,
|
epic: false, 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,
|
priority: 0, mode: foundry.CONST.ACTIVE_EFFECT_MODES.ADD } ]
|
||||||
priority: 0, mode: foundry.CONST.ACTIVE_EFFECT_MODES.ADD } ]
|
})
|
||||||
},
|
mods.push({ name: 'Shroud', id: 'shroud', value: 1, epic: false, effect: true,
|
||||||
{ name: 'Shroud',
|
icon: 'icons/magic/perception/shadow-stealth-eyes-purple.webp',
|
||||||
id: 'shroud',
|
changes: [ { key: '@Skill{Stealth}[system.die.modifier]', value: 1,
|
||||||
value: 1,
|
priority: 0, mode: foundry.CONST.ACTIVE_EFFECT_MODES.ADD } ]
|
||||||
epic: false,
|
})
|
||||||
effect: true,
|
if (this.isDamaging) {
|
||||||
icon: 'icons/magic/perception/shadow-stealth-eyes-purple.webp',
|
mods.push({ name: 'Heavy Weapon', id: 'heavyweapon', value: 2,
|
||||||
changes: [ { key: '@Skill{Stealth}[system.die.modifier]', value: 1,
|
epic: false, effect: false})
|
||||||
priority: 0, mode: foundry.CONST.ACTIVE_EFFECT_MODES.ADD } ]
|
}
|
||||||
},
|
mods.push({ name: 'Hinder', id: 'hinder', value: 1, epic: false, effect: true,
|
||||||
{ name: 'Hinder',
|
|
||||||
id: 'hinder',
|
|
||||||
value: 1,
|
|
||||||
epic: false,
|
|
||||||
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,
|
||||||
priority: 0, mode: foundry.CONST.ACTIVE_EFFECT_MODES.ADD } ]
|
priority: 0, mode: foundry.CONST.ACTIVE_EFFECT_MODES.ADD } ]
|
||||||
},
|
})
|
||||||
{ name: 'Hurry',
|
mods.push({ name: 'Hurry', id: 'hurry', value: 1, epic: false, effect: true,
|
||||||
id: 'hurry',
|
icon: 'icons/skills/movement/feet-winged-sandals-tan.webp',
|
||||||
value: 1,
|
changes: [ { key: 'system.stats.speed.value', value: 2,
|
||||||
epic: false,
|
priority: 0, mode: foundry.CONST.ACTIVE_EFFECT_MODES.ADD } ]
|
||||||
effect: true,
|
})
|
||||||
icon: 'icons/skills/movement/feet-winged-sandals-tan.webp',
|
if (this.isDamaging) {
|
||||||
changes: [ { key: 'system.stats.speed.value', value: 2,
|
mods.push({ name: 'Lingering Damage', id: 'lingeringdamage', value: 2,
|
||||||
priority: 0, mode: foundry.CONST.ACTIVE_EFFECT_MODES.ADD } ]
|
epic: false, effect: false})
|
||||||
},
|
}
|
||||||
]
|
mods.push({ name: 'Selective', id: 'selective', value: 1, epic: false, effect: false })
|
||||||
|
return mods
|
||||||
}
|
}
|
||||||
|
|
||||||
get menuData () {
|
get menuData () {
|
||||||
@ -131,10 +128,7 @@ class PowerEffect {
|
|||||||
label += ` (${this.targets.length - 1} additional recipients ` +
|
label += ` (${this.targets.length - 1} additional recipients ` +
|
||||||
`+${this.additionalRecipientCost} ea.)`
|
`+${this.additionalRecipientCost} ea.)`
|
||||||
}
|
}
|
||||||
data.push({
|
data.push({ type: 'info', label: label })
|
||||||
type: 'info',
|
|
||||||
label: label
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
for (const mod of this.modifiers) {
|
for (const mod of this.modifiers) {
|
||||||
data.push({
|
data.push({
|
||||||
@ -145,6 +139,23 @@ class PowerEffect {
|
|||||||
),
|
),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
if (this.isDamaging) {
|
||||||
|
data.push({ type: 'select', label: 'Armor Piercing',
|
||||||
|
options: [
|
||||||
|
{html: 'None', value: 0, selected: true},
|
||||||
|
{html: 'AP 2 (+1)', value: 1, selected: false},
|
||||||
|
{html: 'AP 4 (+2)', value: 2, selected: false},
|
||||||
|
{html: 'AP 6 (+3)', value: 3, selected: false},
|
||||||
|
]
|
||||||
|
})
|
||||||
|
}
|
||||||
|
data.push({type: 'select', label: 'Range',
|
||||||
|
options: [
|
||||||
|
{html: 'Normal Range', value: 0, selected: true},
|
||||||
|
{html: 'Range ×2 (+1)', value: 1, selected: false},
|
||||||
|
{html: 'Range ×3 (+2)', value: 2, selected: false}
|
||||||
|
]
|
||||||
|
})
|
||||||
return data
|
return data
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -195,6 +206,10 @@ class PowerEffect {
|
|||||||
this.data.mods.add(mod.id)
|
this.data.mods.add(mod.id)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (this.isDamaging) {
|
||||||
|
this.data.armorPiercing = this.data.values.shift()
|
||||||
|
}
|
||||||
|
this.data.range = this.data.values.shift()
|
||||||
}
|
}
|
||||||
|
|
||||||
async createSecondaryEffects (maintId) {
|
async createSecondaryEffects (maintId) {
|
||||||
@ -206,7 +221,7 @@ class PowerEffect {
|
|||||||
// set secondary effects of instant spells to expire on victim's next
|
// set secondary effects of instant spells to expire on victim's next
|
||||||
// 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.EndOfTurnAuto
|
||||||
} else {
|
} else {
|
||||||
doc.duration.seconds = 594
|
doc.duration.seconds = 594
|
||||||
doc.flags[moduleName].maintId = maintId
|
doc.flags[moduleName].maintId = maintId
|
||||||
@ -274,6 +289,21 @@ class PowerEffect {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async sideEffects () {
|
async sideEffects () {
|
||||||
|
if (this.data.mods.has('fatigue')) {
|
||||||
|
for (const target of this.targets) {
|
||||||
|
const actor = target.actor
|
||||||
|
const update = {
|
||||||
|
system: {
|
||||||
|
fatigue: {
|
||||||
|
value: actor.system.fatigue.value + 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (actor.system.fatigue.value < actor.system.fatigue.max) {
|
||||||
|
await actor.update(update)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
get powerPoints () {
|
get powerPoints () {
|
||||||
@ -286,37 +316,62 @@ class PowerEffect {
|
|||||||
if (this.targets.length > 1 && this.hasAdditionalRecipients) {
|
if (this.targets.length > 1 && this.hasAdditionalRecipients) {
|
||||||
total += (this.targets.length - 1) * this.additionalRecipientCost
|
total += (this.targets.length - 1) * this.additionalRecipientCost
|
||||||
}
|
}
|
||||||
|
total += this.data.range
|
||||||
|
if (this.isDamaging) {
|
||||||
|
total += this.data.ap
|
||||||
|
}
|
||||||
return total
|
return total
|
||||||
}
|
}
|
||||||
|
|
||||||
async chatMessage () {
|
get chatMessageEffects () {
|
||||||
let text = `Cast ${this.name}`
|
const list = []
|
||||||
|
if (this.hasAdditionalRecipients && this.targets.length > 1) {
|
||||||
|
list.push(`${this.targets.length - 1} Additional Recipients`)
|
||||||
|
}
|
||||||
|
if (this.data.mods.has('adaptable')) {
|
||||||
|
list.push('Different Trapping (Adaptable Caster)')
|
||||||
|
}
|
||||||
|
if (this.data.mods.has('fatigue')) {
|
||||||
|
list.push('Fatigue (applied to targets')
|
||||||
|
}
|
||||||
|
if (this.data.mods.has('heavyweapon')) {
|
||||||
|
list.push('Heavy Weapon')
|
||||||
|
}
|
||||||
|
if (this.data.mods.has('lingeringdamage')) {
|
||||||
|
list.push('Lingering Damage')
|
||||||
|
}
|
||||||
|
if (this.data.mods.has('selective')) {
|
||||||
|
list.push('Selective')
|
||||||
|
}
|
||||||
|
if (this.isDamaging && this.data.armorPiercing > 0) {
|
||||||
|
list.push(`AP ${this.data.armorPiercing * 2}`)
|
||||||
|
}
|
||||||
|
if (this.data.range > 0) {
|
||||||
|
list.push(`Range ×${this.data.range +1}`)
|
||||||
|
}
|
||||||
|
return list
|
||||||
|
}
|
||||||
|
|
||||||
|
get chatMessageText () {
|
||||||
|
let text = `<p>Cast ${this.name}`
|
||||||
if (this.targets.length > 0) {
|
if (this.targets.length > 0) {
|
||||||
text += ` on ${this.targets.map(t => t.name).join(', ')}`
|
text += ` on ${this.targets.map(t => t.name).join(', ')}`
|
||||||
}
|
}
|
||||||
|
text += '</p>'
|
||||||
|
const effects = this.chatMessageEffects
|
||||||
|
if (effects.length > 0) {
|
||||||
|
text += '<details><summary>Other Effects:</summary><ul><li>' +
|
||||||
|
effects.join('</li><li>') + '</li></ul></details>'
|
||||||
|
}
|
||||||
|
return text
|
||||||
|
}
|
||||||
|
|
||||||
|
async chatMessage () {
|
||||||
return ChatMessage.create({
|
return ChatMessage.create({
|
||||||
flavor: `Calculated cost: ${this.powerPoints} pp`,
|
flavor: `Calculated cost: ${this.powerPoints} pp`,
|
||||||
speaker: ChatMessage.getSpeaker(this.source.actor),
|
speaker: ChatMessage.getSpeaker(this.source.actor),
|
||||||
content: text,
|
content: this.chatMessageText,
|
||||||
whisper: ChatMessage.getWhisperRecipients('GM', game.user.name),
|
whisper: ChatMessage.getWhisperRecipients('GM', game.user.name),
|
||||||
}, { chatBubble: false });
|
}, { chatBubble: false });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class BurrowEffect extends PowerEffect {
|
|
||||||
get name () { return 'Burrow' }
|
|
||||||
get duration () { return 5 }
|
|
||||||
get icon () { return 'icons/magic/earth/projectile-stone-landslide.webp' }
|
|
||||||
get hasAdditionalRecipients () { return true }
|
|
||||||
get additionalRecipientCost () { return 1 }
|
|
||||||
get basePowerPoints () { return 1 }
|
|
||||||
get isTargeted () { return true }
|
|
||||||
get effectName () {
|
|
||||||
return `${this.name} (${this.data.raise ? 'full' : 'half'} pace)`
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export const PowerClasses = {
|
|
||||||
burrow: BurrowEffect
|
|
||||||
}
|
|
||||||
|
|
||||||
@ -1,5 +1,36 @@
|
|||||||
import { moduleName } from './globals.js'
|
import { moduleName } from './globals.js'
|
||||||
import { PowerClasses } from './allPowers.js'
|
import { PowerEffect } from './basePowers.js'
|
||||||
|
|
||||||
|
class BurrowEffect extends PowerEffect {
|
||||||
|
get name () { return 'Burrow' }
|
||||||
|
get duration () { return 5 }
|
||||||
|
get icon () { return 'icons/magic/earth/projectile-stone-landslide.webp' }
|
||||||
|
get hasAdditionalRecipients () { return true }
|
||||||
|
get additionalRecipientCost () { return 1 }
|
||||||
|
get basePowerPoints () { return 1 }
|
||||||
|
get isTargeted () { return true }
|
||||||
|
get modifiers () {
|
||||||
|
const mods = super.modifiers
|
||||||
|
mods.push(
|
||||||
|
{ name: 'Power',
|
||||||
|
id: 'power',
|
||||||
|
value: 1,
|
||||||
|
epic: false,
|
||||||
|
effect: false,
|
||||||
|
})
|
||||||
|
return mods
|
||||||
|
}
|
||||||
|
get effectName () {
|
||||||
|
return `${this.name} ${this.data.mods.has('power') ? '[Power] ' : ''}` +
|
||||||
|
`(${this.data.raise ? 'full' : 'half'} pace)`
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const PowerClasses = {
|
||||||
|
burrow: BurrowEffect
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ---------------------------------------------------------------- */
|
||||||
|
|
||||||
export async function powerEffectManagementHook(effect, data, userId) {
|
export async function powerEffectManagementHook(effect, data, userId) {
|
||||||
if (game.user.id !== userId) {
|
if (game.user.id !== userId) {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user