This commit is contained in:
Brian 2025-09-07 15:19:44 -04:00 committed by GitHub
commit f8dfa7c21b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
25 changed files with 622 additions and 23 deletions

View File

@ -8618,6 +8618,132 @@
"w": 16,
"h": 16
}
},
{
"filename": "repb",
"rotated": false,
"trimmed": true,
"sourceSize": {
"w": 32,
"h": 32
},
"spriteSourceSize": {
"x": 8,
"y": 8,
"w": 16,
"h": 16
},
"frame": {
"x": 204,
"y": 423,
"w": 20,
"h": 20
}
},
{
"filename": "tb",
"rotated": false,
"trimmed": true,
"sourceSize": {
"w": 32,
"h": 32
},
"spriteSourceSize": {
"x": 8,
"y": 8,
"w": 16,
"h": 16
},
"frame": {
"x": 224,
"y": 423,
"w": 20,
"h": 20
}
},
{
"filename": "sb",
"rotated": false,
"trimmed": true,
"sourceSize": {
"w": 32,
"h": 32
},
"spriteSourceSize": {
"x": 8,
"y": 8,
"w": 16,
"h": 16
},
"frame": {
"x": 244,
"y": 423,
"w": 20,
"h": 20
}
},
{
"filename": "qb",
"rotated": false,
"trimmed": true,
"sourceSize": {
"w": 32,
"h": 32
},
"spriteSourceSize": {
"x": 8,
"y": 8,
"w": 16,
"h": 16
},
"frame": {
"x": 264,
"y": 423,
"w": 20,
"h": 20
}
},
{
"filename": "preb",
"rotated": false,
"trimmed": true,
"sourceSize": {
"w": 32,
"h": 32
},
"spriteSourceSize": {
"x": 8,
"y": 8,
"w": 16,
"h": 16
},
"frame": {
"x": 284,
"y": 425,
"w": 20,
"h": 18
}
},
{
"filename": "lb",
"rotated": false,
"trimmed": true,
"sourceSize": {
"w": 32,
"h": 32
},
"spriteSourceSize": {
"x": 8,
"y": 8,
"w": 20,
"h": 20
},
"frame": {
"x": 304,
"y": 425,
"w": 20,
"h": 18
}
}
]
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 53 KiB

After

Width:  |  Height:  |  Size: 80 KiB

BIN
public/images/items/lb.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 363 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 291 B

BIN
public/images/items/qb.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 349 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 358 B

BIN
public/images/items/sb.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 362 B

BIN
public/images/items/tb.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 350 B

View File

