Merge branch 'main' into stakeout
11
.github/workflows/deploy.yml
vendored
@ -31,3 +31,14 @@ jobs:
|
||||
run: |
|
||||
rsync --del --no-times --checksum -vrm dist/* ${{ secrets.SSH_USER }}@${{ secrets.SSH_HOST }}:${{ secrets.DESTINATION_DIR }}
|
||||
ssh -t ${{ secrets.SSH_USER }}@${{ secrets.SSH_HOST }} "~/prmanifest --inpath ${{ secrets.DESTINATION_DIR }} --outpath ${{ secrets.DESTINATION_DIR }}/manifest.json"
|
||||
- name: Purge Cloudflare Cache
|
||||
if: github.event_name == 'push' && github.ref_name == github.event.repository.default_branch
|
||||
id: purge-cache
|
||||
uses: NathanVaughn/actions-cloudflare-purge@v3.1.0
|
||||
with:
|
||||
cf_auth: ${{ secrets.CLOUDFLARE_API_TOKEN }}
|
||||
cf_zone: ${{ secrets.CLOUDFLARE_ZONE_ID }}
|
||||
files: |
|
||||
https://pokerogue.net/
|
||||
https://pokerogue.net/index.html
|
||||
https://pokerogue.net/manifest.json
|
11073
public/images/items.json
Before Width: | Height: | Size: 46 KiB After Width: | Height: | Size: 48 KiB |
BIN
public/images/items/hard_meteorite.png
Normal file
After Width: | Height: | Size: 363 B |
Before Width: | Height: | Size: 411 B After Width: | Height: | Size: 411 B |
BIN
public/images/items/sharp_meteorite.png
Normal file
After Width: | Height: | Size: 318 B |
BIN
public/images/items/smooth_meteorite.png
Normal file
After Width: | Height: | Size: 322 B |
Before Width: | Height: | Size: 9.1 KiB After Width: | Height: | Size: 15 KiB |
Before Width: | Height: | Size: 3.2 KiB After Width: | Height: | Size: 4.6 KiB |
Before Width: | Height: | Size: 3.2 KiB After Width: | Height: | Size: 4.4 KiB |
Before Width: | Height: | Size: 9.1 KiB After Width: | Height: | Size: 15 KiB |
Before Width: | Height: | Size: 3.2 KiB After Width: | Height: | Size: 4.4 KiB |
Before Width: | Height: | Size: 3.2 KiB After Width: | Height: | Size: 4.4 KiB |
@ -1418,7 +1418,7 @@ export default class BattleScene extends SceneBase {
|
||||
|
||||
playBgm(bgmName?: string, fadeOut?: boolean): void {
|
||||
if (bgmName === undefined)
|
||||
bgmName = this.currentBattle.getBgmOverride(this) || this.arena.bgm;
|
||||
bgmName = this.currentBattle?.getBgmOverride(this) || this.arena?.bgm;
|
||||
if (this.bgm && bgmName === this.bgm.key) {
|
||||
if (!this.bgm.isPlaying) {
|
||||
this.bgm.play({
|
||||
|
@ -869,6 +869,13 @@ export class MoveTypeChangePowerMultiplierAbAttr extends VariableMoveTypeAbAttr
|
||||
}
|
||||
}
|
||||
|
||||
export class FieldPreventExplosiveMovesAbAttr extends AbAttr {
|
||||
apply(pokemon: Pokemon, passive: boolean, cancelled: Utils.BooleanHolder, args: any[]): boolean | Promise<boolean> {
|
||||
cancelled.value = true;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
export class MoveTypeChangeAttr extends PreAttackAbAttr {
|
||||
private newType: Type;
|
||||
private powerMultiplier: number;
|
||||
@ -2115,6 +2122,11 @@ export class PostFaintContactDamageAbAttr extends PostFaintAbAttr {
|
||||
|
||||
applyPostFaint(pokemon: Pokemon, passive: boolean, attacker: Pokemon, move: PokemonMove, hitResult: HitResult, args: any[]): boolean {
|
||||
if (move.getMove().checkFlag(MoveFlags.MAKES_CONTACT, attacker, pokemon)) {
|
||||
const cancelled = new Utils.BooleanHolder(false);
|
||||
pokemon.scene.getField(true).map(p=>applyAbAttrs(FieldPreventExplosiveMovesAbAttr, p, cancelled))
|
||||
if (cancelled) {
|
||||
return false;
|
||||
}
|
||||
attacker.damageAndUpdate(Math.ceil(attacker.getMaxHp() * (1 / this.damageRatio)), HitResult.OTHER);
|
||||
return true;
|
||||
}
|
||||
@ -2526,8 +2538,8 @@ export function initAbilities() {
|
||||
.attr(BlockOneHitKOAbAttr)
|
||||
.ignorable(),
|
||||
new Ability(Abilities.DAMP, 3)
|
||||
.ignorable()
|
||||
.unimplemented(),
|
||||
.attr(FieldPreventExplosiveMovesAbAttr)
|
||||
.ignorable(),
|
||||
new Ability(Abilities.LIMBER, 3)
|
||||
.attr(StatusEffectImmunityAbAttr, StatusEffect.PARALYSIS)
|
||||
.ignorable(),
|
||||
@ -2918,7 +2930,6 @@ export function initAbilities() {
|
||||
.unimplemented(),
|
||||
new Ability(Abilities.ANALYTIC, 5)
|
||||
.attr(AnalyticAbAttr),
|
||||
//.attr(MovePowerBoostAbAttr, (user, target, move) => !!target.getLastXMoves(1).find(m => m.turn === target.scene.currentBattle.turn) || user.scene.currentBattle.turnCommands[target.getBattlerIndex()].command !== Command.FIGHT, 1.3),
|
||||
new Ability(Abilities.ILLUSION, 5)
|
||||
.attr(UncopiableAbilityAbAttr)
|
||||
.attr(UnswappableAbilityAbAttr)
|
||||
|
@ -12,7 +12,7 @@ import * as Utils from "../utils";
|
||||
import { WeatherType } from "./weather";
|
||||
import { ArenaTagSide, ArenaTrapTag } from "./arena-tag";
|
||||
import { ArenaTagType } from "./enums/arena-tag-type";
|
||||
import { UnswappableAbilityAbAttr, UncopiableAbilityAbAttr, UnsuppressableAbilityAbAttr, NoTransformAbilityAbAttr, BlockRecoilDamageAttr, BlockOneHitKOAbAttr, IgnoreContactAbAttr, MaxMultiHitAbAttr, applyAbAttrs, BlockNonDirectDamageAbAttr, applyPreSwitchOutAbAttrs, PreSwitchOutAbAttr, applyPostDefendAbAttrs, PostDefendContactApplyStatusEffectAbAttr, MoveAbilityBypassAbAttr, ReverseDrainAbAttr } from "./ability";
|
||||
import { UnswappableAbilityAbAttr, UncopiableAbilityAbAttr, UnsuppressableAbilityAbAttr, NoTransformAbilityAbAttr, BlockRecoilDamageAttr, BlockOneHitKOAbAttr, IgnoreContactAbAttr, MaxMultiHitAbAttr, applyAbAttrs, BlockNonDirectDamageAbAttr, applyPreSwitchOutAbAttrs, PreSwitchOutAbAttr, applyPostDefendAbAttrs, PostDefendContactApplyStatusEffectAbAttr, MoveAbilityBypassAbAttr, ReverseDrainAbAttr, FieldPreventExplosiveMovesAbAttr } from "./ability";
|
||||
import { Abilities } from "./enums/abilities";
|
||||
import { allAbilities } from './ability';
|
||||
import { PokemonHeldItemModifier } from "../modifier/modifier";
|
||||
@ -725,6 +725,40 @@ export class SacrificialAttr extends MoveEffectAttr {
|
||||
}
|
||||
}
|
||||
|
||||
export class HalfSacrificialAttr extends MoveEffectAttr {
|
||||
constructor() {
|
||||
super(true, MoveEffectTrigger.PRE_APPLY);
|
||||
}
|
||||
|
||||
apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): boolean {
|
||||
if (!super.apply(user, target, move, args))
|
||||
return false;
|
||||
|
||||
const cancelled = new Utils.BooleanHolder(false);
|
||||
applyAbAttrs(BlockNonDirectDamageAbAttr, user, cancelled);
|
||||
if (!cancelled){
|
||||
user.damageAndUpdate(Math.ceil(user.getMaxHp()/2), HitResult.OTHER, false, true, true);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
getUserBenefitScore(user: Pokemon, target: Pokemon, move: Move): integer {
|
||||
if (user.isBoss())
|
||||
return -10;
|
||||
return Math.ceil(((1 - user.getHpRatio()/2) * 10 - 10) * (target.getAttackTypeEffectiveness(move.type) - 0.5));
|
||||
}
|
||||
}
|
||||
|
||||
export class ExplosiveAttr extends MoveEffectAttr {
|
||||
getCondition(): MoveCondition | MoveConditionFunc {
|
||||
return (user, target, move) =>{
|
||||
const cancelled = new Utils.BooleanHolder(false);
|
||||
user.scene.getField(true).map(p=>applyAbAttrs(FieldPreventExplosiveMovesAbAttr, p, cancelled));
|
||||
return !cancelled.value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export enum MultiHitType {
|
||||
_2,
|
||||
_2_TO_5,
|
||||
@ -2838,10 +2872,8 @@ export class ForceSwitchOutAttr extends MoveEffectAttr {
|
||||
if (switchOutTarget.hp) {
|
||||
applyPreSwitchOutAbAttrs(PreSwitchOutAbAttr, switchOutTarget);
|
||||
(switchOutTarget as PlayerPokemon).switchOut(this.batonPass, true).then(() => resolve(true));
|
||||
}
|
||||
else {
|
||||
} else
|
||||
resolve(false);
|
||||
}
|
||||
return;
|
||||
}
|
||||
else if (user.scene.currentBattle.battleType) {
|
||||
@ -4012,6 +4044,7 @@ export function initMoves() {
|
||||
.attr(CopyMoveAttr)
|
||||
.ignoresVirtual(),
|
||||
new AttackMove(Moves.SELF_DESTRUCT, Type.NORMAL, MoveCategory.PHYSICAL, 200, 100, 5, -1, 0, 1)
|
||||
.attr(ExplosiveAttr)
|
||||
.attr(SacrificialAttr)
|
||||
.makesContact(false)
|
||||
.target(MoveTarget.ALL_NEAR_OTHERS),
|
||||
@ -4102,6 +4135,7 @@ export function initMoves() {
|
||||
new AttackMove(Moves.CRABHAMMER, Type.WATER, MoveCategory.PHYSICAL, 100, 90, 10, -1, 0, 1)
|
||||
.attr(HighCritAttr),
|
||||
new AttackMove(Moves.EXPLOSION, Type.NORMAL, MoveCategory.PHYSICAL, 250, 100, 5, -1, 0, 1)
|
||||
.attr(ExplosiveAttr)
|
||||
.attr(SacrificialAttr)
|
||||
.makesContact(false)
|
||||
.target(MoveTarget.ALL_NEAR_OTHERS),
|
||||
@ -5634,7 +5668,8 @@ export function initMoves() {
|
||||
.partial(),
|
||||
/* End Unused */
|
||||
new AttackMove(Moves.MIND_BLOWN, Type.FIRE, MoveCategory.SPECIAL, 150, 100, 5, -1, 0, 7)
|
||||
.attr(RecoilAttr, true, 0.5)
|
||||
.attr(ExplosiveAttr)
|
||||
.attr(HalfSacrificialAttr)
|
||||
.target(MoveTarget.ALL_NEAR_OTHERS),
|
||||
new AttackMove(Moves.PLASMA_FISTS, Type.ELECTRIC, MoveCategory.PHYSICAL, 100, 100, 15, -1, 0, 7)
|
||||
.punchingMove()
|
||||
@ -5849,7 +5884,7 @@ export function initMoves() {
|
||||
new AttackMove(Moves.ETERNABEAM, Type.DRAGON, MoveCategory.SPECIAL, 160, 90, 5, -1, 0, 8)
|
||||
.attr(RechargeAttr),
|
||||
new AttackMove(Moves.STEEL_BEAM, Type.STEEL, MoveCategory.SPECIAL, 140, 95, 5, -1, 0, 8)
|
||||
.attr(RecoilAttr, true, 0.5),
|
||||
.attr(HalfSacrificialAttr),
|
||||
new AttackMove(Moves.EXPANDING_FORCE, Type.PSYCHIC, MoveCategory.SPECIAL, 80, 100, 10, -1, 0, 8)
|
||||
.partial(),
|
||||
new AttackMove(Moves.STEEL_ROLLER, Type.STEEL, MoveCategory.PHYSICAL, 130, 100, 5, -1, 0, 8)
|
||||
@ -5870,8 +5905,10 @@ export function initMoves() {
|
||||
.attr(StatusEffectAttr, StatusEffect.POISON)
|
||||
.partial(),
|
||||
new AttackMove(Moves.MISTY_EXPLOSION, Type.FAIRY, MoveCategory.SPECIAL, 100, 100, 5, -1, 0, 8)
|
||||
.attr(ExplosiveAttr)
|
||||
.attr(SacrificialAttr)
|
||||
.target(MoveTarget.ALL_NEAR_OTHERS)
|
||||
.partial(),
|
||||
.attr(MovePowerMultiplierAttr, (user, target, move) => user.scene.arena.getTerrainType() === TerrainType.MISTY && user.isGrounded() ? 1.5 : 1),
|
||||
new AttackMove(Moves.GRASSY_GLIDE, Type.GRASS, MoveCategory.PHYSICAL, 55, 100, 20, -1, 0, 8)
|
||||
.partial(),
|
||||
new AttackMove(Moves.RISING_VOLTAGE, Type.ELECTRIC, MoveCategory.SPECIAL, 70, 100, 20, -1, 0, 8)
|
||||
|
@ -62,6 +62,9 @@ export enum FormChangeItem {
|
||||
|
||||
BLUE_ORB = 50,
|
||||
RED_ORB,
|
||||
SHARP_METEORITE,
|
||||
HARD_METEORITE,
|
||||
SMOOTH_METEORITE,
|
||||
ADAMANT_CRYSTAL,
|
||||
LUSTROUS_ORB,
|
||||
GRISEOUS_CORE,
|
||||
@ -472,6 +475,11 @@ export const pokemonFormChanges: PokemonFormChanges = {
|
||||
[Species.RAYQUAZA]: [
|
||||
new SpeciesFormChange(Species.RAYQUAZA, '', SpeciesFormKey.MEGA, new SpeciesFormChangeCompoundTrigger(new SpeciesFormChangeItemTrigger(FormChangeItem.RAYQUAZITE), new SpeciesFormChangeMoveLearnedTrigger(Moves.DRAGON_ASCENT)))
|
||||
],
|
||||
[Species.DEOXYS]: [
|
||||
new SpeciesFormChange(Species.DEOXYS, 'normal', 'attack', new SpeciesFormChangeItemTrigger(FormChangeItem.SHARP_METEORITE)),
|
||||
new SpeciesFormChange(Species.DEOXYS, 'normal', 'defense', new SpeciesFormChangeItemTrigger(FormChangeItem.HARD_METEORITE)),
|
||||
new SpeciesFormChange(Species.DEOXYS, 'normal', 'speed', new SpeciesFormChangeItemTrigger(FormChangeItem.SMOOTH_METEORITE))
|
||||
],
|
||||
[Species.LOPUNNY]: [
|
||||
new SpeciesFormChange(Species.LOPUNNY, '', SpeciesFormKey.MEGA, new SpeciesFormChangeItemTrigger(FormChangeItem.LOPUNNITE))
|
||||
],
|
||||
|
@ -18359,6 +18359,88 @@ export const pokemonFormLevelMoves: PokemonSpeciesFormLevelMoves = {
|
||||
[ 50, Moves.BUG_BUZZ ],
|
||||
],
|
||||
},
|
||||
[Species.ROTOM]: {
|
||||
1: [
|
||||
[ 0, Moves.OVERHEAT ],
|
||||
[ 1, Moves.DOUBLE_TEAM ],
|
||||
[ 1, Moves.ASTONISH ],
|
||||
[ 5, Moves.THUNDER_SHOCK ],
|
||||
[ 10, Moves.CONFUSE_RAY ],
|
||||
[ 15, Moves.CHARGE ],
|
||||
[ 20, Moves.ELECTRO_BALL ],
|
||||
[ 25, Moves.THUNDER_WAVE ],
|
||||
[ 30, Moves.SHOCK_WAVE ],
|
||||
[ 35, Moves.HEX ],
|
||||
[ 40, Moves.SUBSTITUTE ],
|
||||
[ 45, Moves.TRICK ],
|
||||
[ 50, Moves.DISCHARGE ],
|
||||
[ 55, Moves.UPROAR ],
|
||||
],
|
||||
2: [
|
||||
[ 0, Moves.HYDRO_PUMP ],
|
||||
[ 1, Moves.DOUBLE_TEAM ],
|
||||
[ 1, Moves.ASTONISH ],
|
||||
[ 5, Moves.THUNDER_SHOCK ],
|
||||
[ 10, Moves.CONFUSE_RAY ],
|
||||
[ 15, Moves.CHARGE ],
|
||||
[ 20, Moves.ELECTRO_BALL ],
|
||||
[ 25, Moves.THUNDER_WAVE ],
|
||||
[ 30, Moves.SHOCK_WAVE ],
|
||||
[ 35, Moves.HEX ],
|
||||
[ 40, Moves.SUBSTITUTE ],
|
||||
[ 45, Moves.TRICK ],
|
||||
[ 50, Moves.DISCHARGE ],
|
||||
[ 55, Moves.UPROAR ],
|
||||
],
|
||||
3: [
|
||||
[ 0, Moves.BLIZZARD ],
|
||||
[ 1, Moves.DOUBLE_TEAM ],
|
||||
[ 1, Moves.ASTONISH ],
|
||||
[ 5, Moves.THUNDER_SHOCK ],
|
||||
[ 10, Moves.CONFUSE_RAY ],
|
||||
[ 15, Moves.CHARGE ],
|
||||
[ 20, Moves.ELECTRO_BALL ],
|
||||
[ 25, Moves.THUNDER_WAVE ],
|
||||
[ 30, Moves.SHOCK_WAVE ],
|
||||
[ 35, Moves.HEX ],
|
||||
[ 40, Moves.SUBSTITUTE ],
|
||||
[ 45, Moves.TRICK ],
|
||||
[ 50, Moves.DISCHARGE ],
|
||||
[ 55, Moves.UPROAR ],
|
||||
],
|
||||
4: [
|
||||
[ 0, Moves.AIR_SLASH ],
|
||||
[ 1, Moves.DOUBLE_TEAM ],
|
||||
[ 1, Moves.ASTONISH ],
|
||||
[ 5, Moves.THUNDER_SHOCK ],
|
||||
[ 10, Moves.CONFUSE_RAY ],
|
||||
[ 15, Moves.CHARGE ],
|
||||
[ 20, Moves.ELECTRO_BALL ],
|
||||
[ 25, Moves.THUNDER_WAVE ],
|
||||
[ 30, Moves.SHOCK_WAVE ],
|
||||
[ 35, Moves.HEX ],
|
||||
[ 40, Moves.SUBSTITUTE ],
|
||||
[ 45, Moves.TRICK ],
|
||||
[ 50, Moves.DISCHARGE ],
|
||||
[ 55, Moves.UPROAR ],
|
||||
],
|
||||
5: [
|
||||
[ 0, Moves.LEAF_STORM ],
|
||||
[ 1, Moves.DOUBLE_TEAM ],
|
||||
[ 1, Moves.ASTONISH ],
|
||||
[ 5, Moves.THUNDER_SHOCK ],
|
||||
[ 10, Moves.CONFUSE_RAY ],
|
||||
[ 15, Moves.CHARGE ],
|
||||
[ 20, Moves.ELECTRO_BALL ],
|
||||
[ 25, Moves.THUNDER_WAVE ],
|
||||
[ 30, Moves.SHOCK_WAVE ],
|
||||
[ 35, Moves.HEX ],
|
||||
[ 40, Moves.SUBSTITUTE ],
|
||||
[ 45, Moves.TRICK ],
|
||||
[ 50, Moves.DISCHARGE ],
|
||||
[ 55, Moves.UPROAR ],
|
||||
],
|
||||
},
|
||||
[Species.SHAYMIN]: {
|
||||
1: [
|
||||
[ 1, Moves.GROWTH ],
|
||||
|
@ -4,7 +4,7 @@ import { Variant, VariantSet, variantColorCache } from '#app/data/variant';
|
||||
import { variantData } from '#app/data/variant';
|
||||
import BattleInfo, { PlayerBattleInfo, EnemyBattleInfo } from '../ui/battle-info';
|
||||
import { Moves } from "../data/enums/moves";
|
||||
import Move, { HighCritAttr, HitsTagAttr, applyMoveAttrs, FixedDamageAttr, VariableAtkAttr, VariablePowerAttr, allMoves, MoveCategory, TypelessAttr, CritOnlyAttr, getMoveTargets, OneHitKOAttr, MultiHitAttr, StatusMoveTypeImmunityAttr, MoveTarget, VariableDefAttr, AttackMove, ModifiedDamageAttr, VariableMoveTypeMultiplierAttr, IgnoreOpponentStatChangesAttr, SacrificialAttr, VariableMoveTypeAttr, VariableMoveCategoryAttr } from "../data/move";
|
||||
import Move, { HighCritAttr, HitsTagAttr, applyMoveAttrs, FixedDamageAttr, VariableAtkAttr, VariablePowerAttr, allMoves, MoveCategory, TypelessAttr, CritOnlyAttr, getMoveTargets, OneHitKOAttr, MultiHitAttr, StatusMoveTypeImmunityAttr, MoveTarget, VariableDefAttr, AttackMove, ModifiedDamageAttr, VariableMoveTypeMultiplierAttr, IgnoreOpponentStatChangesAttr, SacrificialAttr, VariableMoveTypeAttr, VariableMoveCategoryAttr, ExplosiveAttr } from "../data/move";
|
||||
import { default as PokemonSpecies, PokemonSpeciesForm, SpeciesFormKey, getFusedSpeciesName, getPokemonSpecies, getPokemonSpeciesForm, starterPassiveAbilities } from '../data/pokemon-species';
|
||||
import * as Utils from '../utils';
|
||||
import { Type, TypeDamageMultiplier, getTypeDamageMultiplier, getTypeRgb } from '../data/type';
|
||||
@ -1229,6 +1229,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
|
||||
if (types.find(t => move.isTypeImmune(t)))
|
||||
typeMultiplier.value = 0;
|
||||
|
||||
applyMoveAttrs(ExplosiveAttr, source, null, battlerMove.getMove());
|
||||
switch (moveCategory) {
|
||||
case MoveCategory.PHYSICAL:
|
||||
case MoveCategory.SPECIAL:
|
||||
@ -2316,7 +2317,8 @@ export class PlayerPokemon extends Pokemon {
|
||||
switchOut(batonPass: boolean, removeFromField: boolean = false): Promise<void> {
|
||||
return new Promise(resolve => {
|
||||
this.resetTurnData();
|
||||
this.resetSummonData();
|
||||
if (!batonPass)
|
||||
this.resetSummonData();
|
||||
this.hideInfo();
|
||||
this.setVisible(false);
|
||||
|
||||
|
1244
src/locales/de/ability.ts
Normal file
9
src/locales/de/command-ui-handler.ts
Normal file
@ -0,0 +1,9 @@
|
||||
import { SimpleTranslationEntries } from "#app/plugins/i18n";
|
||||
|
||||
export const commandUiHandler: SimpleTranslationEntries = {
|
||||
"fight": "Kampf",
|
||||
"ball": "Ball",
|
||||
"pokemon": "Pokémon",
|
||||
"run": "Fliehen",
|
||||
"actionMessage": "Was soll\n{{pokemonName}} tun?",
|
||||
} as const;
|
23
src/locales/de/menu-ui-handler.ts
Normal file
@ -0,0 +1,23 @@
|
||||
import { SimpleTranslationEntries } from "#app/plugins/i18n";
|
||||
|
||||
export const menuUiHandler: SimpleTranslationEntries = {
|
||||
"GAME_SETTINGS": 'Spieleinstellungen',
|
||||
"ACHIEVEMENTS": "Achievements",
|
||||
"STATS": "Statistiken",
|
||||
"VOUCHERS": "Gutscheine",
|
||||
"EGG_LIST": "Eierliste",
|
||||
"EGG_GACHA": "Eier-Gacha",
|
||||
"MANAGE_DATA": "Daten verwalten",
|
||||
"COMMUNITY": "Community",
|
||||
"RETURN_TO_TITLE": "Zurück zum Titelbildschirm",
|
||||
"LOG_OUT": "Ausloggen",
|
||||
"slot": "Slot {{slotNumber}}",
|
||||
"importSession": "Sitzung importieren",
|
||||
"importSlotSelect": "Wähle einen Slot zum Importieren.",
|
||||
"exportSession": "Sitzung exportieren",
|
||||
"exportSlotSelect": "Wähle einen Slot zum Exportieren.",
|
||||
"importData": "Daten importieren",
|
||||
"exportData": "Daten exportieren",
|
||||
"cancel": "Abbrechen",
|
||||
"losingProgressionWarning": "Du wirst jeglichen Fortschritt seit Anfang dieses Kampfes verlieren. Fortfahren?"
|
||||
} as const;
|
62
src/locales/de/menu.ts
Normal file
@ -0,0 +1,62 @@
|
||||
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": "Abbrechen",
|
||||
"continue": "Fortfahren",
|
||||
"dailyRun": "Täglicher Run (Beta)",
|
||||
"loadGame": "Spiel laden",
|
||||
"newGame": "Neues Spiel",
|
||||
"selectGameMode": "Wähle einen Spielmodus",
|
||||
"logInOrCreateAccount": "Logge dich ein oder erstelle einen Account zum starten. Keine Email nötig!",
|
||||
"username": "Benutzername",
|
||||
"password": "Passwort",
|
||||
"login": "Einloggen",
|
||||
"register": "Registrieren",
|
||||
"emptyUsername": "Benutzername darf nicht leer sein",
|
||||
"invalidLoginUsername": "Der eingegebene Benutzername ist ungültig",
|
||||
"invalidRegisterUsername": "Benutzername darf nur Buchstaben, Zahlen oder Unterstriche enthalten",
|
||||
"invalidLoginPassword": "Das eingegebene Passwort ist ungültig",
|
||||
"invalidRegisterPassword": "Passwort muss 6 Zeichen oder länger sein",
|
||||
"usernameAlreadyUsed": "Der eingegebene Benutzername wird bereits verwendet",
|
||||
"accountNonExistent": "Der eingegebene Benutzer existiert nicht",
|
||||
"unmatchingPassword": "Das eingegebene Passwort stimmt nicht überein",
|
||||
"passwordNotMatchingConfirmPassword": "Passwort muss mit Bestätigungspasswort übereinstimmen",
|
||||
"confirmPassword": "Besätige Passwort",
|
||||
"registrationAgeWarning": "Mit der Registrierung bestätigen Sie, dass Sie 13 Jahre oder älter sind.",
|
||||
"backToLogin": "Zurück zum Einloggen",
|
||||
"failedToLoadSaveData": "Speicherdaten konnten nicht geladen werden. Bitte laden Sie die Seite neu.\nWenn dies weiterhin der Fall ist, wenden Sie sich bitte an den Administrator.",
|
||||
"sessionSuccess": "Sitzung erfolgreich geladen.",
|
||||
"failedToLoadSession": "Ihre Sitzungsdaten konnten nicht geladen werden.\nSie könnten beschädigt sein.",
|
||||
"boyOrGirl": "Bist du ein Junge oder ein Mädchen?",
|
||||
"boy": "Junge",
|
||||
"girl": "Mädchen",
|
||||
"bossAppeared": "{{bossName}} erscheint.",
|
||||
"trainerAppeared": "{{trainerName}}\nmöchte kämpfen!",
|
||||
"singleWildAppeared": "Ein wildes {{pokemonName}} erscheint!",
|
||||
"multiWildAppeared": "Ein wildes {{pokemonName1}}\nund {{pokemonName2}} erscheinen!",
|
||||
"playerComeBack": "Komm zurück, {{pokemonName}}!",
|
||||
"trainerComeBack": "{{trainerName}} ruft {{pokemonName}} zurück!",
|
||||
"playerGo": "Los! {{pokemonName}}!",
|
||||
"trainerGo": "{{trainerName}} sendet {{pokemonName}} raus!",
|
||||
"switchQuestion": "Willst du\n{{pokemonName}} auswechseln?",
|
||||
"pokemon": "Pokémon",
|
||||
"sendOutPokemon": "Los! {{pokemonName}}!",
|
||||
"levelCapUp": "Das Levellimit\nhat sich zu {{levelCap}} erhöht!",
|
||||
"moveNotImplemented": "{{moveName}} ist noch nicht implementiert und kann nicht ausgewählt werden.",
|
||||
"moveDisabled": "{{moveName}} ist deaktiviert!",
|
||||
"noPokeballForce": "Eine unsichtbare Kraft\nverhindert die Nutzung von Pokébällen.",
|
||||
"noPokeballTrainer": "Du kannst das Pokémon\neines anderen Trainers nicht fangen!",
|
||||
"noPokeballMulti": "Du kannst erst einen Pokéball werden,\nwenn nur noch ein Pokémon übrig ist!",
|
||||
"noPokeballStrong": "Das Ziel-Pokémon ist zu stark, um gefangen zu werden!\nDu musst es zuerst schwächen!",
|
||||
"noEscapeForce": "Eine unsichtbare Kraft\nverhindert die Flucht.",
|
||||
"noEscapeTrainer": "Du kannst nicht\naus einem Trainerkampf fliehen!",
|
||||
"noEscapePokemon": "{{pokemonName}}'s {{moveName}}\nverhindert {{escapeVerb}}!",
|
||||
"escapeVerbSwitch": "auswechseln",
|
||||
"escapeVerbFlee": "flucht",
|
||||
"notDisabled": "{{moveName}} ist\nnicht mehr deaktiviert!",
|
||||
} as const;
|
3812
src/locales/de/move.ts
Normal file
10
src/locales/de/pokeball.ts
Normal file
@ -0,0 +1,10 @@
|
||||
import { SimpleTranslationEntries } from "#app/plugins/i18n";
|
||||
|
||||
export const pokeball: SimpleTranslationEntries = {
|
||||
"pokeBall": "Pokéball",
|
||||
"greatBall": "Superball",
|
||||
"ultraBall": "Hyperball",
|
||||
"rogueBall": "Rogueball",
|
||||
"masterBall": "Meisterball",
|
||||
"luxuryBall": "Luxusball",
|
||||
} as const;
|
16
src/locales/de/pokemon-stat.ts
Normal file
@ -0,0 +1,16 @@
|
||||
import { SimpleTranslationEntries } from "#app/plugins/i18n";
|
||||
|
||||
export const pokemonStat: SimpleTranslationEntries = {
|
||||
"HP": "Max. KP",
|
||||
"HPshortened": "MaxKP",
|
||||
"ATK": "Angriff",
|
||||
"ATKshortened": "Ang",
|
||||
"DEF": "Verteidigung",
|
||||
"DEFshortened": "Vert",
|
||||
"SPATK": "Sp. Ang",
|
||||
"SPATKshortened": "SpAng",
|
||||
"SPDEF": "Sp. Vert",
|
||||
"SPDEFshortened": "SpVert",
|
||||
"SPD": "Initiative",
|
||||
"SPDshortened": "Init"
|
||||
} as const;
|
1086
src/locales/de/pokemon.ts
Normal file
6
src/locales/en/fight-ui-handler.ts
Normal file
@ -0,0 +1,6 @@
|
||||
import { SimpleTranslationEntries } from "#app/plugins/i18n";
|
||||
|
||||
export const fightUiHandler: SimpleTranslationEntries = {
|
||||
"pp": "PP",
|
||||
"power": "POWER",
|
||||
} as const;
|
23
src/locales/en/menu-ui-handler.ts
Normal file
@ -0,0 +1,23 @@
|
||||
import { SimpleTranslationEntries } from "#app/plugins/i18n";
|
||||
|
||||
export const menuUiHandler: SimpleTranslationEntries = {
|
||||
"GAME_SETTINGS": 'Game Settings',
|
||||
"ACHIEVEMENTS": "Achievements",
|
||||
"STATS": "Stats",
|
||||
"VOUCHERS": "Vouchers",
|
||||
"EGG_LIST": "Egg List",
|
||||
"EGG_GACHA": "Egg Gacha",
|
||||
"MANAGE_DATA": "Manage Data",
|
||||
"COMMUNITY": "Community",
|
||||
"RETURN_TO_TITLE": "Return To Title",
|
||||
"LOG_OUT": "Log Out",
|
||||
"slot": "Slot {{slotNumber}}",
|
||||
"importSession": "Import Session",
|
||||
"importSlotSelect": "Select a slot to import to.",
|
||||
"exportSession": "Export Session",
|
||||
"exportSlotSelect": "Select a slot to export from.",
|
||||
"importData": "Import Data",
|
||||
"exportData": "Export Data",
|
||||
"cancel": "Cancel",
|
||||
"losingProgressionWarning": "You will lose any progress since the beginning of the battle. Proceed?"
|
||||
} as const;
|
23
src/locales/es/menu-ui-handler.ts
Normal file
@ -0,0 +1,23 @@
|
||||
import { SimpleTranslationEntries } from "#app/plugins/i18n";
|
||||
|
||||
export const menuUiHandler: SimpleTranslationEntries = {
|
||||
"GAME_SETTINGS": 'Game Settings',
|
||||
"ACHIEVEMENTS": "Achievements",
|
||||
"STATS": "Stats",
|
||||
"VOUCHERS": "Vouchers",
|
||||
"EGG_LIST": "Egg List",
|
||||
"EGG_GACHA": "Egg Gacha",
|
||||
"MANAGE_DATA": "Manage Data",
|
||||
"COMMUNITY": "Community",
|
||||
"RETURN_TO_TITLE": "Return To Title",
|
||||
"LOG_OUT": "Log Out",
|
||||
"slot": "Slot {{slotNumber}}",
|
||||
"importSession": "Import Session",
|
||||
"importSlotSelect": "Select a slot to import to.",
|
||||
"exportSession": "Export Session",
|
||||
"exportSlotSelect": "Select a slot to export from.",
|
||||
"importData": "Import Data",
|
||||
"exportData": "Export Data",
|
||||
"cancel": "Cancel",
|
||||
"losingProgressionWarning": "You will lose any progress since the beginning of the battle. Proceed?"
|
||||
} as const;
|
6
src/locales/fr/fight-ui-handler.ts
Normal file
@ -0,0 +1,6 @@
|
||||
import { SimpleTranslationEntries } from "#app/plugins/i18n";
|
||||
|
||||
export const fightUiHandler: SimpleTranslationEntries = {
|
||||
"pp": "PP",
|
||||
"power": "PUISSANCE",
|
||||
} as const;
|
23
src/locales/fr/menu-ui-handler.ts
Normal file
@ -0,0 +1,23 @@
|
||||
import { SimpleTranslationEntries } from "#app/plugins/i18n";
|
||||
|
||||
export const menuUiHandler: SimpleTranslationEntries = {
|
||||
"GAME_SETTINGS": 'Options',
|
||||
"ACHIEVEMENTS": "Succès",
|
||||
"STATS": "Statistiques",
|
||||
"VOUCHERS": "Coupons",
|
||||
"EGG_LIST": "Liste des œufs",
|
||||
"EGG_GACHA": "Gacha-œufs",
|
||||
"MANAGE_DATA": "Mes données",
|
||||
"COMMUNITY": "Communauté",
|
||||
"RETURN_TO_TITLE": "Écran titre",
|
||||
"LOG_OUT": "Déconnexion",
|
||||
"slot": "Emplacement {{slotNumber}}",
|
||||
"importSession": "Importer session",
|
||||
"importSlotSelect": "Sélectionnez l'emplacement vers lequel importer les données.",
|
||||
"exportSession": "Exporter session",
|
||||
"exportSlotSelect": "Sélectionnez l'emplacement depuis lequel exporter les données.",
|
||||
"importData": "Importer données",
|
||||
"exportData": "Exporter données",
|
||||
"cancel": "Retour",
|
||||
"losingProgressionWarning": "Vous allez perdre votre progression depuis le début du combat. Continuer ?"
|
||||
} as const;
|
23
src/locales/it/menu-ui-handler.ts
Normal file
@ -0,0 +1,23 @@
|
||||
import { SimpleTranslationEntries } from "#app/plugins/i18n";
|
||||
|
||||
export const menuUiHandler: SimpleTranslationEntries = {
|
||||
"GAME_SETTINGS": 'Game Settings',
|
||||
"ACHIEVEMENTS": "Achievements",
|
||||
"STATS": "Stats",
|
||||
"VOUCHERS": "Vouchers",
|
||||
"EGG_LIST": "Egg List",
|
||||
"EGG_GACHA": "Egg Gacha",
|
||||
"MANAGE_DATA": "Manage Data",
|
||||
"COMMUNITY": "Community",
|
||||
"RETURN_TO_TITLE": "Return To Title",
|
||||
"LOG_OUT": "Log Out",
|
||||
"slot": "Slot {{slotNumber}}",
|
||||
"importSession": "Import Session",
|
||||
"importSlotSelect": "Select a slot to import to.",
|
||||
"exportSession": "Export Session",
|
||||
"exportSlotSelect": "Select a slot to export from.",
|
||||
"importData": "Import Data",
|
||||
"exportData": "Export Data",
|
||||
"cancel": "Cancel",
|
||||
"losingProgressionWarning": "You will lose any progress since the beginning of the battle. Proceed?"
|
||||
} as const;
|
@ -874,14 +874,6 @@ export class BerryModifier extends PokemonHeldItemModifier {
|
||||
apply(args: any[]): boolean {
|
||||
const pokemon = args[0] as Pokemon;
|
||||
|
||||
const cancelled = new Utils.BooleanHolder(false);
|
||||
pokemon.getOpponents().map(opp => applyAbAttrs(PreventBerryUseAbAttr, opp, cancelled));
|
||||
|
||||
if (cancelled.value) {
|
||||
pokemon.scene.queueMessage(getPokemonMessage(pokemon, ' is too\nnervous to eat berries!'));
|
||||
return false;
|
||||
}
|
||||
|
||||
const preserve = new Utils.BooleanHolder(false);
|
||||
pokemon.scene.applyModifiers(PreserveBerryModifier, pokemon.isPlayer(), pokemon, preserve);
|
||||
|
||||
|
@ -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 } 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 } from "./data/ability";
|
||||
import { Unlockables, getUnlockableName } from "./system/unlockables";
|
||||
import { getBiomeKey } from "./field/arena";
|
||||
import { BattleType, BattlerIndex, TurnCommand } from "./battle";
|
||||
@ -3804,7 +3804,14 @@ export class BerryPhase extends CommonAnimPhase {
|
||||
start() {
|
||||
let berryModifiers: BerryModifier[];
|
||||
|
||||
if ((berryModifiers = this.scene.applyModifiers(BerryModifier, this.player, this.getPokemon()) as BerryModifier[])) {
|
||||
const pokemon = this.getPokemon();
|
||||
|
||||
const cancelled = new Utils.BooleanHolder(false);
|
||||
pokemon.getOpponents().map(opp => applyAbAttrs(PreventBerryUseAbAttr, opp, cancelled));
|
||||
|
||||
if (cancelled.value)
|
||||
pokemon.scene.queueMessage(getPokemonMessage(pokemon, ' is too\nnervous to eat berries!'));
|
||||
else if ((berryModifiers = this.scene.applyModifiers(BerryModifier, this.player, pokemon) as BerryModifier[])) {
|
||||
for (let berryModifier of berryModifiers) {
|
||||
if (berryModifier.consumed) {
|
||||
if (!--berryModifier.stackCount)
|
||||
|
@ -3,31 +3,47 @@ import { menu as enMenu } from '../locales/en/menu';
|
||||
import { menu as esMenu } from '../locales/es/menu';
|
||||
import { menu as itMenu } from '../locales/it/menu';
|
||||
import { menu as frMenu } from '../locales/fr/menu';
|
||||
import { menu as deMenu } from '../locales/de/menu';
|
||||
|
||||
import { menuUiHandler as enMenuUiHandler } from '../locales/en/menu-ui-handler.js';
|
||||
import { menuUiHandler as esMenuUiHandler } from '../locales/es/menu-ui-handler.js';
|
||||
import { menuUiHandler as frMenuUiHandler } from '../locales/fr/menu-ui-handler.js';
|
||||
import { menuUiHandler as itMenuUiHandler } from '../locales/it/menu-ui-handler.js';
|
||||
import { menuUiHandler as deMenuUiHandler } from '../locales/de/menu-ui-handler.js';
|
||||
|
||||
import { move as enMove } from '../locales/en/move';
|
||||
import { move as esMove } from '../locales/es/move';
|
||||
import { move as frMove } from '../locales/fr/move';
|
||||
import { move as deMove } from '../locales/de/move';
|
||||
|
||||
import { ability as enAbility } from '../locales/en/ability';
|
||||
import { ability as esAbility } from '../locales/es/ability';
|
||||
import { ability as frAbility } from '../locales/fr/ability';
|
||||
import { ability as deAbility } from '../locales/de/ability';
|
||||
|
||||
import { pokeball as enPokeball } from '../locales/en/pokeball';
|
||||
import { pokeball as esPokeball } from '../locales/es/pokeball';
|
||||
import { pokeball as frPokeball } from '../locales/fr/pokeball';
|
||||
import { pokeball as dePokeball } from '../locales/de/pokeball';
|
||||
|
||||
import { pokemon as enPokemon } from '../locales/en/pokemon';
|
||||
import { pokemon as esPokemon } from '../locales/es/pokemon';
|
||||
import { pokemon as frPokemon } from '../locales/fr/pokemon';
|
||||
import { pokemon as dePokemon } from '../locales/de/pokemon';
|
||||
|
||||
import { pokemonStat as enPokemonStat } from '../locales/en/pokemon-stat';
|
||||
import { pokemonStat as esPokemonStat } from '../locales/es/pokemon-stat';
|
||||
import { pokemonStat as frPokemonStat } from '../locales/fr/pokemon-stat';
|
||||
import { pokemonStat as itPokemonStat } from '../locales/it/pokemon-stat';
|
||||
import { pokemonStat as dePokemonStat } from '../locales/de/pokemon-stat';
|
||||
|
||||
import { commandUiHandler as enCommandUiHandler } from '../locales/en/command-ui-handler';
|
||||
import { commandUiHandler as esCommandUiHandler } from '../locales/es/command-ui-handler';
|
||||
import { commandUiHandler as frCommandUiHandler } from '../locales/fr/command-ui-handler';
|
||||
import { commandUiHandler as deCommandUiHandler } from '../locales/de/command-ui-handler';
|
||||
|
||||
import { fightUiHandler as enFightUiHandler } from '../locales/en/fight-ui-handler';
|
||||
import { fightUiHandler as frFightUiHandler } from '../locales/fr/fight-ui-handler';
|
||||
|
||||
export interface SimpleTranslationEntries {
|
||||
[key: string]: string
|
||||
@ -66,14 +82,17 @@ export function initI18n(): void {
|
||||
|
||||
/**
|
||||
* i18next is a localization library for maintaining and using translation resources.
|
||||
*
|
||||
*
|
||||
* Q: How do I add a new language?
|
||||
* A: To add a new language, create a new folder in the locales directory with the language code.
|
||||
* Each language folder should contain a file for each namespace (ex. menu.ts) with the translations.
|
||||
*
|
||||
*
|
||||
* Q: How do I add a new namespace?
|
||||
* A: To add a new namespace, create a new file in each language folder with the translations.
|
||||
* Then update the `resources` field in the init() call and the CustomTypeOptions interface.
|
||||
*
|
||||
* Q: How do I make a language selectable in the settings?
|
||||
* A: In src/system/settings.ts, add a new case to the Setting.Language switch statement.
|
||||
*/
|
||||
|
||||
i18next.init({
|
||||
@ -86,15 +105,18 @@ export function initI18n(): void {
|
||||
resources: {
|
||||
en: {
|
||||
menu: enMenu,
|
||||
menuUiHandler: enMenuUiHandler,
|
||||
move: enMove,
|
||||
ability: enAbility,
|
||||
pokeball: enPokeball,
|
||||
pokemon: enPokemon,
|
||||
pokemonStat: enPokemonStat,
|
||||
commandUiHandler: enCommandUiHandler,
|
||||
fightUiHandler: enFightUiHandler,
|
||||
},
|
||||
es: {
|
||||
menu: esMenu,
|
||||
menuUiHandler: esMenuUiHandler,
|
||||
move: esMove,
|
||||
ability: esAbility,
|
||||
pokeball: esPokeball,
|
||||
@ -104,17 +126,30 @@ export function initI18n(): void {
|
||||
},
|
||||
fr: {
|
||||
menu: frMenu,
|
||||
menuUiHandler: frMenuUiHandler,
|
||||
move: frMove,
|
||||
ability: frAbility,
|
||||
pokeball: frPokeball,
|
||||
pokemon: frPokemon,
|
||||
pokemonStat: frPokemonStat,
|
||||
commandUiHandler: frCommandUiHandler,
|
||||
fightUiHandler: frFightUiHandler,
|
||||
},
|
||||
it: {
|
||||
menu: itMenu,
|
||||
menuUiHandler: itMenuUiHandler,
|
||||
pokemonStat: itPokemonStat,
|
||||
},
|
||||
de: {
|
||||
menu: deMenu,
|
||||
menuUiHandler: deMenuUiHandler,
|
||||
move: deMove,
|
||||
ability: deAbility,
|
||||
pokeball: dePokeball,
|
||||
pokemon: dePokemon,
|
||||
pokemonStat: dePokemonStat,
|
||||
commandUiHandler: deCommandUiHandler,
|
||||
}
|
||||
},
|
||||
});
|
||||
}
|
||||
@ -124,12 +159,14 @@ declare module 'i18next' {
|
||||
interface CustomTypeOptions {
|
||||
resources: {
|
||||
menu: typeof enMenu;
|
||||
menuUiHandler: typeof enMenuUiHandler;
|
||||
move: typeof enMove;
|
||||
ability: typeof enAbility;
|
||||
pokeball: typeof enPokeball;
|
||||
pokemon: typeof enPokemon;
|
||||
pokemonStat: typeof enPokemonStat;
|
||||
commandUiHandler: typeof enCommandUiHandler;
|
||||
fightUiHandler: typeof enFightUiHandler;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
@ -421,6 +421,9 @@ export class GameData {
|
||||
if (response.startsWith('failed to open save file')) {
|
||||
this.scene.queueMessage('Save data could not be found. If this is a new account, you can safely ignore this message.', null, true);
|
||||
return resolve(true);
|
||||
} else if (response.indexOf('Too many connections') > -1) {
|
||||
this.scene.queueMessage('Too many people are trying to connect and the server is overloaded. Please try again later.', null, true);
|
||||
return resolve(false);
|
||||
}
|
||||
console.error(response);
|
||||
return resolve(false);
|
||||
|
@ -184,6 +184,10 @@ export function setSetting(scene: BattleScene, setting: Setting, value: integer)
|
||||
label: 'French',
|
||||
handler: () => changeLocaleHandler('fr')
|
||||
},
|
||||
{
|
||||
label: 'German',
|
||||
handler: () => changeLocaleHandler('de')
|
||||
},
|
||||
{
|
||||
label: 'Cancel',
|
||||
handler: () => cancelHandler()
|
||||
|
@ -50,9 +50,10 @@ export default class BattleMessageUiHandler extends MessageUiHandler {
|
||||
moveDetailsWindow.setOrigin(0, 1);
|
||||
this.movesWindowContainer.add(moveDetailsWindow);
|
||||
|
||||
const commandFightLabels = this.scene.add.image(246, -10, 'command_fight_labels');
|
||||
commandFightLabels.setOrigin(0, 1);
|
||||
this.movesWindowContainer.add(commandFightLabels);
|
||||
// TODO: Maybe remove this asset definitively if it's no longer needed?
|
||||
// const commandFightLabels = this.scene.add.image(246, -10, 'command_fight_labels');
|
||||
// commandFightLabels.setOrigin(0, 1);
|
||||
// this.movesWindowContainer.add(commandFightLabels);
|
||||
|
||||
ui.add(this.movesWindowContainer);
|
||||
|
||||
|
@ -7,11 +7,15 @@ import UiHandler from "./ui-handler";
|
||||
import * as Utils from "../utils";
|
||||
import { CommandPhase } from "../phases";
|
||||
import { MoveCategory } from "#app/data/move.js";
|
||||
import i18next from '../plugins/i18n';
|
||||
|
||||
export default class FightUiHandler extends UiHandler {
|
||||
private movesContainer: Phaser.GameObjects.Container;
|
||||
private typeIcon: Phaser.GameObjects.Sprite;
|
||||
private ppLabel: Phaser.GameObjects.Text;
|
||||
private ppText: Phaser.GameObjects.Text;
|
||||
private powerLabel: Phaser.GameObjects.Text;
|
||||
private powerText: Phaser.GameObjects.Text;
|
||||
private cursorObj: Phaser.GameObjects.Image;
|
||||
private moveCategoryIcon: Phaser.GameObjects.Sprite;
|
||||
|
||||
@ -24,23 +28,39 @@ export default class FightUiHandler extends UiHandler {
|
||||
|
||||
setup() {
|
||||
const ui = this.getUi();
|
||||
|
||||
|
||||
this.movesContainer = this.scene.add.container(18, -38.7);
|
||||
ui.add(this.movesContainer);
|
||||
|
||||
this.typeIcon = this.scene.add.sprite((this.scene.game.canvas.width / 6) - 41, -31, 'types', 'unknown');
|
||||
this.typeIcon = this.scene.add.sprite((this.scene.game.canvas.width / 6) - 57, -34, 'types', 'unknown');
|
||||
this.typeIcon.setVisible(false);
|
||||
ui.add(this.typeIcon);
|
||||
|
||||
this.moveCategoryIcon = this.scene.add.sprite((this.scene.game.canvas.width / 6) - 19, -31, 'categories', 'physical');
|
||||
this.moveCategoryIcon = this.scene.add.sprite((this.scene.game.canvas.width / 6) - 25, -34, 'categories', 'physical');
|
||||
this.moveCategoryIcon.setVisible(false);
|
||||
ui.add(this.moveCategoryIcon);
|
||||
|
||||
|
||||
this.ppText = addTextObject(this.scene, (this.scene.game.canvas.width / 6) - 18, -15.5, ' / ', TextStyle.WINDOW);
|
||||
this.ppLabel = addTextObject(this.scene, (this.scene.game.canvas.width / 6) - 70, -22, 'PP', TextStyle.TOOLTIP_CONTENT);
|
||||
this.ppLabel.setOrigin(0.0, 0.5);
|
||||
this.ppLabel.setVisible(false);
|
||||
this.ppLabel.setText(i18next.t('fightUiHandler:pp'));
|
||||
ui.add(this.ppLabel);
|
||||
|
||||
this.ppText = addTextObject(this.scene, (this.scene.game.canvas.width / 6) - 12, -22, '--/--', TextStyle.TOOLTIP_CONTENT);
|
||||
this.ppText.setOrigin(1, 0.5);
|
||||
this.ppText.setVisible(false);
|
||||
ui.add(this.ppText);
|
||||
|
||||
this.powerLabel = addTextObject(this.scene, (this.scene.game.canvas.width / 6) - 70, -12, 'POWER', TextStyle.TOOLTIP_CONTENT);
|
||||
this.powerLabel.setOrigin(0.0, 0.5);
|
||||
this.powerLabel.setVisible(false);
|
||||
this.powerLabel.setText(i18next.t('fightUiHandler:power'));
|
||||
ui.add(this.powerLabel);
|
||||
|
||||
this.powerText = addTextObject(this.scene, (this.scene.game.canvas.width / 6) - 12, -12, '---', TextStyle.TOOLTIP_CONTENT);
|
||||
this.powerText.setOrigin(1, 0.5);
|
||||
this.powerText.setVisible(false);
|
||||
ui.add(this.powerText);
|
||||
}
|
||||
|
||||
show(args: any[]): boolean {
|
||||
@ -127,18 +147,22 @@ export default class FightUiHandler extends UiHandler {
|
||||
|
||||
if (hasMove) {
|
||||
const pokemonMove = moveset[cursor];
|
||||
this.typeIcon.setTexture('types', Type[pokemonMove.getMove().type].toLowerCase()).setScale(0.65);
|
||||
this.moveCategoryIcon.setTexture('categories', MoveCategory[pokemonMove.getMove().category].toLowerCase()).setScale(0.8);
|
||||
this.typeIcon.setTexture('types', Type[pokemonMove.getMove().type].toLowerCase()).setScale(0.8);
|
||||
this.moveCategoryIcon.setTexture('categories', MoveCategory[pokemonMove.getMove().category].toLowerCase()).setScale(1.0);
|
||||
|
||||
const power = pokemonMove.getMove().power;
|
||||
const maxPP = pokemonMove.getMovePp();
|
||||
const pp = maxPP - pokemonMove.ppUsed;
|
||||
|
||||
|
||||
this.ppText.setText(`${Utils.padInt(pp, 2, ' ')}/${Utils.padInt(maxPP, 2, ' ')}`);
|
||||
this.powerText.setText(`${power >= 0 ? power : '---'}`);
|
||||
}
|
||||
|
||||
this.typeIcon.setVisible(hasMove);
|
||||
this.ppLabel.setVisible(hasMove);
|
||||
this.ppText.setVisible(hasMove);
|
||||
this.powerLabel.setVisible(hasMove);
|
||||
this.powerText.setVisible(hasMove);
|
||||
this.moveCategoryIcon.setVisible(hasMove);
|
||||
|
||||
this.cursorObj.setPosition(13 + (cursor % 2 === 1 ? 100 : 0), -31 + (cursor >= 2 ? 15 : 0));
|
||||
@ -160,7 +184,10 @@ export default class FightUiHandler extends UiHandler {
|
||||
super.clear();
|
||||
this.clearMoves();
|
||||
this.typeIcon.setVisible(false);
|
||||
this.ppLabel.setVisible(false);
|
||||
this.ppText.setVisible(false);
|
||||
this.powerLabel.setVisible(false);
|
||||
this.powerText.setVisible(false);
|
||||
this.moveCategoryIcon.setVisible(false);
|
||||
this.eraseCursor();
|
||||
}
|
||||
|
@ -8,6 +8,7 @@ import { GameDataType } from "../system/game-data";
|
||||
import { OptionSelectConfig, OptionSelectItem } from "./abstact-option-select-ui-handler";
|
||||
import { Tutorial, handleTutorial } from "../tutorial";
|
||||
import { updateUserInfo } from "../account";
|
||||
import i18next from '../plugins/i18n';
|
||||
|
||||
export enum MenuOptions {
|
||||
GAME_SETTINGS,
|
||||
@ -57,14 +58,20 @@ export default class MenuUiHandler extends MessageUiHandler {
|
||||
|
||||
this.menuContainer.setInteractive(new Phaser.Geom.Rectangle(0, 0, this.scene.game.canvas.width / 6, this.scene.game.canvas.height / 6), Phaser.Geom.Rectangle.Contains);
|
||||
|
||||
this.menuBg = addWindow(this.scene, (this.scene.game.canvas.width / 6) - 100, 0, 98, (this.scene.game.canvas.height / 6) - 2);
|
||||
const menuMessageText = addTextObject(this.scene, 8, 8, '', TextStyle.WINDOW, { maxLines: 2 });
|
||||
menuMessageText.setWordWrapWidth(1224);
|
||||
menuMessageText.setOrigin(0, 0);
|
||||
|
||||
this.optionSelectText = addTextObject(this.scene, 0, 0, this.menuOptions.map(o => `${i18next.t(`menuUiHandler:${MenuOptions[o]}`)}`).join('\n'), TextStyle.WINDOW, { maxLines: this.menuOptions.length });
|
||||
this.optionSelectText.setLineSpacing(12);
|
||||
|
||||
this.menuBg = addWindow(this.scene, (this.scene.game.canvas.width / 6) - (this.optionSelectText.displayWidth + 25), 0, this.optionSelectText.displayWidth + 23, (this.scene.game.canvas.height / 6) - 2);
|
||||
this.menuBg.setOrigin(0, 0);
|
||||
|
||||
this.optionSelectText.setPositionRelative(this.menuBg, 14, 6);
|
||||
|
||||
this.menuContainer.add(this.menuBg);
|
||||
|
||||
this.optionSelectText = addTextObject(this.scene, 0, 0, this.menuOptions.map(o => Utils.toReadableString(MenuOptions[o])).join('\n'), TextStyle.WINDOW, { maxLines: this.menuOptions.length });
|
||||
this.optionSelectText.setPositionRelative(this.menuBg, 14, 6);
|
||||
this.optionSelectText.setLineSpacing(12);
|
||||
this.menuContainer.add(this.optionSelectText);
|
||||
|
||||
ui.add(this.menuContainer);
|
||||
@ -77,9 +84,6 @@ export default class MenuUiHandler extends MessageUiHandler {
|
||||
menuMessageBox.setOrigin(0, 0);
|
||||
this.menuMessageBoxContainer.add(menuMessageBox);
|
||||
|
||||
const menuMessageText = addTextObject(this.scene, 8, 8, '', TextStyle.WINDOW, { maxLines: 2 });
|
||||
menuMessageText.setWordWrapWidth(1224);
|
||||
menuMessageText.setOrigin(0, 0);
|
||||
this.menuMessageBoxContainer.add(menuMessageText);
|
||||
|
||||
this.message = menuMessageText;
|
||||
@ -94,7 +98,7 @@ export default class MenuUiHandler extends MessageUiHandler {
|
||||
const config: OptionSelectConfig = {
|
||||
options: new Array(3).fill(null).map((_, i) => i).filter(slotFilter).map(i => {
|
||||
return {
|
||||
label: `Slot ${i + 1}`,
|
||||
label: i18next.t('menuUiHandler:slot', {slotNumber: i+1}),
|
||||
handler: () => {
|
||||
callback(i);
|
||||
ui.revertMode();
|
||||
@ -103,7 +107,7 @@ export default class MenuUiHandler extends MessageUiHandler {
|
||||
}
|
||||
};
|
||||
}).concat([{
|
||||
label: 'Cancel',
|
||||
label: i18next.t('menuUiHandler:cancel'),
|
||||
handler: () => {
|
||||
ui.revertMode();
|
||||
ui.showText(null, 0);
|
||||
@ -118,16 +122,16 @@ export default class MenuUiHandler extends MessageUiHandler {
|
||||
|
||||
if (Utils.isLocal) {
|
||||
manageDataOptions.push({
|
||||
label: 'Import Session',
|
||||
label: i18next.t("menuUiHandler:importSession"),
|
||||
handler: () => {
|
||||
confirmSlot('Select a slot to import to.', () => true, slotId => this.scene.gameData.importData(GameDataType.SESSION, slotId));
|
||||
confirmSlot(i18next.t("menuUiHandler:importSlotSelect"), () => true, slotId => this.scene.gameData.importData(GameDataType.SESSION, slotId));
|
||||
return true;
|
||||
},
|
||||
keepOpen: true
|
||||
});
|
||||
}
|
||||
manageDataOptions.push({
|
||||
label: 'Export Session',
|
||||
label: i18next.t("menuUiHandler:exportSession"),
|
||||
handler: () => {
|
||||
const dataSlots: integer[] = [];
|
||||
Promise.all(
|
||||
@ -138,7 +142,7 @@ export default class MenuUiHandler extends MessageUiHandler {
|
||||
dataSlots.push(slotId);
|
||||
})
|
||||
})).then(() => {
|
||||
confirmSlot('Select a slot to export from.',
|
||||
confirmSlot(i18next.t("menuUiHandler:exportSlotSelect"),
|
||||
i => dataSlots.indexOf(i) > -1,
|
||||
slotId => this.scene.gameData.tryExportData(GameDataType.SESSION, slotId));
|
||||
});
|
||||
@ -148,7 +152,7 @@ export default class MenuUiHandler extends MessageUiHandler {
|
||||
});
|
||||
if (Utils.isLocal) {
|
||||
manageDataOptions.push({
|
||||
label: 'Import Data',
|
||||
label: i18next.t("menuUiHandler:importData"),
|
||||
handler: () => {
|
||||
this.scene.gameData.importData(GameDataType.SYSTEM);
|
||||
return true;
|
||||
@ -158,7 +162,7 @@ export default class MenuUiHandler extends MessageUiHandler {
|
||||
}
|
||||
manageDataOptions.push(
|
||||
{
|
||||
label: 'Export Data',
|
||||
label: i18next.t("menuUiHandler:exportData"),
|
||||
handler: () => {
|
||||
this.scene.gameData.tryExportData(GameDataType.SYSTEM);
|
||||
return true;
|
||||
@ -166,7 +170,7 @@ export default class MenuUiHandler extends MessageUiHandler {
|
||||
keepOpen: true
|
||||
},
|
||||
{
|
||||
label: 'Cancel',
|
||||
label: i18next.t('menuUiHandler:cancel'),
|
||||
handler: () => {
|
||||
this.scene.ui.revertMode();
|
||||
return true;
|
||||
@ -205,7 +209,7 @@ export default class MenuUiHandler extends MessageUiHandler {
|
||||
keepOpen: true
|
||||
},
|
||||
{
|
||||
label: 'Cancel',
|
||||
label: i18next.t('menuUiHandler:cancel'),
|
||||
handler: () => {
|
||||
this.scene.ui.revertMode();
|
||||
return true;
|
||||
@ -295,7 +299,7 @@ export default class MenuUiHandler extends MessageUiHandler {
|
||||
case MenuOptions.RETURN_TO_TITLE:
|
||||
if (this.scene.currentBattle) {
|
||||
success = true;
|
||||
ui.showText('You will lose any progress since the beginning of the battle. Proceed?', null, () => {
|
||||
ui.showText(i18next.t("menuUiHandler:losingProgressionWarning"), null, () => {
|
||||
ui.setOverlayMode(Mode.CONFIRM, () => this.scene.reset(true), () => {
|
||||
ui.revertMode();
|
||||
ui.showText(null, 0);
|
||||
@ -315,7 +319,7 @@ export default class MenuUiHandler extends MessageUiHandler {
|
||||
});
|
||||
};
|
||||
if (this.scene.currentBattle) {
|
||||
ui.showText('You will lose any progress since the beginning of the battle. Proceed?', null, () => {
|
||||
ui.showText(i18next.t("menuUiHandler:losingProgressionWarning"), null, () => {
|
||||
ui.setOverlayMode(Mode.CONFIRM, doLogout, () => {
|
||||
ui.revertMode();
|
||||
ui.showText(null, 0);
|
||||
|
@ -80,7 +80,7 @@ export default class TitleUiHandler extends OptionSelectUiHandler {
|
||||
|
||||
this.updateTitleStats();
|
||||
|
||||
this.titleStatsTimer = setInterval(() => this.updateTitleStats(), 10000);
|
||||
this.titleStatsTimer = setInterval(() => this.updateTitleStats(), 30000);
|
||||
|
||||
this.scene.tweens.add({
|
||||
targets: [ this.titleContainer, ui.getMessageHandler().bg ],
|
||||
|
31
src/utils.ts
@ -212,8 +212,7 @@ export function executeIf<T>(condition: boolean, promiseFunc: () => Promise<T>):
|
||||
export const sessionIdKey = 'pokerogue_sessionId';
|
||||
export const isLocal = window.location.hostname === 'localhost';
|
||||
export const serverUrl = isLocal ? 'http://localhost:8001' : '';
|
||||
export const apiUrl = isLocal ? serverUrl : 'https://api.pokerogue.net';
|
||||
export const fallbackApiUrl = isLocal ? serverUrl : 'api';
|
||||
export const apiUrl = isLocal ? serverUrl : 'api';
|
||||
|
||||
export function setCookie(cName: string, cValue: string): void {
|
||||
const expiration = new Date();
|
||||
@ -234,7 +233,7 @@ export function getCookie(cName: string): string {
|
||||
return '';
|
||||
}
|
||||
|
||||
export function apiFetch(path: string, authed: boolean = false, fallback: boolean = false): Promise<Response> {
|
||||
export function apiFetch(path: string, authed: boolean = false): Promise<Response> {
|
||||
return new Promise((resolve, reject) => {
|
||||
const request = {};
|
||||
if (authed) {
|
||||
@ -242,22 +241,13 @@ export function apiFetch(path: string, authed: boolean = false, fallback: boolea
|
||||
if (sId)
|
||||
request['headers'] = { 'Authorization': sId };
|
||||
}
|
||||
fetch(`${!fallback ? apiUrl : fallbackApiUrl}/${path}`, request)
|
||||
.then(response => {
|
||||
if (!response.ok && response.status === 404 && !fallback)
|
||||
return apiFetch(path, authed, true).then(res => resolve(res));
|
||||
resolve(response);
|
||||
})
|
||||
.catch(err => {
|
||||
if (fallback)
|
||||
reject(err);
|
||||
else
|
||||
apiFetch(path, authed, true).then(res => resolve(res));
|
||||
});
|
||||
fetch(`${apiUrl}/${path}`, request)
|
||||
.then(response => resolve(response))
|
||||
.catch(err => reject(err));
|
||||
});
|
||||
}
|
||||
|
||||
export function apiPost(path: string, data?: any, contentType: string = 'application/json', authed: boolean = false, fallback: boolean = false): Promise<Response> {
|
||||
export function apiPost(path: string, data?: any, contentType: string = 'application/json', authed: boolean = false): Promise<Response> {
|
||||
return new Promise((resolve, reject) => {
|
||||
const headers = {
|
||||
'Accept': contentType,
|
||||
@ -268,14 +258,9 @@ export function apiPost(path: string, data?: any, contentType: string = 'applica
|
||||
if (sId)
|
||||
headers['Authorization'] = sId;
|
||||
}
|
||||
fetch(`${!fallback ? apiUrl : fallbackApiUrl}/${path}`, { method: 'POST', headers: headers, body: data })
|
||||
fetch(`${apiUrl}/${path}`, { method: 'POST', headers: headers, body: data })
|
||||
.then(response => resolve(response))
|
||||
.catch(err => {
|
||||
if (fallback)
|
||||
reject(err);
|
||||
else
|
||||
apiPost(path, data, contentType, authed, true).then(res => resolve(res));
|
||||
});
|
||||
.catch(err => reject(err));
|
||||
});
|
||||
}
|
||||
|
||||
|