Leviathan  0.8.0.0
Leviathan game engine
Leviathan::GameWorld Class Reference

Represents a world that contains entities. More...

#include <GameWorld.h>

Classes

class  Implementation
 

Public Member Functions

DLLEXPORT GameWorld (int32_t worldtype, const std::shared_ptr< PhysicsMaterialManager > &physicsMaterials, int worldid=-1)
 
DLLEXPORT ~GameWorld ()
 
DLLEXPORT bool Init (const WorldNetworkSettings &network, Graphics *graphics)
 Creates resources for the world to work. More...
 
DLLEXPORT void Release ()
 Release resources. More...
 
DLLEXPORT void MarkForClear ()
 Marks all entities to be deleted. More...
 
DLLEXPORT void ClearEntities ()
 Clears all objects from the world. More...
 
DLLEXPORT size_t GetEntityCount () const
 Returns the number of ObjectIDs this world keeps track of. More...
 
DLLEXPORT const auto & GetEntities () const
 Returns the created entity id vector. More...
 
DLLEXPORT void Tick (float elapsed)
 Used to keep track of passed ticks and trigger timed triggers. More...
 
DLLEXPORT void Render (float elapsed)
 Runs systems required for a rendering run. Also updates camera positions. More...
 
DLLEXPORT auto GetCurrentWorldTime () const
 Returns the total amount of time the world has been running. More...
 
DLLEXPORT int GetPhysicalMaterial (const std::string &name)
 Fetches the physical material ID from the material manager. More...
 
DLLEXPORT ObjectID CreateEntity ()
 Creates a new empty entity and returns its id. More...
 
DLLEXPORT void DestroyEntity (ObjectID id)
 Destroys an entity and all of its components. More...
 
DLLEXPORT void QueueDestroyEntity (ObjectID id)
 Deletes an entity during the next tick. More...
 
DLLEXPORT void SetEntitysParent (ObjectID child, ObjectID parent)
 Makes child entity be deleted when parent is deleted. More...
 
DLLEXPORT bool DoesEntityExist (ObjectID id) const
 Returns true if entity exists. More...
 
virtual DLLEXPORT void DestroyAllIn (ObjectID id)
 Removes all components from an entity. More...
 
template<class TComponent >
TComponent & GetComponent (ObjectID id)
 
template<class TComponent >
TComponent * GetComponentPtr (ObjectID id)
 
virtual DLLEXPORT std::tuple< void *, bool > GetComponent (ObjectID id, COMPONENT_TYPE type)
 Gets a component of type or returns nullptr. More...
 
virtual DLLEXPORT std::tuple< void *, ComponentTypeInfo, bool > GetComponentWithType (ObjectID id, COMPONENT_TYPE type)
 Gets a component of type or returns nullptr. More...
 
template<class TComponent >
StateHolder< typename TComponent::StateT > & GetStatesFor ()
 
virtual DLLEXPORT std::tuple< void *, bool > GetStatesFor (COMPONENT_TYPE type)
 Gets a component states of type or returns nullptr. More...
 
virtual DLLEXPORT bool GetRemovedFor (COMPONENT_TYPE type, std::vector< std::tuple< void *, ObjectID >> &result)
 Gets a list of destroyed components of type. More...
 
DLLEXPORT bool GetRemovedForScriptDefined (const std::string &name, std::vector< std::tuple< asIScriptObject *, ObjectID >> &result)
 Variant of GetRemovedFor for script defined types. More...
 
virtual DLLEXPORT bool GetAddedFor (COMPONENT_TYPE type, std::vector< std::tuple< void *, ObjectID, ComponentTypeInfo >> &result)
 Gets a list of created components of type. More...
 
DLLEXPORT bool GetAddedForScriptDefined (const std::string &name, std::vector< std::tuple< asIScriptObject *, ObjectID, ScriptComponentHolder * >> &result)
 Variant of GetAddedFor for script defined types. More...
 
virtual DLLEXPORT void CaptureEntityState (ObjectID id, EntityState &curstate) const
 Captures the current state of an entity. More...
 
virtual DLLEXPORT uint32_t CaptureEntityStaticState (ObjectID id, sf::Packet &receiver) const
 Captures the initial parameters of an entity with components that don't have current state synchronization and also types of all components. More...
 
DLLEXPORT void SetCamera (ObjectID object)
 Sets the entity that acts as a camera. More...
 
DLLEXPORT Ray CastRayFromCamera (int x, int y) const
 Casts a ray from the active camera. More...
 
DLLEXPORT SceneGetScene ()
 
DLLEXPORT SceneNodeGetCameraSceneObject ()
 Returns the scene object the camera is attached to. More...
 
DLLEXPORT void EnablePhysicsDebugDraw ()
 
DLLEXPORT void DisablePhysicsDebugDraw ()
 
PhysicalWorldGetPhysicalWorld ()
 
DLLEXPORT int GetID () const
 
DLLEXPORT int32_t GetType () const
 
DLLEXPORT const auto & GetNetworkSettings () const
 
DLLEXPORT void SetWorldPhysicsFrozenState (bool frozen)
 
DLLEXPORT void SetPaused (bool paused)
 Pause or unpause all systems and physics. More...
 
DLLEXPORT SceneGetSceneWrapper ()
 
DLLEXPORT bool ShouldPlayerReceiveEntity (Position &atposition, Connection &connection)
 Returns true when the player matching the connection should receive updates about an entity. More...
 
DLLEXPORT bool IsConnectionInWorld (Connection &connection) const
 Returns true if a player with the given connection is receiving updates for this world. More...
 
DLLEXPORT void SetPlayerReceiveWorld (std::shared_ptr< ConnectedPlayer > ply)
 Verifies that player is receiving this world. More...
 
const auto & GetConnectedPlayers () const
 This is used by Sendable system to loop all players. More...
 
DLLEXPORT void SendToAllPlayers (const std::shared_ptr< NetworkResponse > &response, RECEIVE_GUARANTEE guarantee) const
 Sends a packet to all connected players. More...
 
DLLEXPORT void SetLocalControl (ObjectID id, bool enabled, const std::shared_ptr< Connection > &allowedconnection)
 Sets local control on a client over an entity or disables it. More...
 
DLLEXPORT const auto & GetOurLocalControl () const
 
DLLEXPORT bool IsUnderOurLocalControl (ObjectID id)
 
DLLEXPORT void SetServerForLocalControl (const std::shared_ptr< Connection > &connection)
 Sets a connection that will be used to send local control entity updates to the server. More...
 
DLLEXPORT const auto & GetServerForLocalControl () const
 
DLLEXPORT void HandleEntityPacket (ResponseEntityUpdate &&message, Connection &connection)
 Applies an entity update packet. More...
 
DLLEXPORT ObjectID HandleEntityPacket (ResponseEntityCreation &message)
 
DLLEXPORT void HandleEntityPacket (ResponseEntityDestruction &message)
 
DLLEXPORT void HandleEntityPacket (ResponseEntityLocalControlStatus &message)
 
DLLEXPORT void SetSunlight ()
 
DLLEXPORT void RemoveSunlight ()
 
DLLEXPORT void SetLightProperties (const Float3 &colour, float intensity=0.0001f, const Float3 &direction=Float3(0.55f, -0.3f, 0.75f), float sourceradius=0.5f, bool castsshadows=true)
 Sets the sunlight properties. More...
 
DLLEXPORT void SetSkybox (const std::string &skyboxname, float brightness=1.f)
 
DLLEXPORT void SetAutoExposure (float mineyeadaptation=0.003f, float maxeyeadaptation=2.0f, float eyeadaptationspeeddown=3.0f, float eyeadaptationspeedup=3.0f, float histogramlog2max=4.0f, float histogramlog2min=-8.0f, float histogrampcthigh=0.985f, float histogrampctlow=0.8f)
 Sets the world camera eye adaptation settings. More...
 
DLLEXPORT CScriptArray * GetRemovedIDsForComponents (CScriptArray *componenttypes)
 Returns a list of ObjectIDs that have been removed from any of the specified component types. More...
 
DLLEXPORT CScriptArray * GetRemovedIDsForScriptComponents (CScriptArray *typenames)
 Returns a list of ObjectIDs that have been removed from any of the script registered component types specified by typeNames. More...
 
DLLEXPORT bool RegisterScriptComponentType (const std::string &name, asIScriptFunction *factory)
 Registers a component type from scripts. More...
 
DLLEXPORT ScriptComponentHolderGetScriptComponentHolder (const std::string &name)
 Retrieves a script registered component type holder. More...
 
DLLEXPORT bool RegisterScriptSystem (const std::string &name, asIScriptObject *system)
 Registers a new system defined in a script. Must implement the ScriptSystem interface. More...
 
DLLEXPORT bool UnregisterScriptSystem (const std::string &name)
 Unregisters a script system that was registered with RegisterScriptSystem. More...
 
DLLEXPORT asIScriptObject * GetScriptSystem (const std::string &name)
 Returns the underlying angelscript object that implements a script system. More...
 
virtual DLLEXPORT void OnUnLinkedFromWindow (Window *window, Graphics *graphics)
 Used to detect that this world is in the background and should not tick. More...
 
virtual DLLEXPORT void OnLinkToWindow (Window *window, Graphics *graphics)
 Called when this is added to a Window. More...
 
virtual DLLEXPORT void SetRunInBackground (bool tickinbackground)
 Configures this world to run tick even when not attached to a window. More...
 
 REFERENCE_HANDLE_UNCOUNTED_TYPE (GameWorld)
 

Protected Member Functions

DLLEXPORT void ApplyQueuedPackets ()
 Applies packets that were received out of order. And throws out any too old packets. More...
 
virtual DLLEXPORT void RunFrameRenderSystems (float elapsed)
 Called by Render which is called from a Window if this is linked to one. More...
 
virtual DLLEXPORT void _RunTickSystems (float elapsed)
 Called by Tick. More...
 
virtual DLLEXPORT void HandleAddedAndDeleted ()
 Handles added entities and components. More...
 
virtual DLLEXPORT void ClearAddedAndRemoved ()
 Clears the added components. Call after HandleAddedAndDeleted. More...
 
virtual DLLEXPORT void _ResetSystems ()
 Resets stored nodes in systems. Used together with _ResetComponents. More...
 
virtual DLLEXPORT void _ResetOrReleaseComponents ()
 Resets components in holders. Used together with _ResetSystems. More...
 
virtual DLLEXPORT void _DoSystemsInit ()
 Called in Init when systems should run their initialization logic. More...
 
virtual DLLEXPORT void _DoSystemsRelease ()
 Called in Release when systems should run their shutdown logic. More...
 
virtual DLLEXPORT void _DoSuspendSystems ()
 Called when this is put in the background and systems (the sound system) should suspend their active objects. More...
 
virtual DLLEXPORT void _DoResumeSystems ()
 Opposite of _DoSuspendSystems. More...
 
virtual DLLEXPORT void _CreateSendableComponentForEntity (ObjectID id)
 Called when this base class wants to create a Sendable component. More...
 
virtual DLLEXPORT void _CreateReceivedComponentForEntity (ObjectID id)
 Called when this base class wants to create a Received component. More...
 
virtual DLLEXPORT void _CreateComponentsFromCreationMessage (ObjectID id, sf::Packet &data, int entriesleft, int decodedtype)
 Called to deserialize initial entity components and their static state. More...
 
virtual DLLEXPORT void _CreateStatesFromUpdateMessage (ObjectID id, int32_t ticknumber, sf::Packet &data, int32_t referencetick, int decodedtype)
 Called to deserialize entity component states from a packet. More...
 
