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 "net.minecraft.world.level.biome.h"
3#include "net.minecraft.world.level.chunk.h"
4#include "net.minecraft.world.level.dimension.h"
5#include "net.minecraft.world.level.tile.h"
6#include "net.minecraft.world.level.redstone.h"
7#include "Material.h"
8#include "Level.h"
9
10#include "Region.h"
11
12
13Region::~Region()
14{
15 for(unsigned int i = 0; i < chunks->length; ++i)
16 {
17 LevelChunkArray *lca = (*chunks)[i];
18 delete [] lca->data;
19 delete lca;
20 }
21 delete [] chunks->data;
22 delete chunks;
23
24 // AP - added a caching system for Chunk::rebuild to take advantage of
25 if( CachedTiles )
26 {
27 free(CachedTiles);
28 }
29}
30
31Region::Region(Level *level, int x1, int y1, int z1, int x2, int y2, int z2, int r)
32{
33 this->level = level;
34
35 xc1 = (x1 - r) >> 4;
36 zc1 = (z1 - r) >> 4;
37 int xc2 = (x2 + r) >> 4;
38 int zc2 = (z2 + r) >> 4;
39
40 chunks = new LevelChunk2DArray(xc2 - xc1 + 1, zc2 - zc1 + 1);
41
42 allEmpty = true;
43 for (int xc = xc1; xc <= xc2; xc++)
44 {
45 for (int zc = zc1; zc <= zc2; zc++)
46 {
47 LevelChunk *chunk = level->getChunk(xc, zc);
48 if(chunk != NULL)
49 {
50 LevelChunkArray *lca = (*chunks)[xc - xc1];
51 lca->data[zc - zc1] = chunk;
52 }
53 }
54 }
55 for (int xc = (x1 >> 4); xc <= (x2 >> 4); xc++)
56 {
57 for (int zc = (z1 >> 4); zc <= (z2 >> 4); zc++)
58 {
59 LevelChunkArray *lca = (*chunks)[xc - xc1];
60 LevelChunk *chunk = lca->data[zc - zc1];
61 if (chunk != NULL)
62 {
63 if (!chunk->isYSpaceEmpty(y1, y2))
64 {
65 allEmpty = false;
66 }
67 }
68 }
69 }
70
71 // AP - added a caching system for Chunk::rebuild to take advantage of
72 xcCached = -1;
73 zcCached = -1;
74 CachedTiles = NULL;
75}
76
77bool Region::isAllEmpty()
78{
79 return allEmpty;
80}
81
82int Region::getTile(int x, int y, int z)
83{
84 if (y < 0) return 0;
85 if (y >= Level::maxBuildHeight) return 0;
86
87 int xc = (x >> 4);
88 int zc = (z >> 4);
89
90#ifdef __PSVITA__
91 // AP - added a caching system for Chunk::rebuild to take advantage of
92 if( CachedTiles && xc == xcCached && zc == zcCached )
93 {
94 unsigned char* Tiles = CachedTiles;
95 Tiles += y;
96 if(y >= Level::COMPRESSED_CHUNK_SECTION_HEIGHT)
97 {
98 Tiles += Level::COMPRESSED_CHUNK_SECTION_TILES - Level::COMPRESSED_CHUNK_SECTION_HEIGHT;
99 }
100
101 return Tiles[ ( (x & 15) << 11 ) | ( (z & 15) << 7 ) ];
102 }
103#endif
104
105 xc -= xc1;
106 zc -= zc1;
107
108 if (xc < 0 || xc >= (int)chunks->length || zc < 0 || zc >= (int)(*chunks)[xc]->length)
109 {
110 return 0;
111 }
112
113 LevelChunk *lc = (*chunks)[xc]->data[zc];
114 if (lc == NULL) return 0;
115
116 return lc->getTile(x & 15, y, z & 15);
117}
118
119// AP - added a caching system for Chunk::rebuild to take advantage of
120void Region::setCachedTiles(unsigned char *tiles, int xc, int zc)
121{
122 xcCached = xc;
123 zcCached = zc;
124 int size = 16 * 16 * Level::maxBuildHeight;
125 if( CachedTiles == NULL )
126 {
127 CachedTiles = (unsigned char *) malloc(size);
128 }
129 memcpy(CachedTiles, tiles, size);
130}
131
132LevelChunk* Region::getLevelChunk(int x, int y, int z)
133{
134 if (y < 0) return 0;
135 if (y >= Level::maxBuildHeight) return NULL;
136
137 int xc = (x >> 4) - xc1;
138 int zc = (z >> 4) - zc1;
139
140 if (xc < 0 || xc >= (int)chunks->length || zc < 0 || zc >= (int)(*chunks)[xc]->length)
141 {
142 return NULL;
143 }
144
145 LevelChunk *lc = (*chunks)[xc]->data[zc];
146 return lc;
147}
148
149
150
151shared_ptr<TileEntity> Region::getTileEntity(int x, int y, int z)
152{
153 int xc = (x >> 4) - xc1;
154 int zc = (z >> 4) - zc1;
155
156 return (*chunks)[xc]->data[zc]->getTileEntity(x & 15, y, z & 15);
157}
158
159int Region::getLightColor(int x, int y, int z, int emitt, int tileId/*=-1*/)
160{
161 int s = getBrightnessPropagate(LightLayer::Sky, x, y, z, tileId);
162 int b = getBrightnessPropagate(LightLayer::Block, x, y, z, tileId);
163 if (b < emitt) b = emitt;
164 return s << 20 | b << 4;
165}
166
167float Region::getBrightness(int x, int y, int z, int emitt)
168{
169 int n = getRawBrightness(x, y, z);
170 if (n < emitt) n = emitt;
171 return level->dimension->brightnessRamp[n];
172}
173
174
175float Region::getBrightness(int x, int y, int z)
176{
177 return level->dimension->brightnessRamp[getRawBrightness(x, y, z)];
178}
179
180
181int Region::getRawBrightness(int x, int y, int z)
182{
183 return getRawBrightness(x, y, z, true);
184}
185
186
187int Region::getRawBrightness(int x, int y, int z, bool propagate)
188{
189 if (x < -Level::MAX_LEVEL_SIZE || z < -Level::MAX_LEVEL_SIZE || x >= Level::MAX_LEVEL_SIZE || z > Level::MAX_LEVEL_SIZE)
190 {
191 return Level::MAX_BRIGHTNESS;
192 }
193
194 if (propagate)
195 {
196 int id = getTile(x, y, z);
197 switch(id)
198 {
199 case Tile::stoneSlabHalf_Id:
200 case Tile::woodSlabHalf_Id:
201 case Tile::farmland_Id:
202 case Tile::stairs_stone_Id:
203 case Tile::stairs_wood_Id:
204 {
205 int br = getRawBrightness(x, y + 1, z, false);
206 int br1 = getRawBrightness(x + 1, y, z, false);
207 int br2 = getRawBrightness(x - 1, y, z, false);
208 int br3 = getRawBrightness(x, y, z + 1, false);
209 int br4 = getRawBrightness(x, y, z - 1, false);
210 if (br1 > br) br = br1;
211 if (br2 > br) br = br2;
212 if (br3 > br) br = br3;
213 if (br4 > br) br = br4;
214 return br;
215 }
216 break;
217 }
218 }
219
220 if (y < 0) return 0;
221 if (y >= Level::maxBuildHeight)
222 {
223 int br = Level::MAX_BRIGHTNESS - level->skyDarken;
224 if (br < 0) br = 0;
225 return br;
226 }
227
228 int xc = (x >> 4) - xc1;
229 int zc = (z >> 4) - zc1;
230
231 return (*chunks)[xc]->data[zc]->getRawBrightness(x & 15, y, z & 15, level->skyDarken);
232}
233
234
235int Region::getData(int x, int y, int z)
236{
237 if (y < 0) return 0;
238 if (y >= Level::maxBuildHeight) return 0;
239 int xc = (x >> 4) - xc1;
240 int zc = (z >> 4) - zc1;
241
242 return (*chunks)[xc]->data[zc]->getData(x & 15, y, z & 15);
243}
244
245Material *Region::getMaterial(int x, int y, int z)
246{
247 int t = getTile(x, y, z);
248 if (t == 0) return Material::air;
249 return Tile::tiles[t]->material;
250}
251
252
253BiomeSource *Region::getBiomeSource()
254{
255 return level->getBiomeSource();
256}
257
258Biome *Region::getBiome(int x, int z)
259{
260 return level->getBiome(x, z);
261}
262
263bool Region::isSolidRenderTile(int x, int y, int z)
264{
265 Tile *tile = Tile::tiles[getTile(x, y, z)];
266 if (tile == NULL) return false;
267
268 // 4J - addition here to make rendering big blocks of leaves more efficient. Normally leaves never consider themselves as solid, so
269 // blocks of leaves will have all sides of each block completely visible. Changing to consider as solid if this block is surrounded by
270 // other leaves (or solid things). This is paired with another change in Tile::getTexture which makes such solid tiles actually visibly solid (these
271 // textures exist already for non-fancy graphics). Note: this tile-specific code is here rather than making some new virtual method in the tiles,
272 // for the sake of efficiency - I don't imagine we'll be doing much more of this sort of thing
273 if( tile->id == Tile::leaves_Id )
274 {
275 int axo[6] = { 1,-1, 0, 0, 0, 0};
276 int ayo[6] = { 0, 0, 1,-1, 0, 0};
277 int azo[6] = { 0, 0, 0, 0, 1,-1};
278 for( int i = 0; i < 6; i++ )
279 {
280 int t = getTile(x + axo[i], y + ayo[i] , z + azo[i]);
281 if( ( t != Tile::leaves_Id ) && ( ( Tile::tiles[t] == NULL ) || !Tile::tiles[t]->isSolidRender() ) )
282 {
283 return false;
284 }
285 }
286
287 return true;
288 }
289
290 return tile->isSolidRender();
291}
292
293
294bool Region::isSolidBlockingTile(int x, int y, int z)
295{
296 Tile *tile = Tile::tiles[getTile(x, y, z)];
297 if (tile == NULL) return false;
298 return tile->material->blocksMotion() && tile->isCubeShaped();
299}
300
301bool Region::isTopSolidBlocking(int x, int y, int z)
302{
303 Tile *tile = Tile::tiles[getTile(x, y, z)];
304 return level->isTopSolidBlocking(tile, getData(x, y, z));
305}
306
307bool Region::isEmptyTile(int x, int y, int z)
308{
309 Tile *tile = Tile::tiles[getTile(x, y, z)];
310 return (tile == NULL);
311}
312
313
314// 4J - brought forward from 1.8.2
315int Region::getBrightnessPropagate(LightLayer::variety layer, int x, int y, int z, int tileId)
316{
317 if (y < 0) y = 0;
318 if (y >= Level::maxBuildHeight) y = Level::maxBuildHeight - 1;
319 if (y < 0 || y >= Level::maxBuildHeight || x < -Level::MAX_LEVEL_SIZE || z < -Level::MAX_LEVEL_SIZE || x >= Level::MAX_LEVEL_SIZE || z > Level::MAX_LEVEL_SIZE)
320 {
321 // 4J Stu - The java LightLayer was an enum class type with a member "surrounding" which is what we
322 // were returning here. Surrounding has the same value as the enum value in our C++ code, so just cast
323 // it to an int
324 return (int)layer;
325 }
326 if (layer == LightLayer::Sky && level->dimension->hasCeiling)
327 {
328 return 0;
329 }
330
331 int id = tileId > -1 ? tileId : getTile(x, y, z);
332 if (Tile::propagate[id])
333 {
334 int br = getBrightness(layer, x, y + 1, z); if( br == 15 ) return 15;
335 int br1 = getBrightness(layer, x + 1, y, z); if( br1 == 15 ) return 15;
336 int br2 = getBrightness(layer, x - 1, y, z); if( br2 == 15 ) return 15;
337 int br3 = getBrightness(layer, x, y, z + 1); if( br3 == 15 ) return 15;
338 int br4 = getBrightness(layer, x, y, z - 1); if( br4 == 15 ) return 15;
339 if (br1 > br) br = br1;
340 if (br2 > br) br = br2;
341 if (br3 > br) br = br3;
342 if (br4 > br) br = br4;
343 return br;
344 }
345
346 int xc = (x >> 4) - xc1;
347 int zc = (z >> 4) - zc1;
348
349 return (*chunks)[xc]->data[zc]->getBrightness(layer, x & 15, y, z & 15);
350}
351
352// 4J - brought forward from 1.8.2
353int Region::getBrightness(LightLayer::variety layer, int x, int y, int z)
354{
355 if (y < 0) y = 0;
356 if (y >= Level::maxBuildHeight) y = Level::maxBuildHeight - 1;
357 if (y < 0 || y >= Level::maxBuildHeight || x < -Level::MAX_LEVEL_SIZE || z < -Level::MAX_LEVEL_SIZE || x >= Level::MAX_LEVEL_SIZE || z > Level::MAX_LEVEL_SIZE)
358 {
359 // 4J Stu - The java LightLayer was an enum class type with a member "surrounding" which is what we
360 // were returning here. Surrounding has the same value as the enum value in our C++ code, so just cast
361 // it to an int
362 return (int)layer;
363 }
364 int xc = (x >> 4) - xc1;
365 int zc = (z >> 4) - zc1;
366
367 return (*chunks)[xc]->data[zc]->getBrightness(layer, x & 15, y, z & 15);
368}
369
370int Region::getMaxBuildHeight()
371{
372 return Level::maxBuildHeight;
373}
374
375int Region::getDirectSignal(int x, int y, int z, int dir)
376{
377 int t = getTile(x, y, z);
378 if (t == 0) return Redstone::SIGNAL_NONE;
379 return Tile::tiles[t]->getDirectSignal(this, x, y, z, dir);
380}