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 SetSkybox (const std::string &skyboxname, float brightness=1.f)
 Sets the sunlight properties. 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 649 of file GameWorld.cpp.

651 {
652  LOG_ERROR("GameWorld: entity component state decoding for local control was not complete "
653  "before calling base GameWorld implementation");
654 }
#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 631 of file GameWorld.cpp.

633 {
634  if(entriesleft < 1)
635  return;
636 
637  LOG_ERROR("GameWorld: entity static state decoding was not complete before calling base "
638  "GameWorld implementation. Received entity won't be fully constructed");
639 }
#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 1166 of file GameWorld.cpp.

1167 {
1168  LOG_ERROR("GameWorld: base version of _CreateReceivedComponentForEntity, this shouldn't "
1169  "happen with correct configuration");
1170 }
#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 1160 of file GameWorld.cpp.

1161 {
1162  LOG_ERROR("GameWorld: base version of _CreateSendableComponentForEntity, this shouldn't "
1163  "happen with correct configuration");
1164 }
#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 641 of file GameWorld.cpp.

643 {
644  LOG_ERROR(
645  "GameWorld: entity component state decoding was not complete before calling base "
646  "GameWorld implementation. Not all states have been decoded");
647 }
#define LOG_ERROR(x)
Definition: Define.h:90

◆ _DoResumeSystems()

DLLEXPORT void GameWorld::_DoResumeSystems ( )
protectedvirtual

Opposite of _DoSuspendSystems.

Definition at line 1150 of file GameWorld.cpp.

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

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

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->Suspend();
1147  }
1148 }

◆ _DoSystemsInit()

DLLEXPORT void GameWorld::_DoSystemsInit ( )
protectedvirtual

Called in Init when systems should run their initialization logic.

Definition at line 1119 of file GameWorld.cpp.

1120 {
1121  // Script systems are initialized as they are created
1122 }

◆ _DoSystemsRelease()

DLLEXPORT void GameWorld::_DoSystemsRelease ( )
protectedvirtual

Called in Release when systems should run their shutdown logic.

Definition at line 1124 of file GameWorld.cpp.

1125 {
1126  // This can be called after Releasing once already
1127  if(!pimpl)
1128  return;
1129 
1130  // We are responsible for script systems //
1131  for(auto iter = pimpl->RegisteredScriptSystems.begin();
1132  iter != pimpl->RegisteredScriptSystems.end(); ++iter) {
1133 
1134  iter->second->Release();
1135  }
1136 
1137  pimpl->RegisteredScriptSystems.clear();
1138 }

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

1480 {
1481  Position* position = GetComponentPtr<Position>(id);
1482  Physics* physics = GetComponentPtr<Physics>(id);
1483 
1484  if(position && physics) {
1485 
1486  if(position->Marked) {
1487 
1488  physics->JumpTo(*position);
1489  }
1490  }
1491 }
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 766 of file GameWorld.cpp.

767 {
768  // Skip double Release
769  if(!pimpl)
770  return;
771 
772  // We are responsible for script components //
773  for(auto iter = pimpl->RegisteredScriptComponents.begin();
774  iter != pimpl->RegisteredScriptComponents.end(); ++iter) {
775 
776  iter->second->ReleaseAllComponents();
777  }
778 }

◆ _ResetSystems()

DLLEXPORT void GameWorld::_ResetSystems ( )
protectedvirtual

Resets stored nodes in systems. Used together with _ResetComponents.

Definition at line 752 of file GameWorld.cpp.

753 {
754  // Skip double Release
755  if(!pimpl)
756  return;
757 
758  // We are responsible for script systems //
759  for(auto iter = pimpl->RegisteredScriptSystems.begin();
760  iter != pimpl->RegisteredScriptSystems.end(); ++iter) {
761 
762  iter->second->Clear();
763  }
764 }

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

790 {
791  // We are responsible for script systems //
792  for(auto iter = pimpl->RegisteredScriptSystems.begin();
793  iter != pimpl->RegisteredScriptSystems.end(); ++iter) {
794 
795  iter->second->Run();
796  }
797 }

◆ ApplyQueuedPackets()

