mirror of
https://github.com/pagefaultgames/pokerogue.git
synced 2025-07-28 11:12:24 +02:00
Keeps shiny variant, gender and form when switching to evolutions; show ability descriptions; properly displaying sprites for megas and other forms
This commit is contained in:
parent
955af4b00d
commit
657fdf07ed
@ -116,6 +116,10 @@ export default abstract class AbstractOptionSelectUiHandler extends UiHandler {
|
||||
).join("\n"),
|
||||
TextStyle.WINDOW, { maxLines: options.length, lineSpacing: 12 }
|
||||
);
|
||||
console.log(options.map(o => o.item
|
||||
? `[color=${o.color || "white"}] ${o.label}[/color]`
|
||||
: `[color=${o.color || "white"}]${o.label}[/color]`
|
||||
).join("\n"));
|
||||
this.optionSelectText.setOrigin(0, 0);
|
||||
this.optionSelectText.setName("text-option-select");
|
||||
this.optionSelectContainer.add(this.optionSelectText);
|
||||
@ -195,6 +199,8 @@ export default abstract class AbstractOptionSelectUiHandler extends UiHandler {
|
||||
|
||||
let playSound = true;
|
||||
|
||||
console.log(button);
|
||||
|
||||
if (button === Button.ACTION || button === Button.CANCEL) {
|
||||
if (this.blockInput) {
|
||||
ui.playError();
|
||||
@ -203,29 +209,36 @@ export default abstract class AbstractOptionSelectUiHandler extends UiHandler {
|
||||
|
||||
success = true;
|
||||
if (button === Button.CANCEL) {
|
||||
console.log("Pressed CANCEL");
|
||||
if (this.config?.maxOptions && this.config.options.length > this.config.maxOptions) {
|
||||
this.scrollCursor = (this.config.options.length - this.config.maxOptions) + 1;
|
||||
this.cursor = options.length - 1;
|
||||
this.cursor = unskippedIndices.length - 1;
|
||||
console.log("A", this.scrollCursor, this.cursor);
|
||||
} else if (!this.config?.noCancel) {
|
||||
this.setCursor(options.length - 1);
|
||||
this.setCursor(unskippedIndices.length - 1);
|
||||
console.log("B", this.scrollCursor, this.cursor);
|
||||
} else {
|
||||
console.log("C", this.scrollCursor, this.cursor);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
const option = this.config?.options[unskippedIndices[this.cursor + (this.scrollCursor - (this.scrollCursor ? 1 : 0))]];
|
||||
const option = this.config?.options[unskippedIndices[this.cursor] + (this.scrollCursor - (this.scrollCursor ? 1 : 0))];
|
||||
console.log("CD", option);
|
||||
if (option?.handler()) {
|
||||
if (!option.keepOpen) {
|
||||
console.log("D", this.scrollCursor, this.cursor);
|
||||
this.clear();
|
||||
}
|
||||
playSound = !option.overrideSound;
|
||||
} else {
|
||||
console.log("E", this.scrollCursor, this.cursor);
|
||||
ui.playError();
|
||||
}
|
||||
} else if (button === Button.SUBMIT && ui.getMode() === Mode.AUTO_COMPLETE) {
|
||||
// this is here to differentiate between a Button.SUBMIT vs Button.ACTION within the autocomplete handler
|
||||
// this is here because Button.ACTION is picked up as z on the keyboard, meaning if you're typing and hit z, it'll select the option you've chosen
|
||||
success = true;
|
||||
const option = this.config?.options[this.cursor + (this.scrollCursor - (this.scrollCursor ? 1 : 0))];
|
||||
const option = this.config?.options[unskippedIndices[this.cursor] + (this.scrollCursor - (this.scrollCursor ? 1 : 0))];
|
||||
if (option?.handler()) {
|
||||
if (!option.keepOpen) {
|
||||
this.clear();
|
||||
@ -253,7 +266,7 @@ export default abstract class AbstractOptionSelectUiHandler extends UiHandler {
|
||||
}
|
||||
if (this.config?.supportHover) {
|
||||
// handle hover code if the element supports hover-handlers and the option has the optional hover-handler set.
|
||||
this.config?.options[this.cursor + (this.scrollCursor - (this.scrollCursor ? 1 : 0))]?.onHover?.();
|
||||
this.config?.options[unskippedIndices[this.cursor] + (this.scrollCursor - (this.scrollCursor ? 1 : 0))]?.onHover?.();
|
||||
}
|
||||
}
|
||||
|
||||
@ -332,9 +345,9 @@ export default abstract class AbstractOptionSelectUiHandler extends UiHandler {
|
||||
// Move the cursor up or down by 1
|
||||
const isDown = cursor && cursor > this.cursor;
|
||||
if (isDown) {
|
||||
if (options[cursor].label === scrollDownLabel) {
|
||||
if (options[Math.min(unskippedIndices[cursor], options.length)].label === scrollDownLabel) {
|
||||
isScroll = true;
|
||||
this.scrollCursor++;
|
||||
this.scrollCursor += unskippedIndices[cursor] - unskippedIndices[this.cursor];
|
||||
}
|
||||
} else {
|
||||
if (!cursor && this.scrollCursor) {
|
||||
|
158
src/ui/pokedex-info-overlay.ts
Normal file
158
src/ui/pokedex-info-overlay.ts
Normal file
@ -0,0 +1,158 @@
|
||||
import BattleScene, { InfoToggle } from "../battle-scene";
|
||||
import { TextStyle, addTextObject } from "./text";
|
||||
import { addWindow } from "./ui-theme";
|
||||
import * as Utils from "../utils";
|
||||
import i18next from "i18next";
|
||||
|
||||
export interface PokedexInfoOverlaySettings {
|
||||
delayVisibility?: boolean; // if true, showing the overlay will only set it to active and populate the fields and the handler using this field has to manually call setVisible later.
|
||||
scale?:number; // scale the box? A scale of 0.5 is recommended
|
||||
top?: boolean; // should the effect box be on top?
|
||||
right?: boolean; // should the effect box be on the right?
|
||||
onSide?: boolean; // should the effect be on the side? ignores top argument if true
|
||||
//location and width of the component; unaffected by scaling
|
||||
x?: number;
|
||||
y?: number;
|
||||
/** Default is always half the screen, regardless of scale */
|
||||
width?: number;
|
||||
/** Determines whether to display the small secondary box */
|
||||
hideEffectBox?: boolean;
|
||||
hideBg?: boolean;
|
||||
}
|
||||
|
||||
const EFF_HEIGHT = 36;
|
||||
const EFF_WIDTH = 82;
|
||||
const DESC_HEIGHT = 36;
|
||||
const BORDER = 8;
|
||||
const GLOBAL_SCALE = 6;
|
||||
|
||||
export default class PokedexInfoOverlay extends Phaser.GameObjects.Container implements InfoToggle {
|
||||
public active: boolean = false;
|
||||
|
||||
private desc: Phaser.GameObjects.Text;
|
||||
private descScroll : Phaser.Tweens.Tween | null = null;
|
||||
|
||||
private descBg: Phaser.GameObjects.NineSlice;
|
||||
|
||||
private options : PokedexInfoOverlaySettings;
|
||||
|
||||
constructor(scene: BattleScene, options?: PokedexInfoOverlaySettings) {
|
||||
if (options?.onSide) {
|
||||
options.top = false;
|
||||
}
|
||||
super(scene, options?.x, options?.y);
|
||||
const scale = options?.scale || 1; // set up the scale
|
||||
this.setScale(scale);
|
||||
this.options = options || {};
|
||||
|
||||
// prepare the description box
|
||||
const width = (options?.width || PokedexInfoOverlay.getWidth(scale, scene)) / scale; // divide by scale as we always want this to be half a window wide
|
||||
this.descBg = addWindow(scene, (options?.onSide && !options?.right ? EFF_WIDTH : 0), options?.top ? EFF_HEIGHT : 0, width - (options?.onSide ? EFF_WIDTH : 0), DESC_HEIGHT);
|
||||
this.descBg.setOrigin(0, 0);
|
||||
this.add(this.descBg);
|
||||
|
||||
// set up the description; wordWrap uses true pixels, unaffected by any scaling, while other values are affected
|
||||
this.desc = addTextObject(scene, (options?.onSide && !options?.right ? EFF_WIDTH : 0) + BORDER, (options?.top ? EFF_HEIGHT : 0) + BORDER - 2, "", TextStyle.BATTLE_INFO, { wordWrap: { width: (width - (BORDER - 2) * 2 - (options?.onSide ? EFF_WIDTH : 0)) * GLOBAL_SCALE }});
|
||||
this.desc.setLineSpacing(i18next.resolvedLanguage === "ja" ? 25 : 5);
|
||||
|
||||
// limit the text rendering, required for scrolling later on
|
||||
const maskPointOrigin = {
|
||||
x: (options?.x || 0),
|
||||
y: (options?.y || 0),
|
||||
};
|
||||
if (maskPointOrigin.x < 0) {
|
||||
maskPointOrigin.x += this.scene.game.canvas.width / GLOBAL_SCALE;
|
||||
}
|
||||
if (maskPointOrigin.y < 0) {
|
||||
maskPointOrigin.y += this.scene.game.canvas.height / GLOBAL_SCALE;
|
||||
}
|
||||
|
||||
const moveDescriptionTextMaskRect = this.scene.make.graphics();
|
||||
moveDescriptionTextMaskRect.fillStyle(0xFF0000);
|
||||
moveDescriptionTextMaskRect.fillRect(
|
||||
maskPointOrigin.x + ((options?.onSide && !options?.right ? EFF_WIDTH : 0) + BORDER) * scale, maskPointOrigin.y + ((options?.top ? EFF_HEIGHT : 0) + BORDER - 2) * scale,
|
||||
width - ((options?.onSide ? EFF_WIDTH : 0) - BORDER * 2) * scale, (DESC_HEIGHT - (BORDER - 2) * 2) * scale);
|
||||
moveDescriptionTextMaskRect.setScale(6);
|
||||
const moveDescriptionTextMask = this.createGeometryMask(moveDescriptionTextMaskRect);
|
||||
|
||||
this.add(this.desc);
|
||||
this.desc.setMask(moveDescriptionTextMask);
|
||||
|
||||
if (options?.hideBg) {
|
||||
this.descBg.setVisible(false);
|
||||
}
|
||||
|
||||
// hide this component for now
|
||||
this.setVisible(false);
|
||||
}
|
||||
|
||||
// show this component with infos for the specific move
|
||||
show(text: string):boolean {
|
||||
if (!(this.scene as BattleScene).enableMoveInfo) {
|
||||
return false; // move infos have been disabled // TODO:: is `false` correct? i used to be `undeefined`
|
||||
}
|
||||
|
||||
this.desc.setText(text ?? "");
|
||||
|
||||
// stop previous scrolling effects and reset y position
|
||||
if (this.descScroll) {
|
||||
this.descScroll.remove();
|
||||
this.descScroll = null;
|
||||
this.desc.y = (this.options?.top ? EFF_HEIGHT : 0) + BORDER - 2;
|
||||
}
|
||||
|
||||
// determine if we need to add new scrolling effects
|
||||
const moveDescriptionLineCount = Math.floor(this.desc.displayHeight * (96 / 72) / 14.83);
|
||||
if (moveDescriptionLineCount > 3) {
|
||||
// generate scrolling effects
|
||||
this.descScroll = this.scene.tweens.add({
|
||||
targets: this.desc,
|
||||
delay: Utils.fixedInt(2000),
|
||||
loop: -1,
|
||||
hold: Utils.fixedInt(2000),
|
||||
duration: Utils.fixedInt((moveDescriptionLineCount - 3) * 2000),
|
||||
y: `-=${14.83 * (72 / 96) * (moveDescriptionLineCount - 3)}`
|
||||
});
|
||||
}
|
||||
|
||||
if (!this.options.delayVisibility) {
|
||||
this.setVisible(true);
|
||||
}
|
||||
this.active = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
clear() {
|
||||
this.setVisible(false);
|
||||
this.active = false;
|
||||
}
|
||||
|
||||
toggleInfo(visible: boolean): void {
|
||||
if (visible) {
|
||||
this.setVisible(true);
|
||||
}
|
||||
this.scene.tweens.add({
|
||||
targets: this.desc,
|
||||
duration: Utils.fixedInt(125),
|
||||
ease: "Sine.easeInOut",
|
||||
alpha: visible ? 1 : 0
|
||||
});
|
||||
if (!visible) {
|
||||
this.setVisible(false);
|
||||
}
|
||||
}
|
||||
|
||||
isActive(): boolean {
|
||||
return this.active;
|
||||
}
|
||||
|
||||
// width of this element
|
||||
static getWidth(scale:number, scene: BattleScene):number {
|
||||
return scene.game.canvas.width / GLOBAL_SCALE / 2;
|
||||
}
|
||||
|
||||
// height of this element
|
||||
static getHeight(scale:number, onSide?: boolean):number {
|
||||
return (onSide ? Math.max(EFF_HEIGHT, DESC_HEIGHT) : (EFF_HEIGHT + DESC_HEIGHT)) * scale;
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load Diff
@ -7,7 +7,7 @@ import { speciesEggMoves } from "#app/data/balance/egg-moves";
|
||||
import { pokemonFormLevelMoves, pokemonSpeciesLevelMoves } from "#app/data/balance/pokemon-level-moves";
|
||||
import PokemonSpecies, { allSpecies, getPokemonSpeciesForm, getPokerusStarters, PokemonForm } from "#app/data/pokemon-species";
|
||||
import { getStarterValueFriendshipCap, speciesStarterCosts, POKERUS_STARTER_COUNT } from "#app/data/balance/starters";
|
||||
import { catchableSpecies } from "#app/data/balance/biomes";
|
||||
import { catchableSpecies, uncatchableSpecies } from "#app/data/balance/biomes";
|
||||
import { Type } from "#enums/type";
|
||||
import { AbilityAttr, DexAttr, DexAttrProps, DexEntry, StarterMoveset, StarterAttributes, StarterPreferences, StarterPrefs } from "#app/system/game-data";
|
||||
import { Tutorial, handleTutorial } from "#app/tutorial";
|
||||
@ -547,8 +547,7 @@ export default class PokedexUiHandler extends MessageUiHandler {
|
||||
this.speciesLoaded.set(species.speciesId, false);
|
||||
this.allSpecies.push(species);
|
||||
|
||||
const starter = !speciesStarterCosts.hasOwnProperty(species.speciesId) ? allSpecies.find(sp => sp.speciesId === pokemonStarters[species.speciesId]) : null ;
|
||||
const starterContainer = new StarterContainer(this.scene, species, starter).setVisible(false);
|
||||
const starterContainer = new StarterContainer(this.scene, species).setVisible(false);
|
||||
this.iconAnimHandler.addOrUpdate(starterContainer.icon, PokemonIconAnimMode.NONE);
|
||||
this.starterContainers.push(starterContainer);
|
||||
starterBoxContainer.add(starterContainer);
|
||||
@ -1381,7 +1380,10 @@ export default class PokedexUiHandler extends MessageUiHandler {
|
||||
// TODO: We might also need to do it the other way around.
|
||||
// const biomes = catchableSpecies[container.species.speciesId].concat(catchableSpecies[this.getStarterSpeciesId(container.species.speciesId)]).map(b => Biome[b.biome]);
|
||||
const biomes = catchableSpecies[container.species.speciesId].map(b => Biome[b.biome]);
|
||||
const fitsBiome = this.filterBar.getVals(DropDownColumn.BIOME).some(item => biomes.includes(indexToBiome.get(item)));
|
||||
// Only show uncatchable mons if all biomes are selected.
|
||||
// TODO: Have an entry for uncatchable mons.
|
||||
const showUncatchable = (uncatchableSpecies.includes(container.species.speciesId) && this.filterBar.getVals(DropDownColumn.BIOME).length === 35) ? true : false;
|
||||
const fitsBiome = this.filterBar.getVals(DropDownColumn.BIOME).some(item => biomes.includes(indexToBiome.get(item))) || showUncatchable;
|
||||
|
||||
|
||||
// Caught / Shiny filter
|
||||
|
Loading…
Reference in New Issue
Block a user