|
Cuberite
A lightweight, fast and extensible game server for Minecraft
|
Go to the documentation of this file.
87 Super(&(a_World.m_ChunkMap.GetCS()))
110 auto LastTime = std::chrono::steady_clock::now();
111 auto TickTime = std::chrono::duration_cast<std::chrono::milliseconds>(1_tick);
113 while (!m_ShouldTerminate)
115 auto NowTime = std::chrono::steady_clock::now();
116 auto WaitTime = std::chrono::duration_cast<std::chrono::milliseconds>(NowTime - LastTime);
117 m_World.Tick(WaitTime, TickTime);
118 TickTime = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::steady_clock::now() - NowTime);
120 if (TickTime < 1_tick)
123 std::this_thread::sleep_for(1_tick - TickTime);
219 LOGD(
"cWorld::cWorld(\"%s\")", a_WorldName.c_str());
239 IniFile.
AddHeaderComment(
" This is the per-world configuration file, managing settings such as generators, simulators, and spawn points");
240 IniFile.
AddKeyComment(
" LinkedWorlds",
"This section governs portal world linkage; leave a value blank to disabled that associated method of teleportation");
246 int UnusedDirtyChunksCap = IniFile.
GetValueSetI(
"General",
"UnusedChunkCap", 1000);
247 if (UnusedDirtyChunksCap < 0)
249 UnusedDirtyChunksCap *= -1;
250 IniFile.
SetValueI(
"General",
"UnusedChunkCap", UnusedDirtyChunksCap);
260 int KeyNum = IniFile.
FindKey(
"SpawnPosition");
273 LOGD(
"Spawnpoint explicitly set!");
301 int TNTShrapnelLevel = IniFile.
GetValueSetI(
"Physics",
"TNTShrapnelLevel",
static_cast<int>(
slAll));
340 auto WorldExists = [&](
const AString & a_CheckWorldName)
342 return (std::find(a_WorldNames.begin(), a_WorldNames.end(), a_CheckWorldName) != a_WorldNames.end());
349 if (!WorldExists(MyNetherName))
351 MyNetherName.clear();
353 if (!WorldExists(MyEndName))
355 MyEndName =
GetName() +
"_end";
356 if (!WorldExists(MyEndName))
375 IniFile.
SetValue(
"LinkedWorlds",
"NetherWorldName",
"");
376 LOG(
"%s Is linked to a nonexisting nether world called \"%s\". The server has modified \"%s/world.ini\" and removed this invalid link.",
382 IniFile.
SetValue(
"LinkedWorlds",
"EndWorldName",
"");
383 LOG(
"%s Is linked to a nonexisting end world called \"%s\". The server has modified \"%s/world.ini\" and removed this invalid link.",
392 IniFile.
SetValue(
"LinkedWorlds",
"OverworldName",
"");
393 LOG(
"%s Is linked to a nonexisting overworld called \"%s\". The server has modified \"%s/world.ini\" and removed this invalid link.",
462 LOG(
"CastThunderbolt(int, int, int) is deprecated, use CastThunderbolt(Vector3i) instead");
482 using namespace std::chrono_literals;
484 return std::chrono::duration_cast<cTickTime>(
m_WorldDate % 20min);
493 return std::chrono::duration_cast<cTickTimeLong>(
m_WorldAge);
502 return std::chrono::duration_cast<cTickTimeLong>(
m_WorldDate);
520 using namespace std::chrono_literals;
559 if (
cRoot::Get()->GetPluginManager()->CallHookWeatherChanging(*
this, a_NewWeather))
636 IniFile.
SetValueI(
"SpawnPosition",
"X", a_X);
637 IniFile.
SetValueI(
"SpawnPosition",
"Y", a_Y);
638 IniFile.
SetValueI(
"SpawnPosition",
"Z", a_Z);
661 #if !defined(NDEBUG) || defined(ANDROID)
662 const int DefaultViewDist = 9;
664 const int DefaultViewDist = 20;
675 int ViewDist = IniFile.
GetValueSetI(
"SpawnPosition",
"PregenerateDistance", DefaultViewDist);
678 int ChunkX = 0, ChunkZ = 0;
702 LOGD(
"Generating random spawnpoint...");
707 static const int BiomeCheckCount = 100;
711 for (
int BiomeCheckIndex = 0; BiomeCheckIndex < BiomeCheckCount; ++BiomeCheckIndex)
722 int ChunkX = 0, ChunkZ = 0;
732 SetSpawn(BiomeOffset.
x, SpawnY, BiomeOffset.
z);
740 static const Vector3i ChunkOffset[] =
747 Vector3i(-HalfChunk, 0, -HalfChunk),
752 static const int PerRadiSearchCount =
ARRAYCOUNT(ChunkOffset);
754 for (
int RadiusOffset = 1; RadiusOffset < (a_MaxSpawnRadius * 2); ++RadiusOffset)
756 for (
int SearchGridIndex = 0; SearchGridIndex < PerRadiSearchCount; ++SearchGridIndex)
758 const Vector3i PotentialSpawn = BiomeOffset + (ChunkOffset[SearchGridIndex] * RadiusOffset);
760 if (
CanSpawnAt(PotentialSpawn.
x, SpawnY, PotentialSpawn.
z))
762 SetSpawn(PotentialSpawn.
x, SpawnY, PotentialSpawn.
z);
786 static const BLOCKTYPE ValidSpawnBlocks[] =
795 static const int ValidSpawnBlocksCount =
ARRAYCOUNT(ValidSpawnBlocks);
798 static const int HighestSpawnPoint =
GetHeight(a_X, a_Z) + 2;
799 static const int LowestSpawnPoint = HighestSpawnPoint / 2;
801 for (
int PotentialY = HighestSpawnPoint; PotentialY > LowestSpawnPoint; --PotentialY)
828 bool ValidSpawnBlock =
false;
829 for (
int BlockIndex = 0; BlockIndex < ValidSpawnBlocksCount; ++BlockIndex)
831 ValidSpawnBlock |= (ValidSpawnBlocks[BlockIndex] == FloorBlock);
834 if (!ValidSpawnBlock)
844 a_Y = PotentialY - 1;
864 constexpr std::array<Vector3i, 8> SurroundingCoords =
878 for (
const auto & Offset : SurroundingCoords)
922 case dimOverworld: DefaultMonsters =
"bat, cavespider, chicken, cow, creeper, guardian, horse, mooshroom, ocelot, pig, rabbit, sheep, silverfish, skeleton, slime, spider, squid, wolf, zombie";
break;
923 case dimNether: DefaultMonsters =
"blaze, ghast, magmacube, witherskeleton, zombiepigman";
break;
924 case dimEnd: DefaultMonsters =
"";
break;
937 for (AStringVector::const_iterator itr = SplitList.begin(), end = SplitList.end(); itr != end; ++itr)
943 LOGD(
"Allowed mob: %s", itr->c_str());
947 LOG(
"World \"%s\": Unknown mob type: %s",
m_WorldName.c_str(), itr->c_str());
1002 void cWorld::Tick(std::chrono::milliseconds a_Dt, std::chrono::milliseconds a_LastTickDurationMSec)
1033 Player->GetClientHandle()->ProcessProtocolIn();
1050 Player->GetClientHandle()->ProcessProtocolOut();
1127 for (
size_t i = 0; i <
ARRAYCOUNT(AllFamilies); i++)
1139 if (
Spawner.CanSpawnAnything())
1143 for (
auto & Mob :
Spawner.getSpawned())
1153 if (!a_Entity.
IsMob())
1162 auto & Monster =
static_cast<cMonster &
>(a_Entity);
1163 ASSERT(Monster.GetParentChunk() !=
nullptr);
1166 if (Monster.GetParentChunk()->HasAnyClients())
1168 Monster.Tick(a_Dt, *(a_Entity.GetParentChunk()));
1171 else if ((Monster.GetMobFamily() == cMonster::eFamily::mfHostile) && !Monster.WasLastTargetAPlayer())
1173 if (Monster.GetMobType() != eMonsterType::mtWolf)
1179 auto & Wolf = static_cast<cWolf &>(Monster);
1180 if (!Wolf.IsAngry() && !Wolf.IsTame())
1204 for (
auto &
Item : SetChunkDataQueue)
1207 const auto Chunk =
Item.Chunk;
1215 Chunk.m_ChunkX, Chunk.m_ChunkZ,
1216 [&ChunkSender](
cChunk & a_Chunk)
1218 if (a_Chunk.HasAnyClients())
1220 ChunkSender.QueueSendChunkTo(
1223 cChunkSender::Priority::Medium,
1224 a_Chunk.GetAllClients()
1249 for (
auto &
Item: EntitiesToAdd)
1251 const auto Entity =
Item.first.get();
1253 if (Entity->IsPlayer())
1255 const auto Player =
static_cast<cPlayer *
>(Entity);
1257 LOGD(
"Adding player %s to world \"%s\".", Player->GetName().c_str(),
m_WorldName.c_str());
1265 if (
const auto OldWorld =
Item.second; OldWorld !=
nullptr)
1288 auto MoveBeginIterator = std::partition(
m_Tasks.begin(),
m_Tasks.end(), [
this](
const decltype(
m_Tasks)::value_type & a_Task)
1296 std::make_move_iterator(MoveBeginIterator),
1297 std::make_move_iterator(
m_Tasks.end())
1303 for (
const auto & Task : Tasks)
1315 const auto TIME_SUNSET = 12000_tick;
1316 const auto TIME_NIGHT_START = 13187_tick;
1317 const auto TIME_NIGHT_END = 22812_tick;
1318 const auto TIME_SUNRISE = 23999_tick;
1319 const auto TIME_SPAWN_DIVISOR = 148_tick;
1322 if (TempTime <= TIME_SUNSET)
1326 else if (TempTime <= TIME_NIGHT_START)
1330 else if (TempTime <= TIME_NIGHT_END)
1374 if (!
cPluginManager::Get()->CallHookExploding(*
this, a_ExplosionSize, a_CanCauseFire, a_BlockX, a_BlockY, a_BlockZ, a_Source, a_SourceData) && (a_ExplosionSize > 0))
1388 Entity =
static_cast<const cEntity *
>(a_SourceData);
1424 const auto & Sign =
static_cast<cSignEntity &
>(a_BlockEntity);
1426 a_Line2 = Sign.GetLine(1);
1427 a_Line3 = Sign.GetLine(2);
1428 a_Line4 = Sign.GetLine(3);
1477 auto WorldAge =
static_cast<int>(
m_WorldTickAge.count() & 0xffffffff);
1479 switch (SaplingMeta & 0x07)
1507 Other.insert(Other.begin(), Logs.begin(), Logs.end());
1518 bool IsLarge =
true;
1519 a_Meta = a_Meta & 0x07;
1522 for (
int x = 0; x < 2; ++x)
1524 for (
int z = 0; z < 2; ++z)
1529 IsLarge = IsLarge && (type ==
E_BLOCK_SAPLING) && ((meta & 0x07) == a_Meta);
1540 for (
int x = 0; x < 2; ++x)
1542 for (
int z = 0; z > -2; --z)
1547 IsLarge = IsLarge && (type ==
E_BLOCK_SAPLING) && ((meta & 0x07) == a_Meta);
1559 for (
int x = 0; x > -2; --x)
1561 for (
int z = 0; z > -2; --z)
1566 IsLarge = IsLarge && (type ==
E_BLOCK_SAPLING) && ((meta & 0x07) == a_Meta);
1579 for (
int x = 0; x > -2; --x)
1581 for (
int z = 0; z < 2; ++z)
1586 IsLarge = IsLarge && (type ==
E_BLOCK_SAPLING) && ((meta & 0x07) == a_Meta);
1606 auto seq =
static_cast<int>(
m_WorldTickAge.count() & 0xffffffff);
1608 Other.insert(Other.begin(), Logs.begin(), Logs.end());
1623 for (sSetBlockVector::const_iterator itr = a_Blocks.begin(); itr != a_Blocks.end(); ++itr)
1638 for (sSetBlockVector::const_iterator itr = b2.begin(); itr != b2.end(); ++itr)
1640 switch (itr->m_BlockType)
1710 std::min(a_Area.
p1.
x, a_Area.
p2.
x), std::max(a_Area.
p1.
x, a_Area.
p2.
x),
1711 std::min(a_Area.
p1.
z, a_Area.
p2.
z), std::max(a_Area.
p1.
z, a_Area.
p2.
z),
1795 auto microX = random.RandReal<
double>(0, 1);
1796 auto microZ = random.RandReal<
double>(0, 1);
1807 a_FlyAwaySpeed /= 100;
1808 for (cItems::const_iterator itr = a_Pickups.begin(); itr != a_Pickups.end(); ++itr)
1816 float SpeedX =
static_cast<float>(a_FlyAwaySpeed * Random.RandInt(-10, 10));
1817 float SpeedY =
static_cast<float>(a_FlyAwaySpeed * Random.RandInt(40, 50));
1818 float SpeedZ =
static_cast<float>(a_FlyAwaySpeed * Random.RandInt(-10, 10));
1820 auto Pickup = std::make_unique<cPickup>(a_Pos, *itr, a_IsPlayerCreated,
Vector3f{SpeedX, SpeedY, SpeedZ});
1821 auto PickupPtr = Pickup.get();
1822 PickupPtr->Initialize(std::move(Pickup), *
this);
1832 for (cItems::const_iterator itr = a_Pickups.begin(); itr != a_Pickups.end(); ++itr)
1839 auto pickup = std::make_unique<cPickup>(a_Pos, *itr, a_IsPlayerCreated, a_Speed);
1840 auto pickupPtr = pickup.get();
1841 pickupPtr->Initialize(std::move(pickup), *
this);
1851 auto pickup = std::make_unique<cPickup>(a_Pos, a_Item,
false, a_Speed, a_LifetimeTicks, a_CanCombine);
1852 auto pickupPtr = pickup.get();
1853 if (!pickupPtr->Initialize(std::move(pickup), *
this))
1857 return pickupPtr->GetUniqueID();
1866 auto fallingBlock = std::make_unique<cFallingBlock>(a_Pos, a_BlockType, a_BlockMeta);
1867 auto fallingBlockPtr = fallingBlock.get();
1868 auto ID = fallingBlock->GetUniqueID();
1869 if (!fallingBlockPtr->Initialize(std::move(fallingBlock), *
this))
1884 LOGWARNING(
"%s: Attempting to create an experience orb with non-positive reward!", __FUNCTION__);
1888 auto expOrb = std::make_unique<cExpOrb>(a_Pos, a_Reward);
1889 auto expOrbPtr = expOrb.get();
1890 if (!expOrbPtr->Initialize(std::move(expOrb), *
this))
1894 return expOrbPtr->GetUniqueID();
1903 std::vector<UInt32> OrbsID;
1907 LOGWARNING(
"%s: Attempting to create an experience orb with non-positive reward!", __FUNCTION__);
1914 float SpeedLimit =
static_cast<float>((Rewards.size() / 2) + 5);
1915 if (SpeedLimit > 10)
1921 for (
auto Reward : Rewards)
1923 auto ExpOrb = std::make_unique<cExpOrb>(a_Pos, Reward);
1924 auto ExpOrbPtr = ExpOrb.get();
1925 double SpeedX = Random.RandReal(-SpeedLimit, SpeedLimit);
1926 double SpeedY = Random.RandReal(0.5);
1927 double SpeedZ = Random.RandReal(-SpeedLimit, SpeedLimit);
1928 ExpOrbPtr->SetSpeed(SpeedX, SpeedY, SpeedZ);
1930 UInt32 Id = ExpOrbPtr->GetUniqueID();
1931 if (ExpOrbPtr->Initialize(std::move(ExpOrb), *
this))
1933 OrbsID.push_back(Id);
1946 std::unique_ptr<cMinecart>
Minecart;
1947 switch (a_MinecartType)
1949 case E_ITEM_MINECART:
Minecart = std::make_unique<cRideableMinecart> (a_Pos, a_Content, a_BlockHeight);
break;
1961 if (!MinecartPtr->Initialize(std::move(
Minecart), *
this))
1965 return MinecartPtr->GetUniqueID();
1974 auto Boat = std::make_unique<cBoat>(a_Pos, a_Material);
1975 auto BoatPtr = Boat.get();
1976 if (!BoatPtr->Initialize(std::move(Boat), *
this))
1980 return BoatPtr->GetUniqueID();
1989 auto TNT = std::make_unique<cTNTEntity>(a_Pos, a_FuseTicks);
1990 auto TNTPtr =
TNT.get();
1991 if (!TNTPtr->Initialize(std::move(
TNT), *
this))
1996 if (a_ShouldPlayFuseSound)
2003 a_InitialVelocityCoeff * Random.RandReal(-0.5f, 0.5f),
2004 a_InitialVelocityCoeff * 2,
2005 a_InitialVelocityCoeff * Random.RandReal(-0.5f, 0.5f)
2007 return TNTPtr->GetUniqueID();
2016 auto EnderCrystal = std::make_unique<cEnderCrystal>(a_Pos, a_ShowBottom);
2017 auto EnderCrystalPtr = EnderCrystal.get();
2018 if (!EnderCrystalPtr->Initialize(std::move(EnderCrystal), *
this))
2022 return EnderCrystalPtr->GetUniqueID();
2035 SetBlock(a_Position, a_BlockType, a_BlockMeta);
2079 if (!
DigBlock(a_BlockPos, a_Digger))
2176 int a_ChunkX,
int a_ChunkZ,
2258 if (Player->IsTicking() && a_Callback(*Player))
2276 if (Player->IsTicking() && (
NoCaseCompare(Player->GetName(), a_PlayerName) == 0))
2278 a_Callback(*Player);
2291 cPlayer * BestMatch =
nullptr;
2292 size_t BestRating = 0;
2293 size_t NameLength = a_PlayerNameHint.length();
2298 if (!Player->IsTicking())
2303 if (Rating >= BestRating)
2306 BestRating = Rating;
2308 if (Rating == NameLength)
2314 if (BestMatch !=
nullptr)
2316 return a_Callback(*BestMatch);
2330 if (Player->IsTicking() && (Player->GetUUID() == a_PlayerUUID))
2332 return a_Callback(*Player);
2344 double ClosestDistance = a_RangeLimit;
2345 cPlayer * ClosestPlayer =
nullptr;
2350 if (!Player->IsTicking())
2355 if (a_IgnoreSpectator && Player->IsGameModeSpectator())
2360 Vector3f Pos = Player->GetPosition();
2361 double Distance = (Pos - a_Pos).Length();
2371 a_CheckLineOfSight &&
2379 ClosestPlayer = Player;
2384 return a_Callback(*ClosestPlayer);
2402 if (!Player->GetClientHandle()->IsDestroyed())
2457 if (
Item.first->GetUniqueID() == a_UniqueID)
2459 a_Callback(*
Item.first);
2555 if (
cRoot::Get()->GetPluginManager()->CallHookUpdatingSign(*
this, a_BlockPos, Line1, Line2, Line3, Line4, a_Player))
2612 return (Meta & 0x4) > 0;
2629 bool IsOpen = (Meta & 0x4) != 0;
2630 if (a_Open != IsOpen)
2632 SetBlockMeta({ a_BlockX, a_BlockY, a_BlockZ }, Meta ^ 0x4);
2723 m_Tasks.emplace_back(0, std::move(a_Task));
2732 const auto TargetTick = a_DelayTicks +
m_WorldAge;
2737 m_Tasks.emplace_back(TargetTick, std::move(a_Task));
2761 const auto Player =
static_cast<cPlayer *
>(&a_Entity);
2762 LOGD(
"Removing player %s from world \"%s\"", Player->GetName().c_str(),
m_WorldName.c_str());
2768 if (Entity !=
nullptr)
2770 Entity->OnRemoveFromWorld(*
this);
2777 [&a_Entity](
const auto &
Item)
2779 return (Item.first.get() == &a_Entity);
2785 Entity = std::move(itr->first);
2836 Block->TicksToWait -= 1;
2837 if (
Block->TicksToWait <= 0)
2857 Block->X = a_BlockX;
2858 Block->Y = a_BlockY;
2859 Block->Z = a_BlockZ;
2860 Block->TicksToWait = a_TicksToWait;
2886 if (Monster ==
nullptr)
2890 Monster->SetPosition(a_PosX, a_PosY, a_PosZ);
2894 Monster->SetAge(-1);
2906 ASSERT(a_Monster !=
nullptr);
2909 a_Monster->SetHealth(a_Monster->GetMaxHealth());
2917 auto & Monster = *a_Monster;
2920 if (!Monster.Initialize(std::move(a_Monster), *
this))
2927 return Monster.GetUniqueID();
2937 if (Projectile ==
nullptr)
2942 auto ProjectilePtr = Projectile.get();
2943 if (!ProjectilePtr->Initialize(std::move(Projectile), *
this))
2948 return ProjectilePtr->GetUniqueID();
2957 return CreateProjectile({a_PosX, a_PosY, a_PosZ}, a_Kind, a_Creator, a_Item, a_Speed);
2975 typedef std::pair<AString::size_type, AString> pair_t;
2976 size_t LastSpace = a_Text.find_last_of(
" ");
2977 AString LastWord = a_Text.substr(LastSpace + 1, a_Text.length());
2979 if (LastWord.empty())
2984 std::vector<pair_t> UsernamesByWeight;
2989 AString PlayerName = Player->HasCustomName() ? Player->GetCustomName() : Player->GetName();
2992 if (Found == AString::npos)
2997 UsernamesByWeight.push_back(std::make_pair(Found, PlayerName));
3001 std::sort(UsernamesByWeight.begin(), UsernamesByWeight.end());
3012 a_Results.reserve(UsernamesByWeight.size());
3013 for (std::vector<pair_t>::const_iterator itr = UsernamesByWeight.begin(); itr != UsernamesByWeight.end(); ++itr)
3015 a_Results.push_back(itr->second);
3034 AString SimulatorName = a_IniFile.
GetValueSet(
"Physics",
"RedstoneSimulator",
"Incremental");
3036 if (SimulatorName.empty())
3038 LOGWARNING(
"[Physics] RedstoneSimulator not present or empty in %s, using the default of \"Incremental\".",
GetIniFileName().c_str());
3039 SimulatorName =
"Incremental";
3054 LOGWARNING(
"[Physics] Unknown RedstoneSimulator \"%s\" in %s, using the default of \"Incremental\".", SimulatorName.c_str(),
GetIniFileName().c_str());
3070 Printf(SimulatorNameKey,
"%sSimulator", a_FluidName);
3072 Printf(SimulatorSectionName,
"%sSimulator", a_FluidName);
3074 bool IsWater = (strcmp(a_FluidName,
"Water") == 0);
3076 AString SimulatorName = a_IniFile.
GetValueSet(
"Physics", SimulatorNameKey, DefaultSimulatorName);
3077 if (SimulatorName.empty())
3079 LOGWARNING(
"[Physics] %s not present or empty in %s, using the default of \"%s\".", SimulatorNameKey.c_str(),
GetIniFileName().c_str(), DefaultSimulatorName.c_str());
3080 SimulatorName = DefaultSimulatorName;
3103 int TickDelay = a_IniFile.
GetValueSetI(SimulatorSectionName,
"TickDelay",
IsWater ? 5 : 30);
3104 int NumNeighborsForSource = a_IniFile.
GetValueSetI(SimulatorSectionName,
"NumNeighborsForSource",
IsWater ? 2 : -1);
3106 if ((Falloff > 15) || (Falloff < 0))
3108 LOGWARNING(
"Falloff for %s simulator is out of range, assuming default of %d", a_FluidName,
IsWater ? 1 : 2);
3123 LOGWARNING(
"%s [Physics]:%s specifies an unknown simulator, using the default \"Vanilla\".",
GetIniFileName().c_str(), SimulatorNameKey.c_str());
3156 Data.BlockData.SetAll(a_ChunkDesc.
GetBlockTypes(), BlockMetas);
3161 Data.Entities = std::move(a_ChunkDesc.
GetEntities());
3164 Data.IsLightValid =
false;
3167 m_World->QueueSetChunkData(std::move(Data));
std::enable_if< std::is_arithmetic< T >::value, C >::type FloorC(T a_Value)
Floors a value, then casts it to C (an int by default).
bool ForEachBlockEntityInChunk(int a_ChunkX, int a_ChunkZ, cBlockEntityCallback a_Callback)
Calls the callback for each block entity in the specified chunk.
const AString & GetIniFileName(void) const
Returns the name of the world.ini file used by this world.
void Initialize(cWorld &a_World, const AString &a_StorageSchemaName, int a_StorageCompressionFactor)
Initializes the storage schemas, ready to be started.
void SetChunkAlwaysTicked(int a_ChunkX, int a_ChunkZ, bool a_AlwaysTicked)
Increments (a_AlwaysTicked == true) or decrements (false) the m_AlwaysTicked counter for the specifie...
bool TryGetHeight(int a_BlockX, int a_BlockZ, int &a_Height)
virtual bool IsChunkValid(cChunkCoords a_Coords) override
Called just before the chunk generation is started, to verify that it hasn't been generated in the me...
void MarkChunkRegenerating(int a_ChunkX, int a_ChunkZ)
Marks the chunk as being regenerated - all its clients want that chunk again (used by cWorld::Regener...
void RemoveClientFromChunks(cClientHandle *a_Client)
Removes the client from all chunks it is present in.
std::chrono::milliseconds m_WorldAge
The age of the world.
std::vector< BlockTickQueueItem * > m_BlockTickQueue
virtual void BroadcastWeather(eWeather a_Weather, const cClientHandle *a_Exclude=nullptr) override
void UntrackCriticalSection(cCriticalSection &a_CS)
Removes the CS from the tracking.
void SaveMapData(void)
Saves the map data to the disk.
UInt32 SpawnMobFinalize(std::unique_ptr< cMonster > a_Monster)
Wraps cEntity::Initialize, doing Monster-specific things before spawning the monster.
bool m_bCommandBlocksEnabled
Whether command blocks are enabled or not.
void GetChunkStats(int &a_NumValid, int &a_NumDirty, int &a_NumInLightingQueue)
Returns the number of chunks loaded and dirty, and in the lighting queue.
@ E_ITEM_FURNACE_MINECART
bool IsBlockDirectlyWatered(int a_BlockX, int a_BlockY, int a_BlockZ)
std::vector< sSetBlock > sSetBlockVector
bool IsPlayer(void) const
IntType RandInt(IntType a_Min, IntType a_Max)
Return a random IntType in the range [a_Min, a_Max].
bool AddChunkClient(int a_ChunkX, int a_ChunkZ, cClientHandle *a_Client)
Adds client to a chunk, if not already present; returns true if added, false if present.
void GenerateRandomSpawn(int a_MaxSpawnRadius)
Generates a random spawnpoint on solid land by walking chunks and finding their biomes.
int GetValueSetI(const AString &keyname, const AString &valuename, const int defValue=0) override
std::vector< std::pair< OwnedEntity, cWorld * > > m_EntitiesToAdd
List of entities that are scheduled for adding, waiting for the Tick thread to add them.
void SetBlockMeta(Vector3i a_BlockPos, NIBBLETYPE a_BlockMeta)
Sets the meta for the specified block, while keeping the blocktype.
Constants used throughout the code, useful typedefs and utility functions.
eExplosionSource
The source of an explosion.
size_t GetNumUnusedDirtyChunks(void) const
Returns the number of unused dirty chunks.
void CastThunderbolt(Vector3i a_Block)
Casts a thunderbolt at the specified coords.
virtual std::vector< UInt32 > SpawnSplitExperienceOrbs(Vector3d a_Pos, int a_Reward) override
Spawns experience orbs of the specified total value at the given location.
void PlaceBlock(const Vector3i a_Position, const BLOCKTYPE a_BlockType, const NIBBLETYPE a_BlockMeta)
Replaces the specified block with another, and calls the OnPlaced block handler.
std::unique_ptr< cFireSimulator > m_FireSimulator
void QueueLightChunk(int a_ChunkX, int a_ChunkZ, std::unique_ptr< cChunkCoordCallback > a_Callback={})
Queues a chunk for lighting; a_Callback is called after the chunk is lighted.
UInt32 SpawnEnderCrystal(Vector3d a_Pos, bool a_ShowBottom)
Spawns a new ender crystal at the specified block coords.
bool ForEachEntity(cEntityCallback a_Callback)
Calls the callback for each entity in the entire world; returns true if all entities processed,...
std::set< eMonsterType > m_AllowedMobs
void ChunkLoadFailed(int a_ChunkX, int a_ChunkZ)
Marks the chunk as failed-to-load:
bool SetAreaBiome(int a_MinX, int a_MaxX, int a_MinZ, int a_MaxZ, EMCSBiome a_Biome)
Sets the biome at the area.
bool HasChunkAnyClients(int a_ChunkX, int a_ChunkZ) const
std::vector< cPlayer * > m_Players
void CollectPickupsByEntity(cEntity &a_Entity)
bool GetBlockInfo(Vector3i, BLOCKTYPE &a_BlockType, NIBBLETYPE &a_Meta, NIBBLETYPE &a_SkyLight, NIBBLETYPE &a_BlockLight) const
size_t GetNumUnusedDirtyChunks(void) const
Returns the number of unused dirty chunks.
virtual void Execute(void) override
This function, overloaded by the descendants, is called in the new thread.
virtual bool ForEachChunkInRect(int a_MinChunkX, int a_MaxChunkX, int a_MinChunkZ, int a_MaxChunkZ, cChunkDataCallback &a_Callback) override
Calls the callback for each chunk in the coords specified (all cords are inclusive).
void WakeUpSimulators(Vector3i a_Block)
Wakes up simulators for the specified block.
bool GetSignLines(int a_BlockX, int a_BlockY, int a_BlockZ, AString &a_Line1, AString &a_Line2, AString &a_Line3, AString &a_Line4)
Retrieves the test on the sign at the specified coords; returns false if there's no sign at those coo...
bool CallHookChunkGenerated(cWorld &a_World, int a_ChunkX, int a_ChunkZ, cChunkDesc *a_ChunkDesc)
void QueueSaveAllChunks(void)
Queues a task to save all chunks onto the tick thread.
int GetTickRandomNumber(int a_Range)
Returns a random number in range [0 .
void MarkChunkSaving(int a_ChunkX, int a_ChunkZ)
bool CallHookUpdatedSign(cWorld &a_World, Vector3i a_BlockPos, const AString &a_Line1, const AString &a_Line2, const AString &a_Line3, const AString &a_Line4, cPlayer *a_Player)
void SetNextBlockToTick(const Vector3i a_BlockPos)
Causes the specified block to be ticked on the next Tick() call.
Represents two sets of coords, minimum and maximum for each direction.
cForEachChunkProvider * GetFECProvider(cWorld *a_World)
void Stop(cDeadlockDetect &a_DeadlockDetect)
Stops threads that belong to this world (part of deinit).
std::unique_ptr< cEntity > OwnedEntity
bool SetAreaBiome(int a_MinX, int a_MaxX, int a_MinZ, int a_MaxZ, EMCSBiome a_Biome)
Sets the biome at the area.
cRedstoneSimulator * InitializeRedstoneSimulator(cIniFile &a_IniFile)
Creates a new redstone simulator.
eShrapnelLevel m_TNTShrapnelLevel
The level of DoExplosionAt() projecting random affected blocks as FallingBlock entities See the eShra...
AString StrToLower(const AString &s)
Returns a lower-cased copy of the string.
void GetChunkStats(int &a_NumChunksValid, int &a_NumChunksDirty) const
Returns the number of valid chunks and the number of dirty chunks.
void InitializeAndLoadMobSpawningValues(cIniFile &a_IniFile)
Sets mob spawning values if nonexistant to their dimension specific defaults.
virtual cTickTimeLong GetWorldAge(void) const override
bool IsChunkQueued(int a_ChunkX, int a_ChunkZ) const
Returns true iff the chunk is in the loader / generator queue.
int GetDefaultWeatherInterval(eWeather a_Weather) const
Returns the default weather interval for the specific weather type.
bool CanSpawnAt(int a_X, int &a_Y, int a_Z)
Can the specified coordinates be used as a spawn point? Returns true if spawn position is valid and s...
virtual void SendBlockTo(int a_X, int a_Y, int a_Z, const cPlayer &a_Player) override
Sends the block at the specified coords to the player.
virtual void BroadcastSoundParticleEffect(const EffectID a_EffectID, Vector3i a_SrcPos, int a_Data, const cClientHandle *a_Exclude=nullptr) override
virtual UInt32 SpawnMob(double a_PosX, double a_PosY, double a_PosZ, eMonsterType a_MonsterType, bool a_Baby=false) override
Spawns a mob of the specified type.
bool IsChunkQueued(int a_ChunkX, int a_ChunkZ) const
Returns true iff the chunk is in the loader / generator queue.
static std::unique_ptr< cProjectileEntity > Create(eKind a_Kind, cEntity *a_Creator, Vector3d a_Pos, const cItem *a_Item, const Vector3d *a_Speed=nullptr)
Creates a new instance of the specified projectile entity.
bool AddChunkClient(int a_ChunkX, int a_ChunkZ, cClientHandle *a_Client)
Adds client to a chunk, if not already present; returns true if added, false if present.
cChunkDef::HeightMap & GetHeightMap(void)
Utilities to allow casting a cWorld to one of its interfaces without including World....
void TickQueuedBlocks(void)
Processes the blocks queued for ticking with a delay (m_BlockTickQueue[])
void SetBlockMeta(Vector3i a_BlockPos, NIBBLETYPE a_MetaData)
Sets the meta for the specified block, while keeping the blocktype.
virtual cTickTime GetTimeOfDay(void) const override
void TickWeather(float a_Dt)
Handles the weather in each tick.
virtual void DoExplosionAt(double a_ExplosionSize, double a_BlockX, double a_BlockY, double a_BlockZ, bool a_CanCauseFire, eExplosionSource a_Source, void *a_SourceData) override
Does an explosion with the specified strength at the specified coordinates.
static const int DEFAULT_VIEW_DISTANCE
void SetChunkAlwaysTicked(int a_ChunkX, int a_ChunkZ, bool a_AlwaysTicked=true)
Increments (a_AlwaysTicked == true) or decrements (false) the m_AlwaysTicked counter for the specifie...
bool RandBool(double a_TrueProbability=0.5)
Return a random bool with the given probability of being true.
bool IsSavingEnabled(void) const
Get whether saving chunks is enabled.
std::vector< BlockTickQueueItem * > m_BlockTickQueueCopy
This class is used to collect information, for each Mob, what is the distance of the closest player i...
cCriticalSection m_CSTasks
Guards the m_Tasks.
int m_MaxNetherPortalHeight
cBlockEntities & GetBlockEntities(void)
void SpawnMobs(cMobSpawner &a_MobSpawner)
Try to Spawn Monsters inside all Chunks.
virtual void WakeUpSimulators(Vector3i a_Block) override
Wakes up the simulators for the specified block.
void QueueSendChunkTo(int a_ChunkX, int a_ChunkZ, Priority a_Priority, cClientHandle *a_Client)
Queues a chunk to be sent to a specific client.
bool IsChunkLighted(int a_ChunkX, int a_ChunkZ)
size_t GetPlayerCount() const
Returns the number of players currently in this world.
virtual ~cWorld() override
cBroadcastInterface * GetBroadcastInterface(cWorld *a_World)
UInt32 SpawnPrimedTNT(double a_X, double a_Y, double a_Z, int a_FuseTimeInSec=80, double a_InitialVelocityCoeff=1, bool a_ShouldPlayFuseSound=true)
bool SetValueI(const AString &a_KeyName, const AString &a_ValueName, const int a_Value, const bool a_CreateIfNotExists=true) override
bool m_VillagersShouldHarvestCrops
bool IsValidItem(int a_ItemType)
Returns true if the specified item type is valid (known).
cChunkGeneratorCallbacks(cWorld &a_World)
int GrowPlantAt(Vector3i a_BlockPos, int a_NumStages=1)
Grows the plant at the specified position by at most a_NumStages.
void SendPlayerList(cPlayer *a_DestPlayer)
int NoCaseCompare(const AString &s1, const AString &s2)
Case-insensitive string comparison.
void AddHeaderComment(const AString &comment)
Adds a header comment.
virtual void BroadcastTimeUpdate(const cClientHandle *a_Exclude=nullptr) override
void CollectPickupsByEntity(cEntity &a_Entity)
Makes the specified entity collect all the pickups around them.
void SendPlayerListAddPlayer(const cPlayer &a_Player)
bool CallHookWeatherChanged(cWorld &a_World)
Vector3< T > addedXZ(T a_AddX, T a_AddZ) const
Returns a copy of this vector moved by the specified amount on the X and Z axes.
virtual bool HasChunkAnyClients(cChunkCoords a_Coords) override
Called when the generator is overloaded to skip chunks that are no longer needed.
size_t GetNumChunks(void) const
void RegenerateChunk(int a_ChunkX, int a_ChunkZ)
Regenerate the given chunk.
cItems PickupsFromBlock(Vector3i a_BlockPos, const cEntity *a_Digger=nullptr, const cItem *a_Tool=nullptr)
Returns all the pickups that would result if the a_Digger dug up the block at a_BlockPos using a_Tool...
void TickMaps(void)
Ticks each registered map.
static void BlockToChunk(int a_X, int a_Z, int &a_ChunkX, int &a_ChunkZ)
Converts absolute block coords to chunk coords:
virtual bool WriteBlockArea(cBlockArea &a_Area, int a_MinBlockX, int a_MinBlockY, int a_MinBlockZ, int a_DataTypes) override
Writes the block area into the specified coords.
int GrowPlantAt(Vector3i a_BlockPos, int a_NumStages=1)
Grows the plant at the specified position by at most a_NumStages.
#define CASE_TREE_ALLOWED_BLOCKS
std::unique_ptr< cSimulatorManager > m_SimulatorManager
eDimension StringToDimension(const AString &a_DimensionString)
Translates a dimension string to dimension enum.
unsigned int m_MaxPlayers
cTickTimeLong GetWorldTickAge() const
bool IsChunkValid(int a_ChunkX, int a_ChunkZ) const
Returns true iff the chunk is present and valid.
unsigned char NIBBLETYPE
The datatype used by nibbledata (meta, light, skylight)
void CompareChunkClients(int a_ChunkX1, int a_ChunkZ1, int a_ChunkX2, int a_ChunkZ2, cClientDiffCallback &a_Callback)
Compares clients of two chunks, calls the callback accordingly.
std::chrono::milliseconds m_WorldDate
The fully controllable age of the world.
int FindKey(const AString &keyname) const
Returns index of specified key, or noID if not found.
cTickThread(cWorld &a_World)
void SetMaxViewDistance(int a_MaxViewDistance)
eWeather ChooseNewWeather(void)
Chooses a reasonable transition from the current weather to a new weather.
virtual void CallHookChunkGenerating(cChunkDesc &a_ChunkDesc) override
Called when the chunk is about to be generated.
void QueueChunk(int a_ChunkX, int a_ChunkZ, std::unique_ptr< cChunkCoordCallback > a_CallbackAfter)
Queues the entire chunk for lighting.
bool CallHookEntityChangedWorld(cEntity &a_Entity, cWorld &a_World)
void SendChunkTo(int a_ChunkX, int a_ChunkZ, cChunkSender::Priority a_Priority, cClientHandle *a_Client)
Sends the chunk to the client specified, if the client doesn't have the chunk yet.
bool IsWeatherSunnyAt(int a_BlockX, int a_BlockZ) const
bool m_BroadcastDeathMessages
virtual eDimension GetDimension(void) const override
static cTickTime GetSpawnDelay(cMonster::eFamily a_MobFamily)
Returns the spawn delay (number of game ticks between spawn attempts) for the given mob family.
cEntityList & GetEntities(void)
bool m_bUseChatPrefixes
Whether prefixes such as [INFO] are prepended to SendMessageXXX() / BroadcastChatXXX() functions.
virtual bool IsChunkQueued(cChunkCoords a_Coords) override
Called to check whether the specified chunk is in the queued state.
int m_MaxNetherPortalWidth
static const int MIN_VIEW_DISTANCE
static const cBlockHandler & For(BLOCKTYPE a_BlockType)
cChunkDef::BiomeMap & GetBiomeMap(void)
bool GetChunkData(cChunkCoords a_Coords, cChunkDataCallback &a_Callback) const
Calls the callback with the chunk's data, if available (with ChunkCS locked).
bool m_bFarmlandTramplingEnabled
void AddEntity(OwnedEntity a_Entity)
Adds the entity to its appropriate chunk, takes ownership of the entity pointer.
void ChunkLighted(int a_ChunkX, int a_ChunkZ, const cChunkDef::BlockNibbles &a_BlockLight, const cChunkDef::BlockNibbles &a_SkyLight)
int m_StorageCompressionFactor
cFluidSimulator * m_WaterSimulator
AString GetLinkedOverworldName(void) const
std::chrono::milliseconds m_LastChunkCheck
static bool IsWater(BLOCKTYPE a_BlockType)
bool WriteBlockArea(cBlockArea &a_Area, int a_MinBlockX, int a_MinBlockY, int a_MinBlockZ, int a_DataTypes)
Writes the block area into the specified coords.
void TickQueuedTasks(void)
Executes all tasks queued onto the tick thread.
bool m_IsDaylightCycleEnabled
cRedstoneSimulator * m_RedstoneSimulator
virtual void BroadcastSoundEffect(const AString &a_SoundName, Vector3d a_Position, float a_Volume, float a_Pitch, const cClientHandle *a_Exclude=nullptr) override
cChunkGeneratorCallbacks m_GeneratorCallbacks
The callbacks that the ChunkGenerator uses to store new chunks and interface to plugins.
void GenerateChunk(int a_ChunkX, int a_ChunkZ)
Generates the given chunk.
virtual void BroadcastPlayerListUpdatePing() override
void CompareChunkClients(int a_ChunkX1, int a_ChunkZ1, int a_ChunkX2, int a_ChunkZ2, cClientDiffCallback &a_Callback)
Compares clients of two chunks, calls the callback accordingly.
void MarkChunkDirty(int a_ChunkX, int a_ChunkZ)
EMCSBiome GetBiomeAt(int a_BlockX, int a_BlockZ) const
Returns the biome at the specified coords.
void Simulate(float a_Dt)
Called in each tick, a_Dt is the time passed since the last tick, in msec.
void Start(void)
Starts the thread; returns without waiting for the actual start.
void SetWeather(eWeather a_NewWeather)
Sets the specified weather; resets weather interval; asks and notifies plugins of the change.
#define ARRAYCOUNT(X)
Evaluates to the number of elements in an array (compile-time!)
bool ForEachEntityInChunk(int a_ChunkX, int a_ChunkZ, cEntityCallback a_Callback)
Calls the callback for each entity in the specified chunk; returns true if all entities processed,...
eMonsterType
Identifies individual monster type.
cChunkDef::BlockTypes & GetBlockTypes(void)
AString m_DataPath
The path to the root directory for the world files.
@ E_META_SAPLING_DARK_OAK
bool IsWeatherWetAt(int a_BlockX, int a_BlockZ) const
bool Initialize(cPluginInterface &a_PluginInterface, cChunkSink &a_ChunkSink, cIniFile &a_IniFile)
Read settings from the ini file and initialize in preperation for being started.
bool GetBlockTypeMeta(Vector3i a_BlockPos, BLOCKTYPE &a_BlockType, NIBBLETYPE &a_BlockMeta) const
void ChangeWeather(void)
Forces a weather change in the next game tick.
T Clamp(T a_Value, T a_Min, T a_Max)
Clamp X to the specified range.
void Start()
Starts threads that belong to this world.
void TickBlock(const Vector3i a_BlockPos)
Ticks a single block.
void PrepareChunk(int a_ChunkX, int a_ChunkZ, std::unique_ptr< cChunkCoordCallback > a_CallAfter={})
Queues the chunk for preparing - making sure that it's generated and lit.
eDimension m_Dimension
The dimension of the world, used by the client to provide correct lighting scheme.
std::unique_ptr< cSandSimulator > m_SandSimulator
void UnloadUnusedChunks(void)
Unloads all chunks immediately.
bool GetBlocks(sSetBlockVector &a_Blocks, bool a_ContinueOnFailure)
Retrieves block types and metas of the specified blocks.
UInt32 SpawnExperienceOrb(Vector3d a_Pos, int a_Reward)
Spawns an experience orb at the given location with the given reward.
Interface class used for comparing clients of two chunks.
AString GetValueSet(const AString &keyname, const AString &valuename, const AString &defValue="") override
Gets the value; if not found, write the default to the repository.
@ E_BLOCK_STATIONARY_WATER
size_t m_UnusedDirtyChunksCap
The maximum number of allowed unused dirty chunks for this world.
cFluidSimulator * InitializeFluidSimulator(cIniFile &a_IniFile, const char *a_FluidName, BLOCKTYPE a_SimulateBlock, BLOCKTYPE a_StationaryBlock)
Creates a new fluid simulator, loads its settings from the inifile (a_FluidName section)
cTickTimeLong m_WorldTickAge
The time since this world began, in ticks.
AStringVector StringSplitAndTrim(const AString &str, const AString &delim)
Split the string at any of the listed delimiters and trim each value.
void TrackCriticalSection(cCriticalSection &a_CS, const AString &a_Name)
Adds the critical section for tracking.
void FLOGWARNING(std::string_view a_Format, const Args &... args)
void GetJungleTreeImage(Vector3i a_BlockPos, cNoise &a_Noise, int a_Seq, sSetBlockVector &a_LogBlocks, sSetBlockVector &a_OtherBlocks, bool a_Large)
Fills a_LogBlocks and a_OtherBlocks (dirt & leaves) with the blocks required to form a random jungle ...
void LoadMapData(void)
Loads the map data from the disk.
void GenerateChunk(int a_ChunkX, int a_ChunkZ)
Queues the chunk for generating.
cWorld(const AString &a_WorldName, const AString &a_DataPath, cDeadlockDetect &a_DeadlockDetect, const AStringVector &a_WorldNames, eDimension a_Dimension=dimOverworld, const AString &a_LinkedOverworldName={})
Construct the world and read settings from its ini file.
bool CallHookSpawnedMonster(cWorld &a_World, cMonster &a_Monster)
bool DigBlock(Vector3i a_BlockPos, const cEntity *a_Digger=nullptr)
Replaces the specified block with air, and calls the OnBroken block handler.
void Kaboom(cWorld &a_World, const Vector3f a_Position, const int a_Power, const bool a_Fiery, const cEntity *const a_ExplodingEntity)
Creates an explosion of Power, centred at Position, with ability to set fires as provided.
bool SetSignLines(Vector3i a_BlockPos, const AString &a_Line1, const AString &a_Line2, const AString &a_Line3, const AString &a_Line4, cPlayer *a_Player=nullptr)
Sets the sign text, asking plugins for permission first.
bool DoWithPlayerByUUID(const cUUID &a_PlayerUUID, cPlayerListCallback a_Callback)
Finds the player over his uuid and calls the callback.
static bool IsValidHeight(Vector3i a_BlockPosition)
Validates a height-coordinate.
void InitializeSpawn(void)
bool SetTrapdoorOpen(int a_BlockX, int a_BlockY, int a_BlockZ, bool a_Open)
Set the state of a trapdoor.
static cPluginManager * Get(void)
Returns the instance of the Plugin Manager (there is only ever one)
MTRand & GetRandomProvider()
Returns the current thread's random number source.
bool SetBiomeAt(int a_BlockX, int a_BlockZ, EMCSBiome a_Biome)
Sets the biome at the specified coords.
size_t GetQueueLength(void)
OwnedEntity RemoveEntity(cEntity &a_Entity)
Removes the entity from its appropriate chunk Returns an owning reference to the found entity.
bool ForEachLoadedChunk(cFunctionRef< bool(int, int)> a_Callback) const
Calls the callback for each loaded chunk.
void SetBlock(Vector3i a_BlockPos, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta)
void Tick(std::chrono::milliseconds a_Dt)
cChunkMap * GetChunkMap(void)
bool GrowTreeByBiome(Vector3i a_BlockPos)
Grows a tree at the specified coords, based on the biome in the place.
bool IsBlockLiquid(BLOCKTYPE a_BlockType)
bool IsBlockWater(BLOCKTYPE a_BlockType)
std::chrono::milliseconds m_LastSave
void QueueSetChunkData(SetChunkData &&a_SetChunkData)
Puts the chunk data into a queue to be set into the chunkmap in the tick thread.
bool ForEachEntity(cEntityCallback a_Callback) const
Calls the callback for each entity in the entire world; returns true if all entities processed,...
Vector3< double > Vector3d
void SetNextBlockToTick(const Vector3i a_BlockPos)
Causes the specified block to be ticked on the next Tick() call.
void MarkChunkSaved(int a_ChunkX, int a_ChunkZ)
void PrepareChunk(int a_ChunkX, int a_ChunkZ, std::unique_ptr< cChunkCoordCallback > a_CallAfter={})
Queues the chunk for preparing - making sure that it's generated and lit.
int GetValueI(const AString &keyname, const AString &valuename, const int defValue=0) const
void RemoveChunkClient(int a_ChunkX, int a_ChunkZ, cClientHandle *a_Client)
Removes client from the chunk specified.
void QueueGenerateChunk(cChunkCoords a_Coords, bool a_ForceRegeneration, cChunkCoordCallback *a_Callback=nullptr)
Queues the chunk for generation If a-ForceGenerate is set, the chunk is regenerated even if the data ...
bool ForEachEntityInChunk(int a_ChunkX, int a_ChunkZ, cEntityCallback a_Callback)
Calls the callback for each entity in the specified chunk; returns true if all entities processed,...
static std::unique_ptr< cMonster > NewMonsterFromType(eMonsterType a_MobType)
Creates a new object of the specified mob.
BLOCKTYPE GetBlock(Vector3i a_BlockPos) const
Returns the block type at the specified position.
EMCSBiome
Biome IDs The first batch corresponds to the clientside biomes, used by MineCraft.
AString DimensionToString(eDimension a_Dimension)
Translates a dimension enum to dimension string.
bool HasChunkAnyClients(int a_ChunkX, int a_ChunkZ) const
static eMonsterType StringToMobType(const AString &a_MobTypeName)
Translates MobType string to the enum, mtInvalidType if not recognized.
bool IsChunkValid(int a_ChunkX, int a_ChunkZ) const
NIBBLETYPE GetBlockSkyLight(Vector3i a_BlockPos) const
int m_MinThunderStormTicks
void SpawnItemPickups(const cItems &a_Pickups, Vector3i a_BlockPos, double a_FlyAwaySpeed=1.0, bool a_IsPlayerCreated=false)
Spawns item pickups for each item in the list.
bool ForEachBlockEntityInChunk(int a_ChunkX, int a_ChunkZ, cBlockEntityCallback a_Callback)
Calls the callback for each block entity in the specified chunk; returns true if all block entities p...
cPluginManager * GetPluginManager(void)
bool m_BroadcastAchievementMessages
int m_MaxViewDistance
The maximum view distance that a player can have in this world.
void SendBlockEntity(int a_BlockX, int a_BlockY, int a_BlockZ, cClientHandle &a_Client)
If there is a block entity at the specified coords, sends it to the client specified.
void UnloadUnusedChunks(void)
bool m_IsSpawnExplicitlySet
void GetConiferTreeImage(Vector3i a_BlockPos, cNoise &a_Noise, int a_Seq, sSetBlockVector &a_LogBlocks, sSetBlockVector &a_OtherBlocks, bool a_Large)
Fills a_LogBlocks and a_OtherBlocks (dirt & leaves) with the blocks required to form a random conifer...
bool FindAndDoWithPlayer(const AString &a_PlayerNameHint, cPlayerListCallback a_Callback)
Finds a player from a partial or complete player name and calls the callback - case-insensitive.
AString m_LinkedNetherWorldName
Name of the nether world - where Nether portals should teleport.
EMCSBiome GetBiomeAt(int a_BlockX, int a_BlockZ)
Returns the biome at the specified coords.
cChunkSender m_ChunkSender
size_t RateCompareString(const AString &s1, const AString &s2)
Case-insensitive string comparison that returns a rating of equal-ness between [0 - s1....
bool DoWithPlayer(const AString &a_PlayerName, cPlayerListCallback a_Callback)
Calls the callback for the player of the given name; returns true if the player was found and the cal...
RAII for cCriticalSection - locks the CS on creation, unlocks on destruction.
void CompressBlockMetas(cChunkDef::BlockNibbles &a_DestMetas)
Compresses the metas from the BlockArea format (1 meta per byte) into regular format (2 metas per byt...
static void InitializeGeneratorDefaults(cIniFile &a_IniFile, eDimension a_Dimension)
If there's no particular sub-generator set in the INI file, adds the default one, based on the dimens...
bool SetCommandBlockCommand(int a_BlockX, int a_BlockY, int a_BlockZ, const AString &a_Command)
Sets the command block command.
bool GrowRipePlant(Vector3i a_BlockPos)
Grows the plant at the specified block to its ripe stage.
AString m_StorageSchema
Name of the storage schema used to load and save chunks.
static const int MAX_VIEW_DISTANCE
std::chrono::duration< signed int, std::ratio_multiply< std::chrono::milliseconds::period, std::ratio< 50 > >> cTickTime
virtual void OnBroken(cChunkInterface &a_ChunkInterface, cWorldInterface &a_WorldInterface, Vector3i a_BlockPos, BLOCKTYPE a_OldBlockType, NIBBLETYPE a_OldBlockMeta, const cEntity *a_Digger) const
Called after a block gets broken (replaced with air), by natural means.
virtual void OnPlaced(cChunkInterface &a_ChunkInterface, cWorldInterface &a_WorldInterface, Vector3i a_BlockPos, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta) const
Called by cWorld::SetBlock() after the block has been set.
UInt32 SpawnBoat(double a_X, double a_Y, double a_Z, cBoat::eMaterial a_Material)
AString GetLine(int a_Index) const
Retrieves individual line (zero-based index)
cItems PickupsFromBlock(Vector3i a_BlockPos, const cEntity *a_Digger, const cItem *a_Tool)
Returns all the pickups that would result if the a_Digger dug up the block at a_BlockPos using a_Tool...
void GetAppleTreeImage(Vector3i a_BlockPos, cNoise &a_Noise, int a_Seq, sSetBlockVector &a_LogBlocks, sSetBlockVector &a_OtherBlocks)
Fills a_LogBlocks and a_OtherBlocks (dirt & leaves) with the blocks required to form a random apple t...
cWorldInterface * GetWorldInterface(cWorld *a_World)
cChunkGeneratorThread m_Generator
The thread responsible for generating chunks.
std::vector< SetChunkData > m_SetChunkDataQueue
Queue for the chunk data to be set into m_ChunkMap by the tick thread.
bool ReadFile(const AString &a_FileName, bool a_AllowExampleRedirect=true)
Reads the contents of the specified ini file If the file doesn't exist and a_AllowExampleRedirect is ...
This class bridges a vector of cItem for safe access via Lua.
NIBBLETYPE GetBlockMeta(Vector3i a_BlockPos) const
Returns the block meta at the specified position.
cSimulatorManager * GetSimulatorManager(void)
bool DoWithEntityByID(UInt32 a_EntityID, cEntityCallback a_Callback) const
Calls the callback if the entity with the specified ID is found, with the entity object as the callba...
void AddWantedChunk(int a_ChunkX, int a_ChunkZ)
Adds the chunk specified to the list of chunks wanted for sending (m_ChunksToSend)
void TickQueuedEntityAdditions(void)
Adds the entities queued in the m_EntitiesToAdd queue into their chunk.
bool AddKeyComment(const int keyID, const AString &comment)
Add a key comment.
bool IsTrapdoorOpen(int a_BlockX, int a_BlockY, int a_BlockZ)
Is the trapdoor open? Returns false if there is no trapdoor at the specified coords.
void ReplaceTreeBlocks(const sSetBlockVector &a_Blocks)
Special function used for growing trees, replaces only blocks that tree may overwrite.
bool DoWithChunkAt(Vector3i a_BlockPos, cChunkCallback a_Callback)
Calls the callback for the chunk at the block position specified, with ChunkMapCS locked.
static const UInt32 INVALID_ID
Special ID that is considered an "invalid value", signifying no entity.
void ChunkLoadFailed(int a_ChunkX, int a_ChunkZ)
Marks the chunk as failed-to-load.
cLock(const cWorld &a_World)
@ SFX_RANDOM_WOODEN_TRAPDOOR_OPEN
bool GetBlockTypeMeta(Vector3i a_BlockPos, BLOCKTYPE &a_BlockType, NIBBLETYPE &a_BlockMeta) const
Retrieves the block type and meta at the specified coords.
void SaveAllChunks(void) const
bool GetBlockInfo(Vector3i a_BlockPos, BLOCKTYPE &a_BlockType, NIBBLETYPE &a_Meta, NIBBLETYPE &a_SkyLight, NIBBLETYPE &a_BlockLight) const
Queries the whole block specification from the world.
cTickTimeLong GetWorldDate() const
void TabCompleteUserName(const AString &a_Text, AStringVector &a_Results)
Appends all usernames starting with a_Text (case-insensitive) into Results.
bool DoWithChunk(int a_ChunkX, int a_ChunkZ, cChunkCallback a_Callback)
Calls the callback for the chunk specified, with ChunkMapCS locked.
void SetChunkData(SetChunkData &&a_SetChunkData)
Sets the chunk data as either loaded from the storage or generated.
void TrackInDeadlockDetect(cDeadlockDetect &a_DeadlockDetect, const AString &a_WorldName)
Adds this chunkmap's CS to the DeadlockDetect's tracked CSs.
bool Save(void)
Try to save the scoreboard.
int m_MaxThunderStormTicks
unsigned char BLOCKTYPE
The datatype used by blockdata.
void MarkChunkSaving(int a_ChunkX, int a_ChunkZ)
bool DoWithNearestPlayer(Vector3d a_Pos, double a_RangeLimit, cPlayerListCallback a_Callback, bool a_CheckLineOfSight=true, bool a_IgnoreSpectator=true)
Calls the callback for nearest player for given position, Returns false if player not found,...
bool GetBlocks(sSetBlockVector &a_Blocks, bool a_ContinueOnFailure)
Retrieves block types of the specified blocks.
NIBBLETYPE GetBlockBlockLight(Vector3i a_BlockPos) const
Returns the block-light value at the specified block position.
void QueueUnloadUnusedChunks(void)
Queues a task to unload unused chunks onto the tick thread.
int FindValue(const int keyID, const AString &valuename) const
Returns index of specified value, in the specified key, or noID if not found.
void Tick(std::chrono::milliseconds a_Dt, std::chrono::milliseconds a_LastTickDurationMSec)
bool DoWithChunkAt(Vector3i a_BlockPos, cChunkCallback a_Callback)
Calls the callback for the chunk at the block position specified, with ChunkMapCS locked; returns fal...
bool CallHookExploded(cWorld &a_World, double a_ExplosionSize, bool a_CanCauseFire, double a_X, double a_Y, double a_Z, eExplosionSource a_Source, void *a_SourceData)
bool IsWeatherSunnyAt(int a_BlockX, int a_BlockZ) const
Returns true if it is sunny at the specified location.
void LOGWARNING(std::string_view a_Format, const Args &... args)
static std::vector< int > Split(int a_Reward)
Split reward into small values according to regular Minecraft rules.
OwnedEntity RemoveEntity(cEntity &a_Entity)
Removes the entity from the world.
NIBBLETYPE GetBlockBlockLight(Vector3i a_BlockPos) const
AString m_LinkedEndWorldName
Name of the End world - where End portals should teleport.
void ScheduleTask(cTickTime a_DelayTicks, std::function< void(cWorld &)> a_Task)
Queues a lambda task onto the tick thread, with the specified delay.
virtual void OnChunkGenerated(cChunkDesc &a_ChunkDesc) override
Called after the chunk has been generated The interface may store the chunk, send it over network,...
eDimension
Dimension of a world.
bool DoWithChunk(int a_ChunkX, int a_ChunkZ, cChunkCallback a_Callback)
Calls the callback for the chunk specified, with ChunkMapCS locked; returns false if the chunk doesn'...
AString & Printf(AString &a_Dst, const char *a_Format, const Args &... a_Args)
A simple RAII locker for the chunkmap - locks the chunkmap in its constructor, unlocks it in the dest...
bool GrowTree(Vector3i a_BlockPos)
Grows a tree at the specified coords.
void TickQueuedChunkDataSets()
Sets the chunk data queued in the m_SetChunkDataQueue queue into their chunk.
eKind
The kind of the projectile.
void AddEntity(OwnedEntity a_Entity, cWorld *a_OldWorld=nullptr)
Adds the entity into its appropriate chunk; takes ownership of the entity ptr.
bool ForEachEntityInBox(const cBoundingBox &a_Box, cEntityCallback a_Callback)
Calls the callback for each entity that has a nonempty intersection with the specified boundingbox.
@ E_BLOCK_STATIONARY_LAVA
cClientHandle * GetClientHandle(void) const
UInt32 SpawnFallingBlock(Vector3d a_Pos, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta)
Spawns an falling block entity at the given position.
void TickMobs(std::chrono::milliseconds a_Dt)
Handles the mob spawning / moving / destroying each tick.
@ E_ITEM_MINECART_WITH_TNT
void Stop(void)
Signals the thread to terminate and waits until it's finished.
Priority
Tag indicating urgency of chunk to be sent.
bool IsTicking(void) const
Returns true if the entity is valid and ticking.
bool GrowTreeFromSapling(Vector3i a_BlockPos)
Grows a tree from the sapling at the specified coords.
unsigned char Distance(const BlockState Block)
static bool CreateFolderRecursive(const AString &a_FolderPath)
Creates a new folder with the specified name, creating its parents if needed.
virtual bool DoWithBlockEntityAt(Vector3i a_Position, cBlockEntityCallback a_Callback) override
Calls the callback for the block entity at the specified coords; returns false if there's no block en...
const AString & GetName(void) const
Returns the name of the world.
cCriticalSection m_CSEntitiesToAdd
Guards m_EntitiesToAdd.
void SaveAllChunks(void)
Saves all chunks immediately.
virtual bool IsWeatherWetAtXYZ(Vector3i a_Position) override
Returns true if it is raining or storming at the specified location, and the rain reaches (the bottom...
void SendBlockTo(int a_BlockX, int a_BlockY, int a_BlockZ, const cPlayer &a_Player)
Sends the block at the specified coords to the specified player.
bool GetValueSetB(const AString &keyname, const AString &valuename, const bool defValue=false) override
void UpdateSkyDarkness(void)
int m_MinNetherPortalWidth
static bool IsSolid(BLOCKTYPE Block)
Is this block solid (player cannot walk through)?
void SetLines(const AString &a_Line1, const AString &a_Line2, const AString &a_Line3, const AString &a_Line4)
Sets all the sign's lines.
@ E_ITEM_MINECART_WITH_HOPPER
cLightingThread m_Lighting
This class is used to determine which monster can be spawned in which place it is essentially static ...
bool CallHookWorldTick(cWorld &a_World, std::chrono::milliseconds a_Dt, std::chrono::milliseconds a_LastTickDurationMSec)
void ChunkLighted(int a_ChunkX, int a_ChunkZ, const cChunkDef::BlockNibbles &a_BlockLight, const cChunkDef::BlockNibbles &a_SkyLight)
std::chrono::duration< signed long long int, cTickTime::period > cTickTimeLong
UInt32 CreateProjectile(Vector3d a_Pos, cProjectileEntity::eKind a_Kind, cEntity *a_Creator, const cItem *a_Item, const Vector3d *a_Speed=nullptr)
Creates a projectile of the specified type.
UInt32 SpawnMinecart(Vector3d a_Pos, int a_MinecartType, const cItem &a_Content=cItem(), int a_BlockHeight=1)
Spawns an minecart at the given coordinates.
size_t GetNumChunks() const
Returns the number of chunks loaded
bool Load(void)
Try to load the scoreboard.
bool ForEachLoadedChunk(cFunctionRef< bool(int, int)> a_Callback)
Calls the callback for each loaded chunk.
std::atomic< bool > m_IsSavingEnabled
Whether or not writing chunks to disk is currently enabled.
void QueueBlockForTick(int a_BlockX, int a_BlockY, int a_BlockZ, int a_TicksToWait)
Queues the block to be ticked after the specified number of game ticks.
bool DigBlock(Vector3i a_BlockPos)
Removes the block at the specified coords and wakes up simulators.
bool DoWithBlockEntityAt(Vector3i a_Position, cBlockEntityCallback a_Callback)
Calls the callback for the block entity at the specified coords.
NIBBLETYPE GetBlockSkyLight(Vector3i a_BlockPos) const
Returns the sky light value at the specified block position.
std::map< cMonster::eFamily, cTickTimeLong > m_LastSpawnMonster
bool IsCapped(cMonster::eFamily a_MobFamily)
Returns true if the family is capped (i.e.
cCriticalSection m_CSSetChunkDataQueue
CS protecting m_SetChunkDataQueue.
bool DoWithEntityByID(UInt32 a_UniqueID, cEntityCallback a_Callback)
Calls the callback if the entity with the specified ID is found, with the entity object as the callba...
bool CallHookChunkGenerating(cWorld &a_World, int a_ChunkX, int a_ChunkZ, cChunkDesc *a_ChunkDesc)
bool SetSpawn(int a_X, int a_Y, int a_Z)
Set default spawn at the given coordinates.
static bool LineOfSightTrace(cWorld &a_World, const Vector3d &a_Start, const Vector3d &a_End, int a_Sight)
Returns true if the two positions are within line of sight (not obscured by blocks).
void RemoveClientFromChunks(cClientHandle *a_Client)
Removes the client from all chunks it is present in.
virtual bool IsWeatherWetAt(int a_BlockX, int a_BlockZ) override
Returns true if it is raining or storming at the specified location.
BLOCKTYPE GetBlockType() const
void GetBirchTreeImage(Vector3i a_BlockPos, cNoise &a_Noise, int a_Seq, sSetBlockVector &a_LogBlocks, sSetBlockVector &a_OtherBlocks)
Fills a_LogBlocks and a_OtherBlocks (dirt & leaves) with the blocks required to form a random birch t...
int GetHeight(int a_BlockX, int a_BlockZ)
NIBBLETYPE BlockNibbles[NumBlocks/2]
The type used for block data in nibble format, AXIS_ORDER ordering.
AString m_LinkedOverworldName
The name of the overworld that portals in this world should link to.
cChunkInterface GetChunkInterface(cWorld &a_World)
bool m_ShouldLavaSpawnFire
int m_MinNetherPortalHeight
bool DropBlockAsPickups(Vector3i a_BlockPos, const cEntity *a_Digger=nullptr, const cItem *a_Tool=nullptr)
Digs the specified block, and spawns the appropriate pickups for it.
void GetDarkoakTreeImage(Vector3i a_BlockPos, cNoise &a_Noise, int a_Seq, sSetBlockVector &a_LogBlocks, sSetBlockVector &a_OtherBlocks)
Fills a_LogBlocks and a_OtherBlocks (dirt & leaves) with the blocks required to form a random darkoak...
virtual void CallHookChunkGenerated(cChunkDesc &a_ChunkDesc) override
Called after the chunk is generated, before it is handed to the chunk sink.
bool IsChunkLighted(int a_ChunkX, int a_ChunkZ)
static void PrepareChunks(cWorld &a_World, int a_SpawnChunkX, int a_SpawnChunkZ, int a_PrepareDistance)
virtual bool ForEachPlayer(cPlayerListCallback a_Callback) override
Calls the callback for each player in the list; returns true if all players processed,...
bool ForEachChunkInRect(int a_MinChunkX, int a_MaxChunkX, int a_MinChunkZ, int a_MaxChunkZ, cChunkDataCallback &a_Callback)
Calls the callback for each chunk in the coords specified (all cords are inclusive).
UInt32 SpawnItemPickup(Vector3d a_Pos, const cItem &a_Item, Vector3f a_Speed, int a_LifetimeTicks=6000, bool a_CanCombine=true)
Spawns a single pickup containing the specified item.
void GetTreeImageByBiome(Vector3i a_BlockPos, cNoise &a_Noise, int a_Seq, EMCSBiome a_Biome, sSetBlockVector &a_LogBlocks, sSetBlockVector &a_OtherBlocks)
Fills a_LogBlocks and a_OtherBlocks (dirt & leaves) with the blocks required to form a tree at the sp...
void CollectMobCensus(cMobCensus &a_ToFill)
Make a Mob census, of all mobs, their family, their chunk and their distance to closest player.
bool CheckPlayerSpawnPoint(int a_PosX, int a_PosY, int a_PosZ)
Check if player starting point is acceptable.
virtual bool ForEachEntityInBox(const cBoundingBox &a_Box, cEntityCallback a_Callback) override
Calls the callback for each entity that has a nonempty intersection with the specified boundingbox.
void ForceSendChunkTo(int a_ChunkX, int a_ChunkZ, cChunkSender::Priority a_Priority, cClientHandle *a_Client)
Sends the chunk to the client specified, even if the client already has the chunk.
void MarkChunkDirty(int a_ChunkX, int a_ChunkZ)
void SetBlock(Vector3i a_BlockPos, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta)
Sets the block at the specified coords to the specified value.
bool SetValue(const int keyID, const int valueID, const AString &value)
bool TryGetHeight(int a_BlockX, int a_BlockZ, int &a_Height)
Retrieves the world height at the specified coords; returns false if chunk not loaded / generated.
bool GetChunkData(cChunkCoords a_Coords, cChunkDataCallback &a_Callback) const
Calls the callback with the chunk's data, if available (with ChunkCS locked).
bool SetValueB(const AString &a_KeyName, const AString &a_ValueName, const bool a_Value, const bool a_CreateIfNotExists=true)
bool SetBiomeAt(int a_BlockX, int a_BlockZ, EMCSBiome a_Biome)
Sets the biome at the specified coords.
void LOG(std::string_view a_Format, const Args &... args)
void FLOGINFO(std::string_view a_Format, const Args &... args)
void MarkChunkSaved(int a_ChunkX, int a_ChunkZ)
cFluidSimulator * m_LavaSimulator
void SendBlockEntity(int a_BlockX, int a_BlockY, int a_BlockZ, cClientHandle &a_Client)
Sends the block entity, if it is at the coords specified, to a_Client.
bool GetLargeTreeAdjustment(Vector3i &a_BlockPos, NIBBLETYPE a_SaplingMeta)
Checks if the sapling at the specified block coord is a part of a large-tree sapling (2x2).
void QueueTask(std::function< void(cWorld &)> a_Task)
Queues a task onto the tick thread.
void UntrackInDeadlockDetect(cDeadlockDetect &a_DeadlockDetect)
Removes this chunkmap's CS from the DeadlockDetect's tracked CSs.
bool WriteFile(const AString &a_FileName) const
Writes data stored in class to the specified ini file.
void RemoveChunkClient(int a_ChunkX, int a_ChunkZ, cClientHandle *a_Client)
Removes the client from the chunk.
void WakeUpSimulatorsInArea(const cCuboid &a_Area)
Wakes up the simulators for the specified area of blocks.
virtual int GetHeight(int a_BlockX, int a_BlockZ) override
Returns the world height at the specified coords; waits for the chunk to get loaded / generated.
virtual void SetTimeOfDay(cTickTime a_TimeOfDay) override
std::vector< std::pair< std::chrono::milliseconds, std::function< void(cWorld &)> > > m_Tasks
Tasks that have been queued onto the tick thread, possibly to be executed at target tick in the futur...
virtual void BroadcastThunderbolt(Vector3i a_BlockPos, const cClientHandle *a_Exclude=nullptr) override
void GetAcaciaTreeImage(Vector3i a_BlockPos, cNoise &a_Noise, int a_Seq, sSetBlockVector &a_LogBlocks, sSetBlockVector &a_OtherBlocks)
Fills a_LogBlocks and a_OtherBlocks (dirt & leaves) with the blocks required to form a random acacia ...
bool GrowTreeImage(const sSetBlockVector &a_Blocks)
Imprints the specified blocks into the world, as long as each log block replaces only allowed blocks.
std::vector< AString > AStringVector