virtual DLLEXPORT void _ApplyLocalControlUpdateMessage (ObjectID id, int32_t ticknumber, sf::Packet &data, int32_t referencetick, int decodedtype)
 Called to apply local control from a clients message. More...
 
virtual DLLEXPORT void _OnLocalControlUpdatedEntity (ObjectID id, int32_t ticknumber)
 This method is for doing checks after applying client sent state to the server. More...
 

Protected Attributes

bool GraphicalMode = false
 If false a graphical Ogre window hasn't been created and purely graphical stuff should be skipped. More...
 

Detailed Description

Represents a world that contains entities.

This is the base class from which worlds that support different components are derived from Custom worls should derive from StandardWorld which has all of the standard components supported. See the GenerateStandardWorld.rb file to figure out how to generate world classes

Definition at line 57 of file GameWorld.h.

Constructor & Destructor Documentation

◆ GameWorld()

DLLEXPORT GameWorld::GameWorld ( int32_t  worldtype,
const std::shared_ptr< PhysicsMaterialManager > &  physicsMaterials,
int  worldid = -1 
)
Parameters
worldidIf >= then uses the specified ID for this world. Otherwise one is automatically generated from IDFactory

Definition at line 77 of file GameWorld.cpp.

78  :
79  pimpl(std::make_unique<Implementation>()),
80  PhysicsMaterials(physicsMaterials), ID(worldid >= 0 ? worldid : IDFactory::GetID()),
81  WorldType(worldtype)
82 {}
static int GetID()
Definition: IDFactory.h:17

◆ ~GameWorld()

DLLEXPORT GameWorld::~GameWorld ( )

Definition at line 84 of file GameWorld.cpp.

85 {
86  // (*WorldDestroyed) = true;
87 
88  // Assert if all objects haven't been released already.
89  // We can't call virtual methods here anymore
90  // This can be hit in tests quite easily if something throws an exception
92  Entities.empty(), "GameWorld: Entities not empty in destructor. Was Release called?");
93 }
#define LEVIATHAN_ASSERT(x, msg)
Definition: Define.h:100

Member Function Documentation

◆ _ApplyLocalControlUpdateMessage()

DLLEXPORT void GameWorld::_ApplyLocalControlUpdateMessage ( ObjectID  id,
int32_t  ticknumber,
sf::Packet &  data,
int32_t  referencetick,
int  decodedtype 
)
protectedvirtual

Called to apply local control from a clients message.

Before this is called it is already verified that the update is allowed, but this method should have cheat checking if that is required

Parameters
decodedtypeThis is used to move unrecognized types up to the base class. -1 if not fetched yet

Definition at line 709 of file GameWorld.cpp.

711 {
712  LOG_ERROR("GameWorld: entity component state decoding for local control was not complete "
713  "before calling base GameWorld implementation");
714 }
#define LOG_ERROR(x)
Definition: Define.h:92

◆ _CreateComponentsFromCreationMessage()

DLLEXPORT void GameWorld::_CreateComponentsFromCreationMessage ( ObjectID  id,
sf::Packet &  data,
int  entriesleft,
int  decodedtype 
)
protectedvirtual

Called to deserialize initial entity components and their static state.

This is the reverse operation for CaptureEntityStaticState

Parameters
decodedtypeThis is used to move unrecognized types up to the base class. -1 if not fetched yet

Definition at line 691 of file GameWorld.cpp.

693 {
694  if(entriesleft < 1)
695  return;
696 
697  LOG_ERROR("GameWorld: entity static state decoding was not complete before calling base "
698  "GameWorld implementation. Received entity won't be fully constructed");
699 }
#define LOG_ERROR(x)
Definition: Define.h:92

◆ _CreateReceivedComponentForEntity()

DLLEXPORT void GameWorld::_CreateReceivedComponentForEntity ( ObjectID  id)
protectedvirtual

Called when this base class wants to create a Received component.

Definition at line 1207 of file GameWorld.cpp.

1208 {
1209  LOG_ERROR("GameWorld: base version of _CreateReceivedComponentForEntity, this shouldn't "
1210  "happen with correct configuration");
1211 }
#define LOG_ERROR(x)
Definition: Define.h:92

◆ _CreateSendableComponentForEntity()

DLLEXPORT void GameWorld::_CreateSendableComponentForEntity ( ObjectID  id)
protectedvirtual

Called when this base class wants to create a Sendable component.

Definition at line 1201 of file GameWorld.cpp.

1202 {
1203  LOG_ERROR("GameWorld: base version of _CreateSendableComponentForEntity, this shouldn't "
1204  "happen with correct configuration");
1205 }
#define LOG_ERROR(x)
Definition: Define.h:92

◆ _CreateStatesFromUpdateMessage()

DLLEXPORT void GameWorld::_CreateStatesFromUpdateMessage ( ObjectID  id,
int32_t  ticknumber,
sf::Packet &  data,
int32_t  referencetick,
int  decodedtype 
)
protectedvirtual

Called to deserialize entity component states from a packet.

Parameters
decodedtypeThis is used to move unrecognized types up to the base class. -1 if not fetched yet

Definition at line 701 of file GameWorld.cpp.

703 {
704  LOG_ERROR(
705  "GameWorld: entity component state decoding was not complete before calling base "
706  "GameWorld implementation. Not all states have been decoded");
707 }
#define LOG_ERROR(x)
Definition: Define.h:92

◆ _DoResumeSystems()

DLLEXPORT void GameWorld::_DoResumeSystems ( )
protectedvirtual

Opposite of _DoSuspendSystems.

Definition at line 1191 of file GameWorld.cpp.

1192 {
1193  // We are responsible for script systems //
1194  for(auto iter = pimpl->RegisteredScriptSystems.begin();
1195  iter != pimpl->RegisteredScriptSystems.end(); ++iter) {
1196 
1197  iter->second->Resume();
1198  }
1199 }

◆ _DoSuspendSystems()

DLLEXPORT void GameWorld::_DoSuspendSystems ( )
protectedvirtual

Called when this is put in the background and systems (the sound system) should suspend their active objects.

Note
Only called if TickWhileInBackground is false (and won't be called if that is changed while this is in the background)

Definition at line 1181 of file GameWorld.cpp.

1182 {
1183  // We are responsible for script systems //
1184  for(auto iter = pimpl->RegisteredScriptSystems.begin();
1185  iter != pimpl->RegisteredScriptSystems.end(); ++iter) {
1186 
1187  iter->second->Suspend();
1188  }
1189 }

◆ _DoSystemsInit()

DLLEXPORT void GameWorld::_DoSystemsInit ( )
protectedvirtual

Called in Init when systems should run their initialization logic.

Definition at line 1160 of file GameWorld.cpp.

1161 {
1162  // Script systems are initialized as they are created
1163 }

◆ _DoSystemsRelease()

DLLEXPORT void GameWorld::_DoSystemsRelease ( )
protectedvirtual

Called in Release when systems should run their shutdown logic.

Definition at line 1165 of file GameWorld.cpp.

1166 {
1167  // This can be called after Releasing once already
1168  if(!pimpl)
1169  return;
1170 
1171  // We are responsible for script systems //
1172  for(auto iter = pimpl->RegisteredScriptSystems.begin();
1173  iter != pimpl->RegisteredScriptSystems.end(); ++iter) {
1174 
1175  iter->second->Release();
1176  }
1177 
1178  pimpl->RegisteredScriptSystems.clear();
1179 }

◆ _OnLocalControlUpdatedEntity()

DLLEXPORT void GameWorld::_OnLocalControlUpdatedEntity ( ObjectID  id,
int32_t  ticknumber 
)
protectedvirtual

This method is for doing checks after applying client sent state to the server.

For example to block cheating and reset things on the server. Right now the base implementation resets the physics position of a moved entity

Definition at line 1521 of file GameWorld.cpp.

1522 {
1523  Position* position = GetComponentPtr<Position>(id);
1524  Physics* physics = GetComponentPtr<Physics>(id);
1525 
1526  if(position && physics) {
1527 
1528  if(position->Marked) {
1529 
1530  physics->JumpTo(*position);
1531  }
1532  }
1533 }
Entity has position and direction it is looking at.
Definition: Components.h:36
Entity has a physical component.
Definition: Components.h:347
DLLEXPORT void JumpTo(Position &target)
Syncs this physics body to a changed position.
Definition: Components.cpp:110

◆ _ResetOrReleaseComponents()

DLLEXPORT void GameWorld::_ResetOrReleaseComponents ( )
protectedvirtual

Resets components in holders. Used together with _ResetSystems.

Definition at line 831 of file GameWorld.cpp.

832 {
833  // Skip double Release
834  if(!pimpl)
835  return;
836 
837  // We are responsible for script components //
838  for(auto iter = pimpl->RegisteredScriptComponents.begin();
839  iter != pimpl->RegisteredScriptComponents.end(); ++iter) {
840 
841  iter->second->ReleaseAllComponents();
842  }
843 }

◆ _ResetSystems()

DLLEXPORT void GameWorld::_ResetSystems ( )
protectedvirtual

Resets stored nodes in systems. Used together with _ResetComponents.

Definition at line 817 of file GameWorld.cpp.

818 {
819  // Skip double Release
820  if(!pimpl)
821  return;
822 
823  // We are responsible for script systems //
824  for(auto iter = pimpl->RegisteredScriptSystems.begin();
825  iter != pimpl->RegisteredScriptSystems.end(); ++iter) {
826 
827  iter->second->Clear();
828  }
829 }

◆ _RunTickSystems()

DLLEXPORT void GameWorld::_RunTickSystems ( float  elapsed)
protectedvirtual

Called by Tick.

Derived worls should run their systems that need to be ran before the basic systems and then call this and finally run systems that need to be ran after the base class' systems (if any)

Definition at line 854 of file GameWorld.cpp.

855 {
856  // We are responsible for script systems //
857  for(auto iter = pimpl->RegisteredScriptSystems.begin();
858  iter != pimpl->RegisteredScriptSystems.end(); ++iter) {
859 
860  iter->second->Run(elapsed);
861  }
862 }

◆ ApplyQueuedPackets()

DLLEXPORT void GameWorld::ApplyQueuedPackets ( )
protected

Applies packets that were received out of order. And throws out any too old packets.

Definition at line 1535 of file GameWorld.cpp.

1536 {
1537  if(!pimpl->QueuedEntityUpdates.empty()) {
1538  }
1539 
1540  // Applies packets that were received out of order. And throws out any too old packets
1541 
1542  // if(!InitialEntityPackets.empty())
1543  // _ApplyInitialEntityPackets();
1544 
1545  // if(!EntityUpdatePackets.empty())
1546  // _ApplyEntityUpdatePackets();
1547 }

◆ CaptureEntityState()

DLLEXPORT void GameWorld::CaptureEntityState ( ObjectID  id,
EntityState curstate 
) const
virtual

Captures the current state of an entity.

Definition at line 684 of file GameWorld.cpp.

684 {}

◆ CaptureEntityStaticState()

DLLEXPORT uint32_t GameWorld::CaptureEntityStaticState ( ObjectID  id,
sf::Packet &  receiver 
) const
virtual

Captures the initial parameters of an entity with components that don't have current state synchronization and also types of all components.

Returns
The count of component data entries in receiver

Definition at line 686 of file GameWorld.cpp.

687 {
688  return 0;
689 }

◆ CastRayFromCamera()

DLLEXPORT Ray GameWorld::CastRayFromCamera ( int  x,
int  y 
) const

Casts a ray from the active camera.

Parameters
xPixel x coordinate (range [0, window width])
yPixel y coordinate (range [0, window height])
Exceptions
InvalidStateif this world has no active camera
See also
SetCamera
Version
This now takes in pixel values

Definition at line 494 of file GameWorld.cpp.

495 {
496  // Fail if there is no active camera //
497  if(CameraEntity == NULL_OBJECT)
498  throw InvalidState("This world has no active CameraEntity");
499 
500  if(!pimpl->WorldCamera)
501  throw InvalidState("This world has no initialized camera resources");
502 
503  // Read the latest set data from the camera
504  // TODO: could jump to the actual latest position here if wanted
505  return pimpl->WorldCamera->screenPointToRay(bs::Vector2I(x, y));
506 }
constexpr ObjectID NULL_OBJECT
Definition: EntityCommon.h:14

◆ ClearAddedAndRemoved()

DLLEXPORT void GameWorld::ClearAddedAndRemoved ( )
protectedvirtual

Clears the added components. Call after HandleAddedAndDeleted.

Definition at line 806 of file GameWorld.cpp.

807 {
808  // We are responsible for script components //
809  for(auto iter = pimpl->RegisteredScriptComponents.begin();
810  iter != pimpl->RegisteredScriptComponents.end(); ++iter) {
811 
812  iter->second->ClearAdded();
813  iter->second->ClearRemoved();
814  }
815 }

◆ ClearEntities()

DLLEXPORT void GameWorld::ClearEntities ( )

Clears all objects from the world.

Definition at line 892 of file GameWorld.cpp.

893 {
894  // Release objects //
895  Entities.clear();
896  Parents.clear();
897  // This shouldn't be used all that much so release the memory
898  Parents.shrink_to_fit();
899 
900  // Clear all nodes //
901  _ResetSystems();
902 
903  // Clears all components
904  // Runs Release on components that need it
906 
907  // Notify everybody that all entities are discarded //
908  for(auto iter = ReceivingPlayers.begin(); iter != ReceivingPlayers.end(); ++iter) {
909 
910  auto safe = (*iter)->GetConnection();
911 
912  if(!safe->IsValidForSend()) {
913  // Player has probably closed their connection //
914  continue;
915  }
916 
917  Logger::Get()->Write("TODO: send world clear message");
918  DEBUG_BREAK;
919  }
920 }
DLLEXPORT void Write(const std::string &data) override
Definition: Logger.cpp:113
virtual DLLEXPORT void _ResetOrReleaseComponents()
Resets components in holders. Used together with _ResetSystems.
Definition: GameWorld.cpp:831
static DLLEXPORT Logger * Get()
Definition: Logger.cpp:106
virtual DLLEXPORT void _ResetSystems()
Resets stored nodes in systems. Used together with _ResetComponents.
Definition: GameWorld.cpp:817

◆ CreateEntity()

DLLEXPORT ObjectID GameWorld::CreateEntity ( )

Creates a new empty entity and returns its id.

Todo:
Make this have a per world counter

Definition at line 865 of file GameWorld.cpp.

866 {
867  if(!GetNetworkSettings().IsAuthoritative) {
868  // Clients create high number entities. This is not optimal but good enough for now
869  auto id = (1 << 31) | static_cast<ObjectID>(IDFactory::GetID());
870 
871  Entities.push_back(id);
872 
873  return id;
874 
875  } else {
876  auto id = static_cast<ObjectID>(IDFactory::GetID());
877 
878  Entities.push_back(id);
879 
880  if(NetworkSettings.IsAuthoritative) {
881  // NewlyCreatedEntities.push_back(id);
882 
883  if(NetworkSettings.AutoCreateNetworkComponents) {
885  }
886  }
887 
888  return id;
889  }
890 }
virtual DLLEXPORT void _CreateSendableComponentForEntity(ObjectID id)
Called when this base class wants to create a Sendable component.
Definition: GameWorld.cpp:1201
static int GetID()
Definition: IDFactory.h:17
bool IsAuthoritative
This is true on the server.
DLLEXPORT const auto & GetNetworkSettings() const
Definition: GameWorld.h:290

◆ DestroyAllIn()

DLLEXPORT void GameWorld::DestroyAllIn ( ObjectID  id)
virtual

Removes all components from an entity.

Definition at line 1214 of file GameWorld.cpp.

1215 {
1216  // This can be called after Releasing once already
1217  if(!pimpl)
1218  return;
1219 
1220  // Handle script types
1221  for(auto iter = pimpl->RegisteredScriptComponents.begin();
1222  iter != pimpl->RegisteredScriptComponents.end(); ++iter) {
1223 
1224  // Just try to remove like the normal c++ components until there is a better way
1225  iter->second->ReleaseComponent(id);
1226  }
1227 }

◆ DestroyEntity()

DLLEXPORT void GameWorld::DestroyEntity ( ObjectID  id)

Destroys an entity and all of its components.

Warning
This destroyes the entity immediately. If called during a system update this will cause issues as required components may be destroyed and cached components will only be updated at the start of next tick. So use QueueDestroyEntity instead.
Todo:
Make this less expensive

Definition at line 937 of file GameWorld.cpp.

938 {
939  // Fail if trying to delete NULL_OBJECT
940  if(id == NULL_OBJECT)
941  throw InvalidArgument("Cannot destroy NULL_OBJECT");
942 
943  // Fail if ticking currently //
944  if(TickInProgress)
945  throw InvalidState(
946  "Cannot DestroyEntity while ticking. Use QueueDestroyEntity instead");
947 
948  for(auto iter = Entities.begin(); iter != Entities.end(); ++iter) {
949 
950  if(*iter == id) {
951 
952  Entities.erase(iter);
953  _DoDestroy(id);
954  return;
955  }
956  }
957 
958  LOG_ERROR("GameWorld: DestroyEntity: unknown entity id: " + std::to_string(id));
959 }
constexpr ObjectID NULL_OBJECT
Definition: EntityCommon.h:14
#define LOG_ERROR(x)
Definition: Define.h:92

◆ DisablePhysicsDebugDraw()

DLLEXPORT void GameWorld::DisablePhysicsDebugDraw ( )

Definition at line 536 of file GameWorld.cpp.

537 {
538  if(_PhysicalWorld) {
539 
540  // Clear the contents
541  if(pimpl->DebugDraw)
542  pimpl->DebugDraw->OnBeginDraw();
543 
544  _PhysicalWorld->SetDebugDrawer(nullptr);
545  }
546 }

◆ DoesEntityExist()

DLLEXPORT bool Leviathan::GameWorld::DoesEntityExist ( ObjectID  id) const
inline

Returns true if entity exists.

Definition at line 131 of file GameWorld.h.

132  {
133  for(const auto& entity : Entities) {
134  if(id == entity)
135  return true;
136  }
137 
138  return false;
139  }

◆ EnablePhysicsDebugDraw()

DLLEXPORT void GameWorld::EnablePhysicsDebugDraw ( )

Definition at line 527 of file GameWorld.cpp.

528 {
529  if(_PhysicalWorld && LinkedToWindow) {
530  pimpl->DebugDraw = std::make_shared<PhysicsDebugDrawer>(*LinkedToWindow, *this);
531 
532  _PhysicalWorld->SetDebugDrawer(pimpl->DebugDraw);
533  }
534 }

◆ GetAddedFor()

DLLEXPORT bool GameWorld::GetAddedFor ( COMPONENT_TYPE  type,
std::vector< std::tuple< void *, ObjectID, ComponentTypeInfo >> &  result 
)
virtual

Gets a list of created components of type.

See also
GetRemovedFor
Todo:
Find a better way than having to have the component type specified here. This is only used by script node proxy, so this has to be somewhere for it to access

Definition at line 1132 of file GameWorld.cpp.

1134 {
1135  return false;
1136 }

◆ GetAddedForScriptDefined()

DLLEXPORT bool GameWorld::GetAddedForScriptDefined ( const std::string &  name,
std::vector< std::tuple< asIScriptObject *, ObjectID, ScriptComponentHolder * >> &  result 
)

Variant of GetAddedFor for script defined types.

Definition at line 1138 of file GameWorld.cpp.

1140 {
1141  auto iter = pimpl->RegisteredScriptComponents.find(name);
1142 
1143  if(iter == pimpl->RegisteredScriptComponents.end())
1144  return false;
1145 
1146  auto& added = iter->second->GetAdded();
1147 
1148  result.reserve(result.size() + added.size());
1149 
1150  for(const auto& tuple : added) {
1151 
1152  result.push_back(
1153  std::make_tuple(std::get<0>(tuple), std::get<1>(tuple), iter->second.get()));
1154  }
1155 
1156  return true;
1157 }

◆ GetCameraSceneObject()

DLLEXPORT SceneNode * GameWorld::GetCameraSceneObject ( )

Returns the scene object the camera is attached to.

Useful to attach backgrounds and other static items to the camera

Definition at line 508 of file GameWorld.cpp.

509 {
510  return pimpl->WorldCameraSO.get();
511 }

◆ GetComponent() [1/2]

template<class TComponent >
TComponent& Leviathan::GameWorld::GetComponent ( ObjectID  id)
inline

Helper for getting component of type. This is much slower than direct lookups with the actual implementation class' GetComponent_Position etc. methods

Exceptions
NotFoundif entity has no component of the wanted type

Definition at line 150 of file GameWorld.h.

151  {
152  std::tuple<void*, bool> component = GetComponent(id, TComponent::TYPE);
153 
154  if(!std::get<1>(component))
155  throw InvalidArgument("Unrecognized component type as template parameter");
156 
157  void* ptr = std::get<0>(component);
158 
159  if(!ptr)
160  throw NotFound("Component for entity with id was not found");
161 
162  return *static_cast<TComponent*>(ptr);
163  }
TComponent & GetComponent(ObjectID id)
Definition: GameWorld.h:150

◆ GetComponent() [2/2]

DLLEXPORT std::tuple< void *, bool > GameWorld::GetComponent ( ObjectID  id,
COMPONENT_TYPE  type 
)
virtual

Gets a component of type or returns nullptr.

Returns
Tuple of pointer to component and boolean indicating if the type is known

Definition at line 1096 of file GameWorld.cpp.

1097 {
1098  return std::make_tuple(nullptr, false);
1099 }

◆ GetComponentPtr()

template<class TComponent >
TComponent* Leviathan::GameWorld::GetComponentPtr ( ObjectID  id)
inline

Helper for getting component of type. This is much slower than direct lookups with the actual implementation class' GetComponent_Position etc. methods

Returns
null if not found

Definition at line 170 of file GameWorld.h.

171  {
172  std::tuple<void*, bool> component = GetComponent(id, TComponent::TYPE);
173 
174  void* ptr = std::get<0>(component);
175 
176  if(!ptr)
177  return nullptr;
178 
179  return static_cast<TComponent*>(ptr);
180  }
TComponent & GetComponent(ObjectID id)
Definition: GameWorld.h:150

◆ GetComponentWithType()

DLLEXPORT std::tuple< void *, ComponentTypeInfo, bool > GameWorld::GetComponentWithType ( ObjectID  id,
COMPONENT_TYPE  type 
)
virtual

Gets a component of type or returns nullptr.

Returns
Tuple of pointer to component and boolean indicating if the type is known

Definition at line 1101 of file GameWorld.cpp.

1103 {
1104  return std::make_tuple(nullptr, ComponentTypeInfo(-1, -1), false);
1105 }

◆ GetConnectedPlayers()

const auto& Leviathan::GameWorld::GetConnectedPlayers ( ) const
inline

This is used by Sendable system to loop all players.

Returns
The list of players in this world

Definition at line 326 of file GameWorld.h.

327  {
328  return ReceivingPlayers;
329  }

◆ GetCurrentWorldTime()

DLLEXPORT auto Leviathan::GameWorld::GetCurrentWorldTime ( ) const
inline

Returns the total amount of time the world has been running.

Definition at line 103 of file GameWorld.h.

104  {
105  return TotalElapsed;
106  }

◆ GetEntities()

DLLEXPORT const auto& Leviathan::GameWorld::GetEntities ( ) const
inline

Returns the created entity id vector.

Definition at line 89 of file GameWorld.h.

90  {
91  return Entities;
92  }

◆ GetEntityCount()

DLLEXPORT size_t Leviathan::GameWorld::GetEntityCount ( ) const
inline

Returns the number of ObjectIDs this world keeps track of.

Note
There may actually be more entities as it is possible to create components for ids that are not created (this is not recommended but it isn't enforced)

Definition at line 83 of file GameWorld.h.

84  {
85  return Entities.size();
86  }

◆ GetID()

DLLEXPORT int Leviathan::GameWorld::GetID ( ) const
inline
Returns
the unique ID of this world

Definition at line 279 of file GameWorld.h.

280  {
281  return ID;
282  }

◆ GetNetworkSettings()

DLLEXPORT const auto& Leviathan::GameWorld::GetNetworkSettings ( ) const
inline

Definition at line 290 of file GameWorld.h.

291  {
292  return NetworkSettings;
293  }

◆ GetOurLocalControl()

DLLEXPORT const auto& Leviathan::GameWorld::GetOurLocalControl ( ) const
inline
Returns
The list of entities that this client has control over

Definition at line 342 of file GameWorld.h.

343  {
344  return OurActiveLocalControl;
345  }

◆ GetPhysicalMaterial()

DLLEXPORT int GameWorld::GetPhysicalMaterial ( const std::string &  name)

Fetches the physical material ID from the material manager.

Returns
-1 if not found. The id otherwise

Definition at line 929 of file GameWorld.cpp.

930 {
931  if(!PhysicsMaterials)
932  return -1;
933 
934  return PhysicsMaterials->GetMaterialID(name);
935 }

◆ GetPhysicalWorld()

PhysicalWorld* Leviathan::GameWorld::GetPhysicalWorld ( )
inline

Definition at line 273 of file GameWorld.h.

274  {
275  return _PhysicalWorld.get();
276  }

◆ GetRemovedFor()

DLLEXPORT bool GameWorld::GetRemovedFor ( COMPONENT_TYPE  type,
std::vector< std::tuple< void *, ObjectID >> &  result 
)
virtual

Gets a list of destroyed components of type.

Returns
True if the type is known and no further base classes need to be checked

Definition at line 1112 of file GameWorld.cpp.

1114 {
1115  return false;
1116 }

◆ GetRemovedForScriptDefined()

DLLEXPORT bool GameWorld::GetRemovedForScriptDefined ( const std::string &  name,
std::vector< std::tuple< asIScriptObject *, ObjectID >> &  result 
)

Variant of GetRemovedFor for script defined types.

Definition at line 1118 of file GameWorld.cpp.

1120 {
1121  auto iter = pimpl->RegisteredScriptComponents.find(name);
1122 
1123  if(iter == pimpl->RegisteredScriptComponents.end())
1124  return false;
1125 
1126  auto& removed = iter->second->GetRemoved();
1127 
1128  result.insert(std::end(result), std::begin(removed), std::end(removed));
1129  return true;
1130 }

◆ GetRemovedIDsForComponents()

DLLEXPORT CScriptArray * GameWorld::GetRemovedIDsForComponents ( CScriptArray *  componenttypes)

Returns a list of ObjectIDs that have been removed from any of the specified component types.

Definition at line 1603 of file GameWorld.cpp.

1604 {
1605  if(!componenttypes)
1606  return nullptr;
1607 
1608  if(componenttypes->GetElementTypeId() !=
1610 
1611  LOG_ERROR("GameWorld: GetRemovedIDsForComponents: given an array of wrong type");
1612  componenttypes->Release();
1613  return nullptr;
1614  }
1615 
1616  std::vector<std::tuple<void*, ObjectID>> result;
1617 
1618  for(asUINT i = 0; i < componenttypes->GetSize(); ++i) {
1619 
1620  uint16_t* type = static_cast<uint16_t*>(componenttypes->At(i));
1621 
1622  if(!GetRemovedFor(static_cast<COMPONENT_TYPE>(*type), result)) {
1623 
1624  LOG_WARNING("GameWorld: GetRemovedIDsForComponents: unknown component type: " +
1625  std::to_string(*type));
1626  }
1627  }
1628 
1629  componenttypes->Release();
1630 
1631  asITypeInfo* typeInfo =
1632  ScriptExecutor::Get()->GetASEngine()->GetTypeInfoByDecl("array<ObjectID>");
1633 
1634  CScriptArray* array = CScriptArray::Create(typeInfo, static_cast<asUINT>(result.size()));
1635 
1636  if(!array)
1637  return nullptr;
1638 
1639  for(asUINT i = 0; i < static_cast<asUINT>(result.size()); ++i) {
1640 
1641  array->SetValue(i, &std::get<1>(result[i]));
1642  }
1643 
1644  return array;
1645 }
DLLEXPORT asIScriptEngine * GetASEngine()
#define LOG_ERROR(x)
Definition: Define.h:92
static int Get(ScriptExecutor *resolver)
#define LOG_WARNING(x)
Definition: Define.h:91
static DLLEXPORT ScriptExecutor * Get()
unsigned short uint16_t
Definition: core.h:39
virtual DLLEXPORT bool GetRemovedFor(COMPONENT_TYPE type, std::vector< std::tuple< void *, ObjectID >> &result)
Gets a list of destroyed components of type.
Definition: GameWorld.cpp:1112

◆ GetRemovedIDsForScriptComponents()

DLLEXPORT CScriptArray * GameWorld::GetRemovedIDsForScriptComponents ( CScriptArray *  typenames)

Returns a list of ObjectIDs that have been removed from any of the script registered component types specified by typeNames.

Definition at line 1647 of file GameWorld.cpp.

1648 {
1649  if(!typenames)
1650  return nullptr;
1651 
1652  if(typenames->GetElementTypeId() !=
1654 
1655  LOG_ERROR("GameWorld: GetRemovedIDsForScriptComponents: given an array of wrong type "
1656  "(expected array<string>)");
1657  typenames->Release();
1658  return nullptr;
1659  }
1660 
1661  std::vector<std::tuple<asIScriptObject*, ObjectID>> result;
1662 
1663  for(asUINT i = 0; i < typenames->GetSize(); ++i) {
1664 
1665  std::string* type = static_cast<std::string*>(typenames->At(i));
1666 
1667  if(!GetRemovedForScriptDefined(*type, result)) {
1668 
1669  LOG_WARNING(
1670  "GameWorld: GetRemovedIDsForScriptComponents: unknown component type: " +
1671  *type);
1672  }
1673  }
1674 
1675  typenames->Release();
1676 
1677  asITypeInfo* typeInfo =
1678  ScriptExecutor::Get()->GetASEngine()->GetTypeInfoByDecl("array<ObjectID>");
1679 
1680  CScriptArray* array = CScriptArray::Create(typeInfo, static_cast<asUINT>(result.size()));
1681 
1682  if(!array)
1683  return nullptr;
1684 
1685  for(asUINT i = 0; i < static_cast<asUINT>(result.size()); ++i) {
1686 
1687  array->SetValue(i, &std::get<1>(result[i]));
1688  }
1689 
1690  return array;
1691 }
DLLEXPORT asIScriptEngine * GetASEngine()
#define LOG_ERROR(x)
Definition: Define.h:92
static int Get(ScriptExecutor *resolver)
#define LOG_WARNING(x)
Definition: Define.h:91
DLLEXPORT bool GetRemovedForScriptDefined(const std::string &name, std::vector< std::tuple< asIScriptObject *, ObjectID >> &result)
Variant of GetRemovedFor for script defined types.
Definition: GameWorld.cpp:1118
static DLLEXPORT ScriptExecutor * Get()

◆ GetScene()

DLLEXPORT Scene * GameWorld::GetScene ( )

Definition at line 513 of file GameWorld.cpp.

514 {
515  LEVIATHAN_ASSERT(pimpl, "GameWorld::GetScene called after releasing");
516  return pimpl->WorldScene.get();
517 }
#define LEVIATHAN_ASSERT(x, msg)
Definition: Define.h:100

◆ GetSceneWrapper()

DLLEXPORT Scene * GameWorld::GetSceneWrapper ( )
Returns
The world scene with reference count incremented

Definition at line 519 of file GameWorld.cpp.

520 {
521  Scene* scene = pimpl->WorldScene.get();
522  if(scene)
523  scene->AddRef();
524  return scene;
525 }
FORCE_INLINE void AddRef() const

◆ GetScriptComponentHolder()

DLLEXPORT ScriptComponentHolder * GameWorld::GetScriptComponentHolder ( const std::string &  name)

Retrieves a script registered component type holder.

Note
Increments refcount on return value

Definition at line 1710 of file GameWorld.cpp.

1711 {
1712  // if called after release
1713  if(!pimpl)
1714  return nullptr;
1715 
1716  auto iter = pimpl->RegisteredScriptComponents.find(name);
1717 
1718  if(iter == pimpl->RegisteredScriptComponents.end())
1719  return nullptr;
1720 
1721  iter->second->AddRef();
1722  return iter->second.get();
1723 }

◆ GetScriptSystem()

DLLEXPORT asIScriptObject * GameWorld::GetScriptSystem ( const std::string &  name)

Returns the underlying angelscript object that implements a script system.

Note
Increases refcount on returned object

Definition at line 1772 of file GameWorld.cpp.

1773 {
1774  // if called after release
1775  if(!pimpl)
1776  return nullptr;
1777 
1778  auto iter = pimpl->RegisteredScriptSystems.find(name);
1779 
1780  if(iter == pimpl->RegisteredScriptSystems.end()) {
1781 
1782  LOG_ERROR("GameWorld: GetScriptSystemDirect: world has no system called: " + name);
1783  return nullptr;
1784  }
1785 
1786  return iter->second->GetASImplementationObject();
1787 }
#define LOG_ERROR(x)
Definition: Define.h:92

◆ GetServerForLocalControl()

DLLEXPORT const auto& Leviathan::GameWorld::GetServerForLocalControl ( ) const
inline

Definition at line 366 of file GameWorld.h.

367  {
368  return ClientToServerConnection;
369  }

◆ GetStatesFor() [1/2]

template<class TComponent >
StateHolder<typename TComponent::StateT>& Leviathan::GameWorld::GetStatesFor ( )
inline

Helper for getting component state holder for type. This is much slower than direct lookups with the actual implementation class' GetStatesFor_Position etc. methods

Exceptions
NotFoundif entity has no component of the wanted type

Definition at line 198 of file GameWorld.h.

199  {
200  std::tuple<void*, bool> stateHolder = GetStatesFor(TComponent::TYPE);
201 
202  if(!std::get<1>(stateHolder))
203  throw InvalidArgument("Unrecognized component type as template parameter for "
204  "state holder");
205 
206  void* ptr = std::get<0>(stateHolder);
207 
208  return *static_cast<StateHolder<typename TComponent::StateT>*>(ptr);
209  }
StateHolder< typename TComponent::StateT > & GetStatesFor()
Definition: GameWorld.h:198

◆ GetStatesFor() [2/2]

DLLEXPORT std::tuple< void *, bool > GameWorld::GetStatesFor ( COMPONENT_TYPE  type)
virtual

Gets a component states of type or returns nullptr.

Returns
Tuple of pointer to component and boolean indicating if the type is known

Definition at line 1107 of file GameWorld.cpp.

1108 {
1109  return std::make_tuple(nullptr, false);
1110 }

◆ GetType()

DLLEXPORT int32_t Leviathan::GameWorld::GetType ( ) const
inline
Returns
the type of this world

Definition at line 285 of file GameWorld.h.

286  {
287  return WorldType;
288  }

◆ HandleAddedAndDeleted()

DLLEXPORT void GameWorld::HandleAddedAndDeleted ( )
protectedvirtual

Handles added entities and components.

Construct new nodes based on components values. This is split into multiple parts to support child classes using the same Component types in additional nodes

Definition at line 796 of file GameWorld.cpp.

797 {
798  // We are responsible for script systems //
799  for(auto iter = pimpl->RegisteredScriptSystems.begin();
800  iter != pimpl->RegisteredScriptSystems.end(); ++iter) {
801 
802  iter->second->CreateAndDestroyNodes();
803  }
804 }

◆ HandleEntityPacket() [1/4]

DLLEXPORT void GameWorld::HandleEntityPacket ( ResponseEntityUpdate &&  message,
Connection connection 
)

Applies an entity update packet.

Note
With updates the message is queued (and moved) if we don't have the entity specified by the id
Todo:
If we receive an update after an entity is destroyed the message should not be queued

Definition at line 1323 of file GameWorld.cpp.

1325 {
1326  if(NetworkSettings.IsAuthoritative) {
1327 
1328  // Find matching local control before allowing
1329  auto found = ActiveLocalControl.find(message.EntityID);
1330 
1331  if(found != ActiveLocalControl.end()) {
1332 
1333  if(found->second != &connection) {
1334 
1335  // It's unsafe to dereference found->second here
1336  LOG_WARNING("GameWorld: wrong player sent local control message, entity: " +
1337  std::to_string(message.EntityID));
1338  return;
1339  }
1340 
1341  _ApplyLocalControlUpdateMessage(message.EntityID, message.TickNumber,
1342  message.UpdateData, message.ReferenceTick, -1);
1343  _OnLocalControlUpdatedEntity(message.EntityID, message.TickNumber);
1344  return;
1345  }
1346 
1347  LOG_WARNING(
1348  "GameWorld: didn't find local control entity for ResponseEntityUpdate, entity: " +
1349  std::to_string(message.EntityID));
1350  return;
1351  }
1352 
1353  // Don't apply if we don't have the entity
1354  bool found = false;
1355 
1356  for(auto entity : Entities) {
1357  if(entity == message.EntityID) {
1358 
1359  found = true;
1360  break;
1361  }
1362  }
1363 
1364  if(!found) {
1365 
1366  LOG_WARNING(
1367  "GameWorld: HandleEntityPacket: received update for non-existing entity, id: " +
1368  std::to_string(message.EntityID) +
1369  " TODO: queue for later applying in case packets are out of order");
1370  return;
1371  }
1372 
1373  // If this is controlled by us this is handled differently
1374  for(auto entity : OurActiveLocalControl) {
1375 
1376  if(entity == message.EntityID) {
1377 
1378  // TODO: apply corrections if our simulation was incorrect / not allowed
1379  return;
1380  }
1381  }
1382 
1383  try {
1384  _CreateStatesFromUpdateMessage(message.EntityID, message.TickNumber,
1385  message.UpdateData, message.ReferenceTick, -1);
1386  } catch(const InvalidArgument& e) {
1387  LOG_ERROR("GameWorld: HandleEntityPacket: trying to load update packet data caused an "
1388  "exception: ");
1389  e.PrintToLog();
1390  LOG_INFO("GameWorld: note: entity may have partially updated states, id: " +
1391  std::to_string(message.EntityID));
1392  }
1393 }
#define LOG_INFO(x)
Definition: Define.h:90
#define LOG_ERROR(x)
Definition: Define.h:92
virtual DLLEXPORT void _ApplyLocalControlUpdateMessage(ObjectID id, int32_t ticknumber, sf::Packet &data, int32_t referencetick, int decodedtype)
Called to apply local control from a clients message.
Definition: GameWorld.cpp:709
#define LOG_WARNING(x)
Definition: Define.h:91
bool IsAuthoritative
This is true on the server.
virtual DLLEXPORT void _CreateStatesFromUpdateMessage(ObjectID id, int32_t ticknumber, sf::Packet &data, int32_t referencetick, int decodedtype)
Called to deserialize entity component states from a packet.
Definition: GameWorld.cpp:701
virtual DLLEXPORT void _OnLocalControlUpdatedEntity(ObjectID id, int32_t ticknumber)
This method is for doing checks after applying client sent state to the server.
Definition: GameWorld.cpp:1521
virtual DLLEXPORT void PrintToLog() const noexcept
Definition: Exceptions.cpp:35

◆ HandleEntityPacket() [2/4]

DLLEXPORT ObjectID GameWorld::HandleEntityPacket ( ResponseEntityCreation &  message)
Returns
The id of the created entity or NULL_OBJECT

Definition at line 1395 of file GameWorld.cpp.

1396 {
1397  if(NetworkSettings.IsAuthoritative) {
1398 
1399  LOG_WARNING("GameWorld: authoritative world is ignoring ResponseEntityCreation");
1400  return NULL_OBJECT;
1401  }
1402 
1403  if(message.ComponentCount > 1000) {
1404  LOG_ERROR("GameWorld: HandleEntityPacket: entity has more than 1000 components. "
1405  "Packet is likely corrupted / forged, ignoring");
1406  return NULL_OBJECT;
1407  }
1408 
1409  // TODO: somehow detect if the ID collides with local entities (once those are allowed)
1410  Entities.push_back(message.EntityID);
1411 
1412  if(!NetworkSettings.IsAuthoritative) {
1413 
1414  if(NetworkSettings.AutoCreateNetworkComponents) {
1415  _CreateReceivedComponentForEntity(message.EntityID);
1416  }
1417  }
1418 
1419  try {
1421  message.EntityID, message.InitialComponentData, message.ComponentCount, -1);
1422 
1423  return message.EntityID;
1424  } catch(const InvalidArgument& e) {
1425  LOG_ERROR(
1426  "GameWorld: HandleEntityPacket: trying to load packet data caused an exception: ");
1427  e.PrintToLog();
1428  LOG_INFO("GameWorld: destroying invalid received entity: " +
1429  std::to_string(message.EntityID));
1430  DestroyEntity(message.EntityID);
1431 
1432  return NULL_OBJECT;
1433  }
1434 }
#define LOG_INFO(x)
Definition: Define.h:90
constexpr ObjectID NULL_OBJECT
Definition: EntityCommon.h:14
#define LOG_ERROR(x)
Definition: Define.h:92
virtual DLLEXPORT void _CreateReceivedComponentForEntity(ObjectID id)
Called when this base class wants to create a Received component.
Definition: GameWorld.cpp:1207
#define LOG_WARNING(x)
Definition: Define.h:91
bool IsAuthoritative
This is true on the server.
virtual DLLEXPORT void _CreateComponentsFromCreationMessage(ObjectID id, sf::Packet &data, int entriesleft, int decodedtype)
Called to deserialize initial entity components and their static state.
Definition: GameWorld.cpp:691
DLLEXPORT void DestroyEntity(ObjectID id)
Destroys an entity and all of its components.
Definition: GameWorld.cpp:937
virtual DLLEXPORT void PrintToLog() const noexcept
Definition: Exceptions.cpp:35

◆ HandleEntityPacket() [3/4]

DLLEXPORT void GameWorld::HandleEntityPacket ( ResponseEntityDestruction &  message)

Definition at line 1436 of file GameWorld.cpp.

1437 {
1438  if(NetworkSettings.IsAuthoritative) {
1439 
1440  LOG_WARNING("GameWorld: authoritative world is ignoring ResponseEntityCreation");
1441  return;
1442  }
1443 
1444  for(auto entity : Entities) {
1445  if(entity == message.EntityID) {
1446 
1447  DestroyEntity(message.EntityID);
1448  return;
1449  }
1450  }
1451 
1452  // TODO: queue if we don't have an entity with the ID
1453  LOG_WARNING("GameWorld: HandleEntityPacket: received destruction message for unknown "
1454  "entity, TODO: queue");
1455 }
#define LOG_WARNING(x)
Definition: Define.h:91
bool IsAuthoritative
This is true on the server.
DLLEXPORT void DestroyEntity(ObjectID id)
Destroys an entity and all of its components.
Definition: GameWorld.cpp:937

◆ HandleEntityPacket() [4/4]

DLLEXPORT void GameWorld::HandleEntityPacket ( ResponseEntityLocalControlStatus &  message)

Definition at line 1457 of file GameWorld.cpp.

1458 {
1459  if(!message.Enabled) {
1460 
1461  for(auto iter = OurActiveLocalControl.begin(); iter != OurActiveLocalControl.end();
1462  ++iter) {
1463 
1464  if(*iter == message.EntityID) {
1465  OurActiveLocalControl.erase(iter);
1466  return;
1467  }
1468  }
1469 
1470  LOG_WARNING("GameWorld: received disable local control message for entity that wasn't "
1471  "controlled by us");
1472  } else {
1473 
1474  // Ignore duplicates
1475  for(auto controlled : OurActiveLocalControl)
1476  if(controlled == message.EntityID)
1477  return;
1478 
1479  OurActiveLocalControl.push_back(message.EntityID);
1480 
1481  if(NetworkSettings.AutoCreateNetworkComponents) {
1482  try {
1483  _CreateSendableComponentForEntity(message.EntityID);
1484  LOG_INFO("GameWorld: created Sendable for locally controlled entity: " +
1485  std::to_string(message.EntityID));
1486  } catch(const InvalidState&) {
1487  LOG_WARNING(
1488  "GameWorld: couldn't create Sendable for now locally controlled entity:" +
1489  std::to_string(message.EntityID));
1490  }
1491  }
1492  }
1493 }
#define LOG_INFO(x)
Definition: Define.h:90
virtual DLLEXPORT void _CreateSendableComponentForEntity(ObjectID id)
Called when this base class wants to create a Sendable component.
Definition: GameWorld.cpp:1201
#define LOG_WARNING(x)
Definition: Define.h:91

◆ Init()

DLLEXPORT bool GameWorld::Init ( const WorldNetworkSettings network,
Graphics graphics 
)

Creates resources for the world to work.

Postcondition
The world can be used after this

Definition at line 95 of file GameWorld.cpp.

96 {
97  NetworkSettings = network;
98 
99  // Detecting non-GUI mode //
100  if(graphics) {
101 
102  GraphicalMode = true;
103  // these are always required for worlds //
104  _CreateRenderingResources(graphics);
105  } else {
106 
107  GraphicalMode = false;
108  InBackground = false;
109  }
110 
111  // Acquire physics engine world only if we have been given physical materials indicating
112  // that physics is wanted
113  if(PhysicsMaterials) {
114 
115  _PhysicalWorld = std::make_shared<PhysicalWorld>(this, PhysicsMaterials.get());
116  }
117 
118  _DoSystemsInit();
119  return true;
120 }
virtual DLLEXPORT void _DoSystemsInit()
Called in Init when systems should run their initialization logic.
Definition: GameWorld.cpp:1160
bool GraphicalMode
If false a graphical Ogre window hasn't been created and purely graphical stuff should be skipped.
Definition: GameWorld.h:574

◆ IsConnectionInWorld()

DLLEXPORT bool GameWorld::IsConnectionInWorld ( Connection connection) const

Returns true if a player with the given connection is receiving updates for this world.

Definition at line 554 of file GameWorld.cpp.

555 {
556  for(auto& player : ReceivingPlayers) {
557 
558  if(player->GetConnection().get() == &connection) {
559 
560  return true;
561  }
562  }
563 
564  return false;
565 }

◆ IsUnderOurLocalControl()

DLLEXPORT bool Leviathan::GameWorld::IsUnderOurLocalControl ( ObjectID  id)
inline
Returns
True if entity is under our local control
Note
It doesn't make sense to call this on a server. So if this is needed to be called where a server might call this you should use "GetNetworkSettings().IsAuthoritative" instead

Definition at line 351 of file GameWorld.h.

352  {
353  for(const auto& entity : OurActiveLocalControl)
354  if(entity == id)
355  return true;
356  return false;
357  }

◆ MarkForClear()

DLLEXPORT void GameWorld::MarkForClear ( )

Marks all entities to be deleted.

Definition at line 1296 of file GameWorld.cpp.

1297 {
1298  ClearAllEntities = true;
1299 }

◆ OnLinkToWindow()

DLLEXPORT void GameWorld::OnLinkToWindow ( Window window,
Graphics graphics 
)
virtual

Called when this is added to a Window.

Note
This creates a compositor workspace that renders this world's scene to the window

Definition at line 1824 of file GameWorld.cpp.

1825 {
1826  // LEVIATHAN_ASSERT(WorldsScene, "World is not initialized");
1827 
1828  if(!window)
1829  throw InvalidArgument("GameWorld attempted to be linked to a nullptr window");
1830 
1831  if(LinkedToWindow // || WorldWorkspace
1832  ) {
1833  throw InvalidArgument(
1834  "GameWorld attempted to be linked to a window while it is already linked");
1835  }
1836 
1837  LinkedToWindow = window;
1838 
1839  // // Create the workspace for this scene //
1840  // // Which will be rendered before the overlay workspace but after potential
1841  // // clearing workspace
1842  // WorldWorkspace = ogre->getCompositorManager2()->addWorkspace(WorldsScene,
1843  // LinkedToWindow->GetOgreWindow(), WorldSceneCamera, "WorldsWorkspace", true, 0);
1844  pimpl->WorldCamera->getViewport()->setTarget(window->GetBSFWindow());
1845 
1846  // TODO: this needs to be reapplied every time the window is resized
1847  pimpl->WorldCamera->setCustomProjectionMatrix(true,
1848  Matrix4::ProjectionPerspective(FOV, LinkedToWindow->GetAspectRatio(), 0.1f, 5000.f));
1849 
1850  if(!TickWhileInBackground) {
1851  _DoResumeSystems();
1852  }
1853 
1854  InBackground = false;
1855 }
DLLEXPORT const auto & GetBSFWindow() const
Definition: Window.h:166
static DLLEXPORT Matrix4 ProjectionPerspective(const Degree &horzFOV, float aspect, float near, float far, bool positiveZ=false)
Definition: Matrix.cpp:1139
DLLEXPORT float GetAspectRatio() const
Definition: Window.h:77
virtual DLLEXPORT void _DoResumeSystems()
Opposite of _DoSuspendSystems.
Definition: GameWorld.cpp:1191

◆ OnUnLinkedFromWindow()

DLLEXPORT void GameWorld::OnUnLinkedFromWindow ( Window window,
Graphics graphics 
)
virtual

Used to detect that this world is in the background and should not tick.

Note
Removes the workspace created in OnLinkToWindow

Definition at line 1789 of file GameWorld.cpp.

1790 {
1791  if(!LinkedToWindow) {
1792  LOG_WARNING(
1793  "GameWorld: unlink from window called while this wasn't linked to a window");
1794  return;
1795  }
1796 
1797  if(window != LinkedToWindow) {
1798 
1799  throw InvalidArgument("GameWorld attempted to be unlinked from window that wasn't the "
1800  "one it was linked to");
1801  }
1802 
1803  pimpl->WorldCamera->getViewport()->setTarget(nullptr);
1804 
1805  if(pimpl->DebugDraw) {
1806  LOG_INFO("GameWorld: stopping debug draw because this was detached from a world");
1807  // Clear the contents
1808  pimpl->DebugDraw->OnBeginDraw();
1809  _PhysicalWorld->SetDebugDrawer(nullptr);
1810  pimpl->DebugDraw = nullptr;
1811  }
1812 
1813  // ogre->getCompositorManager2()->removeWorkspace(WorldWorkspace);
1814  // WorldWorkspace = nullptr;
1815  LinkedToWindow = nullptr;
1816 
1817  if(!TickWhileInBackground) {
1819  }
1820 
1821  InBackground = true;
1822 }
virtual DLLEXPORT void _DoSuspendSystems()
Called when this is put in the background and systems (the sound system) should suspend their active ...
Definition: GameWorld.cpp:1181
#define LOG_INFO(x)
Definition: Define.h:90
#define LOG_WARNING(x)
Definition: Define.h:91

◆ QueueDestroyEntity()

DLLEXPORT void GameWorld::QueueDestroyEntity ( ObjectID  id)

Deletes an entity during the next tick.

Definition at line 961 of file GameWorld.cpp.

962 {
963  // Fail if trying to delete NULL_OBJECT
964  if(id == NULL_OBJECT)
965  throw InvalidArgument("Cannot destroy NULL_OBJECT");
966 
967  // This is a sanity check, can be disabled (or made cheaper when the world no longer uses
968  // IDFactory) when crashing stops
969  bool exists = false;
970 
971  for(auto existingId : Entities) {
972  if(existingId == id) {
973  exists = true;
974  break;
975  }
976  }
977 
978  if(!exists) {
979  LOG_ERROR("GameWorld: QueueDestroyEntity: unknown entity id: " + std::to_string(id));
980  return;
981  }
982 
983  Lock lock(DeleteMutex);
984 
985  // Skip duplicates
986  for(auto alreadyQueued : DelayedDeleteIDS)
987  if(id == alreadyQueued)
988  return;
989 
990  DelayedDeleteIDS.push_back(id);
991 }
constexpr ObjectID NULL_OBJECT
Definition: EntityCommon.h:14
#define LOG_ERROR(x)
Definition: Define.h:92
std::unique_lock< std::mutex > Lock
Definition: ThreadSafe.h:18

◆ REFERENCE_HANDLE_UNCOUNTED_TYPE()

Leviathan::GameWorld::REFERENCE_HANDLE_UNCOUNTED_TYPE ( GameWorld  )

◆ RegisterScriptComponentType()

DLLEXPORT bool GameWorld::RegisterScriptComponentType ( const std::string &  name,
asIScriptFunction *  factory 
)

Registers a component type from scripts.

Definition at line 1693 of file GameWorld.cpp.

1695 {
1696  // Skip if already registered //
1697  if(pimpl->RegisteredScriptComponents.find(name) !=
1698  pimpl->RegisteredScriptComponents.end()) {
1699  factory->Release();
1700  return false;
1701  }
1702 
1703  // ScriptComponentHolder takes care of releasing the reference
1704  pimpl->RegisteredScriptComponents[name] =
1705  ScriptComponentHolder::MakeShared<ScriptComponentHolder>(name, factory, this);
1706 
1707  return true;
1708 }

◆ RegisterScriptSystem()

DLLEXPORT bool GameWorld::RegisterScriptSystem ( const std::string &  name,
asIScriptObject *  system 
)

Registers a new system defined in a script. Must implement the ScriptSystem interface.

Definition at line 1725 of file GameWorld.cpp.

1727 {
1728  if(!system) {
1729  LOG_ERROR("GameWorld: RegisterScriptSystem: passed null object as new system");
1730  return false;
1731  }
1732 
1733  // if called after release
1734  if(!pimpl) {
1735  system->Release();
1736  return false;
1737  }
1738 
1739  // Skip if already registered //
1740  if(pimpl->RegisteredScriptSystems.find(name) != pimpl->RegisteredScriptSystems.end()) {
1741  system->Release();
1742  return false;
1743  }
1744 
1745  // Create a wrapper for it //
1746  // The wrapper handles unreferencing the handle
1747  pimpl->RegisteredScriptSystems[name] = std::make_unique<ScriptSystemWrapper>(name, system);
1748 
1749  // Might as well call Init now as other systems are almost certainly initialized as well //
1750  pimpl->RegisteredScriptSystems[name]->Init(this);
1751  return true;
1752 }
#define LOG_ERROR(x)
Definition: Define.h:92

◆ Release()

DLLEXPORT void GameWorld::Release ( )

Release resources.

Definition at line 122 of file GameWorld.cpp.

123 {
124  // Skip duplicate release
125  if(!pimpl)
126  return;
127 
129 
130  // (*WorldDestroyed) = true;
131 
132  ReceivingPlayers.clear();
133 
134  // release objects //
135  // TODO: allow objects to know that they are about to get killed
136 
137  // As all objects are just pointers to components we can just dump the objects
138  // and once the component pools are released
139  ClearEntities();
140 
141  if(GraphicalMode) {
142  // TODO: notify our window that it no longer has anything rendering on it
143  LinkedToWindow = nullptr;
144 
145  _DestroyRenderingResources();
146  }
147 
148  // This should be relatively cheap if the newton threads don't deadlock while waiting
149  // for each other
150  _PhysicalWorld.reset();
151 
152  // Let go of our these resources
153  pimpl.reset();
154 }
virtual DLLEXPORT void _DoSystemsRelease()
Called in Release when systems should run their shutdown logic.
Definition: GameWorld.cpp:1165
DLLEXPORT void ClearEntities()
Clears all objects from the world.
Definition: GameWorld.cpp:892
bool GraphicalMode
If false a graphical Ogre window hasn't been created and purely graphical stuff should be skipped.
Definition: GameWorld.h:574

◆ RemoveSunlight()

DLLEXPORT void GameWorld::RemoveSunlight ( )

Definition at line 295 of file GameWorld.cpp.

296 {
297  if(pimpl->SunlightSO) {
298  pimpl->SunlightSO->destroy();
299  pimpl->SunlightSO = nullptr;
300  pimpl->Sunlight = nullptr;
301  SunCreated = false;
302  }
303 }
static bool SunCreated
Definition: GameWorld.cpp:269

◆ Render()

DLLEXPORT void GameWorld::Render ( float  elapsed)

Runs systems required for a rendering run. Also updates camera positions.

Todo:
Allow script systems to specify their type

Definition at line 390 of file GameWorld.cpp.

391 {
392  if(InBackground) {
393 
394  LOG_ERROR("GameWorld: Render: called while world is in the background (not attached"
395  "to a window)");
396  return;
397  }
398 
399  RunFrameRenderSystems(elapsed);
400 
401  // Read camera entity and update position //
402 
403  // Skip if no camera //
404  if(CameraEntity == 0)
405  return;
406 
407  try {
408  Camera& properties = GetComponent<Camera>(CameraEntity);
409 
410  Position& position = GetComponent<Position>(CameraEntity);
411 
412  auto& states = GetStatesFor<Position>();
413 
414  // set camera position //
415  // TODO: this interpolation here is likely unneeded as the client side world should set
416  // the Position data from the states. This would only work on a hybrid client server
417  // that is running on fixed ticks not related to rendering (but that feels laggy)
418  const auto interpolated =
419  StateInterpolator::Interpolate(states, CameraEntity, &position, elapsed);
420 
421  if(!std::get<0>(interpolated)) {
422 
423  // No interpolated pos //
424  pimpl->WorldCameraSO->SetPosition(position.Members._Position);
425  pimpl->WorldCameraSO->SetOrientation(position.Members._Orientation);
426 
427  } else {
428 
429  const auto& interpolatedPos = std::get<1>(interpolated);
430  pimpl->WorldCameraSO->SetPosition(interpolatedPos._Position);
431  pimpl->WorldCameraSO->SetOrientation(interpolatedPos._Orientation);
432  }
433 
434  if(properties.SoundPerceiver) {
435 
437  position.Members._Position, position.Members._Orientation);
438  }
439 
440  if(properties.Marked || AppliedCameraPropertiesPtr != &properties) {
441 
442  AppliedCameraPropertiesPtr = &properties;
443 
444  FOV = properties.FOV;
445 
446  pimpl->WorldCamera->setCustomProjectionMatrix(
448  LinkedToWindow ? LinkedToWindow->GetAspectRatio() : 1280 / 720.f,
449  0.1f, 5000.f));
450 
451  // pimpl->WorldCamera->setHorzFOV(bs::Degree(properties.FOV));
452 
453  properties.Marked = false;
454  }
455 
456  } catch(const Exception& e) {
457 
458  LOG_ERROR("GameWorld: Render: camera update failed. Was a component removed?, "
459  "exception:");
460  e.PrintToLog();
461  CameraEntity = 0;
462  }
463 
464  // Finalize world positions for scene nodes
465  if(pimpl && pimpl->WorldScene)
466  pimpl->WorldScene->PrepareForRendering();
467 }
#define LOG_ERROR(x)
Definition: Define.h:92
static std::tuple< bool, StateT > Interpolate(const StateHolder< StateT > &stateholder, ObjectID entity, ComponentT *entitycomponent, float elapsed)
Interpolates states for component.
virtual DLLEXPORT void RunFrameRenderSystems(float elapsed)
Called by Render which is called from a Window if this is linked to one.
Definition: GameWorld.cpp:845
Base class for all exceptions thrown by Leviathan.
Definition: Exceptions.h:10
static DLLEXPORT Matrix4 ProjectionPerspective(const Degree &horzFOV, float aspect, float near, float far, bool positiveZ=false)
Definition: Matrix.cpp:1139
Entity has position and direction it is looking at.
Definition: Components.h:36
SoundDevice * GetSoundDevice()
Definition: Engine.h:227
DLLEXPORT float GetAspectRatio() const
Definition: Window.h:77
DLLEXPORT void SetSoundListenerPosition(const Float3 &pos, const Float4 &orientation)
Loads the file and plays the sound.
Properties that a camera entity has (will also need a Position component)
Definition: Components.h:714
uint16_t FOV
Horizontal (ie. "normal") field of view.
Definition: Components.h:725
static DLLEXPORT Engine * Get()
Definition: Engine.cpp:86
virtual DLLEXPORT void PrintToLog() const noexcept
Definition: Exceptions.cpp:35

