feat(combat): Add pre-battle strike resolution for commanders
- Extend `CombatEngine._resolvePreBattleSkills` to capture `strike` and `strike-all` skills from commanders during the `preBattle` phase. - Introduce `strikeFires` to track strike hits, including damage, targets, and commander status. - Update `BattleScene._processPreBattleSequence` to handle and animate `strikeFires` alongside other pre-battle effects. - Ensure death events are correctly processed for non-commander targets destroyed by pre-battle strikes.
This commit is contained in:
parent
313f14b956
commit
547196f709
|
|
@ -546,13 +546,16 @@ export class CombatEngine {
|
|||
const sanctifyFires = [];
|
||||
const overchargeFires = [];
|
||||
const fortifyFires = [];
|
||||
const strikeFires = [];
|
||||
const liveAllies = allies.filter(c => c.currentHP > 0);
|
||||
const liveEnemies = enemies.filter(c => c.currentHP > 0);
|
||||
for (const card of cards) {
|
||||
if (card.currentHP <= 0) continue;
|
||||
if (card.currentDelay > 0) continue;
|
||||
for (const s of card.skills) {
|
||||
if (s.trigger !== 'preBattle') continue;
|
||||
// Commanders fire their strike/strike-all during preBattle instead of preAttack
|
||||
const isCommanderStrike = card.type === 'commander' && s.name === 'strike' && s.trigger === 'preAttack';
|
||||
if (s.trigger !== 'preBattle' && !isCommanderStrike) continue;
|
||||
// For drain, resolve the card directly across as defender
|
||||
const cardIdx = cards.indexOf(card);
|
||||
const acrossCard = enemyLanes[cardIdx];
|
||||
|
|
@ -676,9 +679,36 @@ export class CombatEngine {
|
|||
fortifyFires.push({ skill: 'fortify', source: card, target: ctx.fortifyTarget, amount: ctx.fortifyAmount });
|
||||
this._log(`${card.name} fortify: +${ctx.fortifyAmount} ARM to self`);
|
||||
}
|
||||
if (s.name === 'strike' && ctx.strikeAllTargets) {
|
||||
const isPlayerCard = this.playerLanes.includes(card) || card === this.playerCommander;
|
||||
for (const t of ctx.strikeAllTargets) {
|
||||
const targetIsCommander = t.target === enemyCommander;
|
||||
strikeFires.push({ skill: 'strike', source: card, target: t.target, damage: t.damage, hpBefore: t.hpBefore, targetIsCommander, isAll: true });
|
||||
this._log(`${card.name} strike all hits ${t.target.name} for ${t.damage}`);
|
||||
if (!targetIsCommander && t.target.currentHP <= 0) {
|
||||
this._log(`${t.target.name} is destroyed by strike all`);
|
||||
const deadSide = isPlayerCard ? 'opponent' : 'player';
|
||||
const deadAllies = isPlayerCard ? this.opponentLanes : this.playerLanes;
|
||||
this.events.push({ type: 'death', card: t.target, side: deadSide });
|
||||
this._processOnDeath(t.target, deadAllies, deadSide);
|
||||
}
|
||||
}
|
||||
} else if (s.name === 'strike' && ctx.strikeTarget) {
|
||||
const isPlayerCard = this.playerLanes.includes(card) || card === this.playerCommander;
|
||||
const targetIsCommander = ctx.strikeTarget === enemyCommander;
|
||||
strikeFires.push({ skill: 'strike', source: card, target: ctx.strikeTarget, damage: ctx.strikeDamage, hpBefore: ctx.strikeTarget.currentHP + ctx.strikeDamage, targetIsCommander });
|
||||
this._log(`${card.name} strike hits ${ctx.strikeTarget.name} for ${ctx.strikeDamage}`);
|
||||
if (!targetIsCommander && ctx.strikeTarget.currentHP <= 0) {
|
||||
this._log(`${ctx.strikeTarget.name} is destroyed by strike`);
|
||||
const deadSide = isPlayerCard ? 'opponent' : 'player';
|
||||
const deadAllies = isPlayerCard ? this.opponentLanes : this.playerLanes;
|
||||
this.events.push({ type: 'death', card: ctx.strikeTarget, side: deadSide });
|
||||
this._processOnDeath(ctx.strikeTarget, deadAllies, deadSide);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return { buffs, siegeFires, protectFires, enfeebeFires, jamFires, weakenFires, drainFires, healFires, sanctifyFires, overchargeFires, fortifyFires };
|
||||
return { buffs, siegeFires, protectFires, enfeebeFires, jamFires, weakenFires, drainFires, healFires, sanctifyFires, overchargeFires, fortifyFires, strikeFires };
|
||||
}
|
||||
|
||||
// Emit the 8-step pre-battle sequence and process preBattle skills.
|
||||
|
|
|
|||
|
|
@ -2260,19 +2260,22 @@ export class BattleScene extends Phaser.Scene {
|
|||
const hasSanctify = event.sanctifyFires?.length > 0;
|
||||
const hasOvercharge = event.overchargeFires?.length > 0;
|
||||
const hasFortify = event.fortifyFires?.length > 0;
|
||||
const hasStrike = event.strikeFires?.length > 0;
|
||||
|
||||
if (hasBuffs || hasSiege || hasProtect || hasEnfeeble || hasJam || hasWeaken || hasDrain || hasHeal || hasSanctify || hasOvercharge || hasFortify) {
|
||||
if (hasBuffs || hasSiege || hasProtect || hasEnfeeble || hasJam || hasWeaken || hasDrain || hasHeal || hasSanctify || hasOvercharge || hasFortify || hasStrike) {
|
||||
this._processSanctifyFires(event.sanctifyFires || [], () => {
|
||||
this._processDrainFires(event.drainFires || [], () => {
|
||||
this._processOverchargeFires(event.overchargeFires || [], () => {
|
||||
this._processBuffAnimations(event.buffs || [], () => {
|
||||
this._processFortifyFires(event.fortifyFires || [], () => {
|
||||
this._processSiegeFires(event.siegeFires || [], () => {
|
||||
this._processProtectFires(event.protectFires || [], () => {
|
||||
this._processEnfeebeFires(event.enfeebeFires || [], () => {
|
||||
this._processJamFires(event.jamFires || [], () => {
|
||||
this._processWeakenFires(event.weakenFires || [], () => {
|
||||
this._processHealFires(event.healFires || [], onComplete);
|
||||
this._processPreBattleStrikeFires(event.strikeFires || [], () => {
|
||||
this._processProtectFires(event.protectFires || [], () => {
|
||||
this._processEnfeebeFires(event.enfeebeFires || [], () => {
|
||||
this._processJamFires(event.jamFires || [], () => {
|
||||
this._processWeakenFires(event.weakenFires || [], () => {
|
||||
this._processHealFires(event.healFires || [], onComplete);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
@ -2288,6 +2291,15 @@ export class BattleScene extends Phaser.Scene {
|
|||
}
|
||||
}
|
||||
|
||||
_processPreBattleStrikeFires(fires, onComplete) {
|
||||
const next = (idx) => {
|
||||
if (idx >= fires.length) { onComplete(); return; }
|
||||
const fire = fires[idx];
|
||||
this._animateStrikeFire(fire.source, fire, () => next(idx + 1));
|
||||
};
|
||||
next(0);
|
||||
}
|
||||
|
||||
_processSiegeFires(fires, onComplete) {
|
||||
const next = (idx) => {
|
||||
if (idx >= fires.length) { onComplete(); return; }
|
||||
|
|
|
|||
Loading…
Reference in New Issue