summaryrefslogtreecommitdiffstats
path: root/source
diff options
context:
space:
mode:
Diffstat (limited to 'source')
-rw-r--r--source/Chunk.cpp37
-rw-r--r--source/Chunk.h8
-rw-r--r--source/ChunkMap.cpp28
-rw-r--r--source/ChunkMap.h11
-rw-r--r--source/MobSpawner.h28
5 files changed, 109 insertions, 3 deletions
diff --git a/source/Chunk.cpp b/source/Chunk.cpp
index 59a65a537..35e44363e 100644
--- a/source/Chunk.cpp
+++ b/source/Chunk.cpp
@@ -31,6 +31,7 @@
#include "Blocks/BlockHandler.h"
#include "Simulator/FluidSimulator.h"
#include "MobCensus.h"
+#include "MobSpawner.h"
#include <json/json.h>
@@ -468,6 +469,42 @@ void cChunk::CollectMobCensus(cMobCensus& toFill)
+void cChunk::getThreeRandomNumber(int& a_X, int& a_Y, int& a_Z,int a_MaxX, int a_MaxY, int a_MaxZ)
+{
+ assert(a_MaxX * a_MaxY * a_MaxZ * 8 < 0x00ffffff);
+ int Random = m_World->GetTickRandomNumber(0x00ffffff);
+ a_X = Random % (a_MaxX * 2);
+ a_Y = (Random / (a_MaxX * 2)) % (a_MaxY * 2);
+ a_Z = ((Random / (a_MaxX * 2)) / (a_MaxY * 2)) % (a_MaxZ * 2);
+ a_X /= 2;
+ a_Y /= 2;
+ a_Z /= 2;
+}
+
+
+
+
+
+void cChunk::getRandomBlock(int& a_X, int& a_Y, int& a_Z)
+{
+ // MG TODO : check if this kind of optimization (only one random call) is still needed
+ // MG TODO : if so propagate it
+
+ getThreeRandomNumber(a_X, a_Y, a_Z, Width, Height-2, Width);
+ a_Y++;
+}
+
+
+
+
+
+void cChunk::SpawnMobs(cMobSpawner& a_MobSpawner)
+{
+}
+
+
+
+
void cChunk::Tick(float a_Dt)
{
diff --git a/source/Chunk.h b/source/Chunk.h
index 5f2bba3d8..69ecbfec4 100644
--- a/source/Chunk.h
+++ b/source/Chunk.h
@@ -50,6 +50,7 @@ class cChunkDataSerializer;
class cBlockArea;
class cFluidSimulatorData;
class cMobCensus;
+class cMobSpawner;
typedef std::list<cClientHandle *> cClientHandleList;
typedef cItemCallback<cEntity> cEntityCallback;
@@ -128,6 +129,9 @@ public:
/// Recence all mobs proximities to players in order to know what to do with them
void CollectMobCensus(cMobCensus& toFill);
+ /// Try to Spawn Monsters inside chunk
+ void SpawnMobs(cMobSpawner& a_MobSpawner);
+
void Tick(float a_Dt);
int GetPosX(void) const { return m_PosX; }
@@ -389,6 +393,10 @@ private:
cSandSimulatorChunkData m_SandSimulatorData;
+ // pick up a random block of this chunk
+ void getRandomBlock(int& a_X, int& a_Y, int& a_Z);
+ void getThreeRandomNumber(int& a_X, int& a_Y, int& a_Z,int a_MaxX, int a_MaxY, int a_MaxZ);
+
void RemoveBlockEntity(cBlockEntity * a_BlockEntity);
void AddBlockEntity (cBlockEntity * a_BlockEntity);
diff --git a/source/ChunkMap.cpp b/source/ChunkMap.cpp
index 610b293b5..f5cbacdc7 100644
--- a/source/ChunkMap.cpp
+++ b/source/ChunkMap.cpp
@@ -13,6 +13,7 @@
#include "PluginManager.h"
#include "Entities/TNTEntity.h"
#include "MobCensus.h"
+#include "MobSpawner.h"
#ifndef _WIN32
#include <cstdlib> // abs
@@ -2167,6 +2168,19 @@ void cChunkMap::CollectMobCensus(cMobCensus& a_ToFill)
+void cChunkMap::SpawnMobs(cMobSpawner& a_MobSpawner)
+{
+ cCSLock Lock(m_CSLayers);
+ for (cChunkLayerList::iterator itr = m_Layers.begin(); itr != m_Layers.end(); ++itr)
+ {
+ (*itr)->SpawnMobs(a_MobSpawner);
+ } // for itr - m_Layers
+}
+
+
+
+
+
void cChunkMap::Tick(float a_Dt)
{
cCSLock Lock(m_CSLayers);
@@ -2343,6 +2357,20 @@ void cChunkMap::cChunkLayer::CollectMobCensus(cMobCensus& a_ToFill)
+void cChunkMap::cChunkLayer::SpawnMobs(cMobSpawner& a_MobSpawner)
+{
+ for (int i = 0; i < ARRAYCOUNT(m_Chunks); i++)
+ {
+ // We only spawn close to players
+ if ((m_Chunks[i] != NULL) && m_Chunks[i]->IsValid() && m_Chunks[i]->HasAnyClients())
+ {
+ m_Chunks[i]->SpawnMobs(a_MobSpawner);
+ }
+ } // for i - m_Chunks[]
+}
+
+
+
void cChunkMap::cChunkLayer::Tick(float a_Dt)
{
for (int i = 0; i < ARRAYCOUNT(m_Chunks); i++)
diff --git a/source/ChunkMap.h b/source/ChunkMap.h
index c9d9abf75..168f54b39 100644
--- a/source/ChunkMap.h
+++ b/source/ChunkMap.h
@@ -27,6 +27,7 @@ class cPickup;
class cChunkDataSerializer;
class cBlockArea;
class cMobCensus;
+class cMobSpawner;
typedef std::list<cClientHandle *> cClientHandleList;
typedef cChunk * cChunkPtr;
@@ -264,12 +265,15 @@ public:
/// Grows a cactus present at the block specified by the amount of blocks specified, up to the max height specified in the config
void GrowCactus(int a_BlockX, int a_BlockY, int a_BlockZ, int a_NumBlocksToGrow);
- /// Sets the blockticking to start at the specified block. Only one blocktick per chunk may be set, second call overwrites the first call
+ /// Sets the blockticking to start at the specified block. Only one blocktick per chunk may be set, second call overwrites the first call
void SetNextBlockTick(int a_BlockX, int a_BlockY, int a_BlockZ);
/// Make a Mob census, of all mobs, their family, their chunk and theyr distance to closest player
void CollectMobCensus(cMobCensus& a_ToFill);
+ /// Try to Spawn Monsters inside all Chunks
+ void SpawnMobs(cMobSpawner& a_MobSpawner);
+
void Tick(float a_Dt);
void UnloadUnusedChunks(void);
@@ -314,8 +318,9 @@ private:
void UnloadUnusedChunks(void);
/// Collect a mob census, of all mobs, their megatype, their chunk and their distance o closest player
- void CollectMobCensus(cMobCensus& a_ToFill);
-
+ void CollectMobCensus(cMobCensus& a_ToFill);
+ /// Try to Spawn Monsters inside all Chunks
+ void SpawnMobs(cMobSpawner& a_MobSpawner);
void Tick(float a_Dt);
diff --git a/source/MobSpawner.h b/source/MobSpawner.h
new file mode 100644
index 000000000..7498c567d
--- /dev/null
+++ b/source/MobSpawner.h
@@ -0,0 +1,28 @@
+
+#pragma once
+
+#include <set>
+#include "BlockID.h"
+#include "ChunkDef.h"
+#include "FastRandom.h"
+#include "Mobs/Monster.h" //this is a side-effect of keeping Mobfamily inside Monster class. I'd prefer to keep both (Mobfamily and Monster) inside a "Monster" namespace MG TODO : do it
+
+class cChunk;
+class cEntity;
+
+
+// This class is used to determine wich monster can be spawned on wich place
+// it is essentially static (f.i. Squids spawn in water, Zombie spawn in dark places)
+// but it also has dynamic part depending on the world.ini
+class cMobSpawner
+{
+public :
+ // constructor
+ // a_MobFamily is the mega type of mobs that this spawner will spawn
+ // a_AllowedTypes is the set of types allowed for mobs it will spawn. Empty set
+ // would result in no spawn at all
+ // Allowed mobs thah are not of the right Megatype will not be include (no warning)
+ cMobSpawner(cMonster::eFamily MobFamily, const std::set<cMonster::eType>& a_AllowedTypes);
+
+
+};