]> git.tdb.fi Git - libs/game.git/commitdiff
Give IDs to entities replicated over the network
authorMikko Rasa <tdb@tdb.fi>
Sat, 17 Jun 2023 21:31:16 +0000 (00:31 +0300)
committerMikko Rasa <tdb@tdb.fi>
Sat, 17 Jun 2023 21:49:05 +0000 (00:49 +0300)
source/game/messages.h
source/game/protocol.cpp
source/game/replicator.cpp
source/game/replicator.h
source/game/zygote.cpp
source/game/zygote.h

index 8cdfb8adebe034b63cf8c778120d9a9b01fbbf57..860fc454f3120593b298e20d4e84db4f5064fd52 100644 (file)
@@ -38,6 +38,7 @@ struct InternString
 
 struct SpawnEntity
 {
+       std::uint32_t id;
        std::uint16_t type;
        std::uint16_t setup;
        LinAl::Vector<float, 3> position;
index 025731ec07be47581bf9fdd0ec0d14cc970e9a6c..9c1d1f6fa10d7b01433d5ab09cf610658b9cb45b 100644 (file)
@@ -24,7 +24,7 @@ StageProtocol::StageProtocol()
        add<Vector3f, float, float, float>(&Vector3f::x, &Vector3f::y, &Vector3f::z);
        add<Quaternion>(&Quaternion::a, &Quaternion::b, &Quaternion::c, &Quaternion::d);
 
-       add<SpawnEntity>(&SpawnEntity::type, &SpawnEntity::setup, &SpawnEntity::position, &SpawnEntity::rotation, &SpawnEntity::scale);
+       add<SpawnEntity>(&SpawnEntity::id, &SpawnEntity::type, &SpawnEntity::setup, &SpawnEntity::position, &SpawnEntity::rotation, &SpawnEntity::scale);
 }
 
 } // namespace Msp::Game
index dff5d482a0094be0660edcd1d53b3216ee59d90e..2962bc72ff18c574f593c724c98912ebc61b4413 100644 (file)
@@ -1,6 +1,7 @@
 #include "replicator.h"
 #include "entity.h"
 #include "networking.h"
+#include <msp/core/raii.h>
 #include "spawner.h"
 #include "transform.h"
 #include "zygote.h"
@@ -60,6 +61,11 @@ void Replicator::component_created(const Events::ComponentCreated &event)
                Handle<Transform> transform = entity->get_transform();
                auto i = lower_bound_member(entities, transform, &ReplicatedEntity::transform);
                entities.emplace(i, entity, transform, zygote);
+
+               if(networking.is_server())
+                       zygote->set_entity_id(next_entity_id++);
+               else if(received_entity_id!=Zygote::NO_ID)
+                       zygote->set_entity_id(received_entity_id);
        }
 }
 
@@ -70,6 +76,7 @@ void Replicator::send_spawn(const ReplicatedEntity &re, int target)
 
        const SpawnInfo &info = re.zygote->get_spawn_info();
        Messages::SpawnEntity message;
+       message.id = re.zygote->get_entity_id();
        message.type = networking.intern_string(info.type_name);
        message.setup = networking.intern_string(info.setup_name);
        const TransformValues &tf = re.transform->get_values();
@@ -93,6 +100,7 @@ void Replicator::receive(const Messages::SpawnEntity &message)
                return;  // TODO report the error somehow
 
        const string &setup_name = networking.get_string(message.setup);
+       SetForScope<uint32_t> set_id(received_entity_id, message.id);
        (*i)->spawn(type_name, setup_name, TransformValues(message.position, message.rotation, message.scale));
 }
 
index 6742593dbbcd219cd5d8540704f1abc78ed617a3..176ec66d4d95f82fc5216b8fbaa2ac90f8f6d7c3 100644 (file)
@@ -6,13 +6,13 @@
 #include "messages.h"
 #include "protocol.h"
 #include "system.h"
+#include "zygote.h"
 
 namespace Msp::Game {
 
 class Networking;
 class Spawner;
 class Transform;
-class Zygote;
 
 class MSPGAME_API Replicator: public System, private Net::PacketReceiver<Messages::SpawnEntity>
 {
@@ -31,6 +31,8 @@ private:
        std::vector<Spawner *> spawners;
        std::vector<ReplicatedEntity> entities;
        std::vector<unsigned> players;
+       std::uint32_t next_entity_id = 1;
+       std::uint32_t received_entity_id = Zygote::NO_ID;
 
 public:
        Replicator(Stage &, Networking &);
index c78e20334800d214b335128d9503700c8fed8e61..4185eedb1d494b2271c295d8b7ebca8c8d433e7a 100644 (file)
@@ -1,6 +1,8 @@
 #include "zygote.h"
 #include <msp/core/except.h>
 
+using namespace std;
+
 namespace Msp::Game {
 
 void Zygote::set_spawn_info(const SpawnInfo &s)
@@ -10,6 +12,13 @@ void Zygote::set_spawn_info(const SpawnInfo &s)
        spawn_info = &s;
 }
 
+void Zygote::set_entity_id(uint32_t id)
+{
+       if(entity_id!=NO_ID)
+               throw already_called("entity_id already set");
+       entity_id = id;
+}
+
 const SpawnInfo &Zygote::get_spawn_info() const
 {
        if(!spawn_info)
index 5f0f1e9e98449a98456cd8e55cd38a2d027e0139..2200aba5f361051ead87e92878a16cae8fb66fb7 100644 (file)
@@ -1,6 +1,7 @@
 #ifndef MSP_GAME_ZYGOTE_H_
 #define MSP_GAME_ZYGOTE_H_
 
+#include <limits>
 #include "component.h"
 
 namespace Msp::Game {
@@ -9,14 +10,20 @@ struct SpawnInfo;
 
 class Zygote: public Component
 {
+public:
+       static constexpr std::uint32_t NO_ID = std::numeric_limits<std::uint32_t>::max();
+
 private:
        const SpawnInfo *spawn_info = nullptr;
+       std::uint32_t entity_id = NO_ID;
 
 public:
        Zygote(Handle<Entity> e): Component(e) { }
 
        void set_spawn_info(const SpawnInfo &);
+       void set_entity_id(std::uint32_t);
        const SpawnInfo &get_spawn_info() const;
+       std::uint32_t get_entity_id() const { return entity_id; }
 };
 
 } // namespace Msp::Game