◆ RunFrameRenderSystems()

DLLEXPORT void GameWorld::RunFrameRenderSystems ( float  elapsed)
protectedvirtual

Called by Render which is called from a Window if this is linked to one.

Note
This is public to allow tests to test interpolation. It might be worth it to make a separate function that is similar to Render but can be called even in non-gui mode

Definition at line 845 of file GameWorld.cpp.

846 {
847  // Don't have any systems, but these updates may be important for interpolation //
848  // _ApplyEntityUpdatePackets();
849 
850  // TODO: if there are any impactful simulation done here it needs to be also inside a block
851  // where TickInProgress is set to true
852 }

◆ SendToAllPlayers()

DLLEXPORT void GameWorld::SendToAllPlayers ( const std::shared_ptr< NetworkResponse > &  response,
RECEIVE_GUARANTEE  guarantee 
) const

Sends a packet to all connected players.

Definition at line 667 of file GameWorld.cpp.

669 {
670  // Notify everybody that an entity has been destroyed //
671  for(auto iter = ReceivingPlayers.begin(); iter != ReceivingPlayers.end(); ++iter) {
672 
673  auto safe = (*iter)->GetConnection();
674 
675  if(!safe->IsValidForSend()) {
676  // Player has probably closed their connection //
677  continue;
678  }
679 
680  safe->SendPacketToConnection(response, guarantee);
681  }
682 }

◆ SetAutoExposure()

DLLEXPORT void GameWorld::SetAutoExposure ( float  mineyeadaptation = 0.003f,
float  maxeyeadaptation = 2.0f,
float  eyeadaptationspeeddown = 3.0f,
float  eyeadaptationspeedup = 3.0f,
float  histogramlog2max = 4.0f,
float  histogramlog2min = -8.0f,
float  histogrampcthigh = 0.985f,
float  histogrampctlow = 0.8f 
)

Sets the world camera eye adaptation settings.

Definition at line 368 of file GameWorld.cpp.

371 {
372  const auto& settings = pimpl->WorldCamera->getRenderSettings();
373 
374  settings->autoExposure.eyeAdaptationSpeedDown = eyeadaptationspeeddown;
375  settings->autoExposure.eyeAdaptationSpeedUp = eyeadaptationspeedup;
376  settings->autoExposure.maxEyeAdaptation = maxeyeadaptation;
377  settings->autoExposure.minEyeAdaptation = mineyeadaptation;
378 
379  settings->autoExposure.histogramLog2Max = histogramlog2max;
380  settings->autoExposure.histogramLog2Min = histogramlog2min;
381  settings->autoExposure.histogramPctHigh = histogrampcthigh;
382  settings->autoExposure.histogramPctLow = histogrampctlow;
383 
384  settings->enableAutoExposure = false;
385 
386  pimpl->WorldCamera->setRenderSettings(settings);
387 }

◆ SetCamera()

DLLEXPORT void GameWorld::SetCamera ( ObjectID  object)

Sets the entity that acts as a camera.

The entity needs at least Position and Camera components

Exceptions
InvalidArgumentif the object is missing required components

Definition at line 469 of file GameWorld.cpp.

470 {
471  CameraEntity = object;
472 
473  AppliedCameraPropertiesPtr = nullptr;
474 
475  if(CameraEntity == NULL_OBJECT)
476  return;
477 
478  // Check components //
479  try {
480  GetComponent<Camera>(object);
481  } catch(const NotFound&) {
482 
483  throw InvalidArgument("SetCamera object is missing a needed component (Camera)");
484  }
485 
486  try {
487  GetComponent<Position>(object);
488  } catch(const NotFound&) {
489 
490  throw InvalidArgument("SetCamera object is missing a needed component (Position)");
491  }
492 }
constexpr ObjectID NULL_OBJECT
Definition: EntityCommon.h:14

◆ SetEntitysParent()

DLLEXPORT void GameWorld::SetEntitysParent ( ObjectID  child,
ObjectID  parent 
)

Makes child entity be deleted when parent is deleted.

Note
Doesn't check that the entitiy ids exist

Definition at line 1091 of file GameWorld.cpp.

1092 {
1093  Parents.push_back(std::make_tuple(parent, child));
1094 }

