]> git.localhorst.tv Git - blank.git/commitdiff
give network players a model
authorDaniel Karbach <daniel.karbach@localhorst.tv>
Sun, 20 Sep 2015 15:07:56 +0000 (17:07 +0200)
committerDaniel Karbach <daniel.karbach@localhorst.tv>
Sun, 20 Sep 2015 15:07:56 +0000 (17:07 +0200)
TODO
src/ai/Spawner.cpp
src/ai/Spawner.hpp
src/app/WorldState.cpp
src/model/composite.cpp
src/server/ClientConnection.hpp
src/server/Server.hpp
src/server/ServerState.cpp
src/server/net.cpp

diff --git a/TODO b/TODO
index 4ae41cc5b0439b723a00ebe1f469f6f6692bb48f..93b880c8b0ea80f54821098d9eb26e72d19a2453 100644 (file)
--- a/TODO
+++ b/TODO
@@ -38,7 +38,6 @@ networking
        do some manual testing
        some more testing
        a little optimization
-       and give players an appearance as well ^^
 
 launcher ui
 
index eaaa1f8a03f30b4d1df690d6a1da0fffc0bcd954..2ea8a6904e2f80042b9e76656f2e66246348d385 100644 (file)
 #include "../world/Entity.hpp"
 #include "../world/World.hpp"
 
