Broadcast refactor (#4264)
* Move Broadcast functions from cChunkMap to cBroadcaster - Remove cBroadcastInterface in favour of cBroadcaster. - cChunk: Remove broadcast functions. * resurect broadcast interface * Absorb cBroadcaster into cWorld. Removes the need for forwarding the function calls. * Improve const-correctness * Use Int8 instead of char + Comment `ForClients` functions * Improve comments * Broadcaster: Rename ForClients functions
This commit is contained in:
parent
b5f29d5d2c
commit
c94d7184eb
@ -6,7 +6,6 @@
|
||||
#include "Globals.h"
|
||||
#include "tolua++/include/tolua++.h"
|
||||
#include "../World.h"
|
||||
#include "../Broadcaster.h"
|
||||
#include "../UUID.h"
|
||||
#include "ManualBindings.h"
|
||||
#include "LuaState.h"
|
||||
@ -54,7 +53,7 @@ static int tolua_cWorld_BroadcastParticleEffect(lua_State * tolua_S)
|
||||
L.GetStackValue(11 + i, data[static_cast<size_t>(i)]);
|
||||
}
|
||||
|
||||
World->GetBroadcaster().BroadcastParticleEffect(Name, Vector3f(PosX, PosY, PosZ), Vector3f(OffX, OffY, OffZ), ParticleData, ParticleAmount, ExcludeClient);
|
||||
World->BroadcastParticleEffect(Name, Vector3f(PosX, PosY, PosZ), Vector3f(OffX, OffY, OffZ), ParticleData, ParticleAmount, ExcludeClient);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -178,11 +178,9 @@ void cMobSpawnerEntity::SpawnEntity(void)
|
||||
if (Chunk->GetWorld()->SpawnMobFinalize(std::move(Monster)) != cEntity::INVALID_ID)
|
||||
{
|
||||
HaveSpawnedEntity = true;
|
||||
Chunk->BroadcastSoundParticleEffect(
|
||||
m_World->BroadcastSoundParticleEffect(
|
||||
EffectID::PARTICLE_MOBSPAWN,
|
||||
static_cast<int>(PosX * 8.0),
|
||||
static_cast<int>(RelY * 8.0),
|
||||
static_cast<int>(PosZ * 8.0),
|
||||
Vector3d(PosX, RelY, PosZ).Floor(),
|
||||
0
|
||||
);
|
||||
NearbyEntities++;
|
||||
|
@ -91,7 +91,7 @@ bool cBlockBedHandler::OnUse(cChunkInterface & a_ChunkInterface, cWorldInterface
|
||||
if ((Meta & 0x8) == 0x8)
|
||||
{
|
||||
// Is pillow
|
||||
a_WorldInterface.GetBroadcastManager().BroadcastUseBed(a_Player, a_BlockX, a_BlockY, a_BlockZ);
|
||||
a_WorldInterface.GetBroadcastManager().BroadcastUseBed(a_Player, { a_BlockX, a_BlockY, a_BlockZ });
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -101,7 +101,7 @@ bool cBlockBedHandler::OnUse(cChunkInterface & a_ChunkInterface, cWorldInterface
|
||||
PillowDirection = MetaDataToDirection(Meta & 0x3);
|
||||
if (a_ChunkInterface.GetBlock(Coords + PillowDirection) == E_BLOCK_BED) // Must always use pillow location for sleeping
|
||||
{
|
||||
a_WorldInterface.GetBroadcastManager().BroadcastUseBed(a_Player, a_BlockX + PillowDirection.x, a_BlockY, a_BlockZ + PillowDirection.z);
|
||||
a_WorldInterface.GetBroadcastManager().BroadcastUseBed(a_Player, Vector3i{ a_BlockX, a_BlockY, a_BlockZ } + PillowDirection);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -39,7 +39,7 @@ public:
|
||||
// Flip the ON bit on / off using the XOR bitwise operation
|
||||
NIBBLETYPE Meta = (a_ChunkInterface.GetBlockMeta({a_BlockX, a_BlockY, a_BlockZ}) ^ 0x04);
|
||||
a_ChunkInterface.SetBlockMeta(a_BlockX, a_BlockY, a_BlockZ, Meta);
|
||||
a_WorldInterface.GetBroadcastManager().BroadcastSoundParticleEffect(EffectID::SFX_RANDOM_FENCE_GATE_OPEN, a_BlockX, a_BlockY, a_BlockZ, 0, a_Player.GetClientHandle());
|
||||
a_WorldInterface.GetBroadcastManager().BroadcastSoundParticleEffect(EffectID::SFX_RANDOM_FENCE_GATE_OPEN, { a_BlockX, a_BlockY, a_BlockZ }, 0, a_Player.GetClientHandle());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -1,9 +1,15 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "EffectID.h"
|
||||
|
||||
#include "Defines.h"
|
||||
#include "Scoreboard.h"
|
||||
|
||||
// fwd:
|
||||
class cClientHandle;
|
||||
class cCompositeChat;
|
||||
class cPlayer;
|
||||
class cWorld;
|
||||
enum class EffectID : Int32;
|
||||
|
||||
|
||||
|
||||
@ -12,8 +18,52 @@ class cBroadcastInterface
|
||||
public:
|
||||
virtual ~cBroadcastInterface() {}
|
||||
|
||||
virtual void BroadcastUseBed (const cEntity & a_Entity, int a_BlockX, int a_BlockY, int a_BlockZ) = 0;
|
||||
virtual void BroadcastSoundEffect(const AString & a_SoundName, Vector3d a_Position, float a_Volume, float a_Pitch, const cClientHandle * a_Exclude = nullptr) = 0;
|
||||
virtual void BroadcastEntityAnimation(const cEntity & a_Entity, char a_Animation, const cClientHandle * a_Exclude = nullptr) = 0;
|
||||
virtual void BroadcastSoundParticleEffect(const EffectID a_EffectID, int a_SrcX, int a_SrcY, int a_SrcZ, int a_Data, const cClientHandle * a_Exclude = nullptr) = 0;
|
||||
// Broadcast respective packets to all clients of the chunk where the event is taking place
|
||||
// (Please keep these alpha-sorted)
|
||||
virtual void BroadcastAttachEntity (const cEntity & a_Entity, const cEntity & a_Vehicle) = 0;
|
||||
virtual void BroadcastBlockAction (Vector3i a_BlockPos, Byte a_Byte1, Byte a_Byte2, BLOCKTYPE a_BlockType, const cClientHandle * a_Exclude = nullptr) = 0;
|
||||
virtual void BroadcastBlockBreakAnimation (UInt32 a_EntityID, Vector3i a_BlockPos, Int8 a_Stage, const cClientHandle * a_Exclude = nullptr) = 0;
|
||||
virtual void BroadcastBlockEntity (Vector3i a_BlockPos, const cClientHandle * a_Exclude = nullptr) = 0;
|
||||
virtual void BroadcastChat (const AString & a_Message, const cClientHandle * a_Exclude = nullptr, eMessageType a_ChatPrefix = mtCustom) = 0;
|
||||
virtual void BroadcastChatInfo (const AString & a_Message, const cClientHandle * a_Exclude = nullptr) = 0;
|
||||
virtual void BroadcastChatFailure (const AString & a_Message, const cClientHandle * a_Exclude = nullptr) = 0;
|
||||
virtual void BroadcastChatSuccess (const AString & a_Message, const cClientHandle * a_Exclude = nullptr) = 0;
|
||||
virtual void BroadcastChatWarning (const AString & a_Message, const cClientHandle * a_Exclude = nullptr) = 0;
|
||||
virtual void BroadcastChatFatal (const AString & a_Message, const cClientHandle * a_Exclude = nullptr) = 0;
|
||||
virtual void BroadcastChatDeath (const AString & a_Message, const cClientHandle * a_Exclude = nullptr) = 0;
|
||||
virtual void BroadcastChat (const cCompositeChat & a_Message, const cClientHandle * a_Exclude = nullptr) = 0;
|
||||
virtual void BroadcastCollectEntity (const cEntity & a_Pickup, const cPlayer & a_Player, int a_Count, const cClientHandle * a_Exclude = nullptr) = 0;
|
||||
virtual void BroadcastDestroyEntity (const cEntity & a_Entity, const cClientHandle * a_Exclude = nullptr) = 0;
|
||||
virtual void BroadcastDetachEntity (const cEntity & a_Entity, const cEntity & a_PreviousVehicle) = 0;
|
||||
virtual void BroadcastEntityEffect (const cEntity & a_Entity, int a_EffectID, int a_Amplifier, short a_Duration, const cClientHandle * a_Exclude = nullptr) = 0;
|
||||
virtual void BroadcastEntityEquipment (const cEntity & a_Entity, short a_SlotNum, const cItem & a_Item, const cClientHandle * a_Exclude = nullptr) = 0;
|
||||
virtual void BroadcastEntityHeadLook (const cEntity & a_Entity, const cClientHandle * a_Exclude = nullptr) = 0;
|
||||
virtual void BroadcastEntityLook (const cEntity & a_Entity, const cClientHandle * a_Exclude = nullptr) = 0;
|
||||
virtual void BroadcastEntityMetadata (const cEntity & a_Entity, const cClientHandle * a_Exclude = nullptr) = 0;
|
||||
virtual void BroadcastEntityRelMove (const cEntity & a_Entity, Vector3<Int8> a_RelMove, const cClientHandle * a_Exclude = nullptr) = 0;
|
||||
virtual void BroadcastEntityRelMoveLook (const cEntity & a_Entity, Vector3<Int8> a_RelMove, const cClientHandle * a_Exclude = nullptr) = 0;
|
||||
virtual void BroadcastEntityStatus (const cEntity & a_Entity, Int8 a_Status, const cClientHandle * a_Exclude = nullptr) = 0;
|
||||
virtual void BroadcastEntityVelocity (const cEntity & a_Entity, const cClientHandle * a_Exclude = nullptr) = 0;
|
||||
virtual void BroadcastEntityAnimation (const cEntity & a_Entity, Int8 a_Animation, const cClientHandle * a_Exclude = nullptr) = 0;
|
||||
virtual void BroadcastLeashEntity (const cEntity & a_Entity, const cEntity & a_EntityLeashedTo) = 0;
|
||||
virtual void BroadcastParticleEffect (const AString & a_ParticleName, Vector3f a_Src, Vector3f a_Offset, float a_ParticleData, int a_ParticleAmount, const cClientHandle * a_Exclude = nullptr) = 0;
|
||||
virtual void BroadcastParticleEffect (const AString & a_ParticleName, Vector3f a_Src, Vector3f a_Offset, float a_ParticleData, int a_ParticleAmount, std::array<int, 2> a_Data, const cClientHandle * a_Exclude = nullptr) = 0;
|
||||
virtual void BroadcastPlayerListAddPlayer (const cPlayer & a_Player, const cClientHandle * a_Exclude = nullptr) = 0;
|
||||
virtual void BroadcastPlayerListRemovePlayer (const cPlayer & a_Player, const cClientHandle * a_Exclude = nullptr) = 0;
|
||||
virtual void BroadcastPlayerListUpdateGameMode (const cPlayer & a_Player, const cClientHandle * a_Exclude = nullptr) = 0;
|
||||
virtual void BroadcastPlayerListUpdatePing (const cPlayer & a_Player, const cClientHandle * a_Exclude = nullptr) = 0;
|
||||
virtual void BroadcastPlayerListUpdateDisplayName(const cPlayer & a_Player, const AString & a_CustomName, const cClientHandle * a_Exclude = nullptr) = 0;
|
||||
virtual void BroadcastRemoveEntityEffect (const cEntity & a_Entity, int a_EffectID, const cClientHandle * a_Exclude = nullptr) = 0;
|
||||
virtual void BroadcastScoreboardObjective (const AString & a_Name, const AString & a_DisplayName, Byte a_Mode) = 0;
|
||||
virtual void BroadcastScoreUpdate (const AString & a_Objective, const AString & a_PlayerName, cObjective::Score a_Score, Byte a_Mode) = 0;
|
||||
virtual void BroadcastDisplayObjective (const AString & a_Objective, cScoreboard::eDisplaySlot a_Display) = 0;
|
||||
virtual void BroadcastSoundEffect (const AString & a_SoundName, Vector3d a_Position, float a_Volume, float a_Pitch, const cClientHandle * a_Exclude = nullptr) = 0;
|
||||
virtual void BroadcastSoundParticleEffect (const EffectID a_EffectID, Vector3i a_SrcPos, int a_Data, const cClientHandle * a_Exclude = nullptr) = 0;
|
||||
virtual void BroadcastSpawnEntity (cEntity & a_Entity, const cClientHandle * a_Exclude = nullptr) = 0;
|
||||
virtual void BroadcastTeleportEntity (const cEntity & a_Entity, const cClientHandle * a_Exclude = nullptr) = 0;
|
||||
virtual void BroadcastThunderbolt (Vector3i a_BlockPos, const cClientHandle * a_Exclude = nullptr) = 0;
|
||||
virtual void BroadcastTimeUpdate (const cClientHandle * a_Exclude = nullptr) = 0;
|
||||
virtual void BroadcastUnleashEntity (const cEntity & a_Entity) = 0;
|
||||
virtual void BroadcastUseBed (const cEntity & a_Entity, Vector3i a_BedPos) = 0;
|
||||
virtual void BroadcastWeather (eWeather a_Weather, const cClientHandle * a_Exclude = nullptr) = 0;
|
||||
};
|
||||
|
@ -1,60 +1,636 @@
|
||||
// Broadcaster.cpp
|
||||
|
||||
// Implements the broadcasting interface for cWorld
|
||||
// Implements the broadcasting functions for cWorld
|
||||
|
||||
#include "Globals.h"
|
||||
#include "Broadcaster.h"
|
||||
#include "World.h"
|
||||
#include "Chunk.h"
|
||||
#include "ClientHandle.h"
|
||||
#include "Entities/Entity.h"
|
||||
#include "Entities/Player.h"
|
||||
#include "BlockEntities/BlockEntity.h"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
cBroadcaster::cBroadcaster(cWorld * a_World) :
|
||||
m_World(a_World)
|
||||
namespace
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cBroadcaster::BroadcastParticleEffect(const AString & a_ParticleName, const Vector3f a_Src, const Vector3f a_Offset, float a_ParticleData, int a_ParticleAmount, cClientHandle * a_Exclude)
|
||||
{
|
||||
m_World->DoWithChunkAt(a_Src,
|
||||
[=](cChunk & a_Chunk) -> bool
|
||||
{
|
||||
for (auto && client : a_Chunk.GetAllClients())
|
||||
/** Calls the function object a_Func for every active client in the world
|
||||
\param a_World World the clients are in
|
||||
\param a_Exclude Client for which a_Func should not be called
|
||||
\param a_Func Function to be called with each non-excluded client */
|
||||
template <typename Func>
|
||||
void ForClientsInWorld(cWorld & a_World, const cClientHandle * a_Exclude, Func a_Func)
|
||||
{
|
||||
a_World.ForEachPlayer([&](cPlayer & a_Player)
|
||||
{
|
||||
if (client == a_Exclude)
|
||||
cClientHandle * Client = a_Player.GetClientHandle();
|
||||
if ((Client != a_Exclude) && (Client != nullptr) && Client->IsLoggedIn() && !Client->IsDestroyed())
|
||||
{
|
||||
continue;
|
||||
a_Func(*Client);
|
||||
}
|
||||
client->SendParticleEffect(a_ParticleName, a_Src.x, a_Src.y, a_Src.z, a_Offset.x, a_Offset.y, a_Offset.z, a_ParticleData, a_ParticleAmount);
|
||||
};
|
||||
return true;
|
||||
});
|
||||
}
|
||||
return false;
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cBroadcaster::BroadcastParticleEffect(const AString & a_ParticleName, const Vector3f a_Src, const Vector3f a_Offset, float a_ParticleData, int a_ParticleAmount, std::array<int, 2> a_Data, cClientHandle * a_Exclude)
|
||||
{
|
||||
m_World->DoWithChunkAt(a_Src,
|
||||
[=](cChunk & a_Chunk) -> bool
|
||||
{
|
||||
for (auto && client : a_Chunk.GetAllClients())
|
||||
/** Calls the function object a_Func for every client who has the specified chunk
|
||||
\param a_ChunkCoords Coords of the chunk to query for clients
|
||||
\param a_World World that the chunk is in
|
||||
\param a_Exclude Client for which a_Func should not be called
|
||||
\param a_Func Function to be called with each non-excluded client */
|
||||
template <typename Func>
|
||||
void ForClientsWithChunk(const cChunkCoords a_ChunkCoords, cWorld & a_World, const cClientHandle * a_Exclude, Func a_Func)
|
||||
{
|
||||
a_World.DoWithChunk(a_ChunkCoords.m_ChunkX, a_ChunkCoords.m_ChunkZ,
|
||||
[&](cChunk & a_Chunk)
|
||||
{
|
||||
if (client == a_Exclude)
|
||||
for (auto * Client : a_Chunk.GetAllClients())
|
||||
{
|
||||
continue;
|
||||
if (Client != a_Exclude)
|
||||
{
|
||||
a_Func(*Client);
|
||||
}
|
||||
};
|
||||
return true;
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/** Calls the function object a_Func for every client who has the chunk at the specified block position
|
||||
\param a_WorldPos Coordinates of the block to query for clients
|
||||
\param a_World World that the block is in
|
||||
\param a_Exclude Client for which a_Func should not be called
|
||||
\param a_Func Function to be called with each non-excluded client */
|
||||
template <typename Func>
|
||||
void ForClientsWithChunkAtPos(const Vector3i a_WorldPos, cWorld & a_World, const cClientHandle * a_Exclude, Func a_Func)
|
||||
{
|
||||
ForClientsWithChunk(cChunkDef::BlockToChunk(a_WorldPos), a_World, a_Exclude, std::move(a_Func));
|
||||
}
|
||||
|
||||
|
||||
|
||||
/** Calls the function object a_Func for every client who has the specified entity
|
||||
\param a_Entity Entity to query for clients
|
||||
\param a_World World that the block is in
|
||||
\param a_Exclude Client for which a_Func should not be called
|
||||
\param a_Func Function to be called with each non-excluded client */
|
||||
template <typename Func>
|
||||
void ForClientsWithEntity(const cEntity & a_Entity, cWorld & a_World, const cClientHandle * a_Exclude, Func a_Func)
|
||||
{
|
||||
cWorld::cLock Lock(a_World); // Lock world before accessing a_Entity
|
||||
auto Chunk = a_Entity.GetParentChunk();
|
||||
if (Chunk != nullptr)
|
||||
{
|
||||
for (auto * Client : Chunk->GetAllClients())
|
||||
{
|
||||
if (Client != a_Exclude)
|
||||
{
|
||||
a_Func(*Client);
|
||||
}
|
||||
client->SendParticleEffect(a_ParticleName, a_Src, a_Offset, a_ParticleData, a_ParticleAmount, a_Data);
|
||||
};
|
||||
return true;
|
||||
});
|
||||
}
|
||||
}
|
||||
else // Some broadcasts happen before the entity's first tick sets its ParentChunk
|
||||
{
|
||||
ForClientsWithChunk({ a_Entity.GetChunkX(), a_Entity.GetChunkZ() }, a_World, a_Exclude, std::move(a_Func));
|
||||
}
|
||||
}
|
||||
} // namespace (anonymous)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cWorld::BroadcastAttachEntity(const cEntity & a_Entity, const cEntity & a_Vehicle)
|
||||
{
|
||||
ForClientsWithEntity(a_Entity, *this, nullptr, [&](cClientHandle & a_Client)
|
||||
{
|
||||
a_Client.SendAttachEntity(a_Entity, a_Vehicle);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cWorld::BroadcastBlockAction(Vector3i a_BlockPos, Byte a_Byte1, Byte a_Byte2, BLOCKTYPE a_BlockType, const cClientHandle * a_Exclude)
|
||||
{
|
||||
ForClientsWithChunkAtPos(a_BlockPos, *this, a_Exclude, [&](cClientHandle & a_Client)
|
||||
{
|
||||
a_Client.SendBlockAction(a_BlockPos.x, a_BlockPos.y, a_BlockPos.z, static_cast<char>(a_Byte1), static_cast<char>(a_Byte2), a_BlockType);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cWorld::BroadcastBlockBreakAnimation(UInt32 a_EntityID, Vector3i a_BlockPos, Int8 a_Stage, const cClientHandle * a_Exclude)
|
||||
{
|
||||
ForClientsWithChunkAtPos(a_BlockPos, *this, a_Exclude, [&](cClientHandle & a_Client)
|
||||
{
|
||||
a_Client.SendBlockBreakAnim(a_EntityID, a_BlockPos.x, a_BlockPos.y, a_BlockPos.z, a_Stage);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cWorld::BroadcastBlockEntity(Vector3i a_BlockPos, const cClientHandle * a_Exclude)
|
||||
{
|
||||
DoWithChunkAt(a_BlockPos, [&](cChunk & a_Chunk)
|
||||
{
|
||||
cBlockEntity * Entity = a_Chunk.GetBlockEntity(a_BlockPos);
|
||||
if (Entity == nullptr)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
for (auto * Client : a_Chunk.GetAllClients())
|
||||
{
|
||||
if (Client != a_Exclude)
|
||||
{
|
||||
Entity->SendTo(*Client);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cWorld::BroadcastChat(const AString & a_Message, const cClientHandle * a_Exclude, eMessageType a_ChatPrefix)
|
||||
{
|
||||
ForClientsInWorld(*this, a_Exclude, [&](cClientHandle & a_Client)
|
||||
{
|
||||
a_Client.SendChat(a_Message, a_ChatPrefix);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cWorld::BroadcastChat(const cCompositeChat & a_Message, const cClientHandle * a_Exclude)
|
||||
{
|
||||
ForClientsInWorld(*this, a_Exclude, [&](cClientHandle & a_Client)
|
||||
{
|
||||
a_Client.SendChat(a_Message);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cWorld::BroadcastCollectEntity(const cEntity & a_Entity, const cPlayer & a_Player, int a_Count, const cClientHandle * a_Exclude)
|
||||
{
|
||||
ForClientsWithEntity(a_Entity, *this, a_Exclude, [&](cClientHandle & a_Client)
|
||||
{
|
||||
a_Client.SendCollectEntity(a_Entity, a_Player, a_Count);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cWorld::BroadcastDestroyEntity(const cEntity & a_Entity, const cClientHandle * a_Exclude)
|
||||
{
|
||||
ForClientsWithEntity(a_Entity, *this, a_Exclude, [&](cClientHandle & a_Client)
|
||||
{
|
||||
a_Client.SendDestroyEntity(a_Entity);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cWorld::BroadcastDetachEntity(const cEntity & a_Entity, const cEntity & a_PreviousVehicle)
|
||||
{
|
||||
ForClientsWithEntity(a_Entity, *this, nullptr, [&](cClientHandle & a_Client)
|
||||
{
|
||||
a_Client.SendDetachEntity(a_Entity, a_PreviousVehicle);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cWorld::BroadcastDisplayObjective(const AString & a_Objective, cScoreboard::eDisplaySlot a_Display)
|
||||
{
|
||||
ForClientsInWorld(*this, nullptr, [&](cClientHandle & a_Client)
|
||||
{
|
||||
a_Client.SendDisplayObjective(a_Objective, a_Display);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cWorld::BroadcastEntityEffect(const cEntity & a_Entity, int a_EffectID, int a_Amplifier, short a_Duration, const cClientHandle * a_Exclude)
|
||||
{
|
||||
ForClientsWithEntity(a_Entity, *this, a_Exclude, [&](cClientHandle & a_Client)
|
||||
{
|
||||
a_Client.SendEntityEffect(a_Entity, a_EffectID, a_Amplifier, a_Duration);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cWorld::BroadcastEntityEquipment(const cEntity & a_Entity, short a_SlotNum, const cItem & a_Item, const cClientHandle * a_Exclude)
|
||||
{
|
||||
ForClientsWithEntity(a_Entity, *this, a_Exclude, [&](cClientHandle & a_Client)
|
||||
{
|
||||
a_Client.SendEntityEquipment(a_Entity, a_SlotNum, a_Item);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cWorld::BroadcastEntityHeadLook(const cEntity & a_Entity, const cClientHandle * a_Exclude)
|
||||
{
|
||||
ForClientsWithEntity(a_Entity, *this, a_Exclude, [&](cClientHandle & a_Client)
|
||||
{
|
||||
a_Client.SendEntityHeadLook(a_Entity);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cWorld::BroadcastEntityLook(const cEntity & a_Entity, const cClientHandle * a_Exclude)
|
||||
{
|
||||
ForClientsWithEntity(a_Entity, *this, a_Exclude, [&](cClientHandle & a_Client)
|
||||
{
|
||||
a_Client.SendEntityLook(a_Entity);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cWorld::BroadcastEntityMetadata(const cEntity & a_Entity, const cClientHandle * a_Exclude)
|
||||
{
|
||||
ForClientsWithEntity(a_Entity, *this, a_Exclude, [&](cClientHandle & a_Client)
|
||||
{
|
||||
a_Client.SendEntityMetadata(a_Entity);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cWorld::BroadcastEntityRelMove(const cEntity & a_Entity, Vector3<Int8> a_RelMove, const cClientHandle * a_Exclude)
|
||||
{
|
||||
ForClientsWithEntity(a_Entity, *this, a_Exclude, [&](cClientHandle & a_Client)
|
||||
{
|
||||
a_Client.SendEntityRelMove(a_Entity, a_RelMove.x, a_RelMove.y, a_RelMove.z);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cWorld::BroadcastEntityRelMoveLook(const cEntity & a_Entity, Vector3<Int8> a_RelMove, const cClientHandle * a_Exclude)
|
||||
{
|
||||
ForClientsWithEntity(a_Entity, *this, a_Exclude, [&](cClientHandle & a_Client)
|
||||
{
|
||||
a_Client.SendEntityRelMoveLook(a_Entity, a_RelMove.x, a_RelMove.y, a_RelMove.z);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cWorld::BroadcastEntityStatus(const cEntity & a_Entity, Int8 a_Status, const cClientHandle * a_Exclude)
|
||||
{
|
||||
ForClientsWithEntity(a_Entity, *this, a_Exclude, [&](cClientHandle & a_Client)
|
||||
{
|
||||
a_Client.SendEntityStatus(a_Entity, a_Status);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cWorld::BroadcastEntityVelocity(const cEntity & a_Entity, const cClientHandle * a_Exclude)
|
||||
{
|
||||
ForClientsWithEntity(a_Entity, *this, a_Exclude, [&](cClientHandle & a_Client)
|
||||
{
|
||||
a_Client.SendEntityVelocity(a_Entity);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void cWorld::BroadcastEntityAnimation(const cEntity & a_Entity, Int8 a_Animation, const cClientHandle * a_Exclude)
|
||||
{
|
||||
ForClientsWithEntity(a_Entity, *this, a_Exclude, [&](cClientHandle & a_Client)
|
||||
{
|
||||
a_Client.SendEntityAnimation(a_Entity, a_Animation);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cWorld::BroadcastLeashEntity(const cEntity & a_Entity, const cEntity & a_EntityLeashedTo)
|
||||
{
|
||||
ForClientsWithEntity(a_Entity, *this, nullptr, [&](cClientHandle & a_Client)
|
||||
{
|
||||
a_Client.SendLeashEntity(a_Entity, a_EntityLeashedTo);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cWorld::BroadcastParticleEffect(const AString & a_ParticleName, const Vector3f a_Src, const Vector3f a_Offset, float a_ParticleData, int a_ParticleAmount, const cClientHandle * a_Exclude)
|
||||
{
|
||||
ForClientsWithChunkAtPos(a_Src, *this, a_Exclude, [&](cClientHandle & a_Client)
|
||||
{
|
||||
a_Client.SendParticleEffect(a_ParticleName, a_Src.x, a_Src.y, a_Src.z, a_Offset.x, a_Offset.y, a_Offset.z, a_ParticleData, a_ParticleAmount);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cWorld::BroadcastParticleEffect(const AString & a_ParticleName, const Vector3f a_Src, const Vector3f a_Offset, float a_ParticleData, int a_ParticleAmount, std::array<int, 2> a_Data, const cClientHandle * a_Exclude)
|
||||
{
|
||||
ForClientsWithChunkAtPos(a_Src, *this, a_Exclude, [&](cClientHandle & a_Client)
|
||||
{
|
||||
a_Client.SendParticleEffect(a_ParticleName, a_Src, a_Offset, a_ParticleData, a_ParticleAmount, a_Data);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cWorld::BroadcastPlayerListAddPlayer(const cPlayer & a_Player, const cClientHandle * a_Exclude)
|
||||
{
|
||||
ForClientsInWorld(*this, a_Exclude, [&](cClientHandle & a_Client)
|
||||
{
|
||||
a_Client.SendPlayerListAddPlayer(a_Player);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cWorld::BroadcastPlayerListRemovePlayer(const cPlayer & a_Player, const cClientHandle * a_Exclude)
|
||||
{
|
||||
ForClientsInWorld(*this, a_Exclude, [&](cClientHandle & a_Client)
|
||||
{
|
||||
a_Client.SendPlayerListRemovePlayer(a_Player);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cWorld::BroadcastPlayerListUpdateGameMode(const cPlayer & a_Player, const cClientHandle * a_Exclude)
|
||||
{
|
||||
ForClientsInWorld(*this, a_Exclude, [&](cClientHandle & a_Client)
|
||||
{
|
||||
a_Client.SendPlayerListUpdateGameMode(a_Player);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cWorld::BroadcastPlayerListUpdatePing(const cPlayer & a_Player, const cClientHandle * a_Exclude)
|
||||
{
|
||||
ForClientsInWorld(*this, a_Exclude, [&](cClientHandle & a_Client)
|
||||
{
|
||||
a_Client.SendPlayerListUpdatePing(a_Player);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cWorld::BroadcastPlayerListUpdateDisplayName(const cPlayer & a_Player, const AString & a_CustomName, const cClientHandle * a_Exclude)
|
||||
{
|
||||
ForClientsInWorld(*this, a_Exclude, [&](cClientHandle & a_Client)
|
||||
{
|
||||
a_Client.SendPlayerListUpdateDisplayName(a_Player, a_CustomName);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cWorld::BroadcastRemoveEntityEffect(const cEntity & a_Entity, int a_EffectID, const cClientHandle * a_Exclude)
|
||||
{
|
||||
ForClientsWithEntity(a_Entity, *this, a_Exclude, [&](cClientHandle & a_Client)
|
||||
{
|
||||
a_Client.SendRemoveEntityEffect(a_Entity, a_EffectID);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cWorld::BroadcastScoreboardObjective(const AString & a_Name, const AString & a_DisplayName, Byte a_Mode)
|
||||
{
|
||||
ForClientsInWorld(*this, nullptr, [&](cClientHandle & a_Client)
|
||||
{
|
||||
a_Client.SendScoreboardObjective(a_Name, a_DisplayName, a_Mode);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cWorld::BroadcastScoreUpdate(const AString & a_Objective, const AString & a_PlayerName, cObjective::Score a_Score, Byte a_Mode)
|
||||
{
|
||||
ForClientsInWorld(*this, nullptr, [&](cClientHandle & a_Client)
|
||||
{
|
||||
a_Client.SendScoreUpdate(a_Objective, a_PlayerName, a_Score, a_Mode);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cWorld::BroadcastSoundEffect(const AString & a_SoundName, Vector3d a_Position, float a_Volume, float a_Pitch, const cClientHandle * a_Exclude)
|
||||
{
|
||||
ForClientsWithChunkAtPos(a_Position, *this, a_Exclude, [&](cClientHandle & a_Client)
|
||||
{
|
||||
a_Client.SendSoundEffect(a_SoundName, a_Position, a_Volume, a_Pitch);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cWorld::BroadcastSoundParticleEffect(const EffectID a_EffectID, Vector3i a_SrcPos, int a_Data, const cClientHandle * a_Exclude)
|
||||
{
|
||||
ForClientsWithChunkAtPos(a_SrcPos, *this, a_Exclude, [&](cClientHandle & a_Client)
|
||||
{
|
||||
a_Client.SendSoundParticleEffect(a_EffectID, a_SrcPos.x, a_SrcPos.y, a_SrcPos.z, a_Data);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cWorld::BroadcastSpawnEntity(cEntity & a_Entity, const cClientHandle * a_Exclude)
|
||||
{
|
||||
ForClientsWithEntity(a_Entity, *this, a_Exclude, [&](cClientHandle & a_Client)
|
||||
{
|
||||
a_Entity.SpawnOn(a_Client);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cWorld::BroadcastTeleportEntity(const cEntity & a_Entity, const cClientHandle * a_Exclude)
|
||||
{
|
||||
ForClientsInWorld(*this, a_Exclude, [&](cClientHandle & a_Client)
|
||||
{
|
||||
a_Client.SendTeleportEntity(a_Entity);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cWorld::BroadcastThunderbolt(Vector3i a_BlockPos, const cClientHandle * a_Exclude)
|
||||
{
|
||||
ForClientsWithChunkAtPos(a_BlockPos, *this, a_Exclude, [&](cClientHandle & a_Client)
|
||||
{
|
||||
a_Client.SendThunderbolt(a_BlockPos.x, a_BlockPos.y, a_BlockPos.z);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cWorld::BroadcastTimeUpdate(const cClientHandle * a_Exclude)
|
||||
{
|
||||
ForClientsInWorld(*this, a_Exclude, [&](cClientHandle & a_Client)
|
||||
{
|
||||
a_Client.SendTimeUpdate(GetWorldAge(), GetTimeOfDay(), IsDaylightCycleEnabled());
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cWorld::BroadcastUnleashEntity(const cEntity & a_Entity)
|
||||
{
|
||||
ForClientsWithEntity(a_Entity, *this, nullptr, [&](cClientHandle & a_Client)
|
||||
{
|
||||
a_Client.SendUnleashEntity(a_Entity);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cWorld::BroadcastUseBed(const cEntity & a_Entity, Vector3i a_BedPos)
|
||||
{
|
||||
ForClientsWithChunkAtPos(a_BedPos, *this, nullptr, [&](cClientHandle & a_Client)
|
||||
{
|
||||
a_Client.SendUseBed(a_Entity, a_BedPos.x, a_BedPos.y, a_BedPos.z);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cWorld::BroadcastWeather(eWeather a_Weather, const cClientHandle * a_Exclude)
|
||||
{
|
||||
ForClientsInWorld(*this, a_Exclude, [&](cClientHandle & a_Client)
|
||||
{
|
||||
a_Client.SendWeather(a_Weather);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
@ -1,18 +0,0 @@
|
||||
|
||||
class cWorld;
|
||||
|
||||
class cBroadcaster
|
||||
{
|
||||
|
||||
public:
|
||||
|
||||
cBroadcaster(cWorld * a_World);
|
||||
|
||||
void BroadcastParticleEffect(const AString & a_ParticleName, const Vector3f a_Src, const Vector3f a_Offset, float a_ParticleData, int a_ParticleAmount, cClientHandle * a_Exclude = nullptr);
|
||||
|
||||
void BroadcastParticleEffect(const AString & a_ParticleName, const Vector3f a_Src, const Vector3f a_Offset, float a_ParticleData, int a_ParticleAmount, std::array<int, 2> a_Data, cClientHandle * a_Exclude = nullptr);
|
||||
|
||||
private:
|
||||
cWorld * m_World;
|
||||
|
||||
};
|
@ -85,7 +85,6 @@ SET (HDRS
|
||||
BlockInfo.h
|
||||
BlockTracer.h
|
||||
BrewingRecipes.h
|
||||
Broadcaster.h
|
||||
BoundingBox.h
|
||||
BuildInfo.h
|
||||
BuildInfo.h.cmake
|
||||
@ -136,6 +135,7 @@ SET (HDRS
|
||||
MobSpawner.h
|
||||
MonsterConfig.h
|
||||
NetherPortalScanner.h
|
||||
OpaqueWorld.h
|
||||
OverridesSettingsRepository.h
|
||||
ProbabDistrib.h
|
||||
RankManager.h
|
||||
|
402
src/Chunk.cpp
402
src/Chunk.cpp
@ -484,7 +484,7 @@ void cChunk::WriteBlockArea(cBlockArea & a_Area, int a_MinBlockX, int a_MinBlock
|
||||
auto clone = be->Clone(posX, posY, posZ);
|
||||
clone->SetWorld(m_World);
|
||||
AddBlockEntityClean(clone);
|
||||
BroadcastBlockEntity({posX, posY, posZ});
|
||||
m_World->BroadcastBlockEntity({posX, posY, posZ});
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -2636,406 +2636,6 @@ cChunk * cChunk::GetRelNeighborChunkAdjustCoords(int & a_RelX, int & a_RelZ) con
|
||||
|
||||
|
||||
|
||||
void cChunk::BroadcastAttachEntity(const cEntity & a_Entity, const cEntity & a_Vehicle)
|
||||
{
|
||||
for (auto ClientHandle : m_LoadedByClient)
|
||||
{
|
||||
ClientHandle->SendAttachEntity(a_Entity, a_Vehicle);
|
||||
} // for itr - LoadedByClient[]
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void cChunk::BroadcastLeashEntity(const cEntity & a_Entity, const cEntity & a_EntityLeashedTo)
|
||||
{
|
||||
for (auto ClientHandle : m_LoadedByClient)
|
||||
{
|
||||
ClientHandle->SendLeashEntity(a_Entity, a_EntityLeashedTo);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void cChunk::BroadcastUnleashEntity(const cEntity & a_Entity)
|
||||
{
|
||||
for (auto ClientHandle : m_LoadedByClient)
|
||||
{
|
||||
ClientHandle->SendUnleashEntity(a_Entity);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cChunk::BroadcastBlockAction(Vector3i a_BlockPos, char a_Byte1, char a_Byte2, BLOCKTYPE a_BlockType, const cClientHandle * a_Exclude)
|
||||
{
|
||||
for (auto itr = m_LoadedByClient.begin(); itr != m_LoadedByClient.end(); ++itr)
|
||||
{
|
||||
if (*itr == a_Exclude)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
(*itr)->SendBlockAction(a_BlockPos.x, a_BlockPos.y, a_BlockPos.z, a_Byte1, a_Byte2, a_BlockType);
|
||||
} // for itr - LoadedByClient[]
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cChunk::BroadcastBlockBreakAnimation(UInt32 a_EntityID, Vector3i a_BlockPos, char a_Stage, const cClientHandle * a_Exclude)
|
||||
{
|
||||
for (auto itr = m_LoadedByClient.begin(); itr != m_LoadedByClient.end(); ++itr)
|
||||
{
|
||||
if (*itr == a_Exclude)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
(*itr)->SendBlockBreakAnim(a_EntityID, a_BlockPos.x, a_BlockPos.y, a_BlockPos.z, a_Stage);
|
||||
} // for itr - LoadedByClient[]
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cChunk::BroadcastBlockEntity(Vector3i a_BlockPos, const cClientHandle * a_Exclude)
|
||||
{
|
||||
// We can operate on entity pointers, we're inside the ChunkMap's CS lock which guards the list
|
||||
cBlockEntity * Entity = GetBlockEntity(a_BlockPos);
|
||||
if (Entity == nullptr)
|
||||
{
|
||||
return;
|
||||
}
|
||||
for (auto itr = m_LoadedByClient.begin(); itr != m_LoadedByClient.end(); ++itr)
|
||||
{
|
||||
if (*itr == a_Exclude)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
Entity->SendTo(*(*itr));
|
||||
} // for itr - LoadedByClient[]
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cChunk::BroadcastCollectEntity(const cEntity & a_Entity, const cPlayer & a_Player, int a_Count, const cClientHandle * a_Exclude)
|
||||
{
|
||||
for (auto itr = m_LoadedByClient.begin(); itr != m_LoadedByClient.end(); ++itr)
|
||||
{
|
||||
if (*itr == a_Exclude)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
(*itr)->SendCollectEntity(a_Entity, a_Player, a_Count);
|
||||
} // for itr - LoadedByClient[]
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cChunk::BroadcastDestroyEntity(const cEntity & a_Entity, const cClientHandle * a_Exclude)
|
||||
{
|
||||
for (auto itr = m_LoadedByClient.begin(); itr != m_LoadedByClient.end(); ++itr)
|
||||
{
|
||||
if (*itr == a_Exclude)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
(*itr)->SendDestroyEntity(a_Entity);
|
||||
} // for itr - LoadedByClient[]
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cChunk::BroadcastDetachEntity(const cEntity & a_Entity, const cEntity & a_PreviousVehicle)
|
||||
{
|
||||
for (auto ClientHandle : m_LoadedByClient)
|
||||
{
|
||||
ClientHandle->SendDetachEntity(a_Entity, a_PreviousVehicle);
|
||||
} // for itr - LoadedByClient[]
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cChunk::BroadcastEntityEffect(const cEntity & a_Entity, int a_EffectID, int a_Amplifier, short a_Duration, const cClientHandle * a_Exclude)
|
||||
{
|
||||
for (auto itr = m_LoadedByClient.begin(); itr != m_LoadedByClient.end(); ++itr)
|
||||
{
|
||||
if (*itr == a_Exclude)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
(*itr)->SendEntityEffect(a_Entity, a_EffectID, a_Amplifier, a_Duration);
|
||||
} // for itr - LoadedByClient[]
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cChunk::BroadcastEntityEquipment(const cEntity & a_Entity, short a_SlotNum, const cItem & a_Item, const cClientHandle * a_Exclude)
|
||||
{
|
||||
for (auto itr = m_LoadedByClient.begin(); itr != m_LoadedByClient.end(); ++itr)
|
||||
{
|
||||
if (*itr == a_Exclude)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
(*itr)->SendEntityEquipment(a_Entity, a_SlotNum, a_Item);
|
||||
} // for itr - LoadedByClient[]
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cChunk::BroadcastEntityHeadLook(const cEntity & a_Entity, const cClientHandle * a_Exclude)
|
||||
{
|
||||
for (auto itr = m_LoadedByClient.begin(); itr != m_LoadedByClient.end(); ++itr)
|
||||
{
|
||||
if (*itr == a_Exclude)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
(*itr)->SendEntityHeadLook(a_Entity);
|
||||
} // for itr - LoadedByClient[]
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cChunk::BroadcastEntityLook(const cEntity & a_Entity, const cClientHandle * a_Exclude)
|
||||
{
|
||||
for (auto itr = m_LoadedByClient.begin(); itr != m_LoadedByClient.end(); ++itr)
|
||||
{
|
||||
if (*itr == a_Exclude)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
(*itr)->SendEntityLook(a_Entity);
|
||||
} // for itr - LoadedByClient[]
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cChunk::BroadcastEntityMetadata(const cEntity & a_Entity, const cClientHandle * a_Exclude)
|
||||
{
|
||||
for (auto itr = m_LoadedByClient.begin(); itr != m_LoadedByClient.end(); ++itr)
|
||||
{
|
||||
if (*itr == a_Exclude)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
(*itr)->SendEntityMetadata(a_Entity);
|
||||
} // for itr - LoadedByClient[]
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cChunk::BroadcastEntityRelMove(const cEntity & a_Entity, char a_RelX, char a_RelY, char a_RelZ, const cClientHandle * a_Exclude)
|
||||
{
|
||||
for (auto itr = m_LoadedByClient.begin(); itr != m_LoadedByClient.end(); ++itr)
|
||||
{
|
||||
if (*itr == a_Exclude)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
(*itr)->SendEntityRelMove(a_Entity, a_RelX, a_RelY, a_RelZ);
|
||||
} // for itr - LoadedByClient[]
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cChunk::BroadcastEntityRelMoveLook(const cEntity & a_Entity, char a_RelX, char a_RelY, char a_RelZ, const cClientHandle * a_Exclude)
|
||||
{
|
||||
for (auto itr = m_LoadedByClient.begin(); itr != m_LoadedByClient.end(); ++itr)
|
||||
{
|
||||
if (*itr == a_Exclude)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
(*itr)->SendEntityRelMoveLook(a_Entity, a_RelX, a_RelY, a_RelZ);
|
||||
} // for itr - LoadedByClient[]
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cChunk::BroadcastEntityStatus(const cEntity & a_Entity, char a_Status, const cClientHandle * a_Exclude)
|
||||
{
|
||||
for (auto itr = m_LoadedByClient.begin(); itr != m_LoadedByClient.end(); ++itr)
|
||||
{
|
||||
if (*itr == a_Exclude)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
(*itr)->SendEntityStatus(a_Entity, a_Status);
|
||||
} // for itr - LoadedByClient[]
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cChunk::BroadcastEntityVelocity(const cEntity & a_Entity, const cClientHandle * a_Exclude)
|
||||
{
|
||||
for (auto itr = m_LoadedByClient.begin(); itr != m_LoadedByClient.end(); ++itr)
|
||||
{
|
||||
if (*itr == a_Exclude)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
(*itr)->SendEntityVelocity(a_Entity);
|
||||
} // for itr - LoadedByClient[]
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cChunk::BroadcastEntityAnimation(const cEntity & a_Entity, char a_Animation, const cClientHandle * a_Exclude)
|
||||
{
|
||||
for (auto itr = m_LoadedByClient.begin(); itr != m_LoadedByClient.end(); ++itr)
|
||||
{
|
||||
if (*itr == a_Exclude)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
(*itr)->SendEntityAnimation(a_Entity, a_Animation);
|
||||
} // for itr - LoadedByClient[]
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cChunk::BroadcastParticleEffect(const AString & a_ParticleName, float a_SrcX, float a_SrcY, float a_SrcZ, float a_OffsetX, float a_OffsetY, float a_OffsetZ, float a_ParticleData, int a_ParticleAmount, cClientHandle * a_Exclude)
|
||||
{
|
||||
for (auto itr = m_LoadedByClient.begin(); itr != m_LoadedByClient.end(); ++itr)
|
||||
{
|
||||
if (*itr == a_Exclude)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
(*itr)->SendParticleEffect(a_ParticleName, a_SrcX, a_SrcY, a_SrcZ, a_OffsetX, a_OffsetY, a_OffsetZ, a_ParticleData, a_ParticleAmount);
|
||||
} // for itr - LoadedByClient[]
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cChunk::BroadcastRemoveEntityEffect(const cEntity & a_Entity, int a_EffectID, const cClientHandle * a_Exclude)
|
||||
{
|
||||
for (auto itr = m_LoadedByClient.begin(); itr != m_LoadedByClient.end(); ++itr)
|
||||
{
|
||||
if (*itr == a_Exclude)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
(*itr)->SendRemoveEntityEffect(a_Entity, a_EffectID);
|
||||
} // for itr - LoadedByClient[]
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cChunk::BroadcastSoundEffect(const AString & a_SoundName, Vector3d a_Position, float a_Volume, float a_Pitch, const cClientHandle * a_Exclude)
|
||||
{
|
||||
for (auto itr = m_LoadedByClient.begin(); itr != m_LoadedByClient.end(); ++itr)
|
||||
{
|
||||
if (*itr == a_Exclude)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
(*itr)->SendSoundEffect(a_SoundName, a_Position, a_Volume, a_Pitch);
|
||||
} // for itr - LoadedByClient[]
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cChunk::BroadcastSoundParticleEffect(const EffectID a_EffectID, int a_SrcX, int a_SrcY, int a_SrcZ, int a_Data, const cClientHandle * a_Exclude)
|
||||
{
|
||||
for (auto itr = m_LoadedByClient.begin(); itr != m_LoadedByClient.end(); ++itr)
|
||||
{
|
||||
if (*itr == a_Exclude)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
(*itr)->SendSoundParticleEffect(a_EffectID, a_SrcX, a_SrcY, a_SrcZ, a_Data);
|
||||
} // for itr - LoadedByClient[]
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cChunk::BroadcastSpawnEntity(cEntity & a_Entity, const cClientHandle * a_Exclude)
|
||||
{
|
||||
for (auto itr = m_LoadedByClient.begin(); itr != m_LoadedByClient.end(); ++itr)
|
||||
{
|
||||
if (*itr == a_Exclude)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
a_Entity.SpawnOn(*(*itr));
|
||||
} // for itr - LoadedByClient[]
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cChunk::BroadcastThunderbolt(Vector3i a_BlockPos, const cClientHandle * a_Exclude)
|
||||
{
|
||||
for (auto itr = m_LoadedByClient.begin(); itr != m_LoadedByClient.end(); ++itr)
|
||||
{
|
||||
if (*itr == a_Exclude)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
(*itr)->SendThunderbolt(a_BlockPos.x, a_BlockPos.y, a_BlockPos.z);
|
||||
} // for itr - LoadedByClient[]
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cChunk::BroadcastUseBed(const cEntity & a_Entity, int a_BlockX, int a_BlockY, int a_BlockZ)
|
||||
{
|
||||
for (auto itr = m_LoadedByClient.begin(); itr != m_LoadedByClient.end(); ++itr)
|
||||
{
|
||||
(*itr)->SendUseBed(a_Entity, a_BlockX, a_BlockY, a_BlockZ);
|
||||
} // for itr - LoadedByClient[]
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cChunk::SendBlockEntity(int a_BlockX, int a_BlockY, int a_BlockZ, cClientHandle & a_Client)
|
||||
{
|
||||
cBlockEntity * Entity = GetBlockEntity(a_BlockX, a_BlockY, a_BlockZ);
|
||||
|
34
src/Chunk.h
34
src/Chunk.h
@ -352,35 +352,6 @@ public:
|
||||
|
||||
void CalculateHeightmap(const BLOCKTYPE * a_BlockTypes);
|
||||
|
||||
// Broadcast various packets to all clients of this chunk:
|
||||
// (Please keep these alpha-sorted)
|
||||
void BroadcastAttachEntity (const cEntity & a_Entity, const cEntity & a_Vehicle);
|
||||
void BroadcastBlockAction (Vector3i a_BlockPos, char a_Byte1, char a_Byte2, BLOCKTYPE a_BlockType, const cClientHandle * a_Exclude = nullptr);
|
||||
void BroadcastBlockBreakAnimation(UInt32 a_EntityID, Vector3i a_BlockPos, char a_Stage, const cClientHandle * a_Exclude = nullptr);
|
||||
void BroadcastBlockEntity (Vector3i a_BlockPos, const cClientHandle * a_Exclude = nullptr);
|
||||
void BroadcastCollectEntity (const cEntity & a_Entity, const cPlayer & a_Player, int a_Count, const cClientHandle * a_Exclude = nullptr);
|
||||
void BroadcastDestroyEntity (const cEntity & a_Entity, const cClientHandle * a_Exclude = nullptr);
|
||||
void BroadcastDetachEntity (const cEntity & a_Entity, const cEntity & a_PreviousVehicle);
|
||||
void BroadcastEntityEffect (const cEntity & a_Entity, int a_EffectID, int a_Amplifier, short a_Duration, const cClientHandle * a_Exclude = nullptr);
|
||||
void BroadcastEntityEquipment (const cEntity & a_Entity, short a_SlotNum, const cItem & a_Item, const cClientHandle * a_Exclude = nullptr);
|
||||
void BroadcastEntityHeadLook (const cEntity & a_Entity, const cClientHandle * a_Exclude = nullptr);
|
||||
void BroadcastEntityLook (const cEntity & a_Entity, const cClientHandle * a_Exclude = nullptr);
|
||||
void BroadcastEntityMetadata (const cEntity & a_Entity, const cClientHandle * a_Exclude = nullptr);
|
||||
void BroadcastEntityRelMove (const cEntity & a_Entity, char a_RelX, char a_RelY, char a_RelZ, const cClientHandle * a_Exclude = nullptr);
|
||||
void BroadcastEntityRelMoveLook (const cEntity & a_Entity, char a_RelX, char a_RelY, char a_RelZ, const cClientHandle * a_Exclude = nullptr);
|
||||
void BroadcastEntityStatus (const cEntity & a_Entity, char a_Status, const cClientHandle * a_Exclude = nullptr);
|
||||
void BroadcastEntityVelocity (const cEntity & a_Entity, const cClientHandle * a_Exclude = nullptr);
|
||||
void BroadcastEntityAnimation (const cEntity & a_Entity, char a_Animation, const cClientHandle * a_Exclude = nullptr);
|
||||
void BroadcastLeashEntity (const cEntity & a_Entity, const cEntity & a_EntityLeashedTo);
|
||||
void BroadcastParticleEffect (const AString & a_ParticleName, float a_SrcX, float a_SrcY, float a_SrcZ, float a_OffsetX, float a_OffsetY, float a_OffsetZ, float a_ParticleData, int a_ParticleAmount, cClientHandle * a_Exclude = nullptr);
|
||||
void BroadcastRemoveEntityEffect (const cEntity & a_Entity, int a_EffectID, const cClientHandle * a_Exclude = nullptr);
|
||||
void BroadcastSoundEffect (const AString & a_SoundName, Vector3d a_Position, float a_Volume, float a_Pitch, const cClientHandle * a_Exclude = nullptr);
|
||||
void BroadcastSoundParticleEffect(const EffectID a_EffectID, int a_SrcX, int a_SrcY, int a_SrcZ, int a_Data, const cClientHandle * a_Exclude = nullptr);
|
||||
void BroadcastSpawnEntity (cEntity & a_Entity, const cClientHandle * a_Exclude = nullptr);
|
||||
void BroadcastThunderbolt (Vector3i a_BlockPos, const cClientHandle * a_Exclude = nullptr);
|
||||
void BroadcastUnleashEntity (const cEntity & a_Entity);
|
||||
void BroadcastUseBed (const cEntity & a_Entity, int a_BlockX, int a_BlockY, int a_BlockZ);
|
||||
|
||||
void SendBlockEntity (int a_BlockX, int a_BlockY, int a_BlockZ, cClientHandle & a_Client);
|
||||
|
||||
Vector3i PositionToWorldPosition(Vector3i a_RelPos)
|
||||
@ -503,10 +474,9 @@ public:
|
||||
as at least one requests is active the chunk will be ticked). */
|
||||
void SetAlwaysTicked(bool a_AlwaysTicked);
|
||||
|
||||
// Makes a copy of the list
|
||||
cClientHandleList GetAllClients(void) const
|
||||
cChunkClientHandles GetAllClients(void) const
|
||||
{
|
||||
return cClientHandleList(m_LoadedByClient.begin(), m_LoadedByClient.end());
|
||||
return cChunkClientHandles(m_LoadedByClient);
|
||||
}
|
||||
|
||||
private:
|
||||
|
@ -71,6 +71,33 @@ public:
|
||||
|
||||
|
||||
|
||||
/** Non-owning view of a chunk's client handles. */
|
||||
class cChunkClientHandles
|
||||
{
|
||||
public:
|
||||
using const_iterator = std::vector<cClientHandle *>::const_iterator;
|
||||
using iterator = const_iterator;
|
||||
|
||||
explicit cChunkClientHandles(const std::vector<cClientHandle *> & a_Container):
|
||||
m_Begin(a_Container.cbegin()),
|
||||
m_End(a_Container.cend())
|
||||
{
|
||||
}
|
||||
|
||||
const_iterator begin() const { return m_Begin; }
|
||||
const_iterator cbegin() const { return m_Begin; }
|
||||
|
||||
const_iterator end() const { return m_End; }
|
||||
const_iterator cend() const { return m_End; }
|
||||
|
||||
private:
|
||||
const_iterator m_Begin, m_End;
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/** Constants used throughout the code, useful typedefs and utility functions */
|
||||
class cChunkDef
|
||||
{
|
||||
|
469
src/ChunkMap.cpp
469
src/ChunkMap.cpp
@ -259,439 +259,6 @@ cChunk * cChunkMap::FindChunk(int a_ChunkX, int a_ChunkZ)
|
||||
|
||||
|
||||
|
||||
void cChunkMap::BroadcastAttachEntity(const cEntity & a_Entity, const cEntity & a_Vehicle)
|
||||
{
|
||||
cCSLock Lock(m_CSChunks);
|
||||
cChunkPtr Chunk = GetChunkNoGen(a_Entity.GetChunkX(), a_Entity.GetChunkZ());
|
||||
if (Chunk == nullptr)
|
||||
{
|
||||
return;
|
||||
}
|
||||
// It's perfectly legal to broadcast packets even to invalid chunks!
|
||||
Chunk->BroadcastAttachEntity(a_Entity, a_Vehicle);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void cChunkMap::BroadcastLeashEntity(const cEntity & a_Entity, const cEntity & a_EntityLeashedTo)
|
||||
{
|
||||
cCSLock Lock(m_CSChunks);
|
||||
cChunkPtr Chunk = GetChunkNoGen(a_Entity.GetChunkX(), a_Entity.GetChunkZ());
|
||||
if (Chunk == nullptr)
|
||||
{
|
||||
return;
|
||||
}
|
||||
Chunk->BroadcastLeashEntity(a_Entity, a_EntityLeashedTo);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cChunkMap::BroadcastUnleashEntity(const cEntity & a_Entity)
|
||||
{
|
||||
cCSLock Lock(m_CSChunks);
|
||||
cChunkPtr Chunk = GetChunkNoGen(a_Entity.GetChunkX(), a_Entity.GetChunkZ());
|
||||
if (Chunk == nullptr)
|
||||
{
|
||||
return;
|
||||
}
|
||||
Chunk->BroadcastUnleashEntity(a_Entity);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cChunkMap::BroadcastBlockAction(Vector3i a_BlockPos, char a_Byte1, char a_Byte2, BLOCKTYPE a_BlockType, const cClientHandle * a_Exclude)
|
||||
{
|
||||
cCSLock Lock(m_CSChunks);
|
||||
int x, z, ChunkX, ChunkZ;
|
||||
x = a_BlockPos.x;
|
||||
z = a_BlockPos.z;
|
||||
cChunkDef::BlockToChunk(x, z, ChunkX, ChunkZ);
|
||||
cChunkPtr Chunk = GetChunkNoGen(ChunkX, ChunkZ);
|
||||
if (Chunk == nullptr)
|
||||
{
|
||||
return;
|
||||
}
|
||||
// It's perfectly legal to broadcast packets even to invalid chunks!
|
||||
Chunk->BroadcastBlockAction(a_BlockPos, a_Byte1, a_Byte2, a_BlockType, a_Exclude);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cChunkMap::BroadcastBlockBreakAnimation(UInt32 a_EntityID, Vector3i a_BlockPos, char a_Stage, const cClientHandle * a_Exclude)
|
||||
{
|
||||
cCSLock Lock(m_CSChunks);
|
||||
cChunkCoords ChunkPos = cChunkDef::BlockToChunk(a_BlockPos);
|
||||
cChunkPtr Chunk = GetChunkNoGen(ChunkPos);
|
||||
if (Chunk == nullptr)
|
||||
{
|
||||
return;
|
||||
}
|
||||
// It's perfectly legal to broadcast packets even to invalid chunks!
|
||||
Chunk->BroadcastBlockBreakAnimation(a_EntityID, a_BlockPos, a_Stage, a_Exclude);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cChunkMap::BroadcastBlockEntity(Vector3i a_BlockPos, const cClientHandle * a_Exclude)
|
||||
{
|
||||
cCSLock Lock(m_CSChunks);
|
||||
cChunkCoords ChunkPos = cChunkDef::BlockToChunk(a_BlockPos);
|
||||
cChunkPtr Chunk = GetChunkNoGen(ChunkPos);
|
||||
if ((Chunk == nullptr) || !Chunk->IsValid())
|
||||
{
|
||||
return;
|
||||
}
|
||||
Chunk->BroadcastBlockEntity(a_BlockPos, a_Exclude);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cChunkMap::BroadcastCollectEntity(const cEntity & a_Entity, const cPlayer & a_Player, int a_Count, const cClientHandle * a_Exclude)
|
||||
{
|
||||
cCSLock Lock(m_CSChunks);
|
||||
cChunkPtr Chunk = GetChunkNoGen(a_Entity.GetChunkX(), a_Entity.GetChunkZ());
|
||||
if (Chunk == nullptr)
|
||||
{
|
||||
return;
|
||||
}
|
||||
// It's perfectly legal to broadcast packets even to invalid chunks!
|
||||
Chunk->BroadcastCollectEntity(a_Entity, a_Player, a_Count, a_Exclude);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cChunkMap::BroadcastDestroyEntity(const cEntity & a_Entity, const cClientHandle * a_Exclude)
|
||||
{
|
||||
cCSLock Lock(m_CSChunks);
|
||||
cChunkPtr Chunk = GetChunkNoGen(a_Entity.GetChunkX(), a_Entity.GetChunkZ());
|
||||
if (Chunk == nullptr)
|
||||
{
|
||||
return;
|
||||
}
|
||||
// It's perfectly legal to broadcast packets even to invalid chunks!
|
||||
Chunk->BroadcastDestroyEntity(a_Entity, a_Exclude);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cChunkMap::BroadcastDetachEntity(const cEntity & a_Entity, const cEntity & a_PreviousVehicle)
|
||||
{
|
||||
cCSLock Lock(m_CSChunks);
|
||||
cChunkPtr Chunk = GetChunkNoGen(a_Entity.GetChunkX(), a_Entity.GetChunkZ());
|
||||
if (Chunk == nullptr)
|
||||
{
|
||||
return;
|
||||
}
|
||||
// It's perfectly legal to broadcast packets even to invalid chunks!
|
||||
Chunk->BroadcastDetachEntity(a_Entity, a_PreviousVehicle);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cChunkMap::BroadcastEntityEffect(const cEntity & a_Entity, int a_EffectID, int a_Amplifier, short a_Duration, const cClientHandle * a_Exclude)
|
||||
{
|
||||
cCSLock Lock(m_CSChunks);
|
||||
cChunkPtr Chunk = GetChunkNoGen(a_Entity.GetChunkX(), a_Entity.GetChunkZ());
|
||||
if (Chunk == nullptr)
|
||||
{
|
||||
return;
|
||||
}
|
||||
// It's perfectly legal to broadcast packets even to invalid chunks!
|
||||
Chunk->BroadcastEntityEffect(a_Entity, a_EffectID, a_Amplifier, a_Duration);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cChunkMap::BroadcastEntityEquipment(const cEntity & a_Entity, short a_SlotNum, const cItem & a_Item, const cClientHandle * a_Exclude)
|
||||
{
|
||||
cCSLock Lock(m_CSChunks);
|
||||
cChunkPtr Chunk = GetChunkNoGen(a_Entity.GetChunkX(), a_Entity.GetChunkZ());
|
||||
if (Chunk == nullptr)
|
||||
{
|
||||
return;
|
||||
}
|
||||
// It's perfectly legal to broadcast packets even to invalid chunks!
|
||||
Chunk->BroadcastEntityEquipment(a_Entity, a_SlotNum, a_Item, a_Exclude);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cChunkMap::BroadcastEntityHeadLook(const cEntity & a_Entity, const cClientHandle * a_Exclude)
|
||||
{
|
||||
cCSLock Lock(m_CSChunks);
|
||||
cChunkPtr Chunk = GetChunkNoGen(a_Entity.GetChunkX(), a_Entity.GetChunkZ());
|
||||
if (Chunk == nullptr)
|
||||
{
|
||||
return;
|
||||
}
|
||||
// It's perfectly legal to broadcast packets even to invalid chunks!
|
||||
Chunk->BroadcastEntityHeadLook(a_Entity, a_Exclude);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cChunkMap::BroadcastEntityLook(const cEntity & a_Entity, const cClientHandle * a_Exclude)
|
||||
{
|
||||
cCSLock Lock(m_CSChunks);
|
||||
cChunkPtr Chunk = GetChunkNoGen(a_Entity.GetChunkX(), a_Entity.GetChunkZ());
|
||||
if (Chunk == nullptr)
|
||||
{
|
||||
return;
|
||||
}
|
||||
// It's perfectly legal to broadcast packets even to invalid chunks!
|
||||
Chunk->BroadcastEntityLook(a_Entity, a_Exclude);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cChunkMap::BroadcastEntityMetadata(const cEntity & a_Entity, const cClientHandle * a_Exclude)
|
||||
{
|
||||
cCSLock Lock(m_CSChunks);
|
||||
cChunkPtr Chunk = GetChunkNoGen(a_Entity.GetChunkX(), a_Entity.GetChunkZ());
|
||||
if (Chunk == nullptr)
|
||||
{
|
||||
return;
|
||||
}
|
||||
// It's perfectly legal to broadcast packets even to invalid chunks!
|
||||
Chunk->BroadcastEntityMetadata(a_Entity, a_Exclude);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cChunkMap::BroadcastEntityRelMove(const cEntity & a_Entity, char a_RelX, char a_RelY, char a_RelZ, const cClientHandle * a_Exclude)
|
||||
{
|
||||
cCSLock Lock(m_CSChunks);
|
||||
cChunkPtr Chunk = GetChunkNoGen(a_Entity.GetChunkX(), a_Entity.GetChunkZ());
|
||||
if (Chunk == nullptr)
|
||||
{
|
||||
return;
|
||||
}
|
||||
// It's perfectly legal to broadcast packets even to invalid chunks!
|
||||
Chunk->BroadcastEntityRelMove(a_Entity, a_RelX, a_RelY, a_RelZ, a_Exclude);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cChunkMap::BroadcastEntityRelMoveLook(const cEntity & a_Entity, char a_RelX, char a_RelY, char a_RelZ, const cClientHandle * a_Exclude)
|
||||
{
|
||||
cCSLock Lock(m_CSChunks);
|
||||
cChunkPtr Chunk = GetChunkNoGen(a_Entity.GetChunkX(), a_Entity.GetChunkZ());
|
||||
if (Chunk == nullptr)
|
||||
{
|
||||
return;
|
||||
}
|
||||
// It's perfectly legal to broadcast packets even to invalid chunks!
|
||||
Chunk->BroadcastEntityRelMoveLook(a_Entity, a_RelX, a_RelY, a_RelZ, a_Exclude);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cChunkMap::BroadcastEntityStatus(const cEntity & a_Entity, char a_Status, const cClientHandle * a_Exclude)
|
||||
{
|
||||
cCSLock Lock(m_CSChunks);
|
||||
cChunkPtr Chunk = GetChunkNoGen(a_Entity.GetChunkX(), a_Entity.GetChunkZ());
|
||||
if (Chunk == nullptr)
|
||||
{
|
||||
return;
|
||||
}
|
||||
// It's perfectly legal to broadcast packets even to invalid chunks!
|
||||
Chunk->BroadcastEntityStatus(a_Entity, a_Status, a_Exclude);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cChunkMap::BroadcastEntityVelocity(const cEntity & a_Entity, const cClientHandle * a_Exclude)
|
||||
{
|
||||
cCSLock Lock(m_CSChunks);
|
||||
cChunkPtr Chunk = GetChunkNoGen(a_Entity.GetChunkX(), a_Entity.GetChunkZ());
|
||||
if (Chunk == nullptr)
|
||||
{
|
||||
return;
|
||||
}
|
||||
// It's perfectly legal to broadcast packets even to invalid chunks!
|
||||
Chunk->BroadcastEntityVelocity(a_Entity, a_Exclude);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cChunkMap::BroadcastEntityAnimation(const cEntity & a_Entity, char a_Animation, const cClientHandle * a_Exclude)
|
||||
{
|
||||
cCSLock Lock(m_CSChunks);
|
||||
cChunkPtr Chunk = GetChunkNoGen(a_Entity.GetChunkX(), a_Entity.GetChunkZ());
|
||||
if (Chunk == nullptr)
|
||||
{
|
||||
return;
|
||||
}
|
||||
// It's perfectly legal to broadcast packets even to invalid chunks!
|
||||
Chunk->BroadcastEntityAnimation(a_Entity, a_Animation, a_Exclude);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cChunkMap::BroadcastParticleEffect(const AString & a_ParticleName, float a_SrcX, float a_SrcY, float a_SrcZ, float a_OffsetX, float a_OffsetY, float a_OffsetZ, float a_ParticleData, int a_ParticleAmount, cClientHandle * a_Exclude)
|
||||
{
|
||||
cCSLock Lock(m_CSChunks);
|
||||
int ChunkX, ChunkZ;
|
||||
|
||||
cChunkDef::BlockToChunk(FloorC(a_SrcX), FloorC(a_SrcZ), ChunkX, ChunkZ);
|
||||
cChunkPtr Chunk = GetChunkNoGen(ChunkX, ChunkZ);
|
||||
if (Chunk == nullptr)
|
||||
{
|
||||
return;
|
||||
}
|
||||
// It's perfectly legal to broadcast packets even to invalid chunks!
|
||||
Chunk->BroadcastParticleEffect(a_ParticleName, a_SrcX, a_SrcY, a_SrcZ, a_OffsetX, a_OffsetY, a_OffsetZ, a_ParticleData, a_ParticleAmount, a_Exclude);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cChunkMap::BroadcastRemoveEntityEffect(const cEntity & a_Entity, int a_EffectID, const cClientHandle * a_Exclude)
|
||||
{
|
||||
cCSLock Lock(m_CSChunks);
|
||||
|
||||
cChunkPtr Chunk = GetChunkNoGen(a_Entity.GetChunkX(), a_Entity.GetChunkZ());
|
||||
if (Chunk == nullptr)
|
||||
{
|
||||
return;
|
||||
}
|
||||
// It's perfectly legal to broadcast packets even to invalid chunks!
|
||||
Chunk->BroadcastRemoveEntityEffect(a_Entity, a_EffectID, a_Exclude);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cChunkMap::BroadcastSoundEffect(const AString & a_SoundName, Vector3d a_Position, float a_Volume, float a_Pitch, const cClientHandle * a_Exclude)
|
||||
{
|
||||
cCSLock Lock(m_CSChunks);
|
||||
int ChunkX, ChunkZ;
|
||||
|
||||
cChunkDef::BlockToChunk(FloorC(std::floor(a_Position.x)), FloorC(std::floor(a_Position.z)), ChunkX, ChunkZ);
|
||||
cChunkPtr Chunk = GetChunkNoGen(ChunkX, ChunkZ);
|
||||
if (Chunk == nullptr)
|
||||
{
|
||||
return;
|
||||
}
|
||||
// It's perfectly legal to broadcast packets even to invalid chunks!
|
||||
Chunk->BroadcastSoundEffect(a_SoundName, a_Position, a_Volume, a_Pitch, a_Exclude);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cChunkMap::BroadcastSoundParticleEffect(const EffectID a_EffectID, int a_SrcX, int a_SrcY, int a_SrcZ, int a_Data, const cClientHandle * a_Exclude)
|
||||
{
|
||||
cCSLock Lock(m_CSChunks);
|
||||
int ChunkX, ChunkZ;
|
||||
|
||||
cChunkDef::BlockToChunk(a_SrcX, a_SrcZ, ChunkX, ChunkZ);
|
||||
cChunkPtr Chunk = GetChunkNoGen(ChunkX, ChunkZ);
|
||||
if (Chunk == nullptr)
|
||||
{
|
||||
return;
|
||||
}
|
||||
// It's perfectly legal to broadcast packets even to invalid chunks!
|
||||
Chunk->BroadcastSoundParticleEffect(a_EffectID, a_SrcX, a_SrcY, a_SrcZ, a_Data, a_Exclude);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cChunkMap::BroadcastSpawnEntity(cEntity & a_Entity, const cClientHandle * a_Exclude)
|
||||
{
|
||||
cCSLock Lock(m_CSChunks);
|
||||
cChunkPtr Chunk = GetChunkNoGen(a_Entity.GetChunkX(), a_Entity.GetChunkZ());
|
||||
if (Chunk == nullptr)
|
||||
{
|
||||
return;
|
||||
}
|
||||
// It's perfectly legal to broadcast packets even to invalid chunks!
|
||||
Chunk->BroadcastSpawnEntity(a_Entity, a_Exclude);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cChunkMap::BroadcastThunderbolt(Vector3i a_BlockPos, const cClientHandle * a_Exclude)
|
||||
{
|
||||
cCSLock Lock(m_CSChunks);
|
||||
int ChunkX, ChunkZ;
|
||||
cChunkDef::BlockToChunk(a_BlockPos.x, a_BlockPos.z, ChunkX, ChunkZ);
|
||||
cChunkPtr Chunk = GetChunkNoGen(ChunkX, ChunkZ);
|
||||
if (Chunk == nullptr)
|
||||
{
|
||||
return;
|
||||
}
|
||||
// It's perfectly legal to broadcast packets even to invalid chunks!
|
||||
Chunk->BroadcastThunderbolt(a_BlockPos, a_Exclude);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cChunkMap::BroadcastUseBed(const cEntity & a_Entity, int a_BlockX, int a_BlockY, int a_BlockZ)
|
||||
{
|
||||
cCSLock Lock(m_CSChunks);
|
||||
int ChunkX, ChunkZ;
|
||||
|
||||
cChunkDef::BlockToChunk(a_BlockX, a_BlockZ, ChunkX, ChunkZ);
|
||||
cChunkPtr Chunk = GetChunkNoGen(ChunkX, ChunkZ);
|
||||
if (Chunk == nullptr)
|
||||
{
|
||||
return;
|
||||
}
|
||||
// It's perfectly legal to broadcast packets even to invalid chunks!
|
||||
Chunk->BroadcastUseBed(a_Entity, a_BlockX, a_BlockY, a_BlockZ);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cChunkMap::SendBlockEntity(int a_BlockX, int a_BlockY, int a_BlockZ, cClientHandle & a_Client)
|
||||
{
|
||||
cCSLock Lock(m_CSChunks);
|
||||
@ -1418,44 +985,28 @@ void cChunkMap::CompareChunkClients(int a_ChunkX1, int a_ChunkZ1, int a_ChunkX2,
|
||||
|
||||
void cChunkMap::CompareChunkClients(cChunk * a_Chunk1, cChunk * a_Chunk2, cClientDiffCallback & a_Callback)
|
||||
{
|
||||
cClientHandleList Clients1(a_Chunk1->GetAllClients());
|
||||
cClientHandleList Clients2(a_Chunk2->GetAllClients());
|
||||
auto Clients1 = a_Chunk1->GetAllClients();
|
||||
auto Clients2 = a_Chunk2->GetAllClients();
|
||||
|
||||
// Find "removed" clients:
|
||||
for (cClientHandleList::iterator itr1 = Clients1.begin(); itr1 != Clients1.end(); ++itr1)
|
||||
for (auto * Client : Clients1)
|
||||
{
|
||||
bool Found = false;
|
||||
for (cClientHandleList::iterator itr2 = Clients2.begin(); itr2 != Clients2.end(); ++itr2)
|
||||
{
|
||||
if (*itr1 == *itr2)
|
||||
{
|
||||
Found = true;
|
||||
break;
|
||||
}
|
||||
} // for itr2 - Clients2[]
|
||||
bool Found = (std::find(Clients2.begin(), Clients2.end(), Client) != Clients2.end());
|
||||
if (!Found)
|
||||
{
|
||||
a_Callback.Removed(*itr1);
|
||||
a_Callback.Removed(Client);
|
||||
}
|
||||
} // for itr1 - Clients1[]
|
||||
} // for Client - Clients1[]
|
||||
|
||||
// Find "added" clients:
|
||||
for (cClientHandleList::iterator itr2 = Clients2.begin(); itr2 != Clients2.end(); ++itr2)
|
||||
for (auto * Client : Clients2)
|
||||
{
|
||||
bool Found = false;
|
||||
for (cClientHandleList::iterator itr1 = Clients1.begin(); itr1 != Clients1.end(); ++itr1)
|
||||
{
|
||||
if (*itr1 == *itr2)
|
||||
{
|
||||
Found = true;
|
||||
break;
|
||||
}
|
||||
} // for itr1 - Clients1[]
|
||||
bool Found = (std::find(Clients1.begin(), Clients1.end(), Client) != Clients1.end());
|
||||
if (!Found)
|
||||
{
|
||||
a_Callback.Added(*itr2);
|
||||
a_Callback.Added(Client);
|
||||
}
|
||||
} // for itr2 - Clients2[]
|
||||
} // for Client - Clients2[]
|
||||
}
|
||||
|
||||
|
||||
|
@ -68,35 +68,6 @@ public:
|
||||
cChunkMap(cWorld * a_World);
|
||||
~cChunkMap();
|
||||
|
||||
// Broadcast respective packets to all clients of the chunk where the event is taking place
|
||||
// (Please keep these alpha-sorted)
|
||||
void BroadcastAttachEntity(const cEntity & a_Entity, const cEntity & a_Vehicle);
|
||||
void BroadcastBlockAction(Vector3i a_BlockPos, char a_Byte1, char a_Byte2, BLOCKTYPE a_BlockType, const cClientHandle * a_Exclude = nullptr);
|
||||
void BroadcastBlockBreakAnimation(UInt32 a_EntityID, Vector3i a_BlockPos, char a_Stage, const cClientHandle * a_Exclude = nullptr);
|
||||
void BroadcastBlockEntity(Vector3i a_BlockPos, const cClientHandle * a_Exclude);
|
||||
void BroadcastCollectEntity(const cEntity & a_Entity, const cPlayer & a_Player, int a_Count, const cClientHandle * a_Exclude = nullptr);
|
||||
void BroadcastDestroyEntity(const cEntity & a_Entity, const cClientHandle * a_Exclude = nullptr);
|
||||
void BroadcastDetachEntity(const cEntity & a_Entity, const cEntity & a_PreviousVehicle);
|
||||
void BroadcastEntityEffect(const cEntity & a_Entity, int a_EffectID, int a_Amplifier, short a_Duration, const cClientHandle * a_Exclude = nullptr);
|
||||
void BroadcastEntityEquipment(const cEntity & a_Entity, short a_SlotNum, const cItem & a_Item, const cClientHandle * a_Exclude = nullptr);
|
||||
void BroadcastEntityHeadLook(const cEntity & a_Entity, const cClientHandle * a_Exclude = nullptr);
|
||||
void BroadcastEntityLook(const cEntity & a_Entity, const cClientHandle * a_Exclude = nullptr);
|
||||
void BroadcastEntityMetadata(const cEntity & a_Entity, const cClientHandle * a_Exclude = nullptr);
|
||||
void BroadcastEntityRelMove(const cEntity & a_Entity, char a_RelX, char a_RelY, char a_RelZ, const cClientHandle * a_Exclude = nullptr);
|
||||
void BroadcastEntityRelMoveLook(const cEntity & a_Entity, char a_RelX, char a_RelY, char a_RelZ, const cClientHandle * a_Exclude = nullptr);
|
||||
void BroadcastEntityStatus(const cEntity & a_Entity, char a_Status, const cClientHandle * a_Exclude = nullptr);
|
||||
void BroadcastEntityVelocity(const cEntity & a_Entity, const cClientHandle * a_Exclude = nullptr);
|
||||
void BroadcastEntityAnimation(const cEntity & a_Entity, char a_Animation, const cClientHandle * a_Exclude = nullptr);
|
||||
void BroadcastLeashEntity(const cEntity & a_Entity, const cEntity & a_EntityLeashedTo);
|
||||
void BroadcastParticleEffect(const AString & a_ParticleName, float a_SrcX, float a_SrcY, float a_SrcZ, float a_OffsetX, float a_OffsetY, float a_OffsetZ, float a_ParticleData, int a_ParticleAmount, cClientHandle * a_Exclude = nullptr);
|
||||
void BroadcastRemoveEntityEffect (const cEntity & a_Entity, int a_EffectID, const cClientHandle * a_Exclude = nullptr);
|
||||
void BroadcastSoundEffect(const AString & a_SoundName, Vector3d a_Position, float a_Volume, float a_Pitch, const cClientHandle * a_Exclude = nullptr);
|
||||
void BroadcastSoundParticleEffect(const EffectID a_EffectID, int a_SrcX, int a_SrcY, int a_SrcZ, int a_Data, const cClientHandle * a_Exclude = nullptr);
|
||||
void BroadcastSpawnEntity(cEntity & a_Entity, const cClientHandle * a_Exclude = nullptr);
|
||||
void BroadcastThunderbolt(Vector3i a_BlockPos, const cClientHandle * a_Exclude = nullptr);
|
||||
void BroadcastUnleashEntity(const cEntity & a_Entity);
|
||||
void BroadcastUseBed(const cEntity & a_Entity, int a_BlockX, int a_BlockY, int a_BlockZ);
|
||||
|
||||
/** Sends the block entity, if it is at the coords specified, to a_Client */
|
||||
void SendBlockEntity(int a_BlockX, int a_BlockY, int a_BlockZ, cClientHandle & a_Client);
|
||||
|
||||
|
@ -123,7 +123,7 @@ void cChunkSender::QueueSendChunkTo(int a_ChunkX, int a_ChunkZ, eChunkPriority a
|
||||
|
||||
|
||||
|
||||
void cChunkSender::QueueSendChunkTo(int a_ChunkX, int a_ChunkZ, eChunkPriority a_Priority, std::list<cClientHandle *> a_Clients)
|
||||
void cChunkSender::QueueSendChunkTo(int a_ChunkX, int a_ChunkZ, eChunkPriority a_Priority, cChunkClientHandles a_Clients)
|
||||
{
|
||||
{
|
||||
cChunkCoords Chunk{a_ChunkX, a_ChunkZ};
|
||||
|
@ -71,7 +71,7 @@ public:
|
||||
|
||||
/** Queues a chunk to be sent to a specific client */
|
||||
void QueueSendChunkTo(int a_ChunkX, int a_ChunkZ, eChunkPriority a_Priority, cClientHandle * a_Client);
|
||||
void QueueSendChunkTo(int a_ChunkX, int a_ChunkZ, eChunkPriority a_Priority, std::list<cClientHandle *> a_Client);
|
||||
void QueueSendChunkTo(int a_ChunkX, int a_ChunkZ, eChunkPriority a_Priority, cChunkClientHandles a_Client);
|
||||
|
||||
/** Removes the a_Client from all waiting chunk send operations */
|
||||
void RemoveClient(cClientHandle * a_Client);
|
||||
|
@ -214,15 +214,6 @@ void cEntity::SetParentChunk(cChunk * a_Chunk)
|
||||
|
||||
|
||||
|
||||
cChunk * cEntity::GetParentChunk()
|
||||
{
|
||||
return m_ParentChunk;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cEntity::Destroy(bool a_ShouldBroadcast)
|
||||
{
|
||||
SetIsTicking(false);
|
||||
@ -1923,23 +1914,21 @@ void cEntity::BroadcastMovementUpdate(const cClientHandle * a_Exclude)
|
||||
if (!m_bHasSentNoSpeed || IsPlayer())
|
||||
{
|
||||
// TODO: Pickups move disgracefully if relative move packets are sent as opposed to just velocity. Have a system to send relmove only when SetPosXXX() is called with a large difference in position
|
||||
int DiffX = FloorC(GetPosX() * 32.0) - FloorC(m_LastSentPosition.x * 32.0);
|
||||
int DiffY = FloorC(GetPosY() * 32.0) - FloorC(m_LastSentPosition.y * 32.0);
|
||||
int DiffZ = FloorC(GetPosZ() * 32.0) - FloorC(m_LastSentPosition.z * 32.0);
|
||||
Vector3i Diff = (GetPosition() * 32.0).Floor() - (m_LastSentPosition * 32.0).Floor();
|
||||
|
||||
if ((DiffX != 0) || (DiffY != 0) || (DiffZ != 0)) // Have we moved?
|
||||
if (Diff.HasNonZeroLength()) // Have we moved?
|
||||
{
|
||||
if ((abs(DiffX) <= 127) && (abs(DiffY) <= 127) && (abs(DiffZ) <= 127)) // Limitations of a Byte
|
||||
if ((abs(Diff.x) <= 127) && (abs(Diff.y) <= 127) && (abs(Diff.z) <= 127)) // Limitations of a Byte
|
||||
{
|
||||
// Difference within Byte limitations, use a relative move packet
|
||||
if (m_bDirtyOrientation)
|
||||
{
|
||||
m_World->BroadcastEntityRelMoveLook(*this, static_cast<char>(DiffX), static_cast<char>(DiffY), static_cast<char>(DiffZ), a_Exclude);
|
||||
m_World->BroadcastEntityRelMoveLook(*this, Vector3<Int8>(Diff), a_Exclude);
|
||||
m_bDirtyOrientation = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_World->BroadcastEntityRelMove(*this, static_cast<char>(DiffX), static_cast<char>(DiffY), static_cast<char>(DiffZ), a_Exclude);
|
||||
m_World->BroadcastEntityRelMove(*this, Vector3<Int8>(Diff), a_Exclude);
|
||||
}
|
||||
// Clients seem to store two positions, one for the velocity packet and one for the teleport / relmove packet
|
||||
// The latter is only changed with a relmove / teleport, and m_LastSentPosition stores this position
|
||||
|
@ -535,7 +535,8 @@ public:
|
||||
void SetParentChunk(cChunk * a_Chunk);
|
||||
|
||||
/** Returns the chunk responsible for ticking this entity. */
|
||||
cChunk * GetParentChunk();
|
||||
cChunk * GetParentChunk() { return m_ParentChunk; }
|
||||
const cChunk * GetParentChunk() const { return m_ParentChunk; }
|
||||
|
||||
/** Set the entity's status to either ticking or not ticking. */
|
||||
void SetIsTicking(bool a_IsTicking);
|
||||
|
@ -410,10 +410,10 @@ void cEntityEffectHunger::OnTick(cPawn & a_Target)
|
||||
|
||||
void cEntityEffectInvisibility::BroadcastMetadata(cPawn & a_Target)
|
||||
{
|
||||
auto ParentChunk = a_Target.GetParentChunk();
|
||||
if (ParentChunk != nullptr)
|
||||
auto World = a_Target.GetWorld();
|
||||
if (World != nullptr)
|
||||
{
|
||||
ParentChunk->BroadcastEntityMetadata(a_Target);
|
||||
World->BroadcastEntityMetadata(a_Target);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -6,7 +6,6 @@
|
||||
#include "Floater.h"
|
||||
#include "Player.h"
|
||||
#include "../ClientHandle.h"
|
||||
#include "Broadcaster.h"
|
||||
|
||||
|
||||
|
||||
@ -123,12 +122,12 @@ void cFloater::Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk)
|
||||
{
|
||||
LOGD("Started producing particles for floater %i", GetUniqueID());
|
||||
m_ParticlePos.Set(GetPosX() + Random.RandInt(-4, 4), GetPosY(), GetPosZ() + Random.RandInt(-4, 4));
|
||||
m_World->GetBroadcaster().BroadcastParticleEffect("splash", static_cast<Vector3f>(m_ParticlePos), Vector3f{}, 0, 15);
|
||||
m_World->BroadcastParticleEffect("splash", static_cast<Vector3f>(m_ParticlePos), Vector3f{}, 0, 15);
|
||||
}
|
||||
else if (m_CountDownTime < 20)
|
||||
{
|
||||
m_ParticlePos = (m_ParticlePos + (GetPosition() - m_ParticlePos) / 6);
|
||||
m_World->GetBroadcaster().BroadcastParticleEffect("splash", static_cast<Vector3f>(m_ParticlePos), Vector3f{}, 0, 15);
|
||||
m_World->BroadcastParticleEffect("splash", static_cast<Vector3f>(m_ParticlePos), Vector3f{}, 0, 15);
|
||||
}
|
||||
|
||||
m_CountDownTime--;
|
||||
|
@ -60,10 +60,8 @@ public:
|
||||
if (Item.m_ItemCount <= 0)
|
||||
{
|
||||
/* Experimental: show animation pickups getting together */
|
||||
int DiffX = FloorC(m_Pickup->GetPosX() * 32.0) - FloorC(EntityPos.x * 32.0);
|
||||
int DiffY = FloorC(m_Pickup->GetPosY() * 32.0) - FloorC(EntityPos.y * 32.0);
|
||||
int DiffZ = FloorC(m_Pickup->GetPosZ() * 32.0) - FloorC(EntityPos.z * 32.0);
|
||||
a_Entity.GetWorld()->BroadcastEntityRelMove(a_Entity, static_cast<char>(DiffX), static_cast<char>(DiffY), static_cast<char>(DiffZ));
|
||||
auto Diff = (m_Pickup->GetPosition() * 32.0).Floor() - (EntityPos * 32.0).Floor();
|
||||
a_Entity.GetWorld()->BroadcastEntityRelMove(a_Entity, Vector3<char>(Diff));
|
||||
/* End of experimental animation */
|
||||
a_Entity.Destroy();
|
||||
|
||||
|
@ -4,7 +4,6 @@
|
||||
#include "../World.h"
|
||||
#include "../EffectID.h"
|
||||
#include "../Entities/Player.h"
|
||||
#include "Broadcaster.h"
|
||||
#include "UI/HorseWindow.h"
|
||||
|
||||
|
||||
@ -90,7 +89,7 @@ void cHorse::Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk)
|
||||
}
|
||||
else
|
||||
{
|
||||
m_World->GetBroadcaster().BroadcastParticleEffect("heart", static_cast<Vector3f>(GetPosition()), Vector3f{}, 0, 5);
|
||||
m_World->BroadcastParticleEffect("heart", static_cast<Vector3f>(GetPosition()), Vector3f{}, 0, 5);
|
||||
m_bIsTame = true;
|
||||
}
|
||||
}
|
||||
|
@ -5,7 +5,6 @@
|
||||
#include "../World.h"
|
||||
#include "../Entities/Player.h"
|
||||
#include "../Items/ItemHandler.h"
|
||||
#include "Broadcaster.h"
|
||||
#include "../BoundingBox.h"
|
||||
|
||||
|
||||
@ -159,13 +158,13 @@ void cOcelot::OnRightClicked(cPlayer & a_Player)
|
||||
SetOwner(a_Player.GetName(), a_Player.GetUUID());
|
||||
SetCatType(static_cast<eCatType>(Random.RandInt<int>(1, 3)));
|
||||
m_World->BroadcastEntityStatus(*this, esWolfTamed);
|
||||
m_World->GetBroadcaster().BroadcastParticleEffect("heart", static_cast<Vector3f>(GetPosition()), Vector3f{}, 0, 5);
|
||||
m_World->BroadcastParticleEffect("heart", static_cast<Vector3f>(GetPosition()), Vector3f{}, 0, 5);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Taming failed
|
||||
m_World->BroadcastEntityStatus(*this, esWolfTaming);
|
||||
m_World->GetBroadcaster().BroadcastParticleEffect("smoke", static_cast<Vector3f>(GetPosition()), Vector3f{}, 0, 5);
|
||||
m_World->BroadcastParticleEffect("smoke", static_cast<Vector3f>(GetPosition()), Vector3f{}, 0, 5);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -5,7 +5,6 @@
|
||||
#include "../World.h"
|
||||
#include "../Entities/Player.h"
|
||||
#include "../Items/ItemHandler.h"
|
||||
#include "Broadcaster.h"
|
||||
|
||||
|
||||
|
||||
@ -183,13 +182,13 @@ void cWolf::OnRightClicked(cPlayer & a_Player)
|
||||
SetIsTame(true);
|
||||
SetOwner(a_Player.GetName(), a_Player.GetUUID());
|
||||
m_World->BroadcastEntityStatus(*this, esWolfTamed);
|
||||
m_World->GetBroadcaster().BroadcastParticleEffect("heart", static_cast<Vector3f>(GetPosition()), Vector3f{}, 0, 5);
|
||||
m_World->BroadcastParticleEffect("heart", static_cast<Vector3f>(GetPosition()), Vector3f{}, 0, 5);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Taming failed
|
||||
m_World->BroadcastEntityStatus(*this, esWolfTaming);
|
||||
m_World->GetBroadcaster().BroadcastParticleEffect("smoke", static_cast<Vector3f>(GetPosition()), Vector3f{}, 0, 5);
|
||||
m_World->BroadcastParticleEffect("smoke", static_cast<Vector3f>(GetPosition()), Vector3f{}, 0, 5);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
25
src/OpaqueWorld.h
Normal file
25
src/OpaqueWorld.h
Normal file
@ -0,0 +1,25 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
// fwd:
|
||||
class cBroadcastInterface;
|
||||
class cChunkInterface;
|
||||
class cForEachChunkProvider;
|
||||
class cWorld;
|
||||
class cWorldInterface;
|
||||
|
||||
/** Utilities to allow casting a cWorld to one of its interfaces without including World.h. */
|
||||
namespace World
|
||||
{
|
||||
// Defined in World.cpp
|
||||
cBroadcastInterface * GetBroadcastInterface(cWorld * a_World);
|
||||
cForEachChunkProvider * GetFECProvider (cWorld * a_World);
|
||||
cWorldInterface * GetWorldInterface (cWorld * a_World);
|
||||
|
||||
inline cBroadcastInterface & GetBroadcastInterface(cWorld & a_World) { return *GetBroadcastInterface(&a_World); }
|
||||
inline cForEachChunkProvider & GetFECProvider (cWorld & a_World) { return *GetFECProvider(&a_World); }
|
||||
inline cWorldInterface & GetWorldInterface (cWorld & a_World) { return *GetWorldInterface(&a_World); }
|
||||
|
||||
// cChunkInterface is more like a pimpl for cChunkMap than an interface so it needs to be returned by value
|
||||
cChunkInterface GetChunkInterface(cWorld & a_World);
|
||||
}
|
@ -258,7 +258,7 @@ void cFloodyFluidSimulator::SpreadToNeighbor(cChunk * a_NearChunk, int a_RelX, i
|
||||
);
|
||||
a_NearChunk->SetBlock(a_RelX, a_RelY, a_RelZ, NewBlock, 0);
|
||||
|
||||
a_NearChunk->BroadcastSoundEffect(
|
||||
m_World.BroadcastSoundEffect(
|
||||
"block.lava.extinguish",
|
||||
Vector3d(BlockX, a_RelY, BlockZ),
|
||||
0.5f,
|
||||
@ -278,7 +278,7 @@ void cFloodyFluidSimulator::SpreadToNeighbor(cChunk * a_NearChunk, int a_RelX, i
|
||||
);
|
||||
a_NearChunk->SetBlock(a_RelX, a_RelY, a_RelZ, NewBlock, 0);
|
||||
|
||||
a_NearChunk->BroadcastSoundEffect(
|
||||
m_World.BroadcastSoundEffect(
|
||||
"block.lava.extinguish",
|
||||
Vector3d(BlockX, a_RelY, BlockZ),
|
||||
0.5f,
|
||||
|
@ -5,7 +5,9 @@
|
||||
|
||||
#include "Globals.h"
|
||||
#include "VaporizeFluidSimulator.h"
|
||||
#include "../OpaqueWorld.h"
|
||||
#include "../Chunk.h"
|
||||
#include "../Blocks/BroadcastInterface.h"
|
||||
|
||||
|
||||
|
||||
@ -35,13 +37,9 @@ void cVaporizeFluidSimulator::AddBlock(Vector3i a_Block, cChunk * a_Chunk)
|
||||
)
|
||||
{
|
||||
a_Chunk->SetBlock(RelX, a_Block.y, RelZ, E_BLOCK_AIR, 0);
|
||||
a_Chunk->BroadcastSoundEffect(
|
||||
World::GetBroadcastInterface(m_World).BroadcastSoundEffect(
|
||||
"block.fire.extinguish",
|
||||
{
|
||||
static_cast<double>(a_Block.x),
|
||||
static_cast<double>(a_Block.y),
|
||||
static_cast<double>(a_Block.z)
|
||||
},
|
||||
Vector3d(a_Block),
|
||||
1.0f,
|
||||
0.6f
|
||||
);
|
||||
|
505
src/World.cpp
505
src/World.cpp
@ -50,9 +50,9 @@
|
||||
#include <stdlib.h>
|
||||
#endif
|
||||
|
||||
#include "Broadcaster.h"
|
||||
#include "SpawnPrepare.h"
|
||||
#include "FastRandom.h"
|
||||
#include "OpaqueWorld.h"
|
||||
|
||||
|
||||
|
||||
@ -66,6 +66,23 @@ const int TIME_SPAWN_DIVISOR = 148;
|
||||
|
||||
|
||||
|
||||
namespace World
|
||||
{
|
||||
// Implement conversion functions from OpaqueWorld.h
|
||||
cBroadcastInterface * GetBroadcastInterface(cWorld * a_World) { return a_World; }
|
||||
cForEachChunkProvider * GetFECProvider (cWorld * a_World) { return a_World; }
|
||||
cWorldInterface * GetWorldInterface (cWorld * a_World) { return a_World; }
|
||||
|
||||
cChunkInterface GetChunkInterface(cWorld & a_World)
|
||||
{
|
||||
return { a_World.GetChunkMap() };
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// cWorld::cLock:
|
||||
|
||||
@ -2409,485 +2426,6 @@ bool cWorld::TryGetHeight(int a_BlockX, int a_BlockZ, int & a_Height)
|
||||
|
||||
|
||||
|
||||
void cWorld::BroadcastAttachEntity(const cEntity & a_Entity, const cEntity & a_Vehicle)
|
||||
{
|
||||
m_ChunkMap->BroadcastAttachEntity(a_Entity, a_Vehicle);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cWorld::BroadcastBlockAction(Vector3i a_BlockPos, Byte a_Byte1, Byte a_Byte2, BLOCKTYPE a_BlockType, const cClientHandle * a_Exclude)
|
||||
{
|
||||
m_ChunkMap->BroadcastBlockAction(a_BlockPos, static_cast<char>(a_Byte1), static_cast<char>(a_Byte2), a_BlockType, a_Exclude);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cWorld::BroadcastBlockAction(int a_BlockX, int a_BlockY, int a_BlockZ, Byte a_Byte1, Byte a_Byte2, BLOCKTYPE a_BlockType, const cClientHandle * a_Exclude)
|
||||
{
|
||||
LOG("BroadcastBlockAction with integer position is deprecated, use vector-parametered version instead.");
|
||||
m_ChunkMap->BroadcastBlockAction({a_BlockX, a_BlockY, a_BlockZ}, static_cast<char>(a_Byte1), static_cast<char>(a_Byte2), a_BlockType, a_Exclude);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cWorld::BroadcastBlockBreakAnimation(UInt32 a_EntityID, Vector3i a_BlockPos, char a_Stage, const cClientHandle * a_Exclude)
|
||||
{
|
||||
m_ChunkMap->BroadcastBlockBreakAnimation(a_EntityID, a_BlockPos, a_Stage, a_Exclude);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cWorld::BroadcastBlockEntity(Vector3i a_BlockPos, const cClientHandle * a_Exclude)
|
||||
{
|
||||
m_ChunkMap->BroadcastBlockEntity(a_BlockPos, a_Exclude);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cWorld::BroadcastChat(const AString & a_Message, const cClientHandle * a_Exclude, eMessageType a_ChatPrefix)
|
||||
{
|
||||
cCSLock Lock(m_CSPlayers);
|
||||
for (cPlayerList::iterator itr = m_Players.begin(); itr != m_Players.end(); ++itr)
|
||||
{
|
||||
cClientHandle * ch = (*itr)->GetClientHandle();
|
||||
if ((ch == a_Exclude) || (ch == nullptr) || !ch->IsLoggedIn() || ch->IsDestroyed())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
ch->SendChat(a_Message, a_ChatPrefix);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cWorld::BroadcastChat(const cCompositeChat & a_Message, const cClientHandle * a_Exclude)
|
||||
{
|
||||
cCSLock Lock(m_CSPlayers);
|
||||
for (cPlayerList::iterator itr = m_Players.begin(); itr != m_Players.end(); ++itr)
|
||||
{
|
||||
cClientHandle * ch = (*itr)->GetClientHandle();
|
||||
if ((ch == a_Exclude) || (ch == nullptr) || !ch->IsLoggedIn() || ch->IsDestroyed())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
ch->SendChat(a_Message);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cWorld::BroadcastCollectEntity(const cEntity & a_Entity, const cPlayer & a_Player, int a_Count, const cClientHandle * a_Exclude)
|
||||
{
|
||||
m_ChunkMap->BroadcastCollectEntity(a_Entity, a_Player, a_Count, a_Exclude);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cWorld::BroadcastDestroyEntity(const cEntity & a_Entity, const cClientHandle * a_Exclude)
|
||||
{
|
||||
m_ChunkMap->BroadcastDestroyEntity(a_Entity, a_Exclude);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cWorld::BroadcastDetachEntity(const cEntity & a_Entity, const cEntity & a_PreviousVehicle)
|
||||
{
|
||||
m_ChunkMap->BroadcastDetachEntity(a_Entity, a_PreviousVehicle);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cWorld::BroadcastLeashEntity(const cEntity & a_Entity, const cEntity & a_EntityLeashedTo)
|
||||
{
|
||||
m_ChunkMap->BroadcastLeashEntity(a_Entity, a_EntityLeashedTo);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cWorld::BroadcastUnleashEntity(const cEntity & a_Entity)
|
||||
{
|
||||
m_ChunkMap->BroadcastUnleashEntity(a_Entity);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cWorld::BroadcastEntityEffect(const cEntity & a_Entity, int a_EffectID, int a_Amplifier, short a_Duration, const cClientHandle * a_Exclude)
|
||||
{
|
||||
m_ChunkMap->BroadcastEntityEffect(a_Entity, a_EffectID, a_Amplifier, a_Duration, a_Exclude);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cWorld::BroadcastEntityEquipment(const cEntity & a_Entity, short a_SlotNum, const cItem & a_Item, const cClientHandle * a_Exclude)
|
||||
{
|
||||
m_ChunkMap->BroadcastEntityEquipment(a_Entity, a_SlotNum, a_Item, a_Exclude);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cWorld::BroadcastEntityHeadLook(const cEntity & a_Entity, const cClientHandle * a_Exclude)
|
||||
{
|
||||
m_ChunkMap->BroadcastEntityHeadLook(a_Entity, a_Exclude);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cWorld::BroadcastEntityLook(const cEntity & a_Entity, const cClientHandle * a_Exclude)
|
||||
{
|
||||
m_ChunkMap->BroadcastEntityLook(a_Entity, a_Exclude);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cWorld::BroadcastEntityMetadata(const cEntity & a_Entity, const cClientHandle * a_Exclude)
|
||||
{
|
||||
m_ChunkMap->BroadcastEntityMetadata(a_Entity, a_Exclude);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cWorld::BroadcastEntityRelMove(const cEntity & a_Entity, char a_RelX, char a_RelY, char a_RelZ, const cClientHandle * a_Exclude)
|
||||
{
|
||||
m_ChunkMap->BroadcastEntityRelMove(a_Entity, a_RelX, a_RelY, a_RelZ, a_Exclude);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cWorld::BroadcastEntityRelMoveLook(const cEntity & a_Entity, char a_RelX, char a_RelY, char a_RelZ, const cClientHandle * a_Exclude)
|
||||
{
|
||||
m_ChunkMap->BroadcastEntityRelMoveLook(a_Entity, a_RelX, a_RelY, a_RelZ, a_Exclude);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cWorld::BroadcastEntityStatus(const cEntity & a_Entity, char a_Status, const cClientHandle * a_Exclude)
|
||||
{
|
||||
m_ChunkMap->BroadcastEntityStatus(a_Entity, a_Status, a_Exclude);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cWorld::BroadcastEntityVelocity(const cEntity & a_Entity, const cClientHandle * a_Exclude)
|
||||
{
|
||||
m_ChunkMap->BroadcastEntityVelocity(a_Entity, a_Exclude);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void cWorld::BroadcastEntityAnimation(const cEntity & a_Entity, char a_Animation, const cClientHandle * a_Exclude)
|
||||
{
|
||||
m_ChunkMap->BroadcastEntityAnimation(a_Entity, a_Animation, a_Exclude);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cWorld::BroadcastPlayerListAddPlayer(const cPlayer & a_Player, const cClientHandle * a_Exclude)
|
||||
{
|
||||
cCSLock Lock(m_CSPlayers);
|
||||
for (cPlayerList::iterator itr = m_Players.begin(); itr != m_Players.end(); ++itr)
|
||||
{
|
||||
cClientHandle * ch = (*itr)->GetClientHandle();
|
||||
if ((ch == a_Exclude) || (ch == nullptr) || !ch->IsLoggedIn() || ch->IsDestroyed())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
ch->SendPlayerListAddPlayer(a_Player);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cWorld::BroadcastPlayerListRemovePlayer(const cPlayer & a_Player, const cClientHandle * a_Exclude)
|
||||
{
|
||||
cCSLock Lock(m_CSPlayers);
|
||||
for (cPlayerList::iterator itr = m_Players.begin(); itr != m_Players.end(); ++itr)
|
||||
{
|
||||
cClientHandle * ch = (*itr)->GetClientHandle();
|
||||
if ((ch == a_Exclude) || (ch == nullptr) || !ch->IsLoggedIn())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
ch->SendPlayerListRemovePlayer(a_Player);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cWorld::BroadcastPlayerListUpdateGameMode(const cPlayer & a_Player, const cClientHandle * a_Exclude)
|
||||
{
|
||||
cCSLock Lock(m_CSPlayers);
|
||||
for (cPlayerList::iterator itr = m_Players.begin(); itr != m_Players.end(); ++itr)
|
||||
{
|
||||
cClientHandle * ch = (*itr)->GetClientHandle();
|
||||
if ((ch == a_Exclude) || (ch == nullptr) || !ch->IsLoggedIn() || ch->IsDestroyed())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
ch->SendPlayerListUpdateGameMode(a_Player);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cWorld::BroadcastPlayerListUpdatePing(const cPlayer & a_Player, const cClientHandle * a_Exclude)
|
||||
{
|
||||
cCSLock Lock(m_CSPlayers);
|
||||
for (cPlayerList::iterator itr = m_Players.begin(); itr != m_Players.end(); ++itr)
|
||||
{
|
||||
cClientHandle * ch = (*itr)->GetClientHandle();
|
||||
if ((ch == a_Exclude) || (ch == nullptr) || !ch->IsLoggedIn() || ch->IsDestroyed())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
ch->SendPlayerListUpdatePing(a_Player);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cWorld::BroadcastPlayerListUpdateDisplayName(const cPlayer & a_Player, const AString & a_CustomName, const cClientHandle * a_Exclude)
|
||||
{
|
||||
cCSLock Lock(m_CSPlayers);
|
||||
for (cPlayerList::iterator itr = m_Players.begin(); itr != m_Players.end(); ++itr)
|
||||
{
|
||||
cClientHandle * ch = (*itr)->GetClientHandle();
|
||||
if ((ch == a_Exclude) || (ch == nullptr) || !ch->IsLoggedIn() || ch->IsDestroyed())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
ch->SendPlayerListUpdateDisplayName(a_Player, a_CustomName);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cWorld::BroadcastRemoveEntityEffect(const cEntity & a_Entity, int a_EffectID, const cClientHandle * a_Exclude)
|
||||
{
|
||||
m_ChunkMap->BroadcastRemoveEntityEffect(a_Entity, a_EffectID, a_Exclude);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cWorld::BroadcastScoreboardObjective(const AString & a_Name, const AString & a_DisplayName, Byte a_Mode)
|
||||
{
|
||||
cCSLock Lock(m_CSPlayers);
|
||||
for (cPlayerList::iterator itr = m_Players.begin(); itr != m_Players.end(); ++itr)
|
||||
{
|
||||
cClientHandle * ch = (*itr)->GetClientHandle();
|
||||
if ((ch == nullptr) || !ch->IsLoggedIn() || ch->IsDestroyed())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
ch->SendScoreboardObjective(a_Name, a_DisplayName, a_Mode);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cWorld::BroadcastScoreUpdate(const AString & a_Objective, const AString & a_Player, cObjective::Score a_Score, Byte a_Mode)
|
||||
{
|
||||
cCSLock Lock(m_CSPlayers);
|
||||
for (cPlayerList::iterator itr = m_Players.begin(); itr != m_Players.end(); ++itr)
|
||||
{
|
||||
cClientHandle * ch = (*itr)->GetClientHandle();
|
||||
if ((ch == nullptr) || !ch->IsLoggedIn() || ch->IsDestroyed())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
ch->SendScoreUpdate(a_Objective, a_Player, a_Score, a_Mode);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cWorld::BroadcastDisplayObjective(const AString & a_Objective, cScoreboard::eDisplaySlot a_Display)
|
||||
{
|
||||
cCSLock Lock(m_CSPlayers);
|
||||
for (cPlayerList::iterator itr = m_Players.begin(); itr != m_Players.end(); ++itr)
|
||||
{
|
||||
cClientHandle * ch = (*itr)->GetClientHandle();
|
||||
if ((ch == nullptr) || !ch->IsLoggedIn() || ch->IsDestroyed())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
ch->SendDisplayObjective(a_Objective, a_Display);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cWorld::BroadcastSoundEffect(const AString & a_SoundName, Vector3d a_Position, float a_Volume, float a_Pitch, const cClientHandle * a_Exclude)
|
||||
{
|
||||
m_ChunkMap->BroadcastSoundEffect(a_SoundName, a_Position, a_Volume, a_Pitch, a_Exclude);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cWorld::BroadcastSoundEffect(const AString & a_SoundName, double a_X, double a_Y, double a_Z, float a_Volume, float a_Pitch, const cClientHandle * a_Exclude)
|
||||
{
|
||||
LOG("BroadcastSoundEffect with double position arguments is deprecated, use vector-parametered version instead.");
|
||||
BroadcastSoundEffect(a_SoundName, {a_X, a_Y, a_Z}, a_Volume, a_Pitch, a_Exclude);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cWorld::BroadcastSoundParticleEffect(const EffectID a_EffectID, int a_SrcX, int a_SrcY, int a_SrcZ, int a_Data, const cClientHandle * a_Exclude)
|
||||
{
|
||||
m_ChunkMap->BroadcastSoundParticleEffect(a_EffectID, a_SrcX, a_SrcY, a_SrcZ, a_Data, a_Exclude);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cWorld::BroadcastSpawnEntity(cEntity & a_Entity, const cClientHandle * a_Exclude)
|
||||
{
|
||||
m_ChunkMap->BroadcastSpawnEntity(a_Entity, a_Exclude);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cWorld::BroadcastTeleportEntity(const cEntity & a_Entity, const cClientHandle * a_Exclude)
|
||||
{
|
||||
cCSLock Lock(m_CSPlayers);
|
||||
for (cPlayerList::iterator itr = m_Players.begin(); itr != m_Players.end(); ++itr)
|
||||
{
|
||||
cClientHandle * ch = (*itr)->GetClientHandle();
|
||||
if ((ch == a_Exclude) || (ch == nullptr) || !ch->IsLoggedIn() || ch->IsDestroyed())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
ch->SendTeleportEntity(a_Entity);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cWorld::BroadcastThunderbolt(Vector3i a_BlockPos, const cClientHandle * a_Exclude)
|
||||
{
|
||||
m_ChunkMap->BroadcastThunderbolt(a_BlockPos, a_Exclude);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cWorld::BroadcastTimeUpdate(const cClientHandle * a_Exclude)
|
||||
{
|
||||
cCSLock Lock(m_CSPlayers);
|
||||
for (cPlayerList::iterator itr = m_Players.begin(); itr != m_Players.end(); ++itr)
|
||||
{
|
||||
cClientHandle * ch = (*itr)->GetClientHandle();
|
||||
if ((ch == a_Exclude) || (ch == nullptr) || !ch->IsLoggedIn() || ch->IsDestroyed())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
ch->SendTimeUpdate(std::chrono::duration_cast<cTickTimeLong>(m_WorldAge).count(), std::chrono::duration_cast<cTickTimeLong>(m_TimeOfDay).count(), m_IsDaylightCycleEnabled);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cWorld::BroadcastUseBed(const cEntity & a_Entity, int a_BlockX, int a_BlockY, int a_BlockZ)
|
||||
{
|
||||
m_ChunkMap->BroadcastUseBed(a_Entity, a_BlockX, a_BlockY, a_BlockZ);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cWorld::BroadcastWeather(eWeather a_Weather, const cClientHandle * a_Exclude)
|
||||
{
|
||||
cCSLock Lock(m_CSPlayers);
|
||||
for (cPlayerList::iterator itr = m_Players.begin(); itr != m_Players.end(); ++itr)
|
||||
{
|
||||
cClientHandle * ch = (*itr)->GetClientHandle();
|
||||
if ((ch == a_Exclude) || (ch == nullptr) || !ch->IsLoggedIn() || ch->IsDestroyed())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
ch->SendWeather(a_Weather);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cWorld::SendBlockEntity(int a_BlockX, int a_BlockY, int a_BlockZ, cClientHandle & a_Client)
|
||||
{
|
||||
m_ChunkMap->SendBlockEntity(a_BlockX, a_BlockY, a_BlockZ, a_Client);
|
||||
@ -4228,10 +3766,3 @@ void cWorld::cChunkGeneratorCallbacks::CallHookChunkGenerated (cChunkDesc & a_Ch
|
||||
*m_World, a_ChunkDesc.GetChunkX(), a_ChunkDesc.GetChunkZ(), &a_ChunkDesc
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
|
||||
cBroadcaster cWorld::GetBroadcaster()
|
||||
{
|
||||
return cBroadcaster(this);
|
||||
}
|
||||
|
123
src/World.h
123
src/World.h
@ -49,7 +49,6 @@ class cNoteEntity;
|
||||
class cMobHeadEntity;
|
||||
class cCompositeChat;
|
||||
class cSetChunkData;
|
||||
class cBroadcaster;
|
||||
class cDeadlockDetect;
|
||||
class cUUID;
|
||||
|
||||
@ -63,14 +62,14 @@ typedef std::vector<cSetChunkDataPtr> cSetChunkDataPtrs;
|
||||
|
||||
|
||||
|
||||
// tolua_begin
|
||||
class cWorld :
|
||||
class cWorld // tolua_export
|
||||
final:
|
||||
public cForEachChunkProvider,
|
||||
public cWorldInterface,
|
||||
public cBroadcastInterface
|
||||
// tolua_begin
|
||||
{
|
||||
public:
|
||||
|
||||
// tolua_end
|
||||
|
||||
/** A simple RAII locker for the chunkmap - locks the chunkmap in its constructor, unlocks it in the destructor */
|
||||
@ -160,57 +159,79 @@ public:
|
||||
bool TryGetHeight(int a_BlockX, int a_BlockZ, int & a_Height); // Exported in ManualBindings.cpp
|
||||
|
||||
// Broadcast respective packets to all clients of the chunk where the event is taking place
|
||||
// Implemented in Broadcaster.cpp
|
||||
// (Please keep these alpha-sorted)
|
||||
void BroadcastAttachEntity (const cEntity & a_Entity, const cEntity & a_Vehicle);
|
||||
void BroadcastBlockAction (Vector3i a_BlockPos, Byte a_Byte1, Byte a_Byte2, BLOCKTYPE a_BlockType, const cClientHandle * a_Exclude = nullptr); // tolua_export
|
||||
void BroadcastBlockAction (int a_BlockX, int a_BlockY, int a_BlockZ, Byte a_Byte1, Byte a_Byte2, BLOCKTYPE a_BlockType, const cClientHandle * a_Exclude = nullptr); // tolua_export
|
||||
void BroadcastBlockBreakAnimation(UInt32 a_EntityID, Vector3i a_BlockPos, char a_Stage, const cClientHandle * a_Exclude = nullptr);
|
||||
void BroadcastBlockEntity (Vector3i a_BlockPos, const cClientHandle * a_Exclude = nullptr); ///< If there is a block entity at the specified coods, sends it to all clients except a_Exclude
|
||||
virtual void BroadcastAttachEntity (const cEntity & a_Entity, const cEntity & a_Vehicle) override;
|
||||
virtual void BroadcastBlockAction (Vector3i a_BlockPos, Byte a_Byte1, Byte a_Byte2, BLOCKTYPE a_BlockType, const cClientHandle * a_Exclude = nullptr) override; // tolua_export
|
||||
virtual void BroadcastBlockBreakAnimation(UInt32 a_EntityID, Vector3i a_BlockPos, Int8 a_Stage, const cClientHandle * a_Exclude = nullptr) override;
|
||||
virtual void BroadcastBlockEntity (Vector3i a_BlockPos, const cClientHandle * a_Exclude = nullptr) override; ///< If there is a block entity at the specified coods, sends it to all clients except a_Exclude
|
||||
|
||||
// tolua_begin
|
||||
void BroadcastChat (const AString & a_Message, const cClientHandle * a_Exclude = nullptr, eMessageType a_ChatPrefix = mtCustom);
|
||||
void BroadcastChatInfo (const AString & a_Message, const cClientHandle * a_Exclude = nullptr) { BroadcastChat(a_Message, a_Exclude, mtInformation); }
|
||||
void BroadcastChatFailure(const AString & a_Message, const cClientHandle * a_Exclude = nullptr) { BroadcastChat(a_Message, a_Exclude, mtFailure); }
|
||||
void BroadcastChatSuccess(const AString & a_Message, const cClientHandle * a_Exclude = nullptr) { BroadcastChat(a_Message, a_Exclude, mtSuccess); }
|
||||
void BroadcastChatWarning(const AString & a_Message, const cClientHandle * a_Exclude = nullptr) { BroadcastChat(a_Message, a_Exclude, mtWarning); }
|
||||
void BroadcastChatFatal (const AString & a_Message, const cClientHandle * a_Exclude = nullptr) { BroadcastChat(a_Message, a_Exclude, mtFailure); }
|
||||
void BroadcastChatDeath (const AString & a_Message, const cClientHandle * a_Exclude = nullptr) { BroadcastChat(a_Message, a_Exclude, mtDeath); }
|
||||
void BroadcastChat (const cCompositeChat & a_Message, const cClientHandle * a_Exclude = nullptr);
|
||||
virtual void BroadcastChat (const AString & a_Message, const cClientHandle * a_Exclude = nullptr, eMessageType a_ChatPrefix = mtCustom) override;
|
||||
virtual void BroadcastChatInfo (const AString & a_Message, const cClientHandle * a_Exclude = nullptr) override { BroadcastChat(a_Message, a_Exclude, mtInformation); }
|
||||
virtual void BroadcastChatFailure(const AString & a_Message, const cClientHandle * a_Exclude = nullptr) override { BroadcastChat(a_Message, a_Exclude, mtFailure); }
|
||||
virtual void BroadcastChatSuccess(const AString & a_Message, const cClientHandle * a_Exclude = nullptr) override { BroadcastChat(a_Message, a_Exclude, mtSuccess); }
|
||||
virtual void BroadcastChatWarning(const AString & a_Message, const cClientHandle * a_Exclude = nullptr) override { BroadcastChat(a_Message, a_Exclude, mtWarning); }
|
||||
virtual void BroadcastChatFatal (const AString & a_Message, const cClientHandle * a_Exclude = nullptr) override { BroadcastChat(a_Message, a_Exclude, mtFailure); }
|
||||
virtual void BroadcastChatDeath (const AString & a_Message, const cClientHandle * a_Exclude = nullptr) override { BroadcastChat(a_Message, a_Exclude, mtDeath); }
|
||||
virtual void BroadcastChat (const cCompositeChat & a_Message, const cClientHandle * a_Exclude = nullptr) override;
|
||||
// tolua_end
|
||||
|
||||
void BroadcastCollectEntity (const cEntity & a_Pickup, const cPlayer & a_Player, int a_Count, const cClientHandle * a_Exclude = nullptr);
|
||||
void BroadcastDestroyEntity (const cEntity & a_Entity, const cClientHandle * a_Exclude = nullptr);
|
||||
void BroadcastDetachEntity (const cEntity & a_Entity, const cEntity & a_PreviousVehicle);
|
||||
void BroadcastEntityEffect (const cEntity & a_Entity, int a_EffectID, int a_Amplifier, short a_Duration, const cClientHandle * a_Exclude = nullptr);
|
||||
void BroadcastEntityEquipment (const cEntity & a_Entity, short a_SlotNum, const cItem & a_Item, const cClientHandle * a_Exclude = nullptr);
|
||||
void BroadcastEntityHeadLook (const cEntity & a_Entity, const cClientHandle * a_Exclude = nullptr);
|
||||
void BroadcastEntityLook (const cEntity & a_Entity, const cClientHandle * a_Exclude = nullptr);
|
||||
void BroadcastEntityMetadata (const cEntity & a_Entity, const cClientHandle * a_Exclude = nullptr);
|
||||
void BroadcastEntityRelMove (const cEntity & a_Entity, char a_RelX, char a_RelY, char a_RelZ, const cClientHandle * a_Exclude = nullptr);
|
||||
void BroadcastEntityRelMoveLook (const cEntity & a_Entity, char a_RelX, char a_RelY, char a_RelZ, const cClientHandle * a_Exclude = nullptr);
|
||||
void BroadcastEntityStatus (const cEntity & a_Entity, char a_Status, const cClientHandle * a_Exclude = nullptr);
|
||||
void BroadcastEntityVelocity (const cEntity & a_Entity, const cClientHandle * a_Exclude = nullptr);
|
||||
virtual void BroadcastEntityAnimation (const cEntity & a_Entity, char a_Animation, const cClientHandle * a_Exclude = nullptr) override; // tolua_export
|
||||
void BroadcastLeashEntity (const cEntity & a_Entity, const cEntity & a_EntityLeashedTo);
|
||||
void BroadcastPlayerListAddPlayer (const cPlayer & a_Player, const cClientHandle * a_Exclude = nullptr);
|
||||
void BroadcastPlayerListRemovePlayer (const cPlayer & a_Player, const cClientHandle * a_Exclude = nullptr);
|
||||
void BroadcastPlayerListUpdateGameMode (const cPlayer & a_Player, const cClientHandle * a_Exclude = nullptr);
|
||||
void BroadcastPlayerListUpdatePing (const cPlayer & a_Player, const cClientHandle * a_Exclude = nullptr);
|
||||
void BroadcastPlayerListUpdateDisplayName(const cPlayer & a_Player, const AString & a_CustomName, const cClientHandle * a_Exclude = nullptr);
|
||||
void BroadcastRemoveEntityEffect (const cEntity & a_Entity, int a_EffectID, const cClientHandle * a_Exclude = nullptr);
|
||||
void BroadcastScoreboardObjective (const AString & a_Name, const AString & a_DisplayName, Byte a_Mode);
|
||||
void BroadcastScoreUpdate (const AString & a_Objective, const AString & a_Player, cObjective::Score a_Score, Byte a_Mode);
|
||||
void BroadcastDisplayObjective (const AString & a_Objective, cScoreboard::eDisplaySlot a_Display);
|
||||
void BroadcastSoundEffect (const AString & a_SoundName, Vector3d a_Position, float a_Volume, float a_Pitch, const cClientHandle * a_Exclude = nullptr) override; // tolua_export
|
||||
void BroadcastSoundEffect (const AString & a_SoundName, double a_X, double a_Y, double a_Z, float a_Volume, float a_Pitch, const cClientHandle * a_Exclude = nullptr); // tolua_export
|
||||
virtual void BroadcastSoundParticleEffect (const EffectID a_EffectID, int a_SrcX, int a_SrcY, int a_SrcZ, int a_Data, const cClientHandle * a_Exclude = nullptr) override; // tolua_export
|
||||
void BroadcastSpawnEntity (cEntity & a_Entity, const cClientHandle * a_Exclude = nullptr);
|
||||
void BroadcastTeleportEntity (const cEntity & a_Entity, const cClientHandle * a_Exclude = nullptr);
|
||||
void BroadcastThunderbolt (Vector3i a_BlockPos, const cClientHandle * a_Exclude = nullptr);
|
||||
void BroadcastTimeUpdate (const cClientHandle * a_Exclude = nullptr);
|
||||
void BroadcastUnleashEntity (const cEntity & a_Entity);
|
||||
virtual void BroadcastUseBed (const cEntity & a_Entity, int a_BlockX, int a_BlockY, int a_BlockZ) override;
|
||||
void BroadcastWeather (eWeather a_Weather, const cClientHandle * a_Exclude = nullptr);
|
||||
virtual void BroadcastCollectEntity (const cEntity & a_Pickup, const cPlayer & a_Player, int a_Count, const cClientHandle * a_Exclude = nullptr) override;
|
||||
virtual void BroadcastDestroyEntity (const cEntity & a_Entity, const cClientHandle * a_Exclude = nullptr) override;
|
||||
virtual void BroadcastDetachEntity (const cEntity & a_Entity, const cEntity & a_PreviousVehicle) override;
|
||||
virtual void BroadcastEntityEffect (const cEntity & a_Entity, int a_EffectID, int a_Amplifier, short a_Duration, const cClientHandle * a_Exclude = nullptr) override;
|
||||
virtual void BroadcastEntityEquipment (const cEntity & a_Entity, short a_SlotNum, const cItem & a_Item, const cClientHandle * a_Exclude = nullptr) override;
|
||||
virtual void BroadcastEntityHeadLook (const cEntity & a_Entity, const cClientHandle * a_Exclude = nullptr) override;
|
||||
virtual void BroadcastEntityLook (const cEntity & a_Entity, const cClientHandle * a_Exclude = nullptr) override;
|
||||
virtual void BroadcastEntityMetadata (const cEntity & a_Entity, const cClientHandle * a_Exclude = nullptr) override;
|
||||
virtual void BroadcastEntityRelMove (const cEntity & a_Entity, Vector3<Int8> a_RelMove, const cClientHandle * a_Exclude = nullptr) override;
|
||||
virtual void BroadcastEntityRelMoveLook (const cEntity & a_Entity, Vector3<Int8> a_RelMove, const cClientHandle * a_Exclude = nullptr) override;
|
||||
virtual void BroadcastEntityStatus (const cEntity & a_Entity, Int8 a_Status, const cClientHandle * a_Exclude = nullptr) override;
|
||||
virtual void BroadcastEntityVelocity (const cEntity & a_Entity, const cClientHandle * a_Exclude = nullptr) override;
|
||||
virtual void BroadcastEntityAnimation (const cEntity & a_Entity, Int8 a_Animation, const cClientHandle * a_Exclude = nullptr) override; // tolua_export
|
||||
virtual void BroadcastLeashEntity (const cEntity & a_Entity, const cEntity & a_EntityLeashedTo) override;
|
||||
virtual void BroadcastParticleEffect (const AString & a_ParticleName, Vector3f a_Src, Vector3f a_Offset, float a_ParticleData, int a_ParticleAmount, const cClientHandle * a_Exclude = nullptr) override;
|
||||
virtual void BroadcastParticleEffect (const AString & a_ParticleName, Vector3f a_Src, Vector3f a_Offset, float a_ParticleData, int a_ParticleAmount, std::array<int, 2> a_Data, const cClientHandle * a_Exclude = nullptr) override;
|
||||
virtual void BroadcastPlayerListAddPlayer (const cPlayer & a_Player, const cClientHandle * a_Exclude = nullptr) override;
|
||||
virtual void BroadcastPlayerListRemovePlayer (const cPlayer & a_Player, const cClientHandle * a_Exclude = nullptr) override;
|
||||
virtual void BroadcastPlayerListUpdateGameMode (const cPlayer & a_Player, const cClientHandle * a_Exclude = nullptr) override;
|
||||
virtual void BroadcastPlayerListUpdatePing (const cPlayer & a_Player, const cClientHandle * a_Exclude = nullptr) override;
|
||||
virtual void BroadcastPlayerListUpdateDisplayName(const cPlayer & a_Player, const AString & a_CustomName, const cClientHandle * a_Exclude = nullptr) override;
|
||||
virtual void BroadcastRemoveEntityEffect (const cEntity & a_Entity, int a_EffectID, const cClientHandle * a_Exclude = nullptr) override;
|
||||
virtual void BroadcastScoreboardObjective (const AString & a_Name, const AString & a_DisplayName, Byte a_Mode) override;
|
||||
virtual void BroadcastScoreUpdate (const AString & a_Objective, const AString & a_Player, cObjective::Score a_Score, Byte a_Mode) override;
|
||||
virtual void BroadcastDisplayObjective (const AString & a_Objective, cScoreboard::eDisplaySlot a_Display) override;
|
||||
virtual void BroadcastSoundEffect (const AString & a_SoundName, Vector3d a_Position, float a_Volume, float a_Pitch, const cClientHandle * a_Exclude = nullptr) override; // tolua_export
|
||||
virtual void BroadcastSoundParticleEffect (const EffectID a_EffectID, Vector3i a_SrcPos, int a_Data, const cClientHandle * a_Exclude = nullptr) override;
|
||||
virtual void BroadcastSpawnEntity (cEntity & a_Entity, const cClientHandle * a_Exclude = nullptr) override;
|
||||
virtual void BroadcastTeleportEntity (const cEntity & a_Entity, const cClientHandle * a_Exclude = nullptr) override;
|
||||
virtual void BroadcastThunderbolt (Vector3i a_BlockPos, const cClientHandle * a_Exclude = nullptr) override;
|
||||
virtual void BroadcastTimeUpdate (const cClientHandle * a_Exclude = nullptr) override;
|
||||
virtual void BroadcastUnleashEntity (const cEntity & a_Entity) override;
|
||||
virtual void BroadcastUseBed (const cEntity & a_Entity, Vector3i a_BlockPos) override;
|
||||
virtual void BroadcastWeather (eWeather a_Weather, const cClientHandle * a_Exclude = nullptr) override;
|
||||
|
||||
// Deprecated broadcasts maintained for lua compatibility
|
||||
|
||||
// tolua_begin
|
||||
void BroadcastBlockAction(int a_BlockX, int a_BlockY, int a_BlockZ, Byte a_Byte1, Byte a_Byte2, BLOCKTYPE a_BlockType, const cClientHandle * a_Exclude)
|
||||
{
|
||||
LOG("BroadcastBlockAction with integer position is deprecated, use vector-parametered version instead.");
|
||||
BroadcastBlockAction({ a_BlockX, a_BlockY, a_BlockZ }, a_Byte1, a_Byte2, a_BlockType, a_Exclude);
|
||||
}
|
||||
|
||||
void BroadcastSoundEffect(const AString & a_SoundName, double a_X, double a_Y, double a_Z, float a_Volume, float a_Pitch, const cClientHandle * a_Exclude = nullptr)
|
||||
{
|
||||
LOG("BroadcastSoundEffect with double position arguments is deprecated, use vector-parametered version instead.");
|
||||
BroadcastSoundEffect(a_SoundName, { a_X, a_Y, a_Z }, a_Volume, a_Pitch, a_Exclude);
|
||||
}
|
||||
|
||||
void BroadcastSoundParticleEffect(const EffectID a_EffectID, int a_SrcX, int a_SrcY, int a_SrcZ, int a_Data, const cClientHandle * a_Exclude = nullptr)
|
||||
{
|
||||
BroadcastSoundParticleEffect(a_EffectID, { a_SrcX, a_SrcY, a_SrcZ }, a_Data, a_Exclude);
|
||||
}
|
||||
// tolua_end
|
||||
|
||||
virtual cBroadcastInterface & GetBroadcastManager(void) override
|
||||
{
|
||||
@ -855,8 +876,6 @@ public:
|
||||
as at least one requests is active the chunk will be ticked). */
|
||||
void SetChunkAlwaysTicked(int a_ChunkX, int a_ChunkZ, bool a_AlwaysTicked = true); // tolua_export
|
||||
|
||||
cBroadcaster GetBroadcaster();
|
||||
|
||||
private:
|
||||
|
||||
friend class cRoot;
|
||||
|
Loading…
Reference in New Issue
Block a user