DLLEXPORT void GameWorld::ApplyQueuedPackets ( )
protected

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

Definition at line 1493 of file GameWorld.cpp.

1494 {
1495  if(!pimpl->QueuedEntityUpdates.empty()) {
1496  }
1497 
1498  // Applies packets that were received out of order. And throws out any too old packets
1499 
1500  // if(!InitialEntityPackets.empty())
1501  // _ApplyInitialEntityPackets();
1502 
1503  // if(!EntityUpdatePackets.empty())
1504  // _ApplyEntityUpdatePackets();
1505 }

◆ CaptureEntityState()

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

Captures the current state of an entity.

Definition at line 624 of file GameWorld.cpp.

624 {}

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

627 {
628  return 0;
629 }

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

470 {
471  // Fail if there is no active camera //
472  if(CameraEntity == NULL_OBJECT)
473  throw InvalidState("This world has no active CameraEntity");
474 
475  if(!pimpl->WorldCamera)
476  throw InvalidState("This world has no initialized camera resources");
477 
478  // Read the latest set data from the camera
479  // TODO: could jump to the actual latest position here if wanted
480  return pimpl->WorldCamera->screenPointToRay(bs::Vector2I(x, y));
481 }
constexpr ObjectID NULL_OBJECT
Definition: EntityCommon.h:14

◆ ClearAddedAndRemoved()

DLLEXPORT void GameWorld::ClearAddedAndRemoved ( )
protectedvirtual

Clears the added components. Call after HandleAddedAndDeleted.

Definition at line 741 of file GameWorld.cpp.

742 {
743  // We are responsible for script components //
744  for(auto iter = pimpl->RegisteredScriptComponents.begin();
745  iter != pimpl->RegisteredScriptComponents.end(); ++iter) {
746 
747  iter->second->ClearAdded();
748  iter->second->ClearRemoved();
749  }
750 }

◆ ClearEntities()

DLLEXPORT void GameWorld::ClearEntities ( )

Clears all objects from the world.

Definition at line 851 of file GameWorld.cpp.

852 {
853  // Release objects //
854  Entities.clear();
855  Parents.clear();
856  // This shouldn't be used all that much so release the memory
857  Parents.shrink_to_fit();
858 
859  // Clear all nodes //
860  _ResetSystems();
861 
862  // Clears all components
863  // Runs Release on components that need it
865 
866  // Notify everybody that all entities are discarded //
867  for(auto iter = ReceivingPlayers.begin(); iter != ReceivingPlayers.end(); ++iter) {
868 
869  auto safe = (*iter)->GetConnection();
870 
871  if(!safe->IsValidForSend()) {
872  // Player has probably closed their connection //
873  continue;
874  }
875 
876  Logger::Get()->Write("TODO: send world clear message");
877  DEBUG_BREAK;
878  }
879 }
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:766
static DLLEXPORT Logger * Get()
Definition: Logger.cpp:106
virtual DLLEXPORT void _ResetSystems()
Resets stored nodes in systems. Used together with _ResetComponents.
Definition: GameWorld.cpp:752

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

825 {
826  if(!GetNetworkSettings().IsAuthoritative) {
827  // Clients create high number entities. This is not optimal but good enough for now
828  auto id = (1 << 31) | static_cast<ObjectID>(IDFactory::GetID());
829 
830  Entities.push_back(id);
831 
832  return id;
833 
834  } else {
835  auto id = static_cast<ObjectID>(IDFactory::GetID());
836 
837  Entities.push_back(id);
838 
839  if(NetworkSettings.IsAuthoritative) {
840  // NewlyCreatedEntities.push_back(id);
841 
842  if(NetworkSettings.AutoCreateNetworkComponents) {
844  }
845  }
846 
847  return id;
848  }
849 }
int32_t ObjectID
Definition: EntityCommon.h:11
virtual DLLEXPORT void _CreateSendableComponentForEntity(ObjectID id)
Called when this base class wants to create a Sendable component.
Definition: GameWorld.cpp:1160
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 1173 of file GameWorld.cpp.

