mirror of
https://github.com/pagefaultgames/pokerogue.git
synced 2025-09-24 07:23:24 +02:00
Merge 7803834c5b
into 8d5ba221d8
This commit is contained in:
commit
e6650a4203
@ -4,6 +4,7 @@ import { MoveCategory } from "#enums/move-category";
|
|||||||
import { PokemonType } from "#enums/pokemon-type";
|
import { PokemonType } from "#enums/pokemon-type";
|
||||||
import { TextStyle } from "#enums/text-style";
|
import { TextStyle } from "#enums/text-style";
|
||||||
import type { Move } from "#moves/move";
|
import type { Move } from "#moves/move";
|
||||||
|
import { ScrollingText } from "#ui/containers/scrolling-text";
|
||||||
import { addTextObject } from "#ui/text";
|
import { addTextObject } from "#ui/text";
|
||||||
import { addWindow } from "#ui/ui-theme";
|
import { addWindow } from "#ui/ui-theme";
|
||||||
import { fixedInt, getLocalizedSpriteKey } from "#utils/common";
|
import { fixedInt, getLocalizedSpriteKey } from "#utils/common";
|
||||||
@ -35,14 +36,11 @@ export interface MoveInfoOverlaySettings {
|
|||||||
const EFF_HEIGHT = 48;
|
const EFF_HEIGHT = 48;
|
||||||
const EFF_WIDTH = 82;
|
const EFF_WIDTH = 82;
|
||||||
const DESC_HEIGHT = 48;
|
const DESC_HEIGHT = 48;
|
||||||
const BORDER = 8;
|
|
||||||
const GLOBAL_SCALE = 6;
|
|
||||||
|
|
||||||
export class MoveInfoOverlay extends Phaser.GameObjects.Container implements InfoToggle {
|
export class MoveInfoOverlay extends Phaser.GameObjects.Container implements InfoToggle {
|
||||||
public active = false;
|
public active = false;
|
||||||
|
|
||||||
private desc: Phaser.GameObjects.Text;
|
private desc: ScrollingText;
|
||||||
private descScroll: Phaser.Tweens.Tween | null = null;
|
|
||||||
|
|
||||||
private val: Phaser.GameObjects.Container;
|
private val: Phaser.GameObjects.Container;
|
||||||
private pp: Phaser.GameObjects.Text;
|
private pp: Phaser.GameObjects.Text;
|
||||||
@ -50,7 +48,6 @@ export class MoveInfoOverlay extends Phaser.GameObjects.Container implements Inf
|
|||||||
private acc: Phaser.GameObjects.Text;
|
private acc: Phaser.GameObjects.Text;
|
||||||
private typ: Phaser.GameObjects.Sprite;
|
private typ: Phaser.GameObjects.Sprite;
|
||||||
private cat: Phaser.GameObjects.Sprite;
|
private cat: Phaser.GameObjects.Sprite;
|
||||||
private descBg: Phaser.GameObjects.NineSlice;
|
|
||||||
|
|
||||||
private options: MoveInfoOverlaySettings;
|
private options: MoveInfoOverlaySettings;
|
||||||
|
|
||||||
@ -62,55 +59,26 @@ export class MoveInfoOverlay extends Phaser.GameObjects.Container implements Inf
|
|||||||
this.setScale(1);
|
this.setScale(1);
|
||||||
this.options = options || {};
|
this.options = options || {};
|
||||||
|
|
||||||
|
const descBoxX = options?.onSide && !options?.right ? EFF_WIDTH : 0;
|
||||||
|
const descBoxY = options?.top ? EFF_HEIGHT : 0;
|
||||||
|
const width = options?.width || MoveInfoOverlay.getWidth();
|
||||||
|
const descBoxWidth = width - (options?.onSide ? EFF_WIDTH : 0);
|
||||||
|
const descBoxHeight = DESC_HEIGHT;
|
||||||
|
|
||||||
// prepare the description box
|
// prepare the description box
|
||||||
const width = options?.width || MoveInfoOverlay.getWidth(); // we always want this to be half a window wide
|
this.desc = new ScrollingText(
|
||||||
this.descBg = addWindow(
|
globalScene,
|
||||||
options?.onSide && !options?.right ? EFF_WIDTH : 0,
|
descBoxX,
|
||||||
options?.top ? EFF_HEIGHT : 0,
|
descBoxY,
|
||||||
width - (options?.onSide ? EFF_WIDTH : 0),
|
descBoxWidth,
|
||||||
DESC_HEIGHT,
|
descBoxHeight,
|
||||||
);
|
3, // maxLineCount
|
||||||
this.descBg.setOrigin(0, 0);
|
"", // initial content
|
||||||
this.add(this.descBg);
|
|
||||||
|
|
||||||
// set up the description; wordWrap uses true pixels, unaffected by any scaling, while other values are affected
|
|
||||||
this.desc = addTextObject(
|
|
||||||
(options?.onSide && !options?.right ? EFF_WIDTH : 0) + BORDER,
|
|
||||||
(options?.top ? EFF_HEIGHT : 0) + BORDER - 2,
|
|
||||||
"",
|
|
||||||
TextStyle.BATTLE_INFO,
|
TextStyle.BATTLE_INFO,
|
||||||
{
|
!options?.hideBg,
|
||||||
wordWrap: {
|
|
||||||
width: (width - (BORDER - 2) * 2 - (options?.onSide ? EFF_WIDTH : 0)) * GLOBAL_SCALE,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
);
|
);
|
||||||
|
this.desc.createMask(globalScene, this.x + this.desc.x, this.y + this.desc.y);
|
||||||
// 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 += globalScene.scaledCanvas.width;
|
|
||||||
}
|
|
||||||
if (maskPointOrigin.y < 0) {
|
|
||||||
maskPointOrigin.y += globalScene.scaledCanvas.height;
|
|
||||||
}
|
|
||||||
|
|
||||||
const moveDescriptionTextMaskRect = globalScene.make.graphics();
|
|
||||||
moveDescriptionTextMaskRect.fillStyle(0xff0000);
|
|
||||||
moveDescriptionTextMaskRect.fillRect(
|
|
||||||
maskPointOrigin.x + ((options?.onSide && !options?.right ? EFF_WIDTH : 0) + BORDER),
|
|
||||||
maskPointOrigin.y + ((options?.top ? EFF_HEIGHT : 0) + BORDER - 2),
|
|
||||||
width - ((options?.onSide ? EFF_WIDTH : 0) - BORDER * 2),
|
|
||||||
DESC_HEIGHT - (BORDER - 2) * 2,
|
|
||||||
);
|
|
||||||
moveDescriptionTextMaskRect.setScale(6);
|
|
||||||
const moveDescriptionTextMask = this.createGeometryMask(moveDescriptionTextMaskRect);
|
|
||||||
|
|
||||||
this.add(this.desc);
|
this.add(this.desc);
|
||||||
this.desc.setMask(moveDescriptionTextMask);
|
|
||||||
|
|
||||||
// prepare the effect box
|
// prepare the effect box
|
||||||
this.val = new Phaser.GameObjects.Container(
|
this.val = new Phaser.GameObjects.Container(
|
||||||
@ -162,10 +130,6 @@ export class MoveInfoOverlay extends Phaser.GameObjects.Container implements Inf
|
|||||||
this.val.setVisible(false);
|
this.val.setVisible(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (options?.hideBg) {
|
|
||||||
this.descBg.setVisible(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
// hide this component for now
|
// hide this component for now
|
||||||
this.setVisible(false);
|
this.setVisible(false);
|
||||||
}
|
}
|
||||||
@ -181,28 +145,10 @@ export class MoveInfoOverlay extends Phaser.GameObjects.Container implements Inf
|
|||||||
this.typ.setTexture(getLocalizedSpriteKey("types"), PokemonType[move.type].toLowerCase());
|
this.typ.setTexture(getLocalizedSpriteKey("types"), PokemonType[move.type].toLowerCase());
|
||||||
this.cat.setFrame(MoveCategory[move.category].toLowerCase());
|
this.cat.setFrame(MoveCategory[move.category].toLowerCase());
|
||||||
|
|
||||||
this.desc.setText(move?.effect || "");
|
this.desc.text.setText(move?.effect || "");
|
||||||
|
|
||||||
// stop previous scrolling effects and reset y position
|
// stop previous scrolling effects and reset y position
|
||||||
if (this.descScroll) {
|
this.desc.activate();
|
||||||
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 = globalScene.tweens.add({
|
|
||||||
targets: this.desc,
|
|
||||||
delay: fixedInt(2000),
|
|
||||||
loop: -1,
|
|
||||||
hold: fixedInt(2000),
|
|
||||||
duration: fixedInt((moveDescriptionLineCount - 3) * 2000),
|
|
||||||
y: `-=${14.83 * (72 / 96) * (moveDescriptionLineCount - 3)}`,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!this.options.delayVisibility) {
|
if (!this.options.delayVisibility) {
|
||||||
this.setVisible(true);
|
this.setVisible(true);
|
||||||
@ -221,7 +167,7 @@ export class MoveInfoOverlay extends Phaser.GameObjects.Container implements Inf
|
|||||||
this.setVisible(true);
|
this.setVisible(true);
|
||||||
}
|
}
|
||||||
globalScene.tweens.add({
|
globalScene.tweens.add({
|
||||||
targets: this.desc,
|
targets: this.desc.text,
|
||||||
duration: fixedInt(125),
|
duration: fixedInt(125),
|
||||||
ease: "Sine.easeInOut",
|
ease: "Sine.easeInOut",
|
||||||
alpha: visible ? 1 : 0,
|
alpha: visible ? 1 : 0,
|
||||||
|
@ -1,8 +1,7 @@
|
|||||||
import type { InfoToggle } from "#app/battle-scene";
|
import type { InfoToggle } from "#app/battle-scene";
|
||||||
import { globalScene } from "#app/global-scene";
|
import { globalScene } from "#app/global-scene";
|
||||||
import { TextStyle } from "#enums/text-style";
|
import { TextStyle } from "#enums/text-style";
|
||||||
import { addTextObject } from "#ui/text";
|
import { ScrollingText } from "#ui/containers/scrolling-text";
|
||||||
import { addWindow } from "#ui/ui-theme";
|
|
||||||
import { fixedInt } from "#utils/common";
|
import { fixedInt } from "#utils/common";
|
||||||
|
|
||||||
export interface PokedexInfoOverlaySettings {
|
export interface PokedexInfoOverlaySettings {
|
||||||
@ -14,17 +13,14 @@ export interface PokedexInfoOverlaySettings {
|
|||||||
width?: number;
|
width?: number;
|
||||||
/** Determines whether to display the small secondary box */
|
/** Determines whether to display the small secondary box */
|
||||||
hideEffectBox?: boolean;
|
hideEffectBox?: boolean;
|
||||||
hideBg?: boolean;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const DESC_HEIGHT = 48;
|
const DESC_HEIGHT = 48;
|
||||||
const BORDER = 8;
|
|
||||||
const GLOBAL_SCALE = 6;
|
|
||||||
|
|
||||||
export class PokedexInfoOverlay extends Phaser.GameObjects.Container implements InfoToggle {
|
export class PokedexInfoOverlay extends Phaser.GameObjects.Container implements InfoToggle {
|
||||||
public active = false;
|
public active = false;
|
||||||
|
|
||||||
private desc: Phaser.GameObjects.Text;
|
private desc: ScrollingText;
|
||||||
private descScroll: Phaser.Tweens.Tween | null = null;
|
private descScroll: Phaser.Tweens.Tween | null = null;
|
||||||
|
|
||||||
private descBg: Phaser.GameObjects.NineSlice;
|
private descBg: Phaser.GameObjects.NineSlice;
|
||||||
@ -35,52 +31,32 @@ export class PokedexInfoOverlay extends Phaser.GameObjects.Container implements
|
|||||||
|
|
||||||
private maskPointOriginX: number;
|
private maskPointOriginX: number;
|
||||||
private maskPointOriginY: number;
|
private maskPointOriginY: number;
|
||||||
public width: number;
|
|
||||||
|
|
||||||
constructor(options?: PokedexInfoOverlaySettings) {
|
constructor(options?: PokedexInfoOverlaySettings) {
|
||||||
super(globalScene, options?.x, options?.y);
|
super(globalScene, options?.x, options?.y);
|
||||||
this.setScale(1);
|
this.setScale(1);
|
||||||
this.options = options || {};
|
this.options = options || {};
|
||||||
|
|
||||||
|
const descBoxX = 0;
|
||||||
|
const descBoxY = 0;
|
||||||
|
const width = options?.width || PokedexInfoOverlay.getWidth();
|
||||||
|
const descBoxWidth = width;
|
||||||
|
const descBoxHeight = DESC_HEIGHT;
|
||||||
|
|
||||||
// prepare the description box
|
// prepare the description box
|
||||||
this.width = options?.width || PokedexInfoOverlay.getWidth(); // we always want this to be half a window wide
|
this.desc = new ScrollingText(
|
||||||
this.descBg = addWindow(0, 0, this.width, DESC_HEIGHT);
|
globalScene,
|
||||||
this.descBg.setOrigin(0, 0);
|
descBoxX,
|
||||||
this.add(this.descBg);
|
descBoxY,
|
||||||
|
descBoxWidth,
|
||||||
// set up the description; wordWrap uses true pixels, unaffected by any scaling, while other values are affected
|
descBoxHeight,
|
||||||
this.desc = addTextObject(BORDER, BORDER - 2, "", TextStyle.BATTLE_INFO, {
|
3, // maxLineCount
|
||||||
wordWrap: { width: (this.width - (BORDER - 2) * 2) * GLOBAL_SCALE },
|
"", // initial content
|
||||||
});
|
TextStyle.BATTLE_INFO,
|
||||||
|
true,
|
||||||
// limit the text rendering, required for scrolling later on
|
|
||||||
this.maskPointOriginX = options?.x || 0;
|
|
||||||
this.maskPointOriginY = options?.y || 0;
|
|
||||||
|
|
||||||
if (this.maskPointOriginX < 0) {
|
|
||||||
this.maskPointOriginX += globalScene.scaledCanvas.width;
|
|
||||||
}
|
|
||||||
if (this.maskPointOriginY < 0) {
|
|
||||||
this.maskPointOriginY += globalScene.scaledCanvas.height;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.textMaskRect = globalScene.make.graphics();
|
|
||||||
this.textMaskRect.fillStyle(0xff0000);
|
|
||||||
this.textMaskRect.fillRect(
|
|
||||||
this.maskPointOriginX + BORDER,
|
|
||||||
this.maskPointOriginY + (BORDER - 2),
|
|
||||||
this.width - BORDER * 2,
|
|
||||||
DESC_HEIGHT - (BORDER - 2) * 2,
|
|
||||||
);
|
);
|
||||||
this.textMaskRect.setScale(6);
|
this.desc.createMask(globalScene, this.x + this.desc.x, this.y + this.desc.y);
|
||||||
const textMask = this.createGeometryMask(this.textMaskRect);
|
|
||||||
|
|
||||||
this.add(this.desc);
|
this.add(this.desc);
|
||||||
this.desc.setMask(textMask);
|
|
||||||
|
|
||||||
if (options?.hideBg) {
|
|
||||||
this.descBg.setVisible(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
// hide this component for now
|
// hide this component for now
|
||||||
this.setVisible(false);
|
this.setVisible(false);
|
||||||
@ -92,45 +68,10 @@ export class PokedexInfoOverlay extends Phaser.GameObjects.Container implements
|
|||||||
return false; // move infos have been disabled // TODO:: is `false` correct? i used to be `undeefined`
|
return false; // move infos have been disabled // TODO:: is `false` correct? i used to be `undeefined`
|
||||||
}
|
}
|
||||||
|
|
||||||
this.desc.setText(text ?? "");
|
this.desc.text.setText(text ?? "");
|
||||||
|
|
||||||
// stop previous scrolling effects and reset y position
|
// stop previous scrolling effects and reset y position
|
||||||
if (this.descScroll) {
|
this.desc.activate();
|
||||||
this.descScroll.remove();
|
|
||||||
this.descScroll = null;
|
|
||||||
this.desc.y = BORDER - 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
// determine if we need to add new scrolling effects
|
|
||||||
const lineCount = Math.floor((this.desc.displayHeight * (96 / 72)) / 14.83);
|
|
||||||
|
|
||||||
const newHeight = lineCount >= 3 ? 48 : lineCount === 2 ? 36 : 24;
|
|
||||||
this.textMaskRect.clear();
|
|
||||||
this.textMaskRect.fillStyle(0xff0000);
|
|
||||||
this.textMaskRect.fillRect(
|
|
||||||
this.maskPointOriginX + BORDER,
|
|
||||||
this.maskPointOriginY + (BORDER - 2) + (48 - newHeight),
|
|
||||||
this.width - BORDER * 2,
|
|
||||||
newHeight - (BORDER - 2) * 2,
|
|
||||||
);
|
|
||||||
const updatedMask = this.createGeometryMask(this.textMaskRect);
|
|
||||||
this.desc.setMask(updatedMask);
|
|
||||||
|
|
||||||
this.descBg.setSize(this.descBg.width, newHeight);
|
|
||||||
this.descBg.setY(48 - newHeight);
|
|
||||||
this.desc.setY(BORDER - 2 + (48 - newHeight));
|
|
||||||
|
|
||||||
if (lineCount > 3) {
|
|
||||||
// generate scrolling effects
|
|
||||||
this.descScroll = globalScene.tweens.add({
|
|
||||||
targets: this.desc,
|
|
||||||
delay: fixedInt(2000),
|
|
||||||
loop: -1,
|
|
||||||
hold: fixedInt(2000),
|
|
||||||
duration: fixedInt((lineCount - 3) * 2000),
|
|
||||||
y: `-=${14.83 * (72 / 96) * (lineCount - 3)}`,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!this.options.delayVisibility) {
|
if (!this.options.delayVisibility) {
|
||||||
this.setVisible(true);
|
this.setVisible(true);
|
||||||
|
107
src/ui/containers/scrolling-text.ts
Normal file
107
src/ui/containers/scrolling-text.ts
Normal file
@ -0,0 +1,107 @@
|
|||||||
|
import { globalScene } from "#app/global-scene";
|
||||||
|
import { fixedInt } from "#app/utils/common";
|
||||||
|
import type { TextStyle } from "#enums/text-style";
|
||||||
|
import { addBBCodeTextObject } from "#ui/text";
|
||||||
|
import { addWindow } from "#ui/ui-theme";
|
||||||
|
import i18next from "i18next";
|
||||||
|
import type BBCodeText from "phaser3-rex-plugins/plugins/bbcodetext";
|
||||||
|
|
||||||
|
/*
|
||||||
|
This takes various coordinates:
|
||||||
|
- The x and y coordinates relative to the parent container, this is typical behavior for Phaser.GameObjects.Container.
|
||||||
|
- The width and height of the box; these are needed to create the background.
|
||||||
|
The mask is not created right away (although this is possible in principle). Instead, we have a separate function,
|
||||||
|
which takes as input the _global_ coordinates of scrolling text object. This is necessary to correctly position the mask in the scene.
|
||||||
|
*/
|
||||||
|
|
||||||
|
const BORDER = 8;
|
||||||
|
|
||||||
|
export class ScrollingText extends Phaser.GameObjects.Container {
|
||||||
|
private descBg: Phaser.GameObjects.NineSlice;
|
||||||
|
public text: BBCodeText;
|
||||||
|
private descScroll: Phaser.Tweens.Tween | null = null;
|
||||||
|
private maxLineCount: number;
|
||||||
|
|
||||||
|
private offsetX: number;
|
||||||
|
private offsetY: number;
|
||||||
|
maskHeight: number;
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
scene: Phaser.Scene,
|
||||||
|
x: number,
|
||||||
|
y: number,
|
||||||
|
width: number,
|
||||||
|
height: number,
|
||||||
|
maxLineCount: number,
|
||||||
|
content: string,
|
||||||
|
style: TextStyle,
|
||||||
|
hasBackground = false,
|
||||||
|
extraStyleOptions: Phaser.Types.GameObjects.Text.TextStyle = {},
|
||||||
|
) {
|
||||||
|
super(scene, x, y);
|
||||||
|
|
||||||
|
this.offsetX = hasBackground ? BORDER : 0;
|
||||||
|
this.offsetY = hasBackground ? BORDER - 2 : 0;
|
||||||
|
|
||||||
|
// Adding the background
|
||||||
|
this.descBg = addWindow(0, 0, width, height).setOrigin(0, 0).setVisible(hasBackground);
|
||||||
|
this.add(this.descBg);
|
||||||
|
|
||||||
|
// Adding the text element
|
||||||
|
const wrapWidth = (width - (this.offsetX - 2) * 2) * 6;
|
||||||
|
|
||||||
|
this.text = addBBCodeTextObject(this.offsetX, this.offsetY, content, style, {
|
||||||
|
wordWrap: {
|
||||||
|
width: wrapWidth,
|
||||||
|
},
|
||||||
|
...extraStyleOptions,
|
||||||
|
});
|
||||||
|
this.maxLineCount = maxLineCount;
|
||||||
|
// TODO: change this based on which text is being used, etc
|
||||||
|
this.text.setLineSpacing(i18next.resolvedLanguage === "ja" ? 25 : 5);
|
||||||
|
this.add(this.text);
|
||||||
|
}
|
||||||
|
|
||||||
|
createMask(scene: Phaser.Scene, globalX: number, globalY: number) {
|
||||||
|
// Adding the mask for the scrolling effect
|
||||||
|
const globalMaskX = globalX + this.offsetX;
|
||||||
|
const globalMaskY = globalY + this.offsetY;
|
||||||
|
|
||||||
|
const visibleWidth = this.descBg.width - (this.offsetX - 2) * 2;
|
||||||
|
this.maskHeight = (this.text.style.lineHeight / 6) * this.maxLineCount;
|
||||||
|
const visibleHeight = this.maskHeight;
|
||||||
|
|
||||||
|
const maskGraphics = scene.make.graphics({ x: 0, y: 0 });
|
||||||
|
maskGraphics.fillRect(globalMaskX, globalMaskY, visibleWidth, visibleHeight).setScale(6);
|
||||||
|
|
||||||
|
scene.add.existing(maskGraphics);
|
||||||
|
const mask = this.createGeometryMask(maskGraphics);
|
||||||
|
this.text.setMask(mask);
|
||||||
|
}
|
||||||
|
|
||||||
|
activate() {
|
||||||
|
// stop previous scrolling effects and reset y position
|
||||||
|
if (this.descScroll) {
|
||||||
|
this.descScroll.remove();
|
||||||
|
this.descScroll = null;
|
||||||
|
this.text.y = this.offsetY;
|
||||||
|
}
|
||||||
|
|
||||||
|
// determine if we need to add new scrolling effects
|
||||||
|
const displayHeight = this.text.displayHeight;
|
||||||
|
const scrollAmount = displayHeight - this.maskHeight;
|
||||||
|
const lineHeight = this.text.style.lineHeight / 6;
|
||||||
|
|
||||||
|
if (scrollAmount) {
|
||||||
|
// generate scrolling effects
|
||||||
|
this.descScroll = globalScene.tweens.add({
|
||||||
|
targets: this.text,
|
||||||
|
delay: fixedInt(2000),
|
||||||
|
loop: -1,
|
||||||
|
hold: fixedInt(2000),
|
||||||
|
duration: fixedInt((scrollAmount / lineHeight) * 2000),
|
||||||
|
y: `-=${scrollAmount}`,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -10,6 +10,7 @@ import type { OptionSelectSettings } from "#mystery-encounters/encounter-phase-u
|
|||||||
import type { MysteryEncounterOption } from "#mystery-encounters/mystery-encounter-option";
|
import type { MysteryEncounterOption } from "#mystery-encounters/mystery-encounter-option";
|
||||||
import type { MysteryEncounterPhase } from "#phases/mystery-encounter-phases";
|
import type { MysteryEncounterPhase } from "#phases/mystery-encounter-phases";
|
||||||
import { PartyUiMode } from "#ui/party-ui-handler";
|
import { PartyUiMode } from "#ui/party-ui-handler";
|
||||||
|
import { ScrollingText } from "#ui/scrolling-text";
|
||||||
import { addBBCodeTextObject, getBBCodeFrag } from "#ui/text";
|
import { addBBCodeTextObject, getBBCodeFrag } from "#ui/text";
|
||||||
import { UiHandler } from "#ui/ui-handler";
|
import { UiHandler } from "#ui/ui-handler";
|
||||||
import { addWindow, WindowVariant } from "#ui/ui-theme";
|
import { addWindow, WindowVariant } from "#ui/ui-theme";
|
||||||
@ -46,6 +47,8 @@ export class MysteryEncounterUiHandler extends UiHandler {
|
|||||||
protected viewPartyXPosition = 0;
|
protected viewPartyXPosition = 0;
|
||||||
|
|
||||||
protected blockInput = true;
|
protected blockInput = true;
|
||||||
|
desc: ScrollingText;
|
||||||
|
tooltipDesc: ScrollingText;
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
super(UiMode.MYSTERY_ENCOUNTER);
|
super(UiMode.MYSTERY_ENCOUNTER);
|
||||||
@ -499,41 +502,21 @@ export class MysteryEncounterUiHandler extends UiHandler {
|
|||||||
const ballType = getPokeballAtlasKey(index);
|
const ballType = getPokeballAtlasKey(index);
|
||||||
this.rarityBall.setTexture("pb", ballType);
|
this.rarityBall.setTexture("pb", ballType);
|
||||||
|
|
||||||
const descriptionTextObject = addBBCodeTextObject(6, 25, descriptionText ?? "", TextStyle.TOOLTIP_CONTENT, {
|
// prepare the description box
|
||||||
wordWrap: { width: 830 },
|
this.desc = new ScrollingText(
|
||||||
});
|
globalScene,
|
||||||
|
6,
|
||||||
// Sets up the mask that hides the description text to give an illusion of scrolling
|
22,
|
||||||
const descriptionTextMaskRect = globalScene.make.graphics({});
|
830 / 6,
|
||||||
descriptionTextMaskRect.setScale(6);
|
62,
|
||||||
descriptionTextMaskRect.fillStyle(0xffffff);
|
6, // maxLineCount
|
||||||
descriptionTextMaskRect.beginPath();
|
descriptionText ?? "", // initial content
|
||||||
descriptionTextMaskRect.fillRect(6, 53, 206, 57);
|
TextStyle.TOOLTIP_CONTENT,
|
||||||
|
false,
|
||||||
const abilityDescriptionTextMask = descriptionTextMaskRect.createGeometryMask();
|
);
|
||||||
|
this.desc.createMask(globalScene, 6, 50);
|
||||||
descriptionTextObject.setMask(abilityDescriptionTextMask);
|
this.descriptionContainer.add(this.desc);
|
||||||
|
this.desc.activate();
|
||||||
const descriptionLineCount = Math.floor(descriptionTextObject.displayHeight / 9.2);
|
|
||||||
|
|
||||||
if (this.descriptionScrollTween) {
|
|
||||||
this.descriptionScrollTween.remove();
|
|
||||||
this.descriptionScrollTween = undefined;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Animates the description text moving upwards
|
|
||||||
if (descriptionLineCount > 6) {
|
|
||||||
this.descriptionScrollTween = globalScene.tweens.add({
|
|
||||||
targets: descriptionTextObject,
|
|
||||||
delay: fixedInt(2000),
|
|
||||||
loop: -1,
|
|
||||||
hold: fixedInt(2000),
|
|
||||||
duration: fixedInt((descriptionLineCount - 6) * 2000),
|
|
||||||
y: `-=${10 * (descriptionLineCount - 6)}`,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
this.descriptionContainer.add(descriptionTextObject);
|
|
||||||
|
|
||||||
const queryTextObject = addBBCodeTextObject(0, 0, queryText ?? "", TextStyle.TOOLTIP_CONTENT, {
|
const queryTextObject = addBBCodeTextObject(0, 0, queryText ?? "", TextStyle.TOOLTIP_CONTENT, {
|
||||||
wordWrap: { width: 830 },
|
wordWrap: { width: 830 },
|
||||||
@ -608,42 +591,25 @@ export class MysteryEncounterUiHandler extends UiHandler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (text) {
|
if (text) {
|
||||||
const tooltipTextObject = addBBCodeTextObject(6, 7, text, TextStyle.TOOLTIP_CONTENT, {
|
this.tooltipDesc = new ScrollingText(
|
||||||
wordWrap: { width: 600 },
|
globalScene,
|
||||||
fontSize: "72px",
|
6,
|
||||||
padding: { top: 8 },
|
5,
|
||||||
lineSpacing: 1.25,
|
96,
|
||||||
});
|
32,
|
||||||
this.tooltipContainer.add(tooltipTextObject);
|
3, // maxLineCount
|
||||||
|
text ?? "", // initial content
|
||||||
// Sets up the mask that hides the description text to give an illusion of scrolling
|
TextStyle.TOOLTIP_CONTENT,
|
||||||
const tooltipTextMaskRect = globalScene.make.graphics({});
|
false,
|
||||||
tooltipTextMaskRect.setScale(6);
|
{
|
||||||
tooltipTextMaskRect.fillStyle(0xffffff);
|
fontSize: "72px",
|
||||||
tooltipTextMaskRect.beginPath();
|
padding: { top: 8 },
|
||||||
tooltipTextMaskRect.fillRect(this.tooltipContainer.x, this.tooltipContainer.y + 188.5, 150, 32);
|
lineSpacing: 1.25,
|
||||||
|
},
|
||||||
const textMask = tooltipTextMaskRect.createGeometryMask();
|
);
|
||||||
tooltipTextObject.setMask(textMask);
|
this.tooltipDesc.createMask(globalScene, this.tooltipContainer.x, this.tooltipContainer.y + 188.5);
|
||||||
|
this.tooltipContainer.add(this.tooltipDesc);
|
||||||
const tooltipLineCount = Math.floor(tooltipTextObject.displayHeight / 10.2);
|
this.tooltipDesc.activate();
|
||||||
|
|
||||||
if (this.tooltipScrollTween) {
|
|
||||||
this.tooltipScrollTween.remove();
|
|
||||||
this.tooltipScrollTween = undefined;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Animates the tooltip text moving upwards
|
|
||||||
if (tooltipLineCount > 3) {
|
|
||||||
this.tooltipScrollTween = globalScene.tweens.add({
|
|
||||||
targets: tooltipTextObject,
|
|
||||||
delay: fixedInt(1200),
|
|
||||||
loop: -1,
|
|
||||||
hold: fixedInt(1200),
|
|
||||||
duration: fixedInt((tooltipLineCount - 3) * 1200),
|
|
||||||
y: `-=${11.2 * (tooltipLineCount - 3)}`,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Dex progress indicator
|
// Dex progress indicator
|
||||||
|
@ -25,6 +25,7 @@ import type { PokemonMove } from "#moves/pokemon-move";
|
|||||||
import type { Variant } from "#sprites/variant";
|
import type { Variant } from "#sprites/variant";
|
||||||
import { getVariantTint } from "#sprites/variant";
|
import { getVariantTint } from "#sprites/variant";
|
||||||
import { achvs } from "#system/achv";
|
import { achvs } from "#system/achv";
|
||||||
|
import { ScrollingText } from "#ui/scrolling-text";
|
||||||
import { addBBCodeTextObject, addTextObject, getBBCodeFrag, getTextColor } from "#ui/text";
|
import { addBBCodeTextObject, addTextObject, getBBCodeFrag, getTextColor } from "#ui/text";
|
||||||
import { UiHandler } from "#ui/ui-handler";
|
import { UiHandler } from "#ui/ui-handler";
|
||||||
import { fixedInt, formatStat, getLocalizedSpriteKey, getShinyDescriptor, padInt, rgbHexToRgba } from "#utils/common";
|
import { fixedInt, formatStat, getLocalizedSpriteKey, getShinyDescriptor, padInt, rgbHexToRgba } from "#utils/common";
|
||||||
@ -53,7 +54,7 @@ interface abilityContainer {
|
|||||||
/** The text object displaying the name of the ability */
|
/** The text object displaying the name of the ability */
|
||||||
nameText: Phaser.GameObjects.Text | null;
|
nameText: Phaser.GameObjects.Text | null;
|
||||||
/** The text object displaying the description of the ability */
|
/** The text object displaying the description of the ability */
|
||||||
descriptionText: Phaser.GameObjects.Text | null;
|
description: ScrollingText | null;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class SummaryUiHandler extends UiHandler {
|
export class SummaryUiHandler extends UiHandler {
|
||||||
@ -89,7 +90,7 @@ export class SummaryUiHandler extends UiHandler {
|
|||||||
private movesContainer: Phaser.GameObjects.Container;
|
private movesContainer: Phaser.GameObjects.Container;
|
||||||
private movesContainerMovesTitle: Phaser.GameObjects.Image;
|
private movesContainerMovesTitle: Phaser.GameObjects.Image;
|
||||||
private movesContainerDescriptionsTitle: Phaser.GameObjects.Image;
|
private movesContainerDescriptionsTitle: Phaser.GameObjects.Image;
|
||||||
private moveDescriptionText: Phaser.GameObjects.Text;
|
private moveDescription: ScrollingText;
|
||||||
private moveCursorObj: Phaser.GameObjects.Sprite | null;
|
private moveCursorObj: Phaser.GameObjects.Sprite | null;
|
||||||
private selectedMoveCursorObj: Phaser.GameObjects.Sprite | null;
|
private selectedMoveCursorObj: Phaser.GameObjects.Sprite | null;
|
||||||
private moveRowsContainer: Phaser.GameObjects.Container;
|
private moveRowsContainer: Phaser.GameObjects.Container;
|
||||||
@ -589,12 +590,12 @@ export class SummaryUiHandler extends UiHandler {
|
|||||||
} else if (this.cursor === Page.PROFILE && this.pokemon?.hasPassive()) {
|
} else if (this.cursor === Page.PROFILE && this.pokemon?.hasPassive()) {
|
||||||
// if we're on the PROFILE page and this pokemon has a passive unlocked..
|
// if we're on the PROFILE page and this pokemon has a passive unlocked..
|
||||||
// Since abilities are displayed by default, all we need to do is toggle visibility on all elements to show passives
|
// Since abilities are displayed by default, all we need to do is toggle visibility on all elements to show passives
|
||||||
this.abilityContainer.nameText?.setVisible(!this.abilityContainer.descriptionText?.visible);
|
this.abilityContainer.nameText?.setVisible(!this.abilityContainer.description?.visible);
|
||||||
this.abilityContainer.descriptionText?.setVisible(!this.abilityContainer.descriptionText.visible);
|
this.abilityContainer.description?.setVisible(!this.abilityContainer.description.visible);
|
||||||
this.abilityContainer.labelImage.setVisible(!this.abilityContainer.labelImage.visible);
|
this.abilityContainer.labelImage.setVisible(!this.abilityContainer.labelImage.visible);
|
||||||
|
|
||||||
this.passiveContainer.nameText?.setVisible(!this.passiveContainer.descriptionText?.visible);
|
this.passiveContainer.nameText?.setVisible(!this.passiveContainer.description?.visible);
|
||||||
this.passiveContainer.descriptionText?.setVisible(!this.passiveContainer.descriptionText.visible);
|
this.passiveContainer.description?.setVisible(!this.passiveContainer.description.visible);
|
||||||
this.passiveContainer.labelImage.setVisible(!this.passiveContainer.labelImage.visible);
|
this.passiveContainer.labelImage.setVisible(!this.passiveContainer.labelImage.visible);
|
||||||
} else if (this.cursor === Page.STATS) {
|
} else if (this.cursor === Page.STATS) {
|
||||||
//Show IVs
|
//Show IVs
|
||||||
@ -673,7 +674,6 @@ export class SummaryUiHandler extends UiHandler {
|
|||||||
const selectedMove = this.getSelectedMove();
|
const selectedMove = this.getSelectedMove();
|
||||||
|
|
||||||
if (selectedMove) {
|
if (selectedMove) {
|
||||||
this.moveDescriptionText.setY(84);
|
|
||||||
this.movePowerText.setText(selectedMove.power >= 0 ? selectedMove.power.toString() : "---");
|
this.movePowerText.setText(selectedMove.power >= 0 ? selectedMove.power.toString() : "---");
|
||||||
this.moveAccuracyText.setText(selectedMove.accuracy >= 0 ? selectedMove.accuracy.toString() : "---");
|
this.moveAccuracyText.setText(selectedMove.accuracy >= 0 ? selectedMove.accuracy.toString() : "---");
|
||||||
this.moveCategoryIcon.setFrame(MoveCategory[selectedMove.category].toLowerCase());
|
this.moveCategoryIcon.setFrame(MoveCategory[selectedMove.category].toLowerCase());
|
||||||
@ -682,24 +682,9 @@ export class SummaryUiHandler extends UiHandler {
|
|||||||
this.hideMoveEffect();
|
this.hideMoveEffect();
|
||||||
}
|
}
|
||||||
|
|
||||||
this.moveDescriptionText.setText(selectedMove?.effect || "");
|
this.moveDescription.text.setText(selectedMove?.effect || "");
|
||||||
const moveDescriptionLineCount = Math.floor(this.moveDescriptionText.displayHeight / 14.83);
|
|
||||||
|
|
||||||
if (this.descriptionScrollTween) {
|
this.moveDescription.activate();
|
||||||
this.descriptionScrollTween.remove();
|
|
||||||
this.descriptionScrollTween = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (moveDescriptionLineCount > 3) {
|
|
||||||
this.descriptionScrollTween = globalScene.tweens.add({
|
|
||||||
targets: this.moveDescriptionText,
|
|
||||||
delay: fixedInt(2000),
|
|
||||||
loop: -1,
|
|
||||||
hold: fixedInt(2000),
|
|
||||||
duration: fixedInt((moveDescriptionLineCount - 3) * 2000),
|
|
||||||
y: `-=${14.83 * (moveDescriptionLineCount - 3)}`,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!this.moveCursorObj) {
|
if (!this.moveCursorObj) {
|
||||||
this.moveCursorObj = globalScene.add.sprite(-2, 0, "summary_moves_cursor", "highlight");
|
this.moveCursorObj = globalScene.add.sprite(-2, 0, "summary_moves_cursor", "highlight");
|
||||||
@ -898,7 +883,7 @@ export class SummaryUiHandler extends UiHandler {
|
|||||||
labelImage: globalScene.add.image(0, 0, getLocalizedSpriteKey("summary_profile_ability")), // Pixel text 'ABILITY'
|
labelImage: globalScene.add.image(0, 0, getLocalizedSpriteKey("summary_profile_ability")), // Pixel text 'ABILITY'
|
||||||
ability: this.pokemon?.getAbility(true)!, // TODO: is this bang correct?
|
ability: this.pokemon?.getAbility(true)!, // TODO: is this bang correct?
|
||||||
nameText: null,
|
nameText: null,
|
||||||
descriptionText: null,
|
description: null,
|
||||||
};
|
};
|
||||||
|
|
||||||
const allAbilityInfo = [this.abilityContainer]; // Creates an array to iterate through
|
const allAbilityInfo = [this.abilityContainer]; // Creates an array to iterate through
|
||||||
@ -908,7 +893,7 @@ export class SummaryUiHandler extends UiHandler {
|
|||||||
labelImage: globalScene.add.image(0, 0, getLocalizedSpriteKey("summary_profile_passive")), // Pixel text 'PASSIVE'
|
labelImage: globalScene.add.image(0, 0, getLocalizedSpriteKey("summary_profile_passive")), // Pixel text 'PASSIVE'
|
||||||
ability: this.pokemon.getPassiveAbility(),
|
ability: this.pokemon.getPassiveAbility(),
|
||||||
nameText: null,
|
nameText: null,
|
||||||
descriptionText: null,
|
description: null,
|
||||||
};
|
};
|
||||||
allAbilityInfo.push(this.passiveContainer);
|
allAbilityInfo.push(this.passiveContainer);
|
||||||
|
|
||||||
@ -934,42 +919,26 @@ export class SummaryUiHandler extends UiHandler {
|
|||||||
abilityInfo.nameText.setOrigin(0, 1);
|
abilityInfo.nameText.setOrigin(0, 1);
|
||||||
profileContainer.add(abilityInfo.nameText);
|
profileContainer.add(abilityInfo.nameText);
|
||||||
|
|
||||||
abilityInfo.descriptionText = addTextObject(7, 71, abilityInfo.ability?.description!, TextStyle.WINDOW_ALT, {
|
abilityInfo.description = new ScrollingText(
|
||||||
wordWrap: { width: 1224 },
|
globalScene,
|
||||||
}); // TODO: is this bang correct?
|
7,
|
||||||
abilityInfo.descriptionText.setOrigin(0, 0);
|
71,
|
||||||
profileContainer.add(abilityInfo.descriptionText);
|
206,
|
||||||
|
31,
|
||||||
|
2, // maxLineCount
|
||||||
|
abilityInfo.ability?.description!, // initial content
|
||||||
|
TextStyle.WINDOW_ALT,
|
||||||
|
);
|
||||||
|
abilityInfo.description.createMask(globalScene, 110, 90.5);
|
||||||
|
profileContainer.add(abilityInfo.description);
|
||||||
|
|
||||||
// Sets up the mask that hides the description text to give an illusion of scrolling
|
abilityInfo.description.activate();
|
||||||
const descriptionTextMaskRect = globalScene.make.graphics({});
|
|
||||||
descriptionTextMaskRect.setScale(6);
|
|
||||||
descriptionTextMaskRect.fillStyle(0xffffff);
|
|
||||||
descriptionTextMaskRect.beginPath();
|
|
||||||
descriptionTextMaskRect.fillRect(110, 90.5, 206, 31);
|
|
||||||
|
|
||||||
const abilityDescriptionTextMask = descriptionTextMaskRect.createGeometryMask();
|
|
||||||
|
|
||||||
abilityInfo.descriptionText.setMask(abilityDescriptionTextMask);
|
|
||||||
|
|
||||||
const abilityDescriptionLineCount = Math.floor(abilityInfo.descriptionText.displayHeight / 14.83);
|
|
||||||
|
|
||||||
// Animates the description text moving upwards
|
|
||||||
if (abilityDescriptionLineCount > 2) {
|
|
||||||
abilityInfo.descriptionText.setY(69);
|
|
||||||
this.descriptionScrollTween = globalScene.tweens.add({
|
|
||||||
targets: abilityInfo.descriptionText,
|
|
||||||
delay: fixedInt(2000),
|
|
||||||
loop: -1,
|
|
||||||
hold: fixedInt(2000),
|
|
||||||
duration: fixedInt((abilityDescriptionLineCount - 2) * 2000),
|
|
||||||
y: `-=${14.83 * (abilityDescriptionLineCount - 2)}`,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
// Turn off visibility of passive info by default
|
// Turn off visibility of passive info by default
|
||||||
this.passiveContainer?.labelImage.setVisible(false);
|
this.passiveContainer?.labelImage.setVisible(false);
|
||||||
this.passiveContainer?.nameText?.setVisible(false);
|
this.passiveContainer?.nameText?.setVisible(false);
|
||||||
this.passiveContainer?.descriptionText?.setVisible(false);
|
this.passiveContainer?.description?.setVisible(false);
|
||||||
|
|
||||||
const closeFragment = getBBCodeFrag("", TextStyle.WINDOW_ALT);
|
const closeFragment = getBBCodeFrag("", TextStyle.WINDOW_ALT);
|
||||||
const rawNature = toCamelCase(Nature[this.pokemon?.getNature()!]); // TODO: is this bang correct?
|
const rawNature = toCamelCase(Nature[this.pokemon?.getNature()!]); // TODO: is this bang correct?
|
||||||
@ -1240,18 +1209,18 @@ export class SummaryUiHandler extends UiHandler {
|
|||||||
moveRowContainer.add(ppText);
|
moveRowContainer.add(ppText);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.moveDescriptionText = addTextObject(2, 84, "", TextStyle.WINDOW_ALT, { wordWrap: { width: 1212 } });
|
this.moveDescription = new ScrollingText(
|
||||||
this.movesContainer.add(this.moveDescriptionText);
|
globalScene,
|
||||||
|
2,
|
||||||
const moveDescriptionTextMaskRect = globalScene.make.graphics({});
|
84,
|
||||||
moveDescriptionTextMaskRect.setScale(6);
|
202,
|
||||||
moveDescriptionTextMaskRect.fillStyle(0xffffff);
|
46,
|
||||||
moveDescriptionTextMaskRect.beginPath();
|
3, // maxLineCount
|
||||||
moveDescriptionTextMaskRect.fillRect(112, 130, 202, 46);
|
"", // initial content
|
||||||
|
TextStyle.WINDOW_ALT,
|
||||||
const moveDescriptionTextMask = moveDescriptionTextMaskRect.createGeometryMask();
|
);
|
||||||
|
this.moveDescription.createMask(globalScene, 112, 130);
|
||||||
this.moveDescriptionText.setMask(moveDescriptionTextMask);
|
this.movesContainer.add(this.moveDescription);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1313,7 +1282,7 @@ export class SummaryUiHandler extends UiHandler {
|
|||||||
|
|
||||||
this.moveSelect = false;
|
this.moveSelect = false;
|
||||||
this.extraMoveRowContainer.setVisible(false);
|
this.extraMoveRowContainer.setVisible(false);
|
||||||
this.moveDescriptionText.setText("");
|
this.moveDescription.text.setText("");
|
||||||
|
|
||||||
this.destroyBlinkCursor();
|
this.destroyBlinkCursor();
|
||||||
this.hideMoveEffect();
|
this.hideMoveEffect();
|
||||||
|
Loading…
Reference in New Issue
Block a user