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 (int currenttick)
 Used to keep track of passed ticks and trigger timed triggers. More...
 
DLLEXPORT void Render (int mspassed, int tick, int timeintick)
 Runs systems required for a rendering run. Also updates camera positions. More...
 
DLLEXPORT int GetTickNumber () const
 Returns the current tick. More...
 
DLLEXPORT float GetTickProgress () const
 Returns float between 0.f and 1.f based on how far current tick has progressed. More...
 
DLLEXPORT std::tuple< int, int > GetTickAndTime () const
 Returns a tuple of the current tick number and how long it has passed since last tick. 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 bs::Ray CastRayFromCamera (int x, int y) const
 Casts a ray from the active camera. More...
 
bs::SceneGetScene ()
 
DLLEXPORT bs::HSceneObject GetCameraSceneObject ()
 Returns the scene object the camera is attached to. More...
 
PhysicalWorldGetPhysicalWorld ()
 
DLLEXPORT int GetID () const
 
DLLEXPORT int32_t GetType () const
 
DLLEXPORT const auto & GetNetworkSettings () const
 
DLLEXPORT void SetWorldPhysicsFrozenState (bool frozen)
 
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 (int tick, int timeintick)
 Called by Render which is called from a Window if this is linked to one. More...
 
virtual DLLEXPORT void _RunTickSystems ()
 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 94 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 85 of file GameWorld.cpp.

86  :
87  pimpl(std::make_unique<Implementation>()),
88  PhysicsMaterials(physicsMaterials), ID(worldid >= 0 ? worldid : IDFactory::GetID()),
89  WorldType(worldtype)
90 {}
static int GetID()
Definition: IDFactory.h:17

◆ ~GameWorld()

DLLEXPORT GameWorld::~GameWorld ( )

Definition at line 92 of file GameWorld.cpp.

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

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 661 of file GameWorld.cpp.

663 {
664  LOG_ERROR("GameWorld: entity component state decoding for local control was not complete "
665  "before calling base GameWorld implementation");
666 }
#define LOG_ERROR(x)
Definition: Define.h:90

◆ _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 643 of file GameWorld.cpp.

645 {
646  if(entriesleft < 1)
647  return;
648 
649  LOG_ERROR("GameWorld: entity static state decoding was not complete before calling base "
650  "GameWorld implementation. Received entity won't be fully constructed");
651 }
#define LOG_ERROR(x)
Definition: Define.h:90

◆ _CreateReceivedComponentForEntity()

DLLEXPORT void GameWorld::_CreateReceivedComponentForEntity ( ObjectID  id)
protectedvirtual

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

Definition at line 1178 of file GameWorld.cpp.

1179 {
1180  LOG_ERROR("GameWorld: base version of _CreateReceivedComponentForEntity, this shouldn't "
1181  "happen with correct configuration");
1182 }
#define LOG_ERROR(x)
Definition: Define.h:90

◆ _CreateSendableComponentForEntity()

DLLEXPORT void GameWorld::_CreateSendableComponentForEntity ( ObjectID  id)
protectedvirtual

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

Definition at line 1172 of file GameWorld.cpp.

1173 {
1174  LOG_ERROR("GameWorld: base version of _CreateSendableComponentForEntity, this shouldn't "
1175  "happen with correct configuration");
1176 }
#define LOG_ERROR(x)
Definition: Define.h:90

◆ _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 653 of file GameWorld.cpp.

655 {
656  LOG_ERROR(
657  "GameWorld: entity component state decoding was not complete before calling base "
658  "GameWorld implementation. Not all states have been decoded");
659 }
#define LOG_ERROR(x)
Definition: Define.h:90

◆ _DoResumeSystems()

DLLEXPORT void GameWorld::_DoResumeSystems ( )
protectedvirtual

Opposite of _DoSuspendSystems.

Definition at line 1162 of file GameWorld.cpp.

1163 {
1164  // We are responsible for script systems //
1165  for(auto iter = pimpl->RegisteredScriptSystems.begin();
1166  iter != pimpl->RegisteredScriptSystems.end(); ++iter) {
1167 
1168  iter->second->Resume();
1169  }
1170 }

◆ _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 1152 of file GameWorld.cpp.

1153 {
1154  // We are responsible for script systems //
1155  for(auto iter = pimpl->RegisteredScriptSystems.begin();
1156  iter != pimpl->RegisteredScriptSystems.end(); ++iter) {
1157 
1158  iter->second->Suspend();
1159  }
1160 }

◆ _DoSystemsInit()

DLLEXPORT void GameWorld::_DoSystemsInit ( )
protectedvirtual

Called in Init when systems should run their initialization logic.

Definition at line 1131 of file GameWorld.cpp.

1132 {
1133  // Script systems are initialized as they are created
1134 }

◆ _DoSystemsRelease()

DLLEXPORT void GameWorld::_DoSystemsRelease ( )
protectedvirtual

Called in Release when systems should run their shutdown logic.

Definition at line 1136 of file GameWorld.cpp.

1137 {
1138  // This can be called after Releasing once already
1139  if(!pimpl)
1140  return;
1141 
1142  // We are responsible for script systems //
1143  for(auto iter = pimpl->RegisteredScriptSystems.begin();
1144  iter != pimpl->RegisteredScriptSystems.end(); ++iter) {
1145 
1146  iter->second->Release();
1147  }
1148 
1149  pimpl->RegisteredScriptSystems.clear();
1150 }

◆ _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 1491 of file GameWorld.cpp.

1492 {
1493  Position* position = GetComponentPtr<Position>(id);
1494  Physics* physics = GetComponentPtr<Physics>(id);
1495 
1496  if(position && physics) {
1497 
1498  if(position->Marked) {
1499 
1500  physics->JumpTo(*position);
1501  }
1502  }
1503 }
Entity has position and direction it is looking at.
Definition: Components.h:34
Entity has a physical component.
Definition: Components.h:346
DLLEXPORT void JumpTo(Position &target)
Syncs this physics body to a changed position.
Definition: Components.cpp:117

◆ _ResetOrReleaseComponents()

DLLEXPORT void GameWorld::_ResetOrReleaseComponents ( )
protectedvirtual

Resets components in holders. Used together with _ResetSystems.

Definition at line 778 of file GameWorld.cpp.

779 {
780  // Skip double Release
781  if(!pimpl)
782  return;
783 
784  // We are responsible for script components //
785  for(auto iter = pimpl->RegisteredScriptComponents.begin();
786  iter != pimpl->RegisteredScriptComponents.end(); ++iter) {
787 
788  iter->second->ReleaseAllComponents();
789  }
790 }

◆ _ResetSystems()

DLLEXPORT void GameWorld::_ResetSystems ( )
protectedvirtual

Resets stored nodes in systems. Used together with _ResetComponents.

Definition at line 764 of file GameWorld.cpp.

765 {
766  // Skip double Release
767  if(!pimpl)
768  return;
769 
770  // We are responsible for script systems //
771  for(auto iter = pimpl->RegisteredScriptSystems.begin();
772  iter != pimpl->RegisteredScriptSystems.end(); ++iter) {
773 
774  iter->second->Clear();
775  }
776 }

◆ _RunTickSystems()

DLLEXPORT void GameWorld::_RunTickSystems ( )
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 801 of file GameWorld.cpp.

802 {
803  // We are responsible for script systems //
804  for(auto iter = pimpl->RegisteredScriptSystems.begin();
805  iter != pimpl->RegisteredScriptSystems.end(); ++iter) {
806 
807  iter->second->Run();
808  }
809 }

◆ ApplyQueuedPackets()

DLLEXPORT void GameWorld::ApplyQueuedPackets ( )
protected

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

Definition at line 1505 of file GameWorld.cpp.

1506 {
1507  if(!pimpl->QueuedEntityUpdates.empty()) {
1508  }
1509 
1510  // Applies packets that were received out of order. And throws out any too old packets
1511 
1512  // if(!InitialEntityPackets.empty())
1513  // _ApplyInitialEntityPackets();
1514 
1515  // if(!EntityUpdatePackets.empty())
1516  // _ApplyEntityUpdatePackets();
1517 }

◆ CaptureEntityState()

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

Captures the current state of an entity.

Definition at line 636 of file GameWorld.cpp.

636 {}

◆ 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 638 of file GameWorld.cpp.

639 {
640  return 0;
641 }

◆ CastRayFromCamera()

DLLEXPORT bs::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 481 of file GameWorld.cpp.

482 {
483  // Fail if there is no active camera //
484  if(CameraEntity == NULL_OBJECT)
485  throw InvalidState("This world has no active CameraEntity");
486 
487  if(!pimpl->WorldCamera)
488  throw InvalidState("This world has no initialized camera resources");
489 
490  // Read the latest set data from the camera
491  // TODO: could jump to the actual latest position here if wanted
492  return pimpl->WorldCamera->screenPointToRay(bs::Vector2I(x, y));
493 }
constexpr ObjectID NULL_OBJECT
Definition: EntityCommon.h:14

◆ ClearAddedAndRemoved()

DLLEXPORT void GameWorld::ClearAddedAndRemoved ( )
protectedvirtual

Clears the added components. Call after HandleAddedAndDeleted.

Definition at line 753 of file GameWorld.cpp.

754 {
755  // We are responsible for script components //
756  for(auto iter = pimpl->RegisteredScriptComponents.begin();
757  iter != pimpl->RegisteredScriptComponents.end(); ++iter) {
758 
759  iter->second->ClearAdded();
760  iter->second->ClearRemoved();
761  }
762 }

◆ ClearEntities()

DLLEXPORT void GameWorld::ClearEntities ( )

Clears all objects from the world.

Definition at line 863 of file GameWorld.cpp.

864 {
865  // Release objects //
866  Entities.clear();
867  Parents.clear();
868  // This shouldn't be used all that much so release the memory
869  Parents.shrink_to_fit();
870 
871  // Clear all nodes //
872  _ResetSystems();
873 
874  // Clears all components
875  // Runs Release on components that need it
877 
878  // Notify everybody that all entities are discarded //
879  for(auto iter = ReceivingPlayers.begin(); iter != ReceivingPlayers.end(); ++iter) {
880 
881  auto safe = (*iter)->GetConnection();
882 
883  if(!safe->IsValidForSend()) {
884  // Player has probably closed their connection //
885  continue;
886  }
887 
888  Logger::Get()->Write("TODO: send world clear message");
889  DEBUG_BREAK;
890  }
891 }
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:778
static DLLEXPORT Logger * Get()
Definition: Logger.cpp:106
virtual DLLEXPORT void _ResetSystems()
Resets stored nodes in systems. Used together with _ResetComponents.
Definition: GameWorld.cpp:764

◆ 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 836 of file GameWorld.cpp.

837 {
838  if(!GetNetworkSettings().IsAuthoritative) {
839  // Clients create high number entities. This is not optimal but good enough for now
840  auto id = (1 << 31) | static_cast<ObjectID>(IDFactory::GetID());
841 
842  Entities.push_back(id);
843 
844  return id;
845 
846  } else {
847  auto id = static_cast<ObjectID>(IDFactory::GetID());
848 
849  Entities.push_back(id);
850 
851  if(NetworkSettings.IsAuthoritative) {
852  // NewlyCreatedEntities.push_back(id);
853 
854  if(NetworkSettings.AutoCreateNetworkComponents) {
856  }
857  }
858 
859  return id;
860  }
861 }
virtual DLLEXPORT void _CreateSendableComponentForEntity(ObjectID id)
Called when this base class wants to create a Sendable component.
Definition: GameWorld.cpp:1172
static int GetID()
Definition: IDFactory.h:17
bool IsAuthoritative
This is true on the server.
DLLEXPORT const auto & GetNetworkSettings() const
Definition: GameWorld.h:346

◆ DestroyAllIn()

DLLEXPORT void GameWorld::DestroyAllIn ( ObjectID  id)
virtual

Removes all components from an entity.

Definition at line 1185 of file GameWorld.cpp.

1186 {
1187  // This can be called after Releasing once already
1188  if(!pimpl)
1189  return;
1190 
1191  // Handle script types
1192  for(auto iter = pimpl->RegisteredScriptComponents.begin();
1193  iter != pimpl->RegisteredScriptComponents.end(); ++iter) {
1194 
1195  // Just try to remove like the normal c++ components until there is a better way
1196  iter->second->ReleaseComponent(id);
1197  }
1198 }

◆ 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 908 of file GameWorld.cpp.

909 {
910  // Fail if trying to delete NULL_OBJECT
911  if(id == NULL_OBJECT)
912  throw InvalidArgument("Cannot destroy NULL_OBJECT");
913 
914  // Fail if ticking currently //
915  if(TickInProgress)
916  throw InvalidState(
917  "Cannot DestroyEntity while ticking. Use QueueDestroyEntity instead");
918 
919  for(auto iter = Entities.begin(); iter != Entities.end(); ++iter) {
920 
921  if(*iter == id) {
922 
923  Entities.erase(iter);
924  _DoDestroy(id);
925  return;
926  }
927  }
928 
929  LOG_ERROR("GameWorld: DestroyEntity: unknown entity id: " + std::to_string(id));
930 }
constexpr ObjectID NULL_OBJECT
Definition: EntityCommon.h:14
#define LOG_ERROR(x)
Definition: Define.h:90