1174 {
1175  // This can be called after Releasing once already
1176  if(!pimpl)
1177  return;
1178 
1179  // Handle script types
1180  for(auto iter = pimpl->RegisteredScriptComponents.begin();
1181  iter != pimpl->RegisteredScriptComponents.end(); ++iter) {
1182 
1183  // Just try to remove like the normal c++ components until there is a better way
1184  iter->second->ReleaseComponent(id);
1185  }
1186 }

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

897 {
898  // Fail if trying to delete NULL_OBJECT
899  if(id == NULL_OBJECT)
900  throw InvalidArgument("Cannot destroy NULL_OBJECT");
901 
902  // Fail if ticking currently //
903  if(TickInProgress)
904  throw InvalidState(
905  "Cannot DestroyEntity while ticking. Use QueueDestroyEntity instead");
906 
907  for(auto iter = Entities.begin(); iter != Entities.end(); ++iter) {
908 
909  if(*iter == id) {
910 
911  Entities.erase(iter);
912  _DoDestroy(id);
913  return;
914  }
915  }
916 
917  LOG_ERROR("GameWorld: DestroyEntity: unknown entity id: " + std::to_string(id));
918 }
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 1091 of file GameWorld.cpp.

1093 {
1094  return false;
1095 }

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

1099 {
1100  auto iter = pimpl->RegisteredScriptComponents.find(name);
1101 
1102  if(iter == pimpl->RegisteredScriptComponents.end())
1103  return false;
1104 
1105  auto& added = iter->second->GetAdded();
1106 
1107  result.reserve(result.size() + added.size());
1108 
1109  for(const auto& tuple : added) {
1110 
1111  result.push_back(
1112  std::make_tuple(std::get<0>(tuple), std::get<1>(tuple), iter->second.get()));
1113  }
1114 
1115  return true;
1116 }

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

484 {
485  return pimpl->WorldCameraSO;
486 }

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

1056 {
1057  return std::make_tuple(nullptr, false);
1058 }

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

1062 {
1063  return std::make_tuple(nullptr, ComponentTypeInfo(-1, -1), false);
1064 }

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

889 {
890  if(!PhysicsMaterials)
891  return -1;
892 
893  return PhysicsMaterials->GetMaterialID(name);
894 }

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

1073 {
1074  return false;
1075 }

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

1079 {
1080  auto iter = pimpl->RegisteredScriptComponents.find(name);
1081 
1082  if(iter == pimpl->RegisteredScriptComponents.end())
1083  return false;
1084 
1085  auto& removed = iter->second->GetRemoved();
1086 
1087  result.insert(std::end(result), std::begin(removed), std::end(removed));
1088  return true;
1089 }

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

1562 {
1563  if(!componenttypes)
1564  return nullptr;
1565 
1566  if(componenttypes->GetElementTypeId() !=
1568 
1569  LOG_ERROR("GameWorld: GetRemovedIDsForComponents: given an array of wrong type");
1570  componenttypes->Release();
1571  return nullptr;
1572  }
1573 
1574  std::vector<std::tuple<void*, ObjectID>> result;
1575 
1576  for(asUINT i = 0; i < componenttypes->GetSize(); ++i) {
1577 
1578  uint16_t* type = static_cast<uint16_t*>(componenttypes->At(i));
1579 
1580  if(!GetRemovedFor(static_cast<COMPONENT_TYPE>(*type), result)) {
1581 
1582  LOG_WARNING("GameWorld: GetRemovedIDsForComponents: unknown component type: " +
1583  std::to_string(*type));
1584  }
1585  }
1586 
1587  componenttypes->Release();
1588 
1589  asITypeInfo* typeInfo =
1590  ScriptExecutor::Get()->GetASEngine()->GetTypeInfoByDecl("array<ObjectID>");
1591 
1592  CScriptArray* array = CScriptArray::Create(typeInfo, static_cast<asUINT>(result.size()));
1593 
1594  if(!array)
1595  return nullptr;
1596 
1597  for(asUINT i = 0; i < static_cast<asUINT>(result.size()); ++i) {
1598 
1599  array->SetValue(i, &std::get<1>(result[i]));
1600  }
1601 
1602  return array;
1603 }
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:1071

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

