summaryrefslogtreecommitdiffstats
path: root/source
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--source/cChunk.cpp11
-rw-r--r--source/cChunk.h8
-rw-r--r--source/cChunkGenerator.cpp19
-rw-r--r--source/cChunkMap.cpp12
-rw-r--r--source/cChunkMap.h15
-rw-r--r--source/cMonsterConfig.cpp2
-rw-r--r--source/cWorld.cpp9
-rw-r--r--source/cWorld.h15
-rw-r--r--source/cWorldGenerator.cpp21
-rw-r--r--source/cWorldGenerator.h7
-rw-r--r--source/cWorldGenerator_Test.h4
11 files changed, 81 insertions, 42 deletions
diff --git a/source/cChunk.cpp b/source/cChunk.cpp
index 5ebf8b656..5bd6ca1e9 100644
--- a/source/cChunk.cpp
+++ b/source/cChunk.cpp
@@ -805,8 +805,6 @@ void cChunk::SetBlock( int a_X, int a_Y, int a_Z, char a_BlockType, char a_Block
assert(IsValid()); // Is this chunk loaded / generated?
- MarkDirty();
-
int index = a_Y + (a_Z * 128) + (a_X * 128 * 16);
char OldBlockMeta = GetLight( m_BlockMeta, index );
char OldBlockType = m_BlockType[index];
@@ -819,6 +817,8 @@ void cChunk::SetBlock( int a_X, int a_Y, int a_Z, char a_BlockType, char a_Block
return;
}
+ MarkDirty();
+
cCSLock Lock(m_CSBlockLists);
m_PendingSendBlocks.push_back( index );
@@ -871,14 +871,15 @@ void cChunk::FastSetBlock( int a_X, int a_Y, int a_Z, char a_BlockType, char a_B
assert(IsValid());
- MarkDirty();
-
const int index = a_Y + (a_Z * 128) + (a_X * 128 * 16);
const char OldBlock = m_BlockType[index];
if (OldBlock == a_BlockType)
{
return;
}
+
+ MarkDirty();
+
m_BlockType[index] = a_BlockType;
{
@@ -1107,7 +1108,7 @@ bool cChunk::HasClient( cClientHandle* a_Client )
-bool cChunk::HasAnyClient(void)
+bool cChunk::HasAnyClients(void)
{
cCSLock Lock(m_CSClients);
return !m_LoadedByClient.empty();
diff --git a/source/cChunk.h b/source/cChunk.h
index ebaa21e34..66efa0d1e 100644
--- a/source/cChunk.h
+++ b/source/cChunk.h
@@ -114,10 +114,10 @@ public:
void SendBlockTo( int a_X, int a_Y, int a_Z, cClientHandle* a_Client );
- void AddClient ( cClientHandle* a_Client );
- void RemoveClient( cClientHandle* a_Client );
- bool HasClient ( cClientHandle* a_Client );
- bool HasAnyClient(void); // Returns true if theres any client in the chunk; false otherwise
+ void AddClient (cClientHandle* a_Client );
+ void RemoveClient (cClientHandle* a_Client );
+ bool HasClient (cClientHandle* a_Client );
+ bool HasAnyClients(void); // Returns true if theres any client in the chunk; false otherwise
void AddEntity( cEntity * a_Entity );
void RemoveEntity( cEntity * a_Entity);
diff --git a/source/cChunkGenerator.cpp b/source/cChunkGenerator.cpp
index 8755ea325..4d9aef421 100644
--- a/source/cChunkGenerator.cpp
+++ b/source/cChunkGenerator.cpp
@@ -53,11 +53,11 @@ bool cChunkGenerator::Start(cWorld * a_World, const AString & a_WorldGeneratorNa
if (a_WorldGeneratorName.compare("Test") == 0 )
{
- m_pWorldGenerator = new cWorldGenerator_Test();
+ m_pWorldGenerator = new cWorldGenerator_Test(a_World);
}
else // Default
{
- m_pWorldGenerator = new cWorldGenerator();
+ m_pWorldGenerator = new cWorldGenerator(a_World);
}
return super::Start();
@@ -129,17 +129,22 @@ void cChunkGenerator::Execute(void)
bool SkipEnabled = (m_Queue.size() > QUEUE_SKIP_LIMIT);
Lock.Unlock(); // Unlock ASAP
- cChunkPtr Chunk = m_World->GetChunk(coords.m_ChunkX, 0, coords.m_ChunkZ);
- if ((Chunk != NULL) && (Chunk->IsValid() || (SkipEnabled && !Chunk->HasAnyClient())))
+ if (
+ m_World->IsChunkValid(coords.m_ChunkX, 0, coords.m_ChunkZ) ||
+ (SkipEnabled && m_World->HasChunkAnyClients(coords.m_ChunkX, 0, coords.m_ChunkZ))
+ )
{
// Already generated / overload-skip, ignore request
continue;
}
-
+
LOG("Generating chunk [%d, %d]", coords.m_ChunkX, coords.m_ChunkZ);
- m_pWorldGenerator->GenerateChunk(Chunk);
+ m_pWorldGenerator->GenerateChunk(coords.m_ChunkX, 0, coords.m_ChunkZ);
- Chunk->SetValid();
+ // Chunk->SetValid();
+
+ // Save the chunk right after generating, so that we don't have to generate it again on next run
+ m_World->GetStorage().QueueSaveChunk(coords.m_ChunkX, coords.m_ChunkZ);
} // while (!bStop)
}
diff --git a/source/cChunkMap.cpp b/source/cChunkMap.cpp
index 7b249dcae..dbe6607fc 100644
--- a/source/cChunkMap.cpp
+++ b/source/cChunkMap.cpp
@@ -276,6 +276,17 @@ bool cChunkMap::IsChunkValid(int a_ChunkX, int a_ChunkY, int a_ChunkZ)
+bool cChunkMap::HasChunkAnyClients(int a_ChunkX, int a_ChunkY, int a_ChunkZ)
+{
+ cCSLock Lock(m_CSLayers);
+ cChunkPtr Chunk = GetChunkNoGen(a_ChunkX, a_ChunkY, a_ChunkZ);
+ return (Chunk != NULL) && Chunk->HasAnyClients();
+}
+
+
+
+
+
void cChunkMap::Tick( float a_Dt, MTRand & a_TickRandom )
{
cCSLock Lock(m_CSLayers);
@@ -389,7 +400,6 @@ void cChunkMap::cChunkLayer::Save(void)
void cChunkMap::cChunkLayer::UnloadUnusedChunks(void)
{
- cWorld * World = m_Parent->GetWorld();
for (int i = 0; i < ARRAYCOUNT(m_Chunks); i++)
{
if ((m_Chunks[i] != NULL) && (m_Chunks[i]->CanUnload()))
diff --git a/source/cChunkMap.h b/source/cChunkMap.h
index e53153c24..0b3e79931 100644
--- a/source/cChunkMap.h
+++ b/source/cChunkMap.h
@@ -36,13 +36,14 @@ public:
void BroadcastToChunkOfBlock(int a_X, int a_Y, int a_Z, cPacket * a_Packet, cClientHandle * a_Exclude = NULL);
void UseBlockEntity(cPlayer * a_Player, int a_X, int a_Y, int a_Z); // a_Player rclked block entity at the coords specified, handle it
- void MarkChunkDirty (int a_ChunkX, int a_ChunkY, int a_ChunkZ);
- void MarkChunkSaving(int a_ChunkX, int a_ChunkY, int a_ChunkZ);
- void MarkChunkSaved (int a_ChunkX, int a_ChunkY, int a_ChunkZ);
- void ChunkDataLoaded(int a_ChunkX, int a_ChunkY, int a_ChunkZ, const char * a_BlockData, cEntityList & a_Entities, cBlockEntityList & a_BlockEntities);
- void SetChunkData (int a_ChunkX, int a_ChunkY, int a_ChunkZ, const char * a_BlockData, cEntityList & a_Entities, cBlockEntityList & a_BlockEntities);
- void GetChunkData (int a_ChunkX, int a_ChunkY, int a_ChunkZ, cChunkDataCallback * a_Callback);
- bool IsChunkValid (int a_ChunkX, int a_ChunkY, int a_ChunkZ);
+ void MarkChunkDirty (int a_ChunkX, int a_ChunkY, int a_ChunkZ);
+ void MarkChunkSaving (int a_ChunkX, int a_ChunkY, int a_ChunkZ);
+ void MarkChunkSaved (int a_ChunkX, int a_ChunkY, int a_ChunkZ);
+ void ChunkDataLoaded (int a_ChunkX, int a_ChunkY, int a_ChunkZ, const char * a_BlockData, cEntityList & a_Entities, cBlockEntityList & a_BlockEntities);
+ void SetChunkData (int a_ChunkX, int a_ChunkY, int a_ChunkZ, const char * a_BlockData, cEntityList & a_Entities, cBlockEntityList & a_BlockEntities);
+ void GetChunkData (int a_ChunkX, int a_ChunkY, int a_ChunkZ, cChunkDataCallback * a_Callback);
+ bool IsChunkValid (int a_ChunkX, int a_ChunkY, int a_ChunkZ);
+ bool HasChunkAnyClients(int a_ChunkX, int a_ChunkY, int a_ChunkZ);
void Tick( float a_Dt, MTRand & a_TickRand );
diff --git a/source/cMonsterConfig.cpp b/source/cMonsterConfig.cpp
index 43c2ca689..7f4389e5f 100644
--- a/source/cMonsterConfig.cpp
+++ b/source/cMonsterConfig.cpp
@@ -105,7 +105,7 @@ void cMonsterConfig::AssignAttributes(cMonster *m, const char* n)
m->SetAttackRange (itr->m_AttackRange);
m->SetSightDistance(itr->m_SightDistance);
m->SetAttackRate ((int)itr->m_AttackRate);
- m->SetMaxHealth ((int)itr->m_MaxHealth);
+ m->SetMaxHealth ((short)itr->m_MaxHealth);
}
} // for itr - m_pState->AttributesList[]
}
diff --git a/source/cWorld.cpp b/source/cWorld.cpp
index fc6941250..81058cd93 100644
--- a/source/cWorld.cpp
+++ b/source/cWorld.cpp
@@ -1009,6 +1009,15 @@ bool cWorld::IsChunkValid(int a_ChunkX, int a_ChunkY, int a_ChunkZ) const
+bool cWorld::HasChunkAnyClients(int a_ChunkX, int a_ChunkY, int a_ChunkZ) const
+{
+ return m_ChunkMap->HasChunkAnyClients(a_ChunkX, a_ChunkY, a_ChunkZ);
+}
+
+
+
+
+
void cWorld::SetMaxPlayers(int iMax)
{
m_MaxPlayers = MAX_PLAYERS;
diff --git a/source/cWorld.h b/source/cWorld.h
index 025d0782a..70b502780 100644
--- a/source/cWorld.h
+++ b/source/cWorld.h
@@ -70,13 +70,14 @@ public:
void BroadcastToChunkOfBlock(int a_X, int a_Y, int a_Z, cPacket * a_Packet, cClientHandle * a_Exclude = NULL);
- void MarkChunkDirty (int a_ChunkX, int a_ChunkY, int a_ChunkZ);
- void MarkChunkSaving(int a_ChunkX, int a_ChunkY, int a_ChunkZ);
- void MarkChunkSaved (int a_ChunkX, int a_ChunkY, int a_ChunkZ);
- void ChunkDataLoaded(int a_ChunkX, int a_ChunkY, int a_ChunkZ, const char * a_BlockData, cEntityList & a_Entities, cBlockEntityList & a_BlockEntities);
- void SetChunkData (int a_ChunkX, int a_ChunkY, int a_ChunkZ, const char * a_BlockData, cEntityList & a_Entities, cBlockEntityList & a_BlockEntities);
- void GetChunkData (int a_ChunkX, int a_ChunkY, int a_ChunkZ, cChunkDataCallback * a_Callback);
- bool IsChunkValid (int a_ChunkX, int a_ChunkY, int a_ChunkZ) const;
+ void MarkChunkDirty (int a_ChunkX, int a_ChunkY, int a_ChunkZ);
+ void MarkChunkSaving (int a_ChunkX, int a_ChunkY, int a_ChunkZ);
+ void MarkChunkSaved (int a_ChunkX, int a_ChunkY, int a_ChunkZ);
+ void ChunkDataLoaded (int a_ChunkX, int a_ChunkY, int a_ChunkZ, const char * a_BlockData, cEntityList & a_Entities, cBlockEntityList & a_BlockEntities);
+ void SetChunkData (int a_ChunkX, int a_ChunkY, int a_ChunkZ, const char * a_BlockData, cEntityList & a_Entities, cBlockEntityList & a_BlockEntities);
+ void GetChunkData (int a_ChunkX, int a_ChunkY, int a_ChunkZ, cChunkDataCallback * a_Callback);
+ bool IsChunkValid (int a_ChunkX, int a_ChunkY, int a_ChunkZ) const;
+ bool HasChunkAnyClients(int a_ChunkX, int a_ChunkY, int a_ChunkZ) const;
// MOTD
const AString & GetDescription(void) const {return m_Description; }
diff --git a/source/cWorldGenerator.cpp b/source/cWorldGenerator.cpp
index 5d087014b..fcbbcdad3 100644
--- a/source/cWorldGenerator.cpp
+++ b/source/cWorldGenerator.cpp
@@ -14,7 +14,8 @@
-cWorldGenerator::cWorldGenerator()
+cWorldGenerator::cWorldGenerator(cWorld * a_World) :
+ m_World(a_World)
{
}
@@ -30,15 +31,19 @@ cWorldGenerator::~cWorldGenerator()
-void cWorldGenerator::GenerateChunk( cChunkPtr a_Chunk )
+void cWorldGenerator::GenerateChunk(int a_ChunkX, int a_ChunkY, int a_ChunkZ)
{
- assert(!a_Chunk->IsValid());
+ // TODO: use a raw char array instead of the entire chunk, then set it as chunk's blockdata
- memset(a_Chunk->pGetBlockData(), 0, cChunk::c_BlockDataSize);
- GenerateTerrain( a_Chunk );
- GenerateFoliage( a_Chunk );
- a_Chunk->CalculateHeightmap();
- a_Chunk->CalculateLighting();
+ cChunkPtr Chunk = m_World->GetChunkNoGen(a_ChunkX, a_ChunkY, a_ChunkZ);
+ assert(!Chunk->IsValid());
+
+ memset(Chunk->pGetBlockData(), 0, cChunk::c_BlockDataSize);
+ GenerateTerrain(Chunk);
+ GenerateFoliage(Chunk);
+ Chunk->CalculateHeightmap();
+ Chunk->CalculateLighting();
+ Chunk->SetValid();
}
diff --git a/source/cWorldGenerator.h b/source/cWorldGenerator.h
index 933105d24..208178d4a 100644
--- a/source/cWorldGenerator.h
+++ b/source/cWorldGenerator.h
@@ -15,13 +15,16 @@
class cWorldGenerator
{
public:
- cWorldGenerator();
+ cWorldGenerator(cWorld * a_World);
~cWorldGenerator();
- virtual void GenerateChunk( cChunkPtr a_Chunk );
+ virtual void GenerateChunk(int a_ChunkX, int a_ChunkY, int a_ChunkZ);
protected:
+ cWorld * m_World;
+
+ // Thread-unsafe:
MTRand r1;
virtual void GenerateTerrain( cChunkPtr a_Chunk );
diff --git a/source/cWorldGenerator_Test.h b/source/cWorldGenerator_Test.h
index 0dd9d5b1c..5a5483fa9 100644
--- a/source/cWorldGenerator_Test.h
+++ b/source/cWorldGenerator_Test.h
@@ -10,6 +10,10 @@
class cWorldGenerator_Test :
public cWorldGenerator
{
+public:
+
+ cWorldGenerator_Test(cWorld * a_World) : cWorldGenerator(a_World) {}
+
protected:
virtual void GenerateTerrain( cChunkPtr a_Chunk ) override;
virtual void GenerateFoliage( cChunkPtr a_Chunk ) override;