diff options
Diffstat (limited to 'src/World.cpp')
-rw-r--r-- | src/World.cpp | 145 |
1 files changed, 143 insertions, 2 deletions
diff --git a/src/World.cpp b/src/World.cpp index 39300d419..3e7c0ef74 100644 --- a/src/World.cpp +++ b/src/World.cpp @@ -10,11 +10,13 @@ #include "Root.h" #include "inifile/iniFile.h" #include "ChunkMap.h" +#include "Generating/ChunkDesc.h" #include "OSSupport/Timer.h" // Entities (except mobs): #include "Entities/ExpOrb.h" #include "Entities/FallingBlock.h" +#include "Entities/Minecart.h" #include "Entities/Pickup.h" #include "Entities/Player.h" #include "Entities/TNTEntity.h" @@ -229,6 +231,7 @@ cWorld::cWorld(const AString & a_WorldName) : m_WorldName(a_WorldName), m_IniFileName(m_WorldName + "/world.ini"), m_StorageSchema("Default"), + m_StorageCompressionFactor(6), m_IsSpawnExplicitlySet(false), m_WorldAgeSecs(0), m_TimeOfDaySecs(0), @@ -238,6 +241,7 @@ cWorld::cWorld(const AString & a_WorldName) : m_SkyDarkness(0), m_Weather(eWeather_Sunny), m_WeatherInterval(24000), // Guaranteed 1 day of sunshine at server start :) + m_GeneratorCallbacks(*this), m_TickThread(*this) { LOGD("cWorld::cWorld(\"%s\")", a_WorldName.c_str()); @@ -509,6 +513,7 @@ void cWorld::Start(void) } m_StorageSchema = IniFile.GetValueSet ("Storage", "Schema", m_StorageSchema); + m_StorageCompressionFactor = IniFile.GetValueSetI ("Storage", "CompressionFactor", m_StorageCompressionFactor); m_MaxCactusHeight = IniFile.GetValueSetI("Plants", "MaxCactusHeight", 3); m_MaxSugarcaneHeight = IniFile.GetValueSetI("Plants", "MaxSugarcaneHeight", 3); m_IsCactusBonemealable = IniFile.GetValueSetB("Plants", "IsCactusBonemealable", false); @@ -582,8 +587,8 @@ void cWorld::Start(void) m_SimulatorManager->RegisterSimulator(m_RedstoneSimulator, 1); m_Lighting.Start(this); - m_Storage.Start(this, m_StorageSchema); - m_Generator.Start(this, IniFile); + m_Storage.Start(this, m_StorageSchema, m_StorageCompressionFactor ); + m_Generator.Start(m_GeneratorCallbacks, m_GeneratorCallbacks, IniFile); m_ChunkSender.Start(this); m_TickThread.Start(); @@ -688,6 +693,7 @@ void cWorld::Tick(float a_Dt, int a_LastTickDurationMSec) TickClients(a_Dt); TickQueuedBlocks(); TickQueuedTasks(); + TickScheduledTasks(); GetSimulatorManager()->Simulate(a_Dt); @@ -859,6 +865,31 @@ void cWorld::TickQueuedTasks(void) } // for itr - m_Tasks[] } +void cWorld::TickScheduledTasks() +{ + ScheduledTaskList Tasks; + // Make a copy of the tasks to avoid deadlocks on accessing m_Tasks + { + cCSLock Lock(m_CSScheduledTasks); + ScheduledTaskList::iterator itr = m_ScheduledTasks.begin(); + while (itr != m_ScheduledTasks.end() && (*itr)->Ticks > 0) + { + Tasks.push_back(m_ScheduledTasks.front()); + m_ScheduledTasks.pop_front(); + } + for(;itr != m_ScheduledTasks.end(); itr++) + { + (*itr)->Ticks--; + } + } + + // Execute and delete each task: + for (ScheduledTaskList::iterator itr = Tasks.begin(), end = Tasks.end(); itr != end; ++itr) + { + (*itr)->Run(*this); + delete *itr; + } // for itr - m_Tasks[] +} @@ -1645,6 +1676,29 @@ int cWorld::SpawnExperienceOrb(double a_X, double a_Y, double a_Z, int a_Reward) +int cWorld::SpawnMinecart(double a_X, double a_Y, double a_Z, int a_MinecartType, const cItem & a_Content, int a_BlockHeight) +{ + cMinecart * Minecart; + switch (a_MinecartType) + { + case E_ITEM_MINECART: Minecart = new cRideableMinecart (a_X, a_Y, a_Z, a_Content, a_BlockHeight); break; + case E_ITEM_CHEST_MINECART: Minecart = new cMinecartWithChest (a_X, a_Y, a_Z); break; + case E_ITEM_FURNACE_MINECART: Minecart = new cMinecartWithFurnace (a_X, a_Y, a_Z); break; + case E_ITEM_MINECART_WITH_TNT: Minecart = new cMinecartWithTNT (a_X, a_Y, a_Z); break; + case E_ITEM_MINECART_WITH_HOPPER: Minecart = new cMinecartWithHopper (a_X, a_Y, a_Z); break; + default: + { + return -1; + } + } // switch (a_MinecartType) + Minecart->Initialize(this); + return Minecart->GetUniqueID(); +} + + + + + void cWorld::SpawnPrimedTNT(double a_X, double a_Y, double a_Z, double a_FuseTimeInSec, double a_InitialVelocityCoeff) { UNUSED(a_InitialVelocityCoeff); @@ -2569,6 +2623,19 @@ void cWorld::QueueTask(cTask * a_Task) m_Tasks.push_back(a_Task); } +void cWorld::ScheduleTask(cScheduledTask * a_Task) +{ + cCSLock Lock(m_CSScheduledTasks); + for(ScheduledTaskList::iterator itr = m_ScheduledTasks.begin(); itr != m_ScheduledTasks.end(); itr++) + { + if((*itr)->Ticks >= a_Task->Ticks) + { + m_ScheduledTasks.insert(itr, a_Task); + return; + } + } + m_ScheduledTasks.push_back(a_Task); +} @@ -2843,3 +2910,77 @@ void cWorld::cTaskSaveAllChunks::Run(cWorld & a_World) +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// cWorld::cChunkGeneratorCallbacks: + +cWorld::cChunkGeneratorCallbacks::cChunkGeneratorCallbacks(cWorld & a_World) : + m_World(&a_World) +{ +} + + + + + +void cWorld::cChunkGeneratorCallbacks::OnChunkGenerated(cChunkDesc & a_ChunkDesc) +{ + cChunkDef::BlockNibbles BlockMetas; + a_ChunkDesc.CompressBlockMetas(BlockMetas); + + m_World->SetChunkData( + a_ChunkDesc.GetChunkX(), a_ChunkDesc.GetChunkZ(), + a_ChunkDesc.GetBlockTypes(), BlockMetas, + NULL, NULL, // We don't have lighting, chunk will be lighted when needed + &a_ChunkDesc.GetHeightMap(), &a_ChunkDesc.GetBiomeMap(), + a_ChunkDesc.GetEntities(), a_ChunkDesc.GetBlockEntities(), + true + ); + + // Save the chunk right after generating, so that we don't have to generate it again on next run + m_World->GetStorage().QueueSaveChunk(a_ChunkDesc.GetChunkX(), 0, a_ChunkDesc.GetChunkZ()); +} + + + + + +bool cWorld::cChunkGeneratorCallbacks::IsChunkValid(int a_ChunkX, int a_ChunkZ) +{ + return m_World->IsChunkValid(a_ChunkX, a_ChunkZ); +} + + + + + +bool cWorld::cChunkGeneratorCallbacks::HasChunkAnyClients(int a_ChunkX, int a_ChunkZ) +{ + return m_World->HasChunkAnyClients(a_ChunkX, a_ChunkZ); +} + + + + + +void cWorld::cChunkGeneratorCallbacks::CallHookChunkGenerating(cChunkDesc & a_ChunkDesc) +{ + cPluginManager::Get()->CallHookChunkGenerating( + m_World, a_ChunkDesc.GetChunkX(), a_ChunkDesc.GetChunkZ(), &a_ChunkDesc + ); +} + + + + + +void cWorld::cChunkGeneratorCallbacks::CallHookChunkGenerated (cChunkDesc & a_ChunkDesc) +{ + cPluginManager::Get()->CallHookChunkGenerated( + m_World, a_ChunkDesc.GetChunkX(), a_ChunkDesc.GetChunkZ(), &a_ChunkDesc + ); +} + + + + + |