]> git.localhorst.tv Git - blank.git/commitdiff
give unique IDs to entities
authorDaniel Karbach <daniel.karbach@localhorst.tv>
Fri, 4 Sep 2015 22:27:15 +0000 (00:27 +0200)
committerDaniel Karbach <daniel.karbach@localhorst.tv>
Fri, 4 Sep 2015 22:27:15 +0000 (00:27 +0200)
please don't modify from outside the world :P

src/app/WorldState.cpp
src/client/InteractiveState.hpp
src/client/client.cpp
src/net/Packet.hpp
src/net/net.cpp
src/ui/Interface.hpp
src/ui/ui.cpp
src/world/Entity.cpp
src/world/Entity.hpp
src/world/World.cpp
src/world/World.hpp

index fabd332c6a725b5ea55ca9cf222b11aeaad27f7f..db8c9635c22a57a734d902fdd06ac8bd873dec17 100644 (file)
@@ -20,7 +20,7 @@ WorldState::WorldState(
 , world(block_types, wc, save)
 , chunk_renderer(world, wc.load.load_dist)
 , spawner(world, wc.gen.seed)
-, interface(ic, env, world)
+, interface(ic, env, world, *world.AddPlayer(ic.player_name))
 , preload(env, world.Loader(), chunk_renderer)
 , unload(env, world.Loader()) {
        TextureIndex tex_index;
index e679eb2990a5f47f285eee7eef3202776e71e83f..65c92d08ff33ab905421201621c575a1ce333250 100644 (file)
@@ -21,7 +21,7 @@ class InteractiveState
 : public State {
 
 public:
-       explicit InteractiveState(MasterState &);
+       explicit InteractiveState(MasterState &, std::uint32_t player_id);
 
        World &GetWorld() noexcept { return world; }
        Interface &GetInterface() noexcept { return interface; }
index 49ea4007d6a63524c392ad9953fc67812ef0dfb0..8dd575a0ac8bf03aa9c10068319b998f0de235f0 100644 (file)
@@ -38,13 +38,19 @@ void InitialState::Render(Viewport &viewport) {
 }
 
 
-InteractiveState::InteractiveState(MasterState &master)
+// TODO: this clutter is a giant mess
+InteractiveState::InteractiveState(MasterState &master, uint32_t player_id)
 : master(master)
 , block_types()
 , save(master.GetEnv().config.GetWorldPath(master.GetWorldConf().name, master.GetClientConf().host))
 , world(block_types, master.GetWorldConf(), save)
 , chunk_renderer(world, master.GetWorldConf().load.load_dist)
-, interface(master.GetInterfaceConf(), master.GetEnv(), world) {
+, interface(
+       master.GetInterfaceConf(),
+       master.GetEnv(),
+       world,
+       *world.AddPlayer(master.GetInterfaceConf().player_name, player_id)
+) {
        TextureIndex tex_index;
        master.GetEnv().loader.LoadBlockTypes("default", block_types, tex_index);
        chunk_renderer.LoadTextures(master.GetEnv().loader, tex_index);
@@ -175,7 +181,10 @@ void MasterState::On(const Packet::Join &pack) {
                // joining game
                std::cout << "joined game" << std::endl;
        }
-       state.reset(new InteractiveState(*this));
+
+       uint32_t player_id;
+       pack.ReadPlayerID(player_id);
+       state.reset(new InteractiveState(*this, player_id));
 
        pack.ReadPlayer(state->GetInterface().Player());
 
index fa35189056d3201ca982539913303e3c0a19ed92..af2f8727e3383669042365d2085c2f4c9a178083 100644 (file)
@@ -72,6 +72,7 @@ struct Packet {
                static constexpr std::size_t MAX_LEN = 100;
 
                void WritePlayer(const Entity &) noexcept;
+               void ReadPlayerID(std::uint32_t &) const noexcept;
                void ReadPlayer(Entity &) const noexcept;
                void WriteWorldName(const std::string &) noexcept;
                void ReadWorldName(std::string &) const noexcept;
index 852efd3a419f2075ebd4b2878ff17216ce61e36c..4d364124253d9e5d5e5668e77a6ec52ef29eb9b0 100644 (file)
@@ -282,8 +282,7 @@ void Packet::Login::ReadPlayerName(string &name) const noexcept {
 }
 
 void Packet::Join::WritePlayer(const Entity &player) noexcept {
-       // TODO: generate entity IDs
-       Write(uint32_t(1), 0);
+       Write(player.ID(), 0);
        Write(player.ChunkCoords(), 4);
        Write(player.Position(), 16);
        Write(player.Velocity(), 28);
@@ -291,15 +290,17 @@ void Packet::Join::WritePlayer(const Entity &player) noexcept {
        Write(player.AngularVelocity(), 56);
 }
 
+void Packet::Join::ReadPlayerID(uint32_t &id) const noexcept {
+       Read(id, 0);
+}
+
 void Packet::Join::ReadPlayer(Entity &player) const noexcept {
-       uint32_t id = 0;
        glm::ivec3 chunk_coords(0);
        glm::vec3 pos;
        glm::vec3 vel;
        glm::quat rot;
        glm::vec3 ang;
 
-       Read(id, 0);
        Read(chunk_coords, 4);
        Read(pos, 16);
        Read(vel, 28);
index aab8b156596e5cdf42ba691bb8cbe8a381c46dc4..7c9a91e33324520c458ff7cf773ea90d51360f56 100644 (file)
@@ -20,6 +20,7 @@
 
 namespace blank {
 
+class Entity;
 class Environment;
 class Viewport;
 class World;
@@ -40,7 +41,7 @@ public:
                bool visual_disabled = false;
        };
 
-       Interface(const Config &, Environment &, World &);
+       Interface(const Config &, Environment &, World &, Entity &);
 
        Entity &Player() noexcept { return ctrl.Controlled(); }
        const Entity &Player() const noexcept { return ctrl.Controlled(); }
index d8459e5190419f1c27e8f069d0da6efdae388d01..2ec4d883d3e6f963dc047e85694a5bfb9bcec00d 100644 (file)
@@ -102,11 +102,12 @@ void HUD::Render(Viewport &viewport) noexcept {
 Interface::Interface(
        const Config &config,
        Environment &env,
-       World &world)
+       World &world,
+       Entity &player)
 : env(env)
 , world(world)
 // let's assume this succeeds and hope for the best for now
-, ctrl(*world.AddPlayer(config.player_name))
+, ctrl(player)
 , hud(world.BlockTypes(), env.assets.small_ui_font)
 , aim{{ 0, 0, 0 }, { 0, 0, -1 }}
 , aim_world()
index f116153e640a467eec61b434860e118e1369e150..b9096031a3b2dd94558f9cfffcba1d4eff0cf5c2 100644 (file)
@@ -16,6 +16,7 @@ namespace blank {
 
 Entity::Entity() noexcept
 : model()
+, id(-1)
 , name("anonymous")
 , bounds()
 , velocity(0, 0, 0)
index a3811427332628250761bad32210bc64103ea9de..c0d9a0bd858159bbd969f225d15abf16f689fa92 100644 (file)
@@ -5,6 +5,7 @@
 #include "../model/CompositeInstance.hpp"
 #include "../model/geometry.hpp"
 
+#include <cstdint>
 #include <string>
 #include <glm/glm.hpp>
 #include <glm/gtc/quaternion.hpp>
@@ -23,6 +24,9 @@ public:
        CompositeInstance &GetModel() noexcept { return model; }
        const CompositeInstance &GetModel() const noexcept { return model; }
 
+       std::uint32_t ID() const noexcept { return id; }
+       void ID(std::uint32_t i) noexcept { id = i; }
+
        const std::string &Name() const noexcept { return name; }
        void Name(const std::string &n) { name = n; }
 
@@ -77,6 +81,7 @@ public:
 private:
        CompositeInstance model;
 
+       std::uint32_t id;
        std::string name;
 
        AABB bounds;
index 06ccb62cfea1f97f0341ac313c3848f9ee81e9a6..6ad30ff0761b445a19dc6757203019b6b727d662 100644 (file)
@@ -46,6 +46,70 @@ Entity *World::AddPlayer(const std::string &name) {
        return &player;
 }
 
+Entity *World::AddPlayer(const std::string &name, std::uint32_t id) {
+       for (Entity *e : players) {
+               if (e->Name() == name) {
+                       return nullptr;
+               }
+       }
+       Entity *player = AddEntity(id);
+       if (!player) {
+               return nullptr;
+       }
+       player->Name(name);
+       // TODO: load from save file here
+       player->Bounds({ { -0.5f, -0.5f, -0.5f }, { 0.5f, 0.5f, 0.5f } });
+       player->WorldCollidable(true);
+       player->Position(config.spawn);
+       players.push_back(player);
+       chunks.QueueSurrounding(player->ChunkCoords());
+       return player;
+}
+
+Entity &World::AddEntity() {
+       if (entities.empty()) {
+               entities.emplace_back();
+               entities.back().ID(1);
+               return entities.back();
+       }
+       if (entities.back().ID() < std::numeric_limits<std::uint32_t>::max()) {
+               std::uint32_t id = entities.back().ID() + 1;
+               entities.emplace_back();
+               entities.back().ID(id);
+               return entities.back();
+       }
+       std::uint32_t id = 1;
+       auto position = entities.begin();
+       auto end = entities.end();
+       while (position != end && position->ID() == id) {
+               ++id;
+               ++position;
+       }
+       auto entity = entities.emplace(position);
+       entity->ID(id);
+       return *entity;
+}
+
+Entity *World::AddEntity(std::uint32_t id) {
+       if (entities.empty() || entities.back().ID() < id) {
+               entities.emplace_back();
+               entities.back().ID(id);
+               return &entities.back();
+       }
+
+       auto position = entities.begin();
+       auto end = entities.end();
+       while (position != end && position->ID() < id) {
+               ++position;
+       }
+       if (position != end && position->ID() == id) {
+               return nullptr;
+       }
+       auto entity = entities.emplace(position);
+       entity->ID(id);
+       return &*entity;
+}
+
 
 namespace {
 
index 7d2c2926a1732ee4ea5f663cd112f3de6dd4335a..9ae0faa57217e629816a5e7f0744e4b2de88b0df 100644 (file)
@@ -5,6 +5,7 @@
 #include "Entity.hpp"
 #include "Generator.hpp"
 
+#include <cstdint>
 #include <list>
 #include <string>
 #include <vector>
@@ -70,7 +71,14 @@ public:
        /// add player with given name
        /// returns nullptr if the name is already taken
        Entity *AddPlayer(const std::string &name);
-       Entity &AddEntity() { entities.emplace_back(); return entities.back(); }
+       /// add player with given name and ID
+       /// returns nullptr if the name or ID is already taken
+       Entity *AddPlayer(const std::string &name, std::uint32_t id);
+       /// add an entity with an autogenerated ID
+       Entity &AddEntity();
+       /// add entity with given ID
+       /// returns nullptr if the ID is already taken
+       Entity *AddEntity(std::uint32_t id);
 
        const std::vector<Entity *> &Players() const noexcept { return players; }
        const std::list<Entity> &Entities() const noexcept { return entities; }