◆ SetLightProperties()

DLLEXPORT void GameWorld::SetLightProperties ( const Float3 colour,
float  intensity = 0.0001f,
const Float3 direction = Float3(0.55f, -0.3f, 0.75f),
float  sourceradius = 0.5f,
bool  castsshadows = true 
)

Sets the sunlight properties.

Precondition
SetSunlight has been called

Definition at line 338 of file GameWorld.cpp.

340 {
341  if(!pimpl->SunlightSO) {
342 
343  LOG_ERROR("GameWorld: SetLightProperties: world doesn't have sun light set");
344  return;
345  }
346 
347  pimpl->Sunlight->setColor(bs::Color(colour.X, colour.Y, colour.Z));
348  pimpl->Sunlight->setIntensity(intensity);
349  pimpl->Sunlight->setSourceRadius(sourceradius);
350  pimpl->Sunlight->setCastsShadow(castsshadows);
351 
352  // pimpl->SunlightSO->setPosition(bs::Vector3(1, 20, 1));
353  // pimpl->SunlightSO->setPosition(bs::Vector3(20, 15, 20));
354  pimpl->SunlightSO->setPosition(-direction);
355 
356  pimpl->SunlightSO->lookAt(bs::Vector3(0, 0, 0));
357  // pimpl->SunlightSO->setWorldRotation(const Quaternion &rotation)
358 
359  // TODO: scene ambient colour
360 
361  // Set scene ambient colour //
362  // TODO: Ogre samples also use this so maybe this works with PBR HLMS system
363  // WorldsScene->setAmbientLight(Ogre::ColourValue(0.3f, 0.5f, 0.7f) * 0.1f * 0.75f,
364  // Ogre::ColourValue(0.6f, 0.45f, 0.3f) * 0.065f * 0.75f,
365  // -Sunlight->getDirection() + Ogre::Vector3::UNIT_Y * 0.2f);
366 }
#define LOG_ERROR(x)
Definition: Define.h:92

◆ SetLocalControl()

DLLEXPORT void GameWorld::SetLocalControl ( ObjectID  id,
bool  enabled,
const std::shared_ptr< Connection > &  allowedconnection 
)

Sets local control on a client over an entity or disables it.

Note
Only one player can have local control over a single entity at once

Definition at line 1495 of file GameWorld.cpp.

1497 {
1498  // Apply the change
1499  if(enabled) {
1500 
1501  // TODO: detect changing owner
1502  ActiveLocalControl[id] = allowedconnection.get();
1503  } else {
1504 
1505  auto found = ActiveLocalControl.find(id);
1506 
1507  if(found != ActiveLocalControl.end()) {
1508  ActiveLocalControl.erase(found);
1509  } else {
1510  LOG_ERROR("GameWorld: SetLocalControl: disable called on entity that wasn't being "
1511  "controlled");
1512  }
1513  }
1514 
1515  // Notify
1516  auto response = std::make_shared<ResponseEntityLocalControlStatus>(0, ID, id, enabled);
1517 
1518  allowedconnection->SendPacketToConnection(response, RECEIVE_GUARANTEE::Critical);
1519 }
DLLEXPORT std::shared_ptr< SentRequest > SendPacketToConnection(const std::shared_ptr< NetworkRequest > &request, RECEIVE_GUARANTEE guarantee)
Definition: Connection.cpp:139
#define LOG_ERROR(x)
Definition: Define.h:92

◆ SetPaused()

DLLEXPORT void Leviathan::GameWorld::SetPaused ( bool  paused)
inline

Pause or unpause all systems and physics.

Definition at line 299 of file GameWorld.h.

300  {
301  Paused = paused;
302  }

◆ SetPlayerReceiveWorld()

DLLEXPORT void GameWorld::SetPlayerReceiveWorld ( std::shared_ptr< ConnectedPlayer ply)

Verifies that player is receiving this world.

Definition at line 567 of file GameWorld.cpp.

