Merge branch 'main' of github.com:Greenlamp2/pokerogue into feat/mapping_setting

pull/685/head
Greenlamp 2024-05-10 18:48:37 +02:00
commit 05f2233cf2
14 changed files with 146 additions and 35 deletions

View File

@ -53,7 +53,7 @@ import PokemonSpriteSparkleHandler from './field/pokemon-sprite-sparkle-handler'
import CharSprite from './ui/char-sprite'; import CharSprite from './ui/char-sprite';
import DamageNumberHandler from './field/damage-number-handler'; import DamageNumberHandler from './field/damage-number-handler';
import PokemonInfoContainer from './ui/pokemon-info-container'; import PokemonInfoContainer from './ui/pokemon-info-container';
import { biomeDepths } from './data/biomes'; import { biomeDepths, getBiomeName } from './data/biomes';
import { UiTheme } from './enums/ui-theme'; import { UiTheme } from './enums/ui-theme';
import { SceneBase } from './scene-base'; import { SceneBase } from './scene-base';
import CandyBar from './ui/candy-bar'; import CandyBar from './ui/candy-bar';
@ -101,6 +101,19 @@ export default class BattleScene extends SceneBase {
public experimentalSprites: boolean = false; public experimentalSprites: boolean = false;
public moveAnimations: boolean = true; public moveAnimations: boolean = true;
public expGainsSpeed: integer = 0; public expGainsSpeed: integer = 0;
/**
* Defines the experience gain display mode.
*
* @remarks
* The `expParty` can have several modes:
* - `0` - Default: The normal experience gain display, nothing changed.
* - `1` - Level Up Notification: Displays the level up in the small frame instead of a message.
* - `2` - Skip: No level up frame nor message.
*
* Modes `1` and `2` are still compatible with stats display, level up, new move, etc.
* @default 0 - Uses the default normal experience gain display.
*/
public expParty: integer = 0;
public hpBarSpeed: integer = 0; public hpBarSpeed: integer = 0;
public fusionPaletteSwaps: boolean = true; public fusionPaletteSwaps: boolean = true;
public enableTouchControls: boolean = false; public enableTouchControls: boolean = false;
@ -187,6 +200,7 @@ export default class BattleScene extends SceneBase {
this.phaseQueuePrepend = []; this.phaseQueuePrepend = [];
this.phaseQueuePrependSpliceIndex = -1; this.phaseQueuePrependSpliceIndex = -1;
this.nextCommandPhaseQueue = []; this.nextCommandPhaseQueue = [];
this.updateGameInfo();
} }
loadPokemonAtlas(key: string, atlasPath: string, experimental?: boolean) { loadPokemonAtlas(key: string, atlasPath: string, experimental?: boolean) {
@ -757,6 +771,8 @@ export default class BattleScene extends SceneBase {
this.trainer.setPosition(406, 186); this.trainer.setPosition(406, 186);
this.trainer.setVisible(true); this.trainer.setVisible(true);
this.updateGameInfo();
if (reloadI18n) { if (reloadI18n) {
const localizable: Localizable[] = [ const localizable: Localizable[] = [
...allSpecies, ...allSpecies,
@ -1950,4 +1966,16 @@ export default class BattleScene extends SceneBase {
return false; return false;
} }
updateGameInfo(): void {
const gameInfo = {
gameMode: this.currentBattle ? this.gameMode.getName() : 'Title',
biome: this.currentBattle ? getBiomeName(this.arena.biomeType) : '',
wave: this.currentBattle?.waveIndex || 0,
party: this.party ? this.party.map(p => {
return { name: p.name, level: p.level };
}) : []
};
(window as any).gameInfo = gameInfo;
}
} }

View File

@ -2377,6 +2377,8 @@ export class RedirectTypeMoveAbAttr extends RedirectMoveAbAttr {
} }
} }
export class BlockRedirectAbAttr extends AbAttr { }
export class ReduceStatusEffectDurationAbAttr extends AbAttr { export class ReduceStatusEffectDurationAbAttr extends AbAttr {
private statusEffect: StatusEffect; private statusEffect: StatusEffect;
@ -3465,7 +3467,7 @@ export function initAbilities() {
.attr(PostDefendStatChangeAbAttr, (target, user, move) => move.category !== MoveCategory.STATUS, BattleStat.SPD, -1, false, true) .attr(PostDefendStatChangeAbAttr, (target, user, move) => move.category !== MoveCategory.STATUS, BattleStat.SPD, -1, false, true)
.bypassFaint(), .bypassFaint(),
new Ability(Abilities.PROPELLER_TAIL, 8) new Ability(Abilities.PROPELLER_TAIL, 8)
.unimplemented(), .attr(BlockRedirectAbAttr),
new Ability(Abilities.MIRROR_ARMOR, 8) new Ability(Abilities.MIRROR_ARMOR, 8)
.ignorable() .ignorable()
.unimplemented(), .unimplemented(),
@ -3475,7 +3477,7 @@ export function initAbilities() {
.attr(NoFusionAbilityAbAttr) .attr(NoFusionAbilityAbAttr)
.unimplemented(), .unimplemented(),
new Ability(Abilities.STALWART, 8) new Ability(Abilities.STALWART, 8)
.unimplemented(), .attr(BlockRedirectAbAttr),
new Ability(Abilities.STEAM_ENGINE, 8) new Ability(Abilities.STEAM_ENGINE, 8)
.attr(PostDefendStatChangeAbAttr, (target, user, move) => (move.type === Type.FIRE || move.type === Type.WATER) && move.category !== MoveCategory.STATUS, BattleStat.SPD, 6), .attr(PostDefendStatChangeAbAttr, (target, user, move) => (move.type === Type.FIRE || move.type === Type.WATER) && move.category !== MoveCategory.STATUS, BattleStat.SPD, 6),
new Ability(Abilities.PUNK_ROCK, 8) new Ability(Abilities.PUNK_ROCK, 8)

View File

@ -2653,6 +2653,11 @@ const crashDamageFunc = (user: Pokemon, move: Move) => {
}; };
export class TypelessAttr extends MoveAttr { } export class TypelessAttr extends MoveAttr { }
/**
* Attribute used for moves which ignore redirection effects, and always target their original target, i.e. Snipe Shot
* Bypasses Storm Drain, Follow Me, Ally Switch, and the like.
*/
export class BypassRedirectAttr extends MoveAttr { }
export class DisableMoveAttr extends MoveEffectAttr { export class DisableMoveAttr extends MoveEffectAttr {
constructor() { constructor() {
@ -6172,7 +6177,8 @@ export function initMoves() {
.attr(DiscourageFrequentUseAttr) .attr(DiscourageFrequentUseAttr)
.ignoresVirtual(), .ignoresVirtual(),
new AttackMove(Moves.SNIPE_SHOT, Type.WATER, MoveCategory.SPECIAL, 80, 100, 15, -1, 0, 8) new AttackMove(Moves.SNIPE_SHOT, Type.WATER, MoveCategory.SPECIAL, 80, 100, 15, -1, 0, 8)
.partial(), .attr(HighCritAttr)
.attr(BypassRedirectAttr),
new AttackMove(Moves.JAW_LOCK, Type.DARK, MoveCategory.PHYSICAL, 80, 100, 10, -1, 0, 8) new AttackMove(Moves.JAW_LOCK, Type.DARK, MoveCategory.PHYSICAL, 80, 100, 10, -1, 0, 8)
.attr(AddBattlerTagAttr, BattlerTagType.TRAPPED, false, false, 1) .attr(AddBattlerTagAttr, BattlerTagType.TRAPPED, false, false, 1)
.attr(AddBattlerTagAttr, BattlerTagType.TRAPPED, true, false, 1) .attr(AddBattlerTagAttr, BattlerTagType.TRAPPED, true, false, 1)

View File

@ -2,5 +2,6 @@ import { SimpleTranslationEntries } from "#app/plugins/i18n";
export const fightUiHandler: SimpleTranslationEntries = { export const fightUiHandler: SimpleTranslationEntries = {
"pp": "PP", "pp": "PP",
"power": "POWER", "power": "Power",
"accuracy": "Accuracy",
} as const; } as const;

View File

@ -2,5 +2,6 @@ import { SimpleTranslationEntries } from "#app/plugins/i18n";
export const fightUiHandler: SimpleTranslationEntries = { export const fightUiHandler: SimpleTranslationEntries = {
"pp": "PP", "pp": "PP",
"power": "POWER", "power": "Power",
"accuracy": "Accuracy",
} as const; } as const;

View File

@ -2,5 +2,6 @@ import { SimpleTranslationEntries } from "#app/plugins/i18n";
export const fightUiHandler: SimpleTranslationEntries = { export const fightUiHandler: SimpleTranslationEntries = {
"pp": "PP", "pp": "PP",
"power": "POTENCIA", "power": "Potencia",
"accuracy": "Accuracy",
} as const; } as const;

View File

@ -2,5 +2,6 @@ import { SimpleTranslationEntries } from "#app/plugins/i18n";
export const fightUiHandler: SimpleTranslationEntries = { export const fightUiHandler: SimpleTranslationEntries = {
"pp": "PP", "pp": "PP",
"power": "PUISSANCE", "power": "Puissance",
"accuracy": "Précision",
} as const; } as const;

View File

@ -2,5 +2,6 @@ import { SimpleTranslationEntries } from "#app/plugins/i18n";
export const fightUiHandler: SimpleTranslationEntries = { export const fightUiHandler: SimpleTranslationEntries = {
"pp": "PP", "pp": "PP",
"power": "POTENZA", "power": "Potenza",
"accuracy": "Accuracy",
} as const; } as const;

View File

@ -2,5 +2,6 @@ import { SimpleTranslationEntries } from "#app/plugins/i18n";
export const fightUiHandler: SimpleTranslationEntries = { export const fightUiHandler: SimpleTranslationEntries = {
"pp": "PP", "pp": "PP",
"power": "POWER", "power": "Power",
"accuracy": "Accuracy",
} as const; } as const;

View File

@ -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 { default as Pokemon, PlayerPokemon, EnemyPokemon, PokemonMove, MoveResult, DamageResult, FieldPosition, HitResult, TurnMove } from "./field/pokemon";
import * as Utils from './utils'; import * as Utils from './utils';
import { Moves } from "./data/enums/moves"; 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, FixedDamageAttr, PostVictoryStatChangeAttr, OneHitKOAccuracyAttr, ForceSwitchOutAttr, VariableTargetAttr } 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 } from "./data/move";
import { Mode } from './ui/ui'; import { Mode } from './ui/ui';
import { Command } from "./ui/command-ui-handler"; import { Command } from "./ui/command-ui-handler";
import { Stat } from "./data/pokemon-stat"; import { Stat } from "./data/pokemon-stat";
@ -30,7 +30,7 @@ import { Weather, WeatherType, getRandomWeatherType, getTerrainBlockMessage, get
import { TempBattleStat } from "./data/temp-battle-stat"; import { TempBattleStat } from "./data/temp-battle-stat";
import { ArenaTagSide, ArenaTrapTag, MistTag, TrickRoomTag } from "./data/arena-tag"; import { ArenaTagSide, ArenaTrapTag, MistTag, TrickRoomTag } from "./data/arena-tag";
import { ArenaTagType } from "./data/enums/arena-tag-type"; import { ArenaTagType } from "./data/enums/arena-tag-type";
import { CheckTrappedAbAttr, IgnoreOpponentStatChangesAbAttr, PostAttackAbAttr, PostBattleAbAttr, PostDefendAbAttr, PostSummonAbAttr, PostTurnAbAttr, PostWeatherLapseAbAttr, PreSwitchOutAbAttr, PreWeatherDamageAbAttr, ProtectStatAbAttr, RedirectMoveAbAttr, RunSuccessAbAttr, StatChangeMultiplierAbAttr, SuppressWeatherEffectAbAttr, SyncEncounterNatureAbAttr, applyAbAttrs, applyCheckTrappedAbAttrs, applyPostAttackAbAttrs, applyPostBattleAbAttrs, applyPostDefendAbAttrs, applyPostSummonAbAttrs, applyPostTurnAbAttrs, applyPostWeatherLapseAbAttrs, applyPreStatChangeAbAttrs, applyPreSwitchOutAbAttrs, applyPreWeatherEffectAbAttrs, BattleStatMultiplierAbAttr, applyBattleStatMultiplierAbAttrs, IncrementMovePriorityAbAttr, applyPostVictoryAbAttrs, PostVictoryAbAttr, applyPostBattleInitAbAttrs, PostBattleInitAbAttr, BlockNonDirectDamageAbAttr as BlockNonDirectDamageAbAttr, applyPostKnockOutAbAttrs, PostKnockOutAbAttr, PostBiomeChangeAbAttr, applyPostFaintAbAttrs, PostFaintAbAttr, IncreasePpAbAttr, PostStatChangeAbAttr, applyPostStatChangeAbAttrs, AlwaysHitAbAttr, PreventBerryUseAbAttr, StatChangeCopyAbAttr } from "./data/ability"; import { CheckTrappedAbAttr, IgnoreOpponentStatChangesAbAttr, PostAttackAbAttr, PostBattleAbAttr, PostDefendAbAttr, PostSummonAbAttr, PostTurnAbAttr, PostWeatherLapseAbAttr, PreSwitchOutAbAttr, PreWeatherDamageAbAttr, ProtectStatAbAttr, RedirectMoveAbAttr, BlockRedirectAbAttr, RunSuccessAbAttr, StatChangeMultiplierAbAttr, SuppressWeatherEffectAbAttr, SyncEncounterNatureAbAttr, applyAbAttrs, applyCheckTrappedAbAttrs, applyPostAttackAbAttrs, applyPostBattleAbAttrs, applyPostDefendAbAttrs, applyPostSummonAbAttrs, applyPostTurnAbAttrs, applyPostWeatherLapseAbAttrs, applyPreStatChangeAbAttrs, applyPreSwitchOutAbAttrs, applyPreWeatherEffectAbAttrs, BattleStatMultiplierAbAttr, applyBattleStatMultiplierAbAttrs, IncrementMovePriorityAbAttr, applyPostVictoryAbAttrs, PostVictoryAbAttr, applyPostBattleInitAbAttrs, PostBattleInitAbAttr, BlockNonDirectDamageAbAttr as BlockNonDirectDamageAbAttr, applyPostKnockOutAbAttrs, PostKnockOutAbAttr, PostBiomeChangeAbAttr, applyPostFaintAbAttrs, PostFaintAbAttr, IncreasePpAbAttr, PostStatChangeAbAttr, applyPostStatChangeAbAttrs, AlwaysHitAbAttr, PreventBerryUseAbAttr, StatChangeCopyAbAttr } from "./data/ability";
import { Unlockables, getUnlockableName } from "./system/unlockables"; import { Unlockables, getUnlockableName } from "./system/unlockables";
import { getBiomeKey } from "./field/arena"; import { getBiomeKey } from "./field/arena";
import { BattleType, BattlerIndex, TurnCommand } from "./battle"; import { BattleType, BattlerIndex, TurnCommand } from "./battle";
@ -680,6 +680,8 @@ export class EncounterPhase extends BattlePhase {
start() { start() {
super.start(); super.start();
this.scene.updateGameInfo();
this.scene.initSession(); this.scene.initSession();
const loadEnemyAssets = []; const loadEnemyAssets = [];
@ -2209,13 +2211,22 @@ export class MovePhase extends BattlePhase {
} }
// Move redirection abilities (ie. Storm Drain) only support single target moves // Move redirection abilities (ie. Storm Drain) only support single target moves
const moveTarget = this.targets.length === 1 const moveTarget = this.targets.length === 1
? new Utils.IntegerHolder(this.targets[0]) ? new Utils.IntegerHolder(this.targets[0])
: null; : null;
if (moveTarget) { if (moveTarget) {
this.scene.getField(true).filter(p => p !== this.pokemon).forEach(p => applyAbAttrs(RedirectMoveAbAttr, p, null, this.move.moveId, moveTarget)); var oldTarget = moveTarget.value;
this.targets[0] = moveTarget.value; this.scene.getField(true).filter(p => p !== this.pokemon).forEach(p => applyAbAttrs(RedirectMoveAbAttr, p, null, this.move.moveId, moveTarget));
} //Check if this move is immune to being redirected, and restore its target to the intended target if it is.
if ((this.pokemon.hasAbilityWithAttr(BlockRedirectAbAttr) || this.move.getMove().getAttrs(BypassRedirectAttr).length)) {
//If an ability prevented this move from being redirected, display its ability pop up.
if ((this.pokemon.hasAbilityWithAttr(BlockRedirectAbAttr) && !this.move.getMove().getAttrs(BypassRedirectAttr).length) && oldTarget != moveTarget.value) {
this.scene.unshiftPhase(new ShowAbilityPhase(this.scene, this.pokemon.getBattlerIndex(), this.pokemon.getPassiveAbility().hasAttr(BlockRedirectAbAttr)));
}
moveTarget.value = oldTarget;
}
this.targets[0] = moveTarget.value;
}
if (this.targets.length === 1 && this.targets[0] === BattlerIndex.ATTACKER) { if (this.targets.length === 1 && this.targets[0] === BattlerIndex.ATTACKER) {
if (this.pokemon.turnData.attacksReceived.length) { if (this.pokemon.turnData.attacksReceived.length) {
@ -3745,11 +3756,20 @@ export class ShowPartyExpBarPhase extends PlayerPartyMemberPokemonPhase {
this.scene.unshiftPhase(new HidePartyExpBarPhase(this.scene)); this.scene.unshiftPhase(new HidePartyExpBarPhase(this.scene));
pokemon.updateInfo(); pokemon.updateInfo();
if (this.scene.expGainsSpeed < 3) { if (this.scene.expParty === 2) { // 2 - Skip - no level up frame nor message
this.scene.partyExpBar.showPokemonExp(pokemon, exp.value).then(() => { this.end();
if (newLevel > lastLevel) } else if (this.scene.expParty === 1) { // 1 - Only level up - we display the level up in the small frame instead of a message
this.end(); if (newLevel > lastLevel) { // this means if we level up
else // instead of displaying the exp gain in the small frame, we display the new level
// we use the same method for mode 0 & 1, by giving a parameter saying to display the exp or the level
this.scene.partyExpBar.showPokemonExp(pokemon, exp.value, this.scene.expParty === 1, newLevel).then(() => {
setTimeout(() => this.end(), 800 / Math.pow(2, this.scene.expGainsSpeed));
});
} else {
this.end();
}
} else if (this.scene.expGainsSpeed < 3) {
this.scene.partyExpBar.showPokemonExp(pokemon, exp.value, this.scene.expParty === 1, newLevel).then(() => {
setTimeout(() => this.end(), 500 / Math.pow(2, this.scene.expGainsSpeed)); setTimeout(() => this.end(), 500 / Math.pow(2, this.scene.expGainsSpeed));
}); });
} else { } else {
@ -3780,6 +3800,7 @@ export class LevelUpPhase extends PlayerPartyMemberPokemonPhase {
this.lastLevel = lastLevel; this.lastLevel = lastLevel;
this.level = level; this.level = level;
this.scene = scene;
} }
start() { start() {
@ -3794,8 +3815,15 @@ export class LevelUpPhase extends PlayerPartyMemberPokemonPhase {
const prevStats = pokemon.stats.slice(0); const prevStats = pokemon.stats.slice(0);
pokemon.calculateStats(); pokemon.calculateStats();
pokemon.updateInfo(); pokemon.updateInfo();
this.scene.playSound('level_up_fanfare'); if (this.scene.expParty === 0) { // 0 - default - the normal exp gain display, nothing changed
this.scene.ui.showText(i18next.t('battle:levelUp', { pokemonName: this.getPokemon().name, level: this.level }), null, () => this.scene.ui.getMessageHandler().promptLevelUpStats(this.partyMemberIndex, prevStats, false).then(() => this.end()), null, true); this.scene.playSound('level_up_fanfare');
this.scene.ui.showText(i18next.t('battle:levelUp', { pokemonName: this.getPokemon().name, level: this.level }), null, () => this.scene.ui.getMessageHandler().promptLevelUpStats(this.partyMemberIndex, prevStats, false).then(() => this.end()), null, true);
} else if (this.scene.expParty === 2) { // 2 - Skip - no level up frame nor message
this.end();
} else { // 1 - Only level up - we display the level up in the small frame instead of a message
// we still want to display the stats if activated
this.scene.ui.getMessageHandler().promptLevelUpStats(this.partyMemberIndex, prevStats, false).then(() => this.end());
}
if (this.level <= 100) { if (this.level <= 100) {
const levelMoves = this.getPokemon().getLevelMoves(this.lastLevel + 1); const levelMoves = this.getPokemon().getLevelMoves(this.lastLevel + 1);
for (let lm of levelMoves) for (let lm of levelMoves)

View File

@ -21,6 +21,7 @@ export enum Setting {
Move_Animations = "MOVE_ANIMATIONS", Move_Animations = "MOVE_ANIMATIONS",
Show_Stats_on_Level_Up = "SHOW_LEVEL_UP_STATS", Show_Stats_on_Level_Up = "SHOW_LEVEL_UP_STATS",
EXP_Gains_Speed = "EXP_GAINS_SPEED", EXP_Gains_Speed = "EXP_GAINS_SPEED",
EXP_Party_Display = "EXP_PARTY_DISPLAY",
HP_Bar_Speed = "HP_BAR_SPEED", HP_Bar_Speed = "HP_BAR_SPEED",
Fusion_Palette_Swaps = "FUSION_PALETTE_SWAPS", Fusion_Palette_Swaps = "FUSION_PALETTE_SWAPS",
Player_Gender = "PLAYER_GENDER", Player_Gender = "PLAYER_GENDER",
@ -51,6 +52,7 @@ export const settingOptions: SettingOptions = {
[Setting.Move_Animations]: [ 'Off', 'On' ], [Setting.Move_Animations]: [ 'Off', 'On' ],
[Setting.Show_Stats_on_Level_Up]: [ 'Off', 'On' ], [Setting.Show_Stats_on_Level_Up]: [ 'Off', 'On' ],
[Setting.EXP_Gains_Speed]: [ 'Normal', 'Fast', 'Faster', 'Skip' ], [Setting.EXP_Gains_Speed]: [ 'Normal', 'Fast', 'Faster', 'Skip' ],
[Setting.EXP_Party_Display]: [ 'Normal', 'Level Up Notification', 'Skip' ],
[Setting.HP_Bar_Speed]: [ 'Normal', 'Fast', 'Faster', 'Instant' ], [Setting.HP_Bar_Speed]: [ 'Normal', 'Fast', 'Faster', 'Instant' ],
[Setting.Fusion_Palette_Swaps]: [ 'Off', 'On' ], [Setting.Fusion_Palette_Swaps]: [ 'Off', 'On' ],
[Setting.Player_Gender]: [ 'Boy', 'Girl' ], [Setting.Player_Gender]: [ 'Boy', 'Girl' ],
@ -73,6 +75,7 @@ export const settingDefaults: SettingDefaults = {
[Setting.Move_Animations]: 1, [Setting.Move_Animations]: 1,
[Setting.Show_Stats_on_Level_Up]: 1, [Setting.Show_Stats_on_Level_Up]: 1,
[Setting.EXP_Gains_Speed]: 0, [Setting.EXP_Gains_Speed]: 0,
[Setting.EXP_Party_Display]: 0,
[Setting.HP_Bar_Speed]: 0, [Setting.HP_Bar_Speed]: 0,
[Setting.Fusion_Palette_Swaps]: 1, [Setting.Fusion_Palette_Swaps]: 1,
[Setting.Player_Gender]: 0, [Setting.Player_Gender]: 0,
@ -128,6 +131,9 @@ export function setSetting(scene: BattleScene, setting: Setting, value: integer)
case Setting.EXP_Gains_Speed: case Setting.EXP_Gains_Speed:
scene.expGainsSpeed = value; scene.expGainsSpeed = value;
break; break;
case Setting.EXP_Party_Display:
scene.expParty = value;
break;
case Setting.HP_Bar_Speed: case Setting.HP_Bar_Speed:
scene.hpBarSpeed = value; scene.hpBarSpeed = value;
break; break;

View File

@ -17,6 +17,8 @@ export default class FightUiHandler extends UiHandler {
private ppText: Phaser.GameObjects.Text; private ppText: Phaser.GameObjects.Text;
private powerLabel: Phaser.GameObjects.Text; private powerLabel: Phaser.GameObjects.Text;
private powerText: Phaser.GameObjects.Text; private powerText: Phaser.GameObjects.Text;
private accuracyLabel: Phaser.GameObjects.Text;
private accuracyText: Phaser.GameObjects.Text;
private cursorObj: Phaser.GameObjects.Image; private cursorObj: Phaser.GameObjects.Image;
private moveCategoryIcon: Phaser.GameObjects.Sprite; private moveCategoryIcon: Phaser.GameObjects.Sprite;
@ -33,35 +35,46 @@ export default class FightUiHandler extends UiHandler {
this.movesContainer = this.scene.add.container(18, -38.7); this.movesContainer = this.scene.add.container(18, -38.7);
ui.add(this.movesContainer); ui.add(this.movesContainer);
this.typeIcon = this.scene.add.sprite((this.scene.game.canvas.width / 6) - 57, -34, 'types', 'unknown'); this.typeIcon = this.scene.add.sprite((this.scene.game.canvas.width / 6) - 57, -36, 'types', 'unknown');
this.typeIcon.setVisible(false); this.typeIcon.setVisible(false);
ui.add(this.typeIcon); ui.add(this.typeIcon);
this.moveCategoryIcon = this.scene.add.sprite((this.scene.game.canvas.width / 6) - 25, -34, 'categories', 'physical'); this.moveCategoryIcon = this.scene.add.sprite((this.scene.game.canvas.width / 6) - 25, -36, 'categories', 'physical');
this.moveCategoryIcon.setVisible(false); this.moveCategoryIcon.setVisible(false);
ui.add(this.moveCategoryIcon); ui.add(this.moveCategoryIcon);
this.ppLabel = addTextObject(this.scene, (this.scene.game.canvas.width / 6) - 70, -22, 'PP', TextStyle.TOOLTIP_CONTENT); this.ppLabel = addTextObject(this.scene, (this.scene.game.canvas.width / 6) - 70, -26, 'PP', TextStyle.MOVE_INFO_CONTENT);
this.ppLabel.setOrigin(0.0, 0.5); this.ppLabel.setOrigin(0.0, 0.5);
this.ppLabel.setVisible(false); this.ppLabel.setVisible(false);
this.ppLabel.setText(i18next.t('fightUiHandler:pp')); this.ppLabel.setText(i18next.t('fightUiHandler:pp'));
ui.add(this.ppLabel); ui.add(this.ppLabel);
this.ppText = addTextObject(this.scene, (this.scene.game.canvas.width / 6) - 12, -22, '--/--', TextStyle.TOOLTIP_CONTENT); this.ppText = addTextObject(this.scene, (this.scene.game.canvas.width / 6) - 12, -26, '--/--', TextStyle.MOVE_INFO_CONTENT);
this.ppText.setOrigin(1, 0.5); this.ppText.setOrigin(1, 0.5);
this.ppText.setVisible(false); this.ppText.setVisible(false);
ui.add(this.ppText); ui.add(this.ppText);
this.powerLabel = addTextObject(this.scene, (this.scene.game.canvas.width / 6) - 70, -12, 'POWER', TextStyle.TOOLTIP_CONTENT); this.powerLabel = addTextObject(this.scene, (this.scene.game.canvas.width / 6) - 70, -18, 'POWER', TextStyle.MOVE_INFO_CONTENT);
this.powerLabel.setOrigin(0.0, 0.5); this.powerLabel.setOrigin(0.0, 0.5);
this.powerLabel.setVisible(false); this.powerLabel.setVisible(false);
this.powerLabel.setText(i18next.t('fightUiHandler:power')); this.powerLabel.setText(i18next.t('fightUiHandler:power'));
ui.add(this.powerLabel); ui.add(this.powerLabel);
this.powerText = addTextObject(this.scene, (this.scene.game.canvas.width / 6) - 12, -12, '---', TextStyle.TOOLTIP_CONTENT); this.powerText = addTextObject(this.scene, (this.scene.game.canvas.width / 6) - 12, -18, '---', TextStyle.MOVE_INFO_CONTENT);
this.powerText.setOrigin(1, 0.5); this.powerText.setOrigin(1, 0.5);
this.powerText.setVisible(false); this.powerText.setVisible(false);
ui.add(this.powerText); ui.add(this.powerText);
this.accuracyLabel = addTextObject(this.scene, (this.scene.game.canvas.width / 6) - 70, -10, 'ACC', TextStyle.MOVE_INFO_CONTENT);
this.accuracyLabel.setOrigin(0.0, 0.5);
this.accuracyLabel.setVisible(false);
this.accuracyLabel.setText(i18next.t('fightUiHandler:accuracy'))
ui.add(this.accuracyLabel);
this.accuracyText = addTextObject(this.scene, (this.scene.game.canvas.width / 6) - 12, -10, '---', TextStyle.MOVE_INFO_CONTENT);
this.accuracyText.setOrigin(1, 0.5);
this.accuracyText.setVisible(false);
ui.add(this.accuracyText);
} }
show(args: any[]): boolean { show(args: any[]): boolean {
@ -152,11 +165,13 @@ export default class FightUiHandler extends UiHandler {
this.moveCategoryIcon.setTexture('categories', MoveCategory[pokemonMove.getMove().category].toLowerCase()).setScale(1.0); this.moveCategoryIcon.setTexture('categories', MoveCategory[pokemonMove.getMove().category].toLowerCase()).setScale(1.0);
const power = pokemonMove.getMove().power; const power = pokemonMove.getMove().power;
const accuracy = pokemonMove.getMove().accuracy;
const maxPP = pokemonMove.getMovePp(); const maxPP = pokemonMove.getMovePp();
const pp = maxPP - pokemonMove.ppUsed; const pp = maxPP - pokemonMove.ppUsed;
this.ppText.setText(`${Utils.padInt(pp, 2, ' ')}/${Utils.padInt(maxPP, 2, ' ')}`); this.ppText.setText(`${Utils.padInt(pp, 2, ' ')}/${Utils.padInt(maxPP, 2, ' ')}`);
this.powerText.setText(`${power >= 0 ? power : '---'}`); this.powerText.setText(`${power >= 0 ? power : '---'}`);
this.accuracyText.setText(`${accuracy >= 0 ? accuracy : '---'}`);
} }
this.typeIcon.setVisible(hasMove); this.typeIcon.setVisible(hasMove);
@ -164,6 +179,8 @@ export default class FightUiHandler extends UiHandler {
this.ppText.setVisible(hasMove); this.ppText.setVisible(hasMove);
this.powerLabel.setVisible(hasMove); this.powerLabel.setVisible(hasMove);
this.powerText.setVisible(hasMove); this.powerText.setVisible(hasMove);
this.accuracyLabel.setVisible(hasMove);
this.accuracyText.setVisible(hasMove);
this.moveCategoryIcon.setVisible(hasMove); this.moveCategoryIcon.setVisible(hasMove);
this.cursorObj.setPosition(13 + (cursor % 2 === 1 ? 100 : 0), -31 + (cursor >= 2 ? 15 : 0)); this.cursorObj.setPosition(13 + (cursor % 2 === 1 ? 100 : 0), -31 + (cursor >= 2 ? 15 : 0));
@ -189,6 +206,8 @@ export default class FightUiHandler extends UiHandler {
this.ppText.setVisible(false); this.ppText.setVisible(false);
this.powerLabel.setVisible(false); this.powerLabel.setVisible(false);
this.powerText.setVisible(false); this.powerText.setVisible(false);
this.accuracyLabel.setVisible(false);
this.accuracyText.setVisible(false);
this.moveCategoryIcon.setVisible(false); this.moveCategoryIcon.setVisible(false);
this.eraseCursor(); this.eraseCursor();
} }

View File

@ -29,7 +29,7 @@ export default class PartyExpBar extends Phaser.GameObjects.Container {
this.shown = false; this.shown = false;
} }
showPokemonExp(pokemon: Pokemon, expValue: integer): Promise<void> { showPokemonExp(pokemon: Pokemon, expValue: integer, showOnlyLevelUp: boolean, newLevel: number): Promise<void> {
return new Promise<void>(resolve => { return new Promise<void>(resolve => {
if (this.shown) if (this.shown)
return resolve(); return resolve();
@ -39,7 +39,17 @@ export default class PartyExpBar extends Phaser.GameObjects.Container {
this.add(this.pokemonIcon); this.add(this.pokemonIcon);
this.expText.setText(`+${expValue.toString()}`); // if we want to only display the level in the small frame
if (showOnlyLevelUp) {
if (newLevel > 200) { // if the level is greater than 200, we only display Lv. UP
this.expText.setText('Lv. UP');
} else { // otherwise we display Lv. Up and the new level
this.expText.setText(`Lv. UP: ${newLevel.toString()}`);
}
} else {
// if we want to display the exp
this.expText.setText(`+${expValue.toString()}`);
}
this.bg.width = this.expText.displayWidth + 28; this.bg.width = this.expText.displayWidth + 28;

View File

@ -24,7 +24,8 @@ export enum TextStyle {
SETTINGS_LABEL, SETTINGS_LABEL,
SETTINGS_SELECTED, SETTINGS_SELECTED,
TOOLTIP_TITLE, TOOLTIP_TITLE,
TOOLTIP_CONTENT TOOLTIP_CONTENT,
MOVE_INFO_CONTENT
}; };
export function addTextObject(scene: Phaser.Scene, x: number, y: number, content: string, style: TextStyle, extraStyleOptions?: Phaser.Types.GameObjects.Text.TextStyle): Phaser.GameObjects.Text { export function addTextObject(scene: Phaser.Scene, x: number, y: number, content: string, style: TextStyle, extraStyleOptions?: Phaser.Types.GameObjects.Text.TextStyle): Phaser.GameObjects.Text {
@ -106,6 +107,10 @@ function getTextStyleOptions(style: TextStyle, uiTheme: UiTheme, extraStyleOptio
styleOptions.fontSize = '64px'; styleOptions.fontSize = '64px';
shadowSize = 4; shadowSize = 4;
break; break;
case TextStyle.MOVE_INFO_CONTENT:
styleOptions.fontSize = '56px';
shadowSize = 3;
break;
} }
shadowColor = getTextColor(style, true, uiTheme); shadowColor = getTextColor(style, true, uiTheme);
@ -130,6 +135,7 @@ export function getTextColor(textStyle: TextStyle, shadow?: boolean, uiTheme: Ui
case TextStyle.MESSAGE: case TextStyle.MESSAGE:
return !shadow ? '#f8f8f8' : '#6b5a73'; return !shadow ? '#f8f8f8' : '#6b5a73';
case TextStyle.WINDOW: case TextStyle.WINDOW:
case TextStyle.MOVE_INFO_CONTENT:
case TextStyle.TOOLTIP_CONTENT: case TextStyle.TOOLTIP_CONTENT:
if (uiTheme) if (uiTheme)
return !shadow ? '#484848' : '#d0d0c8'; return !shadow ? '#484848' : '#d0d0c8';