◆ DoesEntityExist()

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

Returns true if entity exists.

Definition at line 186 of file GameWorld.h.

187  {
188  for(const auto& entity : Entities) {
189  if(id == entity)
190  return true;
191  }
192 
193  return false;
194  }

◆ 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 1103 of file GameWorld.cpp.

1105 {
1106  return false;
1107 }

◆ 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 1109 of file GameWorld.cpp.

1111 {
1112  auto iter = pimpl->RegisteredScriptComponents.find(name);
1113 
1114  if(iter == pimpl->RegisteredScriptComponents.end())
1115  return false;
1116 
1117  auto& added = iter->second->GetAdded();
1118 
1119  result.reserve(result.size() + added.size());
1120 
1121  for(const auto& tuple : added) {
1122 
1123  result.push_back(
1124  std::make_tuple(std::get<0>(tuple), std::get<1>(tuple), iter->second.get()));
1125  }
1126 
1127  return true;
1128 }

◆ GetCameraSceneObject()

DLLEXPORT bs::HSceneObject 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 495 of file GameWorld.cpp.

496 {
497  return pimpl->WorldCameraSO;
498 }

◆ 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 205 of file GameWorld.h.

206  {
207  std::tuple<void*, bool> component = GetComponent(id, TComponent::TYPE);
208 
209  if(!std::get<1>(component))
210  throw InvalidArgument("Unrecognized component type as template parameter");
211 
212  void* ptr = std::get<0>(component);
213 
214  if(!ptr)
215  throw NotFound("Component for entity with id was not found");
216 
217  return *static_cast<TComponent*>(ptr);
218  }
TComponent & GetComponent(ObjectID id)
Definition: GameWorld.h:205

◆ 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 1067 of file GameWorld.cpp.

1068 {
1069  return std::make_tuple(nullptr, false);
1070 }

◆ 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 225 of file GameWorld.h.

226  {
227  std::tuple<void*, bool> component = GetComponent(id, TComponent::TYPE);
228 
229  void* ptr = std::get<0>(component);
230 
231  if(!ptr)
232  return nullptr;
233 
234  return static_cast<TComponent*>(ptr);
235  }
TComponent & GetComponent(ObjectID id)
Definition: GameWorld.h:205

◆ 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 1072 of file GameWorld.cpp.

1074 {
1075  return std::make_tuple(nullptr, ComponentTypeInfo(-1, -1), false);
1076 }

◆ 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 374 of file GameWorld.h.

375  {
376  return ReceivingPlayers;
377  }

◆ GetEntities()

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

Returns the created entity id vector.

Definition at line 126 of file GameWorld.h.

127  {
128  return Entities;
129  }

◆ 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 120 of file GameWorld.h.

121  {
122  return Entities.size();
123  }

◆ GetID()

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

Definition at line 335 of file GameWorld.h.

336  {
337  return ID;
338  }

◆ GetNetworkSettings()

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

Definition at line 346 of file GameWorld.h.

347  {
348  return NetworkSettings;
349  }

◆ GetOurLocalControl()

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

Definition at line 390 of file GameWorld.h.

391  {
392  return OurActiveLocalControl;
393  }

◆ 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 900 of file GameWorld.cpp.

901 {
902  if(!PhysicsMaterials)
903  return -1;
904 
905  return PhysicsMaterials->GetMaterialID(name);
906 }

◆ GetPhysicalWorld()

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

Definition at line 329 of file GameWorld.h.

330  {
331  return _PhysicalWorld.get();
332  }

◆ 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 1083 of file GameWorld.cpp.

1085 {
1086  return false;
1087 }

◆ 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 1089 of file GameWorld.cpp.

1091 {
1092  auto iter = pimpl->RegisteredScriptComponents.find(name);
1093 
1094  if(iter == pimpl->RegisteredScriptComponents.end())
1095  return false;
1096 
1097  auto& removed = iter->second->GetRemoved();
1098 
1099  result.insert(std::end(result), std::begin(removed), std::end(removed));
1100  return true;
1101 }

◆ 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 1573 of file GameWorld.cpp.

1574 {
1575  if(!componenttypes)
1576  return nullptr;
1577 
1578  if(componenttypes->GetElementTypeId() !=
1580 
1581  LOG_ERROR("GameWorld: GetRemovedIDsForComponents: given an array of wrong type");
1582  componenttypes->Release();
1583  return nullptr;
1584  }
1585 
1586  std::vector<std::tuple<void*, ObjectID>> result;
1587 
1588  for(asUINT i = 0; i < componenttypes->GetSize(); ++i) {
1589 
1590  uint16_t* type = static_cast<uint16_t*>(componenttypes->At(i));
1591 
1592  if(!GetRemovedFor(static_cast<COMPONENT_TYPE>(*type), result)) {
1593 
1594  LOG_WARNING("GameWorld: GetRemovedIDsForComponents: unknown component type: " +
1595  std::to_string(*type));
1596  }
1597  }
1598 
1599  componenttypes->Release();
1600 
1601  asITypeInfo* typeInfo =
1602  ScriptExecutor::Get()->GetASEngine()->GetTypeInfoByDecl("array<ObjectID>");
1603 
1604  CScriptArray* array = CScriptArray::Create(typeInfo, static_cast<asUINT>(result.size()));
1605 
1606  if(!array)
1607  return nullptr;
1608 
1609  for(asUINT i = 0; i < static_cast<asUINT>(result.size()); ++i) {
1610 
1611  array->SetValue(i, &std::get<1>(result[i]));
1612  }
1613 
1614  return array;
1615 }
DLLEXPORT asIScriptEngine * GetASEngine()
#define LOG_ERROR(x)
Definition: Define.h:90
static int Get(ScriptExecutor *resolver)
#define LOG_WARNING(x)
Definition: Define.h:89
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:1083

◆ 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 1617 of file GameWorld.cpp.

