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, Ogre::Root *ogre)
 Creates resources for the world to work. More...
 
DLLEXPORT void Release ()
 Release to not use Ogre when deleting. 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 Ogre::Ray CastRayFromCamera (float x, float y) const
 Casts a ray from the active camera. More...
 
Ogre::SceneManager * GetScene ()
 
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 SetFog ()
 
DLLEXPORT void SetSunlight ()
 
DLLEXPORT void RemoveSunlight ()
 
DLLEXPORT void SetLightProperties (const Ogre::ColourValue &diffuse, const Ogre::ColourValue &specular, const Ogre::Vector3 &direction, float power, const Ogre::ColourValue &upperhemisphere, const Ogre::ColourValue &lowerhemisphere, const Ogre::Vector3 &hemispheredir, float envmapscale=1.0f)
 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, Ogre::Root *ogre)
 Used to detect that this world is in the background and should not tick. More...
 
virtual DLLEXPORT void OnLinkToWindow (Window *window, Ogre::Root *ogre)
 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 99 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 73 of file GameWorld.cpp.

74  :
75  pimpl(std::make_unique<Implementation>()),
76  PhysicsMaterials(physicsMaterials), ID(worldid >= 0 ? worldid : IDFactory::GetID()),
77  WorldType(worldtype)
78 {}
static int GetID()
Definition: IDFactory.h:17

◆ ~GameWorld()

DLLEXPORT GameWorld::~GameWorld ( )

Definition at line 80 of file GameWorld.cpp.

81 {
82  (*WorldDestroyed) = true;
83 
84  // Assert if all objects haven't been released already.
85  // We can't call virtual methods here anymore
86  // This can be hit in tests quite easily if something throws an exception
87  LEVIATHAN_ASSERT(
88  Entities.empty(), "GameWorld: Entities not empty in destructor. Was Release called?");
89 }

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

547 {
548  LOG_ERROR("GameWorld: entity component state decoding for local control was not complete "
549  "before calling base GameWorld implementation");
550 }
#define LOG_ERROR(x)
Definition: Define.h:83

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

529 {
530  if(entriesleft < 1)
531  return;
532 
533  LOG_ERROR("GameWorld: entity static state decoding was not complete before calling base "
534  "GameWorld implementation. Received entity won't be fully constructed");
535 }
#define LOG_ERROR(x)
Definition: Define.h:83

◆ _CreateReceivedComponentForEntity()

DLLEXPORT void GameWorld::_CreateReceivedComponentForEntity ( ObjectID  id)
protectedvirtual

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

Definition at line 1062 of file GameWorld.cpp.

1063 {
1064  LOG_ERROR("GameWorld: base version of _CreateReceivedComponentForEntity, this shouldn't "
1065  "happen with correct configuration");
1066 }
#define LOG_ERROR(x)
Definition: Define.h:83

◆ _CreateSendableComponentForEntity()

DLLEXPORT void GameWorld::_CreateSendableComponentForEntity ( ObjectID  id)
protectedvirtual

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

Definition at line 1056 of file GameWorld.cpp.

1057 {
1058  LOG_ERROR("GameWorld: base version of _CreateSendableComponentForEntity, this shouldn't "
1059  "happen with correct configuration");
1060 }
#define LOG_ERROR(x)
Definition: Define.h:83

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

539 {
540  LOG_ERROR(
541  "GameWorld: entity component state decoding was not complete before calling base "
542  "GameWorld implementation. Not all states have been decoded");
543 }
#define LOG_ERROR(x)
Definition: Define.h:83

◆ _DoResumeSystems()

DLLEXPORT void GameWorld::_DoResumeSystems ( )
protectedvirtual

Opposite of _DoSuspendSystems.

Definition at line 1046 of file GameWorld.cpp.

1047 {
1048  // We are responsible for script systems //
1049  for(auto iter = pimpl->RegisteredScriptSystems.begin();
1050  iter != pimpl->RegisteredScriptSystems.end(); ++iter) {
1051 
1052  iter->second->Resume();
1053  }
1054 }

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

1037 {
1038  // We are responsible for script systems //
1039  for(auto iter = pimpl->RegisteredScriptSystems.begin();
1040  iter != pimpl->RegisteredScriptSystems.end(); ++iter) {
1041 
1042  iter->second->Suspend();
1043  }
1044 }

◆ _DoSystemsInit()

DLLEXPORT void GameWorld::_DoSystemsInit ( )
protectedvirtual

Called in Init when systems should run their initialization logic.

Definition at line 1015 of file GameWorld.cpp.

1016 {
1017  // Script systems are initialized as they are created
1018 }

◆ _DoSystemsRelease()

DLLEXPORT void GameWorld::_DoSystemsRelease ( )
protectedvirtual

Called in Release when systems should run their shutdown logic.

Definition at line 1020 of file GameWorld.cpp.

1021 {
1022  // This can be called after Releasing once already
1023  if(!pimpl)
1024  return;
1025 
1026  // We are responsible for script systems //
1027  for(auto iter = pimpl->RegisteredScriptSystems.begin();
1028  iter != pimpl->RegisteredScriptSystems.end(); ++iter) {
1029 
1030  iter->second->Release();
1031  }
1032 
1033  pimpl->RegisteredScriptSystems.clear();
1034 }

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

1376 {
1377  Position* position = GetComponentPtr<Position>(id);
1378  Physics* physics = GetComponentPtr<Physics>(id);
1379 
1380  if(position && physics) {
1381 
1382  if(position->Marked) {
1383 
1384  physics->JumpTo(*position);
1385  }
1386  }
1387 }
Entity has position and direction it is looking at.
Definition: Components.h:38
Entity has a physical component.
Definition: Components.h:333
DLLEXPORT void JumpTo(Position &target)
Syncs this physics body to a changed position.
Definition: Components.cpp:118

◆ _ResetOrReleaseComponents()

DLLEXPORT void GameWorld::_ResetOrReleaseComponents ( )
protectedvirtual

Resets components in holders. Used together with _ResetSystems.

Definition at line 662 of file GameWorld.cpp.

663 {
664  // Skip double Release
665  if(!pimpl)
666  return;
667 
668  // We are responsible for script components //
669  for(auto iter = pimpl->RegisteredScriptComponents.begin();
670  iter != pimpl->RegisteredScriptComponents.end(); ++iter) {
671 
672  iter->second->ReleaseAllComponents();
673  }
674 }

◆ _ResetSystems()

DLLEXPORT void GameWorld::_ResetSystems ( )
protectedvirtual

Resets stored nodes in systems. Used together with _ResetComponents.

Definition at line 648 of file GameWorld.cpp.

