mirror of
https://github.com/neoStudiosLCE/neoLegacy.git
synced 2026-06-08 22:12:56 +00:00
feat: Feat/expanded worlds (#107)
* it works kinda but its laggy * attempt at making it faster * Revert "attempt at making it faster" This reverts commit32a68ed3ae. * Revert "it works kinda but its laggy" This reverts commit2830b973d4. * round robin client chunk cache, expanded world type
This commit is contained in:
parent
5d196d97cf
commit
98c33aa677
|
|
@ -56,7 +56,8 @@ enum EGameHostOptionWorldSize
|
|||
e_worldSize_Classic,
|
||||
e_worldSize_Small,
|
||||
e_worldSize_Medium,
|
||||
e_worldSize_Large
|
||||
e_worldSize_Large,
|
||||
e_worldSize_Expanded
|
||||
};
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -15,8 +15,8 @@ MultiPlayerChunkCache::MultiPlayerChunkCache(Level *level)
|
|||
XZSIZE = level->dimension->getXZSize(); // 4J Added
|
||||
XZOFFSET = XZSIZE/2; // 4J Added
|
||||
m_XZSize = XZSIZE;
|
||||
hasData = new bool[XZSIZE * XZSIZE];
|
||||
memset(hasData, 0, sizeof(bool) * XZSIZE * XZSIZE);
|
||||
hasData = new bool[LEVEL_MIN_WIDTH * LEVEL_MIN_WIDTH];
|
||||
memset(hasData, 0, sizeof(bool) * LEVEL_MIN_WIDTH * LEVEL_MIN_WIDTH);
|
||||
|
||||
emptyChunk = new EmptyLevelChunk(level, byteArray(16 * 16 * Level::maxBuildHeight), 0, 0);
|
||||
|
||||
|
|
@ -93,8 +93,8 @@ MultiPlayerChunkCache::MultiPlayerChunkCache(Level *level)
|
|||
|
||||
this->level = level;
|
||||
|
||||
this->cache = new LevelChunk *[XZSIZE * XZSIZE];
|
||||
memset(this->cache, 0, XZSIZE * XZSIZE * sizeof(LevelChunk *));
|
||||
this->cache = new LevelChunk *[LEVEL_MIN_WIDTH * LEVEL_MIN_WIDTH];
|
||||
memset(this->cache, 0, sizeof(LevelChunk*) * LEVEL_MIN_WIDTH * LEVEL_MIN_WIDTH);
|
||||
InitializeCriticalSectionAndSpinCount(&m_csLoadCreate,4000);
|
||||
}
|
||||
|
||||
|
|
@ -129,10 +129,11 @@ bool MultiPlayerChunkCache::reallyHasChunk(int x, int z)
|
|||
// Check we're in range of the stored level - if we aren't, then consider that we do have that chunk as we'll be able to use the water chunk there
|
||||
if( ( ix < 0 ) || ( ix >= XZSIZE ) ) return true;
|
||||
if( ( iz < 0 ) || ( iz >= XZSIZE ) ) return true;
|
||||
int idx = ix * XZSIZE + iz;
|
||||
|
||||
int idx = wrapCoord(x, LEVEL_MIN_WIDTH) * LEVEL_MIN_WIDTH + wrapCoord(z, LEVEL_MIN_WIDTH);
|
||||
|
||||
LevelChunk *chunk = cache[idx];
|
||||
if( chunk == nullptr )
|
||||
if (chunk == nullptr || chunk->x != x || chunk->z != z)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
|
@ -145,10 +146,11 @@ void MultiPlayerChunkCache::drop(const int x, const int z)
|
|||
const int iz = z + XZOFFSET;
|
||||
if ((ix < 0) || (ix >= XZSIZE)) return;
|
||||
if ((iz < 0) || (iz >= XZSIZE)) return;
|
||||
const int idx = ix * XZSIZE + iz;
|
||||
|
||||
int idx = wrapCoord(x, LEVEL_MIN_WIDTH) * LEVEL_MIN_WIDTH + wrapCoord(z, LEVEL_MIN_WIDTH);
|
||||
LevelChunk* chunk = cache[idx];
|
||||
|
||||
if (chunk != nullptr && !chunk->isEmpty())
|
||||
if (chunk != nullptr && !chunk->isEmpty() && chunk->x == x && chunk->z == z)
|
||||
{
|
||||
// Drop entities in the chunks, especially for the case when a player is dead
|
||||
// as they will not get the RemoveEntity packet if an entity is removed.
|
||||
|
|
@ -168,11 +170,12 @@ LevelChunk *MultiPlayerChunkCache::create(int x, int z)
|
|||
// Check we're in range of the stored level
|
||||
if( ( ix < 0 ) || ( ix >= XZSIZE ) ) return ( waterChunk ? waterChunk : emptyChunk );
|
||||
if( ( iz < 0 ) || ( iz >= XZSIZE ) ) return ( waterChunk ? waterChunk : emptyChunk );
|
||||
int idx = ix * XZSIZE + iz;
|
||||
int idx = wrapCoord(x, LEVEL_MIN_WIDTH) * LEVEL_MIN_WIDTH + wrapCoord(z, LEVEL_MIN_WIDTH);
|
||||
|
||||
LevelChunk *chunk = cache[idx];
|
||||
LevelChunk *lastChunk = chunk;
|
||||
|
||||
if( chunk == nullptr )
|
||||
if( chunk == nullptr || chunk->x != x || chunk->z != z )
|
||||
{
|
||||
EnterCriticalSection(&m_csLoadCreate);
|
||||
|
||||
|
|
@ -251,10 +254,10 @@ LevelChunk *MultiPlayerChunkCache::getChunk(int x, int z)
|
|||
// Check we're in range of the stored level
|
||||
if( ( ix < 0 ) || ( ix >= XZSIZE ) ) return ( waterChunk ? waterChunk : emptyChunk );
|
||||
if( ( iz < 0 ) || ( iz >= XZSIZE ) ) return ( waterChunk ? waterChunk : emptyChunk );
|
||||
int idx = ix * XZSIZE + iz;
|
||||
int idx = wrapCoord(x, LEVEL_MIN_WIDTH) * LEVEL_MIN_WIDTH + wrapCoord(z, LEVEL_MIN_WIDTH);
|
||||
|
||||
LevelChunk *chunk = cache[idx];
|
||||
if( chunk == nullptr )
|
||||
if( chunk == nullptr || chunk->x != x || chunk->z != z )
|
||||
{
|
||||
return emptyChunk;
|
||||
}
|
||||
|
|
@ -313,6 +316,6 @@ void MultiPlayerChunkCache::dataReceived(int x, int z)
|
|||
// Check we're in range of the stored level
|
||||
if( ( ix < 0 ) || ( ix >= XZSIZE ) ) return;
|
||||
if( ( iz < 0 ) || ( iz >= XZSIZE ) ) return;
|
||||
int idx = ix * XZSIZE + iz;
|
||||
int idx = wrapCoord(x, LEVEL_MIN_WIDTH) * LEVEL_MIN_WIDTH + wrapCoord(z, LEVEL_MIN_WIDTH);
|
||||
hasData[idx] = true;
|
||||
}
|
||||
|
|
@ -45,4 +45,9 @@ public:
|
|||
virtual void dataReceived(int x, int z); // 4J added
|
||||
|
||||
virtual LevelChunk **getCache() { return cache; } // 4J added
|
||||
|
||||
static inline int wrapCoord(int v, int size) {
|
||||
int r = v % size;
|
||||
return (r < 0) ? r + size : r;
|
||||
}
|
||||
};
|
||||
|
|
@ -628,6 +628,8 @@ static std::string WorldSizeToPropertyValue(int worldSize)
|
|||
return "medium";
|
||||
case e_worldSize_Large:
|
||||
return "large";
|
||||
case e_worldSize_Expanded:
|
||||
return "expanded";
|
||||
case e_worldSize_Classic:
|
||||
default:
|
||||
return "classic";
|
||||
|
|
@ -644,6 +646,8 @@ static int WorldSizeToXzChunks(int worldSize)
|
|||
return LEVEL_WIDTH_MEDIUM;
|
||||
case e_worldSize_Large:
|
||||
return LEVEL_WIDTH_LARGE;
|
||||
case e_worldSize_Expanded:
|
||||
return LEVEL_WIDTH_EXPANDED;
|
||||
case e_worldSize_Classic:
|
||||
default:
|
||||
return LEVEL_WIDTH_CLASSIC;
|
||||
|
|
@ -659,6 +663,7 @@ static int WorldSizeToHellScale(int worldSize)
|
|||
case e_worldSize_Medium:
|
||||
return HELL_LEVEL_SCALE_MEDIUM;
|
||||
case e_worldSize_Large:
|
||||
case e_worldSize_Expanded:
|
||||
return HELL_LEVEL_SCALE_LARGE;
|
||||
case e_worldSize_Classic:
|
||||
default:
|
||||
|
|
@ -694,6 +699,12 @@ static bool TryParseWorldSize(const std::string &lowered, int *outWorldSize)
|
|||
return true;
|
||||
}
|
||||
|
||||
if (lowered == "expanded" || lowered == "344" || lowered == "8")
|
||||
{
|
||||
*outWorldSize = e_worldSize_Expanded;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -7,12 +7,14 @@ class TilePos;
|
|||
// The maximum number of chunks that we can store
|
||||
#ifdef _LARGE_WORLDS
|
||||
// 4J Stu - Our default map (at zoom level 3) is 1024x1024 blocks (or 64 chunks)
|
||||
#define LEVEL_MAX_WIDTH (5*64) //(6*54)
|
||||
|
||||
#define LEVEL_WIDTH_CLASSIC 54
|
||||
#define LEVEL_WIDTH_SMALL 64
|
||||
#define LEVEL_WIDTH_MEDIUM (3*64)
|
||||
#define LEVEL_WIDTH_LARGE (5*64)
|
||||
#define LEVEL_WIDTH_EXPANDED (5*64) + 24
|
||||
|
||||
|
||||
#define LEVEL_MAX_WIDTH LEVEL_WIDTH_EXPANDED
|
||||
|
||||
#else
|
||||
#define LEVEL_MAX_WIDTH 54
|
||||
|
|
|
|||
|
|
@ -46,6 +46,7 @@ DWORD Level::tlsIdxLightCache = TlsAlloc();
|
|||
|
||||
// 4J : WESTY : Added for time played stats.
|
||||
#include "net.minecraft.stats.h"
|
||||
#include "../Minecraft.Client/MultiPlayerChunkCache.h"
|
||||
|
||||
// 4J - Caching of lighting data added. This is implemented as a 16x16x16 cache of ints (ie 16K storage in total). The index of the element to be used in the array is determined by the lower
|
||||
// four bits of each x/y/z position, and the upper 7/4/7 bits of the x/y/z positions are stored within the element itself along with the cached values etc. The cache can be enabled per thread by
|
||||
|
|
@ -1332,10 +1333,10 @@ int Level::getBrightness(LightLayer::variety layer, int x, int y, int z)
|
|||
|
||||
if( ( ix < 0 ) || ( ix >= chunkSourceXZSize ) ) return 0;
|
||||
if( ( iz < 0 ) || ( iz >= chunkSourceXZSize ) ) return 0;
|
||||
int idx = ix * chunkSourceXZSize + iz;
|
||||
int idx = MultiPlayerChunkCache::wrapCoord(ix, LEVEL_MIN_WIDTH) * LEVEL_MIN_WIDTH + MultiPlayerChunkCache::wrapCoord(iz, LEVEL_MIN_WIDTH);
|
||||
LevelChunk *c = chunkSourceCache[idx];
|
||||
|
||||
if( c == nullptr ) return (int)layer;
|
||||
if( c == nullptr) return (int)layer;
|
||||
|
||||
if (y < 0) y = 0;
|
||||
if (y >= maxBuildHeight) y = maxBuildHeight - 1;
|
||||
|
|
@ -1381,7 +1382,7 @@ void Level::getNeighbourBrightnesses(int *brightnesses, LightLayer::variety laye
|
|||
return;
|
||||
}
|
||||
|
||||
int idx = ix * chunkSourceXZSize + iz;
|
||||
int idx = MultiPlayerChunkCache::wrapCoord(ix, LEVEL_MIN_WIDTH) * LEVEL_MIN_WIDTH + MultiPlayerChunkCache::wrapCoord(iz, LEVEL_MIN_WIDTH);
|
||||
LevelChunk *c = chunkSourceCache[idx];
|
||||
|
||||
// 4J Stu - The java LightLayer was an enum class type with a member "surrounding" which is what we
|
||||
|
|
|
|||
|
|
@ -185,6 +185,7 @@ LevelData::LevelData(CompoundTag *tag)
|
|||
case LEVEL_WIDTH_SMALL: hostOptionworldSize = e_worldSize_Small; break;
|
||||
case LEVEL_WIDTH_MEDIUM: hostOptionworldSize = e_worldSize_Medium; break;
|
||||
case LEVEL_WIDTH_LARGE: hostOptionworldSize = e_worldSize_Large; break;
|
||||
case LEVEL_WIDTH_EXPANDED: hostOptionworldSize = e_worldSize_Expanded; break;
|
||||
default: assert(0); break;
|
||||
}
|
||||
app.SetGameHostOption(eGameHostOption_WorldSize, hostOptionworldSize );
|
||||
|
|
|
|||
Loading…
Reference in a new issue