1618 {
1619  if(!typenames)
1620  return nullptr;
1621 
1622  if(typenames->GetElementTypeId() !=
1624 
1625  LOG_ERROR("GameWorld: GetRemovedIDsForScriptComponents: given an array of wrong type "
1626  "(expected array<string>)");
1627  typenames->Release();
1628  return nullptr;
1629  }
1630 
1631  std::vector<std::tuple<asIScriptObject*, ObjectID>> result;
1632 
1633  for(asUINT i = 0; i < typenames->GetSize(); ++i) {
1634 
1635  std::string* type = static_cast<std::string*>(typenames->At(i));
1636 
1637  if(!GetRemovedForScriptDefined(*type, result)) {
1638 
1639  LOG_WARNING(
1640  "GameWorld: GetRemovedIDsForScriptComponents: unknown component type: " +
1641  *type);
1642  }
1643  }
1644 
1645  typenames->Release();
1646 
1647  asITypeInfo* typeInfo =
1648  ScriptExecutor::Get()->GetASEngine()->GetTypeInfoByDecl("array<ObjectID>");
1649 
1650  CScriptArray* array = CScriptArray::Create(typeInfo, static_cast<asUINT>(result.size()));
1651 
1652  if(!array)
1653  return nullptr;
1654 
1655  for(asUINT i = 0; i < static_cast<asUINT>(result.size()); ++i) {
1656 
1657  array->SetValue(i, &std::get<1>(result[i]));
1658  }
1659 
1660  return array;
1661 }
DLLEXPORT asIScriptEngine * GetASEngine()
#define LOG_ERROR(x)
Definition: Define.h:90
static int Get(ScriptExecutor *resolver)
#define LOG_WARNING(x)
Definition: Define.h:89
DLLEXPORT bool GetRemovedForScriptDefined(const std::string &name, std::vector< std::tuple< asIScriptObject *, ObjectID >> &result)
Variant of GetRemovedFor for script defined types.
Definition: GameWorld.cpp:1089
static DLLEXPORT ScriptExecutor * Get()

◆ GetScene()

bs::Scene* Leviathan::GameWorld::GetScene ( )
inline

Definition at line 315 of file GameWorld.h.

316  {
317  return &BSFLayerHack;
318  // return WorldsScene;
319  }

◆ 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 1680 of file GameWorld.cpp.

1681 {
1682  // if called after release
1683  if(!pimpl)
1684  return nullptr;
1685 
1686  auto iter = pimpl->RegisteredScriptComponents.find(name);
1687 
1688  if(iter == pimpl->RegisteredScriptComponents.end())
1689  return nullptr;
1690 
1691  iter->second->AddRef();
1692  return iter->second.get();
1693 }

◆ 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 1742 of file GameWorld.cpp.

1743 {
1744  // if called after release
1745  if(!pimpl)
1746  return nullptr;
1747 
1748  auto iter = pimpl->RegisteredScriptSystems.find(name);
1749 
1750  if(iter == pimpl->RegisteredScriptSystems.end()) {
1751 
1752  LOG_ERROR("GameWorld: GetScriptSystemDirect: world has no system called: " + name);
1753  return nullptr;
1754  }
1755 
1756  return iter->second->GetASImplementationObject();
1757 }
#define LOG_ERROR(x)
Definition: Define.h:90

◆ GetServerForLocalControl()

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

Definition at line 414 of file GameWorld.h.

415  {
416  return ClientToServerConnection;
417  }

◆ 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 253 of file GameWorld.h.

254  {
255  std::tuple<void*, bool> stateHolder = GetStatesFor(TComponent::TYPE);
256 
257  if(!std::get<1>(stateHolder))
258  throw InvalidArgument("Unrecognized component type as template parameter for "
259  "state holder");
260 
261  void* ptr = std::get<0>(stateHolder);
262 
263  return *static_cast<StateHolder<typename TComponent::StateT>*>(ptr);
264  }
StateHolder< typename TComponent::StateT > & GetStatesFor()
Definition: GameWorld.h:253

◆ 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 1078 of file GameWorld.cpp.

1079 {
1080  return std::make_tuple(nullptr, false);
1081 }

◆ GetTickAndTime()

DLLEXPORT std::tuple< int, int > GameWorld::GetTickAndTime ( ) const

Returns a tuple of the current tick number and how long it has passed since last tick.

The tick number is always adjusted so that the time since last tick is < TICKSPEED

Definition at line 821 of file GameWorld.cpp.

822 {
823  int tick = TickNumber;
824  int timeSince = static_cast<int>(Engine::Get()->GetTimeSinceLastTick());
825 
826  while(timeSince >= TICKSPEED) {
827 
828  ++tick;
829  timeSince -= TICKSPEED;
830  }
831 
832  return std::make_tuple(tick, timeSince);
833 }
constexpr auto TICKSPEED
Number of milliseconds between engine and world ticks.
Definition: Define.h:22
static DLLEXPORT Engine * Get()
Definition: Engine.cpp:85

◆ GetTickNumber()

DLLEXPORT int Leviathan::GameWorld::GetTickNumber ( ) const
inline

Returns the current tick.

Definition at line 142 of file GameWorld.h.

143  {
144  return TickNumber;
145  }

◆ GetTickProgress()

DLLEXPORT float GameWorld::GetTickProgress ( ) const

Returns float between 0.f and 1.f based on how far current tick has progressed.

Definition at line 811 of file GameWorld.cpp.

812 {
813  float progress = Engine::Get()->GetTimeSinceLastTick() / (float)TICKSPEED;
814 
815  if(progress < 0.f)
816  return 0.f;
817 
818  return progress < 1.f ? progress : 1.f;
819 }
constexpr auto TICKSPEED
Number of milliseconds between engine and world ticks.
Definition: Define.h:22
DLLEXPORT int64_t GetTimeSinceLastTick() const
Calculates how long has elapsed since the last tick.
Definition: Engine.cpp:1266
static DLLEXPORT Engine * Get()
Definition: Engine.cpp:85

◆ GetType()

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

Definition at line 341 of file GameWorld.h.

342  {
343  return WorldType;
344  }

◆ 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 743 of file GameWorld.cpp.

744 {
745  // We are responsible for script systems //
746  for(auto iter = pimpl->RegisteredScriptSystems.begin();
747  iter != pimpl->RegisteredScriptSystems.end(); ++iter) {
748 
749  iter->second->CreateAndDestroyNodes();
750  }
751 }

◆ 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 1293 of file GameWorld.cpp.

1295 {
1296  if(NetworkSettings.IsAuthoritative) {
1297 
1298  // Find matching local control before allowing
1299  auto found = ActiveLocalControl.find(message.EntityID);
1300 
1301  if(found != ActiveLocalControl.end()) {
1302 
1303  if(found->second != &connection) {
1304 
1305  // It's unsafe to dereference found->second here
1306  LOG_WARNING("GameWorld: wrong player sent local control message, entity: " +
1307  std::to_string(message.EntityID));
1308  return;
1309  }
1310 
1311  _ApplyLocalControlUpdateMessage(message.EntityID, message.TickNumber,
1312  message.UpdateData, message.ReferenceTick, -1);
1313  _OnLocalControlUpdatedEntity(message.EntityID, message.TickNumber);
1314  return;
1315  }
1316 
1317  LOG_WARNING(
1318  "GameWorld: didn't find local control entity for ResponseEntityUpdate, entity: " +
1319  std::to_string(message.EntityID));
1320  return;
1321  }
1322 
1323  // Don't apply if we don't have the entity
1324  bool found = false;
1325 
1326  for(auto entity : Entities) {
1327  if(entity == message.EntityID) {
1328 
1329  found = true;
1330  break;
1331  }
1332  }
1333 
1334  if(!found) {
1335 
1336  LOG_WARNING(
1337  "GameWorld: HandleEntityPacket: received update for non-existing entity, id: " +
1338  std::to_string(message.EntityID) +
1339  " TODO: queue for later applying in case packets are out of order");
1340  return;
1341  }
1342 
1343  // If this is controlled by us this is handled differently
1344  for(auto entity : OurActiveLocalControl) {
1345 
1346  if(entity == message.EntityID) {
1347 
1348  // TODO: apply corrections if our simulation was incorrect / not allowed
1349  return;
1350  }
1351  }
1352 
1353  try {
1354  _CreateStatesFromUpdateMessage(message.EntityID, message.TickNumber,
1355  message.UpdateData, message.ReferenceTick, -1);
1356  } catch(const InvalidArgument& e) {
1357  LOG_ERROR("GameWorld: HandleEntityPacket: trying to load update packet data caused an "
1358  "exception: ");
1359  e.PrintToLog();
1360  LOG_INFO("GameWorld: note: entity may have partially updated states, id: " +
1361  std::to_string(message.EntityID));
1362  }
1363 }
#define LOG_INFO(x)
Definition: Define.h:88
#define LOG_ERROR(x)
Definition: Define.h:90
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:661
#define LOG_WARNING(x)
Definition: Define.h:89
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:653
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:1491
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 1365 of file GameWorld.cpp.

1366 {
1367  if(NetworkSettings.IsAuthoritative) {
1368 
1369  LOG_WARNING("GameWorld: authoritative world is ignoring ResponseEntityCreation");
1370  return NULL_OBJECT;
1371  }
1372 
1373  if(message.ComponentCount > 1000) {
1374  LOG_ERROR("GameWorld: HandleEntityPacket: entity has more than 1000 components. "
1375  "Packet is likely corrupted / forged, ignoring");
1376  return NULL_OBJECT;
1377  }
1378 
1379  // TODO: somehow detect if the ID collides with local entities (once those are allowed)
1380  Entities.push_back(message.EntityID);
1381 
1382  if(!NetworkSettings.IsAuthoritative) {
1383 
1384  if(NetworkSettings.AutoCreateNetworkComponents) {
1385  _CreateReceivedComponentForEntity(message.EntityID);
1386  }
1387  }
1388 
1389  try {
1391  message.EntityID, message.InitialComponentData, message.ComponentCount, -1);
1392 
1393  return message.EntityID;
1394  } catch(const InvalidArgument& e) {
1395  LOG_ERROR(
1396  "GameWorld: HandleEntityPacket: trying to load packet data caused an exception: ");
1397  e.PrintToLog();
1398  LOG_INFO("GameWorld: destroying invalid received entity: " +
1399  std::to_string(message.EntityID));
1400  DestroyEntity(message.EntityID);
1401 
1402  return NULL_OBJECT;
1403  }
1404 }
#define LOG_INFO(x)
Definition: Define.h:88
constexpr ObjectID NULL_OBJECT
Definition: EntityCommon.h:14
#define LOG_ERROR(x)
Definition: Define.h:90
virtual DLLEXPORT void _CreateReceivedComponentForEntity(ObjectID id)
Called when this base class wants to create a Received component.
Definition: GameWorld.cpp:1178
#define LOG_WARNING(x)
Definition: Define.h:89
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:643
DLLEXPORT void DestroyEntity(ObjectID id)
Destroys an entity and all of its components.
Definition: GameWorld.cpp:908
virtual DLLEXPORT void PrintToLog() const noexcept
Definition: Exceptions.cpp:35

◆ HandleEntityPacket() [3/4]

DLLEXPORT void GameWorld::HandleEntityPacket ( ResponseEntityDestruction &  message)

Definition at line 1406 of file GameWorld.cpp.

1407 {
1408  if(NetworkSettings.IsAuthoritative) {
1409 
1410  LOG_WARNING("GameWorld: authoritative world is ignoring ResponseEntityCreation");
1411  return;
1412  }
1413 
1414  for(auto entity : Entities) {
1415  if(entity == message.EntityID) {
1416 
1417  DestroyEntity(message.EntityID);
1418  return;
1419  }
1420  }
1421 
1422  // TODO: queue if we don't have an entity with the ID
1423  LOG_WARNING("GameWorld: HandleEntityPacket: received destruction message for unknown "
1424  "entity, TODO: queue");
1425 }
#define LOG_WARNING(x)
Definition: Define.h:89
bool IsAuthoritative
This is true on the server.
DLLEXPORT void DestroyEntity(ObjectID id)
Destroys an entity and all of its components.
Definition: GameWorld.cpp:908

◆ HandleEntityPacket() [4/4]

DLLEXPORT void GameWorld::HandleEntityPacket ( ResponseEntityLocalControlStatus &  message)

Definition at line 1427 of file GameWorld.cpp.

1428 {
1429  if(!message.Enabled) {
1430 
1431  for(auto iter = OurActiveLocalControl.begin(); iter != OurActiveLocalControl.end();
1432  ++iter) {
1433 
1434  if(*iter == message.EntityID) {
1435  OurActiveLocalControl.erase(iter);
1436  return;
1437  }
1438  }
1439 
1440  LOG_WARNING("GameWorld: received disable local control message for entity that wasn't "
1441  "controlled by us");
1442  } else {
1443 
1444  // Ignore duplicates
1445  for(auto controlled : OurActiveLocalControl)
1446  if(controlled == message.EntityID)
1447  return;
1448 
1449  OurActiveLocalControl.push_back(message.EntityID);
1450 
1451  if(NetworkSettings.AutoCreateNetworkComponents) {
1452  try {
1453  _CreateSendableComponentForEntity(message.EntityID);
1454  LOG_INFO("GameWorld: created Sendable for locally controlled entity: " +
1455  std::to_string(message.EntityID));
1456  } catch(const InvalidState&) {
1457  LOG_WARNING(
1458  "GameWorld: couldn't create Sendable for now locally controlled entity:" +
1459  std::to_string(message.EntityID));
1460  }
1461  }
1462  }
1463 }
#define LOG_INFO(x)
Definition: Define.h:88
virtual DLLEXPORT void _CreateSendableComponentForEntity(ObjectID id)
Called when this base class wants to create a Sendable component.
Definition: GameWorld.cpp:1172
#define LOG_WARNING(x)
Definition: Define.h:89

◆ 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 103 of file GameWorld.cpp.

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

◆ 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 506 of file GameWorld.cpp.

507 {
508  for(auto& player : ReceivingPlayers) {
509 
510  if(player->GetConnection().get() == &connection) {
511 
512  return true;
513  }
514  }
515 
516  return false;
517 }

◆ 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 399 of file GameWorld.h.

400  {
401  for(const auto& entity : OurActiveLocalControl)
402  if(entity == id)
403  return true;
404  return false;
405  }

◆ MarkForClear()

DLLEXPORT void GameWorld::MarkForClear ( )

Marks all entities to be deleted.

Definition at line 1266 of file GameWorld.cpp.

1267 {
1268  ClearAllEntities = true;
1269 }

◆ 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 1786 of file GameWorld.cpp.

1787 {
1788  // LEVIATHAN_ASSERT(WorldsScene, "World is not initialized");
1789 
1790  if(!window)
1791  throw InvalidArgument("GameWorld attempted to be linked to a nullptr window");
1792 
1793  if(LinkedToWindow // || WorldWorkspace
1794  ) {
1795 
1796  throw InvalidArgument(
1797  "GameWorld attempted to be linked to a window while it is already linked");
1798  }
1799 
1800  LinkedToWindow = window;
1801 
1802  // // Create the workspace for this scene //
1803  // // Which will be rendered before the overlay workspace but after potential
1804  // // clearing workspace
1805  // WorldWorkspace = ogre->getCompositorManager2()->addWorkspace(WorldsScene,
1806  // LinkedToWindow->GetOgreWindow(), WorldSceneCamera, "WorldsWorkspace", true, 0);
1807  pimpl->WorldCamera->getViewport()->setTarget(window->GetBSFWindow());
1808 
1809  // TODO: this needs to be reapplied every time the window is resized
1810  // TODO: ask for BSF auto aspect ratio (setAutoAspectRatio?)
1811  int32_t width, height;
1812  window->GetSize(width, height);
1813  pimpl->WorldCamera->setAspectRatio(width / static_cast<float>(height));
1814 
1815  if(!TickWhileInBackground) {
1816  _DoResumeSystems();
1817  }
1818 
1819  InBackground = false;
1820 }
DLLEXPORT void GetSize(int32_t &width, int32_t &height) const
Definition: Window.cpp:896
DLLEXPORT const auto & GetBSFWindow() const
Definition: Window.h:166
virtual DLLEXPORT void _DoResumeSystems()
Opposite of _DoSuspendSystems.
Definition: GameWorld.cpp:1162

◆ 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 1759 of file GameWorld.cpp.

1760 {
1761  if(!LinkedToWindow) {
1762  LOG_WARNING(
1763  "GameWorld: unlink from window called while this wasn't linked to a window");
1764  return;
1765  }
1766 
1767  if(window != LinkedToWindow) {
1768 
1769  throw InvalidArgument("GameWorld attempted to be unlinked from window that wasn't the "
1770  "one it was linked to");
1771  }
1772 
1773  pimpl->WorldCamera->getViewport()->setTarget(nullptr);
1774 
1775  // ogre->getCompositorManager2()->removeWorkspace(WorldWorkspace);
1776  // WorldWorkspace = nullptr;
1777  LinkedToWindow = nullptr;
1778 
1779  if(!TickWhileInBackground) {
1781  }
1782 
1783  InBackground = true;
1784 }
virtual DLLEXPORT void _DoSuspendSystems()
Called when this is put in the background and systems (the sound system) should suspend their active ...
Definition: GameWorld.cpp:1152
#define LOG_WARNING(x)
Definition: Define.h:89

◆ QueueDestroyEntity()

DLLEXPORT void GameWorld::QueueDestroyEntity ( ObjectID  id)

Deletes an entity during the next tick.

Definition at line 932 of file GameWorld.cpp.

933 {
934  // Fail if trying to delete NULL_OBJECT
935  if(id == NULL_OBJECT)
936  throw InvalidArgument("Cannot destroy NULL_OBJECT");
937 
938  // This is a sanity check, can be disabled (or made cheaper when the world no longer uses
939  // IDFactory) when crashing stops
940  bool exists = false;
941 
942  for(auto existingId : Entities) {
943  if(existingId == id) {
944  exists = true;
945  break;
946  }
947  }
948 
949  if(!exists) {
950  LOG_ERROR("GameWorld: QueueDestroyEntity: unknown entity id: " + std::to_string(id));
951  return;
952  }
953 
954  Lock lock(DeleteMutex);
955 
956  // Skip duplicates
957  for(auto alreadyQueued : DelayedDeleteIDS)
958  if(id == alreadyQueued)
959  return;
960 
961  DelayedDeleteIDS.push_back(id);
962 }
constexpr ObjectID NULL_OBJECT
Definition: EntityCommon.h:14
#define LOG_ERROR(x)
Definition: Define.h:90
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 1663 of file GameWorld.cpp.

1665 {
1666  // Skip if already registered //
1667  if(pimpl->RegisteredScriptComponents.find(name) !=
1668  pimpl->RegisteredScriptComponents.end()) {
1669  factory->Release();
1670  return false;
1671  }
1672 
1673  // ScriptComponentHolder takes care of releasing the reference
1674  pimpl->RegisteredScriptComponents[name] =
1675  ScriptComponentHolder::MakeShared<ScriptComponentHolder>(name, factory, this);
1676 
1677  return true;
1678 }

◆ 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 1695 of file GameWorld.cpp.

1697 {
1698  if(!system) {
1699  LOG_ERROR("GameWorld: RegisterScriptSystem: passed null object as new system");
1700  return false;
1701  }
1702 
1703  // if called after release
1704  if(!pimpl) {
1705  system->Release();
1706  return false;
1707  }
1708 
1709  // Skip if already registered //
1710  if(pimpl->RegisteredScriptSystems.find(name) != pimpl->RegisteredScriptSystems.end()) {
1711  system->Release();
1712  return false;
1713  }
1714 
1715  // Create a wrapper for it //
1716  // The wrapper handles unreferencing the handle
1717  pimpl->RegisteredScriptSystems[name] = std::make_unique<ScriptSystemWrapper>(name, system);
1718 
1719  // Might as well call Init now as other systems are almost certainly initialized as well //
1720  pimpl->RegisteredScriptSystems[name]->Init(this);
1721  return true;
1722 }
#define LOG_ERROR(x)
Definition: Define.h:90

◆ Release()

DLLEXPORT void GameWorld::Release ( )

Release resources.

Definition at line 130 of file GameWorld.cpp.

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

◆ 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 ( int  mspassed,
int  tick,
int  timeintick 
)

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(tick, timeintick);
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  const auto interpolated =
416  StateInterpolator::Interpolate(states, CameraEntity, &position, tick, timeintick);
417 
418  if(!std::get<0>(interpolated)) {
419 
420  // No interpolated pos //
421  pimpl->WorldCameraSO->setPosition(position.Members._Position);
422  pimpl->WorldCameraSO->setRotation(position.Members._Orientation);
423 
424  } else {
425 
426  const auto& interpolatedPos = std::get<1>(interpolated);
427  pimpl->WorldCameraSO->setPosition(interpolatedPos._Position);
428  pimpl->WorldCameraSO->setRotation(interpolatedPos._Orientation);
429  }
430 
431  if(properties.SoundPerceiver) {
432 
434  position.Members._Position, position.Members._Orientation);
435  }
436 
437  if(properties.Marked || AppliedCameraPropertiesPtr != &properties) {
438 
439  AppliedCameraPropertiesPtr = &properties;
440 
441  pimpl->WorldCamera->setHorzFOV(bs::Degree(properties.FOV));
442 
443  properties.Marked = false;
444  }
445 
446  } catch(const Exception& e) {
447 
448  LOG_ERROR("GameWorld: Render: camera update failed. Was a component removed?, "
449  "exception:");
450  e.PrintToLog();
451  CameraEntity = 0;
452  return;
453  }
454 }
#define LOG_ERROR(x)
Definition: Define.h:90
Base class for all exceptions thrown by Leviathan.
Definition: Exceptions.h:10
static std::tuple< bool, StateT > Interpolate(const StateHolder< StateT > &stateholder, ObjectID entity, ComponentT *entitycomponent, int currenttick, int timeintick)
Interpolates states for component.
Entity has position and direction it is looking at.
Definition: Components.h:34
SoundDevice * GetSoundDevice()
Definition: Engine.h:221
DLLEXPORT void SetSoundListenerPosition(const Float3 &pos, const Float4 &orientation)
Loads the file and plays the sound.
virtual DLLEXPORT void RunFrameRenderSystems(int tick, int timeintick)
Called by Render which is called from a Window if this is linked to one.
Definition: GameWorld.cpp:792
Properties that a camera entity has (will also need a Position component)
Definition: Components.h:713
uint16_t FOV
Horizontal (ie. "normal") field of view.
Definition: Components.h:724
static DLLEXPORT Engine * Get()
Definition: Engine.cpp:85
virtual DLLEXPORT void PrintToLog() const noexcept
Definition: Exceptions.cpp:35

◆ RunFrameRenderSystems()

DLLEXPORT void GameWorld::RunFrameRenderSystems ( int  tick,
int  timeintick 
)
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 792 of file GameWorld.cpp.

793 {
794  // Don't have any systems, but these updates may be important for interpolation //
795  // _ApplyEntityUpdatePackets();
796 
797  // TODO: if there are any impactful simulation done here it needs to be also inside a block
798  // where TickInProgress is set to true
799 }

◆ 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 619 of file GameWorld.cpp.

621 {
622  // Notify everybody that an entity has been destroyed //
623  for(auto iter = ReceivingPlayers.begin(); iter != ReceivingPlayers.end(); ++iter) {
624 
625  auto safe = (*iter)->GetConnection();
626 
627  if(!safe->IsValidForSend()) {
628  // Player has probably closed their connection //
629  continue;
630  }
631 
632  safe->SendPacketToConnection(response, guarantee);
633  }
634 }

◆ 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 456 of file GameWorld.cpp.

457 {
458  CameraEntity = object;
459 
460  AppliedCameraPropertiesPtr = nullptr;
461 
462  if(CameraEntity == NULL_OBJECT)
463  return;
464 
465  // Check components //
466  try {
467  GetComponent<Camera>(object);
468  } catch(const NotFound&) {
469 
470  throw InvalidArgument("SetCamera object is missing a needed component (Camera)");
471  }
472 
473  try {
474  GetComponent<Position>(object);
475  } catch(const NotFound&) {
476 
477  throw InvalidArgument("SetCamera object is missing a needed component (Position)");
478  }
479 }
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 1062 of file GameWorld.cpp.

1063 {
1064  Parents.push_back(std::make_tuple(parent, child));
1065 }

◆ 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:90

◆ 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 1465 of file GameWorld.cpp.

1467 {
1468  // Apply the change
1469  if(enabled) {
1470 
1471  // TODO: detect changing owner
1472  ActiveLocalControl[id] = allowedconnection.get();
1473  } else {
1474 
1475  auto found = ActiveLocalControl.find(id);
1476 
1477  if(found != ActiveLocalControl.end()) {
1478  ActiveLocalControl.erase(found);
1479  } else {
1480  LOG_ERROR("GameWorld: SetLocalControl: disable called on entity that wasn't being "
1481  "controlled");
1482  }
1483  }
1484 
1485  // Notify
1486  auto response = std::make_shared<ResponseEntityLocalControlStatus>(0, ID, id, enabled);
1487 
1488  allowedconnection->SendPacketToConnection(response, RECEIVE_GUARANTEE::Critical);
1489 }
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:90

◆ SetPlayerReceiveWorld()

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

Verifies that player is receiving this world.

Definition at line 519 of file GameWorld.cpp.

520 {
521  // Skip if already added //
522  for(auto& player : ReceivingPlayers) {
523 
524  if(player == ply) {
525 
526  return;
527  }
528  }
529 
530  LOG_INFO("GameWorld: player(\"" + ply->GetNickname() + "\") is now receiving world");
531 
532  // Add them to the list of receiving players //
533  ReceivingPlayers.push_back(ply);
534 
535  if(!ply->GetConnection()->IsValidForSend()) {
536 
537  // The closing should be handled by somebody else
538  Logger::Get()->Error("GameWorld: requested to sync with a player who has closed their "
539  "connection");
540 
541  return;
542  }
543 
544  {
545  // Start world receive information
546  ply->GetConnection()->SendPacketToConnection(
547  std::make_shared<ResponseStartWorldReceive>(0, ID, WorldType),
549  }
550 
551  // Update the position data //
552  UpdatePlayersPositionData(*ply);
553 
554  // Start sending initial update //
555  Logger::Get()->Info(
556  "Starting to send " + Convert::ToString(Entities.size()) + " to player");
557 
558  // Now we can queue all objects for sending //
559  // TODO: make sure that all objects are sent
560  // TODO: redo this inside the world tick
561  // ThreadingManager::Get()->QueueTask(
562  // new RepeatCountedTask(std::bind<void>([](
563  // std::shared_ptr<Connection> connection,
564  // std::shared_ptr<ConnectedPlayer> processingobject, GameWorld* world,
565  // std::shared_ptr<bool> WorldInvalid)
566  // -> void
567  // {
568  // // Get the next object //
569  // RepeatCountedTask* task =
570  // dynamic_cast<RepeatCountedTask*>(TaskThread::GetThreadSpecificThreadObject()->
571  // QuickTaskAccess.get());
572 
573  // LEVIATHAN_ASSERT(task, "wrong type passed to our task");
574 
575  // size_t num = task->GetRepeatCount();
576 
577  // if(*WorldInvalid){
578 
579  // taskstopprocessingobjectsforinitialsynclabel:
580 
581  // // Stop processing //
582  // task->StopRepeating();
583  // return;
584  // }
585 
586  // // Stop if out of bounds //
587  // if(num >= world->Entities.size()){
588 
589  // goto taskstopprocessingobjectsforinitialsynclabel;
590  // }
591 
592  // // Get the object //
593  // auto tosend = world->Entities[num];
594 
595  // // Skip if shouldn't send //
596  // try{
597 
598  // auto& position = world->GetComponent<Position>(tosend);
599 
600  // if(!world->ShouldPlayerReceiveObject(position, *connection)){
601 
602  // return;
603  // }
604 
605  // } catch(const NotFound&){
606 
607  // // No position, should probably always send //
608  // }
609 
610 
611  // // Send it //
612  // world->SendObjectToConnection(guard, tosend, connection);
613 
614  // return;
615 
616  // }, ply->GetConnection(), ply, this, WorldDestroyed), Entities.size()));
617 }
#define LOG_INFO(x)
Definition: Define.h:88
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 1822 of file GameWorld.cpp.

1823 {
1824  TickWhileInBackground = tickinbackground;
1825 }

◆ 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 409 of file GameWorld.h.

410  {
411  ClientToServerConnection = connection;
412  }

◆ 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:90
DLLEXPORT bs::HTexture LoadTextureByName(const std::string &name)
Works the same as LoadShaderByName.
Definition: Graphics.cpp:581
Graphics * GetGraphics()
Definition: Engine.h:179
static DLLEXPORT Engine * Get()
Definition: Engine.cpp:85

◆ 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:91

◆ SetWorldPhysicsFrozenState()

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

Definition at line 1206 of file GameWorld.cpp.

1207 {
1208  // Skip if set to the same //
1209  if(frozen == WorldFrozen)
1210  return;
1211 
1212  WorldFrozen = frozen;
1213 
1214  // Send it to receiving players (if we are a server) //
1215  if(ReceivingPlayers.empty())
1216  return;
1217 
1218  // Should be safe to create the packet now and send it to all the connections //
1219  SendToAllPlayers(std::make_shared<ResponseWorldFrozen>(0, ID, WorldFrozen, TickNumber),
1221 }
DLLEXPORT void SendToAllPlayers(const std::shared_ptr< NetworkResponse > &response, RECEIVE_GUARANTEE guarantee) const
Sends a packet to all connected players.
Definition: GameWorld.cpp:619

◆ 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 500 of file GameWorld.cpp.

502 {
503  return true;
504 }

◆ Tick()

DLLEXPORT void GameWorld::Tick ( int  currenttick)

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

Note
This will be called (or should be) every time the engine ticks
This cannot be used for accurate time keeping for that use timers, but for events that need to happen at certain game world times this is ideal

Definition at line 668 of file GameWorld.cpp.

669 {
670  if(InBackground && !TickWhileInBackground && GraphicalMode)
671  return;
672 
673  TickNumber = currenttick;
674 
675  // Apply queued packets //
677 
678  _HandleDelayedDelete();
679 
680  // All required nodes for entities are created //
683 
684  // Remove closed player connections //
685 
686  for(auto iter = ReceivingPlayers.begin(); iter != ReceivingPlayers.end();) {
687 
688  if(!(*iter)->GetConnection()->IsValidForSend()) {
689 
690  LOG_INFO("GameWorld: a player has diconnected, removing. TODO: release Sendable "
691  "memory");
692  // DEBUG_BREAK;
693  iter = ReceivingPlayers.erase(iter);
694  } else {
695 
696  ++iter;
697  }
698  }
699 
700  // Set this to disallow deleting while running physics as well
701  TickInProgress = true;
702 
703  // Simulate physics //
704  if(!WorldFrozen) {
705 
706  // TODO: a game type that is a client and server at the same time
707  // if(IsOnServer) {
708 
709  // _ApplyEntityUpdatePackets();
710  if(_PhysicalWorld)
711  _PhysicalWorld->SimulateWorld(TICKSPEED / 1000.f);
712 
713  // } else {
714 
715  // Simulate direct control //
716  // }
717  }
718 
719  _RunTickSystems();
720 
721  TickInProgress = false;
722 
723  // Sendable objects may need something to be done //
724 
725  if(NetworkSettings.IsAuthoritative) {
726 
727  // Notify new entities //
728  // DEBUG_BREAK;
729 
730  // Skip if not tick that will be stored //
731  // if(TickNumber % WORLD_OBJECT_UPDATE_CLIENTS_INTERVAL == 0){
732 
733  // _SendableSystem.Run(ComponentSendable.GetIndex(), *this);
734  // }
735 
736  } else {
737 
738  // TODO: direct control objects
739  // _ReceivedSystem.Run(ComponentReceived.GetIndex(), *this);
740  }
741 }
#define LOG_INFO(x)
Definition: Define.h:88
constexpr auto TICKSPEED
Number of milliseconds between engine and world ticks.
Definition: Define.h:22
virtual DLLEXPORT void HandleAddedAndDeleted()
Handles added entities and components.
Definition: GameWorld.cpp:743
DLLEXPORT void ApplyQueuedPackets()
Applies packets that were received out of order. And throws out any too old packets.
Definition: GameWorld.cpp:1505
bool IsAuthoritative
This is true on the server.
virtual DLLEXPORT void ClearAddedAndRemoved()
Clears the added components. Call after HandleAddedAndDeleted.
Definition: GameWorld.cpp:753
virtual DLLEXPORT void _RunTickSystems()
Called by Tick.
Definition: GameWorld.cpp:801
bool GraphicalMode
If false a graphical Ogre window hasn't been created and purely graphical stuff should be skipped.
Definition: GameWorld.h:623

◆ 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 1724 of file GameWorld.cpp.

1725 {
1726  // if called after release
1727  if(!pimpl) {
1728  return false;
1729  }
1730 
1731  const auto iter = pimpl->RegisteredScriptSystems.find(name);
1732  if(iter == pimpl->RegisteredScriptSystems.end()) {
1733  return false;
1734  }
1735 
1736  iter->second->Release();
1737  pimpl->RegisteredScriptSystems.erase(iter);
1738 
1739  return true;
1740 }

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 623 of file GameWorld.h.


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