4jcraft/Minecraft.Client/Platform/Common/UI/UIScene_TradingMenu.cpp
MatthewBeshay a0fdc643d1 Merge branch 'upstream-dev' into cleanup/nullptr-replacement
# Conflicts:
#	Minecraft.Client/Network/PlayerChunkMap.cpp
#	Minecraft.Client/Network/PlayerList.cpp
#	Minecraft.Client/Network/ServerChunkCache.cpp
#	Minecraft.Client/Platform/Common/Consoles_App.cpp
#	Minecraft.Client/Platform/Common/DLC/DLCManager.cpp
#	Minecraft.Client/Platform/Common/GameRules/LevelGenerationOptions.cpp
#	Minecraft.Client/Platform/Common/GameRules/LevelRuleset.cpp
#	Minecraft.Client/Platform/Common/Tutorial/Tutorial.cpp
#	Minecraft.Client/Platform/Common/Tutorial/TutorialTask.cpp
#	Minecraft.Client/Platform/Common/UI/IUIScene_CreativeMenu.cpp
#	Minecraft.Client/Platform/Common/UI/UIComponent_Panorama.cpp
#	Minecraft.Client/Platform/Common/UI/UIController.cpp
#	Minecraft.Client/Platform/Common/UI/UIController.h
#	Minecraft.Client/Platform/Extrax64Stubs.cpp
#	Minecraft.Client/Platform/Windows64/4JLibs/inc/4J_Input.h
#	Minecraft.Client/Platform/Windows64/4JLibs/inc/4J_Storage.h
#	Minecraft.Client/Player/EntityTracker.cpp
#	Minecraft.Client/Player/ServerPlayer.cpp
#	Minecraft.Client/Rendering/EntityRenderers/PlayerRenderer.cpp
#	Minecraft.Client/Textures/Packs/DLCTexturePack.cpp
#	Minecraft.Client/Textures/Stitching/StitchedTexture.cpp
#	Minecraft.Client/Textures/Stitching/TextureMap.cpp
#	Minecraft.Client/Textures/Textures.cpp
#	Minecraft.World/Blocks/NotGateTile.cpp
#	Minecraft.World/Blocks/PressurePlateTile.cpp
#	Minecraft.World/Blocks/TileEntities/PotionBrewing.cpp
#	Minecraft.World/Enchantments/EnchantmentHelper.cpp
#	Minecraft.World/Entities/HangingEntity.cpp
#	Minecraft.World/Entities/LeashFenceKnotEntity.cpp
#	Minecraft.World/Entities/LivingEntity.cpp
#	Minecraft.World/Entities/Mobs/Boat.cpp
#	Minecraft.World/Entities/Mobs/Minecart.cpp
#	Minecraft.World/Entities/Mobs/Witch.cpp
#	Minecraft.World/Entities/SyncedEntityData.cpp
#	Minecraft.World/Items/LeashItem.cpp
#	Minecraft.World/Items/PotionItem.cpp
#	Minecraft.World/Level/BaseMobSpawner.cpp
#	Minecraft.World/Level/CustomLevelSource.cpp
#	Minecraft.World/Level/Level.cpp
#	Minecraft.World/Level/Storage/DirectoryLevelStorage.cpp
#	Minecraft.World/Level/Storage/McRegionLevelStorage.cpp
#	Minecraft.World/Level/Storage/RegionFileCache.cpp
#	Minecraft.World/Player/Player.cpp
#	Minecraft.World/WorldGen/Biomes/BiomeCache.cpp
#	Minecraft.World/WorldGen/Features/RandomScatteredLargeFeature.cpp
#	Minecraft.World/WorldGen/Layers/BiomeOverrideLayer.cpp
2026-03-30 16:28:40 +11:00

285 lines
9.8 KiB
C++

