the game where you go into mines and start crafting! but for consoles (forked directly from smartcmd's github)
1#include "stdafx.h"
2#include <xuiresource.h>
3#include <xuiapp.h>
4#include <assert.h>
5
6#include "..\..\..\Minecraft.World\Player.h"
7#include "..\..\..\Minecraft.Client\LocalPlayer.h"
8#include "..\..\..\Minecraft.Client\Minecraft.h"
9#include "..\..\..\Minecraft.Client\GameMode.h"
10#include "..\..\..\Minecraft.World\AbstractContainerMenu.h"
11#include "..\..\..\Minecraft.World\net.minecraft.world.inventory.h"
12#include "..\..\..\Minecraft.World\net.minecraft.world.item.h"
13#include "..\..\..\Minecraft.World\Tile.h"
14#include "..\..\..\Minecraft.World\FurnaceRecipes.h"
15#include "..\..\..\Minecraft.World\Recipy.h"
16#include "..\..\..\Minecraft.World\Recipes.h"
17#include "..\..\..\Minecraft.World\ArmorRecipes.h"
18#include "..\..\..\Minecraft.World\StringHelpers.h"
19
20#include "..\..\Common\Tutorial\Tutorial.h"
21#include "..\..\Common\Tutorial\TutorialMode.h"
22
23#include "XUI_Ctrl_SlotList.h"
24#include "XUI_Ctrl_SlotItem.h"
25#include "XUI_Ctrl_SlotItemListItem.h"
26#include "XUI_Scene_AbstractContainer.h"
27#ifdef _DEBUG_MENUS_ENABLED
28#include "XUI_DebugItemEditor.h"
29#endif
30
31#define IGNORE_KEYPRESS_TIMERID 11
32#define IGNORE_KEYPRESS_TIME 100
33
34void CXuiSceneAbstractContainer::PlatformInitialize(int iPad, int startIndex)
35{
36 m_bIgnoreKeyPresses=true;
37 m_iPad = iPad;
38
39 XuiControlSetText(m_InventoryText,app.GetString(IDS_INVENTORY));
40
41 // Determine min and max extents for pointer, it needs to be able to move off the container to drop items.
42 float fPanelWidth, fPanelHeight;
43 float fPointerWidth, fPointerHeight;
44
45 // We may have varying depths of controls here, so base off the pointers parent
46 HXUIOBJ parent;
47 XuiElementGetBounds( m_pointerControl->m_hObj, &fPointerWidth, &fPointerHeight );
48 XuiElementGetParent( m_pointerControl->m_hObj, &parent );
49 m_pointerControl->SetShow(TRUE);
50 XuiElementGetBounds( parent, &fPanelWidth, &fPanelHeight );
51 // Get size of pointer
52 m_fPointerImageOffsetX = floor(fPointerWidth/2.0f);
53 m_fPointerImageOffsetY = floor(fPointerHeight/2.0f);
54
55 m_fPanelMinX = 0.0f;
56 m_fPanelMaxX = fPanelWidth;
57 m_fPanelMinY = 0.0f;
58 m_fPanelMaxY = fPanelHeight;
59
60 // 4J-PB - need to limit this in splitscreen
61 if(app.GetLocalPlayerCount()>1)
62 {
63 // don't let the pointer go into someone's screen
64 m_fPointerMinY = floor(fPointerHeight/2.0f);
65 }
66 else
67 {
68 m_fPointerMinY = -fPointerHeight;
69 }
70 m_fPointerMinX = -fPointerWidth;
71 m_fPointerMaxX = fPanelWidth + fPointerWidth;
72 m_fPointerMaxY = fPanelHeight + (fPointerHeight/2);
73
74// m_hPointerText=NULL;
75// m_hPointerTextBkg=NULL;
76
77 UIVec2D itemPos;
78 UIVec2D itemSize;
79 GetItemScreenData( m_eCurrSection, 0, &( itemPos ), &( itemSize ) );
80
81 UIVec2D sectionPos;
82 GetPositionOfSection( m_eCurrSection, &( sectionPos ) );
83
84 UIVec2D vPointerPos = sectionPos;
85 vPointerPos += itemPos;
86 vPointerPos.x += ( itemSize.x / 2.0f );
87 vPointerPos.y += ( itemSize.y / 2.0f );
88
89 vPointerPos.x -= m_fPointerImageOffsetX;
90 vPointerPos.y -= m_fPointerImageOffsetY;
91
92 D3DXVECTOR3 newPointerPos;
93 newPointerPos.x = vPointerPos.x;
94 newPointerPos.y = vPointerPos.y;
95 newPointerPos.z = 0.0f;
96 m_pointerControl->SetPosition( &newPointerPos );
97 m_pointerPos.x = newPointerPos.x;
98 m_pointerPos.y = newPointerPos.y;
99
100#ifdef USE_POINTER_ACCEL
101 m_fPointerVelX = 0.0f;
102 m_fPointerVelY = 0.0f;
103 m_fPointerAccelX = 0.0f;
104 m_fPointerAccelY = 0.0f;
105#endif
106
107 // Add timer to poll controller stick input at 60Hz
108 HRESULT timerResult = SetTimer( POINTER_INPUT_TIMER_ID, ( 1000 / 60 ) );
109 assert( timerResult == S_OK );
110
111 XuiSetTimer(m_hObj,IGNORE_KEYPRESS_TIMERID,IGNORE_KEYPRESS_TIME);
112
113 // Disable the default navigation behaviour for all slot lsit items (prevent old style cursor navigation).
114 for ( int iSection = m_eFirstSection; iSection < m_eMaxSection; ++iSection )
115 {
116 ESceneSection eSection = ( ESceneSection )( iSection );
117
118 if(!IsSectionSlotList(eSection)) continue;
119
120 // Get dimensions of this section.
121 int iNumRows;
122 int iNumColumns;
123 int iNumItems = GetSectionDimensions( eSection, &( iNumColumns ), &( iNumRows ) );
124
125 for ( int iItem = 0; iItem < iNumItems; ++iItem )
126 {
127 CXuiCtrlSlotItemListItem* pCXuiCtrlSlotItem;
128 GetSectionSlotList( eSection )->GetCXuiCtrlSlotItem( iItem, &( pCXuiCtrlSlotItem ) );
129 pCXuiCtrlSlotItem->SetSkipsDefaultNavigation( TRUE );
130 }
131 }
132}
133
134// 4J Stu - Added to support auto-save. Need to re-associate on a navigate back
135void CXuiSceneAbstractContainer::InitDataAssociations(int iPad, AbstractContainerMenu *menu, int startIndex /*= 0*/)
136{
137 // TODO Inventory dimensions need defined as constants
138 m_inventoryControl->SetData( iPad, menu, 3, 9, startIndex, startIndex + 3*9 );
139
140 // TODO Inventory dimensions need defined as constants
141 m_useRowControl->SetData( iPad, menu, 1, 9, startIndex + 3*9, startIndex + 4*9 );
142
143 m_pointerControl->SetUserIndex(m_pointerControl->m_hObj, iPad);
144}
145
146int CXuiSceneAbstractContainer::getSectionColumns(ESceneSection eSection)
147{
148 return GetSectionSlotList( eSection )->GetColumns();
149}
150
151int CXuiSceneAbstractContainer::getSectionRows(ESceneSection eSection)
152{
153 return GetSectionSlotList( eSection )->GetRows();
154}
155
156// Adding this so we can turn off the pointer text background, since it flickers on then off at the start of a scene where a tutorial popup is
157HRESULT CXuiSceneAbstractContainer::OnTransitionStart( XUIMessageTransition *pTransition, BOOL& bHandled )
158{
159 if(pTransition->dwTransAction==XUI_TRANSITION_ACTION_DESTROY ) return S_OK;
160
161 if(pTransition->dwTransType == XUI_TRANSITION_TO || pTransition->dwTransType == XUI_TRANSITION_BACKTO)
162 {
163 // 4J Stu - Added to support auto-save. Need to re-associate on a navigate back
164 if(pTransition->dwTransType == XUI_TRANSITION_BACKTO)
165 {
166 // Add timer to poll controller stick input at 60Hz
167 HRESULT timerResult = SetTimer( POINTER_INPUT_TIMER_ID, ( 1000 / 60 ) );
168 assert( timerResult == S_OK );
169
170 InitDataAssociations(m_iPad, m_menu);
171 }
172
173 HXUIOBJ hObj=NULL;
174 HRESULT hr=XuiControlGetVisual(m_pointerControl->m_hObj,&hObj);
175 hr=XuiElementGetChildById(hObj,L"text_measurer",&m_hPointerTextMeasurer);
176 hr=XuiElementGetChildById(hObj,L"text_name",&m_hPointerText);
177 hr=XuiElementGetChildById(hObj,L"text_panel",&m_hPointerTextBkg);
178 hr=XuiElementGetChildById(hObj,L"pointer_image",&m_hPointerImg);
179 XuiElementSetShow(m_hPointerText,FALSE);
180 XuiElementSetShow(m_hPointerTextBkg,FALSE);
181 }
182
183 return S_OK;
184}
185
186
187D3DXVECTOR3 CXuiSceneAbstractContainer::GetCursorScreenPosition()
188{
189 return app.GetElementScreenPosition(m_pointerControl->m_hObj);
190}
191
192HRESULT CXuiSceneAbstractContainer::OnKeyDown(XUIMessageInput *pInputData, BOOL& bHandled)
193{
194 if(m_bIgnoreKeyPresses) return S_OK;
195
196 bHandled = handleKeyDown(pInputData->UserIndex, mapVKToAction(pInputData->dwKeyCode), (pInputData->dwFlags & XUI_INPUT_FLAG_REPEAT) != 0);
197
198 return S_OK;
199}
200
201int CXuiSceneAbstractContainer::mapVKToAction(int vk)
202{
203 int action = MINECRAFT_ACTION_MAX;
204 switch(vk)
205 {
206 case VK_PAD_A:
207 action = ACTION_MENU_A;
208 break;
209 case VK_PAD_B:
210 case VK_PAD_START:
211 action = ACTION_MENU_B;
212 break;
213 case VK_PAD_X:
214 action = ACTION_MENU_X;
215 break;
216 case VK_PAD_Y:
217 action = ACTION_MENU_Y;
218 break;
219 case VK_PAD_DPAD_LEFT:
220 action = ACTION_MENU_LEFT;
221 break;
222 case VK_PAD_DPAD_RIGHT:
223 action = ACTION_MENU_RIGHT;
224 break;
225 case VK_PAD_DPAD_UP:
226 action = ACTION_MENU_UP;
227 break;
228 case VK_PAD_DPAD_DOWN:
229 action = ACTION_MENU_DOWN;
230 break;
231 case VK_PAD_LTRIGGER:
232 action = ACTION_MENU_PAGEUP;
233 break;
234 case VK_PAD_RTRIGGER:
235 action = ACTION_MENU_PAGEDOWN;
236 break;
237 case VK_PAD_LSHOULDER:
238 action = ACTION_MENU_LEFT_SCROLL;
239 break;
240 case VK_PAD_RSHOULDER:
241 action = ACTION_MENU_RIGHT_SCROLL;
242 break;
243 case VK_PAD_RTHUMB_UP:
244 action = ACTION_MENU_OTHER_STICK_UP;
245 break;
246 case VK_PAD_RTHUMB_DOWN:
247 action = ACTION_MENU_OTHER_STICK_DOWN;
248 break;
249 case VK_PAD_RTHUMB_RIGHT:
250 action = ACTION_MENU_OTHER_STICK_RIGHT;
251 break;
252 case VK_PAD_RTHUMB_LEFT:
253 action = ACTION_MENU_OTHER_STICK_LEFT;
254 break;
255 };
256
257 return action;
258}
259
260void CXuiSceneAbstractContainer::handleSectionClick(ESceneSection eSection)
261{
262 CXuiCtrlSlotList *slotList = GetSectionSlotList( eSection );
263 slotList->Clicked();
264}
265
266HRESULT CXuiSceneAbstractContainer::handleCustomTimer( XUIMessageTimer *pTimer, BOOL& bHandled )
267{
268 return S_OK;
269}
270
271// Returns XUI position of given scene section.
272void CXuiSceneAbstractContainer::GetPositionOfSection( ESceneSection eSection, UIVec2D* pPosition )
273{
274 D3DXVECTOR3 xuiPos;
275 GetSectionControl( eSection )->GetPosition( &xuiPos );
276 pPosition->x = xuiPos.x;
277 pPosition->y = xuiPos.y;
278}
279
280void CXuiSceneAbstractContainer::GetItemScreenData( ESceneSection eSection, int iItemIndex, UIVec2D* pPosition, UIVec2D* pSize )
281{
282 D3DXVECTOR3 xuiPos;
283 if(IsSectionSlotList(eSection))
284 {
285 // Get slot item.
286 CXuiCtrlSlotItemListItem* pCXuiCtrlSlotItem;
287 GetSectionSlotList( eSection )->GetCXuiCtrlSlotItem( iItemIndex, &( pCXuiCtrlSlotItem ) );
288
289 // Get size of slot.
290 pCXuiCtrlSlotItem->GetBounds( &( pSize->x ), &( pSize->y ) );
291
292 // Get position of slot.
293 pCXuiCtrlSlotItem->GetPosition( &xuiPos );
294 pPosition->x = xuiPos.x;
295 pPosition->y = xuiPos.y;
296 }
297 else
298 {
299 // Get size of control
300 GetSectionControl( eSection )->GetBounds( &( pSize->x ), &( pSize->y ) );
301
302 // Get position of control
303 GetSectionControl( eSection )->GetPosition( &xuiPos );
304 pPosition->x = xuiPos.x;
305 pPosition->y = xuiPos.y;
306 }
307}
308
309shared_ptr<ItemInstance> CXuiSceneAbstractContainer::getSlotItem(ESceneSection eSection, int iSlot)
310{
311 CXuiCtrlSlotItemListItem* pCXuiCtrlSlotItem;
312 GetSectionSlotList( eSection )->GetCXuiCtrlSlotItem( iSlot, &( pCXuiCtrlSlotItem ) );
313 return pCXuiCtrlSlotItem->getItemInstance( pCXuiCtrlSlotItem->m_hObj );
314}
315
316bool CXuiSceneAbstractContainer::isSlotEmpty(ESceneSection eSection, int iSlot)
317{
318 CXuiCtrlSlotItemListItem* pCXuiCtrlSlotItem;
319 GetSectionSlotList( eSection )->GetCXuiCtrlSlotItem( iSlot, &( pCXuiCtrlSlotItem ) );
320 return pCXuiCtrlSlotItem->isEmpty( pCXuiCtrlSlotItem->m_hObj );
321}
322
323HRESULT CXuiSceneAbstractContainer::OnTimer( XUIMessageTimer *pTimer, BOOL& bHandled )
324{
325 HRESULT hr = S_OK;
326
327 // Update pointer from stick input on timer.
328 if ( pTimer->nId == POINTER_INPUT_TIMER_ID )
329 {
330
331 onMouseTick();
332 D3DXVECTOR3 pointerPos;
333 pointerPos.x = m_pointerPos.x;
334 pointerPos.y = m_pointerPos.y;
335 pointerPos.z = 0.0f;
336 m_pointerControl->SetPosition( &pointerPos );
337 // This message has been dealt with, don't pass it on further.
338 bHandled = TRUE;
339 }
340 else if ( pTimer->nId == IGNORE_KEYPRESS_TIMERID)
341 {
342 KillTimer(IGNORE_KEYPRESS_TIMERID);
343 m_bIgnoreKeyPresses=false;
344 }
345 else
346 {
347 // Some scenes may have their own timers for other events, so handle them here
348 hr = handleCustomTimer( pTimer, bHandled );
349 }
350 return hr;
351}
352
353HRESULT CXuiSceneAbstractContainer::OnCustomMessage_Splitscreenplayer(bool bJoining, BOOL& bHandled)
354{
355 bHandled=true;
356 return app.AdjustSplitscreenScene_PlayerChanged(m_hObj,&m_OriginalPosition,m_iPad,bJoining);
357}
358
359bool CXuiSceneAbstractContainer::doesSectionTreeHaveFocus(ESceneSection eSection)
360{
361 return GetSectionControl( eSection )->TreeHasFocus();
362}
363
364void CXuiSceneAbstractContainer::setSectionFocus(ESceneSection eSection, int iPad)
365{
366 HRESULT focusResult = GetSectionControl( eSection )->SetFocus( iPad );
367 assert( focusResult == S_OK );
368}
369
370void CXuiSceneAbstractContainer::setSectionSelectedSlot(ESceneSection eSection, int x, int y)
371{
372 GetSectionSlotList( eSection )->SetCurrentSlot(y,x);
373}
374
375void CXuiSceneAbstractContainer::setFocusToPointer(int iPad)
376{
377 m_pointerControl->SetFocus( iPad );
378}
379
380void CXuiSceneAbstractContainer::SetPointerText(const wstring &description, vector<wstring> &unformattedStrings, bool newSlot)
381{
382 if(description.empty())
383 {
384 m_pointerControl->SetText(L"");
385 XuiElementSetShow(m_hPointerText,FALSE);
386 XuiElementSetShow(m_hPointerTextBkg,FALSE);
387 return;
388 }
389
390 bool smallPointer = m_bSplitscreen || (!RenderManager.IsHiDef() && !RenderManager.IsWidescreen());
391 wstring desc = L"<font size=\"" + _toString<int>(smallPointer ? 12 :14) + L"\">" + description + L"</font>";
392
393 XUIRect tempXuiRect, xuiRect;
394 HRESULT hr;
395 xuiRect.right = 0;
396
397 for(AUTO_VAR(it, unformattedStrings.begin()); it != unformattedStrings.end(); ++it)
398 {
399 XuiTextPresenterMeasureText(m_hPointerTextMeasurer, parseXMLSpecials((*it)).c_str(), &tempXuiRect);
400 if(tempXuiRect.right > xuiRect.right) xuiRect = tempXuiRect;
401 }
402
403 // Set size with the new width so that the HTML height check is correct
404 XuiElementSetBounds(m_hPointerTextBkg,xuiRect.right+4.0f+4.0f+4.0f,xuiRect.bottom); // edge graphics are 8 pixels, with 4 for the border, extra 4 for the background is fudge
405 XuiElementSetBounds(m_hPointerText,xuiRect.right+4.0f+4.0f,xuiRect.bottom); // edge graphics are 8 pixels, text is centred
406
407 XuiHtmlSetText(m_hPointerText, desc.c_str() );
408
409 // Check if we need to resize the box
410 XUIContentDims contentDims;
411 XuiHtmlGetContentDims(m_hPointerText,&contentDims);
412 xuiRect.bottom = contentDims.nContentHeight;
413
414 // get the size of the button, and apply the change in size due to the text to the whole button
415 float fImgWidth,fImgHeight;
416 XuiElementGetBounds(m_hPointerImg,&fImgWidth, &fImgHeight);
417 // 4J-PB - changing to calculate values
418 D3DXVECTOR3 vPosText, vPosTextBkg,vPosImg;
419
420 XuiElementGetPosition(m_hPointerImg,&vPosImg);
421 XuiElementGetPosition(m_hPointerText,&vPosText);
422 XuiElementGetPosition(m_hPointerTextBkg,&vPosTextBkg);
423
424 // Set the new height
425 XuiElementSetBounds(m_hPointerTextBkg,xuiRect.right+4.0f+4.0f+4.0f,xuiRect.bottom+4.0f+4.0f); // edge graphics are 8 pixels, with 4 for the border, extra 4 for the background is fudge
426 XuiElementSetBounds(m_hPointerText,xuiRect.right+4.0f+4.0f,xuiRect.bottom+4.0f+4.0f); // edge graphics are 8 pixels, text is centred
427
428 // position the text and panel relative to the pointer image
429 vPosTextBkg.x=vPosImg.x+fImgWidth*0.6f;
430 vPosText.x=vPosTextBkg.x + 4;
431 vPosTextBkg.y=vPosImg.y-(xuiRect.bottom+4.0f+4.0f)+fImgWidth*0.4f;
432 vPosText.y=vPosTextBkg.y + 4;
433
434 XuiElementSetPosition(m_hPointerText,&vPosText);
435 XuiElementSetPosition(m_hPointerTextBkg,&vPosTextBkg);
436
437 XuiElementSetShow(m_hPointerTextBkg,TRUE);
438 XuiElementSetShow(m_hPointerText,TRUE);
439}
440
441void CXuiSceneAbstractContainer::adjustPointerForSafeZone()
442{
443 D3DXVECTOR2 baseSceneOrigin;
444 float baseWidth, baseHeight;
445 if(CXuiSceneBase::GetBaseSceneSafeZone( m_iPad, baseSceneOrigin, baseWidth, baseHeight))
446 {
447 D3DXMATRIX pointerBackgroundMatrix;
448 XuiElementGetFullXForm( m_hPointerTextBkg, &pointerBackgroundMatrix);
449
450 float width, height;
451 XuiElementGetBounds( m_hPointerTextBkg, &width, &height );
452
453 if( ( (pointerBackgroundMatrix._41 / pointerBackgroundMatrix._11) + width) > (baseSceneOrigin.x + baseWidth) )
454 {
455 //app.DebugPrintf("Pointer is outside the safe zone for this base scene\n");
456
457 // get the size of the button, and apply the change in size due to the text to the whole button
458 float fImgWidth,fImgHeight;
459 XuiElementGetBounds(m_hPointerImg,&fImgWidth, &fImgHeight);
460 // 4J-PB - changing to calculate values
461 D3DXVECTOR3 vPosText, vPosTextBkg,vPosImg;
462
463 XuiElementGetPosition(m_hPointerImg,&vPosImg);
464 XuiElementGetPosition(m_hPointerText,&vPosText);
465 XuiElementGetPosition(m_hPointerTextBkg,&vPosTextBkg);
466
467 // position the text and panel relative to the pointer image
468 vPosTextBkg.x= (vPosImg.x+fImgWidth*0.4f) - width;
469 vPosText.x=vPosTextBkg.x + 4;
470
471 XuiElementSetPosition(m_hPointerText,&vPosText);
472 XuiElementSetPosition(m_hPointerTextBkg,&vPosTextBkg);
473 }
474 }
475}