Compare commits

...

48 Commits

Author SHA1 Message Date
Eucalyptus a2d8171403
Merge d49d49f9bc into 10e0f9f0de 2024-12-20 23:41:58 -08:00
NightKev 10e0f9f0de
Merge pull request #5024 from pagefaultgames/main
Merge main to beta
2024-12-20 19:32:30 -08:00
AJ Fontaine 8457fb96fe
[Hotfix] Fix off-by-one error for event encounters (#5022)
* Fix off-by-one error for event encounters

* Increment version to 1.4.1

---------

Co-authored-by: NightKev <34855794+DayKev@users.noreply.github.com>
2024-12-20 18:41:07 -08:00
damocleas f95a5d41cb
Merge pull request #5019 from pagefaultgames/beta
Release 1.4.0
2024-12-20 19:06:24 -05:00
Tempoanon 6d903440b4
Release 1.3.0
Release 1.3.0
2024-12-03 18:05:48 -05:00
Eucalyptus d49d49f9bc Update use of isTransferrable to isTransferable 2024-10-06 12:54:08 -04:00
Eucalyptus caf6708067 Merge branch 'beta' into trick 2024-10-05 12:57:00 -04:00
eucalyptusJ 25761f7632 Fix enemy Pokemon not receiving any moves in tests 2024-09-10 11:00:24 -04:00
Eucalyptus 876d0894be
Merge branch 'beta' into trick 2024-09-09 23:57:36 -04:00
Eucalyptus 62aa532959
Update src/locales/ja/move-trigger.json
Co-authored-by: Chapybara-jp <charlie.beer@hotmail.com>
2024-09-09 23:56:39 -04:00
Eucalyptus 310bdc31cb
Merge branch 'beta' into trick 2024-09-09 14:16:53 -04:00
Eucalyptus 3680b4c334
Merge branch 'beta' into trick 2024-09-05 19:21:13 -04:00
Eucalyptus b32b024179
Merge branch 'beta' into trick 2024-09-03 23:17:34 -04:00
Eucalyptus 0be4fff72a
Merge branch 'beta' into trick 2024-09-01 05:42:27 -04:00
Eucalyptus a49e05a752
Merge branch 'beta' into trick 2024-08-29 20:40:00 -04:00
Eucalyptus 5d73dcfaf8
Merge branch 'beta' into trick 2024-08-29 11:05:13 -04:00
eucalyptusJ c05408c476 Readd removed German locales for Trick 2024-08-27 13:52:31 -04:00
eucalyptusJ b0ee897d5b Merge branch 'beta' into trick 2024-08-27 13:45:59 -04:00
Eucalyptus b37e1f4f55
Remove .js for importing modifier-tier
Co-authored-by: NightKev <34855794+DayKev@users.noreply.github.com>
2024-08-26 16:59:29 -04:00
eucalyptusJ 8a0b78a67f Add missing check for getEnemyPokemon being undefined 2024-08-26 11:06:28 -04:00
eucalyptusJ 9b011802e6 Account for getEnemyPokemon and getPlayerPokemon possibly returning undefined 2024-08-26 09:40:37 -04:00
Niccolò 5435781072
Update src/locales/it/move-trigger.json 2024-08-26 11:56:31 +02:00
eucalyptusJ 9e176906b5 Merge branch 'beta' into trick 2024-08-25 20:43:09 -04:00
Eucalyptus c38dfaaeff Update import for TurnEndPhase 2024-08-23 16:15:46 -04:00
Eucalyptus a27960a838 Replace doAttack with move.select 2024-08-23 16:15:19 -04:00
Eucalyptus a18d2db74d Merge branch 'beta' into trick 2024-08-23 15:58:09 -04:00
Eucalyptus a94b41e179 Merge branch 'beta' into trick 2024-08-23 01:34:12 -04:00
Eucalyptus 38495f9df3 Add tests for Toxic Orb and Flame Orb priorities 2024-08-23 01:09:56 -04:00
Eucalyptus 9d8b25ad2d Update base Trick test to match tier priority system 2024-08-23 00:32:03 -04:00
Eucalyptus 9d63f24b28 Fix index of the item to swap not being updated 2024-08-22 12:48:54 -04:00
Eucalyptus 9a9a0274d9 Merge branch 'beta' into trick 2024-08-17 03:17:27 -04:00
Eucalyptus ce4d22bb8a Trick no longer selects items randomly and instead bases it on item tier, and prioritizes Toxic Orb and Flame Orb 2024-08-17 03:08:54 -04:00
Eucalyptus 7bf6b1e250 Fix non player trainers being unable to use Trick 2024-08-16 15:18:00 -04:00
Eucalyptus c59bfa5686 Merge branch 'beta' into trick 2024-08-08 19:59:40 -04:00
Eucalyptus 96a553b8d0 Add tests for Trick 2024-08-07 18:25:57 -04:00
Eucalyptus 68150a7fb0 Add placeholder Japanese Trick locales 2024-08-07 03:55:20 -04:00
Eucalyptus eac4bef886 Move Trick locales to move-trigger 2024-08-07 03:33:06 -04:00
Eucalyptus 7ccbf9c141 Merge branch 'beta' into trick 2024-08-07 02:43:18 -04:00
Eucalyptus c84b769bfd
Merge branch 'pagefaultgames:main' into trick 2024-08-07 01:57:35 -04:00
Eucalyptus 8a1c7ca604
Update src/locales/zh_CN/battle.ts
Co-authored-by: mercurius-00 <80205689+mercurius-00@users.noreply.github.com>
2024-08-06 21:39:41 -04:00
Eucalyptus 7af542bd9d
Update src/locales/zh_TW/battle.ts
Co-authored-by: mercurius-00 <80205689+mercurius-00@users.noreply.github.com>
2024-08-06 21:39:34 -04:00
Eucalyptus 2ae2a9e0e6
Update src/locales/ko/battle.ts
Co-authored-by: Enoch <enoch.jwsong@gmail.com>
2024-08-06 21:39:25 -04:00
Eucalyptus 2bea2ed5db
Update src/locales/pt_BR/battle.ts
Co-authored-by: José Ricardo Fleury Oliveira <josefleury@discente.ufg.br>
2024-08-06 11:14:33 -04:00
Eucalyptus d7e700cfaf
Update src/locales/de/battle.ts
Co-authored-by: Jannik Tappert <38758606+CodeTappert@users.noreply.github.com>
2024-08-06 11:14:27 -04:00
Eucalyptus 261d9813d8
Update src/locales/fr/battle.ts
Co-authored-by: Lugiad' <adrien.grivel@hotmail.fr>
2024-08-06 11:14:19 -04:00
Eucalyptus 094781c38c Add placeholder Trick battler tags for remaining languages 2024-08-06 02:13:30 -04:00
Eucalyptus bbb693fe99 Implement Trick 2024-08-05 18:35:27 -04:00
Eucalyptus 316a759267 Add English Trick battler tags 2024-08-05 18:34:33 -04:00
7 changed files with 353 additions and 14 deletions

4
package-lock.json generated
View File

@ -1,12 +1,12 @@
{ {
"name": "pokemon-rogue-battle", "name": "pokemon-rogue-battle",
"version": "1.4.0", "version": "1.4.1",
"lockfileVersion": 3, "lockfileVersion": 3,
"requires": true, "requires": true,
"packages": { "packages": {
"": { "": {
"name": "pokemon-rogue-battle", "name": "pokemon-rogue-battle",
"version": "1.4.0", "version": "1.4.1",
"hasInstallScript": true, "hasInstallScript": true,
"dependencies": { "dependencies": {
"@material/material-color-utilities": "^0.2.7", "@material/material-color-utilities": "^0.2.7",

View File

@ -1,7 +1,7 @@
{ {
"name": "pokemon-rogue-battle", "name": "pokemon-rogue-battle",
"private": true, "private": true,
"version": "1.4.0", "version": "1.4.1",
"type": "module", "type": "module",
"scripts": { "scripts": {
"start": "vite", "start": "vite",

View File

@ -36,6 +36,7 @@ import { SwitchPhase } from "#app/phases/switch-phase";
import { SwitchSummonPhase } from "#app/phases/switch-summon-phase"; import { SwitchSummonPhase } from "#app/phases/switch-summon-phase";
import { ShowAbilityPhase } from "#app/phases/show-ability-phase"; import { ShowAbilityPhase } from "#app/phases/show-ability-phase";
import { SpeciesFormChangeRevertWeatherFormTrigger } from "./pokemon-forms"; import { SpeciesFormChangeRevertWeatherFormTrigger } from "./pokemon-forms";
import { ModifierTier } from "#app/modifier/modifier-tier";
import { GameMode } from "#app/game-mode"; import { GameMode } from "#app/game-mode";
import { applyChallenges, ChallengeType } from "./challenge"; import { applyChallenges, ChallengeType } from "./challenge";
import { SwitchType } from "#enums/switch-type"; import { SwitchType } from "#enums/switch-type";
@ -7855,6 +7856,91 @@ export class ResistLastMoveTypeAttr extends MoveEffectAttr {
} }
} }
/**
* Attribute used for transferring items between a user Pokemon and target Pokemon
*/
export class SwapHeldItemsAttr extends MoveEffectAttr {
/**
* A random item is taken from user and given to target, and a random item is taken from target and given to user
* @param {Pokemon} user Pokemon that used the move
* @param {Pokemon} target Enemy Pokemon
* @param {Move} move Unused
* @param {any[]} args Unused
* @returns {boolean} Returns true if an item swap occured, false if not
*/
apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): boolean {
const targetHeldItems = target.getHeldItems().filter(i => i.isTransferable);
const userHeldItems = user.getHeldItems().filter(i => i.isTransferable);
if (!user.hasTrainer() || target.hasAbility(Abilities.STICKY_HOLD) || (!userHeldItems.length && !targetHeldItems.length)) {
user.scene.queueMessage(i18next.t("battle:attackFailed"));
return false;
}
user.scene.queueMessage(i18next.t("moveTriggers:trickOnSwap", {
pokemonNameWithAffix: getPokemonNameWithAffix(user),
}));
if (targetHeldItems.length) {
let swapItemIdx = 0;
const targetPool = target.isPlayer() ? ModifierPoolType.PLAYER : ModifierPoolType.TRAINER;
for (let idx = 1; idx < targetHeldItems.length; idx++) {
const currentItemFlameOrToxic = targetHeldItems[swapItemIdx].type.id === "TOXIC_ORB" || targetHeldItems[swapItemIdx].type.id === "FLAME_ORB";
const nextItemNotFlameOrToxic = targetHeldItems[idx].type.id !== "TOXIC_ORB" && targetHeldItems[idx].type.id !== "FLAME_ORB";
let nextItemTier = targetHeldItems[idx].type.getOrInferTier(targetPool);
let currentItemTier = targetHeldItems[swapItemIdx].type.getOrInferTier(targetPool);
nextItemTier = nextItemTier !== null ? nextItemTier : ModifierTier.COMMON;
currentItemTier = currentItemTier !== null ? currentItemTier : ModifierTier.COMMON;
if (nextItemNotFlameOrToxic && (nextItemTier > currentItemTier || currentItemFlameOrToxic)) {
swapItemIdx = idx;
}
if (targetHeldItems[swapItemIdx].type.tier === ModifierTier.LUXURY) {
break;
}
}
user.scene.tryTransferHeldItemModifier(targetHeldItems[swapItemIdx], user, false);
}
if (userHeldItems.length) {
let swapItemIdx = 0;
const userPool = user.isPlayer() ? ModifierPoolType.PLAYER : ModifierPoolType.TRAINER;
for (let idx = 1; idx < userHeldItems.length; idx++) {
if (userHeldItems[swapItemIdx].type.id === "TOXIC_ORB" || userHeldItems[swapItemIdx].type.id === "FLAME_ORB") {
break;
}
if (userHeldItems[idx].type.id === "TOXIC_ORB" || userHeldItems[idx].type.id === "FLAME_ORB") {
swapItemIdx = idx;
break;
}
let nextItemTier = userHeldItems[idx].type.getOrInferTier(userPool);
let currentItemTier = userHeldItems[swapItemIdx].type.getOrInferTier(userPool);
nextItemTier = nextItemTier !== null ? nextItemTier : ModifierTier.COMMON;
currentItemTier = currentItemTier !== null ? currentItemTier : ModifierTier.COMMON;
if (nextItemTier < currentItemTier) {
swapItemIdx = idx;
}
}
const swappedItemName = userHeldItems[swapItemIdx].type.name;
target.scene.tryTransferHeldItemModifier(userHeldItems[swapItemIdx], target, false);
user.scene.queueMessage(i18next.t("moveTriggers:trickFoeNewItem", {
pokemonNameWithAffix: getPokemonNameWithAffix(target),
itemName: swappedItemName,
}));
}
return true;
}
}
/** /**
* Drops the target's immunity to types it is immune to * Drops the target's immunity to types it is immune to
* and makes its evasiveness be ignored during accuracy * and makes its evasiveness be ignored during accuracy
@ -7887,7 +7973,6 @@ export class ExposedMoveAttr extends AddBattlerTagAttr {
} }
} }
const unknownTypeCondition: MoveConditionFunc = (user, target, move) => !user.getTypes().includes(Type.UNKNOWN); const unknownTypeCondition: MoveConditionFunc = (user, target, move) => !user.getTypes().includes(Type.UNKNOWN);
export type MoveTargetSet = { export type MoveTargetSet = {
@ -8764,7 +8849,7 @@ export function initMoves() {
.target(MoveTarget.NEAR_ALLY) .target(MoveTarget.NEAR_ALLY)
.condition(failIfSingleBattle), .condition(failIfSingleBattle),
new StatusMove(Moves.TRICK, Type.PSYCHIC, 100, 10, -1, 0, 3) new StatusMove(Moves.TRICK, Type.PSYCHIC, 100, 10, -1, 0, 3)
.unimplemented(), .attr(SwapHeldItemsAttr),
new StatusMove(Moves.ROLE_PLAY, Type.PSYCHIC, -1, 10, -1, 0, 3) new StatusMove(Moves.ROLE_PLAY, Type.PSYCHIC, -1, 10, -1, 0, 3)
.ignoresSubstitute() .ignoresSubstitute()
.attr(AbilityCopyAttr), .attr(AbilityCopyAttr),

View File

@ -31,7 +31,7 @@ import { BerryType } from "#enums/berry-type";
import { PERMANENT_STATS, Stat } from "#enums/stat"; import { PERMANENT_STATS, Stat } from "#enums/stat";
import { StatStageChangePhase } from "#app/phases/stat-stage-change-phase"; import { StatStageChangePhase } from "#app/phases/stat-stage-change-phase";
import { CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES } from "#app/game-mode"; import { CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES } from "#app/game-mode";
import PokemonSpecies, { allSpecies } from "#app/data/pokemon-species"; import PokemonSpecies, { getPokemonSpecies } from "#app/data/pokemon-species";
/** the i18n namespace for the encounter */ /** the i18n namespace for the encounter */
const namespace = "mysteryEncounters/berriesAbound"; const namespace = "mysteryEncounters/berriesAbound";
@ -62,8 +62,8 @@ export const BerriesAboundEncounter: MysteryEncounter =
let bossSpecies: PokemonSpecies; let bossSpecies: PokemonSpecies;
if (scene.eventManager.isEventActive() && scene.eventManager.activeEvent()?.uncommonBreedEncounters && randSeedInt(2) === 1) { if (scene.eventManager.isEventActive() && scene.eventManager.activeEvent()?.uncommonBreedEncounters && randSeedInt(2) === 1) {
const eventEncounter = randSeedItem(scene.eventManager.activeEvent()!.uncommonBreedEncounters!); const eventEncounter = randSeedItem(scene.eventManager.activeEvent()!.uncommonBreedEncounters!);
bossSpecies = allSpecies[eventEncounter.species]; const levelSpecies = getPokemonSpecies(eventEncounter.species).getWildSpeciesForLevel(level, eventEncounter.allowEvolution ?? false, true, scene.gameMode);
bossSpecies.speciesId = bossSpecies.getSpeciesForLevel(level, eventEncounter.allowEvolution); bossSpecies = getPokemonSpecies( levelSpecies );
} else { } else {
bossSpecies = scene.arena.randomSpecies(scene.currentBattle.waveIndex, level, 0, getPartyLuckValue(scene.getPlayerParty()), true); bossSpecies = scene.arena.randomSpecies(scene.currentBattle.waveIndex, level, 0, getPartyLuckValue(scene.getPlayerParty()), true);
} }

View File

@ -29,7 +29,7 @@ import { queueEncounterMessage } from "#app/data/mystery-encounters/utils/encoun
import { randSeedInt, randSeedItem } from "#app/utils"; import { randSeedInt, randSeedItem } from "#app/utils";
import { StatStageChangePhase } from "#app/phases/stat-stage-change-phase"; import { StatStageChangePhase } from "#app/phases/stat-stage-change-phase";
import { CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES } from "#app/game-mode"; import { CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES } from "#app/game-mode";
import PokemonSpecies, { allSpecies } from "#app/data/pokemon-species"; import PokemonSpecies, { getPokemonSpecies } from "#app/data/pokemon-species";
/** the i18n namespace for the encounter */ /** the i18n namespace for the encounter */
const namespace = "mysteryEncounters/fightOrFlight"; const namespace = "mysteryEncounters/fightOrFlight";
@ -60,8 +60,8 @@ export const FightOrFlightEncounter: MysteryEncounter =
let bossSpecies: PokemonSpecies; let bossSpecies: PokemonSpecies;
if (scene.eventManager.isEventActive() && scene.eventManager.activeEvent()?.uncommonBreedEncounters && randSeedInt(2) === 1) { if (scene.eventManager.isEventActive() && scene.eventManager.activeEvent()?.uncommonBreedEncounters && randSeedInt(2) === 1) {
const eventEncounter = randSeedItem(scene.eventManager.activeEvent()!.uncommonBreedEncounters!); const eventEncounter = randSeedItem(scene.eventManager.activeEvent()!.uncommonBreedEncounters!);
bossSpecies = allSpecies[eventEncounter.species]; const levelSpecies = getPokemonSpecies(eventEncounter.species).getWildSpeciesForLevel(level, eventEncounter.allowEvolution ?? false, true, scene.gameMode);
bossSpecies.speciesId = bossSpecies.getSpeciesForLevel(level, eventEncounter.allowEvolution); bossSpecies = getPokemonSpecies( levelSpecies );
} else { } else {
bossSpecies = scene.arena.randomSpecies(scene.currentBattle.waveIndex, level, 0, getPartyLuckValue(scene.getPlayerParty()), true); bossSpecies = scene.arena.randomSpecies(scene.currentBattle.waveIndex, level, 0, getPartyLuckValue(scene.getPlayerParty()), true);
} }

View File

@ -23,7 +23,7 @@ import { BerryModifier } from "#app/modifier/modifier";
import { StatStageChangePhase } from "#app/phases/stat-stage-change-phase"; import { StatStageChangePhase } from "#app/phases/stat-stage-change-phase";
import { Stat } from "#enums/stat"; import { Stat } from "#enums/stat";
import { CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES } from "#app/game-mode"; import { CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES } from "#app/game-mode";
import PokemonSpecies, { allSpecies } from "#app/data/pokemon-species"; import PokemonSpecies, { getPokemonSpecies } from "#app/data/pokemon-species";
/** the i18n namespace for the encounter */ /** the i18n namespace for the encounter */
const namespace = "mysteryEncounters/uncommonBreed"; const namespace = "mysteryEncounters/uncommonBreed";
@ -55,8 +55,8 @@ export const UncommonBreedEncounter: MysteryEncounter =
let species: PokemonSpecies; let species: PokemonSpecies;
if (scene.eventManager.isEventActive() && scene.eventManager.activeEvent()?.uncommonBreedEncounters && randSeedInt(2) === 1) { if (scene.eventManager.isEventActive() && scene.eventManager.activeEvent()?.uncommonBreedEncounters && randSeedInt(2) === 1) {
const eventEncounter = randSeedItem(scene.eventManager.activeEvent()!.uncommonBreedEncounters!); const eventEncounter = randSeedItem(scene.eventManager.activeEvent()!.uncommonBreedEncounters!);
species = allSpecies[eventEncounter.species]; const levelSpecies = getPokemonSpecies(eventEncounter.species).getWildSpeciesForLevel(level, eventEncounter.allowEvolution ?? false, true, scene.gameMode);
species.speciesId = species.getSpeciesForLevel(level, eventEncounter.allowEvolution); species = getPokemonSpecies( levelSpecies );
} else { } else {
species = scene.arena.randomSpecies(scene.currentBattle.waveIndex, level, 0, getPartyLuckValue(scene.getPlayerParty()), true); species = scene.arena.randomSpecies(scene.currentBattle.waveIndex, level, 0, getPartyLuckValue(scene.getPlayerParty()), true);
} }

View File

@ -0,0 +1,254 @@
import GameManager from "#app/test/utils/gameManager";
import Phaser from "phaser";
import { Moves } from "#enums/moves";
import { Species } from "#enums/species";
import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest";
import { TurnEndPhase } from "#app/phases/turn-end-phase";
import { PokemonHeldItemModifier } from "#app/modifier/modifier.js";
import { deepCopy } from "#app/utils";
import { Abilities } from "#app/enums/abilities.js";
const TIMEOUT = 20000;
const TRICK_ONLY = [Moves.TRICK, Moves.TRICK, Moves.TRICK, Moves.TRICK];
const SPLASH_ONLY = [Moves.SPLASH, Moves.SPLASH, Moves.SPLASH, Moves.SPLASH];
/**
* Gets the PokemonHeldItemModifier for a given item ID, if the Pokemon has that item
* @param {PokemonHeldItemModifier[]} inventory Held items of a Pokemon
* @param {string} itemId The ID of the item to search for
* @returns PokemonHeldItemModifier if the item is found, undefined if not
*/
function getHeldItemModifierFromId(inventory: PokemonHeldItemModifier[], itemId: string) {
let idxOfSearchedItem = -1;
for (let idx = 0; idx < inventory.length; idx++) {
if (inventory[idx].type.id === itemId) {
idxOfSearchedItem = idx;
break;
}
}
return idxOfSearchedItem !== -1 ? inventory[idxOfSearchedItem] : undefined;
}
/**
* Prints a string to the console showing how many of an item a Pokemon currently has
* @param {string} pokemonName The name of the checked Pokemon
* @param {string} itemId The ID of the checked item
* @param {number} stackCount How many of this item ID the checked Pokemon has
*/
function printStackCount(pokemonName: string, itemId: string, stackCount: number) {
console.log(`${pokemonName} has ${stackCount} of ${itemId}`);
}
describe("Moves - Trick", () => {
let phaserGame: Phaser.Game;
let game: GameManager;
beforeAll(() => {
phaserGame = new Phaser.Game({
type: Phaser.HEADLESS,
});
});
afterEach(() => {
game.phaseInterceptor.restoreOg();
});
beforeEach(() => {
game = new GameManager(phaserGame);
game.override.battleType("single");
});
it(
"both pokemon have two items, they will always swap Leftovers and Golden Punch, due to the priority system",
async () => {
game.override.startingHeldItems([{name: "MULTI_LENS"}, {name: "GOLDEN_PUNCH"}]);
game.override.enemyHeldItems([{name: "LEFTOVERS"}, {name: "GOLDEN_PUNCH"}]);
game.override.moveset(TRICK_ONLY);
game.override.enemySpecies(Species.MAGIKARP);
game.override.enemyMoveset(SPLASH_ONLY);
await game.startBattle([Species.MIME_JR]);
const playerPokemon = game.scene.getPlayerPokemon()!;
const enemyPokemon = game.scene.getEnemyPokemon()!;
const playerLostItem = playerPokemon.getHeldItems()[1];
const enemyLostItem = enemyPokemon.getHeldItems()[0];
const prevPlayerLostItemStack = playerLostItem.stackCount;
const prevEnemyLostItemStack = enemyLostItem.stackCount;
const prevPlayerGainedItemModifier = getHeldItemModifierFromId(playerPokemon.getHeldItems(), enemyLostItem.type.id);
const prevEnemyGainedItemModifier = getHeldItemModifierFromId(enemyPokemon.getHeldItems(), playerLostItem.type.id);
let prevPlayerGainedItemStackCount = 0;
let prevEnemyGainedItemStackCount = 0;
if (prevPlayerGainedItemModifier !== undefined) {
prevPlayerGainedItemStackCount = prevPlayerGainedItemModifier.stackCount;
}
if (prevEnemyGainedItemModifier !== undefined) {
prevEnemyGainedItemStackCount = prevEnemyGainedItemModifier.stackCount;
}
printStackCount(playerPokemon.name, playerLostItem.type.id, prevPlayerLostItemStack);
printStackCount(playerPokemon.name, enemyLostItem.type.id, prevPlayerGainedItemStackCount);
printStackCount(enemyPokemon.name, enemyLostItem.type.id, prevEnemyLostItemStack);
printStackCount(enemyPokemon.name, playerLostItem.type.id, prevEnemyGainedItemStackCount);
game.move.select(Moves.TRICK);
await game.phaseInterceptor.to(TurnEndPhase);
const currPlayerLostItemStack = playerLostItem.stackCount;
const currEnemyLostItemStack = enemyLostItem.stackCount;
const currPlayerGainedItemModifier = getHeldItemModifierFromId(playerPokemon.getHeldItems(), enemyLostItem.type.id);
const currEnemyGainedItemModifier = getHeldItemModifierFromId(enemyPokemon.getHeldItems(), playerLostItem.type.id);
expect(currPlayerGainedItemModifier).toBeDefined();
expect(currEnemyGainedItemModifier).toBeDefined();
if (currPlayerGainedItemModifier && currEnemyGainedItemModifier) {
const currPlayerGainedItemStackCount = currPlayerGainedItemModifier.stackCount;
const currEnemyGainedItemStackCount = currEnemyGainedItemModifier.stackCount;
printStackCount(playerPokemon.name, playerLostItem.type.id, currPlayerLostItemStack);
printStackCount(playerPokemon.name, enemyLostItem.type.id, currPlayerGainedItemStackCount);
printStackCount(enemyPokemon.name, enemyLostItem.type.id, currEnemyLostItemStack);
printStackCount(enemyPokemon.name, playerLostItem.type.id, currEnemyGainedItemStackCount);
const didPlayerTransferItems = prevPlayerLostItemStack > currPlayerLostItemStack && prevPlayerGainedItemStackCount < currPlayerGainedItemStackCount;
const didEnemyTransferItems = prevEnemyLostItemStack > currEnemyLostItemStack && prevEnemyGainedItemStackCount < currEnemyGainedItemStackCount;
const playerReceivedLeftovers = currPlayerGainedItemModifier.type.id === "LEFTOVERS";
const enemyReceivedGoldenPunch = currEnemyGainedItemModifier.type.id === "GOLDEN_PUNCH";
expect(didPlayerTransferItems && didEnemyTransferItems && playerReceivedLeftovers && enemyReceivedGoldenPunch).toBeTruthy();
}
}, TIMEOUT
);
it(
"the user will always give Toxic Orb, as it has special priority to be given",
async () => {
game.override.startingHeldItems([{name: "GOLDEN_PUNCH"}, {name: "TOXIC_ORB"}]);
game.override.enemyHeldItems([{name: "LEFTOVERS"}, {name: "GOLDEN_PUNCH"}]);
game.override.moveset(TRICK_ONLY);
game.override.enemySpecies(Species.MAGIKARP);
game.override.enemyMoveset(SPLASH_ONLY);
await game.startBattle([Species.MIME_JR]);
game.move.select(Moves.TRICK);
await game.phaseInterceptor.to(TurnEndPhase);
const playerPokemon = game.scene.getPlayerPokemon()!;
expect(playerPokemon.getHeldItems()[1].type.id === "TOXIC_ORB").toBeFalsy();
}
);
it(
"the user will never take Flame Orb, as it has special priority to not be taken",
async () => {
game.override.enemyHeldItems([{name: "FLAME_ORB"}, {name: "GOLDEN_PUNCH"}]);
game.override.moveset(TRICK_ONLY);
game.override.enemySpecies(Species.MAGIKARP);
game.override.enemyMoveset(SPLASH_ONLY);
await game.startBattle([Species.MIME_JR]);
game.move.select(Moves.TRICK);
await game.phaseInterceptor.to(TurnEndPhase);
const enemyPokemon = game.scene.getEnemyPokemon()!;
expect(enemyPokemon.getHeldItems()[0].type.id === "FLAME_ORB").toBeTruthy();
}
);
it(
"the move fails and no transfer occurs when a wild pokemon is the user",
async () => {
game.override.startingHeldItems([{name: "GOLDEN_PUNCH"}]);
game.override.enemyHeldItems([{name: "LEFTOVERS"}]);
game.override.moveset(SPLASH_ONLY);
game.override.enemySpecies(Species.MIME_JR);
game.override.enemyMoveset(TRICK_ONLY);
await game.startBattle([Species.MAGIKARP]);
const playerPokemon = game.scene.getPlayerPokemon()!;
const enemyPokemon = game.scene.getEnemyPokemon()!;
const playerPokemonFirstHeldItem = deepCopy(playerPokemon.getHeldItems()[0]) as PokemonHeldItemModifier;
const enemyPokemonFirstHeldItem = deepCopy(enemyPokemon.getHeldItems()[0]) as PokemonHeldItemModifier;
printStackCount(playerPokemon.name, playerPokemonFirstHeldItem.type.id, playerPokemonFirstHeldItem.stackCount);
printStackCount(enemyPokemon.name, enemyPokemonFirstHeldItem.type.id, enemyPokemonFirstHeldItem.stackCount);
game.move.select(Moves.TRICK);
await game.phaseInterceptor.to(TurnEndPhase);
const playerPokemonCurrentHeldItem = playerPokemon.getHeldItems()[0];
const enemyPokemonCurrentHeldItem = enemyPokemon.getHeldItems()[0];
printStackCount(playerPokemon.name, playerPokemonFirstHeldItem.type.id, playerPokemonFirstHeldItem.stackCount);
printStackCount(enemyPokemon.name, enemyPokemonFirstHeldItem.type.id, enemyPokemonFirstHeldItem.stackCount);
const playerDidNotLoseItem = playerPokemonFirstHeldItem.type.id === playerPokemonCurrentHeldItem.type.id && playerPokemonFirstHeldItem.stackCount === playerPokemonCurrentHeldItem.stackCount;
const enemyDidNotLoseItem = enemyPokemonFirstHeldItem.type.id === enemyPokemonCurrentHeldItem.type.id && enemyPokemonFirstHeldItem.stackCount === enemyPokemonCurrentHeldItem.stackCount;
expect(playerDidNotLoseItem && enemyDidNotLoseItem).toBeTruthy();
}, TIMEOUT
);
it(
"the move fails and no transfer occurs when the target pokemon has sticky hold",
async () => {
game.override.startingHeldItems([{name: "GOLDEN_PUNCH"}]);
game.override.enemyHeldItems([{name: "LEFTOVERS"}]);
game.override.moveset(TRICK_ONLY);
game.override.enemySpecies(Species.MAGIKARP);
game.override.enemyMoveset(SPLASH_ONLY);
game.override.enemyAbility(Abilities.STICKY_HOLD);
await game.startBattle([Species.MIME_JR]);
const playerPokemon = game.scene.getPlayerPokemon()!;
const enemyPokemon = game.scene.getEnemyPokemon()!;
const playerPokemonFirstHeldItem = deepCopy(playerPokemon.getHeldItems()[0]) as PokemonHeldItemModifier;
const enemyPokemonFirstHeldItem = deepCopy(enemyPokemon.getHeldItems()[0]) as PokemonHeldItemModifier;
printStackCount(playerPokemon.name, playerPokemonFirstHeldItem.type.id, playerPokemonFirstHeldItem.stackCount);
printStackCount(enemyPokemon.name, enemyPokemonFirstHeldItem.type.id, enemyPokemonFirstHeldItem.stackCount);
game.move.select(Moves.TRICK);
await game.phaseInterceptor.to(TurnEndPhase);
const playerPokemonCurrentHeldItem = playerPokemon.getHeldItems()[0];
const enemyPokemonCurrentHeldItem = enemyPokemon.getHeldItems()[0];
printStackCount(playerPokemon.name, playerPokemonFirstHeldItem.type.id, playerPokemonFirstHeldItem.stackCount);
printStackCount(enemyPokemon.name, enemyPokemonFirstHeldItem.type.id, enemyPokemonFirstHeldItem.stackCount);
const playerDidNotLoseItem = playerPokemonFirstHeldItem.type.id === playerPokemonCurrentHeldItem.type.id && playerPokemonFirstHeldItem.stackCount === playerPokemonCurrentHeldItem.stackCount;
const enemyDidNotLoseItem = enemyPokemonFirstHeldItem.type.id === enemyPokemonCurrentHeldItem.type.id && enemyPokemonFirstHeldItem.stackCount === enemyPokemonCurrentHeldItem.stackCount;
expect(playerDidNotLoseItem && enemyDidNotLoseItem).toBeTruthy();
}, TIMEOUT
);
it(
"the move fails and no transfer occurs when neither pokemon have any items",
async() => {
game.override.moveset(TRICK_ONLY);
game.override.enemySpecies(Species.MAGIKARP);
game.override.enemyMoveset(SPLASH_ONLY);
await game.startBattle([Species.MIME_JR]);
const playerPokemon = game.scene.getPlayerPokemon()!;
const enemyPokemon = game.scene.getEnemyPokemon()!;
expect(playerPokemon.getHeldItems().length === 0);
expect(enemyPokemon.getHeldItems().length === 0);
game.move.select(Moves.TRICK);
await game.phaseInterceptor.to(TurnEndPhase);
expect(playerPokemon.getHeldItems().length === 0);
expect(enemyPokemon.getHeldItems().length === 0);
}, TIMEOUT
);
});