#include "../../Minecraft.World/Platform/stdafx.h"
#include "UI.h"
#include "../../Minecraft.World/Util/HtmlString.h"
#include "../../Minecraft.World/Headers/net.minecraft.world.inventory.h"
#include "../../Minecraft.World/Headers/net.minecraft.world.item.trading.h"
#include "../../Minecraft.World/Headers/net.minecraft.world.level.tile.entity.h"
#include "../../Minecraft.Client/Player/MultiPlayerLocalPlayer.h"
#include "../../Minecraft.Client/Minecraft.h"
#include "UIScene_TradingMenu.h"
UIScene_TradingMenu::UIScene_TradingMenu(int iPad, void* _initData,
UILayer* parentLayer)
: UIScene(iPad, parentLayer) {
// Setup all the Iggy references we need for this scene
initialiseMovie();
m_showingLeftArrow = true;
m_showingRightArrow = true;
// 4J-PB - "Villager" appears for a short time on opening the trading menu
// m_labelTrading.init( app.GetString(IDS_VILLAGER) );
m_labelTrading.init(L"");
m_labelInventory.init(app.GetString(IDS_INVENTORY));
m_labelRequired.init(app.GetString(IDS_REQUIRED_ITEMS_FOR_TRADE));
m_labelRequest1.init(L"");
m_labelRequest2.init(L"");
TradingScreenInput* initData = (TradingScreenInput*)_initData;
m_merchant = initData->trader;
Minecraft* pMinecraft = Minecraft::GetInstance();
if (pMinecraft->localgameModes[iPad] != nullptr) {
TutorialMode* gameMode =
(TutorialMode*)pMinecraft->localgameModes[iPad];
m_previousTutorialState = gameMode->getTutorial()->getCurrentState();
gameMode->getTutorial()->changeTutorialState(
e_Tutorial_State_Trading_Menu, this);
}
m_menu = new MerchantMenu(initData->inventory, initData->trader,
initData->level);
Minecraft::GetInstance()->localplayers[iPad]->containerMenu = m_menu;
m_slotListRequest1.addSlots(BUY_A, 1);
m_slotListRequest2.addSlots(BUY_B, 1);
m_slotListTrades.addSlots(TRADES_START, DISPLAY_TRADES_COUNT);
m_slotListInventory.addSlots(MerchantMenu::INV_SLOT_START, 27);
m_slotListHotbar.addSlots(MerchantMenu::USE_ROW_SLOT_START, 9);
if (initData) delete initData;
// in this scene, we override the press sound with our own for crafting
// success or fail
ui.OverrideSFX(m_iPad, ACTION_MENU_A, true);
ui.OverrideSFX(m_iPad, ACTION_MENU_OK, true);
ui.OverrideSFX(m_iPad, ACTION_MENU_LEFT_SCROLL, true);
ui.OverrideSFX(m_iPad, ACTION_MENU_RIGHT_SCROLL, true);
ui.OverrideSFX(m_iPad, ACTION_MENU_LEFT, true);
ui.OverrideSFX(m_iPad, ACTION_MENU_RIGHT, true);
ui.OverrideSFX(m_iPad, ACTION_MENU_UP, true);
ui.OverrideSFX(m_iPad, ACTION_MENU_DOWN, true);
app.SetRichPresenceContext(iPad, CONTEXT_GAME_STATE_TRADING);
}
std::wstring UIScene_TradingMenu::getMoviePath() {
if (app.GetLocalPlayerCount() > 1) {
return L"TradingMenuSplit";
} else {
return L"TradingMenu";
}
}
void UIScene_TradingMenu::updateTooltips() {
ui.SetTooltips(m_iPad, IDS_TOOLTIPS_TRADE, IDS_TOOLTIPS_BACK);
}
void UIScene_TradingMenu::handleDestroy() {
app.DebugPrintf("UIScene_TradingMenu::handleDestroy\n");
Minecraft* pMinecraft = Minecraft::GetInstance();
if (pMinecraft->localgameModes[m_iPad] != nullptr) {
TutorialMode* gameMode =
(TutorialMode*)pMinecraft->localgameModes[m_iPad];
if (gameMode != nullptr)
gameMode->getTutorial()->changeTutorialState(
m_previousTutorialState);
}
// 4J Stu - Fix for #11302 - TCR 001: Network Connectivity: Host crashed
// after being killed by the client while accessing a chest during burst
// packet loss. We need to make sure that we call closeContainer() anytime
// this menu is closed, even if it is forced to close by some other reason
// (like the player dying)
if (pMinecraft->localplayers[m_iPad] != nullptr)
pMinecraft->localplayers[m_iPad]->closeContainer();
ui.OverrideSFX(m_iPad, ACTION_MENU_A, false);
ui.OverrideSFX(m_iPad, ACTION_MENU_OK, false);
ui.OverrideSFX(m_iPad, ACTION_MENU_LEFT_SCROLL, false);
ui.OverrideSFX(m_iPad, ACTION_MENU_RIGHT_SCROLL, false);
ui.OverrideSFX(m_iPad, ACTION_MENU_LEFT, false);
ui.OverrideSFX(m_iPad, ACTION_MENU_RIGHT, false);
ui.OverrideSFX(m_iPad, ACTION_MENU_UP, false);
ui.OverrideSFX(m_iPad, ACTION_MENU_DOWN, false);
}
void UIScene_TradingMenu::handleReload() {
m_slotListRequest1.addSlots(BUY_A, 1);
m_slotListRequest2.addSlots(BUY_B, 1);
m_slotListTrades.addSlots(TRADES_START, DISPLAY_TRADES_COUNT);
m_slotListInventory.addSlots(MerchantMenu::INV_SLOT_START, 27);
m_slotListHotbar.addSlots(MerchantMenu::USE_ROW_SLOT_START, 9);
updateDisplay();
IggyDataValue result;
IggyDataValue value[1];
value[0].type = IGGY_DATATYPE_number;
value[0].number = m_selectedSlot;
IggyResult out = IggyPlayerCallMethodRS(getMovie(), &result,
IggyPlayerRootPath(getMovie()),
m_funcSetActiveSlot, 1, value);
}
void UIScene_TradingMenu::tick() {
UIScene::tick();
handleTick();
}
void UIScene_TradingMenu::handleInput(int iPad, int key, bool repeat,
bool pressed, bool released,
bool& handled) {
// app.DebugPrintf("UIScene_InventoryMenu handling input for pad %d, key %d,
// down- %s, pressed- %s, released- %s\n", iPad, key, down?"TRUE":"FALSE",
// pressed?"TRUE":"FALSE", released?"TRUE":"FALSE");
ui.AnimateKeyPress(m_iPad, key, repeat, pressed, released);
switch (key) {
default:
if (pressed) {
handled = handleKeyDown(m_iPad, key, repeat);
}
break;
};
}
void UIScene_TradingMenu::customDraw(IggyCustomDrawCallbackRegion* region) {
Minecraft* pMinecraft = Minecraft::GetInstance();
if (pMinecraft->localplayers[m_iPad] == nullptr ||
pMinecraft->localgameModes[m_iPad] == nullptr)
return;
std::shared_ptr<ItemInstance> item = nullptr;
int slotId = parseSlotId(region->name);
if (slotId < MerchantMenu::USE_ROW_SLOT_END) {
Slot* slot = m_menu->getSlot(slotId);
item = slot->getItem();
} else if (slotId >= TRADES_START) {
int tradeId = (slotId - TRADES_START) + m_offersStartIndex;
if (tradeId < m_activeOffers.size()) {
item = m_activeOffers.at(tradeId).first->getSellItem();
}
} else {
int tradeId = m_selectedSlot + m_offersStartIndex;
if (tradeId < m_activeOffers.size()) {
switch (slotId) {
case BUY_A:
item = m_activeOffers.at(tradeId).first->getBuyAItem();
break;
case BUY_B:
item = m_activeOffers.at(tradeId).first->getBuyBItem();
break;
};
}
}
if (item != nullptr)
customDrawSlotControl(region, m_iPad, item, 1.0f, item->isFoil(), true);
}
void UIScene_TradingMenu::showScrollRightArrow(bool show) {
if (m_showingRightArrow != show) {
IggyDataValue result;
IggyDataValue value[1];
value[0].type = IGGY_DATATYPE_boolean;
value[0].boolval = show;
IggyResult out = IggyPlayerCallMethodRS(
getMovie(), &result, IggyPlayerRootPath(getMovie()),
m_funcShowScrollRightArrow, 1, value);
m_showingRightArrow = show;
}
}
void UIScene_TradingMenu::showScrollLeftArrow(bool show) {
if (m_showingLeftArrow != show) {
IggyDataValue result;
IggyDataValue value[1];
value[0].type = IGGY_DATATYPE_boolean;
value[0].boolval = show;
IggyResult out = IggyPlayerCallMethodRS(
getMovie(), &result, IggyPlayerRootPath(getMovie()),
m_funcShowScrollLeftArrow, 1, value);
m_showingLeftArrow = show;
}
}
void UIScene_TradingMenu::moveSelector(bool right) {
IggyDataValue result;
IggyDataValue value[1];
value[0].type = IGGY_DATATYPE_boolean;
value[0].boolval = right;
IggyResult out = IggyPlayerCallMethodRS(getMovie(), &result,
IggyPlayerRootPath(getMovie()),
m_funcMoveSelector, 1, value);
}
void UIScene_TradingMenu::setTitle(const std::wstring& name) {
m_labelTrading.setLabel(name);
}
void UIScene_TradingMenu::setRequest1Name(const std::wstring& name) {
m_labelRequest1.setLabel(name);
}
void UIScene_TradingMenu::setRequest2Name(const std::wstring& name) {
m_labelRequest2.setLabel(name);
}
void UIScene_TradingMenu::setRequest1RedBox(bool show) {
m_slotListRequest1.showSlotRedBox(0, show);
}
void UIScene_TradingMenu::setRequest2RedBox(bool show) {
m_slotListRequest2.showSlotRedBox(0, show);
}
void UIScene_TradingMenu::setTradeRedBox(int index, bool show) {
m_slotListTrades.showSlotRedBox(index, show);
}
void UIScene_TradingMenu::setOfferDescription(
std::vector<HtmlString>* description) {
std::wstring descriptionStr = HtmlString::Compose(description);
const std::u16string conv = wstring_to_u16string(descriptionStr);
IggyDataValue result;
IggyDataValue value[1];
IggyStringUTF16 stringVal;
stringVal.string = conv.c_str();
stringVal.length = conv.length();
value[0].type = IGGY_DATATYPE_string_UTF16;
value[0].string16 = stringVal;
IggyResult out = IggyPlayerCallMethodRS(
getMovie(), &result, IggyPlayerRootPath(getMovie()),
m_funcSetOfferDescription, 1, value);
}
void UIScene_TradingMenu::HandleMessage(EUIMessage message, void* data) {
switch (message) {
case eUIMessage_InventoryUpdated:
handleInventoryUpdated(data);
break;
default:
break;
};
}
void UIScene_TradingMenu::handleInventoryUpdated(void* data) {
HandleInventoryUpdated();
}