diff --git a/src/data/arena-tag.ts b/src/data/arena-tag.ts index a879c68d4ce..6da860ed22e 100644 --- a/src/data/arena-tag.ts +++ b/src/data/arena-tag.ts @@ -77,6 +77,24 @@ export class MistTag extends ArenaTag { } } + +export class TailwindTag extends ArenaTag { + constructor(turnCount: integer, sourceId: integer, side: ArenaTagSide) { + super(ArenaTagType.TAILWIND, turnCount, Moves.TAILWIND, sourceId, side); + } + + onAdd(arena: Arena): void { + const sideDescriptor = this.side === ArenaTagSide.PLAYER ? '\non your side' : (this.side === ArenaTagSide.ENEMY ? '\non the foe\'s side' : ''); + arena.scene.queueMessage(`The tail wind blew from behind ${sideDescriptor}.`); + } + + onRemove(arena: Arena): void { + const sideDescriptor = this.side === ArenaTagSide.PLAYER ? '\non your side' : (this.side === ArenaTagSide.ENEMY ? '\non the foe\'s side' : ''); + arena.scene.queueMessage(`The tail wind behind ${sideDescriptor} faded.`); + } +} + + export class WeakenMoveScreenTag extends ArenaTag { constructor(tagType: ArenaTagType, turnCount: integer, sourceMove: Moves, sourceId: integer, side: ArenaTagSide) { super(tagType, turnCount, sourceMove, sourceId, side); @@ -513,5 +531,7 @@ export function getArenaTag(tagType: ArenaTagType, turnCount: integer, sourceMov return new LightScreenTag(turnCount, sourceId, side); case ArenaTagType.AURORA_VEIL: return new AuroraVeilTag(turnCount, sourceId, side); + case ArenaTagType.TAILWIND: + return new TailwindTag(turnCount, sourceId, side); } } diff --git a/src/data/enums/arena-tag-type.ts b/src/data/enums/arena-tag-type.ts index 8478b6f3f57..2ecac8b5677 100644 --- a/src/data/enums/arena-tag-type.ts +++ b/src/data/enums/arena-tag-type.ts @@ -15,5 +15,6 @@ export enum ArenaTagType { GRAVITY = "GRAVITY", REFLECT = "REFLECT", LIGHT_SCREEN = "LIGHT_SCREEN", - AURORA_VEIL = "AURORA_VEIL" + AURORA_VEIL = "AURORA_VEIL", + TAILWIND = "TAILWIND" } diff --git a/src/data/move.ts b/src/data/move.ts index 70753bcb8bc..039f0706f11 100644 --- a/src/data/move.ts +++ b/src/data/move.ts @@ -2821,7 +2821,9 @@ export class AddArenaTagAttr extends MoveEffectAttr { return false; if (move.chance < 0 || move.chance === 100 || user.randSeedInt(100) < move.chance) { - user.scene.arena.addTag(this.tagType, this.turnCount, move.id, user.id, (this.selfSideTarget ? user : target).isPlayer() ? ArenaTagSide.PLAYER : ArenaTagSide.ENEMY); + const side = (this.selfSideTarget ? user : target).isPlayer() ? ArenaTagSide.PLAYER : ArenaTagSide.ENEMY; + user.scene.arena.addTag(this.tagType, this.turnCount, move.id, user.id, side); + console.log(`Adding tag ${this.tagType} to the side ${side} for ${this.turnCount} turns`); return true; } @@ -2829,8 +2831,8 @@ export class AddArenaTagAttr extends MoveEffectAttr { } getCondition(): MoveConditionFunc { - return this.failOnOverlap - ? (user, target, move) => !user.scene.arena.getTagOnSide(this.tagType, target.isPlayer() ? ArenaTagSide.PLAYER : ArenaTagSide.ENEMY) + return this.failOnOverlap ? + (user, target, move) => !user.scene.arena.getTagOnSide(this.tagType, (this.selfSideTarget ? user : target).isPlayer() ? ArenaTagSide.PLAYER : ArenaTagSide.ENEMY) : null; } } @@ -4780,8 +4782,9 @@ export function initMoves() { .partial(), new StatusMove(Moves.TAILWIND, Type.FLYING, -1, 15, -1, 0, 4) .windMove() - .target(MoveTarget.USER_SIDE) - .unimplemented(), + .attr(AddArenaTagAttr, ArenaTagType.TAILWIND, 4, true) + .target(MoveTarget.USER_SIDE), + // .unimplemented(), new StatusMove(Moves.ACUPRESSURE, Type.NORMAL, -1, 30, -1, 0, 4) .attr(StatChangeAttr, BattleStat.RAND, 2) .target(MoveTarget.USER_OR_NEAR_ALLY), diff --git a/src/field/arena.ts b/src/field/arena.ts index 5b14560d407..5c9d0274c6c 100644 --- a/src/field/arena.ts +++ b/src/field/arena.ts @@ -492,7 +492,7 @@ export class Arena { } addTag(tagType: ArenaTagType, turnCount: integer, sourceMove: Moves, sourceId: integer, side: ArenaTagSide = ArenaTagSide.BOTH, targetIndex?: BattlerIndex): boolean { - const existingTag = this.getTag(tagType); + const existingTag = side === ArenaTagSide.BOTH ? this.getTag(tagType) : this.getTagOnSide(tagType, side); if (existingTag) { existingTag.onOverlap(this); return false; diff --git a/src/field/pokemon.ts b/src/field/pokemon.ts index 55036e1906d..9a6186157fc 100644 --- a/src/field/pokemon.ts +++ b/src/field/pokemon.ts @@ -581,6 +581,11 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { ret *= 1.5; break; case Stat.SPD: + if((this.isPlayer() && this.scene.arena.getTagOnSide(ArenaTagType.TAILWIND, ArenaTagSide.PLAYER)) + || (!this.isPlayer() && this.scene.arena.getTagOnSide(ArenaTagType.TAILWIND, ArenaTagSide.ENEMY))) { + ret *= 2; + } + if (this.getTag(BattlerTagType.SLOW_START)) ret >>= 1; if (this.status && this.status.effect === StatusEffect.PARALYSIS) diff --git a/src/overrides.ts b/src/overrides.ts index 732b1a5a45b..0b956b53489 100644 --- a/src/overrides.ts +++ b/src/overrides.ts @@ -14,10 +14,10 @@ export const STARTING_MONEY_OVERRIDE = 0; export const WEATHER_OVERRIDE = WeatherType.NONE; export const ABILITY_OVERRIDE = Abilities.NONE; -export const MOVE_OVERRIDE = Moves.NONE; +export const MOVE_OVERRIDE = Moves.TAILWIND; export const OPP_SPECIES_OVERRIDE = 0; export const OPP_ABILITY_OVERRIDE = Abilities.NONE; -export const OPP_MOVE_OVERRIDE = Moves.NONE; +export const OPP_MOVE_OVERRIDE = Moves.TAILWIND; export const OPP_SHINY_OVERRIDE = false; export const OPP_VARIANT_OVERRIDE = 0; diff --git a/src/phases.ts b/src/phases.ts index a3209ea36b9..0bc3a0ee049 100644 --- a/src/phases.ts +++ b/src/phases.ts @@ -1941,7 +1941,8 @@ export class TurnStartPhase extends FieldPhase { // Set the priority of the different move command for (let _battlerIndex of moveOrder) { let command = this.scene.currentBattle.turnCommands[_battlerIndex]; - + + command.priority = 6; // Default Command priority for non battling actions if(command.command === Command.FIGHT) { // The command Priority is the Command of the Move let source = this.scene.getField().find(p => p?.isActive() && p.getBattlerIndex() === _battlerIndex); @@ -1953,13 +1954,9 @@ export class TurnStartPhase extends FieldPhase { applyAbAttrs(IncrementMovePriorityAbAttr, source, null, move, movePriority); command.priority = movePriority.value; } - else { - // The command Priority is +6 - command.priority = 6; - } } - + moveOrder.sort((a, b) => { // Comparison of the priority Brackets const priorityComp = this.scene.currentBattle.turnCommands[b].priority - this.scene.currentBattle.turnCommands[a].priority;