1
0

Merge branch 'master' of github.com:mc-server/MCServer

This commit is contained in:
Tycho 2014-06-16 15:12:50 +01:00
parent 84c83e0deb
commit ee50790398
35 changed files with 929 additions and 498 deletions

109
src/AllocationPool.h Normal file
View File

@ -0,0 +1,109 @@
#pragma once
#include <memory>
template<class T>
class cAllocationPool
{
public:
class cStarvationCallbacks
{
public:
virtual ~cStarvationCallbacks() {}
/** Is called when the reserve buffer starts to be used **/
virtual void OnStartUsingReserve() = 0;
/** Is called once the reserve buffer has returned to normal size **/
virtual void OnEndUsingReserve() = 0;
/** Is called when the allocation pool is unable to allocate memory. Will be repeatedly
called if it does not free sufficient memory **/
virtual void OnOutOfReserve() = 0;
};
virtual ~cAllocationPool() {}
/** Allocates a pointer to T **/
virtual T * Allocate() = 0;
/** Frees the pointer passed in a_ptr, invalidating it **/
virtual void Free(T * a_ptr) = 0;
};
/** Allocates memory storing unused elements in a linked list. Keeps at least NumElementsInReserve
elements in the list unless malloc fails so that the program has a reserve to handle OOM.**/
template<class T, size_t NumElementsInReserve>
class cListAllocationPool : public cAllocationPool<T>
{
public:
cListAllocationPool(std::auto_ptr<typename cAllocationPool<T>::cStarvationCallbacks> a_Callbacks) :
m_Callbacks(a_Callbacks)
{
for (size_t i = 0; i < NumElementsInReserve; i++)
{
void * space = malloc(sizeof(T));
if (space == NULL)
{
m_Callbacks->OnStartUsingReserve();
break;
}
m_FreeList.push_front(space);
}
}
virtual ~cListAllocationPool()
{
while (!m_FreeList.empty())
{
free (m_FreeList.front());
m_FreeList.pop_front();
}
}
virtual T * Allocate() override
{
if (m_FreeList.size() <= NumElementsInReserve)
{
void * space = malloc(sizeof(T));
if (space != NULL)
{
return new(space) T;
}
else if (m_FreeList.size() == NumElementsInReserve)
{
m_Callbacks->OnStartUsingReserve();
}
else if (m_FreeList.empty())
{
m_Callbacks->OnOutOfReserve();
// Try again until the memory is avalable
return Allocate();
}
}
// placement new, used to initalize the object
T * ret = new (m_FreeList.front()) T;
m_FreeList.pop_front();
return ret;
}
virtual void Free(T * a_ptr) override
{
if (a_ptr == NULL)
{
return;
}
// placement destruct.
a_ptr->~T();
m_FreeList.push_front(a_ptr);
if (m_FreeList.size() == NumElementsInReserve)
{
m_Callbacks->OnEndUsingReserve();
}
}
private:
std::list<void *> m_FreeList;
std::auto_ptr<typename cAllocationPool<T>::cStarvationCallbacks> m_Callbacks;
};

View File

