aboutsummaryrefslogtreecommitdiff
path: root/Minecraft.World/FlatLevelSource.cpp
blob: ec2c0f9606a1062cc06a5ef6167ea44cdb755373 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
#include "stdafx.h"
#include "net.minecraft.world.level.h"
#include "net.minecraft.world.level.levelgen.h"
#include "net.minecraft.world.level.levelgen.feature.h"
#include "net.minecraft.world.level.levelgen.structure.h"
#include "net.minecraft.world.level.levelgen.synth.h"
#include "net.minecraft.world.level.tile.h"
#include "net.minecraft.world.level.storage.h"
#include "FlatLevelSource.h"


//FlatLevelSource::villageFeature = new VillageFeature(1);

FlatLevelSource::FlatLevelSource(Level *level, int64_t seed, bool generateStructures)
{
	m_XZSize = level->getLevelData()->getXZSize();

	this->level = level;
	this->generateStructures = generateStructures;
	this->random = new Random(seed);
	this->pprandom = new Random(seed);		// 4J - added, so that we can have a separate random for doing post-processing in parallel with creation

	villageFeature = new VillageFeature(m_XZSize);


}

FlatLevelSource::~FlatLevelSource()
{
	delete random;
	delete pprandom;
	delete villageFeature;
}

void FlatLevelSource::prepareHeights(byteArray blocks)
{
	int height = blocks.length / (16 * 16);

	for (int xc = 0; xc < 16; xc++)
	{
		for (int zc = 0; zc < 16; zc++)
		{
			for (int yc = 0; yc < height; yc++)
			{
				int block = 0;
				if (yc == 0)
				{
					block = Tile::unbreakable_Id;
				}
				else if (yc <= 2)
				{
					block = Tile::dirt_Id;
				}
				else if (yc == 3)
				{
					block = Tile::grass_Id;
				}
				blocks[xc << 11 | zc << 7 | yc] = (byte) block;
			}
		}
	}
}

LevelChunk *FlatLevelSource::create(int x, int z)
{
	return getChunk(x, z);
}

LevelChunk *FlatLevelSource::getChunk(int xOffs, int zOffs)
{
	// 4J - now allocating this with a physical alloc & bypassing general memory management so that it will get cleanly freed
	int chunksSize = Level::genDepth * 16  * 16;
	byte *tileData = (byte *)XPhysicalAlloc(chunksSize, MAXULONG_PTR, 4096, PAGE_READWRITE);
	XMemSet128(tileData,0,chunksSize);
	byteArray blocks = byteArray(tileData,chunksSize);
//	byteArray blocks = byteArray(16 * level->depth * 16);
	prepareHeights(blocks);

//	LevelChunk *levelChunk = new LevelChunk(level, blocks, xOffs, zOffs);		// 4J - moved below
	//        double[] temperatures = level.getBiomeSource().temperatures;


	if (generateStructures)
	{
		villageFeature->apply(this, level, xOffs, zOffs, blocks);
	}

	// 4J - this now creates compressed block data from the blocks array passed in, so moved it until after the blocks are actually finalised. We also
	// now need to free the passed in blocks as the LevelChunk doesn't use the passed in allocation anymore.
	LevelChunk *levelChunk = new LevelChunk(level, blocks, xOffs, zOffs);
	XPhysicalFree(tileData);

	levelChunk->recalcHeightmap();

	return levelChunk;
}


bool FlatLevelSource::hasChunk(int x, int y)
{
	return true;
}

void FlatLevelSource::postProcess(ChunkSource *parent, int xt, int zt)
{
	// 4J - changed from random to pprandom so we can run in parallel with getChunk etc.
	pprandom->setSeed(level->getSeed());
	int64_t xScale = pprandom->nextLong() / 2 * 2 + 1;
	int64_t zScale = pprandom->nextLong() / 2 * 2 + 1;
	pprandom->setSeed(((xt * xScale) + (zt * zScale)) ^ level->getSeed());

	if (generateStructures)
	{
		villageFeature->postProcess(level, pprandom, xt, zt);
	}

	app.processSchematics(parent->getChunk(xt,zt));
}

bool FlatLevelSource::save(bool force, ProgressListener *progressListener)
{
	return true;
}

bool FlatLevelSource::tick()
{
	return false;
}

bool FlatLevelSource::shouldSave()
{
	return true;
}

wstring FlatLevelSource::gatherStats()
{
	return L"FlatLevelSource";
}

vector<Biome::MobSpawnerData *> *FlatLevelSource::getMobsAt(MobCategory *mobCategory, int x, int y, int z)
{
 	Biome *biome = level->getBiome(x, z);
 	if (biome == NULL)
 	{
 		return NULL;
 	}
 	return biome->getMobs(mobCategory);
}

TilePos *FlatLevelSource::findNearestMapFeature(Level *level, const wstring& featureName, int x, int y, int z)
{
	return NULL;
}

void FlatLevelSource::recreateLogicStructuresForChunk(int chunkX, int chunkZ)
{
	// TODO
}