Merge 9035685b55
into 8b95361d61
@ -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
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
|
Before Width: | Height: | Size: 53 KiB After Width: | Height: | Size: 80 KiB |
BIN
public/images/items/lb.png
Normal file
After Width: | Height: | Size: 363 B |
BIN
public/images/items/preb.png
Normal file
After Width: | Height: | Size: 291 B |
BIN
public/images/items/qb.png
Normal file
After Width: | Height: | Size: 349 B |
BIN
public/images/items/repb.png
Normal file
After Width: | Height: | Size: 358 B |
BIN
public/images/items/sb.png
Normal file
After Width: | Height: | Size: 362 B |
BIN
public/images/items/tb.png
Normal file
After Width: | Height: | Size: 350 B |
@ -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
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
|
Before Width: | Height: | Size: 1016 B After Width: | Height: | Size: 2.4 KiB |
@ -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;
|
||||
|
@ -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> {
|
||||
|
@ -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,
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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),
|
||||
|
@ -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"),
|
||||
|
@ -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 */
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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)) {
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
}
|
||||
}
|
||||
|
||||
|