feat(combat): rename "valor" to "legion" and add parallel "all" weaken animation
- Updated `data/cards.json` to rename the `valor` skill to `legion`, change its trigger to `preBattle`, and adjust `strike` values across multiple card tiers. - Reduced the `enfeeble` skill value from 3 to 1 in `data/cards.json`. - Enhanced `weaken` skill tracking in `CombatEngine.js` and `SkillProcessor.js` by adding an `isAll` flag to distinguish area-of-effect weaken effects. - Refactored `BattleScene.js` to group consecutive "all" weaken fires and animate them in parallel via a new `_animateWeakenFireAll` method, improving visual feedback and performance for multi-target weaken effects.
This commit is contained in:
parent
b2c55d903a
commit
52808806a8
|
|
@ -1071,13 +1071,13 @@
|
|||
"delay": 1,
|
||||
"skills": [
|
||||
{
|
||||
"name": "valor",
|
||||
"name": "legion",
|
||||
"value": 2,
|
||||
"trigger": "passive"
|
||||
"trigger": "preBattle"
|
||||
},
|
||||
{
|
||||
"name": "strike",
|
||||
"value": 1,
|
||||
"value": 2,
|
||||
"trigger": "preAttack"
|
||||
}
|
||||
]
|
||||
|
|
@ -1089,13 +1089,13 @@
|
|||
"delay": 1,
|
||||
"skills": [
|
||||
{
|
||||
"name": "valor",
|
||||
"name": "legion",
|
||||
"value": 3,
|
||||
"trigger": "passive"
|
||||
"trigger": "preBattle"
|
||||
},
|
||||
{
|
||||
"name": "strike",
|
||||
"value": 2,
|
||||
"value": 6,
|
||||
"trigger": "preAttack"
|
||||
}
|
||||
]
|
||||
|
|
@ -1107,13 +1107,13 @@
|
|||
"delay": 1,
|
||||
"skills": [
|
||||
{
|
||||
"name": "valor",
|
||||
"name": "legion",
|
||||
"value": 5,
|
||||
"trigger": "passive"
|
||||
"trigger": "preBattle"
|
||||
},
|
||||
{
|
||||
"name": "strike",
|
||||
"value": 3,
|
||||
"value": 12,
|
||||
"trigger": "preAttack"
|
||||
}
|
||||
]
|
||||
|
|
@ -1125,13 +1125,13 @@
|
|||
"delay": 1,
|
||||
"skills": [
|
||||
{
|
||||
"name": "valor",
|
||||
"name": "legion",
|
||||
"value": 7,
|
||||
"trigger": "passive"
|
||||
"trigger": "preBattle"
|
||||
},
|
||||
{
|
||||
"name": "strike",
|
||||
"value": 5,
|
||||
"value": 24,
|
||||
"trigger": "preAttack"
|
||||
}
|
||||
]
|
||||
|
|
@ -1143,13 +1143,13 @@
|
|||
"delay": 1,
|
||||
"skills": [
|
||||
{
|
||||
"name": "valor",
|
||||
"name": "legion",
|
||||
"value": 10,
|
||||
"trigger": "passive"
|
||||
"trigger": "preBattle"
|
||||
},
|
||||
{
|
||||
"name": "strike",
|
||||
"value": 7,
|
||||
"value": 48,
|
||||
"trigger": "preAttack"
|
||||
}
|
||||
]
|
||||
|
|
@ -2228,7 +2228,7 @@
|
|||
"skills": [
|
||||
{
|
||||
"name": "enfeeble",
|
||||
"value": 3,
|
||||
"value": 1,
|
||||
"all": true,
|
||||
"trigger": "preBattle"
|
||||
},
|
||||
|
|
|
|||
|
|
@ -605,7 +605,7 @@ export class CombatEngine {
|
|||
}
|
||||
if (s.name === 'weaken' && ctx.weakenFires?.length) {
|
||||
for (const wf of ctx.weakenFires) {
|
||||
weakenFires.push({ skill: 'weaken', source: wf.source, target: wf.target, armorAmount: wf.armorAmount, attackAmount: wf.attackAmount });
|
||||
weakenFires.push({ skill: 'weaken', source: wf.source, target: wf.target, armorAmount: wf.armorAmount, attackAmount: wf.attackAmount, isAll: wf.isAll });
|
||||
this._log(`${card.name} weaken reduces ${wf.target.name} ARM by ${wf.armorAmount} and ATK by ${wf.attackAmount}`);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -302,7 +302,7 @@ export class SkillProcessor {
|
|||
if (targets.length === 0) return;
|
||||
for (const t of targets) {
|
||||
const { armorAmt, attackAmt } = _applyWeaken(t);
|
||||
weakenFires.push({ source: attacker, target: t, armorAmount: armorAmt, attackAmount: attackAmt });
|
||||
weakenFires.push({ source: attacker, target: t, armorAmount: armorAmt, attackAmount: attackAmt, isAll: true });
|
||||
}
|
||||
if (context) context.weakenFires = weakenFires;
|
||||
return;
|
||||
|
|
|
|||
|
|
@ -2353,9 +2353,28 @@ export class BattleScene extends Phaser.Scene {
|
|||
}
|
||||
|
||||
_processWeakenFires(fires, onComplete) {
|
||||
// Group consecutive "all" weaken fires for parallel animation
|
||||
const groups = [];
|
||||
for (const fire of fires) {
|
||||
if (fire.isAll) {
|
||||
const last = groups[groups.length - 1];
|
||||
if (last?.isAll) {
|
||||
last.items.push(fire);
|
||||
} else {
|
||||
groups.push({ isAll: true, items: [fire] });
|
||||
}
|
||||
} else {
|
||||
groups.push(fire);
|
||||
}
|
||||
}
|
||||
const next = (idx) => {
|
||||
if (idx >= fires.length) { onComplete(); return; }
|
||||
this._animateWeakenFire(fires[idx], () => next(idx + 1));
|
||||
if (idx >= groups.length) { onComplete(); return; }
|
||||
const group = groups[idx];
|
||||
if (group.isAll) {
|
||||
this._animateWeakenFireAll(group.items, () => next(idx + 1));
|
||||
} else {
|
||||
this._animateWeakenFire(group, () => next(idx + 1));
|
||||
}
|
||||
};
|
||||
next(0);
|
||||
}
|
||||
|
|
@ -3592,6 +3611,75 @@ export class BattleScene extends Phaser.Scene {
|
|||
});
|
||||
}
|
||||
|
||||
_animateWeakenFireAll(fires, onComplete) {
|
||||
if (!fires?.length) { onComplete(); return; }
|
||||
const _lookup = id => id && (this.cardObjects.get(id) || this.commanderObjects?.get(id));
|
||||
const sourceObj = _lookup(fires[0].source.instanceId);
|
||||
|
||||
this.statusText.setText(`${fires[0].source.name} weakens all enemies!`);
|
||||
this.sound.play('sfx_weaken', { volume: 0.8 });
|
||||
|
||||
const BASE_SCALE = 160 / 460;
|
||||
let remaining = fires.length;
|
||||
const done = () => { if (--remaining <= 0) onComplete(); };
|
||||
|
||||
for (const fire of fires) {
|
||||
const targetObj = _lookup(fire.target.instanceId);
|
||||
if (!targetObj?.scene) { done(); continue; }
|
||||
|
||||
const armorAmt = fire.armorAmount;
|
||||
const attackAmt = fire.attackAmount;
|
||||
if (armorAmt <= 0 && attackAmt <= 0) { done(); continue; }
|
||||
|
||||
if (!sourceObj?.scene) {
|
||||
targetObj.refresh();
|
||||
targetObj.flash(0x8800ff);
|
||||
this.time.delayedCall(400, done);
|
||||
continue;
|
||||
}
|
||||
|
||||
const weakenSprite = this.add.sprite(sourceObj.x, sourceObj.y, 'attacks', 43)
|
||||
.setScale(BASE_SCALE)
|
||||
.setDepth(30);
|
||||
|
||||
this.tweens.add({
|
||||
targets: weakenSprite,
|
||||
x: targetObj.x,
|
||||
y: targetObj.y,
|
||||
duration: 1350,
|
||||
ease: 'Cubic.easeIn',
|
||||
onComplete: () => {
|
||||
if (!targetObj.scene) { if (weakenSprite.scene) weakenSprite.destroy(); done(); return; }
|
||||
|
||||
this.tweens.add({
|
||||
targets: weakenSprite,
|
||||
alpha: 0,
|
||||
scaleX: BASE_SCALE * 1.4,
|
||||
scaleY: BASE_SCALE * 1.4,
|
||||
duration: 300,
|
||||
ease: 'Power2',
|
||||
onComplete: () => { if (weakenSprite.scene) weakenSprite.destroy(); }
|
||||
});
|
||||
|
||||
let pending = (armorAmt > 0 ? 1 : 0) + (attackAmt > 0 ? 1 : 0);
|
||||
if (pending === 0) { done(); return; }
|
||||
const statDone = () => { if (--pending === 0) done(); };
|
||||
|
||||
if (armorAmt > 0) {
|
||||
const fromARM = fire.target.currentArmor + armorAmt;
|
||||
const toARM = fire.target.currentArmor;
|
||||
targetObj.animateArmorLoss(armorAmt, statDone, fromARM, toARM);
|
||||
}
|
||||
if (attackAmt > 0) {
|
||||
const fromATK = fire.target.currentAttack + attackAmt;
|
||||
const toATK = fire.target.currentAttack;
|
||||
this._animateAttackLoss(targetObj, attackAmt, fromATK, toATK, statDone);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// Re-apply jam reductions after _renderState() so combat math stays correct.
|
||||
_reapplyJamSkillReductions(preBattleEvents) {
|
||||
for (const event of preBattleEvents) {
|
||||
|
|
|
|||
Loading…
Reference in New Issue