summon mods for zombie pt 1

This commit is contained in:
Mike Bloy 2024-06-08 00:27:30 -05:00
parent 57e6ab1bd3
commit 929cdda415
2 changed files with 242 additions and 87 deletions

View File

@ -481,6 +481,10 @@ export class PowerEffect {
const name = 'effects' in mod ? mod.effects[modValue].name : mod.name; const name = 'effects' in mod ? mod.effects[modValue].name : mod.name;
const changes = 'effects' in mod ? mod.effects[modValue].changes : mod.changes; const changes = 'effects' in mod ? mod.effects[modValue].changes : mod.changes;
const doc = this.enhanceSecondaryEffect(maintId, this.createEffectDocument(icon, name, changes)); const doc = this.enhanceSecondaryEffect(maintId, this.createEffectDocument(icon, name, changes));
const desc = 'effects' in mod ? mod.effects?.[modValue]?.description : mod.description;
if (desc) {
doc.description += desc;
}
docs.push(doc); docs.push(doc);
} }
} }

View File

@ -11,12 +11,56 @@ class BaseSummonEffect extends ActorFolderEffect {
return 'Summonables'; return 'Summonables';
} }
get summonCount() {
return 0;
}
async parseValuesPre() {}
async parseValuesMid() {}
async parseValuesPost() {}
async parseValues() {
await super.parseValues();
await this.parseValuesPre();
await this.parseValuesMid();
await this.parseValuesPost();
}
async spawn() {
const spawned = await new Portal()
.addCreature(this.targetTokenDoc, { count: this.summonCount })
.texture(this.targetTokenDoc.texture.src)
.spawn();
return spawned;
}
async apply() {
await super.apply();
const maintainDoc = await this.createMaintainEffect(this.data.maintId);
maintainDoc.flags[moduleName].targetIds = this.data.spawned.map((t) => t.id);
if (this.duration > 0) {
await this.applyActiveEffects(this.source, [maintainDoc]);
}
}
}
class BaseAllyEffect extends BaseSummonEffect {
get values() { get values() {
return {}; return {};
} }
get hasIncreasedTrait() { get basePowerPoints() {
return true; return 0;
}
get duration() {
return 5;
}
get isTargeted() {
return false;
} }
get summonCount() { get summonCount() {
@ -37,7 +81,6 @@ class BaseSummonEffect extends ActorFolderEffect {
get modifiers() { get modifiers() {
const mods = super.modifiers; const mods = super.modifiers;
if (this.hasIncreasedTrait) {
mods.push({ mods.push({
type: 'checkbox', type: 'checkbox',
name: 'Increased Trait (+1 per trait)', name: 'Increased Trait (+1 per trait)',
@ -47,7 +90,6 @@ class BaseSummonEffect extends ActorFolderEffect {
epic: false, epic: false,
default: false, default: false,
}); });
}
mods.push({ mods.push({
type: 'number', type: 'number',
name: `${this.additionalName} ${this.additionalDesc}`, name: `${this.additionalName} ${this.additionalDesc}`,
@ -62,7 +104,10 @@ class BaseSummonEffect extends ActorFolderEffect {
name: 'Mind Rider', name: 'Mind Rider',
id: 'mindRider', id: 'mindRider',
value: 1, value: 1,
effect: false, effect: true,
icon: 'icons/magic/control/hypnosis-mesmerism-eye.webp',
changes: [],
description: 'The caster can communicate and sense through the ally.',
epic: false, epic: false,
default: false, default: false,
}); });
@ -77,8 +122,36 @@ class BaseSummonEffect extends ActorFolderEffect {
return 0; return 0;
} }
async prepIncreasedTrait() { get powerPoints() {
if (!(this.hasIncreasedTrait && this?.data?.increasedTrait)) { let value = super.powerPoints;
value += this.data.increasedTraitCount;
let halfValue = Math.ceil(value / 2);
return value + (this.data.additionalAllies ?? 0) * halfValue;
}
async parseValuesPre() {
await super.parseValuesPre();
this.data.actorUpdates = {
name: `${this.source.actor.name}'s summoned ${this.targetActor.name}`,
};
this.data.tokenUpdates = {
actorLink: false,
name: `${this.source.name}'s ${this.targetActor.prototypeToken.name}`,
disposition: this.source.document.disposition,
sight: {
enabled: true,
},
};
this.data.embeddedUpdates = {
ActiveEffect: {},
Item: {},
};
this.data.primaryEffectChanges = [];
}
async parseValuesPost() {
await super.parseValuesPost();
if (!this?.data?.increasedTrait) {
this.data.increasedTraitCount = 0; this.data.increasedTraitCount = 0;
return; return;
} }
@ -153,51 +226,20 @@ class BaseSummonEffect extends ActorFolderEffect {
this.data.increasedTraitCount = count; this.data.increasedTraitCount = count;
} }
get powerPoints() {
let value = super.powerPoints;
value += this.data.increasedTraitCount;
let halfValue = Math.ceil(value / 2);
return value + (this.data.additionalAllies ?? 0) * halfValue;
}
async prePrep() {}
async parseValues() {
await super.parseValues();
this.data.actorUpdates = {
name: `${this.source.actor.name}'s summoned ${this.targetActor.name}`,
};
this.data.tokenUpdates = {
actorLink: false,
name: `${this.source.name}'s ${this.targetActor.prototypeToken.name}`,
disposition: this.source.document.disposition,
sight: {
enabled: true,
},
};
this.data.embeddedUpdates = {
ActiveEffect: {},
Item: {},
};
this.data.primaryEffectChanges = [];
await this.prePrep();
await this.prepIncreasedTrait();
}
getPrimaryEffectChanges() { getPrimaryEffectChanges() {
return [...super.getPrimaryEffectChanges(), ...this.data.primaryEffectChanges]; return [...super.getPrimaryEffectChanges(), ...this.data.primaryEffectChanges];
} }
async createSecondaryEffects(maintId) { async createSecondaryEffects(maintId) {
const effects = await super.createSecondaryEffects(maintId); const effects = await super.createSecondaryEffects(maintId);
if (this.data.mindRider) { // if (this.data.mindRider) {
const doc = this.enhanceSecondaryEffect( // const doc = this.enhanceSecondaryEffect(
maintId, // maintId,
this.createEffectDocument('icons/magic/control/hypnosis-mesmerism-eye.webp', 'Mind Rider', []), // this.createEffectDocument('icons/magic/control/hypnosis-mesmerism-eye.webp', 'Mind Rider', []),
); // );
doc.description = `The caster can communicate and sense through the ally`; // doc.description = `The caster can communicate and sense through the ally`;
effects.push(doc); // effects.push(doc);
} // }
if ((this.data?.increasedTraitChanges?.length ?? 0) > 0) { if ((this.data?.increasedTraitChanges?.length ?? 0) > 0) {
const doc = this.enhanceSecondaryEffect( const doc = this.enhanceSecondaryEffect(
maintId, maintId,
@ -216,23 +258,6 @@ class BaseSummonEffect extends ActorFolderEffect {
return updates; return updates;
} }
async spawn() {
const spawned = await new Portal()
.addCreature(this.targetTokenDoc, { count: this.summonCount })
.texture(this.targetTokenDoc.texture.src)
.spawn();
return spawned;
}
async apply() {
await super.apply();
const maintainDoc = await this.createMaintainEffect(this.data.maintId);
maintainDoc.flags[moduleName].targetIds = this.data.spawned.map((t) => t.id);
if (this.duration > 0) {
await this.applyActiveEffects(this.source, [maintainDoc]);
}
}
get description() { get description() {
let desc = super.description; let desc = super.description;
desc += `<p>Summon a ${this.targetActor.prototypeToken.name} ally to serve desc += `<p>Summon a ${this.targetActor.prototypeToken.name} ally to serve
@ -245,27 +270,15 @@ class BaseSummonEffect extends ActorFolderEffect {
} }
} }
export class SummonAllyEffect extends BaseSummonEffect { export class SummonAllyEffect extends BaseAllyEffect {
get name() { get name() {
return 'Summon Ally'; return 'Summon Ally';
} }
get basePowerPoints() {
return 0;
}
get duration() {
return 5;
}
get icon() { get icon() {
return 'icons/magic/control/silhouette-hold-beam-blue.webp'; return 'icons/magic/control/silhouette-hold-beam-blue.webp';
} }
get isTargeted() {
return false;
}
get values() { get values() {
return { return {
attendant: 1, attendant: 1,
@ -325,8 +338,8 @@ export class SummonAllyEffect extends BaseSummonEffect {
return mods; return mods;
} }
async prePrep() { async parseValuesMid() {
await super.prePrep(); await super.parseValuesMid();
if (this.data.raise && this.data.actors['raise_template']) { if (this.data.raise && this.data.actors['raise_template']) {
const raiseTemplate = this.data.actors.raise_template; const raiseTemplate = this.data.actors.raise_template;
for (const item of raiseTemplate.items) { for (const item of raiseTemplate.items) {
@ -438,3 +451,141 @@ export class SummonAllyEffect extends BaseSummonEffect {
return desc; return desc;
} }
} }
export class ZombieEffect extends BaseSummonEffect {
get name() {
return 'Zombie';
}
get icon() {
return 'icons/magic/death/hand-dirt-undead-zombie.webp';
}
get modifiers() {
const mods = super.modifiers;
mods.push(
{
type: 'number',
name: 'Additional Zombies (+1 per zombie)',
id: 'additionalAllies',
value: 0,
default: 0,
epic: false,
effect: false,
},
{
type: 'checkbox',
name: 'Armed (+1 per zombie)',
id: 'armed',
value: 0,
default: false,
epic: false,
effect: false,
},
{
type: 'checkbox',
name: 'Armor (+1 per zombie)',
id: 'armor',
default: false,
epic: false,
effect: true,
icon: 'icons/equipment/chest/breastplate-leather-brown-belted.webp',
changes: [
{
key: 'system.stats.toughness.armor',
value: 2,
priority: 0,
mode: foundry.CONST.ACTIVE_EFFECT_MODES.ADD,
},
],
},
{
type: 'checkbox',
name: 'Skeletal',
value: 0,
id: 'skeletal',
epic: false,
default: false,
effect: true,
icon: 'icons/magic/death/hand-undead-skeleton-fire-pink.webp',
changes: [
{
key: 'system.attributes.agility.die.sides',
value: 2,
priority: 0,
mode: foundry.CONST.ACTIVE_EFFECT_MODES.ADD,
},
{
key: '@Skill{Athletics}[system.die.sides]',
value: 2,
priority: 0,
mode: foundry.CONST.ACTIVE_EFFECT_MODES.ADD,
},
{
key: '@Skill{Fighting}[system.die.sides]',
value: 2,
priority: 0,
mode: foundry.CONST.ACTIVE_EFFECT_MODES.ADD,
},
{
key: '@Skill{Shooting}[system.die.sides]',
value: 2,
priority: 0,
mode: foundry.CONST.ACTIVE_EFFECT_MODES.ADD,
},
],
},
{
type: 'radio',
name: 'Mind Rider',
id: 'mindRider',
default: 'none',
epic: false,
choices: { none: 'None', single: 'Single', all: 'All' },
values: { none: 0, single: 1, all: 3 },
effects: {
none: null,
single: {
name: 'Mind Rider (single)',
icon: 'icons/magic/control/hypnosis-mesmerism-eye.webp',
changes: [],
description: 'The caster can communicate and sense through the ally.',
},
all: {
name: 'Mind Rider (all)',
icon: 'icons/magic/control/hypnosis-mesmerism-eye.webp',
changes: [],
description: 'The caster can communicate and sense through the ally.',
},
},
},
{
type: 'checkbox',
name: 'Permanent',
id: 'permanent',
default: false,
epic: false,
value: 0,
effect: true,
icon: 'icons/magic/death/skeleton-worn-skull-tan.webp',
changes: [],
description: 'This zombie is permanant until dismissed.',
},
);
return mods;
}
actorValue(actor) {
const size = actor.system.stats.size;
if (size <= -1) {
return 2;
}
return 3 + size;
}
async parseValuesPre() {
await super.parseValuesPre();
this.data.actorUpdates.name = `${this.source.acor.name}'s raised ${this.targetActor.name}`;
this.data.tokenUpdates.name = `${this.source.name}'s raised ${this.targetActor.name}`;
}
}