@ -386,6 +386,321 @@
"w": 12,
"h": 12
}
},
{
"filename": "repb_open",
"rotated": false,
"trimmed": false,
"sourceSize": {
"w": 12,
"h": 16
},
"spriteSourceSize": {
"x": 0,
"y": 0,
"w": 12,
"h": 16
},
"frame": {
"x": 0,
"y": 246,
"w": 12,
"h": 16
}
},
{
"filename": "repb_opening",
"rotated": false,
"trimmed": true,
"sourceSize": {
"w": 12,
"h": 16
},
"spriteSourceSize": {
"x": 0,
"y": 3,
"w": 12,
"h": 13
},
"frame": {
"x": 0,
"y": 262,
"w": 12,
"h": 13
}
},
{
"filename": "repb",
"rotated": false,
"trimmed": true,
"sourceSize": {
"w": 12,
"h": 16
},
"spriteSourceSize": {
"x": 0,
"y": 4,
"w": 12,
"h": 12
},
"frame": {
"x": 0,
"y": 276,
"w": 12,
"h": 12
}
},
{
"filename": "tb_open",
"rotated": false,
"trimmed": false,
"sourceSize": {
"w": 12,
"h": 16
},
"spriteSourceSize": {
"x": 0,
"y": 0,
"w": 12,
"h": 16
},
"frame": {
"x": 0,
"y": 288,
"w": 12,
"h": 16
}
},
{
"filename": "tb_opening",
"rotated": false,
"trimmed": true,
"sourceSize": {
"w": 12,
"h": 16
},
"spriteSourceSize": {
"x": 0,
"y": 3,
"w": 12,
"h": 13
},
"frame": {
"x": 0,
"y": 304,
"w": 12,
"h": 13
}
},
{
"filename": "tb",
"rotated": false,
"trimmed": true,
"sourceSize": {
"w": 12,
"h": 16
},
"spriteSourceSize": {
"x": 0,
"y": 4,
"w": 12,
"h": 12
},
"frame": {
"x": 0,
"y": 318,
"w": 12,
"h": 12
}
},
{
"filename": "sb_open",
"rotated": false,
"trimmed": false,
"sourceSize": {
"w": 12,
"h": 16
},
"spriteSourceSize": {
"x": 0,
"y": 0,
"w": 12,
"h": 16
},
"frame": {
"x": 0,
"y": 330,
"w": 12,
"h": 16
}
},
{
"filename": "sb_opening",
"rotated": false,
"trimmed": true,
"sourceSize": {
"w": 12,
"h": 16
},
"spriteSourceSize": {
"x": 0,
"y": 3,
"w": 12,
"h": 13
},
"frame": {
"x": 0,
"y": 346,
"w": 12,
"h": 13
}
},
{
"filename": "sb",
"rotated": false,
"trimmed": true,
"sourceSize": {
"w": 12,
"h": 16
},
"spriteSourceSize": {
"x": 0,
"y": 4,
"w": 12,
"h": 12
},
"frame": {
"x": 0,
"y": 360,
"w": 12,
"h": 12
}
},
{
"filename": "qb_open",
"rotated": false,
"trimmed": false,
"sourceSize": {
"w": 12,
"h": 16
},
"spriteSourceSize": {
"x": 0,
"y": 0,
"w": 12,
"h": 16
},
"frame": {
"x": 0,
"y": 372,
"w": 12,
"h": 16
}
},
{
"filename": "qb_opening",
"rotated": false,
"trimmed": true,
"sourceSize": {
"w": 12,
"h": 16
},
"spriteSourceSize": {
"x": 0,
"y": 3,
"w": 12,
"h": 13
},
"frame": {
"x": 0,
"y": 388,
"w": 12,
"h": 13
}
},
{
"filename": "qb",
"rotated": false,
"trimmed": true,
"sourceSize": {
"w": 12,
"h": 16
},
"spriteSourceSize": {
"x": 0,
"y": 4,
"w": 12,
"h": 12
},
"frame": {
"x": 0,
"y": 402,
"w": 12,
"h": 12
}
},
{
"filename": "preb_open",
"rotated": false,
"trimmed": false,
"sourceSize": {
"w": 12,
"h": 16
},
"spriteSourceSize": {
"x": 0,
"y": 0,
"w": 12,
"h": 16
},
"frame": {
"x": 0,
"y": 414,
"w": 12,
"h": 16
}
},
{
"filename": "preb_opening",
"rotated": false,
"trimmed": true,
"sourceSize": {
"w": 12,
"h": 16
},
"spriteSourceSize": {
"x": 0,
"y": 3,
"w": 12,
"h": 13
},
"frame": {
"x": 0,
"y": 430,
"w": 12,
"h": 13
}
},
{
"filename": "preb",
"rotated": false,
"trimmed": true,
"sourceSize": {
"w": 12,
"h": 16
},
"spriteSourceSize": {
"x": 0,
"y": 4,
"w": 12,
"h": 12
},
"frame": {
"x": 0,
"y": 444,
"w": 12,
"h": 12
}
}
]
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1016 B

After

Width:  |  Height:  |  Size: 2.4 KiB

View File