649 {
650  // Skip double Release
651  if(!pimpl)
652  return;
653 
654  // We are responsible for script systems //
655  for(auto iter = pimpl->RegisteredScriptSystems.begin();
656  iter != pimpl->RegisteredScriptSystems.end(); ++iter) {
657 
658  iter->second->Clear();
659  }
660 }

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

686 {
687  // We are responsible for script systems //
688  for(auto iter = pimpl->RegisteredScriptSystems.begin();
689  iter != pimpl->RegisteredScriptSystems.end(); ++iter) {
690 
691  iter->second->Run();
692  }
693 }

◆ ApplyQueuedPackets()

DLLEXPORT void GameWorld::ApplyQueuedPackets ( )
protected

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

Definition at line 1389 of file GameWorld.cpp.

1390 {
1391  if(!pimpl->QueuedEntityUpdates.empty()) {
1392  }
1393 
1394  // Applies packets that were received out of order. And throws out any too old packets
1395 
1396  // if(!InitialEntityPackets.empty())
1397  // _ApplyInitialEntityPackets();
1398 
1399  // if(!EntityUpdatePackets.empty())
1400  // _ApplyEntityUpdatePackets();
1401 }

◆ CaptureEntityState()

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

Captures the current state of an entity.

Definition at line 520 of file GameWorld.cpp.

520 {}

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

523 {
524  return 0;
525 }

◆ CastRayFromCamera()

DLLEXPORT Ogre::Ray GameWorld::CastRayFromCamera ( float  x,
float  y 
) const

Casts a ray from the active camera.

Parameters
xNormalized x coordinate (range [0, 1])
yNormalized y coordinate (range [0, 1])
Exceptions
InvalidStateif this world has no active camera
See also
SetCamera

Definition at line 370 of file GameWorld.cpp.

371 {
372  // Fail if there is no active camera //
373  if(CameraEntity == NULL_OBJECT)
374  throw InvalidState("This world has no active CameraEntity");
375 
376  if(!WorldSceneCamera)
377  throw InvalidState("This world has initialized Ogre resources");
378 
379  // Read the latest set data from the camera
380  // TODO: could jump to the actual latest position here if wanted
381  return WorldSceneCamera->getCameraToViewportRay(x, y);
382 }
constexpr ObjectID NULL_OBJECT
Definition: EntityCommon.h:14

◆ ClearAddedAndRemoved()

DLLEXPORT void GameWorld::ClearAddedAndRemoved ( )
protectedvirtual

Clears the added components. Call after HandleAddedAndDeleted.

Definition at line 637 of file GameWorld.cpp.

638 {
639  // We are responsible for script components //
640  for(auto iter = pimpl->RegisteredScriptComponents.begin();
641  iter != pimpl->RegisteredScriptComponents.end(); ++iter) {
642 
643  iter->second->ClearAdded();
644  iter->second->ClearRemoved();
645  }
646 }

◆ ClearEntities()

DLLEXPORT void GameWorld::ClearEntities ( )

Clears all objects from the world.

Definition at line 747 of file GameWorld.cpp.

748 {
749  // Release objects //
750  Entities.clear();
751  Parents.clear();
752  // This shouldn't be used all that much so release the memory
753  Parents.shrink_to_fit();
754 
755  // Clear all nodes //
756  _ResetSystems();
757 
758  // Clears all components
759  // Runs Release on components that need it
761 
762  // Notify everybody that all entities are discarded //
763  for(auto iter = ReceivingPlayers.begin(); iter != ReceivingPlayers.end(); ++iter) {
764 
765  auto safe = (*iter)->GetConnection();
766 
767  if(!safe->IsValidForSend()) {
768  // Player has probably closed their connection //
769  continue;
770  }
771 
772  Logger::Get()->Write("TODO: send world clear message");
773  DEBUG_BREAK;
774  }
775 }
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:662
static DLLEXPORT Logger * Get()
Definition: Logger.cpp:106
virtual DLLEXPORT void _ResetSystems()
Resets stored nodes in systems. Used together with _ResetComponents.
Definition: GameWorld.cpp:648

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

721 {
722  if(!GetNetworkSettings().IsAuthoritative) {
723  // Clients create high number entities. This is not optimal but good enough for now
724  auto id = (1 << 31) | static_cast<ObjectID>(IDFactory::GetID());
725 
726  Entities.push_back(id);
727 
728  return id;
729 
730  } else {
731  auto id = static_cast<ObjectID>(IDFactory::GetID());
732 
733  Entities.push_back(id);
734 
735  if(NetworkSettings.IsAuthoritative) {
736  // NewlyCreatedEntities.push_back(id);
737 
738  if(NetworkSettings.AutoCreateNetworkComponents) {
740  }
741  }
742 
743  return id;
744  }
745 }
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:1056
static int GetID()
Definition: IDFactory.h:17
bool IsAuthoritative
This is true on the server.
DLLEXPORT const auto & GetNetworkSettings() const
Definition: GameWorld.h:345

◆ DestroyAllIn()

DLLEXPORT void GameWorld::DestroyAllIn ( ObjectID  id)
virtual

Removes all components from an entity.

Definition at line 1069 of file GameWorld.cpp.

1070 {
1071  // This can be called after Releasing once already
1072  if(!pimpl)
1073  return;
1074 
1075  // Handle script types
1076  for(auto iter = pimpl->RegisteredScriptComponents.begin();
1077  iter != pimpl->RegisteredScriptComponents.end(); ++iter) {
1078 
1079  // Just try to remove like the normal c++ components until there is a better way
1080  iter->second->ReleaseComponent(id);
1081  }
1082 }

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

793 {
794  // Fail if trying to delete NULL_OBJECT
795  if(id == NULL_OBJECT)
796  throw InvalidArgument("Cannot destroy NULL_OBJECT");
797 
798  // Fail if ticking currently //
799  if(TickInProgress)
800  throw InvalidState(
801  "Cannot DestroyEntity while ticking. Use QueueDestroyEntity instead");
802 
803  for(auto iter = Entities.begin(); iter != Entities.end(); ++iter) {
804 
805  if(*iter == id) {
806 
807  Entities.erase(iter);
808  _DoDestroy(id);
809  return;
810  }
811  }
812 
813  LOG_ERROR("GameWorld: DestroyEntity: unknown entity id: " + std::to_string(id));
814 }
constexpr ObjectID NULL_OBJECT
Definition: EntityCommon.h:14
#define LOG_ERROR(x)
Definition: Define.h:83

◆ DoesEntityExist()

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

Returns true if entity exists.

Definition at line 191 of file GameWorld.h.

192  {
193  for(const auto& entity : Entities) {
194  if(id == entity)
195  return true;
196  }
197 
198  return false;
199  }

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

989 {
990  return false;
991 }

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