@ -64,7 +64,8 @@ sSetBlock::sSetBlock( int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_Bloc
cChunk::cChunk( cChunk::cChunk(
int a_ChunkX, int a_ChunkY, int a_ChunkZ, int a_ChunkX, int a_ChunkY, int a_ChunkZ,
cChunkMap * a_ChunkMap, cWorld * a_World, cChunkMap * a_ChunkMap, cWorld * a_World,
cChunk * a_NeighborXM, cChunk * a_NeighborXP, cChunk * a_NeighborZM, cChunk * a_NeighborZP cChunk * a_NeighborXM, cChunk * a_NeighborXP, cChunk * a_NeighborZM, cChunk * a_NeighborZP,
cAllocationPool<cChunkData::sChunkSection> & a_Pool
) : ) :
m_IsValid(false), m_IsValid(false),
m_IsLightValid(false), m_IsLightValid(false),
@ -77,6 +78,7 @@ cChunk::cChunk(
m_PosZ(a_ChunkZ), m_PosZ(a_ChunkZ),
m_World(a_World), m_World(a_World),
m_ChunkMap(a_ChunkMap), m_ChunkMap(a_ChunkMap),
m_ChunkData(a_Pool),
m_BlockTickX(0), m_BlockTickX(0),
m_BlockTickY(0), m_BlockTickY(0),
m_BlockTickZ(0), m_BlockTickZ(0),

View File

@ -65,7 +65,8 @@ public:
cChunk( cChunk(
int a_ChunkX, int a_ChunkY, int a_ChunkZ, // Chunk coords int a_ChunkX, int a_ChunkY, int a_ChunkZ, // Chunk coords
cChunkMap * a_ChunkMap, cWorld * a_World, // Parent objects cChunkMap * a_ChunkMap, cWorld * a_World, // Parent objects
cChunk * a_NeighborXM, cChunk * a_NeighborXP, cChunk * a_NeighborZM, cChunk * a_NeighborZP // Neighbor chunks cChunk * a_NeighborXM, cChunk * a_NeighborXP, cChunk * a_NeighborZM, cChunk * a_NeighborZP, // Neighbor chunks
cAllocationPool<cChunkData::sChunkSection> & a_Pool
); );
cChunk(cChunk & other); cChunk(cChunk & other);
~cChunk(); ~cChunk();

View File

@ -27,11 +27,12 @@ template <typename T> inline bool IsAllValue(const T * a_Array, size_t a_NumElem
cChunkData::cChunkData(void) cChunkData::cChunkData(cAllocationPool<cChunkData::sChunkSection> & a_Pool) :
#if __cplusplus < 201103L #if __cplusplus < 201103L
// auto_ptr style interface for memory management // auto_ptr style interface for memory management
: m_IsOwner(true) m_IsOwner(true),
#endif #endif
m_Pool(a_Pool)
{ {
for (size_t i = 0; i < NumSections; i++) for (size_t i = 0; i < NumSections; i++)
{ {
@ -66,7 +67,8 @@ cChunkData::~cChunkData()
#if __cplusplus < 201103L #if __cplusplus < 201103L
// auto_ptr style interface for memory management // auto_ptr style interface for memory management
cChunkData::cChunkData(const cChunkData & a_Other) : cChunkData::cChunkData(const cChunkData & a_Other) :
m_IsOwner(true) m_IsOwner(true),
m_Pool(a_Other.m_Pool)
{ {
// Move contents and ownership from a_Other to this, pointer-wise: // Move contents and ownership from a_Other to this, pointer-wise:
for (size_t i = 0; i < NumSections; i++) for (size_t i = 0; i < NumSections; i++)
@ -105,13 +107,15 @@ cChunkData::~cChunkData()
m_Sections[i] = a_Other.m_Sections[i]; m_Sections[i] = a_Other.m_Sections[i];
} }
a_Other.m_IsOwner = false; a_Other.m_IsOwner = false;
ASSERT(&m_Pool == &a_Other.m_Pool);
return *this; return *this;
} }
#else #else
// unique_ptr style interface for memory management // unique_ptr style interface for memory management
cChunkData::cChunkData(cChunkData && other) cChunkData::cChunkData(cChunkData && other) :
m_Pool(other.m_Pool)
{ {
for (size_t i = 0; i < NumSections; i++) for (size_t i = 0; i < NumSections; i++)
{ {
@ -128,6 +132,7 @@ cChunkData::~cChunkData()
{ {
if (&other != this) if (&other != this)
{ {
ASSERT(&m_Pool == &other.m_Pool);
for (size_t i = 0; i < NumSections; i++) for (size_t i = 0; i < NumSections; i++)
{ {
Free(m_Sections[i]); Free(m_Sections[i]);
@ -317,12 +322,12 @@ NIBBLETYPE cChunkData::GetSkyLight(int a_RelX, int a_RelY, int a_RelZ) const
cChunkData cChunkData::Copy(void) const cChunkData cChunkData::Copy(void) const
{ {
cChunkData copy; cChunkData copy(m_Pool);
for (size_t i = 0; i < NumSections; i++) for (size_t i = 0; i < NumSections; i++)
{ {
if (m_Sections[i] != NULL) if (m_Sections[i] != NULL)
{ {
copy.m_Sections[i] = Allocate(); copy.m_Sections[i] = copy.Allocate();
*copy.m_Sections[i] = *m_Sections[i]; *copy.m_Sections[i] = *m_Sections[i];
} }
} }
@ -561,8 +566,7 @@ void cChunkData::SetSkyLight(const NIBBLETYPE * a_Src)
cChunkData::sChunkSection * cChunkData::Allocate(void) cChunkData::sChunkSection * cChunkData::Allocate(void)
{ {
// TODO: Use an allocation pool return m_Pool.Allocate();
return new cChunkData::sChunkSection;
} }
@ -571,8 +575,7 @@ cChunkData::sChunkSection * cChunkData::Allocate(void)
void cChunkData::Free(cChunkData::sChunkSection * a_Section) void cChunkData::Free(cChunkData::sChunkSection * a_Section)
{ {
// TODO: Use an allocation pool m_Pool.Free(a_Section);
delete a_Section;
} }

View File

@ -15,6 +15,7 @@
#include "ChunkDef.h" #include "ChunkDef.h"
#include "AllocationPool.h"
@ -26,9 +27,17 @@
class cChunkData class cChunkData
{ {
private:
static const size_t SectionHeight = 16;
static const size_t NumSections = (cChunkDef::Height / SectionHeight);
static const size_t SectionBlockCount = SectionHeight * cChunkDef::Width * cChunkDef::Width;
public: public:
cChunkData(void); struct sChunkSection;
cChunkData(cAllocationPool<cChunkData::sChunkSection> & a_Pool);
~cChunkData(); ~cChunkData();
#if __cplusplus < 201103L #if __cplusplus < 201103L
@ -87,35 +96,34 @@ public:
Allows a_Src to be NULL, in which case it doesn't do anything. */ Allows a_Src to be NULL, in which case it doesn't do anything. */
void SetSkyLight(const NIBBLETYPE * a_Src); void SetSkyLight(const NIBBLETYPE * a_Src);
struct sChunkSection
{
BLOCKTYPE m_BlockTypes [SectionHeight * 16 * 16] ;
NIBBLETYPE m_BlockMetas [SectionHeight * 16 * 16 / 2];
NIBBLETYPE m_BlockLight [SectionHeight * 16 * 16 / 2];
NIBBLETYPE m_BlockSkyLight[SectionHeight * 16 * 16 / 2];
};
private: private:
static const size_t SectionHeight = 16;
static const size_t NumSections = (cChunkDef::Height / SectionHeight);
static const size_t SectionBlockCount = SectionHeight * cChunkDef::Width * cChunkDef::Width;
#if __cplusplus < 201103L #if __cplusplus < 201103L
// auto_ptr style interface for memory management // auto_ptr style interface for memory management
mutable bool m_IsOwner; mutable bool m_IsOwner;
#endif #endif
struct sChunkSection {
BLOCKTYPE m_BlockTypes [SectionBlockCount];
NIBBLETYPE m_BlockMetas [SectionBlockCount / 2];
NIBBLETYPE m_BlockLight [SectionBlockCount / 2];
NIBBLETYPE m_BlockSkyLight[SectionBlockCount / 2];
};
sChunkSection * m_Sections[NumSections]; sChunkSection * m_Sections[NumSections];
cAllocationPool<cChunkData::sChunkSection> & m_Pool;
/** Allocates a new section. Entry-point to custom allocators. */ /** Allocates a new section. Entry-point to custom allocators. */
static sChunkSection * Allocate(void); sChunkSection * Allocate(void);
/** Frees the specified section, previously allocated using Allocate(). /** Frees the specified section, previously allocated using Allocate().
Note that a_Section may be NULL. */ Note that a_Section may be NULL. */
static void Free(sChunkSection * a_Section); void Free(sChunkSection * a_Section);
/** Sets the data in the specified section to their default values. */ /** Sets the data in the specified section to their default values. */
void ZeroSection(sChunkSection * a_Section) const; void ZeroSection(sChunkSection * a_Section) const;
}; };

View File

@ -34,8 +34,15 @@
// cChunkMap: // cChunkMap:
cChunkMap::cChunkMap(cWorld * a_World ) cChunkMap::cChunkMap(cWorld * a_World )
: m_World( a_World ) : m_World( a_World ),
m_Pool(
new cListAllocationPool<cChunkData::sChunkSection, 1600>(
std::auto_ptr<cAllocationPool<cChunkData::sChunkSection>::cStarvationCallbacks>(
new cStarvationCallbacks())
)
)
{ {
} }
@ -78,7 +85,7 @@ cChunkMap::cChunkLayer * cChunkMap::GetLayer(int a_LayerX, int a_LayerZ)
} }
// Not found, create new: // Not found, create new:
cChunkLayer * Layer = new cChunkLayer(a_LayerX, a_LayerZ, this); cChunkLayer * Layer = new cChunkLayer(a_LayerX, a_LayerZ, this, *m_Pool);
if (Layer == NULL) if (Layer == NULL)
{ {
LOGERROR("cChunkMap: Cannot create new layer, server out of memory?"); LOGERROR("cChunkMap: Cannot create new layer, server out of memory?");
@ -2670,11 +2677,16 @@ void cChunkMap::QueueTickBlock(int a_BlockX, int a_BlockY, int a_BlockZ)
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
// cChunkMap::cChunkLayer: // cChunkMap::cChunkLayer:
cChunkMap::cChunkLayer::cChunkLayer(int a_LayerX, int a_LayerZ, cChunkMap * a_Parent) cChunkMap::cChunkLayer::cChunkLayer(
int a_LayerX, int a_LayerZ,
cChunkMap * a_Parent,
cAllocationPool<cChunkData::sChunkSection> & a_Pool
)
: m_LayerX( a_LayerX ) : m_LayerX( a_LayerX )
, m_LayerZ( a_LayerZ ) , m_LayerZ( a_LayerZ )
, m_Parent( a_Parent ) , m_Parent( a_Parent )
, m_NumChunksLoaded( 0 ) , m_NumChunksLoaded( 0 )
, m_Pool(a_Pool)
{ {
memset(m_Chunks, 0, sizeof(m_Chunks)); memset(m_Chunks, 0, sizeof(m_Chunks));
} }
@ -2716,7 +2728,7 @@ cChunkPtr cChunkMap::cChunkLayer::GetChunk( int a_ChunkX, int a_ChunkY, int a_Ch
cChunk * neixp = (LocalX < LAYER_SIZE - 1) ? m_Chunks[Index + 1] : m_Parent->FindChunk(a_ChunkX + 1, a_ChunkZ); cChunk * neixp = (LocalX < LAYER_SIZE - 1) ? m_Chunks[Index + 1] : m_Parent->FindChunk(a_ChunkX + 1, a_ChunkZ);
cChunk * neizm = (LocalZ > 0) ? m_Chunks[Index - LAYER_SIZE] : m_Parent->FindChunk(a_ChunkX , a_ChunkZ - 1); cChunk * neizm = (LocalZ > 0) ? m_Chunks[Index - LAYER_SIZE] : m_Parent->FindChunk(a_ChunkX , a_ChunkZ - 1);
cChunk * neizp = (LocalZ < LAYER_SIZE - 1) ? m_Chunks[Index + LAYER_SIZE] : m_Parent->FindChunk(a_ChunkX , a_ChunkZ + 1); cChunk * neizp = (LocalZ < LAYER_SIZE - 1) ? m_Chunks[Index + LAYER_SIZE] : m_Parent->FindChunk(a_ChunkX , a_ChunkZ + 1);
m_Chunks[Index] = new cChunk(a_ChunkX, 0, a_ChunkZ, m_Parent, m_Parent->GetWorld(), neixm, neixp, neizm, neizp); m_Chunks[Index] = new cChunk(a_ChunkX, 0, a_ChunkZ, m_Parent, m_Parent->GetWorld(), neixm, neixp, neizm, neizp, m_Pool);
} }
return m_Chunks[Index]; return m_Chunks[Index];
} }

View File

@ -351,7 +351,11 @@ private:
class cChunkLayer class cChunkLayer
{ {
public: public:
cChunkLayer(int a_LayerX, int a_LayerZ, cChunkMap * a_Parent); cChunkLayer(
int a_LayerX, int a_LayerZ,
cChunkMap * a_Parent,
cAllocationPool<cChunkData::sChunkSection> & a_Pool
);
~cChunkLayer(); ~cChunkLayer();
/** Always returns an assigned chunkptr, but the chunk needn't be valid (loaded / generated) - callers must check */ /** Always returns an assigned chunkptr, but the chunk needn't be valid (loaded / generated) - callers must check */
@ -395,6 +399,25 @@ private:
int m_LayerZ; int m_LayerZ;
cChunkMap * m_Parent; cChunkMap * m_Parent;
int m_NumChunksLoaded; int m_NumChunksLoaded;
cAllocationPool<cChunkData::sChunkSection> & m_Pool;
};
class cStarvationCallbacks
: public cAllocationPool<cChunkData::sChunkSection>::cStarvationCallbacks
{
virtual void OnStartUsingReserve() override
{
LOG("Using backup memory buffer");
}
virtual void OnEndUsingReserve() override
{
LOG("Stoped using backup memory buffer");
}
virtual void OnOutOfReserve() override
{
LOG("Out of Memory");
}
}; };
typedef std::list<cChunkLayer *> cChunkLayerList; typedef std::list<cChunkLayer *> cChunkLayerList;
@ -427,6 +450,8 @@ private:
/** The cChunkStay descendants that are currently enabled in this chunkmap */ /** The cChunkStay descendants that are currently enabled in this chunkmap */
cChunkStays m_ChunkStays; cChunkStays m_ChunkStays;
std::auto_ptr<cAllocationPool<cChunkData::sChunkSection>> m_Pool;
cChunkPtr GetChunk (int a_ChunkX, int a_ChunkY, int a_ChunkZ); // Also queues the chunk for loading / generating if not valid cChunkPtr GetChunk (int a_ChunkX, int a_ChunkY, int a_ChunkZ); // Also queues the chunk for loading / generating if not valid
cChunkPtr GetChunkNoGen (int a_ChunkX, int a_ChunkY, int a_ChunkZ); // Also queues the chunk for loading if not valid; doesn't generate cChunkPtr GetChunkNoGen (int a_ChunkX, int a_ChunkY, int a_ChunkZ); // Also queues the chunk for loading if not valid; doesn't generate
cChunkPtr GetChunkNoLoad(int a_ChunkX, int a_ChunkY, int a_ChunkZ); // Doesn't load, doesn't generate cChunkPtr GetChunkNoLoad(int a_ChunkX, int a_ChunkY, int a_ChunkZ); // Doesn't load, doesn't generate

View File

@ -179,14 +179,9 @@ void cEntity::WrapRotation(void)
void cEntity::WrapSpeed(void) void cEntity::WrapSpeed(void)
{ {
// There shoudn't be a need for flipping the flag on because this function is called m_Speed.x = Clamp(m_Speed.x, -78.0, 78.0);
// after any update, so the flag is already turned on m_Speed.y = Clamp(m_Speed.y, -78.0, 78.0);
if (m_Speed.x > 78.0f) m_Speed.x = 78.0f; m_Speed.z = Clamp(m_Speed.z, -78.0, 78.0);
else if (m_Speed.x < -78.0f) m_Speed.x = -78.0f;
if (m_Speed.y > 78.0f) m_Speed.y = 78.0f;
else if (m_Speed.y < -78.0f) m_Speed.y = -78.0f;
if (m_Speed.z > 78.0f) m_Speed.z = 78.0f;
else if (m_Speed.z < -78.0f) m_Speed.z = -78.0f;
} }
@ -1076,6 +1071,17 @@ void cEntity::SetSwimState(cChunk & a_Chunk)
void cEntity::DoSetSpeed(double a_SpeedX, double a_SpeedY, double a_SpeedZ)
{
m_Speed.Set(a_SpeedX, a_SpeedY, a_SpeedZ);
WrapSpeed();
}
void cEntity::HandleAir(void) void cEntity::HandleAir(void)
{ {
// Ref.: http://www.minecraftwiki.net/wiki/Chunk_format // Ref.: http://www.minecraftwiki.net/wiki/Chunk_format
@ -1428,9 +1434,7 @@ void cEntity::SetRoll(double a_Roll)
void cEntity::SetSpeed(double a_SpeedX, double a_SpeedY, double a_SpeedZ) void cEntity::SetSpeed(double a_SpeedX, double a_SpeedY, double a_SpeedZ)
{ {
m_Speed.Set(a_SpeedX, a_SpeedY, a_SpeedZ); DoSetSpeed(a_SpeedX, a_SpeedY, a_SpeedZ);
WrapSpeed();
} }
@ -1438,9 +1442,7 @@ void cEntity::SetSpeed(double a_SpeedX, double a_SpeedY, double a_SpeedZ)
void cEntity::SetSpeedX(double a_SpeedX) void cEntity::SetSpeedX(double a_SpeedX)
{ {
m_Speed.x = a_SpeedX; SetSpeed(a_SpeedX, m_Speed.y, m_Speed.z);
WrapSpeed();
} }
@ -1448,9 +1450,7 @@ void cEntity::SetSpeedX(double a_SpeedX)
void cEntity::SetSpeedY(double a_SpeedY) void cEntity::SetSpeedY(double a_SpeedY)
{ {
m_Speed.y = a_SpeedY; SetSpeed(m_Speed.x, a_SpeedY, m_Speed.z);
WrapSpeed();
} }
@ -1458,9 +1458,7 @@ void cEntity::SetSpeedY(double a_SpeedY)
void cEntity::SetSpeedZ(double a_SpeedZ) void cEntity::SetSpeedZ(double a_SpeedZ)
{ {
m_Speed.z = a_SpeedZ; SetSpeed(m_Speed.x, m_Speed.y, a_SpeedZ);
WrapSpeed();
} }

View File

@ -215,11 +215,22 @@ public:
void SetYaw (double a_Yaw); // In degrees, normalizes to [-180, +180) void SetYaw (double a_Yaw); // In degrees, normalizes to [-180, +180)
void SetPitch (double a_Pitch); // In degrees, normalizes to [-180, +180) void SetPitch (double a_Pitch); // In degrees, normalizes to [-180, +180)
void SetRoll (double a_Roll); // In degrees, normalizes to [-180, +180) void SetRoll (double a_Roll); // In degrees, normalizes to [-180, +180)
void SetSpeed (double a_SpeedX, double a_SpeedY, double a_SpeedZ);
void SetSpeed (const Vector3d & a_Speed) { SetSpeed(a_Speed.x, a_Speed.y, a_Speed.z); } /** Sets the speed of the entity, measured in m / sec */
void SetSpeedX (double a_SpeedX); void SetSpeed(double a_SpeedX, double a_SpeedY, double a_SpeedZ);
void SetSpeedY (double a_SpeedY);
void SetSpeedZ (double a_SpeedZ); /** Sets the speed of the entity, measured in m / sec */
void SetSpeed(const Vector3d & a_Speed) { SetSpeed(a_Speed.x, a_Speed.y, a_Speed.z); }
/** Sets the speed in the X axis, leaving the other speed components intact. Measured in m / sec. */
void SetSpeedX(double a_SpeedX);
/** Sets the speed in the Y axis, leaving the other speed components intact. Measured in m / sec. */
void SetSpeedY(double a_SpeedY);
/** Sets the speed in the Z axis, leaving the other speed components intact. Measured in m / sec. */
void SetSpeedZ(double a_SpeedZ);
void SetWidth (double a_Width); void SetWidth (double a_Width);
void AddPosX (double a_AddPosX); void AddPosX (double a_AddPosX);
@ -429,6 +440,9 @@ protected:
static cCriticalSection m_CSCount; static cCriticalSection m_CSCount;
static int m_EntityCount; static int m_EntityCount;
/** Measured in meter/second (m/s) */
Vector3d m_Speed;
int m_UniqueID; int m_UniqueID;
int m_Health; int m_Health;
@ -487,10 +501,14 @@ protected:
int m_TicksSinceLastVoidDamage; int m_TicksSinceLastVoidDamage;
/** Does the actual speed-setting. The default implementation just sets the member variable value;
overrides can provide further processing, such as forcing players to move at the given speed. */
virtual void DoSetSpeed(double a_SpeedX, double a_SpeedY, double a_SpeedZ);
virtual void Destroyed(void) {} // Called after the entity has been destroyed virtual void Destroyed(void) {} // Called after the entity has been destroyed
/** Called in each tick to handle air-related processing i.e. drowning */ /** Called in each tick to handle air-related processing i.e. drowning */
virtual void HandleAir(); virtual void HandleAir(void);
/** Called once per tick to set IsSwimming and IsSubmerged */ /** Called once per tick to set IsSwimming and IsSubmerged */
virtual void SetSwimState(cChunk & a_Chunk); virtual void SetSwimState(cChunk & a_Chunk);
@ -506,9 +524,6 @@ private:
/** Measured in degrees, [-180, +180) */ /** Measured in degrees, [-180, +180) */
double m_HeadYaw; double m_HeadYaw;
/** Measured in meter/second (m/s) */
Vector3d m_Speed;
/** Measured in degrees, [-180, +180) */ /** Measured in degrees, [-180, +180) */
Vector3d m_Rot; Vector3d m_Rot;

View File

@ -22,6 +22,12 @@
#include "inifile/iniFile.h" #include "inifile/iniFile.h"
#include "json/json.h" #include "json/json.h"
// 6000 ticks or 5 minutes
#define PLAYER_INVENTORY_SAVE_INTERVAL 6000
// 1000 = once per second
#define PLAYER_LIST_TIME_MS 1000
@ -64,6 +70,7 @@ cPlayer::cPlayer(cClientHandle* a_Client, const AString & a_PlayerName)
, m_BowCharge(0) , m_BowCharge(0)
, m_FloaterID(-1) , m_FloaterID(-1)
, m_Team(NULL) , m_Team(NULL)
, m_TicksUntilNextSave(PLAYER_INVENTORY_SAVE_INTERVAL)
{ {
LOGD("Created a player object for \"%s\" @ \"%s\" at %p, ID %d", LOGD("Created a player object for \"%s\" @ \"%s\" at %p, ID %d",
a_PlayerName.c_str(), a_Client->GetIPString().c_str(), a_PlayerName.c_str(), a_Client->GetIPString().c_str(),
@ -250,7 +257,7 @@ void cPlayer::Tick(float a_Dt, cChunk & a_Chunk)
// Send Player List (Once per m_LastPlayerListTime/1000 ms) // Send Player List (Once per m_LastPlayerListTime/1000 ms)
cTimer t1; cTimer t1;
if (m_LastPlayerListTime + cPlayer::PLAYER_LIST_TIME_MS <= t1.GetNowTime()) if (m_LastPlayerListTime + PLAYER_LIST_TIME_MS <= t1.GetNowTime())
{ {
m_World->SendPlayerList(this); m_World->SendPlayerList(this);
m_LastPlayerListTime = t1.GetNowTime(); m_LastPlayerListTime = t1.GetNowTime();
@ -260,6 +267,16 @@ void cPlayer::Tick(float a_Dt, cChunk & a_Chunk)
{ {
m_LastGroundHeight = (float)GetPosY(); m_LastGroundHeight = (float)GetPosY();
} }
if (m_TicksUntilNextSave == 0)
{
SaveToDisk();
m_TicksUntilNextSave = PLAYER_INVENTORY_SAVE_INTERVAL;
}
else
{
m_TicksUntilNextSave--;
}
} }
@ -1257,6 +1274,17 @@ Vector3d cPlayer::GetThrowSpeed(double a_SpeedCoeff) const
void cPlayer::ForceSetSpeed(const Vector3d & a_Speed) void cPlayer::ForceSetSpeed(const Vector3d & a_Speed)
{ {
SetSpeed(a_Speed); SetSpeed(a_Speed);
}
void cPlayer::DoSetSpeed(double a_SpeedX, double a_SpeedY, double a_SpeedZ)
{
super::DoSetSpeed(a_SpeedX, a_SpeedY, a_SpeedZ);
// Send the speed to the client so he actualy moves
m_ClientHandle->SendEntityVelocity(*this); m_ClientHandle->SendEntityVelocity(*this);
} }

View File

@ -194,7 +194,8 @@ public:
// Sets the current gamemode, doesn't check validity, doesn't send update packets to client // Sets the current gamemode, doesn't check validity, doesn't send update packets to client
void LoginSetGameMode(eGameMode a_GameMode); void LoginSetGameMode(eGameMode a_GameMode);
/** Forces the player to move in the given direction. */ /** Forces the player to move in the given direction.
@deprecated Use SetSpeed instead. */
void ForceSetSpeed(const Vector3d & a_Speed); // tolua_export void ForceSetSpeed(const Vector3d & a_Speed); // tolua_export
/** Tries to move to a new position, with attachment-related checks (y == -999) */ /** Tries to move to a new position, with attachment-related checks (y == -999) */
@ -461,7 +462,6 @@ protected:
cItem m_DraggingItem; cItem m_DraggingItem;
long long m_LastPlayerListTime; long long m_LastPlayerListTime;
static const unsigned short PLAYER_LIST_TIME_MS = 1000; // 1000 = once per second
cClientHandle * m_ClientHandle; cClientHandle * m_ClientHandle;
@ -512,6 +512,9 @@ protected:
/** Sets the speed and sends it to the client, so that they are forced to move so. */
virtual void DoSetSpeed(double a_SpeedX, double a_SpeedY, double a_SpeedZ) override;
void ResolvePermissions(void); void ResolvePermissions(void);
void ResolveGroups(void); void ResolveGroups(void);
@ -539,6 +542,10 @@ protected:
Set by a right click on unoccupied bed, unset by a time fast forward or teleport */ Set by a right click on unoccupied bed, unset by a time fast forward or teleport */
bool m_bIsInBed; bool m_bIsInBed;
/** How long till the player's inventory will be saved
Default save interval is #defined in PLAYER_INVENTORY_SAVE_INTERVAL */
unsigned int m_TicksUntilNextSave;
} ; // tolua_export } ; // tolua_export

View File

@ -125,7 +125,7 @@ public:
int m_BlockX; int m_BlockX;
int m_BlockZ; int m_BlockZ;
cCaveSystem(int a_OriginX, int a_OriginZ, int a_MaxOffset, int a_Size, cNoise & a_Noise); cCaveSystem(int a_GridX, int a_GridZ, int a_OriginX, int a_OriginZ, int a_MaxOffset, int a_Size, cNoise & a_Noise);
~cCaveSystem(); ~cCaveSystem();
protected: protected:
@ -574,8 +574,8 @@ AString cCaveTunnel::ExportAsSVG(int a_Color, int a_OffsetX, int a_OffsetZ) cons
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// cStructGenWormNestCaves::cCaveSystem: // cStructGenWormNestCaves::cCaveSystem:
cStructGenWormNestCaves::cCaveSystem::cCaveSystem(int a_OriginX, int a_OriginZ, int a_MaxOffset, int a_Size, cNoise & a_Noise) : cStructGenWormNestCaves::cCaveSystem::cCaveSystem(int a_GridX, int a_GridZ, int a_OriginX, int a_OriginZ, int a_MaxOffset, int a_Size, cNoise & a_Noise) :
super(a_OriginX, a_OriginZ), super(a_GridX, a_GridZ, a_OriginX, a_OriginZ),
m_Size(a_Size) m_Size(a_Size)
{ {
int Num = 1 + a_Noise.IntNoise2DInt(a_OriginX, a_OriginZ) % 3; int Num = 1 + a_Noise.IntNoise2DInt(a_OriginX, a_OriginZ) % 3;
@ -690,9 +690,9 @@ int cStructGenWormNestCaves::cCaveSystem::GetRadius(cNoise & a_Noise, int a_Orig
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// cStructGenWormNestCaves: // cStructGenWormNestCaves:
cGridStructGen::cStructurePtr cStructGenWormNestCaves::CreateStructure(int a_OriginX, int a_OriginZ) cGridStructGen::cStructurePtr cStructGenWormNestCaves::CreateStructure(int a_GridX, int a_GridZ, int a_OriginX, int a_OriginZ)
{ {
return cStructurePtr(new cCaveSystem(a_OriginX, a_OriginZ, m_MaxOffset, m_Size, m_Noise)); return cStructurePtr(new cCaveSystem(a_GridX, a_GridZ, a_OriginX, a_OriginZ, m_MaxOffset, m_Size, m_Noise));
} }

View File

@ -69,7 +69,7 @@ class cStructGenWormNestCaves :
typedef cGridStructGen super; typedef cGridStructGen super;
public: public:
cStructGenWormNestCaves(int a_Seed, int a_Size = 64, int a_Grid = 96, int a_MaxOffset = 128) : cStructGenWormNestCaves(int a_Seed, int a_Size = 64, int a_Grid = 96, int a_MaxOffset = 128) :
super(a_Seed, a_Grid, a_Grid, a_Size + a_MaxOffset, a_Size + a_MaxOffset, 100), super(a_Seed, a_Grid, a_Grid, a_MaxOffset, a_MaxOffset, a_Size, a_Size, 100),
m_Noise(a_Seed), m_Noise(a_Seed),
m_Size(a_Size), m_Size(a_Size),
m_MaxOffset(a_MaxOffset), m_MaxOffset(a_MaxOffset),
@ -86,7 +86,7 @@ protected:
int m_Grid; // average spacing of the nests int m_Grid; // average spacing of the nests
// cGridStructGen override: // cGridStructGen override:
virtual cStructurePtr CreateStructure(int a_OriginX, int a_OriginZ) override; virtual cStructurePtr CreateStructure(int a_GridX, int a_GridZ, int a_OriginX, int a_OriginZ) override;
} ; } ;

View File

@ -357,12 +357,13 @@ void cComposableGenerator::InitFinishGens(cIniFile & a_IniFile)
else if (NoCaseCompare(*itr, "MineShafts") == 0) else if (NoCaseCompare(*itr, "MineShafts") == 0)
{ {
int GridSize = a_IniFile.GetValueSetI("Generator", "MineShaftsGridSize", 512); int GridSize = a_IniFile.GetValueSetI("Generator", "MineShaftsGridSize", 512);
int MaxOffset = a_IniFile.GetValueSetI("Generator", "MineShaftsMaxOffset", 256);
int MaxSystemSize = a_IniFile.GetValueSetI("Generator", "MineShaftsMaxSystemSize", 160); int MaxSystemSize = a_IniFile.GetValueSetI("Generator", "MineShaftsMaxSystemSize", 160);
int ChanceCorridor = a_IniFile.GetValueSetI("Generator", "MineShaftsChanceCorridor", 600); int ChanceCorridor = a_IniFile.GetValueSetI("Generator", "MineShaftsChanceCorridor", 600);
int ChanceCrossing = a_IniFile.GetValueSetI("Generator", "MineShaftsChanceCrossing", 200); int ChanceCrossing = a_IniFile.GetValueSetI("Generator", "MineShaftsChanceCrossing", 200);
int ChanceStaircase = a_IniFile.GetValueSetI("Generator", "MineShaftsChanceStaircase", 200); int ChanceStaircase = a_IniFile.GetValueSetI("Generator", "MineShaftsChanceStaircase", 200);
m_FinishGens.push_back(new cStructGenMineShafts( m_FinishGens.push_back(new cStructGenMineShafts(
Seed, GridSize, MaxSystemSize, Seed, GridSize, MaxOffset, MaxSystemSize,
ChanceCorridor, ChanceCrossing, ChanceStaircase ChanceCorridor, ChanceCrossing, ChanceStaircase
)); ));
} }
@ -376,9 +377,10 @@ void cComposableGenerator::InitFinishGens(cIniFile & a_IniFile)
} }
else if (NoCaseCompare(*itr, "NetherForts") == 0) else if (NoCaseCompare(*itr, "NetherForts") == 0)
{ {
int GridSize = a_IniFile.GetValueSetI("Generator", "NetherFortsGridSize", 512); int GridSize = a_IniFile.GetValueSetI("Generator", "NetherFortsGridSize", 512);
int MaxDepth = a_IniFile.GetValueSetI("Generator", "NetherFortsMaxDepth", 12); int MaxOffset = a_IniFile.GetValueSetI("Generator", "NetherFortMaxOffset", 128);
m_FinishGens.push_back(new cNetherFortGen(Seed, GridSize, MaxDepth)); int MaxDepth = a_IniFile.GetValueSetI("Generator", "NetherFortsMaxDepth", 12);
m_FinishGens.push_back(new cNetherFortGen(Seed, GridSize, MaxOffset, MaxDepth));
} }
else if (NoCaseCompare(*itr, "OreNests") == 0) else if (NoCaseCompare(*itr, "OreNests") == 0)
{ {
@ -394,10 +396,11 @@ void cComposableGenerator::InitFinishGens(cIniFile & a_IniFile)
} }
else if (NoCaseCompare(*itr, "RainbowRoads") == 0) else if (NoCaseCompare(*itr, "RainbowRoads") == 0)
{ {
int GridSize = a_IniFile.GetValueSetI("Generator", "RainbowRoadsGridSize", 512); int GridSize = a_IniFile.GetValueSetI("Generator", "RainbowRoadsGridSize", 512);
int MaxDepth = a_IniFile.GetValueSetI("Generator", "RainbowRoadsMaxDepth", 30); int MaxOffset = a_IniFile.GetValueSetI("Generator", "RainbowRoadsMaxOffset", 128);
int MaxSize = a_IniFile.GetValueSetI("Generator", "RainbowRoadsMaxSize", 260); int MaxDepth = a_IniFile.GetValueSetI("Generator", "RainbowRoadsMaxDepth", 30);
m_FinishGens.push_back(new cRainbowRoadsGen(Seed, GridSize, MaxDepth, MaxSize)); int MaxSize = a_IniFile.GetValueSetI("Generator", "RainbowRoadsMaxSize", 260);
m_FinishGens.push_back(new cRainbowRoadsGen(Seed, GridSize, MaxOffset, MaxDepth, MaxSize));
} }
else if (NoCaseCompare(*itr, "Ravines") == 0) else if (NoCaseCompare(*itr, "Ravines") == 0)
{ {
@ -417,19 +420,21 @@ void cComposableGenerator::InitFinishGens(cIniFile & a_IniFile)
} }
else if (NoCaseCompare(*itr, "UnderwaterBases") == 0) else if (NoCaseCompare(*itr, "UnderwaterBases") == 0)
{ {
int GridSize = a_IniFile.GetValueSetI("Generator", "UnderwaterBaseGridSize", 1024); int GridSize = a_IniFile.GetValueSetI("Generator", "UnderwaterBaseGridSize", 1024);
int MaxDepth = a_IniFile.GetValueSetI("Generator", "UnderwaterBaseMaxDepth", 7); int MaxOffset = a_IniFile.GetValueSetI("Generator", "UnderwaterBaseMaxOffset", 128);
int MaxSize = a_IniFile.GetValueSetI("Generator", "UnderwaterBaseMaxSize", 128); int MaxDepth = a_IniFile.GetValueSetI("Generator", "UnderwaterBaseMaxDepth", 7);
m_FinishGens.push_back(new cUnderwaterBaseGen(Seed, GridSize, MaxDepth, MaxSize, *m_BiomeGen)); int MaxSize = a_IniFile.GetValueSetI("Generator", "UnderwaterBaseMaxSize", 128);
m_FinishGens.push_back(new cUnderwaterBaseGen(Seed, GridSize, MaxOffset, MaxDepth, MaxSize, *m_BiomeGen));
} }
else if (NoCaseCompare(*itr, "Villages") == 0) else if (NoCaseCompare(*itr, "Villages") == 0)
{ {
int GridSize = a_IniFile.GetValueSetI("Generator", "VillageGridSize", 384); int GridSize = a_IniFile.GetValueSetI("Generator", "VillageGridSize", 384);
int MaxOffset = a_IniFile.GetValueSetI("Generator", "VillageMaxOffset", 128);
int MaxDepth = a_IniFile.GetValueSetI("Generator", "VillageMaxDepth", 2); int MaxDepth = a_IniFile.GetValueSetI("Generator", "VillageMaxDepth", 2);
int MaxSize = a_IniFile.GetValueSetI("Generator", "VillageMaxSize", 128); int MaxSize = a_IniFile.GetValueSetI("Generator", "VillageMaxSize", 128);
int MinDensity = a_IniFile.GetValueSetI("Generator", "VillageMinDensity", 50); int MinDensity = a_IniFile.GetValueSetI("Generator", "VillageMinDensity", 50);
int MaxDensity = a_IniFile.GetValueSetI("Generator", "VillageMaxDensity", 80); int MaxDensity = a_IniFile.GetValueSetI("Generator", "VillageMaxDensity", 80);
m_FinishGens.push_back(new cVillageGen(Seed, GridSize, MaxDepth, MaxSize, MinDensity, MaxDensity, *m_BiomeGen, *m_HeightGen)); m_FinishGens.push_back(new cVillageGen(Seed, GridSize, MaxOffset, MaxDepth, MaxSize, MinDensity, MaxDensity, *m_BiomeGen, *m_HeightGen));
} }
else if (NoCaseCompare(*itr, "WaterLakes") == 0) else if (NoCaseCompare(*itr, "WaterLakes") == 0)
{ {
@ -442,7 +447,10 @@ void cComposableGenerator::InitFinishGens(cIniFile & a_IniFile)
} }
else if (NoCaseCompare(*itr, "WormNestCaves") == 0) else if (NoCaseCompare(*itr, "WormNestCaves") == 0)
{ {
m_FinishGens.push_back(new cStructGenWormNestCaves(Seed)); int Size = a_IniFile.GetValueSetI("Generator", "WormNestCavesSize", 64);
int Grid = a_IniFile.GetValueSetI("Generator", "WormNestCavesGrid", 96);
int MaxOffset = a_IniFile.GetValueSetI("Generator", "WormNestMaxOffset", 32);
m_FinishGens.push_back(new cStructGenWormNestCaves(Seed, Size, Grid, MaxOffset));
} }
else else
{ {

View File

@ -21,8 +21,8 @@ class cEmptyStructure :
typedef cGridStructGen::cStructure super; typedef cGridStructGen::cStructure super;
public: public:
cEmptyStructure(int a_OriginX, int a_OriginZ) : cEmptyStructure(int a_GridX, int a_GridZ, int a_OriginX, int a_OriginZ) :
super(a_OriginX, a_OriginZ) super(a_GridX, a_GridZ, a_OriginX, a_OriginZ)
{ {
} }
@ -40,17 +40,20 @@ protected:
cGridStructGen::cGridStructGen( cGridStructGen::cGridStructGen(
int a_Seed, int a_Seed,
int a_GridSizeX, int a_GridSizeZ, int a_GridSizeX, int a_GridSizeZ,
int a_MaxOffsetX, int a_MaxOffsetZ,
int a_MaxStructureSizeX, int a_MaxStructureSizeZ, int a_MaxStructureSizeX, int a_MaxStructureSizeZ,
size_t a_MaxCacheSize size_t a_MaxCacheSize
) : ) :
m_Seed(a_Seed), m_Noise(a_Seed),
m_GridSizeX(a_GridSizeX), m_GridSizeX(a_GridSizeX),
m_GridSizeZ(a_GridSizeZ), m_GridSizeZ(a_GridSizeZ),
m_MaxOffsetX(a_MaxOffsetX),
m_MaxOffsetZ(a_MaxOffsetZ),
m_MaxStructureSizeX(a_MaxStructureSizeX), m_MaxStructureSizeX(a_MaxStructureSizeX),
m_MaxStructureSizeZ(a_MaxStructureSizeZ), m_MaxStructureSizeZ(a_MaxStructureSizeZ),
m_MaxCacheSize(a_MaxCacheSize) m_MaxCacheSize(a_MaxCacheSize)
{ {
size_t NumStructuresPerQuery = (size_t)((m_MaxStructureSizeX / m_GridSizeX + 1) * (m_MaxStructureSizeZ / m_GridSizeZ + 1)); size_t NumStructuresPerQuery = (size_t)(((m_MaxStructureSizeX + m_MaxOffsetX) / m_GridSizeX + 1) * ((m_MaxStructureSizeZ + m_MaxOffsetZ) / m_GridSizeZ + 1));
if (NumStructuresPerQuery > m_MaxCacheSize) if (NumStructuresPerQuery > m_MaxCacheSize)
{ {
m_MaxCacheSize = NumStructuresPerQuery * 4; m_MaxCacheSize = NumStructuresPerQuery * 4;
@ -68,10 +71,10 @@ cGridStructGen::cGridStructGen(
void cGridStructGen::GetStructuresForChunk(int a_ChunkX, int a_ChunkZ, cStructurePtrs & a_Structures) void cGridStructGen::GetStructuresForChunk(int a_ChunkX, int a_ChunkZ, cStructurePtrs & a_Structures)
{ {
// Calculate the min and max grid coords of the structures to be returned: // Calculate the min and max grid coords of the structures to be returned:
int MinBlockX = a_ChunkX * cChunkDef::Width - m_MaxStructureSizeX; int MinBlockX = a_ChunkX * cChunkDef::Width - m_MaxStructureSizeX - m_MaxOffsetX;
int MinBlockZ = a_ChunkZ * cChunkDef::Width - m_MaxStructureSizeZ; int MinBlockZ = a_ChunkZ * cChunkDef::Width - m_MaxStructureSizeZ - m_MaxOffsetZ;
int MaxBlockX = a_ChunkX * cChunkDef::Width + m_MaxStructureSizeX + cChunkDef::Width - 1; int MaxBlockX = a_ChunkX * cChunkDef::Width + m_MaxStructureSizeX + m_MaxOffsetX + cChunkDef::Width - 1;
int MaxBlockZ = a_ChunkZ * cChunkDef::Width + m_MaxStructureSizeZ + cChunkDef::Width - 1; int MaxBlockZ = a_ChunkZ * cChunkDef::Width + m_MaxStructureSizeZ + m_MaxOffsetZ + cChunkDef::Width - 1;
int MinGridX = MinBlockX / m_GridSizeX; int MinGridX = MinBlockX / m_GridSizeX;
int MinGridZ = MinBlockZ / m_GridSizeZ; int MinGridZ = MinBlockZ / m_GridSizeZ;
int MaxGridX = (MaxBlockX + m_GridSizeX - 1) / m_GridSizeX; int MaxGridX = (MaxBlockX + m_GridSizeX - 1) / m_GridSizeX;
@ -103,14 +106,14 @@ void cGridStructGen::GetStructuresForChunk(int a_ChunkX, int a_ChunkZ, cStructur
// Create those structures that haven't been in the cache: // Create those structures that haven't been in the cache:
for (int x = MinGridX; x < MaxGridX; x++) for (int x = MinGridX; x < MaxGridX; x++)
{ {
int OriginX = x * m_GridSizeX; int GridX = x * m_GridSizeX;
for (int z = MinGridZ; z < MaxGridZ; z++) for (int z = MinGridZ; z < MaxGridZ; z++)
{ {
int OriginZ = z * m_GridSizeZ; int GridZ = z * m_GridSizeZ;
bool Found = false; bool Found = false;
for (cStructurePtrs::const_iterator itr = a_Structures.begin(), end = a_Structures.end(); itr != end; ++itr) for (cStructurePtrs::const_iterator itr = a_Structures.begin(), end = a_Structures.end(); itr != end; ++itr)
{ {
if (((*itr)->m_OriginX == OriginX) && ((*itr)->m_OriginZ == OriginZ)) if (((*itr)->m_GridX == GridX) && ((*itr)->m_GridZ == GridZ))
{ {
Found = true; Found = true;
break; break;
@ -118,10 +121,12 @@ void cGridStructGen::GetStructuresForChunk(int a_ChunkX, int a_ChunkZ, cStructur
} // for itr - a_Structures[] } // for itr - a_Structures[]
if (!Found) if (!Found)
{ {
cStructurePtr Structure = CreateStructure(OriginX, OriginZ); int OriginX = GridX + ((m_Noise.IntNoise2DInt(GridX + 3, GridZ + 5) / 7) % (m_MaxOffsetX * 2)) - m_MaxOffsetX;
int OriginZ = GridZ + ((m_Noise.IntNoise2DInt(GridX + 5, GridZ + 3) / 7) % (m_MaxOffsetZ * 2)) - m_MaxOffsetZ;
cStructurePtr Structure = CreateStructure(GridX, GridZ, OriginX, OriginZ);
if (Structure.get() == NULL) if (Structure.get() == NULL)
{ {
Structure.reset(new cEmptyStructure(OriginX, OriginZ)); Structure.reset(new cEmptyStructure(GridX, GridZ, OriginX, OriginZ));
} }
a_Structures.push_back(Structure); a_Structures.push_back(Structure);
} }

View File

@ -10,6 +10,7 @@
#pragma once #pragma once
#include "ComposableGenerator.h" #include "ComposableGenerator.h"
#include "../Noise.h"
@ -19,7 +20,12 @@
Defines a grid in the XZ space with predefined cell size in each direction. Each cell then receives exactly Defines a grid in the XZ space with predefined cell size in each direction. Each cell then receives exactly
one structure (provided by the descendant class). The structure is placed within the cell, but doesn't need one structure (provided by the descendant class). The structure is placed within the cell, but doesn't need
to be bounded by the cell, it can be well outside the cell; the generator uses the MaxStructureSize parameter to be bounded by the cell, it can be well outside the cell; the generator uses the MaxStructureSize parameter
to determine how far away from the cell the structure can be at most. to determine how far away from the cell the structure can be at most. Each structure has an offset from the
grid's center point, the offset is generated randomly from a range given to this class as a parameter.
Each structure thus contains the coords of its grid center (m_GridX, m_GridZ) and the actual origin from
which it's built (m_OriginX, m_OriginZ).
This class provides a cache for the structures generated for successive chunks and manages that cache. It This class provides a cache for the structures generated for successive chunks and manages that cache. It
also provides the cFinishGen override that uses the cache to actually generate the structure into chunk data. also provides the cFinishGen override that uses the cache to actually generate the structure into chunk data.
@ -43,12 +49,17 @@ public:
class cStructure class cStructure
{ {
public: public:
/** The origin (the coords of the gridpoint for which the structure is generated) */ /** The grid point for which the structure is generated. */
int m_GridX, m_GridZ;
/** The origin (the coords for which the structure is generated) */
int m_OriginX, m_OriginZ; int m_OriginX, m_OriginZ;
/** Creates a structure that has its originset at the specified coords. */ /** Creates a structure that has its origin set at the specified coords. */
cStructure (int a_OriginX, int a_OriginZ) : cStructure (int a_GridX, int a_GridZ, int a_OriginX, int a_OriginZ) :
m_GridX(a_GridX),
m_GridZ(a_GridZ),
m_OriginX(a_OriginX), m_OriginX(a_OriginX),
m_OriginZ(a_OriginZ) m_OriginZ(a_OriginZ)
{ {
@ -70,20 +81,30 @@ public:
cGridStructGen( cGridStructGen(
int a_Seed, int a_Seed,
int a_GridSizeX, int a_GridSizeZ, int a_GridSizeX, int a_GridSizeZ,
int a_MaxOffsetX, int a_MaxOffsetZ,
int a_MaxStructureSizeX, int a_MaxStructureSizeZ, int a_MaxStructureSizeX, int a_MaxStructureSizeZ,
size_t a_MaxCacheSize size_t a_MaxCacheSize
); );
protected: protected:
/** Seed for generating the semi-random grid. */ /** Seed for generating grid offsets and also available for descendants. */
int m_Seed; int m_Seed;
/** The noise used for generating grid offsets. */
cNoise m_Noise;
/** The size of each grid's cell in the X axis */ /** The size of each grid's cell in the X axis */
int m_GridSizeX; int m_GridSizeX;
/** The size of each grid's cell in the Z axis */ /** The size of each grid's cell in the Z axis */
int m_GridSizeZ; int m_GridSizeZ;
/** The maximum offset of the structure's origin from the grid midpoint, in X coord. */
int m_MaxOffsetX;
/** The maximum offset of the structure's origin from the grid midpoint, in Z coord. */
int m_MaxOffsetZ;
/** Maximum theoretical size of the structure in the X axis. /** Maximum theoretical size of the structure in the X axis.
This limits the structures considered for a single chunk, so the lesser the number, the better performance. This limits the structures considered for a single chunk, so the lesser the number, the better performance.
Structures large than this may get cropped. */ Structures large than this may get cropped. */
@ -115,7 +136,7 @@ protected:
// Functions for the descendants to override: // Functions for the descendants to override:
/** Create a new structure at the specified gridpoint */ /** Create a new structure at the specified gridpoint */
virtual cStructurePtr CreateStructure(int a_OriginX, int a_OriginZ) = 0; virtual cStructurePtr CreateStructure(int a_GridX, int a_GridZ, int a_OriginX, int a_OriginZ) = 0;
} ; } ;

View File

@ -248,7 +248,8 @@ public:
/** Creates and generates the entire system */ /** Creates and generates the entire system */
cMineShaftSystem( cMineShaftSystem(
int a_OriginX, int a_OriginZ, int a_GridSize, int a_MaxSystemSize, cNoise & a_Noise, int a_GridX, int a_GridZ, int a_OriginX, int a_OriginZ,
int a_GridSize, int a_MaxSystemSize, cNoise & a_Noise,
int a_ProbLevelCorridor, int a_ProbLevelCrossing, int a_ProbLevelStaircase int a_ProbLevelCorridor, int a_ProbLevelCrossing, int a_ProbLevelStaircase
); );
@ -278,10 +279,11 @@ public:
// cStructGenMineShafts::cMineShaftSystem: // cStructGenMineShafts::cMineShaftSystem:
cStructGenMineShafts::cMineShaftSystem::cMineShaftSystem( cStructGenMineShafts::cMineShaftSystem::cMineShaftSystem(
int a_OriginX, int a_OriginZ, int a_GridSize, int a_MaxSystemSize, cNoise & a_Noise, int a_GridX, int a_GridZ, int a_OriginX, int a_OriginZ,
int a_GridSize, int a_MaxSystemSize, cNoise & a_Noise,
int a_ProbLevelCorridor, int a_ProbLevelCrossing, int a_ProbLevelStaircase int a_ProbLevelCorridor, int a_ProbLevelCrossing, int a_ProbLevelStaircase
) : ) :
super(a_OriginX, a_OriginZ), super(a_GridX, a_GridZ, a_OriginX, a_OriginZ),
m_GridSize(a_GridSize), m_GridSize(a_GridSize),
m_MaxRecursion(8), // TODO: settable m_MaxRecursion(8), // TODO: settable
m_ProbLevelCorridor(a_ProbLevelCorridor), m_ProbLevelCorridor(a_ProbLevelCorridor),
@ -1280,10 +1282,10 @@ void cMineShaftStaircase::ProcessChunk(cChunkDesc & a_ChunkDesc)
// cStructGenMineShafts: // cStructGenMineShafts:
cStructGenMineShafts::cStructGenMineShafts( cStructGenMineShafts::cStructGenMineShafts(
int a_Seed, int a_GridSize, int a_MaxSystemSize, int a_Seed, int a_GridSize, int a_MaxOffset, int a_MaxSystemSize,
int a_ChanceCorridor, int a_ChanceCrossing, int a_ChanceStaircase int a_ChanceCorridor, int a_ChanceCrossing, int a_ChanceStaircase
) : ) :
super(a_Seed, a_GridSize, a_GridSize, a_MaxSystemSize, a_MaxSystemSize, 100), super(a_Seed, a_GridSize, a_GridSize, a_MaxOffset, a_MaxOffset, a_MaxSystemSize, a_MaxSystemSize, 100),
m_Noise(a_Seed), m_Noise(a_Seed),
m_GridSize(a_GridSize), m_GridSize(a_GridSize),
m_MaxSystemSize(a_MaxSystemSize), m_MaxSystemSize(a_MaxSystemSize),
@ -1297,9 +1299,9 @@ cStructGenMineShafts::cStructGenMineShafts(
cGridStructGen::cStructurePtr cStructGenMineShafts::CreateStructure(int a_OriginX, int a_OriginZ) cGridStructGen::cStructurePtr cStructGenMineShafts::CreateStructure(int a_GridX, int a_GridZ, int a_OriginX, int a_OriginZ)
{ {
return cStructurePtr(new cMineShaftSystem(a_OriginX, a_OriginZ, m_GridSize, m_MaxSystemSize, m_Noise, m_ProbLevelCorridor, m_ProbLevelCrossing, m_ProbLevelStaircase)); return cStructurePtr(new cMineShaftSystem(a_GridX, a_GridZ, a_OriginX, a_OriginZ, m_GridSize, m_MaxSystemSize, m_Noise, m_ProbLevelCorridor, m_ProbLevelCrossing, m_ProbLevelStaircase));
} }

View File

@ -23,7 +23,7 @@ class cStructGenMineShafts :
public: public:
cStructGenMineShafts( cStructGenMineShafts(
int a_Seed, int a_GridSize, int a_MaxSystemSize, int a_Seed, int a_GridSize, int a_MaxOffset, int a_MaxSystemSize,
int a_ChanceCorridor, int a_ChanceCrossing, int a_ChanceStaircase int a_ChanceCorridor, int a_ChanceCrossing, int a_ChanceStaircase
); );
@ -43,7 +43,7 @@ protected:
int m_ProbLevelStaircase; ///< Probability level of a branch object being the staircase, minus Crossing int m_ProbLevelStaircase; ///< Probability level of a branch object being the staircase, minus Crossing
// cGridStructGen overrides: // cGridStructGen overrides:
virtual cStructurePtr CreateStructure(int a_OriginX, int a_OriginZ) override; virtual cStructurePtr CreateStructure(int a_GridX, int a_GridZ, int a_OriginX, int a_OriginZ) override;
} ; } ;

View File

@ -26,8 +26,8 @@ public:
cPlacedPieces m_Pieces; cPlacedPieces m_Pieces;
cNetherFort(cNetherFortGen & a_ParentGen, int a_OriginX, int a_OriginZ, int a_GridSize, int a_MaxDepth, int a_Seed) : cNetherFort(cNetherFortGen & a_ParentGen, int a_GridX, int a_GridZ, int a_OriginX, int a_OriginZ, int a_GridSize, int a_MaxDepth, int a_Seed) :
super(a_OriginX, a_OriginZ), super(a_GridX, a_GridZ, a_OriginX, a_OriginZ),
m_ParentGen(a_ParentGen), m_ParentGen(a_ParentGen),
m_GridSize(a_GridSize), m_GridSize(a_GridSize),
m_Seed(a_Seed) m_Seed(a_Seed)
@ -108,8 +108,8 @@ cPrefabPiecePool cNetherFortGen::m_PiecePool(g_NetherFortPrefabs, g_NetherFortPr
cNetherFortGen::cNetherFortGen(int a_Seed, int a_GridSize, int a_MaxDepth) : cNetherFortGen::cNetherFortGen(int a_Seed, int a_GridSize, int a_MaxOffset, int a_MaxDepth) :
super(a_Seed, a_GridSize, a_GridSize, a_MaxDepth * 10, a_MaxDepth * 10, 200), super(a_Seed, a_GridSize, a_GridSize, a_MaxOffset, a_MaxOffset, a_MaxDepth * 10, a_MaxDepth * 10, 200),
m_MaxDepth(a_MaxDepth) m_MaxDepth(a_MaxDepth)
{ {
/* /*
@ -124,8 +124,11 @@ cNetherFortGen::cNetherFortGen(int a_Seed, int a_GridSize, int a_MaxDepth) :
cGridStructGen::cStructurePtr cNetherFortGen::CreateStructure(int a_OriginX, int a_OriginZ) cGridStructGen::cStructurePtr cNetherFortGen::CreateStructure(int a_GridX, int a_GridZ, int a_OriginX, int a_OriginZ)
{ {
return cStructurePtr(new cNetherFort(*this, a_OriginX, a_OriginZ, m_GridSizeX, m_MaxDepth, m_Seed)); return cStructurePtr(new cNetherFort(*this, a_GridX, a_GridZ, a_OriginX, a_OriginZ, m_GridSizeX, m_MaxDepth, m_Seed));
} }

View File

@ -23,7 +23,7 @@ class cNetherFortGen :
typedef cGridStructGen super; typedef cGridStructGen super;
public: public:
cNetherFortGen(int a_Seed, int a_GridSize, int a_MaxDepth); cNetherFortGen(int a_Seed, int a_GridSize, int a_MaxOffset, int a_MaxDepth);
protected: protected:
friend class cNetherFortPerfTest; // fwd: NetherFortGen.cpp friend class cNetherFortPerfTest; // fwd: NetherFortGen.cpp
@ -37,7 +37,7 @@ protected:
// cGridStructGen overrides: // cGridStructGen overrides:
virtual cStructurePtr CreateStructure(int a_OriginX, int a_OriginZ) override; virtual cStructurePtr CreateStructure(int a_GridX, int a_GridZ, int a_OriginX, int a_OriginZ) override;
} ; } ;

File diff suppressed because it is too large Load Diff

View File

@ -29,11 +29,12 @@ class cRainbowRoadsGen::cRainbowRoads :
public: public:
cRainbowRoads( cRainbowRoads(
int a_Seed, int a_Seed,
int a_GridX, int a_GridZ,
int a_OriginX, int a_OriginZ, int a_OriginX, int a_OriginZ,
int a_MaxDepth, int a_MaxDepth,
int a_MaxSize int a_MaxSize
) : ) :
super(a_OriginX, a_OriginZ), super(a_GridX, a_GridZ, a_OriginX, a_OriginZ),
m_Seed(a_Seed), m_Seed(a_Seed),
m_Noise(a_Seed), m_Noise(a_Seed),
m_MaxSize(a_MaxSize), m_MaxSize(a_MaxSize),
@ -92,8 +93,8 @@ protected:
cRainbowRoadsGen::cRainbowRoadsGen(int a_Seed, int a_GridSize, int a_MaxDepth, int a_MaxSize) : cRainbowRoadsGen::cRainbowRoadsGen(int a_Seed, int a_GridSize, int a_MaxOffset, int a_MaxDepth, int a_MaxSize) :
super(a_Seed, a_GridSize, a_GridSize, a_MaxSize, a_MaxSize, 100), super(a_Seed, a_GridSize, a_GridSize, a_MaxOffset, a_MaxOffset, a_MaxSize, a_MaxSize, 100),
m_Noise(a_Seed + 9000), m_Noise(a_Seed + 9000),
m_MaxDepth(a_MaxDepth), m_MaxDepth(a_MaxDepth),
m_MaxSize(a_MaxSize) m_MaxSize(a_MaxSize)
@ -104,10 +105,10 @@ cRainbowRoadsGen::cRainbowRoadsGen(int a_Seed, int a_GridSize, int a_MaxDepth, i
cGridStructGen::cStructurePtr cRainbowRoadsGen::CreateStructure(int a_OriginX, int a_OriginZ) cGridStructGen::cStructurePtr cRainbowRoadsGen::CreateStructure(int a_GridX, int a_GridZ, int a_OriginX, int a_OriginZ)
{ {
// Create a base based on the chosen prefabs: // Create a base based on the chosen prefabs:
return cStructurePtr(new cRainbowRoads(m_Seed, a_OriginX, a_OriginZ, m_MaxDepth, m_MaxSize)); return cStructurePtr(new cRainbowRoads(m_Seed, a_GridX, a_GridZ, a_OriginX, a_OriginZ, m_MaxDepth, m_MaxSize));
} }

View File

@ -22,7 +22,7 @@ class cRainbowRoadsGen :
typedef cGridStructGen super; typedef cGridStructGen super;
public: public:
cRainbowRoadsGen(int a_Seed, int a_GridSize, int a_MaxDepth, int a_MaxSize); cRainbowRoadsGen(int a_Seed, int a_GridSize, int a_MaxOffset, int a_MaxDepth, int a_MaxSize);
protected: protected:
class cRainbowRoads; // fwd: RainbowRoadsGen.cpp class cRainbowRoads; // fwd: RainbowRoadsGen.cpp
@ -39,7 +39,7 @@ protected:
// cGridStructGen overrides: // cGridStructGen overrides:
virtual cStructurePtr CreateStructure(int a_OriginX, int a_OriginZ) override; virtual cStructurePtr CreateStructure(int a_GridX, int a_GridZ, int a_OriginX, int a_OriginZ) override;
} ; } ;

View File

@ -61,7 +61,7 @@ class cStructGenRavines::cRavine :
public: public:
cRavine(int a_BlockX, int a_BlockZ, int a_Size, cNoise & a_Noise); cRavine(int a_GridX, int a_GridZ, int a_OriginX, int a_OriginZ, int a_Size, cNoise & a_Noise);
#ifdef _DEBUG #ifdef _DEBUG
/// Exports itself as a SVG line definition /// Exports itself as a SVG line definition
@ -81,7 +81,7 @@ protected:
// cStructGenRavines: // cStructGenRavines:
cStructGenRavines::cStructGenRavines(int a_Seed, int a_Size) : cStructGenRavines::cStructGenRavines(int a_Seed, int a_Size) :
super(a_Seed, a_Size, a_Size, a_Size * 2, a_Size * 2, 100), super(a_Seed, a_Size, a_Size, a_Size, a_Size, a_Size * 2, a_Size * 2, 100),
m_Noise(a_Seed), m_Noise(a_Seed),
m_Size(a_Size) m_Size(a_Size)
{ {
@ -91,9 +91,9 @@ cStructGenRavines::cStructGenRavines(int a_Seed, int a_Size) :
cGridStructGen::cStructurePtr cStructGenRavines::CreateStructure(int a_OriginX, int a_OriginZ) cGridStructGen::cStructurePtr cStructGenRavines::CreateStructure(int a_GridX, int a_GridZ, int a_OriginX, int a_OriginZ)
{ {
return cStructurePtr(new cRavine(a_OriginX, a_OriginZ, m_Size, m_Noise)); return cStructurePtr(new cRavine(a_GridX, a_GridZ, a_OriginX, a_OriginZ, m_Size, m_Noise));
} }
@ -104,8 +104,8 @@ cGridStructGen::cStructurePtr cStructGenRavines::CreateStructure(int a_OriginX,
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// cStructGenRavines::cRavine // cStructGenRavines::cRavine
cStructGenRavines::cRavine::cRavine(int a_OriginX, int a_OriginZ, int a_Size, cNoise & a_Noise) : cStructGenRavines::cRavine::cRavine(int a_GridX, int a_GridZ, int a_OriginX, int a_OriginZ, int a_Size, cNoise & a_Noise) :
super(a_OriginX, a_OriginZ) super(a_GridX, a_GridZ, a_OriginX, a_OriginZ)
{ {
// Calculate the ravine shape-defining points: // Calculate the ravine shape-defining points:
GenerateBaseDefPoints(a_OriginX, a_OriginZ, a_Size, a_Noise); GenerateBaseDefPoints(a_OriginX, a_OriginZ, a_Size, a_Noise);

View File

@ -32,7 +32,7 @@ protected:
// cGridStructGen overrides: // cGridStructGen overrides:
virtual cStructurePtr CreateStructure(int a_OriginX, int a_OriginZ) override; virtual cStructurePtr CreateStructure(int a_GridX, int a_GridZ, int a_OriginX, int a_OriginZ) override;
} ; } ;

View File

@ -29,11 +29,12 @@ class cUnderwaterBaseGen::cUnderwaterBase :
public: public:
cUnderwaterBase( cUnderwaterBase(
int a_Seed, int a_Seed,
int a_GridX, int a_GridZ,
int a_OriginX, int a_OriginZ, int a_OriginX, int a_OriginZ,
int a_MaxDepth, int a_MaxDepth,
int a_MaxSize int a_MaxSize
) : ) :
super(a_OriginX, a_OriginZ), super(a_GridX, a_GridZ, a_OriginX, a_OriginZ),
m_Seed(a_Seed), m_Seed(a_Seed),
m_Noise(a_Seed), m_Noise(a_Seed),
m_MaxSize(a_MaxSize), m_MaxSize(a_MaxSize),
@ -92,8 +93,8 @@ protected:
cUnderwaterBaseGen::cUnderwaterBaseGen(int a_Seed, int a_GridSize, int a_MaxDepth, int a_MaxSize, cBiomeGen & a_BiomeGen) : cUnderwaterBaseGen::cUnderwaterBaseGen(int a_Seed, int a_GridSize, int a_MaxOffset, int a_MaxDepth, int a_MaxSize, cBiomeGen & a_BiomeGen) :
super(a_Seed, a_GridSize, a_GridSize, a_MaxSize, a_MaxSize, 100), super(a_Seed, a_GridSize, a_GridSize, a_MaxOffset, a_MaxOffset, a_MaxSize, a_MaxSize, 100),
m_Noise(a_Seed + 1000), m_Noise(a_Seed + 1000),
m_MaxDepth(a_MaxDepth), m_MaxDepth(a_MaxDepth),
m_MaxSize(a_MaxSize), m_MaxSize(a_MaxSize),
@ -105,7 +106,7 @@ cUnderwaterBaseGen::cUnderwaterBaseGen(int a_Seed, int a_GridSize, int a_MaxDept
cGridStructGen::cStructurePtr cUnderwaterBaseGen::CreateStructure(int a_OriginX, int a_OriginZ) cGridStructGen::cStructurePtr cUnderwaterBaseGen::CreateStructure(int a_GridX, int a_GridZ, int a_OriginX, int a_OriginZ)
{ {
// Generate the biomes for the chunk surrounding the origin: // Generate the biomes for the chunk surrounding the origin:
int ChunkX, ChunkZ; int ChunkX, ChunkZ;
@ -134,7 +135,7 @@ cGridStructGen::cStructurePtr cUnderwaterBaseGen::CreateStructure(int a_OriginX,
} // for i - Biomes[] } // for i - Biomes[]
// Create a base based on the chosen prefabs: // Create a base based on the chosen prefabs:
return cStructurePtr(new cUnderwaterBase(m_Seed, a_OriginX, a_OriginZ, m_MaxDepth, m_MaxSize)); return cStructurePtr(new cUnderwaterBase(m_Seed, a_GridX, a_GridZ, a_OriginX, a_OriginZ, m_MaxDepth, m_MaxSize));
} }

View File

@ -22,7 +22,7 @@ class cUnderwaterBaseGen :
typedef cGridStructGen super; typedef cGridStructGen super;
public: public:
cUnderwaterBaseGen(int a_Seed, int a_GridSize, int a_MaxDepth, int a_MaxSize, cBiomeGen & a_BiomeGen); cUnderwaterBaseGen(int a_Seed, int a_GridSize, int a_MaxOffset, int a_MaxDepth, int a_MaxSize, cBiomeGen & a_BiomeGen);
protected: protected:
class cUnderwaterBase; // fwd: UnderwaterBaseGen.cpp class cUnderwaterBase; // fwd: UnderwaterBaseGen.cpp
@ -42,7 +42,7 @@ protected:
// cGridStructGen overrides: // cGridStructGen overrides:
virtual cStructurePtr CreateStructure(int a_OriginX, int a_OriginZ) override; virtual cStructurePtr CreateStructure(int a_GridX, int a_GridZ, int a_OriginX, int a_OriginZ) override;
} ; } ;

View File

@ -110,6 +110,7 @@ class cVillageGen::cVillage :
public: public:
cVillage( cVillage(
int a_Seed, int a_Seed,
int a_GridX, int a_GridZ,
int a_OriginX, int a_OriginZ, int a_OriginX, int a_OriginZ,
int a_MaxRoadDepth, int a_MaxRoadDepth,
int a_MaxSize, int a_MaxSize,
@ -119,7 +120,7 @@ public:
BLOCKTYPE a_RoadBlock, BLOCKTYPE a_RoadBlock,
BLOCKTYPE a_WaterRoadBlock BLOCKTYPE a_WaterRoadBlock
) : ) :
super(a_OriginX, a_OriginZ), super(a_GridX, a_GridZ, a_OriginX, a_OriginZ),
m_Seed(a_Seed), m_Seed(a_Seed),
m_Noise(a_Seed), m_Noise(a_Seed),
m_MaxSize(a_MaxSize), m_MaxSize(a_MaxSize),
@ -358,8 +359,8 @@ static cVillagePiecePool * g_PlainsVillagePools[] =
cVillageGen::cVillageGen(int a_Seed, int a_GridSize, int a_MaxDepth, int a_MaxSize, int a_MinDensity, int a_MaxDensity, cBiomeGen & a_BiomeGen, cTerrainHeightGen & a_HeightGen) : cVillageGen::cVillageGen(int a_Seed, int a_GridSize, int a_MaxOffset, int a_MaxDepth, int a_MaxSize, int a_MinDensity, int a_MaxDensity, cBiomeGen & a_BiomeGen, cTerrainHeightGen & a_HeightGen) :
super(a_Seed, a_GridSize, a_GridSize, a_MaxSize, a_MaxSize, 100), super(a_Seed, a_GridSize, a_GridSize, a_MaxOffset, a_MaxOffset, a_MaxSize, a_MaxSize, 100),
m_Noise(a_Seed + 1000), m_Noise(a_Seed + 1000),
m_MaxDepth(a_MaxDepth), m_MaxDepth(a_MaxDepth),
m_MaxSize(a_MaxSize), m_MaxSize(a_MaxSize),
@ -374,7 +375,7 @@ cVillageGen::cVillageGen(int a_Seed, int a_GridSize, int a_MaxDepth, int a_MaxSi
cGridStructGen::cStructurePtr cVillageGen::CreateStructure(int a_OriginX, int a_OriginZ) cGridStructGen::cStructurePtr cVillageGen::CreateStructure(int a_GridX, int a_GridZ, int a_OriginX, int a_OriginZ)
{ {
// Generate the biomes for the chunk surrounding the origin: // Generate the biomes for the chunk surrounding the origin:
int ChunkX, ChunkZ; int ChunkX, ChunkZ;
@ -435,7 +436,7 @@ cGridStructGen::cStructurePtr cVillageGen::CreateStructure(int a_OriginX, int a_
{ {
return cStructurePtr(); return cStructurePtr();
} }
return cStructurePtr(new cVillage(m_Seed, a_OriginX, a_OriginZ, m_MaxDepth, m_MaxSize, Density, *VillagePrefabs, m_HeightGen, RoadBlock, WaterRoadBlock)); return cStructurePtr(new cVillage(m_Seed, a_GridX, a_GridZ, a_OriginX, a_OriginZ, m_MaxDepth, m_MaxSize, Density, *VillagePrefabs, m_HeightGen, RoadBlock, WaterRoadBlock));
} }

View File

@ -21,7 +21,7 @@ class cVillageGen :
{ {
typedef cGridStructGen super; typedef cGridStructGen super;
public: public:
cVillageGen(int a_Seed, int a_GridSize, int a_MaxDepth, int a_MaxSize, int a_MinDensity, int a_MaxDensity, cBiomeGen & a_BiomeGen, cTerrainHeightGen & a_HeightGen); cVillageGen(int a_Seed, int a_GridSize, int a_MaxOffset, int a_MaxDepth, int a_MaxSize, int a_MinDensity, int a_MaxDensity, cBiomeGen & a_BiomeGen, cTerrainHeightGen & a_HeightGen);
protected: protected:
class cVillage; // fwd: VillageGen.cpp class cVillage; // fwd: VillageGen.cpp
@ -49,7 +49,7 @@ protected:
// cGridStructGen overrides: // cGridStructGen overrides:
virtual cStructurePtr CreateStructure(int a_OriginX, int a_OriginZ) override; virtual cStructurePtr CreateStructure(int a_GridX, int a_GridZ, int a_OriginX, int a_OriginZ) override;
} ; } ;

View File

@ -59,19 +59,21 @@ void cIncrementalRedstoneSimulator::RedstoneAddBlock(int a_BlockX, int a_BlockY,
int RelZ = 0; int RelZ = 0;
BLOCKTYPE Block; BLOCKTYPE Block;
NIBBLETYPE Meta; NIBBLETYPE Meta;
cChunk * Chunk;
if (a_OtherChunk != NULL) if (a_OtherChunk != NULL)
{ {
RelX = a_BlockX - a_OtherChunk->GetPosX() * cChunkDef::Width; RelX = a_BlockX - a_OtherChunk->GetPosX() * cChunkDef::Width;
RelZ = a_BlockZ - a_OtherChunk->GetPosZ() * cChunkDef::Width; RelZ = a_BlockZ - a_OtherChunk->GetPosZ() * cChunkDef::Width;
a_OtherChunk->GetBlockTypeMeta(RelX, a_BlockY, RelZ, Block, Meta); a_OtherChunk->GetBlockTypeMeta(RelX, a_BlockY, RelZ, Block, Meta);
a_OtherChunk->SetIsRedstoneDirty(true); Chunk = a_OtherChunk;
} }
else else
{ {
RelX = a_BlockX - a_Chunk->GetPosX() * cChunkDef::Width; RelX = a_BlockX - a_Chunk->GetPosX() * cChunkDef::Width;
RelZ = a_BlockZ - a_Chunk->GetPosZ() * cChunkDef::Width; RelZ = a_BlockZ - a_Chunk->GetPosZ() * cChunkDef::Width;
a_Chunk->GetBlockTypeMeta(RelX, a_BlockY, RelZ, Block, Meta); a_Chunk->GetBlockTypeMeta(RelX, a_BlockY, RelZ, Block, Meta);
Chunk = a_Chunk;
} }
// Every time a block is changed (AddBlock called), we want to go through all lists and check to see if the coordiantes stored within are still valid // Every time a block is changed (AddBlock called), we want to go through all lists and check to see if the coordiantes stored within are still valid
@ -90,7 +92,7 @@ void cIncrementalRedstoneSimulator::RedstoneAddBlock(int a_BlockX, int a_BlockY,
{ {
LOGD("cIncrementalRedstoneSimulator: Erased block @ {%i, %i, %i} from powered blocks list as it no longer connected to a source", itr->a_BlockPos.x, itr->a_BlockPos.y, itr->a_BlockPos.z); LOGD("cIncrementalRedstoneSimulator: Erased block @ {%i, %i, %i} from powered blocks list as it no longer connected to a source", itr->a_BlockPos.x, itr->a_BlockPos.y, itr->a_BlockPos.z);
itr = PoweredBlocks->erase(itr); itr = PoweredBlocks->erase(itr);
a_Chunk->SetIsRedstoneDirty(true); Chunk->SetIsRedstoneDirty(true);
continue; continue;
} }
else if ( else if (
@ -105,9 +107,25 @@ void cIncrementalRedstoneSimulator::RedstoneAddBlock(int a_BlockX, int a_BlockY,
{ {
LOGD("cIncrementalRedstoneSimulator: Erased block @ {%i, %i, %i} from powered blocks list due to present/past metadata mismatch", itr->a_BlockPos.x, itr->a_BlockPos.y, itr->a_BlockPos.z); LOGD("cIncrementalRedstoneSimulator: Erased block @ {%i, %i, %i} from powered blocks list due to present/past metadata mismatch", itr->a_BlockPos.x, itr->a_BlockPos.y, itr->a_BlockPos.z);
itr = PoweredBlocks->erase(itr); itr = PoweredBlocks->erase(itr);
a_Chunk->SetIsRedstoneDirty(true); Chunk->SetIsRedstoneDirty(true);
continue; continue;
} }
else if (Block == E_BLOCK_DAYLIGHT_SENSOR)
{
if (!m_World.IsChunkLighted(Chunk->GetPosX(), Chunk->GetPosZ()))
{
m_World.QueueLightChunk(Chunk->GetPosX(), Chunk->GetPosZ());
}
else
{
if (Chunk->GetTimeAlteredLight(Chunk->GetSkyLight(RelX, a_BlockY + 1, RelZ)) <= 7)
{
itr = PoweredBlocks->erase(itr);
Chunk->SetIsRedstoneDirty(true);
continue;
}
}
}
++itr; ++itr;
} }
@ -121,7 +139,7 @@ void cIncrementalRedstoneSimulator::RedstoneAddBlock(int a_BlockX, int a_BlockY,
{ {
LOGD("cIncrementalRedstoneSimulator: Erased block @ {%i, %i, %i} from linked powered blocks list as it is no longer connected to a source", itr->a_BlockPos.x, itr->a_BlockPos.y, itr->a_BlockPos.z); LOGD("cIncrementalRedstoneSimulator: Erased block @ {%i, %i, %i} from linked powered blocks list as it is no longer connected to a source", itr->a_BlockPos.x, itr->a_BlockPos.y, itr->a_BlockPos.z);
itr = LinkedPoweredBlocks->erase(itr); itr = LinkedPoweredBlocks->erase(itr);
a_Chunk->SetIsRedstoneDirty(true); Chunk->SetIsRedstoneDirty(true);
continue; continue;
} }
else if ( else if (
@ -135,7 +153,7 @@ void cIncrementalRedstoneSimulator::RedstoneAddBlock(int a_BlockX, int a_BlockY,
{ {
LOGD("cIncrementalRedstoneSimulator: Erased block @ {%i, %i, %i} from linked powered blocks list due to present/past metadata mismatch", itr->a_BlockPos.x, itr->a_BlockPos.y, itr->a_BlockPos.z); LOGD("cIncrementalRedstoneSimulator: Erased block @ {%i, %i, %i} from linked powered blocks list due to present/past metadata mismatch", itr->a_BlockPos.x, itr->a_BlockPos.y, itr->a_BlockPos.z);
itr = LinkedPoweredBlocks->erase(itr); itr = LinkedPoweredBlocks->erase(itr);
a_Chunk->SetIsRedstoneDirty(true); Chunk->SetIsRedstoneDirty(true);
continue; continue;
} }
} }
@ -145,7 +163,7 @@ void cIncrementalRedstoneSimulator::RedstoneAddBlock(int a_BlockX, int a_BlockY,
{ {
LOGD("cIncrementalRedstoneSimulator: Erased block @ {%i, %i, %i} from linked powered blocks list as it is no longer powered through a valid middle block", itr->a_BlockPos.x, itr->a_BlockPos.y, itr->a_BlockPos.z); LOGD("cIncrementalRedstoneSimulator: Erased block @ {%i, %i, %i} from linked powered blocks list as it is no longer powered through a valid middle block", itr->a_BlockPos.x, itr->a_BlockPos.y, itr->a_BlockPos.z);
itr = LinkedPoweredBlocks->erase(itr); itr = LinkedPoweredBlocks->erase(itr);
a_Chunk->SetIsRedstoneDirty(true); Chunk->SetIsRedstoneDirty(true);
continue; continue;
} }
} }
@ -788,12 +806,12 @@ void cIncrementalRedstoneSimulator::HandleRedstoneRepeater(int a_RelBlockX, int
{ {
WereItrsChanged = QueueRepeaterPowerChange(a_RelBlockX, a_RelBlockY, a_RelBlockZ, a_Meta, false); WereItrsChanged = QueueRepeaterPowerChange(a_RelBlockX, a_RelBlockY, a_RelBlockZ, a_Meta, false);
} }
else if (a_Itr != m_RepeatersDelayList->end()) else if (a_Itr == m_RepeatersDelayList->end())
{ {
return; return;
} }
} }
else if (a_Itr != m_RepeatersDelayList->end()) else if (a_Itr == m_RepeatersDelayList->end())
{ {
return; return;
} }
@ -1145,6 +1163,10 @@ void cIncrementalRedstoneSimulator::HandleDaylightSensor(int a_RelBlockX, int a_
{ {
SetAllDirsAsPowered(a_RelBlockX, a_RelBlockY, a_RelBlockZ); SetAllDirsAsPowered(a_RelBlockX, a_RelBlockY, a_RelBlockZ);
} }
else
{
WakeUp(BlockX, a_RelBlockY, BlockZ, m_Chunk);
}
} }
} }

View File

@ -6,9 +6,23 @@
int main(int argc, char** argv) int main(int argc, char** argv)
{ {
class cMockAllocationPool
: public cAllocationPool<cChunkData::sChunkSection>
{
virtual cChunkData::sChunkSection * Allocate()
{
return new cChunkData::sChunkSection();
}
virtual void Free(cChunkData::sChunkSection * a_Ptr)
{
delete a_Ptr;
}
} Pool;
{ {
// Test first segment // Test first segment
cChunkData buffer; cChunkData buffer(Pool);
BLOCKTYPE SrcBlockBuffer[16 * 16 * 256]; BLOCKTYPE SrcBlockBuffer[16 * 16 * 256];
memset(SrcBlockBuffer, 0x00, sizeof(SrcBlockBuffer)); memset(SrcBlockBuffer, 0x00, sizeof(SrcBlockBuffer));
@ -35,7 +49,7 @@ int main(int argc, char** argv)
{ {
// test following segment // test following segment
cChunkData buffer; cChunkData buffer(Pool);
BLOCKTYPE SrcBlockBuffer[16 * 16 * 256]; BLOCKTYPE SrcBlockBuffer[16 * 16 * 256];
memset(SrcBlockBuffer, 0x00, sizeof(SrcBlockBuffer)); memset(SrcBlockBuffer, 0x00, sizeof(SrcBlockBuffer));
@ -62,7 +76,7 @@ int main(int argc, char** argv)
{ {
// test zeros // test zeros
cChunkData buffer; cChunkData buffer(Pool);
BLOCKTYPE SrcBlockBuffer[16 * 16 * 256]; BLOCKTYPE SrcBlockBuffer[16 * 16 * 256];
memset(SrcBlockBuffer, 0x00, sizeof(SrcBlockBuffer)); memset(SrcBlockBuffer, 0x00, sizeof(SrcBlockBuffer));

View File

@ -6,8 +6,21 @@
int main(int argc, char** argv) int main(int argc, char** argv)
{ {
class cMockAllocationPool
: public cAllocationPool<cChunkData::sChunkSection>
{
virtual cChunkData::sChunkSection * Allocate()
{
return new cChunkData::sChunkSection();
}
virtual void Free(cChunkData::sChunkSection * a_Ptr)
{
delete a_Ptr;
}
} Pool;
{ {
cChunkData buffer; cChunkData buffer(Pool);
// Empty chunks // Empty chunks
buffer.SetBlock(0, 0, 0, 0xAB); buffer.SetBlock(0, 0, 0, 0xAB);
@ -105,7 +118,7 @@ int main(int argc, char** argv)
} }
{ {
cChunkData buffer; cChunkData buffer(Pool);
// Zero's // Zero's
buffer.SetBlock(0, 0, 0, 0x0); buffer.SetBlock(0, 0, 0, 0x0);
@ -122,9 +135,9 @@ int main(int argc, char** argv)
{ {
// Operator = // Operator =
cChunkData buffer; cChunkData buffer(Pool);
buffer.SetBlock(0, 0, 0, 0x42); buffer.SetBlock(0, 0, 0, 0x42);
cChunkData copy; cChunkData copy(Pool);
#if __cplusplus < 201103L #if __cplusplus < 201103L
copy = buffer; copy = buffer;
#else #else

View File

@ -6,8 +6,21 @@
int main(int argc, char** argv) int main(int argc, char** argv)
{ {
class cMockAllocationPool
: public cAllocationPool<cChunkData::sChunkSection>
{
virtual cChunkData::sChunkSection * Allocate()
{
return new cChunkData::sChunkSection();
}
virtual void Free(cChunkData::sChunkSection * a_Ptr)
{
delete a_Ptr;
}
} Pool;
{ {
cChunkData buffer; cChunkData buffer(Pool);
buffer.SetBlock(3, 1, 4, 0xDE); buffer.SetBlock(3, 1, 4, 0xDE);
buffer.SetMeta(3, 1, 4, 0xA); buffer.SetMeta(3, 1, 4, 0xA);
@ -37,7 +50,7 @@ int main(int argc, char** argv)
} }
{ {
cChunkData buffer; cChunkData buffer(Pool);
NIBBLETYPE SrcNibbleBuffer[16 * 16 * 256 / 2]; NIBBLETYPE SrcNibbleBuffer[16 * 16 * 256 / 2];
for (int i = 0; i < 16 * 16 * 256 / 2; i += 4) for (int i = 0; i < 16 * 16 * 256 / 2; i += 4)
@ -60,7 +73,7 @@ int main(int argc, char** argv)
} }
{ {
cChunkData buffer; cChunkData buffer(Pool);
NIBBLETYPE SrcNibbleBuffer[16 * 16 * 256 / 2]; NIBBLETYPE SrcNibbleBuffer[16 * 16 * 256 / 2];
for (int i = 0; i < 16 * 16 * 256 / 2; i += 4) for (int i = 0; i < 16 * 16 * 256 / 2; i += 4)
@ -83,7 +96,7 @@ int main(int argc, char** argv)
} }
{ {
cChunkData buffer; cChunkData buffer(Pool);
NIBBLETYPE SrcNibbleBuffer[16 * 16 * 256 / 2]; NIBBLETYPE SrcNibbleBuffer[16 * 16 * 256 / 2];
for (int i = 0; i < 16 * 16 * 256 / 2; i += 4) for (int i = 0; i < 16 * 16 * 256 / 2; i += 4)
@ -106,7 +119,7 @@ int main(int argc, char** argv)
} }
{ {
cChunkData buffer; cChunkData buffer(Pool);
BLOCKTYPE SrcBlockBuffer[16 * 16 * 256]; BLOCKTYPE SrcBlockBuffer[16 * 16 * 256];
memset(SrcBlockBuffer, 0x00, 16 * 16 * 256); memset(SrcBlockBuffer, 0x00, 16 * 16 * 256);

View File

@ -17,7 +17,20 @@
int main(int argc, char ** argv) int main(int argc, char ** argv)
{ {
// Set up a cChunkData with known contents - all blocks 0x01, all metas 0x02: // Set up a cChunkData with known contents - all blocks 0x01, all metas 0x02:
cChunkData Data; class cMockAllocationPool
: public cAllocationPool<cChunkData::sChunkSection>
{
virtual cChunkData::sChunkSection * Allocate()
{
return new cChunkData::sChunkSection();
}
virtual void Free(cChunkData::sChunkSection * a_Ptr)
{
delete a_Ptr;
}
} Pool;
cChunkData Data(Pool);
cChunkDef::BlockTypes BlockTypes; cChunkDef::BlockTypes BlockTypes;
cChunkDef::BlockNibbles BlockMetas; cChunkDef::BlockNibbles BlockMetas;
memset(BlockTypes, 0x01, sizeof(BlockTypes)); memset(BlockTypes, 0x01, sizeof(BlockTypes));

View File

@ -4,6 +4,19 @@
int main(int argc, char** argv) int main(int argc, char** argv)
{ {
cChunkData buffer; class cMockAllocationPool
: public cAllocationPool<cChunkData::sChunkSection>
{
virtual cChunkData::sChunkSection * Allocate()
{
return new cChunkData::sChunkSection();
}
virtual void Free(cChunkData::sChunkSection * a_Ptr)
{
delete a_Ptr;
}
} Pool;
cChunkData buffer(Pool);
return 0; return 0;
} }