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 <unordered_set>
4
5#include "..\..\..\Minecraft.World\StringHelpers.h"
6#include "..\..\..\Minecraft.World\Pos.h"
7#include "..\..\..\Minecraft.World\net.minecraft.world.phys.h"
8#include "..\..\..\Minecraft.World\net.minecraft.world.level.h"
9#include "..\..\..\Minecraft.World\net.minecraft.world.level.chunk.h"
10#include "Common\DLC\DLCGameRulesHeader.h"
11#include "..\..\StringTable.h"
12#include "LevelGenerationOptions.h"
13#include "ConsoleGameRules.h"
14
15JustGrSource::JustGrSource()
16{
17 m_displayName = L"Default_DisplayName";
18 m_worldName= L"Default_WorldName";
19 m_defaultSaveName = L"Default_DefaultSaveName";
20 m_bRequiresTexturePack = false;
21 m_requiredTexturePackId = 0;
22 m_grfPath = L"__NO_GRF_PATH__";
23 m_bRequiresBaseSave = false;
24}
25
26bool JustGrSource::requiresTexturePack() {return m_bRequiresTexturePack;}
27UINT JustGrSource::getRequiredTexturePackId() {return m_requiredTexturePackId;}
28wstring JustGrSource::getDefaultSaveName() {return m_defaultSaveName;}
29LPCWSTR JustGrSource::getWorldName() {return m_worldName.c_str();}
30LPCWSTR JustGrSource::getDisplayName() {return m_displayName.c_str();}
31wstring JustGrSource::getGrfPath() {return m_grfPath;}
32bool JustGrSource::requiresBaseSave() { return m_bRequiresBaseSave; };
33wstring JustGrSource::getBaseSavePath() { return m_baseSavePath; };
34
35void JustGrSource::setRequiresTexturePack(bool x) {m_bRequiresTexturePack = x;}
36void JustGrSource::setRequiredTexturePackId(UINT x) {m_requiredTexturePackId = x;}
37void JustGrSource::setDefaultSaveName(const wstring &x) {m_defaultSaveName = x;}
38void JustGrSource::setWorldName(const wstring &x) {m_worldName = x;}
39void JustGrSource::setDisplayName(const wstring &x) {m_displayName = x;}
40void JustGrSource::setGrfPath(const wstring &x) {m_grfPath = x;}
41void JustGrSource::setBaseSavePath(const wstring &x) { m_baseSavePath = x; m_bRequiresBaseSave = true; }
42
43bool JustGrSource::ready() { return true; }
44
45LevelGenerationOptions::LevelGenerationOptions(DLCPack *parentPack)
46{
47 m_spawnPos = NULL;
48 m_stringTable = NULL;
49
50 m_hasLoadedData = false;
51
52 m_seed = 0;
53 m_bHasBeenInCreative = true;
54 m_useFlatWorld = false;
55 m_bHaveMinY = false;
56 m_minY = INT_MAX;
57 m_bRequiresGameRules = false;
58
59 m_pbBaseSaveData = NULL;
60 m_dwBaseSaveSize = 0;
61
62 m_parentDLCPack = parentPack;
63 m_bLoadingData = false;
64}
65
66LevelGenerationOptions::~LevelGenerationOptions()
67{
68 clearSchematics();
69 if(m_spawnPos != NULL) delete m_spawnPos;
70 for(AUTO_VAR(it, m_schematicRules.begin()); it != m_schematicRules.end(); ++it)
71 {
72 delete *it;
73 }
74 for(AUTO_VAR(it, m_structureRules.begin()); it != m_structureRules.end(); ++it)
75 {
76 delete *it;
77 }
78
79 for(AUTO_VAR(it, m_biomeOverrides.begin()); it != m_biomeOverrides.end(); ++it)
80 {
81 delete *it;
82 }
83
84 for(AUTO_VAR(it, m_features.begin()); it != m_features.end(); ++it)
85 {
86 delete *it;
87 }
88
89 if (m_stringTable)
90 if (!isTutorial())
91 delete m_stringTable;
92
93 if (isFromSave()) delete m_pSrc;
94}
95
96ConsoleGameRules::EGameRuleType LevelGenerationOptions::getActionType() { return ConsoleGameRules::eGameRuleType_LevelGenerationOptions; }
97
98void LevelGenerationOptions::writeAttributes(DataOutputStream *dos, UINT numAttrs)
99{
100 GameRuleDefinition::writeAttributes(dos, numAttrs + 5);
101
102 ConsoleGameRules::write(dos, ConsoleGameRules::eGameRuleAttr_spawnX);
103 dos->writeUTF(_toString(m_spawnPos->x));
104 ConsoleGameRules::write(dos, ConsoleGameRules::eGameRuleAttr_spawnY);
105 dos->writeUTF(_toString(m_spawnPos->y));
106 ConsoleGameRules::write(dos, ConsoleGameRules::eGameRuleAttr_spawnZ);
107 dos->writeUTF(_toString(m_spawnPos->z));
108
109 ConsoleGameRules::write(dos, ConsoleGameRules::eGameRuleAttr_seed);
110 dos->writeUTF(_toString(m_seed));
111 ConsoleGameRules::write(dos, ConsoleGameRules::eGameRuleAttr_flatworld);
112 dos->writeUTF(_toString(m_useFlatWorld));
113}
114
115void LevelGenerationOptions::getChildren(vector<GameRuleDefinition *> *children)
116{
117 GameRuleDefinition::getChildren(children);
118
119 vector<ApplySchematicRuleDefinition *> used_schematics;
120 for (AUTO_VAR(it, m_schematicRules.begin()); it != m_schematicRules.end(); it++)
121 if ( !(*it)->isComplete() )
122 used_schematics.push_back( *it );
123
124 for(AUTO_VAR(it, m_structureRules.begin()); it!=m_structureRules.end(); it++)
125 children->push_back( *it );
126 for(AUTO_VAR(it, used_schematics.begin()); it!=used_schematics.end(); it++)
127 children->push_back( *it );
128 for(AUTO_VAR(it, m_biomeOverrides.begin()); it != m_biomeOverrides.end(); ++it)
129 children->push_back( *it );
130 for(AUTO_VAR(it, m_features.begin()); it != m_features.end(); ++it)
131 children->push_back( *it );
132}
133
134GameRuleDefinition *LevelGenerationOptions::addChild(ConsoleGameRules::EGameRuleType ruleType)
135{
136 GameRuleDefinition *rule = NULL;
137 if(ruleType == ConsoleGameRules::eGameRuleType_ApplySchematic)
138 {
139 rule = new ApplySchematicRuleDefinition(this);
140 m_schematicRules.push_back((ApplySchematicRuleDefinition *)rule);
141 }
142 else if(ruleType == ConsoleGameRules::eGameRuleType_GenerateStructure)
143 {
144 rule = new ConsoleGenerateStructure();
145 m_structureRules.push_back((ConsoleGenerateStructure *)rule);
146 }
147 else if(ruleType == ConsoleGameRules::eGameRuleType_BiomeOverride)
148 {
149 rule = new BiomeOverride();
150 m_biomeOverrides.push_back((BiomeOverride *)rule);
151 }
152 else if(ruleType == ConsoleGameRules::eGameRuleType_StartFeature)
153 {
154 rule = new StartFeature();
155 m_features.push_back((StartFeature *)rule);
156 }
157 else
158 {
159#ifndef _CONTENT_PACKAGE
160 wprintf(L"LevelGenerationOptions: Attempted to add invalid child rule - %d\n", ruleType );
161#endif
162 }
163 return rule;
164}
165
166void LevelGenerationOptions::addAttribute(const wstring &attributeName, const wstring &attributeValue)
167{
168 if(attributeName.compare(L"seed") == 0)
169 {
170 m_seed = _fromString<__int64>(attributeValue);
171 app.DebugPrintf("LevelGenerationOptions: Adding parameter m_seed=%I64d\n",m_seed);
172 }
173 else if(attributeName.compare(L"spawnX") == 0)
174 {
175 if(m_spawnPos == NULL) m_spawnPos = new Pos();
176 int value = _fromString<int>(attributeValue);
177 m_spawnPos->x = value;
178 app.DebugPrintf("LevelGenerationOptions: Adding parameter spawnX=%d\n",value);
179 }
180 else if(attributeName.compare(L"spawnY") == 0)
181 {
182 if(m_spawnPos == NULL) m_spawnPos = new Pos();
183 int value = _fromString<int>(attributeValue);
184 m_spawnPos->y = value;
185 app.DebugPrintf("LevelGenerationOptions: Adding parameter spawnY=%d\n",value);
186 }
187 else if(attributeName.compare(L"spawnZ") == 0)
188 {
189 if(m_spawnPos == NULL) m_spawnPos = new Pos();
190 int value = _fromString<int>(attributeValue);
191 m_spawnPos->z = value;
192 app.DebugPrintf("LevelGenerationOptions: Adding parameter spawnZ=%d\n",value);
193 }
194 else if(attributeName.compare(L"flatworld") == 0)
195 {
196 if(attributeValue.compare(L"true") == 0) m_useFlatWorld = true;
197 app.DebugPrintf("LevelGenerationOptions: Adding parameter flatworld=%s\n",m_useFlatWorld?"TRUE":"FALSE");
198 }
199 else if(attributeName.compare(L"saveName") == 0)
200 {
201 wstring string(attributeValue);
202 if(!string.empty()) setDefaultSaveName( string );
203 else setDefaultSaveName( attributeValue );
204 app.DebugPrintf("LevelGenerationOptions: Adding parameter saveName=%ls\n", getDefaultSaveName().c_str());
205 }
206 else if(attributeName.compare(L"worldName") == 0)
207 {
208 wstring string(attributeValue);
209 if(!string.empty()) setWorldName( string );
210 else setWorldName( attributeValue );
211 app.DebugPrintf("LevelGenerationOptions: Adding parameter worldName=%ls\n", getWorldName());
212 }
213 else if(attributeName.compare(L"displayName") == 0)
214 {
215 wstring string(attributeValue);
216 if(!string.empty()) setDisplayName( string );
217 else setDisplayName( attributeValue );
218 app.DebugPrintf("LevelGenerationOptions: Adding parameter displayName=%ls\n", getDisplayName());
219 }
220 else if(attributeName.compare(L"texturePackId") == 0)
221 {
222 setRequiredTexturePackId( _fromString<unsigned int>(attributeValue) );
223 setRequiresTexturePack( true );
224 app.DebugPrintf("LevelGenerationOptions: Adding parameter texturePackId=%0x\n", getRequiredTexturePackId());
225 }
226 else if(attributeName.compare(L"isTutorial") == 0)
227 {
228 if(attributeValue.compare(L"true") == 0) setSrc(eSrc_tutorial);
229 app.DebugPrintf("LevelGenerationOptions: Adding parameter isTutorial=%s\n",isTutorial()?"TRUE":"FALSE");
230 }
231 else if(attributeName.compare(L"baseSaveName") == 0)
232 {
233 setBaseSavePath( attributeValue );
234 app.DebugPrintf("LevelGenerationOptions: Adding parameter baseSaveName=%ls\n", getBaseSavePath().c_str());
235 }
236 else if(attributeName.compare(L"hasBeenInCreative") == 0)
237 {
238 bool value = _fromString<bool>(attributeValue);
239 m_bHasBeenInCreative = value;
240 app.DebugPrintf("LevelGenerationOptions: Adding parameter gameMode=%d\n", m_bHasBeenInCreative);
241 }
242 else
243 {
244 GameRuleDefinition::addAttribute(attributeName, attributeValue);
245 }
246}
247
248void LevelGenerationOptions::processSchematics(LevelChunk *chunk)
249{
250 PIXBeginNamedEvent(0,"Processing schematics for chunk (%d,%d)", chunk->x, chunk->z);
251 AABB *chunkBox = AABB::newTemp(chunk->x*16,0,chunk->z*16,chunk->x*16 + 16,Level::maxBuildHeight,chunk->z*16 + 16);
252 for( AUTO_VAR(it, m_schematicRules.begin()); it != m_schematicRules.end();++it)
253 {
254 ApplySchematicRuleDefinition *rule = *it;
255 rule->processSchematic(chunkBox, chunk);
256 }
257
258 int cx = (chunk->x << 4);
259 int cz = (chunk->z << 4);
260
261 for( AUTO_VAR(it, m_structureRules.begin()); it != m_structureRules.end(); it++ )
262 {
263 ConsoleGenerateStructure *structureStart = *it;
264
265 if (structureStart->getBoundingBox()->intersects(cx, cz, cx + 15, cz + 15))
266 {
267 BoundingBox *bb = new BoundingBox(cx, cz, cx + 15, cz + 15);
268 structureStart->postProcess(chunk->level, NULL, bb);
269 delete bb;
270 }
271 }
272 PIXEndNamedEvent();
273}
274
275void LevelGenerationOptions::processSchematicsLighting(LevelChunk *chunk)
276{
277 PIXBeginNamedEvent(0,"Processing schematics (lighting) for chunk (%d,%d)", chunk->x, chunk->z);
278 AABB *chunkBox = AABB::newTemp(chunk->x*16,0,chunk->z*16,chunk->x*16 + 16,Level::maxBuildHeight,chunk->z*16 + 16);
279 for( AUTO_VAR(it, m_schematicRules.begin()); it != m_schematicRules.end();++it)
280 {
281 ApplySchematicRuleDefinition *rule = *it;
282 rule->processSchematicLighting(chunkBox, chunk);
283 }
284 PIXEndNamedEvent();
285}
286
287bool LevelGenerationOptions::checkIntersects(int x0, int y0, int z0, int x1, int y1, int z1)
288{
289 PIXBeginNamedEvent(0,"Check Intersects");
290
291 // As an optimisation, we can quickly discard things below a certain y which makes most ore checks faster due to
292 // a) ores generally being below ground/sea level and b) tutorial world additions generally being above ground/sea level
293 if(!m_bHaveMinY)
294 {
295 for(AUTO_VAR(it, m_schematicRules.begin()); it != m_schematicRules.end();++it)
296 {
297 ApplySchematicRuleDefinition *rule = *it;
298 int minY = rule->getMinY();
299 if(minY < m_minY) m_minY = minY;
300 }
301
302 for( AUTO_VAR(it, m_structureRules.begin()); it != m_structureRules.end(); it++ )
303 {
304 ConsoleGenerateStructure *structureStart = *it;
305 int minY = structureStart->getMinY();
306 if(minY < m_minY) m_minY = minY;
307 }
308
309 m_bHaveMinY = true;
310 }
311
312 // 4J Stu - We DO NOT intersect if our upper bound is below the lower bound for all schematics
313 if( y1 < m_minY ) return false;
314
315 bool intersects = false;
316 for(AUTO_VAR(it, m_schematicRules.begin()); it != m_schematicRules.end();++it)
317 {
318 ApplySchematicRuleDefinition *rule = *it;
319 intersects = rule->checkIntersects(x0,y0,z0,x1,y1,z1);
320 if(intersects) break;
321 }
322
323 if(!intersects)
324 {
325 for( AUTO_VAR(it, m_structureRules.begin()); it != m_structureRules.end(); it++ )
326 {
327 ConsoleGenerateStructure *structureStart = *it;
328 intersects = structureStart->checkIntersects(x0,y0,z0,x1,y1,z1);
329 if(intersects) break;
330 }
331 }
332 PIXEndNamedEvent();
333 return intersects;
334}
335
336void LevelGenerationOptions::clearSchematics()
337{
338 for(AUTO_VAR(it, m_schematics.begin()); it != m_schematics.end(); ++it)
339 {
340 delete it->second;
341 }
342 m_schematics.clear();
343}
344
345ConsoleSchematicFile *LevelGenerationOptions::loadSchematicFile(const wstring &filename, PBYTE pbData, DWORD dwLen)
346{
347 // If we have already loaded this, just return
348 AUTO_VAR(it, m_schematics.find(filename));
349 if(it != m_schematics.end())
350 {
351#ifndef _CONTENT_PACKAGE
352 wprintf(L"We have already loaded schematic file %ls\n", filename.c_str() );
353#endif
354 it->second->incrementRefCount();
355 return it->second;
356 }
357
358 ConsoleSchematicFile *schematic = NULL;
359 byteArray data(pbData,dwLen);
360 ByteArrayInputStream bais(data);
361 DataInputStream dis(&bais);
362 schematic = new ConsoleSchematicFile();
363 schematic->load(&dis);
364 m_schematics[filename] = schematic;
365 bais.reset();
366 return schematic;
367}
368
369ConsoleSchematicFile *LevelGenerationOptions::getSchematicFile(const wstring &filename)
370{
371 ConsoleSchematicFile *schematic = NULL;
372 // If we have already loaded this, just return
373 AUTO_VAR(it, m_schematics.find(filename));
374 if(it != m_schematics.end())
375 {
376 schematic = it->second;
377 }
378 return schematic;
379}
380
381void LevelGenerationOptions::releaseSchematicFile(const wstring &filename)
382{
383 // 4J Stu - We don't want to delete them when done, but probably want to keep a set of active schematics for the current world
384 //AUTO_VAR(it, m_schematics.find(filename));
385 //if(it != m_schematics.end())
386 //{
387 // ConsoleSchematicFile *schematic = it->second;
388 // schematic->decrementRefCount();
389 // if(schematic->shouldDelete())
390 // {
391 // delete schematic;
392 // m_schematics.erase(it);
393 // }
394 //}
395}
396
397void LevelGenerationOptions::loadStringTable(StringTable *table)
398{
399 m_stringTable = table;
400}
401
402LPCWSTR LevelGenerationOptions::getString(const wstring &key)
403{
404 if(m_stringTable == NULL)
405 {
406 return L"";
407 }
408 else
409 {
410 return m_stringTable->getString(key);
411 }
412}
413
414void LevelGenerationOptions::getBiomeOverride(int biomeId, BYTE &tile, BYTE &topTile)
415{
416 for(AUTO_VAR(it, m_biomeOverrides.begin()); it != m_biomeOverrides.end(); ++it)
417 {
418 BiomeOverride *bo = *it;
419 if(bo->isBiome(biomeId))
420 {
421 bo->getTileValues(tile,topTile);
422 break;
423 }
424 }
425}
426
427bool LevelGenerationOptions::isFeatureChunk(int chunkX, int chunkZ, StructureFeature::EFeatureTypes feature, int *orientation)
428{
429 bool isFeature = false;
430
431 for(AUTO_VAR(it, m_features.begin()); it != m_features.end(); ++it)
432 {
433 StartFeature *sf = *it;
434 if(sf->isFeatureChunk(chunkX, chunkZ, feature, orientation))
435 {
436 isFeature = true;
437 break;
438 }
439 }
440 return isFeature;
441}
442
443unordered_map<wstring, ConsoleSchematicFile *> *LevelGenerationOptions::getUnfinishedSchematicFiles()
444{
445 // Clean schematic rules.
446 unordered_set<wstring> usedFiles = unordered_set<wstring>();
447 for (AUTO_VAR(it, m_schematicRules.begin()); it!=m_schematicRules.end(); it++)
448 if ( !(*it)->isComplete() )
449 usedFiles.insert( (*it)->getSchematicName() );
450
451 // Clean schematic files.
452 unordered_map<wstring, ConsoleSchematicFile *> *out
453 = new unordered_map<wstring, ConsoleSchematicFile *>();
454 for (AUTO_VAR(it, usedFiles.begin()); it!=usedFiles.end(); it++)
455 out->insert( pair<wstring, ConsoleSchematicFile *>(*it, getSchematicFile(*it)) );
456
457 return out;
458}
459
460void LevelGenerationOptions::loadBaseSaveData()
461{
462 int mountIndex = -1;
463 if(m_parentDLCPack != NULL) mountIndex = m_parentDLCPack->GetDLCMountIndex();
464
465 if(mountIndex > -1)
466 {
467#ifdef _DURANGO
468 if(StorageManager.MountInstalledDLC(ProfileManager.GetPrimaryPad(),mountIndex,&LevelGenerationOptions::packMounted,this,L"WPACK")!=ERROR_IO_PENDING)
469#else
470 if(StorageManager.MountInstalledDLC(ProfileManager.GetPrimaryPad(),mountIndex,&LevelGenerationOptions::packMounted,this,"WPACK")!=ERROR_IO_PENDING)
471#endif
472 {
473 // corrupt DLC
474 setLoadedData();
475 app.DebugPrintf("Failed to mount LGO DLC %d for pad %d\n",mountIndex,ProfileManager.GetPrimaryPad());
476 }
477 else
478 {
479 m_bLoadingData = true;
480 app.DebugPrintf("Attempted to mount DLC data for LGO %d\n", mountIndex);
481 }
482 }
483 else
484 {
485 setLoadedData();
486 app.SetAction(ProfileManager.GetPrimaryPad(), eAppAction_ReloadTexturePack);
487 }
488}
489
490int LevelGenerationOptions::packMounted(LPVOID pParam,int iPad,DWORD dwErr,DWORD dwLicenceMask)
491{
492 LevelGenerationOptions *lgo = (LevelGenerationOptions *)pParam;
493 lgo->m_bLoadingData = false;
494 if(dwErr!=ERROR_SUCCESS)
495 {
496 // corrupt DLC
497 app.DebugPrintf("Failed to mount LGO DLC for pad %d: %d\n",iPad,dwErr);
498 }
499 else
500 {
501 app.DebugPrintf("Mounted DLC for LGO, attempting to load data\n");
502 DWORD dwFilesProcessed = 0;
503 int gameRulesCount = lgo->m_parentDLCPack->getDLCItemsCount(DLCManager::e_DLCType_GameRulesHeader);
504 for(int i = 0; i < gameRulesCount; ++i)
505 {
506 DLCGameRulesHeader *dlcFile = (DLCGameRulesHeader *) lgo->m_parentDLCPack->getFile(DLCManager::e_DLCType_GameRulesHeader, i);
507
508 if (!dlcFile->getGrfPath().empty())
509 {
510 File grf( app.getFilePath(lgo->m_parentDLCPack->GetPackID(), dlcFile->getGrfPath(),true, L"WPACK:" ) );
511 if (grf.exists())
512 {
513#ifdef _UNICODE
514 wstring path = grf.getPath();
515 const WCHAR *pchFilename=path.c_str();
516 HANDLE fileHandle = CreateFile(
517 pchFilename, // file name
518 GENERIC_READ, // access mode
519 0, // share mode // TODO 4J Stu - Will we need to share file? Probably not but...
520 NULL, // Unused
521 OPEN_EXISTING , // how to create // TODO 4J Stu - Assuming that the file already exists if we are opening to read from it
522 FILE_FLAG_SEQUENTIAL_SCAN, // file attributes
523 NULL // Unsupported
524 );
525#else
526 const char *pchFilename=wstringtofilename(grf.getPath());
527 HANDLE fileHandle = CreateFile(
528 pchFilename, // file name
529 GENERIC_READ, // access mode
530 0, // share mode // TODO 4J Stu - Will we need to share file? Probably not but...
531 NULL, // Unused
532 OPEN_EXISTING , // how to create // TODO 4J Stu - Assuming that the file already exists if we are opening to read from it
533 FILE_FLAG_SEQUENTIAL_SCAN, // file attributes
534 NULL // Unsupported
535 );
536#endif
537
538 if( fileHandle != INVALID_HANDLE_VALUE )
539 {
540 DWORD dwFileSize = grf.length();
541 DWORD bytesRead;
542 PBYTE pbData = (PBYTE) new BYTE[dwFileSize];
543 BOOL bSuccess = ReadFile(fileHandle,pbData,dwFileSize,&bytesRead,NULL);
544 if(bSuccess==FALSE)
545 {
546 app.FatalLoadError();
547 }
548 CloseHandle(fileHandle);
549
550 // 4J-PB - is it possible that we can get here after a read fail and it's not an error?
551 dlcFile->setGrfData(pbData, dwFileSize, lgo->m_stringTable);
552
553 delete [] pbData;
554
555 app.m_gameRules.setLevelGenerationOptions( dlcFile->lgo );
556 }
557 }
558 }
559 }
560 if(lgo->requiresBaseSave() && !lgo->getBaseSavePath().empty() )
561 {
562 File save(app.getFilePath(lgo->m_parentDLCPack->GetPackID(), lgo->getBaseSavePath(),true, L"WPACK:" ));
563 if (save.exists())
564 {
565#ifdef _UNICODE
566 wstring path = save.getPath();
567 const WCHAR *pchFilename=path.c_str();
568 HANDLE fileHandle = CreateFile(
569 pchFilename, // file name
570 GENERIC_READ, // access mode
571 0, // share mode // TODO 4J Stu - Will we need to share file? Probably not but...
572 NULL, // Unused
573 OPEN_EXISTING , // how to create // TODO 4J Stu - Assuming that the file already exists if we are opening to read from it
574 FILE_FLAG_SEQUENTIAL_SCAN, // file attributes
575 NULL // Unsupported
576 );
577#else
578 const char *pchFilename=wstringtofilename(save.getPath());
579 HANDLE fileHandle = CreateFile(
580 pchFilename, // file name
581 GENERIC_READ, // access mode
582 0, // share mode // TODO 4J Stu - Will we need to share file? Probably not but...
583 NULL, // Unused
584 OPEN_EXISTING , // how to create // TODO 4J Stu - Assuming that the file already exists if we are opening to read from it
585 FILE_FLAG_SEQUENTIAL_SCAN, // file attributes
586 NULL // Unsupported
587 );
588#endif
589
590 if( fileHandle != INVALID_HANDLE_VALUE )
591 {
592 DWORD bytesRead,dwFileSize = GetFileSize(fileHandle,NULL);
593 PBYTE pbData = (PBYTE) new BYTE[dwFileSize];
594 BOOL bSuccess = ReadFile(fileHandle,pbData,dwFileSize,&bytesRead,NULL);
595 if(bSuccess==FALSE)
596 {
597 app.FatalLoadError();
598 }
599 CloseHandle(fileHandle);
600
601 // 4J-PB - is it possible that we can get here after a read fail and it's not an error?
602 lgo->setBaseSaveData(pbData, dwFileSize);
603 }
604 }
605
606 }
607#ifdef _DURANGO
608 DWORD result = StorageManager.UnmountInstalledDLC(L"WPACK");
609#else
610 DWORD result = StorageManager.UnmountInstalledDLC("WPACK");
611#endif
612
613 }
614
615 lgo->setLoadedData();
616
617 return 0;
618}
619
620void LevelGenerationOptions::reset_start()
621{
622 for ( AUTO_VAR( it, m_schematicRules.begin());
623 it != m_schematicRules.end();
624 it++ )
625 {
626 (*it)->reset();
627 }
628}
629
630void LevelGenerationOptions::reset_finish()
631{
632 //if (m_spawnPos) { delete m_spawnPos; m_spawnPos = NULL; }
633 //if (m_stringTable) { delete m_stringTable; m_stringTable = NULL; }
634
635 if (isFromDLC())
636 {
637 m_hasLoadedData = false;
638 }
639}
640
641
642GrSource *LevelGenerationOptions::info() { return m_pSrc; }
643void LevelGenerationOptions::setSrc(eSrc src) { m_src = src; }
644LevelGenerationOptions::eSrc LevelGenerationOptions::getSrc() { return m_src; }
645
646bool LevelGenerationOptions::isTutorial() { return getSrc() == eSrc_tutorial; }
647bool LevelGenerationOptions::isFromSave() { return getSrc() == eSrc_fromSave; }
648bool LevelGenerationOptions::isFromDLC() { return getSrc() == eSrc_fromDLC; }
649
650bool LevelGenerationOptions::requiresTexturePack() { return info()->requiresTexturePack(); }
651UINT LevelGenerationOptions::getRequiredTexturePackId() { return info()->getRequiredTexturePackId(); }
652
653wstring LevelGenerationOptions::getDefaultSaveName()
654{
655 switch (getSrc())
656 {
657 case eSrc_fromSave: return getString( info()->getDefaultSaveName() );
658 case eSrc_fromDLC: return getString( info()->getDefaultSaveName() );
659 case eSrc_tutorial: return app.GetString(IDS_TUTORIALSAVENAME);
660 }
661 return L"";
662}
663LPCWSTR LevelGenerationOptions::getWorldName()
664{
665 switch (getSrc())
666 {
667 case eSrc_fromSave: return getString( info()->getWorldName() );
668 case eSrc_fromDLC: return getString( info()->getWorldName() );
669 case eSrc_tutorial: return app.GetString(IDS_PLAY_TUTORIAL);
670 }
671 return L"";
672}
673LPCWSTR LevelGenerationOptions::getDisplayName()
674{
675 switch (getSrc())
676 {
677 case eSrc_fromSave: return getString( info()->getDisplayName() );
678 case eSrc_fromDLC: return getString( info()->getDisplayName() );
679 case eSrc_tutorial: return L"";
680 }
681 return L"";
682}
683
684wstring LevelGenerationOptions::getGrfPath() { return info()->getGrfPath(); }
685bool LevelGenerationOptions::requiresBaseSave() { return info()->requiresBaseSave(); }
686wstring LevelGenerationOptions::getBaseSavePath() { return info()->getBaseSavePath(); }
687
688void LevelGenerationOptions::setGrSource(GrSource *grs) { m_pSrc = grs; }
689
690void LevelGenerationOptions::setRequiresTexturePack(bool x) { info()->setRequiresTexturePack(x); }
691void LevelGenerationOptions::setRequiredTexturePackId(UINT x) { info()->setRequiredTexturePackId(x); }
692void LevelGenerationOptions::setDefaultSaveName(const wstring &x) { info()->setDefaultSaveName(x); }
693void LevelGenerationOptions::setWorldName(const wstring &x) { info()->setWorldName(x); }
694void LevelGenerationOptions::setDisplayName(const wstring &x) { info()->setDisplayName(x); }
695void LevelGenerationOptions::setGrfPath(const wstring &x) { info()->setGrfPath(x); }
696void LevelGenerationOptions::setBaseSavePath(const wstring &x) { info()->setBaseSavePath(x); }
697
698bool LevelGenerationOptions::ready() { return info()->ready(); }
699
700void LevelGenerationOptions::setBaseSaveData(PBYTE pbData, DWORD dwSize) { m_pbBaseSaveData = pbData; m_dwBaseSaveSize = dwSize; }
701PBYTE LevelGenerationOptions::getBaseSaveData(DWORD &size) { size = m_dwBaseSaveSize; return m_pbBaseSaveData; }
702bool LevelGenerationOptions::hasBaseSaveData() { return m_dwBaseSaveSize > 0 && m_pbBaseSaveData != NULL; }
703void LevelGenerationOptions::deleteBaseSaveData() { if(m_pbBaseSaveData) delete m_pbBaseSaveData; m_pbBaseSaveData = NULL; m_dwBaseSaveSize = 0; }
704
705bool LevelGenerationOptions::hasLoadedData() { return m_hasLoadedData; }
706void LevelGenerationOptions::setLoadedData() { m_hasLoadedData = true; }
707
708__int64 LevelGenerationOptions::getLevelSeed() { return m_seed; }
709int LevelGenerationOptions::getLevelHasBeenInCreative() { return m_bHasBeenInCreative; }
710Pos *LevelGenerationOptions::getSpawnPos() { return m_spawnPos; }
711bool LevelGenerationOptions::getuseFlatWorld() { return m_useFlatWorld; }
712
713bool LevelGenerationOptions::requiresGameRules() { return m_bRequiresGameRules; }
714void LevelGenerationOptions::setRequiredGameRules(LevelRuleset *rules) { m_requiredGameRules = rules; m_bRequiresGameRules = true; }
715LevelRuleset *LevelGenerationOptions::getRequiredGameRules() { return m_requiredGameRules; }