995 {
996  auto iter = pimpl->RegisteredScriptComponents.find(name);
997 
998  if(iter == pimpl->RegisteredScriptComponents.end())
999  return false;
1000 
1001  auto& added = iter->second->GetAdded();
1002 
1003  result.reserve(result.size() + added.size());
1004 
1005  for(const auto& tuple : added) {
1006 
1007  result.push_back(
1008  std::make_tuple(std::get<0>(tuple), std::get<1>(tuple), iter->second.get()));
1009  }
1010 
1011  return true;
1012 }

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

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

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

952 {
953  return std::make_tuple(nullptr, false);
954 }

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

231  {
232  std::tuple<void*, bool> component = GetComponent(id, TComponent::TYPE);
233 
234  void* ptr = std::get<0>(component);
235 
236  if(!ptr)
237  return nullptr;
238 
239  return static_cast<TComponent*>(ptr);
240  }
TComponent & GetComponent(ObjectID id)
Definition: GameWorld.h:210

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

958 {
959  return std::make_tuple(nullptr, ComponentTypeInfo(-1, -1), false);
960 }

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

374  {
375  return ReceivingPlayers;
376  }

◆ GetEntities()

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

Returns the created entity id vector.

Definition at line 131 of file GameWorld.h.

132  {
133  return Entities;
134  }

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

126  {
127  return Entities.size();
128  }

◆ GetID()

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

Definition at line 334 of file GameWorld.h.

335  {
336  return ID;
337  }

◆ GetNetworkSettings()

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

Definition at line 345 of file GameWorld.h.

346  {
347  return NetworkSettings;
348  }

◆ GetOurLocalControl()

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

Definition at line 389 of file GameWorld.h.

390  {
391  return OurActiveLocalControl;
392  }

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

785 {
786  if(!PhysicsMaterials)
787  return -1;
788 
789  return PhysicsMaterials->GetMaterialID(name);
790 }

◆ GetPhysicalWorld()

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

Definition at line 328 of file GameWorld.h.

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

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

969 {
970  return false;
971 }

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

975 {
976  auto iter = pimpl->RegisteredScriptComponents.find(name);
977 
978  if(iter == pimpl->RegisteredScriptComponents.end())
979  return false;
980 
981  auto& removed = iter->second->GetRemoved();
982 
983  result.insert(std::end(result), std::begin(removed), std::end(removed));
984  return true;
985 }

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

1458 {
1459  if(!componenttypes)
1460  return nullptr;
1461 
1462  if(componenttypes->GetElementTypeId() !=
1464 
1465  LOG_ERROR("GameWorld: GetRemovedIDsForComponents: given an array of wrong type");
1466  componenttypes->Release();
1467  return nullptr;
1468  }
1469 
1470  std::vector<std::tuple<void*, ObjectID>> result;
1471 
1472  for(asUINT i = 0; i < componenttypes->GetSize(); ++i) {
1473 
1474  uint16_t* type = static_cast<uint16_t*>(componenttypes->At(i));
1475 
1476  if(!GetRemovedFor(static_cast<COMPONENT_TYPE>(*type), result)) {
1477 
1478  LOG_WARNING("GameWorld: GetRemovedIDsForComponents: unknown component type: " +
1479  std::to_string(*type));
1480  }
1481  }
1482 
1483  componenttypes->Release();
1484 
1485  asITypeInfo* typeInfo =
1486  ScriptExecutor::Get()->GetASEngine()->GetTypeInfoByDecl("array<ObjectID>");
1487 
1488  CScriptArray* array = CScriptArray::Create(typeInfo, static_cast<asUINT>(result.size()));
1489 
1490  if(!array)
1491  return nullptr;
1492 
1493  for(asUINT i = 0; i < static_cast<asUINT>(result.size()); ++i) {
1494 
1495  array->SetValue(i, &std::get<1>(result[i]));
1496  }
1497 
1498  return array;
1499 }
DLLEXPORT asIScriptEngine * GetASEngine()
#define LOG_ERROR(x)
Definition: Define.h:83
static int Get(ScriptExecutor *resolver)
#define LOG_WARNING(x)
Definition: Define.h:82
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:967

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

1502 {
1503  if(!typenames)
1504  return nullptr;
1505 
1506  if(typenames->GetElementTypeId() !=
1508 
1509  LOG_ERROR("GameWorld: GetRemovedIDsForScriptComponents: given an array of wrong type "
1510  "(expected array<string>)");
1511  typenames->Release();
1512  return nullptr;
1513  }
1514 
1515  std::vector<std::tuple<asIScriptObject*, ObjectID>> result;
1516 
1517  for(asUINT i = 0; i < typenames->GetSize(); ++i) {
1518 
1519  std::string* type = static_cast<std::string*>(typenames->At(i));
1520 
1521  if(!GetRemovedForScriptDefined(*type, result)) {
1522 
1523  LOG_WARNING(
1524  "GameWorld: GetRemovedIDsForScriptComponents: unknown component type: " +
1525  *type);
1526  }
1527  }
1528 
1529  typenames->Release();
1530 
1531  asITypeInfo* typeInfo =
1532  ScriptExecutor::Get()->GetASEngine()->GetTypeInfoByDecl("array<ObjectID>");
1533 
1534  CScriptArray* array = CScriptArray::Create(typeInfo, static_cast<asUINT>(result.size()));
1535 
1536  if(!array)
1537  return nullptr;
1538 
1539  for(asUINT i = 0; i < static_cast<asUINT>(result.size()); ++i) {
1540 
1541  array->SetValue(i, &std::get<1>(result[i]));
1542  }
1543 
1544  return array;
1545 }
DLLEXPORT asIScriptEngine * GetASEngine()
#define LOG_ERROR(x)
Definition: Define.h:83
static int Get(ScriptExecutor *resolver)
#define LOG_WARNING(x)
Definition: Define.h:82
DLLEXPORT bool GetRemovedForScriptDefined(const std::string &name, std::vector< std::tuple< asIScriptObject *, ObjectID >> &result)
Variant of GetRemovedFor for script defined types.
Definition: GameWorld.cpp:973
static DLLEXPORT ScriptExecutor * Get()

◆ GetScene()

Ogre::SceneManager* Leviathan::GameWorld::GetScene ( )
inline

Definition at line 320 of file GameWorld.h.

321  {
322  return WorldsScene;
323  }

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

1565 {
1566  // if called after release
1567  if(!pimpl)
1568  return nullptr;
1569 
1570  auto iter = pimpl->RegisteredScriptComponents.find(name);
1571 
1572  if(iter == pimpl->RegisteredScriptComponents.end())
1573  return nullptr;
1574 
1575  iter->second->AddRef();
1576  return iter->second.get();
1577 }

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

