mirror of
https://github.com/pagefaultgames/pokerogue.git
synced 2025-07-04 23:42:18 +02:00
Merge branch 'pagefaultgames:main' into main
This commit is contained in:
commit
8c4443beef
11
.github/workflows/deploy.yml
vendored
11
.github/workflows/deploy.yml
vendored
@ -28,11 +28,6 @@ jobs:
|
||||
ssh-keyscan -H ${{ secrets.SSH_HOST }} >> ~/.ssh/known_hosts
|
||||
- name: Deploy build on server
|
||||
if: github.event_name == 'push' && github.ref_name == github.event.repository.default_branch
|
||||
run: rsync -vrm dist/* ${{ secrets.SSH_USER }}@${{ secrets.SSH_HOST }}:${{ secrets.DESTINATION_DIR }}
|
||||
- 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 }}
|
||||
run: |
|
||||
rsync --del -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"
|
||||
|
1208
public/battle-anims/common-snap-trap.json
Normal file
1208
public/battle-anims/common-snap-trap.json
Normal file
File diff suppressed because it is too large
Load Diff
Binary file not shown.
Before Width: | Height: | Size: 36 KiB After Width: | Height: | Size: 31 KiB |
2414
public/images/pokemon/variant/back/female/399_2.json
Normal file
2414
public/images/pokemon/variant/back/female/399_2.json
Normal file
File diff suppressed because it is too large
Load Diff
BIN
public/images/pokemon/variant/back/female/399_2.png
Normal file
BIN
public/images/pokemon/variant/back/female/399_2.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 6.8 KiB |
13
public/images/pokemon/variant/back/female/400.json
Normal file
13
public/images/pokemon/variant/back/female/400.json
Normal file
@ -0,0 +1,13 @@
|
||||
{
|
||||
"1": {
|
||||
"ad947b": "bd9171",
|
||||
"e6d69c": "fff5d1",
|
||||
"5a3a31": "70323f",
|
||||
"3a3129": "3a3129",
|
||||
"bd844a": "dba0ac",
|
||||
"8c5a31": "c46269",
|
||||
"101010": "101010",
|
||||
"423a31": "3e3040",
|
||||
"63523a": "824561"
|
||||
}
|
||||
}
|
16
public/images/pokemon/variant/female/399.json
Normal file
16
public/images/pokemon/variant/female/399.json
Normal file
@ -0,0 +1,16 @@
|
||||
{
|
||||
"1": {
|
||||
"423110": "423110",
|
||||
"9c6331": "d46378",
|
||||
"c58c42": "e5a5bb",
|
||||
"634a31": "70323f",
|
||||
"101010": "101010",
|
||||
"cebd84": "eba978",
|
||||
"ffefbd": "fff5d1",
|
||||
"ffffff": "ffffff",
|
||||
"5a4229": "824561",
|
||||
"ef5a4a": "ffa488",
|
||||
"cec5c5": "b7b9d0",
|
||||
"848484": "848484"
|
||||
}
|
||||
}
|
16
public/images/pokemon/variant/female/400.json
Normal file
16
public/images/pokemon/variant/female/400.json
Normal file
@ -0,0 +1,16 @@
|
||||
{
|
||||
"1": {
|
||||
"5a3a31": "5a3a31",
|
||||
"bd844a": "dba0ac",
|
||||
"101010": "101010",
|
||||
"8c5a31": "c46269",
|
||||
"e6d69c": "fff5d1",
|
||||
"ad947b": "bd9171",
|
||||
"c5c5b5": "b7b9d0",
|
||||
"ffffff": "ffffff",
|
||||
"3a3129": "3a3129",
|
||||
"63523a": "824561",
|
||||
"de4a4a": "ffa488",
|
||||
"423a31": "3e3040"
|
||||
}
|
||||
}
|
@ -271,7 +271,7 @@ export default class BattleScene extends SceneBase {
|
||||
|
||||
populateAnims();
|
||||
|
||||
await fetch('./images/pokemon/variant/_masterlist.json').then(res => res.json()).then(v => Object.keys(v).forEach(k => variantData[k] = v[k]));
|
||||
await this.cachedFetch('./images/pokemon/variant/_masterlist.json').then(res => res.json()).then(v => Object.keys(v).forEach(k => variantData[k] = v[k]));
|
||||
}
|
||||
|
||||
create() {
|
||||
@ -468,8 +468,8 @@ export default class BattleScene extends SceneBase {
|
||||
|
||||
Promise.all([
|
||||
Promise.all(loadPokemonAssets),
|
||||
initCommonAnims().then(() => loadCommonAnimAssets(this, true)),
|
||||
Promise.all([ Moves.TACKLE, Moves.TAIL_WHIP, Moves.FOCUS_ENERGY, Moves.STRUGGLE ].map(m => initMoveAnim(m))).then(() => loadMoveAnimAssets(this, defaultMoves, true)),
|
||||
initCommonAnims(this).then(() => loadCommonAnimAssets(this, true)),
|
||||
Promise.all([ Moves.TACKLE, Moves.TAIL_WHIP, Moves.FOCUS_ENERGY, Moves.STRUGGLE ].map(m => initMoveAnim(this, m))).then(() => loadMoveAnimAssets(this, defaultMoves, true)),
|
||||
this.initStarterColors()
|
||||
]).then(() => {
|
||||
this.pushPhase(new LoginPhase(this));
|
||||
@ -505,19 +505,29 @@ export default class BattleScene extends SceneBase {
|
||||
async initExpSprites(): Promise<void> {
|
||||
if (expSpriteKeys.length)
|
||||
return;
|
||||
fetch('./exp-sprites.json').then(res => res.json()).then(keys => {
|
||||
this.cachedFetch('./exp-sprites.json').then(res => res.json()).then(keys => {
|
||||
if (Array.isArray(keys))
|
||||
expSpriteKeys.push(...keys);
|
||||
Promise.resolve();
|
||||
});
|
||||
}
|
||||
|
||||
cachedFetch(url: string, init?: RequestInit): Promise<Response> {
|
||||
const manifest = this.game['manifest'];
|
||||
if (manifest) {
|
||||
const timestamp = manifest[`/${url.replace('./', '')}`];
|
||||
if (timestamp)
|
||||
url += `?t=${timestamp}`;
|
||||
}
|
||||
return fetch(url, init);
|
||||
}
|
||||
|
||||
initStarterColors(): Promise<void> {
|
||||
return new Promise(resolve => {
|
||||
if (starterColors)
|
||||
return resolve();
|
||||
|
||||
fetch('./starter-colors.json').then(res => res.json()).then(sc => {
|
||||
this.cachedFetch('./starter-colors.json').then(res => res.json()).then(sc => {
|
||||
starterColors = {};
|
||||
Object.keys(sc).forEach(key => {
|
||||
starterColors[key] = sc[key];
|
||||
|
@ -78,6 +78,7 @@ export enum CommonAnim {
|
||||
CURSE,
|
||||
MAGMA_STORM,
|
||||
CLAMP,
|
||||
SNAP_TRAP,
|
||||
THUNDER_CAGE,
|
||||
INFESTATION,
|
||||
ORDER_UP_CURLY,
|
||||
@ -423,14 +424,14 @@ export const moveAnims = new Map<Moves, AnimConfig | [AnimConfig, AnimConfig]>()
|
||||
export const chargeAnims = new Map<ChargeAnim, AnimConfig | [AnimConfig, AnimConfig]>();
|
||||
export const commonAnims = new Map<CommonAnim, AnimConfig>();
|
||||
|
||||
export function initCommonAnims(): Promise<void> {
|
||||
export function initCommonAnims(scene: BattleScene): Promise<void> {
|
||||
return new Promise(resolve => {
|
||||
const commonAnimNames = Utils.getEnumKeys(CommonAnim);
|
||||
const commonAnimIds = Utils.getEnumValues(CommonAnim);
|
||||
const commonAnimFetches = [];
|
||||
for (let ca = 0; ca < commonAnimIds.length; ca++) {
|
||||
const commonAnimId = commonAnimIds[ca];
|
||||
commonAnimFetches.push(fetch(`./battle-anims/common-${commonAnimNames[ca].toLowerCase().replace(/\_/g, '-')}.json`)
|
||||
commonAnimFetches.push(scene.cachedFetch(`./battle-anims/common-${commonAnimNames[ca].toLowerCase().replace(/\_/g, '-')}.json`)
|
||||
.then(response => response.json())
|
||||
.then(cas => commonAnims.set(commonAnimId, new AnimConfig(cas))));
|
||||
}
|
||||
@ -438,7 +439,7 @@ export function initCommonAnims(): Promise<void> {
|
||||
});
|
||||
}
|
||||
|
||||
export function initMoveAnim(move: Moves): Promise<void> {
|
||||
export function initMoveAnim(scene: BattleScene, move: Moves): Promise<void> {
|
||||
return new Promise(resolve => {
|
||||
if (moveAnims.has(move)) {
|
||||
if (moveAnims.get(move) !== null)
|
||||
@ -459,7 +460,7 @@ export function initMoveAnim(move: Moves): Promise<void> {
|
||||
const defaultMoveAnim = allMoves[move] instanceof AttackMove ? Moves.TACKLE : allMoves[move] instanceof SelfStatusMove ? Moves.FOCUS_ENERGY : Moves.TAIL_WHIP;
|
||||
const moveName = Moves[move].toLowerCase().replace(/\_/g, '-');
|
||||
const fetchAnimAndResolve = (move: Moves) => {
|
||||
fetch(`./battle-anims/${moveName}.json`)
|
||||
scene.cachedFetch(`./battle-anims/${moveName}.json`)
|
||||
.then(response => {
|
||||
if (!response.ok) {
|
||||
console.error(`Could not load animation file for move '${moveName}'`, response.status, response.statusText);
|
||||
@ -476,7 +477,7 @@ export function initMoveAnim(move: Moves): Promise<void> {
|
||||
populateMoveAnim(move, ba);
|
||||
const chargeAttr = allMoves[move].getAttrs(ChargeAttr).find(() => true) as ChargeAttr || allMoves[move].getAttrs(DelayedAttackAttr).find(() => true) as DelayedAttackAttr;
|
||||
if (chargeAttr)
|
||||
initMoveChargeAnim(chargeAttr.chargeAnim).then(() => resolve());
|
||||
initMoveChargeAnim(scene, chargeAttr.chargeAnim).then(() => resolve());
|
||||
else
|
||||
resolve();
|
||||
});
|
||||
@ -486,7 +487,7 @@ export function initMoveAnim(move: Moves): Promise<void> {
|
||||
});
|
||||
}
|
||||
|
||||
export function initMoveChargeAnim(chargeAnim: ChargeAnim): Promise<void> {
|
||||
export function initMoveChargeAnim(scene: BattleScene, chargeAnim: ChargeAnim): Promise<void> {
|
||||
return new Promise(resolve => {
|
||||
if (chargeAnims.has(chargeAnim)) {
|
||||
if (chargeAnims.get(chargeAnim) !== null)
|
||||
@ -501,7 +502,7 @@ export function initMoveChargeAnim(chargeAnim: ChargeAnim): Promise<void> {
|
||||
}
|
||||
} else {
|
||||
chargeAnims.set(chargeAnim, null);
|
||||
fetch(`./battle-anims/${ChargeAnim[chargeAnim].toLowerCase().replace(/\_/g, '-')}.json`)
|
||||
scene.cachedFetch(`./battle-anims/${ChargeAnim[chargeAnim].toLowerCase().replace(/\_/g, '-')}.json`)
|
||||
.then(response => response.json())
|
||||
.then(ca => {
|
||||
if (Array.isArray(ca)) {
|
||||
|
@ -614,6 +614,16 @@ export class MagmaStormTag extends DamagingTrapTag {
|
||||
}
|
||||
}
|
||||
|
||||
export class SnapTrapTag extends DamagingTrapTag {
|
||||
constructor(turnCount: integer, sourceId: integer) {
|
||||
super(BattlerTagType.SNAP_TRAP, CommonAnim.SNAP_TRAP, turnCount, Moves.SNAP_TRAP, sourceId);
|
||||
}
|
||||
|
||||
getTrapMessage(pokemon: Pokemon): string {
|
||||
return getPokemonMessage(pokemon, ` got trapped\nby a snap trap!`);
|
||||
}
|
||||
}
|
||||
|
||||
export class ThunderCageTag extends DamagingTrapTag {
|
||||
constructor(turnCount: integer, sourceId: integer) {
|
||||
super(BattlerTagType.THUNDER_CAGE, CommonAnim.THUNDER_CAGE, turnCount, Moves.THUNDER_CAGE, sourceId);
|
||||
@ -1103,6 +1113,8 @@ export function getBattlerTag(tagType: BattlerTagType, turnCount: integer, sourc
|
||||
return new SandTombTag(turnCount, sourceId);
|
||||
case BattlerTagType.MAGMA_STORM:
|
||||
return new MagmaStormTag(turnCount, sourceId);
|
||||
case BattlerTagType.SNAP_TRAP:
|
||||
return new SnapTrapTag(turnCount, sourceId);
|
||||
case BattlerTagType.THUNDER_CAGE:
|
||||
return new ThunderCageTag(turnCount, sourceId);
|
||||
case BattlerTagType.INFESTATION:
|
||||
|
@ -1844,7 +1844,7 @@ export const biomeTrainerPools: BiomeTrainerPools = {
|
||||
[BiomePoolTier.RARE]: [],
|
||||
[BiomePoolTier.SUPER_RARE]: [],
|
||||
[BiomePoolTier.ULTRA_RARE]: [],
|
||||
[BiomePoolTier.BOSS]: [ TrainerType.BRAWLY, TrainerType.KORRINA, TrainerType.BEA, TrainerType.MAYLENE ],
|
||||
[BiomePoolTier.BOSS]: [ TrainerType.BRAWLY, TrainerType.MAYLENE, TrainerType.KORRINA, TrainerType.BEA ],
|
||||
[BiomePoolTier.BOSS_RARE]: [],
|
||||
[BiomePoolTier.BOSS_SUPER_RARE]: [],
|
||||
[BiomePoolTier.BOSS_ULTRA_RARE]: []
|
||||
|
@ -21,6 +21,7 @@ export enum BattlerTagType {
|
||||
CLAMP = "CLAMP",
|
||||
SAND_TOMB = "SAND_TOMB",
|
||||
MAGMA_STORM = "MAGMA_STORM",
|
||||
SNAP_TRAP = "SNAP_TRAP",
|
||||
THUNDER_CAGE = "THUNDER_CAGE",
|
||||
INFESTATION = "INFESTATION",
|
||||
PROTECTED = "PROTECTED",
|
||||
|
@ -2301,6 +2301,14 @@ export class WaterSuperEffectTypeMultiplierAttr extends VariableMoveTypeMultipli
|
||||
}
|
||||
}
|
||||
|
||||
export class FlyingTypeMultiplierAttr extends VariableMoveTypeMultiplierAttr {
|
||||
apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): boolean {
|
||||
const multiplier = args[0] as Utils.NumberHolder;
|
||||
multiplier.value *= target.getAttackTypeEffectiveness(Type.FLYING);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
export class OneHitKOAccuracyAttr extends VariableAccuracyAttr {
|
||||
apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): boolean {
|
||||
const accuracy = args[0] as Utils.NumberHolder;
|
||||
@ -2511,6 +2519,7 @@ export class AddBattlerTagAttr extends MoveEffectAttr {
|
||||
case BattlerTagType.CLAMP:
|
||||
case BattlerTagType.SAND_TOMB:
|
||||
case BattlerTagType.MAGMA_STORM:
|
||||
case BattlerTagType.SNAP_TRAP:
|
||||
case BattlerTagType.THUNDER_CAGE:
|
||||
case BattlerTagType.INFESTATION:
|
||||
return -3;
|
||||
@ -3095,7 +3104,7 @@ export class RandomMoveAttr extends OverrideMoveEffectAttr {
|
||||
: [ moveTargets.targets[user.randSeedInt(moveTargets.targets.length)] ];
|
||||
user.getMoveQueue().push({ move: moveId, targets: targets, ignorePP: true });
|
||||
user.scene.unshiftPhase(new MovePhase(user.scene, user, targets, new PokemonMove(moveId, 0, 0, true), true));
|
||||
initMoveAnim(moveId).then(() => {
|
||||
initMoveAnim(user.scene, moveId).then(() => {
|
||||
loadMoveAnimAssets(user.scene, [ moveId ], true)
|
||||
.then(() => resolve(true));
|
||||
});
|
||||
@ -3238,7 +3247,7 @@ export class NaturePowerAttr extends OverrideMoveEffectAttr {
|
||||
|
||||
user.getMoveQueue().push({ move: moveId, targets: [target.getBattlerIndex()], ignorePP: true });
|
||||
user.scene.unshiftPhase(new MovePhase(user.scene, user, [target.getBattlerIndex()], new PokemonMove(moveId, 0, 0, true), true));
|
||||
initMoveAnim(moveId).then(() => {
|
||||
initMoveAnim(user.scene, moveId).then(() => {
|
||||
loadMoveAnimAssets(user.scene, [ moveId ], true)
|
||||
.then(() => resolve(true));
|
||||
});
|
||||
@ -4313,6 +4322,7 @@ export function initMoves() {
|
||||
BattlerTagType.CLAMP,
|
||||
BattlerTagType.SAND_TOMB,
|
||||
BattlerTagType.MAGMA_STORM,
|
||||
BattlerTagType.SNAP_TRAP,
|
||||
BattlerTagType.THUNDER_CAGE,
|
||||
BattlerTagType.SEEDED,
|
||||
BattlerTagType.INFESTATION
|
||||
@ -5202,7 +5212,8 @@ export function initMoves() {
|
||||
.makesContact(false)
|
||||
.partial(),
|
||||
new AttackMove(Moves.FLYING_PRESS, Type.FIGHTING, MoveCategory.PHYSICAL, 100, 95, 10, -1, 0, 6)
|
||||
.partial(),
|
||||
.attr(FlyingTypeMultiplierAttr)
|
||||
.condition(failOnGravityCondition),
|
||||
new StatusMove(Moves.MAT_BLOCK, Type.FIGHTING, -1, 10, -1, 0, 6)
|
||||
.unimplemented(),
|
||||
new AttackMove(Moves.BELCH, Type.POISON, MoveCategory.SPECIAL, 120, 90, 10, -1, 0, 6)
|
||||
@ -5784,7 +5795,7 @@ export function initMoves() {
|
||||
.attr(StatChangeAttr, BattleStat.SPD, -1)
|
||||
.makesContact(false),
|
||||
new AttackMove(Moves.SNAP_TRAP, Type.GRASS, MoveCategory.PHYSICAL, 35, 100, 15, 100, 0, 8)
|
||||
.partial(),
|
||||
.attr(TrapAttr, BattlerTagType.SNAP_TRAP),
|
||||
new AttackMove(Moves.PYRO_BALL, Type.FIRE, MoveCategory.PHYSICAL, 120, 90, 5, 10, 0, 8)
|
||||
.attr(HealStatusEffectAttr, true, StatusEffect.FREEZE)
|
||||
.attr(StatusEffectAttr, StatusEffect.BURN)
|
||||
@ -6147,6 +6158,7 @@ export function initMoves() {
|
||||
BattlerTagType.CLAMP,
|
||||
BattlerTagType.SAND_TOMB,
|
||||
BattlerTagType.MAGMA_STORM,
|
||||
BattlerTagType.SNAP_TRAP,
|
||||
BattlerTagType.THUNDER_CAGE,
|
||||
BattlerTagType.SEEDED,
|
||||
BattlerTagType.INFESTATION
|
||||
|
@ -625,6 +625,10 @@ export const pokemonEvolutions: PokemonEvolutions = {
|
||||
[Species.FINNEON]: [
|
||||
new SpeciesEvolution(Species.LUMINEON, 31, null, null)
|
||||
],
|
||||
[Species.MANTYKE]: [
|
||||
new SpeciesEvolution(Species.MANTINE, 1, null, new SpeciesEvolutionCondition(p => !!p.scene.getParty().find(p => p.species.speciesId === Species.REMORAID)), SpeciesWildEvolutionDelay.MEDIUM),
|
||||
new SpeciesEvolution(Species.MANTINE, 32, null, new SpeciesEvolutionCondition(p => !!p.scene.gameData.dexData[Species.REMORAID].caughtAttr), SpeciesWildEvolutionDelay.MEDIUM)
|
||||
],
|
||||
[Species.SNOVER]: [
|
||||
new SpeciesEvolution(Species.ABOMASNOW, 40, null, null)
|
||||
],
|
||||
@ -1341,9 +1345,6 @@ export const pokemonEvolutions: PokemonEvolutions = {
|
||||
new SpeciesEvolution(Species.GALAR_MR_MIME, 1, null, new SpeciesEvolutionCondition(p => p.moveset.filter(m => m.moveId === Moves.MIMIC).length > 0 && (p.scene.arena.biomeType === Biome.ICE_CAVE || p.scene.arena.biomeType === Biome.SNOWY_FOREST)), SpeciesWildEvolutionDelay.MEDIUM),
|
||||
new SpeciesEvolution(Species.MR_MIME, 1, null, new SpeciesEvolutionCondition(p => p.moveset.filter(m => m.moveId === Moves.MIMIC).length > 0), SpeciesWildEvolutionDelay.MEDIUM)
|
||||
],
|
||||
[Species.MANTYKE]: [
|
||||
new SpeciesEvolution(Species.MANTINE, 1, null, new SpeciesEvolutionCondition(p => !!p.scene.getParty().find(p => p.species.speciesId === Species.REMORAID)), SpeciesWildEvolutionDelay.MEDIUM)
|
||||
],
|
||||
[Species.PANSAGE]: [
|
||||
new SpeciesEvolution(Species.SIMISAGE, 1, EvolutionItem.LEAF_STONE, null, SpeciesWildEvolutionDelay.LONG)
|
||||
],
|
||||
|
@ -394,7 +394,7 @@ export abstract class PokemonSpeciesForm {
|
||||
return new Promise(resolve => {
|
||||
if (variantColorCache.hasOwnProperty(key))
|
||||
return resolve();
|
||||
fetch(`./images/pokemon/variant/${spritePath}.json`).then(res => res.json()).then(c => {
|
||||
scene.cachedFetch(`./images/pokemon/variant/${spritePath}.json`).then(res => res.json()).then(c => {
|
||||
variantColorCache[key] = c;
|
||||
resolve();
|
||||
});
|
||||
|
@ -275,7 +275,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
|
||||
loadAssets(ignoreOverride: boolean = true): Promise<void> {
|
||||
return new Promise(resolve => {
|
||||
const moveIds = this.getMoveset().map(m => m.getMove().id);
|
||||
Promise.allSettled(moveIds.map(m => initMoveAnim(m)))
|
||||
Promise.allSettled(moveIds.map(m => initMoveAnim(this.scene, m)))
|
||||
.then(() => {
|
||||
loadMoveAnimAssets(this.scene, moveIds);
|
||||
this.getSpeciesForm().loadAssets(this.scene, this.getGender() === Gender.FEMALE, this.formIndex, this.shiny, this.variant);
|
||||
@ -317,7 +317,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
|
||||
if (variantSet && variantSet[this.variant] === 1) {
|
||||
if (variantColorCache.hasOwnProperty(key))
|
||||
return resolve();
|
||||
fetch(`./images/pokemon/variant/${battleSpritePath}.json`).then(res => res.json()).then(c => {
|
||||
this.scene.cachedFetch(`./images/pokemon/variant/${battleSpritePath}.json`).then(res => res.json()).then(c => {
|
||||
variantColorCache[key] = c;
|
||||
resolve();
|
||||
});
|
||||
|
@ -19,12 +19,7 @@ export class LoadingScene extends SceneBase {
|
||||
}
|
||||
|
||||
preload() {
|
||||
const indexFile = Array.from(document.querySelectorAll('script')).map(s => s.src).find(s => /\/index/.test(s));
|
||||
if (indexFile) {
|
||||
const buildIdMatch = /index\-(.*?)\.js$/.exec(indexFile);
|
||||
if (buildIdMatch)
|
||||
this.load['cacheBuster'] = buildIdMatch[1];
|
||||
}
|
||||
this.load['manifest'] = this.game['manifest'];
|
||||
|
||||
if (!isMobile())
|
||||
this.load.video('intro_dark', 'images/intro_dark.mp4', true);
|
||||
|
9
src/locales/en/command-ui-handler.ts
Normal file
9
src/locales/en/command-ui-handler.ts
Normal file
@ -0,0 +1,9 @@
|
||||
import { SimpleTranslationEntries } from "#app/plugins/i18n";
|
||||
|
||||
export const commandUiHandler: SimpleTranslationEntries = {
|
||||
"fight": "Fight",
|
||||
"ball": "Ball",
|
||||
"pokemon": "Pokémon",
|
||||
"run": "Run",
|
||||
"actionMessage": "What will\n{{pokemonName}} do?",
|
||||
} as const;
|
9
src/locales/es/command-ui-handler.ts
Normal file
9
src/locales/es/command-ui-handler.ts
Normal file
@ -0,0 +1,9 @@
|
||||
import { SimpleTranslationEntries } from "#app/plugins/i18n";
|
||||
|
||||
export const commandUiHandler: SimpleTranslationEntries = {
|
||||
"fight": "Fight",
|
||||
"ball": "Ball",
|
||||
"pokemon": "Pokémon",
|
||||
"run": "Run",
|
||||
"actionMessage": "What will\n{{pokemonName}} do?",
|
||||
} as const;
|
1086
src/locales/es/pokemon.ts
Normal file
1086
src/locales/es/pokemon.ts
Normal file
File diff suppressed because it is too large
Load Diff
9
src/locales/fr/command-ui-handler.ts
Normal file
9
src/locales/fr/command-ui-handler.ts
Normal file
@ -0,0 +1,9 @@
|
||||
import { SimpleTranslationEntries } from "#app/plugins/i18n";
|
||||
|
||||
export const commandUiHandler: SimpleTranslationEntries = {
|
||||
"fight": "Attaque",
|
||||
"ball": "Ball",
|
||||
"pokemon": "Pokémon",
|
||||
"run": "Fuite",
|
||||
"actionMessage": "Que doit faire\n{{pokemonName}}?",
|
||||
} as const;
|
18
src/main.ts
18
src/main.ts
@ -76,7 +76,21 @@ Phaser.GameObjects.Rectangle.prototype.setPositionRelative = setPositionRelative
|
||||
|
||||
document.fonts.load('16px emerald').then(() => document.fonts.load('10px pkmnems'));
|
||||
|
||||
const game = new Phaser.Game(config);
|
||||
game.sound.pauseOnBlur = false;
|
||||
let game;
|
||||
|
||||
const startGame = () => {
|
||||
game = new Phaser.Game(config);
|
||||
game.sound.pauseOnBlur = false;
|
||||
};
|
||||
|
||||
fetch('/manifest.json')
|
||||
.then(res => res.json())
|
||||
.then(jsonResponse => {
|
||||
startGame();
|
||||
game['manifest'] = jsonResponse.manifest;
|
||||
}).catch(() => {
|
||||
// Manifest not found (likely local build)
|
||||
startGame();
|
||||
});
|
||||
|
||||
export default game;
|
||||
|
@ -2613,7 +2613,7 @@ export class MoveAnimTestPhase extends BattlePhase {
|
||||
} else if (player)
|
||||
console.log(Moves[moveId]);
|
||||
|
||||
initMoveAnim(moveId).then(() => {
|
||||
initMoveAnim(this.scene, moveId).then(() => {
|
||||
loadMoveAnimAssets(this.scene, [ moveId ], true)
|
||||
.then(() => {
|
||||
new MoveAnim(moveId, player ? this.scene.getPlayerPokemon() : this.scene.getEnemyPokemon(), (player !== (allMoves[moveId] instanceof SelfStatusMove) ? this.scene.getEnemyPokemon() : this.scene.getPlayerPokemon()).getBattlerIndex()).play(this.scene, () => {
|
||||
@ -2665,11 +2665,20 @@ export class StatChangePhase extends PokemonPhase {
|
||||
start() {
|
||||
const pokemon = this.getPokemon();
|
||||
|
||||
if (!pokemon.isActive(true))
|
||||
return this.end();
|
||||
let random = false;
|
||||
|
||||
const allStats = Utils.getEnumValues(BattleStat);
|
||||
const filteredStats = this.stats.map(s => s !== BattleStat.RAND ? s : allStats[pokemon.randSeedInt(BattleStat.SPD + 1)]).filter(stat => {
|
||||
if (this.stats.length === 1 && this.stats[0] === BattleStat.RAND) {
|
||||
this.stats[0] = this.getRandomStat();
|
||||
random = true;
|
||||
}
|
||||
|
||||
this.aggregateStatChanges(random);
|
||||
|
||||
if (!pokemon.isActive(true))
|
||||
return this.end();
|
||||
|
||||
const filteredStats = this.stats.map(s => s !== BattleStat.RAND ? s : this.getRandomStat()).filter(stat => {
|
||||
const cancelled = new Utils.BooleanHolder(false);
|
||||
|
||||
if (!this.selfTarget && this.levels < 0)
|
||||
@ -2750,11 +2759,62 @@ export class StatChangePhase extends PokemonPhase {
|
||||
end();
|
||||
}
|
||||
|
||||
getRandomStat(): BattleStat {
|
||||
const allStats = Utils.getEnumValues(BattleStat);
|
||||
return allStats[this.getPokemon().randSeedInt(BattleStat.SPD + 1)];
|
||||
}
|
||||
|
||||
aggregateStatChanges(random: boolean = false): void {
|
||||
const isAccEva = [ BattleStat.ACC, BattleStat.EVA ].some(s => this.stats.includes(s));
|
||||
let existingPhase: StatChangePhase;
|
||||
if (this.stats.length === 1) {
|
||||
while ((existingPhase = (this.scene.findPhase(p => p instanceof StatChangePhase && p.battlerIndex === this.battlerIndex && p.stats.length === 1
|
||||
&& (p.stats[0] === this.stats[0] || (random && p.stats[0] === BattleStat.RAND))
|
||||
&& p.selfTarget === this.selfTarget && p.showMessage === this.showMessage && p.ignoreAbilities === this.ignoreAbilities) as StatChangePhase))) {
|
||||
if (existingPhase.stats[0] === BattleStat.RAND) {
|
||||
existingPhase.stats[0] = this.getRandomStat();
|
||||
if (existingPhase.stats[0] !== this.stats[0])
|
||||
continue;
|
||||
}
|
||||
this.levels += existingPhase.levels;
|
||||
|
||||
if (!this.scene.tryRemovePhase(p => p === existingPhase))
|
||||
break;
|
||||
}
|
||||
}
|
||||
while ((existingPhase = (this.scene.findPhase(p => p instanceof StatChangePhase && p.battlerIndex === this.battlerIndex && p.selfTarget === this.selfTarget
|
||||
&& ([ BattleStat.ACC, BattleStat.EVA ].some(s => p.stats.includes(s)) === isAccEva)
|
||||
&& p.levels === this.levels && p.showMessage === this.showMessage && p.ignoreAbilities === this.ignoreAbilities) as StatChangePhase))) {
|
||||
this.stats.push(...existingPhase.stats);
|
||||
if (!this.scene.tryRemovePhase(p => p === existingPhase))
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
getStatChangeMessages(stats: BattleStat[], levels: integer, relLevels: integer[]): string[] {
|
||||
const messages: string[] = [];
|
||||
|
||||
for (let s = 0; s < stats.length; s++)
|
||||
messages.push(getPokemonMessage(this.getPokemon(), `'s ${getBattleStatName(stats[s])} ${getBattleStatLevelChangeDescription(Math.abs(relLevels[s]), levels >= 1)}!`));
|
||||
|
||||
const relLevelStatIndexes = {};
|
||||
for (let rl = 0; rl < relLevels.length; rl++) {
|
||||
const relLevel = relLevels[rl];
|
||||
if (!relLevelStatIndexes[relLevel])
|
||||
relLevelStatIndexes[relLevel] = [];
|
||||
relLevelStatIndexes[relLevel].push(rl);
|
||||
}
|
||||
|
||||
Object.keys(relLevelStatIndexes).forEach(rl => {
|
||||
const relLevelStats = stats.filter((_, i) => relLevelStatIndexes[rl].includes(i));
|
||||
let statsFragment = '';
|
||||
|
||||
if (relLevelStats.length > 1) {
|
||||
statsFragment = relLevelStats.length >= 5
|
||||
? 'stats'
|
||||
: `${relLevelStats.slice(0, -1).map(s => getBattleStatName(s)).join(', ')}, and ${getBattleStatName(relLevelStats[relLevelStats.length - 1])}`;
|
||||
} else
|
||||
statsFragment = getBattleStatName(relLevelStats[0]);
|
||||
messages.push(getPokemonMessage(this.getPokemon(), `'s ${statsFragment} ${getBattleStatLevelChangeDescription(Math.abs(parseInt(rl)), levels >= 1)}!`));
|
||||
});
|
||||
|
||||
return messages;
|
||||
}
|
||||
}
|
||||
@ -3675,7 +3735,7 @@ export class LearnMovePhase extends PlayerPartyMemberPokemonPhase {
|
||||
|
||||
if (emptyMoveIndex > -1) {
|
||||
pokemon.setMove(emptyMoveIndex, this.moveId);
|
||||
initMoveAnim(this.moveId).then(() => {
|
||||
initMoveAnim(this.scene, this.moveId).then(() => {
|
||||
loadMoveAnimAssets(this.scene, [ this.moveId ], true)
|
||||
.then(() => {
|
||||
this.scene.ui.setMode(messageMode).then(() => {
|
||||
|
@ -1,26 +1,29 @@
|
||||
let cacheBuster = '';
|
||||
|
||||
const ignoredFiles = [ 'intro_dark' ];
|
||||
let manifest: object;
|
||||
|
||||
export default class CacheBustedLoaderPlugin extends Phaser.Loader.LoaderPlugin {
|
||||
constructor(scene: Phaser.Scene) {
|
||||
super(scene)
|
||||
}
|
||||
|
||||
get cacheBuster() {
|
||||
return cacheBuster
|
||||
get manifest() {
|
||||
return manifest;
|
||||
}
|
||||
|
||||
set cacheBuster(version) {
|
||||
cacheBuster = version
|
||||
set manifest(manifestObj: object) {
|
||||
manifest = manifestObj;
|
||||
}
|
||||
|
||||
addFile(file): void {
|
||||
if (!Array.isArray(file))
|
||||
file = [ file ];
|
||||
|
||||
if (!ignoredFiles.includes(file?.key) && cacheBuster)
|
||||
file.forEach(item => item.url += '?v=' + cacheBuster);
|
||||
file.forEach(item => {
|
||||
if (manifest) {
|
||||
const timestamp = manifest[`/${item.url.replace(/\/\//g, '/')}` ];
|
||||
if (timestamp)
|
||||
item.url += `?t=${timestamp}`;
|
||||
}
|
||||
});
|
||||
|
||||
super.addFile(file);
|
||||
}
|
||||
|
@ -13,12 +13,18 @@ import { pokeball as esPokeball } from '../locales/es/pokeball';
|
||||
import { pokeball as frPokeball } from '../locales/fr/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 { 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';
|
||||
|
||||
export interface SimpleTranslationEntries {
|
||||
[key: string]: string
|
||||
}
|
||||
|
||||
|
||||
export interface MoveTranslationEntry {
|
||||
name: string,
|
||||
effect: string
|
||||
@ -65,21 +71,25 @@ export function initI18n(): void {
|
||||
move: enMove,
|
||||
pokeball: enPokeball,
|
||||
pokemon: enPokemon,
|
||||
commandUiHandler: enCommandUiHandler,
|
||||
},
|
||||
es: {
|
||||
menu: esMenu,
|
||||
move: esMove,
|
||||
pokeball: esPokeball,
|
||||
},
|
||||
it: {
|
||||
menu: itMenu,
|
||||
pokemon: esPokemon,
|
||||
commandUiHandler: esCommandUiHandler,
|
||||
},
|
||||
fr: {
|
||||
menu: frMenu,
|
||||
move: frMove,
|
||||
pokeball: frPokeball,
|
||||
pokemon: frPokemon,
|
||||
}
|
||||
commandUiHandler: frCommandUiHandler,
|
||||
},
|
||||
it: {
|
||||
menu: itMenu,
|
||||
},
|
||||
},
|
||||
});
|
||||
}
|
||||
@ -92,6 +102,7 @@ declare module 'i18next' {
|
||||
move: typeof enMove;
|
||||
pokeball: typeof enPokeball;
|
||||
pokemon: typeof enPokemon;
|
||||
commandUiHandler: typeof enCommandUiHandler;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
@ -5,25 +5,35 @@ export class SceneBase extends Phaser.Scene {
|
||||
super(config);
|
||||
}
|
||||
|
||||
getCachedUrl(url: string): string {
|
||||
const manifest = this.game['manifest'];
|
||||
if (manifest) {
|
||||
const timestamp = manifest[`/${url}`];
|
||||
if (timestamp)
|
||||
url += `?t=${timestamp}`;
|
||||
}
|
||||
return url;
|
||||
}
|
||||
|
||||
loadImage(key: string, folder: string, filename?: string) {
|
||||
if (!filename)
|
||||
filename = `${key}.png`;
|
||||
this.load.image(key, `images/${folder}/${filename}`);
|
||||
this.load.image(key, this.getCachedUrl(`images/${folder}/${filename}`));
|
||||
if (folder.startsWith('ui')) {
|
||||
legacyCompatibleImages.push(key);
|
||||
folder = folder.replace('ui', 'ui/legacy');
|
||||
this.load.image(`${key}_legacy`, `images/${folder}/${filename}`);
|
||||
this.load.image(`${key}_legacy`, this.getCachedUrl(`images/${folder}/${filename}`));
|
||||
}
|
||||
}
|
||||
|
||||
loadSpritesheet(key: string, folder: string, size: integer, filename?: string) {
|
||||
if (!filename)
|
||||
filename = `${key}.png`;
|
||||
this.load.spritesheet(key, `images/${folder}/${filename}`, { frameWidth: size, frameHeight: size });
|
||||
this.load.spritesheet(key, this.getCachedUrl(`images/${folder}/${filename}`), { frameWidth: size, frameHeight: size });
|
||||
if (folder.startsWith('ui')) {
|
||||
legacyCompatibleImages.push(key);
|
||||
folder = folder.replace('ui', 'ui/legacy');
|
||||
this.load.spritesheet(`${key}_legacy`, `images/${folder}/${filename}`, { frameWidth: size, frameHeight: size });
|
||||
this.load.spritesheet(`${key}_legacy`, this.getCachedUrl(`images/${folder}/${filename}`), { frameWidth: size, frameHeight: size });
|
||||
}
|
||||
}
|
||||
|
||||
@ -32,11 +42,11 @@ export class SceneBase extends Phaser.Scene {
|
||||
filenameRoot = key;
|
||||
if (folder)
|
||||
folder += '/';
|
||||
this.load.atlas(key, `images/${folder}${filenameRoot}.png`, `images/${folder}/${filenameRoot}.json`);
|
||||
this.load.atlas(key, this.getCachedUrl(`images/${folder}${filenameRoot}.png`), this.getCachedUrl(`images/${folder}/${filenameRoot}.json`));
|
||||
if (folder.startsWith('ui')) {
|
||||
legacyCompatibleImages.push(key);
|
||||
folder = folder.replace('ui', 'ui/legacy');
|
||||
this.load.atlas(`${key}_legacy`, `images/${folder}${filenameRoot}.png`, `images/${folder}/${filenameRoot}.json`);
|
||||
this.load.atlas(`${key}_legacy`, this.getCachedUrl(`images/${folder}${filenameRoot}.png`), this.getCachedUrl(`images/${folder}/${filenameRoot}.json`));
|
||||
}
|
||||
}
|
||||
|
||||
@ -49,14 +59,13 @@ export class SceneBase extends Phaser.Scene {
|
||||
folder += '/';
|
||||
if (!Array.isArray(filenames))
|
||||
filenames = [ filenames ];
|
||||
for (let f of filenames as string[]) {
|
||||
this.load.audio(key, `audio/se/${folder}${f}`);
|
||||
}
|
||||
for (let f of filenames as string[])
|
||||
this.load.audio(key, this.getCachedUrl(`audio/se/${folder}${f}`));
|
||||
}
|
||||
|
||||
loadBgm(key: string, filename?: string) {
|
||||
if (!filename)
|
||||
filename = `${key}.mp3`;
|
||||
this.load.audio(key, `audio/bgm/${filename}`);
|
||||
this.load.audio(key, this.getCachedUrl(`audio/bgm/${filename}`));
|
||||
}
|
||||
}
|
@ -347,7 +347,8 @@ export class GameData {
|
||||
} else {
|
||||
if ([ '1.0.0', '1.0.1' ].includes(systemData.gameVersion))
|
||||
this.migrateStarterAbilities(systemData);
|
||||
this.fixVariantData(systemData);
|
||||
//this.fixVariantData(systemData);
|
||||
this.fixStarterData(systemData);
|
||||
// Migrate ability starter data if empty for caught species
|
||||
Object.keys(systemData.starterData).forEach(sd => {
|
||||
if (systemData.dexData[sd].caughtAttr && !systemData.starterData[sd].abilityAttr)
|
||||
@ -984,7 +985,7 @@ export class GameData {
|
||||
moveset: null,
|
||||
eggMoves: 0,
|
||||
candyCount: 0,
|
||||
abilityAttr: 0,
|
||||
abilityAttr: defaultStarterSpecies.includes(speciesId) ? AbilityAttr.ABILITY_1 : 0,
|
||||
passiveAttr: 0,
|
||||
valueReduction: 0
|
||||
};
|
||||
@ -1291,4 +1292,9 @@ export class GameData {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fixStarterData(systemData: SystemSaveData): void {
|
||||
for (let starterId of defaultStarterSpecies)
|
||||
systemData.starterData[starterId].abilityAttr |= AbilityAttr.ABILITY_1;
|
||||
}
|
||||
}
|
@ -4,6 +4,7 @@ import { addTextObject, TextStyle } from "./text";
|
||||
import PartyUiHandler, { PartyUiMode } from "./party-ui-handler";
|
||||
import { Mode } from "./ui";
|
||||
import UiHandler from "./ui-handler";
|
||||
import i18next from '../plugins/i18n';
|
||||
|
||||
export enum Command {
|
||||
FIGHT = 0,
|
||||
@ -25,7 +26,12 @@ export default class CommandUiHandler extends UiHandler {
|
||||
|
||||
setup() {
|
||||
const ui = this.getUi();
|
||||
const commands = [ 'Fight', 'Ball', 'Pokémon', 'Run' ];
|
||||
const commands = [
|
||||
i18next.t('commandUiHandler:fight'),
|
||||
i18next.t('commandUiHandler:ball'),
|
||||
i18next.t('commandUiHandler:pokemon'),
|
||||
i18next.t('commandUiHandler:run')
|
||||
];
|
||||
|
||||
this.commandsContainer = this.scene.add.container(216, -38.7);
|
||||
this.commandsContainer.setVisible(false);
|
||||
@ -55,7 +61,7 @@ export default class CommandUiHandler extends UiHandler {
|
||||
messageHandler.commandWindow.setVisible(true);
|
||||
messageHandler.movesWindowContainer.setVisible(false);
|
||||
messageHandler.message.setWordWrapWidth(1110);
|
||||
messageHandler.showText(`What will\n${commandPhase.getPokemon().name} do?`, 0);
|
||||
messageHandler.showText(i18next.t('commandUiHandler:actionMessage', {pokemonName: commandPhase.getPokemon().name}), 0);
|
||||
this.setCursor(this.getCursor());
|
||||
|
||||
return true;
|
||||
|
@ -5,6 +5,7 @@ import { TextStyle, addTextInputObject, addTextObject } from "./text";
|
||||
import { WindowVariant, addWindow } from "./ui-theme";
|
||||
import InputText from "phaser3-rex-plugins/plugins/inputtext";
|
||||
import * as Utils from "../utils";
|
||||
import i18next from '../plugins/i18n';
|
||||
|
||||
export interface FormModalConfig extends ModalConfig {
|
||||
errorMessage?: string;
|
||||
@ -55,7 +56,7 @@ export abstract class FormModalUiHandler extends ModalUiHandler {
|
||||
|
||||
const inputBg = addWindow(this.scene, 0, 0, 80, 16, false, false, 0, 0, WindowVariant.XTHIN);
|
||||
|
||||
const isPassword = field.includes('Password');
|
||||
const isPassword = field.includes(i18next.t("menu:password")) || field.includes(i18next.t("menu:confirmPassword"));
|
||||
const input = addTextInputObject(this.scene, 4, -2, 440, 116, TextStyle.TOOLTIP_CONTENT, { type: isPassword ? 'password' : 'text', maxLength: isPassword ? 64 : 16 });
|
||||
input.setOrigin(0, 0);
|
||||
|
||||
|
@ -7,10 +7,9 @@ import { addWindow } from "./ui-theme";
|
||||
import * as Utils from "../utils";
|
||||
import PokemonData from "../system/pokemon-data";
|
||||
import { PokemonHeldItemModifier } from "../modifier/modifier";
|
||||
import { TitlePhase } from "../phases";
|
||||
import MessageUiHandler from "./message-ui-handler";
|
||||
|
||||
const sessionSlotCount = 3;
|
||||
const sessionSlotCount = 5;
|
||||
|
||||
export enum SaveSlotUiMode {
|
||||
LOAD,
|
||||
@ -30,8 +29,12 @@ export default class SaveSlotSelectUiHandler extends MessageUiHandler {
|
||||
private uiMode: SaveSlotUiMode;
|
||||
private saveSlotSelectCallback: SaveSlotSelectCallback;
|
||||
|
||||
private scrollCursor: integer = 0;
|
||||
|
||||
private cursorObj: Phaser.GameObjects.NineSlice;
|
||||
|
||||
private sessionSlotsContainerInitialY: number;
|
||||
|
||||
constructor(scene: BattleScene) {
|
||||
super(scene, Mode.SAVE_SLOT);
|
||||
}
|
||||
@ -47,7 +50,9 @@ export default class SaveSlotSelectUiHandler extends MessageUiHandler {
|
||||
loadSessionBg.setOrigin(0, 0);
|
||||
this.saveSlotSelectContainer.add(loadSessionBg);
|
||||
|
||||
this.sessionSlotsContainer = this.scene.add.container(8, -this.scene.game.canvas.height / 6 + 8);
|
||||
this.sessionSlotsContainerInitialY = -this.scene.game.canvas.height / 6 + 8;
|
||||
|
||||
this.sessionSlotsContainer = this.scene.add.container(8, this.sessionSlotsContainerInitialY);
|
||||
this.saveSlotSelectContainer.add(this.sessionSlotsContainer);
|
||||
|
||||
this.saveSlotSelectMessageBoxContainer = this.scene.add.container(0, 0);
|
||||
@ -76,6 +81,7 @@ export default class SaveSlotSelectUiHandler extends MessageUiHandler {
|
||||
|
||||
this.saveSlotSelectContainer.setVisible(true);
|
||||
this.populateSessionSlots();
|
||||
this.setScrollCursor(0);
|
||||
this.setCursor(0);
|
||||
|
||||
return true;
|
||||
@ -90,13 +96,14 @@ export default class SaveSlotSelectUiHandler extends MessageUiHandler {
|
||||
if (button === Button.ACTION || button === Button.CANCEL) {
|
||||
const originalCallback = this.saveSlotSelectCallback;
|
||||
if (button === Button.ACTION) {
|
||||
if (this.uiMode === SaveSlotUiMode.LOAD && !this.sessionSlots[this.cursor].hasData)
|
||||
const cursor = this.cursor + this.scrollCursor;
|
||||
if (this.uiMode === SaveSlotUiMode.LOAD && !this.sessionSlots[cursor].hasData)
|
||||
error = true;
|
||||
else {
|
||||
switch (this.uiMode) {
|
||||
case SaveSlotUiMode.LOAD:
|
||||
this.saveSlotSelectCallback = null;
|
||||
originalCallback(this.cursor);
|
||||
originalCallback(cursor);
|
||||
break;
|
||||
case SaveSlotUiMode.SAVE:
|
||||
const saveAndCallback = () => {
|
||||
@ -105,16 +112,16 @@ export default class SaveSlotSelectUiHandler extends MessageUiHandler {
|
||||
ui.revertMode();
|
||||
ui.showText(null, 0);
|
||||
ui.setMode(Mode.MESSAGE);
|
||||
originalCallback(this.cursor);
|
||||
originalCallback(cursor);
|
||||
};
|
||||
if (this.sessionSlots[this.cursor].hasData) {
|
||||
if (this.sessionSlots[cursor].hasData) {
|
||||
ui.showText('Overwrite the data in the selected slot?', null, () => {
|
||||
ui.setOverlayMode(Mode.CONFIRM, () => saveAndCallback(), () => {
|
||||
ui.revertMode();
|
||||
ui.showText(null, 0);
|
||||
}, false, 0, 19, 2000);
|
||||
});
|
||||
} else if (this.sessionSlots[this.cursor].hasData === false)
|
||||
} else if (this.sessionSlots[cursor].hasData === false)
|
||||
saveAndCallback();
|
||||
else
|
||||
return false;
|
||||
@ -130,10 +137,16 @@ export default class SaveSlotSelectUiHandler extends MessageUiHandler {
|
||||
} else {
|
||||
switch (button) {
|
||||
case Button.UP:
|
||||
success = this.setCursor(this.cursor ? this.cursor - 1 : 0);
|
||||
if (this.cursor)
|
||||
success = this.setCursor(this.cursor - 1);
|
||||
else if (this.scrollCursor)
|
||||
success = this.setScrollCursor(this.scrollCursor - 1);
|
||||
break;
|
||||
case Button.DOWN:
|
||||
success = this.setCursor(this.cursor < sessionSlotCount - 1 ? this.cursor + 1 : 2);
|
||||
if (this.cursor < 2)
|
||||
success = this.setCursor(this.cursor + 1);
|
||||
else if (this.scrollCursor < sessionSlotCount - 3)
|
||||
success = this.setScrollCursor(this.scrollCursor + 1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -178,7 +191,24 @@ export default class SaveSlotSelectUiHandler extends MessageUiHandler {
|
||||
this.cursorObj.setOrigin(0, 0);
|
||||
this.sessionSlotsContainer.add(this.cursorObj);
|
||||
}
|
||||
this.cursorObj.setPosition(4, 4 + cursor * 56);
|
||||
this.cursorObj.setPosition(4, 4 + (cursor + this.scrollCursor) * 56);
|
||||
|
||||
return changed;
|
||||
}
|
||||
|
||||
setScrollCursor(scrollCursor: integer): boolean {
|
||||
let changed = scrollCursor !== this.scrollCursor;
|
||||
|
||||
if (changed) {
|
||||
this.scrollCursor = scrollCursor;
|
||||
this.setCursor(this.cursor);
|
||||
this.scene.tweens.add({
|
||||
targets: this.sessionSlotsContainer,
|
||||
y: this.sessionSlotsContainerInitialY - 56 * scrollCursor,
|
||||
duration: Utils.fixedInt(325),
|
||||
ease: 'Sine.easeInOut'
|
||||
});
|
||||
}
|
||||
|
||||
return changed;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user