mirror of
https://github.com/LCEMP/LCEMP.git
synced 2026-08-20 09:57:09 +00:00
fix: multiple savefile fixes
This commit is contained in:
parent
c1a9648bf4
commit
ff2cb7b582
|
|
@ -1474,6 +1474,33 @@ void MinecraftServer::tick()
|
||||||
|
|
||||||
tickCount++;
|
tickCount++;
|
||||||
|
|
||||||
|
#ifdef WITH_SERVER_CODE
|
||||||
|
if (tickCount % 6000 == 0 && !s_bServerHalted)
|
||||||
|
{
|
||||||
|
app.DebugPrintf("Auto-saving world...\n");
|
||||||
|
if (players != NULL)
|
||||||
|
{
|
||||||
|
players->saveAll(NULL);
|
||||||
|
}
|
||||||
|
for (unsigned int j = 0; j < levels.length; j++)
|
||||||
|
{
|
||||||
|
if (s_bServerHalted) break;
|
||||||
|
ServerLevel *level = levels[levels.length - 1 - j];
|
||||||
|
if (level) level->save(false, NULL, true);
|
||||||
|
}
|
||||||
|
if (!s_bServerHalted)
|
||||||
|
{
|
||||||
|
saveGameRules();
|
||||||
|
levels[0]->saveToDisc(NULL, true);
|
||||||
|
}
|
||||||
|
while (StorageManager.GetSaveState() != C4JStorage::ESaveGame_Idle)
|
||||||
|
{
|
||||||
|
Sleep(10);
|
||||||
|
}
|
||||||
|
app.DebugPrintf("Auto-save complete\n");
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
// 4J We need to update client difficulty levels based on the servers
|
// 4J We need to update client difficulty levels based on the servers
|
||||||
Minecraft *pMinecraft = Minecraft::GetInstance();
|
Minecraft *pMinecraft = Minecraft::GetInstance();
|
||||||
// 4J-PB - sending this on the host changing the difficulty in the menus
|
// 4J-PB - sending this on the host changing the difficulty in the menus
|
||||||
|
|
|
||||||
|
|
@ -174,11 +174,12 @@ LevelChunk *MultiPlayerChunkCache::create(int x, int z)
|
||||||
// 4J-JEV: We are about to use shared data, abort if the server is stopped and the data is deleted.
|
// 4J-JEV: We are about to use shared data, abort if the server is stopped and the data is deleted.
|
||||||
if (MinecraftServer::getInstance()->serverHalted()) return NULL;
|
if (MinecraftServer::getInstance()->serverHalted()) return NULL;
|
||||||
|
|
||||||
// If we're the host, then don't create the chunk, share data from the server's copy
|
// If we're the host, then don't create the chunk, share data from the server's copy
|
||||||
|
int dimId = level->dimension->id;
|
||||||
#ifdef _LARGE_WORLDS
|
#ifdef _LARGE_WORLDS
|
||||||
LevelChunk *serverChunk = MinecraftServer::getInstance()->getLevel(level->dimension->id)->cache->getChunkLoadedOrUnloaded(x,z);
|
LevelChunk *serverChunk = MinecraftServer::getInstance()->getLevel(dimId)->cache->getChunkLoadedOrUnloaded(x,z);
|
||||||
#else
|
#else
|
||||||
LevelChunk *serverChunk = MinecraftServer::getInstance()->getLevel(level->dimension->id)->cache->getChunk(x,z);
|
LevelChunk *serverChunk = MinecraftServer::getInstance()->getLevel(dimId)->cache->getChunk(x,z);
|
||||||
#endif
|
#endif
|
||||||
chunk = new LevelChunk(level, x, z, serverChunk);
|
chunk = new LevelChunk(level, x, z, serverChunk);
|
||||||
// Let renderer know that this chunk has been created - it might have made render data from the EmptyChunk if it got to a chunk before the server sent it
|
// Let renderer know that this chunk has been created - it might have made render data from the EmptyChunk if it got to a chunk before the server sent it
|
||||||
|
|
|
||||||
|
|
@ -149,8 +149,10 @@ LevelChunk *ServerChunkCache::create(int x, int z, bool asyncPostProcess) // 4J
|
||||||
|
|
||||||
if( ( chunk == NULL ) || ( chunk->x != x ) || ( chunk->z != z ) )
|
if( ( chunk == NULL ) || ( chunk->x != x ) || ( chunk->z != z ) )
|
||||||
{
|
{
|
||||||
|
bool wasLoaded = false;
|
||||||
EnterCriticalSection(&m_csLoadCreate);
|
EnterCriticalSection(&m_csLoadCreate);
|
||||||
chunk = load(x, z);
|
chunk = load(x, z);
|
||||||
|
wasLoaded = (chunk != NULL);
|
||||||
if (chunk == NULL)
|
if (chunk == NULL)
|
||||||
{
|
{
|
||||||
if (source == NULL)
|
if (source == NULL)
|
||||||
|
|
@ -470,7 +472,7 @@ void ServerChunkCache::postProcess(ChunkSource *parent, int x, int z )
|
||||||
{
|
{
|
||||||
LevelChunk *chunk = getChunk(x, z);
|
LevelChunk *chunk = getChunk(x, z);
|
||||||
if ( (chunk->terrainPopulated & LevelChunk::sTerrainPopulatedFromHere) == 0 )
|
if ( (chunk->terrainPopulated & LevelChunk::sTerrainPopulatedFromHere) == 0 )
|
||||||
{
|
{
|
||||||
if (source != NULL)
|
if (source != NULL)
|
||||||
{
|
{
|
||||||
PIXBeginNamedEvent(0,"Main post processing");
|
PIXBeginNamedEvent(0,"Main post processing");
|
||||||
|
|
@ -478,7 +480,7 @@ void ServerChunkCache::postProcess(ChunkSource *parent, int x, int z )
|
||||||
PIXEndNamedEvent();
|
PIXEndNamedEvent();
|
||||||
|
|
||||||
chunk->markUnsaved();
|
chunk->markUnsaved();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Flag not only this chunk as being post-processed, but also all the chunks that this post-processing might affect. We can guarantee that these
|
// Flag not only this chunk as being post-processed, but also all the chunks that this post-processing might affect. We can guarantee that these
|
||||||
// chunks exist as that's determined before post-processing can even run
|
// chunks exist as that's determined before post-processing can even run
|
||||||
|
|
|
||||||
|
|
@ -89,7 +89,9 @@ bool WinsockNetLayer::Initialize()
|
||||||
|
|
||||||
s_initialized = true;
|
s_initialized = true;
|
||||||
|
|
||||||
|
#ifndef WITH_SERVER_CODE
|
||||||
StartDiscovery();
|
StartDiscovery();
|
||||||
|
#endif
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -455,24 +455,27 @@ LevelChunk *OldChunkStorage::load(Level *level, DataInputStream *dis)
|
||||||
|
|
||||||
CompoundTag *tag = NbtIo::read(dis);
|
CompoundTag *tag = NbtIo::read(dis);
|
||||||
|
|
||||||
loadEntities(levelChunk, level, tag);
|
if (tag != NULL)
|
||||||
|
|
||||||
if (tag->contains(L"TileTicks"))
|
|
||||||
{
|
{
|
||||||
ListTag<CompoundTag> *tileTicks = (ListTag<CompoundTag> *) tag->getList(L"TileTicks");
|
loadEntities(levelChunk, level, tag);
|
||||||
|
|
||||||
if (tileTicks != NULL)
|
if (tag->contains(L"TileTicks"))
|
||||||
{
|
{
|
||||||
for (int i = 0; i < tileTicks->size(); i++)
|
ListTag<CompoundTag> *tileTicks = (ListTag<CompoundTag> *) tag->getList(L"TileTicks");
|
||||||
{
|
|
||||||
CompoundTag *teTag = tileTicks->get(i);
|
|
||||||
|
|
||||||
level->forceAddTileTick(teTag->getInt(L"x"), teTag->getInt(L"y"), teTag->getInt(L"z"), teTag->getInt(L"i"), teTag->getInt(L"t"));
|
if (tileTicks != NULL)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < tileTicks->size(); i++)
|
||||||
|
{
|
||||||
|
CompoundTag *teTag = tileTicks->get(i);
|
||||||
|
|
||||||
|
level->forceAddTileTick(teTag->getInt(L"x"), teTag->getInt(L"y"), teTag->getInt(L"z"), teTag->getInt(L"i"), teTag->getInt(L"t"));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
delete tag;
|
delete tag;
|
||||||
|
}
|
||||||
|
|
||||||
return levelChunk;
|
return levelChunk;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -664,7 +664,7 @@ void RandomLevelSource::postProcess(ChunkSource *parent, int xt, int zt)
|
||||||
mineShaftFeature->postProcess(level, pprandom, xt, zt);
|
mineShaftFeature->postProcess(level, pprandom, xt, zt);
|
||||||
hasVillage = villageFeature->postProcess(level, pprandom, xt, zt);
|
hasVillage = villageFeature->postProcess(level, pprandom, xt, zt);
|
||||||
strongholdFeature->postProcess(level, pprandom, xt, zt);
|
strongholdFeature->postProcess(level, pprandom, xt, zt);
|
||||||
scatteredFeature->postProcess(level, random, xt, zt);
|
scatteredFeature->postProcess(level, pprandom, xt, zt);
|
||||||
}
|
}
|
||||||
PIXEndNamedEvent();
|
PIXEndNamedEvent();
|
||||||
|
|
||||||
|
|
@ -674,7 +674,7 @@ void RandomLevelSource::postProcess(ChunkSource *parent, int xt, int zt)
|
||||||
int x = xo + pprandom->nextInt(16) + 8;
|
int x = xo + pprandom->nextInt(16) + 8;
|
||||||
int y = pprandom->nextInt(Level::genDepth);
|
int y = pprandom->nextInt(Level::genDepth);
|
||||||
int z = zo + pprandom->nextInt(16) + 8;
|
int z = zo + pprandom->nextInt(16) + 8;
|
||||||
|
|
||||||
LakeFeature *calmWater = new LakeFeature(Tile::calmWater_Id);
|
LakeFeature *calmWater = new LakeFeature(Tile::calmWater_Id);
|
||||||
calmWater->place(level, pprandom, x, y, z);
|
calmWater->place(level, pprandom, x, y, z);
|
||||||
delete calmWater;
|
delete calmWater;
|
||||||
|
|
|
||||||
|
|
@ -38,7 +38,12 @@ RegionFile::RegionFile(ConsoleSaveFile *saveFile, File *path)
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
fileEntry = m_saveFile->createFile( fileName->getName() );
|
wstring saveName = fileName->getPath();
|
||||||
|
for (size_t i = 0; i < saveName.size(); i++)
|
||||||
|
{
|
||||||
|
if (saveName[i] == L'\\') saveName[i] = L'/';
|
||||||
|
}
|
||||||
|
fileEntry = m_saveFile->createFile( ConsoleSavePath(saveName) );
|
||||||
m_saveFile->setFilePointer( fileEntry, 0, NULL, FILE_END );
|
m_saveFile->setFilePointer( fileEntry, 0, NULL, FILE_END );
|
||||||
|
|
||||||
if ( fileEntry->getFileSize() < SECTOR_BYTES)
|
if ( fileEntry->getFileSize() < SECTOR_BYTES)
|
||||||
|
|
|
||||||
|
|
@ -17,15 +17,11 @@ bool RegionFileCache::useSplitSaves(ESavePlatform platform)
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
RegionFile *RegionFileCache::_getRegionFile(ConsoleSaveFile *saveFile, const wstring &prefix, int chunkX, int chunkZ) // 4J - TODO was synchronized
|
RegionFile *RegionFileCache::_getRegionFile(ConsoleSaveFile *saveFile, const wstring &prefix, int chunkX, int chunkZ) // 4J - synchronized restored
|
||||||
{
|
{
|
||||||
|
EnterCriticalSection(&m_cs);
|
||||||
|
|
||||||
// 4J Jev - changed back to use of the File class.
|
// 4J Jev - changed back to use of the File class.
|
||||||
//char file[MAX_PATH_SIZE];
|
|
||||||
//sprintf(file,"%s\\region\\r.%d.%d.mcr",basePath,chunkX >> 5,chunkZ >> 5);
|
|
||||||
|
|
||||||
//File regionDir(basePath, L"region");
|
|
||||||
|
|
||||||
//File file(regionDir, wstring(L"r.") + _toString(chunkX>>5) + L"." + _toString(chunkZ>>5) + L".mcr" );
|
|
||||||
MemSect(31);
|
MemSect(31);
|
||||||
File file;
|
File file;
|
||||||
if(useSplitSaves(saveFile->getSavePlatform()))
|
if(useSplitSaves(saveFile->getSavePlatform()))
|
||||||
|
|
@ -46,45 +42,37 @@ RegionFile *RegionFileCache::_getRegionFile(ConsoleSaveFile *saveFile, const wst
|
||||||
// 4J Jev, put back in.
|
// 4J Jev, put back in.
|
||||||
if (ref != NULL)
|
if (ref != NULL)
|
||||||
{
|
{
|
||||||
|
LeaveCriticalSection(&m_cs);
|
||||||
return ref;
|
return ref;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 4J Stu - Remove for new save files
|
|
||||||
/*
|
|
||||||
if (!regionDir.exists())
|
|
||||||
{
|
|
||||||
regionDir.mkdirs();
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
if (cache.size() >= MAX_CACHE_SIZE)
|
if (cache.size() >= MAX_CACHE_SIZE)
|
||||||
{
|
{
|
||||||
_clear();
|
_clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
RegionFile *reg = new RegionFile(saveFile, &file);
|
RegionFile *reg = new RegionFile(saveFile, &file);
|
||||||
cache[file] = reg; // 4J - this was originally a softReferenc
|
cache[file] = reg; // 4J - this was originally a softReference
|
||||||
|
LeaveCriticalSection(&m_cs);
|
||||||
return reg;
|
return reg;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void RegionFileCache::_clear() // 4J - TODO was synchronized
|
void RegionFileCache::_clear() // 4J - synchronized (recursive CS is safe here)
|
||||||
{
|
{
|
||||||
|
EnterCriticalSection(&m_cs);
|
||||||
AUTO_VAR(itEnd, cache.end());
|
AUTO_VAR(itEnd, cache.end());
|
||||||
for( AUTO_VAR(it, cache.begin()); it != itEnd; it++ )
|
for( AUTO_VAR(it, cache.begin()); it != itEnd; it++ )
|
||||||
{
|
{
|
||||||
// 4J - removed try/catch
|
|
||||||
// try {
|
|
||||||
RegionFile *regionFile = it->second;
|
RegionFile *regionFile = it->second;
|
||||||
if (regionFile != NULL)
|
if (regionFile != NULL)
|
||||||
{
|
{
|
||||||
regionFile->close();
|
regionFile->close();
|
||||||
}
|
}
|
||||||
delete regionFile;
|
delete regionFile;
|
||||||
// } catch (IOException e) {
|
|
||||||
// e.printStackTrace();
|
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
cache.clear();
|
cache.clear();
|
||||||
|
LeaveCriticalSection(&m_cs);
|
||||||
}
|
}
|
||||||
|
|
||||||
int RegionFileCache::_getSizeDelta(ConsoleSaveFile *saveFile, const wstring &prefix, int chunkX, int chunkZ)
|
int RegionFileCache::_getSizeDelta(ConsoleSaveFile *saveFile, const wstring &prefix, int chunkX, int chunkZ)
|
||||||
|
|
|
||||||
|
|
@ -10,12 +10,14 @@ private:
|
||||||
static const int MAX_CACHE_SIZE = 256;
|
static const int MAX_CACHE_SIZE = 256;
|
||||||
|
|
||||||
unordered_map<File, RegionFile *, FileKeyHash, FileKeyEq> cache;
|
unordered_map<File, RegionFile *, FileKeyHash, FileKeyEq> cache;
|
||||||
|
CRITICAL_SECTION m_cs;
|
||||||
|
|
||||||
static RegionFileCache s_defaultCache;
|
static RegionFileCache s_defaultCache;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
// Made public and non-static so we can have a cache for input and output files
|
// Made public and non-static so we can have a cache for input and output files
|
||||||
RegionFileCache() {}
|
RegionFileCache() { InitializeCriticalSectionAndSpinCount(&m_cs, 4000); }
|
||||||
|
~RegionFileCache() { DeleteCriticalSection(&m_cs); }
|
||||||
|
|
||||||
RegionFile *_getRegionFile(ConsoleSaveFile *saveFile, const wstring &prefix, int chunkX, int chunkZ); // 4J - TODO was synchronized
|
RegionFile *_getRegionFile(ConsoleSaveFile *saveFile, const wstring &prefix, int chunkX, int chunkZ); // 4J - TODO was synchronized
|
||||||
void _clear(); // 4J - TODO was synchronized
|
void _clear(); // 4J - TODO was synchronized
|
||||||
|
|
|
||||||
|
|
@ -602,9 +602,10 @@ bool SparseDataStorage::isCompressed()
|
||||||
|
|
||||||
void SparseDataStorage::write(DataOutputStream *dos)
|
void SparseDataStorage::write(DataOutputStream *dos)
|
||||||
{
|
{
|
||||||
int count = ( dataAndCount >> 48 ) & 0xffff;
|
__int64 snapshot = dataAndCount;
|
||||||
|
int count = ( snapshot >> 48 ) & 0xffff;
|
||||||
dos->writeInt(count);
|
dos->writeInt(count);
|
||||||
unsigned char *dataPointer = (unsigned char *)(dataAndCount & 0x0000ffffffffffff);
|
unsigned char *dataPointer = (unsigned char *)(snapshot & 0x0000ffffffffffff);
|
||||||
byteArray wrapper(dataPointer, count * 128 + 128);
|
byteArray wrapper(dataPointer, count * 128 + 128);
|
||||||
dos->write(wrapper);
|
dos->write(wrapper);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -619,9 +619,10 @@ bool SparseLightStorage::isCompressed()
|
||||||
|
|
||||||
void SparseLightStorage::write(DataOutputStream *dos)
|
void SparseLightStorage::write(DataOutputStream *dos)
|
||||||
{
|
{
|
||||||
int count = ( dataAndCount >> 48 ) & 0xffff;
|
__int64 snapshot = dataAndCount;
|
||||||
|
int count = ( snapshot >> 48 ) & 0xffff;
|
||||||
dos->writeInt(count);
|
dos->writeInt(count);
|
||||||
unsigned char *dataPointer = (unsigned char *)(dataAndCount & 0x0000ffffffffffff);
|
unsigned char *dataPointer = (unsigned char *)(snapshot & 0x0000ffffffffffff);
|
||||||
byteArray wrapper(dataPointer, count * 128 + 128);
|
byteArray wrapper(dataPointer, count * 128 + 128);
|
||||||
dos->write(wrapper);
|
dos->write(wrapper);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -7,12 +7,20 @@
|
||||||
#include "net.minecraft.world.level.h"
|
#include "net.minecraft.world.level.h"
|
||||||
#include "LevelData.h"
|
#include "LevelData.h"
|
||||||
|
|
||||||
|
StructureFeature::StructureFeature()
|
||||||
|
{
|
||||||
|
InitializeCriticalSectionAndSpinCount(&m_csCachedStructures, 4000);
|
||||||
|
}
|
||||||
|
|
||||||
StructureFeature::~StructureFeature()
|
StructureFeature::~StructureFeature()
|
||||||
{
|
{
|
||||||
|
EnterCriticalSection(&m_csCachedStructures);
|
||||||
for( AUTO_VAR(it, cachedStructures.begin()); it != cachedStructures.end(); it++ )
|
for( AUTO_VAR(it, cachedStructures.begin()); it != cachedStructures.end(); it++ )
|
||||||
{
|
{
|
||||||
delete it->second;
|
delete it->second;
|
||||||
}
|
}
|
||||||
|
LeaveCriticalSection(&m_csCachedStructures);
|
||||||
|
DeleteCriticalSection(&m_csCachedStructures);
|
||||||
}
|
}
|
||||||
|
|
||||||
void StructureFeature::addFeature(Level *level, int x, int z, int xOffs, int zOffs, byteArray blocks)
|
void StructureFeature::addFeature(Level *level, int x, int z, int xOffs, int zOffs, byteArray blocks)
|
||||||
|
|
@ -21,10 +29,13 @@ void StructureFeature::addFeature(Level *level, int x, int z, int xOffs, int zOf
|
||||||
// the chunk being generated, but not all chunks are the sources of
|
// the chunk being generated, but not all chunks are the sources of
|
||||||
// structures
|
// structures
|
||||||
|
|
||||||
|
EnterCriticalSection(&m_csCachedStructures);
|
||||||
if (cachedStructures.find(ChunkPos::hashCode(x, z)) != cachedStructures.end())
|
if (cachedStructures.find(ChunkPos::hashCode(x, z)) != cachedStructures.end())
|
||||||
{
|
{
|
||||||
|
LeaveCriticalSection(&m_csCachedStructures);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
LeaveCriticalSection(&m_csCachedStructures);
|
||||||
|
|
||||||
// clear random key
|
// clear random key
|
||||||
random->nextInt();
|
random->nextInt();
|
||||||
|
|
@ -32,7 +43,9 @@ void StructureFeature::addFeature(Level *level, int x, int z, int xOffs, int zOf
|
||||||
if (isFeatureChunk(x, z,level->getLevelData()->getGenerator() == LevelType::lvl_flat))
|
if (isFeatureChunk(x, z,level->getLevelData()->getGenerator() == LevelType::lvl_flat))
|
||||||
{
|
{
|
||||||
StructureStart *start = createStructureStart(x, z);
|
StructureStart *start = createStructureStart(x, z);
|
||||||
|
EnterCriticalSection(&m_csCachedStructures);
|
||||||
cachedStructures[ChunkPos::hashCode(x, z)] = start;
|
cachedStructures[ChunkPos::hashCode(x, z)] = start;
|
||||||
|
LeaveCriticalSection(&m_csCachedStructures);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -46,6 +59,7 @@ bool StructureFeature::postProcess(Level *level, Random *random, int chunkX, int
|
||||||
int cz = (chunkZ << 4); // + 8;
|
int cz = (chunkZ << 4); // + 8;
|
||||||
|
|
||||||
bool intersection = false;
|
bool intersection = false;
|
||||||
|
EnterCriticalSection(&m_csCachedStructures);
|
||||||
for( AUTO_VAR(it, cachedStructures.begin()); it != cachedStructures.end(); it++ )
|
for( AUTO_VAR(it, cachedStructures.begin()); it != cachedStructures.end(); it++ )
|
||||||
{
|
{
|
||||||
StructureStart *structureStart = it->second;
|
StructureStart *structureStart = it->second;
|
||||||
|
|
@ -61,12 +75,14 @@ bool StructureFeature::postProcess(Level *level, Random *random, int chunkX, int
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
LeaveCriticalSection(&m_csCachedStructures);
|
||||||
|
|
||||||
return intersection;
|
return intersection;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool StructureFeature::isIntersection(int cellX, int cellZ)
|
bool StructureFeature::isIntersection(int cellX, int cellZ)
|
||||||
{
|
{
|
||||||
|
EnterCriticalSection(&m_csCachedStructures);
|
||||||
for( AUTO_VAR(it, cachedStructures.begin()); it != cachedStructures.end(); it++ )
|
for( AUTO_VAR(it, cachedStructures.begin()); it != cachedStructures.end(); it++ )
|
||||||
{
|
{
|
||||||
StructureStart *structureStart = it->second;
|
StructureStart *structureStart = it->second;
|
||||||
|
|
@ -80,12 +96,14 @@ bool StructureFeature::isIntersection(int cellX, int cellZ)
|
||||||
StructurePiece *next = *it2++;
|
StructurePiece *next = *it2++;
|
||||||
if (next->getBoundingBox()->intersects(cellX, cellZ, cellX, cellZ))
|
if (next->getBoundingBox()->intersects(cellX, cellZ, cellX, cellZ))
|
||||||
{
|
{
|
||||||
|
LeaveCriticalSection(&m_csCachedStructures);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
LeaveCriticalSection(&m_csCachedStructures);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -94,7 +112,7 @@ bool StructureFeature::isIntersection(int cellX, int cellZ)
|
||||||
///////////////////////////////////////////
|
///////////////////////////////////////////
|
||||||
bool StructureFeature::isInsideFeature(int cellX, int cellY, int cellZ)
|
bool StructureFeature::isInsideFeature(int cellX, int cellY, int cellZ)
|
||||||
{
|
{
|
||||||
//for (StructureStart structureStart : cachedStructures.values())
|
EnterCriticalSection(&m_csCachedStructures);
|
||||||
for(AUTO_VAR(it, cachedStructures.begin()); it != cachedStructures.end(); ++it)
|
for(AUTO_VAR(it, cachedStructures.begin()); it != cachedStructures.end(); ++it)
|
||||||
{
|
{
|
||||||
StructureStart *pStructureStart = it->second;
|
StructureStart *pStructureStart = it->second;
|
||||||
|
|
@ -103,14 +121,6 @@ bool StructureFeature::isInsideFeature(int cellX, int cellY, int cellZ)
|
||||||
{
|
{
|
||||||
if (pStructureStart->getBoundingBox()->intersects(cellX, cellZ, cellX, cellZ))
|
if (pStructureStart->getBoundingBox()->intersects(cellX, cellZ, cellX, cellZ))
|
||||||
{
|
{
|
||||||
/*
|
|
||||||
Iterator<StructurePiece> it = structureStart.getPieces().iterator();
|
|
||||||
while (it.hasNext()) {
|
|
||||||
StructurePiece next = it.next();
|
|
||||||
if (next.getBoundingBox().isInside(cellX, cellY, cellZ)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
list<StructurePiece *> *pieces=pStructureStart->getPieces();
|
list<StructurePiece *> *pieces=pStructureStart->getPieces();
|
||||||
|
|
||||||
for ( AUTO_VAR(it2, pieces->begin()); it2 != pieces->end(); it2++ )
|
for ( AUTO_VAR(it2, pieces->begin()); it2 != pieces->end(); it2++ )
|
||||||
|
|
@ -118,12 +128,14 @@ bool StructureFeature::isInsideFeature(int cellX, int cellY, int cellZ)
|
||||||
StructurePiece* piece = *it2;
|
StructurePiece* piece = *it2;
|
||||||
if ( piece->getBoundingBox()->isInside(cellX, cellY, cellZ) )
|
if ( piece->getBoundingBox()->isInside(cellX, cellY, cellZ) )
|
||||||
{
|
{
|
||||||
|
LeaveCriticalSection(&m_csCachedStructures);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
LeaveCriticalSection(&m_csCachedStructures);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -146,6 +158,7 @@ TilePos *StructureFeature::getNearestGeneratedFeature(Level *level, int cellX, i
|
||||||
double minDistance = DBL_MAX;
|
double minDistance = DBL_MAX;
|
||||||
TilePos *selected = NULL;
|
TilePos *selected = NULL;
|
||||||
|
|
||||||
|
EnterCriticalSection(&m_csCachedStructures);
|
||||||
for(AUTO_VAR(it, cachedStructures.begin()); it != cachedStructures.end(); ++it)
|
for(AUTO_VAR(it, cachedStructures.begin()); it != cachedStructures.end(); ++it)
|
||||||
{
|
{
|
||||||
StructureStart *pStructureStart = it->second;
|
StructureStart *pStructureStart = it->second;
|
||||||
|
|
@ -169,6 +182,7 @@ TilePos *StructureFeature::getNearestGeneratedFeature(Level *level, int cellX, i
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
LeaveCriticalSection(&m_csCachedStructures);
|
||||||
if (selected != NULL)
|
if (selected != NULL)
|
||||||
{
|
{
|
||||||
return selected;
|
return selected;
|
||||||
|
|
|
||||||
|
|
@ -17,8 +17,10 @@ public:
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
unordered_map<__int64, StructureStart *> cachedStructures;
|
unordered_map<__int64, StructureStart *> cachedStructures;
|
||||||
|
CRITICAL_SECTION m_csCachedStructures;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
StructureFeature();
|
||||||
~StructureFeature();
|
~StructureFeature();
|
||||||
|
|
||||||
virtual void addFeature(Level *level, int x, int z, int xOffs, int zOffs, byteArray blocks);
|
virtual void addFeature(Level *level, int x, int z, int xOffs, int zOffs, byteArray blocks);
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue