[Bug] Adjust how counter attacks target to account for uturn/voltswitch and double battles (#2462)
* Adjust how counter attacks target to account for uturn/voltswitch * Creates move flag for metal burst/comeuppance to redirect in some cases * Remove debug printing * Bit shifts the redirect counter flag * Removes extraneous class from prior testing * Remove vitest timestamp file that was accidentally added
This commit is contained in:
parent
3c93aa6d36
commit
e1662b8251
|
@ -92,6 +92,10 @@ export enum MoveFlags {
|
|||
* Enables all hits of a multi-hit move to be accuracy checked individually
|
||||
*/
|
||||
CHECK_ALL_HITS = 1 << 17,
|
||||
/**
|
||||
* Indicates a move is able to be redirected to allies in a double battle if the attacker faints
|
||||
*/
|
||||
REDIRECT_COUNTER = 1 << 18,
|
||||
}
|
||||
|
||||
type MoveConditionFunc = (user: Pokemon, target: Pokemon, move: Move) => boolean;
|
||||
|
@ -549,6 +553,17 @@ export default class Move implements Localizable {
|
|||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the {@linkcode MoveFlags.REDIRECT_COUNTER} flag for the calling Move
|
||||
* @param redirectCounter The value (boolean) to set the flag to
|
||||
* example: @see {@linkcode Moves.METAL_BURST}
|
||||
* @returns The {@linkcode Move} that called this function
|
||||
*/
|
||||
redirectCounter(redirectCounter?: boolean): this {
|
||||
this.setFlag(MoveFlags.REDIRECT_COUNTER, redirectCounter);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the move flag applies to the pokemon(s) using/receiving the move
|
||||
* @param flag {@linkcode MoveFlags} MoveFlag to check on user and/or target
|
||||
|
@ -6907,6 +6922,7 @@ export function initMoves() {
|
|||
.target(MoveTarget.USER_OR_NEAR_ALLY),
|
||||
new AttackMove(Moves.METAL_BURST, Type.STEEL, MoveCategory.PHYSICAL, -1, 100, 10, -1, 0, 4)
|
||||
.attr(CounterDamageAttr, (move: Move) => (move.category === MoveCategory.PHYSICAL || move.category === MoveCategory.SPECIAL), 1.5)
|
||||
.redirectCounter()
|
||||
.makesContact(false)
|
||||
.target(MoveTarget.ATTACKER),
|
||||
new AttackMove(Moves.U_TURN, Type.BUG, MoveCategory.PHYSICAL, 70, 100, 20, -1, 0, 4)
|
||||
|
@ -8587,6 +8603,7 @@ export function initMoves() {
|
|||
}), // TODO Add Instruct/Encore interaction
|
||||
new AttackMove(Moves.COMEUPPANCE, Type.DARK, MoveCategory.PHYSICAL, -1, 100, 10, -1, 0, 9)
|
||||
.attr(CounterDamageAttr, (move: Move) => (move.category === MoveCategory.PHYSICAL || move.category === MoveCategory.SPECIAL), 1.5)
|
||||
.redirectCounter()
|
||||
.target(MoveTarget.ATTACKER),
|
||||
new AttackMove(Moves.AQUA_CUTTER, Type.WATER, MoveCategory.PHYSICAL, 70, 100, 20, -1, 0, 9)
|
||||
.attr(HighCritAttr)
|
||||
|
|
|
@ -2075,7 +2075,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
|
|||
source.turnData.damageDealt += damage.value;
|
||||
source.turnData.currDamageDealt = damage.value;
|
||||
this.battleData.hitCount++;
|
||||
const attackResult = { move: move.id, result: result as DamageResult, damage: damage.value, critical: isCritical, sourceId: source.id };
|
||||
const attackResult = { move: move.id, result: result as DamageResult, damage: damage.value, critical: isCritical, sourceId: source.id, attackingPosition: source.getBattlerIndex() };
|
||||
this.turnData.attacksReceived.unshift(attackResult);
|
||||
if (source.isPlayer() && !this.isPlayer()) {
|
||||
this.scene.applyModifiers(DamageMoneyRewardModifier, true, source, damage);
|
||||
|
@ -3990,6 +3990,7 @@ export interface AttackMoveResult {
|
|||
damage: integer;
|
||||
critical: boolean;
|
||||
sourceId: integer;
|
||||
attackingPosition: BattlerIndex;
|
||||
}
|
||||
|
||||
export class PokemonSummonData {
|
||||
|
|
|
@ -2661,11 +2661,18 @@ export class MovePhase extends BattlePhase {
|
|||
this.targets[0] = moveTarget.value;
|
||||
}
|
||||
|
||||
// Check for counterattack moves to switch target
|
||||
if (this.targets.length === 1 && this.targets[0] === BattlerIndex.ATTACKER) {
|
||||
if (this.pokemon.turnData.attacksReceived.length) {
|
||||
const attacker = this.pokemon.turnData.attacksReceived.length ? this.pokemon.scene.getPokemonById(this.pokemon.turnData.attacksReceived[0].sourceId) : null;
|
||||
if (attacker?.isActive(true)) {
|
||||
this.targets[0] = attacker.getBattlerIndex();
|
||||
const attack = this.pokemon.turnData.attacksReceived[0];
|
||||
this.targets[0] = attack.attackingPosition;
|
||||
|
||||
// account for metal burst and comeuppance hitting remaining targets in double battles
|
||||
// counterattack will redirect to remaining ally if original attacker faints
|
||||
if (this.scene.currentBattle.double && this.move.getMove().hasFlag(MoveFlags.REDIRECT_COUNTER)) {
|
||||
if (!this.scene.getEnemyField()[this.targets[0]]) {
|
||||
this.targets[0] = this.scene.getEnemyField().find(p => p.isActive(true)).getBattlerIndex();
|
||||
}
|
||||
}
|
||||
}
|
||||
if (this.targets[0] === BattlerIndex.ATTACKER) {
|
||||
|
|
Loading…
Reference in New Issue