1606 {
1607  if(!typenames)
1608  return nullptr;
1609 
1610  if(typenames->GetElementTypeId() !=
1612 
1613  LOG_ERROR("GameWorld: GetRemovedIDsForScriptComponents: given an array of wrong type "
1614  "(expected array<string>)");
1615  typenames->Release();
1616  return nullptr;
1617  }
1618 
1619  std::vector<std::tuple<asIScriptObject*, ObjectID>> result;
1620 
1621  for(asUINT i = 0; i < typenames->GetSize(); ++i) {
1622 
1623  std::string* type = static_cast<std::string*>(typenames->At(i));
1624 
1625  if(!GetRemovedForScriptDefined(*type, result)) {
1626 
1627  LOG_WARNING(
1628  "GameWorld: GetRemovedIDsForScriptComponents: unknown component type: " +
1629  *type);
1630  }
1631  }
1632 
1633  typenames->Release();
1634 
1635  asITypeInfo* typeInfo =
1636  ScriptExecutor::Get()->GetASEngine()->GetTypeInfoByDecl("array<ObjectID>");
1637 
1638  CScriptArray* array = CScriptArray::Create(typeInfo, static_cast<asUINT>(result.size()));
1639 
1640  if(!array)
1641  return nullptr;
1642 
1643  for(asUINT i = 0; i < static_cast<asUINT>(result.size()); ++i) {
1644 
1645  array->SetValue(i, &std::get<1>(result[i]));
1646  }
1647 
1648  return array;
1649 }
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:1077
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 1668 of file GameWorld.cpp.

1669 {
1670  // if called after release
1671  if(!pimpl)
1672  return nullptr;
1673 
1674  auto iter = pimpl->RegisteredScriptComponents.find(name);
1675 
1676  if(iter == pimpl->RegisteredScriptComponents.end())
1677  return nullptr;
1678 
1679  iter->second->AddRef();
1680  return iter->second.get();
1681 }

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

1731 {
1732  // if called after release
1733  if(!pimpl)
1734  return nullptr;
1735 
1736  auto iter = pimpl->RegisteredScriptSystems.find(name);
1737 
1738  if(iter == pimpl->RegisteredScriptSystems.end()) {
1739 
1740  LOG_ERROR("GameWorld: GetScriptSystemDirect: world has no system called: " + name);
1741  return nullptr;
1742  }
1743 
1744  return iter->second->GetASImplementationObject();
1745 }
#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 1066 of file GameWorld.cpp.

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

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

810 {
811  int tick = TickNumber;
812  int timeSince = static_cast<int>(Engine::Get()->GetTimeSinceLastTick());
813 
814  while(timeSince >= TICKSPEED) {
815 
816  ++tick;
817  timeSince -= TICKSPEED;
818  }
819 
820  return std::make_tuple(tick, timeSince);
821 }
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:1268
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 799 of file GameWorld.cpp.

800 {
801  float progress = Engine::Get()->GetTimeSinceLastTick() / (float)TICKSPEED;
802 
803  if(progress < 0.f)
804  return 0.f;
805 
806  return progress < 1.f ? progress : 1.f;
807 }
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:1268
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 731 of file GameWorld.cpp.

732 {
733  // We are responsible for script systems //
734  for(auto iter = pimpl->RegisteredScriptSystems.begin();
735  iter != pimpl->RegisteredScriptSystems.end(); ++iter) {
736 
737  iter->second->CreateAndDestroyNodes();
738  }
739 }

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

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

1354 {
1355  if(NetworkSettings.IsAuthoritative) {
1356 
1357  LOG_WARNING("GameWorld: authoritative world is ignoring ResponseEntityCreation");
1358  return NULL_OBJECT;
1359  }
1360 
1361  if(message.ComponentCount > 1000) {
1362  LOG_ERROR("GameWorld: HandleEntityPacket: entity has more than 1000 components. "
1363  "Packet is likely corrupted / forged, ignoring");
1364  return NULL_OBJECT;
1365  }
1366 
1367  // TODO: somehow detect if the ID collides with local entities (once those are allowed)
1368  Entities.push_back(message.EntityID);
1369 
1370  if(!NetworkSettings.IsAuthoritative) {
1371 
1372  if(NetworkSettings.AutoCreateNetworkComponents) {
1373  _CreateReceivedComponentForEntity(message.EntityID);
1374  }
1375  }
1376 
1377  try {
1379  message.EntityID, message.InitialComponentData, message.ComponentCount, -1);
1380 
1381  return message.EntityID;
1382  } catch(const InvalidArgument& e) {
1383  LOG_ERROR(
1384  "GameWorld: HandleEntityPacket: trying to load packet data caused an exception: ");
1385  e.PrintToLog();
1386  LOG_INFO("GameWorld: destroying invalid received entity: " +
1387  std::to_string(message.EntityID));
1388  DestroyEntity(message.EntityID);
1389 
1390  return NULL_OBJECT;
1391  }
1392 }
#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:1166
#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:631
DLLEXPORT void DestroyEntity(ObjectID id)
Destroys an entity and all of its components.
Definition: GameWorld.cpp:896
virtual DLLEXPORT void PrintToLog() const noexcept
Definition: Exceptions.cpp:35

◆ HandleEntityPacket() [3/4]

DLLEXPORT void GameWorld::HandleEntityPacket ( ResponseEntityDestruction &  message)

Definition at line 1394 of file GameWorld.cpp.

1395 {
1396  if(NetworkSettings.IsAuthoritative) {
1397 
1398  LOG_WARNING("GameWorld: authoritative world is ignoring ResponseEntityCreation");
1399  return;
1400  }
1401 
1402  for(auto entity : Entities) {
1403  if(entity == message.EntityID) {
1404 
1405  DestroyEntity(message.EntityID);
1406  return;
1407  }
1408  }
1409 
1410  // TODO: queue if we don't have an entity with the ID
1411  LOG_WARNING("GameWorld: HandleEntityPacket: received destruction message for unknown "
1412  "entity, TODO: queue");
1413 }
#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:896

◆ HandleEntityPacket() [4/4]

DLLEXPORT void GameWorld::HandleEntityPacket ( ResponseEntityLocalControlStatus &  message)

Definition at line 1415 of file GameWorld.cpp.

1416 {
1417  if(!message.Enabled) {
1418 
1419  for(auto iter = OurActiveLocalControl.begin(); iter != OurActiveLocalControl.end();
1420  ++iter) {
1421 
1422  if(*iter == message.EntityID) {
1423  OurActiveLocalControl.erase(iter);
1424  return;
1425  }
1426  }
1427 
1428  LOG_WARNING("GameWorld: received disable local control message for entity that wasn't "
1429  "controlled by us");
1430  } else {
1431 
1432  // Ignore duplicates
1433  for(auto controlled : OurActiveLocalControl)
1434  if(controlled == message.EntityID)
1435  return;
1436 
1437  OurActiveLocalControl.push_back(message.EntityID);
1438 
1439  if(NetworkSettings.AutoCreateNetworkComponents) {
1440  try {
1441  _CreateSendableComponentForEntity(message.EntityID);
1442  LOG_INFO("GameWorld: created Sendable for locally controlled entity: " +
1443  std::to_string(message.EntityID));
1444  } catch(const InvalidState&) {
1445  LOG_WARNING(
1446  "GameWorld: couldn't create Sendable for now locally controlled entity:" +
1447  std::to_string(message.EntityID));
1448  }
1449  }
1450  }
1451 }
#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:1160
#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:1119
bool GraphicalMode
If false a graphical Ogre window hasn&#39;t been created and purely graphical stuff should be skipped...
Definition: GameWorld.h:617

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

495 {
496  for(auto& player : ReceivingPlayers) {
497 
498  if(player->GetConnection().get() == &connection) {
499 
500  return true;
501  }
502  }
503 
504  return false;
505 }

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

1255 {
1256  ClearAllEntities = true;
1257 }

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

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

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

1748 {
1749  if(!LinkedToWindow) {
1750  LOG_WARNING(
1751  "GameWorld: unlink from window called while this wasn't linked to a window");
1752  return;
1753  }
1754 
1755  if(window != LinkedToWindow) {
1756 
1757  throw InvalidArgument("GameWorld attempted to be unlinked from window that wasn't the "
1758  "one it was linked to");
1759  }
1760 
1761  pimpl->WorldCamera->getViewport()->setTarget(nullptr);
1762 
1763  // ogre->getCompositorManager2()->removeWorkspace(WorldWorkspace);
1764  // WorldWorkspace = nullptr;
1765  LinkedToWindow = nullptr;
1766 
1767  if(!TickWhileInBackground) {
1769  }
1770 
1771  InBackground = true;
1772 }
virtual DLLEXPORT void _DoSuspendSystems()
Called when this is put in the background and systems (the sound system) should suspend their active ...
Definition: GameWorld.cpp:1140
#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 920 of file GameWorld.cpp.

921 {
922  // Fail if trying to delete NULL_OBJECT
923  if(id == NULL_OBJECT)
924  throw InvalidArgument("Cannot destroy NULL_OBJECT");
925 
926  // This is a sanity check, can be disabled (or made cheaper when the world no longer uses
927  // IDFactory) when crashing stops
928  bool exists = false;
929 
930  for(auto existingId : Entities) {
931  if(existingId == id) {
932  exists = true;
933  break;
934  }
935  }
936 
937  if(!exists) {
938  LOG_ERROR("GameWorld: QueueDestroyEntity: unknown entity id: " + std::to_string(id));
939  return;
940  }
941 
942  Lock lock(DeleteMutex);
943 
944  // Skip duplicates
945  for(auto alreadyQueued : DelayedDeleteIDS)
946  if(id == alreadyQueued)
947  return;
948 
949  DelayedDeleteIDS.push_back(id);
950 }
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 1651 of file GameWorld.cpp.

1653 {
1654  // Skip if already registered //
1655  if(pimpl->RegisteredScriptComponents.find(name) !=
1656  pimpl->RegisteredScriptComponents.end()) {
1657  factory->Release();
1658  return false;
1659  }
1660 
1661  // ScriptComponentHolder takes care of releasing the reference
1662  pimpl->RegisteredScriptComponents[name] =
1663  ScriptComponentHolder::MakeShared<ScriptComponentHolder>(name, factory, this);
1664 
1665  return true;
1666 }

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

1685 {
1686  if(!system) {
1687  LOG_ERROR("GameWorld: RegisterScriptSystem: passed null object as new system");
1688  return false;
1689  }
1690 
1691  // if called after release
1692  if(!pimpl) {
1693  system->Release();
1694  return false;
1695  }
1696 
1697  // Skip if already registered //
1698  if(pimpl->RegisteredScriptSystems.find(name) != pimpl->RegisteredScriptSystems.end()) {
1699  system->Release();
1700  return false;
1701  }
1702 
1703  // Create a wrapper for it //
1704  // The wrapper handles unreferencing the handle
1705  pimpl->RegisteredScriptSystems[name] = std::make_unique<ScriptSystemWrapper>(name, system);
1706 
1707  // Might as well call Init now as other systems are almost certainly initialized as well //
1708  pimpl->RegisteredScriptSystems[name]->Init(this);
1709  return true;
1710 }
#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:1124
DLLEXPORT void ClearEntities()
Clears all objects from the world.
Definition: GameWorld.cpp:851
bool GraphicalMode
If false a graphical Ogre window hasn&#39;t been created and purely graphical stuff should be skipped...
Definition: GameWorld.h:617

◆ RemoveSunlight()

DLLEXPORT void GameWorld::RemoveSunlight ( )

Definition at line 312 of file GameWorld.cpp.

313 {
314  if(pimpl->SunlightSO) {
315  pimpl->SunlightSO->destroy();
316  pimpl->SunlightSO = nullptr;
317  pimpl->Sunlight = nullptr;
318  SunCreated = false;
319  }
320 }
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 378 of file GameWorld.cpp.

379 {
380  if(InBackground) {
381 
382  LOG_ERROR("GameWorld: Render: called while world is in the background (not attached"
383  "to a window)");
384  return;
385  }
386 
387  RunFrameRenderSystems(tick, timeintick);
388 
389  // Read camera entity and update position //
390 
391  // Skip if no camera //
392  if(CameraEntity == 0)
393  return;
394 
395  try {
396  Camera& properties = GetComponent<Camera>(CameraEntity);
397 
398  Position& position = GetComponent<Position>(CameraEntity);
399 
400  auto& states = GetStatesFor<Position>();
401 
402  // set camera position //
403  const auto interpolated =
404  StateInterpolator::Interpolate(states, CameraEntity, &position, tick, timeintick);
405 
406  if(!std::get<0>(interpolated)) {
407 
408  // No interpolated pos //
409  pimpl->WorldCameraSO->setPosition(position.Members._Position);
410  pimpl->WorldCameraSO->setRotation(position.Members._Orientation);
411 
412  } else {
413 
414  const auto& interpolatedPos = std::get<1>(interpolated);
415  pimpl->WorldCameraSO->setPosition(interpolatedPos._Position);
416  pimpl->WorldCameraSO->setRotation(interpolatedPos._Orientation);
417  }
418 
419  if(properties.SoundPerceiver) {
420 
422  position.Members._Position, position.Members._Orientation);
423  }
424 
425  if(properties.Marked || AppliedCameraPropertiesPtr != &properties) {
426 
427  AppliedCameraPropertiesPtr = &properties;
428 
429  pimpl->WorldCamera->setHorzFOV(bs::Degree(properties.FOV));
430 
431  properties.Marked = false;
432  }
433 
434  } catch(const Exception& e) {
435 
436  LOG_ERROR("GameWorld: Render: camera update failed. Was a component removed?, "
437  "exception:");
438  e.PrintToLog();
439  CameraEntity = 0;
440  return;
441  }
442 }
#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:780
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 780 of file GameWorld.cpp.

781 {
782  // Don't have any systems, but these updates may be important for interpolation //
783  // _ApplyEntityUpdatePackets();
784 
785  // TODO: if there are any impactful simulation done here it needs to be also inside a block
786  // where TickInProgress is set to true
787 }

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

609 {
610  // Notify everybody that an entity has been destroyed //
611  for(auto iter = ReceivingPlayers.begin(); iter != ReceivingPlayers.end(); ++iter) {
612 
613  auto safe = (*iter)->GetConnection();
614 
615  if(!safe->IsValidForSend()) {
616  // Player has probably closed their connection //
617  continue;
618  }
619 
620  safe->SendPacketToConnection(response, guarantee);
621  }
622 }

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

445 {
446  CameraEntity = object;
447 
448  AppliedCameraPropertiesPtr = nullptr;
449 
450  if(CameraEntity == NULL_OBJECT)
451  return;
452 
453  // Check components //
454  try {
455  GetComponent<Camera>(object);
456  } catch(const NotFound&) {
457 
458  throw InvalidArgument("SetCamera object is missing a needed component (Camera)");
459  }
460 
461  try {
462  GetComponent<Position>(object);
463  } catch(const NotFound&) {
464 
465  throw InvalidArgument("SetCamera object is missing a needed component (Position)");
466  }
467 }
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 1050 of file GameWorld.cpp.

1051 {
1052  Parents.push_back(std::make_tuple(parent, child));
1053 }

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

1455 {
1456  // Apply the change
1457  if(enabled) {
1458 
1459  // TODO: detect changing owner
1460  ActiveLocalControl[id] = allowedconnection.get();
1461  } else {
1462 
1463  auto found = ActiveLocalControl.find(id);
1464 
1465  if(found != ActiveLocalControl.end()) {
1466  ActiveLocalControl.erase(found);
1467  } else {
1468  LOG_ERROR("GameWorld: SetLocalControl: disable called on entity that wasn't being "
1469  "controlled");
1470  }
1471  }
1472 
1473  // Notify
1474  auto response = std::make_shared<ResponseEntityLocalControlStatus>(0, ID, id, enabled);
1475 
1476  allowedconnection->SendPacketToConnection(response, RECEIVE_GUARANTEE::Critical);
1477 }
#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 507 of file GameWorld.cpp.

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

1811 {
1812  TickWhileInBackground = tickinbackground;
1813 }

◆ 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 
)

Sets the sunlight properties.

Precondition
SetSunlight has been called
Parameters
skyboxnameName of the skybox to set. Or empty to clear the skybox

Definition at line 322 of file GameWorld.cpp.

323 {
324  if(!pimpl->SkyboxSO) {
325  if(skyboxname.empty())
326  return;
327 
328  pimpl->SkyboxSO = bs::SceneObject::create("Skybox");
329  pimpl->Skybox = pimpl->SkyboxSO->addComponent<bs::CSkybox>();
330  // Oh no! this method does not exist
331  // pimpl->Skybox->setLayer
332  }
333 
334  if(!skyboxname.empty()) {
335 
336  auto texture = Engine::Get()->GetGraphics()->LoadTextureByName(skyboxname);
337 
338  if(!texture) {
339 
340  LOG_ERROR("GameWorld: SetSkybox: could not load skybox texture with the name: " +
341  skyboxname);
342  return;
343  }
344 
345  pimpl->Skybox->setTexture(texture);
346  pimpl->Skybox->setBrightness(brightness);
347 
348  } else {
349 
350  pimpl->Skybox->setTexture(nullptr);
351  pimpl->Skybox->setBrightness(0);
352  }
353 }
#define LOG_ERROR(x)
Definition: Define.h:90
DLLEXPORT bs::HTexture LoadTextureByName(const std::string &name)
Works the same as LoadShaderByName.
Definition: Graphics.cpp:696
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  pimpl->Sunlight->setColor(bs::Color(1, 1, 1));
292  pimpl->Sunlight->setIntensity(0.0001f);
293  pimpl->Sunlight->setSourceRadius(0.5f);
294  pimpl->Sunlight->setCastsShadow(true);
295 
296  // pimpl->SunlightSO->setPosition(bs::Vector3(1, 20, 1));
297  // pimpl->SunlightSO->setPosition(bs::Vector3(20, 15, 20));
298  pimpl->SunlightSO->setPosition(bs::Vector3(-0.55f, 0.3f, -0.75f));
299 
300  pimpl->SunlightSO->lookAt(bs::Vector3(0, 0, 0));
301  // pimpl->SunlightSO->setWorldRotation(const Quaternion &rotation)
302 
303  // TODO: scene ambient colour
304 
305  // Set scene ambient colour //
306  // TODO: Ogre samples also use this so maybe this works with PBR HLMS system
307  // WorldsScene->setAmbientLight(Ogre::ColourValue(0.3f, 0.5f, 0.7f) * 0.1f * 0.75f,
308  // Ogre::ColourValue(0.6f, 0.45f, 0.3f) * 0.065f * 0.75f,
309  // -Sunlight->getDirection() + Ogre::Vector3::UNIT_Y * 0.2f);
310 }
static bool SunCreated
Definition: GameWorld.cpp:269
#define LOG_WRITE(x)
Definition: Define.h:91

◆ SetWorldPhysicsFrozenState()

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

Definition at line 1194 of file GameWorld.cpp.

1195 {
1196  // Skip if set to the same //
1197  if(frozen == WorldFrozen)
1198  return;
1199 
1200  WorldFrozen = frozen;
1201 
1202  // Send it to receiving players (if we are a server) //
1203  if(ReceivingPlayers.empty())
1204  return;
1205 
1206  // Should be safe to create the packet now and send it to all the connections //
1207  SendToAllPlayers(std::make_shared<ResponseWorldFrozen>(0, ID, WorldFrozen, TickNumber),
1209 }
DLLEXPORT void SendToAllPlayers(const std::shared_ptr< NetworkResponse > &response, RECEIVE_GUARANTEE guarantee) const
Sends a packet to all connected players.
Definition: GameWorld.cpp:607

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

490 {
491  return true;
492 }

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

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

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

1713 {
1714  // if called after release
1715  if(!pimpl) {
1716  return false;
1717  }
1718 
1719  const auto iter = pimpl->RegisteredScriptSystems.find(name);
1720  if(iter == pimpl->RegisteredScriptSystems.end()) {
1721  return false;
1722  }
1723 
1724  iter->second->Release();
1725  pimpl->RegisteredScriptSystems.erase(iter);
1726 
1727  return true;
1728 }

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


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