This commit is contained in:
Wlowscha 2025-08-05 08:52:47 +00:00 committed by GitHub
commit 598c6c134c
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 312 additions and 127 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 837 B

After

Width:  |  Height:  |  Size: 799 B

View File

@ -0,0 +1,146 @@
{
"textures": [
{
"image": "party_slot_main_short.png",
"format": "RGBA8888",
"size": {
"w": 110,
"h": 294
},
"scale": 1,
"frames": [
{
"filename": "party_slot_main_short",
"rotated": false,
"trimmed": false,
"sourceSize": {
"w": 110,
"h": 41
},
"spriteSourceSize": {
"x": 0,
"y": 0,
"w": 110,
"h": 41
},
"frame": {
"x": 0,
"y": 0,
"w": 110,
"h": 41
}
},
{
"filename": "party_slot_main_short_sel",
"rotated": false,
"trimmed": false,
"sourceSize": {
"w": 110,
"h": 41
},
"spriteSourceSize": {
"x": 0,
"y": 0,
"w": 110,
"h": 41
},
"frame": {
"x": 0,
"y": 41,
"w": 110,
"h": 41
}
},
{
"filename": "party_slot_main_short_fnt",
"rotated": false,
"trimmed": false,
"sourceSize": {
"w": 110,
"h": 41
},
"spriteSourceSize": {
"x": 0,
"y": 0,
"w": 110,
"h": 41
},
"frame": {
"x": 0,
"y": 82,
"w": 110,
"h": 41
}
},
{
"filename": "party_slot_main_short_fnt_sel",
"rotated": false,
"trimmed": false,
"sourceSize": {
"w": 110,
"h": 41
},
"spriteSourceSize": {
"x": 0,
"y": 0,
"w": 110,
"h": 41
},
"frame": {
"x": 0,
"y": 123,
"w": 110,
"h": 41
}
},
{
"filename": "party_slot_main_short_swap",
"rotated": false,
"trimmed": false,
"sourceSize": {
"w": 110,
"h": 41
},
"spriteSourceSize": {
"x": 0,
"y": 0,
"w": 110,
"h": 41
},
"frame": {
"x": 0,
"y": 164,
"w": 110,
"h": 41
}
},
{
"filename": "party_slot_main_short_swap_sel",
"rotated": false,
"trimmed": false,
"sourceSize": {
"w": 110,
"h": 41
},
"spriteSourceSize": {
"x": 0,
"y": 0,
"w": 110,
"h": 41
},
"frame": {
"x": 0,
"y": 205,
"w": 110,
"h": 41
}
}
]
}
],
"meta": {
"app": "https://www.codeandweb.com/texturepacker",
"version": "3.0",
"smartupdate": "$TexturePacker:SmartUpdate:29685f2f538901cf5bf7f0ed2ea867c3:a080ea6c8cccd1e03244214053e79796:565f7afc5ca419b6ba8dbce51ea30818$"
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

View File

@ -121,6 +121,7 @@ export class LoadingScene extends SceneBase {
this.loadImage("party_bg_double", "ui");
this.loadImage("party_bg_double_manage", "ui");
this.loadAtlas("party_slot_main", "ui");
this.loadAtlas("party_slot_main_short", "ui");
this.loadAtlas("party_slot", "ui");
this.loadImage("party_slot_overlay_lv", "ui");
this.loadImage("party_slot_hp_bar", "ui");

View File

@ -31,6 +31,11 @@ import { toTitleCase } from "#utils/strings";
import i18next from "i18next";
import type BBCodeText from "phaser3-rex-plugins/plugins/bbcodetext";
const DISCARD_BUTTON_X = 60;
const DISCARD_BUTTON_X_DOUBLES = 64;
const DISCARD_BUTTON_Y = -73;
const DISCARD_BUTTON_Y_DOUBLES = -58;
const defaultMessage = i18next.t("partyUiHandler:choosePokemon");
/**
@ -301,7 +306,7 @@ export class PartyUiHandler extends MessageUiHandler {
const partyMessageText = addTextObject(10, 8, defaultMessage, TextStyle.WINDOW, { maxLines: 2 });
partyMessageText.setName("text-party-msg");
partyMessageText.setOrigin(0, 0);
partyMessageText.setOrigin(0);
partyMessageBoxContainer.add(partyMessageText);
this.message = partyMessageText;
@ -317,10 +322,8 @@ export class PartyUiHandler extends MessageUiHandler {
this.iconAnimHandler = new PokemonIconAnimHandler();
this.iconAnimHandler.setup();
const partyDiscardModeButton = new PartyDiscardModeButton(60, -globalScene.game.canvas.height / 15 - 1, this);
const partyDiscardModeButton = new PartyDiscardModeButton(DISCARD_BUTTON_X, DISCARD_BUTTON_Y, this);
partyContainer.add(partyDiscardModeButton);
this.partyDiscardModeButton = partyDiscardModeButton;
// prepare move overlay. in case it appears to be too big, set the overlayScale to .5
@ -1235,7 +1238,7 @@ export class PartyUiHandler extends MessageUiHandler {
}
if (!this.optionsCursorObj) {
this.optionsCursorObj = globalScene.add.image(0, 0, "cursor");
this.optionsCursorObj.setOrigin(0, 0);
this.optionsCursorObj.setOrigin(0);
this.optionsContainer.add(this.optionsCursorObj);
}
this.optionsCursorObj.setPosition(
@ -1607,7 +1610,7 @@ export class PartyUiHandler extends MessageUiHandler {
optionText.setColor("#40c8f8");
optionText.setShadowColor("#006090");
}
optionText.setOrigin(0, 0);
optionText.setOrigin(0);
/** For every item that has stack bigger than 1, display the current quantity selection */
const itemModifiers = this.getItemModifiers(pokemon);
@ -1804,6 +1807,7 @@ class PartySlot extends Phaser.GameObjects.Container {
private selected: boolean;
private transfer: boolean;
private slotIndex: number;
private isBenched: boolean;
private pokemon: PlayerPokemon;
private slotBg: Phaser.GameObjects.Image;
@ -1814,6 +1818,7 @@ class PartySlot extends Phaser.GameObjects.Container {
public slotHpText: Phaser.GameObjects.Text;
public slotDescriptionLabel: Phaser.GameObjects.Text; // this is used to show text instead of the HP bar i.e. for showing "Able"/"Not Able" for TMs when you try to learn them
private slotBgKey: string;
private pokemonIcon: Phaser.GameObjects.Container;
private iconAnimHandler: PokemonIconAnimHandler;
@ -1824,19 +1829,33 @@ class PartySlot extends Phaser.GameObjects.Container {
partyUiMode: PartyUiMode,
tmMoveId: MoveId,
) {
super(
globalScene,
slotIndex >= globalScene.currentBattle.getBattlerCount() ? 230.5 : 64,
slotIndex >= globalScene.currentBattle.getBattlerCount()
? -184 +
(globalScene.currentBattle.double ? -40 : 0) +
(28 + (globalScene.currentBattle.double ? 8 : 0)) * slotIndex
: partyUiMode === PartyUiMode.MODIFIER_TRANSFER
? -124 + (globalScene.currentBattle.double ? -20 : 0) + slotIndex * 55
: -124 + (globalScene.currentBattle.double ? -8 : 0) + slotIndex * 64,
);
const isBenched = slotIndex >= globalScene.currentBattle.getBattlerCount();
const isDoubleBattle = globalScene.currentBattle.double;
const isItemManageMode = partyUiMode === PartyUiMode.MODIFIER_TRANSFER || partyUiMode === PartyUiMode.DISCARD;
/*
* Here we determine the position of the slot.
* The x coordinate depends on whether the pokemon is on the field or in the bench.
* The y coordinate depends on various factors, such as
*/
const slotPositionX = isBenched ? 143 : 9;
let slotPositionY: number;
if (isBenched) {
slotPositionY = -196 + (isDoubleBattle ? -40 : 0);
slotPositionY += (28 + (isDoubleBattle ? 8 : 0)) * slotIndex;
} else {
slotPositionY = -148.5;
if (isDoubleBattle) {
slotPositionY += isItemManageMode ? -20 : -8;
}
slotPositionY += (isItemManageMode ? (isDoubleBattle ? 47 : 55) : 64) * slotIndex;
}
super(globalScene, slotPositionX, slotPositionY);
this.slotIndex = slotIndex;
this.isBenched = isBenched;
this.pokemon = pokemon;
this.iconAnimHandler = iconAnimHandler;
@ -1850,27 +1869,62 @@ class PartySlot extends Phaser.GameObjects.Container {
setup(partyUiMode: PartyUiMode, tmMoveId: MoveId) {
const currentLanguage = i18next.resolvedLanguage ?? "en";
const offsetJa = currentLanguage === "ja";
const isItemManageMode = partyUiMode === PartyUiMode.MODIFIER_TRANSFER || partyUiMode === PartyUiMode.DISCARD;
const battlerCount = globalScene.currentBattle.getBattlerCount();
const slotKey = this.isBenched
? "party_slot"
: isItemManageMode && globalScene.currentBattle.double
? "party_slot_main_short"
: "party_slot_main";
this.slotBgKey = this.pokemon.hp ? slotKey : `${slotKey}${"_fnt"}`;
this.slotBg = globalScene.add.sprite(0, 0, slotKey, this.slotBgKey);
this.slotBg.setOrigin(0);
this.add(this.slotBg);
const slotKey = `party_slot${this.slotIndex >= battlerCount ? "" : "_main"}`;
const genderSymbol = getGenderSymbol(this.pokemon.getGender(true));
const isFusion = this.pokemon.fusionSpecies;
const slotBg = globalScene.add.sprite(0, 0, slotKey, `${slotKey}${this.pokemon.hp ? "" : "_fnt"}`);
this.slotBg = slotBg;
// Here we define positions and offsets
const magicNumbers = {
slotPb: { x: 4, y: 4 },
namePosition: { x: 24, y: 10 + (offsetJa ? 2 : 0) },
nameTextWidth: 76 - (isFusion ? 8 : 0),
levelLabelPosition: { x: 24 + 8, y: 10 + 12 },
levelTextToLevelLabelOffset: { x: 9, y: offsetJa ? 1.5 : 0 },
genderTextToLevelLabelOffset: { x: 68 - (isFusion ? 8 : 0), y: -9 },
splicedIconToLevelLabelOffset: { x: 68, y: 3.5 - 12 },
statusIconToLevelLabelOffset: { x: 55, y: 0 },
shinyIconToNameOffset: { x: -9, y: 3 },
hpBarPosition: { x: 8, y: 31 },
hpOverlayToBarOffset: { x: 16, y: 2 }, // This should stay fixed
hpTextToBarOffset: { x: -3, y: -2 + (offsetJa ? 2 : 0) }, // This should stay fixed; relative to HP bar length
descriptionLabelPosition: { x: 32, y: 46 },
};
this.add(slotBg);
if (isItemManageMode && globalScene.currentBattle.double && !this.isBenched) {
magicNumbers.namePosition.y -= 8;
magicNumbers.levelLabelPosition.y -= 8;
magicNumbers.hpBarPosition.y -= 8;
magicNumbers.descriptionLabelPosition.y -= 8;
}
const slotPb = globalScene.add.sprite(
this.slotIndex >= battlerCount ? -85.5 : -51,
this.slotIndex >= battlerCount ? 0 : -20.5,
"party_pb",
);
this.slotPb = slotPb;
if (this.isBenched) {
magicNumbers.slotPb = { x: 2, y: 12 };
magicNumbers.namePosition = { x: 21, y: 2 + (offsetJa ? 2 : 0) };
magicNumbers.nameTextWidth = 52;
magicNumbers.levelLabelPosition = { x: 21 + 8, y: 2 + 12 };
magicNumbers.genderTextToLevelLabelOffset = { x: 36, y: 0 };
magicNumbers.splicedIconToLevelLabelOffset = { x: 36 + (genderSymbol ? 8 : 0), y: 0.5 };
magicNumbers.statusIconToLevelLabelOffset = { x: 43, y: 0 };
magicNumbers.hpBarPosition = { x: 72, y: 6 };
magicNumbers.descriptionLabelPosition = { x: 94, y: 16 };
}
this.add(slotPb);
this.pokemonIcon = globalScene.addPokemonIcon(this.pokemon, slotPb.x, slotPb.y, 0.5, 0.5, true);
this.slotPb = globalScene.add.sprite(0, 0, "party_pb");
this.slotPb.setPosition(magicNumbers.slotPb.x, magicNumbers.slotPb.y);
this.add(this.slotPb);
this.pokemonIcon = globalScene.addPokemonIcon(this.pokemon, this.slotPb.x, this.slotPb.y, 0.5, 0.5, true);
this.add(this.pokemonIcon);
this.iconAnimHandler.addOrUpdate(this.pokemonIcon, PokemonIconAnimMode.PASSIVE);
@ -1884,7 +1938,7 @@ class PartySlot extends Phaser.GameObjects.Container {
const nameSizeTest = addTextObject(0, 0, displayName, TextStyle.PARTY);
nameTextWidth = nameSizeTest.displayWidth;
while (nameTextWidth > (this.slotIndex >= battlerCount ? 52 : 76 - (this.pokemon.fusionSpecies ? 8 : 0))) {
while (nameTextWidth > magicNumbers.nameTextWidth) {
displayName = `${displayName.slice(0, displayName.endsWith(".") ? -2 : -1).trimEnd()}.`;
nameSizeTest.setText(displayName);
nameTextWidth = nameSizeTest.displayWidth;
@ -1893,78 +1947,75 @@ class PartySlot extends Phaser.GameObjects.Container {
nameSizeTest.destroy();
this.slotName = addTextObject(0, 0, displayName, TextStyle.PARTY);
this.slotName.setPositionRelative(
slotBg,
this.slotIndex >= battlerCount ? 21 : 24,
(this.slotIndex >= battlerCount ? 2 : 10) + (offsetJa ? 2 : 0),
);
this.slotName.setOrigin(0, 0);
this.slotName.setPositionRelative(this.slotBg, magicNumbers.namePosition.x, magicNumbers.namePosition.y);
this.slotName.setOrigin(0);
const slotLevelLabel = globalScene.add.image(0, 0, "party_slot_overlay_lv");
slotLevelLabel.setPositionRelative(
slotBg,
(this.slotIndex >= battlerCount ? 21 : 24) + 8,
(this.slotIndex >= battlerCount ? 2 : 10) + 12,
);
slotLevelLabel.setOrigin(0, 0);
const slotLevelLabel = globalScene.add
.image(0, 0, "party_slot_overlay_lv")
.setPositionRelative(this.slotBg, magicNumbers.levelLabelPosition.x, magicNumbers.levelLabelPosition.y)
.setOrigin(0);
const slotLevelText = addTextObject(
0,
0,
this.pokemon.level.toString(),
this.pokemon.level < globalScene.getMaxExpLevel() ? TextStyle.PARTY : TextStyle.PARTY_RED,
);
slotLevelText.setPositionRelative(slotLevelLabel, 9, offsetJa ? 1.5 : 0);
slotLevelText.setOrigin(0, 0.25);
)
.setPositionRelative(
slotLevelLabel,
magicNumbers.levelTextToLevelLabelOffset.x,
magicNumbers.levelTextToLevelLabelOffset.y,
)
.setOrigin(0, 0.25);
slotInfoContainer.add([this.slotName, slotLevelLabel, slotLevelText]);
const genderSymbol = getGenderSymbol(this.pokemon.getGender(true));
if (genderSymbol) {
const slotGenderText = addTextObject(0, 0, genderSymbol, TextStyle.PARTY);
slotGenderText.setColor(getGenderColor(this.pokemon.getGender(true)));
slotGenderText.setShadowColor(getGenderColor(this.pokemon.getGender(true), true));
if (this.slotIndex >= battlerCount) {
slotGenderText.setPositionRelative(slotLevelLabel, 36, 0);
} else {
slotGenderText.setPositionRelative(this.slotName, 76 - (this.pokemon.fusionSpecies ? 8 : 0), 3);
}
slotGenderText.setOrigin(0, 0.25);
const slotGenderText = addTextObject(0, 0, genderSymbol, TextStyle.PARTY)
.setColor(getGenderColor(this.pokemon.getGender(true)))
.setShadowColor(getGenderColor(this.pokemon.getGender(true), true))
.setPositionRelative(
slotLevelLabel,
magicNumbers.genderTextToLevelLabelOffset.x,
magicNumbers.genderTextToLevelLabelOffset.y,
)
.setOrigin(0, 0.25);
slotInfoContainer.add(slotGenderText);
}
if (this.pokemon.fusionSpecies) {
const splicedIcon = globalScene.add.image(0, 0, "icon_spliced");
splicedIcon.setScale(0.5);
splicedIcon.setOrigin(0, 0);
if (this.slotIndex >= battlerCount) {
splicedIcon.setPositionRelative(slotLevelLabel, 36 + (genderSymbol ? 8 : 0), 0.5);
} else {
splicedIcon.setPositionRelative(this.slotName, 76, 3.5);
}
if (isFusion) {
const splicedIcon = globalScene.add
.image(0, 0, "icon_spliced")
.setScale(0.5)
.setOrigin(0)
.setPositionRelative(
slotLevelLabel,
magicNumbers.splicedIconToLevelLabelOffset.x,
magicNumbers.splicedIconToLevelLabelOffset.y,
);
slotInfoContainer.add(splicedIcon);
}
if (this.pokemon.status) {
const statusIndicator = globalScene.add.sprite(0, 0, getLocalizedSpriteKey("statuses"));
statusIndicator.setFrame(StatusEffect[this.pokemon.status?.effect].toLowerCase());
statusIndicator.setOrigin(0, 0);
statusIndicator.setPositionRelative(slotLevelLabel, this.slotIndex >= battlerCount ? 43 : 55, 0);
const statusIndicator = globalScene.add
.sprite(0, 0, getLocalizedSpriteKey("statuses"))
.setFrame(StatusEffect[this.pokemon.status?.effect].toLowerCase())
.setOrigin(0)
.setPositionRelative(
slotLevelLabel,
magicNumbers.statusIconToLevelLabelOffset.x,
magicNumbers.statusIconToLevelLabelOffset.y,
);
slotInfoContainer.add(statusIndicator);
}
if (this.pokemon.isShiny()) {
const doubleShiny = this.pokemon.isDoubleShiny(false);
const shinyStar = globalScene.add.image(0, 0, `shiny_star_small${doubleShiny ? "_1" : ""}`);
shinyStar.setOrigin(0, 0);
shinyStar.setPositionRelative(this.slotName, -9, 3);
shinyStar.setTint(getVariantTint(this.pokemon.getBaseVariant()));
const shinyStar = globalScene.add
.image(0, 0, `shiny_star_small${doubleShiny ? "_1" : ""}`)
.setOrigin(0)
.setPositionRelative(this.slotName, magicNumbers.shinyIconToNameOffset.x, magicNumbers.shinyIconToNameOffset.y)
.setTint(getVariantTint(this.pokemon.getBaseVariant()));
slotInfoContainer.add(shinyStar);
if (doubleShiny) {
@ -1973,50 +2024,42 @@ class PartySlot extends Phaser.GameObjects.Container {
.setOrigin(0)
.setPosition(shinyStar.x, shinyStar.y)
.setTint(getVariantTint(this.pokemon.fusionVariant));
slotInfoContainer.add(fusionShinyStar);
}
}
this.slotHpBar = globalScene.add.image(0, 0, "party_slot_hp_bar");
this.slotHpBar.setPositionRelative(
slotBg,
this.slotIndex >= battlerCount ? 72 : 8,
this.slotIndex >= battlerCount ? 6 : 31,
);
this.slotHpBar.setOrigin(0, 0);
this.slotHpBar.setVisible(false);
this.slotHpBar = globalScene.add
.image(0, 0, "party_slot_hp_bar")
.setOrigin(0)
.setVisible(false)
.setPositionRelative(this.slotBg, magicNumbers.hpBarPosition.x, magicNumbers.hpBarPosition.y);
const hpRatio = this.pokemon.getHpRatio();
this.slotHpOverlay = globalScene.add.sprite(
0,
0,
"party_slot_hp_overlay",
hpRatio > 0.5 ? "high" : hpRatio > 0.25 ? "medium" : "low",
);
this.slotHpOverlay.setPositionRelative(this.slotHpBar, 16, 2);
this.slotHpOverlay.setOrigin(0, 0);
this.slotHpOverlay.setScale(hpRatio, 1);
this.slotHpOverlay.setVisible(false);
this.slotHpOverlay = globalScene.add
.sprite(0, 0, "party_slot_hp_overlay", hpRatio > 0.5 ? "high" : hpRatio > 0.25 ? "medium" : "low")
.setOrigin(0)
.setPositionRelative(this.slotHpBar, magicNumbers.hpOverlayToBarOffset.x, magicNumbers.hpOverlayToBarOffset.y)
.setScale(hpRatio, 1)
.setVisible(false);
this.slotHpText = addTextObject(0, 0, `${this.pokemon.hp}/${this.pokemon.getMaxHp()}`, TextStyle.PARTY);
this.slotHpText.setPositionRelative(
this.slotHpBar,
this.slotHpBar.width - 3,
this.slotHpBar.height - 2 + (offsetJa ? 2 : 0),
);
this.slotHpText.setOrigin(1, 0);
this.slotHpText.setVisible(false);
this.slotHpText = addTextObject(0, 0, `${this.pokemon.hp}/${this.pokemon.getMaxHp()}`, TextStyle.PARTY)
.setOrigin(1, 0)
.setPositionRelative(
this.slotHpBar,
this.slotHpBar.width + magicNumbers.hpTextToBarOffset.x,
this.slotHpBar.height + magicNumbers.hpTextToBarOffset.y,
) // TODO: annoying because it contains the width
.setVisible(false);
this.slotDescriptionLabel = addTextObject(0, 0, "", TextStyle.MESSAGE);
this.slotDescriptionLabel.setPositionRelative(
slotBg,
this.slotIndex >= battlerCount ? 94 : 32,
this.slotIndex >= battlerCount ? 16 : 46,
);
this.slotDescriptionLabel.setOrigin(0, 1);
this.slotDescriptionLabel.setVisible(false);
this.slotDescriptionLabel = addTextObject(0, 0, "", TextStyle.MESSAGE)
.setOrigin(0, 1)
.setVisible(false)
.setPositionRelative(
this.slotBg,
magicNumbers.descriptionLabelPosition.x,
magicNumbers.descriptionLabelPosition.y,
);
slotInfoContainer.add([this.slotHpBar, this.slotHpOverlay, this.slotHpText, this.slotDescriptionLabel]);
@ -2078,10 +2121,9 @@ class PartySlot extends Phaser.GameObjects.Container {
}
private updateSlotTexture(): void {
const battlerCount = globalScene.currentBattle.getBattlerCount();
this.slotBg.setTexture(
`party_slot${this.slotIndex >= battlerCount ? "" : "_main"}`,
`party_slot${this.slotIndex >= battlerCount ? "" : "_main"}${this.transfer ? "_swap" : this.pokemon.hp ? "" : "_fnt"}${this.selected ? "_sel" : ""}`,
this.slotBgKey,
`${this.slotBgKey}${this.transfer ? "_swap" : this.pokemon.hp ? "" : "_fnt"}${this.selected ? "_sel" : ""}`,
);
}
}
@ -2200,10 +2242,6 @@ class PartyDiscardModeButton extends Phaser.GameObjects.Container {
this.discardIcon.setVisible(false);
this.textBox.setVisible(true);
this.textBox.setText(i18next.t("partyUiHandler:TRANSFER"));
this.setPosition(
globalScene.currentBattle.double ? 64 : 60,
globalScene.currentBattle.double ? -48 : -globalScene.game.canvas.height / 15 - 1,
);
this.transferIcon.displayWidth = this.textBox.text.length * 9 + 3;
break;
case PartyUiMode.DISCARD:
@ -2211,13 +2249,13 @@ class PartyDiscardModeButton extends Phaser.GameObjects.Container {
this.discardIcon.setVisible(true);
this.textBox.setVisible(true);
this.textBox.setText(i18next.t("partyUiHandler:DISCARD"));
this.setPosition(
globalScene.currentBattle.double ? 64 : 60,
globalScene.currentBattle.double ? -48 : -globalScene.game.canvas.height / 15 - 1,
);
this.discardIcon.displayWidth = this.textBox.text.length * 9 + 3;
break;
}
this.setPosition(
globalScene.currentBattle.double ? DISCARD_BUTTON_X_DOUBLES : DISCARD_BUTTON_X,
globalScene.currentBattle.double ? DISCARD_BUTTON_Y_DOUBLES : DISCARD_BUTTON_Y,
);
}
clear() {