Do not spawn mobs too close to player
This commit is contained in:
parent
062b51c822
commit
e77af000df
117
src/World.cpp
117
src/World.cpp
|
@ -109,7 +109,7 @@ void cWorld::cTickThread::Execute(void)
|
||||||
auto WaitTime = std::chrono::duration_cast<std::chrono::milliseconds>(NowTime - LastTime);
|
auto WaitTime = std::chrono::duration_cast<std::chrono::milliseconds>(NowTime - LastTime);
|
||||||
m_World.Tick(WaitTime, TickTime);
|
m_World.Tick(WaitTime, TickTime);
|
||||||
TickTime = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::steady_clock::now() - NowTime);
|
TickTime = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::steady_clock::now() - NowTime);
|
||||||
|
|
||||||
if (TickTime < cTickTime(1))
|
if (TickTime < cTickTime(1))
|
||||||
{
|
{
|
||||||
// Stretch tick time until it's at least 1 tick
|
// Stretch tick time until it's at least 1 tick
|
||||||
|
@ -216,7 +216,7 @@ cWorld::~cWorld()
|
||||||
delete m_RedstoneSimulator; m_RedstoneSimulator = nullptr;
|
delete m_RedstoneSimulator; m_RedstoneSimulator = nullptr;
|
||||||
|
|
||||||
UnloadUnusedChunks();
|
UnloadUnusedChunks();
|
||||||
|
|
||||||
m_Storage.WaitForFinish();
|
m_Storage.WaitForFinish();
|
||||||
|
|
||||||
// Unload the scoreboard
|
// Unload the scoreboard
|
||||||
|
@ -283,19 +283,19 @@ void cWorld::SetWeather(eWeather a_NewWeather)
|
||||||
m_WeatherInterval = GetDefaultWeatherInterval(m_Weather);
|
m_WeatherInterval = GetDefaultWeatherInterval(m_Weather);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set new period for the selected weather:
|
// Set new period for the selected weather:
|
||||||
m_WeatherInterval = GetDefaultWeatherInterval(a_NewWeather);
|
m_WeatherInterval = GetDefaultWeatherInterval(a_NewWeather);
|
||||||
|
|
||||||
// The weather can't be found:
|
// The weather can't be found:
|
||||||
if (m_WeatherInterval < 0)
|
if (m_WeatherInterval < 0)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_Weather = a_NewWeather;
|
m_Weather = a_NewWeather;
|
||||||
BroadcastWeather(m_Weather);
|
BroadcastWeather(m_Weather);
|
||||||
|
|
||||||
// Let the plugins know about the change:
|
// Let the plugins know about the change:
|
||||||
cPluginManager::Get()->CallHookWeatherChanged(*this);
|
cPluginManager::Get()->CallHookWeatherChanged(*this);
|
||||||
}
|
}
|
||||||
|
@ -352,7 +352,7 @@ void cWorld::InitializeSpawn(void)
|
||||||
int ChunkX = 0, ChunkZ = 0;
|
int ChunkX = 0, ChunkZ = 0;
|
||||||
cChunkDef::BlockToChunk(FloorC(m_SpawnX), FloorC(m_SpawnZ), ChunkX, ChunkZ);
|
cChunkDef::BlockToChunk(FloorC(m_SpawnX), FloorC(m_SpawnZ), ChunkX, ChunkZ);
|
||||||
cSpawnPrepare::PrepareChunks(*this, ChunkX, ChunkZ, ViewDist);
|
cSpawnPrepare::PrepareChunks(*this, ChunkX, ChunkZ, ViewDist);
|
||||||
|
|
||||||
#ifdef TEST_LINEBLOCKTRACER
|
#ifdef TEST_LINEBLOCKTRACER
|
||||||
// DEBUG: Test out the cLineBlockTracer class by tracing a few lines:
|
// DEBUG: Test out the cLineBlockTracer class by tracing a few lines:
|
||||||
class cTracerCallbacks :
|
class cTracerCallbacks :
|
||||||
|
@ -366,7 +366,7 @@ void cWorld::InitializeSpawn(void)
|
||||||
);
|
);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual bool OnNextBlockNoData(int a_BlockX, int a_BlockY, int a_BlockZ) override
|
virtual bool OnNextBlockNoData(int a_BlockX, int a_BlockY, int a_BlockZ) override
|
||||||
{
|
{
|
||||||
LOGD("Block {%d, %d, %d}: no data available",
|
LOGD("Block {%d, %d, %d}: no data available",
|
||||||
|
@ -509,7 +509,7 @@ void cWorld::Start(void)
|
||||||
std::swap(m_MaxThunderStormTicks, m_MinThunderStormTicks);
|
std::swap(m_MaxThunderStormTicks, m_MinThunderStormTicks);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (GetDimension() == dimOverworld)
|
if (GetDimension() == dimOverworld)
|
||||||
{
|
{
|
||||||
m_LinkedNetherWorldName = IniFile.GetValueSet("LinkedWorlds", "NetherWorldName", GetName() + "_nether");
|
m_LinkedNetherWorldName = IniFile.GetValueSet("LinkedWorlds", "NetherWorldName", GetName() + "_nether");
|
||||||
|
@ -519,7 +519,7 @@ void cWorld::Start(void)
|
||||||
{
|
{
|
||||||
m_LinkedOverworldName = IniFile.GetValueSet("LinkedWorlds", "OverworldName", GetLinkedOverworldName());
|
m_LinkedOverworldName = IniFile.GetValueSet("LinkedWorlds", "OverworldName", GetLinkedOverworldName());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Adjust the enum-backed variables into their respective bounds:
|
// Adjust the enum-backed variables into their respective bounds:
|
||||||
m_GameMode = static_cast<eGameMode> (Clamp<int>(GameMode, gmSurvival, gmSpectator));
|
m_GameMode = static_cast<eGameMode> (Clamp<int>(GameMode, gmSurvival, gmSpectator));
|
||||||
m_TNTShrapnelLevel = static_cast<eShrapnelLevel>(Clamp<int>(TNTShrapnelLevel, slNone, slAll));
|
m_TNTShrapnelLevel = static_cast<eShrapnelLevel>(Clamp<int>(TNTShrapnelLevel, slNone, slAll));
|
||||||
|
@ -530,7 +530,7 @@ void cWorld::Start(void)
|
||||||
SetTimeOfDay(IniFile.GetValueSetI("General", "TimeInTicks", GetTimeOfDay()));
|
SetTimeOfDay(IniFile.GetValueSetI("General", "TimeInTicks", GetTimeOfDay()));
|
||||||
|
|
||||||
m_ChunkMap = cpp14::make_unique<cChunkMap>(this);
|
m_ChunkMap = cpp14::make_unique<cChunkMap>(this);
|
||||||
|
|
||||||
// preallocate some memory for ticking blocks so we don't need to allocate that often
|
// preallocate some memory for ticking blocks so we don't need to allocate that often
|
||||||
m_BlockTickQueue.reserve(1000);
|
m_BlockTickQueue.reserve(1000);
|
||||||
m_BlockTickQueueCopy.reserve(1000);
|
m_BlockTickQueueCopy.reserve(1000);
|
||||||
|
@ -599,7 +599,7 @@ void cWorld::GenerateRandomSpawn(int a_MaxSpawnRadius)
|
||||||
cSpawnPrepare::PrepareChunks(*this, ChunkX, ChunkZ, a_MaxSpawnRadius);
|
cSpawnPrepare::PrepareChunks(*this, ChunkX, ChunkZ, a_MaxSpawnRadius);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check 0, 0 first.
|
// Check 0, 0 first.
|
||||||
double SpawnY = 0.0;
|
double SpawnY = 0.0;
|
||||||
if (CanSpawnAt(BiomeOffset.x, SpawnY, BiomeOffset.z))
|
if (CanSpawnAt(BiomeOffset.x, SpawnY, BiomeOffset.z))
|
||||||
|
@ -633,7 +633,7 @@ void cWorld::GenerateRandomSpawn(int a_MaxSpawnRadius)
|
||||||
for (int SearchGridIndex = 0; SearchGridIndex < PerRadiSearchCount; ++SearchGridIndex)
|
for (int SearchGridIndex = 0; SearchGridIndex < PerRadiSearchCount; ++SearchGridIndex)
|
||||||
{
|
{
|
||||||
const Vector3i PotentialSpawn = BiomeOffset + (ChunkOffset[SearchGridIndex] * RadiusOffset);
|
const Vector3i PotentialSpawn = BiomeOffset + (ChunkOffset[SearchGridIndex] * RadiusOffset);
|
||||||
|
|
||||||
if (CanSpawnAt(PotentialSpawn.x, SpawnY, PotentialSpawn.z))
|
if (CanSpawnAt(PotentialSpawn.x, SpawnY, PotentialSpawn.z))
|
||||||
{
|
{
|
||||||
m_SpawnX = PotentialSpawn.x + 0.5;
|
m_SpawnX = PotentialSpawn.x + 0.5;
|
||||||
|
@ -780,7 +780,7 @@ eWeather cWorld::ChooseNewWeather()
|
||||||
{
|
{
|
||||||
case eWeather_Sunny:
|
case eWeather_Sunny:
|
||||||
case eWeather_ThunderStorm: return eWeather_Rain;
|
case eWeather_ThunderStorm: return eWeather_Rain;
|
||||||
|
|
||||||
case eWeather_Rain:
|
case eWeather_Rain:
|
||||||
{
|
{
|
||||||
// 1 / 8 chance of turning into a thunderstorm
|
// 1 / 8 chance of turning into a thunderstorm
|
||||||
|
@ -855,7 +855,7 @@ void cWorld::InitialiseAndLoadMobSpawningValues(cIniFile & a_IniFile)
|
||||||
case dimEnd: DefaultMonsters = "enderman"; break;
|
case dimEnd: DefaultMonsters = "enderman"; break;
|
||||||
case dimNotSet: ASSERT(!"Dimension not set"); break;
|
case dimNotSet: ASSERT(!"Dimension not set"); break;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_bAnimals = a_IniFile.GetValueSetB("Monsters", "AnimalsOn", true);
|
m_bAnimals = a_IniFile.GetValueSetB("Monsters", "AnimalsOn", true);
|
||||||
AString AllMonsters = a_IniFile.GetValueSet("Monsters", "Types", DefaultMonsters);
|
AString AllMonsters = a_IniFile.GetValueSet("Monsters", "Types", DefaultMonsters);
|
||||||
|
|
||||||
|
@ -915,7 +915,7 @@ void cWorld::Stop(void)
|
||||||
IniFile.SetValueI("General", "Weather", static_cast<int>(m_Weather));
|
IniFile.SetValueI("General", "Weather", static_cast<int>(m_Weather));
|
||||||
IniFile.SetValueI("General", "TimeInTicks", GetTimeOfDay());
|
IniFile.SetValueI("General", "TimeInTicks", GetTimeOfDay());
|
||||||
IniFile.WriteFile(m_IniFileName);
|
IniFile.WriteFile(m_IniFileName);
|
||||||
|
|
||||||
m_TickThread.Stop();
|
m_TickThread.Stop();
|
||||||
m_Lighting.Stop();
|
m_Lighting.Stop();
|
||||||
m_Generator.Stop();
|
m_Generator.Stop();
|
||||||
|
@ -931,7 +931,7 @@ void cWorld::Tick(std::chrono::milliseconds a_Dt, std::chrono::milliseconds a_La
|
||||||
{
|
{
|
||||||
// Call the plugins
|
// Call the plugins
|
||||||
cPluginManager::Get()->CallHookWorldTick(*this, a_Dt, a_LastTickDurationMSec);
|
cPluginManager::Get()->CallHookWorldTick(*this, a_Dt, a_LastTickDurationMSec);
|
||||||
|
|
||||||
// Set any chunk data that has been queued for setting:
|
// Set any chunk data that has been queued for setting:
|
||||||
cSetChunkDataPtrs SetChunkDataQueue;
|
cSetChunkDataPtrs SetChunkDataQueue;
|
||||||
{
|
{
|
||||||
|
@ -987,7 +987,7 @@ void cWorld::Tick(std::chrono::milliseconds a_Dt, std::chrono::milliseconds a_La
|
||||||
TickClients(static_cast<float>(a_Dt.count()));
|
TickClients(static_cast<float>(a_Dt.count()));
|
||||||
TickQueuedBlocks();
|
TickQueuedBlocks();
|
||||||
TickQueuedTasks();
|
TickQueuedTasks();
|
||||||
|
|
||||||
GetSimulatorManager()->Simulate(static_cast<float>(a_Dt.count()));
|
GetSimulatorManager()->Simulate(static_cast<float>(a_Dt.count()));
|
||||||
|
|
||||||
TickWeather(static_cast<float>(a_Dt.count()));
|
TickWeather(static_cast<float>(a_Dt.count()));
|
||||||
|
@ -1151,7 +1151,7 @@ void cWorld::TickClients(float a_Dt)
|
||||||
cClientHandlePtrs RemoveClients;
|
cClientHandlePtrs RemoveClients;
|
||||||
{
|
{
|
||||||
cCSLock Lock(m_CSClients);
|
cCSLock Lock(m_CSClients);
|
||||||
|
|
||||||
// Remove clients scheduled for removal:
|
// Remove clients scheduled for removal:
|
||||||
for (auto itr = m_ClientsToRemove.begin(), end = m_ClientsToRemove.end(); itr != end; ++itr)
|
for (auto itr = m_ClientsToRemove.begin(), end = m_ClientsToRemove.end(); itr != end; ++itr)
|
||||||
{
|
{
|
||||||
|
@ -1165,7 +1165,7 @@ void cWorld::TickClients(float a_Dt)
|
||||||
}
|
}
|
||||||
} // for itr - m_ClientsToRemove[]
|
} // for itr - m_ClientsToRemove[]
|
||||||
m_ClientsToRemove.clear();
|
m_ClientsToRemove.clear();
|
||||||
|
|
||||||
// Add clients scheduled for adding:
|
// Add clients scheduled for adding:
|
||||||
for (auto itr = m_ClientsToAdd.begin(), end = m_ClientsToAdd.end(); itr != end; ++itr)
|
for (auto itr = m_ClientsToAdd.begin(), end = m_ClientsToAdd.end(); itr != end; ++itr)
|
||||||
{
|
{
|
||||||
|
@ -1173,7 +1173,7 @@ void cWorld::TickClients(float a_Dt)
|
||||||
m_Clients.push_back(*itr);
|
m_Clients.push_back(*itr);
|
||||||
} // for itr - m_ClientsToRemove[]
|
} // for itr - m_ClientsToRemove[]
|
||||||
m_ClientsToAdd.clear();
|
m_ClientsToAdd.clear();
|
||||||
|
|
||||||
// Tick the clients, take out those that have been destroyed into RemoveClients
|
// Tick the clients, take out those that have been destroyed into RemoveClients
|
||||||
for (auto itr = m_Clients.begin(); itr != m_Clients.end();)
|
for (auto itr = m_Clients.begin(); itr != m_Clients.end();)
|
||||||
{
|
{
|
||||||
|
@ -1309,7 +1309,7 @@ void cWorld::DoExplosionAt(double a_ExplosionSize, double a_BlockX, double a_Blo
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Implement block hardiness
|
// TODO: Implement block hardiness
|
||||||
Vector3d explosion_pos = Vector3d(a_BlockX, a_BlockY, a_BlockZ);
|
Vector3d explosion_pos = Vector3d(a_BlockX, a_BlockY, a_BlockZ);
|
||||||
cVector3iArray BlocksAffected;
|
cVector3iArray BlocksAffected;
|
||||||
|
@ -1483,7 +1483,7 @@ bool cWorld::DoWithChunk(int a_ChunkX, int a_ChunkZ, std::function<bool(cChunk &
|
||||||
m_Callback(a_InnerCallback)
|
m_Callback(a_InnerCallback)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual bool Item(cChunk * a_Chunk)
|
virtual bool Item(cChunk * a_Chunk)
|
||||||
{
|
{
|
||||||
return m_Callback(*a_Chunk);
|
return m_Callback(*a_Chunk);
|
||||||
|
@ -1580,7 +1580,7 @@ void cWorld::GrowTreeByBiome(int a_X, int a_Y, int a_Z)
|
||||||
void cWorld::GrowTreeImage(const sSetBlockVector & a_Blocks)
|
void cWorld::GrowTreeImage(const sSetBlockVector & a_Blocks)
|
||||||
{
|
{
|
||||||
// Check that the tree has place to grow
|
// Check that the tree has place to grow
|
||||||
|
|
||||||
// Make a copy of the log blocks:
|
// Make a copy of the log blocks:
|
||||||
sSetBlockVector b2;
|
sSetBlockVector b2;
|
||||||
for (sSetBlockVector::const_iterator itr = a_Blocks.begin(); itr != a_Blocks.end(); ++itr)
|
for (sSetBlockVector::const_iterator itr = a_Blocks.begin(); itr != a_Blocks.end(); ++itr)
|
||||||
|
@ -1590,13 +1590,13 @@ void cWorld::GrowTreeImage(const sSetBlockVector & a_Blocks)
|
||||||
b2.push_back(*itr);
|
b2.push_back(*itr);
|
||||||
}
|
}
|
||||||
} // for itr - a_Blocks[]
|
} // for itr - a_Blocks[]
|
||||||
|
|
||||||
// Query blocktypes and metas at those log blocks:
|
// Query blocktypes and metas at those log blocks:
|
||||||
if (!GetBlocks(b2, false))
|
if (!GetBlocks(b2, false))
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check that at each log's coord there's an block allowed to be overwritten:
|
// Check that at each log's coord there's an block allowed to be overwritten:
|
||||||
for (sSetBlockVector::const_iterator itr = b2.begin(); itr != b2.end(); ++itr)
|
for (sSetBlockVector::const_iterator itr = b2.begin(); itr != b2.end(); ++itr)
|
||||||
{
|
{
|
||||||
|
@ -1612,7 +1612,7 @@ void cWorld::GrowTreeImage(const sSetBlockVector & a_Blocks)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} // for itr - b2[]
|
} // for itr - b2[]
|
||||||
|
|
||||||
// All ok, replace blocks with the tree image:
|
// All ok, replace blocks with the tree image:
|
||||||
m_ChunkMap->ReplaceTreeBlocks(a_Blocks);
|
m_ChunkMap->ReplaceTreeBlocks(a_Blocks);
|
||||||
}
|
}
|
||||||
|
@ -1688,7 +1688,7 @@ bool cWorld::GrowRipePlant(int a_BlockX, int a_BlockY, int a_BlockZ, bool a_IsBy
|
||||||
}
|
}
|
||||||
return BlockMeta == 7;
|
return BlockMeta == 7;
|
||||||
}
|
}
|
||||||
|
|
||||||
case E_BLOCK_MELON_STEM:
|
case E_BLOCK_MELON_STEM:
|
||||||
{
|
{
|
||||||
if (BlockMeta < 7)
|
if (BlockMeta < 7)
|
||||||
|
@ -1720,7 +1720,7 @@ bool cWorld::GrowRipePlant(int a_BlockX, int a_BlockY, int a_BlockZ, bool a_IsBy
|
||||||
}
|
}
|
||||||
return BlockMeta == 7;
|
return BlockMeta == 7;
|
||||||
}
|
}
|
||||||
|
|
||||||
case E_BLOCK_POTATOES:
|
case E_BLOCK_POTATOES:
|
||||||
{
|
{
|
||||||
if (a_IsByBonemeal && !m_IsPotatoesBonemealable)
|
if (a_IsByBonemeal && !m_IsPotatoesBonemealable)
|
||||||
|
@ -1743,7 +1743,7 @@ bool cWorld::GrowRipePlant(int a_BlockX, int a_BlockY, int a_BlockZ, bool a_IsBy
|
||||||
}
|
}
|
||||||
return BlockMeta == 7;
|
return BlockMeta == 7;
|
||||||
}
|
}
|
||||||
|
|
||||||
case E_BLOCK_PUMPKIN_STEM:
|
case E_BLOCK_PUMPKIN_STEM:
|
||||||
{
|
{
|
||||||
if (BlockMeta < 7)
|
if (BlockMeta < 7)
|
||||||
|
@ -1775,7 +1775,7 @@ bool cWorld::GrowRipePlant(int a_BlockX, int a_BlockY, int a_BlockZ, bool a_IsBy
|
||||||
}
|
}
|
||||||
return BlockMeta == 7;
|
return BlockMeta == 7;
|
||||||
}
|
}
|
||||||
|
|
||||||
case E_BLOCK_SAPLING:
|
case E_BLOCK_SAPLING:
|
||||||
{
|
{
|
||||||
if (a_IsByBonemeal && !m_IsSaplingBonemealable)
|
if (a_IsByBonemeal && !m_IsSaplingBonemealable)
|
||||||
|
@ -1808,7 +1808,7 @@ bool cWorld::GrowRipePlant(int a_BlockX, int a_BlockY, int a_BlockZ, bool a_IsBy
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
case E_BLOCK_GRASS:
|
case E_BLOCK_GRASS:
|
||||||
{
|
{
|
||||||
if (a_IsByBonemeal && !m_IsGrassBonemealable)
|
if (a_IsByBonemeal && !m_IsGrassBonemealable)
|
||||||
|
@ -1849,7 +1849,7 @@ bool cWorld::GrowRipePlant(int a_BlockX, int a_BlockY, int a_BlockZ, bool a_IsBy
|
||||||
} // for i - 50 times
|
} // for i - 50 times
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
case E_BLOCK_SUGARCANE:
|
case E_BLOCK_SUGARCANE:
|
||||||
{
|
{
|
||||||
if (a_IsByBonemeal && !m_IsSugarcaneBonemealable)
|
if (a_IsByBonemeal && !m_IsSugarcaneBonemealable)
|
||||||
|
@ -1859,7 +1859,7 @@ bool cWorld::GrowRipePlant(int a_BlockX, int a_BlockY, int a_BlockZ, bool a_IsBy
|
||||||
m_ChunkMap->GrowSugarcane(a_BlockX, a_BlockY, a_BlockZ, m_MaxSugarcaneHeight);
|
m_ChunkMap->GrowSugarcane(a_BlockX, a_BlockY, a_BlockZ, m_MaxSugarcaneHeight);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
case E_BLOCK_CACTUS:
|
case E_BLOCK_CACTUS:
|
||||||
{
|
{
|
||||||
if (a_IsByBonemeal && !m_IsCactusBonemealable)
|
if (a_IsByBonemeal && !m_IsCactusBonemealable)
|
||||||
|
@ -2020,7 +2020,7 @@ void cWorld::SpawnItemPickups(const cItems & a_Pickups, double a_BlockX, double
|
||||||
float SpeedX = static_cast<float>(a_FlyAwaySpeed * (GetTickRandomNumber(10) - 5));
|
float SpeedX = static_cast<float>(a_FlyAwaySpeed * (GetTickRandomNumber(10) - 5));
|
||||||
float SpeedY = static_cast<float>(a_FlyAwaySpeed * GetTickRandomNumber(50));
|
float SpeedY = static_cast<float>(a_FlyAwaySpeed * GetTickRandomNumber(50));
|
||||||
float SpeedZ = static_cast<float>(a_FlyAwaySpeed * (GetTickRandomNumber(10) - 5));
|
float SpeedZ = static_cast<float>(a_FlyAwaySpeed * (GetTickRandomNumber(10) - 5));
|
||||||
|
|
||||||
cPickup * Pickup = new cPickup(
|
cPickup * Pickup = new cPickup(
|
||||||
a_BlockX, a_BlockY, a_BlockZ,
|
a_BlockX, a_BlockY, a_BlockZ,
|
||||||
*itr, IsPlayerCreated, SpeedX, SpeedY, SpeedZ
|
*itr, IsPlayerCreated, SpeedX, SpeedY, SpeedZ
|
||||||
|
@ -2675,13 +2675,13 @@ void cWorld::QueueSetChunkData(const cSetChunkDataPtr & a_SetChunkData)
|
||||||
m_Generator.GenerateBiomes(a_SetChunkData->GetChunkX(), a_SetChunkData->GetChunkZ(), a_SetChunkData->GetBiomes());
|
m_Generator.GenerateBiomes(a_SetChunkData->GetChunkX(), a_SetChunkData->GetChunkZ(), a_SetChunkData->GetBiomes());
|
||||||
a_SetChunkData->MarkBiomesValid();
|
a_SetChunkData->MarkBiomesValid();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Validate heightmap, if needed:
|
// Validate heightmap, if needed:
|
||||||
if (!a_SetChunkData->IsHeightMapValid())
|
if (!a_SetChunkData->IsHeightMapValid())
|
||||||
{
|
{
|
||||||
a_SetChunkData->CalculateHeightMap();
|
a_SetChunkData->CalculateHeightMap();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Store a copy of the data in the queue:
|
// Store a copy of the data in the queue:
|
||||||
// TODO: If the queue is too large, wait for it to get processed. Not likely, though.
|
// TODO: If the queue is too large, wait for it to get processed. Not likely, though.
|
||||||
cCSLock Lock(m_CSSetChunkDataQueue);
|
cCSLock Lock(m_CSSetChunkDataQueue);
|
||||||
|
@ -2696,9 +2696,9 @@ void cWorld::SetChunkData(cSetChunkData & a_SetChunkData)
|
||||||
{
|
{
|
||||||
ASSERT(a_SetChunkData.AreBiomesValid());
|
ASSERT(a_SetChunkData.AreBiomesValid());
|
||||||
ASSERT(a_SetChunkData.IsHeightMapValid());
|
ASSERT(a_SetChunkData.IsHeightMapValid());
|
||||||
|
|
||||||
m_ChunkMap->SetChunkData(a_SetChunkData);
|
m_ChunkMap->SetChunkData(a_SetChunkData);
|
||||||
|
|
||||||
// Initialize the entities (outside the m_ChunkMap's CS, to fix FS #347):
|
// Initialize the entities (outside the m_ChunkMap's CS, to fix FS #347):
|
||||||
cEntityList Entities;
|
cEntityList Entities;
|
||||||
std::swap(a_SetChunkData.GetEntities(), Entities);
|
std::swap(a_SetChunkData.GetEntities(), Entities);
|
||||||
|
@ -2706,7 +2706,7 @@ void cWorld::SetChunkData(cSetChunkData & a_SetChunkData)
|
||||||
{
|
{
|
||||||
(*itr)->Initialize(*this);
|
(*itr)->Initialize(*this);
|
||||||
}
|
}
|
||||||
|
|
||||||
// If a client is requesting this chunk, send it to them:
|
// If a client is requesting this chunk, send it to them:
|
||||||
int ChunkX = a_SetChunkData.GetChunkX();
|
int ChunkX = a_SetChunkData.GetChunkX();
|
||||||
int ChunkZ = a_SetChunkData.GetChunkZ();
|
int ChunkZ = a_SetChunkData.GetChunkZ();
|
||||||
|
@ -2852,7 +2852,7 @@ void cWorld::RemovePlayer(cPlayer * a_Player, bool a_RemoveFromChunk)
|
||||||
LOGD("Removing player %s from world \"%s\"", a_Player->GetName().c_str(), m_WorldName.c_str());
|
LOGD("Removing player %s from world \"%s\"", a_Player->GetName().c_str(), m_WorldName.c_str());
|
||||||
m_Players.remove(a_Player);
|
m_Players.remove(a_Player);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Remove the player's client from the list of clients to be ticked:
|
// Remove the player's client from the list of clients to be ticked:
|
||||||
cClientHandle * Client = a_Player->GetClientHandle();
|
cClientHandle * Client = a_Player->GetClientHandle();
|
||||||
if (Client != nullptr)
|
if (Client != nullptr)
|
||||||
|
@ -3184,7 +3184,7 @@ bool cWorld::SetCommandBlockCommand(int a_BlockX, int a_BlockY, int a_BlockZ, co
|
||||||
AString m_Command;
|
AString m_Command;
|
||||||
public:
|
public:
|
||||||
cUpdateCommandBlock(const AString & a_CallbackCommand) : m_Command(a_CallbackCommand) {}
|
cUpdateCommandBlock(const AString & a_CallbackCommand) : m_Command(a_CallbackCommand) {}
|
||||||
|
|
||||||
virtual bool Item(cCommandBlockEntity * a_CommandBlock) override
|
virtual bool Item(cCommandBlockEntity * a_CommandBlock) override
|
||||||
{
|
{
|
||||||
a_CommandBlock->SetCommand(m_Command);
|
a_CommandBlock->SetCommand(m_Command);
|
||||||
|
@ -3208,7 +3208,7 @@ bool cWorld::IsTrapdoorOpen(int a_BlockX, int a_BlockY, int a_BlockZ)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return (Meta & 0x4) > 0;
|
return (Meta & 0x4) > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3225,7 +3225,7 @@ bool cWorld::SetTrapdoorOpen(int a_BlockX, int a_BlockY, int a_BlockZ, bool a_Op
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool IsOpen = (Meta & 0x4) != 0;
|
bool IsOpen = (Meta & 0x4) != 0;
|
||||||
if (a_Open != IsOpen)
|
if (a_Open != IsOpen)
|
||||||
{
|
{
|
||||||
|
@ -3243,7 +3243,7 @@ bool cWorld::SetTrapdoorOpen(int a_BlockX, int a_BlockY, int a_BlockZ, bool a_Op
|
||||||
void cWorld::RegenerateChunk(int a_ChunkX, int a_ChunkZ)
|
void cWorld::RegenerateChunk(int a_ChunkX, int a_ChunkZ)
|
||||||
{
|
{
|
||||||
m_ChunkMap->MarkChunkRegenerating(a_ChunkX, a_ChunkZ);
|
m_ChunkMap->MarkChunkRegenerating(a_ChunkX, a_ChunkZ);
|
||||||
|
|
||||||
m_Generator.QueueGenerateChunk(a_ChunkX, a_ChunkZ, true);
|
m_Generator.QueueGenerateChunk(a_ChunkX, a_ChunkZ, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3445,7 +3445,7 @@ void cWorld::QueueBlockForTick(int a_BlockX, int a_BlockY, int a_BlockZ, int a_T
|
||||||
Block->Y = a_BlockY;
|
Block->Y = a_BlockY;
|
||||||
Block->Z = a_BlockZ;
|
Block->Z = a_BlockZ;
|
||||||
Block->TicksToWait = a_TicksToWait;
|
Block->TicksToWait = a_TicksToWait;
|
||||||
|
|
||||||
m_BlockTickQueue.push_back(Block);
|
m_BlockTickQueue.push_back(Block);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3477,7 +3477,7 @@ UInt32 cWorld::SpawnMob(double a_PosX, double a_PosY, double a_PosZ, eMonsterTyp
|
||||||
return cEntity::INVALID_ID;
|
return cEntity::INVALID_ID;
|
||||||
}
|
}
|
||||||
Monster->SetPosition(a_PosX, a_PosY, a_PosZ);
|
Monster->SetPosition(a_PosX, a_PosY, a_PosZ);
|
||||||
|
|
||||||
if (a_Baby)
|
if (a_Baby)
|
||||||
{
|
{
|
||||||
Monster->SetAge(-1);
|
Monster->SetAge(-1);
|
||||||
|
@ -3504,6 +3504,15 @@ UInt32 cWorld::SpawnMobFinalize(cMonster * a_Monster)
|
||||||
return cEntity::INVALID_ID;
|
return cEntity::INVALID_ID;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cPlayer * a_Closest_Player = FindClosestPlayer(a_Monster->GetPosition(), 24);
|
||||||
|
if (a_Closest_Player != nullptr) // Too close to a player, bail out.
|
||||||
|
{
|
||||||
|
delete a_Monster;
|
||||||
|
a_Monster = nullptr;
|
||||||
|
return cEntity::INVALID_ID;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// Initialize the monster into the current world.
|
// Initialize the monster into the current world.
|
||||||
if (!a_Monster->Initialize(*this))
|
if (!a_Monster->Initialize(*this))
|
||||||
{
|
{
|
||||||
|
@ -3613,7 +3622,7 @@ cRedstoneSimulator * cWorld::InitializeRedstoneSimulator(cIniFile & a_IniFile)
|
||||||
LOGWARNING("[Physics] RedstoneSimulator not present or empty in %s, using the default of \"Incremental\".", GetIniFileName().c_str());
|
LOGWARNING("[Physics] RedstoneSimulator not present or empty in %s, using the default of \"Incremental\".", GetIniFileName().c_str());
|
||||||
SimulatorName = "Incremental";
|
SimulatorName = "Incremental";
|
||||||
}
|
}
|
||||||
|
|
||||||
cRedstoneSimulator * res = nullptr;
|
cRedstoneSimulator * res = nullptr;
|
||||||
|
|
||||||
if (NoCaseCompare(SimulatorName, "Incremental") == 0)
|
if (NoCaseCompare(SimulatorName, "Incremental") == 0)
|
||||||
|
@ -3624,9 +3633,9 @@ cRedstoneSimulator * cWorld::InitializeRedstoneSimulator(cIniFile & a_IniFile)
|
||||||
{
|
{
|
||||||
res = new cRedstoneNoopSimulator(*this);
|
res = new cRedstoneNoopSimulator(*this);
|
||||||
}
|
}
|
||||||
|
|
||||||
m_SimulatorManager->RegisterSimulator(res, 2 /* Two game ticks is a redstone tick */);
|
m_SimulatorManager->RegisterSimulator(res, 2 /* Two game ticks is a redstone tick */);
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3646,7 +3655,7 @@ cFluidSimulator * cWorld::InitializeFluidSimulator(cIniFile & a_IniFile, const c
|
||||||
LOGWARNING("[Physics] %s not present or empty in %s, using the default of \"Vanilla\".", SimulatorNameKey.c_str(), GetIniFileName().c_str());
|
LOGWARNING("[Physics] %s not present or empty in %s, using the default of \"Vanilla\".", SimulatorNameKey.c_str(), GetIniFileName().c_str());
|
||||||
SimulatorName = "Vanilla";
|
SimulatorName = "Vanilla";
|
||||||
}
|
}
|
||||||
|
|
||||||
cFluidSimulator * res = nullptr;
|
cFluidSimulator * res = nullptr;
|
||||||
bool IsWater = (strcmp(a_FluidName, "Water") == 0); // Used for defaults
|
bool IsWater = (strcmp(a_FluidName, "Water") == 0); // Used for defaults
|
||||||
int Rate = 1;
|
int Rate = 1;
|
||||||
|
@ -3671,7 +3680,7 @@ cFluidSimulator * cWorld::InitializeFluidSimulator(cIniFile & a_IniFile, const c
|
||||||
int Falloff = a_IniFile.GetValueSetI(SimulatorSectionName, "Falloff", IsWater ? 1 : 2);
|
int Falloff = a_IniFile.GetValueSetI(SimulatorSectionName, "Falloff", IsWater ? 1 : 2);
|
||||||
int TickDelay = a_IniFile.GetValueSetI(SimulatorSectionName, "TickDelay", IsWater ? 5 : 30);
|
int TickDelay = a_IniFile.GetValueSetI(SimulatorSectionName, "TickDelay", IsWater ? 5 : 30);
|
||||||
int NumNeighborsForSource = a_IniFile.GetValueSetI(SimulatorSectionName, "NumNeighborsForSource", IsWater ? 2 : -1);
|
int NumNeighborsForSource = a_IniFile.GetValueSetI(SimulatorSectionName, "NumNeighborsForSource", IsWater ? 2 : -1);
|
||||||
|
|
||||||
if ((Falloff > 15) || (Falloff < 0))
|
if ((Falloff > 15) || (Falloff < 0))
|
||||||
{
|
{
|
||||||
LOGWARNING("Falloff for %s simulator is out of range, assuming default of %d", a_FluidName, IsWater ? 1 : 2);
|
LOGWARNING("Falloff for %s simulator is out of range, assuming default of %d", a_FluidName, IsWater ? 1 : 2);
|
||||||
|
@ -3693,7 +3702,7 @@ cFluidSimulator * cWorld::InitializeFluidSimulator(cIniFile & a_IniFile, const c
|
||||||
res = new cVanillaFluidSimulator(*this, a_SimulateBlock, a_StationaryBlock, static_cast<NIBBLETYPE>(Falloff), TickDelay, NumNeighborsForSource);
|
res = new cVanillaFluidSimulator(*this, a_SimulateBlock, a_StationaryBlock, static_cast<NIBBLETYPE>(Falloff), TickDelay, NumNeighborsForSource);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
m_SimulatorManager->RegisterSimulator(res, Rate);
|
m_SimulatorManager->RegisterSimulator(res, Rate);
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
|
@ -3714,7 +3723,7 @@ void cWorld::AddQueuedPlayers(void)
|
||||||
cCSLock Lock(m_CSPlayersToAdd);
|
cCSLock Lock(m_CSPlayersToAdd);
|
||||||
std::swap(PlayersToAdd, m_PlayersToAdd);
|
std::swap(PlayersToAdd, m_PlayersToAdd);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add all the players in the grabbed list:
|
// Add all the players in the grabbed list:
|
||||||
{
|
{
|
||||||
cCSLock Lock(m_CSPlayers);
|
cCSLock Lock(m_CSPlayers);
|
||||||
|
|
Loading…
Reference in New Issue
Block a user