@ -271,6 +271,8 @@ export class BattleScene extends SceneBase {
public lastEnemyTrainer: Trainer | null;
public currentBattle: Battle;
public pokeballCounts: PokeballCounts;
public lastPokeballType: PokeballType = PokeballType.POKEBALL;
public premierPokeballMultiplier: number = 1;
public money: number;
public pokemonInfoContainer: PokemonInfoContainer;
private party: PlayerPokemon[];
@ -1148,12 +1150,14 @@ export class BattleScene extends SceneBase {
this.score = 0;
this.money = 0;
this.lastPokeballType = PokeballType.POKEBALL;
this.premierPokeballMultiplier = 1;
this.lockModifierTiers = false;
this.pokeballCounts = Object.fromEntries(
getEnumValues(PokeballType)
.filter(p => p <= PokeballType.MASTER_BALL)
.filter(p => p <= PokeballType.REPEAT_BALL)
.map(t => [t, 0]),
);
this.pokeballCounts[PokeballType.POKEBALL] += 5;

View File

@ -22,7 +22,7 @@ import {
doPlayerFlee,
doPokemonFlee,
getRandomSpeciesByStarterCost,
trainerThrowPokeball,
trainerThrowSafariball,
} from "#mystery-encounters/encounter-pokemon-utils";
import type { MysteryEncounter } from "#mystery-encounters/mystery-encounter";
import { MysteryEncounterBuilder } from "#mystery-encounters/mystery-encounter";
@ -349,7 +349,7 @@ function throwPokeball(pokemon: EnemyPokemon): Promise<boolean> {
const pokeballMultiplier = 1.5;
const catchRate = Math.round(baseCatchRate * pokeballMultiplier * safariModifier);
const ballTwitchRate = Math.round(1048560 / Math.sqrt(Math.sqrt(16711680 / catchRate)));
return trainerThrowPokeball(pokemon, PokeballType.POKEBALL, ballTwitchRate);
return trainerThrowSafariball(pokemon, PokeballType.SAFARI_BALL, ballTwitchRate);
}
async function throwBait(pokemon: EnemyPokemon): Promise<boolean> {

View File

@ -439,7 +439,7 @@ export async function applyModifierTypeToPlayerPokemon(
* @param pokeballType
* @param ballTwitchRate - can pass custom ball catch rates (for special events, like safari)
*/
export function trainerThrowPokeball(
export function trainerThrowSafariball(
pokemon: EnemyPokemon,
pokeballType: PokeballType,
ballTwitchRate?: number,

View File

@ -19,6 +19,19 @@ export function getPokeballAtlasKey(type: PokeballType): string {
return "mb";
case PokeballType.LUXURY_BALL:
return "lb";
case PokeballType.QUICK_BALL:
return "qb";
case PokeballType.TIMER_BALL:
return "tb";
case PokeballType.PREMIER_BALL:
return "preb";
case PokeballType.REPEAT_BALL:
return "repb";
case PokeballType.SAFARI_BALL:
return "sb";
default:
console.error("Missing ball atlas key");
return "pb";
}
}
@ -43,6 +56,25 @@ export function getPokeballName(type: PokeballType): string {
case PokeballType.LUXURY_BALL:
ret = i18next.t("pokeball:luxuryBall");
break;
case PokeballType.QUICK_BALL:
ret = i18next.t("pokeball:quickBall");
break;
case PokeballType.TIMER_BALL:
ret = i18next.t("pokeball:timerBall");
break;
case PokeballType.PREMIER_BALL:
ret = i18next.t("pokeball:premierBall");
break;
case PokeballType.REPEAT_BALL:
ret = i18next.t("pokeball:repeatBall");
break;
case PokeballType.SAFARI_BALL:
ret = i18next.t("pokeball:safariBall");
break;
default:
console.error("Missing ball language translation description");
ret = i18next.t("pokeball:pokeBall");
}
return ret;
}
@ -61,6 +93,24 @@ export function getPokeballCatchMultiplier(type: PokeballType): number {
return -1;
case PokeballType.LUXURY_BALL:
return 1;
case PokeballType.QUICK_BALL:
return globalScene.currentBattle.turn == 1 ? 5 : 1;
case PokeballType.TIMER_BALL:
return globalScene.currentBattle.turn > 11 ? 4 : 1 + ((globalScene.currentBattle.turn-1) * 0.3);
case PokeballType.PREMIER_BALL:
return globalScene.premierPokeballMultiplier;
case PokeballType.REPEAT_BALL:
if (globalScene.getEnemyPokemon()){
return globalScene.gameData.dexData[globalScene.getEnemyPokemon().species.speciesId].caughtAttr ? 3.5 : 1;
}
return 1
case PokeballType.SAFARI_BALL:
return 1.5
default:
console.error("Missing ball catch multiplier");
return 1;
}
}
@ -78,6 +128,21 @@ export function getPokeballTintColor(type: PokeballType): number {
return 0xa441bd;
case PokeballType.LUXURY_BALL:
return 0xffde6a;
case PokeballType.QUICK_BALL:
return 0xd52929;
case PokeballType.TIMER_BALL:
return 0xd52929;
case PokeballType.PREMIER_BALL:
return 0xd52929;
case PokeballType.REPEAT_BALL:
return 0xd52929;
case PokeballType.TIMER_BALL:
return 0xd52929;
case PokeballType.SAFARI_BALL:
return 0xd52929;
default:
console.error("Missing ball tint color");
return 0xd52929;
}
}

View File

@ -5,4 +5,10 @@ export enum PokeballType {
ROGUE_BALL,
MASTER_BALL,
LUXURY_BALL,
QUICK_BALL,
TIMER_BALL,
PREMIER_BALL,
REPEAT_BALL,
CRITICAL_BALL, // Not implemented
SAFARI_BALL // Do not put anything above this ball
}

View File

@ -20,6 +20,28 @@ export function addPokeballOpenParticles(x: number, y: number, pokeballType: Pok
case PokeballType.MASTER_BALL:
doMbOpenParticles(x, y);
break;
case PokeballType.LUXURY_BALL:
doMbOpenParticles(x, y);
break;
case PokeballType.QUICK_BALL:
doMbOpenParticles(x, y);
break;
case PokeballType.TIMER_BALL:
doMbOpenParticles(x, y);
break;
case PokeballType.PREMIER_BALL:
doMbOpenParticles(x, y);
break;
case PokeballType.REPEAT_BALL:
doMbOpenParticles(x, y);
break;
case PokeballType.SAFARI_BALL:
doMbOpenParticles(x, y);
break;
default:
doDefaultPbOpenParticles(x, y, 48);
console.log("Missing pokeball animation.")
break;
}
}

View File

@ -5957,8 +5957,7 @@ export class PlayerPokemon extends Pokemon {
const amount = new NumberHolder(friendship);
globalScene.applyModifier(PokemonFriendshipBoosterModifier, true, this, amount);
friendship = amount.value;
const newFriendship = this.friendship + friendship;
const newFriendship = this.friendship + (this.pokeball === PokeballType.LUXURY_BALL ? friendship * 2 : friendship);
// If capped is true, only adjust friendship if the new friendship is less than or equal to 200.
if (!capped || newFriendship <= RARE_CANDY_FRIENDSHIP_CAP) {
this.friendship = Math.min(newFriendship, 255);

View File

@ -145,6 +145,8 @@ function initCommonModifierPool() {
function initGreatModifierPool() {
modifierPool[ModifierTier.GREAT] = [
new WeightedModifierType(modifierTypes.GREAT_BALL, () => (hasMaximumBalls(PokeballType.GREAT_BALL) ? 0 : 6), 6),
new WeightedModifierType(modifierTypes.PREMIER_BALL, () => (hasMaximumBalls(PokeballType.PREMIER_BALL) ? 0 : 6), 6),
new WeightedModifierType(modifierTypes.LUXURY_BALL, () => (hasMaximumBalls(PokeballType.LUXURY_BALL) ? 0 : 6), 6),
new WeightedModifierType(modifierTypes.PP_UP, 2),
new WeightedModifierType(
modifierTypes.FULL_HEAL,
@ -348,6 +350,8 @@ function initGreatModifierPool() {
function initUltraModifierPool() {
modifierPool[ModifierTier.ULTRA] = [
new WeightedModifierType(modifierTypes.ULTRA_BALL, () => (hasMaximumBalls(PokeballType.ULTRA_BALL) ? 0 : 15), 15),
new WeightedModifierType(modifierTypes.REPEAT_BALL, () => (hasMaximumBalls(PokeballType.REPEAT_BALL) ? 0 : 15), 15),
new WeightedModifierType(modifierTypes.TIMER_BALL, () => (hasMaximumBalls(PokeballType.TIMER_BALL) ? 0 : 15), 15),
new WeightedModifierType(modifierTypes.MAX_LURE, lureWeightFunc(30, 4)),
new WeightedModifierType(modifierTypes.BIG_NUGGET, skipInLastClassicWaveOrDefault(12)),
new WeightedModifierType(modifierTypes.PP_MAX, 3),
@ -572,6 +576,7 @@ function initUltraModifierPool() {
function initRogueModifierPool() {
modifierPool[ModifierTier.ROGUE] = [
new WeightedModifierType(modifierTypes.ROGUE_BALL, () => (hasMaximumBalls(PokeballType.ROGUE_BALL) ? 0 : 16), 16),
new WeightedModifierType(modifierTypes.QUICK_BALL, () => (hasMaximumBalls(PokeballType.QUICK_BALL) ? 0 : 16), 16),
new WeightedModifierType(modifierTypes.RELIC_GOLD, skipInLastClassicWaveOrDefault(2)),
new WeightedModifierType(modifierTypes.LEFTOVERS, 3),
new WeightedModifierType(modifierTypes.SHELL_BELL, 3),

View File

@ -1837,6 +1837,11 @@ const modifierTypeInitObj = Object.freeze({
ULTRA_BALL: () => new AddPokeballModifierType("ub", PokeballType.ULTRA_BALL, 5),
ROGUE_BALL: () => new AddPokeballModifierType("rb", PokeballType.ROGUE_BALL, 5),
MASTER_BALL: () => new AddPokeballModifierType("mb", PokeballType.MASTER_BALL, 1),
LUXURY_BALL: () => new AddPokeballModifierType("lb", PokeballType.LUXURY_BALL, 5),
QUICK_BALL: () => new AddPokeballModifierType("qb", PokeballType.QUICK_BALL, 3),
TIMER_BALL: () => new AddPokeballModifierType("tb", PokeballType.TIMER_BALL, 5),
PREMIER_BALL: () => new AddPokeballModifierType("preb", PokeballType.PREMIER_BALL, 5),
REPEAT_BALL: () => new AddPokeballModifierType("repb", PokeballType.REPEAT_BALL, 3),
RARE_CANDY: () => new PokemonLevelIncrementModifierType("modifierType:ModifierType.RARE_CANDY", "rare_candy"),
RARER_CANDY: () => new AllPokemonLevelIncrementModifierType("modifierType:ModifierType.RARER_CANDY", "rarer_candy"),

View File

@ -105,6 +105,11 @@ class DefaultOverrides {
[PokeballType.ULTRA_BALL]: 0,
[PokeballType.ROGUE_BALL]: 0,
[PokeballType.MASTER_BALL]: 0,
[PokeballType.LUXURY_BALL]: 0,
[PokeballType.QUICK_BALL]: 0,
[PokeballType.TIMER_BALL]: 0,
[PokeballType.PREMIER_BALL]: 0,
[PokeballType.REPEAT_BALL]: 0,
},
};
/** Forces an item to be UNLOCKED */

View File

@ -13,7 +13,7 @@ import {
import { getStatusEffectCatchRateMultiplier } from "#data/status-effect";
import { BattlerIndex } from "#enums/battler-index";
import { ChallengeType } from "#enums/challenge-type";
import type { PokeballType } from "#enums/pokeball";
import { PokeballType } from "#enums/pokeball";
import { StatusEffect } from "#enums/status-effect";
import { UiMode } from "#enums/ui-mode";
import { addPokeballCaptureStars, addPokeballOpenParticles } from "#field/anims";
@ -56,6 +56,16 @@ export class AttemptCapturePhase extends PokemonPhase {
}
globalScene.pokeballCounts[this.pokeballType]--;
if (globalScene.lastPokeballType != this.pokeballType){
globalScene.lastPokeballType = this.pokeballType;
globalScene.premierPokeballMultiplier = 1
}else if (globalScene.lastPokeballType == PokeballType.PREMIER_BALL && PokeballType.PREMIER_BALL == this.pokeballType){
if (globalScene.premierPokeballMultiplier < 5){
globalScene.premierPokeballMultiplier += 0.5
}else{
globalScene.premierPokeballMultiplier = 5
}
}
this.originalY = pokemon.y;
@ -63,6 +73,7 @@ export class AttemptCapturePhase extends PokemonPhase {
const _2h = 2 * pokemon.hp;
const catchRate = pokemon.species.catchRate;
const pokeballMultiplier = getPokeballCatchMultiplier(this.pokeballType);
console.log(pokeballMultiplier);
const statusMultiplier = pokemon.status ? getStatusEffectCatchRateMultiplier(pokemon.status.effect) : 1;
const modifiedCatchRate = Math.round((((_3m - _2h) * catchRate * pokeballMultiplier) / _3m) * statusMultiplier);
const shakeProbability = Math.round(65536 / Math.pow(255 / modifiedCatchRate, 0.1875)); // Formula taken from gen 6

View File

@ -454,7 +454,7 @@ export class CommandPhase extends FieldPhase {
const isChallengeActive = globalScene.gameMode.hasAnyChallenges();
const isFinalBoss = globalScene.gameMode.isBattleClassicFinalBoss(globalScene.currentBattle.waveIndex);
const numBallTypes = 5;
const numBallTypes = 10;
if (cursor < numBallTypes) {
const targetPokemon = globalScene.getEnemyPokemon(false);
if (
@ -467,13 +467,13 @@ export class CommandPhase extends FieldPhase {
// The message is customized for the final boss.
if (
isFinalBoss &&
(cursor < PokeballType.MASTER_BALL || (cursor === PokeballType.MASTER_BALL && isChallengeActive))
(cursor !== PokeballType.MASTER_BALL || (cursor === PokeballType.MASTER_BALL && isChallengeActive))
) {
this.queueShowText("battle:noPokeballForceFinalBossCatchable");
return false;
}
// When facing any other boss, Master Ball can always be used, and we use the standard message.
if (cursor < PokeballType.MASTER_BALL) {
if (cursor !== PokeballType.MASTER_BALL) {
this.queueShowText("battle:noPokeballStrong");
return false;
}

View File

@ -14,6 +14,7 @@ import { SettingsKeyboardUiHandler } from "#ui/settings-keyboard-ui-handler";
import { SettingsUiHandler } from "#ui/settings-ui-handler";
import { StarterSelectUiHandler } from "#ui/starter-select-ui-handler";
import Phaser from "phaser";
import { CommandUiHandler } from "#ui/command-ui-handler";
type ActionKeys = Record<Button, () => void>;
@ -213,6 +214,7 @@ export class UiInputs {
SettingsAudioUiHandler,
SettingsGamepadUiHandler,
SettingsKeyboardUiHandler,
CommandUiHandler,
];
const uiHandler = globalScene.ui?.getHandler();
if (whitelist.some(handler => uiHandler instanceof handler)) {

View File

@ -14,6 +14,8 @@ export class BallUiHandler extends UiHandler {
private pokeballSelectContainer: Phaser.GameObjects.Container;
private pokeballSelectBg: Phaser.GameObjects.NineSlice;
private countsText: Phaser.GameObjects.Text;
private optionsText: Phaser.GameObjects.Text;
private cursorOffSet: number = 0;
private cursorObj: Phaser.GameObjects.Image | null;
@ -30,12 +32,12 @@ export class BallUiHandler extends UiHandler {
let optionsTextContent = "";
for (let pb = 0; pb < Object.keys(globalScene.pokeballCounts).length; pb++) {
for (let pb = 0; pb < 6; pb++) {
optionsTextContent += `${getPokeballName(pb)}\n`;
}
optionsTextContent += i18next.t("commandUiHandler:ballCancel");
const optionsText = addTextObject(0, 0, optionsTextContent, TextStyle.WINDOW, { align: "right", maxLines: 6 });
const optionsTextWidth = optionsText.displayWidth;
this.optionsText = addTextObject(0, 0, optionsTextContent, TextStyle.WINDOW, { align: "right", maxLines: 6 });
const optionsTextWidth = this.optionsText.displayWidth;
this.pokeballSelectContainer = globalScene.add.container(
globalScene.scaledCanvas.width - 51 - Math.max(64, optionsTextWidth),
-49,
@ -46,18 +48,17 @@ export class BallUiHandler extends UiHandler {
this.pokeballSelectBg = addWindow(0, 0, 50 + Math.max(64, optionsTextWidth), 32 + 480 * this.scale);
this.pokeballSelectBg.setOrigin(0, 1);
this.pokeballSelectContainer.add(this.pokeballSelectBg);
this.pokeballSelectContainer.add(optionsText);
optionsText.setOrigin(0, 0);
optionsText.setPositionRelative(this.pokeballSelectBg, 42, 9);
optionsText.setLineSpacing(this.scale * 72);
this.pokeballSelectContainer.add(this.optionsText);
this.optionsText.setOrigin(0, 0);
this.optionsText.setPositionRelative(this.pokeballSelectBg, 42, 9);
this.optionsText.setLineSpacing(this.scale * 72);
this.countsText = addTextObject(0, 0, "", TextStyle.WINDOW, {
maxLines: 5,
maxLines: 6,
});
this.countsText.setPositionRelative(this.pokeballSelectBg, 18, 9);
this.countsText.setLineSpacing(this.scale * 72);
this.pokeballSelectContainer.add(this.countsText);
this.setCursor(0);
}
@ -116,11 +117,27 @@ export class BallUiHandler extends UiHandler {
updateCounts() {
this.countsText.setText(
Object.values(globalScene.pokeballCounts)
.slice(this.cursorOffSet)
.map(c => `×${c}`)
.join("\n"),
);
}
updatePokeballs() {
let optionsTextContent = "";
let totalDisplayed = Object.keys(globalScene.pokeballCounts).length - this.cursorOffSet > 5 ? 6 : 5;
for (let pb = 0; pb < totalDisplayed; pb++) {
optionsTextContent += `${getPokeballName(pb + this.cursorOffSet)}\n`;
}
if (totalDisplayed == 5){
optionsTextContent += i18next.t("commandUiHandler:ballCancel");
}
this.optionsText.setText(
optionsTextContent
);
}
setCursor(cursor: number): boolean {
const ret = super.setCursor(cursor);
@ -128,10 +145,16 @@ export class BallUiHandler extends UiHandler {
this.cursorObj = globalScene.add.image(0, 0, "cursor");
this.pokeballSelectContainer.add(this.cursorObj);
}
if (this.cursor > this.cursorOffSet + 5){
this.cursorOffSet = this.cursor - 5
}
else if (this.cursor < this.cursorOffSet){
this.cursorOffSet = this.cursor;
}
this.cursorObj.setScale(this.scale * 6);
this.cursorObj.setPositionRelative(this.pokeballSelectBg, 12, 15 + (6 + this.cursor * 96) * this.scale);
this.cursorObj.setPositionRelative(this.pokeballSelectBg, 12, 15 + (6 + (this.cursor - this.cursorOffSet) * 96) * this.scale);
this.updateCounts();
this.updatePokeballs();
return ret;
}

View File

@ -117,7 +117,6 @@ export class CommandUiHandler extends UiHandler {
let success = false;
const cursor = this.getCursor();
if (button === Button.CANCEL || button === Button.ACTION) {
if (button === Button.ACTION) {
switch (cursor) {
@ -187,6 +186,18 @@ export class CommandUiHandler extends UiHandler {
this.toggleTeraButton();
}
break;
case Button.CYCLE_SHINY:
const commandPhase = globalScene.phaseManager.getCurrentPhase() as CommandPhase;
if (globalScene.pokeballCounts[globalScene.lastPokeballType]) {
if (commandPhase.handleCommand(Command.BALL, globalScene.lastPokeballType)) {
globalScene.ui.setMode(UiMode.COMMAND, commandPhase.getFieldIndex());
globalScene.ui.setMode(UiMode.MESSAGE);
success = true;
}
} else {
ui.playError();
}
break
}
}