1627 {
1628  // if called after release
1629  if(!pimpl)
1630  return nullptr;
1631 
1632  auto iter = pimpl->RegisteredScriptSystems.find(name);
1633 
1634  if(iter == pimpl->RegisteredScriptSystems.end()) {
1635 
1636  LOG_ERROR("GameWorld: GetScriptSystemDirect: world has no system called: " + name);
1637  return nullptr;
1638  }
1639 
1640  return iter->second->GetASImplementationObject();
1641 }
#define LOG_ERROR(x)
Definition: Define.h:83

◆ GetServerForLocalControl()

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

Definition at line 413 of file GameWorld.h.

414  {
415  return ClientToServerConnection;
416  }

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

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

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

963 {
964  return std::make_tuple(nullptr, false);
965 }

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

706 {
707  int tick = TickNumber;
708  int timeSince = static_cast<int>(Engine::Get()->GetTimeSinceLastTick());
709 
710  while(timeSince >= TICKSPEED) {
711 
712  ++tick;
713  timeSince -= TICKSPEED;
714  }
715 
716  return std::make_tuple(tick, timeSince);
717 }
constexpr auto TICKSPEED
Number of milliseconds between engine and world ticks.
Definition: Define.h:21
DLLEXPORT int64_t GetTimeSinceLastTick() const
Calculates how long has elapsed since the last tick.
Definition: Engine.cpp:1244
static DLLEXPORT Engine * Get()
Definition: Engine.cpp:84

◆ GetTickNumber()

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

Returns the current tick.

Definition at line 147 of file GameWorld.h.

148  {
149  return TickNumber;
150  }

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

696 {
697  float progress = Engine::Get()->GetTimeSinceLastTick() / (float)TICKSPEED;
698 
699  if(progress < 0.f)
700  return 0.f;
701 
702  return progress < 1.f ? progress : 1.f;
703 }
constexpr auto TICKSPEED
Number of milliseconds between engine and world ticks.
Definition: Define.h:21
DLLEXPORT int64_t GetTimeSinceLastTick() const
Calculates how long has elapsed since the last tick.
Definition: Engine.cpp:1244
static DLLEXPORT Engine * Get()
Definition: Engine.cpp:84

◆ GetType()

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

Definition at line 340 of file GameWorld.h.

341  {
342  return WorldType;
343  }

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

628 {
629  // We are responsible for script systems //
630  for(auto iter = pimpl->RegisteredScriptSystems.begin();
631  iter != pimpl->RegisteredScriptSystems.end(); ++iter) {
632 
633  iter->second->CreateAndDestroyNodes();
634  }
635 }

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

1179 {
1180  if(NetworkSettings.IsAuthoritative) {
1181 
1182  // Find matching local control before allowing
1183  auto found = ActiveLocalControl.find(message.EntityID);
1184 
1185  if(found != ActiveLocalControl.end()) {
1186 
1187  if(found->second != &connection) {
1188 
1189  // It's unsafe to dereference found->second here
1190  LOG_WARNING("GameWorld: wrong player sent local control message, entity: " +
1191  std::to_string(message.EntityID));
1192  return;
1193  }
1194 
1195  _ApplyLocalControlUpdateMessage(message.EntityID, message.TickNumber,
1196  message.UpdateData, message.ReferenceTick, -1);
1197  _OnLocalControlUpdatedEntity(message.EntityID, message.TickNumber);
1198  return;
1199  }
1200 
1201  LOG_WARNING(
1202  "GameWorld: didn't find local control entity for ResponseEntityUpdate, entity: " +
1203  std::to_string(message.EntityID));
1204  return;
1205  }
1206 
1207  // Don't apply if we don't have the entity
1208  bool found = false;
1209 
1210  for(auto entity : Entities) {
1211  if(entity == message.EntityID) {
1212 
1213  found = true;
1214  break;
1215  }
1216  }
1217 
1218  if(!found) {
1219 
1220  LOG_WARNING(
1221  "GameWorld: HandleEntityPacket: received update for non-existing entity, id: " +
1222  std::to_string(message.EntityID) +
1223  " TODO: queue for later applying in case packets are out of order");
1224  return;
1225  }
1226 
1227  // If this is controlled by us this is handled differently
1228  for(auto entity : OurActiveLocalControl) {
1229 
1230  if(entity == message.EntityID) {
1231 
1232  // TODO: apply corrections if our simulation was incorrect / not allowed
1233  return;
1234  }
1235  }
1236 
1237  try {
1238  _CreateStatesFromUpdateMessage(message.EntityID, message.TickNumber,
1239  message.UpdateData, message.ReferenceTick, -1);
1240  } catch(const InvalidArgument& e) {
1241  LOG_ERROR("GameWorld: HandleEntityPacket: trying to load update packet data caused an "
1242  "exception: ");
1243  e.PrintToLog();
1244  LOG_INFO("GameWorld: note: entity may have partially updated states, id: " +
1245  std::to_string(message.EntityID));
1246  }
1247 }
#define LOG_INFO(x)
Definition: Define.h:81
#define LOG_ERROR(x)
Definition: Define.h:83
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:545
#define LOG_WARNING(x)
Definition: Define.h:82
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:537
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:1375

◆ HandleEntityPacket() [2/4]

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

Definition at line 1249 of file GameWorld.cpp.

1250 {
1251  if(NetworkSettings.IsAuthoritative) {
1252 
1253  LOG_WARNING("GameWorld: authoritative world is ignoring ResponseEntityCreation");
1254  return NULL_OBJECT;
1255  }
1256 
1257  if(message.ComponentCount > 1000) {
1258  LOG_ERROR("GameWorld: HandleEntityPacket: entity has more than 1000 components. "
1259  "Packet is likely corrupted / forged, ignoring");
1260  return NULL_OBJECT;
1261  }
1262 
1263  // TODO: somehow detect if the ID collides with local entities (once those are allowed)
1264  Entities.push_back(message.EntityID);
1265 
1266  if(!NetworkSettings.IsAuthoritative) {
1267 
1268  if(NetworkSettings.AutoCreateNetworkComponents) {
1269  _CreateReceivedComponentForEntity(message.EntityID);
1270  }
1271  }
1272 
1273  try {
1275  message.EntityID, message.InitialComponentData, message.ComponentCount, -1);
1276 
1277  return message.EntityID;
1278  } catch(const InvalidArgument& e) {
1279  LOG_ERROR(
1280  "GameWorld: HandleEntityPacket: trying to load packet data caused an exception: ");
1281  e.PrintToLog();
1282  LOG_INFO("GameWorld: destroying invalid received entity: " +
1283  std::to_string(message.EntityID));
1284  DestroyEntity(message.EntityID);
1285 
1286  return NULL_OBJECT;
1287  }
1288 }
#define LOG_INFO(x)
Definition: Define.h:81
constexpr ObjectID NULL_OBJECT
Definition: EntityCommon.h:14
#define LOG_ERROR(x)
Definition: Define.h:83
virtual DLLEXPORT void _CreateReceivedComponentForEntity(ObjectID id)
Called when this base class wants to create a Received component.
Definition: GameWorld.cpp:1062
#define LOG_WARNING(x)
Definition: Define.h:82
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:527
DLLEXPORT void DestroyEntity(ObjectID id)
Destroys an entity and all of its components.
Definition: GameWorld.cpp:792

