summaryrefslogtreecommitdiffstats
path: root/source
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--source/cChunk.cpp27
-rw-r--r--source/cFluidSimulator.cpp18
-rw-r--r--source/cFluidSimulator.h8
-rw-r--r--source/cPassiveMonster.cpp3
-rw-r--r--source/cSandSimulator.cpp74
-rw-r--r--source/cSandSimulator.h24
-rw-r--r--source/cSimulator.cpp27
-rw-r--r--source/cSimulator.h20
-rw-r--r--source/cSimulatorManager.cpp38
-rw-r--r--source/cSimulatorManager.h20
-rw-r--r--source/cSquid.cpp25
-rw-r--r--source/cSquid.h5
-rw-r--r--source/cWorld.cpp30
-rw-r--r--source/cWorld.h13
14 files changed, 277 insertions, 55 deletions
diff --git a/source/cChunk.cpp b/source/cChunk.cpp
index 4eeb5c5b8..e0322dc91 100644
--- a/source/cChunk.cpp
+++ b/source/cChunk.cpp
@@ -257,8 +257,7 @@ void cChunk::Tick(float a_Dt)
int wX, wY, wZ;
PositionToWorldPosition(X, Y, Z, wX, wY, wZ);
- m_World->GetWaterSimulator()->WakeUp( wX, wY, wZ );
- m_World->GetLavaSimulator()->WakeUp( wX, wY, wZ );
+ m_World->GetSimulatorManager()->WakeUp(wX, wY, wZ);
if (isRedstone) {
cRedstone Redstone(m_World);
Redstone.ChangeRedstone( (X+m_PosX*16), (Y+m_PosY*16), (Z+m_PosZ*16), false );
@@ -306,30 +305,6 @@ void cChunk::Tick(float a_Dt)
}
}
break;
- case E_BLOCK_STATIONARY_WATER:
- case E_BLOCK_WATER:
-
- break;
- case E_BLOCK_GRAVEL:
- case E_BLOCK_SAND:
- {
- char BottomBlock = GetBlock( X, Y-1, Z );
- if( BottomBlock == E_BLOCK_AIR || IsBlockWater(BottomBlock) || IsBlockLava(BottomBlock) )
- {
- SetBlock( X, Y, Z, E_BLOCK_AIR, 0 );
- SetBlock( X, Y-1, Z, BlockID, 0 );
-
- int wX, wY, wZ;
-
- PositionToWorldPosition(X, Y, Z, wX, wY, wZ);
-
- m_World->GetWaterSimulator()->WakeUp( wX, wY, wZ );
- m_World->GetLavaSimulator()->WakeUp( wX, wY, wZ );
- m_World->GetWaterSimulator()->WakeUp( wX, wY - 1, wZ );
- m_World->GetLavaSimulator()->WakeUp( wX, wY - 1, wZ );
- }
- }
- break;
default:
break;
};
diff --git a/source/cFluidSimulator.cpp b/source/cFluidSimulator.cpp
index 6eb5dbb0a..2ede7ba49 100644
--- a/source/cFluidSimulator.cpp
+++ b/source/cFluidSimulator.cpp
@@ -72,7 +72,7 @@ public:
};
cFluidSimulator::cFluidSimulator( cWorld* a_World )
- : m_World(a_World)
+ : cSimulator(a_World)
, m_Data(0)
{
m_Data = new FluidData(a_World, this);
@@ -80,17 +80,7 @@ cFluidSimulator::cFluidSimulator( cWorld* a_World )
cFluidSimulator::~cFluidSimulator()
{
-}
-
-void cFluidSimulator::WakeUp( int a_X, int a_Y, int a_Z )
-{
- AddBlock( a_X, a_Y, a_Z );
- AddBlock( a_X-1, a_Y, a_Z );
- AddBlock( a_X+1, a_Y, a_Z );
- AddBlock( a_X, a_Y-1, a_Z );
- AddBlock( a_X, a_Y+1, a_Z );
- AddBlock( a_X, a_Y, a_Z-1 );
- AddBlock( a_X, a_Y, a_Z+1 );
+ delete m_Data;
}
void cFluidSimulator::AddBlock( int a_X, int a_Y, int a_Z )
@@ -99,8 +89,8 @@ void cFluidSimulator::AddBlock( int a_X, int a_Y, int a_Z )
std::vector< Vector3i > & ActiveFluid = *m_Data->m_ActiveFluid;
for( std::vector< Vector3i >::iterator itr = ActiveFluid.begin(); itr != ActiveFluid.end(); ++itr )
{
- Vector3i & pos = *itr;
- if( pos.x == a_X && pos.y == a_Y && pos.z == a_Z )
+ Vector3i & Pos = *itr;
+ if( Pos.x == a_X && Pos.y == a_Y && Pos.z == a_Z )
return;
}
diff --git a/source/cFluidSimulator.h b/source/cFluidSimulator.h
index 758bfc022..1b4cd0d55 100644
--- a/source/cFluidSimulator.h
+++ b/source/cFluidSimulator.h
@@ -1,5 +1,7 @@
#pragma once
+#include "cSimulator.h"
+
//TODO This definitly needs a better naming :D but how?
enum Direction
@@ -15,14 +17,13 @@ enum Direction
class Vector3i;
class cWorld;
-class cFluidSimulator
+class cFluidSimulator : public cSimulator
{
public:
cFluidSimulator( cWorld* a_World );
~cFluidSimulator();
virtual void Simulate( float a_Dt );
- void WakeUp( int a_X, int a_Y, int a_Z );
//Gets the flowing direction. if a_Over is true also the block over the current block affects the direction (standard)
Direction GetFlowingDirection(int a_X, int a_Y, int a_Z, bool a_Over = true);
@@ -31,12 +32,11 @@ public:
virtual inline bool IsPassableForFluid( char a_BlockID ) = 0;
protected:
- void AddBlock( int a_X, int a_Y, int a_Z);
+ virtual void AddBlock( int a_X, int a_Y, int a_Z);
char GetHighestLevelAround( int a_X, int a_Y, int a_Z );
float m_Timer;
- cWorld* m_World;
class FluidData;
FluidData* m_Data;
diff --git a/source/cPassiveMonster.cpp b/source/cPassiveMonster.cpp
index 1f11484ef..0879ebbee 100644
--- a/source/cPassiveMonster.cpp
+++ b/source/cPassiveMonster.cpp
@@ -14,7 +14,8 @@ cPassiveMonster::~cPassiveMonster()
void cPassiveMonster::TakeDamage(int a_Damage, cEntity* a_Instigator)
{
cMonster::TakeDamage(a_Damage, a_Instigator);
- m_EMState = ESCAPING;
+ if(a_Instigator != this)
+ m_EMState = ESCAPING;
}
void cPassiveMonster::Tick(float a_Dt)
diff --git a/source/cSandSimulator.cpp b/source/cSandSimulator.cpp
new file mode 100644
index 000000000..b25b498c5
--- /dev/null
+++ b/source/cSandSimulator.cpp
@@ -0,0 +1,74 @@
+#include "cSandSimulator.h"
+#include "cWorld.h"
+#include "Vector3i.h"
+#include "BlockID.h"
+#include "Defines.h"
+#include <vector>
+
+cSandSimulator::cSandSimulator( cWorld* a_World )
+ : cSimulator(a_World)
+ , m_Blocks(new std::vector <Vector3i *>)
+ , m_Buffer(new std::vector <Vector3i *>)
+{
+
+}
+
+cSandSimulator::~cSandSimulator()
+{
+ delete m_Buffer;
+ delete m_Blocks;
+}
+
+void cSandSimulator::Simulate( float a_Dt )
+{
+ m_Buffer->clear();
+ std::swap( m_Blocks, m_Buffer );
+
+ for( std::vector<Vector3i *>::iterator itr = m_Buffer->begin(); itr != m_Buffer->end(); ++itr )
+ {
+ Vector3i *Pos = *itr;
+ char BlockID = m_World->GetBlock(Pos->x, Pos->y, Pos->z);
+ if(!IsAllowedBlock(BlockID))
+ continue;
+
+ char BottomBlock = m_World->GetBlock( Pos->x, Pos->y - 1, Pos->z );
+
+ if( IsPassable(BottomBlock) )
+ {
+ m_World->SetBlock( Pos->x, Pos->y, Pos->z, E_BLOCK_AIR, 0 );
+ m_World->SetBlock( Pos->x, Pos->y - 1, Pos->z, BlockID, 0 );
+ }
+ }
+
+}
+
+
+bool cSandSimulator::IsAllowedBlock( char a_BlockID )
+{
+ return a_BlockID == E_BLOCK_SAND
+ || a_BlockID == E_BLOCK_GRAVEL;
+}
+
+void cSandSimulator::AddBlock(int a_X, int a_Y, int a_Z)
+{
+ Vector3i *Block = new Vector3i(a_X, a_Y, a_Z);
+
+ //check for duplicates
+ for( std::vector<Vector3i *>::iterator itr = m_Blocks->begin(); itr != m_Blocks->end(); ++itr )
+ {
+ Vector3i *Pos = *itr;
+ if( Pos->x == a_X && Pos->y == a_Y && Pos->z == a_Z )
+ return;
+ }
+
+ m_Blocks->push_back(Block);
+
+}
+
+bool cSandSimulator::IsPassable( char a_BlockID )
+{
+ return a_BlockID == E_BLOCK_AIR
+ || IsBlockWater(a_BlockID)
+ || IsBlockLava(a_BlockID);
+
+} \ No newline at end of file
diff --git a/source/cSandSimulator.h b/source/cSandSimulator.h
new file mode 100644
index 000000000..84bba935f
--- /dev/null
+++ b/source/cSandSimulator.h
@@ -0,0 +1,24 @@
+#pragma once
+#include "cSimulator.h"
+#include "cBlockEntity.h"
+#include "vector"
+
+class Vector3i;
+class cWorld;
+class cSandSimulator : public cSimulator
+{
+public:
+ cSandSimulator( cWorld* a_World );
+ ~cSandSimulator();
+
+ virtual void Simulate( float a_Dt );
+
+ virtual inline bool IsAllowedBlock( char a_BlockID );
+ virtual inline bool IsPassable( char a_BlockID );
+
+protected:
+ virtual void AddBlock(int a_X, int a_Y, int a_Z);
+
+ std::vector <Vector3i *> *m_Blocks;
+ std::vector <Vector3i *> *m_Buffer;
+}; \ No newline at end of file
diff --git a/source/cSimulator.cpp b/source/cSimulator.cpp
new file mode 100644
index 000000000..a5bb4e311
--- /dev/null
+++ b/source/cSimulator.cpp
@@ -0,0 +1,27 @@
+#include "cSimulator.h"
+#include "cWorld.h"
+#include "Vector3i.h"
+#include "BlockID.h"
+#include "Defines.h"
+#include <vector>
+
+cSimulator::cSimulator( cWorld* a_World )
+ : m_World(a_World)
+{
+
+}
+
+cSimulator::~cSimulator()
+{
+}
+
+void cSimulator::WakeUp( int a_X, int a_Y, int a_Z )
+{
+ AddBlock( a_X, a_Y, a_Z );
+ AddBlock( a_X-1, a_Y, a_Z );
+ AddBlock( a_X+1, a_Y, a_Z );
+ AddBlock( a_X, a_Y-1, a_Z );
+ AddBlock( a_X, a_Y+1, a_Z );
+ AddBlock( a_X, a_Y, a_Z-1 );
+ AddBlock( a_X, a_Y, a_Z+1 );
+}
diff --git a/source/cSimulator.h b/source/cSimulator.h
new file mode 100644
index 000000000..2aaabe184
--- /dev/null
+++ b/source/cSimulator.h
@@ -0,0 +1,20 @@
+#pragma once
+
+class Vector3i;
+class cWorld;
+class cSimulator
+{
+public:
+ cSimulator( cWorld* a_World );
+ ~cSimulator();
+
+ virtual void Simulate( float a_Dt ) = 0;
+ virtual inline void WakeUp( int a_X, int a_Y, int a_Z ); //Used often so inline saves some calls
+
+ virtual inline bool IsAllowedBlock( char a_BlockID ) = 0;
+
+protected:
+ virtual void AddBlock(int a_X, int a_Y, int a_Z) = 0;
+
+ cWorld *m_World;
+}; \ No newline at end of file
diff --git a/source/cSimulatorManager.cpp b/source/cSimulatorManager.cpp
new file mode 100644
index 000000000..98303008a
--- /dev/null
+++ b/source/cSimulatorManager.cpp
@@ -0,0 +1,38 @@
+#include "cSimulatorManager.h"
+#include <vector>
+
+cSimulatorManager::cSimulatorManager()
+{
+
+}
+
+cSimulatorManager::~cSimulatorManager()
+{
+}
+
+void cSimulatorManager::Simulate( float a_Dt )
+{
+ m_Ticks++;
+ for( std::vector <std::pair<cSimulator *, short> *>::iterator itr = m_Simulators.begin(); itr != m_Simulators.end(); ++itr )
+ {
+
+ if(m_Ticks % (*itr)->second == 0)
+ (*itr)->first->Simulate(a_Dt);
+ }
+}
+
+void cSimulatorManager::WakeUp(int a_X, int a_Y, int a_Z)
+{
+ for( std::vector <std::pair<cSimulator *, short> *>::iterator itr = m_Simulators.begin(); itr != m_Simulators.end(); ++itr )
+ {
+ (*itr)->first->WakeUp(a_X, a_Y, a_Z);
+ }
+}
+
+void cSimulatorManager::RegisterSimulator(cSimulator *a_Simulator, short a_Rate)
+{
+ //TODO needs some checking
+ std::pair<cSimulator *, short> *Pair = new std::pair<cSimulator *, short>(a_Simulator, a_Rate);
+
+ m_Simulators.push_back(Pair);
+} \ No newline at end of file
diff --git a/source/cSimulatorManager.h b/source/cSimulatorManager.h
new file mode 100644
index 000000000..de59b8536
--- /dev/null
+++ b/source/cSimulatorManager.h
@@ -0,0 +1,20 @@
+#pragma once
+#include "cSimulator.h"
+#include <vector>
+
+
+class cSimulatorManager
+{
+public:
+ cSimulatorManager();
+ ~cSimulatorManager();
+
+ void Simulate( float a_Dt );
+ void WakeUp(int a_X, int a_Y, int a_Z);
+
+ void RegisterSimulator(cSimulator *a_Simulator, short a_Rate);
+
+protected:
+ std::vector <std::pair<cSimulator *, short> *> m_Simulators;
+ long long m_Ticks;
+}; \ No newline at end of file
diff --git a/source/cSquid.cpp b/source/cSquid.cpp
index b2baf462b..af4b167f2 100644
--- a/source/cSquid.cpp
+++ b/source/cSquid.cpp
@@ -1,13 +1,16 @@
#include "cSquid.h"
+#include "Vector3d.h"
cSquid::cSquid()
{
m_MobType = 94;
GetMonsterConfig("Squid");
+ m_NoWater = 0.f;
}
cSquid::~cSquid()
{
+
}
bool cSquid::IsA( const char* a_EntityType )
@@ -23,3 +26,25 @@ void cSquid::KilledBy( cEntity* a_Killer )
cMonster::KilledBy( a_Killer );
}
+
+void cSquid::Tick(float a_Dt)
+{
+ cPassiveMonster::Tick(a_Dt);
+
+ Vector3d Pos = GetPosition();
+
+
+ //TODO Not a real behavior, but cool :D
+ if(!IsBlockWater(GetWorld()->GetBlock(Pos.x, Pos.y, Pos.z)))
+ {
+ //Die slowly Muhahaha :D (To prevent all this squids on the land :D)
+ m_NoWater += a_Dt;
+
+ if(m_NoWater > 1000.f)
+ {
+ m_NoWater -= 1000.f;
+ TakeDamage(1, this);
+ }
+ }
+
+} \ No newline at end of file
diff --git a/source/cSquid.h b/source/cSquid.h
index 277166517..069172efd 100644
--- a/source/cSquid.h
+++ b/source/cSquid.h
@@ -8,6 +8,11 @@ public:
cSquid();
~cSquid();
+ virtual void Tick(float a_Dt);
+
virtual bool IsA( const char* a_EntityType );
virtual void KilledBy( cEntity* a_Killer );
+
+protected:
+ float m_NoWater;
};
diff --git a/source/cWorld.cpp b/source/cWorld.cpp
index 382744e43..7b181c982 100644
--- a/source/cWorld.cpp
+++ b/source/cWorld.cpp
@@ -13,8 +13,10 @@
#include "cRoot.h"
#include "../iniFile/iniFile.h"
#include "cChunkMap.h"
+#include "cSimulatorManager.h"
#include "cWaterSimulator.h"
#include "cLavaSimulator.h"
+#include "cSandSimulator.h"
#include "cChicken.h"
#include "cSpider.h"
#include "cCow.h" //cow
@@ -119,6 +121,8 @@ cWorld::~cWorld()
}
UnlockEntities();
+ delete m_SimulatorManager;
+ delete m_SandSimulator;
delete m_WaterSimulator;
delete m_LavaSimulator;
@@ -219,8 +223,20 @@ cWorld::cWorld( const char* a_WorldName )
m_EntitiesCriticalSection = new cCriticalSection();
m_ChunksCriticalSection = new cCriticalSection();
+ //Simulators:
+ m_SimulatorManager = new cSimulatorManager();
+
m_WaterSimulator = new cWaterSimulator( this );
+ m_SimulatorManager->RegisterSimulator(m_WaterSimulator, 6);
+
m_LavaSimulator = new cLavaSimulator( this );
+ m_SimulatorManager->RegisterSimulator(m_LavaSimulator, 12);
+
+ m_SandSimulator = new cSandSimulator(this);
+
+ m_SimulatorManager->RegisterSimulator(m_SandSimulator, 1);
+
+
memset( g_BlockLightValue, 0x0, 128 );
memset( g_BlockSpreadLightFalloff, 0xf, 128 ); // 0xf means total falloff
@@ -407,10 +423,9 @@ void cWorld::Tick(float a_Dt)
}
m_ChunkMap->Tick(a_Dt);
- if( CurrentTick % 6 == 0 )
- m_WaterSimulator->Simulate(a_Dt);
- if( CurrentTick % 12 == 0 )
- m_LavaSimulator->Simulate(a_Dt);
+
+ GetSimulatorManager()->Simulate(a_Dt);
+
UnlockChunks();
MTRand r1;
@@ -700,8 +715,7 @@ cChunk* cWorld::GetChunkOfBlock( int a_X, int a_Y, int a_Z )
void cWorld::SetBlock( int a_X, int a_Y, int a_Z, char a_BlockType, char a_BlockMeta )
{
- m_WaterSimulator->WakeUp( a_X, a_Y, a_Z );
- m_LavaSimulator->WakeUp( a_X, a_Y, a_Z );
+ this->GetSimulatorManager()->WakeUp(a_X, a_Y, a_Z);
int ChunkX, ChunkY, ChunkZ;
AbsoluteToRelative( a_X, a_Y, a_Z, ChunkX, ChunkY, ChunkZ );
@@ -785,8 +799,8 @@ bool cWorld::DigBlock( int a_X, int a_Y, int a_Z, cItem & a_PickupItem )
if(DestChunk)
{
DestChunk->SetBlock(PosX, PosY, PosZ, E_BLOCK_AIR, 0 );
- m_WaterSimulator->WakeUp( a_X, a_Y, a_Z );
- m_LavaSimulator->WakeUp( a_X, a_Y, a_Z );
+
+ GetSimulatorManager()->WakeUp(a_X, a_Y, a_Z);
if( !a_PickupItem.IsEmpty() )
{
diff --git a/source/cWorld.h b/source/cWorld.h
index ec30db956..44b89b5ab 100644
--- a/source/cWorld.h
+++ b/source/cWorld.h
@@ -12,10 +12,13 @@ enum ENUM_ITEM_ID;
#include <vector>
#include <string>
+#include "cSimulatorManager.h"
+
class cPacket;
class cRedstone;
class cWaterSimulator;
class cLavaSimulator;
+class cSandSimulator;
class cChunkMap;
class cItem;
class cCriticalSection;
@@ -24,6 +27,8 @@ class cClientHandle;
class cChunk;
class cEntity;
class cBlockEntity;
+
+
class cWorld //tolua_export
{ //tolua_export
public:
@@ -92,8 +97,9 @@ public:
const double & GetSpawnY(); //tolua_export
const double & GetSpawnZ() { return m_SpawnZ; } //tolua_export
- cWaterSimulator *GetWaterSimulator() { return m_WaterSimulator; }
- cLavaSimulator *GetLavaSimulator() { return m_LavaSimulator; }
+ inline cSimulatorManager *GetSimulatorManager() { return m_SimulatorManager; }
+ inline cWaterSimulator *GetWaterSimulator() { return m_WaterSimulator; }
+ inline cLavaSimulator *GetLavaSimulator() { return m_LavaSimulator; }
cBlockEntity* GetBlockEntity( int a_X, int a_Y, int a_Z ); //tolua_export
@@ -173,8 +179,11 @@ private:
int m_GameMode;
float m_WorldTimeFraction; // When this > 1.f m_WorldTime is incremented by 20
+ cSimulatorManager *m_SimulatorManager;
+ cSandSimulator *m_SandSimulator;
cWaterSimulator* m_WaterSimulator;
cLavaSimulator* m_LavaSimulator;
+
cCriticalSection* m_ClientHandleCriticalSection;
cCriticalSection* m_EntitiesCriticalSection;