From 8fdc24f0b3fb287f5d4e1c7d1f85ad85d5ed2414 Mon Sep 17 00:00:00 2001 From: Daniel Karbach Date: Sun, 20 Sep 2015 17:07:56 +0200 Subject: [PATCH] give network players a model --- TODO | 1 - src/ai/Spawner.cpp | 32 ++++++++++++++++++++----- src/ai/Spawner.hpp | 8 +++++++ src/app/WorldState.cpp | 1 + src/model/composite.cpp | 28 ++++++++++++++++------ src/server/ClientConnection.hpp | 8 +++++++ src/server/Server.hpp | 6 +++++ src/server/ServerState.cpp | 2 ++ src/server/net.cpp | 42 +++++++++++++++++++++++++++++++-- 9 files changed, 112 insertions(+), 16 deletions(-) diff --git a/TODO b/TODO index 4ae41cc..93b880c 100644 --- 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 diff --git a/src/ai/Spawner.cpp b/src/ai/Spawner.cpp index eaaa1f8..2ea8a69 100644 --- a/src/ai/Spawner.cpp +++ b/src/ai/Spawner.cpp @@ -10,10 +10,14 @@ #include "../world/Entity.hpp" #include "../world/World.hpp" +#include + +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() % skeletons.Size()].Instantiate(e.GetModel()); + RandomSkeleton().Instantiate(e.GetModel()); e.AngularVelocity(rot); Controller *ctrl; if (random()) { ctrl = new RandomWalk(e, random.Next()); - 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() % skeletons_length) + skeletons_offset; + return skeletons[offset]; +} + } diff --git a/src/ai/Spawner.hpp b/src/ai/Spawner.hpp index d4c0a57..d0c6f97 100644 --- a/src/ai/Spawner.hpp +++ b/src/ai/Spawner.hpp @@ -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; + }; } diff --git a/src/app/WorldState.cpp b/src/app/WorldState.cpp index 5bb01bf..b4f8e64 100644 --- a/src/app/WorldState.cpp +++ b/src/app/WorldState.cpp @@ -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(); } diff --git a/src/model/composite.cpp b/src/model/composite.cpp index bb77fa5..f43b726 100644 --- a/src/model/composite.cpp +++ b/src/model/composite.cpp @@ -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 { diff --git a/src/server/ClientConnection.hpp b/src/server/ClientConnection.hpp index 2f03e67..99657de 100644 --- a/src/server/ClientConnection.hpp +++ b/src/server/ClientConnection.hpp @@ -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 spawns; unsigned int confirm_wait; diff --git a/src/server/Server.hpp b/src/server/Server.hpp index 8bbb778..bf23991 100644 --- a/src/server/Server.hpp +++ b/src/server/Server.hpp @@ -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 clients; World &world; + const CompositeModel *player_model; }; diff --git a/src/server/ServerState.cpp b/src/server/ServerState.cpp index 5545818..ebe675f 100644 --- a/src/server/ServerState.cpp +++ b/src/server/ServerState.cpp @@ -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(); diff --git a/src/server/net.cpp b/src/server/net.cpp index abe00a9..68880c7 100644 --- a/src/server/net.cpp +++ b/src/server/net.cpp @@ -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::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; +} + } } -- 2.39.2