mirror of
https://github.com/pagefaultgames/pokerogue.git
synced 2025-06-29 04:52:43 +02:00
Merge remote-tracking branch 'upstream/beta' into held-item-refactor
This commit is contained in:
commit
8d63f06de2
@ -2535,48 +2535,38 @@ export class AllyStatMultiplierAbAttr extends AbAttr {
|
||||
}
|
||||
|
||||
/**
|
||||
* Ability attribute for Gorilla Tactics
|
||||
* @extends PostAttackAbAttr
|
||||
* Takes effect whenever a move succesfully executes, such as gorilla tactics' move-locking.
|
||||
* (More specifically, whenever a move is pushed to the move history)
|
||||
* @extends AbAttr
|
||||
*/
|
||||
export class GorillaTacticsAbAttr extends PostAttackAbAttr {
|
||||
constructor() {
|
||||
super((_user, _target, _move) => true, false);
|
||||
export class ExecutedMoveAbAttr extends AbAttr {
|
||||
canApplyExecutedMove(
|
||||
_pokemon: Pokemon,
|
||||
_simulated: boolean,
|
||||
): boolean {
|
||||
return true;
|
||||
}
|
||||
|
||||
override canApplyPostAttack(
|
||||
pokemon: Pokemon,
|
||||
passive: boolean,
|
||||
simulated: boolean,
|
||||
defender: Pokemon,
|
||||
move: Move,
|
||||
hitResult: HitResult | null,
|
||||
args: any[],
|
||||
): boolean {
|
||||
return (
|
||||
(super.canApplyPostAttack(pokemon, passive, simulated, defender, move, hitResult, args) && simulated) ||
|
||||
!pokemon.getTag(BattlerTagType.GORILLA_TACTICS)
|
||||
);
|
||||
applyExecutedMove(
|
||||
_pokemon: Pokemon,
|
||||
_simulated: boolean,
|
||||
): void {}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {Pokemon} pokemon the {@linkcode Pokemon} with this ability
|
||||
* @param _passive n/a
|
||||
* @param simulated whether the ability is being simulated
|
||||
* @param _defender n/a
|
||||
* @param _move n/a
|
||||
* @param _hitResult n/a
|
||||
* @param _args n/a
|
||||
* Ability attribute for Gorilla Tactics
|
||||
* @extends ExecutedMoveAbAttr
|
||||
*/
|
||||
override applyPostAttack(
|
||||
pokemon: Pokemon,
|
||||
_passive: boolean,
|
||||
simulated: boolean,
|
||||
_defender: Pokemon,
|
||||
_move: Move,
|
||||
_hitResult: HitResult | null,
|
||||
_args: any[],
|
||||
): void {
|
||||
export class GorillaTacticsAbAttr extends ExecutedMoveAbAttr {
|
||||
constructor(showAbility: boolean = false) {
|
||||
super(showAbility);
|
||||
}
|
||||
|
||||
override canApplyExecutedMove(pokemon: Pokemon, simulated: boolean): boolean {
|
||||
return simulated || !pokemon.getTag(BattlerTagType.GORILLA_TACTICS);
|
||||
}
|
||||
|
||||
override applyExecutedMove(pokemon: Pokemon, simulated: boolean): void {
|
||||
if (!simulated) {
|
||||
pokemon.addTag(BattlerTagType.GORILLA_TACTICS);
|
||||
}
|
||||
@ -7789,6 +7779,22 @@ export function applyPreAttackAbAttrs(
|
||||
);
|
||||
}
|
||||
|
||||
export function applyExecutedMoveAbAttrs(
|
||||
attrType: Constructor<ExecutedMoveAbAttr>,
|
||||
pokemon: Pokemon,
|
||||
simulated: boolean = false,
|
||||
...args: any[]
|
||||
): void {
|
||||
applyAbAttrsInternal<ExecutedMoveAbAttr>(
|
||||
attrType,
|
||||
pokemon,
|
||||
attr => attr.applyExecutedMove(pokemon, simulated),
|
||||
attr => attr.canApplyExecutedMove(pokemon, simulated),
|
||||
args,
|
||||
simulated,
|
||||
);
|
||||
}
|
||||
|
||||
export function applyPostAttackAbAttrs(
|
||||
attrType: Constructor<PostAttackAbAttr>,
|
||||
pokemon: Pokemon,
|
||||
|
@ -5988,6 +5988,7 @@ export const tmSpecies: TmSpecies = {
|
||||
SpeciesId.FEZANDIPITI,
|
||||
SpeciesId.ARCHALUDON,
|
||||
SpeciesId.IRON_CROWN,
|
||||
SpeciesId.TERAPAGOS,
|
||||
SpeciesId.ALOLA_RATICATE,
|
||||
SpeciesId.ALOLA_RAICHU,
|
||||
SpeciesId.ALOLA_SANDSLASH,
|
||||
@ -16248,6 +16249,7 @@ export const tmSpecies: TmSpecies = {
|
||||
SpeciesId.CALYREX,
|
||||
SpeciesId.SANDY_SHOCKS,
|
||||
SpeciesId.IRON_JUGULIS,
|
||||
SpeciesId.TERAPAGOS,
|
||||
SpeciesId.ALOLA_DUGTRIO,
|
||||
SpeciesId.GALAR_SLOWPOKE,
|
||||
SpeciesId.GALAR_SLOWBRO,
|
||||
@ -39466,6 +39468,8 @@ export const tmSpecies: TmSpecies = {
|
||||
SpeciesId.FARFETCHD,
|
||||
SpeciesId.DODUO,
|
||||
SpeciesId.DODRIO,
|
||||
SpeciesId.DEWGONG,
|
||||
SpeciesId.GRIMER,
|
||||
SpeciesId.MUK,
|
||||
SpeciesId.GASTLY,
|
||||
SpeciesId.HAUNTER,
|
||||
@ -39477,6 +39481,7 @@ export const tmSpecies: TmSpecies = {
|
||||
SpeciesId.CUBONE,
|
||||
SpeciesId.MAROWAK,
|
||||
SpeciesId.HITMONLEE,
|
||||
SpeciesId.HITMONCHAN,
|
||||
SpeciesId.LICKITUNG,
|
||||
SpeciesId.TANGELA,
|
||||
SpeciesId.GOLDEEN,
|
||||
@ -48806,6 +48811,7 @@ export const tmSpecies: TmSpecies = {
|
||||
SpeciesId.GARGANACL,
|
||||
SpeciesId.GLIMMET,
|
||||
SpeciesId.GLIMMORA,
|
||||
SpeciesId.TERAPAGOS,
|
||||
SpeciesId.ALOLA_GEODUDE,
|
||||
SpeciesId.ALOLA_GRAVELER,
|
||||
SpeciesId.ALOLA_GOLEM,
|
||||
@ -53077,6 +53083,7 @@ export const tmSpecies: TmSpecies = {
|
||||
SpeciesId.MIRAIDON,
|
||||
SpeciesId.ARCHALUDON,
|
||||
SpeciesId.IRON_CROWN,
|
||||
SpeciesId.TERAPAGOS,
|
||||
[
|
||||
SpeciesId.WORMADAM,
|
||||
"trash",
|
||||
|
@ -3,10 +3,12 @@ import { globalScene } from "#app/global-scene";
|
||||
import {
|
||||
AddSecondStrikeAbAttr,
|
||||
AlwaysHitAbAttr,
|
||||
applyExecutedMoveAbAttrs,
|
||||
applyPostAttackAbAttrs,
|
||||
applyPostDamageAbAttrs,
|
||||
applyPostDefendAbAttrs,
|
||||
applyPreAttackAbAttrs,
|
||||
ExecutedMoveAbAttr,
|
||||
IgnoreMoveEffectsAbAttr,
|
||||
MaxMultiHitAbAttr,
|
||||
PostAttackAbAttr,
|
||||
@ -374,6 +376,7 @@ export class MoveEffectPhase extends PokemonPhase {
|
||||
// Add to the move history entry
|
||||
if (this.firstHit) {
|
||||
user.pushMoveHistory(this.moveHistoryEntry);
|
||||
applyExecutedMoveAbAttrs(ExecutedMoveAbAttr, user);
|
||||
}
|
||||
|
||||
try {
|
||||
|
@ -32,6 +32,8 @@ import Overrides from "#app/overrides";
|
||||
import type { CustomModifierSettings } from "#app/modifier/modifier-type";
|
||||
import { isNullOrUndefined, NumberHolder } from "#app/utils/common";
|
||||
|
||||
export type ModifierSelectCallback = (rowCursor: number, cursor: number) => boolean;
|
||||
|
||||
export class SelectModifierPhase extends BattlePhase {
|
||||
public readonly phaseName = "SelectModifierPhase";
|
||||
private rerollCount: number;
|
||||
@ -58,6 +60,10 @@ export class SelectModifierPhase extends BattlePhase {
|
||||
start() {
|
||||
super.start();
|
||||
|
||||
if (!this.isPlayer()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!this.rerollCount && !this.isCopy) {
|
||||
this.updateSeed();
|
||||
} else if (this.rerollCount) {
|
||||
@ -70,6 +76,9 @@ export class SelectModifierPhase extends BattlePhase {
|
||||
}
|
||||
const modifierCount = this.getModifierCount();
|
||||
|
||||
this.typeOptions = this.getModifierTypeOptions(modifierCount);
|
||||
const modifierCount = this.getModifierCount();
|
||||
|
||||
this.typeOptions = this.getModifierTypeOptions(modifierCount);
|
||||
|
||||
const modifierSelectCallback = (rowCursor: number, cursor: number) => {
|
||||
@ -121,7 +130,7 @@ export class SelectModifierPhase extends BattlePhase {
|
||||
}
|
||||
|
||||
// Pick a modifier from among the rewards and apply it
|
||||
private selectRewardModifierOption(cursor: number, modifierSelectCallback): boolean {
|
||||
private selectRewardModifierOption(cursor: number, modifierSelectCallback: ModifierSelectCallback): boolean {
|
||||
if (this.typeOptions.length === 0) {
|
||||
globalScene.ui.clearText();
|
||||
globalScene.ui.setMode(UiMode.MESSAGE);
|
||||
@ -133,7 +142,11 @@ export class SelectModifierPhase extends BattlePhase {
|
||||
}
|
||||
|
||||
// Pick a modifier from the shop and apply it
|
||||
private selectShopModifierOption(rowCursor: number, cursor: number, modifierSelectCallback): boolean {
|
||||
private selectShopModifierOption(
|
||||
rowCursor: number,
|
||||
cursor: number,
|
||||
modifierSelectCallback: ModifierSelectCallback,
|
||||
): boolean {
|
||||
const shopOptions = getPlayerShopModifierTypeOptionsForWave(
|
||||
globalScene.currentBattle.waveIndex,
|
||||
globalScene.getWaveMoneyAmount(1),
|
||||
@ -157,18 +170,19 @@ export class SelectModifierPhase extends BattlePhase {
|
||||
}
|
||||
|
||||
// Apply a chosen modifier: do an effect or open the party menu
|
||||
private applyChosenModifier(modifierType: ModifierType, cost: number, modifierSelectCallback): boolean {
|
||||
if (modifierType! instanceof PokemonModifierType) {
|
||||
//TODO: is the bang correct?
|
||||
if (modifierType instanceof PokemonHeldItemReward) {
|
||||
this.openGiveHeldItemMenu(modifierType, modifierSelectCallback);
|
||||
} else if (modifierType instanceof FusePokemonModifierType) {
|
||||
private applyChosenModifier(
|
||||
modifierType: ModifierType,
|
||||
cost: number,
|
||||
modifierSelectCallback: ModifierSelectCallback,
|
||||
): boolean {
|
||||
if (modifierType instanceof PokemonModifierType) {
|
||||
if (modifierType instanceof FusePokemonModifierType) {
|
||||
this.openFusionMenu(modifierType, cost, modifierSelectCallback);
|
||||
} else {
|
||||
this.openModifierMenu(modifierType, cost, modifierSelectCallback);
|
||||
}
|
||||
} else {
|
||||
this.applyModifier(modifierType!.newModifier()!); // TODO: is the bang correct?
|
||||
this.applyModifier(modifierType.newModifier()!);
|
||||
}
|
||||
return !cost;
|
||||
}
|
||||
@ -198,7 +212,7 @@ export class SelectModifierPhase extends BattlePhase {
|
||||
}
|
||||
|
||||
// Transfer modifiers among party pokemon
|
||||
private openModifierTransferScreen(modifierSelectCallback) {
|
||||
private openModifierTransferScreen(modifierSelectCallback: ModifierSelectCallback) {
|
||||
const party = globalScene.getPlayerParty();
|
||||
globalScene.ui.setModeWithoutClear(
|
||||
UiMode.PARTY,
|
||||
@ -251,7 +265,7 @@ export class SelectModifierPhase extends BattlePhase {
|
||||
}
|
||||
|
||||
// Applies the effects of the chosen modifier
|
||||
private applyModifier(modifier: Modifier, cost = 0, playSound = false) {
|
||||
private applyModifier(modifier: Modifier, cost = 0, playSound = false): void {
|
||||
const result = globalScene.addModifier(modifier, false, playSound, undefined, undefined, cost);
|
||||
// Queue a copy of this phase when applying a TM or Memory Mushroom.
|
||||
// If the player selects either of these, then escapes out of consuming them,
|
||||
@ -399,7 +413,7 @@ export class SelectModifierPhase extends BattlePhase {
|
||||
|
||||
// Function that resets the reward selection screen,
|
||||
// e.g. after pressing cancel in the party ui or while learning a move
|
||||
private resetModifierSelect(modifierSelectCallback) {
|
||||
private resetModifierSelect(modifierSelectCallback: ModifierSelectCallback) {
|
||||
globalScene.ui.setMode(
|
||||
UiMode.MODIFIER_SELECT,
|
||||
this.isPlayer(),
|
||||
|
@ -25,7 +25,7 @@ describe("Abilities - Dancer", () => {
|
||||
|
||||
beforeEach(() => {
|
||||
game = new GameManager(phaserGame);
|
||||
game.override.battleStyle("double");
|
||||
game.override.battleStyle("double").enemyAbility(AbilityId.BALL_FETCH);
|
||||
});
|
||||
|
||||
// Reference Link: https://bulbapedia.bulbagarden.net/wiki/Dancer_(Ability)
|
||||
|
@ -73,9 +73,38 @@ describe("Abilities - Gorilla Tactics", () => {
|
||||
await game.toNextTurn();
|
||||
|
||||
game.move.select(MoveId.TACKLE);
|
||||
await game.move.forceEnemyMove(MoveId.SPLASH); //prevent protect from being used by the enemy
|
||||
await game.setTurnOrder([BattlerIndex.PLAYER, BattlerIndex.ENEMY]);
|
||||
|
||||
await game.phaseInterceptor.to("MoveEndPhase");
|
||||
expect(darmanitan.hp).toBeLessThan(darmanitan.getMaxHp());
|
||||
});
|
||||
|
||||
it("should activate when the opponenet protects", async () => {
|
||||
await game.classicMode.startBattle([SpeciesId.GALAR_DARMANITAN]);
|
||||
|
||||
const darmanitan = game.field.getPlayerPokemon();
|
||||
|
||||
game.move.select(MoveId.TACKLE);
|
||||
await game.move.selectEnemyMove(MoveId.PROTECT);
|
||||
|
||||
await game.toEndOfTurn();
|
||||
expect(darmanitan.isMoveRestricted(MoveId.SPLASH)).toBe(true);
|
||||
expect(darmanitan.isMoveRestricted(MoveId.TACKLE)).toBe(false);
|
||||
});
|
||||
|
||||
it("should activate when a move is succesfully executed but misses", async () => {
|
||||
await game.classicMode.startBattle([SpeciesId.GALAR_DARMANITAN]);
|
||||
|
||||
const darmanitan = game.field.getPlayerPokemon();
|
||||
|
||||
game.move.select(MoveId.TACKLE);
|
||||
await game.move.selectEnemyMove(MoveId.SPLASH);
|
||||
await game.setTurnOrder([BattlerIndex.PLAYER, BattlerIndex.ENEMY]);
|
||||
await game.move.forceMiss();
|
||||
await game.toEndOfTurn();
|
||||
|
||||
expect(darmanitan.isMoveRestricted(MoveId.SPLASH)).toBe(true);
|
||||
expect(darmanitan.isMoveRestricted(MoveId.TACKLE)).toBe(false);
|
||||
});
|
||||
});
|
||||
|
Loading…
Reference in New Issue
Block a user