mirror of
https://github.com/pagefaultgames/pokerogue.git
synced 2025-08-07 16:09:27 +02:00
[UI/UX] Implement Discard Button (#5985)
* [feature]Implemented needed parts for discard function from issue #4780: -TryDiscardFunction in battlescene; -Created a party discard mode button; -Updated Transfer button in modifier-select-ui-handler to Manage items; -Created tests for the discard function in test/ui; -Added images for the new discard and transfer buttons to loading-scene; -Created placeholder messages for discard feature in party-ui-handler; Co-authored-by: Tiago Rodrigues <tiago.n.rodrigues@tecnico.ulisboa.pt> * [Fix] Updated icon for dynamic messaging * [Fix] Corrected legacy mode icons and adjusted double-battle button location * [Fix]Adjusted button positioning and mapping after review. Mapping requires debugging. * [Fix] Fixed visible pokeball in legacy mode and key mapping * [Fix] Background fixes,manage menu is the only one affected by changes now * Implement i18n keys * [Fix] implemented most code optimizations and callbacks to the modified locales folder * [Fix] Implemented 3 suggestions * [Fix]improved/corrected test structure Co-authored-by: NightKev <34855794+DayKev@users.noreply.github.com> * [Fix] added functionality test for the discard button * [Fix] added necessary comment Co-authored-by: Bertie690 <136088738+Bertie690@users.noreply.github.com> * [Fix] Implemented suggested changes in test/discard text prompt * [Fix] Implemented UI suggestions and removed discard text confirmation * [Fix] added missing imports * Fix imports in test file * [Fix] Implemented suggested cursor behavior and reworked test code * [Fix] Corrected failed test * [Fix] atempting to fix the test timeout issue * [Fix] Undoing latest attempt * [Fix] Implemented suggestions to fix broken tests * Reviews * [Fix] replaced icon images * [Fix] Updated jsons to match new icons and removed pokeball icon from legacy mode * Optimized new images * [Fix] Fixed referenced bug and added similar confirmation box to release * [Fix] Updated tests to handle the corfirmation box * [Fix] Added back the accidentally removed changes * [Fix]updated incorrect import path * [fix] add description for the manageItemMode function Co-authored-by: Bertie690 <136088738+Bertie690@users.noreply.github.com> * Update src/ui/party-ui-handler.ts Co-authored-by: Bertie690 <136088738+Bertie690@users.noreply.github.com> * [Fix] corrected formating issue --------- Co-authored-by: Mikhail Shueb <mikhail.shueb@tecnico.ulisboa.pt> Co-authored-by: NightKev <34855794+DayKev@users.noreply.github.com> Co-authored-by: Bertie690 <136088738+Bertie690@users.noreply.github.com> Co-authored-by: damocleas <damocleas25@gmail.com> Co-authored-by: Bertie690 <taylormw163@gmail.com> Co-authored-by: Adri1 <adrien.grivel@hotmail.fr>
This commit is contained in:
parent
8b304adf14
commit
75ececd942
BIN
public/images/ui/legacy/party_bg_double_manage.png
Normal file
BIN
public/images/ui/legacy/party_bg_double_manage.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 431 B |
62
public/images/ui/legacy/party_discard.json
Normal file
62
public/images/ui/legacy/party_discard.json
Normal file
@ -0,0 +1,62 @@
|
|||||||
|
{
|
||||||
|
"textures": [
|
||||||
|
{
|
||||||
|
"image": "party_discard.png",
|
||||||
|
"format": "RGBA8888",
|
||||||
|
"size": {
|
||||||
|
"w": 75,
|
||||||
|
"h": 50
|
||||||
|
},
|
||||||
|
"scale": 1,
|
||||||
|
"frames": [
|
||||||
|
{
|
||||||
|
"filename": "normal",
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": false,
|
||||||
|
"sourceSize": {
|
||||||
|
"w": 75,
|
||||||
|
"h": 25
|
||||||
|
},
|
||||||
|
"spriteSourceSize": {
|
||||||
|
"x": 0,
|
||||||
|
"y": 0,
|
||||||
|
"w": 75,
|
||||||
|
"h": 25
|
||||||
|
},
|
||||||
|
"frame": {
|
||||||
|
"x": 0,
|
||||||
|
"y": 0,
|
||||||
|
"w": 75,
|
||||||
|
"h": 25
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "selected",
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": false,
|
||||||
|
"sourceSize": {
|
||||||
|
"w": 75,
|
||||||
|
"h": 25
|
||||||
|
},
|
||||||
|
"spriteSourceSize": {
|
||||||
|
"x": 0,
|
||||||
|
"y": 0,
|
||||||
|
"w": 75,
|
||||||
|
"h": 25
|
||||||
|
},
|
||||||
|
"frame": {
|
||||||
|
"x": 0,
|
||||||
|
"y": 25,
|
||||||
|
"w": 75,
|
||||||
|
"h": 25
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"meta": {
|
||||||
|
"app": "https://www.codeandweb.com/texturepacker",
|
||||||
|
"version": "3.0",
|
||||||
|
"smartupdate": "$TexturePacker:SmartUpdate:17219773dfffd6b1204d988fea3f9462:1127ad21d64bc7ebb9df4fc28f3d2d39:7ad46e8fb4648c3d3d84a746ecb371ea$"
|
||||||
|
}
|
||||||
|
}
|
BIN
public/images/ui/legacy/party_discard.png
Normal file
BIN
public/images/ui/legacy/party_discard.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 346 B |
62
public/images/ui/legacy/party_transfer.json
Normal file
62
public/images/ui/legacy/party_transfer.json
Normal file
@ -0,0 +1,62 @@
|
|||||||
|
{
|
||||||
|
"textures": [
|
||||||
|
{
|
||||||
|
"image": "party_transfer.png",
|
||||||
|
"format": "RGBA8888",
|
||||||
|
"size": {
|
||||||
|
"w": 75,
|
||||||
|
"h": 50
|
||||||
|
},
|
||||||
|
"scale": 1,
|
||||||
|
"frames": [
|
||||||
|
{
|
||||||
|
"filename": "normal",
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": false,
|
||||||
|
"sourceSize": {
|
||||||
|
"w": 75,
|
||||||
|
"h": 25
|
||||||
|
},
|
||||||
|
"spriteSourceSize": {
|
||||||
|
"x": 0,
|
||||||
|
"y": 0,
|
||||||
|
"w": 75,
|
||||||
|
"h": 25
|
||||||
|
},
|
||||||
|
"frame": {
|
||||||
|
"x": 0,
|
||||||
|
"y": 0,
|
||||||
|
"w": 75,
|
||||||
|
"h": 25
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "selected",
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": false,
|
||||||
|
"sourceSize": {
|
||||||
|
"w": 75,
|
||||||
|
"h": 25
|
||||||
|
},
|
||||||
|
"spriteSourceSize": {
|
||||||
|
"x": 0,
|
||||||
|
"y": 0,
|
||||||
|
"w": 75,
|
||||||
|
"h": 25
|
||||||
|
},
|
||||||
|
"frame": {
|
||||||
|
"x": 0,
|
||||||
|
"y": 25,
|
||||||
|
"w": 75,
|
||||||
|
"h": 25
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"meta": {
|
||||||
|
"app": "https://www.codeandweb.com/texturepacker",
|
||||||
|
"version": "3.0",
|
||||||
|
"smartupdate": "$TexturePacker:SmartUpdate:17219773dfffd6b1204d988fea3f9462:1127ad21d64bc7ebb9df4fc28f3d2d39:7ad46e8fb4648c3d3d84a746ecb371ea$"
|
||||||
|
}
|
||||||
|
}
|
BIN
public/images/ui/legacy/party_transfer.png
Normal file
BIN
public/images/ui/legacy/party_transfer.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 366 B |
BIN
public/images/ui/party_bg_double_manage.png
Normal file
BIN
public/images/ui/party_bg_double_manage.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 837 B |
62
public/images/ui/party_discard.json
Normal file
62
public/images/ui/party_discard.json
Normal file
@ -0,0 +1,62 @@
|
|||||||
|
{
|
||||||
|
"textures": [
|
||||||
|
{
|
||||||
|
"image": "party_discard.png",
|
||||||
|
"format": "RGBA8888",
|
||||||
|
"size": {
|
||||||
|
"w": 75,
|
||||||
|
"h": 50
|
||||||
|
},
|
||||||
|
"scale": 1,
|
||||||
|
"frames": [
|
||||||
|
{
|
||||||
|
"filename": "normal",
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": false,
|
||||||
|
"sourceSize": {
|
||||||
|
"w": 75,
|
||||||
|
"h": 25
|
||||||
|
},
|
||||||
|
"spriteSourceSize": {
|
||||||
|
"x": 0,
|
||||||
|
"y": 0,
|
||||||
|
"w": 75,
|
||||||
|
"h": 25
|
||||||
|
},
|
||||||
|
"frame": {
|
||||||
|
"x": 0,
|
||||||
|
"y": 0,
|
||||||
|
"w": 75,
|
||||||
|
"h": 25
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "selected",
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": false,
|
||||||
|
"sourceSize": {
|
||||||
|
"w": 75,
|
||||||
|
"h": 25
|
||||||
|
},
|
||||||
|
"spriteSourceSize": {
|
||||||
|
"x": 0,
|
||||||
|
"y": 0,
|
||||||
|
"w": 75,
|
||||||
|
"h": 25
|
||||||
|
},
|
||||||
|
"frame": {
|
||||||
|
"x": 0,
|
||||||
|
"y": 25,
|
||||||
|
"w": 75,
|
||||||
|
"h": 25
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"meta": {
|
||||||
|
"app": "https://www.codeandweb.com/texturepacker",
|
||||||
|
"version": "3.0",
|
||||||
|
"smartupdate": "$TexturePacker:SmartUpdate:17219773dfffd6b1204d988fea3f9462:1127ad21d64bc7ebb9df4fc28f3d2d39:7ad46e8fb4648c3d3d84a746ecb371ea$"
|
||||||
|
}
|
||||||
|
}
|
BIN
public/images/ui/party_discard.png
Normal file
BIN
public/images/ui/party_discard.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 386 B |
62
public/images/ui/party_transfer.json
Normal file
62
public/images/ui/party_transfer.json
Normal file
@ -0,0 +1,62 @@
|
|||||||
|
{
|
||||||
|
"textures": [
|
||||||
|
{
|
||||||
|
"image": "party_transfer.png",
|
||||||
|
"format": "RGBA8888",
|
||||||
|
"size": {
|
||||||
|
"w": 75,
|
||||||
|
"h": 50
|
||||||
|
},
|
||||||
|
"scale": 1,
|
||||||
|
"frames": [
|
||||||
|
{
|
||||||
|
"filename": "normal",
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": false,
|
||||||
|
"sourceSize": {
|
||||||
|
"w": 75,
|
||||||
|
"h": 25
|
||||||
|
},
|
||||||
|
"spriteSourceSize": {
|
||||||
|
"x": 0,
|
||||||
|
"y": 0,
|
||||||
|
"w": 75,
|
||||||
|
"h": 25
|
||||||
|
},
|
||||||
|
"frame": {
|
||||||
|
"x": 0,
|
||||||
|
"y": 0,
|
||||||
|
"w": 75,
|
||||||
|
"h": 25
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "selected",
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": false,
|
||||||
|
"sourceSize": {
|
||||||
|
"w": 75,
|
||||||
|
"h": 25
|
||||||
|
},
|
||||||
|
"spriteSourceSize": {
|
||||||
|
"x": 0,
|
||||||
|
"y": 0,
|
||||||
|
"w": 75,
|
||||||
|
"h": 25
|
||||||
|
},
|
||||||
|
"frame": {
|
||||||
|
"x": 0,
|
||||||
|
"y": 25,
|
||||||
|
"w": 75,
|
||||||
|
"h": 25
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"meta": {
|
||||||
|
"app": "https://www.codeandweb.com/texturepacker",
|
||||||
|
"version": "3.0",
|
||||||
|
"smartupdate": "$TexturePacker:SmartUpdate:17219773dfffd6b1204d988fea3f9462:1127ad21d64bc7ebb9df4fc28f3d2d39:7ad46e8fb4648c3d3d84a746ecb371ea$"
|
||||||
|
}
|
||||||
|
}
|
BIN
public/images/ui/party_transfer.png
Normal file
BIN
public/images/ui/party_transfer.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 403 B |
@ -2845,6 +2845,23 @@ export class BattleScene extends SceneBase {
|
|||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
/**
|
||||||
|
* Attempt to discard one or more copies of a held item.
|
||||||
|
* @param itemModifier - The {@linkcode PokemonHeldItemModifier} being discarded
|
||||||
|
* @param discardQuantity - The number of copies to remove (up to the amount currently held); default `1`
|
||||||
|
* @returns Whether the item was successfully discarded.
|
||||||
|
* Removing fewer items than requested is still considered a success.
|
||||||
|
*/
|
||||||
|
tryDiscardHeldItemModifier(itemModifier: PokemonHeldItemModifier, discardQuantity = 1): boolean {
|
||||||
|
const countTaken = Math.min(discardQuantity, itemModifier.stackCount);
|
||||||
|
itemModifier.stackCount -= countTaken;
|
||||||
|
|
||||||
|
if (itemModifier.stackCount > 0) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.removeModifier(itemModifier);
|
||||||
|
}
|
||||||
|
|
||||||
canTransferHeldItemModifier(itemModifier: PokemonHeldItemModifier, target: Pokemon, transferQuantity = 1): boolean {
|
canTransferHeldItemModifier(itemModifier: PokemonHeldItemModifier, target: Pokemon, transferQuantity = 1): boolean {
|
||||||
const mod = itemModifier.clone() as PokemonHeldItemModifier;
|
const mod = itemModifier.clone() as PokemonHeldItemModifier;
|
||||||
|
@ -119,6 +119,7 @@ export class LoadingScene extends SceneBase {
|
|||||||
|
|
||||||
this.loadImage("party_bg", "ui");
|
this.loadImage("party_bg", "ui");
|
||||||
this.loadImage("party_bg_double", "ui");
|
this.loadImage("party_bg_double", "ui");
|
||||||
|
this.loadImage("party_bg_double_manage", "ui");
|
||||||
this.loadAtlas("party_slot_main", "ui");
|
this.loadAtlas("party_slot_main", "ui");
|
||||||
this.loadAtlas("party_slot", "ui");
|
this.loadAtlas("party_slot", "ui");
|
||||||
this.loadImage("party_slot_overlay_lv", "ui");
|
this.loadImage("party_slot_overlay_lv", "ui");
|
||||||
@ -126,6 +127,8 @@ export class LoadingScene extends SceneBase {
|
|||||||
this.loadAtlas("party_slot_hp_overlay", "ui");
|
this.loadAtlas("party_slot_hp_overlay", "ui");
|
||||||
this.loadAtlas("party_pb", "ui");
|
this.loadAtlas("party_pb", "ui");
|
||||||
this.loadAtlas("party_cancel", "ui");
|
this.loadAtlas("party_cancel", "ui");
|
||||||
|
this.loadAtlas("party_discard", "ui");
|
||||||
|
this.loadAtlas("party_transfer", "ui");
|
||||||
|
|
||||||
this.loadImage("summary_bg", "ui");
|
this.loadImage("summary_bg", "ui");
|
||||||
this.loadImage("summary_overlay_shiny", "ui");
|
this.loadImage("summary_overlay_shiny", "ui");
|
||||||
|
@ -69,7 +69,7 @@ export class ModifierSelectUiHandler extends AwaitableUiHandler {
|
|||||||
|
|
||||||
if (context) {
|
if (context) {
|
||||||
context.font = styleOptions.fontSize + "px " + styleOptions.fontFamily;
|
context.font = styleOptions.fontSize + "px " + styleOptions.fontFamily;
|
||||||
this.transferButtonWidth = context.measureText(i18next.t("modifierSelectUiHandler:transfer")).width;
|
this.transferButtonWidth = context.measureText(i18next.t("modifierSelectUiHandler:manageItems")).width;
|
||||||
this.checkButtonWidth = context.measureText(i18next.t("modifierSelectUiHandler:checkTeam")).width;
|
this.checkButtonWidth = context.measureText(i18next.t("modifierSelectUiHandler:checkTeam")).width;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -81,7 +81,7 @@ export class ModifierSelectUiHandler extends AwaitableUiHandler {
|
|||||||
this.transferButtonContainer.setVisible(false);
|
this.transferButtonContainer.setVisible(false);
|
||||||
ui.add(this.transferButtonContainer);
|
ui.add(this.transferButtonContainer);
|
||||||
|
|
||||||
const transferButtonText = addTextObject(-4, -2, i18next.t("modifierSelectUiHandler:transfer"), TextStyle.PARTY);
|
const transferButtonText = addTextObject(-4, -2, i18next.t("modifierSelectUiHandler:manageItems"), TextStyle.PARTY);
|
||||||
transferButtonText.setName("text-transfer-btn");
|
transferButtonText.setName("text-transfer-btn");
|
||||||
transferButtonText.setOrigin(1, 0);
|
transferButtonText.setOrigin(1, 0);
|
||||||
this.transferButtonContainer.add(transferButtonText);
|
this.transferButtonContainer.add(transferButtonText);
|
||||||
@ -601,7 +601,7 @@ export class ModifierSelectUiHandler extends AwaitableUiHandler {
|
|||||||
(globalScene.game.canvas.width - this.transferButtonWidth - this.checkButtonWidth) / 6 - 30,
|
(globalScene.game.canvas.width - this.transferButtonWidth - this.checkButtonWidth) / 6 - 30,
|
||||||
OPTION_BUTTON_YPOSITION + 4,
|
OPTION_BUTTON_YPOSITION + 4,
|
||||||
);
|
);
|
||||||
ui.showText(i18next.t("modifierSelectUiHandler:transferDesc"));
|
ui.showText(i18next.t("modifierSelectUiHandler:manageItemsDesc"));
|
||||||
} else if (cursor === 2) {
|
} else if (cursor === 2) {
|
||||||
this.cursorObj.setPosition(
|
this.cursorObj.setPosition(
|
||||||
(globalScene.game.canvas.width - this.checkButtonWidth) / 6 - 10,
|
(globalScene.game.canvas.width - this.checkButtonWidth) / 6 - 10,
|
||||||
|
@ -103,6 +103,11 @@ export enum PartyUiMode {
|
|||||||
* This is generally used in for Mystery Encounter or special effects that require the player to select a Pokemon
|
* This is generally used in for Mystery Encounter or special effects that require the player to select a Pokemon
|
||||||
*/
|
*/
|
||||||
SELECT,
|
SELECT,
|
||||||
|
/**
|
||||||
|
* Indicates that the party UI is open to select a party member from which items will be discarded.
|
||||||
|
* This type of selection can be cancelled.
|
||||||
|
*/
|
||||||
|
DISCARD,
|
||||||
}
|
}
|
||||||
|
|
||||||
export enum PartyOption {
|
export enum PartyOption {
|
||||||
@ -121,6 +126,7 @@ export enum PartyOption {
|
|||||||
RELEASE,
|
RELEASE,
|
||||||
RENAME,
|
RENAME,
|
||||||
SELECT,
|
SELECT,
|
||||||
|
DISCARD,
|
||||||
SCROLL_UP = 1000,
|
SCROLL_UP = 1000,
|
||||||
SCROLL_DOWN = 1001,
|
SCROLL_DOWN = 1001,
|
||||||
FORM_CHANGE_ITEM = 2000,
|
FORM_CHANGE_ITEM = 2000,
|
||||||
@ -155,6 +161,7 @@ export class PartyUiHandler extends MessageUiHandler {
|
|||||||
private partySlotsContainer: Phaser.GameObjects.Container;
|
private partySlotsContainer: Phaser.GameObjects.Container;
|
||||||
private partySlots: PartySlot[];
|
private partySlots: PartySlot[];
|
||||||
private partyCancelButton: PartyCancelButton;
|
private partyCancelButton: PartyCancelButton;
|
||||||
|
private partyDiscardModeButton: PartyDiscardModeButton;
|
||||||
private partyMessageBox: Phaser.GameObjects.NineSlice;
|
private partyMessageBox: Phaser.GameObjects.NineSlice;
|
||||||
private moveInfoOverlay: MoveInfoOverlay;
|
private moveInfoOverlay: MoveInfoOverlay;
|
||||||
|
|
||||||
@ -180,6 +187,8 @@ export class PartyUiHandler extends MessageUiHandler {
|
|||||||
private transferAll: boolean;
|
private transferAll: boolean;
|
||||||
|
|
||||||
private lastCursor = 0;
|
private lastCursor = 0;
|
||||||
|
private lastLeftPokemonCursor = 0;
|
||||||
|
private lastRightPokemonCursor = 0;
|
||||||
private selectCallback: PartySelectCallback | PartyModifierTransferSelectCallback | null;
|
private selectCallback: PartySelectCallback | PartyModifierTransferSelectCallback | null;
|
||||||
private selectFilter: PokemonSelectFilter | PokemonModifierTransferSelectFilter;
|
private selectFilter: PokemonSelectFilter | PokemonModifierTransferSelectFilter;
|
||||||
private moveSelectFilter: PokemonMoveSelectFilter;
|
private moveSelectFilter: PokemonMoveSelectFilter;
|
||||||
@ -308,6 +317,12 @@ export class PartyUiHandler extends MessageUiHandler {
|
|||||||
this.iconAnimHandler = new PokemonIconAnimHandler();
|
this.iconAnimHandler = new PokemonIconAnimHandler();
|
||||||
this.iconAnimHandler.setup();
|
this.iconAnimHandler.setup();
|
||||||
|
|
||||||
|
const partyDiscardModeButton = new PartyDiscardModeButton(60, -globalScene.game.canvas.height / 15 - 1, this);
|
||||||
|
|
||||||
|
partyContainer.add(partyDiscardModeButton);
|
||||||
|
|
||||||
|
this.partyDiscardModeButton = partyDiscardModeButton;
|
||||||
|
|
||||||
// prepare move overlay. in case it appears to be too big, set the overlayScale to .5
|
// prepare move overlay. in case it appears to be too big, set the overlayScale to .5
|
||||||
const overlayScale = 1;
|
const overlayScale = 1;
|
||||||
this.moveInfoOverlay = new MoveInfoOverlay({
|
this.moveInfoOverlay = new MoveInfoOverlay({
|
||||||
@ -349,8 +364,18 @@ export class PartyUiHandler extends MessageUiHandler {
|
|||||||
this.showMovePp = args.length > 6 && args[6];
|
this.showMovePp = args.length > 6 && args[6];
|
||||||
|
|
||||||
this.partyContainer.setVisible(true);
|
this.partyContainer.setVisible(true);
|
||||||
|
if (this.isItemManageMode()) {
|
||||||
|
this.partyBg.setTexture(`party_bg${globalScene.currentBattle.double ? "_double_manage" : ""}`);
|
||||||
|
} else {
|
||||||
this.partyBg.setTexture(`party_bg${globalScene.currentBattle.double ? "_double" : ""}`);
|
this.partyBg.setTexture(`party_bg${globalScene.currentBattle.double ? "_double" : ""}`);
|
||||||
|
}
|
||||||
|
|
||||||
this.populatePartySlots();
|
this.populatePartySlots();
|
||||||
|
// If we are currently transferring items, set the icon to its proper state and reveal the button.
|
||||||
|
if (this.isItemManageMode()) {
|
||||||
|
this.partyDiscardModeButton.toggleIcon(this.partyUiMode as PartyUiMode.MODIFIER_TRANSFER | PartyUiMode.DISCARD);
|
||||||
|
}
|
||||||
|
this.showPartyText();
|
||||||
this.setCursor(0);
|
this.setCursor(0);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@ -595,7 +620,7 @@ export class PartyUiHandler extends MessageUiHandler {
|
|||||||
const option = this.options[this.optionsCursor];
|
const option = this.options[this.optionsCursor];
|
||||||
if (button === Button.LEFT) {
|
if (button === Button.LEFT) {
|
||||||
/** Decrease quantity for the current item and update UI */
|
/** Decrease quantity for the current item and update UI */
|
||||||
if (this.partyUiMode === PartyUiMode.MODIFIER_TRANSFER) {
|
if (this.isItemManageMode()) {
|
||||||
this.transferQuantities[option] =
|
this.transferQuantities[option] =
|
||||||
this.transferQuantities[option] === 1
|
this.transferQuantities[option] === 1
|
||||||
? this.transferQuantitiesMax[option]
|
? this.transferQuantitiesMax[option]
|
||||||
@ -609,7 +634,7 @@ export class PartyUiHandler extends MessageUiHandler {
|
|||||||
|
|
||||||
if (button === Button.RIGHT) {
|
if (button === Button.RIGHT) {
|
||||||
/** Increase quantity for the current item and update UI */
|
/** Increase quantity for the current item and update UI */
|
||||||
if (this.partyUiMode === PartyUiMode.MODIFIER_TRANSFER) {
|
if (this.isItemManageMode()) {
|
||||||
this.transferQuantities[option] =
|
this.transferQuantities[option] =
|
||||||
this.transferQuantities[option] === this.transferQuantitiesMax[option]
|
this.transferQuantities[option] === this.transferQuantitiesMax[option]
|
||||||
? 1
|
? 1
|
||||||
@ -639,6 +664,45 @@ export class PartyUiHandler extends MessageUiHandler {
|
|||||||
return success;
|
return success;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private processDiscardMenuInput(pokemon: PlayerPokemon) {
|
||||||
|
const ui = this.getUi();
|
||||||
|
const option = this.options[this.optionsCursor];
|
||||||
|
this.clearOptions();
|
||||||
|
|
||||||
|
this.blockInput = true;
|
||||||
|
this.showText(i18next.t("partyUiHandler:discardConfirmation"), null, () => {
|
||||||
|
this.blockInput = false;
|
||||||
|
ui.setModeWithoutClear(
|
||||||
|
UiMode.CONFIRM,
|
||||||
|
() => {
|
||||||
|
ui.setMode(UiMode.PARTY);
|
||||||
|
this.doDiscard(option, pokemon);
|
||||||
|
},
|
||||||
|
() => {
|
||||||
|
ui.setMode(UiMode.PARTY);
|
||||||
|
this.showPartyText();
|
||||||
|
},
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private doDiscard(option: PartyOption, pokemon: PlayerPokemon) {
|
||||||
|
const itemModifiers = this.getTransferrableItemsFromPokemon(pokemon);
|
||||||
|
this.clearOptions();
|
||||||
|
|
||||||
|
if (option === PartyOption.ALL) {
|
||||||
|
// Discard all currently held items
|
||||||
|
for (let i = 0; i < itemModifiers.length; i++) {
|
||||||
|
globalScene.tryDiscardHeldItemModifier(itemModifiers[i], this.transferQuantities[i]);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Discard the currently selected item
|
||||||
|
globalScene.tryDiscardHeldItemModifier(itemModifiers[option], this.transferQuantities[option]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private moveOptionCursor(button: Button.UP | Button.DOWN): boolean {
|
private moveOptionCursor(button: Button.UP | Button.DOWN): boolean {
|
||||||
if (button === Button.UP) {
|
if (button === Button.UP) {
|
||||||
return this.setCursor(this.optionsCursor ? this.optionsCursor - 1 : this.options.length - 1);
|
return this.setCursor(this.optionsCursor ? this.optionsCursor - 1 : this.options.length - 1);
|
||||||
@ -725,6 +789,10 @@ export class PartyUiHandler extends MessageUiHandler {
|
|||||||
return this.processModifierTransferModeInput(pokemon);
|
return this.processModifierTransferModeInput(pokemon);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (this.partyUiMode === PartyUiMode.DISCARD) {
|
||||||
|
return this.processDiscardMenuInput(pokemon);
|
||||||
|
}
|
||||||
|
|
||||||
// options specific to the mode (moves)
|
// options specific to the mode (moves)
|
||||||
if (this.partyUiMode === PartyUiMode.REMEMBER_MOVE_MODIFIER) {
|
if (this.partyUiMode === PartyUiMode.REMEMBER_MOVE_MODIFIER) {
|
||||||
return this.processRememberMoveModeInput(pokemon);
|
return this.processRememberMoveModeInput(pokemon);
|
||||||
@ -864,7 +932,7 @@ export class PartyUiHandler extends MessageUiHandler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (button === Button.LEFT || button === Button.RIGHT) {
|
if (button === Button.LEFT || button === Button.RIGHT) {
|
||||||
if (this.partyUiMode === PartyUiMode.MODIFIER_TRANSFER) {
|
if (this.isItemManageMode()) {
|
||||||
return this.processModifierTransferModeLeftRightInput(button);
|
return this.processModifierTransferModeLeftRightInput(button);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -919,10 +987,22 @@ export class PartyUiHandler extends MessageUiHandler {
|
|||||||
return !(this.partyUiMode === PartyUiMode.FAINT_SWITCH || this.partyUiMode === PartyUiMode.REVIVAL_BLESSING);
|
return !(this.partyUiMode === PartyUiMode.FAINT_SWITCH || this.partyUiMode === PartyUiMode.REVIVAL_BLESSING);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return whether this UI handler is responsible for managing items.
|
||||||
|
* Used to ensure proper placement of mode toggle buttons in the UI, etc.
|
||||||
|
* @returns Whether the current handler is responsible for managing items.
|
||||||
|
*/
|
||||||
|
private isItemManageMode(): boolean {
|
||||||
|
return this.partyUiMode === PartyUiMode.MODIFIER_TRANSFER || this.partyUiMode === PartyUiMode.DISCARD;
|
||||||
|
}
|
||||||
|
|
||||||
private processPartyActionInput(): boolean {
|
private processPartyActionInput(): boolean {
|
||||||
const ui = this.getUi();
|
const ui = this.getUi();
|
||||||
if (this.cursor < 6) {
|
if (this.cursor < 6) {
|
||||||
if (this.partyUiMode === PartyUiMode.MODIFIER_TRANSFER && !this.transferMode) {
|
if (
|
||||||
|
(this.partyUiMode === PartyUiMode.MODIFIER_TRANSFER && !this.transferMode) ||
|
||||||
|
this.partyUiMode === PartyUiMode.DISCARD
|
||||||
|
) {
|
||||||
/** Initialize item quantities for the selected Pokemon */
|
/** Initialize item quantities for the selected Pokemon */
|
||||||
const itemModifiers = globalScene.findModifiers(
|
const itemModifiers = globalScene.findModifiers(
|
||||||
m =>
|
m =>
|
||||||
@ -936,6 +1016,25 @@ export class PartyUiHandler extends MessageUiHandler {
|
|||||||
this.showOptions();
|
this.showOptions();
|
||||||
ui.playSelect();
|
ui.playSelect();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Toggle item transfer mode to discard items or vice versa
|
||||||
|
if (this.cursor === 7) {
|
||||||
|
switch (this.partyUiMode) {
|
||||||
|
case PartyUiMode.DISCARD:
|
||||||
|
this.partyUiMode = PartyUiMode.MODIFIER_TRANSFER;
|
||||||
|
break;
|
||||||
|
case PartyUiMode.MODIFIER_TRANSFER:
|
||||||
|
this.partyUiMode = PartyUiMode.DISCARD;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
ui.playError();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
this.partyDiscardModeButton.toggleIcon(this.partyUiMode);
|
||||||
|
ui.playSelect();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
// Pressing return button
|
// Pressing return button
|
||||||
if (this.cursor === 6) {
|
if (this.cursor === 6) {
|
||||||
if (!this.allowCancel()) {
|
if (!this.allowCancel()) {
|
||||||
@ -956,6 +1055,7 @@ export class PartyUiHandler extends MessageUiHandler {
|
|||||||
this.clearTransfer();
|
this.clearTransfer();
|
||||||
ui.playSelect();
|
ui.playSelect();
|
||||||
} else if (this.allowCancel()) {
|
} else if (this.allowCancel()) {
|
||||||
|
this.partyDiscardModeButton.clear();
|
||||||
if (this.selectCallback) {
|
if (this.selectCallback) {
|
||||||
const selectCallback = this.selectCallback;
|
const selectCallback = this.selectCallback;
|
||||||
this.selectCallback = null;
|
this.selectCallback = null;
|
||||||
@ -974,30 +1074,74 @@ export class PartyUiHandler extends MessageUiHandler {
|
|||||||
const slotCount = this.partySlots.length;
|
const slotCount = this.partySlots.length;
|
||||||
const battlerCount = globalScene.currentBattle.getBattlerCount();
|
const battlerCount = globalScene.currentBattle.getBattlerCount();
|
||||||
|
|
||||||
|
if (this.lastCursor < battlerCount) {
|
||||||
|
this.lastLeftPokemonCursor = this.lastCursor;
|
||||||
|
}
|
||||||
|
if (this.lastCursor >= battlerCount && this.lastCursor < 6) {
|
||||||
|
this.lastRightPokemonCursor = this.lastCursor;
|
||||||
|
}
|
||||||
|
|
||||||
let success = false;
|
let success = false;
|
||||||
switch (button) {
|
switch (button) {
|
||||||
|
// Item manage mode adds an extra 8th "toggle mode" button to the UI, located *below* both active party members.
|
||||||
|
// The following logic serves to ensure its menu behaviour matches its in-game position,
|
||||||
|
// being selected when scrolling up from the first inactive party member or down from the last active one.
|
||||||
case Button.UP:
|
case Button.UP:
|
||||||
|
if (this.isItemManageMode()) {
|
||||||
|
if (this.cursor === 1) {
|
||||||
|
success = this.setCursor(globalScene.currentBattle.double ? 0 : 7);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (this.cursor === 2) {
|
||||||
|
success = this.setCursor(globalScene.currentBattle.double ? 7 : 1);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (this.cursor === 6) {
|
||||||
|
success = this.setCursor(slotCount <= globalScene.currentBattle.getBattlerCount() ? 7 : slotCount - 1);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (this.cursor === 7) {
|
||||||
|
success = this.setCursor(globalScene.currentBattle.double && slotCount > 1 ? 1 : 0);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
success = this.setCursor(this.cursor ? (this.cursor < 6 ? this.cursor - 1 : slotCount - 1) : 6);
|
success = this.setCursor(this.cursor ? (this.cursor < 6 ? this.cursor - 1 : slotCount - 1) : 6);
|
||||||
break;
|
break;
|
||||||
case Button.DOWN:
|
case Button.DOWN:
|
||||||
|
if (this.isItemManageMode()) {
|
||||||
|
if (this.cursor === 0) {
|
||||||
|
success = this.setCursor(globalScene.currentBattle.double && slotCount > 1 ? 1 : 7);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (this.cursor === 1) {
|
||||||
|
success = this.setCursor(globalScene.currentBattle.double ? 7 : slotCount > 2 ? 2 : 6);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (this.cursor === 7) {
|
||||||
|
success = this.setCursor(
|
||||||
|
slotCount > globalScene.currentBattle.getBattlerCount() ? globalScene.currentBattle.getBattlerCount() : 6,
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
success = this.setCursor(this.cursor < 6 ? (this.cursor < slotCount - 1 ? this.cursor + 1 : 6) : 0);
|
success = this.setCursor(this.cursor < 6 ? (this.cursor < slotCount - 1 ? this.cursor + 1 : 6) : 0);
|
||||||
break;
|
break;
|
||||||
case Button.LEFT:
|
case Button.LEFT:
|
||||||
if (this.cursor >= battlerCount && this.cursor <= 6) {
|
if (this.cursor === 6) {
|
||||||
success = this.setCursor(0);
|
success = this.setCursor(this.isItemManageMode() ? 7 : this.lastLeftPokemonCursor);
|
||||||
|
}
|
||||||
|
if (this.cursor >= battlerCount && this.cursor < 6) {
|
||||||
|
success = this.setCursor(this.lastLeftPokemonCursor);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case Button.RIGHT:
|
case Button.RIGHT:
|
||||||
if (slotCount === battlerCount) {
|
// Scrolling right from item transfer button or with no backup party members goes to cancel
|
||||||
|
if (this.cursor === 7 || slotCount <= battlerCount) {
|
||||||
success = this.setCursor(6);
|
success = this.setCursor(6);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (battlerCount >= 2 && slotCount > battlerCount && this.getCursor() === 0 && this.lastCursor === 1) {
|
if (this.cursor < battlerCount) {
|
||||||
success = this.setCursor(2);
|
success = this.setCursor(this.lastRightPokemonCursor || battlerCount);
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (slotCount > battlerCount && this.cursor < battlerCount) {
|
|
||||||
success = this.setCursor(this.lastCursor < 6 ? this.lastCursor || battlerCount : battlerCount);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1044,11 +1188,15 @@ export class PartyUiHandler extends MessageUiHandler {
|
|||||||
this.partySlots[this.lastCursor].deselect();
|
this.partySlots[this.lastCursor].deselect();
|
||||||
} else if (this.lastCursor === 6) {
|
} else if (this.lastCursor === 6) {
|
||||||
this.partyCancelButton.deselect();
|
this.partyCancelButton.deselect();
|
||||||
|
} else if (this.lastCursor === 7) {
|
||||||
|
this.partyDiscardModeButton.deselect();
|
||||||
}
|
}
|
||||||
if (cursor < 6) {
|
if (cursor < 6) {
|
||||||
this.partySlots[cursor].select();
|
this.partySlots[cursor].select();
|
||||||
} else if (cursor === 6) {
|
} else if (cursor === 6) {
|
||||||
this.partyCancelButton.select();
|
this.partyCancelButton.select();
|
||||||
|
} else if (cursor === 7) {
|
||||||
|
this.partyDiscardModeButton.select();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return changed;
|
return changed;
|
||||||
@ -1143,14 +1291,16 @@ export class PartyUiHandler extends MessageUiHandler {
|
|||||||
optionsMessage = i18next.t("partyUiHandler:selectAnotherPokemonToSplice");
|
optionsMessage = i18next.t("partyUiHandler:selectAnotherPokemonToSplice");
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case PartyUiMode.DISCARD:
|
||||||
|
optionsMessage = i18next.t("partyUiHandler:changeQuantityDiscard");
|
||||||
}
|
}
|
||||||
|
|
||||||
this.showText(optionsMessage, 0);
|
this.showText(optionsMessage, 0);
|
||||||
|
|
||||||
this.updateOptions();
|
this.updateOptions();
|
||||||
|
|
||||||
/** When an item is being selected for transfer, the message box is taller as the message occupies two lines */
|
/** When an item is being selected for transfer or discard, the message box is taller as the message occupies two lines */
|
||||||
if (this.partyUiMode === PartyUiMode.MODIFIER_TRANSFER) {
|
if (this.isItemManageMode()) {
|
||||||
this.partyMessageBox.setSize(262 - Math.max(this.optionsBg.displayWidth - 56, 0), 42);
|
this.partyMessageBox.setSize(262 - Math.max(this.optionsBg.displayWidth - 56, 0), 42);
|
||||||
} else {
|
} else {
|
||||||
this.partyMessageBox.setSize(262 - Math.max(this.optionsBg.displayWidth - 56, 0), 30);
|
this.partyMessageBox.setSize(262 - Math.max(this.optionsBg.displayWidth - 56, 0), 30);
|
||||||
@ -1159,6 +1309,20 @@ export class PartyUiHandler extends MessageUiHandler {
|
|||||||
this.setCursor(0);
|
this.setCursor(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
showPartyText() {
|
||||||
|
switch (this.partyUiMode) {
|
||||||
|
case PartyUiMode.MODIFIER_TRANSFER:
|
||||||
|
this.showText(i18next.t("partyUiHandler:partyTransfer"));
|
||||||
|
break;
|
||||||
|
case PartyUiMode.DISCARD:
|
||||||
|
this.showText(i18next.t("partyUiHandler:partyDiscard"));
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
this.showText("", 0);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private allowBatonModifierSwitch(): boolean {
|
private allowBatonModifierSwitch(): boolean {
|
||||||
return !!(
|
return !!(
|
||||||
this.partyUiMode !== PartyUiMode.FAINT_SWITCH &&
|
this.partyUiMode !== PartyUiMode.FAINT_SWITCH &&
|
||||||
@ -1276,6 +1440,9 @@ export class PartyUiHandler extends MessageUiHandler {
|
|||||||
this.addCommonOptions(pokemon);
|
this.addCommonOptions(pokemon);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case PartyUiMode.DISCARD:
|
||||||
|
this.updateOptionsWithModifierTransferMode(pokemon);
|
||||||
|
break;
|
||||||
// TODO: This still needs to be broken up.
|
// TODO: This still needs to be broken up.
|
||||||
// It could use a rework differentiating different kind of switches
|
// It could use a rework differentiating different kind of switches
|
||||||
// to treat baton passing separately from switching on faint.
|
// to treat baton passing separately from switching on faint.
|
||||||
@ -1381,7 +1548,8 @@ export class PartyUiHandler extends MessageUiHandler {
|
|||||||
optionName = "↓";
|
optionName = "↓";
|
||||||
} else if (
|
} else if (
|
||||||
(this.partyUiMode !== PartyUiMode.REMEMBER_MOVE_MODIFIER &&
|
(this.partyUiMode !== PartyUiMode.REMEMBER_MOVE_MODIFIER &&
|
||||||
(this.partyUiMode !== PartyUiMode.MODIFIER_TRANSFER || this.transferMode)) ||
|
(this.partyUiMode !== PartyUiMode.MODIFIER_TRANSFER || this.transferMode) &&
|
||||||
|
this.partyUiMode !== PartyUiMode.DISCARD) ||
|
||||||
option === PartyOption.CANCEL
|
option === PartyOption.CANCEL
|
||||||
) {
|
) {
|
||||||
switch (option) {
|
switch (option) {
|
||||||
@ -1444,7 +1612,7 @@ export class PartyUiHandler extends MessageUiHandler {
|
|||||||
const itemModifiers = this.getItemModifiers(pokemon);
|
const itemModifiers = this.getItemModifiers(pokemon);
|
||||||
const itemModifier = itemModifiers[option];
|
const itemModifier = itemModifiers[option];
|
||||||
if (
|
if (
|
||||||
this.partyUiMode === PartyUiMode.MODIFIER_TRANSFER &&
|
this.isItemManageMode() &&
|
||||||
this.transferQuantitiesMax[option] > 1 &&
|
this.transferQuantitiesMax[option] > 1 &&
|
||||||
!this.transferMode &&
|
!this.transferMode &&
|
||||||
itemModifier !== undefined &&
|
itemModifier !== undefined &&
|
||||||
@ -1474,7 +1642,6 @@ export class PartyUiHandler extends MessageUiHandler {
|
|||||||
optionText.x = 15 - this.optionsBg.width;
|
optionText.x = 15 - this.optionsBg.width;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
startTransfer(): void {
|
startTransfer(): void {
|
||||||
this.transferMode = true;
|
this.transferMode = true;
|
||||||
this.transferCursor = this.cursor;
|
this.transferCursor = this.cursor;
|
||||||
@ -1608,7 +1775,7 @@ export class PartyUiHandler extends MessageUiHandler {
|
|||||||
this.eraseOptionsCursor();
|
this.eraseOptionsCursor();
|
||||||
|
|
||||||
this.partyMessageBox.setSize(262, 30);
|
this.partyMessageBox.setSize(262, 30);
|
||||||
this.showText("", 0);
|
this.showPartyText();
|
||||||
}
|
}
|
||||||
|
|
||||||
eraseOptionsCursor() {
|
eraseOptionsCursor() {
|
||||||
@ -1663,6 +1830,8 @@ class PartySlot extends Phaser.GameObjects.Container {
|
|||||||
? -184 +
|
? -184 +
|
||||||
(globalScene.currentBattle.double ? -40 : 0) +
|
(globalScene.currentBattle.double ? -40 : 0) +
|
||||||
(28 + (globalScene.currentBattle.double ? 8 : 0)) * slotIndex
|
(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,
|
: -124 + (globalScene.currentBattle.double ? -8 : 0) + slotIndex * 64,
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -1918,7 +2087,6 @@ class PartySlot extends Phaser.GameObjects.Container {
|
|||||||
|
|
||||||
class PartyCancelButton extends Phaser.GameObjects.Container {
|
class PartyCancelButton extends Phaser.GameObjects.Container {
|
||||||
private selected: boolean;
|
private selected: boolean;
|
||||||
|
|
||||||
private partyCancelBg: Phaser.GameObjects.Sprite;
|
private partyCancelBg: Phaser.GameObjects.Sprite;
|
||||||
private partyCancelPb: Phaser.GameObjects.Sprite;
|
private partyCancelPb: Phaser.GameObjects.Sprite;
|
||||||
|
|
||||||
@ -1965,3 +2133,96 @@ class PartyCancelButton extends Phaser.GameObjects.Container {
|
|||||||
this.partyCancelPb.setFrame("party_pb");
|
this.partyCancelPb.setFrame("party_pb");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class PartyDiscardModeButton extends Phaser.GameObjects.Container {
|
||||||
|
private selected: boolean;
|
||||||
|
private transferIcon: Phaser.GameObjects.Sprite;
|
||||||
|
private discardIcon: Phaser.GameObjects.Sprite;
|
||||||
|
private textBox: Phaser.GameObjects.Text;
|
||||||
|
private party: PartyUiHandler;
|
||||||
|
|
||||||
|
constructor(x: number, y: number, party: PartyUiHandler) {
|
||||||
|
super(globalScene, x, y);
|
||||||
|
|
||||||
|
this.setup(party);
|
||||||
|
}
|
||||||
|
|
||||||
|
setup(party: PartyUiHandler) {
|
||||||
|
this.transferIcon = globalScene.add.sprite(0, 0, "party_transfer");
|
||||||
|
this.discardIcon = globalScene.add.sprite(0, 0, "party_discard");
|
||||||
|
this.textBox = addTextObject(-8, -7, i18next.t("partyUiHandler:TRANSFER"), TextStyle.PARTY);
|
||||||
|
this.party = party;
|
||||||
|
|
||||||
|
this.add(this.transferIcon);
|
||||||
|
this.add(this.discardIcon);
|
||||||
|
this.add(this.textBox);
|
||||||
|
|
||||||
|
this.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
select() {
|
||||||
|
if (this.selected) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.selected = true;
|
||||||
|
|
||||||
|
this.party.showText(i18next.t("partyUiHandler:changeMode"));
|
||||||
|
|
||||||
|
this.transferIcon.setFrame("selected");
|
||||||
|
this.discardIcon.setFrame("selected");
|
||||||
|
}
|
||||||
|
|
||||||
|
deselect() {
|
||||||
|
if (!this.selected) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.selected = false;
|
||||||
|
this.party.showPartyText();
|
||||||
|
|
||||||
|
this.transferIcon.setFrame("normal");
|
||||||
|
this.discardIcon.setFrame("normal");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If the current mode deals with transferring items, toggle the discard items button's name and assets.
|
||||||
|
* @param partyMode - The current {@linkcode PartyUiMode}
|
||||||
|
* @remarks
|
||||||
|
* This will also reveal the button if it is currently hidden.
|
||||||
|
*/
|
||||||
|
public toggleIcon(partyMode: PartyUiMode.MODIFIER_TRANSFER | PartyUiMode.DISCARD): void {
|
||||||
|
this.setActive(true).setVisible(true);
|
||||||
|
switch (partyMode) {
|
||||||
|
case PartyUiMode.MODIFIER_TRANSFER:
|
||||||
|
this.transferIcon.setVisible(true);
|
||||||
|
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:
|
||||||
|
this.transferIcon.setVisible(false);
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
clear() {
|
||||||
|
this.setActive(false).setVisible(false);
|
||||||
|
this.transferIcon.setVisible(false);
|
||||||
|
this.discardIcon.setVisible(false);
|
||||||
|
this.textBox.setVisible(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
172
test/ui/item-manage-button.test.ts
Normal file
172
test/ui/item-manage-button.test.ts
Normal file
@ -0,0 +1,172 @@
|
|||||||
|
import { BerryType } from "#enums/berry-type";
|
||||||
|
import { Button } from "#enums/buttons";
|
||||||
|
import { MoveId } from "#enums/move-id";
|
||||||
|
import { SpeciesId } from "#enums/species-id";
|
||||||
|
import { UiMode } from "#enums/ui-mode";
|
||||||
|
import type { Pokemon } from "#field/pokemon";
|
||||||
|
import { GameManager } from "#test/test-utils/game-manager";
|
||||||
|
import type { ModifierSelectUiHandler } from "#ui/modifier-select-ui-handler";
|
||||||
|
import type { PartyUiHandler } from "#ui/party-ui-handler";
|
||||||
|
import Phaser from "phaser";
|
||||||
|
import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest";
|
||||||
|
|
||||||
|
describe("UI - Transfer Items", () => {
|
||||||
|
let phaserGame: Phaser.Game;
|
||||||
|
let game: GameManager;
|
||||||
|
|
||||||
|
beforeAll(() => {
|
||||||
|
phaserGame = new Phaser.Game({
|
||||||
|
type: Phaser.HEADLESS,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
afterEach(() => {
|
||||||
|
game.phaseInterceptor.restoreOg();
|
||||||
|
});
|
||||||
|
|
||||||
|
beforeEach(async () => {
|
||||||
|
game = new GameManager(phaserGame);
|
||||||
|
game.override
|
||||||
|
.battleStyle("single")
|
||||||
|
.startingLevel(100)
|
||||||
|
.startingHeldItems([
|
||||||
|
{ name: "BERRY", count: 1, type: BerryType.SITRUS },
|
||||||
|
{ name: "BERRY", count: 2, type: BerryType.APICOT },
|
||||||
|
{ name: "BERRY", count: 2, type: BerryType.LUM },
|
||||||
|
])
|
||||||
|
.enemySpecies(SpeciesId.MAGIKARP)
|
||||||
|
.enemyMoveset(MoveId.SPLASH);
|
||||||
|
|
||||||
|
await game.classicMode.startBattle([SpeciesId.RAYQUAZA, SpeciesId.RAYQUAZA, SpeciesId.RAYQUAZA]);
|
||||||
|
|
||||||
|
game.move.use(MoveId.DRAGON_CLAW);
|
||||||
|
|
||||||
|
await game.phaseInterceptor.to("SelectModifierPhase");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("manage button exists in the proper screen", async () => {
|
||||||
|
let handlerLength: Phaser.GameObjects.GameObject[] | undefined;
|
||||||
|
|
||||||
|
await new Promise<void>(resolve => {
|
||||||
|
//select manage items menu
|
||||||
|
game.onNextPrompt("SelectModifierPhase", UiMode.MODIFIER_SELECT, async () => {
|
||||||
|
await new Promise(r => setTimeout(r, 100));
|
||||||
|
const handler = game.scene.ui.getHandler() as ModifierSelectUiHandler;
|
||||||
|
|
||||||
|
handler.processInput(Button.DOWN);
|
||||||
|
handler.setCursor(1);
|
||||||
|
handler.processInput(Button.ACTION);
|
||||||
|
});
|
||||||
|
|
||||||
|
game.onNextPrompt("SelectModifierPhase", UiMode.PARTY, async () => {
|
||||||
|
await new Promise(r => setTimeout(r, 100));
|
||||||
|
const handler = game.scene.ui.getHandler() as PartyUiHandler;
|
||||||
|
|
||||||
|
handler.processInput(Button.DOWN);
|
||||||
|
handler.processInput(Button.ACTION);
|
||||||
|
handlerLength = handler.optionsContainer.list;
|
||||||
|
|
||||||
|
handler.processInput(Button.CANCEL);
|
||||||
|
|
||||||
|
resolve();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(handlerLength).toHaveLength(0); // should select manage button, which has no menu
|
||||||
|
});
|
||||||
|
|
||||||
|
it("manage button doesn't exist in the other screens", async () => {
|
||||||
|
let handlerLength: Phaser.GameObjects.GameObject[] | undefined;
|
||||||
|
|
||||||
|
await new Promise<void>(resolve => {
|
||||||
|
game.onNextPrompt("SelectModifierPhase", UiMode.MODIFIER_SELECT, async () => {
|
||||||
|
await new Promise(r => setTimeout(r, 100));
|
||||||
|
const handler = game.scene.ui.getHandler() as ModifierSelectUiHandler;
|
||||||
|
|
||||||
|
handler.processInput(Button.DOWN);
|
||||||
|
handler.setCursor(2);
|
||||||
|
handler.processInput(Button.ACTION);
|
||||||
|
});
|
||||||
|
|
||||||
|
game.onNextPrompt("SelectModifierPhase", UiMode.PARTY, async () => {
|
||||||
|
await new Promise(r => setTimeout(r, 100));
|
||||||
|
const handler = game.scene.ui.getHandler() as PartyUiHandler;
|
||||||
|
|
||||||
|
handler.processInput(Button.DOWN);
|
||||||
|
handler.processInput(Button.ACTION);
|
||||||
|
handlerLength = handler.optionsContainer.list;
|
||||||
|
|
||||||
|
handler.processInput(Button.CANCEL);
|
||||||
|
handler.processInput(Button.CANCEL);
|
||||||
|
|
||||||
|
resolve();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(handlerLength).toHaveLength(6); // should select 2nd pokemon (length is 5 options + image)
|
||||||
|
});
|
||||||
|
|
||||||
|
// Test that the manage button actually discards items, needs proofreading
|
||||||
|
it("should discard items when button is selected", async () => {
|
||||||
|
let pokemon: Pokemon | undefined;
|
||||||
|
|
||||||
|
await new Promise<void>(resolve => {
|
||||||
|
game.onNextPrompt("SelectModifierPhase", UiMode.MODIFIER_SELECT, async () => {
|
||||||
|
await new Promise(r => setTimeout(r, 100));
|
||||||
|
const handler = game.scene.ui.getHandler() as ModifierSelectUiHandler;
|
||||||
|
|
||||||
|
handler.processInput(Button.DOWN);
|
||||||
|
handler.setCursor(1);
|
||||||
|
handler.processInput(Button.ACTION);
|
||||||
|
});
|
||||||
|
game.onNextPrompt("SelectModifierPhase", UiMode.PARTY, async () => {
|
||||||
|
await new Promise(r => setTimeout(r, 100));
|
||||||
|
const handler = game.scene.ui.getHandler() as PartyUiHandler;
|
||||||
|
|
||||||
|
// Enter discard mode and select first party member
|
||||||
|
handler.setCursor(7);
|
||||||
|
handler.processInput(Button.ACTION);
|
||||||
|
handler.setCursor(0);
|
||||||
|
handler.processInput(Button.ACTION);
|
||||||
|
pokemon = game.field.getPlayerPokemon();
|
||||||
|
|
||||||
|
resolve();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(pokemon).toBeDefined();
|
||||||
|
if (pokemon) {
|
||||||
|
expect(pokemon.getHeldItems()).toHaveLength(3);
|
||||||
|
expect(pokemon.getHeldItems().map(h => h.stackCount)).toEqual([1, 2, 2]);
|
||||||
|
}
|
||||||
|
|
||||||
|
await new Promise<void>(resolve => {
|
||||||
|
game.onNextPrompt("SelectModifierPhase", UiMode.PARTY, async () => {
|
||||||
|
await new Promise(r => setTimeout(r, 100));
|
||||||
|
const handler = game.scene.ui.getHandler() as PartyUiHandler;
|
||||||
|
handler.processInput(Button.ACTION);
|
||||||
|
resolve();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
await new Promise<void>(resolve => {
|
||||||
|
game.onNextPrompt("SelectModifierPhase", UiMode.PARTY, async () => {
|
||||||
|
await new Promise(r => setTimeout(r, 100));
|
||||||
|
const handler = game.scene.ui.getHandler() as PartyUiHandler;
|
||||||
|
handler.processInput(Button.ACTION);
|
||||||
|
|
||||||
|
pokemon = game.field.getPlayerPokemon();
|
||||||
|
|
||||||
|
handler.processInput(Button.CANCEL);
|
||||||
|
resolve();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(pokemon).toBeDefined();
|
||||||
|
if (pokemon) {
|
||||||
|
// Sitrus berry was discarded, leaving 2 stacks of 2 berries behind
|
||||||
|
expect(pokemon.getHeldItems()).toHaveLength(2);
|
||||||
|
expect(pokemon.getHeldItems().map(h => h.stackCount)).toEqual([2, 2]);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
Loading…
Reference in New Issue
Block a user