From b691c43c44ff180d10e7d4a9afc83b98551ff586 Mon Sep 17 00:00:00 2001 From: daoge_cmd <3523206925@qq.com> Date: Sun, 1 Mar 2026 12:16:08 +0800 Subject: Initial commit --- Minecraft.Client/Common/XUI/XUI_Scene_Trading.cpp | 320 ++++++++++++++++++++++ 1 file changed, 320 insertions(+) create mode 100644 Minecraft.Client/Common/XUI/XUI_Scene_Trading.cpp (limited to 'Minecraft.Client/Common/XUI/XUI_Scene_Trading.cpp') diff --git a/Minecraft.Client/Common/XUI/XUI_Scene_Trading.cpp b/Minecraft.Client/Common/XUI/XUI_Scene_Trading.cpp new file mode 100644 index 00000000..fec13460 --- /dev/null +++ b/Minecraft.Client/Common/XUI/XUI_Scene_Trading.cpp @@ -0,0 +1,320 @@ +#include "stdafx.h" + +#include "..\..\..\Minecraft.World\net.minecraft.world.inventory.h" +#include "..\..\..\Minecraft.World\net.minecraft.world.item.trading.h" +#include "..\..\MultiPlayerLocalPlayer.h" +#include "..\..\Common\Tutorial\Tutorial.h" +#include "..\..\Common\Tutorial\TutorialMode.h" +#include "..\..\Common\Tutorial\TutorialEnum.h" +#include "..\..\Minecraft.h" +#include "XUI_Ctrl_SlotList.h" +#include "XUI_Scene_Trading.h" +#include "..\..\..\Minecraft.World\StringHelpers.h" +#include "..\..\..\Minecraft.World\JavaMath.h" + +//-------------------------------------------------------------------------------------- +// Name: CXuiSceneTrading::OnInit +// Desc: Message handler for XM_INIT +//-------------------------------------------------------------------------------------- +HRESULT CXuiSceneTrading::OnInit( XUIMessageInit* pInitData, BOOL& bHandled ) +{ + MapChildControls(); + + //XuiControlSetText(m_villagerText,app.GetString(IDS_VILLAGER)); + XuiControlSetText(m_inventoryLabel,app.GetString(IDS_INVENTORY)); + XuiControlSetText(m_requiredLabel,app.GetString(IDS_REQUIRED_ITEMS_FOR_TRADE)); + + + Minecraft *pMinecraft = Minecraft::GetInstance(); + + TradingScreenInput* initData = (TradingScreenInput *)pInitData->pvInitData; + m_iPad=initData->iPad; + m_bSplitscreen=initData->bSplitscreen; + m_merchant = initData->trader; + + // if we are in splitscreen, then we need to figure out if we want to move this scene + + if(m_bSplitscreen) + { + app.AdjustSplitscreenScene(m_hObj,&m_OriginalPosition,m_iPad); + } + + if( pMinecraft->localgameModes[m_iPad] != NULL ) + { + TutorialMode *gameMode = (TutorialMode *)pMinecraft->localgameModes[m_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[m_iPad]->containerMenu = m_menu; + + // TODO Inventory dimensions need defined as constants + m_inventoryControl->SetData( m_iPad, m_menu, 3, 9, MerchantMenu::INV_SLOT_START, MerchantMenu::INV_SLOT_END ); + + // TODO Inventory dimensions need defined as constants + m_useRowControl->SetData( m_iPad, m_menu, 1, 9, MerchantMenu::USE_ROW_SLOT_START, MerchantMenu::USE_ROW_SLOT_END ); + + delete initData; + + D3DXVECTOR3 vec; + // store the slot 0 position + m_tradeHSlots[0]->GetPosition(&m_vTradeSlot0Pos); + m_tradeHSlots[1]->GetPosition(&vec); + m_fSlotSize=vec.x-m_vTradeSlot0Pos.x; + + // store the slot 0 highlight position + m_tradingSelector.GetPosition(&m_vSelectorInitialPos); + + //app.SetRichPresenceContextValue(m_iPad,CONTEXT_GAME_STATE_FORGING); + + XuiSetTimer(m_hObj,TRADING_UPDATE_TIMER_ID,TRADING_UPDATE_TIMER_TIME); + + ui.SetTooltips(m_iPad, -1, IDS_TOOLTIPS_EXIT); + + return S_OK; +} + +HRESULT CXuiSceneTrading::OnDestroy() +{ + Minecraft *pMinecraft = Minecraft::GetInstance(); + + if( pMinecraft->localgameModes[m_iPad] != NULL ) + { + TutorialMode *gameMode = (TutorialMode *)pMinecraft->localgameModes[m_iPad]; + if(gameMode != NULL) 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(Minecraft::GetInstance()->localplayers[m_iPad] != NULL) Minecraft::GetInstance()->localplayers[m_iPad]->closeContainer(); + return S_OK; +} + +HRESULT CXuiSceneTrading::OnTransitionStart( XUIMessageTransition *pTransition, BOOL& bHandled ) +{ + if(pTransition->dwTransAction==XUI_TRANSITION_ACTION_DESTROY ) return S_OK; + + if(pTransition->dwTransType == XUI_TRANSITION_TO || pTransition->dwTransType == XUI_TRANSITION_BACKTO) + { + HXUIOBJ hObj=NULL; + HRESULT hr=XuiControlGetVisual(m_offerInfoControl.m_hObj,&hObj); + hr=XuiElementGetChildById(hObj,L"text_measurer",&m_hOfferInfoTextMeasurer); + hr=XuiElementGetChildById(hObj,L"text_name",&m_hOfferInfoText); + hr=XuiElementGetChildById(hObj,L"text_panel",&m_hOfferInfoTextBkg); + } + + return S_OK; +} + +HRESULT CXuiSceneTrading::OnKeyDown(XUIMessageInput *pInputData, BOOL& bHandled) +{ + bHandled = handleKeyDown(pInputData->UserIndex, mapVKToAction(pInputData->dwKeyCode), (pInputData->dwFlags & XUI_INPUT_FLAG_REPEAT) != 0); + + return S_OK; +} + +HRESULT CXuiSceneTrading::OnCustomMessage_Splitscreenplayer(bool bJoining, BOOL& bHandled) +{ + bHandled=true; + return app.AdjustSplitscreenScene_PlayerChanged(m_hObj,&m_OriginalPosition,m_iPad,bJoining); +} + +HRESULT CXuiSceneTrading::OnTimer( XUIMessageTimer *pTimer, BOOL& bHandled ) +{ + if(pTimer->nId == TRADING_UPDATE_TIMER_ID) + { + handleTick(); + bHandled = TRUE; + } + return S_OK; +} + +int CXuiSceneTrading::mapVKToAction(int vk) +{ + int action = MINECRAFT_ACTION_MAX; + switch(vk) + { + case VK_PAD_A: + action = ACTION_MENU_A; + break; + case VK_PAD_B: + case VK_PAD_START: + action = ACTION_MENU_B; + break; + case VK_PAD_X: + action = ACTION_MENU_X; + break; + case VK_PAD_Y: + action = ACTION_MENU_Y; + break; + case VK_PAD_DPAD_LEFT: + case VK_PAD_LTHUMB_LEFT: + action = ACTION_MENU_LEFT; + break; + case VK_PAD_DPAD_RIGHT: + case VK_PAD_LTHUMB_RIGHT: + action = ACTION_MENU_RIGHT; + break; + case VK_PAD_LTHUMB_UP: + case VK_PAD_DPAD_UP: + action = ACTION_MENU_UP; + break; + case VK_PAD_LTHUMB_DOWN: + case VK_PAD_DPAD_DOWN: + action = ACTION_MENU_DOWN; + break; + case VK_PAD_LTRIGGER: + action = ACTION_MENU_PAGEUP; + break; + case VK_PAD_RTRIGGER: + action = ACTION_MENU_PAGEDOWN; + break; + case VK_PAD_LSHOULDER: + action = ACTION_MENU_LEFT_SCROLL; + break; + case VK_PAD_RSHOULDER: + action = ACTION_MENU_RIGHT_SCROLL; + break; + case VK_PAD_RTHUMB_UP: + action = ACTION_MENU_OTHER_STICK_UP; + break; + case VK_PAD_RTHUMB_DOWN: + action = ACTION_MENU_OTHER_STICK_DOWN; + break; + case VK_PAD_RTHUMB_RIGHT: + action = ACTION_MENU_OTHER_STICK_RIGHT; + break; + case VK_PAD_RTHUMB_LEFT: + action = ACTION_MENU_OTHER_STICK_LEFT; + break; + }; + + return action; +} + +void CXuiSceneTrading::showScrollRightArrow(bool show) +{ + m_scrollRight.SetShow(show?TRUE:FALSE); + m_scrollRight.PlayOptionalVisual(L"ScrollMore",L"EndScrollMore"); +} + +void CXuiSceneTrading::showScrollLeftArrow(bool show) +{ + m_scrollLeft.SetShow(show?TRUE:FALSE); + m_scrollLeft.PlayOptionalVisual(L"ScrollMore",L"EndScrollMore"); +} + +void CXuiSceneTrading::moveSelector(bool right) +{ + D3DXVECTOR3 vec; + + vec.z=0.0f; + vec.x=m_vSelectorInitialPos.x + (m_selectedSlot*m_fSlotSize); + vec.y=m_vSelectorInitialPos.y; + m_tradingSelector.SetPosition(&vec); +} + +void CXuiSceneTrading::setTitle(const wstring &name) +{ + XuiControlSetText(m_villagerText,name.c_str()); +} + +void CXuiSceneTrading::setRequest1Name(const wstring &name) +{ + m_request1Label.SetText(name.c_str()); +} + +void CXuiSceneTrading::setRequest2Name(const wstring &name) +{ + m_request2Label.SetText(name.c_str()); +} + +void CXuiSceneTrading::setRequest1RedBox(bool show) +{ + m_request1Control->SetRedBox(show?TRUE:FALSE); +} + +void CXuiSceneTrading::setRequest2RedBox(bool show) +{ + m_request2Control->SetRedBox(show?TRUE:FALSE); +} + +void CXuiSceneTrading::setTradeRedBox(int index, bool show) +{ + m_tradeHSlots[index]->SetRedBox(show?TRUE:FALSE); +} + +void CXuiSceneTrading::setRequest1Item(shared_ptr item) +{ + m_request1Control->SetIcon(getPad(), item, 12, 31, true); +} + +void CXuiSceneTrading::setRequest2Item(shared_ptr item) +{ + m_request2Control->SetIcon(getPad(), item, 12, 31, true); +} + +void CXuiSceneTrading::setTradeItem(int index, shared_ptr item) +{ + m_tradeHSlots[index]->SetIcon(getPad(), item, 12, 31, true); +} + +void CXuiSceneTrading::setOfferDescription(const wstring &name, vector &unformattedStrings) +{ + if(name.empty()) + { + m_offerInfoControl.SetText(L""); + m_offerInfoControl.SetShow(FALSE); + return; + } + + bool smallPointer = m_bSplitscreen || (!RenderManager.IsHiDef() && !RenderManager.IsWidescreen()); + wstring desc = L"(smallPointer ? 12 :14) + L"\">" + name + L""; + + XUIRect tempXuiRect, xuiRect; + HRESULT hr; + xuiRect.right = 0; + + for(AUTO_VAR(it, unformattedStrings.begin()); it != unformattedStrings.end(); ++it) + { + XuiTextPresenterMeasureText(m_hOfferInfoTextMeasurer, (*it).c_str(), &tempXuiRect); + if(tempXuiRect.right > xuiRect.right) xuiRect = tempXuiRect; + } + + // Set size with the new width so that the HTML height check is correct + XuiElementSetBounds(m_hOfferInfoTextBkg,xuiRect.right+4.0f+4.0f+4.0f,xuiRect.bottom); // edge graphics are 8 pixels, with 4 for the border, extra 4 for the background is fudge + XuiElementSetBounds(m_hOfferInfoText,xuiRect.right+4.0f+4.0f,xuiRect.bottom); // edge graphics are 8 pixels, text is centred + + XuiHtmlSetText(m_hOfferInfoText, desc.c_str() ); + + // Check if we need to resize the box + XUIContentDims contentDims; + XuiHtmlGetContentDims(m_hOfferInfoText,&contentDims); + xuiRect.bottom = contentDims.nContentHeight; + + // Set the new height + float backgroundWidth = xuiRect.right+4.0f+4.0f+4.0f; + XuiElementSetBounds(m_hOfferInfoTextBkg,backgroundWidth,xuiRect.bottom+4.0f+4.0f); // edge graphics are 8 pixels, with 4 for the border, extra 4 for the background is fudge + XuiElementSetBounds(m_hOfferInfoText,xuiRect.right+4.0f+4.0f,xuiRect.bottom+4.0f+4.0f); // edge graphics are 8 pixels, text is centred + + m_offerInfoControl.SetShow(TRUE); + + D3DXVECTOR3 highlightPos, offerInfoPos; + float highlightWidth, highlightHeight; + m_tradingSelector.GetPosition(&highlightPos); + m_tradingSelector.GetBounds(&highlightWidth,&highlightHeight); + m_offerInfoControl.GetPosition(&offerInfoPos); + + if(m_selectedSlot < DISPLAY_TRADES_COUNT/2) + { + // Display on the right + offerInfoPos.x = Math::round(highlightPos.x + highlightWidth * 1.1); + } + else + { + // Display on the left + offerInfoPos.x = Math::round(highlightPos.x - backgroundWidth - highlightWidth * 0.1); + } + m_offerInfoControl.SetPosition(&offerInfoPos); +} \ No newline at end of file -- cgit v1.2.3