the game where you go into mines and start crafting! but for consoles (forked directly from smartcmd's github)
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}