◆ HandleEntityPacket() [3/4]

DLLEXPORT void GameWorld::HandleEntityPacket ( ResponseEntityDestruction &  message)

Definition at line 1290 of file GameWorld.cpp.

1291 {
1292  if(NetworkSettings.IsAuthoritative) {
1293 
1294  LOG_WARNING("GameWorld: authoritative world is ignoring ResponseEntityCreation");
1295  return;
1296  }
1297 
1298  for(auto entity : Entities) {
1299  if(entity == message.EntityID) {
1300 
1301  DestroyEntity(message.EntityID);
1302  return;
1303  }
1304  }
1305 
1306  // TODO: queue if we don't have an entity with the ID
1307  LOG_WARNING("GameWorld: HandleEntityPacket: received destruction message for unknown "
1308  "entity, TODO: queue");
1309 }
#define LOG_WARNING(x)
Definition: Define.h:82
bool IsAuthoritative
This is true on the server.
DLLEXPORT void DestroyEntity(ObjectID id)
Destroys an entity and all of its components.
Definition: GameWorld.cpp:792

◆ HandleEntityPacket() [4/4]

DLLEXPORT void GameWorld::HandleEntityPacket ( ResponseEntityLocalControlStatus &  message)

Definition at line 1311 of file GameWorld.cpp.

1312 {
1313  if(!message.Enabled) {
1314 
1315  for(auto iter = OurActiveLocalControl.begin(); iter != OurActiveLocalControl.end();
1316  ++iter) {
1317 
1318  if(*iter == message.EntityID) {
1319  OurActiveLocalControl.erase(iter);
1320  return;
1321  }
1322  }
1323 
1324  LOG_WARNING("GameWorld: received disable local control message for entity that wasn't "
1325  "controlled by us");
1326  } else {
1327 
1328  // Ignore duplicates
1329  for(auto controlled : OurActiveLocalControl)
1330  if(controlled == message.EntityID)
1331  return;
1332 
1333  OurActiveLocalControl.push_back(message.EntityID);
1334 
1335  if(NetworkSettings.AutoCreateNetworkComponents) {
1336  try {
1337  _CreateSendableComponentForEntity(message.EntityID);
1338  LOG_INFO("GameWorld: created Sendable for locally controlled entity: " +
1339  std::to_string(message.EntityID));
1340  } catch(const InvalidState&) {
1341  LOG_WARNING(
1342  "GameWorld: couldn't create Sendable for now locally controlled entity:" +
1343  std::to_string(message.EntityID));
1344  }
1345  }
1346  }
1347 }
#define LOG_INFO(x)
Definition: Define.h:81
virtual DLLEXPORT void _CreateSendableComponentForEntity(ObjectID id)
Called when this base class wants to create a Sendable component.
Definition: GameWorld.cpp:1056
#define LOG_WARNING(x)
Definition: Define.h:82

◆ Init()

DLLEXPORT bool GameWorld::Init ( const WorldNetworkSettings network,
Ogre::Root *  ogre 
)

Creates resources for the world to work.

Postcondition
The world can be used after this

Definition at line 91 of file GameWorld.cpp.

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

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

391 {
392  for(auto& player : ReceivingPlayers) {
393 
394  if(player->GetConnection().get() == &connection) {
395 
396  return true;
397  }
398  }
399 
400  return false;
401 }

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

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

◆ MarkForClear()

DLLEXPORT void GameWorld::MarkForClear ( )

Marks all entities to be deleted.

Definition at line 1150 of file GameWorld.cpp.

1151 {
1152  ClearAllEntities = true;
1153 }

◆ OnLinkToWindow()

DLLEXPORT void GameWorld::OnLinkToWindow ( Window window,
Ogre::Root *  ogre 
)
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 1668 of file GameWorld.cpp.

1669 {
1670  LEVIATHAN_ASSERT(WorldsScene, "World is not initialized");
1671 
1672  if(!window)
1673  throw InvalidArgument("GameWorld attempted to be linked to a nullptr window");
1674 
1675  if(LinkedToWindow || WorldWorkspace) {
1676 
1677  throw InvalidArgument(
1678  "GameWorld attempted to be linked to a window while it is already linked");
1679  }
1680 
1681  LinkedToWindow = window;
1682 
1683  // Create the workspace for this scene //
1684  // Which will be rendered before the overlay workspace but after potential
1685  // clearing workspace
1686  WorldWorkspace = ogre->getCompositorManager2()->addWorkspace(WorldsScene,
1687  LinkedToWindow->GetOgreWindow(), WorldSceneCamera, "WorldsWorkspace", true, 0);
1688 
1689  if(!TickWhileInBackground) {
1690  _DoResumeSystems();
1691  }
1692 
1693  InBackground = false;
1694 }
DLLEXPORT Ogre::RenderWindow * GetOgreWindow() const
Definition: Window.h:165
virtual DLLEXPORT void _DoResumeSystems()
Opposite of _DoSuspendSystems.
Definition: GameWorld.cpp:1046

◆ OnUnLinkedFromWindow()

DLLEXPORT void GameWorld::OnUnLinkedFromWindow ( Window window,
Ogre::Root *  ogre 
)
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 1643 of file GameWorld.cpp.

1644 {
1645  if(!LinkedToWindow) {
1646  LOG_WARNING(
1647  "GameWorld: unlink from window called while this wasn't linked to a window");
1648  return;
1649  }
1650 
1651  if(window != LinkedToWindow) {
1652 
1653  throw InvalidArgument("GameWorld attempted to be unlinked from window that wasn't the "
1654  "one it was linked to");
1655  }
1656 
1657  ogre->getCompositorManager2()->removeWorkspace(WorldWorkspace);
1658  WorldWorkspace = nullptr;
1659  LinkedToWindow = nullptr;
1660 
1661  if(!TickWhileInBackground) {
1663  }
1664 
1665  InBackground = true;
1666 }
virtual DLLEXPORT void _DoSuspendSystems()
Called when this is put in the background and systems (the sound system) should suspend their active ...
Definition: GameWorld.cpp:1036
#define LOG_WARNING(x)
Definition: Define.h:82

◆ QueueDestroyEntity()

DLLEXPORT void GameWorld::QueueDestroyEntity ( ObjectID  id)

Deletes an entity during the next tick.

Definition at line 816 of file GameWorld.cpp.

817 {
818  // Fail if trying to delete NULL_OBJECT
819  if(id == NULL_OBJECT)
820  throw InvalidArgument("Cannot destroy NULL_OBJECT");
821 
822  // This is a sanity check, can be disabled (or made cheaper when the world no longer uses
823  // IDFactory) when crashing stops
824  bool exists = false;
825 
826  for(auto existingId : Entities) {
827  if(existingId == id) {
828  exists = true;
829  break;
830  }
831  }
832 
833  if(!exists) {
834  LOG_ERROR("GameWorld: QueueDestroyEntity: unknown entity id: " + std::to_string(id));
835  return;
836  }
837 
838  Lock lock(DeleteMutex);
839 
840  // Skip duplicates
841  for(auto alreadyQueued : DelayedDeleteIDS)
842  if(id == alreadyQueued)
843  return;
844 
845  DelayedDeleteIDS.push_back(id);
846 }
constexpr ObjectID NULL_OBJECT
Definition: EntityCommon.h:14
#define LOG_ERROR(x)
Definition: Define.h:83
std::unique_lock< std::mutex > Lock
Definition: ThreadSafe.h:16

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

1549 {
1550  // Skip if already registered //
1551  if(pimpl->RegisteredScriptComponents.find(name) !=
1552  pimpl->RegisteredScriptComponents.end()) {
1553  factory->Release();
1554  return false;
1555  }
1556 
1557  // ScriptComponentHolder takes care of releasing the reference
1558  pimpl->RegisteredScriptComponents[name] =
1559  ScriptComponentHolder::MakeShared<ScriptComponentHolder>(name, factory, this);
1560 
1561  return true;
1562 }

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

1581 {
1582  if(!system) {
1583  LOG_ERROR("GameWorld: RegisterScriptSystem: passed null object as new system");
1584  return false;
1585  }
1586 
1587  // if called after release
1588  if(!pimpl) {
1589  system->Release();
1590  return false;
1591  }
1592 
1593  // Skip if already registered //
1594  if(pimpl->RegisteredScriptSystems.find(name) != pimpl->RegisteredScriptSystems.end()) {
1595  system->Release();
1596  return false;
1597  }
1598 
1599  // Create a wrapper for it //
1600  // The wrapper handles unreferencing the handle
1601  pimpl->RegisteredScriptSystems[name] = std::make_unique<ScriptSystemWrapper>(name, system);
1602 
1603  // Might as well call Init now as other systems are almost certainly initialized as well //
1604  pimpl->RegisteredScriptSystems[name]->Init(this);
1605  return true;
1606 }
#define LOG_ERROR(x)
Definition: Define.h:83

◆ Release()

DLLEXPORT void GameWorld::Release ( )

Release to not use Ogre when deleting.

Definition at line 118 of file GameWorld.cpp.

119 {
121 
122  (*WorldDestroyed) = true;
123 
124  ReceivingPlayers.clear();
125 
126  // release objects //
127  // TODO: allow objects to know that they are about to get killed
128 
129  // As all objects are just pointers to components we can just dump the objects
130  // and once the component pools are released
131  ClearEntities();
132 
133  if(GraphicalMode) {
134  // TODO: notify our window that it no longer has a world workspace
135  LinkedToWindow = nullptr;
136 
137  // release Ogre resources //
138 
139  // Destroy the compositor //
140  Ogre::Root& ogre = Ogre::Root::getSingleton();
141 
142  // Allow releasing twice
143  if(WorldWorkspace) {
144  ogre.getCompositorManager2()->removeWorkspace(WorldWorkspace);
145  WorldWorkspace = nullptr;
146  }
147 
148  if(WorldsScene) {
149  ogre.destroySceneManager(WorldsScene);
150  WorldsScene = nullptr;
151  }
152  }
153 
154  // This should be relatively cheap if the newton threads don't deadlock while waiting
155  // for each other
156  _PhysicalWorld.reset();
157 
158  // Let go of our these resources
159  pimpl.reset();
160 }
virtual DLLEXPORT void _DoSystemsRelease()
Called in Release when systems should run their shutdown logic.
Definition: GameWorld.cpp:1020
DLLEXPORT void ClearEntities()
Clears all objects from the world.
Definition: GameWorld.cpp:747
bool GraphicalMode
If false a graphical Ogre window hasn&#39;t been created and purely graphical stuff should be skipped...
Definition: GameWorld.h:614

◆ RemoveSunlight()

DLLEXPORT void GameWorld::RemoveSunlight ( )

Definition at line 249 of file GameWorld.cpp.

250 {
251  if(SunLightNode) {
252  SunLightNode->detachAllObjects();
253  // might be safe to delete
254  OGRE_DELETE SunLightNode;
255  SunLightNode = nullptr;
256  }
257 }

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

280 {
281  if(InBackground) {
282 
283  LOG_ERROR("GameWorld: Render: called while world is in the background (not attached "
284  "to a window)");
285  return;
286  }
287 
288  RunFrameRenderSystems(tick, timeintick);
289 
290  // Read camera entity and update position //
291 
292  // Skip if no camera //
293  if(CameraEntity == 0)
294  return;
295 
296  try {
297  Camera& properties = GetComponent<Camera>(CameraEntity);
298 
299  Position& position = GetComponent<Position>(CameraEntity);
300 
301  auto& states = GetStatesFor<Position>();
302 
303  // set camera position //
304  const auto interpolated =
305  StateInterpolator::Interpolate(states, CameraEntity, &position, tick, timeintick);
306 
307  if(!std::get<0>(interpolated)) {
308 
309  // No interpolated pos //
310  WorldSceneCamera->setPosition(position.Members._Position);
311  WorldSceneCamera->setOrientation(position.Members._Orientation);
312 
313  } else {
314 
315  const auto& interpolatedPos = std::get<1>(interpolated);
316  WorldSceneCamera->setPosition(interpolatedPos._Position);
317  WorldSceneCamera->setOrientation(interpolatedPos._Orientation);
318  }
319 
320  if(properties.SoundPerceiver) {
321 
323  position.Members._Position, position.Members._Orientation);
324  }
325 
326  if(properties.Marked || AppliedCameraPropertiesPtr != &properties) {
327 
328  AppliedCameraPropertiesPtr = &properties;
329 
330  WorldSceneCamera->setFOVy(Ogre::Degree(properties.FOVY));
331 
332  properties.Marked = false;
333  }
334 
335  } catch(const Exception& e) {
336 
337  LOG_ERROR("GameWorld: Render: camera update failed. Was a component removed?, "
338  "exception:");
339  e.PrintToLog();
340  CameraEntity = 0;
341  return;
342  }
343 }
#define LOG_ERROR(x)
Definition: Define.h:83
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:38
SoundDevice * GetSoundDevice()
Definition: Engine.h:214
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:676
Properties that a camera entity has (will also need a Position component)
Definition: Components.h:699
static DLLEXPORT Engine * Get()
Definition: Engine.cpp:84

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

677 {
678  // Don't have any systems, but these updates may be important for interpolation //
679  // _ApplyEntityUpdatePackets();
680 
681  // TODO: if there are any impactful simulation done here it needs to be also inside a block
682  // where TickInProgress is set to true
683 }

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

505 {
506  // Notify everybody that an entity has been destroyed //
507  for(auto iter = ReceivingPlayers.begin(); iter != ReceivingPlayers.end(); ++iter) {
508 
509  auto safe = (*iter)->GetConnection();
510 
511  if(!safe->IsValidForSend()) {
512  // Player has probably closed their connection //
513  continue;
514  }
515 
516  safe->SendPacketToConnection(response, guarantee);
517  }
518 }

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

346 {
347  CameraEntity = object;
348 
349  AppliedCameraPropertiesPtr = nullptr;
350 
351  if(CameraEntity == NULL_OBJECT)
352  return;
353 
354  // Check components //
355  try {
356  GetComponent<Camera>(object);
357  } catch(const NotFound&) {
358 
359  throw InvalidArgument("SetCamera object is missing a needed component (Camera)");
360  }
361 
362  try {
363  GetComponent<Position>(object);
364  } catch(const NotFound&) {
365 
366  throw InvalidArgument("SetCamera object is missing a needed component (Position)");
367  }
368 }
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 946 of file GameWorld.cpp.

947 {
948  Parents.push_back(std::make_tuple(parent, child));
949 }

◆ SetFog()

DLLEXPORT void GameWorld::SetFog ( )
Todo:
Fix this for Ogre 2.1

Definition at line 209 of file GameWorld.cpp.

210 {
211  WorldsScene->setFog(Ogre::FOG_LINEAR, Ogre::ColourValue(0.7f, 0.7f, 0.8f), 0, 4000, 10000);
212  WorldsScene->setFog(Ogre::FOG_NONE);
213 }

◆ SetLightProperties()

DLLEXPORT void GameWorld::SetLightProperties ( const Ogre::ColourValue &  diffuse,
const Ogre::ColourValue &  specular,
const Ogre::Vector3 &  direction,
float  power,
const Ogre::ColourValue &  upperhemisphere,
const Ogre::ColourValue &  lowerhemisphere,
const Ogre::Vector3 &  hemispheredir,
float  envmapscale = 1.0f 
)

Sets the sunlight properties.

Precondition
SetSunlight has been called

Definition at line 259 of file GameWorld.cpp.

263 {
264  if(!Sunlight || !SunLightNode) {
265 
266  LOG_ERROR("GameWorld: SetLightProperties: world doesn't have sun light set");
267  return;
268  }
269 
270  Sunlight->setDiffuseColour(diffuse);
271  Sunlight->setSpecularColour(specular);
272  Sunlight->setDirection(direction);
273  Sunlight->setPowerScale(power);
274 
275  WorldsScene->setAmbientLight(upperhemisphere, lowerhemisphere, hemispheredir, envmapscale);
276 }
#define LOG_ERROR(x)
Definition: Define.h:83

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

1351 {
1352  // Apply the change
1353  if(enabled) {
1354 
1355  // TODO: detect changing owner
1356  ActiveLocalControl[id] = allowedconnection.get();
1357  } else {
1358 
1359  auto found = ActiveLocalControl.find(id);
1360 
1361  if(found != ActiveLocalControl.end()) {
1362  ActiveLocalControl.erase(found);
1363  } else {
1364  LOG_ERROR("GameWorld: SetLocalControl: disable called on entity that wasn't being "
1365  "controlled");
1366  }
1367  }
1368 
1369  // Notify
1370  auto response = std::make_shared<ResponseEntityLocalControlStatus>(0, ID, id, enabled);
1371 
1372  allowedconnection->SendPacketToConnection(response, RECEIVE_GUARANTEE::Critical);
1373 }
#define LOG_ERROR(x)
Definition: Define.h:83

◆ SetPlayerReceiveWorld()

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

Verifies that player is receiving this world.

Definition at line 403 of file GameWorld.cpp.

404 {
405  // Skip if already added //
406  for(auto& player : ReceivingPlayers) {
407 
408  if(player == ply) {
409 
410  return;
411  }
412  }
413 
414  LOG_INFO("GameWorld: player(\"" + ply->GetNickname() + "\") is now receiving world");
415 
416  // Add them to the list of receiving players //
417  ReceivingPlayers.push_back(ply);
418 
419  if(!ply->GetConnection()->IsValidForSend()) {
420 
421  // The closing should be handled by somebody else
422  Logger::Get()->Error("GameWorld: requested to sync with a player who has closed their "
423  "connection");
424 
425  return;
426  }
427 
428  {
429  // Start world receive information
430  ply->GetConnection()->SendPacketToConnection(
431  std::make_shared<ResponseStartWorldReceive>(0, ID, WorldType),
433  }
434 
435  // Update the position data //
436  UpdatePlayersPositionData(*ply);
437 
438  // Start sending initial update //
439  Logger::Get()->Info(
440  "Starting to send " + Convert::ToString(Entities.size()) + " to player");
441 
442  // Now we can queue all objects for sending //
443  // TODO: make sure that all objects are sent
444  // TODO: redo this inside the world tick
445  // ThreadingManager::Get()->QueueTask(
446  // new RepeatCountedTask(std::bind<void>([](
447  // std::shared_ptr<Connection> connection,
448  // std::shared_ptr<ConnectedPlayer> processingobject, GameWorld* world,
449  // std::shared_ptr<bool> WorldInvalid)
450  // -> void
451  // {
452  // // Get the next object //
453  // RepeatCountedTask* task =
454  // dynamic_cast<RepeatCountedTask*>(TaskThread::GetThreadSpecificThreadObject()->
455  // QuickTaskAccess.get());
456 
457  // LEVIATHAN_ASSERT(task, "wrong type passed to our task");
458 
459  // size_t num = task->GetRepeatCount();
460 
461  // if(*WorldInvalid){
462 
463  // taskstopprocessingobjectsforinitialsynclabel:
464 
465  // // Stop processing //
466  // task->StopRepeating();
467  // return;
468  // }
469 
470  // // Stop if out of bounds //
471  // if(num >= world->Entities.size()){
472 
473  // goto taskstopprocessingobjectsforinitialsynclabel;
474  // }
475 
476  // // Get the object //
477  // auto tosend = world->Entities[num];
478 
479  // // Skip if shouldn't send //
480  // try{
481 
482  // auto& position = world->GetComponent<Position>(tosend);
483 
484  // if(!world->ShouldPlayerReceiveObject(position, *connection)){
485 
486  // return;
487  // }
488 
489  // } catch(const NotFound&){
490 
491  // // No position, should probably always send //
492  // }
493 
494 
495  // // Send it //
496  // world->SendObjectToConnection(guard, tosend, connection);
497 
498  // return;
499 
500  // }, ply->GetConnection(), ply, this, WorldDestroyed), Entities.size()));
501 }
#define LOG_INFO(x)
Definition: Define.h:81
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 1696 of file GameWorld.cpp.

1697 {
1698  TickWhileInBackground = tickinbackground;
1699 }

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

409  {
410  ClientToServerConnection = connection;
411  }

◆ SetSunlight()

DLLEXPORT void GameWorld::SetSunlight ( )

Definition at line 215 of file GameWorld.cpp.

216 {
217  // create/update things if they are nullptr //
218  if(!Sunlight) {
219  Sunlight = WorldsScene->createLight();
220  Sunlight->setName("sunlight");
221  }
222 
223  if(!SunLightNode) {
224 
225  SunLightNode = WorldsScene->getRootSceneNode()->createChildSceneNode();
226  SunLightNode->setName("sunlight node");
227 
228  SunLightNode->attachObject(Sunlight);
229  }
230 
231  Sunlight->setType(Ogre::Light::LT_DIRECTIONAL);
232  // Sunlight->setDiffuseColour(0.98f, 1.f, 0.95f);
233  Sunlight->setDiffuseColour(1.f, 1.f, 1.f);
234  Sunlight->setSpecularColour(1.f, 1.f, 1.f);
235  // Sunlight->setDirection(Float3(-1, -1, -1).Normalize());
236  Sunlight->setDirection(Float3(0.55f, -0.3f, 0.75f).Normalize());
237  Sunlight->setPowerScale(7.0f);
238 
239  // Set scene ambient colour //
240  // TODO: Ogre samples also use this so maybe this works with PBR HLMS system
241  // WorldsScene->setAmbientLight(Ogre::ColourValue(0.3f, 0.5f, 0.7f) * 0.1f * 0.75f,
242  // Ogre::ColourValue(0.6f, 0.45f, 0.3f) * 0.065f * 0.75f,
243  // -Sunlight->getDirection() + Ogre::Vector3::UNIT_Y * 0.2f);
244  WorldsScene->setAmbientLight(Ogre::ColourValue(0.3f, 0.3f, 0.3f),
245  Ogre::ColourValue(0.2f, 0.2f, 0.2f), /*Ogre::Vector3(0.1f, 1.f, 0.085f),*/
246  -Sunlight->getDirection() + Ogre::Vector3::UNIT_Y * 0.2f);
247 }

◆ SetWorldPhysicsFrozenState()

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

Definition at line 1090 of file GameWorld.cpp.

1091 {
1092  // Skip if set to the same //
1093  if(frozen == WorldFrozen)
1094  return;
1095 
1096  WorldFrozen = frozen;
1097 
1098  // Send it to receiving players (if we are a server) //
1099  if(ReceivingPlayers.empty())
1100  return;
1101 
1102  // Should be safe to create the packet now and send it to all the connections //
1103  SendToAllPlayers(std::make_shared<ResponseWorldFrozen>(0, ID, WorldFrozen, TickNumber),
1105 }
DLLEXPORT void SendToAllPlayers(const std::shared_ptr< NetworkResponse > &response, RECEIVE_GUARANTEE guarantee) const
Sends a packet to all connected players.
Definition: GameWorld.cpp:503

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

386 {
387  return true;
388 }

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

553 {
554  if(InBackground && !TickWhileInBackground && GraphicalMode)
555  return;
556 
557  TickNumber = currenttick;
558 
559  // Apply queued packets //
561 
562  _HandleDelayedDelete();
563 
564  // All required nodes for entities are created //
567 
568  // Remove closed player connections //
569 
570  for(auto iter = ReceivingPlayers.begin(); iter != ReceivingPlayers.end();) {
571 
572  if(!(*iter)->GetConnection()->IsValidForSend()) {
573 
574  LOG_INFO("GameWorld: a player has diconnected, removing. TODO: release Sendable "
575  "memory");
576  // DEBUG_BREAK;
577  iter = ReceivingPlayers.erase(iter);
578  } else {
579 
580  ++iter;
581  }
582  }
583 
584  // Set this to disallow deleting while running physics as well
585  TickInProgress = true;
586 
587  // Simulate physics //
588  if(!WorldFrozen) {
589 
590  // TODO: a game type that is a client and server at the same time
591  // if(IsOnServer) {
592 
593  // _ApplyEntityUpdatePackets();
594  if(_PhysicalWorld)
595  _PhysicalWorld->SimulateWorld(TICKSPEED / 1000.f);
596 
597  // } else {
598 
599  // Simulate direct control //
600  // }
601  }
602 
603  _RunTickSystems();
604 
605  TickInProgress = false;
606 
607  // Sendable objects may need something to be done //
608 
609  if(NetworkSettings.IsAuthoritative) {
610 
611  // Notify new entities //
612  // DEBUG_BREAK;
613 
614  // Skip if not tick that will be stored //
615  // if(TickNumber % WORLD_OBJECT_UPDATE_CLIENTS_INTERVAL == 0){
616 
617  // _SendableSystem.Run(ComponentSendable.GetIndex(), *this);
618  // }
619 
620  } else {
621 
622  // TODO: direct control objects
623  // _ReceivedSystem.Run(ComponentReceived.GetIndex(), *this);
624  }
625 }
#define LOG_INFO(x)
Definition: Define.h:81
constexpr auto TICKSPEED
Number of milliseconds between engine and world ticks.
Definition: Define.h:21
virtual DLLEXPORT void HandleAddedAndDeleted()
Handles added entities and components.
Definition: GameWorld.cpp:627
DLLEXPORT void ApplyQueuedPackets()
Applies packets that were received out of order. And throws out any too old packets.
Definition: GameWorld.cpp:1389
bool IsAuthoritative
This is true on the server.
virtual DLLEXPORT void ClearAddedAndRemoved()
Clears the added components. Call after HandleAddedAndDeleted.
Definition: GameWorld.cpp:637
virtual DLLEXPORT void _RunTickSystems()
Called by Tick.
Definition: GameWorld.cpp:685
bool GraphicalMode
If false a graphical Ogre window hasn&#39;t been created and purely graphical stuff should be skipped...
Definition: GameWorld.h:614

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

1609 {
1610  // if called after release
1611  if(!pimpl) {
1612  return false;
1613  }
1614 
1615  const auto iter = pimpl->RegisteredScriptSystems.find(name);
1616  if(iter == pimpl->RegisteredScriptSystems.end()) {
1617  return false;
1618  }
1619 
1620  iter->second->Release();
1621  pimpl->RegisteredScriptSystems.erase(iter);
1622 
1623  return true;
1624 }

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


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