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);
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();
1051 Player->GetClientHandle()->ProcessProtocolOut();
1080 Player->GetClientHandle()->Tick(a_Dt);
1140 for (
size_t i = 0; i <
ARRAYCOUNT(AllFamilies); i++)
1152 if (
Spawner.CanSpawnAnything())
1156 for (
auto & Mob :
Spawner.getSpawned())
1166 if (!a_Entity.
IsMob())
1175 auto & Monster =
static_cast<cMonster &
>(a_Entity);
1176 ASSERT(Monster.GetParentChunk() !=
nullptr);
1179 if (Monster.GetParentChunk()->HasAnyClients())
1181 Monster.Tick(a_Dt, *(a_Entity.GetParentChunk()));
1184 else if ((Monster.GetMobFamily() == cMonster::eFamily::mfHostile) && !Monster.WasLastTargetAPlayer())
1186 if (Monster.GetMobType() != eMonsterType::mtWolf)
1192 auto & Wolf = static_cast<cWolf &>(Monster);
1193 if (!Wolf.IsAngry() && !Wolf.IsTame())
1217 for (
auto &
Item : SetChunkDataQueue)
1220 const auto Chunk =
Item.Chunk;
1228 Chunk.m_ChunkX, Chunk.m_ChunkZ,
1229 [&ChunkSender](
cChunk & a_Chunk)
1231 if (a_Chunk.HasAnyClients())
1233 ChunkSender.QueueSendChunkTo(
1236 cChunkSender::Priority::Medium,
1237 a_Chunk.GetAllClients()
1262 for (
auto &
Item: EntitiesToAdd)
1264 const auto Entity =
Item.first.get();
1266 if (Entity->IsPlayer())
1268 const auto Player =
static_cast<cPlayer *
>(Entity);
1270 LOGD(
"Adding player %s to world \"%s\".", Player->GetName().c_str(),
m_WorldName.c_str());
1278 if (
const auto OldWorld =
Item.second; OldWorld !=
nullptr)
1301 auto MoveBeginIterator = std::partition(
m_Tasks.begin(),
m_Tasks.end(), [
this](
const decltype(
m_Tasks)::value_type & a_Task)
1309 std::make_move_iterator(MoveBeginIterator),
1310 std::make_move_iterator(
m_Tasks.end())
1316 for (
const auto & Task : Tasks)
1328 const auto TIME_SUNSET = 12000_tick;
1329 const auto TIME_NIGHT_START = 13187_tick;
1330 const auto TIME_NIGHT_END = 22812_tick;
1331 const auto TIME_SUNRISE = 23999_tick;
1332 const auto TIME_SPAWN_DIVISOR = 148_tick;
1335 if (TempTime <= TIME_SUNSET)
1339 else if (TempTime <= TIME_NIGHT_START)
1343 else if (TempTime <= TIME_NIGHT_END)
1387 if (!
cPluginManager::Get()->CallHookExploding(*
this, a_ExplosionSize, a_CanCauseFire, a_BlockX, a_BlockY, a_BlockZ, a_Source, a_SourceData) && (a_ExplosionSize > 0))
1402 Entity =
static_cast<const cEntity *
>(a_SourceData);
1438 const auto & Sign =
static_cast<cSignEntity &
>(a_BlockEntity);
1440 a_Line2 = Sign.GetLine(1);
1441 a_Line3 = Sign.GetLine(2);
1442 a_Line4 = Sign.GetLine(3);
1491 auto WorldAge =
static_cast<int>(
m_WorldTickAge.count() & 0xffffffff);
1493 switch (SaplingMeta & 0x07)
1521 Other.insert(Other.begin(), Logs.begin(), Logs.end());
1532 bool IsLarge =
true;
1533 a_Meta = a_Meta & 0x07;
1536 for (
int x = 0; x < 2; ++x)
1538 for (
int z = 0; z < 2; ++z)
1543 IsLarge = IsLarge && (type ==
E_BLOCK_SAPLING) && ((meta & 0x07) == a_Meta);
1554 for (
int x = 0; x < 2; ++x)
1556 for (
int z = 0; z > -2; --z)
1561 IsLarge = IsLarge && (type ==
E_BLOCK_SAPLING) && ((meta & 0x07) == a_Meta);
1573 for (
int x = 0; x > -2; --x)
1575 for (
int z = 0; z > -2; --z)
1580 IsLarge = IsLarge && (type ==
E_BLOCK_SAPLING) && ((meta & 0x07) == a_Meta);
1593 for (
int x = 0; x > -2; --x)
1595 for (
int z = 0; z < 2; ++z)
1600 IsLarge = IsLarge && (type ==
E_BLOCK_SAPLING) && ((meta & 0x07) == a_Meta);
1620 auto seq =
static_cast<int>(
m_WorldTickAge.count() & 0xffffffff);
1622 Other.insert(Other.begin(), Logs.begin(), Logs.end());
1637 for (sSetBlockVector::const_iterator itr = a_Blocks.begin(); itr != a_Blocks.end(); ++itr)
1652 for (sSetBlockVector::const_iterator itr = b2.begin(); itr != b2.end(); ++itr)
1654 switch (itr->m_BlockType)
1724 std::min(a_Area.
p1.
x, a_Area.
p2.
x), std::max(a_Area.
p1.
x, a_Area.
p2.
x),
1725 std::min(a_Area.
p1.
z, a_Area.
p2.
z), std::max(a_Area.
p1.
z, a_Area.
p2.
z),
1809 auto microX = random.RandReal<
double>(0, 1);
1810 auto microZ = random.RandReal<
double>(0, 1);
1821 a_FlyAwaySpeed /= 100;
1822 for (cItems::const_iterator itr = a_Pickups.begin(); itr != a_Pickups.end(); ++itr)
1830 float SpeedX =
static_cast<float>(a_FlyAwaySpeed * Random.RandInt(-10, 10));
1831 float SpeedY =
static_cast<float>(a_FlyAwaySpeed * Random.RandInt(40, 50));
1832 float SpeedZ =
static_cast<float>(a_FlyAwaySpeed * Random.RandInt(-10, 10));
1834 auto Pickup = std::make_unique<cPickup>(a_Pos, *itr, a_IsPlayerCreated,
Vector3f{SpeedX, SpeedY, SpeedZ});
1835 auto PickupPtr = Pickup.get();
1836 PickupPtr->Initialize(std::move(Pickup), *
this);
1846 for (cItems::const_iterator itr = a_Pickups.begin(); itr != a_Pickups.end(); ++itr)
1853 auto pickup = std::make_unique<cPickup>(a_Pos, *itr, a_IsPlayerCreated, a_Speed);
1854 auto pickupPtr = pickup.get();
1855 pickupPtr->Initialize(std::move(pickup), *
this);
1865 auto pickup = std::make_unique<cPickup>(a_Pos, a_Item,
false, a_Speed, a_LifetimeTicks, a_CanCombine);
1866 auto pickupPtr = pickup.get();
1867 if (!pickupPtr->Initialize(std::move(pickup), *
this))
1871 return pickupPtr->GetUniqueID();
1880 auto fallingBlock = std::make_unique<cFallingBlock>(a_Pos, a_BlockType, a_BlockMeta);
1881 auto fallingBlockPtr = fallingBlock.get();
1882 auto ID = fallingBlock->GetUniqueID();
1883 if (!fallingBlockPtr->Initialize(std::move(fallingBlock), *
this))
1898 LOGWARNING(
"%s: Attempting to create an experience orb with non-positive reward!", __FUNCTION__);
1902 auto expOrb = std::make_unique<cExpOrb>(a_Pos, a_Reward);
1903 auto expOrbPtr = expOrb.get();
1904 if (!expOrbPtr->Initialize(std::move(expOrb), *
this))
1908 return expOrbPtr->GetUniqueID();
1917 std::vector<UInt32> OrbsID;
1921 LOGWARNING(
"%s: Attempting to create an experience orb with non-positive reward!", __FUNCTION__);
1928 float SpeedLimit =
static_cast<float>((Rewards.size() / 2) + 5);
1929 if (SpeedLimit > 10)
1935 for (
auto Reward : Rewards)
1937 auto ExpOrb = std::make_unique<cExpOrb>(a_Pos, Reward);
1938 auto ExpOrbPtr = ExpOrb.get();
1939 double SpeedX = Random.RandReal(-SpeedLimit, SpeedLimit);
1940 double SpeedY = Random.RandReal(0.5);
1941 double SpeedZ = Random.RandReal(-SpeedLimit, SpeedLimit);
1942 ExpOrbPtr->SetSpeed(SpeedX, SpeedY, SpeedZ);
1944 UInt32 Id = ExpOrbPtr->GetUniqueID();
1945 if (ExpOrbPtr->Initialize(std::move(ExpOrb), *
this))
1947 OrbsID.push_back(Id);
1960 std::unique_ptr<cMinecart>
Minecart;
1961 switch (a_MinecartType)
1963 case E_ITEM_MINECART:
Minecart = std::make_unique<cRideableMinecart> (a_Pos, a_Content, a_BlockHeight);
break;
1975 if (!MinecartPtr->Initialize(std::move(
Minecart), *
this))
1979 return MinecartPtr->GetUniqueID();
1988 auto Boat = std::make_unique<cBoat>(a_Pos, a_Material);
1989 auto BoatPtr = Boat.get();
1990 if (!BoatPtr->Initialize(std::move(Boat), *
this))
1994 return BoatPtr->GetUniqueID();
2003 auto TNT = std::make_unique<cTNTEntity>(a_Pos, a_FuseTicks);
2004 auto TNTPtr =
TNT.get();
2005 if (!TNTPtr->Initialize(std::move(
TNT), *
this))
2010 if (a_ShouldPlayFuseSound)
2017 a_InitialVelocityCoeff * Random.RandReal(-0.5f, 0.5f),
2018 a_InitialVelocityCoeff * 2,
2019 a_InitialVelocityCoeff * Random.RandReal(-0.5f, 0.5f)
2021 return TNTPtr->GetUniqueID();
2030 auto EnderCrystal = std::make_unique<cEnderCrystal>(a_Pos, a_ShowBottom);
2031 auto EnderCrystalPtr = EnderCrystal.get();
2032 if (!EnderCrystalPtr->Initialize(std::move(EnderCrystal), *
this))
2036 return EnderCrystalPtr->GetUniqueID();
2049 SetBlock(a_Position, a_BlockType, a_BlockMeta);
2093 if (!
DigBlock(a_BlockPos, a_Digger))
2190 int a_ChunkX,
int a_ChunkZ,
2272 if (Player->IsTicking() && a_Callback(*Player))
2290 if (Player->IsTicking() && (
NoCaseCompare(Player->GetName(), a_PlayerName) == 0))
2292 a_Callback(*Player);
2305 cPlayer * BestMatch =
nullptr;
2306 size_t BestRating = 0;
2307 size_t NameLength = a_PlayerNameHint.length();
2312 if (!Player->IsTicking())
2317 if (Rating >= BestRating)
2320 BestRating = Rating;
2322 if (Rating == NameLength)
2328 if (BestMatch !=
nullptr)
2330 return a_Callback(*BestMatch);
2344 if (Player->IsTicking() && (Player->GetUUID() == a_PlayerUUID))
2346 return a_Callback(*Player);
2358 double ClosestDistance = a_RangeLimit;
2359 cPlayer * ClosestPlayer =
nullptr;
2364 if (!Player->IsTicking())
2369 if (a_IgnoreSpectator && Player->IsGameModeSpectator())
2374 Vector3f Pos = Player->GetPosition();
2375 double Distance = (Pos - a_Pos).Length();
2385 a_CheckLineOfSight &&
2393 ClosestPlayer = Player;
2398 return a_Callback(*ClosestPlayer);
2416 if (!Player->GetClientHandle()->IsDestroyed())
2471 if (
Item.first->GetUniqueID() == a_UniqueID)
2473 a_Callback(*
Item.first);
2569 if (
cRoot::Get()->GetPluginManager()->CallHookUpdatingSign(*
this, a_BlockPos, Line1, Line2, Line3, Line4, a_Player))
2626 return (Meta & 0x4) > 0;
2643 bool IsOpen = (Meta & 0x4) != 0;
2644 if (a_Open != IsOpen)
2646 SetBlockMeta({ a_BlockX, a_BlockY, a_BlockZ }, Meta ^ 0x4);
2737 m_Tasks.emplace_back(0, std::move(a_Task));
2746 const auto TargetTick = a_DelayTicks +
m_WorldAge;
2751 m_Tasks.emplace_back(TargetTick, std::move(a_Task));
2775 const auto Player =
static_cast<cPlayer *
>(&a_Entity);
2776 LOGD(
"Removing player %s from world \"%s\"", Player->GetName().c_str(),
m_WorldName.c_str());
2782 if (Entity !=
nullptr)
2784 Entity->OnRemoveFromWorld(*
this);
2791 [&a_Entity](
const auto &
Item)
2793 return (Item.first.get() == &a_Entity);
2799 Entity = std::move(itr->first);
2850 Block->TicksToWait -= 1;
2851 if (
Block->TicksToWait <= 0)
2871 Block->X = a_BlockX;
2872 Block->Y = a_BlockY;
2873 Block->Z = a_BlockZ;
2874 Block->TicksToWait = a_TicksToWait;
2900 if (Monster ==
nullptr)
2904 Monster->SetPosition(a_PosX, a_PosY, a_PosZ);
2908 Monster->SetAge(-1);
2920 ASSERT(a_Monster !=
nullptr);
2923 a_Monster->SetHealth(a_Monster->GetMaxHealth());
2931 auto & Monster = *a_Monster;
2934 if (!Monster.Initialize(std::move(a_Monster), *
this))
2941 return Monster.GetUniqueID();
2951 if (Projectile ==
nullptr)
2956 auto ProjectilePtr = Projectile.get();
2957 if (!ProjectilePtr->Initialize(std::move(Projectile), *
this))
2962 return ProjectilePtr->GetUniqueID();
2971 return CreateProjectile({a_PosX, a_PosY, a_PosZ}, a_Kind, a_Creator, a_Item, a_Speed);
2989 typedef std::pair<AString::size_type, AString> pair_t;
2990 size_t LastSpace = a_Text.find_last_of(
" ");
2991 AString LastWord = a_Text.substr(LastSpace + 1, a_Text.length());
2993 if (LastWord.empty())
2998 std::vector<pair_t> UsernamesByWeight;
3003 AString PlayerName = Player->HasCustomName() ? Player->GetCustomName() : Player->GetName();
3006 if (Found == AString::npos)
3011 UsernamesByWeight.push_back(std::make_pair(Found, PlayerName));
3015 std::sort(UsernamesByWeight.begin(), UsernamesByWeight.end());
3026 a_Results.reserve(UsernamesByWeight.size());
3027 for (std::vector<pair_t>::const_iterator itr = UsernamesByWeight.begin(); itr != UsernamesByWeight.end(); ++itr)
3029 a_Results.push_back(itr->second);
3048 AString SimulatorName = a_IniFile.
GetValueSet(
"Physics",
"RedstoneSimulator",
"Incremental");
3050 if (SimulatorName.empty())
3052 LOGWARNING(
"[Physics] RedstoneSimulator not present or empty in %s, using the default of \"Incremental\".",
GetIniFileName().c_str());
3053 SimulatorName =
"Incremental";
3068 LOGWARNING(
"[Physics] Unknown RedstoneSimulator \"%s\" in %s, using the default of \"Incremental\".", SimulatorName.c_str(),
GetIniFileName().c_str());
3083 auto SimulatorNameKey = fmt::format(FMT_STRING(
"{}Simulator"), a_FluidName);
3084 auto SimulatorSectionName = fmt::format(FMT_STRING(
"{}Simulator"), a_FluidName);
3086 bool IsWater = (strcmp(a_FluidName,
"Water") == 0);
3088 AString SimulatorName = a_IniFile.
GetValueSet(
"Physics", SimulatorNameKey, DefaultSimulatorName);
3089 if (SimulatorName.empty())
3091 LOGWARNING(
"[Physics] %s not present or empty in %s, using the default of \"%s\".", SimulatorNameKey,
GetIniFileName(), DefaultSimulatorName);
3092 SimulatorName = DefaultSimulatorName;
3115 int TickDelay = a_IniFile.
GetValueSetI(SimulatorSectionName,
"TickDelay",
IsWater ? 5 : 30);
3116 int NumNeighborsForSource = a_IniFile.
GetValueSetI(SimulatorSectionName,
"NumNeighborsForSource",
IsWater ? 2 : -1);
3118 if ((Falloff > 15) || (Falloff < 0))
3120 LOGWARNING(
"Falloff for %s simulator is out of range, assuming default of %d", a_FluidName,
IsWater ? 1 : 2);
3135 LOGWARNING(
"%s [Physics]:%s specifies an unknown simulator, using the default \"Vanilla\".",
GetIniFileName().c_str(), SimulatorNameKey.c_str());
3168 Data.BlockData.SetAll(a_ChunkDesc.
GetBlockTypes(), BlockMetas);
3173 Data.Entities = std::move(a_ChunkDesc.
GetEntities());
3176 Data.IsLightValid =
false;
3179 m_World->QueueSetChunkData(std::move(Data));
3238 return (Noise.
IntNoise2DInt(a_ChunkX, a_ChunkZ) / 8) % 10 == 0;
EMCSBiome
Biome IDs The first batch corresponds to the clientside biomes, used by MineCraft.
bool IsBlockWater(BLOCKTYPE a_BlockType)
bool IsBlockLiquid(BLOCKTYPE a_BlockType)
@ E_META_SAPLING_DARK_OAK
@ E_BLOCK_STATIONARY_LAVA
@ E_BLOCK_STATIONARY_WATER
@ E_ITEM_MINECART_WITH_TNT
@ E_ITEM_MINECART_WITH_HOPPER
@ E_ITEM_FURNACE_MINECART
std::vector< sSetBlock > sSetBlockVector
unsigned char NIBBLETYPE
The datatype used by nibbledata (meta, light, skylight)
std::unique_ptr< cEntity > OwnedEntity
unsigned char BLOCKTYPE
The datatype used by blockdata.
AString DimensionToString(eDimension a_Dimension)
Translates a dimension enum to dimension string.
bool IsValidItem(int a_ItemType)
Returns true if the specified item type is valid (known).
eDimension StringToDimension(const AString &a_DimensionString)
Translates a dimension string to dimension enum.
eDimension
Dimension of a world.
eExplosionSource
The source of an explosion.
@ SFX_RANDOM_WOODEN_TRAPDOOR_OPEN
MTRand & GetRandomProvider()
Returns the current thread's random number source.
static bool IsWater(BLOCKTYPE a_BlockType)
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...
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...
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 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 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...
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 ...
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...
#define CASE_TREE_ALLOWED_BLOCKS
std::chrono::duration< signed long long int, cTickTime::period > cTickTimeLong
#define ARRAYCOUNT(X)
Evaluates to the number of elements in an array (compile-time!)
T Clamp(T a_Value, T a_Min, T a_Max)
Clamp X to the specified range.
std::chrono::duration< signed int, std::ratio_multiply< std::chrono::milliseconds::period, std::ratio< 50 > >> cTickTime
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).
void FLOGINFO(std::string_view a_Format, const Args &... args)
void LOGWARNING(std::string_view a_Format, const Args &... args)
void LOG(std::string_view a_Format, const Args &... args)
void FLOGWARNING(std::string_view a_Format, const Args &... args)
eMonsterType
Identifies individual monster type.
AStringVector StringSplitAndTrim(const AString &str, const AString &delim)
Split the string at any of the listed delimiters and trim each value.
AString StrToLower(const AString &s)
Returns a lower-cased copy of the string.
int NoCaseCompare(const AString &s1, const AString &s2)
Case-insensitive string comparison.
size_t RateCompareString(const AString &s1, const AString &s2)
Case-insensitive string comparison that returns a rating of equal-ness between [0 - s1....
std::vector< AString > AStringVector
Vector3< double > Vector3d
Implements custom fmtlib formatting for cChunkCoords.
Utilities to allow casting a cWorld to one of its interfaces without including World....
cWorldInterface * GetWorldInterface(cWorld *a_World)
cBroadcastInterface * GetBroadcastInterface(cWorld *a_World)
cChunkInterface GetChunkInterface(cWorld &a_World)
cForEachChunkProvider * GetFECProvider(cWorld *a_World)
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.
unsigned char Distance(const BlockState Block)
bool CallHookChunkGenerated(cWorld &a_World, int a_ChunkX, int a_ChunkZ, cChunkDesc *a_ChunkDesc)
bool CallHookChunkGenerating(cWorld &a_World, int a_ChunkX, int a_ChunkZ, cChunkDesc *a_ChunkDesc)
static cPluginManager * Get(void)
Returns the instance of the Plugin Manager (there is only ever one)
bool CallHookSpawnedMonster(cWorld &a_World, cMonster &a_Monster)
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)
bool CallHookEntityChangedWorld(cEntity &a_Entity, cWorld &a_World)
bool CallHookWeatherChanged(cWorld &a_World)
bool CallHookWorldTick(cWorld &a_World, std::chrono::milliseconds a_Dt, std::chrono::milliseconds a_LastTickDurationMSec)
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)
BLOCKTYPE GetBlockType() const
void SetLines(const AString &a_Line1, const AString &a_Line2, const AString &a_Line3, const AString &a_Line4)
Sets all the sign's lines.
AString GetLine(size_t a_Index) const
Retrieves individual line (zero-based index)
static bool IsSolid(BLOCKTYPE Block)
Is this block solid (player cannot walk through)?
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.
static const cBlockHandler & For(BLOCKTYPE a_BlockType)
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.
Represents two sets of coords, minimum and maximum for each direction.
Wraps the chunk coords into a single structure.
Constants used throughout the code, useful typedefs and utility functions.
static bool IsValidHeight(Vector3i a_BlockPosition)
Validates a height-coordinate.
static void BlockToChunk(int a_X, int a_Z, int &a_ChunkX, int &a_ChunkZ)
Converts absolute block coords to chunk coords:
NIBBLETYPE BlockNibbles[NumBlocks/2]
The type used for block data in nibble format, AXIS_ORDER ordering.
Interface class used for comparing clients of two chunks.
bool Initialize(cPluginInterface &a_PluginInterface, cChunkSink &a_ChunkSink, cIniFile &a_IniFile)
Read settings from the ini file and initialize in preperation for being started.
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 SetBiomeAt(int a_BlockX, int a_BlockZ, EMCSBiome a_Biome)
Sets the biome at the specified coords.
bool ForEachLoadedChunk(cFunctionRef< bool(int, int)> a_Callback) const
Calls the callback for each loaded chunk.
bool GetBlockTypeMeta(Vector3i a_BlockPos, BLOCKTYPE &a_BlockType, NIBBLETYPE &a_BlockMeta) const
void UntrackInDeadlockDetect(cDeadlockDetect &a_DeadlockDetect)
Removes this chunkmap's CS from the DeadlockDetect's tracked CSs.
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.
void SpawnMobs(cMobSpawner &a_MobSpawner)
Try to Spawn Monsters inside all Chunks.
bool SetAreaBiome(int a_MinX, int a_MaxX, int a_MinZ, int a_MaxZ, EMCSBiome a_Biome)
Sets the biome at the area.
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...
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 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'...
NIBBLETYPE GetBlockSkyLight(Vector3i a_BlockPos) const
void MarkChunkSaving(int a_ChunkX, int a_ChunkZ)
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...
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 SaveAllChunks(void) const
bool IsChunkValid(int a_ChunkX, int a_ChunkZ) const
bool IsChunkLighted(int a_ChunkX, int a_ChunkZ)
void SetChunkData(SetChunkData &&a_SetChunkData)
Sets the chunk data as either loaded from the storage or generated.
void RemoveClientFromChunks(cClientHandle *a_Client)
Removes the client from all chunks it is present in.
void ChunkLoadFailed(int a_ChunkX, int a_ChunkZ)
Marks the chunk as failed-to-load.
NIBBLETYPE GetBlockBlockLight(Vector3i a_BlockPos) const
void GenerateChunk(int a_ChunkX, int a_ChunkZ)
Queues the chunk for generating.
void GetChunkStats(int &a_NumChunksValid, int &a_NumChunksDirty) const
Returns the number of valid chunks and the number of dirty chunks.
void RemoveChunkClient(int a_ChunkX, int a_ChunkZ, cClientHandle *a_Client)
Removes the client from the chunk.
void AddEntity(OwnedEntity a_Entity)
Adds the entity to its appropriate chunk, takes ownership of the entity pointer.
void SetNextBlockToTick(const Vector3i a_BlockPos)
Causes the specified block to be ticked on the next Tick() call.
void MarkChunkDirty(int a_ChunkX, int a_ChunkZ)
bool GetBlockInfo(Vector3i, BLOCKTYPE &a_BlockType, NIBBLETYPE &a_Meta, NIBBLETYPE &a_SkyLight, NIBBLETYPE &a_BlockLight) const
void SetBlockMeta(Vector3i a_BlockPos, NIBBLETYPE a_BlockMeta)
Sets the meta for the specified block, while keeping the blocktype.
void TickBlock(const Vector3i a_BlockPos)
Ticks a single block.
void ReplaceTreeBlocks(const sSetBlockVector &a_Blocks)
Special function used for growing trees, replaces only blocks that tree may overwrite.
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.
bool ForEachEntity(cEntityCallback a_Callback) const
Calls the callback for each entity in the entire world; returns true if all entities processed,...
bool ForEachEntityInBox(const cBoundingBox &a_Box, cEntityCallback a_Callback)
Calls the callback for each entity that has a nonempty intersection with the specified boundingbox.
bool DoWithBlockEntityAt(Vector3i a_Position, cBlockEntityCallback a_Callback)
Calls the callback for the block entity at the specified coords.
OwnedEntity RemoveEntity(cEntity &a_Entity)
Removes the entity from its appropriate chunk Returns an owning reference to the found entity.
void TrackInDeadlockDetect(cDeadlockDetect &a_DeadlockDetect, const AString &a_WorldName)
Adds this chunkmap's CS to the DeadlockDetect's tracked CSs.
void CollectPickupsByEntity(cEntity &a_Entity)
Makes the specified entity collect all the pickups around them.
bool IsWeatherSunnyAt(int a_BlockX, int a_BlockZ) const
void MarkChunkSaved(int a_ChunkX, int a_ChunkZ)
void WakeUpSimulators(Vector3i a_Block)
Wakes up simulators for the specified block.
bool GetBlocks(sSetBlockVector &a_Blocks, bool a_ContinueOnFailure)
Retrieves block types and metas of the specified blocks.
bool IsChunkQueued(int a_ChunkX, int a_ChunkZ) const
Returns true iff the chunk is in the loader / generator queue.
bool ForEachBlockEntityInChunk(int a_ChunkX, int a_ChunkZ, cBlockEntityCallback a_Callback)
Calls the callback for each block entity in the specified chunk.
bool DigBlock(Vector3i a_BlockPos)
Removes the block at the specified coords and wakes up simulators.
bool TryGetHeight(int a_BlockX, int a_BlockZ, int &a_Height)
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 Tick(std::chrono::milliseconds a_Dt)
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,...
EMCSBiome GetBiomeAt(int a_BlockX, int a_BlockZ) const
Returns the biome at the specified coords.
void SetBlock(Vector3i a_BlockPos, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta)
void UnloadUnusedChunks(void)
int GrowPlantAt(Vector3i a_BlockPos, int a_NumStages=1)
Grows the plant at the specified position by at most a_NumStages.
int GetHeight(int a_BlockX, int a_BlockZ)
bool DoWithChunkAt(Vector3i a_BlockPos, cChunkCallback a_Callback)
Calls the callback for the chunk at the block position specified, with ChunkMapCS locked; returns fal...
void CollectMobCensus(cMobCensus &a_ToFill)
Make a Mob census, of all mobs, their family, their chunk and their distance to closest player.
size_t GetNumChunks(void) const
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).
size_t GetNumUnusedDirtyChunks(void) const
Returns the number of unused dirty chunks.
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 IsWeatherWetAt(int a_BlockX, int a_BlockZ) const
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...
bool HasChunkAnyClients(int a_ChunkX, int a_ChunkZ) const
void ChunkLighted(int a_ChunkX, int a_ChunkZ, const cChunkDef::BlockNibbles &a_BlockLight, const cChunkDef::BlockNibbles &a_SkyLight)
bool GetChunkData(cChunkCoords a_Coords, cChunkDataCallback &a_Callback) const
Calls the callback with the chunk's data, if available (with ChunkCS locked).
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 QueueSendChunkTo(int a_ChunkX, int a_ChunkZ, Priority a_Priority, cClientHandle *a_Client)
Queues a chunk to be sent to a specific client.
Priority
Tag indicating urgency of chunk to be sent.
static const int MAX_VIEW_DISTANCE
static const int MIN_VIEW_DISTANCE
void SendPlayerListAddPlayer(const cPlayer &a_Player)
static const int DEFAULT_VIEW_DISTANCE
void AddWantedChunk(int a_ChunkX, int a_ChunkZ)
Adds the chunk specified to the list of chunks wanted for sending (m_ChunksToSend)
void UntrackCriticalSection(cCriticalSection &a_CS)
Removes the CS from the tracking.
void TrackCriticalSection(cCriticalSection &a_CS, const AString &a_Name)
Adds the critical section for tracking.
bool IsPlayer(void) const
static const UInt32 INVALID_ID
Special ID that is considered an "invalid value", signifying no entity.
bool IsTicking(void) const
Returns true if the entity is valid and ticking.
static std::vector< int > Split(int a_Reward)
Split reward into small values according to regular Minecraft rules.
cClientHandle * GetClientHandle(void) const
eKind
The kind of the projectile.
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.
IntType RandInt(IntType a_Min, IntType a_Max)
Return a random IntType in the range [a_Min, a_Max].
bool RandBool(double a_TrueProbability=0.5)
Return a random bool with the given probability of being true.
cEntityList & GetEntities(void)
cChunkDef::BlockTypes & GetBlockTypes(void)
cBlockEntities & GetBlockEntities(void)
void CompressBlockMetas(cChunkDef::BlockNibbles &a_DestMetas)
Compresses the metas from the BlockArea format (1 meta per byte) into regular format (2 metas per byt...
cChunkDef::HeightMap & GetHeightMap(void)
cChunkDef::BiomeMap & GetBiomeMap(void)
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...
int FindKey(const AString &keyname) const
Returns index of specified key, or noID if not found.
bool WriteFile(const AString &a_FileName) const
Writes data stored in class to the specified ini file.
bool AddKeyComment(const int keyID, const AString &comment)
Add a key comment.
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 ...
bool SetValueB(const AString &a_KeyName, const AString &a_ValueName, const bool a_Value, const bool a_CreateIfNotExists=true)
int GetValueI(const AString &keyname, const AString &valuename, const int defValue=0) const
void AddHeaderComment(const AString &comment)
Adds a header comment.
int GetValueSetI(const AString &keyname, const AString &valuename, const int defValue=0) override
bool SetValueI(const AString &a_KeyName, const AString &a_ValueName, const int a_Value, const bool a_CreateIfNotExists=true) override
bool SetValue(const int keyID, const int valueID, const AString &value)
AString GetValueSet(const AString &keyname, const AString &valuename, const AString &defValue="") override
Gets the value; if not found, write the default to the repository.
bool GetValueSetB(const AString &keyname, const AString &valuename, const bool defValue=false) override
int FindValue(const int keyID, const AString &valuename) const
Returns index of specified value, in the specified key, or noID if not found.
This class bridges a vector of cItem for safe access via Lua.
size_t GetQueueLength(void)
void QueueChunk(int a_ChunkX, int a_ChunkZ, std::unique_ptr< cChunkCoordCallback > a_CallbackAfter)
Queues the entire chunk for lighting.
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 LoadMapData(void)
Loads the map data from the disk.
void TickMaps(void)
Ticks each registered map.
void SaveMapData(void)
Saves the map data to the disk.
This class is used to collect information, for each Mob, what is the distance of the closest player i...
bool IsCapped(cMonster::eFamily a_MobFamily)
Returns true if the family is capped (i.e.
static cTickTime GetSpawnDelay(cMonster::eFamily a_MobFamily)
Returns the spawn delay (number of game ticks between spawn attempts) for the given mob family.
static std::unique_ptr< cMonster > NewMonsterFromType(eMonsterType a_MobType)
Creates a new object of the specified mob.
static eMonsterType StringToMobType(const AString &a_MobTypeName)
Translates MobType string to the enum, mtInvalidType if not recognized.
This class is used to determine which monster can be spawned in which place it is essentially static ...
int IntNoise2DInt(int a_X, int a_Y) const
RAII for cCriticalSection - locks the CS on creation, unlocks on destruction.
static bool CreateFolderRecursive(const AString &a_FolderPath)
Creates a new folder with the specified name, creating its parents if needed.
void Stop(void)
Signals the thread to terminate and waits until it's finished.
void Start(void)
Starts the thread; returns without waiting for the actual start.
cPluginManager * GetPluginManager(void)
Contains the data for a loaded / generated chunk, ready to be set into a cWorld.
void Simulate(float a_Dt)
Called in each tick, a_Dt is the time passed since the last tick, in msec.
static void PrepareChunks(cWorld &a_World, int a_SpawnChunkX, int a_SpawnChunkZ, int a_PrepareDistance)
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.
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.
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).
cRedstoneSimulator * InitializeRedstoneSimulator(cIniFile &a_IniFile)
Creates a new redstone simulator.
bool IsSlimeChunk(int a_ChunkX, int a_ChunkZ) const
Returns true if slimes should spawn in the chunk.
void ScheduleTask(cTickTime a_DelayTicks, std::function< void(cWorld &)> a_Task)
Queues a lambda task onto the tick thread, with the specified delay.
int GetSeed(void) const
Returns the seed of the world.
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...
void MarkChunkDirty(int a_ChunkX, int a_ChunkZ)
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.
virtual void BroadcastThunderbolt(Vector3i a_BlockPos, const cClientHandle *a_Exclude=nullptr) override
bool m_bCommandBlocksEnabled
Whether command blocks are enabled or not.
UInt32 SpawnMobFinalize(std::unique_ptr< cMonster > a_Monster)
Wraps cEntity::Initialize, doing Monster-specific things before spawning the monster.
void ChunkLoadFailed(int a_ChunkX, int a_ChunkZ)
Marks the chunk as failed-to-load:
void TickMobs(std::chrono::milliseconds a_Dt)
Handles the mob spawning / moving / destroying each tick.
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.
cChunkSender m_ChunkSender
UInt32 SpawnPrimedTNT(double a_X, double a_Y, double a_Z, int a_FuseTimeInSec=80, double a_InitialVelocityCoeff=1, bool a_ShouldPlayFuseSound=true)
bool IsSavingEnabled(void) const
Get whether saving chunks is enabled.
virtual ~cWorld() override
void RemoveClientFromChunks(cClientHandle *a_Client)
Removes the client from all chunks it is present in.
bool CheckPlayerSpawnPoint(int a_PosX, int a_PosY, int a_PosZ)
Check if player starting point is acceptable.
eShrapnelLevel m_TNTShrapnelLevel
The level of DoExplosionAt() projecting random affected blocks as FallingBlock entities See the eShra...
bool DoWithPlayerByUUID(const cUUID &a_PlayerUUID, cPlayerListCallback a_Callback)
Finds the player over his uuid and calls the callback.
void AddEntity(OwnedEntity a_Entity, cWorld *a_OldWorld=nullptr)
Adds the entity into its appropriate chunk; takes ownership of the entity ptr.
UInt32 SpawnExperienceOrb(Vector3d a_Pos, int a_Reward)
Spawns an experience orb at the given location with the given reward.
std::chrono::milliseconds m_WorldDate
The fully controllable age of the world.
std::unique_ptr< cSandSimulator > m_SandSimulator
virtual void BroadcastPlayerListUpdatePing() override
bool DoWithChunkAt(Vector3i a_BlockPos, cChunkCallback a_Callback)
Calls the callback for the chunk at the block position specified, with ChunkMapCS locked.
size_t GetPlayerCount() const
Returns the number of players currently in this world.
cLightingThread m_Lighting
virtual void BroadcastTimeUpdate(const cClientHandle *a_Exclude=nullptr) override
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.
int m_MinThunderStormTicks
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.
void RegenerateChunk(int a_ChunkX, int a_ChunkZ)
Regenerate the given chunk.
void UnloadUnusedChunks(void)
Unloads all chunks immediately.
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.
std::chrono::milliseconds m_WorldAge
The age of the world.
std::vector< BlockTickQueueItem * > m_BlockTickQueueCopy
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.
void QueueSetChunkData(SetChunkData &&a_SetChunkData)
Puts the chunk data into a queue to be set into the chunkmap in the tick thread.
cRedstoneSimulator * m_RedstoneSimulator
void TabCompleteUserName(const AString &a_Text, AStringVector &a_Results)
Appends all usernames starting with a_Text (case-insensitive) into Results.
UInt32 SpawnBoat(double a_X, double a_Y, double a_Z, cBoat::eMaterial a_Material)
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...
NIBBLETYPE GetBlockSkyLight(Vector3i a_BlockPos) const
Returns the sky light value at the specified block position.
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...
int GrowPlantAt(Vector3i a_BlockPos, int a_NumStages=1)
Grows the plant at the specified position by at most a_NumStages.
bool GrowRipePlant(Vector3i a_BlockPos)
Grows the plant at the specified block to its ripe stage.
int GetDefaultWeatherInterval(eWeather a_Weather) const
Returns the default weather interval for the specific weather type.
bool DoWithChunk(int a_ChunkX, int a_ChunkZ, cChunkCallback a_Callback)
Calls the callback for the chunk specified, with ChunkMapCS locked.
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.
BLOCKTYPE GetBlock(Vector3i a_BlockPos) const
Returns the block type at the specified position.
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).
bool SetAreaBiome(int a_MinX, int a_MaxX, int a_MinZ, int a_MaxZ, EMCSBiome a_Biome)
Sets the biome at the area.
int GetTickRandomNumber(int a_Range)
Returns a random number in range [0 .
void QueueUnloadUnusedChunks(void)
Queues a task to unload unused chunks onto the tick thread.
int m_MaxNetherPortalHeight
cCriticalSection m_CSTasks
Guards the m_Tasks.
virtual cTickTimeLong GetWorldAge(void) const override
bool GetChunkData(cChunkCoords a_Coords, cChunkDataCallback &a_Callback) const
Calls the callback with the chunk's data, if available (with ChunkCS locked).
void TickQueuedChunkDataSets()
Sets the chunk data queued in the m_SetChunkDataQueue queue into their chunk.
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...
void MarkChunkSaved(int a_ChunkX, int a_ChunkZ)
NIBBLETYPE GetBlockBlockLight(Vector3i a_BlockPos) const
Returns the block-light value at the specified block position.
void RemoveChunkClient(int a_ChunkX, int a_ChunkZ, cClientHandle *a_Client)
Removes client from the chunk specified.
std::vector< cPlayer * > m_Players
UInt32 SpawnEnderCrystal(Vector3d a_Pos, bool a_ShowBottom)
Spawns a new ender crystal at the specified block coords.
const AString & GetName(void) const
Returns the name of the 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.
bool GetBlockTypeMeta(Vector3i a_BlockPos, BLOCKTYPE &a_BlockType, NIBBLETYPE &a_BlockMeta) const
Retrieves the block type and meta at the specified coords.
bool m_BroadcastAchievementMessages
bool m_bUseChatPrefixes
Whether prefixes such as [INFO] are prepended to SendMessageXXX() / BroadcastChatXXX() functions.
int m_StorageCompressionFactor
void TickWeather(float a_Dt)
Handles the weather in each tick.
void GetChunkStats(int &a_NumValid, int &a_NumDirty, int &a_NumInLightingQueue)
Returns the number of chunks loaded and dirty, and in the lighting queue.
int m_MaxViewDistance
The maximum view distance that a player can have in this world.
std::atomic< bool > m_IsSavingEnabled
Whether or not writing chunks to disk is currently enabled.
bool IsChunkValid(int a_ChunkX, int a_ChunkZ) const
Returns true iff the chunk is present and valid.
void QueueTask(std::function< void(cWorld &)> a_Task)
Queues a task onto the tick thread.
AString GetLinkedOverworldName(void) const
bool m_IsDaylightCycleEnabled
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.
bool IsWeatherSunnyAt(int a_BlockX, int a_BlockZ) const
Returns true if it is sunny at the specified location.
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...
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 GenerateRandomSpawn(int a_MaxSpawnRadius)
Generates a random spawnpoint on solid land by walking chunks and finding their biomes.
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.
virtual void BroadcastSoundParticleEffect(const EffectID a_EffectID, Vector3i a_SrcPos, int a_Data, const cClientHandle *a_Exclude=nullptr) override
void TickClients(std::chrono::milliseconds a_Dt)
Ticks all clients that are in this world.
virtual eDimension GetDimension(void) const override
void SaveAllChunks(void)
Saves all chunks immediately.
void SendPlayerList(cPlayer *a_DestPlayer)
void TickQueuedTasks(void)
Executes all tasks queued onto the tick thread.
std::unique_ptr< cFireSimulator > m_FireSimulator
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 SetNextBlockToTick(const Vector3i a_BlockPos)
Causes the specified block to be ticked on the next Tick() call.
int m_MaxNetherPortalWidth
void InitializeSpawn(void)
bool DigBlock(Vector3i a_BlockPos, const cEntity *a_Digger=nullptr)
Replaces the specified block with air, and calls the OnBroken block handler.
void GenerateChunk(int a_ChunkX, int a_ChunkZ)
Generates the given chunk.
void InitializeAndLoadMobSpawningValues(cIniFile &a_IniFile)
Sets mob spawning values if nonexistant to their dimension specific defaults.
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.
bool IsBlockDirectlyWatered(int a_BlockX, int a_BlockY, int a_BlockZ)
bool IsChunkQueued(int a_ChunkX, int a_ChunkZ) const
Returns true iff the chunk is in the loader / generator queue.
size_t m_UnusedDirtyChunksCap
The maximum number of allowed unused dirty chunks for this world.
cFluidSimulator * m_LavaSimulator
cChunkGeneratorThread m_Generator
The thread responsible for generating chunks.
NIBBLETYPE GetBlockMeta(Vector3i a_BlockPos) const
Returns the block meta at the specified position.
AString m_LinkedOverworldName
The name of the overworld that portals in this world should link to.
bool GrowTreeFromSapling(Vector3i a_BlockPos)
Grows a tree from the sapling at the specified coords.
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.
void CollectPickupsByEntity(cEntity &a_Entity)
bool m_BroadcastDeathMessages
bool m_ShouldLavaSpawnFire
std::set< eMonsterType > m_AllowedMobs
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.
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.
virtual void WakeUpSimulators(Vector3i a_Block) override
Wakes up the simulators for the specified block.
bool SetCommandBlockCommand(int a_BlockX, int a_BlockY, int a_BlockZ, const AString &a_Command)
Sets the command block command.
bool SetTrapdoorOpen(int a_BlockX, int a_BlockY, int a_BlockZ, bool a_Open)
Set the state of a trapdoor.
void Start()
Starts threads that belong to this world.
void TickQueuedBlocks(void)
Processes the blocks queued for ticking with a delay (m_BlockTickQueue[])
eDimension m_Dimension
The dimension of the world, used by the client to provide correct lighting scheme.
virtual void BroadcastWeather(eWeather a_Weather, const cClientHandle *a_Exclude=nullptr) override
void ChunkLighted(int a_ChunkX, int a_ChunkZ, const cChunkDef::BlockNibbles &a_BlockLight, const cChunkDef::BlockNibbles &a_SkyLight)
bool HasChunkAnyClients(int a_ChunkX, int a_ChunkZ) const
void ChangeWeather(void)
Forces a weather change in the next game tick.
std::unique_ptr< cSimulatorManager > m_SimulatorManager
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.
bool GrowTreeImage(const sSetBlockVector &a_Blocks)
Imprints the specified blocks into the world, as long as each log block replaces only allowed blocks.
bool ForEachEntity(cEntityCallback a_Callback)
Calls the callback for each entity in the entire world; returns true if all entities processed,...
bool SetSpawn(int a_X, int a_Y, int a_Z)
Set default spawn at the given coordinates.
void TickQueuedEntityAdditions(void)
Adds the entities queued in the m_EntitiesToAdd queue into their chunk.
std::map< cMonster::eFamily, cTickTimeLong > m_LastSpawnMonster
size_t GetNumUnusedDirtyChunks(void) const
Returns the number of unused dirty chunks.
cTickTimeLong m_WorldTickAge
The time since this world began, in ticks.
void MarkChunkSaving(int a_ChunkX, int a_ChunkZ)
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.
virtual bool IsWeatherWetAt(int a_BlockX, int a_BlockZ) override
Returns true if it is raining or storming at the specified location.
cChunkGeneratorCallbacks m_GeneratorCallbacks
The callbacks that the ChunkGenerator uses to store new chunks and interface to plugins.
cCriticalSection m_CSEntitiesToAdd
Guards m_EntitiesToAdd.
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.
unsigned int m_MaxPlayers
bool GrowTreeByBiome(Vector3i a_BlockPos)
Grows a tree at the specified coords, based on the biome in the place.
bool GrowTree(Vector3i a_BlockPos)
Grows a tree at the specified coords.
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.
void QueueSaveAllChunks(void)
Queues a task to save all chunks onto the tick thread.
std::vector< SetChunkData > m_SetChunkDataQueue
Queue for the chunk data to be set into m_ChunkMap by the tick thread.
std::chrono::milliseconds m_LastChunkCheck
EMCSBiome GetBiomeAt(int a_BlockX, int a_BlockZ)
Returns the biome at the specified coords.
AString m_StorageSchema
Name of the storage schema used to load and save chunks.
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...
bool m_bFarmlandTramplingEnabled
UInt32 SpawnMinecart(Vector3d a_Pos, int a_MinecartType, const cItem &a_Content=cItem(), int a_BlockHeight=1)
Spawns an minecart at the given coordinates.
const AString & GetIniFileName(void) const
Returns the name of the world.ini file used by this world.
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...
int m_MaxThunderStormTicks
virtual cTickTime GetTimeOfDay(void) const override
bool SetBiomeAt(int a_BlockX, int a_BlockZ, EMCSBiome a_Biome)
Sets the biome at the specified coords.
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...
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...
std::vector< std::pair< OwnedEntity, cWorld * > > m_EntitiesToAdd
List of entities that are scheduled for adding, waiting for the Tick thread to add them.
int m_MinNetherPortalWidth
cTickTimeLong GetWorldTickAge() const
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 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.
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)
AString m_DataPath
The path to the root directory for the world files.
std::vector< BlockTickQueueItem * > m_BlockTickQueue
std::chrono::milliseconds m_LastSave
eWeather ChooseNewWeather(void)
Chooses a reasonable transition from the current weather to a new weather.
void CastThunderbolt(Vector3i a_Block)
Casts a thunderbolt at the specified coords.
UInt32 SpawnFallingBlock(Vector3d a_Pos, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta)
Spawns an falling block entity at the given position.
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.
void SetMaxViewDistance(int a_MaxViewDistance)
size_t GetNumChunks() const
Returns the number of chunks loaded
AString m_LinkedEndWorldName
Name of the End world - where End portals should teleport.
cCriticalSection m_CSSetChunkDataQueue
CS protecting m_SetChunkDataQueue.
virtual void BroadcastSoundEffect(const AString &a_SoundName, Vector3d a_Position, float a_Volume, float a_Pitch, const cClientHandle *a_Exclude=nullptr) override
virtual void SendBlockTo(int a_BlockX, int a_BlockY, int a_BlockZ, const cPlayer &a_Player)=0
Sends the block on those coords to the player.
bool GetBlocks(sSetBlockVector &a_Blocks, bool a_ContinueOnFailure)
Retrieves block types of the specified blocks.
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 ForEachLoadedChunk(cFunctionRef< bool(int, int)> a_Callback)
Calls the callback for each loaded chunk.
void WakeUpSimulatorsInArea(const cCuboid &a_Area)
Wakes up the simulators for the specified area of blocks.
cTickTimeLong GetWorldDate() const
void SetBlockMeta(Vector3i a_BlockPos, NIBBLETYPE a_MetaData)
Sets the meta for the specified block, while keeping the blocktype.
cChunkMap * GetChunkMap(void)
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,...
void UpdateSkyDarkness(void)
cSimulatorManager * GetSimulatorManager(void)
bool IsChunkLighted(int a_ChunkX, int a_ChunkZ)
int m_MinNetherPortalHeight
OwnedEntity RemoveEntity(cEntity &a_Entity)
Removes the entity from the world.
bool m_VillagersShouldHarvestCrops
void Tick(std::chrono::milliseconds a_Dt, std::chrono::milliseconds a_LastTickDurationMSec)
virtual bool ForEachPlayer(cPlayerListCallback a_Callback) override
Calls the callback for each player in the list; returns true if all players processed,...
virtual void SetTimeOfDay(cTickTime a_TimeOfDay) override
void SetBlock(Vector3i a_BlockPos, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta)
Sets the block at the specified coords to the specified value.
void SetWeather(eWeather a_NewWeather)
Sets the specified weather; resets weather interval; asks and notifies plugins of the change.
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.
void Stop(cDeadlockDetect &a_DeadlockDetect)
Stops threads that belong to this world (part of deinit).
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.
bool m_IsSpawnExplicitlySet
cFluidSimulator * m_WaterSimulator
A simple RAII locker for the chunkmap - locks the chunkmap in its constructor, unlocks it in the dest...
cLock(const cWorld &a_World)
cTickThread(cWorld &a_World)
virtual void Execute(void) override
This function, overloaded by the descendants, is called in the new thread.
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...
cChunkGeneratorCallbacks(cWorld &a_World)
virtual void CallHookChunkGenerated(cChunkDesc &a_ChunkDesc) override
Called after the chunk is generated, before it is handed to the chunk sink.
virtual void CallHookChunkGenerating(cChunkDesc &a_ChunkDesc) override
Called when the chunk is about to be generated.
virtual bool HasChunkAnyClients(cChunkCoords a_Coords) override
Called when the generator is overloaded to skip chunks that are no longer needed.
virtual void OnChunkGenerated(cChunkDesc &a_ChunkDesc) override
Called after the chunk has been generated The interface may store the chunk, send it over network,...
virtual bool IsChunkQueued(cChunkCoords a_Coords) override
Called to check whether the specified chunk is in the queued state.
bool Load(void)
Try to load the scoreboard.
bool Save(void)
Try to save the scoreboard.
void Initialize(cWorld &a_World, const AString &a_StorageSchemaName, int a_StorageCompressionFactor)
Initializes the storage schemas, ready to be started.