mirror of
https://github.com/pagefaultgames/pokerogue.git
synced 2025-07-16 21:32:18 +02:00
Merge branch 'main' into 1078Fix
This commit is contained in:
commit
a920e6dcb2
@ -1,15 +1,15 @@
|
||||
{
|
||||
"0": {
|
||||
"7b4a9c": "323f81",
|
||||
"63197b": "142557",
|
||||
"a55ace": "6265b4",
|
||||
"7b4a9c": "d684ce",
|
||||
"63197b": "9c528c",
|
||||
"a55ace": "ffb5f7",
|
||||
"101010": "101010",
|
||||
"b57bce": "99a3ee",
|
||||
"08426b": "277eb2",
|
||||
"ce0021": "ce0021",
|
||||
"ffd600": "ffc3f4",
|
||||
"d69400": "ff61e2",
|
||||
"216b94": "4aa6ce",
|
||||
"b57bce": "ffd6ef",
|
||||
"08426b": "638400",
|
||||
"ce0021": "940821",
|
||||
"ffd600": "ffd600",
|
||||
"d69400": "d69400",
|
||||
"216b94": "8ca508",
|
||||
"ffffff": "ffffff",
|
||||
"a5a5a5": "a5a5a5",
|
||||
"6b6b6b": "6b6b6b"
|
||||
|
@ -14,26 +14,26 @@
|
||||
"943a7b": "175990"
|
||||
},
|
||||
"1": {
|
||||
"3a3a7b": "1d0f4e",
|
||||
"5aadef": "3d4381",
|
||||
"6384ce": "2f2a5f",
|
||||
"631052": "892d03",
|
||||
"ce6bb5": "f1a139",
|
||||
"adceff": "666fb4",
|
||||
"3a3a7b": "084a00",
|
||||
"5aadef": "6b9c29",
|
||||
"6384ce": "317300",
|
||||
"631052": "c52931",
|
||||
"ce6bb5": "ffada5",
|
||||
"adceff": "84d64a",
|
||||
"000000": "000000",
|
||||
"ad52ad": "d5711b",
|
||||
"ad52ad": "e6737b",
|
||||
"636363": "636363",
|
||||
"ffffff": "ffffff",
|
||||
"d6d6d6": "d6d6d6",
|
||||
"943a7b": "af4e0c"
|
||||
"943a7b": "d6525a"
|
||||
},
|
||||
"2": {
|
||||
"3a3a7b": "584055",
|
||||
"5aadef": "c1aec0",
|
||||
"6384ce": "866881",
|
||||
"3a3a7b": "3d2349",
|
||||
"5aadef": "cbabca",
|
||||
"6384ce": "916c8b",
|
||||
"631052": "54070c",
|
||||
"ce6bb5": "bc3b1d",
|
||||
"adceff": "dfcddd",
|
||||
"adceff": "e8d2e6",
|
||||
"000000": "000000",
|
||||
"ad52ad": "94241c",
|
||||
"636363": "636363",
|
||||
|
@ -909,6 +909,11 @@
|
||||
2,
|
||||
2
|
||||
],
|
||||
"472": [
|
||||
0,
|
||||
0,
|
||||
0
|
||||
],
|
||||
"475-mega": [
|
||||
0,
|
||||
2,
|
||||
@ -2050,6 +2055,16 @@
|
||||
2,
|
||||
1
|
||||
],
|
||||
"41": [
|
||||
0,
|
||||
1,
|
||||
1
|
||||
],
|
||||
"42": [
|
||||
0,
|
||||
1,
|
||||
1
|
||||
],
|
||||
"308": [
|
||||
0,
|
||||
1,
|
||||
@ -2869,7 +2884,7 @@
|
||||
],
|
||||
"383": [
|
||||
0,
|
||||
2,
|
||||
1,
|
||||
1
|
||||
],
|
||||
"384-mega": [
|
||||
@ -4143,6 +4158,16 @@
|
||||
1,
|
||||
1
|
||||
],
|
||||
"41": [
|
||||
0,
|
||||
1,
|
||||
1
|
||||
],
|
||||
"42": [
|
||||
0,
|
||||
1,
|
||||
1
|
||||
],
|
||||
"308": [
|
||||
0,
|
||||
1,
|
||||
@ -4538,7 +4563,7 @@
|
||||
],
|
||||
"747": [
|
||||
0,
|
||||
1,
|
||||
2,
|
||||
1
|
||||
],
|
||||
"748": [
|
||||
@ -4591,6 +4616,11 @@
|
||||
1,
|
||||
1
|
||||
],
|
||||
"770": [
|
||||
0,
|
||||
0,
|
||||
0
|
||||
],
|
||||
"771": [
|
||||
0,
|
||||
2,
|
||||
|
@ -1,4 +1,21 @@
|
||||
{
|
||||
"1": {
|
||||
"000000": "000000",
|
||||
"7b2129": "032a10",
|
||||
"9c2929": "10371a",
|
||||
"ff736b": "419e49",
|
||||
"ff2129": "2b5b32",
|
||||
"bd3131": "0f461c",
|
||||
"3a3a3a": "383540",
|
||||
"736363": "625769",
|
||||
"ffffff": "fff6de",
|
||||
"bdbdd6": "e5d4b6",
|
||||
"9c6b31": "d51b3e",
|
||||
"ffce31": "ff435d",
|
||||
"94848c": "72798b",
|
||||
"ffbdbd": "49c74f",
|
||||
"ad9ca5": "ad9ca5"
|
||||
},
|
||||
"2": {
|
||||
"000000": "000000",
|
||||
"7b2129": "123953",
|
||||
|
@ -1,19 +1,19 @@
|
||||
{
|
||||
"0": {
|
||||
"298c8c": "1c3820",
|
||||
"5aada5": "3e5d43",
|
||||
"84cece": "758076",
|
||||
"004a52": "102c16",
|
||||
"106b63": "0d1e10",
|
||||
"298c8c": "427373",
|
||||
"5aada5": "6b9c94",
|
||||
"84cece": "94bdbd",
|
||||
"004a52": "192121",
|
||||
"106b63": "21524a",
|
||||
"191921": "191921",
|
||||
"106b7b": "102c16",
|
||||
"29848c": "224427",
|
||||
"6b4200": "54190e",
|
||||
"c59c52": "a65c3f",
|
||||
"9c7329": "763826",
|
||||
"dece94": "e46424",
|
||||
"ffefa5": "ff9942",
|
||||
"bdad73": "cb3000"
|
||||
"106b7b": "293a42",
|
||||
"29848c": "424a5a",
|
||||
"6b4200": "523a10",
|
||||
"c59c52": "b59463",
|
||||
"9c7329": "846b3a",
|
||||
"dece94": "b5de21",
|
||||
"ffefa5": "d6ff42",
|
||||
"bdad73": "94bd00"
|
||||
},
|
||||
"1": {
|
||||
"298c8c": "793907",
|
||||
|
24
public/images/pokemon/variant/back/female/41.json
Normal file
24
public/images/pokemon/variant/back/female/41.json
Normal file
@ -0,0 +1,24 @@
|
||||
{
|
||||
"1": {
|
||||
"101010": "101010",
|
||||
"8cb5ef": "4e538f",
|
||||
"4a427b": "14093b",
|
||||
"637bb5": "37326f",
|
||||
"73215a": "aa4c18",
|
||||
"b5529c": "cc7b32",
|
||||
"bdceff": "868ecc",
|
||||
"ffffff": "ffffff",
|
||||
"636363": "636363"
|
||||
},
|
||||
"2": {
|
||||
"101010": "101010",
|
||||
"8cb5ef": "cbabca",
|
||||
"4a427b": "4d3259",
|
||||
"637bb5": "916c8b",
|
||||
"73215a": "670f10",
|
||||
"b5529c": "94241c",
|
||||
"bdceff": "e8d2e6",
|
||||
"ffffff": "ffffff",
|
||||
"636363": "636363"
|
||||
}
|
||||
}
|
24
public/images/pokemon/variant/back/female/42.json
Normal file
24
public/images/pokemon/variant/back/female/42.json
Normal file
@ -0,0 +1,24 @@
|
||||
{
|
||||
"1": {
|
||||
"3a3a7b": "1d0f4e",
|
||||
"6384ce": "2f2a5f",
|
||||
"adceff": "666fb4",
|
||||
"5aadef": "3d4381",
|
||||
"631052": "892d03",
|
||||
"000000": "000000",
|
||||
"ce6bb5": "f1a139",
|
||||
"ad52ad": "d5711b",
|
||||
"943a7b": "af4e0c"
|
||||
},
|
||||
"2": {
|
||||
"3a3a7b": "3d2349",
|
||||
"6384ce": "916c8b",
|
||||
"adceff": "e8d2e6",
|
||||
"5aadef": "cbabca",
|
||||
"631052": "54070c",
|
||||
"000000": "000000",
|
||||
"ce6bb5": "bc3b1d",
|
||||
"ad52ad": "94241c",
|
||||
"943a7b": "6c1314"
|
||||
}
|
||||
}
|
188
public/images/pokemon/variant/exp/747_2.json
Normal file
188
public/images/pokemon/variant/exp/747_2.json
Normal file
@ -0,0 +1,188 @@
|
||||
{
|
||||
"textures": [
|
||||
{
|
||||
"image": "747_2.png",
|
||||
"format": "RGBA8888",
|
||||
"size": {
|
||||
"w": 110,
|
||||
"h": 110
|
||||
},
|
||||
"scale": 1,
|
||||
"frames": [
|
||||
{
|
||||
"filename": "0003.png",
|
||||
"rotated": false,
|
||||
"trimmed": false,
|
||||
"sourceSize": {
|
||||
"w": 55,
|
||||
"h": 47
|
||||
},
|
||||
"spriteSourceSize": {
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
"w": 55,
|
||||
"h": 47
|
||||
},
|
||||
"frame": {
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
"w": 55,
|
||||
"h": 47
|
||||
}
|
||||
},
|
||||
{
|
||||
"filename": "0004.png",
|
||||
"rotated": false,
|
||||
"trimmed": false,
|
||||
"sourceSize": {
|
||||
"w": 55,
|
||||
"h": 47
|
||||
},
|
||||
"spriteSourceSize": {
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
"w": 55,
|
||||
"h": 47
|
||||
},
|
||||
"frame": {
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
"w": 55,
|
||||
"h": 47
|
||||
}
|
||||
},
|
||||
{
|
||||
"filename": "0007.png",
|
||||
"rotated": false,
|
||||
"trimmed": false,
|
||||
"sourceSize": {
|
||||
"w": 55,
|
||||
"h": 47
|
||||
},
|
||||
"spriteSourceSize": {
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
"w": 55,
|
||||
"h": 47
|
||||
},
|
||||
"frame": {
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
"w": 55,
|
||||
"h": 47
|
||||
}
|
||||
},
|
||||
{
|
||||
"filename": "0008.png",
|
||||
"rotated": false,
|
||||
"trimmed": false,
|
||||
"sourceSize": {
|
||||
"w": 55,
|
||||
"h": 47
|
||||
},
|
||||
"spriteSourceSize": {
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
"w": 55,
|
||||
"h": 47
|
||||
},
|
||||
"frame": {
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
"w": 55,
|
||||
"h": 47
|
||||
}
|
||||
},
|
||||
{
|
||||
"filename": "0001.png",
|
||||
"rotated": false,
|
||||
"trimmed": true,
|
||||
"sourceSize": {
|
||||
"w": 55,
|
||||
"h": 47
|
||||
},
|
||||
"spriteSourceSize": {
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
"w": 55,
|
||||
"h": 46
|
||||
},
|
||||
"frame": {
|
||||
"x": 55,
|
||||
"y": 0,
|
||||
"w": 55,
|
||||
"h": 46
|
||||
}
|
||||
},
|
||||
{
|
||||
"filename": "0002.png",
|
||||
"rotated": false,
|
||||
"trimmed": true,
|
||||
"sourceSize": {
|
||||
"w": 55,
|
||||
"h": 47
|
||||
},
|
||||
"spriteSourceSize": {
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
"w": 55,
|
||||
"h": 46
|
||||
},
|
||||
"frame": {
|
||||
"x": 55,
|
||||
"y": 0,
|
||||
"w": 55,
|
||||
"h": 46
|
||||
}
|
||||
},
|
||||
{
|
||||
"filename": "0005.png",
|
||||
"rotated": false,
|
||||
"trimmed": true,
|
||||
"sourceSize": {
|
||||
"w": 55,
|
||||
"h": 47
|
||||
},
|
||||
"spriteSourceSize": {
|
||||
"x": 0,
|
||||
"y": 1,
|
||||
"w": 55,
|
||||
"h": 46
|
||||
},
|
||||
"frame": {
|
||||
"x": 55,
|
||||
"y": 46,
|
||||
"w": 55,
|
||||
"h": 46
|
||||
}
|
||||
},
|
||||
{
|
||||
"filename": "0006.png",
|
||||
"rotated": false,
|
||||
"trimmed": true,
|
||||
"sourceSize": {
|
||||
"w": 55,
|
||||
"h": 47
|
||||
},
|
||||
"spriteSourceSize": {
|
||||
"x": 0,
|
||||
"y": 1,
|
||||
"w": 55,
|
||||
"h": 46
|
||||
},
|
||||
"frame": {
|
||||
"x": 55,
|
||||
"y": 46,
|
||||
"w": 55,
|
||||
"h": 46
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"meta": {
|
||||
"app": "https://www.codeandweb.com/texturepacker",
|
||||
"version": "3.0",
|
||||
"smartupdate": "$TexturePacker:SmartUpdate:e4c4f790c4f0286f608dcdb15a609059:464f7ae7db1c0d034c2a1a65612b0da8:b26f7254994561969f00f765318acf1c$"
|
||||
}
|
||||
}
|
26
public/images/pokemon/variant/female/41.json
Normal file
26
public/images/pokemon/variant/female/41.json
Normal file
@ -0,0 +1,26 @@
|
||||
{
|
||||
"1": {
|
||||
"101010": "101010",
|
||||
"637bb5": "37326f",
|
||||
"4a427b": "14093b",
|
||||
"bdceff": "868ecc",
|
||||
"8cb5ef": "4e538f",
|
||||
"b5529c": "cc7b32",
|
||||
"73215a": "aa4c18",
|
||||
"d673bd": "f0ad57",
|
||||
"ffffff": "ffffff",
|
||||
"636363": "636363"
|
||||
},
|
||||
"2": {
|
||||
"101010": "101010",
|
||||
"637bb5": "916c8b",
|
||||
"4a427b": "4d3259",
|
||||
"bdceff": "e8d2e6",
|
||||
"8cb5ef": "cbabca",
|
||||
"b5529c": "94241c",
|
||||
"73215a": "670f10",
|
||||
"d673bd": "bc3b1d",
|
||||
"ffffff": "ffffff",
|
||||
"636363": "636363"
|
||||
}
|
||||
}
|
30
public/images/pokemon/variant/female/42.json
Normal file
30
public/images/pokemon/variant/female/42.json
Normal file
@ -0,0 +1,30 @@
|
||||
{
|
||||
"1": {
|
||||
"3a3a7b": "1d0f4e",
|
||||
"5aadef": "3d4381",
|
||||
"6384ce": "2f2a5f",
|
||||
"631052": "892d03",
|
||||
"ce6bb5": "f1a139",
|
||||
"adceff": "666fb4",
|
||||
"000000": "000000",
|
||||
"ad52ad": "d5711b",
|
||||
"636363": "636363",
|
||||
"ffffff": "ffffff",
|
||||
"d6d6d6": "d6d6d6",
|
||||
"943a7b": "af4e0c"
|
||||
},
|
||||
"2": {
|
||||
"3a3a7b": "3d2349",
|
||||
"5aadef": "cbabca",
|
||||
"6384ce": "916c8b",
|
||||
"631052": "54070c",
|
||||
"ce6bb5": "bc3b1d",
|
||||
"adceff": "e8d2e6",
|
||||
"000000": "000000",
|
||||
"ad52ad": "94241c",
|
||||
"636363": "636363",
|
||||
"ffffff": "ffffff",
|
||||
"d6d6d6": "d6d6d6",
|
||||
"943a7b": "6c1314"
|
||||
}
|
||||
}
|
@ -9,7 +9,7 @@ import { BattlerTag } from "./battler-tags";
|
||||
import { BattlerTagType } from "./enums/battler-tag-type";
|
||||
import { StatusEffect, getStatusEffectDescriptor, getStatusEffectHealText } from "./status-effect";
|
||||
import { Gender } from "./gender";
|
||||
import Move, { AttackMove, MoveCategory, MoveFlags, MoveTarget, RecoilAttr, StatusMoveTypeImmunityAttr, FlinchAttr, OneHitKOAttr, HitHealAttr, StrengthSapHealAttr, allMoves, StatusMove, VariablePowerAttr, applyMoveAttrs } from "./move";
|
||||
import Move, { AttackMove, MoveCategory, MoveFlags, MoveTarget, RecoilAttr, StatusMoveTypeImmunityAttr, FlinchAttr, OneHitKOAttr, HitHealAttr, StrengthSapHealAttr, allMoves, StatusMove, VariablePowerAttr, applyMoveAttrs, IncrementMovePriorityAttr } from "./move";
|
||||
import { ArenaTagSide, ArenaTrapTag } from "./arena-tag";
|
||||
import { ArenaTagType } from "./enums/arena-tag-type";
|
||||
import { Stat } from "./pokemon-stat";
|
||||
@ -491,8 +491,13 @@ export class PostDefendFormChangeAbAttr extends PostDefendAbAttr {
|
||||
export class FieldPriorityMoveImmunityAbAttr extends PreDefendAbAttr {
|
||||
applyPreDefend(pokemon: Pokemon, passive: boolean, attacker: Pokemon, move: PokemonMove, cancelled: Utils.BooleanHolder, args: any[]): boolean {
|
||||
const attackPriority = new Utils.IntegerHolder(move.getMove().priority);
|
||||
applyMoveAttrs(IncrementMovePriorityAttr,attacker,null,move.getMove(),attackPriority);
|
||||
applyAbAttrs(IncrementMovePriorityAbAttr, attacker, null, move.getMove(), attackPriority);
|
||||
|
||||
if(move.getMove().moveTarget===MoveTarget.USER) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if(attackPriority.value > 0 && !move.getMove().isMultiTarget()) {
|
||||
cancelled.value = true;
|
||||
return true;
|
||||
|
@ -130,9 +130,11 @@ export function getBerryEffectFunc(berryType: BerryType): BerryEffectFunc {
|
||||
return (pokemon: Pokemon) => {
|
||||
if (pokemon.battleData)
|
||||
pokemon.battleData.berriesEaten.push(berryType);
|
||||
const ppRestoreMove = pokemon.getMoveset().find(m => !m.getPpRatio());
|
||||
ppRestoreMove.ppUsed = Math.max(ppRestoreMove.ppUsed - 10, 0);
|
||||
pokemon.scene.queueMessage(getPokemonMessage(pokemon, ` restored PP to its move ${ppRestoreMove.getName()}\nusing its ${getBerryName(berryType)}!`));
|
||||
const ppRestoreMove = pokemon.getMoveset().find(m => !m.getPpRatio()) ? pokemon.getMoveset().find(m => !m.getPpRatio()) : pokemon.getMoveset().find(m => m.getPpRatio() < 1);
|
||||
if(ppRestoreMove !== undefined){
|
||||
ppRestoreMove.ppUsed = Math.max(ppRestoreMove.ppUsed - 10, 0);
|
||||
pokemon.scene.queueMessage(getPokemonMessage(pokemon, ` restored PP to its move ${ppRestoreMove.getName()}\nusing its ${getBerryName(berryType)}!`));
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
210
src/data/move.ts
210
src/data/move.ts
@ -1,6 +1,6 @@
|
||||
import { Moves } from "./enums/moves";
|
||||
import { ChargeAnim, MoveChargeAnim, initMoveAnim, loadMoveAnimAssets } from "./battle-anims";
|
||||
import { BattleEndPhase, MoveEffectPhase, MovePhase, NewBattlePhase, PartyStatusCurePhase, PokemonHealPhase, StatChangePhase, SwitchSummonPhase } from "../phases";
|
||||
import { BattleEndPhase, MoveEffectPhase, MovePhase, NewBattlePhase, PartyStatusCurePhase, PokemonHealPhase, StatChangePhase, SwitchSummonPhase, ToggleDoublePositionPhase } from "../phases";
|
||||
import { BattleStat, getBattleStatName } from "./battle-stat";
|
||||
import { EncoreTag } from "./battler-tags";
|
||||
import { BattlerTagType } from "./enums/battler-tag-type";
|
||||
@ -12,10 +12,10 @@ 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, FieldPreventExplosiveMovesAbAttr, ForceSwitchOutImmunityAbAttr } from "./ability";
|
||||
import { UnswappableAbilityAbAttr, UncopiableAbilityAbAttr, UnsuppressableAbilityAbAttr, NoTransformAbilityAbAttr, BlockRecoilDamageAttr, BlockOneHitKOAbAttr, IgnoreContactAbAttr, MaxMultiHitAbAttr, applyAbAttrs, BlockNonDirectDamageAbAttr, applyPreSwitchOutAbAttrs, PreSwitchOutAbAttr, applyPostDefendAbAttrs, PostDefendContactApplyStatusEffectAbAttr, MoveAbilityBypassAbAttr, ReverseDrainAbAttr, FieldPreventExplosiveMovesAbAttr, ForceSwitchOutImmunityAbAttr, PreventBerryUseAbAttr, BlockItemTheftAbAttr } from "./ability";
|
||||
import { Abilities } from "./enums/abilities";
|
||||
import { allAbilities } from './ability';
|
||||
import { PokemonHeldItemModifier } from "../modifier/modifier";
|
||||
import { PokemonHeldItemModifier, BerryModifier, PreserveBerryModifier } from "../modifier/modifier";
|
||||
import { BattlerIndex } from "../battle";
|
||||
import { Stat } from "./pokemon-stat";
|
||||
import { TerrainType } from "./terrain";
|
||||
@ -25,6 +25,7 @@ import { ModifierPoolType } from "#app/modifier/modifier-type";
|
||||
import { Command } from "../ui/command-ui-handler";
|
||||
import { Biome } from "./enums/biome";
|
||||
import i18next, { Localizable } from '../plugins/i18n';
|
||||
import { BerryType, BerryEffectFunc, getBerryEffectFunc } from './berry';
|
||||
|
||||
export enum MoveCategory {
|
||||
PHYSICAL,
|
||||
@ -781,8 +782,8 @@ export class RecoilAttr extends MoveEffectAttr {
|
||||
if (cancelled.value)
|
||||
return false;
|
||||
|
||||
const recoilDamage = Math.max(Math.floor((!this.useHp ? user.turnData.damageDealt : user.getMaxHp()) * this.damageRatio),
|
||||
user.turnData.damageDealt ? 1 : 0);
|
||||
const recoilDamage = Math.max(Math.floor((!this.useHp ? user.turnData.currDamageDealt : user.getMaxHp()) * this.damageRatio),
|
||||
user.turnData.currDamageDealt ? 1 : 0);
|
||||
if (!recoilDamage)
|
||||
return false;
|
||||
|
||||
@ -1168,6 +1169,42 @@ export class StrengthSapHealAttr extends MoveEffectAttr {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Attribute used for moves that change priority in a turn given a condition,
|
||||
* e.g. Grassy Glide
|
||||
* Called when move order is calculated in {@linkcode TurnStartPhase}.
|
||||
* @extends MoveAttr
|
||||
* @see {@linkcode apply}
|
||||
*/
|
||||
export class IncrementMovePriorityAttr extends MoveAttr {
|
||||
/** The condition for a move's priority being incremented */
|
||||
private moveIncrementFunc: (pokemon: Pokemon, target:Pokemon, move: Move) => boolean;
|
||||
/** The amount to increment priority by, if condition passes. */
|
||||
private increaseAmount: integer;
|
||||
|
||||
constructor(moveIncrementFunc: (pokemon: Pokemon, target:Pokemon, move: Move) => boolean, increaseAmount = 1) {
|
||||
super();
|
||||
|
||||
this.moveIncrementFunc = moveIncrementFunc;
|
||||
this.increaseAmount = increaseAmount;
|
||||
}
|
||||
|
||||
/**
|
||||
* Increments move priority by set amount if condition passes
|
||||
* @param user {@linkcode Pokemon} using this move
|
||||
* @param target {@linkcode Pokemon} target of this move
|
||||
* @param move {@linkcode Move} being used
|
||||
* @param args [0] {@linkcode Utils.IntegerHolder} for move priority.
|
||||
* @returns true if function succeeds
|
||||
*/
|
||||
apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): boolean {
|
||||
if (!this.moveIncrementFunc(user, target, move))
|
||||
return false;
|
||||
|
||||
(args[0] as Utils.IntegerHolder).value += this.increaseAmount;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
export class MultiHitAttr extends MoveAttr {
|
||||
private multiHitType: MultiHitType;
|
||||
@ -1443,6 +1480,95 @@ export class RemoveHeldItemAttr extends MoveEffectAttr {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Attribute that causes targets of the move to eat a berry. If chosenBerry is not overriden, a random berry will be picked from the target's inventory.
|
||||
*/
|
||||
export class EatBerryAttr extends MoveEffectAttr {
|
||||
protected chosenBerry: BerryModifier;
|
||||
constructor() {
|
||||
super(true, MoveEffectTrigger.HIT);
|
||||
this.chosenBerry = undefined;
|
||||
}
|
||||
/**
|
||||
* Causes the target to eat a berry.
|
||||
* @param user {@linkcode Pokemon} Pokemon that used the move
|
||||
* @param target {@linkcode Pokemon} Pokemon that will eat a berry
|
||||
* @param move {@linkcode Move} The move being used
|
||||
* @param args Unused
|
||||
* @returns {boolean} true if the function succeeds
|
||||
*/
|
||||
apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): boolean {
|
||||
if (!super.apply(user, target, move, args))
|
||||
return false;
|
||||
|
||||
if(this.chosenBerry === undefined) { // if no berry has been provided, pick a random berry from their inventory
|
||||
const heldBerries = this.getTargetHeldBerries(target);
|
||||
if(heldBerries.length <= 0)
|
||||
return false;
|
||||
this.chosenBerry = heldBerries[user.randSeedInt(heldBerries.length)];
|
||||
}
|
||||
|
||||
getBerryEffectFunc(this.chosenBerry.berryType)(target); // target eats the berry
|
||||
|
||||
const preserve = new Utils.BooleanHolder(false);
|
||||
target.scene.applyModifiers(PreserveBerryModifier, target.isPlayer(), target, preserve);
|
||||
|
||||
if (!preserve.value){ // remove the eaten berry if not preserved
|
||||
if (!--this.chosenBerry.stackCount)
|
||||
target.scene.removeModifier(this.chosenBerry, !target.isPlayer());
|
||||
target.scene.updateModifiers(target.isPlayer());
|
||||
}
|
||||
this.chosenBerry = undefined;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
getTargetHeldBerries(target: Pokemon): BerryModifier[] {
|
||||
return target.scene.findModifiers(m => m instanceof BerryModifier
|
||||
&& (m as BerryModifier).pokemonId === target.id, target.isPlayer()) as BerryModifier[];
|
||||
}
|
||||
|
||||
}
|
||||
/**
|
||||
* Attribute used for moves that steal a random berry from the target. The user then eats the stolen berry.
|
||||
* Used for Pluck & Bug Bite.
|
||||
*/
|
||||
export class StealEatBerryAttr extends EatBerryAttr {
|
||||
constructor() {
|
||||
super();
|
||||
}
|
||||
/**
|
||||
* User steals a random berry from the target and then eats it.
|
||||
* @param {Pokemon} user Pokemon that used the move and will eat the stolen berry
|
||||
* @param {Pokemon} target Pokemon that will have its berry stolen
|
||||
* @param {Move} move Move being used
|
||||
* @param {any[]} args Unused
|
||||
* @returns {boolean} true if the function succeeds
|
||||
*/
|
||||
apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): boolean {
|
||||
|
||||
const cancelled = new Utils.BooleanHolder(false);
|
||||
applyAbAttrs(BlockItemTheftAbAttr, target, cancelled); // check for abilities that block item theft
|
||||
if(cancelled.value == true)
|
||||
return false;
|
||||
|
||||
const heldBerries = this.getTargetHeldBerries(target).filter(i => i.getTransferrable(false));
|
||||
|
||||
if (heldBerries.length) { // if the target has berries, pick a random berry and steal it
|
||||
this.chosenBerry = heldBerries[user.randSeedInt(heldBerries.length)];
|
||||
|
||||
if (this.chosenBerry.stackCount == 1) // remove modifier if its the last berry
|
||||
target.scene.removeModifier(this.chosenBerry, !target.isPlayer());
|
||||
target.scene.updateModifiers(target.isPlayer());
|
||||
|
||||
user.scene.queueMessage(getPokemonMessage(user, ` stole and ate\n${target.name}'s ${this.chosenBerry.type.name}!`));
|
||||
return super.apply(user, user, move, args);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
export class HealStatusEffectAttr extends MoveEffectAttr {
|
||||
private effects: StatusEffect[];
|
||||
|
||||
@ -3568,6 +3694,67 @@ export class RemoveScreensAttr extends MoveEffectAttr {
|
||||
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Attribute used for Revival Blessing.
|
||||
* @extends MoveEffectAttr
|
||||
* @see {@linkcode apply}
|
||||
*/
|
||||
export class RevivalBlessingAttr extends MoveEffectAttr {
|
||||
constructor(user?: boolean) {
|
||||
super(true);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param user {@linkcode Pokemon} using this move
|
||||
* @param target {@linkcode Pokemon} target of this move
|
||||
* @param move {@linkcode Move} being used
|
||||
* @param args N/A
|
||||
* @returns Promise, true if function succeeds.
|
||||
*/
|
||||
apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): Promise<boolean> {
|
||||
return new Promise(resolve => {
|
||||
// If user is player, checks if the user has fainted pokemon
|
||||
if(user instanceof PlayerPokemon
|
||||
&& user.scene.getParty().findIndex(p => p.isFainted())>-1) {
|
||||
(user as PlayerPokemon).revivalBlessing().then(() => {
|
||||
resolve(true)
|
||||
});
|
||||
// If user is enemy, checks that it is a trainer, and it has fainted non-boss pokemon in party
|
||||
} else if(user instanceof EnemyPokemon
|
||||
&& user.hasTrainer()
|
||||
&& user.scene.getEnemyParty().findIndex(p => p.isFainted() && !p.isBoss()) > -1) {
|
||||
// Selects a random fainted pokemon
|
||||
const faintedPokemon = user.scene.getEnemyParty().filter(p => p.isFainted() && !p.isBoss());
|
||||
const pokemon = faintedPokemon[user.randSeedInt(faintedPokemon.length)];
|
||||
const slotIndex = user.scene.getEnemyParty().findIndex(p => pokemon.id === p.id);
|
||||
pokemon.resetStatus();
|
||||
pokemon.heal(Math.min(Math.max(Math.ceil(Math.floor(0.5 * pokemon.getMaxHp())), 1), pokemon.getMaxHp()));
|
||||
user.scene.queueMessage(`${pokemon.name} was revived!`,0,true);
|
||||
|
||||
if(user.scene.currentBattle.double && user.scene.getEnemyParty().length > 1) {
|
||||
const allyPokemon = user.getAlly();
|
||||
if(slotIndex<=1) {
|
||||
user.scene.unshiftPhase(new SwitchSummonPhase(user.scene, pokemon.getFieldIndex(), slotIndex, false, false, false));
|
||||
} else if(allyPokemon.isFainted()){
|
||||
user.scene.unshiftPhase(new SwitchSummonPhase(user.scene, allyPokemon.getFieldIndex(), slotIndex, false, false,false));
|
||||
}
|
||||
}
|
||||
resolve(true);
|
||||
} else {
|
||||
user.scene.queueMessage(`But it failed!`);
|
||||
resolve(false);
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
getUserBenefitScore(user: Pokemon, target: Pokemon, move: Move): integer {
|
||||
if(user.hasTrainer() && user.scene.getEnemyParty().findIndex(p => p.isFainted() && !p.isBoss()) > -1)
|
||||
return 20;
|
||||
|
||||
return -20;
|
||||
}
|
||||
}
|
||||
|
||||
export class ForceSwitchOutAttr extends MoveEffectAttr {
|
||||
private user: boolean;
|
||||
@ -5556,7 +5743,7 @@ export function initMoves() {
|
||||
.makesContact(false)
|
||||
.ignoresProtect(),
|
||||
new AttackMove(Moves.PLUCK, Type.FLYING, MoveCategory.PHYSICAL, 60, 100, 20, -1, 0, 4)
|
||||
.partial(),
|
||||
.attr(StealEatBerryAttr),
|
||||
new StatusMove(Moves.TAILWIND, Type.FLYING, -1, 15, -1, 0, 4)
|
||||
.windMove()
|
||||
.attr(AddArenaTagAttr, ArenaTagType.TAILWIND, 4, true)
|
||||
@ -5793,7 +5980,7 @@ export function initMoves() {
|
||||
new AttackMove(Moves.JUDGMENT, Type.NORMAL, MoveCategory.SPECIAL, 100, 100, 10, -1, 0, 4)
|
||||
.partial(),
|
||||
new AttackMove(Moves.BUG_BITE, Type.BUG, MoveCategory.PHYSICAL, 60, 100, 20, -1, 0, 4)
|
||||
.partial(),
|
||||
.attr(StealEatBerryAttr),
|
||||
new AttackMove(Moves.CHARGE_BEAM, Type.ELECTRIC, MoveCategory.SPECIAL, 50, 90, 10, 70, 0, 4)
|
||||
.attr(StatChangeAttr, BattleStat.SPATK, 1, true),
|
||||
new AttackMove(Moves.WOOD_HAMMER, Type.GRASS, MoveCategory.PHYSICAL, 120, 100, 15, -1, 0, 4)
|
||||
@ -6655,8 +6842,8 @@ export function initMoves() {
|
||||
.makesContact(false)
|
||||
.partial(),
|
||||
new StatusMove(Moves.TEATIME, Type.NORMAL, -1, 10, -1, 0, 8)
|
||||
.target(MoveTarget.ALL)
|
||||
.unimplemented(),
|
||||
.attr(EatBerryAttr)
|
||||
.target(MoveTarget.ALL),
|
||||
new StatusMove(Moves.OCTOLOCK, Type.FIGHTING, 100, 15, -1, 0, 8)
|
||||
.attr(AddBattlerTagAttr, BattlerTagType.TRAPPED, false, true, 1)
|
||||
.partial(),
|
||||
@ -6826,7 +7013,7 @@ export function initMoves() {
|
||||
.condition(failIfDampCondition)
|
||||
.makesContact(false),
|
||||
new AttackMove(Moves.GRASSY_GLIDE, Type.GRASS, MoveCategory.PHYSICAL, 55, 100, 20, -1, 0, 8)
|
||||
.partial(),
|
||||
.attr(IncrementMovePriorityAttr,(user,target,move) =>user.scene.arena.getTerrainType()===TerrainType.GRASSY&&user.isGrounded()),
|
||||
new AttackMove(Moves.RISING_VOLTAGE, Type.ELECTRIC, MoveCategory.SPECIAL, 70, 100, 20, -1, 0, 8)
|
||||
.attr(MovePowerMultiplierAttr, (user, target, move) => user.scene.arena.getTerrainType() === TerrainType.ELECTRIC && target.isGrounded() ? 2 : 1),
|
||||
new AttackMove(Moves.TERRAIN_PULSE, Type.NORMAL, MoveCategory.SPECIAL, 50, 100, 10, -1, 0, 8)
|
||||
@ -7109,7 +7296,8 @@ export function initMoves() {
|
||||
.partial(),
|
||||
new StatusMove(Moves.REVIVAL_BLESSING, Type.NORMAL, -1, 1, -1, 0, 9)
|
||||
.triageMove()
|
||||
.unimplemented(),
|
||||
.attr(RevivalBlessingAttr)
|
||||
.target(MoveTarget.USER),
|
||||
new AttackMove(Moves.SALT_CURE, Type.ROCK, MoveCategory.PHYSICAL, 40, 100, 15, -1, 0, 9)
|
||||
.attr(AddBattlerTagAttr, BattlerTagType.SALT_CURED)
|
||||
.makesContact(false),
|
||||
|
@ -60026,10 +60026,14 @@ export const tmSpecies: TmSpecies = {
|
||||
Species.ARCANINE,
|
||||
Species.AERODACTYL,
|
||||
Species.MEW,
|
||||
Species.CROCONAW,
|
||||
Species.FERALIGATR,
|
||||
Species.ESPEON,
|
||||
Species.GIRAFARIG,
|
||||
Species.GLIGAR,
|
||||
Species.STEELIX,
|
||||
Species.SNUBBULL,
|
||||
Species.GRANBULL,
|
||||
Species.HOUNDOUR,
|
||||
Species.HOUNDOOM,
|
||||
Species.POOCHYENA,
|
||||
|
@ -17,7 +17,7 @@ import { initMoveAnim, loadMoveAnimAssets } from '../data/battle-anims';
|
||||
import { Status, StatusEffect, getRandomStatus } from '../data/status-effect';
|
||||
import { pokemonEvolutions, pokemonPrevolutions, SpeciesFormEvolution, SpeciesEvolutionCondition, FusionSpeciesFormEvolution } from '../data/pokemon-evolutions';
|
||||
import { reverseCompatibleTms, tmSpecies, tmPoolTiers } from '../data/tms';
|
||||
import { DamagePhase, FaintPhase, LearnMovePhase, ObtainStatusEffectPhase, StatChangePhase, SwitchSummonPhase } from '../phases';
|
||||
import { DamagePhase, FaintPhase, LearnMovePhase, ObtainStatusEffectPhase, StatChangePhase, SwitchPhase, SwitchSummonPhase, ToggleDoublePositionPhase } from '../phases';
|
||||
import { BattleStat } from '../data/battle-stat';
|
||||
import { BattlerTag, BattlerTagLapseType, EncoreTag, HelpingHandTag, HighestStatBoostTag, TypeBoostTag, getBattlerTag } from '../data/battler-tags';
|
||||
import { BattlerTagType } from "../data/enums/battler-tag-type";
|
||||
@ -1659,6 +1659,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
|
||||
this.scene.gameData.gameStats.highestDamage = damage.value;
|
||||
}
|
||||
source.turnData.damageDealt += damage.value;
|
||||
source.turnData.currDamageDealt = damage.value;
|
||||
this.battleData.hitCount++;
|
||||
const attackResult = { move: move.id, result: result as DamageResult, damage: damage.value, critical: isCritical, sourceId: source.id };
|
||||
this.turnData.attacksReceived.unshift(attackResult);
|
||||
@ -2680,6 +2681,42 @@ export class PlayerPokemon extends Pokemon {
|
||||
sd.friendship = Math.max((sd.friendship || 0) + starterAmount.value, 0);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Handles Revival Blessing when used by player.
|
||||
* @returns Promise to revive a pokemon.
|
||||
* @see {@linkcode RevivalBlessingAttr}
|
||||
*/
|
||||
revivalBlessing(): Promise<void> {
|
||||
return new Promise(resolve => {
|
||||
this.scene.ui.setMode(Mode.PARTY, PartyUiMode.REVIVAL_BLESSING, this.getFieldIndex(), (slotIndex:integer, option: PartyOption) => {
|
||||
if(slotIndex >= 0 && slotIndex<6) {
|
||||
const pokemon = this.scene.getParty()[slotIndex];
|
||||
if(!pokemon || !pokemon.isFainted())
|
||||
resolve();
|
||||
|
||||
pokemon.resetTurnData();
|
||||
pokemon.resetStatus();
|
||||
pokemon.heal(Math.min(Math.max(Math.ceil(Math.floor(0.5 * pokemon.getMaxHp())), 1), pokemon.getMaxHp()));
|
||||
this.scene.queueMessage(`${pokemon.name} was revived!`,0,true);
|
||||
|
||||
if(this.scene.currentBattle.double && this.scene.getParty().length > 1) {
|
||||
const allyPokemon = this.getAlly();
|
||||
if(slotIndex<=1) {
|
||||
// Revived ally pokemon
|
||||
this.scene.unshiftPhase(new SwitchSummonPhase(this.scene, pokemon.getFieldIndex(), slotIndex, false, false, true));
|
||||
this.scene.unshiftPhase(new ToggleDoublePositionPhase(this.scene, true));
|
||||
} else if(allyPokemon.isFainted()) {
|
||||
// Revived party pokemon, and ally pokemon is fainted
|
||||
this.scene.unshiftPhase(new SwitchSummonPhase(this.scene, allyPokemon.getFieldIndex(), slotIndex, false, false, true));
|
||||
this.scene.unshiftPhase(new ToggleDoublePositionPhase(this.scene, true));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
this.scene.ui.setMode(Mode.MESSAGE).then(() => resolve());
|
||||
}, PartyUiHandler.FilterFainted)
|
||||
})
|
||||
}
|
||||
|
||||
getPossibleEvolution(evolution: SpeciesFormEvolution): Promise<Pokemon> {
|
||||
return new Promise(resolve => {
|
||||
@ -3381,6 +3418,7 @@ export class PokemonTurnData {
|
||||
public hitCount: integer;
|
||||
public hitsLeft: integer;
|
||||
public damageDealt: integer = 0;
|
||||
public currDamageDealt: integer = 0;
|
||||
public damageTaken: integer = 0;
|
||||
public attacksReceived: AttackMoveResult[] = [];
|
||||
}
|
||||
|
@ -20,6 +20,7 @@ import { tutorial } from "./tutorial";
|
||||
import { weather } from "./weather";
|
||||
import { battleMessageUiHandler } from "./battle-message-ui-handler";
|
||||
import { berry } from "./berry";
|
||||
import { voucher } from "./voucher";
|
||||
|
||||
export const deConfig = {
|
||||
ability: ability,
|
||||
@ -46,4 +47,5 @@ export const deConfig = {
|
||||
weather: weather,
|
||||
battleMessageUiHandler: battleMessageUiHandler,
|
||||
berry: berry,
|
||||
}
|
||||
voucher: voucher,
|
||||
}
|
||||
|
11
src/locales/de/voucher.ts
Normal file
11
src/locales/de/voucher.ts
Normal file
@ -0,0 +1,11 @@
|
||||
import { SimpleTranslationEntries } from "#app/plugins/i18n";
|
||||
|
||||
export const voucher: SimpleTranslationEntries = {
|
||||
"vouchers": "Vouchers",
|
||||
"eggVoucher": "Egg Voucher",
|
||||
"eggVoucherPlus": "Egg Voucher Plus",
|
||||
"eggVoucherPremium": "Egg Voucher Premium",
|
||||
"eggVoucherGold": "Egg Voucher Gold",
|
||||
"locked": "Locked",
|
||||
"defeatTrainer": "Defeat {{trainerName}}"
|
||||
} as const;
|
@ -20,6 +20,7 @@ import { tutorial } from "./tutorial";
|
||||
import { weather } from "./weather";
|
||||
import { battleMessageUiHandler } from "./battle-message-ui-handler";
|
||||
import { berry } from "./berry";
|
||||
import { voucher } from "./voucher";
|
||||
|
||||
export const enConfig = {
|
||||
ability: ability,
|
||||
@ -46,4 +47,5 @@ export const enConfig = {
|
||||
weather: weather,
|
||||
battleMessageUiHandler: battleMessageUiHandler,
|
||||
berry: berry,
|
||||
}
|
||||
voucher: voucher,
|
||||
}
|
||||
|
11
src/locales/en/voucher.ts
Normal file
11
src/locales/en/voucher.ts
Normal file
@ -0,0 +1,11 @@
|
||||
import { SimpleTranslationEntries } from "#app/plugins/i18n";
|
||||
|
||||
export const voucher: SimpleTranslationEntries = {
|
||||
"vouchers": "Vouchers",
|
||||
"eggVoucher": "Egg Voucher",
|
||||
"eggVoucherPlus": "Egg Voucher Plus",
|
||||
"eggVoucherPremium": "Egg Voucher Premium",
|
||||
"eggVoucherGold": "Egg Voucher Gold",
|
||||
"locked": "Locked",
|
||||
"defeatTrainer": "Defeat {{trainerName}}"
|
||||
} as const;
|
@ -20,6 +20,7 @@ import { tutorial } from "./tutorial";
|
||||
import { weather } from "./weather";
|
||||
import { battleMessageUiHandler } from "./battle-message-ui-handler";
|
||||
import { berry } from "./berry";
|
||||
import { voucher } from "./voucher";
|
||||
|
||||
export const esConfig = {
|
||||
ability: ability,
|
||||
@ -46,4 +47,5 @@ export const esConfig = {
|
||||
weather: weather,
|
||||
battleMessageUiHandler: battleMessageUiHandler,
|
||||
berry: berry,
|
||||
}
|
||||
voucher: voucher,
|
||||
}
|
||||
|
11
src/locales/es/voucher.ts
Normal file
11
src/locales/es/voucher.ts
Normal file
@ -0,0 +1,11 @@
|
||||
import { SimpleTranslationEntries } from "#app/plugins/i18n";
|
||||
|
||||
export const voucher: SimpleTranslationEntries = {
|
||||
"vouchers": "Vouchers",
|
||||
"eggVoucher": "Egg Voucher",
|
||||
"eggVoucherPlus": "Egg Voucher Plus",
|
||||
"eggVoucherPremium": "Egg Voucher Premium",
|
||||
"eggVoucherGold": "Egg Voucher Gold",
|
||||
"locked": "Locked",
|
||||
"defeatTrainer": "Defeat {{trainerName}}"
|
||||
} as const;
|
@ -20,6 +20,7 @@ import { tutorial } from "./tutorial";
|
||||
import { weather } from "./weather";
|
||||
import { battleMessageUiHandler } from "./battle-message-ui-handler";
|
||||
import { berry } from "./berry";
|
||||
import { voucher } from "./voucher";
|
||||
|
||||
export const frConfig = {
|
||||
ability: ability,
|
||||
@ -46,4 +47,5 @@ export const frConfig = {
|
||||
weather: weather,
|
||||
battleMessageUiHandler: battleMessageUiHandler,
|
||||
berry: berry,
|
||||
}
|
||||
voucher: voucher,
|
||||
}
|
||||
|
11
src/locales/fr/voucher.ts
Normal file
11
src/locales/fr/voucher.ts
Normal file
@ -0,0 +1,11 @@
|
||||
import { SimpleTranslationEntries } from "#app/plugins/i18n";
|
||||
|
||||
export const voucher: SimpleTranslationEntries = {
|
||||
"vouchers": "Coupons",
|
||||
"eggVoucher": "Coupon Œuf",
|
||||
"eggVoucherPlus": "Coupon Œuf +",
|
||||
"eggVoucherPremium": "Coupon Œuf Premium",
|
||||
"eggVoucherGold": "Coupon Œuf Or",
|
||||
"locked": "Verrouillé",
|
||||
"defeatTrainer": "Vaincre {{trainerName}}"
|
||||
} as const;
|
@ -20,6 +20,7 @@ import { tutorial } from "./tutorial";
|
||||
import { weather } from "./weather";
|
||||
import { battleMessageUiHandler } from "./battle-message-ui-handler";
|
||||
import { berry } from "./berry";
|
||||
import { voucher } from "./voucher";
|
||||
|
||||
export const itConfig = {
|
||||
ability: ability,
|
||||
@ -46,4 +47,5 @@ export const itConfig = {
|
||||
weather: weather,
|
||||
battleMessageUiHandler: battleMessageUiHandler,
|
||||
berry: berry,
|
||||
}
|
||||
voucher: voucher,
|
||||
}
|
||||
|
11
src/locales/it/voucher.ts
Normal file
11
src/locales/it/voucher.ts
Normal file
@ -0,0 +1,11 @@
|
||||
import { SimpleTranslationEntries } from "#app/plugins/i18n";
|
||||
|
||||
export const voucher: SimpleTranslationEntries = {
|
||||
"vouchers": "Vouchers",
|
||||
"eggVoucher": "Egg Voucher",
|
||||
"eggVoucherPlus": "Egg Voucher Plus",
|
||||
"eggVoucherPremium": "Egg Voucher Premium",
|
||||
"eggVoucherGold": "Egg Voucher Gold",
|
||||
"locked": "Locked",
|
||||
"defeatTrainer": "Defeat {{trainerName}}"
|
||||
} as const;
|
@ -19,6 +19,7 @@ import { titles, trainerClasses, trainerNames } from "./trainers";
|
||||
import { tutorial } from "./tutorial";
|
||||
import { weather } from "./weather";
|
||||
import { berry } from "./berry";
|
||||
import { voucher } from "./voucher";
|
||||
|
||||
|
||||
export const ptBrConfig = {
|
||||
@ -45,4 +46,5 @@ export const ptBrConfig = {
|
||||
weather: weather,
|
||||
modifierType: modifierType,
|
||||
berry: berry,
|
||||
voucher: voucher,
|
||||
}
|
||||
|
11
src/locales/pt_BR/voucher.ts
Normal file
11
src/locales/pt_BR/voucher.ts
Normal file
@ -0,0 +1,11 @@
|
||||
import { SimpleTranslationEntries } from "#app/plugins/i18n";
|
||||
|
||||
export const voucher: SimpleTranslationEntries = {
|
||||
"vouchers": "Vouchers",
|
||||
"eggVoucher": "Egg Voucher",
|
||||
"eggVoucherPlus": "Egg Voucher Plus",
|
||||
"eggVoucherPremium": "Egg Voucher Premium",
|
||||
"eggVoucherGold": "Egg Voucher Gold",
|
||||
"locked": "Locked",
|
||||
"defeatTrainer": "Defeat {{trainerName}}"
|
||||
} as const;
|
@ -2,7 +2,7 @@ import { ability } from "./ability";
|
||||
import { abilityTriggers } from "./ability-trigger";
|
||||
import { battle } from "./battle";
|
||||
import { commandUiHandler } from "./command-ui-handler";
|
||||
// import { egg } from "./egg";
|
||||
import { egg } from "./egg";
|
||||
import { fightUiHandler } from "./fight-ui-handler";
|
||||
import { growth } from "./growth";
|
||||
import { menu } from "./menu";
|
||||
@ -20,6 +20,7 @@ import { tutorial } from "./tutorial";
|
||||
import { weather } from "./weather";
|
||||
import { battleMessageUiHandler } from "./battle-message-ui-handler";
|
||||
import { berry } from "./berry";
|
||||
import { voucher } from "./voucher";
|
||||
|
||||
|
||||
export const zhCnConfig = {
|
||||
@ -27,7 +28,7 @@ export const zhCnConfig = {
|
||||
abilityTriggers: abilityTriggers,
|
||||
battle: battle,
|
||||
commandUiHandler: commandUiHandler,
|
||||
// egg: egg,
|
||||
egg: egg,
|
||||
fightUiHandler: fightUiHandler,
|
||||
growth: growth,
|
||||
menu: menu,
|
||||
@ -47,4 +48,5 @@ export const zhCnConfig = {
|
||||
weather: weather,
|
||||
battleMessageUiHandler: battleMessageUiHandler,
|
||||
berry: berry,
|
||||
}
|
||||
voucher: voucher,
|
||||
}
|
||||
|
21
src/locales/zh_CN/egg.ts
Normal file
21
src/locales/zh_CN/egg.ts
Normal file
@ -0,0 +1,21 @@
|
||||
import { SimpleTranslationEntries } from "#app/plugins/i18n";
|
||||
|
||||
export const egg: SimpleTranslationEntries = {
|
||||
"egg": "蛋",
|
||||
"greatTier": "稀有",
|
||||
"ultraTier": "史诗",
|
||||
"masterTier": "传说",
|
||||
"defaultTier": "普通",
|
||||
"hatchWavesMessageSoon": "里面传来声音!\n似乎快要孵化了!",
|
||||
"hatchWavesMessageClose": "有时好像会动一下。\n就快孵化了吧?",
|
||||
"hatchWavesMessageNotClose": "会孵化出什么呢?\n看来还需要很长时\n间才能孵化。",
|
||||
"hatchWavesMessageLongTime": "这个蛋需要很长时间\n才能孵化。",
|
||||
"gachaTypeLegendary": "传说概率上升",
|
||||
"gachaTypeMove": "稀有概率上升",
|
||||
"gachaTypeShiny": "闪光概率上升",
|
||||
"selectMachine": "选择一个机器。",
|
||||
"notEnoughVouchers": "你没有足够的兑换券!",
|
||||
"tooManyEggs": "你的蛋太多啦!",
|
||||
"pull": "次",
|
||||
"pulls": "次"
|
||||
} as const;
|
11
src/locales/zh_CN/voucher.ts
Normal file
11
src/locales/zh_CN/voucher.ts
Normal file
@ -0,0 +1,11 @@
|
||||
import { SimpleTranslationEntries } from "#app/plugins/i18n";
|
||||
|
||||
export const voucher: SimpleTranslationEntries = {
|
||||
"vouchers": "兑换券",
|
||||
"eggVoucher": "初级扭蛋券",
|
||||
"eggVoucherPlus": "中级扭蛋券",
|
||||
"eggVoucherPremium": "高级扭蛋券",
|
||||
"eggVoucherGold": "黄金扭蛋券",
|
||||
"locked": "锁定",
|
||||
"defeatTrainer": "你打败了{{trainerName}}"
|
||||
} as const;
|
@ -1423,7 +1423,7 @@ export class ExpBalanceModifier extends PersistentModifier {
|
||||
}
|
||||
|
||||
getMaxStackCount(scene: BattleScene): integer {
|
||||
return 5;
|
||||
return 4;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2,7 +2,7 @@ import BattleScene, { AnySound, bypassLogin, startingWave } from "./battle-scene
|
||||
import { default as Pokemon, PlayerPokemon, EnemyPokemon, PokemonMove, MoveResult, DamageResult, FieldPosition, HitResult, TurnMove } from "./field/pokemon";
|
||||
import * as Utils from './utils';
|
||||
import { Moves } from "./data/enums/moves";
|
||||
import { allMoves, applyMoveAttrs, BypassSleepAttr, ChargeAttr, applyFilteredMoveAttrs, HitsTagAttr, MissEffectAttr, MoveAttr, MoveEffectAttr, MoveFlags, MultiHitAttr, OverrideMoveEffectAttr, VariableAccuracyAttr, MoveTarget, OneHitKOAttr, getMoveTargets, MoveTargetSet, MoveEffectTrigger, CopyMoveAttr, AttackMove, SelfStatusMove, DelayedAttackAttr, RechargeAttr, PreMoveMessageAttr, HealStatusEffectAttr, IgnoreOpponentStatChangesAttr, NoEffectAttr, BypassRedirectAttr, FixedDamageAttr, PostVictoryStatChangeAttr, OneHitKOAccuracyAttr, ForceSwitchOutAttr, VariableTargetAttr, SacrificialAttr } from "./data/move";
|
||||
import { allMoves, applyMoveAttrs, BypassSleepAttr, ChargeAttr, applyFilteredMoveAttrs, HitsTagAttr, MissEffectAttr, MoveAttr, MoveEffectAttr, MoveFlags, MultiHitAttr, OverrideMoveEffectAttr, VariableAccuracyAttr, MoveTarget, OneHitKOAttr, getMoveTargets, MoveTargetSet, MoveEffectTrigger, CopyMoveAttr, AttackMove, SelfStatusMove, DelayedAttackAttr, RechargeAttr, PreMoveMessageAttr, HealStatusEffectAttr, IgnoreOpponentStatChangesAttr, NoEffectAttr, BypassRedirectAttr, FixedDamageAttr, PostVictoryStatChangeAttr, OneHitKOAccuracyAttr, ForceSwitchOutAttr, VariableTargetAttr, SacrificialAttr, IncrementMovePriorityAttr } from "./data/move";
|
||||
import { Mode } from './ui/ui';
|
||||
import { Command } from "./ui/command-ui-handler";
|
||||
import { Stat } from "./data/pokemon-stat";
|
||||
@ -2012,6 +2012,9 @@ export class TurnStartPhase extends FieldPhase {
|
||||
const aPriority = new Utils.IntegerHolder(aMove.priority);
|
||||
const bPriority = new Utils.IntegerHolder(bMove.priority);
|
||||
|
||||
applyMoveAttrs(IncrementMovePriorityAttr,this.scene.getField().find(p => p?.isActive() && p.getBattlerIndex() === a),null,aMove,aPriority);
|
||||
applyMoveAttrs(IncrementMovePriorityAttr,this.scene.getField().find(p => p?.isActive() && p.getBattlerIndex() === b),null,bMove,bPriority);
|
||||
|
||||
applyAbAttrs(IncrementMovePriorityAbAttr, this.scene.getField().find(p => p?.isActive() && p.getBattlerIndex() === a), null, aMove, aPriority);
|
||||
applyAbAttrs(IncrementMovePriorityAbAttr, this.scene.getField().find(p => p?.isActive() && p.getBattlerIndex() === b), null, bMove, bPriority);
|
||||
|
||||
@ -3841,6 +3844,10 @@ export class SwitchPhase extends BattlePhase {
|
||||
if (this.isModal && !this.scene.getParty().filter(p => !p.isFainted() && !p.isActive(true)).length)
|
||||
return super.end();
|
||||
|
||||
// Check if there is any space still in field
|
||||
if (this.isModal && this.scene.getPlayerField().filter(p => !p.isFainted() && p.isActive(true)).length >= this.scene.currentBattle.getBattlerCount())
|
||||
return super.end();
|
||||
|
||||
// Override field index to 0 in case of double battle where 2/3 remaining party members fainted at once
|
||||
const fieldIndex = this.scene.currentBattle.getBattlerCount() === 1 || this.scene.getParty().filter(p => !p.isFainted()).length > 1 ? this.fieldIndex : 0;
|
||||
|
||||
|
@ -153,6 +153,7 @@ declare module 'i18next' {
|
||||
modifierType: ModifierTypeTranslationEntries;
|
||||
battleMessageUiHandler: SimpleTranslationEntries;
|
||||
berry: BerryTranslationEntries;
|
||||
voucher: SimpleTranslationEntries;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
@ -867,8 +867,11 @@ export class GameData {
|
||||
const ret: PersistentModifierData[] = [];
|
||||
if (v === null)
|
||||
v = [];
|
||||
for (let md of v)
|
||||
for (let md of v) {
|
||||
if(md?.className === 'ExpBalanceModifier') // Temporarily limit EXP Balance until it gets reworked
|
||||
md.stackCount = Math.min(md.stackCount, 4);
|
||||
ret.push(new PersistentModifierData(md, player));
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -2,6 +2,7 @@ import BattleScene from "../battle-scene";
|
||||
import { TrainerType } from "../data/enums/trainer-type";
|
||||
import { ModifierTier } from "../modifier/modifier-tier";
|
||||
import { Achv, AchvTier, achvs } from "./achv";
|
||||
import i18next from '../plugins/i18n';
|
||||
|
||||
export enum VoucherType {
|
||||
REGULAR,
|
||||
@ -52,13 +53,13 @@ export class Voucher {
|
||||
export function getVoucherTypeName(voucherType: VoucherType): string {
|
||||
switch (voucherType) {
|
||||
case VoucherType.REGULAR:
|
||||
return 'Egg Voucher';
|
||||
return i18next.t("voucher:eggVoucher");
|
||||
case VoucherType.PLUS:
|
||||
return 'Egg Voucher Plus';
|
||||
return i18next.t("voucher:eggVoucherPlus");
|
||||
case VoucherType.PREMIUM:
|
||||
return 'Egg Voucher Premium';
|
||||
return i18next.t("voucher:eggVoucherPremium");
|
||||
case VoucherType.GOLDEN:
|
||||
return 'Egg Voucher Gold';
|
||||
return i18next.t("voucher:eggVoucherGold");
|
||||
}
|
||||
}
|
||||
|
||||
@ -75,9 +76,8 @@ export function getVoucherTypeIcon(voucherType: VoucherType): string {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
export interface Vouchers {
|
||||
[key: string]: Voucher
|
||||
[key: string]: Voucher;
|
||||
}
|
||||
|
||||
export const vouchers: Vouchers = {};
|
||||
@ -87,6 +87,8 @@ const voucherAchvs: Achv[] = [ achvs.CLASSIC_VICTORY ];
|
||||
{
|
||||
(function() {
|
||||
import('../data/trainer-config').then(tc => {
|
||||
const trainerConfigs = tc.trainerConfigs;
|
||||
|
||||
for (let achv of voucherAchvs) {
|
||||
const voucherType = achv.score >= 150
|
||||
? VoucherType.GOLDEN
|
||||
@ -98,7 +100,6 @@ const voucherAchvs: Achv[] = [ achvs.CLASSIC_VICTORY ];
|
||||
vouchers[achv.id] = new Voucher(voucherType, achv.description);
|
||||
}
|
||||
|
||||
const trainerConfigs = tc.trainerConfigs;
|
||||
const bossTrainerTypes = Object.keys(trainerConfigs)
|
||||
.filter(tt => trainerConfigs[tt].isBoss && trainerConfigs[tt].getDerivedType() !== TrainerType.RIVAL);
|
||||
|
||||
@ -107,12 +108,17 @@ const voucherAchvs: Achv[] = [ achvs.CLASSIC_VICTORY ];
|
||||
? VoucherType.PLUS
|
||||
: VoucherType.PREMIUM;
|
||||
const key = TrainerType[trainerType];
|
||||
vouchers[key] = new Voucher(voucherType, `Defeat ${trainerConfigs[trainerType].name}`);
|
||||
const trainerName = trainerConfigs[trainerType].name;
|
||||
vouchers[key] = new Voucher(
|
||||
voucherType,
|
||||
i18next.t("voucher:defeatTrainer", { trainerName })
|
||||
);
|
||||
}
|
||||
|
||||
const voucherKeys = Object.keys(vouchers);
|
||||
for (let k of voucherKeys)
|
||||
for (let k of voucherKeys) {
|
||||
vouchers[k].id = k;
|
||||
}
|
||||
});
|
||||
})();
|
||||
}
|
||||
}
|
||||
|
213
src/test/pokemonSprite.test.ts
Normal file
213
src/test/pokemonSprite.test.ts
Normal file
@ -0,0 +1,213 @@
|
||||
import {beforeAll, describe, expect, it} from "vitest";
|
||||
import _masterlist from '../../public/images/pokemon/variant/_masterlist.json';
|
||||
import fs from 'fs';
|
||||
import path from 'path';
|
||||
import {getAppRootDir} from "#app/test/testUtils";
|
||||
|
||||
const deepCopy = (data) => {
|
||||
return JSON.parse(JSON.stringify(data));
|
||||
}
|
||||
|
||||
|
||||
describe("check if every variant's sprite are correctly set", () => {
|
||||
let masterlist;
|
||||
let expVariant;
|
||||
let femaleVariant;
|
||||
let backVariant;
|
||||
let rootDir;
|
||||
|
||||
beforeAll(() => {
|
||||
rootDir = `${getAppRootDir()}${path.sep}public${path.sep}images${path.sep}pokemon${path.sep}variant${path.sep}`
|
||||
masterlist = deepCopy(_masterlist);
|
||||
expVariant = masterlist.exp;
|
||||
femaleVariant = masterlist.female;
|
||||
backVariant = masterlist.back;
|
||||
delete masterlist.exp
|
||||
delete masterlist.female
|
||||
delete masterlist.back
|
||||
});
|
||||
|
||||
it('data should not be undefined', () => {
|
||||
expect(masterlist).not.toBeUndefined();
|
||||
expect(expVariant).not.toBeUndefined();
|
||||
expect(femaleVariant).not.toBeUndefined();
|
||||
expect(backVariant).not.toBeUndefined();
|
||||
});
|
||||
|
||||
function getMissingMasterlist(mlist, dirpath, excludes = []) {
|
||||
const errors = [];
|
||||
if (fs.existsSync(dirpath)) {
|
||||
const files = fs.readdirSync(dirpath);
|
||||
for (const filename of files) {
|
||||
const filePath = `${dirpath}${filename}`
|
||||
const ext = filename.split('.')[1];
|
||||
const name = filename.split('.')[0];
|
||||
if (excludes.includes(name)) continue;
|
||||
if (name.includes('_')) {
|
||||
const id = name.split('_')[0];
|
||||
const variant = name.split('_')[1];
|
||||
if (ext !== 'json') {
|
||||
if (mlist.hasOwnProperty(id)) {
|
||||
const urlJsonFile = `${dirpath}${id}.json`;
|
||||
const jsonFileExists = fs.existsSync(urlJsonFile);
|
||||
if (mlist[id].includes(1)) {
|
||||
const msg = `MISSING JSON ${urlJsonFile}`;
|
||||
if (!jsonFileExists && !errors.includes(msg)) errors.push(msg);
|
||||
}
|
||||
}
|
||||
if (!mlist.hasOwnProperty(id)) errors.push(`missing key ${id} in masterlist for ${filePath}`);
|
||||
else if (mlist[id][parseInt(variant, 10) - 1] !== 2) errors.push(`the value should be 2 for the index ${parseInt(variant, 10) - 1} - ${filePath}`);
|
||||
}
|
||||
} else if (!mlist.hasOwnProperty(name)) errors.push(`named - missing key ${name} in masterlist for ${filePath}`);else {
|
||||
const raw = fs.readFileSync(filePath, {encoding: 'utf8', flag: 'r'});
|
||||
const data = JSON.parse(raw);
|
||||
for (const key of Object.keys(data)) {
|
||||
if (mlist[name][key] !== 1) errors.push(`the value should be 1 in the array ${filePath}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return errors;
|
||||
}
|
||||
|
||||
function getMissingFiles(keys, dirPath) {
|
||||
const errors = [];
|
||||
for (const key of Object.keys(keys)) {
|
||||
const row = keys[key];
|
||||
for (const [index, elm] of row.entries()) {
|
||||
let url;
|
||||
if (elm === 0) continue
|
||||
else if (elm === 1) {
|
||||
url = `${key}.json`
|
||||
let filePath = `${dirPath}${url}`;
|
||||
const raw = fs.readFileSync(filePath, {encoding: 'utf8', flag: 'r'});
|
||||
const data = JSON.parse(raw);
|
||||
if (!data.hasOwnProperty(index)) {
|
||||
errors.push(`index: ${index} - ${filePath}`);
|
||||
}
|
||||
} else if (elm === 2) {
|
||||
url = `${key}_${parseInt(index, 10) + 1}.png`;
|
||||
let filePath = `${dirPath}${url}`;
|
||||
if (!fs.existsSync(filePath)) {
|
||||
errors.push(filePath)
|
||||
}
|
||||
|
||||
url = `${key}_${parseInt(index, 10) + 1}.json`;
|
||||
filePath = `${dirPath}${url}`;
|
||||
if (!fs.existsSync(filePath)) {
|
||||
errors.push(filePath)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return errors;
|
||||
}
|
||||
|
||||
// chech presence of every files listed in masterlist
|
||||
|
||||
it('check root variant files', () => {
|
||||
const dirPath = rootDir;
|
||||
const errors = getMissingFiles(masterlist, dirPath);
|
||||
if (errors.length) console.log('errors', errors);
|
||||
expect(errors.length).toBe(0);
|
||||
});
|
||||
|
||||
it('check female variant files', () => {
|
||||
const dirPath = `${rootDir}female${path.sep}`;
|
||||
const errors = getMissingFiles(femaleVariant, dirPath);
|
||||
if (errors.length) console.log('errors', errors);
|
||||
expect(errors.length).toBe(0);
|
||||
});
|
||||
|
||||
it('check back female variant files', () => {
|
||||
const dirPath = `${rootDir}back${path.sep}female${path.sep}`;
|
||||
const errors = getMissingFiles(backVariant.female, dirPath);
|
||||
if (errors.length) console.log('errors', errors);
|
||||
expect(errors.length).toBe(0);
|
||||
});
|
||||
|
||||
it('check back male back variant files', () => {
|
||||
const dirPath = `${rootDir}back${path.sep}`;
|
||||
let backMaleVariant = deepCopy(backVariant);
|
||||
delete backMaleVariant.female;
|
||||
const errors = getMissingFiles(backMaleVariant, dirPath);
|
||||
if (errors.length) console.log('errors', errors);
|
||||
expect(errors.length).toBe(0);
|
||||
});
|
||||
|
||||
it('check exp back variant files', () => {
|
||||
const dirPath = `${rootDir}exp${path.sep}back${path.sep}`;
|
||||
const errors = getMissingFiles(expVariant.back, dirPath);
|
||||
if (errors.length) console.log('errors', errors);
|
||||
expect(errors.length).toBe(0);
|
||||
});
|
||||
|
||||
it('check exp female variant files', () => {
|
||||
const dirPath = `${rootDir}exp${path.sep}female${path.sep}`;
|
||||
const errors = getMissingFiles(expVariant.female, dirPath);
|
||||
if (errors.length) console.log('errors', errors);
|
||||
expect(errors.length).toBe(0);
|
||||
});
|
||||
|
||||
it('check exp male variant files', () => {
|
||||
const dirPath = `${rootDir}exp${path.sep}`;
|
||||
let expMaleVariant = deepCopy(expVariant);
|
||||
delete expMaleVariant.female;
|
||||
delete expMaleVariant.back;
|
||||
const errors = getMissingFiles(expMaleVariant, dirPath);
|
||||
if (errors.length) console.log('errors', errors);
|
||||
expect(errors.length).toBe(0);
|
||||
});
|
||||
|
||||
// check over every file if it's correctly set in the masterlist
|
||||
|
||||
it('look over every file in variant female and check if present in masterlist', () => {
|
||||
const dirPath = `${rootDir}female${path.sep}`;
|
||||
const errors = getMissingMasterlist(femaleVariant, dirPath);
|
||||
if (errors.length) console.log('errors for ', dirPath, errors);
|
||||
expect(errors.length).toBe(0);
|
||||
});
|
||||
|
||||
it('look over every file in variant back female and check if present in masterlist', () => {
|
||||
const dirPath = `${rootDir}back${path.sep}female${path.sep}`;
|
||||
const errors = getMissingMasterlist(backVariant.female, dirPath);
|
||||
if (errors.length) console.log('errors for ', dirPath, errors);
|
||||
expect(errors.length).toBe(0);
|
||||
});
|
||||
|
||||
it('look over every file in variant back male and check if present in masterlist', () => {
|
||||
const dirPath = `${rootDir}back${path.sep}`;
|
||||
let backMaleVariant = deepCopy(backVariant);
|
||||
const errors = getMissingMasterlist(backMaleVariant, dirPath, ['female']);
|
||||
if (errors.length) console.log('errors for ', dirPath, errors);
|
||||
expect(errors.length).toBe(0);
|
||||
});
|
||||
|
||||
it('look over every file in variant exp back and check if present in masterlist', () => {
|
||||
const dirPath = `${rootDir}exp${path.sep}back${path.sep}`;
|
||||
const errors = getMissingMasterlist(expVariant.back, dirPath);
|
||||
if (errors.length) console.log('errors for ', dirPath, errors);
|
||||
expect(errors.length).toBe(0);
|
||||
});
|
||||
|
||||
it('look over every file in variant exp female and check if present in masterlist', () => {
|
||||
const dirPath = `${rootDir}exp${path.sep}female${path.sep}`;
|
||||
const errors = getMissingMasterlist(expVariant.female, dirPath);
|
||||
if (errors.length) console.log('errors for ', dirPath, errors);
|
||||
expect(errors.length).toBe(0);
|
||||
});
|
||||
|
||||
it('look over every file in variant exp male and check if present in masterlist', () => {
|
||||
const dirPath = `${rootDir}exp${path.sep}`;
|
||||
const errors = getMissingMasterlist(expVariant, dirPath, ['back', 'female']);
|
||||
if (errors.length) console.log('errors for ', dirPath, errors);
|
||||
expect(errors.length).toBe(0);
|
||||
});
|
||||
|
||||
it('look over every file in variant root and check if present in masterlist', () => {
|
||||
const dirPath = `${rootDir}`;
|
||||
const errors = getMissingMasterlist(masterlist, dirPath, ['back', 'female', 'exp', 'icons']);
|
||||
if (errors.length) console.log('errors for ', dirPath, errors);
|
||||
expect(errors.length).toBe(0);
|
||||
});
|
||||
});
|
10
src/test/testUtils.ts
Normal file
10
src/test/testUtils.ts
Normal file
@ -0,0 +1,10 @@
|
||||
const fs = require('fs')
|
||||
const path = require('path')
|
||||
|
||||
export function getAppRootDir () {
|
||||
let currentDir = __dirname
|
||||
while(!fs.existsSync(path.join(currentDir, 'package.json'))) {
|
||||
currentDir = path.join(currentDir, '..')
|
||||
}
|
||||
return currentDir
|
||||
}
|
@ -30,13 +30,34 @@ export class DailyRunScoreboard extends Phaser.GameObjects.Container {
|
||||
private pageCount: integer;
|
||||
private page: integer;
|
||||
private category: ScoreboardCategory;
|
||||
|
||||
private _isUpdating: boolean;
|
||||
|
||||
constructor(scene: BattleScene, x: number, y: number) {
|
||||
super(scene, x, y);
|
||||
|
||||
this._isUpdating = false;
|
||||
this.setup();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the updating state and updates button states accordingly.
|
||||
* If value is true (updating), disables the buttons; if false, enables the buttons.
|
||||
* @param {boolean} value - The new updating state.
|
||||
*/
|
||||
set isUpdating(value) {
|
||||
this._isUpdating = value;
|
||||
this.setButtonsState(!value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the current updating state.
|
||||
* @returns {boolean} - The current updating state.
|
||||
*/
|
||||
get isUpdating() {
|
||||
return this._isUpdating;
|
||||
}
|
||||
|
||||
setup() {
|
||||
const titleWindow = addWindow(this.scene, 0, 0, 114, 18, false, false, null, null, WindowVariant.THIN);
|
||||
this.add(titleWindow);
|
||||
@ -140,7 +161,24 @@ export class DailyRunScoreboard extends Phaser.GameObjects.Container {
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the scoreboard rankings based on the selected category and page.
|
||||
*
|
||||
* If the update process is already ongoing, the method exits early. Otherwise, it begins the update process by clearing
|
||||
* the current rankings and showing a loading label. If the category changes, the page is reset to 1.
|
||||
*
|
||||
* The method fetches the total page count if necessary, followed by fetching the rankings for the specified category
|
||||
* and page. It updates the UI with the fetched rankings or shows an appropriate message if no rankings are found.
|
||||
*
|
||||
* @param {ScoreboardCategory} [category=this.category] - The category to fetch rankings for. Defaults to the current category.
|
||||
* @param {number} [page=this.page] - The page number to fetch. Defaults to the current page.
|
||||
*/
|
||||
update(category: ScoreboardCategory = this.category, page: integer = this.page) {
|
||||
if (this.isUpdating) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.isUpdating = true;
|
||||
this.rankingsContainer.removeAll(true);
|
||||
|
||||
this.loadingLabel.setText(i18next.t('menu:loading'));
|
||||
@ -150,7 +188,7 @@ export class DailyRunScoreboard extends Phaser.GameObjects.Container {
|
||||
this.page = page = 1;
|
||||
|
||||
Utils.executeIf(category !== this.category || this.pageCount === undefined,
|
||||
() => Utils.apiFetch(`daily/rankingpagecount?category=${category}`).then(response => response.json()).then(count => this.pageCount = count)
|
||||
() => Utils.apiFetch(`daily/rankingpagecount?category=${category}`).then(response => response.json()).then(count => this.pageCount = count)
|
||||
).then(() => {
|
||||
Utils.apiFetch(`daily/rankings?category=${category}&page=${page}`)
|
||||
.then(response => response.json())
|
||||
@ -158,16 +196,40 @@ export class DailyRunScoreboard extends Phaser.GameObjects.Container {
|
||||
this.page = page;
|
||||
this.category = category;
|
||||
this.titleLabel.setText(`${i18next.t(`menu:${ScoreboardCategory[category].toLowerCase()}Rankings`)}`);
|
||||
this.prevPageButton.setAlpha(page > 1 ? 1 : 0.5);
|
||||
this.nextPageButton.setAlpha(page < this.pageCount ? 1 : 0.5);
|
||||
this.pageNumberLabel.setText(page.toString());
|
||||
if (jsonResponse) {
|
||||
this.loadingLabel.setVisible(false);
|
||||
this.updateRankings(jsonResponse);
|
||||
} else
|
||||
this.loadingLabel.setText(i18next.t('menu:noRankings'));
|
||||
}).finally(() => {
|
||||
this.isUpdating = false;
|
||||
});
|
||||
}).catch(err => { console.error("Failed to load daily rankings:\n", err) });
|
||||
}).catch(err => {
|
||||
console.error("Failed to load daily rankings:\n", err)
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the state of the navigation buttons.
|
||||
* @param {boolean} [enabled=true] - Whether the buttons should be enabled or disabled.
|
||||
*/
|
||||
setButtonsState(enabled: boolean = true) {
|
||||
const buttons = [
|
||||
{ button: this.prevPageButton, alphaValue: enabled ? (this.page > 1 ? 1 : 0.5) : 0.5 },
|
||||
{ button: this.nextPageButton, alphaValue: enabled ? (this.page < this.pageCount ? 1 : 0.5) : 0.5 },
|
||||
{ button: this.nextCategoryButton, alphaValue: enabled ? 1 : 0.5 },
|
||||
{ button: this.prevCategoryButton, alphaValue: enabled ? 1 : 0.5 }
|
||||
];
|
||||
|
||||
buttons.forEach(({ button, alphaValue }) => {
|
||||
if (enabled) {
|
||||
button.setInteractive();
|
||||
} else {
|
||||
button.disableInteractive();
|
||||
}
|
||||
button.setAlpha(alphaValue);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -24,6 +24,7 @@ export enum PartyUiMode {
|
||||
SWITCH,
|
||||
FAINT_SWITCH,
|
||||
POST_BATTLE_SWITCH,
|
||||
REVIVAL_BLESSING,
|
||||
MODIFIER,
|
||||
MOVE_MODIFIER,
|
||||
TM_MODIFIER,
|
||||
@ -37,6 +38,7 @@ export enum PartyOption {
|
||||
CANCEL = -1,
|
||||
SEND_OUT,
|
||||
PASS_BATON,
|
||||
REVIVE,
|
||||
APPLY,
|
||||
TEACH,
|
||||
TRANSFER,
|
||||
@ -103,6 +105,12 @@ export default class PartyUiHandler extends MessageUiHandler {
|
||||
return null;
|
||||
};
|
||||
|
||||
public static FilterFainted = (pokemon: PlayerPokemon) => {
|
||||
if(!pokemon.isFainted())
|
||||
return `${pokemon.name} still has energy\nto battle!`;
|
||||
return null;
|
||||
}
|
||||
|
||||
private static FilterAllMoves = (_pokemonMove: PokemonMove) => null;
|
||||
|
||||
public static FilterItemMaxStacks = (pokemon: PlayerPokemon, modifier: PokemonHeldItemModifier) => {
|
||||
@ -361,7 +369,7 @@ export default class PartyUiHandler extends MessageUiHandler {
|
||||
if (this.cursor < 6) {
|
||||
this.showOptions();
|
||||
ui.playSelect();
|
||||
} else if (this.partyUiMode === PartyUiMode.FAINT_SWITCH)
|
||||
} else if (this.partyUiMode === PartyUiMode.FAINT_SWITCH || this.partyUiMode === PartyUiMode.REVIVAL_BLESSING)
|
||||
ui.playError();
|
||||
else
|
||||
return this.processInput(Button.CANCEL);
|
||||
@ -370,7 +378,7 @@ export default class PartyUiHandler extends MessageUiHandler {
|
||||
if ((this.partyUiMode === PartyUiMode.MODIFIER_TRANSFER || this.partyUiMode === PartyUiMode.SPLICE) && this.transferMode) {
|
||||
this.clearTransfer();
|
||||
ui.playSelect();
|
||||
} else if (this.partyUiMode !== PartyUiMode.FAINT_SWITCH) {
|
||||
} else if (this.partyUiMode !== PartyUiMode.FAINT_SWITCH && this.partyUiMode !== PartyUiMode.REVIVAL_BLESSING) {
|
||||
if (this.selectCallback) {
|
||||
const selectCallback = this.selectCallback;
|
||||
this.selectCallback = null;
|
||||
@ -580,6 +588,9 @@ export default class PartyUiHandler extends MessageUiHandler {
|
||||
this.options.push(PartyOption.FORM_CHANGE_ITEM + i);
|
||||
}
|
||||
break;
|
||||
case PartyUiMode.REVIVAL_BLESSING:
|
||||
this.options.push(PartyOption.REVIVE);
|
||||
break;
|
||||
case PartyUiMode.MODIFIER:
|
||||
this.options.push(PartyOption.APPLY);
|
||||
break;
|
||||
|
@ -42,48 +42,65 @@ export interface Starter {
|
||||
pokerus: boolean;
|
||||
}
|
||||
|
||||
interface LanguageSetting {
|
||||
starterInfoTextSize: string,
|
||||
instructionTextSize: string,
|
||||
starterInfoXPos?: integer,
|
||||
starterInfoYOffset?: integer
|
||||
}
|
||||
|
||||
const languageSettings: { [key: string]: LanguageSetting } = {
|
||||
"en":{
|
||||
starterInfoTextSize: '56px',
|
||||
instructionTextSize: '42px',
|
||||
},
|
||||
"de":{
|
||||
starterInfoTextSize: '56px',
|
||||
instructionTextSize: '35px',
|
||||
},
|
||||
"es":{
|
||||
starterInfoTextSize: '56px',
|
||||
instructionTextSize: '35px',
|
||||
},
|
||||
"it":{
|
||||
starterInfoTextSize: '56px',
|
||||
instructionTextSize: '38px',
|
||||
},
|
||||
"fr":{
|
||||
starterInfoTextSize: '54px',
|
||||
instructionTextSize: '42px',
|
||||
},
|
||||
"zh_CN":{
|
||||
starterInfoTextSize: '40px',
|
||||
instructionTextSize: '42px',
|
||||
starterInfoYOffset: 2
|
||||
},
|
||||
"pt_BR":{
|
||||
starterInfoTextSize: '47px',
|
||||
instructionTextSize: '38px',
|
||||
starterInfoXPos: 32,
|
||||
},
|
||||
}
|
||||
|
||||
const starterCandyCosts: { passive: integer, costReduction: [integer, integer] }[] = [
|
||||
{ passive: 50, costReduction: [30, 75] }, // 1
|
||||
{ passive: 45, costReduction: [25, 60] }, // 2
|
||||
{ passive: 30, costReduction: [20, 50] }, // 3
|
||||
{ passive: 25, costReduction: [15, 40] }, // 4
|
||||
{ passive: 20, costReduction: [12, 35] }, // 5
|
||||
{ passive: 15, costReduction: [10, 30] }, // 6
|
||||
{ passive: 10, costReduction: [8, 20] }, // 7
|
||||
{ passive: 10, costReduction: [5, 15] }, // 8
|
||||
{ passive: 10, costReduction: [3, 10] }, // 9
|
||||
{ passive: 10, costReduction: [3, 10] }, // 10
|
||||
]
|
||||
|
||||
function getPassiveCandyCount(baseValue: integer): integer {
|
||||
switch (baseValue) {
|
||||
case 1:
|
||||
return 50;
|
||||
case 2:
|
||||
return 45;
|
||||
case 3:
|
||||
return 40;
|
||||
case 4:
|
||||
return 30;
|
||||
case 5:
|
||||
return 25;
|
||||
case 6:
|
||||
return 20;
|
||||
case 7:
|
||||
return 15;
|
||||
default:
|
||||
return 10;
|
||||
}
|
||||
return starterCandyCosts[baseValue - 1].passive;
|
||||
}
|
||||
|
||||
function getValueReductionCandyCounts(baseValue: integer): [integer, integer] {
|
||||
switch (baseValue) {
|
||||
case 1:
|
||||
return [ 30, 75];
|
||||
case 2:
|
||||
return [ 25, 60 ];
|
||||
case 3:
|
||||
return [ 20, 50 ];
|
||||
case 4:
|
||||
return [ 15, 40 ];
|
||||
case 5:
|
||||
return [ 12, 35 ];
|
||||
case 6:
|
||||
return [ 10, 30 ];
|
||||
case 7:
|
||||
return [ 8, 20 ];
|
||||
case 8:
|
||||
return [ 5, 15 ];
|
||||
default:
|
||||
return [ 3, 10 ];
|
||||
}
|
||||
return starterCandyCosts[baseValue - 1].costReduction;
|
||||
}
|
||||
|
||||
const gens = [
|
||||
@ -199,6 +216,8 @@ export default class StarterSelectUiHandler extends MessageUiHandler {
|
||||
|
||||
setup() {
|
||||
const ui = this.getUi();
|
||||
const currentLanguage = i18next.language;
|
||||
const textSettings = languageSettings[currentLanguage];
|
||||
|
||||
this.starterSelectContainer = this.scene.add.container(0, -this.scene.game.canvas.height / 6);
|
||||
this.starterSelectContainer.setVisible(false);
|
||||
@ -255,57 +274,38 @@ export default class StarterSelectUiHandler extends MessageUiHandler {
|
||||
this.pokemonUncaughtText.setOrigin(0, 0);
|
||||
this.starterSelectContainer.add(this.pokemonUncaughtText);
|
||||
|
||||
let starterInfoXPosition = 31; // Only text
|
||||
|
||||
// The position should be set per language
|
||||
const currentLanguage = i18next.language;
|
||||
switch (currentLanguage) {
|
||||
case 'pt_BR':
|
||||
starterInfoXPosition = 32;
|
||||
break;
|
||||
default:
|
||||
starterInfoXPosition = 31;
|
||||
break
|
||||
}
|
||||
let starterInfoXPos = textSettings?.starterInfoXPos || 31;
|
||||
let starterInfoYOffset = textSettings?.starterInfoYOffset || 0;
|
||||
|
||||
let starterInfoTextSize = '56px'; // Labels and text
|
||||
// The font size should be set per language
|
||||
// currentLanguage is already defined
|
||||
switch (currentLanguage) {
|
||||
case 'fr':
|
||||
starterInfoTextSize = '54px';
|
||||
break;
|
||||
case 'pt_BR':
|
||||
starterInfoTextSize = '47px';
|
||||
break;
|
||||
default:
|
||||
starterInfoTextSize = '56px';
|
||||
break
|
||||
}
|
||||
let starterInfoTextSize = textSettings.starterInfoTextSize;
|
||||
|
||||
this.pokemonAbilityLabelText = addTextObject(this.scene, 6, 127, i18next.t("starterSelectUiHandler:ability"), TextStyle.SUMMARY_ALT, { fontSize: starterInfoTextSize });
|
||||
this.pokemonAbilityLabelText = addTextObject(this.scene, 6, 127 + starterInfoYOffset, i18next.t("starterSelectUiHandler:ability"), TextStyle.SUMMARY_ALT, { fontSize: starterInfoTextSize });
|
||||
this.pokemonAbilityLabelText.setOrigin(0, 0);
|
||||
this.pokemonAbilityLabelText.setVisible(false);
|
||||
this.starterSelectContainer.add(this.pokemonAbilityLabelText);
|
||||
|
||||
this.pokemonAbilityText = addTextObject(this.scene, starterInfoXPosition, 127, '', TextStyle.SUMMARY_ALT, { fontSize: starterInfoTextSize });
|
||||
this.pokemonAbilityText = addTextObject(this.scene, starterInfoXPos, 127 + starterInfoYOffset, '', TextStyle.SUMMARY_ALT, { fontSize: starterInfoTextSize });
|
||||
this.pokemonAbilityText.setOrigin(0, 0);
|
||||
this.starterSelectContainer.add(this.pokemonAbilityText);
|
||||
|
||||
this.pokemonPassiveLabelText = addTextObject(this.scene, 6, 136, i18next.t("starterSelectUiHandler:passive"), TextStyle.SUMMARY_ALT, { fontSize: starterInfoTextSize });
|
||||
this.pokemonPassiveLabelText = addTextObject(this.scene, 6, 136 + starterInfoYOffset, i18next.t("starterSelectUiHandler:passive"), TextStyle.SUMMARY_ALT, { fontSize: starterInfoTextSize });
|
||||
this.pokemonPassiveLabelText.setOrigin(0, 0);
|
||||
this.pokemonPassiveLabelText.setVisible(false);
|
||||
this.starterSelectContainer.add(this.pokemonPassiveLabelText);
|
||||
|
||||
this.pokemonPassiveText = addTextObject(this.scene, starterInfoXPosition, 136, '', TextStyle.SUMMARY_ALT, { fontSize: starterInfoTextSize });
|
||||
this.pokemonPassiveText = addTextObject(this.scene, starterInfoXPos, 136 + starterInfoYOffset, '', TextStyle.SUMMARY_ALT, { fontSize: starterInfoTextSize });
|
||||
this.pokemonPassiveText.setOrigin(0, 0);
|
||||
this.starterSelectContainer.add(this.pokemonPassiveText);
|
||||
|
||||
this.pokemonNatureLabelText = addTextObject(this.scene, 6, 145, i18next.t("starterSelectUiHandler:nature"), TextStyle.SUMMARY_ALT, { fontSize: starterInfoTextSize });
|
||||
this.pokemonNatureLabelText = addTextObject(this.scene, 6, 145 + starterInfoYOffset, i18next.t("starterSelectUiHandler:nature"), TextStyle.SUMMARY_ALT, { fontSize: starterInfoTextSize });
|
||||
this.pokemonNatureLabelText.setOrigin(0, 0);
|
||||
this.pokemonNatureLabelText.setVisible(false);
|
||||
this.starterSelectContainer.add(this.pokemonNatureLabelText);
|
||||
|
||||
this.pokemonNatureText = addBBCodeTextObject(this.scene, starterInfoXPosition, 145, '', TextStyle.SUMMARY_ALT, { fontSize: starterInfoTextSize });
|
||||
this.pokemonNatureText = addBBCodeTextObject(this.scene, starterInfoXPos, 145 + starterInfoYOffset, '', TextStyle.SUMMARY_ALT, { fontSize: starterInfoTextSize });
|
||||
this.pokemonNatureText.setOrigin(0, 0);
|
||||
this.starterSelectContainer.add(this.pokemonNatureText);
|
||||
|
||||
@ -589,36 +589,8 @@ export default class StarterSelectUiHandler extends MessageUiHandler {
|
||||
|
||||
this.starterSelectContainer.add(this.pokemonEggMovesContainer);
|
||||
|
||||
|
||||
|
||||
let instructionTextSize = '42px';
|
||||
// The font size should be set per language
|
||||
// currentLanguage is already defined in the previous code block
|
||||
switch (currentLanguage) {
|
||||
case 'de':
|
||||
instructionTextSize = '35px';
|
||||
break;
|
||||
case 'en':
|
||||
instructionTextSize = '42px';
|
||||
break;
|
||||
case 'es':
|
||||
instructionTextSize = '35px';
|
||||
break;
|
||||
case 'fr':
|
||||
instructionTextSize = '42px';
|
||||
break;
|
||||
case 'it':
|
||||
instructionTextSize = '38px';
|
||||
break;
|
||||
case 'pt_BR':
|
||||
instructionTextSize = '38px';
|
||||
break;
|
||||
case 'zh_CN':
|
||||
instructionTextSize = '42px';
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
let instructionTextSize = textSettings.instructionTextSize;
|
||||
|
||||
this.instructionsText = addTextObject(this.scene, 4, 156, '', TextStyle.PARTY, { fontSize: instructionTextSize });
|
||||
this.starterSelectContainer.add(this.instructionsText);
|
||||
|
@ -4,6 +4,7 @@ import { ModifierTier } from "../modifier/modifier-tier";
|
||||
import { EggTier } from "../data/enums/egg-type";
|
||||
import BattleScene from "../battle-scene";
|
||||
import { UiTheme } from "../enums/ui-theme";
|
||||
import i18next from "i18next";
|
||||
|
||||
export enum TextStyle {
|
||||
MESSAGE,
|
||||
@ -28,6 +29,25 @@ export enum TextStyle {
|
||||
MOVE_INFO_CONTENT
|
||||
};
|
||||
|
||||
interface LanguageSetting {
|
||||
summaryFontSize?: string,
|
||||
battleInfoFontSize?: string,
|
||||
partyFontSize?: string,
|
||||
tooltipContentFontSize?: string,
|
||||
moveInfoFontSize?: string,
|
||||
textScale?: number
|
||||
}
|
||||
|
||||
const languageSettings: { [key: string]: LanguageSetting } = {
|
||||
"en":{},
|
||||
"de":{},
|
||||
"es":{},
|
||||
"it":{},
|
||||
"fr":{},
|
||||
"zh_CN":{},
|
||||
"pt_BR":{},
|
||||
}
|
||||
|
||||
export function addTextObject(scene: Phaser.Scene, x: number, y: number, content: string, style: TextStyle, extraStyleOptions?: Phaser.Types.GameObjects.Text.TextStyle): Phaser.GameObjects.Text {
|
||||
const [ styleOptions, shadowColor, shadowSize ] = getTextStyleOptions(style, (scene as BattleScene).uiTheme, extraStyleOptions);
|
||||
|
||||
@ -64,6 +84,7 @@ export function addTextInputObject(scene: Phaser.Scene, x: number, y: number, wi
|
||||
}
|
||||
|
||||
function getTextStyleOptions(style: TextStyle, uiTheme: UiTheme, extraStyleOptions?: Phaser.Types.GameObjects.Text.TextStyle): [ Phaser.Types.GameObjects.Text.TextStyle | InputText.IConfig, string, integer ] {
|
||||
const lang = i18next.language;
|
||||
let shadowColor: string;
|
||||
let shadowSize = 6;
|
||||
|
||||
@ -90,25 +111,25 @@ function getTextStyleOptions(style: TextStyle, uiTheme: UiTheme, extraStyleOptio
|
||||
case TextStyle.MESSAGE:
|
||||
case TextStyle.SETTINGS_LABEL:
|
||||
case TextStyle.SETTINGS_SELECTED:
|
||||
styleOptions.fontSize = '96px';
|
||||
styleOptions.fontSize = languageSettings[lang]?.summaryFontSize || '96px';
|
||||
break;
|
||||
case TextStyle.BATTLE_INFO:
|
||||
case TextStyle.MONEY:
|
||||
case TextStyle.TOOLTIP_TITLE:
|
||||
styleOptions.fontSize = '72px';
|
||||
styleOptions.fontSize = languageSettings[lang]?.battleInfoFontSize || '72px';
|
||||
shadowSize = 4.5;
|
||||
break;
|
||||
case TextStyle.PARTY:
|
||||
case TextStyle.PARTY_RED:
|
||||
styleOptions.fontSize = languageSettings[lang]?.partyFontSize || '66px';
|
||||
styleOptions.fontFamily = 'pkmnems';
|
||||
styleOptions.fontSize = '66px';
|
||||
break;
|
||||
case TextStyle.TOOLTIP_CONTENT:
|
||||
styleOptions.fontSize = '64px';
|
||||
styleOptions.fontSize = languageSettings[lang]?.tooltipContentFontSize || '64px';
|
||||
shadowSize = 4;
|
||||
break;
|
||||
case TextStyle.MOVE_INFO_CONTENT:
|
||||
styleOptions.fontSize = '56px';
|
||||
styleOptions.fontSize = languageSettings[lang]?.moveInfoFontSize || '56px';
|
||||
shadowSize = 3;
|
||||
break;
|
||||
}
|
||||
|
@ -5,6 +5,7 @@ import { TextStyle, addTextObject } from "./text";
|
||||
import { Mode } from "./ui";
|
||||
import { addWindow } from "./ui-theme";
|
||||
import {Button} from "../enums/buttons";
|
||||
import i18next from '../plugins/i18n';
|
||||
|
||||
const itemRows = 4;
|
||||
const itemCols = 17;
|
||||
@ -40,7 +41,7 @@ export default class VouchersUiHandler extends MessageUiHandler {
|
||||
const headerBg = addWindow(this.scene, 0, 0, (this.scene.game.canvas.width / 6) - 2, 24);
|
||||
headerBg.setOrigin(0, 0);
|
||||
|
||||
const headerText = addTextObject(this.scene, 0, 0, 'Vouchers', TextStyle.SETTINGS_LABEL);
|
||||
const headerText = addTextObject(this.scene, 0, 0, i18next.t("voucher:vouchers"), TextStyle.SETTINGS_LABEL);
|
||||
headerText.setOrigin(0, 0);
|
||||
headerText.setPositionRelative(headerBg, 8, 4);
|
||||
|
||||
@ -127,7 +128,7 @@ export default class VouchersUiHandler extends MessageUiHandler {
|
||||
|
||||
this.titleText.setText(getVoucherTypeName(voucher.voucherType));
|
||||
this.showText(voucher.description);
|
||||
this.unlockText.setText(unlocked ? new Date(voucherUnlocks[voucher.id]).toLocaleDateString() : 'Locked');
|
||||
this.unlockText.setText(unlocked ? new Date(voucherUnlocks[voucher.id]).toLocaleDateString() : i18next.t("voucher:locked"));
|
||||
}
|
||||
|
||||
processInput(button: Button): boolean {
|
||||
@ -246,4 +247,4 @@ export default class VouchersUiHandler extends MessageUiHandler {
|
||||
this.cursorObj.destroy();
|
||||
this.cursorObj = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user