]> git.localhorst.tv Git - blank.git/blobdiff - src/world/World.cpp
give unique IDs to entities
[blank.git] / src / world / World.cpp
index 1d25e01ba2acd61289aac298a5cccbded2d35f68..6ad30ff0761b445a19dc6757203019b6b727d662 100644 (file)
 namespace blank {
 
 World::World(const BlockTypeRegistry &types, const Config &config, const WorldSave &save)
-: block_type(types)
+: config(config)
+, block_type(types)
 , generate(config.gen)
 , chunks(config.load, types, generate, save)
-, player()
+, players()
 , entities()
 , light_direction(config.light_direction)
 , fog_density(config.fog_density) {
        generate.Space(0);
        generate.Light(13);
        generate.Solids({ 1, 4, 7, 10 });
+}
+
+
+Entity *World::AddPlayer(const std::string &name) {
+       for (Entity *e : players) {
+               if (e->Name() == name) {
+                       return nullptr;
+               }
+       }
+       Entity &player = AddEntity();
+       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;
+}
 
-       player = &AddEntity();
-       player->Name("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;
 }
 
 
@@ -133,11 +208,6 @@ bool World::Intersection(const Entity &e, std::vector<WorldCollision> &col) {
 }
 
 
-Chunk &World::PlayerChunk() {
-       return chunks.ForceLoad(player->ChunkCoords());
-}
-
-
 namespace {
 
 std::vector<WorldCollision> col;
@@ -162,7 +232,8 @@ void World::Update(int dt) {
                        ++iter;
                }
        }
-       chunks.Rebase(player->ChunkCoords());
+       // TODO: make flexible
+       chunks.Rebase(players[0]->ChunkCoords());
        chunks.Update(dt);
 }
 
@@ -205,7 +276,7 @@ void World::Render(Viewport &viewport) {
        entity_prog.SetFogDensity(fog_density);
 
        for (Entity &entity : entities) {
-               entity.Render(entity.ChunkTransform(player->ChunkCoords()), entity_prog);
+               entity.Render(entity.ChunkTransform(players[0]->ChunkCoords()), entity_prog);
        }
 }