568 {
569  // Skip if already added //
570  for(auto& player : ReceivingPlayers) {
571 
572  if(player == ply) {
573 
574  return;
575  }
576  }
577 
578  LOG_INFO("GameWorld: player(\"" + ply->GetNickname() + "\") is now receiving world");
579 
580  // Add them to the list of receiving players //
581  ReceivingPlayers.push_back(ply);
582 
583  if(!ply->GetConnection()->IsValidForSend()) {
584 
585  // The closing should be handled by somebody else
586  Logger::Get()->Error("GameWorld: requested to sync with a player who has closed their "
587  "connection");
588 
589  return;
590  }
591 
592  {
593  // Start world receive information
594  ply->GetConnection()->SendPacketToConnection(
595  std::make_shared<ResponseStartWorldReceive>(0, ID, WorldType),
597  }
598 
599  // Update the position data //
600  UpdatePlayersPositionData(*ply);
601 
602  // Start sending initial update //
603  Logger::Get()->Info(
604  "Starting to send " + Convert::ToString(Entities.size()) + " to player");
605 
606  // Now we can queue all objects for sending //
607  // TODO: make sure that all objects are sent
608  // TODO: redo this inside the world tick
609  // ThreadingManager::Get()->QueueTask(
610  // new RepeatCountedTask(std::bind<void>([](
611  // std::shared_ptr<Connection> connection,
612  // std::shared_ptr<ConnectedPlayer> processingobject, GameWorld* world,
613  // std::shared_ptr<bool> WorldInvalid)
614  // -> void
615  // {
616  // // Get the next object //
617  // RepeatCountedTask* task =
618  // dynamic_cast<RepeatCountedTask*>(TaskThread::GetThreadSpecificThreadObject()->
619  // QuickTaskAccess.get());
620 
621  // LEVIATHAN_ASSERT(task, "wrong type passed to our task");
622 
623  // size_t num = task->GetRepeatCount();
624 
625  // if(*WorldInvalid){
626 
627  // taskstopprocessingobjectsforinitialsynclabel:
628 
629  // // Stop processing //
630  // task->StopRepeating();
631  // return;
632  // }
633 
634  // // Stop if out of bounds //
635  // if(num >= world->Entities.size()){
636 
637  // goto taskstopprocessingobjectsforinitialsynclabel;
638  // }
639 
640  // // Get the object //
641  // auto tosend = world->Entities[num];
642 
643  // // Skip if shouldn't send //
644  // try{
645 
646  // auto& position = world->GetComponent<Position>(tosend);
647 
648  // if(!world->ShouldPlayerReceiveObject(position, *connection)){
649 
650  // return;
651  // }
652 
653  // } catch(const NotFound&){
654 
655  // // No position, should probably always send //
656  // }
657 
658 
659  // // Send it //
660  // world->SendObjectToConnection(guard, tosend, connection);
661 
662  // return;
663 
664  // }, ply->GetConnection(), ply, this, WorldDestroyed), Entities.size()));
665 }
#define LOG_INFO(x)
Definition: Define.h:90
DLLEXPORT void Info(const std::string &data) override
Definition: Logger.cpp:164
const std::shared_ptr< Connection > & GetConnection()
const std::string & GetNickname() override
Returns a friendly name, nickname used to represent this entity.
static std::string ToString(const T &val)
Definition: Convert.h:72
static DLLEXPORT Logger * Get()
Definition: Logger.cpp:106
DLLEXPORT void Error(const std::string &data) override
Definition: Logger.cpp:177

◆ SetRunInBackground()

DLLEXPORT void GameWorld::SetRunInBackground ( bool  tickinbackground)
virtual

Configures this world to run tick even when not attached to a window.

Definition at line 1857 of file GameWorld.cpp.

1858 {
1859  TickWhileInBackground = tickinbackground;
1860 }

◆ SetServerForLocalControl()

DLLEXPORT void Leviathan::GameWorld::SetServerForLocalControl ( const std::shared_ptr< Connection > &  connection)
inline

Sets a connection that will be used to send local control entity updates to the server.

Definition at line 361 of file GameWorld.h.

362  {
363  ClientToServerConnection = connection;
364  }

◆ SetSkybox()

DLLEXPORT void GameWorld::SetSkybox ( const std::string &  skyboxname,
float  brightness = 1.f 
)
Parameters
skyboxnameName of the skybox to set. Or empty to clear the skybox

Definition at line 305 of file GameWorld.cpp.

306 {
307  if(!pimpl->SkyboxSO) {
308  if(skyboxname.empty())
309  return;
310 
311  pimpl->SkyboxSO = bs::SceneObject::create("Skybox");
312  pimpl->Skybox = pimpl->SkyboxSO->addComponent<bs::CSkybox>();
313  // Oh no! this method does not exist
314  // pimpl->Skybox->setLayer
315  }
316 
317  if(!skyboxname.empty()) {
318 
319  auto texture = Engine::Get()->GetGraphics()->LoadTextureByName(skyboxname);
320 
321  if(!texture) {
322 
323  LOG_ERROR("GameWorld: SetSkybox: could not load skybox texture with the name: " +
324  skyboxname);
325  return;
326  }
327 
328  pimpl->Skybox->setTexture(texture);
329  pimpl->Skybox->setBrightness(brightness);
330 
331  } else {
332 
333  pimpl->Skybox->setTexture(nullptr);
334  pimpl->Skybox->setBrightness(0);
335  }
336 }
#define LOG_ERROR(x)
Definition: Define.h:92
DLLEXPORT bs::HTexture LoadTextureByName(const std::string &name)
Works the same as LoadShaderByName.
Definition: Graphics.cpp:595
Graphics * GetGraphics()
Definition: Engine.h:185
static DLLEXPORT Engine * Get()
Definition: Engine.cpp:86

◆ SetSunlight()

DLLEXPORT void GameWorld::SetSunlight ( )

Definition at line 271 of file GameWorld.cpp.

272 {
273  if(SunCreated) {
274  LOG_WRITE("TODO: multi scene support in BSF needed for separate world lights");
275  return;
276  }
277 
278  SunCreated = true;
279 
280  // Create/update things if they are nullptr //
281  if(!pimpl->SunlightSO) {
282 
283  pimpl->SunlightSO = bs::SceneObject::create("Sunlight");
284  pimpl->Sunlight = pimpl->SunlightSO->addComponent<bs::CLight>();
285  // Oh no! this method does not exist
286  // pimpl->Sunlight->setLayer
287  }
288 
289  // Default properties
290  pimpl->Sunlight->setType(bs::LightType::Directional);
291 
292  SetLightProperties(Float3(1, 1, 1));
293 }
static bool SunCreated
Definition: GameWorld.cpp:269
DLLEXPORT void SetLightProperties(const Float3 &colour, float intensity=0.0001f, const Float3 &direction=Float3(0.55f, -0.3f, 0.75f), float sourceradius=0.5f, bool castsshadows=true)
Sets the sunlight properties.
Definition: GameWorld.cpp:338
#define LOG_WRITE(x)
Definition: Define.h:93

◆ SetWorldPhysicsFrozenState()

DLLEXPORT void GameWorld::SetWorldPhysicsFrozenState ( bool  frozen)
Todo:
Synchronize this over the network

Definition at line 1235 of file GameWorld.cpp.

1236 {
1237  // Skip if set to the same //
1238  if(frozen == WorldFrozen)
1239  return;
1240 
1241  WorldFrozen = frozen;
1242 
1243  // Send it to receiving players (if we are a server) //
1244  if(ReceivingPlayers.empty())
1245  return;
1246 
1247  // Should be safe to create the packet now and send it to all the connections //
1248  // TODO: remake this to work better
1249  SendToAllPlayers(std::make_shared<ResponseWorldFrozen>(0, ID, WorldFrozen, -1),
1251 }
DLLEXPORT void SendToAllPlayers(const std::shared_ptr< NetworkResponse > &response, RECEIVE_GUARANTEE guarantee) const
Sends a packet to all connected players.
Definition: GameWorld.cpp:667

◆ ShouldPlayerReceiveEntity()

DLLEXPORT bool GameWorld::ShouldPlayerReceiveEntity ( Position atposition,
Connection connection 
)

Returns true when the player matching the connection should receive updates about an entity.

Todo:
Implement this

Definition at line 548 of file GameWorld.cpp.

550 {
551  return true;
552 }

◆ Tick()

DLLEXPORT void GameWorld::Tick ( float  elapsed)

Used to keep track of passed ticks and trigger timed triggers.

Note
This will be called (or should be) every time the engine ticks

Definition at line 716 of file GameWorld.cpp.

717 {
718  if(InBackground && !TickWhileInBackground && GraphicalMode)
719  return;
720 
721  // Apply queued packets //
723 
724  _HandleDelayedDelete();
725 
726  // All required nodes for entities are created //
729 
730  // Remove closed player connections //
731 
732  for(auto iter = ReceivingPlayers.begin(); iter != ReceivingPlayers.end();) {
733 
734  if(!(*iter)->GetConnection()->IsValidForSend()) {
735 
736  LOG_INFO("GameWorld: a player has diconnected, removing. TODO: release Sendable "
737  "memory");
738  // DEBUG_BREAK;
739  iter = ReceivingPlayers.erase(iter);
740  } else {
741 
742  ++iter;
743  }
744  }
745 
746  // TODO: even while paused sendable objects may need to retransmit stuff
747 
748  if(Paused)
749  return;
750 
751  TotalElapsed += elapsed;
752 
753  // Set this to disallow deleting while running physics as well
754  TickInProgress = true;
755 
756  // Simulate physics //
757  if(!WorldFrozen) {
758 
759  // TODO: a game type that is a client and server at the same time
760  // if(IsOnServer) {
761 
762  // _ApplyEntityUpdatePackets();
763  if(_PhysicalWorld)
764  _PhysicalWorld->SimulateWorld(elapsed);
765 
766  // } else {
767 
768  // Simulate direct control //
769  // }
770  }
771 
772  _RunTickSystems(elapsed);
773 
774  TickInProgress = false;
775 
776  // Sendable objects may need something to be done //
777 
778  if(NetworkSettings.IsAuthoritative) {
779 
780  // Notify new entities //
781  // DEBUG_BREAK;
782 
783  // Skip if not tick that will be stored //
784  // if(TickNumber % WORLD_OBJECT_UPDATE_CLIENTS_INTERVAL == 0){
785 
786  // _SendableSystem.Run(ComponentSendable.GetIndex(), *this);
787  // }
788 
789  } else {
790 
791  // TODO: direct control objects
792  // _ReceivedSystem.Run(ComponentReceived.GetIndex(), *this);
793  }
794 }
#define LOG_INFO(x)
Definition: Define.h:90
virtual DLLEXPORT void HandleAddedAndDeleted()
Handles added entities and components.
Definition: GameWorld.cpp:796
DLLEXPORT void ApplyQueuedPackets()
Applies packets that were received out of order. And throws out any too old packets.
Definition: GameWorld.cpp:1535
bool IsAuthoritative
This is true on the server.
virtual DLLEXPORT void ClearAddedAndRemoved()
Clears the added components. Call after HandleAddedAndDeleted.
Definition: GameWorld.cpp:806
virtual DLLEXPORT void _RunTickSystems(float elapsed)
Called by Tick.
Definition: GameWorld.cpp:854
bool GraphicalMode
If false a graphical Ogre window hasn't been created and purely graphical stuff should be skipped.
Definition: GameWorld.h:574

◆ UnregisterScriptSystem()

DLLEXPORT bool GameWorld::UnregisterScriptSystem ( const std::string &  name)

Unregisters a script system that was registered with RegisterScriptSystem.

Returns
True if unregistered. False if no system with the name was registered
Note
This may not be called during a tick while script systems are running (because this modifies the container for them)

Definition at line 1754 of file GameWorld.cpp.

1755 {
1756  // if called after release
1757  if(!pimpl) {
1758  return false;
1759  }
1760 
1761  const auto iter = pimpl->RegisteredScriptSystems.find(name);
1762  if(iter == pimpl->RegisteredScriptSystems.end()) {
1763  return false;
1764  }
1765 
1766  iter->second->Release();
1767  pimpl->RegisteredScriptSystems.erase(iter);
1768 
1769  return true;
1770 }

Member Data Documentation

◆ GraphicalMode

bool Leviathan::GameWorld::GraphicalMode = false
protected

If false a graphical Ogre window hasn't been created and purely graphical stuff should be skipped.

Used on dedicated servers and other headless applications

Definition at line 574 of file GameWorld.h.


The documentation for this class was generated from the following files: