Merge branch 'pagefaultgames:main' into main

This commit is contained in:
Zanubiss 2024-05-09 09:18:01 +02:00 committed by GitHub
commit 479e232324
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
38 changed files with 6895 additions and 136 deletions

View File

@ -562,19 +562,28 @@ export class PostDefendStatChangeAbAttr extends PostDefendAbAttr {
private stat: BattleStat;
private levels: integer;
private selfTarget: boolean;
private allOthers: boolean;
constructor(condition: PokemonDefendCondition, stat: BattleStat, levels: integer, selfTarget: boolean = true) {
constructor(condition: PokemonDefendCondition, stat: BattleStat, levels: integer, selfTarget: boolean = true, allOthers: boolean = false) {
super(true);
this.condition = condition;
this.stat = stat;
this.levels = levels;
this.selfTarget = selfTarget;
this.allOthers = allOthers;
}
applyPostDefend(pokemon: Pokemon, passive: boolean, attacker: Pokemon, move: PokemonMove, hitResult: HitResult, args: any[]): boolean {
if (this.condition(pokemon, attacker, move.getMove())) {
pokemon.scene.unshiftPhase(new StatChangePhase(pokemon.scene, (this.selfTarget ? pokemon : attacker).getBattlerIndex(), true, [ this.stat ], this.levels));
if (this.allOthers) {
let otherPokemon = pokemon.getAlly() ? pokemon.getOpponents().concat([ pokemon.getAlly() ]) : pokemon.getOpponents();
for (let other of otherPokemon) {
other.scene.unshiftPhase(new StatChangePhase(other.scene, (other).getBattlerIndex(), false, [ this.stat ], this.levels));
}
return true;
}
pokemon.scene.unshiftPhase(new StatChangePhase(pokemon.scene, (this.selfTarget ? pokemon : attacker).getBattlerIndex(), this.selfTarget, [ this.stat ], this.levels));
return true;
}
@ -851,6 +860,36 @@ export class PostDefendAbilityGiveAbAttr extends PostDefendAbAttr {
}
}
export class PostDefendMoveDisableAbAttr extends PostDefendAbAttr {
private chance: integer;
private attacker: Pokemon;
private move: PokemonMove;
constructor(chance: integer) {
super();
this.chance = chance;
}
applyPostDefend(pokemon: Pokemon, passive: boolean, attacker: Pokemon, move: PokemonMove, hitResult: HitResult, args: any[]): boolean {
if (!attacker.summonData.disabledMove) {
if (move.getMove().checkFlag(MoveFlags.MAKES_CONTACT, attacker, pokemon) && (this.chance === -1 || pokemon.randSeedInt(100) < this.chance) && !attacker.isMax()) {
this.attacker = attacker;
this.move = move;
attacker.summonData.disabledMove = move.moveId;
attacker.summonData.disabledTurns = 4;
return true;
}
}
return false;
}
getTriggerMessage(pokemon: Pokemon, abilityName: string, ...args: any[]): string {
return getPokemonMessage(this.attacker, `'s ${this.move.getName()}\nwas disabled!`);
}
}
export class PostStatChangeStatChangeAbAttr extends PostStatChangeAbAttr {
private condition: PokemonStatChangeCondition;
private statsToChange: BattleStat[];
@ -2016,13 +2055,30 @@ export class PostTurnAbAttr extends AbAttr {
}
}
/**
* After the turn ends, resets the status of either the ability holder or their ally
* @param {boolean} allyTarget Whether to target ally, defaults to false (self-target)
*/
export class PostTurnResetStatusAbAttr extends PostTurnAbAttr {
private allyTarget: boolean;
private target: Pokemon;
constructor(allyTarget: boolean = false) {
super(true);
this.allyTarget = allyTarget;
}
applyPostTurn(pokemon: Pokemon, passive: boolean, args: any[]): boolean {
if (pokemon.status) {
if (this.allyTarget) {
this.target = pokemon.getAlly();
} else {
this.target = pokemon;
}
if (this.target?.status) {
pokemon.scene.queueMessage(getPokemonMessage(pokemon, getStatusEffectHealText(pokemon.status?.effect)));
pokemon.resetStatus();
pokemon.updateInfo();
this.target.scene.queueMessage(getPokemonMessage(this.target, getStatusEffectHealText(this.target.status?.effect)));
this.target.resetStatus(false);
this.target.updateInfo();
return true;
}
@ -3067,9 +3123,10 @@ export function initAbilities() {
.attr(BattleStatMultiplierAbAttr, BattleStat.SPATK, 0.5)
.condition((pokemon) => pokemon.getHpRatio() <= 0.5),
new Ability(Abilities.CURSED_BODY, 5)
.unimplemented(),
.attr(PostDefendMoveDisableAbAttr, 30)
.bypassFaint(),
new Ability(Abilities.HEALER, 5)
.unimplemented(),
.conditionalAttr(pokemon => pokemon.getAlly() && Utils.randSeedInt(10) < 3, PostTurnResetStatusAbAttr, true),
new Ability(Abilities.FRIEND_GUARD, 5)
.ignorable()
.unimplemented(),
@ -3248,7 +3305,7 @@ export function initAbilities() {
new Ability(Abilities.EMERGENCY_EXIT, 7)
.unimplemented(),
new Ability(Abilities.WATER_COMPACTION, 7)
.attr(PostDefendStatChangeAbAttr, (target, user, move) => move.type === Type.WATER, BattleStat.DEF, 2),
.attr(PostDefendStatChangeAbAttr, (target, user, move) => move.type === Type.WATER && move.category !== MoveCategory.STATUS, BattleStat.DEF, 2),
new Ability(Abilities.MERCILESS, 7)
.unimplemented(),
new Ability(Abilities.SHIELDS_DOWN, 7)
@ -3405,7 +3462,8 @@ export function initAbilities() {
new Ability(Abilities.BALL_FETCH, 8)
.unimplemented(),
new Ability(Abilities.COTTON_DOWN, 8)
.unimplemented(),
.attr(PostDefendStatChangeAbAttr, (target, user, move) => move.category !== MoveCategory.STATUS, BattleStat.SPD, -1, false, true)
.bypassFaint(),
new Ability(Abilities.PROPELLER_TAIL, 8)
.unimplemented(),
new Ability(Abilities.MIRROR_ARMOR, 8)

View File

@ -68,6 +68,17 @@ export class BattlerTag {
? allMoves[this.sourceMove].name
: null;
}
/**
* When given a battler tag or json representing one, load the data for it.
* This is meant to be inherited from by any battler tag with custom attributes
* @param {BattlerTag | any} source A battler tag
*/
loadTag(source: BattlerTag | any): void {
this.turnCount = source.turnCount;
this.sourceMove = source.sourceMove;
this.sourceId = source.sourceId;
}
}
export interface WeatherBattlerTag {
@ -299,6 +310,15 @@ export class SeedTag extends BattlerTag {
super(BattlerTagType.SEEDED, BattlerTagLapseType.TURN_END, 1, Moves.LEECH_SEED, sourceId);
}
/**
* When given a battler tag or json representing one, load the data for it.
* @param {BattlerTag | any} source A battler tag
*/
loadTag(source: BattlerTag | any): void {
super.loadTag(source);
this.sourceIndex = source.sourceIndex;
}
canAdd(pokemon: Pokemon): boolean {
return !pokemon.isOfType(Type.GRASS);
}
@ -404,6 +424,15 @@ export class EncoreTag extends BattlerTag {
super(BattlerTagType.ENCORE, BattlerTagLapseType.AFTER_MOVE, 3, Moves.ENCORE, sourceId);
}
/**
* When given a battler tag or json representing one, load the data for it.
* @param {BattlerTag | any} source A battler tag
*/
loadTag(source: BattlerTag | any): void {
super.loadTag(source);
this.moveId = source.moveId as Moves;
}
canAdd(pokemon: Pokemon): boolean {
if (pokemon.isMax())
return false;
@ -553,6 +582,15 @@ export abstract class DamagingTrapTag extends TrappedTag {
this.commonAnim = commonAnim;
}
/**
* When given a battler tag or json representing one, load the data for it.
* @param {BattlerTag | any} source A battler tag
*/
loadTag(source: BattlerTag | any): void {
super.loadTag(source);
this.commonAnim = source.commonAnim as CommonAnim;
}
canAdd(pokemon: Pokemon): boolean {
return !pokemon.isOfType(Type.GHOST) && !pokemon.findTag(t => t instanceof DamagingTrapTag);
}
@ -709,6 +747,15 @@ export class ContactDamageProtectedTag extends ProtectedTag {
this.damageRatio = damageRatio;
}
/**
* When given a battler tag or json representing one, load the data for it.
* @param {BattlerTag | any} source A battler tag
*/
loadTag(source: BattlerTag | any): void {
super.loadTag(source);
this.damageRatio = source.damageRatio;
}
lapse(pokemon: Pokemon, lapseType: BattlerTagLapseType): boolean {
const ret = super.lapse(pokemon, lapseType);
@ -735,6 +782,16 @@ export class ContactStatChangeProtectedTag extends ProtectedTag {
this.levels = levels;
}
/**
* When given a battler tag or json representing one, load the data for it.
* @param {BattlerTag | any} source A battler tag
*/
loadTag(source: BattlerTag | any): void {
super.loadTag(source);
this.stat = source.stat as BattleStat;
this.levels = source.levels;
}
lapse(pokemon: Pokemon, lapseType: BattlerTagLapseType): boolean {
const ret = super.lapse(pokemon, lapseType);
@ -855,6 +912,15 @@ export class AbilityBattlerTag extends BattlerTag {
this.ability = ability;
}
/**
* When given a battler tag or json representing one, load the data for it.
* @param {BattlerTag | any} source A battler tag
*/
loadTag(source: BattlerTag | any): void {
super.loadTag(source);
this.ability = source.ability as Abilities;
}
}
export class TruantTag extends AbilityBattlerTag {
@ -912,6 +978,16 @@ export class HighestStatBoostTag extends AbilityBattlerTag {
super(tagType, ability, BattlerTagLapseType.CUSTOM, 1);
}
/**
* When given a battler tag or json representing one, load the data for it.
* @param {BattlerTag | any} source A battler tag
*/
loadTag(source: BattlerTag | any): void {
super.loadTag(source);
this.stat = source.stat as Stat;
this.multiplier = this.multiplier;
}
onAdd(pokemon: Pokemon): void {
super.onAdd(pokemon);
@ -953,6 +1029,15 @@ export class WeatherHighestStatBoostTag extends HighestStatBoostTag implements W
super(tagType, ability);
this.weatherTypes = weatherTypes;
}
/**
* When given a battler tag or json representing one, load the data for it.
* @param {BattlerTag | any} source A battler tag
*/
loadTag(source: BattlerTag | any): void {
super.loadTag(source);
this.weatherTypes = source.weatherTypes.map(w => w as WeatherType);
}
}
export class TerrainHighestStatBoostTag extends HighestStatBoostTag implements TerrainBattlerTag {
@ -962,6 +1047,15 @@ export class TerrainHighestStatBoostTag extends HighestStatBoostTag implements T
super(tagType, ability);
this.terrainTypes = terrainTypes;
}
/**
* When given a battler tag or json representing one, load the data for it.
* @param {BattlerTag | any} source A battler tag
*/
loadTag(source: BattlerTag | any): void {
super.loadTag(source);
this.terrainTypes = source.terrainTypes.map(w => w as TerrainType);
}
}
export class HideSpriteTag extends BattlerTag {
@ -989,6 +1083,15 @@ export class TypeImmuneTag extends BattlerTag {
constructor(tagType: BattlerTagType, sourceMove: Moves, immuneType: Type, length: number) {
super(tagType, BattlerTagLapseType.TURN_END, 1, sourceMove);
}
/**
* When given a battler tag or json representing one, load the data for it.
* @param {BattlerTag | any} source A battler tag
*/
loadTag(source: BattlerTag | any): void {
super.loadTag(source);
this.immuneType = source.immuneType as Type;
}
}
export class MagnetRisenTag extends TypeImmuneTag {
@ -1010,6 +1113,17 @@ export class TypeBoostTag extends BattlerTag {
this.oneUse = oneUse;
}
/**
* When given a battler tag or json representing one, load the data for it.
* @param {BattlerTag | any} source A battler tag
*/
loadTag(source: BattlerTag | any): void {
super.loadTag(source);
this.boostedType = source.boostedType as Type;
this.boostValue = source.boostValue;
this.oneUse = source.oneUse;
}
lapse(pokemon: Pokemon, lapseType: BattlerTagLapseType): boolean {
return lapseType !== BattlerTagLapseType.CUSTOM || super.lapse(pokemon, lapseType);
}
@ -1056,6 +1170,15 @@ export class SaltCuredTag extends BattlerTag {
super(BattlerTagType.SALT_CURED, BattlerTagLapseType.TURN_END, 1, Moves.SALT_CURE, sourceId);
}
/**
* When given a battler tag or json representing one, load the data for it.
* @param {BattlerTag | any} source A battler tag
*/
loadTag(source: BattlerTag | any): void {
super.loadTag(source);
this.sourceIndex = source.sourceIndex;
}
onAdd(pokemon: Pokemon): void {
super.onAdd(pokemon);
@ -1091,6 +1214,15 @@ export class CursedTag extends BattlerTag {
super(BattlerTagType.CURSED, BattlerTagLapseType.TURN_END, 1, Moves.CURSE, sourceId);
}
/**
* When given a battler tag or json representing one, load the data for it.
* @param {BattlerTag | any} source A battler tag
*/
loadTag(source: BattlerTag | any): void {
super.loadTag(source);
this.sourceIndex = source.sourceIndex;
}
onAdd(pokemon: Pokemon): void {
super.onAdd(pokemon);
@ -1231,4 +1363,15 @@ export function getBattlerTag(tagType: BattlerTagType, turnCount: integer, sourc
return new BattlerTag(tagType, BattlerTagLapseType.CUSTOM, turnCount, sourceMove, sourceId);
}
}
/**
* When given a battler tag or json representing one, creates an actual BattlerTag object with the same data.
* @param {BattlerTag | any} source A battler tag
* @return {BattlerTag} The valid battler tag
*/
export function loadBattlerTag(source: BattlerTag | any): BattlerTag {
const tag = getBattlerTag(source.tagType, source.turnCount, source.sourceMove, source.sourceId);
tag.loadTag(source);
return tag;
}

View File

@ -1920,7 +1920,8 @@ export const trainerTypeDialogue = {
},
[TrainerType.WULFRIC]: {
encounter: [
`You know what? We all talk big about what you learn from battling and bonds and all that, but really, I just do it 'cause it's fun.
`You know what? We all talk big about what you learn from battling and bonds and all that…
$But really, I just do it 'cause it's fun.
$Who cares about the grandstanding? Let's get to battling!`,
],
victory: [

View File

@ -4790,7 +4790,7 @@ export function initMoves() {
.ignoresVirtual(),
new SelfStatusMove(Moves.CHARGE, Type.ELECTRIC, -1, 20, -1, 0, 3)
.attr(StatChangeAttr, BattleStat.SPDEF, 1, true)
.attr(AddBattlerTagAttr, BattlerTagType.CHARGED, true, true),
.attr(AddBattlerTagAttr, BattlerTagType.CHARGED, true, false),
new StatusMove(Moves.TAUNT, Type.DARK, 100, 20, -1, 0, 3)
.unimplemented(),
new StatusMove(Moves.HELPING_HAND, Type.NORMAL, -1, 20, -1, 5, 3)
@ -5753,79 +5753,116 @@ export function initMoves() {
.ignoresProtect(),
/* Unused */
new AttackMove(Moves.BREAKNECK_BLITZ__PHYSICAL, Type.NORMAL, MoveCategory.PHYSICAL, -1, -1, 1, -1, 0, 7)
.unimplemented(),
.unimplemented()
.ignoresVirtual(),
new AttackMove(Moves.BREAKNECK_BLITZ__SPECIAL, Type.NORMAL, MoveCategory.SPECIAL, -1, -1, 1, -1, 0, 7)
.unimplemented(),
.unimplemented()
.ignoresVirtual(),
new AttackMove(Moves.ALL_OUT_PUMMELING__PHYSICAL, Type.FIGHTING, MoveCategory.PHYSICAL, -1, -1, 1, -1, 0, 7)
.unimplemented(),
.unimplemented()
.ignoresVirtual(),
new AttackMove(Moves.ALL_OUT_PUMMELING__SPECIAL, Type.FIGHTING, MoveCategory.SPECIAL, -1, -1, 1, -1, 0, 7)
.unimplemented(),
.unimplemented()
.ignoresVirtual(),
new AttackMove(Moves.SUPERSONIC_SKYSTRIKE__PHYSICAL, Type.FLYING, MoveCategory.PHYSICAL, -1, -1, 1, -1, 0, 7)
.unimplemented(),
.unimplemented()
.ignoresVirtual(),
new AttackMove(Moves.SUPERSONIC_SKYSTRIKE__SPECIAL, Type.FLYING, MoveCategory.SPECIAL, -1, -1, 1, -1, 0, 7)
.unimplemented(),
.unimplemented()
.ignoresVirtual(),
new AttackMove(Moves.ACID_DOWNPOUR__PHYSICAL, Type.POISON, MoveCategory.PHYSICAL, -1, -1, 1, -1, 0, 7)
.unimplemented(),
.unimplemented()
.ignoresVirtual(),
new AttackMove(Moves.ACID_DOWNPOUR__SPECIAL, Type.POISON, MoveCategory.SPECIAL, -1, -1, 1, -1, 0, 7)
.unimplemented(),
.unimplemented()
.ignoresVirtual(),
new AttackMove(Moves.TECTONIC_RAGE__PHYSICAL, Type.GROUND, MoveCategory.PHYSICAL, -1, -1, 1, -1, 0, 7)
.unimplemented(),
.unimplemented()
.ignoresVirtual(),
new AttackMove(Moves.TECTONIC_RAGE__SPECIAL, Type.GROUND, MoveCategory.SPECIAL, -1, -1, 1, -1, 0, 7)
.unimplemented(),
.unimplemented()
.ignoresVirtual(),
new AttackMove(Moves.CONTINENTAL_CRUSH__PHYSICAL, Type.ROCK, MoveCategory.PHYSICAL, -1, -1, 1, -1, 0, 7)
.unimplemented(),
.unimplemented()
.ignoresVirtual(),
new AttackMove(Moves.CONTINENTAL_CRUSH__SPECIAL, Type.ROCK, MoveCategory.SPECIAL, -1, -1, 1, -1, 0, 7)
.unimplemented(),
.unimplemented()
.ignoresVirtual(),
new AttackMove(Moves.SAVAGE_SPIN_OUT__PHYSICAL, Type.BUG, MoveCategory.PHYSICAL, -1, -1, 1, -1, 0, 7)
.unimplemented(),
.unimplemented()
.ignoresVirtual(),
new AttackMove(Moves.SAVAGE_SPIN_OUT__SPECIAL, Type.BUG, MoveCategory.SPECIAL, -1, -1, 1, -1, 0, 7)
.unimplemented(),
.unimplemented()
.ignoresVirtual(),
new AttackMove(Moves.NEVER_ENDING_NIGHTMARE__PHYSICAL, Type.GHOST, MoveCategory.PHYSICAL, -1, -1, 1, -1, 0, 7)
.unimplemented(),
.unimplemented()
.ignoresVirtual(),
new AttackMove(Moves.NEVER_ENDING_NIGHTMARE__SPECIAL, Type.GHOST, MoveCategory.SPECIAL, -1, -1, 1, -1, 0, 7)
.unimplemented(),
.unimplemented()
.ignoresVirtual(),
new AttackMove(Moves.CORKSCREW_CRASH__PHYSICAL, Type.STEEL, MoveCategory.PHYSICAL, -1, -1, 1, -1, 0, 7)
.unimplemented(),
.unimplemented()
.ignoresVirtual(),
new AttackMove(Moves.CORKSCREW_CRASH__SPECIAL, Type.STEEL, MoveCategory.SPECIAL, -1, -1, 1, -1, 0, 7)
.unimplemented(),
.unimplemented()
.ignoresVirtual(),
new AttackMove(Moves.INFERNO_OVERDRIVE__PHYSICAL, Type.FIRE, MoveCategory.PHYSICAL, -1, -1, 1, -1, 0, 7)
.unimplemented(),
.unimplemented()
.ignoresVirtual(),
new AttackMove(Moves.INFERNO_OVERDRIVE__SPECIAL, Type.FIRE, MoveCategory.SPECIAL, -1, -1, 1, -1, 0, 7)
.unimplemented(),
.unimplemented()
.ignoresVirtual(),
new AttackMove(Moves.HYDRO_VORTEX__PHYSICAL, Type.WATER, MoveCategory.PHYSICAL, -1, -1, 1, -1, 0, 7)
.unimplemented(),
.unimplemented()
.ignoresVirtual(),
new AttackMove(Moves.HYDRO_VORTEX__SPECIAL, Type.WATER, MoveCategory.SPECIAL, -1, -1, 1, -1, 0, 7)
.unimplemented(),
.unimplemented()
.ignoresVirtual(),
new AttackMove(Moves.BLOOM_DOOM__PHYSICAL, Type.GRASS, MoveCategory.PHYSICAL, -1, -1, 1, -1, 0, 7)
.unimplemented(),
.unimplemented()
.ignoresVirtual(),
new AttackMove(Moves.BLOOM_DOOM__SPECIAL, Type.GRASS, MoveCategory.SPECIAL, -1, -1, 1, -1, 0, 7)
.unimplemented(),
.unimplemented()
.ignoresVirtual(),
new AttackMove(Moves.GIGAVOLT_HAVOC__PHYSICAL, Type.ELECTRIC, MoveCategory.PHYSICAL, -1, -1, 1, -1, 0, 7)
.unimplemented(),
.unimplemented()
.ignoresVirtual(),
new AttackMove(Moves.GIGAVOLT_HAVOC__SPECIAL, Type.ELECTRIC, MoveCategory.SPECIAL, -1, -1, 1, -1, 0, 7)
.unimplemented(),
.unimplemented()
.ignoresVirtual(),
new AttackMove(Moves.SHATTERED_PSYCHE__PHYSICAL, Type.PSYCHIC, MoveCategory.PHYSICAL, -1, -1, 1, -1, 0, 7)
.unimplemented(),
.unimplemented()
.ignoresVirtual(),
new AttackMove(Moves.SHATTERED_PSYCHE__SPECIAL, Type.PSYCHIC, MoveCategory.SPECIAL, -1, -1, 1, -1, 0, 7)
.unimplemented(),
.unimplemented()
.ignoresVirtual(),
new AttackMove(Moves.SUBZERO_SLAMMER__PHYSICAL, Type.ICE, MoveCategory.PHYSICAL, -1, -1, 1, -1, 0, 7)
.unimplemented(),
.unimplemented()
.ignoresVirtual(),
new AttackMove(Moves.SUBZERO_SLAMMER__SPECIAL, Type.ICE, MoveCategory.SPECIAL, -1, -1, 1, -1, 0, 7)
.unimplemented(),
.unimplemented()
.ignoresVirtual(),
new AttackMove(Moves.DEVASTATING_DRAKE__PHYSICAL, Type.DRAGON, MoveCategory.PHYSICAL, -1, -1, 1, -1, 0, 7)
.unimplemented(),
.unimplemented()
.ignoresVirtual(),
new AttackMove(Moves.DEVASTATING_DRAKE__SPECIAL, Type.DRAGON, MoveCategory.SPECIAL, -1, -1, 1, -1, 0, 7)
.unimplemented(),
.unimplemented()
.ignoresVirtual(),
new AttackMove(Moves.BLACK_HOLE_ECLIPSE__PHYSICAL, Type.DARK, MoveCategory.PHYSICAL, -1, -1, 1, -1, 0, 7)
.unimplemented(),
.unimplemented()
.ignoresVirtual(),
new AttackMove(Moves.BLACK_HOLE_ECLIPSE__SPECIAL, Type.DARK, MoveCategory.SPECIAL, -1, -1, 1, -1, 0, 7)
.unimplemented(),
.unimplemented()
.ignoresVirtual(),
new AttackMove(Moves.TWINKLE_TACKLE__PHYSICAL, Type.FAIRY, MoveCategory.PHYSICAL, -1, -1, 1, -1, 0, 7)
.unimplemented(),
.unimplemented()
.ignoresVirtual(),
new AttackMove(Moves.TWINKLE_TACKLE__SPECIAL, Type.FAIRY, MoveCategory.SPECIAL, -1, -1, 1, -1, 0, 7)
.unimplemented(),
.unimplemented()
.ignoresVirtual(),
new AttackMove(Moves.CATASTROPIKA, Type.ELECTRIC, MoveCategory.PHYSICAL, 210, -1, 1, -1, 0, 7)
.unimplemented(),
.unimplemented()
.ignoresVirtual(),
/* End Unused */
new SelfStatusMove(Moves.SHORE_UP, Type.GROUND, -1, 5, -1, 0, 7)
.attr(SandHealAttr)
@ -5933,23 +5970,32 @@ export function initMoves() {
/* Unused */
new AttackMove(Moves.SINISTER_ARROW_RAID, Type.GHOST, MoveCategory.PHYSICAL, 180, -1, 1, -1, 0, 7)
.makesContact(false)
.partial(),
.partial()
.ignoresVirtual(),
new AttackMove(Moves.MALICIOUS_MOONSAULT, Type.DARK, MoveCategory.PHYSICAL, 180, -1, 1, -1, 0, 7)
.partial(),
.partial()
.ignoresVirtual(),
new AttackMove(Moves.OCEANIC_OPERETTA, Type.WATER, MoveCategory.SPECIAL, 195, -1, 1, -1, 0, 7)
.partial(),
.partial()
.ignoresVirtual(),
new AttackMove(Moves.GUARDIAN_OF_ALOLA, Type.FAIRY, MoveCategory.SPECIAL, -1, -1, 1, -1, 0, 7)
.unimplemented(),
.unimplemented()
.ignoresVirtual(),
new AttackMove(Moves.SOUL_STEALING_7_STAR_STRIKE, Type.GHOST, MoveCategory.PHYSICAL, 195, -1, 1, -1, 0, 7)
.unimplemented(),
.unimplemented()
.ignoresVirtual(),
new AttackMove(Moves.STOKED_SPARKSURFER, Type.ELECTRIC, MoveCategory.SPECIAL, 175, -1, 1, 100, 0, 7)
.partial(),
.partial()
.ignoresVirtual(),
new AttackMove(Moves.PULVERIZING_PANCAKE, Type.NORMAL, MoveCategory.PHYSICAL, 210, -1, 1, -1, 0, 7)
.partial(),
.partial()
.ignoresVirtual(),
new SelfStatusMove(Moves.EXTREME_EVOBOOST, Type.NORMAL, -1, 1, 100, 0, 7)
.attr(StatChangeAttr, [ BattleStat.ATK, BattleStat.DEF, BattleStat.SPATK, BattleStat.SPDEF, BattleStat.SPD ], 2, true),
.attr(StatChangeAttr, [ BattleStat.ATK, BattleStat.DEF, BattleStat.SPATK, BattleStat.SPDEF, BattleStat.SPD ], 2, true)
.ignoresVirtual(),
new AttackMove(Moves.GENESIS_SUPERNOVA, Type.PSYCHIC, MoveCategory.SPECIAL, 185, -1, 1, -1, 0, 7)
.attr(TerrainChangeAttr, TerrainType.PSYCHIC),
.attr(TerrainChangeAttr, TerrainType.PSYCHIC)
.ignoresVirtual(),
/* End Unused */
new AttackMove(Moves.SHELL_TRAP, Type.FIRE, MoveCategory.SPECIAL, 150, 100, 5, -1, -3, 7)
.target(MoveTarget.ALL_NEAR_ENEMIES)
@ -5987,7 +6033,8 @@ export function initMoves() {
.partial(),
/* Unused */
new AttackMove(Moves.TEN_MILLION_VOLT_THUNDERBOLT, Type.ELECTRIC, MoveCategory.SPECIAL, 195, -1, 1, -1, 0, 7)
.partial(),
.partial()
.ignoresVirtual(),
/* End Unused */
new AttackMove(Moves.MIND_BLOWN, Type.FIRE, MoveCategory.SPECIAL, 150, 100, 5, -1, 0, 7)
.condition(failIfDampCondition)
@ -6003,21 +6050,27 @@ export function initMoves() {
/* Unused */
new AttackMove(Moves.LIGHT_THAT_BURNS_THE_SKY, Type.PSYCHIC, MoveCategory.SPECIAL, 200, -1, 1, -1, 0, 7)
.attr(PhotonGeyserCategoryAttr)
.ignoresAbilities(),
.ignoresAbilities()
.ignoresVirtual(),
new AttackMove(Moves.SEARING_SUNRAZE_SMASH, Type.STEEL, MoveCategory.PHYSICAL, 200, -1, 1, -1, 0, 7)
.ignoresAbilities(),
.ignoresAbilities()
.ignoresVirtual(),
new AttackMove(Moves.MENACING_MOONRAZE_MAELSTROM, Type.GHOST, MoveCategory.SPECIAL, 200, -1, 1, -1, 0, 7)
.ignoresAbilities(),
.ignoresAbilities()
.ignoresVirtual(),
new AttackMove(Moves.LETS_SNUGGLE_FOREVER, Type.FAIRY, MoveCategory.PHYSICAL, 190, -1, 1, -1, 0, 7)
.partial(),
.partial()
.ignoresVirtual(),
new AttackMove(Moves.SPLINTERED_STORMSHARDS, Type.ROCK, MoveCategory.PHYSICAL, 190, -1, 1, -1, 0, 7)
.attr(ClearTerrainAttr)
.makesContact(false),
.makesContact(false)
.ignoresVirtual(),
new AttackMove(Moves.CLANGOROUS_SOULBLAZE, Type.DRAGON, MoveCategory.SPECIAL, 185, -1, 1, 100, 0, 7)
.attr(StatChangeAttr, [ BattleStat.ATK, BattleStat.DEF, BattleStat.SPATK, BattleStat.SPDEF, BattleStat.SPD ], 1, true)
.soundBased()
.target(MoveTarget.ALL_NEAR_ENEMIES)
.partial(),
.partial()
.ignoresVirtual(),
/* End Unused */
new AttackMove(Moves.ZIPPY_ZAP, Type.ELECTRIC, MoveCategory.PHYSICAL, 80, 100, 10, 100, 2, 7)
.attr(CritOnlyAttr),
@ -6054,7 +6107,8 @@ export function initMoves() {
.punchingMove(),
/* Unused */
new SelfStatusMove(Moves.MAX_GUARD, Type.NORMAL, -1, 10, -1, 4, 8)
.attr(ProtectAttr),
.attr(ProtectAttr)
.ignoresVirtual(),
/* End Unused */
new AttackMove(Moves.DYNAMAX_CANNON, Type.DRAGON, MoveCategory.SPECIAL, 100, 100, 5, -1, 0, 8)
.attr(MovePowerMultiplierAttr, (user, target, move) => target.level > 200 ? 2 : 1)
@ -6098,58 +6152,76 @@ export function initMoves() {
/* Unused */
new AttackMove(Moves.MAX_FLARE, Type.FIRE, MoveCategory.PHYSICAL, 10, -1, 10, -1, 0, 8)
.target(MoveTarget.NEAR_ENEMY)
.unimplemented(),
.unimplemented()
.ignoresVirtual(),
new AttackMove(Moves.MAX_FLUTTERBY, Type.BUG, MoveCategory.PHYSICAL, 10, -1, 10, -1, 0, 8)
.target(MoveTarget.NEAR_ENEMY)
.unimplemented(),
.unimplemented()
.ignoresVirtual(),
new AttackMove(Moves.MAX_LIGHTNING, Type.ELECTRIC, MoveCategory.PHYSICAL, 10, -1, 10, -1, 0, 8)
.target(MoveTarget.NEAR_ENEMY)
.unimplemented(),
.unimplemented()
.ignoresVirtual(),
new AttackMove(Moves.MAX_STRIKE, Type.NORMAL, MoveCategory.PHYSICAL, 10, -1, 10, -1, 0, 8)
.target(MoveTarget.NEAR_ENEMY)
.unimplemented(),
.unimplemented()
.ignoresVirtual(),
new AttackMove(Moves.MAX_KNUCKLE, Type.FIGHTING, MoveCategory.PHYSICAL, 10, -1, 10, -1, 0, 8)
.target(MoveTarget.NEAR_ENEMY)
.unimplemented(),
.unimplemented()
.ignoresVirtual(),
new AttackMove(Moves.MAX_PHANTASM, Type.GHOST, MoveCategory.PHYSICAL, 10, -1, 10, -1, 0, 8)
.target(MoveTarget.NEAR_ENEMY)
.unimplemented(),
.unimplemented()
.ignoresVirtual(),
new AttackMove(Moves.MAX_HAILSTORM, Type.ICE, MoveCategory.PHYSICAL, 10, -1, 10, -1, 0, 8)
.target(MoveTarget.NEAR_ENEMY)
.unimplemented(),
.unimplemented()
.ignoresVirtual(),
new AttackMove(Moves.MAX_OOZE, Type.POISON, MoveCategory.PHYSICAL, 10, -1, 10, -1, 0, 8)
.target(MoveTarget.NEAR_ENEMY)
.unimplemented(),
.unimplemented()
.ignoresVirtual(),
new AttackMove(Moves.MAX_GEYSER, Type.WATER, MoveCategory.PHYSICAL, 10, -1, 10, -1, 0, 8)
.target(MoveTarget.NEAR_ENEMY)
.unimplemented(),
.unimplemented()
.ignoresVirtual(),
new AttackMove(Moves.MAX_AIRSTREAM, Type.FLYING, MoveCategory.PHYSICAL, 10, -1, 10, -1, 0, 8)
.target(MoveTarget.NEAR_ENEMY)
.unimplemented(),
.unimplemented()
.ignoresVirtual(),
new AttackMove(Moves.MAX_STARFALL, Type.FAIRY, MoveCategory.PHYSICAL, 10, -1, 10, -1, 0, 8)
.target(MoveTarget.NEAR_ENEMY)
.unimplemented(),
.unimplemented()
.ignoresVirtual(),
new AttackMove(Moves.MAX_WYRMWIND, Type.DRAGON, MoveCategory.PHYSICAL, 10, -1, 10, -1, 0, 8)
.target(MoveTarget.NEAR_ENEMY)
.unimplemented(),
.unimplemented()
.ignoresVirtual(),
new AttackMove(Moves.MAX_MINDSTORM, Type.PSYCHIC, MoveCategory.PHYSICAL, 10, -1, 10, -1, 0, 8)
.target(MoveTarget.NEAR_ENEMY)
.unimplemented(),
.unimplemented()
.ignoresVirtual(),
new AttackMove(Moves.MAX_ROCKFALL, Type.ROCK, MoveCategory.PHYSICAL, 10, -1, 10, -1, 0, 8)
.target(MoveTarget.NEAR_ENEMY)
.unimplemented(),
.unimplemented()
.ignoresVirtual(),
new AttackMove(Moves.MAX_QUAKE, Type.GROUND, MoveCategory.PHYSICAL, 10, -1, 10, -1, 0, 8)
.target(MoveTarget.NEAR_ENEMY)
.unimplemented(),
.unimplemented()
.ignoresVirtual(),
new AttackMove(Moves.MAX_DARKNESS, Type.DARK, MoveCategory.PHYSICAL, 10, -1, 10, -1, 0, 8)
.target(MoveTarget.NEAR_ENEMY)
.unimplemented(),
.unimplemented()
.ignoresVirtual(),
new AttackMove(Moves.MAX_OVERGROWTH, Type.GRASS, MoveCategory.PHYSICAL, 10, -1, 10, -1, 0, 8)
.target(MoveTarget.NEAR_ENEMY)
.unimplemented(),
.unimplemented()
.ignoresVirtual(),
new AttackMove(Moves.MAX_STEELSPIKE, Type.STEEL, MoveCategory.PHYSICAL, 10, -1, 10, -1, 0, 8)
.target(MoveTarget.NEAR_ENEMY)
.unimplemented(),
.unimplemented()
.ignoresVirtual(),
/* End Unused */
new SelfStatusMove(Moves.CLANGOROUS_SOUL, Type.DRAGON, 100, 5, 100, 0, 8)
.attr(CutHpStatBoostAttr, [ BattleStat.ATK, BattleStat.DEF, BattleStat.SPATK, BattleStat.SPDEF, BattleStat.SPD ], 1, 3)
@ -6668,7 +6740,7 @@ export function initMoves() {
new AttackMove(Moves.FICKLE_BEAM, Type.DRAGON, MoveCategory.SPECIAL, 80, 100, 5, 30, 0, 9)
.attr(PreMoveMessageAttr, doublePowerChanceMessageFunc)
.attr(DoublePowerChanceAttr),
new StatusMove(Moves.BURNING_BULWARK, Type.FIRE, -1, 10, 100, 4, 9)
new SelfStatusMove(Moves.BURNING_BULWARK, Type.FIRE, -1, 10, 100, 4, 9)
.attr(ProtectAttr, BattlerTagType.BURNING_BULWARK),
new AttackMove(Moves.THUNDERCLAP, Type.ELECTRIC, MoveCategory.SPECIAL, 70, 100, 5, -1, 1, 9)
.condition((user, target, move) => user.scene.currentBattle.turnCommands[target.getBattlerIndex()].command === Command.FIGHT && !target.turnData.acted && allMoves[user.scene.currentBattle.turnCommands[target.getBattlerIndex()].move.move].category !== MoveCategory.STATUS),
@ -6685,6 +6757,7 @@ export function initMoves() {
.target(MoveTarget.NEAR_ALLY)
.partial(),
new AttackMove(Moves.ALLURING_VOICE, Type.FAIRY, MoveCategory.SPECIAL, 80, 100, 10, -1, 0, 9)
.soundBased()
.partial(),
new AttackMove(Moves.TEMPER_FLARE, Type.FIRE, MoveCategory.PHYSICAL, 75, 100, 10, -1, 0, 9)
.attr(MovePowerMultiplierAttr, (user, target, move) => user.getLastXMoves(2)[1]?.result == MoveResult.MISS || user.getLastXMoves(2)[1]?.result == MoveResult.FAIL ? 2 : 1),

View File

@ -1324,7 +1324,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
if (typeBoost) {
power.value *= typeBoost.boostValue;
if (typeBoost.oneUse) {
this.removeTag(typeBoost.tagType);
source.removeTag(typeBoost.tagType);
}
}
const arenaAttackTypeMultiplier = this.scene.arena.getAttackTypeMultiplier(type, source.isGrounded());
@ -1959,8 +1959,15 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
return true;
}
resetStatus(): void {
/**
* Resets the status of a pokemon
* @param revive whether revive should be cured, defaults to true
*/
resetStatus(revive: boolean = true): void {
const lastStatus = this.status?.effect;
if (!revive && lastStatus === StatusEffect.FAINT) {
return;
}
this.status = undefined;
if (lastStatus === StatusEffect.SLEEP) {
this.setFrameRate(12);
@ -3206,6 +3213,14 @@ export class PokemonMove {
return allMoves[this.moveId];
}
/**
* Sets {@link ppUsed} for this move and ensures the value does not exceed {@link getMovePp}
* @param {number} count Amount of PP to use
*/
usePp(count: number = 1) {
this.ppUsed = Math.min(this.ppUsed + count, this.getMovePp());
}
getMovePp(): integer {
return this.getMove().pp + this.ppUp * Math.max(Math.floor(this.getMove().pp / 5), 1);
}
@ -3217,4 +3232,13 @@ export class PokemonMove {
getName(): string {
return this.getMove().name;
}
/**
* Copies an existing move or creates a valid PokemonMove object from json representing one
* @param {PokemonMove | any} source The data for the move to copy
* @return {PokemonMove} A valid pokemonmove object
*/
static loadMove(source: PokemonMove | any): PokemonMove {
return new PokemonMove(source.moveId, source.ppUsed, source.ppUp, source.virtual);
}
}

View File

@ -147,6 +147,9 @@ export default class Trainer extends Phaser.GameObjects.Container {
const difficultyWaveIndex = this.scene.gameMode.getWaveForDifficulty(waveIndex);
let baseLevel = 1 + difficultyWaveIndex / 2 + Math.pow(difficultyWaveIndex / 25, 2);
if (this.isDouble() && partyTemplate.size < 2)
partyTemplate.size = 2;
for (let i = 0; i < partyTemplate.size; i++) {
let multiplier = 1;

View File

@ -46,7 +46,7 @@ export const battle: SimpleTranslationEntries = {
"runAwayCannotEscape": 'You can\'t escape!',
"escapeVerbSwitch": "auswechseln",
"escapeVerbFlee": "flucht",
"notDisabled": "{{moveName}} ist\nnicht mehr deaktiviert!",
"notDisabled": "{{pokemonName}}'s {{moveName}} ist\nnicht mehr deaktiviert!",
"skipItemQuestion": "Are you sure you want to skip taking an item?",
"eggHatching": "Oh?",
"ivScannerUseQuestion": "Use IV Scanner on {{pokemonName}}?"

View File

@ -46,7 +46,7 @@ export const battle: SimpleTranslationEntries = {
"runAwayCannotEscape": 'You can\'t escape!',
"escapeVerbSwitch": "switching",
"escapeVerbFlee": "fleeing",
"notDisabled": "{{moveName}} is disabled\nno more!",
"notDisabled": "{{pokemonName}}'s {{moveName}} is disabled\nno more!",
"skipItemQuestion": "Are you sure you want to skip taking an item?",
"eggHatching": "Oh?",
"ivScannerUseQuestion": "Use IV Scanner on {{pokemonName}}?"

View File

@ -46,7 +46,7 @@ export const battle: SimpleTranslationEntries = {
"runAwayCannotEscape": "¡No has podido escapar!",
"escapeVerbSwitch": "cambiar",
"escapeVerbFlee": "huir",
"notDisabled": "¡El movimiento {{moveName}}\nya no está anulado!",
"notDisabled": "¡El movimiento {{moveName}} de {{pokemonName}}\nya no está anulado!",
"skipItemQuestion": "¿Estás seguro de que no quieres coger un objeto?",
"eggHatching": "¿Y esto?",
"ivScannerUseQuestion": "¿Quieres usar el Escáner de IVs en {{pokemonName}}?"

View File

@ -46,7 +46,7 @@ export const battle: SimpleTranslationEntries = {
"runAwayCannotEscape": "Fuite impossible !",
"escapeVerbSwitch": "le changement",
"escapeVerbFlee": "la fuite",
"notDisabled": "{{moveName}} nest plus sous entrave !",
"notDisabled": "La capacité {{moveName}}\nde {{pokemonName}} nest plus sous entrave !",
"skipItemQuestion": "Êtes-vous sûr·e de ne pas vouloir prendre dobjet ?",
"eggHatching": "Oh ?",
"ivScannerUseQuestion": "Utiliser le Scanner dIV sur {{pokemonName}} ?"

View File

@ -24,7 +24,7 @@ export const menu: SimpleTranslationEntries = {
"confirmPassword": "Confirmer le MDP",
"registrationAgeWarning": "Vous confirmez en vous inscrivant que vous avez 13 ans ou plus.",
"backToLogin": "Retour",
"failedToLoadSaveData": "Échec du chargement des données. Veuillez recharger la page.\nSi cela continue, veuillez contacter ladministrateur.",
"failedToLoadSaveData": "Échec du chargement des données. Veuillez recharger\nla page. Si cela persiste, contactez ladministrateur.",
"sessionSuccess": "Session chargée avec succès.",
"failedToLoadSession": "Vos données de session nont pas pu être chargées.\nElles pourraient être corrompues.",
"boyOrGirl": "Es-tu un garçon ou une fille ?",

View File

@ -46,7 +46,7 @@ export const battle: SimpleTranslationEntries = {
"runAwayCannotEscape": 'Non puoi fuggire!',
"escapeVerbSwitch": "cambiando",
"escapeVerbFlee": "fuggendo",
"notDisabled": "{{moveName}} non è più\ndisabilitata!",
"notDisabled": "{{pokemonName}}'s {{moveName}} non è più\ndisabilitata!",
"skipItemQuestion": "Sei sicuro di non voler prendere nessun oggetto?",
"eggHatching": "Oh?",
"ivScannerUseQuestion": "Vuoi usare lo scanner di IV su {{pokemonName}}?"

1244
src/locales/zh_CN/ability.ts Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,53 @@
import { SimpleTranslationEntries } from "#app/plugins/i18n";
export const battle: SimpleTranslationEntries = {
"bossAppeared": "{{bossName}} 出现了。",
"trainerAppeared": "{{trainerName}}\n想要和你对战!",
"singleWildAppeared": "一只野生 {{pokemonName}} 出现了。!",
"multiWildAppeared": "野生的 {{pokemonName1}}\n和 {{pokemonName2}} 出现了。!",
"playerComeBack": "回来吧, {{pokemonName}}!",
"trainerComeBack": "{{trainerName}} 收回了 {{pokemonName}}!",
"playerGo": "去吧! {{pokemonName}}!",
"trainerGo": "{{trainerName}} 派出了 {{pokemonName}}!",
"switchQuestion": "要更换\n{{pokemonName}}吗?",
"trainerDefeated": `你击败了\n{{trainerName}}!`,
"pokemonCaught": "{{pokemonName}} 被抓住了!",
"pokemon": "宝可梦",
"sendOutPokemon": "上吧! {{pokemonName}}!",
"hitResultCriticalHit": "击中了要害!",
"hitResultSuperEffective": "效果拔群!",
"hitResultNotVeryEffective": "收效甚微…",
"hitResultNoEffect": "对 {{pokemonName}} 没有效果!!",
"hitResultOneHitKO": "一击必杀!",
"attackFailed": "但是失败了!",
"attackHitsCount": `击中 {{count}} 次!`,
"expGain": "{{pokemonName}} 获得了 {{exp}} 经验值!",
"levelUp": "{{pokemonName}} 升级到 Lv. {{level}}",
"learnMove": "{{pokemonName}} 学会了 {{moveName}}",
"learnMovePrompt": "{{pokemonName}} 想要学习 {{moveName}}。",
"learnMoveLimitReached": "但是,{{pokemonName}} 已经学会了\n四个技能",
"learnMoveReplaceQuestion": "要忘记一个技能并学习 {{moveName}} 吗?",
"learnMoveStopTeaching": "不再尝试学习 {{moveName}}",
"learnMoveNotLearned": "{{pokemonName}} 没有学会 {{moveName}}。",
"learnMoveForgetQuestion": "要忘记哪个技能?",
"learnMoveForgetSuccess": "{{pokemonName}} 忘记了\n如何使用 {{moveName}}。",
"levelCapUp": "等级上限提升到 {{levelCap}}",
"moveNotImplemented": "{{moveName}} 尚未实装,无法选择。",
"moveNoPP": "这个技能的 PP 用完了",
"moveDisabled": "{{moveName}} 被禁用!",
"noPokeballForce": "一股无形的力量阻止了你使用精灵球。",
"noPokeballTrainer": "你不能捕捉其他训练家的宝可梦!",
"noPokeballMulti": "只能在剩下一只宝可梦时才能扔出精灵球!",
"noPokeballStrong": "目标宝可梦太强了,无法捕捉!你需要先削弱它!",
"noEscapeForce": "一股无形的力量阻止你逃跑。",
"noEscapeTrainer": "你不能从训练家战斗中逃跑!",
"noEscapePokemon": "{{pokemonName}} 的 {{moveName}} 阻止了你 {{escapeVerb}}",
"runAwaySuccess": "你成功逃脱了!",
"runAwayCannotEscape": '你无法逃脱!',
"escapeVerbSwitch": "切换",
"escapeVerbFlee": "逃跑",
"notDisabled": "{{moveName}} 不再被禁用!",
"skipItemQuestion": "你确定要跳过拾取道具吗?",
"eggHatching": "咦?",
"ivScannerUseQuestion": "对 {{pokemonName}} 使用个体值扫描仪?"
} as const;

View File

@ -0,0 +1,9 @@
import { SimpleTranslationEntries } from "#app/plugins/i18n";
export const commandUiHandler: SimpleTranslationEntries = {
"fight": "战斗",
"ball": "精灵球",
"pokemon": "宝可梦",
"run": "逃跑",
"actionMessage": "要让\n{{pokemonName}} 做什么?",
} as const;

View File

@ -0,0 +1,28 @@
import { ability } from "./ability";
import { battle } from "./battle";
import { commandUiHandler } from "./command-ui-handler";
import { fightUiHandler } from "./fight-ui-handler";
import { menu } from "./menu";
import { menuUiHandler } from "./menu-ui-handler";
import { move } from "./move";
import { pokeball } from "./pokeball";
import { pokemon } from "./pokemon";
import { pokemonStat } from "./pokemon-stat";
import { starterSelectUiHandler } from "./starter-select-ui-handler";
import { tutorial } from "./tutorial";
export const zhCnConfig = {
ability: ability,
battle: battle,
commandUiHandler: commandUiHandler,
fightUiHandler: fightUiHandler,
menuUiHandler: menuUiHandler,
menu: menu,
move: move,
pokeball: pokeball,
pokemonStat: pokemonStat,
pokemon: pokemon,
starterSelectUiHandler: starterSelectUiHandler,
tutorial: tutorial
}

View File

@ -0,0 +1,6 @@
import { SimpleTranslationEntries } from "#app/plugins/i18n";
export const fightUiHandler: SimpleTranslationEntries = {
"pp": "PP",
"power": "POWER",
} as const;

View File

@ -0,0 +1,23 @@
import { SimpleTranslationEntries } from "#app/plugins/i18n";
export const menuUiHandler: SimpleTranslationEntries = {
"GAME_SETTINGS": '游戏设置',
"ACHIEVEMENTS": "成就",
"STATS": "数据统计",
"VOUCHERS": "兑换券",
"EGG_LIST": "蛋列表",
"EGG_GACHA": "蛋扭蛋",
"MANAGE_DATA": "管理数据",
"COMMUNITY": "社区",
"RETURN_TO_TITLE": "返回标题画面",
"LOG_OUT": "登出",
"slot": "存档位 {{slotNumber}}",
"importSession": "导入存档",
"importSlotSelect": "选择要导入到的存档位。",
"exportSession": "导出存档",
"exportSlotSelect": "选择要导出的存档位。",
"importData": "导入数据",
"exportData": "导出数据",
"cancel": "取消",
"losingProgressionWarning": "你将失去自战斗开始以来的所有进度。是否继续?"
} as const;

46
src/locales/zh_CN/menu.ts Normal file
View File

@ -0,0 +1,46 @@
import { SimpleTranslationEntries } from "#app/plugins/i18n";
/**
* The menu namespace holds most miscellaneous text that isn't directly part of the game's
* contents or directly related to Pokemon data. This includes menu navigation, settings,
* account interactions, descriptive text, etc.
*/
export const menu: SimpleTranslationEntries = {
"cancel": "取消",
"continue": "继续",
"dailyRun": "每日挑战 (Beta)",
"loadGame": "加载游戏",
"newGame": "新游戏",
"selectGameMode": "选择一个游戏模式",
"logInOrCreateAccount": "登录或创建账户以开始游戏。无需邮箱!",
"username": "用户名",
"password": "密码",
"login": "登录",
"register": "注册",
"emptyUsername": "用户名不能为空",
"invalidLoginUsername": "提供的用户名无效",
"invalidRegisterUsername": "用户名只能包含字母、数字或下划线",
"invalidLoginPassword": "提供的密码无效",
"invalidRegisterPassword": "密码必须至少包含 6 个字符",
"usernameAlreadyUsed": "提供的用户名已被使用",
"accountNonExistent": "提供的用户不存在",
"unmatchingPassword": "提供的密码不匹配",
"passwordNotMatchingConfirmPassword": "密码必须与确认密码一致",
"confirmPassword": "确认密码",
"registrationAgeWarning": "注册即表示您确认您已年满 13 岁。",
"backToLogin": "返回登录",
"failedToLoadSaveData": "读取存档数据失败。请重新加载页面。如果问题仍然存在,请联系管理员。",
"sessionSuccess": "会话加载成功。",
"failedToLoadSession": "无法加载您的会话数据。它可能已损坏。",
"boyOrGirl": "你是男孩还是女孩?",
"boy": "男孩",
"girl": "女孩",
"dailyRankings": "每日排名",
"weeklyRankings": "每周排名",
"noRankings": "无排名",
"loading": "加载中…",
"playersOnline": "在线玩家",
"empty": "空",
"yes": "是",
"no": "否",
} as const;

3812
src/locales/zh_CN/move.ts Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,10 @@
import { SimpleTranslationEntries } from "#app/plugins/i18n";
export const pokeball: SimpleTranslationEntries = {
"pokeBall": "精灵球",
"greatBall": "超级球",
"ultraBall": "高级球",
"rogueBall": "肉鸽球",
"masterBall": "大师球",
"luxuryBall": "豪华球",
} as const;

View File

@ -0,0 +1,16 @@
import { SimpleTranslationEntries } from "#app/plugins/i18n";
export const pokemonStat: SimpleTranslationEntries = {
"HP": "最大HP",
"HPshortened": "最大HP",
"ATK": "攻击",
"ATKshortened": "攻击",
"DEF": "防御",
"DEFshortened": "防御",
"SPATK": "特攻",
"SPATKshortened": "特攻",
"SPDEF": "特防",
"SPDEFshortened": "特防",
"SPD": "速度",
"SPDshortened": "速度"
} as const;

1086
src/locales/zh_CN/pokemon.ts Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,32 @@
import { SimpleTranslationEntries } from "#app/plugins/i18n";
/**
* The menu namespace holds most miscellaneous text that isn't directly part of the game's
* contents or directly related to Pokemon data. This includes menu navigation, settings,
* account interactions, descriptive text, etc.
*/
export const starterSelectUiHandler: SimpleTranslationEntries = {
"confirmStartTeam":'使用这些宝可梦开始游戏吗?',
"growthRate": "成长速度:",
"ability": "特性:",
"passive": "被动:",
"nature": "性格:",
"eggMoves": '蛋招式',
"start": "开始",
"addToParty": "加入队伍",
"toggleIVs": '切换个体值',
"manageMoves": '管理招式',
"useCandies": '使用糖果',
"selectMoveSwapOut": "选择要替换的招式。",
"selectMoveSwapWith": "选择要替换成的招式",
"unlockPassive": "解锁被动",
"reduceCost": "降低花费",
"cycleShiny": "R: 切换闪光",
"cycleForm": 'F: 切换形态',
"cycleGender": 'G: 切换性别',
"cycleAbility": 'E: 切换特性',
"cycleNature": 'N: 切换性格',
"cycleVariant": 'V: 切换变种',
"enablePassive": "启用被动",
"disablePassive": "禁用被动"
}

View File

@ -0,0 +1,42 @@
import { SimpleTranslationEntries } from "#app/plugins/i18n";
export const tutorial: SimpleTranslationEntries = {
"intro": `欢迎来到PokéRogue这是一款以战斗为核心的融合了roguelite元素的宝可梦同人游戏。
$本游戏未进行商业化Pokémon或Pokémon使用的版权资产的所有权
$游戏仍在开发中\n如需报告错误使 Discord
$如果游戏运行缓慢`,
"accessMenu": `在等待输入时,按 M 或 Escape 键可访问菜单。\n菜单包含设置和各种功能。`,
"menu": `在此菜单中,您可以访问设置。
$在设置中
$这里还有各种其他功能`,
"starterSelect": `在此页面中,您可以选择您的初始宝可梦。\n这些是您最初的队伍成员。
$每个初始宝可梦都有一个费用\n6 10
$您还可以根据\n您捕获或孵化的变种选择性别
$一个物种的个体值是您捕获或孵化的所有宝可梦中最好的`,
"pokerus": `每天随机 3 个可选的初始宝可梦会有紫色边框。
$如果您看到您拥有的初始宝可梦带有紫色边框\n请尝试将其添加到您的队伍中`,
"statChange": `只要您的宝可梦没有被召回,属性变化就会在战斗中持续存在。
$在训练家战斗之前和进入新的宝可梦群落之前
$您还可以通过按住 C Shift `,
"selectItem": `每次战斗后,您都可以选择 3 个随机物品。\n您只能选择其中一个。
$这些物品包括消耗品
$大多数非消耗品的效果会以各种方式叠加
$某些物品只有在可以使用时才会出现
$您还可以使用转移选项在宝可梦之间转移携带物品
$一旦您获得了携带物品
$您可以用金钱购买消耗品
$请务必在选择随机物品之前购买这些消耗品`,
"eggGacha": `在此页面中,您可以使用您的兑换券兑换\n宝可梦蛋。
$蛋需要孵化
$孵化的宝可梦不会被添加到您的队伍中
$从蛋中孵化的宝可梦通常比\n野生宝可梦具有更好的个体值
$有些宝可梦只能从蛋中获得
$有 3 \n奖励`,
} as const;

View File

@ -955,7 +955,7 @@ export const modifierTypes = {
ENEMY_DAMAGE_BOOSTER: () => new ModifierType('Damage Token', 'Increases damage by 5%', (type, _args) => new Modifiers.EnemyDamageBoosterModifier(type, 5), 'wl_item_drop'),
ENEMY_DAMAGE_REDUCTION: () => new ModifierType('Protection Token', 'Reduces incoming damage by 2.5%', (type, _args) => new Modifiers.EnemyDamageReducerModifier(type, 2.5), 'wl_guard_spec'),
//ENEMY_SUPER_EFFECT_BOOSTER: () => new ModifierType('Type Advantage Token', 'Increases damage of super effective attacks by 30%', (type, _args) => new Modifiers.EnemySuperEffectiveDamageBoosterModifier(type, 30), 'wl_custom_super_effective'),
ENEMY_HEAL: () => new ModifierType('Recovery Token', 'Heals 3% of max HP every turn', (type, _args) => new Modifiers.EnemyTurnHealModifier(type, 3), 'wl_potion'),
ENEMY_HEAL: () => new ModifierType('Recovery Token', 'Heals 2% of max HP every turn', (type, _args) => new Modifiers.EnemyTurnHealModifier(type, 2), 'wl_potion'),
ENEMY_ATTACK_POISON_CHANCE: () => new EnemyAttackStatusEffectChanceModifierType('Poison Token', 10, StatusEffect.POISON, 'wl_antidote'),
ENEMY_ATTACK_PARALYZE_CHANCE: () => new EnemyAttackStatusEffectChanceModifierType('Paralyze Token', 10, StatusEffect.PARALYSIS, 'wl_paralyze_heal'),
ENEMY_ATTACK_SLEEP_CHANCE: () => new EnemyAttackStatusEffectChanceModifierType('Sleep Token', 10, StatusEffect.SLEEP, 'wl_awakening'),

View File

@ -2004,7 +2004,7 @@ export class EnemyTurnHealModifier extends EnemyPersistentModifier {
super(type, stackCount);
// Hardcode temporarily
this.healPercent = 3;
this.healPercent = 2;
}
match(modifier: Modifier): boolean {
@ -2033,7 +2033,7 @@ export class EnemyTurnHealModifier extends EnemyPersistentModifier {
}
getMaxStackCount(scene: BattleScene): integer {
return 10;
return 15;
}
}

View File

@ -23,7 +23,7 @@ import { FusePokemonModifierType, ModifierPoolType, ModifierType, ModifierTypeFu
import SoundFade from "phaser3-rex-plugins/plugins/soundfade";
import { BattlerTagLapseType, EncoreTag, HideSpriteTag as HiddenTag, ProtectedTag, TrappedTag } from "./data/battler-tags";
import { BattlerTagType } from "./data/enums/battler-tag-type";
import { getPokemonMessage } from "./messages";
import { getPokemonMessage, getPokemonPrefix } from "./messages";
import { Starter } from "./ui/starter-select-ui-handler";
import { Gender } from "./data/gender";
import { Weather, WeatherType, getRandomWeatherType, getTerrainBlockMessage, getWeatherDamageMessage, getWeatherLapseMessage } from "./data/weather";
@ -2046,7 +2046,7 @@ export class TurnEndPhase extends FieldPhase {
pokemon.lapseTags(BattlerTagLapseType.TURN_END);
if (pokemon.summonData.disabledMove && !--pokemon.summonData.disabledTurns) {
this.scene.pushPhase(new MessagePhase(this.scene, i18next.t('battle:notDisabled', { moveName: allMoves[pokemon.summonData.disabledMove].name })));
this.scene.pushPhase(new MessagePhase(this.scene, i18next.t('battle:notDisabled', { pokemonName: `${getPokemonPrefix(pokemon)}${pokemon.name}`, moveName: allMoves[pokemon.summonData.disabledMove].name })));
pokemon.summonData.disabledMove = Moves.NONE;
}
@ -2158,6 +2158,7 @@ export class MovePhase extends BattlePhase {
public targets: BattlerIndex[];
protected followUp: boolean;
protected ignorePp: boolean;
protected failed: boolean;
protected cancelled: boolean;
constructor(scene: BattleScene, pokemon: Pokemon, targets: BattlerIndex[], move: PokemonMove, followUp?: boolean, ignorePp?: boolean) {
@ -2168,6 +2169,7 @@ export class MovePhase extends BattlePhase {
this.move = move;
this.followUp = !!followUp;
this.ignorePp = !!ignorePp;
this.failed = false;
this.cancelled = false;
}
@ -2175,6 +2177,12 @@ export class MovePhase extends BattlePhase {
return this.pokemon.isActive(true) && this.move.isUsable(this.pokemon, this.ignorePp) && !!this.targets.length;
}
/**Signifies the current move should fail but still use PP */
fail(): void {
this.failed = true;
}
/**Signifies the current move should cancel and retain PP */
cancel(): void {
this.cancelled = true;
}
@ -2214,7 +2222,7 @@ export class MovePhase extends BattlePhase {
this.targets[0] = attacker.getBattlerIndex();
}
if (this.targets[0] === BattlerIndex.ATTACKER) {
this.cancel();
this.fail(); // Marks the move as failed for later in doMove
this.showMoveText();
this.showFailedText();
}
@ -2234,11 +2242,24 @@ export class MovePhase extends BattlePhase {
this.pokemon.turnData.acted = true; // Record that the move was attempted, even if it fails
this.pokemon.lapseTags(BattlerTagLapseType.PRE_MOVE);
let ppUsed = 1;
// Filter all opponents to include only those this move is targeting
const targetedOpponents = this.pokemon.getOpponents().filter(o => this.targets.includes(o.getBattlerIndex()));
for (let opponent of targetedOpponents) {
if (this.move.ppUsed + ppUsed >= this.move.getMovePp()) // If we're already at max PP usage, stop checking
break;
if (opponent.hasAbilityWithAttr(IncreasePpAbAttr)) // Accounting for abilities like Pressure
ppUsed++;
}
if (!this.followUp && this.canMove() && !this.cancelled) {
this.pokemon.lapseTags(BattlerTagLapseType.MOVE);
}
if (this.cancelled) {
if (this.cancelled || this.failed) {
if (this.failed)
this.move.usePp(ppUsed); // Only use PP if the move failed
this.pokemon.pushMoveHistory({ move: Moves.NONE, result: MoveResult.FAIL });
return this.end();
}
@ -2253,23 +2274,12 @@ export class MovePhase extends BattlePhase {
if ((moveQueue.length && moveQueue[0].move === Moves.NONE) || !targets.length) {
moveQueue.shift();
this.cancel();
}
if (this.cancelled) {
this.pokemon.pushMoveHistory({ move: Moves.NONE, result: MoveResult.FAIL });
return this.end();
}
if (!moveQueue.length || !moveQueue.shift().ignorePP) {
this.move.ppUsed++;
const targetedOpponents = this.pokemon.getOpponents().filter(o => this.targets.includes(o.getBattlerIndex()));
for (let opponent of targetedOpponents) {
if (this.move.ppUsed === this.move.getMove().pp)
break;
if (opponent.hasAbilityWithAttr(IncreasePpAbAttr))
this.move.ppUsed = Math.min(this.move.ppUsed + 1, this.move.getMovePp());
}
}
if (!moveQueue.length || !moveQueue.shift().ignorePP) // using .shift here clears out two turn moves once they've been used
this.move.usePp(ppUsed);
if (!allMoves[this.move.moveId].getAttrs(CopyMoveAttr).length)
this.scene.currentBattle.lastMove = this.move.moveId;

View File

@ -6,6 +6,7 @@ import { enConfig } from '#app/locales/en/config.js';
import { esConfig } from '#app/locales/es/config.js';
import { frConfig } from '#app/locales/fr/config.js';
import { itConfig } from '#app/locales/it/config.js';
import { zhCnConfig } from '#app/locales/zh_CN/config.js';
export interface SimpleTranslationEntries {
[key: string]: string
@ -58,7 +59,7 @@ export function initI18n(): void {
i18next.use(LanguageDetector).init({
lng: lang,
fallbackLng: 'en',
supportedLngs: ['en', 'es', 'fr', 'it', 'de'],
supportedLngs: ['en', 'es', 'fr', 'it', 'de', 'zh_CN'],
debug: true,
interpolation: {
escapeValue: false,
@ -78,6 +79,9 @@ export function initI18n(): void {
},
de: {
...deConfig
},
zh_CN: {
...zhCnConfig
}
},
});

View File

@ -569,7 +569,7 @@ export class GameData {
resolve(true);
});
} else {
localStorage.setItem('sessionData', btoa(JSON.stringify(sessionData)));
localStorage.setItem(`sessionData${scene.sessionSlotId ? scene.sessionSlotId : ''}`, btoa(JSON.stringify(sessionData)));
console.debug('Session data saved');

View File

@ -11,6 +11,7 @@ import Pokemon, { EnemyPokemon, PokemonMove, PokemonSummonData } from "../field/
import { TrainerSlot } from "../data/trainer-config";
import { Moves } from "../data/enums/moves";
import { Variant } from "#app/data/variant";
import { loadBattlerTag } from '../data/battler-tags';
export default class PokemonData {
public id: integer;
@ -112,9 +113,18 @@ export default class PokemonData {
if (!forHistory && source.summonData) {
this.summonData.battleStats = source.summonData.battleStats;
this.summonData.moveQueue = source.summonData.moveQueue;
this.summonData.tags = []; // TODO
this.summonData.moveset = source.summonData.moveset;
this.summonData.disabledMove = source.summonData.disabledMove;
this.summonData.disabledTurns = source.summonData.disabledTurns;
this.summonData.abilitySuppressed = source.summonData.abilitySuppressed;
this.summonData.ability = source.summonData.ability;
this.summonData.moveset = source.summonData.moveset?.map(m => PokemonMove.loadMove(m));
this.summonData.types = source.summonData.types;
if (source.summonData.tags)
this.summonData.tags = source.summonData.tags?.map(t => loadBattlerTag(t));
else
this.summonData.tags = [];
}
}
}

View File

@ -183,21 +183,25 @@ export function setSetting(scene: BattleScene, setting: Setting, value: integer)
handler: () => changeLocaleHandler('en')
},
{
label: 'Spanish',
label: 'Español',
handler: () => changeLocaleHandler('es')
},
{
label: 'Italian',
label: 'Italiano',
handler: () => changeLocaleHandler('it')
},
{
label: 'French',
label: 'Français',
handler: () => changeLocaleHandler('fr')
},
{
label: 'German',
label: 'Deutsch',
handler: () => changeLocaleHandler('de')
},
{
label: '简体中文',
handler: () => changeLocaleHandler('zh_CN')
},
{
label: 'Cancel',
handler: () => cancelHandler()

View File

@ -417,7 +417,10 @@ export default class BattleInfo extends Phaser.GameObjects.Container {
if (nameUpdated || teraTypeUpdated) {
this.splicedIcon.setVisible(!!pokemon.fusionSpecies);
this.teraIcon.setPositionRelative(this.nameText, this.nameText.displayWidth + this.genderText.displayWidth + 1, 2);
this.splicedIcon.setPositionRelative(this.nameText, this.nameText.displayWidth + this.genderText.displayWidth + 1 + (this.teraIcon.visible ? this.teraIcon.displayWidth + 1 : 0), 1.5);
this.shinyIcon.setPositionRelative(this.nameText, this.nameText.displayWidth + this.genderText.displayWidth + 1 + (this.teraIcon.visible ? this.teraIcon.displayWidth + 1 : 0) + (this.splicedIcon.visible ? this.splicedIcon.displayWidth + 1 : 0), 2.5);
}
if (this.lastStatus !== (pokemon.status?.effect || StatusEffect.NONE)) {

View File

@ -414,7 +414,7 @@ export default class StarterSelectUiHandler extends MessageUiHandler {
this.classicWinIcons = new Array(81).fill(null).map((_, i) => {
const x = (i % 9) * 18;
const y = Math.floor(i / 9) * 18;
const ret = this.scene.add.image(x + 152, y + 16, 'champion_ribbon');
const ret = this.scene.add.image(x + 153, y + 21, 'champion_ribbon');
ret.setOrigin(0, 0);
ret.setScale(0.5);
ret.setVisible(false);
@ -462,7 +462,7 @@ export default class StarterSelectUiHandler extends MessageUiHandler {
this.pokemonCandyDarknessOverlay.setScale(0.5);
this.pokemonCandyDarknessOverlay.setOrigin(0, 0);
this.pokemonCandyDarknessOverlay.setTint(0x000000);
this.pokemonCandyDarknessOverlay.setAlpha(0.5);
this.pokemonCandyDarknessOverlay.setAlpha(0.50);
this.pokemonCandyDarknessOverlay.setInteractive(new Phaser.Geom.Rectangle(0, 0, 16, 16), Phaser.Geom.Rectangle.Contains);
this.starterSelectContainer.add(this.pokemonCandyDarknessOverlay);
@ -1098,7 +1098,7 @@ export default class StarterSelectUiHandler extends MessageUiHandler {
// starterMoveData doesn't have base form moves or is using the single form format
if (!this.scene.gameData.starterData[speciesId].moveset || Array.isArray(this.scene.gameData.starterData[speciesId].moveset))
this.scene.gameData.starterData[speciesId].moveset = { [props.formIndex]: this.starterMoveset.slice(0) as StarterMoveset };
const starterMoveData = this.scene.gameData.starterData[speciesId].moveset[props.formIndex];
const starterMoveData = this.scene.gameData.starterData[speciesId].moveset;
// starterMoveData doesn't have active form moves
if (!starterMoveData.hasOwnProperty(props.formIndex))
@ -1332,7 +1332,6 @@ export default class StarterSelectUiHandler extends MessageUiHandler {
}
this.pokemonCandyDarknessOverlay.setCrop(0,0,16, candyCropY);
this.pokemonCandyDarknessOverlay.setCrop(0,0,16, candyCropY);
}
this.iconAnimHandler.addOrUpdate(this.starterSelectGenIconContainers[species.generation - 1].getAt(this.genSpecies[species.generation - 1].indexOf(species)) as Phaser.GameObjects.Sprite, PokemonIconAnimMode.PASSIVE);

View File

@ -50,6 +50,8 @@ export default class SummaryUiHandler extends UiHandler {
private candyShadow: Phaser.GameObjects.Sprite;
private candyIcon: Phaser.GameObjects.Sprite;
private candyOverlay: Phaser.GameObjects.Sprite;
private candyCountText: Phaser.GameObjects.Text;
private championRibbon: Phaser.GameObjects.Image;
private statusContainer: Phaser.GameObjects.Container;
private status: Phaser.GameObjects.Image;
private summaryPageContainer: Phaser.GameObjects.Container;
@ -142,12 +144,6 @@ 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);
@ -156,6 +152,24 @@ export default class SummaryUiHandler extends UiHandler {
this.candyOverlay.setScale(0.8);
this.summaryContainer.add(this.candyOverlay);
this.candyShadow = this.scene.add.sprite(13, -140, 'candy');
this.candyShadow.setTint(0x000000);
this.candyShadow.setAlpha(0.50);
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.candyCountText = addTextObject(this.scene, 20, -146, 'x0', TextStyle.WINDOW_ALT, { fontSize: '76px' });
this.candyCountText.setOrigin(0, 0);
this.summaryContainer.add(this.candyCountText);
this.championRibbon = this.scene.add.image(88, -146, 'champion_ribbon');
this.championRibbon.setOrigin(0, 0);
//this.championRibbon.setScale(0.8);
this.championRibbon.setScale(1.25);
this.summaryContainer.add(this.championRibbon);
this.championRibbon.setVisible(false);
this.levelText = addTextObject(this.scene, 36, -17, '', TextStyle.SUMMARY_ALT);
this.levelText.setOrigin(0, 1);
this.summaryContainer.add(this.levelText);
@ -275,6 +289,11 @@ export default class SummaryUiHandler extends UiHandler {
this.splicedIcon.on('pointerout', () => (this.scene as BattleScene).ui.hideTooltip());
}
if(this.scene.gameData.starterData[this.pokemon.species.getRootSpeciesId()].classicWinCount > 0 && this.scene.gameData.starterData[this.pokemon.species.getRootSpeciesId(true)].classicWinCount > 0)
this.championRibbon.setVisible(true);
else
this.championRibbon.setVisible(false);
var currentFriendship = this.scene.gameData.starterData[this.pokemon.species.getRootSpeciesId()].friendship;
if (!currentFriendship || currentFriendship === undefined)
currentFriendship = 0;
@ -287,8 +306,9 @@ export default class SummaryUiHandler extends UiHandler {
this.candyShadow.on('pointerout', () => (this.scene as BattleScene).ui.hideTooltip());
}
this.candyIcon.setCrop(0,candyCropY,16, 16);
this.candyOverlay.setCrop(0,candyCropY,16, 16);
this.candyCountText.setText(`x${this.scene.gameData.starterData[this.pokemon.species.getRootSpeciesId()].candyCount}`);
this.candyShadow.setCrop(0,0,16, candyCropY);
const doubleShiny = isFusion && this.pokemon.shiny && this.pokemon.fusionShiny;
const baseVariant = !doubleShiny ? this.pokemon.getVariant() : this.pokemon.variant;

View File

@ -84,7 +84,7 @@ export default class TitleUiHandler extends OptionSelectUiHandler {
this.updateTitleStats();
this.titleStatsTimer = setInterval(() => this.updateTitleStats(), 30000);
this.titleStatsTimer = setInterval(() => this.updateTitleStats(), 60000);
this.scene.tweens.add({
targets: [ this.titleContainer, ui.getMessageHandler().bg ],

View File

@ -220,7 +220,7 @@ export function executeIf<T>(condition: boolean, promiseFunc: () => Promise<T>):
}
export const sessionIdKey = 'pokerogue_sessionId';
export const isLocal = window.location.hostname === 'localhost';
export const isLocal = window.location.hostname === 'localhost' || window.location.hostname === '';
export const serverUrl = isLocal ? 'http://localhost:8001' : '';
export const apiUrl = isLocal ? serverUrl : 'https://api.pokerogue.net';
export const fallbackApiUrl = isLocal ? serverUrl : 'api';