Merge branch 'pagefaultgames:main' into italian-localization

This commit is contained in:
Alessandro Bruzzese 2024-05-05 03:43:34 +02:00 committed by GitHub
commit 40649fb4b5
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
22 changed files with 2296 additions and 2039 deletions

File diff suppressed because it is too large Load Diff

Binary file not shown.

Before

Width:  |  Height:  |  Size: 48 KiB

After

Width:  |  Height:  |  Size: 49 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 303 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 303 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 303 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 303 B

BIN
public/images/ui/candy.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 415 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 211 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 415 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 211 B

View File

@ -3,7 +3,7 @@
"short_name": "PokéRogue",
"description": "A Pokémon fangame heavily inspired by the roguelite genre. Battle endlessly while gathering stacking items, exploring many different biomes, and reaching Pokémon stats you never thought possible.",
"scope": "/",
"start_url": "https://pokerogue.net",
"start_url": "/",
"display": "fullscreen",
"background_color": "#8c8c8c",
"theme_color": "#8c8c8c",

View File

@ -2104,6 +2104,13 @@ export class StatChangeMultiplierAbAttr extends AbAttr {
}
}
export class StatChangeCopyAbAttr extends AbAttr {
apply(pokemon: Pokemon, passive: boolean, cancelled: Utils.BooleanHolder, args: any[]): boolean | Promise<boolean> {
pokemon.scene.unshiftPhase(new StatChangePhase(pokemon.scene, pokemon.getBattlerIndex(), true, (args[0] as BattleStat[]), (args[1] as integer), true, false, false));
return true;
}
}
export class BypassBurnDamageReductionAbAttr extends AbAttr {
constructor() {
super(false);
@ -3484,7 +3491,7 @@ export function initAbilities() {
.attr(PostBiomeChangeTerrainChangeAbAttr, TerrainType.ELECTRIC)
.conditionalAttr(getTerrainCondition(TerrainType.ELECTRIC), BattleStatMultiplierAbAttr, BattleStat.SPATK, 4 / 3),
new Ability(Abilities.OPPORTUNIST, 9)
.unimplemented(),
.attr(StatChangeCopyAbAttr),
new Ability(Abilities.CUD_CHEW, 9)
.unimplemented(),
new Ability(Abilities.SHARPNESS, 9)

View File

@ -115,7 +115,7 @@ export const speciesEggMoves = {
[Species.PHANPY]: [ Moves.SHORE_UP, Moves.HEAD_SMASH, Moves.MOUNTAIN_GALE, Moves.VOLT_TACKLE ],
[Species.STANTLER]: [ Moves.HORN_LEECH, Moves.HIGH_JUMP_KICK, Moves.BULK_UP, Moves.HEAD_CHARGE ],
[Species.SMEARGLE]: [ Moves.BATON_PASS, Moves.BURNING_BULWARK, Moves.SALT_CURE, Moves.SPORE ],
[Species.TYROGUE]: [ Moves.MACH_PUNCH, Moves.WICKED_TORQUE, Moves.METEOR_MASH, Moves.COLLISION_COURSE ],
[Species.TYROGUE]: [ Moves.VICTORY_DANCE, Moves.WICKED_TORQUE, Moves.METEOR_MASH, Moves.COLLISION_COURSE ],
[Species.SMOOCHUM]: [ Moves.EXPANDING_FORCE, Moves.AURA_SPHERE, Moves.FREEZY_FROST, Moves.TAKE_HEART ],
[Species.ELEKID]: [ Moves.DRAIN_PUNCH, Moves.TIDY_UP, Moves.ICE_HAMMER, Moves.PLASMA_FISTS ],
[Species.MAGBY]: [ Moves.STORED_POWER, Moves.EARTH_POWER, Moves.ARMOR_CANNON, Moves.FLEUR_CANNON ],

View File

@ -2216,6 +2216,36 @@ export class VariableMoveTypeAttr extends MoveAttr {
}
}
export class TechnoBlastTypeAttr extends VariableMoveTypeAttr {
apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): boolean {
if ([user.species.speciesId, user.fusionSpecies?.speciesId].includes(Species.GENESECT)) {
const form = user.species.speciesId === Species.GENESECT ? user.formIndex : user.fusionSpecies.formIndex;
const type = (args[0] as Utils.IntegerHolder);
switch (form) {
case 1: // Shock Drive
type.value = Type.ELECTRIC;
break;
case 2: // Burn Drive
type.value = Type.FIRE;
break;
case 3: // Chill Drive
type.value = Type.ICE;
break;
case 4: // Douse Drive
type.value = Type.WATER;
break;
default:
type.value = Type.NORMAL;
break;
}
return true;
}
return false;
}
}
export class AuraWheelTypeAttr extends VariableMoveTypeAttr {
apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): boolean {
if ([user.species.speciesId, user.fusionSpecies?.speciesId].includes(Species.MORPEKO)) {
@ -4736,8 +4766,7 @@ export function initMoves() {
.attr(StatusEffectAttr, StatusEffect.SLEEP)
.soundBased(),
new StatusMove(Moves.TICKLE, Type.NORMAL, 100, 20, -1, 0, 3)
.attr(StatChangeAttr, BattleStat.ATK, -1)
.attr(StatChangeAttr, BattleStat.DEF, -1),
.attr(StatChangeAttr, [ BattleStat.ATK, BattleStat.DEF ], -1),
new SelfStatusMove(Moves.COSMIC_POWER, Type.PSYCHIC, -1, 20, -1, 0, 3)
.attr(StatChangeAttr, [ BattleStat.DEF, BattleStat.SPDEF ], 1, true),
new AttackMove(Moves.WATER_SPOUT, Type.WATER, MoveCategory.SPECIAL, 150, 100, 5, -1, 0, 3)
@ -5334,7 +5363,7 @@ export function initMoves() {
.ballBombMove()
.target(MoveTarget.ALL_NEAR_OTHERS),
new AttackMove(Moves.TECHNO_BLAST, Type.NORMAL, MoveCategory.SPECIAL, 120, 100, 5, -1, 0, 5)
.partial(),
.attr(TechnoBlastTypeAttr),
new AttackMove(Moves.RELIC_SONG, Type.NORMAL, MoveCategory.SPECIAL, 75, 100, 10, 10, 0, 5)
.attr(StatusEffectAttr, StatusEffect.SLEEP)
.soundBased()
@ -5777,8 +5806,7 @@ export function initMoves() {
.ignoresAbilities()
.partial(),
new StatusMove(Moves.TEARFUL_LOOK, Type.NORMAL, -1, 20, 100, 0, 7)
.attr(StatChangeAttr, BattleStat.ATK, -1)
.attr(StatChangeAttr, BattleStat.SPATK, -1),
.attr(StatChangeAttr, [ BattleStat.ATK, BattleStat.SPATK ], -1),
new AttackMove(Moves.ZING_ZAP, Type.ELECTRIC, MoveCategory.PHYSICAL, 80, 100, 10, 30, 0, 7)
.attr(FlinchAttr),
new AttackMove(Moves.NATURES_MADNESS, Type.FAIRY, MoveCategory.SPECIAL, -1, 90, 10, -1, 0, 7)
@ -5957,8 +5985,7 @@ export function initMoves() {
new AttackMove(Moves.BODY_PRESS, Type.FIGHTING, MoveCategory.PHYSICAL, 80, 100, 10, -1, 0, 8)
.attr(DefAtkAttr),
new StatusMove(Moves.DECORATE, Type.FAIRY, -1, 15, 100, 0, 8)
.attr(StatChangeAttr, BattleStat.ATK, 2)
.attr(StatChangeAttr, BattleStat.SPATK, 2),
.attr(StatChangeAttr, [ BattleStat.ATK, BattleStat.SPATK ], 2),
new AttackMove(Moves.DRUM_BEATING, Type.GRASS, MoveCategory.PHYSICAL, 80, 100, 10, 100, 0, 8)
.attr(StatChangeAttr, BattleStat.SPD, -1)
.makesContact(false),

View File

@ -82,7 +82,11 @@ export enum FormChangeItem {
SHADOW_REINS_OF_UNITY,
WELLSPRING_MASK,
HEARTHFLAME_MASK,
CORNERSTONE_MASK
CORNERSTONE_MASK,
SHOCK_DRIVE,
BURN_DRIVE,
CHILL_DRIVE,
DOUSE_DRIVE
}
export type SpeciesFormChangeConditionPredicate = (p: Pokemon) => boolean;
@ -542,6 +546,12 @@ export const pokemonFormChanges: PokemonFormChanges = {
new SpeciesFormChange(Species.MELOETTA, 'pirouette', 'aria', new SpeciesFormChangePostMoveTrigger(Moves.RELIC_SONG), true),
new SpeciesFormChange(Species.MELOETTA, 'pirouette', 'aria', new SpeciesFormChangeActiveTrigger(false), true)
],
[Species.GENESECT]: [
new SpeciesFormChange(Species.GENESECT, '', 'shock', new SpeciesFormChangeItemTrigger(FormChangeItem.SHOCK_DRIVE)),
new SpeciesFormChange(Species.GENESECT, '', 'burn', new SpeciesFormChangeItemTrigger(FormChangeItem.BURN_DRIVE)),
new SpeciesFormChange(Species.GENESECT, '', 'chill', new SpeciesFormChangeItemTrigger(FormChangeItem.CHILL_DRIVE)),
new SpeciesFormChange(Species.GENESECT, '', 'douse', new SpeciesFormChangeItemTrigger(FormChangeItem.DOUSE_DRIVE))
],
[Species.GRENINJA]: [
new SpeciesFormChange(Species.GRENINJA, 'battle-bond', 'ash', new SpeciesFormChangeManualTrigger(), true),
new SpeciesFormChange(Species.GRENINJA, 'ash', 'battle-bond', new SpeciesFormChangeManualTrigger(), true)

View File

@ -2597,7 +2597,7 @@ export const pokemonSpeciesLevelMoves: PokemonSpeciesLevelMoves = {
[ 31, Moves.LIGHT_SCREEN ],
[ 34, Moves.BODY_SLAM ],
[ 39, Moves.SAFEGUARD ],
[ 42, Moves.AROMATHERAPY ],
[ 42, Moves.GIGA_DRAIN ],
[ 45, Moves.SOLAR_BEAM ],
],
[Species.BAYLEEF]: [
@ -2613,7 +2613,7 @@ export const pokemonSpeciesLevelMoves: PokemonSpeciesLevelMoves = {
[ 36, Moves.LIGHT_SCREEN ],
[ 40, Moves.BODY_SLAM ],
[ 46, Moves.SAFEGUARD ],
[ 50, Moves.AROMATHERAPY ],
[ 50, Moves.GIGA_DRAIN ],
[ 54, Moves.SOLAR_BEAM ],
],
[Species.MEGANIUM]: [
@ -2631,7 +2631,7 @@ export const pokemonSpeciesLevelMoves: PokemonSpeciesLevelMoves = {
[ 40, Moves.LIGHT_SCREEN ],
[ 46, Moves.BODY_SLAM ],
[ 54, Moves.SAFEGUARD ],
[ 60, Moves.AROMATHERAPY ],
[ 60, Moves.GIGA_DRAIN ],
[ 65, Moves.SOLAR_BEAM ],
],
[Species.CYNDAQUIL]: [
@ -2795,6 +2795,7 @@ export const pokemonSpeciesLevelMoves: PokemonSpeciesLevelMoves = {
[ 1, Moves.ECHOED_VOICE ],
[ 9, Moves.CONFUSION ],
[ 12, Moves.REFLECT ],
[ 15, Moves.DEFOG ],
[ 18, Moves.AIR_SLASH ],
[ 23, Moves.EXTRASENSORY ],
[ 28, Moves.TAKE_DOWN ],
@ -3573,7 +3574,7 @@ export const pokemonSpeciesLevelMoves: PokemonSpeciesLevelMoves = {
[ 13, Moves.LICK ],
[ 19, Moves.HEADBUTT ],
[ 25, Moves.ROAR ],
[ 31, Moves.RAGE ],
[ 31, Moves.LAST_RESORT ],
[ 37, Moves.PLAY_ROUGH ],
[ 43, Moves.PAYBACK ],
[ 49, Moves.CRUNCH ],
@ -3591,7 +3592,7 @@ export const pokemonSpeciesLevelMoves: PokemonSpeciesLevelMoves = {
[ 13, Moves.LICK ],
[ 19, Moves.HEADBUTT ],
[ 27, Moves.ROAR ],
[ 35, Moves.RAGE ],
[ 35, Moves.LAST_RESORT ],
[ 43, Moves.PLAY_ROUGH ],
[ 51, Moves.PAYBACK ],
[ 59, Moves.CRUNCH ],
@ -3867,7 +3868,7 @@ export const pokemonSpeciesLevelMoves: PokemonSpeciesLevelMoves = {
[ 20, Moves.WING_ATTACK ],
[ 24, Moves.SLASH ],
[ 28, Moves.STEEL_WING ],
[ 32, Moves.AUTOTOMIZE ],
[ 32, Moves.PAYBACK ],
[ 36, Moves.DRILL_PECK ],
[ 40, Moves.METAL_SOUND ],
[ 44, Moves.SPIKES ],
@ -3922,11 +3923,12 @@ export const pokemonSpeciesLevelMoves: PokemonSpeciesLevelMoves = {
[ 20, Moves.DRAGON_BREATH ],
[ 25, Moves.BUBBLE_BEAM ],
[ 30, Moves.AGILITY ],
[ 37, Moves.LASER_FOCUS ],
[ 37, Moves.WATER_PULSE ],
[ 44, Moves.DRAGON_PULSE ],
[ 51, Moves.HYDRO_PUMP ],
[ 58, Moves.DRAGON_DANCE ],
[ 65, Moves.RAIN_DANCE ],
[ 72, Moves.WAVE_CRASH ],
],
[Species.PHANPY]: [
[ 1, Moves.TACKLE ],
@ -3973,10 +3975,9 @@ export const pokemonSpeciesLevelMoves: PokemonSpeciesLevelMoves = {
[ 35, Moves.RECOVER ],
[ 40, Moves.DISCHARGE ],
[ 45, Moves.TRI_ATTACK ],
[ 50, Moves.MAGIC_COAT ],
[ 55, Moves.LOCK_ON ],
[ 60, Moves.ZAP_CANNON ],
[ 65, Moves.HYPER_BEAM ],
[ 50, Moves.LOCK_ON ],
[ 55, Moves.ZAP_CANNON ],
[ 60, Moves.HYPER_BEAM ],
],
[Species.STANTLER]: [
[ 1, Moves.TACKLE ],
@ -4267,7 +4268,7 @@ export const pokemonSpeciesLevelMoves: PokemonSpeciesLevelMoves = {
[ 72, Moves.FIRE_BLAST ],
[ 81, Moves.FUTURE_SIGHT ],
[ 90, Moves.SKY_ATTACK ],
[ 99, Moves.BURN_UP ],
[ 99, Moves.OVERHEAT ],
],
[Species.CELEBI]: [
[ 1, Moves.CONFUSION ],

View File

@ -134,4 +134,44 @@ export function getStatusEffectCatchRateMultiplier(statusEffect: StatusEffect):
}
return 1;
}
/**
* Returns a random non-volatile StatusEffect
*/
export function generateRandomStatusEffect(): StatusEffect {
return Utils.randIntRange(1, 6);
}
/**
* Returns a random non-volatile StatusEffect between the two provided
* @param statusEffectA The first StatusEffect
* @param statusEffectA The second StatusEffect
*/
export function getRandomStatusEffect(statusEffectA: StatusEffect, statusEffectB: StatusEffect): StatusEffect {
if (statusEffectA === StatusEffect.NONE || statusEffectA === StatusEffect.FAINT) {
return statusEffectB;
}
if (statusEffectB === StatusEffect.NONE || statusEffectB === StatusEffect.FAINT) {
return statusEffectA;
}
return Utils.randIntRange(0, 2) ? statusEffectA : statusEffectB;
}
/**
* Returns a random non-volatile StatusEffect between the two provided
* @param statusA The first Status
* @param statusB The second Status
*/
export function getRandomStatus(statusA: Status, statusB: Status): Status {
if (statusA === undefined || statusA.effect === StatusEffect.NONE || statusA.effect === StatusEffect.FAINT) {
return statusB;
}
if (statusB === undefined || statusB.effect === StatusEffect.NONE || statusB.effect === StatusEffect.FAINT) {
return statusA;
}
return Utils.randIntRange(0, 2) ? statusA : statusB;
}

View File

@ -14,7 +14,7 @@ import { AttackTypeBoosterModifier, DamageMoneyRewardModifier, EnemyDamageBooste
import { PokeballType } from '../data/pokeball';
import { Gender } from '../data/gender';
import { initMoveAnim, loadMoveAnimAssets } from '../data/battle-anims';
import { Status, StatusEffect } from '../data/status-effect';
import { Status, StatusEffect, getRandomStatus } from '../data/status-effect';
import { pokemonEvolutions, pokemonPrevolutions, SpeciesFormEvolution, SpeciesEvolutionCondition, FusionSpeciesFormEvolution } from '../data/pokemon-evolutions';
import { reverseCompatibleTms, tmSpecies } from '../data/tms';
import { DamagePhase, FaintPhase, LearnMovePhase, ObtainStatusEffectPhase, StatChangePhase, SwitchSummonPhase } from '../phases';
@ -2542,6 +2542,10 @@ export class PlayerPokemon extends Pokemon {
this.generateCompatibleTms();
}
/**
* Returns a Promise to fuse two PlayerPokemon together
* @param pokemon The PlayerPokemon to fuse to this one
*/
fuse(pokemon: PlayerPokemon): Promise<void> {
return new Promise(resolve => {
this.fusionSpecies = pokemon.species;
@ -2555,8 +2559,25 @@ export class PlayerPokemon extends Pokemon {
this.scene.validateAchv(achvs.SPLICE);
this.scene.gameData.gameStats.pokemonFused++;
// Store the average HP% that each Pokemon has
const newHpPercent = ((pokemon.hp / pokemon.stats[Stat.HP]) + (this.hp / this.stats[Stat.HP])) / 2;
this.generateName();
this.calculateStats();
// Set this Pokemon's HP to the average % of both fusion components
this.hp = Math.round(this.stats[Stat.HP] * newHpPercent);
if (!this.isFainted()) {
// If this Pokemon hasn't fainted, make sure the HP wasn't set over the new maximum
this.hp = Math.min(this.hp, this.stats[Stat.HP]);
this.status = getRandomStatus(this.status, pokemon.status); // Get a random valid status between the two
}
else if (!pokemon.isFainted()) {
// If this Pokemon fainted but the other hasn't, make sure the HP wasn't set to zero
this.hp = Math.max(this.hp, 1);
this.status = pokemon.status; // Inherit the other Pokemon's status
}
this.generateCompatibleTms();
this.updateInfo(true);
const fusedPartyMemberIndex = this.scene.getParty().indexOf(pokemon);

View File

@ -31,6 +31,8 @@ export class LoadingScene extends SceneBase {
this.loadAtlas('bg', 'ui');
this.loadImage('command_fight_labels', 'ui');
this.loadAtlas('prompt', 'ui');
this.loadImage('candy', 'ui');
this.loadImage('candy_overlay', 'ui');
this.loadImage('cursor', 'ui');
this.loadImage('cursor_reverse', 'ui');
for (let wv of Utils.getEnumValues(WindowVariant)) {

View File

@ -30,7 +30,7 @@ import { Weather, WeatherType, getRandomWeatherType, getTerrainBlockMessage, get
import { TempBattleStat } from "./data/temp-battle-stat";
import { ArenaTagSide, ArenaTrapTag, MistTag, TrickRoomTag } from "./data/arena-tag";
import { ArenaTagType } from "./data/enums/arena-tag-type";
import { CheckTrappedAbAttr, IgnoreOpponentStatChangesAbAttr, PostAttackAbAttr, PostBattleAbAttr, PostDefendAbAttr, PostSummonAbAttr, PostTurnAbAttr, PostWeatherLapseAbAttr, PreSwitchOutAbAttr, PreWeatherDamageAbAttr, ProtectStatAbAttr, RedirectMoveAbAttr, RunSuccessAbAttr, StatChangeMultiplierAbAttr, SuppressWeatherEffectAbAttr, SyncEncounterNatureAbAttr, applyAbAttrs, applyCheckTrappedAbAttrs, applyPostAttackAbAttrs, applyPostBattleAbAttrs, applyPostDefendAbAttrs, applyPostSummonAbAttrs, applyPostTurnAbAttrs, applyPostWeatherLapseAbAttrs, applyPreStatChangeAbAttrs, applyPreSwitchOutAbAttrs, applyPreWeatherEffectAbAttrs, BattleStatMultiplierAbAttr, applyBattleStatMultiplierAbAttrs, IncrementMovePriorityAbAttr, applyPostVictoryAbAttrs, PostVictoryAbAttr, applyPostBattleInitAbAttrs, PostBattleInitAbAttr, BlockNonDirectDamageAbAttr as BlockNonDirectDamageAbAttr, applyPostKnockOutAbAttrs, PostKnockOutAbAttr, PostBiomeChangeAbAttr, applyPostFaintAbAttrs, PostFaintAbAttr, IncreasePpAbAttr, PostStatChangeAbAttr, applyPostStatChangeAbAttrs, AlwaysHitAbAttr, PreventBerryUseAbAttr } from "./data/ability";
import { CheckTrappedAbAttr, IgnoreOpponentStatChangesAbAttr, PostAttackAbAttr, PostBattleAbAttr, PostDefendAbAttr, PostSummonAbAttr, PostTurnAbAttr, PostWeatherLapseAbAttr, PreSwitchOutAbAttr, PreWeatherDamageAbAttr, ProtectStatAbAttr, RedirectMoveAbAttr, RunSuccessAbAttr, StatChangeMultiplierAbAttr, SuppressWeatherEffectAbAttr, SyncEncounterNatureAbAttr, applyAbAttrs, applyCheckTrappedAbAttrs, applyPostAttackAbAttrs, applyPostBattleAbAttrs, applyPostDefendAbAttrs, applyPostSummonAbAttrs, applyPostTurnAbAttrs, applyPostWeatherLapseAbAttrs, applyPreStatChangeAbAttrs, applyPreSwitchOutAbAttrs, applyPreWeatherEffectAbAttrs, BattleStatMultiplierAbAttr, applyBattleStatMultiplierAbAttrs, IncrementMovePriorityAbAttr, applyPostVictoryAbAttrs, PostVictoryAbAttr, applyPostBattleInitAbAttrs, PostBattleInitAbAttr, BlockNonDirectDamageAbAttr as BlockNonDirectDamageAbAttr, applyPostKnockOutAbAttrs, PostKnockOutAbAttr, PostBiomeChangeAbAttr, applyPostFaintAbAttrs, PostFaintAbAttr, IncreasePpAbAttr, PostStatChangeAbAttr, applyPostStatChangeAbAttrs, AlwaysHitAbAttr, PreventBerryUseAbAttr, StatChangeCopyAbAttr } from "./data/ability";
import { Unlockables, getUnlockableName } from "./system/unlockables";
import { getBiomeKey } from "./field/arena";
import { BattleType, BattlerIndex, TurnCommand } from "./battle";
@ -1179,14 +1179,25 @@ export class SummonPhase extends PartyMemberPokemonPhase {
this.preSummon();
}
/**
* Sends out a Pokemon before the battle begins and shows the appropriate messages
*/
preSummon(): void {
const partyMember = this.getPokemon();
// If the Pokemon about to be sent out is fainted, switch to the first non-fainted Pokemon
if (partyMember.isFainted()) {
console.warn("The Pokemon about to be sent out is fainted. Attempting to resolve...");
const party = this.getParty();
const nonFaintedIndex = party.slice(this.partyMemberIndex).findIndex(p => !p.isFainted()) + this.partyMemberIndex;
const nonFaintedPartyMember = party[nonFaintedIndex];
party[nonFaintedIndex] = partyMember;
party[this.partyMemberIndex] = nonFaintedPartyMember;
const nonFaintedIndex = party.findIndex(x => !x.isFainted()); // Find the first non-fainted Pokemon index
if (nonFaintedIndex === -1) {
console.error("Party Details:\n", party);
throw new Error("All available Pokemon were fainted!");
}
// Swaps the fainted Pokemon and the first non-fainted Pokemon in the party
[party[this.partyMemberIndex], party[nonFaintedIndex]] = [party[nonFaintedIndex], party[this.partyMemberIndex]];
console.warn("Swapped %s %O with %s %O", partyMember?.name, partyMember, party[0]?.name, party[0]);
}
if (this.player) {
@ -2661,8 +2672,9 @@ export class StatChangePhase extends PokemonPhase {
private levels: integer;
private showMessage: boolean;
private ignoreAbilities: boolean;
private canBeCopied: boolean;
constructor(scene: BattleScene, battlerIndex: BattlerIndex, selfTarget: boolean, stats: BattleStat[], levels: integer, showMessage: boolean = true, ignoreAbilities: boolean = false) {
constructor(scene: BattleScene, battlerIndex: BattlerIndex, selfTarget: boolean, stats: BattleStat[], levels: integer, showMessage: boolean = true, ignoreAbilities: boolean = false, canBeCopied: boolean = true) {
super(scene, battlerIndex);
this.selfTarget = selfTarget;
@ -2670,6 +2682,7 @@ export class StatChangePhase extends PokemonPhase {
this.levels = levels;
this.showMessage = showMessage;
this.ignoreAbilities = ignoreAbilities;
this.canBeCopied = canBeCopied;
}
start() {
@ -2717,8 +2730,12 @@ export class StatChangePhase extends PokemonPhase {
for (let stat of filteredStats)
pokemon.summonData.battleStats[stat] = Math.max(Math.min(pokemon.summonData.battleStats[stat] + levels.value, 6), -6);
if (levels.value > 0 && this.canBeCopied)
for (let opponent of pokemon.getOpponents())
applyAbAttrs(StatChangeCopyAbAttr, opponent, null, this.stats, levels.value);
applyPostStatChangeAbAttrs(PostStatChangeAbAttr, pokemon, filteredStats, this.levels, this.selfTarget);
pokemon.updateInfo();
handleTutorial(this.scene, Tutorial.Stat_Change).then(() => super.end());
@ -4344,7 +4361,7 @@ export class SelectModifierPhase extends BattlePhase {
const isMoveModifier = modifierType instanceof PokemonMoveModifierType;
const isTmModifier = modifierType instanceof TmModifierType;
const isRememberMoveModifier = modifierType instanceof RememberMoveModifierType;
const isPpRestoreModifier = modifierType instanceof PokemonPpRestoreModifierType;
const isPpRestoreModifier = (modifierType instanceof PokemonPpRestoreModifierType || modifierType instanceof PokemonPpUpModifierType);
const partyUiMode = isMoveModifier ? PartyUiMode.MOVE_MODIFIER
: isTmModifier ? PartyUiMode.TM_MODIFIER
: isRememberMoveModifier ? PartyUiMode.REMEMBER_MOVE_MODIFIER

View File

@ -1,8 +1,10 @@
import BattleScene, { Button } from "../battle-scene";
import BattleScene, { Button, starterColors } from "../battle-scene";
import { Mode } from "./ui";
import UiHandler from "./ui-handler";
import * as Utils from "../utils";
import { PlayerPokemon } from "../field/pokemon";
import { default as PokemonSpecies, PokemonSpeciesForm, SpeciesFormKey, getFusedSpeciesName, getPokemonSpecies, getPokemonSpeciesForm, getStarterValueFriendshipCap, speciesStarters, starterPassiveAbilities } from '../data/pokemon-species';
import { argbFromRgba } from "@material/material-color-utilities";
import { Type, getTypeRgb } from "../data/type";
import { TextStyle, addBBCodeTextObject, addTextObject, getBBCodeFrag, getTextColor } from "./text";
import Move, { MoveCategory } from "../data/move";
@ -44,6 +46,9 @@ export default class SummaryUiHandler extends UiHandler {
private genderText: Phaser.GameObjects.Text;
private shinyIcon: Phaser.GameObjects.Image;
private fusionShinyIcon: Phaser.GameObjects.Image;
private candyShadow: Phaser.GameObjects.Sprite;
private candyIcon: Phaser.GameObjects.Sprite;
private candyOverlay: Phaser.GameObjects.Sprite;
private statusContainer: Phaser.GameObjects.Container;
private status: Phaser.GameObjects.Image;
private summaryPageContainer: Phaser.GameObjects.Container;
@ -136,6 +141,20 @@ export default class SummaryUiHandler extends UiHandler {
this.pokeball.setOrigin(0, 1);
this.summaryContainer.add(this.pokeball);
this.candyShadow = this.scene.add.sprite(13, -140, 'candy');
this.candyShadow.setTint(0x141414)
this.candyShadow.setScale(0.8);
this.candyShadow.setInteractive(new Phaser.Geom.Rectangle(0, 0, 16, 16), Phaser.Geom.Rectangle.Contains);
this.summaryContainer.add(this.candyShadow);
this.candyIcon = this.scene.add.sprite(13, -140, 'candy');
this.candyIcon.setScale(0.8);
this.summaryContainer.add(this.candyIcon);
this.candyOverlay = this.scene.add.sprite(13, -140, 'candy_overlay');
this.candyOverlay.setScale(0.8);
this.summaryContainer.add(this.candyOverlay);
this.levelText = addTextObject(this.scene, 36, -17, '', TextStyle.SUMMARY_ALT);
this.levelText.setOrigin(0, 1);
this.summaryContainer.add(this.levelText);
@ -222,6 +241,10 @@ export default class SummaryUiHandler extends UiHandler {
this.shinyOverlay.setVisible(this.pokemon.isShiny());
const colorScheme = starterColors[this.pokemon.species.getRootSpeciesId()];
this.candyIcon.setTint(argbFromRgba(Utils.rgbHexToRgba(colorScheme[0])));
this.candyOverlay.setTint(argbFromRgba(Utils.rgbHexToRgba(colorScheme[1])));
this.numberText.setText(Utils.padInt(this.pokemon.species.speciesId, 4));
this.numberText.setColor(this.getTextColor(!this.pokemon.isShiny() ? TextStyle.SUMMARY : TextStyle.SUMMARY_GOLD));
this.numberText.setShadowColor(this.getTextColor(!this.pokemon.isShiny() ? TextStyle.SUMMARY : TextStyle.SUMMARY_GOLD, true));
@ -251,6 +274,21 @@ export default class SummaryUiHandler extends UiHandler {
this.splicedIcon.on('pointerout', () => (this.scene as BattleScene).ui.hideTooltip());
}
var currentFriendship = this.scene.gameData.starterData[this.pokemon.species.getRootSpeciesId()].friendship;
if (!currentFriendship || currentFriendship === undefined)
currentFriendship = 0;
const friendshipCap = getStarterValueFriendshipCap(speciesStarters[this.pokemon.species.getRootSpeciesId()]);
const candyCropY = 16 - (16 * (currentFriendship / friendshipCap));
if (this.candyShadow.visible) {
this.candyShadow.on('pointerover', () => (this.scene as BattleScene).ui.showTooltip(null, `${currentFriendship}/${friendshipCap}`, true));
this.candyShadow.on('pointerout', () => (this.scene as BattleScene).ui.hideTooltip());
}
this.candyIcon.setCrop(0,candyCropY,16, 16);
this.candyOverlay.setCrop(0,candyCropY,16, 16);
const doubleShiny = isFusion && this.pokemon.shiny && this.pokemon.fusionShiny;
const baseVariant = !doubleShiny ? this.pokemon.getVariant() : this.pokemon.variant;

View File

@ -62,6 +62,11 @@ export function padInt(value: integer, length: integer, padWith?: string): strin
return valueStr;
}
/**
* Returns a random integer between min and min + range
* @param range The amount of possible numbers
* @param min The starting number
*/
export function randInt(range: integer, min: integer = 0): integer {
if (range === 1)
return min;
@ -74,6 +79,11 @@ export function randSeedInt(range: integer, min: integer = 0): integer {
return Phaser.Math.RND.integerInRange(min, (range - 1) + min);
}
/**
* Returns a random integer between min and max (non-inclusive)
* @param min The lowest number
* @param max The highest number
*/
export function randIntRange(min: integer, max: integer): integer {
return randInt(max - min, min);
}