#include "../../Minecraft.World/Platform/stdafx.h" #include "UI.h" #include "UIScene_AbstractContainerMenu.h" #include "../../Minecraft.World/Headers/net.minecraft.world.inventory.h" #include "../../Minecraft.World/Headers/net.minecraft.world.item.h" #include "../../Minecraft.Client/Player/MultiPlayerLocalPlayer.h" UIScene_AbstractContainerMenu::UIScene_AbstractContainerMenu( int iPad, UILayer* parentLayer) : UIScene(iPad, parentLayer) { m_focusSection = eSectionNone; // 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_X, true); ui.OverrideSFX(m_iPad, ACTION_MENU_Y, 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); m_bIgnoreInput = false; } UIScene_AbstractContainerMenu::~UIScene_AbstractContainerMenu() { app.DebugPrintf( "UIScene_AbstractContainerMenu::~UIScene_AbstractContainerMenu\n"); } void UIScene_AbstractContainerMenu::handleDestroy() { app.DebugPrintf("UIScene_AbstractContainerMenu::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]->containerMenu->containerId == m_menu->containerId) { 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_X, false); ui.OverrideSFX(m_iPad, ACTION_MENU_Y, 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_AbstractContainerMenu::InitDataAssociations( int iPad, AbstractContainerMenu* menu, int startIndex) {} void UIScene_AbstractContainerMenu::PlatformInitialize(int iPad, int startIndex) { m_labelInventory.init(app.GetString(IDS_INVENTORY)); if (startIndex >= 0) { m_slotListInventory.addSlots(startIndex, 27); m_slotListHotbar.addSlots(startIndex + 27, 9); } // Determine min and max extents for pointer, it needs to be able to move // off the container to drop items. float fPanelWidth, fPanelHeight; float fPanelX, fPanelY; float fPointerWidth, fPointerHeight; // We may have varying depths of controls here, so base off the pointers // parent #if TO_BE_IMPLEMENTED HXUIOBJ parent; XuiElementGetBounds(m_pointerControl->m_hObj, &fPointerWidth, &fPointerHeight); #else fPointerWidth = 50; fPointerHeight = 50; #endif fPanelWidth = m_controlBackgroundPanel.getWidth(); fPanelHeight = m_controlBackgroundPanel.getHeight(); fPanelX = m_controlBackgroundPanel.getXPos(); fPanelY = m_controlBackgroundPanel.getYPos(); // Get size of pointer m_fPointerImageOffsetX = 0; // floor(fPointerWidth/2.0f); m_fPointerImageOffsetY = 0; // floor(fPointerHeight/2.0f); m_fPanelMinX = fPanelX; m_fPanelMaxX = fPanelX + fPanelWidth; m_fPanelMinY = fPanelY; m_fPanelMaxY = fPanelY + fPanelHeight; // 4J-PB - need to limit this in splitscreen if (app.GetLocalPlayerCount() > 1) { // don't let the pointer go into someone's screen m_fPointerMinY = floor(fPointerHeight / 2.0f); } else { m_fPointerMinY = fPanelY - fPointerHeight; } m_fPointerMinX = fPanelX - fPointerWidth; m_fPointerMaxX = m_fPanelMaxX + fPointerWidth; m_fPointerMaxY = m_fPanelMaxY + (fPointerHeight / 2); // m_hPointerText=nullptr; // m_hPointerTextBkg=nullptr; // Put the pointer over first item in use row to start with. UIVec2D itemPos; UIVec2D itemSize; GetItemScreenData(m_eCurrSection, 0, &(itemPos), &(itemSize)); UIVec2D sectionPos; GetPositionOfSection(m_eCurrSection, &(sectionPos)); UIVec2D vPointerPos = sectionPos; vPointerPos += itemPos; vPointerPos.x += (itemSize.x / 2.0f); vPointerPos.y += (itemSize.y / 2.0f); vPointerPos.x -= m_fPointerImageOffsetX; vPointerPos.y -= m_fPointerImageOffsetY; // m_pointerControl->SetPosition( &vPointerPos ); m_pointerPos = vPointerPos; IggyEvent mouseEvent; S32 width, height; m_parentLayer->getRenderDimensions(width, height); S32 x = m_pointerPos.x * ((float)width / m_movieWidth); S32 y = m_pointerPos.y * ((float)height / m_movieHeight); IggyMakeEventMouseMove(&mouseEvent, x, y); IggyEventResult result; IggyPlayerDispatchEventRS(getMovie(), &mouseEvent, &result); #if defined(USE_POINTER_ACCEL) m_fPointerVelX = 0.0f; m_fPointerVelY = 0.0f; m_fPointerAccelX = 0.0f; m_fPointerAccelY = 0.0f; #endif } void UIScene_AbstractContainerMenu::tick() { UIScene::tick(); onMouseTick(); IggyEvent mouseEvent; S32 width, height; m_parentLayer->getRenderDimensions(width, height); S32 x = m_pointerPos.x * ((float)width / m_movieWidth); S32 y = m_pointerPos.y * ((float)height / m_movieHeight); IggyMakeEventMouseMove(&mouseEvent, x, y); // 4J Stu - This seems to be broken on Durango, so do it ourself IggyEventResult result; IggyPlayerDispatchEventRS(getMovie(), &mouseEvent, &result); } void UIScene_AbstractContainerMenu::render(S32 width, S32 height, C4JRender::eViewportType viewpBort) { m_cacheSlotRenders = true; m_needsCacheRendered = m_needsCacheRendered || m_menu->needsRendered(); if (m_needsCacheRendered) { m_expectedCachedSlotCount = GetBaseSlotCount(); unsigned int count = m_menu->getSize(); for (unsigned int i = 0; i < count; ++i) { if (m_menu->getSlot(i)->hasItem()) { ++m_expectedCachedSlotCount; } } } UIScene::render(width, height, viewpBort); m_needsCacheRendered = false; } void UIScene_AbstractContainerMenu::customDraw( IggyCustomDrawCallbackRegion* region) { Minecraft* pMinecraft = Minecraft::GetInstance(); if (pMinecraft->localplayers[m_iPad] == nullptr || pMinecraft->localgameModes[m_iPad] == nullptr) return; int slotId = parseSlotId(region->name); std::shared_ptr item = nullptr; if (std::char_traits::compare(region->name, u"pointerIcon", 11) == 0) { m_cacheSlotRenders = false; item = pMinecraft->localplayers[m_iPad]->inventory->getCarried(); } else { if (slotId == -1) { app.DebugPrintf("This is not the control we are looking for\n"); } else { m_cacheSlotRenders = true; Slot* slot = m_menu->getSlot(slotId); item = slot->getItem(); } } if (item != nullptr) customDrawSlotControl( region, m_iPad, item, m_menu->isValidIngredient(item, slotId) ? 1.0f : 0.5f, item->isFoil(), true); } void UIScene_AbstractContainerMenu::handleInput(int iPad, int key, bool repeat, bool pressed, bool released, bool& handled) { if (m_bIgnoreInput) return; // 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); if (pressed) { handled = handleKeyDown(m_iPad, key, repeat); } } void UIScene_AbstractContainerMenu::SetPointerText( std::vector* description, bool newSlot) { m_cursorPath.setLabel(HtmlString::Compose(description), false, newSlot); } void UIScene_AbstractContainerMenu::setSectionFocus(ESceneSection eSection, int iPad) { UIControl* newFocus = getSection(eSection); if (newFocus) newFocus->setFocus(true); if (m_focusSection != eSectionNone) { UIControl* currentFocus = getSection(m_focusSection); // 4J-TomK only set current focus to false if it differs from last // (previously this continuously fired iggy functions when they were // identical! if (currentFocus != newFocus) if (currentFocus) currentFocus->setFocus(false); } m_focusSection = eSection; } void UIScene_AbstractContainerMenu::setFocusToPointer(int iPad) { if (m_focusSection != eSectionNone) { UIControl* currentFocus = getSection(m_focusSection); if (currentFocus) currentFocus->setFocus(false); } m_focusSection = eSectionNone; } std::shared_ptr UIScene_AbstractContainerMenu::getSlotItem( ESceneSection eSection, int iSlot) { Slot* slot = m_menu->getSlot(getSectionStartOffset(eSection) + iSlot); if (slot) return slot->getItem(); else return nullptr; } Slot* UIScene_AbstractContainerMenu::getSlot(ESceneSection eSection, int iSlot) { Slot* slot = m_menu->getSlot(getSectionStartOffset(eSection) + iSlot); if (slot) return slot; else return nullptr; } bool UIScene_AbstractContainerMenu::isSlotEmpty(ESceneSection eSection, int iSlot) { Slot* slot = m_menu->getSlot(getSectionStartOffset(eSection) + iSlot); if (slot) return !slot->hasItem(); else return false; } void UIScene_AbstractContainerMenu::adjustPointerForSafeZone() { // Handled by AS }