the game where you go into mines and start crafting! but for consoles (forked directly from smartcmd's github)
at main 1640 lines 45 kB view raw
1#include "stdafx.h" 2 3#include "IUIScene_AbstractContainerMenu.h" 4 5#include "..\..\..\Minecraft.World\net.minecraft.world.inventory.h" 6#include "..\..\..\Minecraft.World\net.minecraft.world.item.h" 7#include "..\..\..\Minecraft.World\net.minecraft.world.item.crafting.h" 8#include "..\..\..\Minecraft.World\net.minecraft.world.level.tile.entity.h" 9#include "..\..\MultiplayerLocalPlayer.h" 10#include "..\..\Minecraft.h" 11 12#ifdef __ORBIS__ 13#include <pad.h> 14#endif 15 16IUIScene_AbstractContainerMenu::IUIScene_AbstractContainerMenu() 17{ 18 m_menu = NULL; 19 m_autoDeleteMenu = false; 20 m_lastPointerLabelSlot = NULL; 21 22 m_pointerPos.x = 0.0f; 23 m_pointerPos.y = 0.0f; 24 m_bPointerDrivenByMouse = false; 25 26} 27 28IUIScene_AbstractContainerMenu::~IUIScene_AbstractContainerMenu() 29{ 30 // Delete associated menu if we were requested to on initialisation. Most menus are 31 // created just before calling CXuiSceneAbstractContainer::Initialize, but the player's inventorymenu 32 // is also passed directly and we don't want to go deleting that 33 if( m_autoDeleteMenu ) delete m_menu; 34} 35 36void IUIScene_AbstractContainerMenu::Initialize(int iPad, AbstractContainerMenu* menu, bool autoDeleteMenu, int startIndex,ESceneSection firstSection,ESceneSection maxSection, bool bNavigateBack) 37{ 38 assert( menu != NULL ); 39 40 m_menu = menu; 41 m_autoDeleteMenu = autoDeleteMenu; 42 43 Minecraft::GetInstance()->localplayers[iPad]->containerMenu = menu; 44 45 // 4J WESTY - New tool tips to support pointer prototype. 46 //UpdateTooltips(); 47 // Default tooltips. 48 for ( int i = 0; i < eToolTipNumButtons; ++i ) 49 { 50 m_aeToolTipSettings[ i ] = eToolTipNone; 51 } 52 // 4J-PB - don't set the eToolTipPickupPlace_OLD here - let the timer do it. 53 /*SetToolTip( eToolTipButtonA, eToolTipPickupPlace_OLD );*/ 54 SetToolTip( eToolTipButtonB, eToolTipExit ); 55 SetToolTip( eToolTipButtonA, eToolTipNone ); 56 SetToolTip( eToolTipButtonX, eToolTipNone ); 57 SetToolTip( eToolTipButtonY, eToolTipNone ); 58 59 // 4J WESTY : To indicate if pointer has left menu window area. 60 m_bPointerOutsideMenu = false; 61 62 // 4J Stu - Store the enum range for the current scene 63 m_eFirstSection = firstSection; 64 m_eMaxSection = maxSection; 65 66 m_iConsectiveInputTicks = 0; 67 68 m_bNavigateBack = bNavigateBack; 69 70 // Put the pointer over first item in use row to start with. 71#ifdef TAP_DETECTION 72 m_eCurrSection = firstSection; 73 m_eCurrTapState = eTapStateNoInput; 74 m_iCurrSlotX = 0; 75 m_iCurrSlotY = 0; 76#endif // TAP_DETECTION 77 // 78 // for(int i=0;i<XUSER_MAX_COUNT;i++) 79 // { 80 // m_bFirstTouchStored[i]=false; 81 // } 82 83#ifdef __ORBIS__ 84 for(int i=0;i<XUSER_MAX_COUNT;i++) 85 { 86 m_bFirstTouchStored[i]=false; 87 } 88#endif 89 90 PlatformInitialize(iPad,startIndex); 91} 92 93int IUIScene_AbstractContainerMenu::GetSectionDimensions( ESceneSection eSection, int* piNumColumns, int* piNumRows ) 94{ 95 if(IsSectionSlotList(eSection)) 96 { 97 *piNumRows = getSectionRows( eSection ); 98 *piNumColumns = getSectionColumns( eSection ); 99 } 100 else 101 { 102 *piNumRows = 0; 103 *piNumColumns = 0; 104 } 105 return( ( *piNumRows ) * ( *piNumColumns ) ); 106} 107 108void IUIScene_AbstractContainerMenu::updateSlotPosition( ESceneSection eSection, ESceneSection newSection, ETapState eTapDirection, int *piTargetX, int *piTargetY, int xOffset, int yOffset ) 109{ 110 // Update the target slot based on the size of the current section 111 int columns, rows; 112 113 // The return value of this function is unused, but the output params are required. 114 //int iItemsNum = GetSectionDimensions( newSection, &columns, &rows ); 115 GetSectionDimensions( newSection, &columns, &rows ); 116 117 if( newSection != eSection ) 118 { 119 // Update Y 120 if(eTapDirection == eTapStateUp) 121 { 122 (*piTargetY) = rows - 1; 123 } 124 else if(eTapDirection == eTapStateDown) 125 { 126 (*piTargetY) = 0; 127 } 128 int offsetY = (*piTargetY) - yOffset; 129 if( offsetY < 0 ) 130 { 131 (*piTargetY) = 0; 132 } 133 else if(offsetY >= rows) 134 { 135 (*piTargetY) = rows - 1; 136 } 137 else 138 { 139 (*piTargetY) = offsetY; 140 } 141 142 // Update X 143 int offsetX = (*piTargetX) - xOffset; 144 if( offsetX < 0 ) 145 { 146 *piTargetX = 0; 147 } 148 else if (offsetX >= columns) 149 { 150 *piTargetX = columns - 1; 151 } 152 else 153 { 154 *piTargetX = offsetX; 155 } 156 } 157 else 158 { 159 // Update X 160 int offsetX = (*piTargetX) - xOffset; 161 if( offsetX < 0 ) 162 { 163 *piTargetX = columns - 1; 164 } 165 else if (offsetX >= columns) 166 { 167 *piTargetX = 0; 168 } 169 else 170 { 171 *piTargetX = offsetX; 172 } 173 } 174} 175 176#ifdef TAP_DETECTION 177IUIScene_AbstractContainerMenu::ETapState IUIScene_AbstractContainerMenu::GetTapInputType( float fInputX, float fInputY ) 178{ 179 if ( ( fabs( fInputX ) < 0.3f ) && ( fabs( fInputY ) < 0.3f ) ) 180 { 181 return eTapStateNoInput; 182 } 183 else if ( ( fInputX < -0.3f ) && ( fabs( fInputY ) < 0.3f ) ) 184 { 185 return eTapStateLeft; 186 } 187 else if ( ( fInputX > 0.3f ) && ( fabs( fInputY ) < 0.3f ) ) 188 { 189 return eTapStateRight; 190 } 191 else if ( ( fInputY < -0.3f ) && ( fabs( fInputX ) < 0.3f ) ) 192 { 193 return eTapStateDown; 194 } 195 else if ( ( fInputY > 0.3f ) && ( fabs( fInputX ) < 0.3f ) ) 196 { 197 return eTapStateUp; 198 } 199 else 200 { 201 return eTapNone; 202 } 203} 204#endif // TAP_DETECTION 205 206void IUIScene_AbstractContainerMenu::SetToolTip( EToolTipButton eButton, EToolTipItem eItem ) 207{ 208 if ( m_aeToolTipSettings[ eButton ] != eItem ) 209 { 210 m_aeToolTipSettings[ eButton ] = eItem; 211 UpdateTooltips(); 212 } 213} 214 215void IUIScene_AbstractContainerMenu::UpdateTooltips() 216{ 217 // Table gives us text id for tooltip. 218 static const DWORD kaToolTipextIds[ eNumToolTips ] = 219 { 220 IDS_TOOLTIPS_PICKUPPLACE, //eToolTipPickupPlace_OLD 221 IDS_TOOLTIPS_EXIT, // eToolTipExit 222 IDS_TOOLTIPS_PICKUP_GENERIC, // eToolTipPickUpGeneric 223 IDS_TOOLTIPS_PICKUP_ALL, // eToolTipPickUpAll 224 IDS_TOOLTIPS_PICKUP_HALF, // eToolTipPickUpHalf 225 IDS_TOOLTIPS_PLACE_GENERIC, // eToolTipPlaceGeneric 226 IDS_TOOLTIPS_PLACE_ONE, // eToolTipPlaceOne 227 IDS_TOOLTIPS_PLACE_ALL, // eToolTipPlaceAll 228 IDS_TOOLTIPS_DROP_GENERIC, // eToolTipDropGeneric 229 IDS_TOOLTIPS_DROP_ONE, // eToolTipDropOne 230 IDS_TOOLTIPS_DROP_ALL, // eToolTipDropAll 231 IDS_TOOLTIPS_SWAP, // eToolTipSwap 232 IDS_TOOLTIPS_QUICK_MOVE, // eToolTipQuickMove 233 IDS_TOOLTIPS_QUICK_MOVE_INGREDIENT, // eToolTipQuickMoveIngredient 234 IDS_TOOLTIPS_QUICK_MOVE_FUEL, // eToolTipQuickMoveTool 235 IDS_TOOLTIPS_WHAT_IS_THIS, // eToolTipWhatIsThis 236 IDS_TOOLTIPS_EQUIP, // eToolTipEquip 237 IDS_TOOLTIPS_CLEAR_QUICK_SELECT, // eToolTipClearQuickSelect 238 IDS_TOOLTIPS_QUICK_MOVE_TOOL, // eToolTipQuickMoveTool 239 IDS_TOOLTIPS_QUICK_MOVE_ARMOR, // eToolTipQuickMoveTool 240 IDS_TOOLTIPS_QUICK_MOVE_WEAPON, // eToolTipQuickMoveTool 241 IDS_TOOLTIPS_DYE, // eToolTipDye 242 IDS_TOOLTIPS_REPAIR, // eToolTipRepair 243 }; 244 245 BYTE focusUser = getPad(); 246 247 for ( int i = 0; i < eToolTipNumButtons; ++i ) 248 { 249 if ( m_aeToolTipSettings[ i ] == eToolTipNone ) 250 { 251 ui.ShowTooltip( focusUser, i, FALSE ); 252 } 253 else 254 { 255 ui.SetTooltipText( focusUser, i, kaToolTipextIds[ m_aeToolTipSettings[ i ] ] ); 256 ui.ShowTooltip( focusUser, i, TRUE ); 257 } 258 } 259} 260 261void IUIScene_AbstractContainerMenu::onMouseTick() 262{ 263 Minecraft *pMinecraft = Minecraft::GetInstance(); 264 if( pMinecraft->localgameModes[getPad()] != NULL) 265 { 266 Tutorial *tutorial = pMinecraft->localgameModes[getPad()]->getTutorial(); 267 if(tutorial != NULL) 268 { 269 if(ui.IsTutorialVisible(getPad()) && !tutorial->isInputAllowed(ACTION_MENU_UP)) 270 { 271 return; 272 } 273 } 274 } 275 276 // Offset to display carried item attached to pointer. 277 // static const float kfCarriedItemOffsetX = -5.0f; 278 // static const float kfCarriedItemOffsetY = -5.0f; 279 float fInputDirX=0.0f; 280 float fInputDirY=0.0f; 281 282 // Get current pointer position. 283 UIVec2D vPointerPos = m_pointerPos; 284 285 // Offset to image centre. 286 vPointerPos.x += m_fPointerImageOffsetX; 287 vPointerPos.y += m_fPointerImageOffsetY; 288 289 // Get stick input. 290 int iPad = getPad(); 291 292 bool bStickInput = false; 293 float fInputX = InputManager.GetJoypadStick_LX( iPad, false )*((float)app.GetGameSettings(iPad,eGameSetting_Sensitivity_InMenu)/100.0f); // apply the sensitivity 294 float fInputY = InputManager.GetJoypadStick_LY( iPad, false )*((float)app.GetGameSettings(iPad,eGameSetting_Sensitivity_InMenu)/100.0f); // apply the sensitivity 295 296#ifdef __ORBIS__ 297 // should have sensitivity for the touchpad 298 //(float)app.GetGameSettings(iPad,eGameSetting_Sensitivity_TouchPadInMenu)/100.0f 299 300 // get the touchpad input and treat it as a map to the window 301 ScePadTouchData *pTouchPadData=InputManager.GetTouchPadData(iPad); 302 303 // make sure the touchpad button isn't down (it's the pausemenu) 304 305 if((!InputManager.ButtonDown(iPad, ACTION_MENU_TOUCHPAD_PRESS)) && (pTouchPadData->touchNum>0)) 306 { 307 if(m_bFirstTouchStored[iPad]==false) 308 { 309 m_oldvTouchPos.x=(float)pTouchPadData->touch[0].x; 310 m_oldvTouchPos.y=(float)pTouchPadData->touch[0].y; 311 m_oldvPointerPos.x=vPointerPos.x; 312 m_oldvPointerPos.y=vPointerPos.y; 313 m_bFirstTouchStored[iPad]=true; 314 } 315 316 // should take the average of multiple touch points 317 318 float fNewX=(((float)pTouchPadData->touch[0].x)-m_oldvTouchPos.x) * m_fTouchPadMulX; 319 float fNewY=(((float)pTouchPadData->touch[0].y)-m_oldvTouchPos.y) * m_fTouchPadMulY; 320 // relative positions - needs a deadzone 321 322 if(fNewX>m_fTouchPadDeadZoneX) 323 { 324 vPointerPos.x=m_oldvPointerPos.x+((fNewX-m_fTouchPadDeadZoneX)*((float)app.GetGameSettings(iPad,eGameSetting_Sensitivity_InMenu)/100.0f)); 325 } 326 else if(fNewX<-m_fTouchPadDeadZoneX) 327 { 328 vPointerPos.x=m_oldvPointerPos.x+((fNewX+m_fTouchPadDeadZoneX)*((float)app.GetGameSettings(iPad,eGameSetting_Sensitivity_InMenu)/100.0f)); 329 } 330 331 if(fNewY>m_fTouchPadDeadZoneY) 332 { 333 vPointerPos.y=m_oldvPointerPos.y+((fNewY-m_fTouchPadDeadZoneY)*((float)app.GetGameSettings(iPad,eGameSetting_Sensitivity_InMenu)/100.0f)); 334 } 335 else if(fNewY<-m_fTouchPadDeadZoneY) 336 { 337 vPointerPos.y=m_oldvPointerPos.y+((fNewY+m_fTouchPadDeadZoneY)*((float)app.GetGameSettings(iPad,eGameSetting_Sensitivity_InMenu)/100.0f)); 338 } 339 340 // Clamp to pointer extents. 341 if ( vPointerPos.x < m_fPointerMinX ) vPointerPos.x = m_fPointerMinX; 342 else if ( vPointerPos.x > m_fPointerMaxX ) vPointerPos.x = m_fPointerMaxX; 343 if ( vPointerPos.y < m_fPointerMinY ) vPointerPos.y = m_fPointerMinY; 344 else if ( vPointerPos.y > m_fPointerMaxY ) vPointerPos.y = m_fPointerMaxY; 345 346 bStickInput = true; 347 m_eCurrTapState=eTapStateNoInput; 348 } 349 else 350 { 351 // reset the touch flag 352 m_bFirstTouchStored[iPad]=false; 353 354#endif 355 356 357 358 // If there is any input on sticks, move the pointer. 359 if ( ( fabs( fInputX ) >= 0.01f ) || ( fabs( fInputY ) >= 0.01f ) ) 360 { 361 m_bPointerDrivenByMouse = false; 362 fInputDirX = ( fInputX > 0.0f ) ? 1.0f : ( fInputX < 0.0f )?-1.0f : 0.0f; 363 fInputDirY = ( fInputY > 0.0f ) ? 1.0f : ( fInputY < 0.0f )?-1.0f : 0.0f; 364 365#ifdef TAP_DETECTION 366 // Check for potential tap input to jump slot. 367 ETapState eNewTapInput = GetTapInputType( fInputX, fInputY ); 368 369 switch( m_eCurrTapState ) 370 { 371 case eTapStateNoInput: 372 m_eCurrTapState = eNewTapInput; 373 break; 374 375 case eTapStateUp: 376 case eTapStateDown: 377 case eTapStateLeft: 378 case eTapStateRight: 379 if ( ( eNewTapInput != m_eCurrTapState ) && ( eNewTapInput != eTapStateNoInput ) ) 380 { 381 // Input is no longer suitable for tap. 382 m_eCurrTapState = eTapNone; 383 } 384 break; 385 386 case eTapNone: 387 /// Nothing to do, input is not a tap. 388 break; 389 } 390#endif // TAP_DETECTION 391 392 // Square it so we get more precision for small inputs. 393 fInputX = fInputX * fInputX * fInputDirX * POINTER_SPEED_FACTOR; 394 fInputY = fInputY * fInputY * fInputDirY * POINTER_SPEED_FACTOR; 395 //fInputX = fInputX * POINTER_SPEED_FACTOR; 396 //fInputY = fInputY * POINTER_SPEED_FACTOR; 397 float fInputScale = 1.0f; 398 399 // Ramp up input from zero when new input is recieved over INPUT_TICKS_FOR_SCALING ticks. This is to try to improve tapping stick to move 1 box. 400 if ( m_iConsectiveInputTicks < MAX_INPUT_TICKS_FOR_SCALING ) 401 { 402 ++m_iConsectiveInputTicks; 403 fInputScale = ( (float)( m_iConsectiveInputTicks) / (float)(MAX_INPUT_TICKS_FOR_SCALING) ); 404 } 405#ifdef TAP_DETECTION 406 else if ( m_iConsectiveInputTicks < MAX_INPUT_TICKS_FOR_TAPPING ) 407 { 408 ++m_iConsectiveInputTicks; 409 } 410 else 411 { 412 m_eCurrTapState = eTapNone; 413 } 414#endif 415 // 4J Stu - The cursor moves too fast in SD mode 416 // The SD/splitscreen scenes are approximately 0.6 times the size of the fullscreen on 417 if(!RenderManager.IsHiDef() || app.GetLocalPlayerCount() > 1) fInputScale *= 0.6f; 418 419 fInputX *= fInputScale; 420 fInputY *= fInputScale; 421 422#ifdef USE_POINTER_ACCEL 423 m_fPointerAccelX += fInputX / 50.0f; 424 m_fPointerAccelY += fInputY / 50.0f; 425 426 if ( fabsf( fInputX ) > fabsf( m_fPointerVelX + m_fPointerAccelX ) ) 427 { 428 m_fPointerVelX += m_fPointerAccelX; 429 } 430 else 431 { 432 m_fPointerAccelX = fInputX - m_fPointerVelX; 433 m_fPointerVelX = fInputX; 434 } 435 436 if ( fabsf( fInputY ) > fabsf( m_fPointerVelY + m_fPointerAccelY ) ) 437 { 438 m_fPointerVelY += m_fPointerAccelY; 439 } 440 else 441 { 442 m_fPointerAccelY = fInputY - m_fPointerVelY; 443 m_fPointerVelY = fInputY; 444 } 445 //printf( "IN %.2f VEL %.2f ACC %.2f\n", fInputY, m_fPointerVelY, m_fPointerAccelY ); 446 447 vPointerPos.x += m_fPointerVelX; 448 vPointerPos.y -= m_fPointerVelY; 449#else 450 // Add input to pointer position. 451 vPointerPos.x += fInputX; 452 vPointerPos.y -= fInputY; 453#endif 454 // Clamp to pointer extents. 455 if ( vPointerPos.x < m_fPointerMinX ) vPointerPos.x = m_fPointerMinX; 456 else if ( vPointerPos.x > m_fPointerMaxX ) vPointerPos.x = m_fPointerMaxX; 457 if ( vPointerPos.y < m_fPointerMinY ) vPointerPos.y = m_fPointerMinY; 458 else if ( vPointerPos.y > m_fPointerMaxY ) vPointerPos.y = m_fPointerMaxY; 459 460 bStickInput = true; 461 } 462 else 463 { 464 m_iConsectiveInputTicks = 0; 465#ifdef USE_POINTER_ACCEL 466 m_fPointerVelX = 0.0f; 467 m_fPointerVelY = 0.0f; 468 m_fPointerAccelX = 0.0f; 469 m_fPointerAccelY = 0.0f; 470#endif 471 } 472 473#ifdef __ORBIS__ 474 } 475#endif 476 477 // Determine which slot the pointer is currently over. 478 ESceneSection eSectionUnderPointer = eSectionNone; 479 int iNewSlotX = -1; 480 int iNewSlotY = -1; 481 int iNewSlotIndex = -1; 482 bool bPointerIsOverSlot = false; 483 484 // Centre position of item under pointer, use this to snap pointer to item. 485 D3DXVECTOR3 vSnapPos; 486 487 for ( int iSection = m_eFirstSection; iSection < m_eMaxSection; ++iSection ) 488 { 489 // Do not check any further if we have already found the item under the pointer. 490 if(m_eCurrTapState == eTapStateJump) 491 { 492 eSectionUnderPointer = m_eCurrSection; 493 } 494 else if ( eSectionUnderPointer == eSectionNone ) 495 { 496 ESceneSection eSection = ( ESceneSection )( iSection ); 497 498 // Get position of this section. 499 UIVec2D sectionPos; 500 GetPositionOfSection( eSection, &( sectionPos ) ); 501 502 if(!IsSectionSlotList(eSection)) 503 { 504 UIVec2D itemPos; 505 UIVec2D itemSize; 506 GetItemScreenData( eSection, 0, &( itemPos ), &( itemSize ) ); 507 508 UIVec2D itemMax = itemSize; 509 itemMax += itemPos; 510 511 if ( ( vPointerPos.x >= sectionPos.x ) && ( vPointerPos.x <= itemMax.x ) && 512 ( vPointerPos.y >= sectionPos.y ) && ( vPointerPos.y <= itemMax.y ) ) 513 { 514 // Pointer is over this control! 515 eSectionUnderPointer = eSection; 516 517 vSnapPos.x = itemPos.x + ( itemSize.x / 2.0f ); 518 vSnapPos.y = itemPos.y + ( itemSize.y / 2.0f ); 519 520 // Does this section already have focus. 521 if ( !doesSectionTreeHaveFocus( eSection ) ) 522 { 523 // Give focus to this section. 524 setSectionFocus(eSection, getPad()); 525 } 526 527 bPointerIsOverSlot = false; 528 529 // Have we actually changed slot? If so, input cannot be a tap. 530 if ( ( eSectionUnderPointer != m_eCurrSection ) || ( iNewSlotX != m_iCurrSlotX ) || ( iNewSlotY != m_iCurrSlotY ) ) 531 { 532 m_eCurrTapState = eTapNone; 533 } 534 535 // Store what is currently under the pointer. 536 m_eCurrSection = eSectionUnderPointer; 537 } 538 } 539 else 540 { 541 542 // Get dimensions of this section. 543 int iNumRows; 544 int iNumColumns; 545 int iNumItems = GetSectionDimensions( eSection, &( iNumColumns ), &( iNumRows ) ); 546 547 // Check each item to see if pointer is over it. 548 for ( int iItem = 0; iItem < iNumItems; ++iItem ) 549 { 550 UIVec2D itemPos; 551 UIVec2D itemSize; 552 GetItemScreenData( eSection, iItem, &( itemPos ), &( itemSize ) ); 553 554 itemPos += sectionPos; 555 556 UIVec2D itemMax = itemSize; 557 itemMax += itemPos; 558 559 if ( ( vPointerPos.x >= itemPos.x ) && ( vPointerPos.x <= itemMax.x ) && 560 ( vPointerPos.y >= itemPos.y ) && ( vPointerPos.y <= itemMax.y ) ) 561 { 562 // Pointer is over this slot! 563 eSectionUnderPointer = eSection; 564 iNewSlotIndex = iItem; 565 iNewSlotX = iNewSlotIndex % iNumColumns; 566 iNewSlotY = iNewSlotIndex / iNumColumns; 567 568 vSnapPos.x = itemPos.x + ( itemSize.x / 2.0f ); 569 vSnapPos.y = itemPos.y + ( itemSize.y / 2.0f ); 570 571 // Does this section already have focus. 572 if ( !doesSectionTreeHaveFocus( eSection ) ) 573 { 574 // Give focus to this section. 575 setSectionFocus(eSection, getPad()); 576 } 577 578 // Set the highlight marker. 579 setSectionSelectedSlot(eSection, iNewSlotX, iNewSlotY ); 580 581 bPointerIsOverSlot = true; 582 583#ifdef TAP_DETECTION 584 // Have we actually changed slot? If so, input cannot be a tap. 585 if ( ( eSectionUnderPointer != m_eCurrSection ) || ( iNewSlotX != m_iCurrSlotX ) || ( iNewSlotY != m_iCurrSlotY ) ) 586 { 587 m_eCurrTapState = eTapNone; 588 } 589 590 // Store what is currently under the pointer. 591 m_eCurrSection = eSectionUnderPointer; 592 m_iCurrSlotX = iNewSlotX; 593 m_iCurrSlotY = iNewSlotY; 594#endif // TAP_DETECTION 595 // No need to check any further slots, the pointer can only ever be over one. 596 break; 597 } 598 } 599 } 600 } 601 } 602 603 // 4J - TomK - set to section none if this is a non-visible section 604 if(!IsVisible(eSectionUnderPointer)) eSectionUnderPointer = eSectionNone; 605 606 // If we are not over any slot, set focus elsewhere. 607 if ( eSectionUnderPointer == eSectionNone ) 608 { 609 setFocusToPointer( getPad() ); 610#ifdef TAP_DETECTION 611 // Input cannot be a tap. 612 m_eCurrTapState = eTapNone; 613 614 // Store what is currently under the pointer. 615 m_eCurrSection = eSectionNone; 616 m_iCurrSlotX = -1; 617 m_iCurrSlotY = -1; 618#endif // TAP_DETECTION 619 } 620 else 621 { 622 if ( !bStickInput ) 623 { 624 // Did we get a tap input? 625 int iDesiredSlotX = -1; 626 int iDesiredSlotY = -1; 627 628 switch( m_eCurrTapState ) 629 { 630 case eTapStateUp: 631 iDesiredSlotX = m_iCurrSlotX; 632 iDesiredSlotY = m_iCurrSlotY - 1; 633 break; 634 case eTapStateDown: 635 iDesiredSlotX = m_iCurrSlotX; 636 iDesiredSlotY = m_iCurrSlotY + 1; 637 break; 638 case eTapStateLeft: 639 iDesiredSlotX = m_iCurrSlotX - 1; 640 iDesiredSlotY = m_iCurrSlotY; 641 break; 642 case eTapStateRight: 643 iDesiredSlotX = m_iCurrSlotX + 1; 644 iDesiredSlotY = m_iCurrSlotY; 645 break; 646 case eTapStateJump: 647 iDesiredSlotX = m_iCurrSlotX; 648 iDesiredSlotY = m_iCurrSlotY; 649 break; 650 } 651 652 int iNumRows; 653 int iNumColumns; 654 int iNumItems = GetSectionDimensions( eSectionUnderPointer, &( iNumColumns ), &( iNumRows ) ); 655 656 657 if ( (m_eCurrTapState != eTapNone && m_eCurrTapState != eTapStateNoInput) && 658 ( !IsSectionSlotList(eSectionUnderPointer) || 659 ( ( iDesiredSlotX < 0 ) || ( iDesiredSlotX >= iNumColumns ) || ( iDesiredSlotY < 0 ) || ( iDesiredSlotY >= iNumRows ) ) 660 )) 661 { 662 663 eSectionUnderPointer = GetSectionAndSlotInDirection( eSectionUnderPointer, m_eCurrTapState, &iDesiredSlotX, &iDesiredSlotY ); 664 665 if(!IsSectionSlotList(eSectionUnderPointer)) bPointerIsOverSlot = false; 666 667 // Get the details for the new section 668 iNumItems = GetSectionDimensions( eSectionUnderPointer, &( iNumColumns ), &( iNumRows ) ); 669 } 670 671 if ( !IsSectionSlotList(eSectionUnderPointer) || ( ( iDesiredSlotX >= 0 ) && ( iDesiredSlotX < iNumColumns ) && ( iDesiredSlotY >= 0 ) && ( iDesiredSlotY < iNumRows ) ) ) 672 { 673 // Desired slot after tap input is valid, so make the jump to this slot. 674 UIVec2D sectionPos; 675 GetPositionOfSection( eSectionUnderPointer, &( sectionPos ) ); 676 677 iNewSlotIndex = ( iDesiredSlotY * iNumColumns ) + iDesiredSlotX; 678 679 UIVec2D itemPos; 680 UIVec2D itemSize; 681 GetItemScreenData( eSectionUnderPointer, iNewSlotIndex, &( itemPos ), &( itemSize ) ); 682 683 if(IsSectionSlotList(eSectionUnderPointer)) itemPos += sectionPos; 684 685 vSnapPos.x = itemPos.x + ( itemSize.x / 2.0f); 686 vSnapPos.y = itemPos.y + ( itemSize.y / 2.0f); 687 688 m_eCurrSection = eSectionUnderPointer; 689 m_iCurrSlotX = iDesiredSlotX; 690 m_iCurrSlotY = iDesiredSlotY; 691 } 692 693 m_eCurrTapState = eTapStateNoInput; 694 695 // If there is no stick input, and we are over a slot, then snap pointer to slot centre. 696 // 4J - TomK - only if this particular component allows so! 697 if(!m_bPointerDrivenByMouse && CanHaveFocus(eSectionUnderPointer)) 698 { 699 vPointerPos.x = vSnapPos.x; 700 vPointerPos.y = vSnapPos.y; 701 } 702 } 703 } 704 705 // Clamp to pointer extents. 706 if ( vPointerPos.x < m_fPointerMinX ) vPointerPos.x = m_fPointerMinX; 707 else if ( vPointerPos.x > m_fPointerMaxX ) vPointerPos.x = m_fPointerMaxX; 708 if ( vPointerPos.y < m_fPointerMinY ) vPointerPos.y = m_fPointerMinY; 709 else if ( vPointerPos.y > m_fPointerMaxY ) vPointerPos.y = m_fPointerMaxY; 710 711 // Check if the pointer is outside of the panel. 712 bool bPointerIsOutsidePanel = false; 713 if ( ( vPointerPos.x < m_fPanelMinX ) || ( vPointerPos.x > m_fPanelMaxX ) || ( vPointerPos.y < m_fPanelMinY ) || ( vPointerPos.y > m_fPanelMaxY ) ) 714 { 715 bPointerIsOutsidePanel = true; 716 } 717 718 // Determine appropriate context sensitive tool tips, based on what is carried on the pointer and what is under the pointer. 719 720 // What are we carrying on pointer. 721 shared_ptr<LocalPlayer> player = Minecraft::GetInstance()->localplayers[getPad()]; 722 shared_ptr<ItemInstance> carriedItem = nullptr; 723 if(player != NULL) carriedItem = player->inventory->getCarried(); 724 725 shared_ptr<ItemInstance> slotItem = nullptr; 726 Slot *slot = NULL; 727 int slotIndex = 0; 728 if(bPointerIsOverSlot) 729 { 730 slotIndex = iNewSlotIndex + getSectionStartOffset( eSectionUnderPointer ); 731 slot = m_menu->getSlot(slotIndex); 732 } 733 bool bIsItemCarried = carriedItem != NULL; 734 int iCarriedCount = 0; 735 bool bCarriedIsSameAsSlot = false; // Indicates if same item is carried on pointer as is in slot under pointer. 736 if ( bIsItemCarried ) 737 { 738 iCarriedCount = carriedItem->count; 739 } 740 741 // What is in the slot that we are over. 742 bool bSlotHasItem = false; 743 bool bMayPlace = false; 744 bool bCanPlaceOne = false; 745 bool bCanPlaceAll = false; 746 bool bCanCombine = false; 747 bool bCanDye = false; 748 int iSlotCount = 0; 749 int iSlotStackSizeRemaining = 0; // How many more items can be stacked on this slot. 750 if ( bPointerIsOverSlot ) 751 { 752 slotItem = slot->getItem(); 753 bSlotHasItem = slotItem != NULL; 754 if ( bSlotHasItem ) 755 { 756 iSlotCount = slotItem->GetCount(); 757 758 if ( bIsItemCarried ) 759 { 760 bCarriedIsSameAsSlot = IsSameItemAs(carriedItem, slotItem); 761 bCanCombine = m_menu->mayCombine(slot,carriedItem); 762 bCanDye = bCanCombine && dynamic_cast<ArmorItem *>(slot->getItem()->getItem()); 763 764 if ( bCarriedIsSameAsSlot ) 765 { 766 iSlotStackSizeRemaining = GetEmptyStackSpace( m_menu->getSlot(slotIndex) ); 767 } 768 } 769 } 770 771 if( bIsItemCarried) 772 { 773 bMayPlace = slot->mayPlace(carriedItem); 774 775 if ( bSlotHasItem ) iSlotStackSizeRemaining = GetEmptyStackSpace( slot ); 776 else iSlotStackSizeRemaining = slot->getMaxStackSize(); 777 778 if(bMayPlace && iSlotStackSizeRemaining > 0) bCanPlaceOne = true; 779 if(bMayPlace && iSlotStackSizeRemaining > 1 && carriedItem->count > 1) bCanPlaceAll = true; 780 } 781 } 782 783 if( bPointerIsOverSlot && bSlotHasItem ) 784 { 785 vector<HtmlString> *desc = GetItemDescription(slot); 786 SetPointerText(desc, slot != m_lastPointerLabelSlot); 787 m_lastPointerLabelSlot = slot; 788 delete desc; 789 } 790 else if (eSectionUnderPointer != eSectionNone && !IsSectionSlotList(eSectionUnderPointer) ) 791 { 792 vector<HtmlString> *desc = GetSectionHoverText(eSectionUnderPointer); 793 SetPointerText(desc, false); 794 m_lastPointerLabelSlot = NULL; 795 delete desc; 796 } 797 else 798 { 799 SetPointerText(NULL, false); 800 m_lastPointerLabelSlot = NULL; 801 } 802 803 EToolTipItem buttonA, buttonX, buttonY, buttonRT, buttonBack; 804 buttonA = buttonX = buttonY = buttonRT = buttonBack = eToolTipNone; 805 if ( bPointerIsOverSlot ) 806 { 807 SetPointerOutsideMenu( false ); 808 if ( bIsItemCarried ) 809 { 810 if ( bSlotHasItem ) 811 { 812 // Item in hand and item in slot ... is item in slot the same as in out hand? If so, can we stack on to it? 813 if ( bCarriedIsSameAsSlot ) 814 { 815 // Can we stack more into this slot? 816 if ( iSlotStackSizeRemaining == 0 ) 817 { 818 // Cannot stack any more. 819 buttonRT = eToolTipWhatIsThis; 820 } 821 else if ( iSlotStackSizeRemaining == 1 ) 822 { 823 // Can only put 1 more on the stack. 824 buttonA = eToolTipPlaceGeneric; 825 buttonRT = eToolTipWhatIsThis; 826 } 827 else // can put 1 or all. 828 { 829 if(bCanPlaceAll) 830 { 831 // Multiple items in hand. 832 buttonA = eToolTipPlaceAll; 833 buttonX = eToolTipPlaceOne; 834 } 835 else if(bCanPlaceOne) 836 { 837 if(iCarriedCount > 1) buttonA = eToolTipPlaceOne; 838 else buttonA = eToolTipPlaceGeneric; 839 } 840 buttonRT = eToolTipWhatIsThis; 841 } 842 } 843 else // items are different, click here will swap them. 844 { 845 846 if(bMayPlace) buttonA = eToolTipSwap; 847 buttonRT = eToolTipWhatIsThis; 848 } 849 if(bCanDye) 850 { 851 buttonX = eToolTipDye; 852 } 853 else if(bCanCombine) 854 { 855 buttonX = eToolTipRepair; 856 } 857 } 858 else // slot empty. 859 { 860 // Item in hand, slot is empty. 861 if ( iCarriedCount == 1 ) 862 { 863 // Only one item in hand. 864 buttonA = eToolTipPlaceGeneric; 865 } 866 else 867 { 868 if(bCanPlaceAll) 869 { 870 // Multiple items in hand. 871 buttonA = eToolTipPlaceAll; 872 buttonX = eToolTipPlaceOne; 873 } 874 else if(bCanPlaceOne) 875 { 876 buttonA = eToolTipPlaceOne; 877 } 878 } 879 } 880 } 881 else // no object in hand 882 { 883 if ( bSlotHasItem ) 884 { 885 if ( iSlotCount == 1 ) 886 { 887 buttonA = eToolTipPickUpGeneric; 888 } 889 else 890 { 891 // Multiple items in slot. 892 buttonA = eToolTipPickUpAll; 893 buttonX = eToolTipPickUpHalf; 894 } 895 896#ifdef __PSVITA__ 897 if (!InputManager.IsVitaTV()) 898 { 899 buttonBack = eToolTipWhatIsThis; 900 } 901 else 902#endif 903 { 904 buttonRT = eToolTipWhatIsThis; 905 } 906 } 907 else 908 { 909 // Nothing in slot and nothing in hand. 910 } 911 } 912 913 if ( bSlotHasItem ) 914 { 915 // Item in slot 916 917 // 4J-PB - show tooltips for quick use of armour 918 919 if((eSectionUnderPointer==eSectionInventoryUsing)||(eSectionUnderPointer==eSectionInventoryInventory)) 920 { 921 shared_ptr<ItemInstance> item = getSlotItem(eSectionUnderPointer, iNewSlotIndex); 922 ArmorRecipes::_eArmorType eArmourType=ArmorRecipes::GetArmorType(item->id); 923 924 if(eArmourType==ArmorRecipes::eArmorType_None) 925 { 926 buttonY = eToolTipQuickMove; 927 } 928 else 929 { 930 // check that the slot required is empty 931 switch(eArmourType) 932 { 933 case ArmorRecipes::eArmorType_Helmet: 934 if(isSlotEmpty(eSectionInventoryArmor,0)) 935 { 936 buttonY = eToolTipEquip; 937 } 938 else 939 { 940 buttonY = eToolTipQuickMove; 941 } 942 break; 943 case ArmorRecipes::eArmorType_Chestplate: 944 if(isSlotEmpty(eSectionInventoryArmor,1)) 945 { 946 buttonY = eToolTipEquip; 947 } 948 else 949 { 950 buttonY = eToolTipQuickMove; 951 } 952 break; 953 case ArmorRecipes::eArmorType_Leggings: 954 if(isSlotEmpty(eSectionInventoryArmor,2)) 955 { 956 buttonY = eToolTipEquip; 957 } 958 else 959 { 960 buttonY = eToolTipQuickMove; 961 } 962 break; 963 case ArmorRecipes::eArmorType_Boots: 964 if(isSlotEmpty(eSectionInventoryArmor,3)) 965 { 966 buttonY = eToolTipEquip; 967 } 968 else 969 { 970 buttonY = eToolTipQuickMove; 971 } 972 break; 973 default: 974 buttonY = eToolTipQuickMove; 975 break; 976 } 977 978 } 979 } 980 // 4J-PB - show tooltips for quick use of fuel or ingredient 981 else if((eSectionUnderPointer==eSectionFurnaceUsing)||(eSectionUnderPointer==eSectionFurnaceInventory)) 982 { 983 // Get the info on this item. 984 shared_ptr<ItemInstance> item = getSlotItem(eSectionUnderPointer, iNewSlotIndex); 985 bool bValidFuel = FurnaceTileEntity::isFuel(item); 986 bool bValidIngredient = FurnaceRecipes::getInstance()->getResult(item->getItem()->id) != NULL; 987 988 if(bValidIngredient) 989 { 990 // is there already something in the ingredient slot? 991 if(!isSlotEmpty(eSectionFurnaceIngredient,0)) 992 { 993 // is it the same as this item 994 shared_ptr<ItemInstance> IngredientItem = getSlotItem(eSectionFurnaceIngredient,0); 995 if(IngredientItem->id == item->id) 996 { 997 buttonY = eToolTipQuickMoveIngredient; 998 } 999 else 1000 { 1001 if(FurnaceRecipes::getInstance()->getResult(item->id)==NULL) 1002 { 1003 buttonY = eToolTipQuickMove; 1004 } 1005 else 1006 { 1007 buttonY = eToolTipQuickMoveIngredient; 1008 } 1009 } 1010 } 1011 else 1012 { 1013 // ingredient slot empty 1014 buttonY = eToolTipQuickMoveIngredient; 1015 } 1016 } 1017 else if(bValidFuel) 1018 { 1019 // Is there already something in the fuel slot? 1020 if(!isSlotEmpty(eSectionFurnaceFuel,0)) 1021 { 1022 // is it the same as this item 1023 shared_ptr<ItemInstance> fuelItem = getSlotItem(eSectionFurnaceFuel,0); 1024 if(fuelItem->id == item->id) 1025 { 1026 buttonY = eToolTipQuickMoveFuel; 1027 } 1028 else if(bValidIngredient) 1029 { 1030 // check if the ingredient slot is empty, or the same as this 1031 if(!isSlotEmpty(eSectionFurnaceIngredient,0)) 1032 { 1033 // is it the same as this item 1034 shared_ptr<ItemInstance> IngredientItem = getSlotItem(eSectionFurnaceIngredient,0); 1035 if(IngredientItem->id == item->id) 1036 { 1037 buttonY = eToolTipQuickMoveIngredient; 1038 } 1039 else 1040 { 1041 if(FurnaceRecipes::getInstance()->getResult(item->id)==NULL) 1042 { 1043 buttonY = eToolTipQuickMove; 1044 } 1045 else 1046 { 1047 buttonY = eToolTipQuickMoveIngredient; 1048 } 1049 } 1050 } 1051 else 1052 { 1053 // ingredient slot empty 1054 buttonY = eToolTipQuickMoveIngredient; 1055 } 1056 } 1057 else 1058 { 1059 buttonY = eToolTipQuickMove; 1060 } 1061 } 1062 else 1063 { 1064 buttonY = eToolTipQuickMoveFuel; 1065 } 1066 } 1067 else 1068 { 1069 buttonY = eToolTipQuickMove; 1070 } 1071 } 1072 // 4J-PB - show tooltips for quick use of ingredients in brewing 1073 else if((eSectionUnderPointer==eSectionBrewingUsing)||(eSectionUnderPointer==eSectionBrewingInventory)) 1074 { 1075 // Get the info on this item. 1076 shared_ptr<ItemInstance> item = getSlotItem(eSectionUnderPointer, iNewSlotIndex); 1077 int iId=item->id; 1078 1079 // valid ingredient? 1080 bool bValidIngredient=false; 1081 //bool bValidIngredientBottom=false; 1082 1083 if(Item::items[iId]->hasPotionBrewingFormula() || (iId == Item::netherwart_seeds_Id)) 1084 { 1085 bValidIngredient=true; 1086 } 1087 1088 if(bValidIngredient) 1089 { 1090 // is there already something in the ingredient slot? 1091 if(!isSlotEmpty(eSectionBrewingIngredient,0)) 1092 { 1093 // is it the same as this item 1094 shared_ptr<ItemInstance> IngredientItem = getSlotItem(eSectionBrewingIngredient,0); 1095 if(IngredientItem->id == item->id) 1096 { 1097 buttonY = eToolTipQuickMoveIngredient; 1098 } 1099 else 1100 { 1101 buttonY=eToolTipQuickMove; 1102 } 1103 } 1104 else 1105 { 1106 // ingredient slot empty 1107 buttonY = eToolTipQuickMoveIngredient; 1108 } 1109 } 1110 else 1111 { 1112 // valid potion? Glass bottle with water in it is a 'potion' too. 1113 if(iId==Item::potion_Id) 1114 { 1115 // space available? 1116 if(isSlotEmpty(eSectionBrewingBottle1,0) || 1117 isSlotEmpty(eSectionBrewingBottle2,0) || 1118 isSlotEmpty(eSectionBrewingBottle3,0)) 1119 { 1120 buttonY = eToolTipQuickMoveIngredient; 1121 } 1122 else 1123 { 1124 buttonY=eToolTipNone; 1125 } 1126 } 1127 else 1128 { 1129 buttonY=eToolTipQuickMove; 1130 } 1131 } 1132 } 1133 else if((eSectionUnderPointer==eSectionEnchantUsing)||(eSectionUnderPointer==eSectionEnchantInventory)) 1134 { 1135 // Get the info on this item. 1136 shared_ptr<ItemInstance> item = getSlotItem(eSectionUnderPointer, iNewSlotIndex); 1137 int iId=item->id; 1138 1139 // valid enchantable tool? 1140 if(Item::items[iId]->isEnchantable(item)) 1141 { 1142 // is there already something in the ingredient slot? 1143 if(isSlotEmpty(eSectionEnchantSlot,0)) 1144 { 1145 // tool slot empty 1146 switch(iId) 1147 { 1148 case Item::bow_Id: 1149 case Item::sword_wood_Id: 1150 case Item::sword_stone_Id: 1151 case Item::sword_iron_Id: 1152 case Item::sword_diamond_Id: 1153 buttonY=eToolTipQuickMoveWeapon; 1154 break; 1155 1156 case Item::helmet_leather_Id: 1157 case Item::chestplate_leather_Id: 1158 case Item::leggings_leather_Id: 1159 case Item::boots_leather_Id: 1160 1161 case Item::helmet_chain_Id: 1162 case Item::chestplate_chain_Id: 1163 case Item::leggings_chain_Id: 1164 case Item::boots_chain_Id: 1165 1166 case Item::helmet_iron_Id: 1167 case Item::chestplate_iron_Id: 1168 case Item::leggings_iron_Id: 1169 case Item::boots_iron_Id: 1170 1171 case Item::helmet_diamond_Id: 1172 case Item::chestplate_diamond_Id: 1173 case Item::leggings_diamond_Id: 1174 case Item::boots_diamond_Id: 1175 1176 case Item::helmet_gold_Id: 1177 case Item::chestplate_gold_Id: 1178 case Item::leggings_gold_Id: 1179 case Item::boots_gold_Id: 1180 buttonY=eToolTipQuickMoveArmor; 1181 1182 break; 1183 case Item::book_Id: 1184 buttonY = eToolTipQuickMove; 1185 break; 1186 default: 1187 buttonY=eToolTipQuickMoveTool; 1188 break; 1189 } 1190 } 1191 else 1192 { 1193 buttonY = eToolTipQuickMove; 1194 } 1195 } 1196 else 1197 { 1198 buttonY=eToolTipQuickMove; 1199 } 1200 } 1201 else 1202 { 1203 buttonY = eToolTipQuickMove; 1204 } 1205 } 1206 } 1207 1208 if ( bPointerIsOutsidePanel ) 1209 { 1210 SetPointerOutsideMenu( true ); 1211 // Outside window, we dropping items. 1212 if ( bIsItemCarried ) 1213 { 1214 //int iCount = m_pointerControl->GetObjectCount( m_pointerControl->m_hObj ); 1215 if ( iCarriedCount > 1 ) 1216 { 1217 buttonA = eToolTipDropAll; 1218 buttonX = eToolTipDropOne; 1219 } 1220 else 1221 { 1222 buttonA = eToolTipDropGeneric; 1223 } 1224 } 1225 } 1226 else // pointer is just over dead space ... can't really do anything. 1227 { 1228 SetPointerOutsideMenu( false ); 1229 } 1230 1231 shared_ptr<ItemInstance> item = nullptr; 1232 if(bPointerIsOverSlot && bSlotHasItem) item = getSlotItem(eSectionUnderPointer, iNewSlotIndex); 1233 overrideTooltips(eSectionUnderPointer, item, bIsItemCarried, bSlotHasItem, bCarriedIsSameAsSlot, iSlotStackSizeRemaining, buttonA, buttonX, buttonY, buttonRT, buttonBack); 1234 1235 SetToolTip( eToolTipButtonA, buttonA ); 1236 SetToolTip( eToolTipButtonX, buttonX ); 1237 SetToolTip( eToolTipButtonY, buttonY ); 1238 SetToolTip( eToolTipButtonRT, buttonRT ); 1239 SetToolTip( eToolTipButtonBack, buttonBack ); 1240 1241 // Offset back to image top left. 1242 vPointerPos.x -= m_fPointerImageOffsetX; 1243 vPointerPos.y -= m_fPointerImageOffsetY; 1244 1245 // Update pointer position. 1246 // 4J-PB - do not allow sub pixel positions or we get broken lines in box edges 1247 1248 // problem here when sensitivity is low - we'll be moving a sub pixel size, so it'll clamp, and we'll never move. In that case, move 1 pixel 1249 if(fInputDirX!=0.0f) 1250 { 1251 if(fInputDirX==1.0f) 1252 { 1253 vPointerPos.x+=0.999999f; 1254 } 1255 else 1256 { 1257 vPointerPos.x-=0.999999f; 1258 } 1259 } 1260 1261 if(fInputDirY!=0.0f) 1262 { 1263 if(fInputDirY==1.0f) 1264 { 1265 vPointerPos.y+=0.999999f; 1266 } 1267 else 1268 { 1269 vPointerPos.y-=0.999999f; 1270 } 1271 } 1272 1273 vPointerPos.x = floor(vPointerPos.x); 1274 vPointerPos.x += ( (int)vPointerPos.x%2); 1275 vPointerPos.y = floor(vPointerPos.y); 1276 vPointerPos.y += ( (int)vPointerPos.y%2); 1277 m_pointerPos = vPointerPos; 1278 1279 adjustPointerForSafeZone(); 1280} 1281 1282bool IUIScene_AbstractContainerMenu::handleKeyDown(int iPad, int iAction, bool bRepeat) 1283{ 1284 bool bHandled = false; 1285 1286 Minecraft *pMinecraft = Minecraft::GetInstance(); 1287 if( pMinecraft->localgameModes[getPad()] != NULL ) 1288 { 1289 Tutorial *tutorial = pMinecraft->localgameModes[getPad()]->getTutorial(); 1290 if(tutorial != NULL) 1291 { 1292 tutorial->handleUIInput(iAction); 1293 if(ui.IsTutorialVisible(getPad()) && !tutorial->isInputAllowed(iAction)) 1294 { 1295 return S_OK; 1296 } 1297 } 1298 } 1299 1300#ifdef _XBOX 1301 ui.AnimateKeyPress(iPad, iAction); 1302#else 1303 ui.AnimateKeyPress(iPad, iAction, bRepeat, true, false); 1304#endif 1305 1306 int buttonNum=0; // 0 = LeftMouse, 1 = RightMouse 1307 BOOL quickKeyHeld=FALSE; // Represents shift key on PC 1308 1309 BOOL validKeyPress = FALSE; 1310 bool itemEditorKeyPress = false; 1311 1312 // Ignore input from other players 1313 //if(pMinecraft->player->GetXboxPad()!=pInputData->UserIndex) return S_OK; 1314 1315 switch(iAction) 1316 { 1317#ifdef _DEBUG_MENUS_ENABLED 1318 case ACTION_MENU_OTHER_STICK_PRESS: 1319 itemEditorKeyPress = TRUE; 1320 break; 1321#endif 1322 case ACTION_MENU_A: 1323#ifdef __ORBIS__ 1324 case ACTION_MENU_TOUCHPAD_PRESS: 1325#endif 1326 if(!bRepeat) 1327 { 1328 validKeyPress = TRUE; 1329 1330 // Standard left click 1331 buttonNum = 0; 1332 quickKeyHeld = FALSE; 1333 1334 if( IsSectionSlotList( m_eCurrSection ) ) 1335 { 1336 int currentIndex = getCurrentIndex( m_eCurrSection ) - getSectionStartOffset(m_eCurrSection); 1337 1338 bool bSlotHasItem = !isSlotEmpty(m_eCurrSection, currentIndex); 1339 if ( bSlotHasItem ) 1340 ui.PlayUISFX(eSFX_Press); 1341 } 1342 // 1343 } 1344 break; 1345 case ACTION_MENU_X: 1346 if(!bRepeat) 1347 { 1348 validKeyPress = TRUE; 1349 1350 // Standard right click 1351 buttonNum = 1; 1352 quickKeyHeld = FALSE; 1353 1354 if( IsSectionSlotList( m_eCurrSection ) ) 1355 { 1356 int currentIndex = getCurrentIndex( m_eCurrSection ) - getSectionStartOffset(m_eCurrSection); 1357 1358 bool bSlotHasItem = !isSlotEmpty(m_eCurrSection, currentIndex); 1359 if ( bSlotHasItem ) 1360 ui.PlayUISFX(eSFX_Press); 1361 } 1362 } 1363 break; 1364 case ACTION_MENU_Y: 1365 if(!bRepeat) 1366 { 1367 //bool bIsItemCarried = !m_pointerControl->isEmpty( m_pointerControl->m_hObj ); 1368 1369 // 4J Stu - TU8: Remove this fix, and fix the tooltip display instead as customers liked the feature 1370 1371 // Fix for #58583 - TU6: Content: UI: The Quick Move button prompt disappears even though it still works 1372 // No quick move tooltip is shown if something is carried, so disable the action as well 1373 //if(!bIsItemCarried) 1374 { 1375 validKeyPress = TRUE; 1376 1377 // Shift and left click 1378 buttonNum = 0; 1379 quickKeyHeld = TRUE; 1380 if( IsSectionSlotList( m_eCurrSection ) ) 1381 { 1382 int currentIndex = getCurrentIndex( m_eCurrSection ) - getSectionStartOffset(m_eCurrSection); 1383 1384 bool bSlotHasItem = !isSlotEmpty(m_eCurrSection, currentIndex); 1385 if ( bSlotHasItem ) 1386 ui.PlayUISFX(eSFX_Press); 1387 } 1388 } 1389 } 1390 break; 1391 // 4J Stu - Also enable start to exit the scene. This key is also not constrained by the tutorials. 1392 case ACTION_MENU_PAUSEMENU: 1393 case ACTION_MENU_B: 1394 { 1395 1396 ui.SetTooltips(iPad, -1); 1397 1398 // 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. 1399 // 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) 1400 // Therefore I have moved this call to the OnDestroy() method to make sure that it always happens. 1401 //Minecraft::GetInstance()->localplayers[pInputData->UserIndex]->closeContainer(); 1402 1403 // Return to the game. We should really callback to the app here as well 1404 // to let it know that we have closed the ui incase we need to do things when that happens 1405 1406 if(m_bNavigateBack) 1407 { 1408 ui.NavigateBack(iPad); 1409 } 1410 else 1411 { 1412 ui.CloseUIScenes(iPad); 1413 } 1414 1415 bHandled = true; 1416 return S_OK; 1417 } 1418 break; 1419 case ACTION_MENU_LEFT: 1420 { 1421 //ui.PlayUISFX(eSFX_Focus); 1422 m_eCurrTapState = eTapStateLeft; 1423 } 1424 break; 1425 case ACTION_MENU_RIGHT: 1426 { 1427 //ui.PlayUISFX(eSFX_Focus); 1428 m_eCurrTapState = eTapStateRight; 1429 } 1430 break; 1431 case ACTION_MENU_UP: 1432 { 1433 //ui.PlayUISFX(eSFX_Focus); 1434 m_eCurrTapState = eTapStateUp; 1435 } 1436 break; 1437 case ACTION_MENU_DOWN: 1438 { 1439 //ui.PlayUISFX(eSFX_Focus); 1440 m_eCurrTapState = eTapStateDown; 1441 } 1442 break; 1443 case ACTION_MENU_PAGEUP: 1444 { 1445 // 4J Stu - Do nothing except stop this being passed anywhere else 1446 bHandled = true; 1447 } 1448 break; 1449 case ACTION_MENU_PAGEDOWN: 1450 { 1451 if( IsSectionSlotList( m_eCurrSection ) ) 1452 { 1453 int currentIndex = getCurrentIndex( m_eCurrSection ) - getSectionStartOffset(m_eCurrSection); 1454 1455 bool bSlotHasItem = !isSlotEmpty(m_eCurrSection, currentIndex); 1456 if ( bSlotHasItem ) 1457 { 1458 shared_ptr<ItemInstance> item = getSlotItem(m_eCurrSection, currentIndex); 1459 if( Minecraft::GetInstance()->localgameModes[iPad] != NULL ) 1460 { 1461 Tutorial::PopupMessageDetails *message = new Tutorial::PopupMessageDetails; 1462 message->m_messageId = item->getUseDescriptionId(); 1463 1464 if(Item::items[item->id] != NULL) message->m_titleString = Item::items[item->id]->getHoverName(item); 1465 message->m_titleId = item->getDescriptionId(); 1466 1467 message->m_icon = item->id; 1468 message->m_iAuxVal = item->getAuxValue(); 1469 message->m_forceDisplay = true; 1470 1471 TutorialMode *gameMode = (TutorialMode *)Minecraft::GetInstance()->localgameModes[iPad]; 1472 gameMode->getTutorial()->setMessage(NULL, message); 1473 ui.PlayUISFX(eSFX_Press); 1474 } 1475 } 1476 } 1477 bHandled = TRUE; 1478 } 1479 break; 1480 }; 1481 1482 if( validKeyPress == TRUE ) 1483 { 1484 if(handleValidKeyPress(iPad,buttonNum,quickKeyHeld)) 1485 { 1486 // Used to allow overriding certain keypresses, so do nothing here 1487 } 1488 else 1489 { 1490 if( IsSectionSlotList( m_eCurrSection ) ) 1491 { 1492 handleSlotListClicked(m_eCurrSection,buttonNum,quickKeyHeld); 1493 } 1494 else 1495 { 1496 // TODO Clicked something else, like for example the craft result. Do something here 1497 1498 // 4J WESTY : For pointer system we can legally drop items outside of the window panel here, or may press button while 1499 // pointer is over empty panel space. 1500 if ( m_bPointerOutsideMenu ) 1501 { 1502 handleOutsideClicked(iPad, buttonNum, quickKeyHeld); 1503 } 1504 else // 1505 { 1506 // over empty space or something else??? 1507 handleOtherClicked(iPad,m_eCurrSection,buttonNum,quickKeyHeld?true:false); 1508 //assert( FALSE ); 1509 } 1510 } 1511 } 1512 bHandled = true; 1513 } 1514#ifdef _DEBUG_MENUS_ENABLED 1515 else if(itemEditorKeyPress == TRUE) 1516 { 1517 if( IsSectionSlotList( m_eCurrSection ) ) 1518 { 1519 ItemEditorInput *initData = new ItemEditorInput(); 1520 initData->iPad = getPad(); 1521 initData->slot = getSlot( m_eCurrSection, getCurrentIndex(m_eCurrSection) ); 1522 initData->menu = m_menu; 1523 1524 ui.NavigateToScene(getPad(),eUIScene_DebugItemEditor,(void *)initData); 1525 } 1526 } 1527#endif 1528 else 1529 { 1530 handleAdditionalKeyPress(iAction); 1531 } 1532 1533 UpdateTooltips(); 1534 1535 return bHandled; 1536} 1537 1538bool IUIScene_AbstractContainerMenu::handleValidKeyPress(int iUserIndex, int buttonNum, BOOL quickKeyHeld) 1539{ 1540 return false; 1541} 1542 1543void IUIScene_AbstractContainerMenu::handleOutsideClicked(int iPad, int buttonNum, BOOL quickKeyHeld) 1544{ 1545 // Drop items. 1546 1547 //pMinecraft->localgameModes[m_iPad]->handleInventoryMouseClick(menu->containerId, AbstractContainerMenu::CLICKED_OUTSIDE, buttonNum, quickKeyHeld?true:false, pMinecraft->localplayers[m_iPad] ); 1548 slotClicked(AbstractContainerMenu::SLOT_CLICKED_OUTSIDE, buttonNum, quickKeyHeld?true:false); 1549} 1550 1551void IUIScene_AbstractContainerMenu::handleOtherClicked(int iPad, ESceneSection eSection, int buttonNum, bool quickKey) 1552{ 1553 // Do nothing 1554} 1555 1556void IUIScene_AbstractContainerMenu::handleAdditionalKeyPress(int iAction) 1557{ 1558 // Do nothing 1559} 1560 1561void IUIScene_AbstractContainerMenu::handleSlotListClicked(ESceneSection eSection, int buttonNum, BOOL quickKeyHeld) 1562{ 1563 int currentIndex = getCurrentIndex(eSection); 1564 1565 //pMinecraft->localgameModes[m_iPad]->handleInventoryMouseClick(menu->containerId, currentIndex, buttonNum, quickKeyHeld?true:false, pMinecraft->localplayers[m_iPad] ); 1566 slotClicked(currentIndex, buttonNum, quickKeyHeld?true:false); 1567 1568 handleSectionClick(eSection); 1569} 1570 1571void IUIScene_AbstractContainerMenu::slotClicked(int slotId, int buttonNum, bool quickKey) 1572{ 1573 // 4J Stu - Removed this line as unused 1574 //if (slot != NULL) slotId = slot->index; 1575 1576 Minecraft *pMinecraft = Minecraft::GetInstance(); 1577 pMinecraft->localgameModes[getPad()]->handleInventoryMouseClick(m_menu->containerId, slotId, buttonNum, quickKey, pMinecraft->localplayers[getPad()] ); 1578} 1579 1580int IUIScene_AbstractContainerMenu::getCurrentIndex(ESceneSection eSection) 1581{ 1582 int rows, columns; 1583 GetSectionDimensions( eSection, &columns, &rows ); 1584 int currentIndex = (m_iCurrSlotY * columns) + m_iCurrSlotX; 1585 1586 return currentIndex + getSectionStartOffset(eSection); 1587} 1588 1589bool IUIScene_AbstractContainerMenu::IsSameItemAs(shared_ptr<ItemInstance> itemA, shared_ptr<ItemInstance> itemB) 1590{ 1591 if(itemA == NULL || itemB == NULL) return false; 1592 1593 return (itemA->id == itemB->id && (!itemB->isStackedByData() || itemB->getAuxValue() == itemA->getAuxValue()) && ItemInstance::tagMatches(itemB, itemA) ); 1594} 1595 1596int IUIScene_AbstractContainerMenu::GetEmptyStackSpace(Slot *slot) 1597{ 1598 int iResult = 0; 1599 1600 if(slot != NULL && slot->hasItem()) 1601 { 1602 shared_ptr<ItemInstance> item = slot->getItem(); 1603 if ( item->isStackable() ) 1604 { 1605 int iCount = item->GetCount(); 1606 int iMaxStackSize = min(item->getMaxStackSize(), slot->getMaxStackSize() ); 1607 1608 iResult = iMaxStackSize - iCount; 1609 1610 if(iResult < 0 ) iResult = 0; 1611 } 1612 } 1613 1614 return iResult; 1615} 1616 1617vector<HtmlString> *IUIScene_AbstractContainerMenu::GetItemDescription(Slot *slot) 1618{ 1619 if(slot == NULL) return NULL; 1620 1621 vector<HtmlString> *lines = slot->getItem()->getHoverText(nullptr, false); 1622 1623 // Add rarity to first line 1624 if (lines->size() > 0) 1625 { 1626 lines->at(0).color = slot->getItem()->getRarity()->color; 1627 1628 if(slot->getItem()->hasCustomHoverName()) 1629 { 1630 lines->at(0).color = eTextColor_RenamedItemTitle; 1631 } 1632 } 1633 1634 return lines; 1635} 1636 1637vector<HtmlString> *IUIScene_AbstractContainerMenu::GetSectionHoverText(ESceneSection eSection) 1638{ 1639 return NULL; 1640}