the game where you go into mines and start crafting! but for consoles (forked directly from smartcmd's github)
at main 451 lines 14 kB view raw
1#include "stdafx.h" 2#include "UI.h" 3#include "UIScene_AbstractContainerMenu.h" 4 5#include "..\..\..\Minecraft.World\net.minecraft.world.inventory.h" 6#include "..\..\..\Minecraft.World\net.minecraft.world.item.h" 7#include "..\..\MultiplayerLocalPlayer.h" 8#ifdef _WINDOWS64 9#include "..\..\Windows64\KeyboardMouseInput.h" 10#endif 11 12UIScene_AbstractContainerMenu::UIScene_AbstractContainerMenu(int iPad, UILayer *parentLayer) : UIScene(iPad, parentLayer) 13{ 14 m_focusSection = eSectionNone; 15 // in this scene, we override the press sound with our own for crafting success or fail 16 ui.OverrideSFX(m_iPad,ACTION_MENU_A,true); 17 ui.OverrideSFX(m_iPad,ACTION_MENU_OK,true); 18#ifdef __ORBIS__ 19 ui.OverrideSFX(m_iPad,ACTION_MENU_TOUCHPAD_PRESS,true); 20#endif 21 ui.OverrideSFX(m_iPad,ACTION_MENU_X,true); 22 ui.OverrideSFX(m_iPad,ACTION_MENU_Y,true); 23 ui.OverrideSFX(m_iPad,ACTION_MENU_LEFT_SCROLL,true); 24 ui.OverrideSFX(m_iPad,ACTION_MENU_RIGHT_SCROLL,true); 25 ui.OverrideSFX(m_iPad,ACTION_MENU_LEFT,true); 26 ui.OverrideSFX(m_iPad,ACTION_MENU_RIGHT,true); 27 ui.OverrideSFX(m_iPad,ACTION_MENU_UP,true); 28 ui.OverrideSFX(m_iPad,ACTION_MENU_DOWN,true); 29 30 m_bIgnoreInput=false; 31#ifdef _WINDOWS64 32 m_bMouseDragSlider=false; 33 m_bHasMousePosition = false; 34 m_lastMouseX = 0; 35 m_lastMouseY = 0; 36#endif 37} 38 39UIScene_AbstractContainerMenu::~UIScene_AbstractContainerMenu() 40{ 41 app.DebugPrintf("UIScene_AbstractContainerMenu::~UIScene_AbstractContainerMenu\n"); 42} 43 44void UIScene_AbstractContainerMenu::handleDestroy() 45{ 46 app.DebugPrintf("UIScene_AbstractContainerMenu::handleDestroy\n"); 47 Minecraft *pMinecraft = Minecraft::GetInstance(); 48 if( pMinecraft->localgameModes[m_iPad] != NULL ) 49 { 50 TutorialMode *gameMode = (TutorialMode *)pMinecraft->localgameModes[m_iPad]; 51 if(gameMode != NULL) gameMode->getTutorial()->changeTutorialState(m_previousTutorialState); 52 } 53 54 // 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. 55 // 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) 56 if(pMinecraft->localplayers[m_iPad] != NULL && pMinecraft->localplayers[m_iPad]->containerMenu->containerId == m_menu->containerId) 57 { 58 pMinecraft->localplayers[m_iPad]->closeContainer(); 59 } 60 61 ui.OverrideSFX(m_iPad,ACTION_MENU_A,false); 62 ui.OverrideSFX(m_iPad,ACTION_MENU_OK,false); 63#ifdef __ORBIS__ 64 ui.OverrideSFX(m_iPad,ACTION_MENU_TOUCHPAD_PRESS,false); 65#endif 66 ui.OverrideSFX(m_iPad,ACTION_MENU_X,false); 67 ui.OverrideSFX(m_iPad,ACTION_MENU_Y,false); 68 ui.OverrideSFX(m_iPad,ACTION_MENU_LEFT_SCROLL,false); 69 ui.OverrideSFX(m_iPad,ACTION_MENU_RIGHT_SCROLL,false); 70 ui.OverrideSFX(m_iPad,ACTION_MENU_LEFT,false); 71 ui.OverrideSFX(m_iPad,ACTION_MENU_RIGHT,false); 72 ui.OverrideSFX(m_iPad,ACTION_MENU_UP,false); 73 ui.OverrideSFX(m_iPad,ACTION_MENU_DOWN,false); 74} 75 76void UIScene_AbstractContainerMenu::InitDataAssociations(int iPad, AbstractContainerMenu *menu, int startIndex) 77{ 78} 79 80void UIScene_AbstractContainerMenu::PlatformInitialize(int iPad, int startIndex) 81{ 82 83 m_labelInventory.init( app.GetString(IDS_INVENTORY) ); 84 85 if(startIndex >= 0) 86 { 87 m_slotListInventory.addSlots(startIndex, 27); 88 m_slotListHotbar.addSlots(startIndex + 27, 9); 89 } 90 91 // Determine min and max extents for pointer, it needs to be able to move off the container to drop items. 92 float fPanelWidth, fPanelHeight; 93 float fPanelX, fPanelY; 94 float fPointerWidth, fPointerHeight; 95 96 // We may have varying depths of controls here, so base off the pointers parent 97#if TO_BE_IMPLEMENTED 98 HXUIOBJ parent; 99 XuiElementGetBounds( m_pointerControl->m_hObj, &fPointerWidth, &fPointerHeight ); 100#else 101 fPointerWidth = 50; 102 fPointerHeight = 50; 103#endif 104 105 fPanelWidth = m_controlBackgroundPanel.getWidth(); 106 fPanelHeight = m_controlBackgroundPanel.getHeight(); 107 fPanelX = m_controlBackgroundPanel.getXPos(); 108 fPanelY = m_controlBackgroundPanel.getYPos(); 109 // Get size of pointer 110 m_fPointerImageOffsetX = 0; //floor(fPointerWidth/2.0f); 111 m_fPointerImageOffsetY = 0; //floor(fPointerHeight/2.0f); 112 113 m_fPanelMinX = fPanelX; 114 m_fPanelMaxX = fPanelX + fPanelWidth; 115 m_fPanelMinY = fPanelY; 116 m_fPanelMaxY = fPanelY + fPanelHeight; 117 118#ifdef __ORBIS__ 119 // we need to map the touchpad rectangle to the UI rectangle. While it works great for the creative menu, it is much too sensitive for the smaller menus. 120 //X coordinate of the touch point (0 to 1919) 121 //Y coordinate of the touch point (0 to 941: DUALSHOCK�4 wireless controllers and the CUH-ZCT1J/CAP-ZCT1J/CAP-ZCT1U controllers for the PlayStation�4 development tool, 122 //0 to 753: JDX-1000x series controllers for the PlayStation�4 development tool,) 123 m_fTouchPadMulX=fPanelWidth/1919.0f; 124 m_fTouchPadMulY=fPanelHeight/941.0f; 125 m_fTouchPadDeadZoneX=15.0f*m_fTouchPadMulX; 126 m_fTouchPadDeadZoneY=15.0f*m_fTouchPadMulY; 127 128#endif 129 130 // 4J-PB - need to limit this in splitscreen 131 if(app.GetLocalPlayerCount()>1) 132 { 133 // don't let the pointer go into someone's screen 134 m_fPointerMinY = floor(fPointerHeight/2.0f); 135 } 136 else 137 { 138 m_fPointerMinY = fPanelY -fPointerHeight; 139 } 140 m_fPointerMinX = fPanelX - fPointerWidth; 141 m_fPointerMaxX = m_fPanelMaxX + fPointerWidth; 142 m_fPointerMaxY = m_fPanelMaxY + (fPointerHeight/2); 143 144// m_hPointerText=NULL; 145// m_hPointerTextBkg=NULL; 146 147 // Put the pointer over first item in use row to start with. 148 UIVec2D itemPos; 149 UIVec2D itemSize; 150 GetItemScreenData( m_eCurrSection, 0, &( itemPos ), &( itemSize ) ); 151 152 UIVec2D sectionPos; 153 GetPositionOfSection( m_eCurrSection, &( sectionPos ) ); 154 155 UIVec2D vPointerPos = sectionPos; 156 vPointerPos += itemPos; 157 vPointerPos.x += ( itemSize.x / 2.0f ); 158 vPointerPos.y += ( itemSize.y / 2.0f ); 159 160 vPointerPos.x -= m_fPointerImageOffsetX; 161 vPointerPos.y -= m_fPointerImageOffsetY; 162 163 //m_pointerControl->SetPosition( &vPointerPos ); 164 m_pointerPos = vPointerPos; 165 166 IggyEvent mouseEvent; 167 S32 width, height; 168 m_parentLayer->getRenderDimensions(width, height); 169 S32 x = m_pointerPos.x*((float)width/m_movieWidth); 170 S32 y = m_pointerPos.y*((float)height/m_movieHeight); 171 IggyMakeEventMouseMove( &mouseEvent, x, y); 172 173 IggyEventResult result; 174 IggyPlayerDispatchEventRS ( getMovie() , &mouseEvent , &result ); 175 176#ifdef USE_POINTER_ACCEL 177 m_fPointerVelX = 0.0f; 178 m_fPointerVelY = 0.0f; 179 m_fPointerAccelX = 0.0f; 180 m_fPointerAccelY = 0.0f; 181#endif 182} 183 184void UIScene_AbstractContainerMenu::tick() 185{ 186 UIScene::tick(); 187 188#ifdef _WINDOWS64 189 bool mouseActive = (m_iPad == 0 && !KMInput.IsCaptured()); 190 bool drivePointerFromMouse = false; 191 float rawMouseMovieX = 0, rawMouseMovieY = 0; 192 int scrollDelta = 0; 193 // Map Windows mouse position to the virtual pointer in movie coordinates 194 if (mouseActive) 195 { 196 RECT clientRect; 197 GetClientRect(KMInput.GetHWnd(), &clientRect); 198 int clientWidth = clientRect.right; 199 int clientHeight = clientRect.bottom; 200 if (clientWidth > 0 && clientHeight > 0) 201 { 202 int mouseX = KMInput.GetMouseX(); 203 int mouseY = KMInput.GetMouseY(); 204 bool mouseMoved = !m_bHasMousePosition || mouseX != m_lastMouseX || mouseY != m_lastMouseY; 205 206 m_bHasMousePosition = true; 207 m_lastMouseX = mouseX; 208 m_lastMouseY = mouseY; 209 scrollDelta = KMInput.ConsumeScrollDelta(); 210 211 // Convert mouse position to movie coordinates using the movie/client ratio 212 float mx = (float)mouseX * ((float)m_movieWidth / (float)clientWidth); 213 float my = (float)mouseY * ((float)m_movieHeight / (float)clientHeight); 214 215 rawMouseMovieX = mx; 216 rawMouseMovieY = my; 217 218 // Once the mouse has taken over the container cursor, keep following the OS cursor 219 // until explicit controller input takes ownership back. 220 drivePointerFromMouse = m_bPointerDrivenByMouse || mouseMoved || KMInput.IsMouseDown(0) || KMInput.IsMouseDown(1) || KMInput.IsMouseDown(2) || scrollDelta != 0; 221 if (drivePointerFromMouse) 222 { 223 m_bPointerDrivenByMouse = true; 224 m_eCurrTapState = eTapStateNoInput; 225 m_pointerPos.x = mx; 226 m_pointerPos.y = my; 227 } 228 } 229 } 230#endif 231 232 onMouseTick(); 233 234#ifdef _WINDOWS64 235 // Dispatch mouse clicks AFTER onMouseTick() has updated m_eCurrSection from the new pointer position 236 if (mouseActive) 237 { 238 if (KMInput.ConsumeMousePress(0)) 239 { 240 if (m_eCurrSection == eSectionInventoryCreativeSlider) 241 { 242 // Scrollbar click: use raw mouse position (onMouseTick may have snapped m_pointerPos) 243 m_bMouseDragSlider = true; 244 m_pointerPos.x = rawMouseMovieX; 245 m_pointerPos.y = rawMouseMovieY; 246 handleOtherClicked(m_iPad, eSectionInventoryCreativeSlider, 0, false); 247 } 248 else 249 { 250 handleKeyDown(m_iPad, ACTION_MENU_A, false); 251 } 252 } 253 else if (m_bMouseDragSlider && KMInput.IsMouseDown(0)) 254 { 255 // Continue scrollbar drag: update scroll position from current mouse Y 256 m_pointerPos.x = rawMouseMovieX; 257 m_pointerPos.y = rawMouseMovieY; 258 handleOtherClicked(m_iPad, eSectionInventoryCreativeSlider, 0, false); 259 } 260 261 if (!KMInput.IsMouseDown(0)) 262 m_bMouseDragSlider = false; 263 264 if (KMInput.ConsumeMousePress(1)) 265 { 266 handleKeyDown(m_iPad, ACTION_MENU_X, false); 267 } 268 if (KMInput.ConsumeMousePress(2)) 269 { 270 handleKeyDown(m_iPad, ACTION_MENU_Y, false); 271 } 272 273 // Mouse scroll wheel for page scrolling 274 if (scrollDelta > 0) 275 { 276 handleKeyDown(m_iPad, ACTION_MENU_OTHER_STICK_UP, false); 277 } 278 else if (scrollDelta < 0) 279 { 280 handleKeyDown(m_iPad, ACTION_MENU_OTHER_STICK_DOWN, false); 281 } 282 283 // ESC to close — must be last since it may destroy this scene 284 if (KMInput.ConsumeKeyPress(VK_ESCAPE)) 285 { 286 handleKeyDown(m_iPad, ACTION_MENU_B, false); 287 return; 288 } 289 } 290#endif 291 292 IggyEvent mouseEvent; 293 S32 width, height; 294 m_parentLayer->getRenderDimensions(width, height); 295 296#ifdef _WINDOWS64 297 S32 x, y; 298 if (mouseActive && m_bPointerDrivenByMouse) 299 { 300 // Send raw mouse position directly as Iggy event to avoid coordinate round-trip errors 301 // Scale mouse client coords to the Iggy display space (which was set to getRenderDimensions()) 302 RECT clientRect; 303 GetClientRect(KMInput.GetHWnd(), &clientRect); 304 x = (S32)((float)KMInput.GetMouseX() * ((float)width / (float)clientRect.right)); 305 y = (S32)((float)KMInput.GetMouseY() * ((float)height / (float)clientRect.bottom)); 306 } 307 else 308 { 309 x = (S32)(m_pointerPos.x * ((float)width / m_movieWidth)); 310 y = (S32)(m_pointerPos.y * ((float)height / m_movieHeight)); 311 } 312#else 313 S32 x = m_pointerPos.x*((float)width/m_movieWidth); 314 S32 y = m_pointerPos.y*((float)height/m_movieHeight); 315#endif 316 IggyMakeEventMouseMove( &mouseEvent, x, y); 317 318 // 4J Stu - This seems to be broken on Durango, so do it ourself 319#ifdef _DURANGO 320 //mouseEvent.x = x; 321 //mouseEvent.y = y; 322#endif 323 324 IggyEventResult result; 325 IggyPlayerDispatchEventRS ( getMovie() , &mouseEvent , &result ); 326} 327 328void UIScene_AbstractContainerMenu::render(S32 width, S32 height, C4JRender::eViewportType viewpBort) 329{ 330 m_cacheSlotRenders = true; 331 332 m_needsCacheRendered = m_needsCacheRendered || m_menu->needsRendered(); 333 334 if(m_needsCacheRendered) 335 { 336 m_expectedCachedSlotCount = GetBaseSlotCount(); 337 unsigned int count = m_menu->getSize(); 338 for(unsigned int i = 0; i < count; ++i) 339 { 340 if(m_menu->getSlot(i)->hasItem()) 341 { 342 ++m_expectedCachedSlotCount; 343 } 344 } 345 } 346 347 UIScene::render(width, height, viewpBort); 348 349 m_needsCacheRendered = false; 350} 351 352void UIScene_AbstractContainerMenu::customDraw(IggyCustomDrawCallbackRegion *region) 353{ 354 Minecraft *pMinecraft = Minecraft::GetInstance(); 355 if(pMinecraft->localplayers[m_iPad] == NULL || pMinecraft->localgameModes[m_iPad] == NULL) return; 356 357 shared_ptr<ItemInstance> item = nullptr; 358 int slotId = -1; 359 if(wcscmp((wchar_t *)region->name,L"pointerIcon")==0) 360 { 361 m_cacheSlotRenders = false; 362 item = pMinecraft->localplayers[m_iPad]->inventory->getCarried(); 363 } 364 else 365 { 366 swscanf((wchar_t*)region->name,L"slot_%d",&slotId); 367 if (slotId == -1) 368 { 369 app.DebugPrintf("This is not the control we are looking for\n"); 370 } 371 else 372 { 373 m_cacheSlotRenders = true; 374 Slot *slot = m_menu->getSlot(slotId); 375 item = slot->getItem(); 376 } 377 } 378 379 if(item != NULL) customDrawSlotControl(region,m_iPad,item,m_menu->isValidIngredient(item, slotId)?1.0f:0.5f,item->isFoil(),true); 380} 381 382void UIScene_AbstractContainerMenu::handleInput(int iPad, int key, bool repeat, bool pressed, bool released, bool &handled) 383{ 384 if(m_bIgnoreInput) return; 385 386 //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"); 387 ui.AnimateKeyPress(m_iPad, key, repeat, pressed, released); 388 389 if(pressed) 390 { 391 m_bPointerDrivenByMouse = false; 392 handled = handleKeyDown(m_iPad, key, repeat); 393 } 394} 395 396void UIScene_AbstractContainerMenu::SetPointerText(vector<HtmlString> *description, bool newSlot) 397{ 398 m_cursorPath.setLabel(HtmlString::Compose(description), false, newSlot); 399} 400 401void UIScene_AbstractContainerMenu::setSectionFocus(ESceneSection eSection, int iPad) 402{ 403 UIControl *newFocus = getSection(eSection); 404 if(newFocus) newFocus->setFocus(true); 405 406 if(m_focusSection != eSectionNone) 407 { 408 UIControl *currentFocus = getSection(m_focusSection); 409 // 4J-TomK only set current focus to false if it differs from last (previously this continuously fired iggy functions when they were identical! 410 if(currentFocus != newFocus) 411 if(currentFocus) currentFocus->setFocus(false); 412 } 413 414 m_focusSection = eSection; 415} 416 417void UIScene_AbstractContainerMenu::setFocusToPointer(int iPad) 418{ 419 if(m_focusSection != eSectionNone) 420 { 421 UIControl *currentFocus = getSection(m_focusSection); 422 if(currentFocus) currentFocus->setFocus(false); 423 } 424 m_focusSection = eSectionNone; 425} 426 427shared_ptr<ItemInstance> UIScene_AbstractContainerMenu::getSlotItem(ESceneSection eSection, int iSlot) 428{ 429 Slot *slot = m_menu->getSlot( getSectionStartOffset(eSection) + iSlot ); 430 if(slot) return slot->getItem(); 431 else return nullptr; 432} 433 434Slot *UIScene_AbstractContainerMenu::getSlot(ESceneSection eSection, int iSlot) 435{ 436 Slot *slot = m_menu->getSlot( getSectionStartOffset(eSection) + iSlot ); 437 if(slot) return slot; 438 else return NULL; 439} 440 441bool UIScene_AbstractContainerMenu::isSlotEmpty(ESceneSection eSection, int iSlot) 442{ 443 Slot *slot = m_menu->getSlot( getSectionStartOffset(eSection) + iSlot ); 444 if(slot) return !slot->hasItem(); 445 else return false; 446} 447 448void UIScene_AbstractContainerMenu::adjustPointerForSafeZone() 449{ 450 // Handled by AS 451}