#include "../../Minecraft.World/Platform/stdafx.h" #include "../../Minecraft.World/Headers/net.minecraft.world.inventory.h" #include "../../Minecraft.World/Headers/net.minecraft.world.item.trading.h" #include "../../Minecraft.Client/Player/MultiPlayerLocalPlayer.h" #include "../Tutorial/Tutorial.h" #include "../Tutorial/TutorialMode.h" #include "../Tutorial/TutorialEnum.h" #include "../../Minecraft.Client/Minecraft.h" #include "XUI_Ctrl_SlotList.h" #include "XUI_Scene_Trading.h" #include "../../Minecraft.World/Util/StringHelpers.h" #include "../../Minecraft.World/Util/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 std::wstring& name) { XuiControlSetText(m_villagerText, name.c_str()); } void CXuiSceneTrading::setRequest1Name(const std::wstring& name) { m_request1Label.SetText(name.c_str()); } void CXuiSceneTrading::setRequest2Name(const std::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(std::shared_ptr item) { m_request1Control->SetIcon(getPad(), item, 12, 31, true); } void CXuiSceneTrading::setRequest2Item(std::shared_ptr item) { m_request2Control->SetIcon(getPad(), item, 12, 31, true); } void CXuiSceneTrading::setTradeItem(int index, std::shared_ptr item) { m_tradeHSlots[index]->SetIcon(getPad(), item, 12, 31, true); } void CXuiSceneTrading::setOfferDescription( const std::wstring& name, std::vector& unformattedStrings) { if (name.empty()) { m_offerInfoControl.SetText(L""); m_offerInfoControl.SetShow(FALSE); return; } bool smallPointer = m_bSplitscreen || (!RenderManager.IsHiDef() && !RenderManager.IsWidescreen()); std::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); }