+#include <iostream>
+
+using namespace std;
+
 
 namespace blank {
 
-Spawner::Spawner(World &world, Skeletons &skeletons, std::uint64_t seed)
+Spawner::Spawner(World &world, Skeletons &skeletons, uint64_t seed)
 : world(world)
 , skeletons(skeletons)
 , controllers()
@@ -22,7 +26,9 @@ Spawner::Spawner(World &world, Skeletons &skeletons, std::uint64_t seed)
 , despawn_range(128 * 128)
 , spawn_distance(16 * 16)
 , max_entities(16)
-, chunk_range(4) {
+, chunk_range(4)
+, skeletons_offset(0)
+, skeletons_length(skeletons.Size()) {
        timer.Start();
 }
 
@@ -33,6 +39,15 @@ Spawner::~Spawner() {
 }
 
 
+void Spawner::LimitSkeletons(size_t begin, size_t end) {
+       if (begin >= skeletons.Size() || end > skeletons.Size() || begin >= end) {
+               cout << "warning, skeleton limit out of bounds or invalid range given" << endl;
+       } else {
+               skeletons_offset = begin;
+               skeletons_length = end - begin;
+       }
+}
+
 void Spawner::Update(int dt) {
        CheckDespawn();
        timer.Update(dt);
@@ -75,7 +90,7 @@ void Spawner::CheckDespawn() noexcept {
 }
 
 void Spawner::TrySpawn() {
-       if (controllers.size() >= max_entities) return;
+       if (controllers.size() >= max_entities || skeletons_length == 0) return;
 
        // select random player to punish
        auto &players = world.Players();
@@ -123,17 +138,22 @@ void Spawner::Spawn(Entity &reference, const glm::ivec3 &chunk, const glm::vec3
        e.Position(chunk, pos);
        e.Bounds({ { -0.5f, -0.5f, -0.5f }, { 0.5f, 0.5f, 0.5f } });
        e.WorldCollidable(true);
-       skeletons[random.Next<unsigned char>() % skeletons.Size()].Instantiate(e.GetModel());
+       RandomSkeleton().Instantiate(e.GetModel());
        e.AngularVelocity(rot);
        Controller *ctrl;
        if (random()) {
                ctrl = new RandomWalk(e, random.Next<std::uint64_t>());
-               e.Name("spawned walker");
+               e.Name("walker");
        } else {
                ctrl = new Chaser(world, e, reference);
-               e.Name("spawned chaser");
+               e.Name("chaser");
        }
        controllers.emplace_back(ctrl);
 }
 
+CompositeModel &Spawner::RandomSkeleton() noexcept {
+       std::size_t offset = (random.Next<std::size_t>() % skeletons_length) + skeletons_offset;
+       return skeletons[offset];
+}
+
 }
index d4c0a57f2c6b345d5749c04aa81ef31a22a0b8ca..d0c6f97c4695cbdf9db26202c8e8b8be4bf176fb 100644 (file)
@@ -10,6 +10,7 @@
 
 namespace blank {
 
+class CompositeModel;
 class Controller;
 class Entity;
 class Skeletons;
@@ -21,6 +22,8 @@ public:
        Spawner(World &, Skeletons &, std::uint64_t seed);
        ~Spawner();
 
+       void LimitSkeletons(std::size_t begin, std::size_t end);
+
        void Update(int dt);
 
 private:
@@ -28,6 +31,8 @@ private:
        void TrySpawn();
        void Spawn(Entity &reference, const glm::ivec3 &, const glm::vec3 &);
 
+       CompositeModel &RandomSkeleton() noexcept;
+
 private:
        World &world;
        Skeletons &skeletons;
@@ -41,6 +46,9 @@ private:
        unsigned int max_entities;
        int chunk_range;
 
+       std::size_t skeletons_offset;
+       std::size_t skeletons_length;
+
 };
 
 }
index 5bb01bfb2bb3fd37d5aa84d4acc2668996b6e858..b4f8e645480a63ed783e12776f77f104e246c893 100644 (file)
@@ -32,6 +32,7 @@ WorldState::WorldState(
        chunk_renderer.LoadTextures(env.loader, tex_index);
        chunk_renderer.FogDensity(wc.fog_density);
        skeletons.Load();
+       spawner.LimitSkeletons(0, skeletons.Size());
        // TODO: better solution for initializing HUD
        interface.SelectNext();
 }
index bb77fa5b3d573b31caed5dd1bf2a8ca1279fb1b9..f43b7264a57ef60463fc600997a7d71a7ff34ac5 100644 (file)
@@ -117,9 +117,9 @@ Skeletons::~Skeletons() {
 
 void Skeletons::LoadHeadless() {
        skeletons.clear();
-       skeletons.reserve(3);
+       skeletons.reserve(4);
        {
-               AABB bounds{{ -0.25f, -0.5f, -0.25f }, { 0.25f, 0.5f, 0.25f }};
+               AABB bounds{{ -0.5f, -0.5f, -0.5f }, { 0.5f, 0.5f, 0.5f }};
                skeletons.emplace_back(new CompositeModel);
                skeletons[0]->ID(1);
                skeletons[0]->Bounds(bounds);
@@ -131,20 +131,26 @@ void Skeletons::LoadHeadless() {
                skeletons[1]->Bounds(bounds);
        }
        {
-               AABB bounds{{ -0.5f, -0.5f, -0.5f }, { 0.5f, 0.5f, 0.5f }};
+               AABB bounds{{ -0.25f, -0.5f, -0.25f }, { 0.25f, 0.5f, 0.25f }};
                skeletons.emplace_back(new CompositeModel);
                skeletons[2]->ID(3);
                skeletons[2]->Bounds(bounds);
        }
+       {
+               AABB bounds{{ -0.25f, -0.5f, -0.35f }, { 0.25f, 0.5f, 0.35f }};
+               skeletons.emplace_back(new CompositeModel);
+               skeletons[3]->ID(4);
+               skeletons[3]->Bounds(bounds);
+       }
 }
 
 void Skeletons::Load() {
        LoadHeadless();
-       models.resize(3);
+       models.resize(4);
        EntityModel::Buffer buf;
        {
                CuboidShape shape(skeletons[0]->Bounds());
-               shape.Vertices(buf, 1.0f);
+               shape.Vertices(buf, 3.0f);
                buf.colors.resize(shape.VertexCount(), { 1.0f, 1.0f, 0.0f });
                models[0].Update(buf);
                skeletons[0]->SetNodeModel(&models[0]);
@@ -152,7 +158,7 @@ void Skeletons::Load() {
        {
                CuboidShape shape(skeletons[1]->Bounds());
                buf.Clear();
-               shape.Vertices(buf, 2.0f);
+               shape.Vertices(buf, 0.0f);
                buf.colors.resize(shape.VertexCount(), { 0.0f, 1.0f, 1.0f });
                models[1].Update(buf);
                skeletons[1]->SetNodeModel(&models[1]);
@@ -160,11 +166,19 @@ void Skeletons::Load() {
        {
                StairShape shape(skeletons[2]->Bounds(), { 0.4f, 0.4f });
                buf.Clear();
-               shape.Vertices(buf, 3.0f);
+               shape.Vertices(buf, 1.0f);
                buf.colors.resize(shape.VertexCount(), { 1.0f, 0.0f, 1.0f });
                models[2].Update(buf);
                skeletons[2]->SetNodeModel(&models[2]);
        }
+       {
+               CuboidShape shape(skeletons[3]->Bounds());
+               buf.Clear();
+               shape.Vertices(buf, 2.0f);
+               buf.colors.resize(shape.VertexCount(), { 1.0f, 0.25f, 0.5f });
+               models[3].Update(buf);
+               skeletons[3]->SetNodeModel(&models[3]);
+       }
 }
 
 CompositeModel *Skeletons::ByID(std::uint16_t id) noexcept {
index 2f03e67eca5bea2315b3b24602fa4f825e220ff7..99657de3642d262b70dbdcee5504e32efb66680b 100644 (file)
@@ -16,6 +16,9 @@
 
 
 namespace blank {
+
+class CompositeModel;
+
 namespace server {
 
 class Server;
@@ -52,6 +55,10 @@ public:
        ChunkIndex &PlayerChunks() noexcept { return *player.chunks; }
        const ChunkIndex &PlayerChunks() const noexcept { return *player.chunks; }
 
+       void SetPlayerModel(const CompositeModel &) noexcept;
+       bool HasPlayerModel() const noexcept;
+       const CompositeModel &GetPlayerModel() const noexcept;
+
 private:
        struct SpawnStatus {
                // the entity in question
@@ -89,6 +96,7 @@ private:
        Server &server;
        Connection conn;
        Player player;
+       const CompositeModel *player_model;
        std::list<SpawnStatus> spawns;
        unsigned int confirm_wait;
 
index 8bbb778a91b358a51cbb3d836cf64423fd4952a5..bf2399180111354191c2a922bfe6754c84464ac7 100644 (file)
@@ -7,6 +7,7 @@
 
 namespace blank {
 
+class CompositeModel;
 class World;
 
 namespace server {
@@ -33,6 +34,10 @@ public:
 
        World &GetWorld() noexcept { return world; }
 
+       void SetPlayerModel(const CompositeModel &) noexcept;
+       bool HasPlayerModel() const noexcept;
+       const CompositeModel &GetPlayerModel() const noexcept;
+
 private:
        void HandlePacket(const UDPpacket &);
 
@@ -44,6 +49,7 @@ private:
        std::list<ClientConnection> clients;
 
        World &world;
+       const CompositeModel *player_model;
 
 };
 
index 5545818e23f16b5536f60492867e9742408c2b72..ebe675f05b2908007b57626106b9a7e033ecf3fd 100644 (file)
@@ -29,6 +29,8 @@ ServerState::ServerState(
        TextureIndex tex_index;
        env.loader.LoadBlockTypes("default", block_types, tex_index);
        skeletons.LoadHeadless();
+       spawner.LimitSkeletons(1, skeletons.Size());
+       server.SetPlayerModel(skeletons[0]);
 
        loop_timer.Start();
 
index abe00a99fb72600449f9cecde40bbcfd7b22834f..68880c7d6fce87ab7b9f1db1f461b752e6bd24b5 100644 (file)
@@ -3,6 +3,7 @@
 #include "Server.hpp"
 
 #include "../app/init.hpp"
+#include "../model/CompositeModel.hpp"
 #include "../world/ChunkIndex.hpp"
 #include "../world/Entity.hpp"
 #include "../world/World.hpp"
@@ -172,6 +173,7 @@ ClientConnection::ClientConnection(Server &server, const IPaddress &addr)
 : server(server)
 , conn(addr)
 , player(nullptr, nullptr)
+, player_model(nullptr)
 , spawns()
 , confirm_wait(0)
 , entity_updates()
@@ -400,6 +402,9 @@ void ClientConnection::AttachPlayer(const Player &new_player) {
                        }
                }
        }
+       if (HasPlayerModel()) {
+               GetPlayerModel().Instantiate(player.entity->GetModel());
+       }
 
        cout << "player \"" << player.entity->Name() << "\" joined" << endl;
 }
@@ -415,6 +420,21 @@ void ClientConnection::DetachPlayer() {
        chunk_queue.clear();
 }
 
+void ClientConnection::SetPlayerModel(const CompositeModel &m) noexcept {
+       player_model = &m;
+       if (HasPlayer()) {
+               m.Instantiate(PlayerEntity().GetModel());
+       }
+}
+
+bool ClientConnection::HasPlayerModel() const noexcept {
+       return player_model;
+}
+
+const CompositeModel &ClientConnection::GetPlayerModel() const noexcept {
+       return *player_model;
+}
+
 void ClientConnection::OnPacketReceived(uint16_t seq) {
        if (transmitter.Waiting()) {
                transmitter.Ack(seq);
@@ -506,7 +526,8 @@ Server::Server(const Config &conf, World &world)
 : serv_sock(nullptr)
 , serv_pack{ -1, nullptr, 0 }
 , clients()
-, world(world) {
+, world(world)
+, player_model(nullptr) {
        serv_sock = SDLNet_UDP_Open(conf.port);
        if (!serv_sock) {
                throw NetError("SDLNet_UDP_Open");
@@ -556,12 +577,14 @@ ClientConnection &Server::GetClient(const IPaddress &addr) {
                }
        }
        clients.emplace_back(*this, addr);
+       if (HasPlayerModel()) {
+               clients.back().SetPlayerModel(GetPlayerModel());
+       }
        return clients.back();
 }
 
 void Server::Update(int dt) {
        for (list<ClientConnection>::iterator client(clients.begin()), end(clients.end()); client != end;) {
-               client->Update(dt);
                if (client->Disconnected()) {
                        client = clients.erase(client);
                } else {
@@ -570,5 +593,20 @@ void Server::Update(int dt) {
        }
 }
 
+void Server::SetPlayerModel(const CompositeModel &m) noexcept {
+       player_model = &m;
+       for (ClientConnection &client : clients) {
+               client.SetPlayerModel(m);
+       }
+}
+
+bool Server::HasPlayerModel() const noexcept {
+       return player_model;
+}
+
+const CompositeModel &Server::GetPlayerModel() const noexcept {
+       return *player_model;
+}
+
 }
 }