Used tag instead of stat changes for Unburden

This commit is contained in:
muscode13 2024-10-02 08:59:58 -06:00
parent 1632a52449
commit 09d2cbb360
4 changed files with 56 additions and 59 deletions

View File

@ -3792,28 +3792,16 @@ export class PostDancingMoveAbAttr extends PostMoveUsedAbAttr {
}
export class UnburdenBerryAbAttr extends PostTurnAbAttr {
private stats: BattleStat[];
private stages: number;
constructor(stats: BattleStat[], stages: number) {
super(true);
this.stats = Array.isArray(stats)
? stats
: [ stats ];
this.stages = stages;
}
applyPostTurn(pokemon: Pokemon, passive: boolean, simulated: boolean, args: any[]): boolean {
const multipleItems = pokemon.battleData.berriesEaten.length * this.stages;
if (multipleItems > 6) {
this.stages = 6;
} else {
this.stages = multipleItems;
if (simulated) {
return simulated;
}
if (!simulated) {
pokemon.scene.unshiftPhase(new StatStageChangePhase(pokemon.scene, pokemon.getBattlerIndex(), true, this.stats, this.stages));
if (pokemon.getTag(BattlerTagType.UNBURDEN)) {
return false;
}
pokemon.addTag(BattlerTagType.UNBURDEN);
return true;
}
@ -3824,23 +3812,16 @@ export class UnburdenBerryAbAttr extends PostTurnAbAttr {
}
export class UnburdenDefStolenAbAttr extends PostDefendAbAttr {
private stats: BattleStat[];
private stages: number;
constructor(stats: BattleStat[], stages: number) {
super(true);
this.stats = Array.isArray(stats)
? stats
: [ stats ];
this.stages = stages;
}
applyPostDefend(pokemon: Pokemon, passive: boolean, simulated: boolean, attacker: Pokemon, move: Move, hitResult: HitResult, args: any[]): boolean {
if (!simulated) {
pokemon.scene.unshiftPhase(new StatStageChangePhase(pokemon.scene, pokemon.getBattlerIndex(), true, this.stats, this.stages));
pokemon.turnData.itemsLost -= 1;
if (simulated) {
return simulated;
}
if (pokemon.getTag(BattlerTagType.UNBURDEN)) {
return false;
}
pokemon.addTag(BattlerTagType.UNBURDEN);
return true;
}
@ -3851,23 +3832,16 @@ export class UnburdenDefStolenAbAttr extends PostDefendAbAttr {
}
export class UnburdenAtkStolenAbAttr extends PostAttackAbAttr {
private stats: BattleStat[];
private stages: number;
constructor(stats: BattleStat[], stages: number) {
super();
this.stats = Array.isArray(stats)
? stats
: [ stats ];
this.stages = stages;
}
applyPostAttackAfterMoveTypeCheck(pokemon: Pokemon, passive: boolean, simulated: boolean, defender: Pokemon, move: Move, hitResult: HitResult, args: any[]): boolean {
if (!simulated) {
pokemon.scene.unshiftPhase(new StatStageChangePhase(pokemon.scene, pokemon.getBattlerIndex(), true, this.stats, this.stages));
pokemon.turnData.itemsLost -= 1;
if (simulated) {
return simulated;
}
if (pokemon.getTag(BattlerTagType.UNBURDEN)) {
return false;
}
pokemon.addTag(BattlerTagType.UNBURDEN);
return true;
}
@ -5188,9 +5162,9 @@ export function initAbilities() {
new Ability(Abilities.ANGER_POINT, 4)
.attr(PostDefendCritStatStageChangeAbAttr, Stat.ATK, 6),
new Ability(Abilities.UNBURDEN, 4)
.attr(UnburdenBerryAbAttr, [ Stat.SPD ], 2)
.attr(UnburdenAtkStolenAbAttr, [ Stat.SPD ], 2)
.attr(UnburdenDefStolenAbAttr, [ Stat.SPD ], 2),
.attr(UnburdenBerryAbAttr)
.attr(UnburdenAtkStolenAbAttr)
.attr(UnburdenDefStolenAbAttr),
new Ability(Abilities.HEATPROOF, 4)
.attr(ReceivedTypeDamageMultiplierAbAttr, Type.FIRE, 0.5)
.attr(ReduceBurnDamageAbAttr, 0.5)

View File

@ -1537,6 +1537,19 @@ export class AbilityBattlerTag extends BattlerTag {
}
}
/**
* Tag used by Unburden to double speed
* @extends AbilityBattlerTag
*/
export class UnburdenTag extends AbilityBattlerTag {
constructor() {
super(BattlerTagType.UNBURDEN, Abilities.UNBURDEN, BattlerTagLapseType.CUSTOM, 1);
}
onAdd(pokemon: Pokemon): void {
pokemon.setStat(Stat.SPD, pokemon.getStat(Stat.SPD, false) * 2, false);
}
}
export class TruantTag extends AbilityBattlerTag {
constructor() {
super(BattlerTagType.TRUANT, Abilities.TRUANT, BattlerTagLapseType.MOVE, 1);
@ -2815,6 +2828,8 @@ export function getBattlerTag(tagType: BattlerTagType, turnCount: number, source
return new ThroatChoppedTag();
case BattlerTagType.GORILLA_TACTICS:
return new GorillaTacticsTag();
case BattlerTagType.UNBURDEN:
return new UnburdenTag();
case BattlerTagType.SUBSTITUTE:
return new SubstituteTag(sourceMove, sourceId);
case BattlerTagType.AUTOTOMIZED:

View File

@ -75,6 +75,7 @@ export enum BattlerTagType {
DRAGON_CHEER = "DRAGON_CHEER",
NO_RETREAT = "NO_RETREAT",
GORILLA_TACTICS = "GORILLA_TACTICS",
UNBURDEN = "UNBURDEN",
THROAT_CHOPPED = "THROAT_CHOPPED",
TAR_SHOT = "TAR_SHOT",
BURNED_UP = "BURNED_UP",

View File

@ -50,29 +50,32 @@ describe("Abilities - Unburden", () => {
await game.classicMode.startBattle();
const playerPokemon = game.scene.getPlayerPokemon()!;
const playerHeldItems = playerPokemon.getHeldItems().length;
const initialPlayerSpeed = playerPokemon.getStat(Stat.SPD);
game.move.select(Moves.FALSE_SWIPE);
await game.toNextTurn();
expect(playerPokemon.getHeldItems().length).toBeLessThan(playerHeldItems);
expect(playerPokemon.getStatStage(Stat.SPD)).toBe(4);
expect(playerPokemon.getStat(Stat.SPD, false)).toBeCloseTo(initialPlayerSpeed * 2);
});
it("should activate when a berry is stolen", async () => {
await game.classicMode.startBattle();
const enemyPokemon = game.scene.getEnemyPokemon()!;
const enemyHeldItemCt = enemyPokemon.getHeldItems().length;
const initialEnemySpeed = enemyPokemon.getStat(Stat.SPD);
game.move.select(Moves.PLUCK);
await game.toNextTurn();
expect(enemyPokemon.getHeldItems().length).toBeLessThan(enemyHeldItemCt);
expect(enemyPokemon.getStatStage(Stat.SPD)).toBe(2);
expect(enemyPokemon.getStat(Stat.SPD, false)).toBeCloseTo(initialEnemySpeed * 2);
});
it("should activate when an item is knocked off", async () => {
await game.classicMode.startBattle();
const enemyPokemon = game.scene.getEnemyPokemon()!;
const enemyHeldItemCt = enemyPokemon.getHeldItems().length;
const initialEnemySpeed = enemyPokemon.getStat(Stat.SPD);
game.move.select(Moves.KNOCK_OFF);
await game.toNextTurn();
expect(enemyPokemon.getHeldItems().length).toBeLessThan(enemyHeldItemCt);
expect(enemyPokemon.getStatStage(Stat.SPD)).toBe(2);
expect(enemyPokemon.getStat(Stat.SPD, false)).toBeCloseTo(initialEnemySpeed * 2);
});
it("should activate when an item is stolen via attacking ability", async () => {
game.override
@ -84,10 +87,11 @@ describe("Abilities - Unburden", () => {
vi.spyOn(allMoves[Moves.POPULATION_BOMB], "accuracy", "get").mockReturnValue(100);
const enemyPokemon = game.scene.getEnemyPokemon()!;
const enemyHeldItemCt = enemyPokemon.getHeldItems().length;
const initialEnemySpeed = enemyPokemon.getStat(Stat.SPD);
game.move.select(Moves.POPULATION_BOMB);
await game.toNextTurn();
expect(enemyPokemon.getHeldItems().length).toBeLessThan(enemyHeldItemCt);
expect(enemyPokemon.getStatStage(Stat.SPD)).toBe(4);
expect(enemyPokemon.getStat(Stat.SPD, false)).toBeCloseTo(initialEnemySpeed * 2);
});
it("should activate when an item is stolen via defending ability", async () => {
game.override
@ -101,10 +105,11 @@ describe("Abilities - Unburden", () => {
vi.spyOn(allMoves[Moves.POPULATION_BOMB], "accuracy", "get").mockReturnValue(100);
const playerPokemon = game.scene.getPlayerPokemon()!;
const playerHeldItems = playerPokemon.getHeldItems().length;
const initialPlayerSpeed = playerPokemon.getStat(Stat.SPD);
game.move.select(Moves.POPULATION_BOMB);
await game.toNextTurn();
expect(playerPokemon.getHeldItems().length).toBeLessThan(playerHeldItems);
expect(playerPokemon.getStatStage(Stat.SPD)).toBe(6);
expect(playerPokemon.getStat(Stat.SPD, false)).toBeCloseTo(initialPlayerSpeed * 2);
});
it("should activate when an item is stolen via move", async () => {
vi.spyOn(allMoves[Moves.THIEF], "attrs", "get").mockReturnValue([new StealHeldItemChanceAttr(1.0)]); // give Thief 100% steal rate
@ -114,10 +119,11 @@ describe("Abilities - Unburden", () => {
await game.classicMode.startBattle();
const enemyPokemon = game.scene.getEnemyPokemon()!;
const enemyHeldItemCt = enemyPokemon.getHeldItems().length;
const initialEnemySpeed = enemyPokemon.getStat(Stat.SPD);
game.move.select(Moves.THIEF);
await game.toNextTurn();
expect(enemyPokemon.getHeldItems().length).toBeLessThan(enemyHeldItemCt);
expect(enemyPokemon.getStatStage(Stat.SPD)).toBe(4);
expect(enemyPokemon.getStat(Stat.SPD, false)).toBeCloseTo(initialEnemySpeed * 2);
});
it("should activate when an item is stolen via grip claw", async () => {
game.override.startingHeldItems([
@ -128,9 +134,10 @@ describe("Abilities - Unburden", () => {
vi.spyOn(allMoves[Moves.POPULATION_BOMB], "accuracy", "get").mockReturnValue(100);
const enemyPokemon = game.scene.getEnemyPokemon()!;
const enemyHeldItemCt = enemyPokemon.getHeldItems().length;
const initialEnemySpeed = enemyPokemon.getStat(Stat.SPD);
game.move.select(Moves.POPULATION_BOMB);
await game.toNextTurn();
expect(enemyPokemon.getHeldItems().length).toBeLessThan(enemyHeldItemCt);
expect(enemyPokemon.getStatStage(Stat.SPD)).toBe(4);
expect(enemyPokemon.getStat(Stat.SPD, false)).toBeCloseTo(initialEnemySpeed * 2);
});
});