[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
|
* Enables all hits of a multi-hit move to be accuracy checked individually
|
||||||
*/
|
*/
|
||||||
CHECK_ALL_HITS = 1 << 17,
|
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;
|
type MoveConditionFunc = (user: Pokemon, target: Pokemon, move: Move) => boolean;
|
||||||
|
@ -549,6 +553,17 @@ export default class Move implements Localizable {
|
||||||
return this;
|
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
|
* 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
|
* @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),
|
.target(MoveTarget.USER_OR_NEAR_ALLY),
|
||||||
new AttackMove(Moves.METAL_BURST, Type.STEEL, MoveCategory.PHYSICAL, -1, 100, 10, -1, 0, 4)
|
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)
|
.attr(CounterDamageAttr, (move: Move) => (move.category === MoveCategory.PHYSICAL || move.category === MoveCategory.SPECIAL), 1.5)
|
||||||
|
.redirectCounter()
|
||||||
.makesContact(false)
|
.makesContact(false)
|
||||||
.target(MoveTarget.ATTACKER),
|
.target(MoveTarget.ATTACKER),
|
||||||
new AttackMove(Moves.U_TURN, Type.BUG, MoveCategory.PHYSICAL, 70, 100, 20, -1, 0, 4)
|
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
|
}), // TODO Add Instruct/Encore interaction
|
||||||
new AttackMove(Moves.COMEUPPANCE, Type.DARK, MoveCategory.PHYSICAL, -1, 100, 10, -1, 0, 9)
|
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)
|
.attr(CounterDamageAttr, (move: Move) => (move.category === MoveCategory.PHYSICAL || move.category === MoveCategory.SPECIAL), 1.5)
|
||||||
|
.redirectCounter()
|
||||||
.target(MoveTarget.ATTACKER),
|
.target(MoveTarget.ATTACKER),
|
||||||
new AttackMove(Moves.AQUA_CUTTER, Type.WATER, MoveCategory.PHYSICAL, 70, 100, 20, -1, 0, 9)
|
new AttackMove(Moves.AQUA_CUTTER, Type.WATER, MoveCategory.PHYSICAL, 70, 100, 20, -1, 0, 9)
|
||||||
.attr(HighCritAttr)
|
.attr(HighCritAttr)
|
||||||
|
|
|
@ -2075,7 +2075,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
|
||||||
source.turnData.damageDealt += damage.value;
|
source.turnData.damageDealt += damage.value;
|
||||||
source.turnData.currDamageDealt = damage.value;
|
source.turnData.currDamageDealt = damage.value;
|
||||||
this.battleData.hitCount++;
|
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);
|
this.turnData.attacksReceived.unshift(attackResult);
|
||||||
if (source.isPlayer() && !this.isPlayer()) {
|
if (source.isPlayer() && !this.isPlayer()) {
|
||||||
this.scene.applyModifiers(DamageMoneyRewardModifier, true, source, damage);
|
this.scene.applyModifiers(DamageMoneyRewardModifier, true, source, damage);
|
||||||
|
@ -3990,6 +3990,7 @@ export interface AttackMoveResult {
|
||||||
damage: integer;
|
damage: integer;
|
||||||
critical: boolean;
|
critical: boolean;
|
||||||
sourceId: integer;
|
sourceId: integer;
|
||||||
|
attackingPosition: BattlerIndex;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class PokemonSummonData {
|
export class PokemonSummonData {
|
||||||
|
|
|
@ -2661,11 +2661,18 @@ export class MovePhase extends BattlePhase {
|
||||||
this.targets[0] = moveTarget.value;
|
this.targets[0] = moveTarget.value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Check for counterattack moves to switch target
|
||||||
if (this.targets.length === 1 && this.targets[0] === BattlerIndex.ATTACKER) {
|
if (this.targets.length === 1 && this.targets[0] === BattlerIndex.ATTACKER) {
|
||||||
if (this.pokemon.turnData.attacksReceived.length) {
|
if (this.pokemon.turnData.attacksReceived.length) {
|
||||||
const attacker = this.pokemon.turnData.attacksReceived.length ? this.pokemon.scene.getPokemonById(this.pokemon.turnData.attacksReceived[0].sourceId) : null;
|
const attack = this.pokemon.turnData.attacksReceived[0];
|
||||||
if (attacker?.isActive(true)) {
|
this.targets[0] = attack.attackingPosition;
|
||||||
this.targets[0] = attacker.getBattlerIndex();
|
|
||||||
|
// 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) {
|
if (this.targets[0] === BattlerIndex.ATTACKER) {
|
||||||
|
|
Loading…
Reference in New Issue