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 "..\..\..\Minecraft.World\Random.h"
3#include "..\..\..\Minecraft.World\StringHelpers.h"
4#include "XUI_MultiGameCreate.h"
5#include "XUI_Controls.h"
6#include "..\..\MinecraftServer.h"
7#include "..\..\Minecraft.h"
8#include "..\..\Options.h"
9#include "..\..\..\Minecraft.World\LevelSettings.h"
10#include "XUI_MultiGameLaunchMoreOptions.h"
11#include "..\..\..\Minecraft.World\BiomeSource.h"
12#include "..\..\..\Minecraft.World\IntCache.h"
13#include "..\..\..\Minecraft.World\LevelType.h"
14#include "..\..\TexturePackRepository.h"
15#include "..\..\TexturePack.h"
16#include "..\DLC\DLCLocalisationFile.h"
17#include "..\..\StringTable.h"
18#include "..\..\DLCTexturePack.h"
19
20#define GAME_CREATE_ONLINE_TIMER_ID 0
21#define GAME_CREATE_ONLINE_TIMER_TIME 100
22#define CHECKFORAVAILABLETEXTUREPACKS_TIMER_ID 1
23#define CHECKFORAVAILABLETEXTUREPACKS_TIMER_TIME 100
24
25int CScene_MultiGameCreate::m_iDifficultyTitleSettingA[4]=
26{
27 IDS_DIFFICULTY_TITLE_PEACEFUL,
28 IDS_DIFFICULTY_TITLE_EASY,
29 IDS_DIFFICULTY_TITLE_NORMAL,
30 IDS_DIFFICULTY_TITLE_HARD
31};
32
33
34//----------------------------------------------------------------------------------
35// Performs initialization tasks - retrieves controls.
36//----------------------------------------------------------------------------------
37HRESULT CScene_MultiGameCreate::OnInit( XUIMessageInit* pInitData, BOOL& bHandled )
38{
39 m_bSetup = false;
40 m_texturePackDescDisplayed = false;
41 m_iConfigA=NULL;
42
43 WCHAR TempString[256];
44 MapChildControls();
45
46 XuiControlSetText(m_EditWorldName,app.GetString(IDS_DEFAULT_WORLD_NAME));
47 XuiControlSetText(m_MoreOptions,app.GetString(IDS_MORE_OPTIONS));
48 XuiControlSetText(m_NewWorld,app.GetString(IDS_CREATE_NEW_WORLD));
49
50 XuiControlSetText(m_labelWorldName,app.GetString(IDS_WORLD_NAME));
51 XuiControlSetText(m_labelSeed,app.GetString(IDS_CREATE_NEW_WORLD_SEED));
52 XuiControlSetText(m_labelRandomSeed,app.GetString(IDS_CREATE_NEW_WORLD_RANDOM_SEED));
53 XuiControlSetText(m_pTexturePacksList->m_hObj,app.GetString(IDS_DLC_MENU_TEXTUREPACKS));
54
55 CreateWorldMenuInitData *params = (CreateWorldMenuInitData *)pInitData->pvInitData;
56
57 m_MoreOptionsParams.bGenerateOptions=TRUE;
58 m_MoreOptionsParams.bStructures=TRUE;
59 m_MoreOptionsParams.bFlatWorld=FALSE;
60 m_MoreOptionsParams.bBonusChest=FALSE;
61 m_MoreOptionsParams.bPVP = TRUE;
62 m_MoreOptionsParams.bTrust = TRUE;
63 m_MoreOptionsParams.bFireSpreads = TRUE;
64 m_MoreOptionsParams.bHostPrivileges = FALSE;
65 m_MoreOptionsParams.bTNT = TRUE;
66 m_MoreOptionsParams.iPad = params->iPad;
67 m_iPad=params->iPad;
68 delete params;
69
70 m_bMultiplayerAllowed = ProfileManager.IsSignedInLive( m_iPad ) && ProfileManager.AllowedToPlayMultiplayer(m_iPad);
71 // 4J-PB - read the settings for the online flag. We'll only save this setting if the user changed it.
72 bool bGameSetting_Online=(app.GetGameSettings(m_iPad,eGameSetting_Online)!=0);
73 m_MoreOptionsParams.bOnlineSettingChangedBySystem=false;
74
75 // Set the text for friends of friends, and default to on
76 if( m_bMultiplayerAllowed)
77 {
78 m_MoreOptionsParams.bOnlineGame = bGameSetting_Online?TRUE:FALSE;
79 if(bGameSetting_Online)
80 {
81 m_MoreOptionsParams.bInviteOnly = (app.GetGameSettings(m_iPad,eGameSetting_InviteOnly)!=0)?TRUE:FALSE;
82 m_MoreOptionsParams.bAllowFriendsOfFriends = (app.GetGameSettings(m_iPad,eGameSetting_FriendsOfFriends)!=0)?TRUE:FALSE;
83 }
84 else
85 {
86 m_MoreOptionsParams.bInviteOnly = FALSE;
87 m_MoreOptionsParams.bAllowFriendsOfFriends = FALSE;
88 }
89 }
90 else
91 {
92 m_MoreOptionsParams.bOnlineGame = FALSE;
93 m_MoreOptionsParams.bInviteOnly = FALSE;
94 m_MoreOptionsParams.bAllowFriendsOfFriends = FALSE;
95 if(bGameSetting_Online)
96 {
97 // The profile settings say Online, but either the player is offline, or they are not allowed to play online
98 m_MoreOptionsParams.bOnlineSettingChangedBySystem=true;
99 }
100 }
101
102 m_ButtonGameMode.SetText(app.GetString(IDS_GAMEMODE_SURVIVAL));
103 m_bGameModeSurvival=true;
104
105 m_CurrentDifficulty=app.GetGameSettings(m_iPad,eGameSetting_Difficulty);
106 m_SliderDifficulty.SetValue(m_CurrentDifficulty);
107 swprintf( (WCHAR *)TempString, 256, L"%ls: %ls", app.GetString( IDS_SLIDER_DIFFICULTY ),app.GetString(m_iDifficultyTitleSettingA[m_CurrentDifficulty]));
108 m_SliderDifficulty.SetText(TempString);
109
110 ui.SetTooltips( DEFAULT_XUI_MENU_USER, IDS_TOOLTIPS_SELECT,IDS_TOOLTIPS_BACK);
111
112 CXuiSceneBase::ShowLogo( DEFAULT_XUI_MENU_USER, FALSE );
113
114 // restrict the keyboard - don't want languages that are not supported, like cyrillic, etc.
115 switch(XGetLanguage())
116 {
117 case XC_LANGUAGE_ENGLISH:
118 case XC_LANGUAGE_GERMAN:
119 case XC_LANGUAGE_FRENCH:
120 case XC_LANGUAGE_SPANISH:
121 case XC_LANGUAGE_ITALIAN:
122 case XC_LANGUAGE_PORTUGUESE:
123 case XC_LANGUAGE_JAPANESE:
124 case XC_LANGUAGE_TCHINESE:
125 case XC_LANGUAGE_KOREAN:
126 m_EditWorldName.SetKeyboardType(C_4JInput::EKeyboardMode_Default);
127 m_EditWorldName.SetKeyboardType(C_4JInput::EKeyboardMode_Default);
128 break;
129 default:
130 m_EditWorldName.SetKeyboardType(C_4JInput::EKeyboardMode_Full);
131 m_EditWorldName.SetKeyboardType(C_4JInput::EKeyboardMode_Full);
132 break;
133 }
134
135 m_NewWorld.SetEnable(true);
136
137 m_EditWorldName.SetTextLimit(XCONTENT_MAX_DISPLAYNAME_LENGTH);
138
139 wstring wWorldName = m_EditWorldName.GetText();
140
141 // set the caret to the end of the default text
142 m_EditWorldName.SetCaretPosition((int)wWorldName.length());
143 // In the dashboard, there's room for about 30 W characters on two lines before they go over the top of things
144 m_EditWorldName.SetTextLimit(25);
145
146 m_EditWorldName.SetTitleAndText(IDS_NAME_WORLD,IDS_NAME_WORLD_TEXT);
147 m_EditSeed.SetTitleAndText(IDS_CREATE_NEW_WORLD,IDS_CREATE_NEW_WORLD_SEEDTEXT);
148
149 XuiSetTimer(m_hObj,GAME_CREATE_ONLINE_TIMER_ID,GAME_CREATE_ONLINE_TIMER_TIME);
150 XuiSetTimer(m_hObj,CHECKFORAVAILABLETEXTUREPACKS_TIMER_ID,CHECKFORAVAILABLETEXTUREPACKS_TIMER_TIME);
151
152 TelemetryManager->RecordMenuShown(m_iPad, eUIScene_CreateWorldMenu, 0);
153
154 // 4J-PB - Load up any texture pack data we have locally in the XZP
155 for(int i=0;i<TMS_COUNT;i++)
156 {
157 if(app.TMSFileA[i].eTMSType==eTMSFileType_TexturePack)
158 {
159 app.LoadLocalTMSFile(app.TMSFileA[i].wchFilename,app.TMSFileA[i].eEXT);
160 app.AddMemoryTPDFile(app.TMSFileA[i].iConfig, app.TMSFileA[i].pbData,app.TMSFileA[i].uiSize);
161 }
162 }
163
164 m_iTexturePacksNotInstalled=0;
165
166 // block input if we're waiting for DLC to install, and wipe the saves list. The end of dlc mounting custom message will fill the list again
167 if(app.StartInstallDLCProcess(m_iPad)==true)
168 {
169 // not doing a mount, so enable input
170 m_bIgnoreInput=true;
171 }
172 else
173 {
174 m_bIgnoreInput = false;
175
176 m_pTexturePacksList->SetSelectionChangedHandle(m_hObj);
177
178 Minecraft *pMinecraft = Minecraft::GetInstance();
179 int texturePacksCount = pMinecraft->skins->getTexturePackCount();
180 CXuiCtrl4JList::LIST_ITEM_INFO ListInfo;
181 HRESULT hr;
182 for(unsigned int i = 0; i < texturePacksCount; ++i)
183 {
184 TexturePack *tp = pMinecraft->skins->getTexturePackByIndex(i);
185 ZeroMemory(&ListInfo,sizeof(CXuiCtrl4JList::LIST_ITEM_INFO));
186
187 DWORD dwImageBytes;
188 PBYTE pbImageData = tp->getPackIcon(dwImageBytes);
189
190 if(dwImageBytes > 0 && pbImageData)
191 {
192 ListInfo.fEnabled = TRUE;
193 DLCTexturePack *pDLCTexPack=(DLCTexturePack *)tp;
194 if(pDLCTexPack)
195 {
196 int id=pDLCTexPack->getDLCParentPackId();
197
198 if(id==0)
199 {
200 // default texture pack - should come first
201 ListInfo.iSortIndex=0x0FFFFFFF;
202 }
203 else
204 {
205 ListInfo.iSortIndex=id;
206 ListInfo.iData=id;
207 }
208 }
209
210#ifdef _DEBUG
211 app.DebugPrintf("TP - ");
212 OutputDebugStringW(tp->getName().c_str());
213 app.DebugPrintf(", sort index - %d\n",ListInfo.iSortIndex);
214#endif
215
216 hr=XuiCreateTextureBrushFromMemory(pbImageData,dwImageBytes,&ListInfo.hXuiBrush);
217
218 m_pTexturePacksList->AddData(ListInfo,0,CXuiCtrl4JList::eSortList_Index);
219 }
220 }
221
222
223 // 4J-PB - there may be texture packs we don't have, so use the info from TMS for this
224
225 DLC_INFO *pDLCInfo=NULL;
226
227 // first pass - look to see if there are any that are not in the list
228 bool bTexturePackAlreadyListed;
229 bool bNeedToGetTPD=false;
230
231 for(unsigned int i = 0; i < app.GetDLCInfoTexturesOffersCount(); ++i)
232 {
233 bTexturePackAlreadyListed=false;
234 ULONGLONG ull=app.GetDLCInfoTexturesFullOffer(i);
235 pDLCInfo=app.GetDLCInfoForFullOfferID(ull);
236 for(unsigned int i = 0; i < texturePacksCount; ++i)
237 {
238 TexturePack *tp = pMinecraft->skins->getTexturePackByIndex(i);
239 if(pDLCInfo->iConfig==tp->getDLCParentPackId())
240 {
241 bTexturePackAlreadyListed=true;
242 }
243 }
244 if(bTexturePackAlreadyListed==false)
245 {
246 // some missing
247 bNeedToGetTPD=true;
248
249 m_iTexturePacksNotInstalled++;
250 }
251 }
252
253 if(bNeedToGetTPD==true)
254 {
255 // add a TMS request for them
256 app.DebugPrintf("+++ Adding TMSPP request for texture pack data\n");
257 app.AddTMSPPFileTypeRequest(e_DLC_TexturePackData);
258 m_iConfigA= new int [m_iTexturePacksNotInstalled];
259 m_iTexturePacksNotInstalled=0;
260
261 for(unsigned int i = 0; i < app.GetDLCInfoTexturesOffersCount(); ++i)
262 {
263 bTexturePackAlreadyListed=false;
264 ULONGLONG ull=app.GetDLCInfoTexturesFullOffer(i);
265 pDLCInfo=app.GetDLCInfoForFullOfferID(ull);
266 for(unsigned int i = 0; i < texturePacksCount; ++i)
267 {
268 TexturePack *tp = pMinecraft->skins->getTexturePackByIndex(i);
269 if(pDLCInfo->iConfig==tp->getDLCParentPackId())
270 {
271 bTexturePackAlreadyListed=true;
272 }
273 }
274 if(bTexturePackAlreadyListed==false)
275 {
276 m_iConfigA[m_iTexturePacksNotInstalled++]=pDLCInfo->iConfig;
277 }
278 }
279 }
280
281 m_currentTexturePackIndex = pMinecraft->skins->getTexturePackIndex(0);
282 UpdateTexturePackDescription(m_currentTexturePackIndex);
283
284 m_bSetup = true;
285 }
286 return S_OK;
287}
288
289
290HRESULT CScene_MultiGameCreate::OnDestroy()
291{
292 // clear out the texture pack data
293 for(int i=0;i<TMS_COUNT;i++)
294 {
295 if(app.TMSFileA[i].eTMSType==eTMSFileType_TexturePack)
296 {
297 app.RemoveMemoryTPDFile(app.TMSFileA[i].iConfig);
298 }
299 }
300
301 app.FreeLocalTMSFiles(eTMSFileType_TexturePack);
302
303 return S_OK;
304}
305
306//----------------------------------------------------------------------------------
307// Handler for the button press message.
308//----------------------------------------------------------------------------------
309HRESULT CScene_MultiGameCreate::OnNotifyPressEx(HXUIOBJ hObjPressed, XUINotifyPress* pNotifyPressData, BOOL& rfHandled)
310{
311 if(m_bIgnoreInput) return S_OK;
312 Minecraft *pMinecraft=Minecraft::GetInstance();
313
314 // This assumes all buttons can only be pressed with the A button
315 ui.AnimateKeyPress(pNotifyPressData->UserIndex, VK_PAD_A);
316
317 if(hObjPressed==m_NewWorld)
318 {
319 // Check if we need to upsell the texture pack
320 if(m_MoreOptionsParams.dwTexturePack!=0)
321 {
322 // texture pack hasn't been set yet, so check what it will be
323 TexturePack *pTexturePack = pMinecraft->skins->getTexturePackById(m_MoreOptionsParams.dwTexturePack);
324
325 if(pTexturePack==NULL)
326 {
327 // They've selected a texture pack they don't have yet
328 // upsell
329 CXuiCtrl4JList::LIST_ITEM_INFO ListItem;
330 // get the current index of the list, and then get the data
331 ListItem=m_pTexturePacksList->GetData(m_currentTexturePackIndex);
332
333
334 // upsell the texture pack
335 // tell sentient about the upsell of the full version of the skin pack
336 ULONGLONG ullOfferID_Full;
337 app.GetDLCFullOfferIDForPackID(ListItem.iData,&ullOfferID_Full);
338
339 // DLC might have been corrupt
340 if(ullOfferID_Full!=0LL)
341 {
342 TelemetryManager->RecordUpsellPresented(ProfileManager.GetPrimaryPad(), eSet_UpsellID_Texture_DLC, ullOfferID_Full & 0xFFFFFFFF);
343
344 UINT uiIDA[3];
345
346 // Need to check if the texture pack has both Full and Trial versions - we may do some as free ones, so only Full
347 DLC_INFO *pDLCInfo=app.GetDLCInfoForFullOfferID(ullOfferID_Full);
348
349 if(pDLCInfo->ullOfferID_Trial!=0LL)
350 {
351 uiIDA[0]=IDS_TEXTUREPACK_FULLVERSION;
352 uiIDA[1]=IDS_TEXTURE_PACK_TRIALVERSION;
353 uiIDA[2]=IDS_CONFIRM_CANCEL;
354 // Give the player a warning about the texture pack missing
355 StorageManager.RequestMessageBox(IDS_DLC_TEXTUREPACK_NOT_PRESENT_TITLE, IDS_DLC_TEXTUREPACK_NOT_PRESENT, uiIDA, 3, ProfileManager.GetPrimaryPad(),&CScene_MultiGameCreate::TexturePackDialogReturned,this,app.GetStringTable());
356 }
357 else
358 {
359 uiIDA[0]=IDS_TEXTUREPACK_FULLVERSION;
360 uiIDA[1]=IDS_CONFIRM_CANCEL;
361 // Give the player a warning about the texture pack missing
362 StorageManager.RequestMessageBox(IDS_DLC_TEXTUREPACK_NOT_PRESENT_TITLE, IDS_DLC_TEXTUREPACK_NOT_PRESENT, uiIDA, 2, ProfileManager.GetPrimaryPad(),&CScene_MultiGameCreate::TexturePackDialogReturned,this,app.GetStringTable());
363 }
364
365 return S_OK;
366 }
367 }
368 }
369
370 m_bIgnoreInput = true;
371 SetShow( FALSE );
372 bool isClientSide = ProfileManager.IsSignedInLive(ProfileManager.GetPrimaryPad()) && m_MoreOptionsParams.bOnlineGame;
373
374 // if the profile data has been changed, then force a profile write (we save the online/invite/friends of friends settings)
375 // It seems we're allowed to break the 5 minute rule if it's the result of a user action
376 // check the checkboxes
377
378 // Only save the online setting if the user changed it - we may change it because we're offline, but don't want that saved
379 if(!m_MoreOptionsParams.bOnlineSettingChangedBySystem)
380 {
381 app.SetGameSettings(m_iPad,eGameSetting_Online,m_MoreOptionsParams.bOnlineGame?1:0);
382 }
383 app.SetGameSettings(m_iPad,eGameSetting_InviteOnly,m_MoreOptionsParams.bInviteOnly?1:0);
384 app.SetGameSettings(m_iPad,eGameSetting_FriendsOfFriends,m_MoreOptionsParams.bAllowFriendsOfFriends?1:0);
385
386 app.CheckGameSettingsChanged(true,pNotifyPressData->UserIndex);
387
388 // Check that we have the rights to use a texture pack we have selected.
389 if(m_MoreOptionsParams.dwTexturePack!=0)
390 {
391 // texture pack hasn't been set yet, so check what it will be
392 TexturePack *pTexturePack = pMinecraft->skins->getTexturePackById(m_MoreOptionsParams.dwTexturePack);
393
394 if(pTexturePack==NULL)
395 {
396 // corrupt DLC so set it to the default textures
397 m_MoreOptionsParams.dwTexturePack=0;
398 }
399 else
400 {
401 m_pDLCPack=pTexturePack->getDLCPack();
402 // do we have a license?
403 if(m_pDLCPack && !m_pDLCPack->hasPurchasedFile( DLCManager::e_DLCType_Texture, L"" ))
404 {
405 // no
406 UINT uiIDA[1];
407 uiIDA[0]=IDS_OK;
408
409 if(!ProfileManager.IsSignedInLive(pNotifyPressData->UserIndex))
410 {
411 // need to be signed in to live
412 StorageManager.RequestMessageBox(IDS_PRO_NOTONLINE_TITLE, IDS_PRO_XBOXLIVE_NOTIFICATION, uiIDA, 1);
413 return S_OK;
414 }
415 else
416 {
417 // upsell
418
419 DLC_INFO *pDLCInfo = app.GetDLCInfoForTrialOfferID(m_pDLCPack->getPurchaseOfferId());
420 ULONGLONG ullOfferID_Full;
421
422 if(pDLCInfo!=NULL)
423 {
424 ullOfferID_Full=pDLCInfo->ullOfferID_Full;
425 }
426 else
427 {
428 ullOfferID_Full=pTexturePack->getDLCPack()->getPurchaseOfferId();
429 }
430
431 // tell sentient about the upsell of the full version of the skin pack
432 TelemetryManager->RecordUpsellPresented(pNotifyPressData->UserIndex, eSet_UpsellID_Texture_DLC, ullOfferID_Full & 0xFFFFFFFF);
433
434 UINT uiIDA[1];
435 uiIDA[0]=IDS_CONFIRM_OK;
436
437 // Give the player a warning about the trial version of the texture pack
438 StorageManager.RequestMessageBox(IDS_WARNING_DLC_TRIALTEXTUREPACK_TITLE, IDS_WARNING_DLC_TRIALTEXTUREPACK_TEXT, uiIDA, 1, pNotifyPressData->UserIndex,&CScene_MultiGameCreate::WarningTrialTexturePackReturned,this,app.GetStringTable());
439 return S_OK;
440 }
441 }
442 }
443 }
444
445 if(m_bGameModeSurvival != true || m_MoreOptionsParams.bHostPrivileges == TRUE)
446 {
447 UINT uiIDA[2];
448 uiIDA[0]=IDS_CONFIRM_OK;
449 uiIDA[1]=IDS_CONFIRM_CANCEL;
450 if(m_bGameModeSurvival != true)
451 {
452 StorageManager.RequestMessageBox(IDS_TITLE_START_GAME, IDS_CONFIRM_START_CREATIVE, uiIDA, 2, m_iPad,&CScene_MultiGameCreate::ConfirmCreateReturned,this,app.GetStringTable());
453 }
454 else
455 {
456 StorageManager.RequestMessageBox(IDS_TITLE_START_GAME, IDS_CONFIRM_START_HOST_PRIVILEGES, uiIDA, 2, m_iPad,&CScene_MultiGameCreate::ConfirmCreateReturned,this,app.GetStringTable());
457 }
458 }
459 else
460 {
461 // 4J Stu - If we only have one controller connected, then don't show the sign-in UI again
462 DWORD connectedControllers = 0;
463 for(unsigned int i = 0; i < XUSER_MAX_COUNT; ++i)
464 {
465 if( InputManager.IsPadConnected(i) || ProfileManager.IsSignedIn(i) ) ++connectedControllers;
466 }
467
468 if(isClientSide && connectedControllers > 1 && RenderManager.IsHiDef())
469 {
470 ProfileManager.RequestSignInUI(false, false, false, true, false,&CScene_MultiGameCreate::StartGame_SignInReturned, this,ProfileManager.GetPrimaryPad());
471 }
472 else
473 {
474 // Check if user-created content is allowed, as we cannot play multiplayer if it's not
475 //bool isClientSide = ProfileManager.IsSignedInLive(ProfileManager.GetPrimaryPad()) && m_MoreOptionsParams.bOnlineGame;
476 bool noUGC = false;
477 BOOL pccAllowed = TRUE;
478 BOOL pccFriendsAllowed = TRUE;
479 ProfileManager.AllowedPlayerCreatedContent(ProfileManager.GetPrimaryPad(),false,&pccAllowed,&pccFriendsAllowed);
480 if(!pccAllowed && !pccFriendsAllowed) noUGC = true;
481
482 if(isClientSide && noUGC )
483 {
484 m_bIgnoreInput = false;
485 SetShow( TRUE );
486 UINT uiIDA[1];
487 uiIDA[0]=IDS_CONFIRM_OK;
488 StorageManager.RequestMessageBox( IDS_FAILED_TO_CREATE_GAME_TITLE, IDS_NO_USER_CREATED_CONTENT_PRIVILEGE_CREATE, uiIDA,1,ProfileManager.GetPrimaryPad(),NULL,NULL, app.GetStringTable());
489 }
490 else
491 {
492 CreateGame(this, 0);
493 }
494 }
495 }
496 }
497 else if(hObjPressed==m_MoreOptions)
498 {
499 app.NavigateToScene(pNotifyPressData->UserIndex,eUIScene_LaunchMoreOptionsMenu,&m_MoreOptionsParams);
500 }
501 else if(hObjPressed == m_ButtonGameMode)
502 {
503 if(m_bGameModeSurvival)
504 {
505 m_ButtonGameMode.SetText(app.GetString(IDS_GAMEMODE_CREATIVE));
506 m_bGameModeSurvival=false;
507 }
508 else
509 {
510 m_ButtonGameMode.SetText(app.GetString(IDS_GAMEMODE_SURVIVAL));
511 m_bGameModeSurvival=true;
512 }
513 }
514 else if(hObjPressed == m_pTexturePacksList->m_hObj)
515 {
516 UpdateCurrentTexturePack();
517 }
518
519 return S_OK;
520}
521
522
523int CScene_MultiGameCreate::UnlockTexturePackReturned(void *pParam,int iPad,C4JStorage::EMessageResult result)
524{
525 CScene_MultiGameCreate* pScene = (CScene_MultiGameCreate*)pParam;
526#ifdef _XBOX
527 if(result==C4JStorage::EMessage_ResultAccept)
528 {
529 if(ProfileManager.IsSignedIn(iPad))
530 {
531 ULONGLONG ullIndexA[1];
532 DLC_INFO *pDLCInfo = app.GetDLCInfoForTrialOfferID(pScene->m_pDLCPack->getPurchaseOfferId());
533
534 if(pDLCInfo!=NULL)
535 {
536 ullIndexA[0]=pDLCInfo->ullOfferID_Full;
537 }
538 else
539 {
540 ullIndexA[0]=pScene->m_pDLCPack->getPurchaseOfferId();
541 }
542
543 StorageManager.InstallOffer(1,ullIndexA,NULL,NULL);
544
545 // the license change coming in when the offer has been installed will cause this scene to refresh
546 }
547 }
548 else
549 {
550 TelemetryManager->RecordUpsellResponded(iPad, eSet_UpsellID_Texture_DLC, ( pScene->m_pDLCPack->getPurchaseOfferId() & 0xFFFFFFFF ), eSen_UpsellOutcome_Declined);
551 }
552#endif
553 pScene->m_bIgnoreInput = false;
554 pScene->SetShow( TRUE );
555
556 return 0;
557}
558
559int CScene_MultiGameCreate::WarningTrialTexturePackReturned(void *pParam,int iPad,C4JStorage::EMessageResult result)
560{
561 CScene_MultiGameCreate* pScene = (CScene_MultiGameCreate*)pParam;
562 pScene->m_bIgnoreInput = false;
563 pScene->SetShow( TRUE );
564 bool isClientSide = ProfileManager.IsSignedInLive(ProfileManager.GetPrimaryPad()) && pScene->m_MoreOptionsParams.bOnlineGame;
565
566
567 // 4J Stu - If we only have one controller connected, then don't show the sign-in UI again
568 DWORD connectedControllers = 0;
569 for(unsigned int i = 0; i < XUSER_MAX_COUNT; ++i)
570 {
571 if( InputManager.IsPadConnected(i) || ProfileManager.IsSignedIn(i) ) ++connectedControllers;
572 }
573
574 if(isClientSide && connectedControllers > 1 && RenderManager.IsHiDef())
575 {
576 ProfileManager.RequestSignInUI(false, false, false, true, false,&CScene_MultiGameCreate::StartGame_SignInReturned, pScene,ProfileManager.GetPrimaryPad());
577 }
578 else
579 {
580 // Check if user-created content is allowed, as we cannot play multiplayer if it's not
581 bool noUGC = false;
582 BOOL pccAllowed = TRUE;
583 BOOL pccFriendsAllowed = TRUE;
584 ProfileManager.AllowedPlayerCreatedContent(ProfileManager.GetPrimaryPad(),false,&pccAllowed,&pccFriendsAllowed);
585 if(!pccAllowed && !pccFriendsAllowed) noUGC = true;
586
587 if(isClientSide && noUGC )
588 {
589 UINT uiIDA[1];
590 uiIDA[0]=IDS_CONFIRM_OK;
591 StorageManager.RequestMessageBox( IDS_FAILED_TO_CREATE_GAME_TITLE, IDS_NO_USER_CREATED_CONTENT_PRIVILEGE_CREATE, uiIDA,1,ProfileManager.GetPrimaryPad(),NULL,NULL, app.GetStringTable());
592 }
593 else
594 {
595 // This is called from a storage manager thread... need to set up thread storage for IntCache as CreateGame requires this to search for a suitable seed if we haven't set a seed.
596 IntCache::CreateNewThreadStorage();
597 CreateGame(pScene, 0);
598 IntCache::ReleaseThreadStorage();
599 }
600 }
601
602 return 0;
603}
604
605HRESULT CScene_MultiGameCreate::OnKeyDown(XUIMessageInput* pInputData, BOOL& rfHandled)
606{
607 if(m_bIgnoreInput) return S_OK;
608
609 ui.AnimateKeyPress(pInputData->UserIndex, pInputData->dwKeyCode);
610
611 // Explicitly handle B button presses
612 switch(pInputData->dwKeyCode)
613 {
614 case VK_PAD_B:
615 case VK_ESCAPE:
616 app.NavigateBack(pInputData->UserIndex);
617 rfHandled = TRUE;
618 break;
619 }
620 return S_OK;
621}
622
623HRESULT CScene_MultiGameCreate::OnNotifyValueChanged (HXUIOBJ hObjSource, XUINotifyValueChanged* pValueChangedData, BOOL& rfHandled)
624{
625 WCHAR TempString[256];
626
627 if(hObjSource == m_EditWorldName)
628 {
629 // Enable the done button when we have all of the necessary information
630 wstring wWorldName = m_EditWorldName.GetText();
631 BOOL bHasWorldName = ( wWorldName.length()!=0);
632 m_NewWorld.SetEnable(bHasWorldName);
633 }
634 else if(hObjSource==m_SliderDifficulty.GetSlider() )
635 {
636 app.SetGameSettings(m_iPad,eGameSetting_Difficulty,pValueChangedData->nValue);
637 swprintf( (WCHAR *)TempString, 256, L"%ls: %ls", app.GetString( IDS_SLIDER_DIFFICULTY ),app.GetString(m_iDifficultyTitleSettingA[pValueChangedData->nValue]));
638 m_SliderDifficulty.SetText(TempString);
639 }
640
641 return S_OK;
642}
643
644HRESULT CScene_MultiGameCreate::OnControlNavigate(XUIMessageControlNavigate *pControlNavigateData, BOOL& bHandled)
645{
646 pControlNavigateData->hObjDest=XuiControlGetNavigation(pControlNavigateData->hObjSource,pControlNavigateData->nControlNavigate,TRUE,TRUE);
647
648 if(pControlNavigateData->hObjDest==NULL)
649 {
650 pControlNavigateData->hObjDest=pControlNavigateData->hObjSource;
651 }
652
653 bHandled=TRUE;
654 return S_OK;
655}
656
657HRESULT CScene_MultiGameCreate::OnTimer( XUIMessageTimer *pTimer, BOOL& bHandled )
658{
659 // 4J-PB - TODO - Don't think we can do this - if a 2nd player signs in here with an offline profile, the signed in LIVE player gets re-logged in, and bMultiplayerAllowed is false briefly
660 switch(pTimer->nId)
661 {
662
663
664 case GAME_CREATE_ONLINE_TIMER_ID:
665 {
666 bool bMultiplayerAllowed = ProfileManager.IsSignedInLive( m_iPad ) && ProfileManager.AllowedToPlayMultiplayer(m_iPad);
667
668 if(bMultiplayerAllowed != m_bMultiplayerAllowed)
669 {
670 if( bMultiplayerAllowed )
671 {
672 bool bGameSetting_Online=(app.GetGameSettings(m_iPad,eGameSetting_Online)!=0);
673 m_MoreOptionsParams.bOnlineGame = bGameSetting_Online?TRUE:FALSE;
674 if(bGameSetting_Online)
675 {
676 m_MoreOptionsParams.bInviteOnly = (app.GetGameSettings(m_iPad,eGameSetting_InviteOnly)!=0)?TRUE:FALSE;
677 m_MoreOptionsParams.bAllowFriendsOfFriends = (app.GetGameSettings(m_iPad,eGameSetting_FriendsOfFriends)!=0)?TRUE:FALSE;
678 }
679 else
680 {
681 m_MoreOptionsParams.bInviteOnly = FALSE;
682 m_MoreOptionsParams.bAllowFriendsOfFriends = FALSE;
683 }
684 }
685 else
686 {
687 m_MoreOptionsParams.bOnlineGame = FALSE;
688 m_MoreOptionsParams.bInviteOnly = FALSE;
689 m_MoreOptionsParams.bAllowFriendsOfFriends = FALSE;
690 }
691
692 m_bMultiplayerAllowed = bMultiplayerAllowed;
693 }
694 }
695 break;
696
697 case CHECKFORAVAILABLETEXTUREPACKS_TIMER_ID:
698 {
699 // also check for any new texture packs info being available
700 // for each item in the mem list, check it's in the data list
701
702 CXuiCtrl4JList::LIST_ITEM_INFO ListInfo;
703 // for each iConfig, check if the data is available, and add it to the List, then remove it from the viConfig
704 for(int i=0;i<m_iTexturePacksNotInstalled;i++)
705 {
706 if(m_iConfigA[i]!=-1)
707 {
708 DWORD dwBytes=0;
709 PBYTE pbData=NULL;
710 //app.DebugPrintf("Retrieving iConfig %d from TPD\n",m_iConfigA[i]);
711
712 app.GetTPD(m_iConfigA[i],&pbData,&dwBytes);
713
714 ZeroMemory(&ListInfo,sizeof(CXuiCtrl4JList::LIST_ITEM_INFO));
715 if(dwBytes > 0 && pbData)
716 {
717 DWORD dwImageBytes=0;
718 PBYTE pbImageData=NULL;
719
720 app.GetFileFromTPD(eTPDFileType_Icon,pbData,dwBytes,&pbImageData,&dwImageBytes );
721 ListInfo.fEnabled = TRUE;
722 ListInfo.iData = m_iConfigA[i];
723 HRESULT hr=XuiCreateTextureBrushFromMemory(pbImageData,dwImageBytes,&ListInfo.hXuiBrush);
724 app.DebugPrintf("Adding texturepack %d from TPD\n",m_iConfigA[i]);
725
726 ListInfo.iSortIndex=m_iConfigA[i];
727 m_pTexturePacksList->AddData(ListInfo,0,CXuiCtrl4JList::eSortList_Index);
728
729 m_iConfigA[i]=-1;
730 }
731 }
732 }
733
734 bool bAllDone=true;
735 for(int i=0;i<m_iTexturePacksNotInstalled;i++)
736 {
737 if(m_iConfigA[i]!=-1)
738 {
739 bAllDone = false;
740 }
741 }
742
743 if(bAllDone )
744 {
745 // kill this timer
746 XuiKillTimer(m_hObj,CHECKFORAVAILABLETEXTUREPACKS_TIMER_ID);
747 }
748 }
749 break;
750 }
751
752 return S_OK;
753}
754
755int CScene_MultiGameCreate::ConfirmCreateReturned(void *pParam,int iPad,C4JStorage::EMessageResult result)
756{
757 CScene_MultiGameCreate* pClass = (CScene_MultiGameCreate*)pParam;
758
759 if(result==C4JStorage::EMessage_ResultAccept)
760 {
761 bool isClientSide = ProfileManager.IsSignedInLive(ProfileManager.GetPrimaryPad()) && pClass->m_MoreOptionsParams.bOnlineGame;
762
763 // 4J Stu - If we only have one controller connected, then don't show the sign-in UI again
764 DWORD connectedControllers = 0;
765 for(unsigned int i = 0; i < XUSER_MAX_COUNT; ++i)
766 {
767 if( InputManager.IsPadConnected(i) || ProfileManager.IsSignedIn(i) ) ++connectedControllers;
768 }
769
770 if(isClientSide && connectedControllers > 1 && RenderManager.IsHiDef())
771 {
772 ProfileManager.RequestSignInUI(false, false, false, true, false,&CScene_MultiGameCreate::StartGame_SignInReturned, pClass,ProfileManager.GetPrimaryPad());
773 }
774 else
775 {
776 // Check if user-created content is allowed, as we cannot play multiplayer if it's not
777 bool isClientSide = ProfileManager.IsSignedInLive(ProfileManager.GetPrimaryPad()) && pClass->m_MoreOptionsParams.bOnlineGame;
778 bool noUGC = false;
779 BOOL pccAllowed = TRUE;
780 BOOL pccFriendsAllowed = TRUE;
781 ProfileManager.AllowedPlayerCreatedContent(ProfileManager.GetPrimaryPad(),false,&pccAllowed,&pccFriendsAllowed);
782 if(!pccAllowed && !pccFriendsAllowed) noUGC = true;
783
784 if(isClientSide && noUGC )
785 {
786 pClass->m_bIgnoreInput = false;
787 pClass->SetShow( TRUE );
788 UINT uiIDA[1];
789 uiIDA[0]=IDS_CONFIRM_OK;
790 StorageManager.RequestMessageBox( IDS_FAILED_TO_CREATE_GAME_TITLE, IDS_NO_USER_CREATED_CONTENT_PRIVILEGE_CREATE, uiIDA,1,ProfileManager.GetPrimaryPad(),NULL,NULL, app.GetStringTable());
791 }
792 else
793 {
794 // This is called from a storage manager thread... need to set up thread storage for IntCache as CreateGame requires this to search for a suitable seed if we haven't set a seed.
795 IntCache::CreateNewThreadStorage();
796 CreateGame(pClass, 0);
797 IntCache::ReleaseThreadStorage();
798 }
799 }
800 }
801 else
802 {
803 pClass->m_bIgnoreInput = false;
804 pClass->SetShow( TRUE );
805 }
806 return 0;
807}
808
809int CScene_MultiGameCreate::StartGame_SignInReturned(void *pParam,bool bContinue, int iPad)
810{
811 CScene_MultiGameCreate* pClass = (CScene_MultiGameCreate*)pParam;
812
813 if(bContinue==true)
814 {
815 // It's possible that the player has not signed in - they can back out
816 if(ProfileManager.IsSignedIn(iPad))
817 {
818 DWORD dwLocalUsersMask = 0;
819
820 bool isClientSide = ProfileManager.IsSignedInLive(ProfileManager.GetPrimaryPad()) && pClass->m_MoreOptionsParams.bOnlineGame;
821 bool noPrivileges = false;
822
823 for(unsigned int index = 0; index < XUSER_MAX_COUNT; ++index)
824 {
825 if(ProfileManager.IsSignedIn(index) )
826 {
827 if( !ProfileManager.AllowedToPlayMultiplayer(index) ) noPrivileges = true;
828 dwLocalUsersMask |= CGameNetworkManager::GetLocalPlayerMask(index);
829 }
830 }
831
832 // Check if user-created content is allowed, as we cannot play multiplayer if it's not
833 bool noUGC = false;
834 BOOL pccAllowed = TRUE;
835 BOOL pccFriendsAllowed = TRUE;
836 ProfileManager.AllowedPlayerCreatedContent(ProfileManager.GetPrimaryPad(),false,&pccAllowed,&pccFriendsAllowed);
837 if(!pccAllowed && !pccFriendsAllowed) noUGC = true;
838
839 if(isClientSide && (noPrivileges || noUGC) )
840 {
841 if( noUGC )
842 {
843 pClass->m_bIgnoreInput = false;
844 pClass->SetShow( TRUE );
845 UINT uiIDA[1];
846 uiIDA[0]=IDS_CONFIRM_OK;
847 StorageManager.RequestMessageBox( IDS_FAILED_TO_CREATE_GAME_TITLE, IDS_NO_USER_CREATED_CONTENT_PRIVILEGE_CREATE, uiIDA,1,ProfileManager.GetPrimaryPad(),NULL,NULL, app.GetStringTable());
848 }
849 else
850 {
851 pClass->m_bIgnoreInput = false;
852 pClass->SetShow( TRUE );
853 UINT uiIDA[1];
854 uiIDA[0]=IDS_CONFIRM_OK;
855 StorageManager.RequestMessageBox( IDS_NO_MULTIPLAYER_PRIVILEGE_TITLE, IDS_NO_MULTIPLAYER_PRIVILEGE_HOST_TEXT, uiIDA,1,ProfileManager.GetPrimaryPad(),NULL,NULL, app.GetStringTable());
856 }
857 }
858 else
859 {
860 // This is NOT called from a storage manager thread, and is in fact called from the main thread in the Profile library tick. Therefore we use the main threads IntCache.
861 CreateGame(pClass, dwLocalUsersMask);
862 }
863 }
864 }
865 else
866 {
867 pClass->m_bIgnoreInput = false;
868 pClass->SetShow( TRUE );
869 }
870 return 0;
871}
872
873// 4J Stu - Shared functionality that is the same whether we needed a quadrant sign-in or not
874void CScene_MultiGameCreate::CreateGame(CScene_MultiGameCreate* pClass, DWORD dwLocalUsersMask)
875{
876 // stop the timer running that causes a check for new texture packs in TMS but not installed, since this will run all through the create game, and will crash if it tries to create an hbrush
877 XuiKillTimer(pClass->m_hObj,CHECKFORAVAILABLETEXTUREPACKS_TIMER_ID);
878
879 bool isClientSide = ProfileManager.IsSignedInLive(ProfileManager.GetPrimaryPad()) && pClass->m_MoreOptionsParams.bOnlineGame;
880 bool isPrivate = pClass->m_MoreOptionsParams.bInviteOnly?true:false;
881
882 // clear out the app's terrain features list
883 app.ClearTerrainFeaturePosition();
884
885 // create the world and launch
886 wstring wWorldName = pClass->m_EditWorldName.GetText();
887
888 StorageManager.ResetSaveData();
889 // Make our next save default to the name of the level
890 StorageManager.SetSaveTitle((wchar_t *)wWorldName.c_str());
891
892 BOOL bHasSeed = (pClass->m_EditSeed.GetText() != NULL);
893
894 wstring wSeed;
895 if(bHasSeed)
896 {
897 wSeed=pClass->m_EditSeed.GetText();
898 }
899 else
900 {
901 // random
902 wSeed=L"";
903 }
904
905 // start the game
906 bool isFlat = (pClass->m_MoreOptionsParams.bFlatWorld==TRUE);
907 __int64 seedValue = 0; //BiomeSource::findSeed(isFlat?LevelType::lvl_flat:LevelType::lvl_normal); // 4J - was (new Random())->nextLong() - now trying to actually find a seed to suit our requirements
908
909 if (wSeed.length() != 0)
910 {
911 __int64 value = 0;
912 unsigned int len = (unsigned int)wSeed.length();
913
914 //Check if the input string contains a numerical value
915 bool isNumber = true;
916 for( unsigned int i = 0 ; i < len ; ++i )
917 if( wSeed.at(i) < L'0' || wSeed.at(i) > L'9' )
918 if( !(i==0 && wSeed.at(i) == L'-' ) )
919 {
920 isNumber = false;
921 break;
922 }
923
924 //If the input string is a numerical value, convert it to a number
925 if( isNumber )
926 value = _fromString<__int64>(wSeed);
927
928 //If the value is not 0 use it, otherwise use the algorithm from the java String.hashCode() function to hash it
929 if( value != 0 )
930 seedValue = value;
931 else
932 {
933 int hashValue = 0;
934 for( unsigned int i = 0 ; i < len ; ++i )
935 hashValue = 31 * hashValue + wSeed.at(i);
936 seedValue = hashValue;
937 }
938
939 }
940 else
941 {
942 seedValue = BiomeSource::findSeed(isFlat?LevelType::lvl_flat:LevelType::lvl_normal); // 4J - was (new Random())->nextLong() - now trying to actually find a seed to suit our requirements
943 }
944
945 g_NetworkManager.HostGame(dwLocalUsersMask,isClientSide,isPrivate,MINECRAFT_NET_MAX_PLAYERS,0);
946
947 NetworkGameInitData *param = new NetworkGameInitData();
948 param->seed = seedValue;
949 param->saveData = NULL;
950 param->texturePackId = pClass->m_MoreOptionsParams.dwTexturePack;
951
952 Minecraft *pMinecraft = Minecraft::GetInstance();
953 pMinecraft->skins->selectTexturePackById(pClass->m_MoreOptionsParams.dwTexturePack);
954 //pMinecraft->skins->updateUI();
955
956 app.SetGameHostOption(eGameHostOption_Difficulty,Minecraft::GetInstance()->options->difficulty);
957 app.SetGameHostOption(eGameHostOption_FriendsOfFriends,pClass->m_MoreOptionsParams.bAllowFriendsOfFriends);
958 app.SetGameHostOption(eGameHostOption_Gamertags,app.GetGameSettings(pClass->m_iPad,eGameSetting_GamertagsVisible)?1:0);
959
960 app.SetGameHostOption(eGameHostOption_BedrockFog,app.GetGameSettings(pClass->m_iPad,eGameSetting_BedrockFog)?1:0);
961
962// CXuiList listObject;
963// listObject.Attach( pClass->m_GameMode.GetListObject() );
964 app.SetGameHostOption(eGameHostOption_GameType,pClass->m_bGameModeSurvival?GameType::SURVIVAL->getId():GameType::CREATIVE->getId());
965 app.SetGameHostOption(eGameHostOption_LevelType,pClass->m_MoreOptionsParams.bFlatWorld );
966 app.SetGameHostOption(eGameHostOption_Structures,pClass->m_MoreOptionsParams.bStructures );
967 app.SetGameHostOption(eGameHostOption_BonusChest,pClass->m_MoreOptionsParams.bBonusChest );
968
969 app.SetGameHostOption(eGameHostOption_PvP,pClass->m_MoreOptionsParams.bPVP);
970 app.SetGameHostOption(eGameHostOption_TrustPlayers,pClass->m_MoreOptionsParams.bTrust );
971 app.SetGameHostOption(eGameHostOption_FireSpreads,pClass->m_MoreOptionsParams.bFireSpreads );
972 app.SetGameHostOption(eGameHostOption_TNT,pClass->m_MoreOptionsParams.bTNT );
973 app.SetGameHostOption(eGameHostOption_HostCanFly,pClass->m_MoreOptionsParams.bHostPrivileges);
974 app.SetGameHostOption(eGameHostOption_HostCanChangeHunger,pClass->m_MoreOptionsParams.bHostPrivileges);
975 app.SetGameHostOption(eGameHostOption_HostCanBeInvisible,pClass->m_MoreOptionsParams.bHostPrivileges );
976
977
978 param->settings = app.GetGameHostOption( eGameHostOption_All );
979
980 LoadingInputParams *loadingParams = new LoadingInputParams();
981 loadingParams->func = &CGameNetworkManager::RunNetworkGameThreadProc;
982 loadingParams->lpParam = (LPVOID)param;
983
984 // Reset the autosave time
985 app.SetAutosaveTimerTime();
986
987 UIFullscreenProgressCompletionData *completionData = new UIFullscreenProgressCompletionData();
988 completionData->bShowBackground=TRUE;
989 completionData->bShowLogo=TRUE;
990 completionData->type = e_ProgressCompletion_CloseAllPlayersUIScenes;
991 completionData->iPad = DEFAULT_XUI_MENU_USER;
992 loadingParams->completionData = completionData;
993
994 app.NavigateToScene(ProfileManager.GetPrimaryPad(),eUIScene_FullscreenProgress, loadingParams);
995}
996
997HRESULT CScene_MultiGameCreate::OnTransitionStart( XUIMessageTransition *pTransition, BOOL& bHandled )
998{
999 if(pTransition->dwTransAction==XUI_TRANSITION_ACTION_DESTROY ) return S_OK;
1000
1001 if(pTransition->dwTransType == XUI_TRANSITION_TO || pTransition->dwTransType == XUI_TRANSITION_BACKTO)
1002 {
1003 m_SliderDifficulty.SetValueDisplay(FALSE);
1004 }
1005
1006 return S_OK;
1007}
1008
1009HRESULT CScene_MultiGameCreate::OnTransitionEnd( XUIMessageTransition *pTransition, BOOL& bHandled )
1010{
1011 //if(pTransition->dwTransAction==XUI_TRANSITION_ACTION_DESTROY ) return S_OK;
1012
1013 if(pTransition->dwTransAction==XUI_TRANSITION_ACTION_DESTROY ||
1014 pTransition->dwTransType == XUI_TRANSITION_FROM || pTransition->dwTransType == XUI_TRANSITION_BACKFROM)
1015 {
1016 }
1017 else if(pTransition->dwTransType == XUI_TRANSITION_TO || pTransition->dwTransType == XUI_TRANSITION_BACKTO)
1018 {
1019 if(m_bSetup && m_texturePackDescDisplayed)
1020 {
1021 XUITimeline *timeline;
1022 XUINamedFrame *startFrame, *endFrame;
1023 GetTimeline( &timeline );
1024 startFrame = timeline->FindNamedFrame( L"SlideOutEnd" );
1025 endFrame = timeline->FindNamedFrame( L"SlideOutEnd" );
1026 timeline->Play( startFrame->m_dwFrame, startFrame->m_dwFrame, endFrame->m_dwFrame, FALSE, FALSE );
1027 m_texturePackDescDisplayed = true;
1028 }
1029 // 4J-PB - Need to check for installed DLC, which might have happened while you were on the info scene
1030 if(pTransition->dwTransType == XUI_TRANSITION_BACKTO)
1031 {
1032 // Can't call this here because if you back out of the load info screen and then go back in and load a game, it will attempt to use the dlc as it's running a mount of the dlc
1033
1034 // block input if we're waiting for DLC to install, and wipe the saves list. The end of dlc mounting custom message will fill the list again
1035 if(app.StartInstallDLCProcess(m_iPad)==false)
1036 {
1037 // not doing a mount, so re-enable input
1038 m_bIgnoreInput=false;
1039 }
1040 else
1041 {
1042 m_bIgnoreInput=true;
1043 m_pTexturePacksList->RemoveAllData();
1044 }
1045 }
1046
1047 }
1048
1049 return S_OK;
1050}
1051
1052HRESULT CScene_MultiGameCreate::OnNotifySelChanged( HXUIOBJ hObjSource, XUINotifySelChanged* pNotifySelChangedData, BOOL& bHandled )
1053{
1054 if(hObjSource == m_pTexturePacksList->m_hObj)
1055 {
1056 UpdateTexturePackDescription(pNotifySelChangedData->iItem);
1057
1058 // 4J-JEV: Removed expand description check, taken care of elsewhere.
1059 }
1060
1061 return S_OK;
1062}
1063
1064HRESULT CScene_MultiGameCreate::OnNotifyKillFocus(HXUIOBJ hObjSource, XUINotifyFocus *pNotifyFocusData, BOOL& bHandled)
1065{
1066 HXUIOBJ hSourceParent, hDestParent;
1067 XuiElementGetParent(hObjSource,&hSourceParent);
1068 XuiElementGetParent(pNotifyFocusData->hObjOther,&hDestParent);
1069 if(hSourceParent != hDestParent && pNotifyFocusData->hObjOther != m_pTexturePacksList->m_hObj && hSourceParent == m_pTexturePacksList->m_hObj)
1070 {
1071 m_pTexturePacksList->SetCurSel(m_currentTexturePackIndex);
1072 m_pTexturePacksList->SetTopItem(m_currentTexturePackIndex); // scroll the item into view if it's not visible
1073 }
1074 else if(!m_texturePackDescDisplayed && pNotifyFocusData->hObjOther == m_pTexturePacksList->m_hObj)
1075 {
1076 // 4J-JEV: Shouldn't we always do this?
1077 //int texturePacksCount = Minecraft::GetInstance()->skins->getTexturePackCount();
1078 //if(texturePacksCount == 1)
1079 //{
1080 XUITimeline *timeline;
1081 XUINamedFrame *startFrame, *endFrame;
1082 GetTimeline( &timeline );
1083 startFrame = timeline->FindNamedFrame( L"SlideOut" );
1084 endFrame = timeline->FindNamedFrame( L"SlideOutEnd" );
1085 timeline->Play( startFrame->m_dwFrame, startFrame->m_dwFrame, endFrame->m_dwFrame, FALSE, FALSE );
1086 m_texturePackDescDisplayed = true;
1087 //}
1088 }
1089
1090 return S_OK;
1091}
1092
1093void CScene_MultiGameCreate::UpdateTexturePackDescription(int index)
1094{
1095 int iTexPackId=m_pTexturePacksList->GetData(index).iData;
1096 TexturePack *tp = Minecraft::GetInstance()->skins->getTexturePackById(iTexPackId);
1097
1098 if(tp==NULL)
1099 {
1100 // this is probably a texture pack icon added from TMS
1101
1102 DWORD dwBytes=0,dwFileBytes=0;
1103 PBYTE pbData=NULL,pbFileData=NULL;
1104
1105 CXuiCtrl4JList::LIST_ITEM_INFO ListItem;
1106 // get the current index of the list, and then get the data
1107 ListItem=m_pTexturePacksList->GetData(index);
1108
1109 app.GetTPD(ListItem.iData,&pbData,&dwBytes);
1110
1111 app.GetFileFromTPD(eTPDFileType_Loc,pbData,dwBytes,&pbFileData,&dwFileBytes );
1112 if(dwFileBytes > 0 && pbFileData)
1113 {
1114 StringTable *pStringTable = new StringTable(pbFileData, dwFileBytes);
1115 m_texturePackTitle.SetText(pStringTable->getString(L"IDS_DISPLAY_NAME"));
1116 m_texturePackDescription.SetText(pStringTable->getString(L"IDS_TP_DESCRIPTION"));
1117 }
1118
1119 app.GetFileFromTPD(eTPDFileType_Icon,pbData,dwBytes,&pbFileData,&dwFileBytes );
1120 if(dwFileBytes >= 0 && pbFileData)
1121 {
1122 XuiCreateTextureBrushFromMemory(pbFileData,dwFileBytes,&m_hTexturePackIconBrush);
1123 m_texturePackIcon->UseBrush(m_hTexturePackIconBrush);
1124 }
1125 app.GetFileFromTPD(eTPDFileType_Comparison,pbData,dwBytes,&pbFileData,&dwFileBytes );
1126 if(dwFileBytes >= 0 && pbFileData)
1127 {
1128 XuiCreateTextureBrushFromMemory(pbFileData,dwFileBytes,&m_hTexturePackComparisonBrush);
1129 m_texturePackComparison->UseBrush(m_hTexturePackComparisonBrush);
1130 }
1131 else
1132 {
1133 m_texturePackComparison->UseBrush(NULL);
1134 }
1135 }
1136 else
1137 {
1138 m_texturePackTitle.SetText(tp->getName().c_str());
1139 m_texturePackDescription.SetText(tp->getDesc1().c_str());
1140
1141 DWORD dwImageBytes;
1142 PBYTE pbImageData = tp->getPackIcon(dwImageBytes);
1143
1144 if(dwImageBytes > 0 && pbImageData)
1145 {
1146 XuiCreateTextureBrushFromMemory(pbImageData,dwImageBytes,&m_hTexturePackIconBrush);
1147 m_texturePackIcon->UseBrush(m_hTexturePackIconBrush);
1148 }
1149
1150 pbImageData = tp->getPackComparison(dwImageBytes);
1151
1152 if(dwImageBytes > 0 && pbImageData)
1153 {
1154 XuiCreateTextureBrushFromMemory(pbImageData,dwImageBytes,&m_hTexturePackComparisonBrush);
1155 m_texturePackComparison->UseBrush(m_hTexturePackComparisonBrush);
1156 }
1157 else
1158 {
1159 m_texturePackComparison->UseBrush(NULL);
1160 }
1161 }
1162}
1163
1164void CScene_MultiGameCreate::UpdateCurrentTexturePack()
1165{
1166 m_currentTexturePackIndex = m_pTexturePacksList->GetCurSel();
1167 int iTexPackId=m_pTexturePacksList->GetData(m_currentTexturePackIndex).iData;
1168 TexturePack *tp = Minecraft::GetInstance()->skins->getTexturePackById(iTexPackId);
1169
1170 // if the texture pack is null, you don't have it yet
1171 if(tp==NULL)
1172 {
1173 // Upsell
1174
1175 CXuiCtrl4JList::LIST_ITEM_INFO ListItem;
1176 // get the current index of the list, and then get the data
1177 ListItem=m_pTexturePacksList->GetData(m_currentTexturePackIndex);
1178
1179
1180 // upsell the texture pack
1181 // tell sentient about the upsell of the full version of the skin pack
1182 ULONGLONG ullOfferID_Full;
1183 app.GetDLCFullOfferIDForPackID(ListItem.iData,&ullOfferID_Full);
1184
1185 TelemetryManager->RecordUpsellPresented(ProfileManager.GetPrimaryPad(), eSet_UpsellID_Texture_DLC, ullOfferID_Full & 0xFFFFFFFF);
1186
1187 UINT uiIDA[3];
1188
1189 // Need to check if the texture pack has both Full and Trial versions - we may do some as free ones, so only Full
1190 DLC_INFO *pDLCInfo=app.GetDLCInfoForFullOfferID(ullOfferID_Full);
1191
1192 if(pDLCInfo->ullOfferID_Trial!=0LL)
1193 {
1194 uiIDA[0]=IDS_TEXTUREPACK_FULLVERSION;
1195 uiIDA[1]=IDS_TEXTURE_PACK_TRIALVERSION;
1196 uiIDA[2]=IDS_CONFIRM_CANCEL;
1197 // Give the player a warning about the texture pack missing
1198 StorageManager.RequestMessageBox(IDS_DLC_TEXTUREPACK_NOT_PRESENT_TITLE, IDS_DLC_TEXTUREPACK_NOT_PRESENT, uiIDA, 3, ProfileManager.GetPrimaryPad(),&CScene_MultiGameCreate::TexturePackDialogReturned,this,app.GetStringTable());
1199 }
1200 else
1201 {
1202 uiIDA[0]=IDS_TEXTUREPACK_FULLVERSION;
1203 uiIDA[1]=IDS_CONFIRM_CANCEL;
1204 // Give the player a warning about the texture pack missing
1205 StorageManager.RequestMessageBox(IDS_DLC_TEXTUREPACK_NOT_PRESENT_TITLE, IDS_DLC_TEXTUREPACK_NOT_PRESENT, uiIDA, 2, ProfileManager.GetPrimaryPad(),&CScene_MultiGameCreate::TexturePackDialogReturned,this,app.GetStringTable());
1206 }
1207
1208 // do set the texture pack id, and on the user pressing create world, check they have it
1209 m_MoreOptionsParams.dwTexturePack = ListItem.iData;
1210 return ;
1211 }
1212 else
1213 {
1214 m_MoreOptionsParams.dwTexturePack = tp->getId();
1215 }
1216}
1217
1218int CScene_MultiGameCreate::TexturePackDialogReturned(void *pParam,int iPad,C4JStorage::EMessageResult result)
1219{
1220 CScene_MultiGameCreate *pClass = (CScene_MultiGameCreate *)pParam;
1221 pClass->m_currentTexturePackIndex = pClass->m_pTexturePacksList->GetCurSel();
1222 // Exit with or without saving
1223 // Decline means install full version of the texture pack in this dialog
1224 if(result==C4JStorage::EMessage_ResultDecline || result==C4JStorage::EMessage_ResultAccept)
1225 {
1226 // we need to enable background downloading for the DLC
1227 XBackgroundDownloadSetMode(XBACKGROUND_DOWNLOAD_MODE_ALWAYS_ALLOW);
1228
1229 ULONGLONG ullOfferID_Full;
1230 ULONGLONG ullIndexA[1];
1231 CXuiCtrl4JList::LIST_ITEM_INFO ListItem;
1232 // get the current index of the list, and then get the data
1233 ListItem=pClass->m_pTexturePacksList->GetData(pClass->m_currentTexturePackIndex);
1234 app.GetDLCFullOfferIDForPackID(ListItem.iData,&ullOfferID_Full);
1235
1236 if( result==C4JStorage::EMessage_ResultAccept ) // Full version
1237 {
1238 ullIndexA[0]=ullOfferID_Full;
1239 StorageManager.InstallOffer(1,ullIndexA,NULL,NULL);
1240
1241 }
1242 else // trial version
1243 {
1244 // if there is no trial version, this is a Cancel
1245 DLC_INFO *pDLCInfo=app.GetDLCInfoForFullOfferID(ullOfferID_Full);
1246 if(pDLCInfo->ullOfferID_Trial!=0LL)
1247 {
1248 ullIndexA[0]=pDLCInfo->ullOfferID_Trial;
1249 StorageManager.InstallOffer(1,ullIndexA,NULL,NULL);
1250 }
1251 }
1252 }
1253 pClass->m_bIgnoreInput=false;
1254 return 0;
1255}
1256
1257HRESULT CScene_MultiGameCreate::OnCustomMessage_DLCInstalled()
1258{
1259 // mounted DLC may have changed
1260 if(app.StartInstallDLCProcess(m_iPad)==false)
1261 {
1262 // not doing a mount, so re-enable input
1263 m_bIgnoreInput=false;
1264 }
1265 else
1266 {
1267 m_bIgnoreInput=true;
1268 // clear out the texture pack list
1269 m_pTexturePacksList->RemoveAllData();
1270 ClearTexturePackDescription();
1271 }
1272 // this will send a CustomMessage_DLCMountingComplete when done
1273 return S_OK;
1274}
1275
1276HRESULT CScene_MultiGameCreate::OnCustomMessage_DLCMountingComplete()
1277{
1278 // refill the texture pack list
1279 m_pTexturePacksList->SetSelectionChangedHandle(m_hObj);
1280
1281 Minecraft *pMinecraft = Minecraft::GetInstance();
1282 int texturePacksCount = pMinecraft->skins->getTexturePackCount();
1283 CXuiCtrl4JList::LIST_ITEM_INFO ListInfo;
1284 HRESULT hr;
1285 for(unsigned int i = 0; i < texturePacksCount; ++i)
1286 {
1287 TexturePack *tp = pMinecraft->skins->getTexturePackByIndex(i);
1288 ZeroMemory(&ListInfo,sizeof(CXuiCtrl4JList::LIST_ITEM_INFO));
1289
1290 DWORD dwImageBytes;
1291 PBYTE pbImageData = tp->getPackIcon(dwImageBytes);
1292
1293 if(dwImageBytes > 0 && pbImageData)
1294 {
1295 ListInfo.fEnabled = TRUE;
1296 hr=XuiCreateTextureBrushFromMemory(pbImageData,dwImageBytes,&ListInfo.hXuiBrush);
1297
1298 DLCTexturePack *pDLCTexPack=(DLCTexturePack *)tp;
1299 if(pDLCTexPack)
1300 {
1301 int id=pDLCTexPack->getDLCParentPackId();
1302
1303 if(id==0)
1304 {
1305 // default texture pack - should come first
1306 ListInfo.iSortIndex=0x0FFFFFFF;
1307 }
1308 else
1309 {
1310 ListInfo.iSortIndex=id;
1311 ListInfo.iData=id;
1312 }
1313 }
1314 m_pTexturePacksList->AddData(ListInfo,0,CXuiCtrl4JList::eSortList_Index);
1315 }
1316 }
1317
1318 m_iTexturePacksNotInstalled=0;
1319
1320 // 4J-PB - there may be texture packs we don't have, so use the info from TMS for this
1321 // REMOVE UNTIL WORKING
1322 DLC_INFO *pDLCInfo=NULL;
1323
1324 // first pass - look to see if there are any that are not in the list
1325 bool bTexturePackAlreadyListed;
1326 bool bNeedToGetTPD=false;
1327
1328 for(unsigned int i = 0; i < app.GetDLCInfoTexturesOffersCount(); ++i)
1329 {
1330 bTexturePackAlreadyListed=false;
1331 ULONGLONG ull=app.GetDLCInfoTexturesFullOffer(i);
1332 pDLCInfo=app.GetDLCInfoForFullOfferID(ull);
1333 for(unsigned int i = 0; i < texturePacksCount; ++i)
1334 {
1335 TexturePack *tp = pMinecraft->skins->getTexturePackByIndex(i);
1336 if(pDLCInfo->iConfig==tp->getDLCParentPackId())
1337 {
1338 bTexturePackAlreadyListed=true;
1339 }
1340 }
1341 if(bTexturePackAlreadyListed==false)
1342 {
1343 // some missing
1344 bNeedToGetTPD=true;
1345
1346 m_iTexturePacksNotInstalled++;
1347 }
1348 }
1349
1350 if(bNeedToGetTPD==true)
1351 {
1352 // add a TMS request for them
1353 app.DebugPrintf("+++ Adding TMSPP request for texture pack data\n");
1354 app.AddTMSPPFileTypeRequest(e_DLC_TexturePackData);
1355 if(m_iConfigA!=NULL)
1356 {
1357 delete m_iConfigA;
1358 }
1359 m_iConfigA= new int [m_iTexturePacksNotInstalled];
1360 m_iTexturePacksNotInstalled=0;
1361
1362 for(unsigned int i = 0; i < app.GetDLCInfoTexturesOffersCount(); ++i)
1363 {
1364 bTexturePackAlreadyListed=false;
1365 ULONGLONG ull=app.GetDLCInfoTexturesFullOffer(i);
1366 pDLCInfo=app.GetDLCInfoForFullOfferID(ull);
1367 for(unsigned int i = 0; i < texturePacksCount; ++i)
1368 {
1369 TexturePack *tp = pMinecraft->skins->getTexturePackByIndex(i);
1370 if(pDLCInfo->iConfig==tp->getDLCParentPackId())
1371 {
1372 bTexturePackAlreadyListed=true;
1373 }
1374 }
1375 if(bTexturePackAlreadyListed==false)
1376 {
1377 m_iConfigA[m_iTexturePacksNotInstalled++]=pDLCInfo->iConfig;
1378 }
1379 }
1380 }
1381
1382 m_currentTexturePackIndex = pMinecraft->skins->getTexturePackIndex(0);
1383 UpdateTexturePackDescription(m_currentTexturePackIndex);
1384
1385 m_bSetup = true;
1386 m_bIgnoreInput=false;
1387 app.m_dlcManager.checkForCorruptDLCAndAlert();
1388 return S_OK;
1389}
1390
1391void CScene_MultiGameCreate::ClearTexturePackDescription()
1392{
1393 m_texturePackTitle.SetText(L" ");
1394 m_texturePackDescription.SetText(L" ");
1395 m_texturePackComparison->UseBrush(NULL);
1396 m_texturePackIcon->UseBrush(NULL);
1397}