From 1e3fc1ae2d276838c19fafc1780163b83343d429 Mon Sep 17 00:00:00 2001 From: sippeangelo Date: Fri, 22 Jan 2016 10:16:35 +0100 Subject: [PATCH 01/24] Created EPlayerSpawned that gets published when a player spawns --- include/Game/Events/EPlayerSpawned.h | 19 +++++++++++++++++++ include/Game/Systems/PlayerSpawnSystem.h | 9 ++++++++- src/Game/Systems/PlayerSpawnSystem.cpp | 18 ++++++++++++++---- 3 files changed, 41 insertions(+), 5 deletions(-) create mode 100644 include/Game/Events/EPlayerSpawned.h diff --git a/include/Game/Events/EPlayerSpawned.h b/include/Game/Events/EPlayerSpawned.h new file mode 100644 index 00000000..a5700ed3 --- /dev/null +++ b/include/Game/Events/EPlayerSpawned.h @@ -0,0 +1,19 @@ +#ifndef EPlayerSpawned_h__ +#define EPlayerSpawned_h__ + +#include "Core/Event.h" +#include "Core/EntityWrapper.h" + +namespace Events +{ + +struct PlayerSpawned : Event +{ + int PlayerID; + EntityWrapper Player; + EntityWrapper Spawner; +}; + +} + +#endif \ No newline at end of file diff --git a/include/Game/Systems/PlayerSpawnSystem.h b/include/Game/Systems/PlayerSpawnSystem.h index 8ade03a6..69014f65 100644 --- a/include/Game/Systems/PlayerSpawnSystem.h +++ b/include/Game/Systems/PlayerSpawnSystem.h @@ -2,6 +2,7 @@ #include "Input/EInputCommand.h" #include "Systems/SpawnerSystem.h" #include "Events/ESpawnerSpawn.h" +#include "Events/EPlayerSpawned.h" class PlayerSpawnSystem : public ImpureSystem { @@ -11,8 +12,14 @@ public: virtual void Update(double dt) override; private: + struct SpawnRequest + { + int PlayerID; + ComponentInfo::EnumType Team; + }; + EventRelay m_OnInputCommand; bool OnInputCommand(const Events::InputCommand& e); - std::vector m_SpawnRequests; + std::vector m_SpawnRequests; }; \ No newline at end of file diff --git a/src/Game/Systems/PlayerSpawnSystem.cpp b/src/Game/Systems/PlayerSpawnSystem.cpp index 4224d46c..11be0486 100644 --- a/src/Game/Systems/PlayerSpawnSystem.cpp +++ b/src/Game/Systems/PlayerSpawnSystem.cpp @@ -13,7 +13,7 @@ void PlayerSpawnSystem::Update(double dt) return; } - for (auto& team : m_SpawnRequests) { + for (auto& req : m_SpawnRequests) { for (auto& cPlayerSpawn : *playerSpawns) { EntityWrapper spawner(m_World, cPlayerSpawn.EntityID); if (!spawner.HasComponent("Spawner")) { @@ -22,7 +22,7 @@ void PlayerSpawnSystem::Update(double dt) // If the spawner has a team affiliation, check it if (spawner.HasComponent("Team")) { - if ((int)spawner["Team"]["Team"] != team) { + if ((int)spawner["Team"]["Team"] != req.Team) { continue; } } @@ -30,7 +30,14 @@ void PlayerSpawnSystem::Update(double dt) // Spawn the player! EntityWrapper player = SpawnerSystem::Spawn(spawner); // Set the player team affiliation - player["Team"]["Team"] = team; + player["Team"]["Team"] = req.Team; + + // Publish a PlayerSpawned event + Events::PlayerSpawned e; + e.PlayerID = req.PlayerID; + e.Player = player; + e.Spawner = spawner; + m_EventBroker->Publish(e); } } m_SpawnRequests.clear(); @@ -43,7 +50,10 @@ bool PlayerSpawnSystem::OnInputCommand(const Events::InputCommand& e) } if (e.Value != 0) { - m_SpawnRequests.push_back((int)e.Value); + SpawnRequest req; + req.PlayerID = e.PlayerID; + req.Team = (ComponentInfo::EnumType)e.Value; + m_SpawnRequests.push_back(req); } return true; From 6cd073c3c8bee442df6a4b6e273d77a2d7f7f43e Mon Sep 17 00:00:00 2001 From: Jocke Date: Fri, 22 Jan 2016 10:32:54 +0100 Subject: [PATCH 02/24] Added network metrics logging and reactored code. --- include/Engine/Network/Client.h | 6 +-- include/Engine/Network/MessageType.h | 3 +- include/Engine/Network/Network.h | 13 ++++++ include/Engine/Network/NetworkData.h | 18 ++++++++ include/Engine/Network/Packet.h | 2 + include/Engine/Network/Server.h | 4 +- src/Engine/Network/Client.cpp | 57 +++++++++++++++----------- src/Engine/Network/Network.cpp | 61 ++++++++++++++++++++++++++++ src/Engine/Network/Packet.cpp | 1 + src/Engine/Network/Server.cpp | 56 ++++++++++++++++++------- 10 files changed, 176 insertions(+), 45 deletions(-) create mode 100644 include/Engine/Network/NetworkData.h create mode 100644 src/Engine/Network/Network.cpp diff --git a/include/Engine/Network/Client.h b/include/Engine/Network/Client.h index 96511baa..38db1e9b 100644 --- a/include/Engine/Network/Client.h +++ b/include/Engine/Network/Client.h @@ -61,21 +61,21 @@ private: SnapshotDefinitions m_NextSnapshot; double m_DurationOfPingTime; std::clock_t m_StartPingTime; + std::clock_t m_TimeSinceSentInputs; + unsigned int m_SendInputIntervalMs = 33; std::vector m_InputCommandBuffer; // Private member functions void readFromServer(); - int receive(char* data, size_t length); + int receive(char* data); void send(Packet& packet); void connect(); void disconnect(); - void ping(); void parseMessageType(Packet& packet); void updateFields(Packet& packet, const ComponentInfo& componentInfo, const EntityID& entityID, const std::string& componentType); void parseConnect(Packet& packet); void parsePlayerConnected(Packet& packet); void parsePing(); - void parseServerPing(); void InterpolateFields(Packet & packet, const ComponentInfo & componentInfo, const EntityID & entityID, const std::string & componentType); void parseSnapshot(Packet& packet); void identifyPacketLoss(); diff --git a/include/Engine/Network/MessageType.h b/include/Engine/Network/MessageType.h index f0026190..8468f2fc 100644 --- a/include/Engine/Network/MessageType.h +++ b/include/Engine/Network/MessageType.h @@ -7,8 +7,7 @@ enum class MessageType { Connect, Disconnect, - ClientPing, - ServerPing, + Ping, Message, Snapshot, OnInputCommand, diff --git a/include/Engine/Network/Network.h b/include/Engine/Network/Network.h index 1464a96f..7166eec6 100644 --- a/include/Engine/Network/Network.h +++ b/include/Engine/Network/Network.h @@ -1,9 +1,14 @@ #ifndef Network_h__ #define Network_h__ +#include + #include "Core/World.h" #include "Core/EventBroker.h" #include "Network/Packet.h" +#include "Network/NetworkData.h" +#include +#include #define MAXCONNECTIONS 8 #define INPUTSIZE 4097 @@ -15,6 +20,14 @@ public: virtual ~Network() { }; virtual void Start(World* m_world, EventBroker *eventBroker) = 0; virtual void Update() = 0; +protected: + // For Debug + bool isReadingData = false; + NetworkData m_NetworkData; + unsigned int m_SaveDataIntervalMs = 1000; + std::clock_t m_SaveDataTimer; + void saveToFile(); + void updateNetworkData(); }; #endif \ No newline at end of file diff --git a/include/Engine/Network/NetworkData.h b/include/Engine/Network/NetworkData.h new file mode 100644 index 00000000..87f7a215 --- /dev/null +++ b/include/Engine/Network/NetworkData.h @@ -0,0 +1,18 @@ +#ifndef NetworkData_h__ +#define NetworkData_h__ +#include + +struct NetworkData { + unsigned int TotalTime = 0; + unsigned int TotalDataReceived = 0; + unsigned int TotalDataSent = 0; + unsigned int AmountOfMessagesReceived = 0; + unsigned int AmountOfMessagesSent = 0; + // Interval based + unsigned int DataReceivedThisInterval = 0; + unsigned int DataSentThisInterval = 0; + // pair: first=reveived, second=send + std::vector> BandwidthBytes; +}; + +#endif diff --git a/include/Engine/Network/Packet.h b/include/Engine/Network/Packet.h index 2891bf87..d38ddf58 100644 --- a/include/Engine/Network/Packet.h +++ b/include/Engine/Network/Packet.h @@ -55,12 +55,14 @@ public: char* Data() { return m_Data; }; unsigned int DataReadSize() { return m_ReturnDataOffset; } unsigned int MaxSize() { return m_MaxPacketSize; } + unsigned int HeaderSize() { return m_HeaderSize; } private: char* m_Data; unsigned int m_ReturnDataOffset = 0; int m_Offset = 0; unsigned int m_MaxPacketSize = 512; + unsigned int m_HeaderSize = 0; void resizeData(); }; diff --git a/include/Engine/Network/Server.h b/include/Engine/Network/Server.h index 8aabceba..c4f1bf16 100644 --- a/include/Engine/Network/Server.h +++ b/include/Engine/Network/Server.h @@ -54,7 +54,7 @@ private: unsigned int m_PreviousPacketID = 0; // Private member functions - int receive(char* data, size_t length); + int receive(char* data); void readFromClients(); void send(Packet& packet, int playerID); void send(Packet& packet); @@ -69,7 +69,7 @@ private: void parseConnect(Packet& packet); void parseDisconnect(); void parseClientPing(); - void parseServerPing(); + void parsePing(); void identifyPacketLoss(); void createPlayer(); int GetPlayerIDFromEndpoint(boost::asio::ip::udp::endpoint endpoint); diff --git a/src/Engine/Network/Client.cpp b/src/Engine/Network/Client.cpp index 8eee335e..644b719b 100644 --- a/src/Engine/Network/Client.cpp +++ b/src/Engine/Network/Client.cpp @@ -7,6 +7,8 @@ Client::Client(ConfigFile* config) : m_Socket(m_IOService) { // Asumes root node is EntityID 0 insertIntoServerClientMaps(0, 0); + // Init timer + m_TimeSinceSentInputs = std::clock(); // Default is local host std::string address = config->Get("Networking.Address", "127.0.0.1"); int port = config->Get("Networking.Port", 13); @@ -37,19 +39,24 @@ void Client::Update() readFromServer(); if (m_IsConnected) { hasServerTimedOut(); + // Don't sent 1 input in 1 packet, bunch em up. + if (m_SendInputIntervalMs < (1000 * (std::clock() - m_TimeSinceSentInputs) / (double)CLOCKS_PER_SEC)) { + sendInputCommands(); + m_TimeSinceSentInputs = std::clock(); + } } + Network::Update(); } void Client::readFromServer() { while (m_Socket.available()) { - bytesRead = receive(readBuf, INPUTSIZE); + bytesRead = receive(readBuf); if (bytesRead > 0) { Packet packet(readBuf, bytesRead); parseMessageType(packet); } } - sendInputCommands(); } void Client::parseMessageType(Packet& packet) @@ -66,12 +73,9 @@ void Client::parseMessageType(Packet& packet) case MessageType::Connect: parseConnect(packet); break; - case MessageType::ClientPing: + case MessageType::Ping: parsePing(); break; - case MessageType::ServerPing: - parseServerPing(); - break; case MessageType::Message: break; case MessageType::Snapshot: @@ -99,11 +103,6 @@ void Client::parsePlayerConnected(Packet & packet) } void Client::parsePing() -{ - -} - -void Client::parseServerPing() { // Might miss connect message so set it here instead. m_IsConnected = true; @@ -112,7 +111,7 @@ void Client::parseServerPing() LOG_INFO("%i: response time with ctime(ms): %f", m_PacketID, m_DurationOfPingTime); m_StartPingTime = std::clock(); - Packet packet(MessageType::ServerPing, m_SendPacketID); + Packet packet(MessageType::Ping, m_SendPacketID); packet.WriteString("Ping recieved"); send(packet); } @@ -211,15 +210,20 @@ void Client::parseSnapshot(Packet& packet) } } -int Client::receive(char* data, size_t length) +int Client::receive(char* data) { boost::system::error_code error; int bytesReceived = m_Socket.receive_from(boost - ::asio::buffer((void*)data, length), + ::asio::buffer((void*)data, INPUTSIZE), m_ReceiverEndpoint, 0, error); - + // Network Debug data + if (isReadingData) { + m_NetworkData.TotalDataReceived += bytesReceived; + m_NetworkData.DataReceivedThisInterval += bytesReceived; + m_NetworkData.AmountOfMessagesReceived++; + } if (error) { //LOG_ERROR("receive: %s", error.message().c_str()); } @@ -232,6 +236,12 @@ void Client::send(Packet& packet) packet.Data(), packet.Size()), m_ReceiverEndpoint, 0); + // Network Debug data + if (isReadingData) { + m_NetworkData.TotalDataSent += packet.Size(); + m_NetworkData.DataSentThisInterval += packet.Size(); + m_NetworkData.AmountOfMessagesSent++; + } } void Client::connect() @@ -250,14 +260,6 @@ void Client::disconnect() send(packet); } -void Client::ping() -{ - //Packet packet(MessageType::Connect, m_SendPacketID); - //packet.WriteString("Ping"); - //m_StartPingTime = std::clock(); - //send(packet); -} - bool Client::OnInputCommand(const Events::InputCommand & e) { if (e.Command == "ConnectToServer") { // Connect for now @@ -275,6 +277,15 @@ bool Client::OnInputCommand(const Events::InputCommand & e) if (e.Value > 0) { becomePlayer(); } + } else if (e.Command == "LogNetworkBandwidth") { + if (e.Value > 0) { + // Save to file if we no longer want to read data. + if (isReadingData) { + saveToFile(); + } + isReadingData = !isReadingData; + m_SaveDataTimer = std::clock(); + } } else { m_InputCommandBuffer.push_back(e); //LOG_DEBUG("Client::OnInputCommand: Command is %s. Value is %f. PlayerID is %i.", e.Command.c_str(), e.Value, e.PlayerID); diff --git a/src/Engine/Network/Network.cpp b/src/Engine/Network/Network.cpp new file mode 100644 index 00000000..c9ed3637 --- /dev/null +++ b/src/Engine/Network/Network.cpp @@ -0,0 +1,61 @@ +#include "Network/Network.h" + +void Network::Update() +{ + updateNetworkData(); +} + +void Network::saveToFile() +{ + std::ofstream outfile; + time_t t = time(0); + // get time now + struct tm * now = localtime(&t); + // Get current time and date + std::string dateAndTime = "BandwidthData - " + std::to_string(now->tm_year + 1900) + '-' + + std::to_string(now->tm_mon + 1) + '-' + + std::to_string(now->tm_mday) + '_' + + std::to_string(now->tm_hour) + "h." + + std::to_string(now->tm_min) + "m." + + std::to_string(now->tm_sec) + 's'; + + outfile.open(dateAndTime + ".csv"); + outfile << "Total time," + std::to_string(m_NetworkData.TotalTime) + "\n"; + outfile << "Total data received," + std::to_string(m_NetworkData.TotalDataReceived) + "\n"; + outfile << "Total data sent," + std::to_string(m_NetworkData.TotalDataSent) + "\n"; + outfile << "Total messages received," + std::to_string(m_NetworkData.AmountOfMessagesReceived) + "\n"; + outfile << "Total messages sent," + std::to_string(m_NetworkData.AmountOfMessagesSent) + "\n"; + + float messagesReceivedPerSec = (float)m_NetworkData.AmountOfMessagesReceived / (m_NetworkData.TotalTime / 1000); + float messagesSentPerSec = (float)m_NetworkData.AmountOfMessagesSent / (m_NetworkData.TotalTime / 1000); + float dataReceivedPerSec = (float)m_NetworkData.TotalDataReceived / (m_NetworkData.TotalTime / 1000); + float dataSentPerSec = (float)m_NetworkData.TotalDataSent / (m_NetworkData.TotalTime / 1000); + outfile << "Avarage messages received / s: " + std::to_string(messagesReceivedPerSec) + "\n"; + outfile << "Avarage messages sents / s: " + std::to_string(messagesSentPerSec) + "\n"; + outfile << "Avarage data received B/s: " + std::to_string(dataReceivedPerSec) + "\n"; + outfile << "Avarage data sents B/s: " + std::to_string(dataSentPerSec) + "\n"; + + outfile << "time, avg receive B, avg send B\n"; + for (int i = 0; i < m_NetworkData.BandwidthBytes.size(); i++) { + outfile << std::to_string(i) + ","; + outfile << std::to_string(m_NetworkData.BandwidthBytes[i].first) + ","; + outfile << std::to_string(m_NetworkData.BandwidthBytes[i].second) + "\n"; + } + outfile.close(); + +} + +void Network::updateNetworkData() +{ + std::clock_t currentTime = std::clock(); + // Send snapshot + if (m_SaveDataIntervalMs < (1000 * (currentTime - m_SaveDataTimer) / (double)CLOCKS_PER_SEC)) { + // Set values + m_NetworkData.TotalTime += (1000 * (currentTime - m_SaveDataTimer) / (double)CLOCKS_PER_SEC); + m_NetworkData.BandwidthBytes.push_back(std::pair(m_NetworkData.DataReceivedThisInterval, m_NetworkData.DataSentThisInterval)); + // Reset interval stuff + m_SaveDataTimer = std::clock(); + m_NetworkData.DataSentThisInterval = 0; + m_NetworkData.DataReceivedThisInterval = 0; + } +} \ No newline at end of file diff --git a/src/Engine/Network/Packet.cpp b/src/Engine/Network/Packet.cpp index 6308a130..d40a1b32 100644 --- a/src/Engine/Network/Packet.cpp +++ b/src/Engine/Network/Packet.cpp @@ -39,6 +39,7 @@ void Packet::Init(MessageType type, unsigned int & packetID) Packet::WritePrimitive(messageType); Packet::WritePrimitive(packetID); packetID++; + m_HeaderSize = m_Offset; } void Packet::WriteString(const std::string& str) diff --git a/src/Engine/Network/Server.cpp b/src/Engine/Network/Server.cpp index 8a194c0e..a3fc4fe8 100644 --- a/src/Engine/Network/Server.cpp +++ b/src/Engine/Network/Server.cpp @@ -24,14 +24,17 @@ void Server::Update() { readFromClients(); m_EventBroker->Process(); -} + if (isReadingData) { + Network::Update(); + } +} void Server::readFromClients() { while (m_Socket.available()) { try { - bytesRead = receive(readBuffer, INPUTSIZE); + bytesRead = receive(readBuffer); Packet packet(readBuffer, bytesRead); parseMessageType(packet); } catch (const std::exception& err) { @@ -70,11 +73,8 @@ void Server::parseMessageType(Packet& packet) case MessageType::Connect: parseConnect(packet); break; - case MessageType::ClientPing: - //parseClientPing(); - break; - case MessageType::ServerPing: - parseServerPing(); + case MessageType::Ping: + parsePing(); break; case MessageType::Message: break; @@ -97,12 +97,18 @@ void Server::parseMessageType(Packet& packet) } } -int Server::receive(char * data, size_t length) +int Server::receive(char * data) { - length = m_Socket.receive_from( + unsigned int length = m_Socket.receive_from( boost::asio::buffer((void*)data - , length) + , INPUTSIZE) , m_ReceiverEndpoint, 0); + // Network Debug data + if (isReadingData) { + m_NetworkData.TotalDataReceived += length; + m_NetworkData.DataReceivedThisInterval += length; + m_NetworkData.AmountOfMessagesReceived++; + } return length; } @@ -112,6 +118,12 @@ void Server::send(Packet& packet, int userID) boost::asio::buffer(packet.Data(), packet.Size()), m_ConnectedUsers[userID].Endpoint, 0); + // Network Debug data + if (isReadingData) { + m_NetworkData.TotalDataSent += packet.Size(); + m_NetworkData.DataSentThisInterval += packet.Size(); + m_NetworkData.AmountOfMessagesSent++; + } } void Server::send(Packet & packet) @@ -122,6 +134,11 @@ void Server::send(Packet & packet) packet.Size()), m_ReceiverEndpoint, 0); + if (isReadingData) { + // Network Debug data + m_NetworkData.TotalDataSent += packet.Size(); + m_NetworkData.DataSentThisInterval += packet.Size(); + } } void Server::broadcast(Packet& packet) @@ -160,7 +177,9 @@ void Server::sendSnapshot() } } } - broadcast(packet); + if (packet.Size() > packet.HeaderSize() + componentInfo.Name.size()) { + broadcast(packet); + } } } @@ -174,7 +193,7 @@ void Server::sendPing() } } // Create ping message - Packet packet(MessageType::ServerPing); + Packet packet(MessageType::Ping); packet.WriteString("Ping from server"); // Time message m_StartPingTime = std::clock(); @@ -298,12 +317,12 @@ void Server::parseClientPing() return; } // Return ping - Packet packet(MessageType::ClientPing, m_PlayerDefinitions[playerID].PacketID); + Packet packet(MessageType::Ping, m_PlayerDefinitions[playerID].PacketID); packet.WriteString("Ping received"); send(packet); } -void Server::parseServerPing() +void Server::parsePing() { for (int i = 0; i < m_ConnectedUsers.size(); i++) { if (m_ConnectedUsers[i].Endpoint.address() == m_ReceiverEndpoint.address()) { @@ -356,7 +375,7 @@ void Server::createPlayer() } } LOG_WARNING("Server is full!"); - + } int Server::GetPlayerIDFromEndpoint(boost::asio::ip::udp::endpoint endpoint) @@ -373,5 +392,12 @@ int Server::GetPlayerIDFromEndpoint(boost::asio::ip::udp::endpoint endpoint) bool Server::OnInputCommand(const Events::InputCommand & e) { //LOG_DEBUG("Server::OnInputCommand: Command is %s. Value is %f. PlayerID is %i.", e.Command.c_str(), e.Value, e.PlayerID); + if (e.Command == "LogNetworkBandwidth" && e.Value > 0) { + if (isReadingData) { + saveToFile(); + } + isReadingData = !isReadingData; + m_SaveDataTimer = std::clock(); + } return true; } From fcc9d64e7a95e2aa420060fe1018327525cf9739 Mon Sep 17 00:00:00 2001 From: stiffly Date: Fri, 22 Jan 2016 10:58:10 +0100 Subject: [PATCH 03/24] Now publishes an EPlayerDisconnected event --- include/Engine/Network/EPlayerDisconnected.h | 18 ++++++++++++++++++ include/Engine/Network/Server.h | 1 + src/Engine/Network/Server.cpp | 5 +++++ 3 files changed, 24 insertions(+) create mode 100644 include/Engine/Network/EPlayerDisconnected.h diff --git a/include/Engine/Network/EPlayerDisconnected.h b/include/Engine/Network/EPlayerDisconnected.h new file mode 100644 index 00000000..278a7b1f --- /dev/null +++ b/include/Engine/Network/EPlayerDisconnected.h @@ -0,0 +1,18 @@ +#ifndef Events_PlayerDisconnected +#define Events_PlayerDisconnected + +#include "Core/EventBroker.h" +#include "Core/Entity.h" + +namespace Events +{ + +struct PlayerDisconnected : public Event +{ + unsigned int PlayerID; + EntityID Entity; +}; + +} + +#endif diff --git a/include/Engine/Network/Server.h b/include/Engine/Network/Server.h index c4f1bf16..cdbcd357 100644 --- a/include/Engine/Network/Server.h +++ b/include/Engine/Network/Server.h @@ -14,6 +14,7 @@ #include "../Network/Network.h" #include "Input/EInputCommand.h" #include "Core/EPlayerDamage.h" +#include "Network/EPlayerDisconnected.h" class Server : public Network { diff --git a/src/Engine/Network/Server.cpp b/src/Engine/Network/Server.cpp index a8c6ced9..4ccc6a7d 100644 --- a/src/Engine/Network/Server.cpp +++ b/src/Engine/Network/Server.cpp @@ -223,6 +223,11 @@ void Server::disconnect(int i) //broadcast("A player disconnected"); LOG_INFO("User %s disconnected/timed out", m_PlayerDefinitions[i].Name.c_str()); // Remove enteties and stuff (When we can remove entity, remove it and tell clients to remove the copy they have) + Events::PlayerDisconnected e; + e.Entity = m_PlayerDefinitions[i].EntityID; + e.PlayerID = i; + m_EventBroker->Publish(e); + m_PlayerDefinitions[i].Endpoint = boost::asio::ip::udp::endpoint(); m_PlayerDefinitions[i].EntityID = -1; m_PlayerDefinitions[i].Name = ""; From b1ea5429cefdfb2243bc8a6581b5bc80d37c0059 Mon Sep 17 00:00:00 2001 From: stiffly Date: Fri, 22 Jan 2016 11:53:04 +0100 Subject: [PATCH 04/24] Used config for a lot of things --- include/Engine/Network/Client.h | 4 +-- include/Engine/Network/Network.h | 7 +++-- include/Engine/Network/Server.h | 6 ++-- include/Game/Systems/InterpolationSystem.h | 9 ++++-- resources/DefaultConfig.ini | 5 +++ src/Engine/Network/Client.cpp | 3 +- src/Engine/Network/Network.cpp | 9 +++++- src/Engine/Network/Server.cpp | 19 +++++++----- src/Game/Systems/InterpolationSystem.cpp | 36 ++-------------------- 9 files changed, 46 insertions(+), 52 deletions(-) diff --git a/include/Engine/Network/Client.h b/include/Engine/Network/Client.h index 38db1e9b..61fa5ff0 100644 --- a/include/Engine/Network/Client.h +++ b/include/Engine/Network/Client.h @@ -57,12 +57,12 @@ private: std::unordered_map m_ClientIDToServerID; // Network logic - PlayerDefinition m_PlayerDefinitions[MAXCONNECTIONS]; + PlayerDefinition m_PlayerDefinitions[8]; SnapshotDefinitions m_NextSnapshot; double m_DurationOfPingTime; std::clock_t m_StartPingTime; std::clock_t m_TimeSinceSentInputs; - unsigned int m_SendInputIntervalMs = 33; + unsigned int m_SendInputIntervalMs; std::vector m_InputCommandBuffer; // Private member functions diff --git a/include/Engine/Network/Network.h b/include/Engine/Network/Network.h index 7166eec6..73cb01d3 100644 --- a/include/Engine/Network/Network.h +++ b/include/Engine/Network/Network.h @@ -7,12 +7,12 @@ #include "Core/EventBroker.h" #include "Network/Packet.h" #include "Network/NetworkData.h" +#include "Core/ResourceManager.h" +#include "Core/ConfigFile.h" #include #include -#define MAXCONNECTIONS 8 #define INPUTSIZE 4097 -#define TIMEOUTMS 15000 class Network { @@ -26,8 +26,11 @@ protected: NetworkData m_NetworkData; unsigned int m_SaveDataIntervalMs = 1000; std::clock_t m_SaveDataTimer; + unsigned int m_MaxConnections; + unsigned int m_TimeoutMs; void saveToFile(); void updateNetworkData(); + void initialize(); }; #endif \ No newline at end of file diff --git a/include/Engine/Network/Server.h b/include/Engine/Network/Server.h index cdbcd357..f1b5691a 100644 --- a/include/Engine/Network/Server.h +++ b/include/Engine/Network/Server.h @@ -30,7 +30,7 @@ private: boost::asio::ip::udp::socket m_Socket; // Sending messages to client logic - PlayerDefinition m_PlayerDefinitions[MAXCONNECTIONS]; + PlayerDefinition m_PlayerDefinitions[8]; // std::vector m_ConnectedUsers; char readBuffer[INPUTSIZE] = { 0 }; int bytesRead = 0; @@ -39,8 +39,8 @@ private: std::clock_t previousSnapshotMessage = std::clock(); std::clock_t timOutTimer = std::clock(); // How often we send messages (milliseconds) - int intervalMs = 1000; - int snapshotInterval = 50; + int pingIntervalMs; + int snapshotInterval; int checkTimeOutInterval = 100; //Timers diff --git a/include/Game/Systems/InterpolationSystem.h b/include/Game/Systems/InterpolationSystem.h index 4b05571b..0e137598 100644 --- a/include/Game/Systems/InterpolationSystem.h +++ b/include/Game/Systems/InterpolationSystem.h @@ -10,11 +10,11 @@ #include "Common.h" #include "Core/System.h" #include "Core/EventBroker.h" +#include "Core/ResourceManager.h" +#include "Core/ConfigFile.h" #include "Network/EInterpolate.h" -#define SNAPSHOTINTERVAL 0.05f - class InterpolationSystem : public PureSystem { struct Transform @@ -29,6 +29,8 @@ public: : System(world, eventBroker) , PureSystem("Transform") { + ConfigFile* config = ResourceManager::Load("Config.ini"); + m_SnapshotInterval = config->Get("Networking.SnapshotInterval", 0.05); EVENT_SUBSCRIBE_MEMBER(m_EInterpolate, &InterpolationSystem::OnInterpolate); } ~InterpolationSystem() { } @@ -42,9 +44,10 @@ private: T vectorInterpolation(T prev, T next, double currentTime) { T difference = next - prev; - T vector = (difference / SNAPSHOTINTERVAL) * static_cast(currentTime); + T vector = (difference / m_SnapshotInterval) * static_cast(currentTime); return vector; } + float m_SnapshotInterval; EventRelay m_EInterpolate; bool InterpolationSystem::OnInterpolate(const Events::Interpolate& e); diff --git a/resources/DefaultConfig.ini b/resources/DefaultConfig.ini index fb490ec8..53e86699 100644 --- a/resources/DefaultConfig.ini +++ b/resources/DefaultConfig.ini @@ -19,6 +19,11 @@ IsServer=false Name=Bob Address=127.0.0.1 Port=13 +MaxConnections=8 +SnapshotInterval=0.05 +SendInputIntervalMs=33 +PingIntervalMs= 1000 +TimeoutMs=15000 [Multithreading] ResourceLoading=true diff --git a/src/Engine/Network/Client.cpp b/src/Engine/Network/Client.cpp index 4dc4c93e..1fd823cf 100644 --- a/src/Engine/Network/Client.cpp +++ b/src/Engine/Network/Client.cpp @@ -15,6 +15,7 @@ Client::Client(ConfigFile* config) : m_Socket(m_IOService) m_ReceiverEndpoint = udp::endpoint(boost::asio::ip::address::from_string(address), port); // Set up network stream m_PlayerName = config->Get("Networking.Name", "Raptorcopter"); + m_SendInputIntervalMs = config->Get("Networking.SendInputIntervalMs", 33); } Client::~Client() @@ -316,7 +317,7 @@ bool Client::hasServerTimedOut() { // Time in ms float timeSincePing = 1000 * (std::clock() - m_StartPingTime) / static_cast(CLOCKS_PER_SEC); - if (timeSincePing > TIMEOUTMS) { + if (timeSincePing > m_TimeoutMs) { // Clear everything and go to menu. LOG_INFO("Server has timed out, returning to menu, Beep Boop."); m_IsConnected = false; diff --git a/src/Engine/Network/Network.cpp b/src/Engine/Network/Network.cpp index c9ed3637..f4dcd1a2 100644 --- a/src/Engine/Network/Network.cpp +++ b/src/Engine/Network/Network.cpp @@ -58,4 +58,11 @@ void Network::updateNetworkData() m_NetworkData.DataSentThisInterval = 0; m_NetworkData.DataReceivedThisInterval = 0; } -} \ No newline at end of file +} + +void Network::initialize() +{ + ConfigFile* config = ResourceManager::Load("Config.ini"); + m_MaxConnections = config->Get("Networking.MaxConnections", 8); + m_TimeoutMs = config->Get("Networking.TimeoutMs", 20000); +} diff --git a/src/Engine/Network/Server.cpp b/src/Engine/Network/Server.cpp index 4ccc6a7d..07c43829 100644 --- a/src/Engine/Network/Server.cpp +++ b/src/Engine/Network/Server.cpp @@ -1,7 +1,12 @@ #include "Network/Server.h" Server::Server() : m_Socket(m_IOService, boost::asio::ip::udp::endpoint(boost::asio::ip::udp::v4(), 13)) -{ } +{ + ConfigFile* config = ResourceManager::Load("Config.ini"); + snapshotInterval = 1000 * config->Get("Networking.SnapshotInterval", 0.05); + pingIntervalMs = config->Get("Networking.PingIntervalMs", 1000); + +} Server::~Server() { @@ -14,7 +19,7 @@ void Server::Start(World* world, EventBroker* eventBroker) m_EventBroker = eventBroker; // Subscribe to events EVENT_SUBSCRIBE_MEMBER(m_EInputCommand, &Server::OnInputCommand); - for (size_t i = 0; i < MAXCONNECTIONS; i++) { + for (size_t i = 0; i < m_MaxConnections; i++) { m_PlayerDefinitions[i].StopTime = std::clock(); } LOG_INFO("I am Server. BIP BOP\n"); @@ -49,7 +54,7 @@ void Server::readFromClients() } // Send pings each - if (intervalMs < (1000 * (currentTime - previousePingMessage) / (double)CLOCKS_PER_SEC)) { + if (pingIntervalMs < (1000 * (currentTime - previousePingMessage) / (double)CLOCKS_PER_SEC)) { sendPing(); previousePingMessage = currentTime; } @@ -210,7 +215,7 @@ void Server::checkForTimeOuts() if (m_ConnectedUsers[i].Endpoint.address() != boost::asio::ip::address()) { int stopPing = 1000 * m_ConnectedUsers[i].StopTime / static_cast(CLOCKS_PER_SEC); - if (startPing > stopPing + TIMEOUTMS) { + if (startPing > stopPing + m_TimeoutMs) { LOG_INFO("User %i timed out!", i); disconnect(i); } @@ -239,7 +244,7 @@ void Server::parseOnInputCommand(Packet& packet) { int playerID = -1; // Check which player it was who sent the message - for (int i = 0; i < MAXCONNECTIONS; i++) { + for (int i = 0; i < m_MaxConnections; i++) { // if the player is connected set playerID to the correct PlayerID if (m_PlayerDefinitions[i].Endpoint.address() == m_ReceiverEndpoint.address() && m_PlayerDefinitions[i].Endpoint.port() == m_ReceiverEndpoint.port()) { @@ -364,7 +369,7 @@ void Server::createPlayer() LOG_WARNING("Not a recognized user!"); return; } - for (int playerIndex = 0; playerIndex < MAXCONNECTIONS; playerIndex++) { + for (int playerIndex = 0; playerIndex < m_MaxConnections; playerIndex++) { if (m_PlayerDefinitions[playerIndex].Endpoint.address() == boost::asio::ip::address()) { m_PlayerDefinitions[playerIndex] = m_ConnectedUsers[userIndex]; EntityID entityID = m_World->CreateEntity(); @@ -384,7 +389,7 @@ void Server::createPlayer() int Server::GetPlayerIDFromEndpoint(boost::asio::ip::udp::endpoint endpoint) { - for (int i = 0; i < MAXCONNECTIONS; i++) { + for (int i = 0; i < m_MaxConnections; i++) { if (m_PlayerDefinitions[i].Endpoint.address() == endpoint.address() && m_PlayerDefinitions[i].Endpoint.port() == endpoint.port()) { return i; diff --git a/src/Game/Systems/InterpolationSystem.cpp b/src/Game/Systems/InterpolationSystem.cpp index 75f68678..be2c9a4f 100644 --- a/src/Game/Systems/InterpolationSystem.cpp +++ b/src/Game/Systems/InterpolationSystem.cpp @@ -1,35 +1,15 @@ #include "Systems/InterpolationSystem.h" -//void InterpolationSystem::UpdateComponent(World * world, ComponentWrapper & transform, double dt) -//{ -// if (m_InterpolationPoints[transform.EntityID].size() > 0) { -// Transform& sTransform = m_InterpolationPoints[transform.EntityID].front(); -// sTransform.interpolationTime += dt; -// if (sTransform.interpolationTime > 0.05) { -// double time = std::fmod(sTransform.interpolationTime, 0.05f); -// m_InterpolationPoints[transform.EntityID].pop(); -// if (m_InterpolationPoints[transform.EntityID].size() <= 0) { -// return; -// } -// sTransform = m_InterpolationPoints[transform.EntityID].front(); -// sTransform.interpolationTime = time; -// } -// glm::vec3 nextPosition = sTransform.Position; -// glm::vec3 currentPosition = static_cast(transform["Position"]); -// transform["Position"] = vectorInterpolation(currentPosition, nextPosition, sTransform.interpolationTime); -// } -//} - void InterpolationSystem::UpdateComponent(EntityWrapper& entity, ComponentWrapper& transform, double dt) { if (m_NextTransform.find(transform.EntityID) != m_NextTransform.end()) { // Exists in map m_NextTransform[transform.EntityID].interpolationTime += dt; Transform sTransform = m_NextTransform[transform.EntityID]; double time = sTransform.interpolationTime; - if (time > SNAPSHOTINTERVAL) { + if (time > m_SnapshotInterval) { if (m_LastReceivedTransform.find(transform.EntityID) != m_LastReceivedTransform.end()) { m_NextTransform[transform.EntityID] = m_LastReceivedTransform[transform.EntityID]; - m_NextTransform[transform.EntityID].interpolationTime = time - SNAPSHOTINTERVAL; + m_NextTransform[transform.EntityID].interpolationTime = time - m_SnapshotInterval; sTransform = m_NextTransform[transform.EntityID]; m_LastReceivedTransform.erase(transform.EntityID); } else { @@ -44,7 +24,7 @@ void InterpolationSystem::UpdateComponent(EntityWrapper& entity, ComponentWrappe // Orientation glm::quat nextOrientation = sTransform.Orientation; glm::quat currentOrientation = glm::quat(static_cast(transform["Orientation"])); - (glm::vec3&)transform["Orientation"] = glm::eulerAngles(glm::slerp(currentOrientation, nextOrientation, sTransform.interpolationTime / SNAPSHOTINTERVAL)); + (glm::vec3&)transform["Orientation"] = glm::eulerAngles(glm::slerp(currentOrientation, nextOrientation, sTransform.interpolationTime / m_SnapshotInterval)); // Scale glm::vec3 nextScale = sTransform.Scale; glm::vec3 currentScale = static_cast(transform["Scale"]); @@ -72,15 +52,5 @@ bool InterpolationSystem::OnInterpolate(const Events::Interpolate & e) } else { // Did not m_NextTransform[e.Entity] = transform; } - // Check if queue already exists - //if (m_InterpolationPoints.find(e.Entity) != m_InterpolationPoints.end()) { // Did exist, push to queue - // m_InterpolationPoints[e.Entity].push(transform); - //} - - //else { // Did not exist, create queue - // std::queue transformQueue; - // transformQueue.push(transform); - // m_InterpolationPoints[e.Entity] = transformQueue; - //} return false; } From 08fcdb382b3dc2ebcf05692c7fa788acc05c6e3d Mon Sep 17 00:00:00 2001 From: stiffly Date: Fri, 22 Jan 2016 11:53:04 +0100 Subject: [PATCH 05/24] Used config for a lot of things --- include/Engine/Network/Client.h | 4 +-- include/Engine/Network/Network.h | 7 +++-- include/Engine/Network/Server.h | 6 ++-- include/Game/Systems/InterpolationSystem.h | 9 ++++-- resources/DefaultConfig.ini | 5 +++ src/Engine/Network/Client.cpp | 6 +++- src/Engine/Network/Network.cpp | 9 +++++- src/Engine/Network/Server.cpp | 20 +++++++----- src/Game/Systems/InterpolationSystem.cpp | 36 ++-------------------- 9 files changed, 50 insertions(+), 52 deletions(-) diff --git a/include/Engine/Network/Client.h b/include/Engine/Network/Client.h index 38db1e9b..61fa5ff0 100644 --- a/include/Engine/Network/Client.h +++ b/include/Engine/Network/Client.h @@ -57,12 +57,12 @@ private: std::unordered_map m_ClientIDToServerID; // Network logic - PlayerDefinition m_PlayerDefinitions[MAXCONNECTIONS]; + PlayerDefinition m_PlayerDefinitions[8]; SnapshotDefinitions m_NextSnapshot; double m_DurationOfPingTime; std::clock_t m_StartPingTime; std::clock_t m_TimeSinceSentInputs; - unsigned int m_SendInputIntervalMs = 33; + unsigned int m_SendInputIntervalMs; std::vector m_InputCommandBuffer; // Private member functions diff --git a/include/Engine/Network/Network.h b/include/Engine/Network/Network.h index 7166eec6..73cb01d3 100644 --- a/include/Engine/Network/Network.h +++ b/include/Engine/Network/Network.h @@ -7,12 +7,12 @@ #include "Core/EventBroker.h" #include "Network/Packet.h" #include "Network/NetworkData.h" +#include "Core/ResourceManager.h" +#include "Core/ConfigFile.h" #include #include -#define MAXCONNECTIONS 8 #define INPUTSIZE 4097 -#define TIMEOUTMS 15000 class Network { @@ -26,8 +26,11 @@ protected: NetworkData m_NetworkData; unsigned int m_SaveDataIntervalMs = 1000; std::clock_t m_SaveDataTimer; + unsigned int m_MaxConnections; + unsigned int m_TimeoutMs; void saveToFile(); void updateNetworkData(); + void initialize(); }; #endif \ No newline at end of file diff --git a/include/Engine/Network/Server.h b/include/Engine/Network/Server.h index cdbcd357..f1b5691a 100644 --- a/include/Engine/Network/Server.h +++ b/include/Engine/Network/Server.h @@ -30,7 +30,7 @@ private: boost::asio::ip::udp::socket m_Socket; // Sending messages to client logic - PlayerDefinition m_PlayerDefinitions[MAXCONNECTIONS]; + PlayerDefinition m_PlayerDefinitions[8]; // std::vector m_ConnectedUsers; char readBuffer[INPUTSIZE] = { 0 }; int bytesRead = 0; @@ -39,8 +39,8 @@ private: std::clock_t previousSnapshotMessage = std::clock(); std::clock_t timOutTimer = std::clock(); // How often we send messages (milliseconds) - int intervalMs = 1000; - int snapshotInterval = 50; + int pingIntervalMs; + int snapshotInterval; int checkTimeOutInterval = 100; //Timers diff --git a/include/Game/Systems/InterpolationSystem.h b/include/Game/Systems/InterpolationSystem.h index 4b05571b..0e137598 100644 --- a/include/Game/Systems/InterpolationSystem.h +++ b/include/Game/Systems/InterpolationSystem.h @@ -10,11 +10,11 @@ #include "Common.h" #include "Core/System.h" #include "Core/EventBroker.h" +#include "Core/ResourceManager.h" +#include "Core/ConfigFile.h" #include "Network/EInterpolate.h" -#define SNAPSHOTINTERVAL 0.05f - class InterpolationSystem : public PureSystem { struct Transform @@ -29,6 +29,8 @@ public: : System(world, eventBroker) , PureSystem("Transform") { + ConfigFile* config = ResourceManager::Load("Config.ini"); + m_SnapshotInterval = config->Get("Networking.SnapshotInterval", 0.05); EVENT_SUBSCRIBE_MEMBER(m_EInterpolate, &InterpolationSystem::OnInterpolate); } ~InterpolationSystem() { } @@ -42,9 +44,10 @@ private: T vectorInterpolation(T prev, T next, double currentTime) { T difference = next - prev; - T vector = (difference / SNAPSHOTINTERVAL) * static_cast(currentTime); + T vector = (difference / m_SnapshotInterval) * static_cast(currentTime); return vector; } + float m_SnapshotInterval; EventRelay m_EInterpolate; bool InterpolationSystem::OnInterpolate(const Events::Interpolate& e); diff --git a/resources/DefaultConfig.ini b/resources/DefaultConfig.ini index fb490ec8..53e86699 100644 --- a/resources/DefaultConfig.ini +++ b/resources/DefaultConfig.ini @@ -19,6 +19,11 @@ IsServer=false Name=Bob Address=127.0.0.1 Port=13 +MaxConnections=8 +SnapshotInterval=0.05 +SendInputIntervalMs=33 +PingIntervalMs= 1000 +TimeoutMs=15000 [Multithreading] ResourceLoading=true diff --git a/src/Engine/Network/Client.cpp b/src/Engine/Network/Client.cpp index 4dc4c93e..fe552fa2 100644 --- a/src/Engine/Network/Client.cpp +++ b/src/Engine/Network/Client.cpp @@ -5,6 +5,8 @@ using namespace boost::asio::ip; Client::Client(ConfigFile* config) : m_Socket(m_IOService) { + Network::initialize(); + // Asumes root node is EntityID 0 insertIntoServerClientMaps(0, 0); // Init timer @@ -15,6 +17,8 @@ Client::Client(ConfigFile* config) : m_Socket(m_IOService) m_ReceiverEndpoint = udp::endpoint(boost::asio::ip::address::from_string(address), port); // Set up network stream m_PlayerName = config->Get("Networking.Name", "Raptorcopter"); + m_SendInputIntervalMs = config->Get("Networking.SendInputIntervalMs", 33); + } Client::~Client() @@ -316,7 +320,7 @@ bool Client::hasServerTimedOut() { // Time in ms float timeSincePing = 1000 * (std::clock() - m_StartPingTime) / static_cast(CLOCKS_PER_SEC); - if (timeSincePing > TIMEOUTMS) { + if (timeSincePing > m_TimeoutMs) { // Clear everything and go to menu. LOG_INFO("Server has timed out, returning to menu, Beep Boop."); m_IsConnected = false; diff --git a/src/Engine/Network/Network.cpp b/src/Engine/Network/Network.cpp index c9ed3637..f4dcd1a2 100644 --- a/src/Engine/Network/Network.cpp +++ b/src/Engine/Network/Network.cpp @@ -58,4 +58,11 @@ void Network::updateNetworkData() m_NetworkData.DataSentThisInterval = 0; m_NetworkData.DataReceivedThisInterval = 0; } -} \ No newline at end of file +} + +void Network::initialize() +{ + ConfigFile* config = ResourceManager::Load("Config.ini"); + m_MaxConnections = config->Get("Networking.MaxConnections", 8); + m_TimeoutMs = config->Get("Networking.TimeoutMs", 20000); +} diff --git a/src/Engine/Network/Server.cpp b/src/Engine/Network/Server.cpp index 4ccc6a7d..719ca16f 100644 --- a/src/Engine/Network/Server.cpp +++ b/src/Engine/Network/Server.cpp @@ -1,7 +1,13 @@ #include "Network/Server.h" Server::Server() : m_Socket(m_IOService, boost::asio::ip::udp::endpoint(boost::asio::ip::udp::v4(), 13)) -{ } +{ + Network::initialize(); + ConfigFile* config = ResourceManager::Load("Config.ini"); + snapshotInterval = 1000 * config->Get("Networking.SnapshotInterval", 0.05); + pingIntervalMs = config->Get("Networking.PingIntervalMs", 1000); + +} Server::~Server() { @@ -14,7 +20,7 @@ void Server::Start(World* world, EventBroker* eventBroker) m_EventBroker = eventBroker; // Subscribe to events EVENT_SUBSCRIBE_MEMBER(m_EInputCommand, &Server::OnInputCommand); - for (size_t i = 0; i < MAXCONNECTIONS; i++) { + for (size_t i = 0; i < m_MaxConnections; i++) { m_PlayerDefinitions[i].StopTime = std::clock(); } LOG_INFO("I am Server. BIP BOP\n"); @@ -49,7 +55,7 @@ void Server::readFromClients() } // Send pings each - if (intervalMs < (1000 * (currentTime - previousePingMessage) / (double)CLOCKS_PER_SEC)) { + if (pingIntervalMs < (1000 * (currentTime - previousePingMessage) / (double)CLOCKS_PER_SEC)) { sendPing(); previousePingMessage = currentTime; } @@ -210,7 +216,7 @@ void Server::checkForTimeOuts() if (m_ConnectedUsers[i].Endpoint.address() != boost::asio::ip::address()) { int stopPing = 1000 * m_ConnectedUsers[i].StopTime / static_cast(CLOCKS_PER_SEC); - if (startPing > stopPing + TIMEOUTMS) { + if (startPing > stopPing + m_TimeoutMs) { LOG_INFO("User %i timed out!", i); disconnect(i); } @@ -239,7 +245,7 @@ void Server::parseOnInputCommand(Packet& packet) { int playerID = -1; // Check which player it was who sent the message - for (int i = 0; i < MAXCONNECTIONS; i++) { + for (int i = 0; i < m_MaxConnections; i++) { // if the player is connected set playerID to the correct PlayerID if (m_PlayerDefinitions[i].Endpoint.address() == m_ReceiverEndpoint.address() && m_PlayerDefinitions[i].Endpoint.port() == m_ReceiverEndpoint.port()) { @@ -364,7 +370,7 @@ void Server::createPlayer() LOG_WARNING("Not a recognized user!"); return; } - for (int playerIndex = 0; playerIndex < MAXCONNECTIONS; playerIndex++) { + for (int playerIndex = 0; playerIndex < m_MaxConnections; playerIndex++) { if (m_PlayerDefinitions[playerIndex].Endpoint.address() == boost::asio::ip::address()) { m_PlayerDefinitions[playerIndex] = m_ConnectedUsers[userIndex]; EntityID entityID = m_World->CreateEntity(); @@ -384,7 +390,7 @@ void Server::createPlayer() int Server::GetPlayerIDFromEndpoint(boost::asio::ip::udp::endpoint endpoint) { - for (int i = 0; i < MAXCONNECTIONS; i++) { + for (int i = 0; i < m_MaxConnections; i++) { if (m_PlayerDefinitions[i].Endpoint.address() == endpoint.address() && m_PlayerDefinitions[i].Endpoint.port() == endpoint.port()) { return i; diff --git a/src/Game/Systems/InterpolationSystem.cpp b/src/Game/Systems/InterpolationSystem.cpp index 75f68678..be2c9a4f 100644 --- a/src/Game/Systems/InterpolationSystem.cpp +++ b/src/Game/Systems/InterpolationSystem.cpp @@ -1,35 +1,15 @@ #include "Systems/InterpolationSystem.h" -//void InterpolationSystem::UpdateComponent(World * world, ComponentWrapper & transform, double dt) -//{ -// if (m_InterpolationPoints[transform.EntityID].size() > 0) { -// Transform& sTransform = m_InterpolationPoints[transform.EntityID].front(); -// sTransform.interpolationTime += dt; -// if (sTransform.interpolationTime > 0.05) { -// double time = std::fmod(sTransform.interpolationTime, 0.05f); -// m_InterpolationPoints[transform.EntityID].pop(); -// if (m_InterpolationPoints[transform.EntityID].size() <= 0) { -// return; -// } -// sTransform = m_InterpolationPoints[transform.EntityID].front(); -// sTransform.interpolationTime = time; -// } -// glm::vec3 nextPosition = sTransform.Position; -// glm::vec3 currentPosition = static_cast(transform["Position"]); -// transform["Position"] = vectorInterpolation(currentPosition, nextPosition, sTransform.interpolationTime); -// } -//} - void InterpolationSystem::UpdateComponent(EntityWrapper& entity, ComponentWrapper& transform, double dt) { if (m_NextTransform.find(transform.EntityID) != m_NextTransform.end()) { // Exists in map m_NextTransform[transform.EntityID].interpolationTime += dt; Transform sTransform = m_NextTransform[transform.EntityID]; double time = sTransform.interpolationTime; - if (time > SNAPSHOTINTERVAL) { + if (time > m_SnapshotInterval) { if (m_LastReceivedTransform.find(transform.EntityID) != m_LastReceivedTransform.end()) { m_NextTransform[transform.EntityID] = m_LastReceivedTransform[transform.EntityID]; - m_NextTransform[transform.EntityID].interpolationTime = time - SNAPSHOTINTERVAL; + m_NextTransform[transform.EntityID].interpolationTime = time - m_SnapshotInterval; sTransform = m_NextTransform[transform.EntityID]; m_LastReceivedTransform.erase(transform.EntityID); } else { @@ -44,7 +24,7 @@ void InterpolationSystem::UpdateComponent(EntityWrapper& entity, ComponentWrappe // Orientation glm::quat nextOrientation = sTransform.Orientation; glm::quat currentOrientation = glm::quat(static_cast(transform["Orientation"])); - (glm::vec3&)transform["Orientation"] = glm::eulerAngles(glm::slerp(currentOrientation, nextOrientation, sTransform.interpolationTime / SNAPSHOTINTERVAL)); + (glm::vec3&)transform["Orientation"] = glm::eulerAngles(glm::slerp(currentOrientation, nextOrientation, sTransform.interpolationTime / m_SnapshotInterval)); // Scale glm::vec3 nextScale = sTransform.Scale; glm::vec3 currentScale = static_cast(transform["Scale"]); @@ -72,15 +52,5 @@ bool InterpolationSystem::OnInterpolate(const Events::Interpolate & e) } else { // Did not m_NextTransform[e.Entity] = transform; } - // Check if queue already exists - //if (m_InterpolationPoints.find(e.Entity) != m_InterpolationPoints.end()) { // Did exist, push to queue - // m_InterpolationPoints[e.Entity].push(transform); - //} - - //else { // Did not exist, create queue - // std::queue transformQueue; - // transformQueue.push(transform); - // m_InterpolationPoints[e.Entity] = transformQueue; - //} return false; } From 08c476e9e37f2cc90465366edc2f894d3efabe56 Mon Sep 17 00:00:00 2001 From: stiffly Date: Fri, 22 Jan 2016 15:42:36 +0100 Subject: [PATCH 06/24] Added kick logic to the server. Also typedefed. --- include/Engine/Network/Client.h | 9 ++--- include/Engine/Network/MessageType.h | 3 +- include/Engine/Network/Network.h | 3 ++ include/Engine/Network/Server.h | 11 +++--- src/Engine/Network/Client.cpp | 9 +++++ src/Engine/Network/Server.cpp | 53 +++++++++++++++++----------- 6 files changed, 57 insertions(+), 31 deletions(-) diff --git a/include/Engine/Network/Client.h b/include/Engine/Network/Client.h index 61fa5ff0..4a16034b 100644 --- a/include/Engine/Network/Client.h +++ b/include/Engine/Network/Client.h @@ -39,14 +39,14 @@ private: char readBuf[INPUTSIZE] = { 0 }; // Packet loss logic - unsigned int m_PacketID = 0; - unsigned int m_PreviousPacketID = 0; - unsigned int m_SendPacketID = 0; + PacketID m_PacketID = 0; + PacketID m_PreviousPacketID = 0; + PacketID m_SendPacketID = 0; // Game logic World* m_World; std::string m_PlayerName; - int m_PlayerID = -1; + PlayerID m_PlayerID = -1; EntityID m_ServerEntityID = std::numeric_limits::max(); bool m_IsConnected = false; // Server Client Lookup map @@ -76,6 +76,7 @@ private: void parseConnect(Packet& packet); void parsePlayerConnected(Packet& packet); void parsePing(); + void parseKick(); void InterpolateFields(Packet & packet, const ComponentInfo & componentInfo, const EntityID & entityID, const std::string & componentType); void parseSnapshot(Packet& packet); void identifyPacketLoss(); diff --git a/include/Engine/Network/MessageType.h b/include/Engine/Network/MessageType.h index 8468f2fc..7d8094de 100644 --- a/include/Engine/Network/MessageType.h +++ b/include/Engine/Network/MessageType.h @@ -13,7 +13,8 @@ enum class MessageType OnInputCommand, OnPlayerDamage, PlayerConnected, - BecomePlayer + BecomePlayer, + Kick }; #endif diff --git a/include/Engine/Network/Network.h b/include/Engine/Network/Network.h index 73cb01d3..480ac602 100644 --- a/include/Engine/Network/Network.h +++ b/include/Engine/Network/Network.h @@ -13,6 +13,9 @@ #include #define INPUTSIZE 4097 +typedef unsigned int PlayerID; +typedef unsigned int PacketID; +typedef unsigned int UserID; class Network { diff --git a/include/Engine/Network/Server.h b/include/Engine/Network/Server.h index f1b5691a..cbad08b0 100644 --- a/include/Engine/Network/Server.h +++ b/include/Engine/Network/Server.h @@ -51,19 +51,19 @@ private: EventBroker* m_EventBroker; // Packet loss logic - unsigned int m_PacketID = 0; - unsigned int m_PreviousPacketID = 0; + PacketID m_PacketID = 0; + PacketID m_PreviousPacketID = 0; // Private member functions int receive(char* data); void readFromClients(); - void send(Packet& packet, int playerID); + void send(Packet& packet, UserID user); void send(Packet& packet); void broadcast(Packet& packet); void sendSnapshot(); void sendPing(); void checkForTimeOuts(); - void disconnect(int i); + void disconnect(UserID user); void parseMessageType(Packet& packet); void parseOnInputCommand(Packet& packet); void parseOnPlayerDamage(Packet& packet); @@ -73,7 +73,8 @@ private: void parsePing(); void identifyPacketLoss(); void createPlayer(); - int GetPlayerIDFromEndpoint(boost::asio::ip::udp::endpoint endpoint); + void kick(PlayerID player); + PlayerID GetPlayerIDFromEndpoint(boost::asio::ip::udp::endpoint endpoint); // Debug event EventRelay m_EInputCommand; bool OnInputCommand(const Events::InputCommand& e); diff --git a/src/Engine/Network/Client.cpp b/src/Engine/Network/Client.cpp index fe552fa2..129e0b42 100644 --- a/src/Engine/Network/Client.cpp +++ b/src/Engine/Network/Client.cpp @@ -89,6 +89,9 @@ void Client::parseMessageType(Packet& packet) break; case MessageType::PlayerConnected: parsePlayerConnected(packet); + case MessageType::Kick: + parseKick(); + break; default: break; } @@ -120,6 +123,12 @@ void Client::parsePing() send(packet); } +void Client::parseKick() +{ + LOG_WARNING("You have been kicked from the server."); + m_IsConnected = false; +} + // Fields with strings will not work right now void Client::InterpolateFields(Packet& packet, const ComponentInfo& componentInfo, const EntityID& entityID, const std::string& componentType) { diff --git a/src/Engine/Network/Server.cpp b/src/Engine/Network/Server.cpp index 719ca16f..03b9775a 100644 --- a/src/Engine/Network/Server.cpp +++ b/src/Engine/Network/Server.cpp @@ -118,11 +118,11 @@ int Server::receive(char * data) return length; } -void Server::send(Packet& packet, int userID) +void Server::send(Packet& packet, UserID user) { int bytesSent = m_Socket.send_to( boost::asio::buffer(packet.Data(), packet.Size()), - m_ConnectedUsers[userID].Endpoint, + m_ConnectedUsers[user].Endpoint, 0); // Network Debug data if (isReadingData) { @@ -224,40 +224,40 @@ void Server::checkForTimeOuts() } } -void Server::disconnect(int i) +void Server::disconnect(UserID user) { //broadcast("A player disconnected"); - LOG_INFO("User %s disconnected/timed out", m_PlayerDefinitions[i].Name.c_str()); + LOG_INFO("User %s disconnected/timed out", m_PlayerDefinitions[user].Name.c_str()); // Remove enteties and stuff (When we can remove entity, remove it and tell clients to remove the copy they have) Events::PlayerDisconnected e; - e.Entity = m_PlayerDefinitions[i].EntityID; - e.PlayerID = i; + e.Entity = m_PlayerDefinitions[user].EntityID; + e.PlayerID = user; m_EventBroker->Publish(e); - m_PlayerDefinitions[i].Endpoint = boost::asio::ip::udp::endpoint(); - m_PlayerDefinitions[i].EntityID = -1; - m_PlayerDefinitions[i].Name = ""; - m_PlayerDefinitions[i].PacketID = 0; - m_ConnectedUsers.erase(m_ConnectedUsers.begin() + i); + m_PlayerDefinitions[user].Endpoint = boost::asio::ip::udp::endpoint(); + m_PlayerDefinitions[user].EntityID = -1; + m_PlayerDefinitions[user].Name = ""; + m_PlayerDefinitions[user].PacketID = 0; + m_ConnectedUsers.erase(m_ConnectedUsers.begin() + user); } void Server::parseOnInputCommand(Packet& packet) { - int playerID = -1; + PlayerID player = -1; // Check which player it was who sent the message for (int i = 0; i < m_MaxConnections; i++) { // if the player is connected set playerID to the correct PlayerID if (m_PlayerDefinitions[i].Endpoint.address() == m_ReceiverEndpoint.address() && m_PlayerDefinitions[i].Endpoint.port() == m_ReceiverEndpoint.port()) { - playerID = i; + player = i; break; } } - if (playerID != -1) { + if (player != -1) { while (packet.DataReadSize() < packet.Size()) { Events::InputCommand e; e.Command = packet.ReadString(); - e.PlayerID = playerID; // Set correct player id + e.PlayerID = player; // Set correct player id e.Value = packet.ReadPrimitive(); m_EventBroker->Publish(e); //LOG_INFO("Server::parseOnInputCommand: Command is %s. Value is %f. PlayerID is %i.", e.Command.c_str(), e.Value, e.PlayerID); @@ -322,12 +322,12 @@ void Server::parseDisconnect() void Server::parseClientPing() { LOG_INFO("%i: Parsing ping", m_PacketID); - int playerID = GetPlayerIDFromEndpoint(m_ReceiverEndpoint); - if (playerID == -1) { + PlayerID player = GetPlayerIDFromEndpoint(m_ReceiverEndpoint); + if (player == -1) { return; } // Return ping - Packet packet(MessageType::Ping, m_PlayerDefinitions[playerID].PacketID); + Packet packet(MessageType::Ping, m_PlayerDefinitions[player].PacketID); packet.WriteString("Ping received"); send(packet); } @@ -358,7 +358,7 @@ void Server::createPlayer() LOG_WARNING("Already connected!"); return; } - int userIndex; + UserID userIndex; for (userIndex = 0; userIndex < m_ConnectedUsers.size(); userIndex++) { if (m_ConnectedUsers[userIndex].Endpoint.address() == m_ReceiverEndpoint.address() && m_ConnectedUsers[userIndex].Endpoint.port() == m_ReceiverEndpoint.port()) { @@ -370,7 +370,7 @@ void Server::createPlayer() LOG_WARNING("Not a recognized user!"); return; } - for (int playerIndex = 0; playerIndex < m_MaxConnections; playerIndex++) { + for (PlayerID playerIndex = 0; playerIndex < m_MaxConnections; playerIndex++) { if (m_PlayerDefinitions[playerIndex].Endpoint.address() == boost::asio::ip::address()) { m_PlayerDefinitions[playerIndex] = m_ConnectedUsers[userIndex]; EntityID entityID = m_World->CreateEntity(); @@ -388,7 +388,14 @@ void Server::createPlayer() } -int Server::GetPlayerIDFromEndpoint(boost::asio::ip::udp::endpoint endpoint) +void Server::kick(PlayerID player) +{ + disconnect(player); + Packet packet = Packet(MessageType::Kick); + send(packet); +} + +PlayerID Server::GetPlayerIDFromEndpoint(boost::asio::ip::udp::endpoint endpoint) { for (int i = 0; i < m_MaxConnections; i++) { if (m_PlayerDefinitions[i].Endpoint.address() == endpoint.address() && @@ -409,5 +416,9 @@ bool Server::OnInputCommand(const Events::InputCommand & e) isReadingData = !isReadingData; m_SaveDataTimer = std::clock(); } + if (e.Command == "KickPlayer" && e.Value > 0) { + kick(0); + } + return true; } From ca2aab449e340af9968dd97c1f39a6706876e511 Mon Sep 17 00:00:00 2001 From: sippeangelo Date: Fri, 22 Jan 2016 16:12:51 +0100 Subject: [PATCH 07/24] Basic movement and camera management between players and editor --- assets | 2 +- include/Engine/Core/EntityWrapper.h | 1 + include/Engine/Core/Transform.h | 5 + .../Editor/EditorCameraInputController.h | 98 ++++++++++++++ include/Engine/Editor/EditorSystem.h | 19 ++- include/Engine/Input/EInputCommand.h | 2 +- .../Engine/Input/FirstPersonInputController.h | 33 ++++- .../Rendering/DebugCameraInputController.h | 84 ------------ include/Engine/Rendering/RenderSystem.h | 1 - include/Game/Systems/PlayerMovementSystem.h | 18 ++- include/Game/Systems/PlayerSpawnSystem.h | 1 + resources/DefaultConfig.ini | 4 +- resources/Schema/Components/Player.xml | 6 +- resources/Schema/Components/Player.xsd | 6 +- resources/Schema/Entities/CollidableCube.xml | 15 +++ resources/Schema/Entities/MovementTest.xml | 125 +++++++++++++----- resources/Schema/Entities/Player.xml | 61 +++++++-- resources/Schema/Types.xsd | 3 + src/Engine/Core/EntityWrapper.cpp | 16 +++ src/Engine/Core/Transform.cpp | 20 +++ src/Engine/Editor/EditorSystem.cpp | 86 +++++++++--- src/Engine/Rendering/RenderSystem.cpp | 9 +- src/Game/Systems/PlayerMovementSystem.cpp | 52 +++++++- src/Game/Systems/PlayerSpawnSystem.cpp | 8 ++ 24 files changed, 499 insertions(+), 176 deletions(-) create mode 100644 include/Engine/Editor/EditorCameraInputController.h delete mode 100644 include/Engine/Rendering/DebugCameraInputController.h create mode 100644 resources/Schema/Entities/CollidableCube.xml diff --git a/assets b/assets index 6ffb46e1..2a800ea9 160000 --- a/assets +++ b/assets @@ -1 +1 @@ -Subproject commit 6ffb46e155c8f013241cd1507098c94900ec2448 +Subproject commit 2a800ea92b323646432c65217d55aab6750d5a72 diff --git a/include/Engine/Core/EntityWrapper.h b/include/Engine/Core/EntityWrapper.h index 3ba4e087..d0e5e31f 100644 --- a/include/Engine/Core/EntityWrapper.h +++ b/include/Engine/Core/EntityWrapper.h @@ -25,6 +25,7 @@ struct EntityWrapper bool HasComponent(const std::string& componentName); EntityWrapper Parent(); + EntityWrapper FirstChildByName(const std::string& name); bool Valid(); ComponentWrapper operator[](const char* componentName); diff --git a/include/Engine/Core/Transform.h b/include/Engine/Core/Transform.h index 474a7bdb..3b0811c9 100644 --- a/include/Engine/Core/Transform.h +++ b/include/Engine/Core/Transform.h @@ -3,13 +3,18 @@ #include "../GLM.h" #include "World.h" +#include "EntityWrapper.h" namespace Transform { +glm::vec3 AbsolutePosition(EntityWrapper entity); glm::vec3 AbsolutePosition(World* world, EntityID entity); +glm::quat AbsoluteOrientation(EntityWrapper entity); glm::quat AbsoluteOrientation(World* world, EntityID entity); +glm::vec3 AbsoluteScale(EntityWrapper entity); glm::vec3 AbsoluteScale(World* world, EntityID entity); +glm::mat4 ModelMatrix(EntityWrapper entity); glm::mat4 ModelMatrix(EntityID entity, World* world); } diff --git a/include/Engine/Editor/EditorCameraInputController.h b/include/Engine/Editor/EditorCameraInputController.h new file mode 100644 index 00000000..c12113c7 --- /dev/null +++ b/include/Engine/Editor/EditorCameraInputController.h @@ -0,0 +1,98 @@ +#ifndef EditorCameraInputController_h__ +#define EditorCameraInputController_h__ + +#include +#include "../Input/FirstPersonInputController.h" +#include "../Core/EMousePress.h" +#include "../Core/EMouseRelease.h" +#include "../Core/EMouseScroll.h" +#include "../Core/ConfigFile.h" + +template +class EditorCameraInputController : public FirstPersonInputController +{ +public: + EditorCameraInputController(EventBroker* eventBroker, unsigned int playerID) + : FirstPersonInputController(eventBroker, playerID) + { + EVENT_SUBSCRIBE_MEMBER(m_EMousePress, &EditorCameraInputController::OnMousePress); + EVENT_SUBSCRIBE_MEMBER(m_EMouseRelease, &EditorCameraInputController::OnMouseRelease); + EVENT_SUBSCRIBE_MEMBER(m_EMouseScroll, &EditorCameraInputController::OnMouseScroll); + + m_Config = ResourceManager::Load("Config.ini"); + m_SpeedMultiplier = m_Config->Get("Editor.CameraSpeed", 3.f); + } + + virtual const glm::vec3 Movement() const override + { + return m_Movement * m_SpeedMultiplier; + } + + virtual bool OnCommand(const Events::InputCommand& e) override + { + ImGuiIO& io = ImGui::GetIO(); + if (glm::abs(e.Value) > 0 && (io.WantCaptureKeyboard || io.WantCaptureMouse)) { + return false; + } + + if (e.Command == "Jump") { + if (e.Value > 0) { + m_Movement.y = glm::max(e.Value, 1.f); + } else { + m_Movement.y = 0.f; + } + } + + if (e.Command == "Crouch") { + if (e.Value > 0) { + m_Movement.y = glm::min(-e.Value, -1.f); + } else { + m_Movement.y = 0.f; + } + } + + if (e.Command == "Sprint") { + if (e.Value > 0) { + m_SpeedMultiplier *= 2.f; + } else { + m_SpeedMultiplier /= 2.f; + } + } + + return FirstPersonInputController::OnCommand(e); + } + +protected: + ConfigFile* m_Config; + float m_SpeedMultiplier = 1.f; + + EventRelay m_EMousePress; + bool OnMousePress(const Events::MousePress& e) + { + if (e.Button == GLFW_MOUSE_BUTTON_2) { + ImGuiIO& io = ImGui::GetIO(); + if (!io.WantCaptureMouse) { + LockMouse(); + } + } + return true; + } + EventRelay m_EMouseRelease; + bool OnMouseRelease(const Events::MouseRelease& e) + { + if (e.Button == GLFW_MOUSE_BUTTON_2) { + UnlockMouse(); + } + return true; + } + EventRelay m_EMouseScroll; + bool OnMouseScroll(const Events::MouseScroll& e) + { + m_SpeedMultiplier += e.DeltaY * (0.1f * m_SpeedMultiplier); + m_Config->Set("Editor.CameraSpeed", m_SpeedMultiplier); + m_Config->SaveToDisk(); + return true; + } +}; + +#endif \ No newline at end of file diff --git a/include/Engine/Editor/EditorSystem.h b/include/Engine/Editor/EditorSystem.h index b354ddf3..2db24ba3 100644 --- a/include/Engine/Editor/EditorSystem.h +++ b/include/Engine/Editor/EditorSystem.h @@ -1,7 +1,6 @@ #include "../Core/System.h" #include "../Rendering/IRenderer.h" #include "../Rendering/Camera.h" -#include "../Rendering/DebugCameraInputController.h" #include "../Rendering/ESetCamera.h" #include "../Core/World.h" #include "../Core/SystemPipeline.h" @@ -10,8 +9,10 @@ #include "../Core/EntityFileParser.h" #include "../Core/EntityFileWriter.h" #include "../Core/EMousePress.h" +#include "../Input/EInputCommand.h" #include "EditorGUI.h" #include "EditorStats.h" +#include "EditorCameraInputController.h" class EditorSystem : public ImpureSystem { @@ -21,18 +22,24 @@ public: void Update(double dt); + void Enable(); + void Disable(); + private: IRenderer* m_Renderer; RenderFrame* m_RenderFrame; World* m_EditorWorld; SystemPipeline* m_EditorWorldSystemPipeline; - Camera* m_EditorCamera; - EntityWrapper m_Camera = EntityWrapper::Invalid; - DebugCameraInputController* m_DebugCameraInputController; + //Camera* m_EditorCamera; + EntityWrapper m_EditorCamera = EntityWrapper::Invalid; + EntityWrapper m_ActualCamera = EntityWrapper::Invalid; + EditorCameraInputController* m_EditorCameraInputController; EditorGUI* m_EditorGUI; EditorStats* m_EditorStats; // State + double m_LastTime = 0.f; + bool m_Enabled = true; EditorGUI::WidgetMode m_WidgetMode = EditorGUI::WidgetMode::Translate; EntityWrapper m_Widget = EntityWrapper::Invalid; EntityWrapper m_CurrentSelection = EntityWrapper::Invalid; @@ -56,4 +63,8 @@ private: bool OnMousePress(const Events::MousePress& e); EventRelay m_EWidgetDelta; bool OnWidgetDelta(const Events::WidgetDelta& e); + EventRelay m_EInputCommand; + bool OnInputCommand(const Events::InputCommand& e); + EventRelay m_ESetCamera; + bool OnSetCamera(const Events::SetCamera& e); }; \ No newline at end of file diff --git a/include/Engine/Input/EInputCommand.h b/include/Engine/Input/EInputCommand.h index 9ec897d3..1e150786 100644 --- a/include/Engine/Input/EInputCommand.h +++ b/include/Engine/Input/EInputCommand.h @@ -9,7 +9,7 @@ namespace Events struct InputCommand : Event { /** Numerical ID of the player. */ - unsigned int PlayerID; + int PlayerID; /** The command that was sent. */ std::string Command; /** The value of the command. */ diff --git a/include/Engine/Input/FirstPersonInputController.h b/include/Engine/Input/FirstPersonInputController.h index d8584494..91445534 100644 --- a/include/Engine/Input/FirstPersonInputController.h +++ b/include/Engine/Input/FirstPersonInputController.h @@ -9,7 +9,7 @@ template class FirstPersonInputController : public InputController { public: - FirstPersonInputController(EventBroker* eventBroker, unsigned int playerID) + FirstPersonInputController(EventBroker* eventBroker, int playerID) : InputController(eventBroker) , m_PlayerID(playerID) { @@ -17,7 +17,8 @@ public: EVENT_SUBSCRIBE_MEMBER(m_EUnlockMouse, &FirstPersonInputController::OnUnlockMouse); } - const glm::quat Orientation() const { return m_Orientation; } + virtual const glm::vec3 Movement() const { return m_Movement; } + virtual const glm::vec3 Orientation() const { return m_Orientation; } void LockMouse() { @@ -42,24 +43,44 @@ public: if (m_MouseLocked) { if (e.Command == "Pitch") { float val = glm::radians(e.Value); - m_Orientation = m_Orientation * glm::angleAxis(-val, glm::vec3(1, 0, 0)); + m_Orientation.x += -val; + m_Orientation.x = glm::clamp(m_Orientation.x, -glm::half_pi(), glm::half_pi()); + //m_Orientation = m_Orientation * glm::angleAxis(-val, glm::vec3(1.f, 0, 0)); return true; } if (e.Command == "Yaw") { float val = glm::radians(e.Value); - m_Orientation = glm::angleAxis(-val, glm::vec3(0, 1, 0)) * m_Orientation; + m_Orientation.y += -val; + //m_Orientation = glm::angleAxis(-val, glm::vec3(0, 1.f, 0)) * m_Orientation; return true; } } + if (e.Command == "Forward" || e.Command == "Right") { + if (e.Command == "Forward") { + float val = glm::clamp(e.Value, -1.f, 1.f); + m_Movement.z = -val; + return true; + } + if (e.Command == "Right") { + float val = glm::clamp(e.Value, -1.f, 1.f); + m_Movement.x = val; + return true; + } + if (glm::length2(m_Movement) > 0) { + m_Movement = glm::normalize(m_Movement); + } + } + return false; } protected: - const unsigned int m_PlayerID; - glm::quat m_Orientation; + const int m_PlayerID; bool m_MouseLocked = false; + glm::vec3 m_Orientation; + glm::vec3 m_Movement; EventRelay m_ELockMouse; bool OnLockMouse(const Events::LockMouse& e) { m_MouseLocked = true; return true; } diff --git a/include/Engine/Rendering/DebugCameraInputController.h b/include/Engine/Rendering/DebugCameraInputController.h deleted file mode 100644 index 5ce85b3f..00000000 --- a/include/Engine/Rendering/DebugCameraInputController.h +++ /dev/null @@ -1,84 +0,0 @@ -#ifndef DebugCameraInputController_h__ -#define DebugCameraInputController_h__ - -#include -#include "../Input/FirstPersonInputController.h" -#include "../Core/EMousePress.h" -#include "../Core/EMouseRelease.h" - -template -class DebugCameraInputController : public FirstPersonInputController -{ -public: - DebugCameraInputController(EventBroker* eventBroker, unsigned int playerID) - : FirstPersonInputController(eventBroker, playerID) - { - EVENT_SUBSCRIBE_MEMBER(m_EMousePress, &DebugCameraInputController::OnMousePress); - EVENT_SUBSCRIBE_MEMBER(m_EMouseRelease, &DebugCameraInputController::OnMouseRelease); - } - - void SetPosition(const glm::vec3 position) { m_Position = position; } - void SetOrientation(const glm::quat orientation) { m_Orientation = orientation; } - - const glm::vec3 Position() const { return m_Position; } - void SetBaseSpeed(float speed) { m_BaseSpeed = speed; } - - virtual bool OnCommand(const Events::InputCommand& e) override - { - ImGuiIO& io = ImGui::GetIO(); - - if (!io.WantCaptureKeyboard) { - if (e.Command == "Right") { - float value = std::max(-1.f, std::min(e.Value, 1.f)); - m_Velocity.x = value; - } - if (e.Command == "Forward") { - float value = std::max(-1.f, std::min(e.Value, 1.f)); - m_Velocity.z = -value; - } - if (e.Command == "Sprint") { - if (e.Value > 0.f) { - m_Speed = m_BaseSpeed * 2.f * (e.Value); - } else { - m_Speed = m_BaseSpeed; - } - } - } - - return FirstPersonInputController::OnCommand(e); - } - - void Update(double dt) - { - if (glm::length2(m_Velocity) > 0) { - m_Position += m_Orientation * (glm::normalize(m_Velocity) * m_Speed * (float)dt); - } - } - -protected: - glm::vec3 m_Position = glm::vec3(0, 0, 0); - glm::vec3 m_Velocity = glm::vec3(0, 0, 0); - float m_BaseSpeed = 2.0f; - float m_Speed = m_BaseSpeed; - EventRelay m_EMousePress; - bool OnMousePress(const Events::MousePress& e) - { - if (e.Button == GLFW_MOUSE_BUTTON_2) { - ImGuiIO& io = ImGui::GetIO(); - if (!io.WantCaptureMouse) { - LockMouse(); - } - } - return true; - } - EventRelay m_EMouseRelease; - bool OnMouseRelease(const Events::MouseRelease& e) - { - if (e.Button == GLFW_MOUSE_BUTTON_2) { - UnlockMouse(); - } - return true; - } -}; - -#endif \ No newline at end of file diff --git a/include/Engine/Rendering/RenderSystem.h b/include/Engine/Rendering/RenderSystem.h index 003e308e..04c394a9 100644 --- a/include/Engine/Rendering/RenderSystem.h +++ b/include/Engine/Rendering/RenderSystem.h @@ -15,7 +15,6 @@ #include "Renderer.h" #include "PointLightJob.h" #include "../Core/Transform.h" -#include "DebugCameraInputController.h" class RenderSystem : public ImpureSystem { diff --git a/include/Game/Systems/PlayerMovementSystem.h b/include/Game/Systems/PlayerMovementSystem.h index 1be61bdd..f5b6539b 100644 --- a/include/Game/Systems/PlayerMovementSystem.h +++ b/include/Game/Systems/PlayerMovementSystem.h @@ -1,14 +1,22 @@ #include "Common.h" #include "GLM.h" #include "Core/System.h" +#include "Events/EPlayerSpawned.h" +#include "Input/FirstPersonInputController.h" -class PlayerMovementSystem : public PureSystem +class PlayerMovementSystem : public ImpureSystem, PureSystem { public: - PlayerMovementSystem(World* world, EventBroker* eventBroker) - : System(world, eventBroker) - , PureSystem("Player") - { } + PlayerMovementSystem(World* world, EventBroker* eventBroker); + ~PlayerMovementSystem(); + virtual void Update(double dt) override; virtual void UpdateComponent(EntityWrapper& entity, ComponentWrapper& component, double dt); + +private: + // State + std::unordered_map*> m_PlayerInputControllers; + + EventRelay m_EPlayerSpawned; + bool OnPlayerSpawned(Events::PlayerSpawned& e); }; \ No newline at end of file diff --git a/include/Game/Systems/PlayerSpawnSystem.h b/include/Game/Systems/PlayerSpawnSystem.h index 69014f65..9e9ce0be 100644 --- a/include/Game/Systems/PlayerSpawnSystem.h +++ b/include/Game/Systems/PlayerSpawnSystem.h @@ -3,6 +3,7 @@ #include "Systems/SpawnerSystem.h" #include "Events/ESpawnerSpawn.h" #include "Events/EPlayerSpawned.h" +#include "Rendering/ESetCamera.h" class PlayerSpawnSystem : public ImpureSystem { diff --git a/resources/DefaultConfig.ini b/resources/DefaultConfig.ini index fb490ec8..7e7dc08c 100644 --- a/resources/DefaultConfig.ini +++ b/resources/DefaultConfig.ini @@ -1,11 +1,13 @@ [Debug] LogLevel=1 LoadMap= -EditorEnabled=false ; if true -> Pool allocation is not used when calling Allocate/Free, just use regular dynamic allocation. ; if false -> Use pool allocation. DisableMemoryPool=false +[Editor] +CameraSpeed=3 + [Video] Fullscreen=false VSYNC=false diff --git a/resources/Schema/Components/Player.xml b/resources/Schema/Components/Player.xml index caefd6e6..a9ecc6be 100644 --- a/resources/Schema/Components/Player.xml +++ b/resources/Schema/Components/Player.xml @@ -1,8 +1,4 @@ - - false - false - false - false + 0.2 \ No newline at end of file diff --git a/resources/Schema/Components/Player.xsd b/resources/Schema/Components/Player.xsd index 1a315a35..89c4a398 100644 --- a/resources/Schema/Components/Player.xsd +++ b/resources/Schema/Components/Player.xsd @@ -9,11 +9,7 @@ - - - - - + diff --git a/resources/Schema/Entities/CollidableCube.xml b/resources/Schema/Entities/CollidableCube.xml new file mode 100644 index 00000000..ebba54be --- /dev/null +++ b/resources/Schema/Entities/CollidableCube.xml @@ -0,0 +1,15 @@ + + + + + + + + Models/Core/UnitCube.obj + + + + + + + diff --git a/resources/Schema/Entities/MovementTest.xml b/resources/Schema/Entities/MovementTest.xml index 93b4d374..9ea1ae68 100644 --- a/resources/Schema/Entities/MovementTest.xml +++ b/resources/Schema/Entities/MovementTest.xml @@ -6,14 +6,7 @@ - - - - - - - - + @@ -22,46 +15,116 @@ - - + + - + - - - - - - - - Models/Assault.obj - - - + + + Schema/Entities/Player.xml + + + + + + - + + + + + + + + + Models/Assault.obj + + + + + + + + + + + + + Models/Assault.obj + + + + + + + + + + + + + + + Models/DirectionalLightWidget.obj + + + + - + + + + Models/Test/ObstacleCourse.obj + + + + + + - - - Models/Core/UnitCube.obj - - - - + + + + + + + + + + + + Models/Core/UnitCube.obj + + + + + + + + + + + + + + Models/Core/UnitCube.obj + + + + diff --git a/resources/Schema/Entities/Player.xml b/resources/Schema/Entities/Player.xml index 6c3b39c3..087b1f7e 100644 --- a/resources/Schema/Entities/Player.xml +++ b/resources/Schema/Entities/Player.xml @@ -2,17 +2,60 @@ - - + + + + - - Models/Core/UnitSphere.obj - - - - + + + 3 + + + + + - + + + + + + Models/Camera.obj + false + + + + + + + + + + + + + Models/Camera.obj + + + + + + + + + + + + Models/Assault.obj + + + + + + + + diff --git a/resources/Schema/Types.xsd b/resources/Schema/Types.xsd index fb584c64..8d9bf289 100644 --- a/resources/Schema/Types.xsd +++ b/resources/Schema/Types.xsd @@ -16,6 +16,9 @@ + + + diff --git a/src/Engine/Core/EntityWrapper.cpp b/src/Engine/Core/EntityWrapper.cpp index 98b9c7d4..6177d91d 100644 --- a/src/Engine/Core/EntityWrapper.cpp +++ b/src/Engine/Core/EntityWrapper.cpp @@ -17,6 +17,22 @@ EntityWrapper EntityWrapper::Parent() } } +EntityWrapper EntityWrapper::FirstChildByName(const std::string& name) +{ + auto itPair = this->World->GetChildren(this->ID); + if (itPair.first == itPair.second) { + return EntityWrapper::Invalid; + } + + for (auto it = itPair.first; it != itPair.second; ++it) { + if (this->World->GetName(it->second) == name) { + return EntityWrapper(this->World, it->second); + } + } + + return EntityWrapper::Invalid; +} + bool EntityWrapper::Valid() { if (this->World == nullptr) { diff --git a/src/Engine/Core/Transform.cpp b/src/Engine/Core/Transform.cpp index cbc405a3..c9869014 100644 --- a/src/Engine/Core/Transform.cpp +++ b/src/Engine/Core/Transform.cpp @@ -1,5 +1,10 @@ #include "Core/Transform.h" +glm::vec3 Transform::AbsolutePosition(EntityWrapper entity) +{ + return AbsolutePosition(entity.World, entity.ID); +} + glm::vec3 Transform::AbsolutePosition(World* world, EntityID entity) { glm::vec3 position; @@ -14,6 +19,11 @@ glm::vec3 Transform::AbsolutePosition(World* world, EntityID entity) return position; } +glm::quat Transform::AbsoluteOrientation(EntityWrapper entity) +{ + return AbsoluteOrientation(entity.World, entity.ID); +} + glm::quat Transform::AbsoluteOrientation(World* world, EntityID entity) { glm::quat orientation; @@ -27,6 +37,11 @@ glm::quat Transform::AbsoluteOrientation(World* world, EntityID entity) return orientation; } +glm::vec3 Transform::AbsoluteScale(EntityWrapper entity) +{ + return AbsoluteScale(entity.World, entity.ID); +} + glm::vec3 Transform::AbsoluteScale(World* world, EntityID entity) { glm::vec3 scale(1.f); @@ -40,6 +55,11 @@ glm::vec3 Transform::AbsoluteScale(World* world, EntityID entity) return scale; } +glm::mat4 Transform::ModelMatrix(EntityWrapper entity) +{ + return ModelMatrix(entity.ID, entity.World); +} + glm::mat4 Transform::ModelMatrix(EntityID entity, World* world) { glm::vec3 position = Transform::AbsolutePosition(world, entity); diff --git a/src/Engine/Editor/EditorSystem.cpp b/src/Engine/Editor/EditorSystem.cpp index 35b8a361..a357a542 100644 --- a/src/Engine/Editor/EditorSystem.cpp +++ b/src/Engine/Editor/EditorSystem.cpp @@ -14,10 +14,11 @@ EditorSystem::EditorSystem(World* world, EventBroker* eventBroker, IRenderer* re m_EditorWorldSystemPipeline->AddSystem(0, m_Renderer); m_EditorWorldSystemPipeline->AddSystem(1, m_Renderer, m_RenderFrame); - m_Camera = importEntity(EntityWrapper(m_EditorWorld, EntityID_Invalid), "Schema/Entities/Empty.xml"); - m_EditorWorld->AttachComponent(m_Camera.ID, "Transform"); - m_EditorWorld->AttachComponent(m_Camera.ID, "Camera"); - m_DebugCameraInputController = new DebugCameraInputController(m_EventBroker, -1); + m_EditorCamera = importEntity(EntityWrapper(m_EditorWorld, EntityID_Invalid), "Schema/Entities/Empty.xml"); + m_ActualCamera = m_EditorCamera; + m_EditorWorld->AttachComponent(m_EditorCamera.ID, "Transform"); + m_EditorWorld->AttachComponent(m_EditorCamera.ID, "Camera"); + m_EditorCameraInputController = new EditorCameraInputController(m_EventBroker, -1); m_EditorGUI = new EditorGUI(m_World, m_EventBroker); m_EditorGUI->SetEntitySelectedCallback(std::bind(&EditorSystem::OnEntitySelected, this, std::placeholders::_1)); @@ -33,38 +34,66 @@ EditorSystem::EditorSystem(World* world, EventBroker* eventBroker, IRenderer* re EVENT_SUBSCRIBE_MEMBER(m_EMousePress, &EditorSystem::OnMousePress); EVENT_SUBSCRIBE_MEMBER(m_EWidgetDelta, &EditorSystem::OnWidgetDelta); + EVENT_SUBSCRIBE_MEMBER(m_EInputCommand, &EditorSystem::OnInputCommand); + EVENT_SUBSCRIBE_MEMBER(m_ESetCamera, &EditorSystem::OnSetCamera); m_EditorStats = new EditorStats(); - Events::SetCamera e; - e.CameraEntity = m_Camera; - m_EventBroker->Publish(e); + if (m_Enabled) { + Enable(); + } } EditorSystem::~EditorSystem() { delete m_EditorStats; delete m_EditorGUI; - delete m_DebugCameraInputController; + delete m_EditorCameraInputController; delete m_EditorWorldSystemPipeline; delete m_EditorWorld; } void EditorSystem::Update(double dt) { - m_EventBroker->Process(); - m_EditorGUI->Draw(); - m_EditorStats->Draw(dt); + double now = glfwGetTime(); + double actualDelta = now - m_LastTime; + m_LastTime = now; - if (m_CurrentSelection.Valid() && m_Widget.Valid()) { - (glm::vec3&)m_Widget["Transform"]["Position"] = Transform::AbsolutePosition(m_CurrentSelection.World, m_CurrentSelection.ID); + if (m_Enabled) { + m_EventBroker->Process(); + m_EditorGUI->Draw(); + m_EditorStats->Draw(actualDelta); + + if (m_CurrentSelection.Valid() && m_Widget.Valid()) { + (glm::vec3&)m_Widget["Transform"]["Position"] = Transform::AbsolutePosition(m_CurrentSelection.World, m_CurrentSelection.ID); + } + + m_EditorWorldSystemPipeline->Update(actualDelta); + + ComponentWrapper& cameraTransform = m_EditorCamera["Transform"]; + glm::vec3& ori = cameraTransform["Orientation"]; + ori.x = m_EditorCameraInputController->Orientation().x; + ori.y = m_EditorCameraInputController->Orientation().y; + glm::vec3& pos = cameraTransform["Position"]; + pos += m_EditorCameraInputController->Movement() * glm::inverse(glm::quat(ori)) * (float)actualDelta; } +} - m_EditorWorldSystemPipeline->Update(dt); +void EditorSystem::Enable() +{ + Events::SetCamera e; + e.CameraEntity = m_EditorCamera; + m_EventBroker->Publish(e); + (glm::vec3&)m_EditorCamera["Transform"]["Position"] = Transform::AbsolutePosition(m_ActualCamera); + m_Enabled = true; +} - m_DebugCameraInputController->Update(dt); - m_Camera["Transform"]["Position"] = m_DebugCameraInputController->Position(); - m_Camera["Transform"]["Orientation"] = glm::eulerAngles(m_DebugCameraInputController->Orientation()); +void EditorSystem::Disable() +{ + Events::SetCamera e; + e.CameraEntity = m_ActualCamera; + m_EventBroker->Publish(e); + m_Enabled = false; } void EditorSystem::OnEntitySelected(EntityWrapper entity) @@ -148,6 +177,29 @@ bool EditorSystem::OnWidgetDelta(const Events::WidgetDelta& e) return true; } +bool EditorSystem::OnInputCommand(const Events::InputCommand& e) +{ + if (e.Command == "ToggleEditor" && e.Value > 0) { + if (m_Enabled) { + Disable(); + } else { + Enable(); + } + } + return true; +} + +bool EditorSystem::OnSetCamera(const Events::SetCamera& e) +{ + if (m_Enabled && e.CameraEntity != m_EditorCamera) { + m_ActualCamera = e.CameraEntity; + Events::SetCamera e2; + e2.CameraEntity = m_EditorCamera; + m_EventBroker->Publish(e2); + } + return true; +} + EntityWrapper EditorSystem::importEntity(EntityWrapper parent, boost::filesystem::path filePath) { if (parent.World == nullptr) { diff --git a/src/Engine/Rendering/RenderSystem.cpp b/src/Engine/Rendering/RenderSystem.cpp index 80b6696c..6eedc34c 100644 --- a/src/Engine/Rendering/RenderSystem.cpp +++ b/src/Engine/Rendering/RenderSystem.cpp @@ -119,11 +119,12 @@ void RenderSystem::Update(double dt) { m_EventBroker->Process(); - if (m_CurrentCamera) { - ComponentWrapper cameraTransform = m_CurrentCamera["Transform"]; - m_Camera->SetPosition(cameraTransform["Position"]); - m_Camera->SetOrientation(glm::quat((const glm::vec3&)cameraTransform["Orientation"])); + // Update the current camera used for rendering + if (m_CurrentCamera.Valid()) { + m_Camera->SetPosition(Transform::AbsolutePosition(m_CurrentCamera)); + m_Camera->SetOrientation(Transform::AbsoluteOrientation(m_CurrentCamera)); } + //Only supports opaque geometry atm RenderScene scene; diff --git a/src/Game/Systems/PlayerMovementSystem.cpp b/src/Game/Systems/PlayerMovementSystem.cpp index e14cd146..351acad5 100644 --- a/src/Game/Systems/PlayerMovementSystem.cpp +++ b/src/Game/Systems/PlayerMovementSystem.cpp @@ -1,5 +1,45 @@ #include "Systems/PlayerMovementSystem.h" +PlayerMovementSystem::PlayerMovementSystem(World* world, EventBroker* eventBroker) + : System(world, eventBroker) + , PureSystem("Player") +{ + EVENT_SUBSCRIBE_MEMBER(m_EPlayerSpawned, &PlayerMovementSystem::OnPlayerSpawned); +} + +PlayerMovementSystem::~PlayerMovementSystem() +{ + for (auto& kv : m_PlayerInputControllers) { + delete kv.second; + } +} + +void PlayerMovementSystem::Update(double dt) +{ + for (auto& kv : m_PlayerInputControllers) { + EntityWrapper player = kv.first; + auto& controller = kv.second; + + if (!player.Valid()) { + continue; + } + + EntityWrapper cameraEntity = player.FirstChildByName("Camera"); + if (cameraEntity.Valid()) { + glm::vec3& cameraOrientation = cameraEntity["Transform"]["Orientation"]; + cameraOrientation.x = controller->Orientation().x; + } + + ComponentWrapper& cTransform = player["Transform"]; + glm::vec3& ori = cTransform["Orientation"]; + ori.y = controller->Orientation().y; + + glm::vec3& pos = cTransform["Position"]; + pos += controller->Movement() * glm::inverse(glm::quat(ori)) * (float)player["Player"]["MovementSpeed"] * (float)dt; + + } +} + void PlayerMovementSystem::UpdateComponent(EntityWrapper& entity, ComponentWrapper& component, double dt) { ComponentWrapper& cTransform = entity["Transform"]; @@ -10,9 +50,17 @@ void PlayerMovementSystem::UpdateComponent(EntityWrapper& entity, ComponentWrapp glm::vec3& velocity = cPhysics["Velocity"]; if (cPhysics["Gravity"]) { - velocity.y -= 9.82 * dt; + velocity.y -= 9.82f * (float)dt; } glm::vec3& position = cTransform["Position"]; position += velocity * (float)dt; -} \ No newline at end of file +} + +bool PlayerMovementSystem::OnPlayerSpawned(Events::PlayerSpawned& e) +{ + // When a player spawns, create an input controller for them + m_PlayerInputControllers[e.Player] = new FirstPersonInputController(m_EventBroker, e.PlayerID); + + return true; +} diff --git a/src/Game/Systems/PlayerSpawnSystem.cpp b/src/Game/Systems/PlayerSpawnSystem.cpp index 11be0486..0763fa9c 100644 --- a/src/Game/Systems/PlayerSpawnSystem.cpp +++ b/src/Game/Systems/PlayerSpawnSystem.cpp @@ -38,6 +38,14 @@ void PlayerSpawnSystem::Update(double dt) e.Player = player; e.Spawner = spawner; m_EventBroker->Publish(e); + + // Set the camera to the correct entity + EntityWrapper cameraEntity = player.FirstChildByName("Camera"); + if (cameraEntity.Valid()) { + Events::SetCamera e; + e.CameraEntity = cameraEntity; + m_EventBroker->Publish(e); + } } } m_SpawnRequests.clear(); From 74d9bae8968d2775b87c1bb49016e49c5188bbed Mon Sep 17 00:00:00 2001 From: sippeangelo Date: Fri, 22 Jan 2016 17:34:57 +0100 Subject: [PATCH 08/24] Added conditional spawning based on whether the running instance is a server or not --- include/Game/Systems/PlayerSpawnSystem.h | 8 +++++-- src/Game/Systems/PlayerSpawnSystem.cpp | 29 ++++++++++++++++++------ 2 files changed, 28 insertions(+), 9 deletions(-) diff --git a/include/Game/Systems/PlayerSpawnSystem.h b/include/Game/Systems/PlayerSpawnSystem.h index 9e9ce0be..6c0f6ce3 100644 --- a/include/Game/Systems/PlayerSpawnSystem.h +++ b/include/Game/Systems/PlayerSpawnSystem.h @@ -4,6 +4,7 @@ #include "Events/ESpawnerSpawn.h" #include "Events/EPlayerSpawned.h" #include "Rendering/ESetCamera.h" +#include "Core/ConfigFile.h" class PlayerSpawnSystem : public ImpureSystem { @@ -19,8 +20,11 @@ private: ComponentInfo::EnumType Team; }; + bool m_NetworkEnabled = false; + std::vector m_SpawnRequests; + EventRelay m_OnInputCommand; bool OnInputCommand(const Events::InputCommand& e); - - std::vector m_SpawnRequests; + EventRelay m_OnPlayerSpawnerd; + bool OnPlayerSpawned(Events::PlayerSpawned& e); }; \ No newline at end of file diff --git a/src/Game/Systems/PlayerSpawnSystem.cpp b/src/Game/Systems/PlayerSpawnSystem.cpp index 0763fa9c..f18808cc 100644 --- a/src/Game/Systems/PlayerSpawnSystem.cpp +++ b/src/Game/Systems/PlayerSpawnSystem.cpp @@ -4,6 +4,8 @@ PlayerSpawnSystem::PlayerSpawnSystem(World* m_World, EventBroker* eventBroker) : System(m_World, eventBroker) { EVENT_SUBSCRIBE_MEMBER(m_OnInputCommand, &PlayerSpawnSystem::OnInputCommand); + EVENT_SUBSCRIBE_MEMBER(m_OnPlayerSpawnerd, &PlayerSpawnSystem::OnPlayerSpawned); + m_NetworkEnabled = ResourceManager::Load("Config.ini")->Get("Networking.StartNetwork", false); } void PlayerSpawnSystem::Update(double dt) @@ -39,13 +41,6 @@ void PlayerSpawnSystem::Update(double dt) e.Spawner = spawner; m_EventBroker->Publish(e); - // Set the camera to the correct entity - EntityWrapper cameraEntity = player.FirstChildByName("Camera"); - if (cameraEntity.Valid()) { - Events::SetCamera e; - e.CameraEntity = cameraEntity; - m_EventBroker->Publish(e); - } } } m_SpawnRequests.clear(); @@ -57,6 +52,12 @@ bool PlayerSpawnSystem::OnInputCommand(const Events::InputCommand& e) return false; } + // Team picks should be processed ONLY server-side! + // Don't make a spawn request if PlayerID is -1, i.e. we're the client. + if (e.PlayerID == -1 && m_NetworkEnabled) { + return false; + } + if (e.Value != 0) { SpawnRequest req; req.PlayerID = e.PlayerID; @@ -67,3 +68,17 @@ bool PlayerSpawnSystem::OnInputCommand(const Events::InputCommand& e) return true; } +bool PlayerSpawnSystem::OnPlayerSpawned(Events::PlayerSpawned& e) +{ + // When a player is actually spawned (since the actual spawning is handled on the server) + + // Set the camera to the correct entity + EntityWrapper cameraEntity = e.Player.FirstChildByName("Camera"); + if (cameraEntity.Valid()) { + Events::SetCamera e; + e.CameraEntity = cameraEntity; + m_EventBroker->Publish(e); + } + + return true; +} \ No newline at end of file From 389e057611105eb97a34dbbe6f1121e39199002d Mon Sep 17 00:00:00 2001 From: stiffly Date: Fri, 22 Jan 2016 17:49:21 +0100 Subject: [PATCH 09/24] EPlayerSpawned special logic added to server and client. --- include/Engine/Network/Client.h | 2 ++ include/Engine/Network/MessageType.h | 13 +++++++------ include/Engine/Network/Server.h | 5 +++++ src/Engine/Network/Client.cpp | 12 ++++++++++++ src/Engine/Network/Server.cpp | 23 +++++++++++++++++++++++ 5 files changed, 49 insertions(+), 6 deletions(-) diff --git a/include/Engine/Network/Client.h b/include/Engine/Network/Client.h index 4a16034b..9717d22f 100644 --- a/include/Engine/Network/Client.h +++ b/include/Engine/Network/Client.h @@ -20,6 +20,7 @@ #include "Input/EInputCommand.h" #include "Core/EPlayerDamage.h" #include "Network/EInterpolate.h" +#include "Game/Events/EPlayerSpawned.h" class Client : public Network { @@ -77,6 +78,7 @@ private: void parsePlayerConnected(Packet& packet); void parsePing(); void parseKick(); + void parsePlayersSpawned(Packet& packet); void InterpolateFields(Packet & packet, const ComponentInfo & componentInfo, const EntityID & entityID, const std::string & componentType); void parseSnapshot(Packet& packet); void identifyPacketLoss(); diff --git a/include/Engine/Network/MessageType.h b/include/Engine/Network/MessageType.h index 7d8094de..13ac5e9d 100644 --- a/include/Engine/Network/MessageType.h +++ b/include/Engine/Network/MessageType.h @@ -5,16 +5,17 @@ // Used to determine what type of message was sent. enum class MessageType { - Connect, - Disconnect, - Ping, - Message, - Snapshot, + Connect, + Disconnect, + Ping, + Message, + Snapshot, OnInputCommand, OnPlayerDamage, PlayerConnected, BecomePlayer, - Kick + Kick, + OnPlayerSpawned }; #endif diff --git a/include/Engine/Network/Server.h b/include/Engine/Network/Server.h index cbad08b0..cf649dba 100644 --- a/include/Engine/Network/Server.h +++ b/include/Engine/Network/Server.h @@ -16,6 +16,8 @@ #include "Core/EPlayerDamage.h" #include "Network/EPlayerDisconnected.h" +#include "Game/Events/EPlayerSpawned.h" + class Server : public Network { public: @@ -58,6 +60,7 @@ private: int receive(char* data); void readFromClients(); void send(Packet& packet, UserID user); + void send(Packet& packet, PlayerID player); void send(Packet& packet); void broadcast(Packet& packet); void sendSnapshot(); @@ -78,6 +81,8 @@ private: // Debug event EventRelay m_EInputCommand; bool OnInputCommand(const Events::InputCommand& e); + EventRelay m_EPlayerSpawned; + bool OnPlayerSpawned(const Events::PlayerSpawned& e); }; #endif diff --git a/src/Engine/Network/Client.cpp b/src/Engine/Network/Client.cpp index 129e0b42..fb5c3573 100644 --- a/src/Engine/Network/Client.cpp +++ b/src/Engine/Network/Client.cpp @@ -92,6 +92,9 @@ void Client::parseMessageType(Packet& packet) case MessageType::Kick: parseKick(); break; + case MessageType::OnPlayerSpawned: + parsePlayersSpawned(); + break; default: break; } @@ -129,6 +132,15 @@ void Client::parseKick() m_IsConnected = false; } +void Client::parsePlayersSpawned(Packet& packet) +{ + Events::PlayerSpawned e; + e.Player = EntityWrapper(m_World, m_ServerIDToClientID[packet.ReadPrimitive()]); + e.Spawner = EntityWrapper(m_World, m_ServerIDToClientID[packet.ReadPrimitive()]); + e.PlayerID = -1; + m_EventBroker->Publish(e); +} + // Fields with strings will not work right now void Client::InterpolateFields(Packet& packet, const ComponentInfo& componentInfo, const EntityID& entityID, const std::string& componentType) { diff --git a/src/Engine/Network/Server.cpp b/src/Engine/Network/Server.cpp index 03b9775a..6f3c6f3a 100644 --- a/src/Engine/Network/Server.cpp +++ b/src/Engine/Network/Server.cpp @@ -132,6 +132,20 @@ void Server::send(Packet& packet, UserID user) } } +void Server::send(Packet& packet, PlayerID player) +{ + int bytesSent = m_Socket.send_to( + boost::asio::buffer(packet.Data(), packet.Size()), + m_PlayerDefinitions[player].Endpoint, + 0); + // Network Debug data + if (isReadingData) { + m_NetworkData.TotalDataSent += packet.Size(); + m_NetworkData.DataSentThisInterval += packet.Size(); + m_NetworkData.AmountOfMessagesSent++; + } +} + void Server::send(Packet & packet) { m_Socket.send_to( @@ -422,3 +436,12 @@ bool Server::OnInputCommand(const Events::InputCommand & e) return true; } + +bool Server::OnPlayerSpawned(const Events::PlayerSpawned & e) +{ + Packet packet = Packet(MessageType::OnPlayerSpawned); + packet.WritePrimitive(e.Player.ID); + packet.WritePrimitive(e.Spawner.ID); + send(packet, e.PlayerID); + return false; +} From b37b20b7d8e755af4d8c2518cd4a1d1f0e27b7d4 Mon Sep 17 00:00:00 2001 From: stiffly Date: Fri, 22 Jan 2016 17:57:31 +0100 Subject: [PATCH 10/24] Didn't bulid lol. Fixed. --- include/Engine/Network/Server.h | 2 +- src/Engine/Network/Client.cpp | 2 +- src/Engine/Network/Server.cpp | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/include/Engine/Network/Server.h b/include/Engine/Network/Server.h index cf649dba..91ea5d21 100644 --- a/include/Engine/Network/Server.h +++ b/include/Engine/Network/Server.h @@ -60,7 +60,7 @@ private: int receive(char* data); void readFromClients(); void send(Packet& packet, UserID user); - void send(Packet& packet, PlayerID player); + void send(PlayerID player, Packet& packet); void send(Packet& packet); void broadcast(Packet& packet); void sendSnapshot(); diff --git a/src/Engine/Network/Client.cpp b/src/Engine/Network/Client.cpp index fb5c3573..98aeb9a8 100644 --- a/src/Engine/Network/Client.cpp +++ b/src/Engine/Network/Client.cpp @@ -93,7 +93,7 @@ void Client::parseMessageType(Packet& packet) parseKick(); break; case MessageType::OnPlayerSpawned: - parsePlayersSpawned(); + parsePlayersSpawned(packet); break; default: break; diff --git a/src/Engine/Network/Server.cpp b/src/Engine/Network/Server.cpp index 6f3c6f3a..b16a6850 100644 --- a/src/Engine/Network/Server.cpp +++ b/src/Engine/Network/Server.cpp @@ -132,7 +132,7 @@ void Server::send(Packet& packet, UserID user) } } -void Server::send(Packet& packet, PlayerID player) +void Server::send(PlayerID player, Packet& packet) { int bytesSent = m_Socket.send_to( boost::asio::buffer(packet.Data(), packet.Size()), @@ -442,6 +442,6 @@ bool Server::OnPlayerSpawned(const Events::PlayerSpawned & e) Packet packet = Packet(MessageType::OnPlayerSpawned); packet.WritePrimitive(e.Player.ID); packet.WritePrimitive(e.Spawner.ID); - send(packet, e.PlayerID); + send(e.PlayerID, packet); return false; } From 406b730ef33e3c74d96ecd9bf264b8c520849fe4 Mon Sep 17 00:00:00 2001 From: stiffly Date: Fri, 22 Jan 2016 19:07:20 +0100 Subject: [PATCH 11/24] Sends entity names. Temporarily --- src/Engine/Network/Client.cpp | 5 +++++ src/Engine/Network/Server.cpp | 6 +++++- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/src/Engine/Network/Client.cpp b/src/Engine/Network/Client.cpp index 98aeb9a8..1dd2bd04 100644 --- a/src/Engine/Network/Client.cpp +++ b/src/Engine/Network/Client.cpp @@ -89,6 +89,7 @@ void Client::parseMessageType(Packet& packet) break; case MessageType::PlayerConnected: parsePlayerConnected(packet); + break; case MessageType::Kick: parseKick(); break; @@ -177,8 +178,12 @@ void Client::parseSnapshot(Packet& packet) { std::string componentType = packet.ReadString(); while (packet.DataReadSize() < packet.Size()) { + // HACK + std::string entityName = packet.ReadString(); // Components EntityID EntityID receivedEntityID = packet.ReadPrimitive(); + // HACK + m_World->SetName(receivedEntityID, entityName); // Parents EntityID EntityID receivedParentEntityID = packet.ReadPrimitive(); ComponentInfo componentInfo = m_World->GetComponents(componentType)->ComponentInfo(); diff --git a/src/Engine/Network/Server.cpp b/src/Engine/Network/Server.cpp index b16a6850..9d0a83d9 100644 --- a/src/Engine/Network/Server.cpp +++ b/src/Engine/Network/Server.cpp @@ -1,6 +1,6 @@ #include "Network/Server.h" -Server::Server() : m_Socket(m_IOService, boost::asio::ip::udp::endpoint(boost::asio::ip::udp::v4(), 13)) +Server::Server() : m_Socket(m_IOService, boost::asio::ip::udp::endpoint(boost::asio::ip::udp::v4(), 27666)) { Network::initialize(); ConfigFile* config = ResourceManager::Load("Config.ini"); @@ -20,6 +20,7 @@ void Server::Start(World* world, EventBroker* eventBroker) m_EventBroker = eventBroker; // Subscribe to events EVENT_SUBSCRIBE_MEMBER(m_EInputCommand, &Server::OnInputCommand); + EVENT_SUBSCRIBE_MEMBER(m_EPlayerSpawned, &Server::OnPlayerSpawned); for (size_t i = 0; i < m_MaxConnections; i++) { m_PlayerDefinitions[i].StopTime = std::clock(); } @@ -180,9 +181,12 @@ void Server::sendSnapshot() Packet packet(MessageType::Snapshot); ComponentPool* componentPool = it.second; ComponentInfo componentInfo = componentPool->ComponentInfo(); + // Component Type packet.WriteString(componentInfo.Name); for (auto& componentWrapper : *componentPool) { + // HACK: Send entity name + packet.WriteString(m_World->GetName(componentWrapper.EntityID)); // Components EntityID packet.WritePrimitive(componentWrapper.EntityID); // Parents EntityID From 55ee2bb3bf1b7ee13a50a86683c517f3a9a0204c Mon Sep 17 00:00:00 2001 From: sippeangelo Date: Fri, 22 Jan 2016 21:35:31 +0100 Subject: [PATCH 12/24] Player input properly separated from editor input and server --- .../Editor/EditorCameraInputController.h | 25 ++++++++++--- .../Engine/Input/FirstPersonInputController.h | 35 ++++++++++--------- src/Engine/Editor/EditorSystem.cpp | 12 +++++-- src/Game/Systems/PlayerMovementSystem.cpp | 7 ++-- 4 files changed, 54 insertions(+), 25 deletions(-) diff --git a/include/Engine/Editor/EditorCameraInputController.h b/include/Engine/Editor/EditorCameraInputController.h index c12113c7..82e8b337 100644 --- a/include/Engine/Editor/EditorCameraInputController.h +++ b/include/Engine/Editor/EditorCameraInputController.h @@ -23,13 +23,17 @@ public: m_SpeedMultiplier = m_Config->Get("Editor.CameraSpeed", 3.f); } - virtual const glm::vec3 Movement() const override - { - return m_Movement * m_SpeedMultiplier; - } + virtual const glm::vec3 Movement() const override { return m_Movement * m_SpeedMultiplier; } + + void Enable() { m_Enabled = true; } + void Disable() { m_Enabled = false; } virtual bool OnCommand(const Events::InputCommand& e) override { + if (!m_MouseLocked) { + return false; + } + ImGuiIO& io = ImGui::GetIO(); if (glm::abs(e.Value) > 0 && (io.WantCaptureKeyboard || io.WantCaptureMouse)) { return false; @@ -64,11 +68,16 @@ public: protected: ConfigFile* m_Config; + bool m_Enabled = false; float m_SpeedMultiplier = 1.f; EventRelay m_EMousePress; bool OnMousePress(const Events::MousePress& e) { + if (!m_Enabled) { + return false; + } + if (e.Button == GLFW_MOUSE_BUTTON_2) { ImGuiIO& io = ImGui::GetIO(); if (!io.WantCaptureMouse) { @@ -80,6 +89,10 @@ protected: EventRelay m_EMouseRelease; bool OnMouseRelease(const Events::MouseRelease& e) { + if (!m_Enabled) { + return false; + } + if (e.Button == GLFW_MOUSE_BUTTON_2) { UnlockMouse(); } @@ -88,6 +101,10 @@ protected: EventRelay m_EMouseScroll; bool OnMouseScroll(const Events::MouseScroll& e) { + if (!m_Enabled) { + return false; + } + m_SpeedMultiplier += e.DeltaY * (0.1f * m_SpeedMultiplier); m_Config->Set("Editor.CameraSpeed", m_SpeedMultiplier); m_Config->SaveToDisk(); diff --git a/include/Engine/Input/FirstPersonInputController.h b/include/Engine/Input/FirstPersonInputController.h index 91445534..cd80fb21 100644 --- a/include/Engine/Input/FirstPersonInputController.h +++ b/include/Engine/Input/FirstPersonInputController.h @@ -18,7 +18,7 @@ public: } virtual const glm::vec3 Movement() const { return m_Movement; } - virtual const glm::vec3 Orientation() const { return m_Orientation; } + virtual const glm::vec3 Rotation() const { return m_Rotation; } void LockMouse() { @@ -40,21 +40,19 @@ public: return false; } - if (m_MouseLocked) { - if (e.Command == "Pitch") { - float val = glm::radians(e.Value); - m_Orientation.x += -val; - m_Orientation.x = glm::clamp(m_Orientation.x, -glm::half_pi(), glm::half_pi()); - //m_Orientation = m_Orientation * glm::angleAxis(-val, glm::vec3(1.f, 0, 0)); - return true; - } + if (e.Command == "Pitch") { + float val = glm::radians(e.Value); + m_Rotation.x += -val; + m_Rotation.x = glm::clamp(m_Rotation.x, -glm::half_pi(), glm::half_pi()); + //m_Rotation = m_Rotation * glm::angleAxis(-val, glm::vec3(1.f, 0, 0)); + return true; + } - if (e.Command == "Yaw") { - float val = glm::radians(e.Value); - m_Orientation.y += -val; - //m_Orientation = glm::angleAxis(-val, glm::vec3(0, 1.f, 0)) * m_Orientation; - return true; - } + if (e.Command == "Yaw") { + float val = glm::radians(e.Value); + m_Rotation.y += -val; + //m_Rotation = glm::angleAxis(-val, glm::vec3(0, 1.f, 0)) * m_Rotation; + return true; } if (e.Command == "Forward" || e.Command == "Right") { @@ -75,11 +73,16 @@ public: return false; } + + virtual void Reset() + { + m_Rotation = glm::vec3(0.f, 0.f, 0.f); + } protected: const int m_PlayerID; bool m_MouseLocked = false; - glm::vec3 m_Orientation; + glm::vec3 m_Rotation; glm::vec3 m_Movement; EventRelay m_ELockMouse; diff --git a/src/Engine/Editor/EditorSystem.cpp b/src/Engine/Editor/EditorSystem.cpp index a357a542..9c0e2e47 100644 --- a/src/Engine/Editor/EditorSystem.cpp +++ b/src/Engine/Editor/EditorSystem.cpp @@ -72,8 +72,8 @@ void EditorSystem::Update(double dt) ComponentWrapper& cameraTransform = m_EditorCamera["Transform"]; glm::vec3& ori = cameraTransform["Orientation"]; - ori.x = m_EditorCameraInputController->Orientation().x; - ori.y = m_EditorCameraInputController->Orientation().y; + ori.x = m_EditorCameraInputController->Rotation().x; + ori.y = m_EditorCameraInputController->Rotation().y; glm::vec3& pos = cameraTransform["Position"]; pos += m_EditorCameraInputController->Movement() * glm::inverse(glm::quat(ori)) * (float)actualDelta; } @@ -81,6 +81,8 @@ void EditorSystem::Update(double dt) void EditorSystem::Enable() { + m_EditorCameraInputController->Enable(); + m_EventBroker->Publish(Events::UnlockMouse()); Events::SetCamera e; e.CameraEntity = m_EditorCamera; m_EventBroker->Publish(e); @@ -90,6 +92,8 @@ void EditorSystem::Enable() void EditorSystem::Disable() { + m_EditorCameraInputController->Disable(); + m_EventBroker->Publish(Events::LockMouse()); Events::SetCamera e; e.CameraEntity = m_ActualCamera; m_EventBroker->Publish(e); @@ -179,6 +183,10 @@ bool EditorSystem::OnWidgetDelta(const Events::WidgetDelta& e) bool EditorSystem::OnInputCommand(const Events::InputCommand& e) { + if (e.PlayerID != -1) { + return false; + } + if (e.Command == "ToggleEditor" && e.Value > 0) { if (m_Enabled) { Disable(); diff --git a/src/Game/Systems/PlayerMovementSystem.cpp b/src/Game/Systems/PlayerMovementSystem.cpp index 351acad5..843601e8 100644 --- a/src/Game/Systems/PlayerMovementSystem.cpp +++ b/src/Game/Systems/PlayerMovementSystem.cpp @@ -27,16 +27,17 @@ void PlayerMovementSystem::Update(double dt) EntityWrapper cameraEntity = player.FirstChildByName("Camera"); if (cameraEntity.Valid()) { glm::vec3& cameraOrientation = cameraEntity["Transform"]["Orientation"]; - cameraOrientation.x = controller->Orientation().x; + cameraOrientation.x += controller->Rotation().x; } ComponentWrapper& cTransform = player["Transform"]; glm::vec3& ori = cTransform["Orientation"]; - ori.y = controller->Orientation().y; + ori.y += controller->Rotation().y; glm::vec3& pos = cTransform["Position"]; pos += controller->Movement() * glm::inverse(glm::quat(ori)) * (float)player["Player"]["MovementSpeed"] * (float)dt; - + + controller->Reset(); } } From 3ac3311c0c5342459d81270772eb6bbcbd008f43 Mon Sep 17 00:00:00 2001 From: sippeangelo Date: Sat, 23 Jan 2016 00:37:47 +0100 Subject: [PATCH 13/24] "inline" caused missing symbol when compiling in Release for some reason --- include/Engine/Core/Octree.h | 2 +- src/Engine/Core/Octree.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/include/Engine/Core/Octree.h b/include/Engine/Core/Octree.h index bbd27b3c..8bac5503 100644 --- a/include/Engine/Core/Octree.h +++ b/include/Engine/Core/Octree.h @@ -111,7 +111,7 @@ struct Child std::vector& m_StaticObjectsRef; std::vector& m_DynamicObjectsRef; - inline bool hasChildren() const; + bool hasChildren() const; int childIndexContainingPoint(const glm::vec3& point) const; std::vector childIndicesContainingBox(const AABB& box) const; }; diff --git a/src/Engine/Core/Octree.cpp b/src/Engine/Core/Octree.cpp index d7feba45..18effea5 100644 --- a/src/Engine/Core/Octree.cpp +++ b/src/Engine/Core/Octree.cpp @@ -276,7 +276,7 @@ std::vector Child::childIndicesContainingBox(const AABB& box) const } } -inline bool Child::hasChildren() const +bool Child::hasChildren() const { return m_Children[0] != nullptr; } From 31e7340daf4ebd0993a17bb229105b17f4f08a7e Mon Sep 17 00:00:00 2001 From: sippeangelo Date: Sat, 23 Jan 2016 00:40:18 +0100 Subject: [PATCH 14/24] Ignoring interpolation and rendering for local player entities! --- assets | 2 +- .../Editor/EditorCameraInputController.h | 2 +- include/Engine/Rendering/RenderSystem.h | 5 ++ include/Game/Systems/InterpolationSystem.h | 13 ++--- resources/Schema/Entities/Player.xml | 47 +++++++++++++++---- src/Engine/Core/EntityWrapper.cpp | 3 ++ src/Engine/Rendering/RenderSystem.cpp | 35 +++++++++++++- src/Game/Systems/InterpolationSystem.cpp | 29 ++++++++++-- 8 files changed, 113 insertions(+), 23 deletions(-) diff --git a/assets b/assets index 2a800ea9..e8174f63 160000 --- a/assets +++ b/assets @@ -1 +1 @@ -Subproject commit 2a800ea92b323646432c65217d55aab6750d5a72 +Subproject commit e8174f630fc3242e15ada1346b42c72f44cbc854 diff --git a/include/Engine/Editor/EditorCameraInputController.h b/include/Engine/Editor/EditorCameraInputController.h index 82e8b337..66c7952a 100644 --- a/include/Engine/Editor/EditorCameraInputController.h +++ b/include/Engine/Editor/EditorCameraInputController.h @@ -30,7 +30,7 @@ public: virtual bool OnCommand(const Events::InputCommand& e) override { - if (!m_MouseLocked) { + if (glm::abs(e.Value) > 0 && !m_MouseLocked) { return false; } diff --git a/include/Engine/Rendering/RenderSystem.h b/include/Engine/Rendering/RenderSystem.h index ef824ea5..4c23c6c6 100644 --- a/include/Engine/Rendering/RenderSystem.h +++ b/include/Engine/Rendering/RenderSystem.h @@ -15,6 +15,7 @@ #include "Renderer.h" #include "PointLightJob.h" #include "../Core/Transform.h" +#include "../../Game/Events/EPlayerSpawned.h" class RenderSystem : public ImpureSystem { @@ -29,6 +30,7 @@ private: RenderFrame* m_RenderFrame; Camera* m_Camera; EntityWrapper m_CurrentCamera = EntityWrapper::Invalid; + EntityWrapper m_LocalPlayer = EntityWrapper::Invalid; EventRelay m_ESetCamera; bool OnSetCamera(Events::SetCamera &event); @@ -40,6 +42,9 @@ private: void fillModels(std::list>& jobs); void fillLight(std::list>& jobs); + + EventRelay m_EPlayerSpawned; + bool OnPlayerSpawned(Events::PlayerSpawned& e); }; #endif \ No newline at end of file diff --git a/include/Game/Systems/InterpolationSystem.h b/include/Game/Systems/InterpolationSystem.h index 0e137598..707c0acf 100644 --- a/include/Game/Systems/InterpolationSystem.h +++ b/include/Game/Systems/InterpolationSystem.h @@ -12,6 +12,7 @@ #include "Core/EventBroker.h" #include "Core/ResourceManager.h" #include "Core/ConfigFile.h" +#include "Events/EPlayerSpawned.h" #include "Network/EInterpolate.h" @@ -25,19 +26,13 @@ class InterpolationSystem : public PureSystem double interpolationTime; }; public: - InterpolationSystem(World* world, EventBroker* eventBroker) - : System(world, eventBroker) - , PureSystem("Transform") - { - ConfigFile* config = ResourceManager::Load("Config.ini"); - m_SnapshotInterval = config->Get("Networking.SnapshotInterval", 0.05); - EVENT_SUBSCRIBE_MEMBER(m_EInterpolate, &InterpolationSystem::OnInterpolate); - } + InterpolationSystem(World* world, EventBroker* eventBroker); ~InterpolationSystem() { } virtual void UpdateComponent(EntityWrapper& entity, ComponentWrapper& transform, double dt) override; private: std::unordered_map m_NextTransform; std::unordered_map m_LastReceivedTransform; + EntityWrapper m_LocalPlayer = EntityWrapper::Invalid; //glm::vec3 vectorInterpolation(glm::vec3 prev, glm::vec3 next, double currentTime); template @@ -51,6 +46,8 @@ private: EventRelay m_EInterpolate; bool InterpolationSystem::OnInterpolate(const Events::Interpolate& e); + EventRelay m_EPlayerSpawned; + bool OnPlayerSpawned(Events::PlayerSpawned& e); }; #endif diff --git a/resources/Schema/Entities/Player.xml b/resources/Schema/Entities/Player.xml index 087b1f7e..fa8b7686 100644 --- a/resources/Schema/Entities/Player.xml +++ b/resources/Schema/Entities/Player.xml @@ -11,9 +11,13 @@ 3 + + + + + - - + @@ -21,22 +25,47 @@ - - Models/Camera.obj - false - - + - + + + + + + Fonts/DroidSans.ttf,100 + + + + + + + + + + + + + + Models/Camera.obj + + + + + + + + + Models/Camera.obj + false @@ -48,7 +77,7 @@ - Models/Assault.obj + Models/AssaultHeadless.obj diff --git a/src/Engine/Core/EntityWrapper.cpp b/src/Engine/Core/EntityWrapper.cpp index 6177d91d..2f9c17db 100644 --- a/src/Engine/Core/EntityWrapper.cpp +++ b/src/Engine/Core/EntityWrapper.cpp @@ -5,6 +5,9 @@ const EntityWrapper EntityWrapper::Invalid = EntityWrapper(nullptr, EntityID_Inv bool EntityWrapper::HasComponent(const std::string& componentName) { + if (!Valid()) { + return false; + } return World->HasComponent(ID, componentName); } diff --git a/src/Engine/Rendering/RenderSystem.cpp b/src/Engine/Rendering/RenderSystem.cpp index 5aa0108e..a478bb43 100644 --- a/src/Engine/Rendering/RenderSystem.cpp +++ b/src/Engine/Rendering/RenderSystem.cpp @@ -7,6 +7,7 @@ RenderSystem::RenderSystem(World* world, EventBroker* eventBroker, const IRender { EVENT_SUBSCRIBE_MEMBER(m_ESetCamera, &RenderSystem::OnSetCamera); EVENT_SUBSCRIBE_MEMBER(m_EInputCommand, &RenderSystem::OnInputCommand); + EVENT_SUBSCRIBE_MEMBER(m_EPlayerSpawned, &RenderSystem::OnPlayerSpawned); m_Camera = new Camera((float)m_Renderer->Resolution().Width / m_Renderer->Resolution().Height, glm::radians(45.f), 0.01f, 5000.f); } @@ -46,6 +47,18 @@ void RenderSystem::fillModels(std::list>& jobs) continue; } + EntityWrapper entity(m_World, modelComponent.EntityID); + bool isLocalPlayer = entity == m_LocalPlayer; + while (entity.Parent().Valid()) { + entity = entity.Parent(); + if (entity == m_LocalPlayer) { + isLocalPlayer = true; + } + } + if (isLocalPlayer) { + continue; + } + Model* model; try { model = ResourceManager::Load<::Model, true>(resource); @@ -68,6 +81,14 @@ void RenderSystem::fillModels(std::list>& jobs) } } +bool RenderSystem::OnPlayerSpawned(Events::PlayerSpawned& e) +{ + if (e.PlayerID == -1) { + m_LocalPlayer = e.Player; + } + return true; +} + void RenderSystem::fillPointLights(std::list>& jobs, World* world) { auto pointLights = m_World->GetComponents("PointLight"); @@ -128,6 +149,18 @@ void RenderSystem::fillText(std::list>& jobs, World* continue; } + EntityWrapper entity(m_World, textComponent.EntityID); + bool isLocalPlayer = entity == m_LocalPlayer; + while (entity.Parent().Valid()) { + entity = entity.Parent(); + if (entity == m_LocalPlayer) { + isLocalPlayer = true; + } + } + if (isLocalPlayer) { + continue; + } + Font* font; try { font = ResourceManager::Load(resource); @@ -169,7 +202,7 @@ void RenderSystem::Update(double dt) fillModels(scene.ForwardJobs); fillPointLights(scene.PointLightJobs, m_World); fillDirectionalLights(scene.DirectionalLightJobs, m_World); - fillText(scene.TextJobs, world); + fillText(scene.TextJobs, m_World); m_RenderFrame->Add(scene); } \ No newline at end of file diff --git a/src/Game/Systems/InterpolationSystem.cpp b/src/Game/Systems/InterpolationSystem.cpp index be2c9a4f..84f50456 100644 --- a/src/Game/Systems/InterpolationSystem.cpp +++ b/src/Game/Systems/InterpolationSystem.cpp @@ -1,5 +1,15 @@ #include "Systems/InterpolationSystem.h" +InterpolationSystem::InterpolationSystem(World* world, EventBroker* eventBroker) + : System(world, eventBroker) + , PureSystem("Transform") +{ + ConfigFile* config = ResourceManager::Load("Config.ini"); + m_SnapshotInterval = config->Get("Networking.SnapshotInterval", 0.05); + EVENT_SUBSCRIBE_MEMBER(m_EInterpolate, &InterpolationSystem::OnInterpolate); + EVENT_SUBSCRIBE_MEMBER(m_EPlayerSpawned, &InterpolationSystem::OnPlayerSpawned); +} + void InterpolationSystem::UpdateComponent(EntityWrapper& entity, ComponentWrapper& transform, double dt) { if (m_NextTransform.find(transform.EntityID) != m_NextTransform.end()) { // Exists in map @@ -17,14 +27,21 @@ void InterpolationSystem::UpdateComponent(EntityWrapper& entity, ComponentWrappe } } if (transform.Info.Name == "Transform") { + bool isLocalPlayer = entity == m_LocalPlayer || entity.Parent() == m_LocalPlayer; // Position glm::vec3 nextPosition = sTransform.Position; glm::vec3 currentPosition = static_cast(transform["Position"]); + if (isLocalPlayer && glm::length(nextPosition - currentPosition) < 1.f) { + return; + } (glm::vec3&)transform["Position"] += vectorInterpolation(currentPosition, nextPosition, sTransform.interpolationTime); // Orientation - glm::quat nextOrientation = sTransform.Orientation; - glm::quat currentOrientation = glm::quat(static_cast(transform["Orientation"])); - (glm::vec3&)transform["Orientation"] = glm::eulerAngles(glm::slerp(currentOrientation, nextOrientation, sTransform.interpolationTime / m_SnapshotInterval)); + //bool isPlayer = entity.HasComponent("Player") || entity.Parent().HasComponent("Player"); + if (!isLocalPlayer) { + glm::quat nextOrientation = sTransform.Orientation; + glm::quat currentOrientation = glm::quat(static_cast(transform["Orientation"])); + (glm::vec3&)transform["Orientation"] = glm::eulerAngles(glm::slerp(currentOrientation, nextOrientation, sTransform.interpolationTime / m_SnapshotInterval)); + } // Scale glm::vec3 nextScale = sTransform.Scale; glm::vec3 currentScale = static_cast(transform["Scale"]); @@ -33,6 +50,12 @@ void InterpolationSystem::UpdateComponent(EntityWrapper& entity, ComponentWrappe } } +bool InterpolationSystem::OnPlayerSpawned(Events::PlayerSpawned& e) +{ + m_LocalPlayer = e.Player; + return true; +} + bool InterpolationSystem::OnInterpolate(const Events::Interpolate & e) { Transform transform; From db0e67b9bd39093d5a2046ae1e6c28c77f18ce77 Mon Sep 17 00:00:00 2001 From: sippeangelo Date: Sat, 23 Jan 2016 11:44:16 +0100 Subject: [PATCH 15/24] Added EntityWrapper::IsChildOf and made snapshot interpolation and rendering exceptions for player less hacky --- .../Events => Engine/Core}/EPlayerSpawned.h | 0 include/Engine/Core/EntityWrapper.h | 1 + include/Engine/Rendering/RenderSystem.h | 2 +- include/Game/Systems/InterpolationSystem.h | 2 +- src/Engine/Core/EntityWrapper.cpp | 12 ++++++++++ src/Engine/Rendering/RenderSystem.cpp | 23 +++---------------- src/Game/Systems/InterpolationSystem.cpp | 5 ++-- 7 files changed, 21 insertions(+), 24 deletions(-) rename include/{Game/Events => Engine/Core}/EPlayerSpawned.h (100%) diff --git a/include/Game/Events/EPlayerSpawned.h b/include/Engine/Core/EPlayerSpawned.h similarity index 100% rename from include/Game/Events/EPlayerSpawned.h rename to include/Engine/Core/EPlayerSpawned.h diff --git a/include/Engine/Core/EntityWrapper.h b/include/Engine/Core/EntityWrapper.h index d0e5e31f..711f5045 100644 --- a/include/Engine/Core/EntityWrapper.h +++ b/include/Engine/Core/EntityWrapper.h @@ -26,6 +26,7 @@ struct EntityWrapper bool HasComponent(const std::string& componentName); EntityWrapper Parent(); EntityWrapper FirstChildByName(const std::string& name); + bool IsChildOf(EntityWrapper potentialParent); bool Valid(); ComponentWrapper operator[](const char* componentName); diff --git a/include/Engine/Rendering/RenderSystem.h b/include/Engine/Rendering/RenderSystem.h index 4c23c6c6..005d2eb7 100644 --- a/include/Engine/Rendering/RenderSystem.h +++ b/include/Engine/Rendering/RenderSystem.h @@ -15,7 +15,7 @@ #include "Renderer.h" #include "PointLightJob.h" #include "../Core/Transform.h" -#include "../../Game/Events/EPlayerSpawned.h" +#include "../Core/EPlayerSpawned.h" class RenderSystem : public ImpureSystem { diff --git a/include/Game/Systems/InterpolationSystem.h b/include/Game/Systems/InterpolationSystem.h index 707c0acf..1e345c91 100644 --- a/include/Game/Systems/InterpolationSystem.h +++ b/include/Game/Systems/InterpolationSystem.h @@ -12,7 +12,7 @@ #include "Core/EventBroker.h" #include "Core/ResourceManager.h" #include "Core/ConfigFile.h" -#include "Events/EPlayerSpawned.h" +#include "Core/EPlayerSpawned.h" #include "Network/EInterpolate.h" diff --git a/src/Engine/Core/EntityWrapper.cpp b/src/Engine/Core/EntityWrapper.cpp index 2f9c17db..55d341e1 100644 --- a/src/Engine/Core/EntityWrapper.cpp +++ b/src/Engine/Core/EntityWrapper.cpp @@ -36,6 +36,18 @@ EntityWrapper EntityWrapper::FirstChildByName(const std::string& name) return EntityWrapper::Invalid; } +bool EntityWrapper::IsChildOf(EntityWrapper potentialParent) +{ + EntityWrapper entity = *this; + while (entity.Parent().Valid()) { + entity = entity.Parent(); + if (entity == potentialParent) { + return true; + } + } + return false; +} + bool EntityWrapper::Valid() { if (this->World == nullptr) { diff --git a/src/Engine/Rendering/RenderSystem.cpp b/src/Engine/Rendering/RenderSystem.cpp index a478bb43..a8f330f0 100644 --- a/src/Engine/Rendering/RenderSystem.cpp +++ b/src/Engine/Rendering/RenderSystem.cpp @@ -48,14 +48,9 @@ void RenderSystem::fillModels(std::list>& jobs) } EntityWrapper entity(m_World, modelComponent.EntityID); - bool isLocalPlayer = entity == m_LocalPlayer; - while (entity.Parent().Valid()) { - entity = entity.Parent(); - if (entity == m_LocalPlayer) { - isLocalPlayer = true; - } - } - if (isLocalPlayer) { + + // Don't render the local player + if (entity == m_LocalPlayer || entity.IsChildOf(m_LocalPlayer)) { continue; } @@ -149,18 +144,6 @@ void RenderSystem::fillText(std::list>& jobs, World* continue; } - EntityWrapper entity(m_World, textComponent.EntityID); - bool isLocalPlayer = entity == m_LocalPlayer; - while (entity.Parent().Valid()) { - entity = entity.Parent(); - if (entity == m_LocalPlayer) { - isLocalPlayer = true; - } - } - if (isLocalPlayer) { - continue; - } - Font* font; try { font = ResourceManager::Load(resource); diff --git a/src/Game/Systems/InterpolationSystem.cpp b/src/Game/Systems/InterpolationSystem.cpp index 84f50456..2b6e82f2 100644 --- a/src/Game/Systems/InterpolationSystem.cpp +++ b/src/Game/Systems/InterpolationSystem.cpp @@ -27,16 +27,17 @@ void InterpolationSystem::UpdateComponent(EntityWrapper& entity, ComponentWrappe } } if (transform.Info.Name == "Transform") { - bool isLocalPlayer = entity == m_LocalPlayer || entity.Parent() == m_LocalPlayer; + bool isLocalPlayer = entity == m_LocalPlayer || entity.IsChildOf(m_LocalPlayer); // Position glm::vec3 nextPosition = sTransform.Position; glm::vec3 currentPosition = static_cast(transform["Position"]); + // HACK: Hardcoded tolerance value for player position desync = 1 if (isLocalPlayer && glm::length(nextPosition - currentPosition) < 1.f) { return; } (glm::vec3&)transform["Position"] += vectorInterpolation(currentPosition, nextPosition, sTransform.interpolationTime); // Orientation - //bool isPlayer = entity.HasComponent("Player") || entity.Parent().HasComponent("Player"); + // Don't force orientation for players if (!isLocalPlayer) { glm::quat nextOrientation = sTransform.Orientation; glm::quat currentOrientation = glm::quat(static_cast(transform["Orientation"])); From 4d5cbb60574239816bb3e4d378b6aeb2077c0770 Mon Sep 17 00:00:00 2001 From: sippeangelo Date: Sat, 23 Jan 2016 12:14:00 +0100 Subject: [PATCH 16/24] fixup! Added EntityWrapper::IsChildOf and made snapshot interpolation and rendering exceptions for player less hacky --- include/Engine/Network/Client.h | 2 +- include/Engine/Network/Server.h | 3 +-- include/Game/Systems/PlayerMovementSystem.h | 2 +- include/Game/Systems/PlayerSpawnSystem.h | 2 +- 4 files changed, 4 insertions(+), 5 deletions(-) diff --git a/include/Engine/Network/Client.h b/include/Engine/Network/Client.h index 9717d22f..92d78f4a 100644 --- a/include/Engine/Network/Client.h +++ b/include/Engine/Network/Client.h @@ -20,7 +20,7 @@ #include "Input/EInputCommand.h" #include "Core/EPlayerDamage.h" #include "Network/EInterpolate.h" -#include "Game/Events/EPlayerSpawned.h" +#include "Core/EPlayerSpawned.h" class Client : public Network { diff --git a/include/Engine/Network/Server.h b/include/Engine/Network/Server.h index 91ea5d21..e7c745e7 100644 --- a/include/Engine/Network/Server.h +++ b/include/Engine/Network/Server.h @@ -15,8 +15,7 @@ #include "Input/EInputCommand.h" #include "Core/EPlayerDamage.h" #include "Network/EPlayerDisconnected.h" - -#include "Game/Events/EPlayerSpawned.h" +#include "Core/EPlayerSpawned.h" class Server : public Network { diff --git a/include/Game/Systems/PlayerMovementSystem.h b/include/Game/Systems/PlayerMovementSystem.h index f5b6539b..72f3b879 100644 --- a/include/Game/Systems/PlayerMovementSystem.h +++ b/include/Game/Systems/PlayerMovementSystem.h @@ -1,7 +1,7 @@ #include "Common.h" #include "GLM.h" #include "Core/System.h" -#include "Events/EPlayerSpawned.h" +#include "Core/EPlayerSpawned.h" #include "Input/FirstPersonInputController.h" class PlayerMovementSystem : public ImpureSystem, PureSystem diff --git a/include/Game/Systems/PlayerSpawnSystem.h b/include/Game/Systems/PlayerSpawnSystem.h index 6c0f6ce3..eb4d3c97 100644 --- a/include/Game/Systems/PlayerSpawnSystem.h +++ b/include/Game/Systems/PlayerSpawnSystem.h @@ -2,7 +2,7 @@ #include "Input/EInputCommand.h" #include "Systems/SpawnerSystem.h" #include "Events/ESpawnerSpawn.h" -#include "Events/EPlayerSpawned.h" +#include "Core/EPlayerSpawned.h" #include "Rendering/ESetCamera.h" #include "Core/ConfigFile.h" From 3aeeb3cad5e7aa3c9743e3bde3c4a27eb1eaf90d Mon Sep 17 00:00:00 2001 From: sippeangelo Date: Sat, 23 Jan 2016 11:54:03 +0100 Subject: [PATCH 17/24] Moved FirstPersonInputController implementation out of header --- .../Engine/Input/FirstPersonInputController.h | 74 ++-------------- .../Input/FirstPersonInputController.cpp | 87 +++++++++++++++++++ 2 files changed, 94 insertions(+), 67 deletions(-) create mode 100644 src/Engine/Input/FirstPersonInputController.cpp diff --git a/include/Engine/Input/FirstPersonInputController.h b/include/Engine/Input/FirstPersonInputController.h index cd80fb21..4a55bf39 100644 --- a/include/Engine/Input/FirstPersonInputController.h +++ b/include/Engine/Input/FirstPersonInputController.h @@ -9,75 +9,15 @@ template class FirstPersonInputController : public InputController { public: - FirstPersonInputController(EventBroker* eventBroker, int playerID) - : InputController(eventBroker) - , m_PlayerID(playerID) - { - EVENT_SUBSCRIBE_MEMBER(m_ELockMouse, &FirstPersonInputController::OnLockMouse); - EVENT_SUBSCRIBE_MEMBER(m_EUnlockMouse, &FirstPersonInputController::OnUnlockMouse); - } + FirstPersonInputController(EventBroker* eventBroker, int playerID); virtual const glm::vec3 Movement() const { return m_Movement; } virtual const glm::vec3 Rotation() const { return m_Rotation; } - void LockMouse() - { - Events::LockMouse e; - m_EventBroker->Publish(e); - m_MouseLocked = true; - } - - void UnlockMouse() - { - Events::UnlockMouse e; - m_EventBroker->Publish(e); - m_MouseLocked = false; - } - - virtual bool OnCommand(const Events::InputCommand& e) override - { - if (m_PlayerID != e.PlayerID) { - return false; - } - - if (e.Command == "Pitch") { - float val = glm::radians(e.Value); - m_Rotation.x += -val; - m_Rotation.x = glm::clamp(m_Rotation.x, -glm::half_pi(), glm::half_pi()); - //m_Rotation = m_Rotation * glm::angleAxis(-val, glm::vec3(1.f, 0, 0)); - return true; - } - - if (e.Command == "Yaw") { - float val = glm::radians(e.Value); - m_Rotation.y += -val; - //m_Rotation = glm::angleAxis(-val, glm::vec3(0, 1.f, 0)) * m_Rotation; - return true; - } - - if (e.Command == "Forward" || e.Command == "Right") { - if (e.Command == "Forward") { - float val = glm::clamp(e.Value, -1.f, 1.f); - m_Movement.z = -val; - return true; - } - if (e.Command == "Right") { - float val = glm::clamp(e.Value, -1.f, 1.f); - m_Movement.x = val; - return true; - } - if (glm::length2(m_Movement) > 0) { - m_Movement = glm::normalize(m_Movement); - } - } - - return false; - } - - virtual void Reset() - { - m_Rotation = glm::vec3(0.f, 0.f, 0.f); - } + void LockMouse(); + void UnlockMouse(); + virtual bool OnCommand(const Events::InputCommand& e) override; + virtual void Reset(); protected: const int m_PlayerID; @@ -86,9 +26,9 @@ protected: glm::vec3 m_Movement; EventRelay m_ELockMouse; - bool OnLockMouse(const Events::LockMouse& e) { m_MouseLocked = true; return true; } + bool OnLockMouse(const Events::LockMouse& e); EventRelay m_EUnlockMouse; - bool OnUnlockMouse(const Events::UnlockMouse& e) { m_MouseLocked = false; return true; } + bool OnUnlockMouse(const Events::UnlockMouse& e); }; #endif \ No newline at end of file diff --git a/src/Engine/Input/FirstPersonInputController.cpp b/src/Engine/Input/FirstPersonInputController.cpp new file mode 100644 index 00000000..cdacc606 --- /dev/null +++ b/src/Engine/Input/FirstPersonInputController.cpp @@ -0,0 +1,87 @@ +#include "Input/FirstPersonInputController.h" + +template +FirstPersonInputController::FirstPersonInputController(EventBroker* eventBroker, int playerID) + : InputController(eventBroker) + , m_PlayerID(playerID) +{ + EVENT_SUBSCRIBE_MEMBER(m_ELockMouse, &FirstPersonInputController::OnLockMouse); + EVENT_SUBSCRIBE_MEMBER(m_EUnlockMouse, &FirstPersonInputController::OnUnlockMouse); +} + +template +void FirstPersonInputController::Reset() +{ + m_Rotation = glm::vec3(0.f, 0.f, 0.f); +} + +template +void FirstPersonInputController::LockMouse() +{ + Events::LockMouse e; + m_EventBroker->Publish(e); + m_MouseLocked = true; +} + +template +void FirstPersonInputController::UnlockMouse() +{ + Events::UnlockMouse e; + m_EventBroker->Publish(e); + m_MouseLocked = false; +} + +template +bool FirstPersonInputController::OnCommand(const Events::InputCommand& e) +{ + if (m_PlayerID != e.PlayerID) { + return false; + } + + if (e.Command == "Pitch") { + float val = glm::radians(e.Value); + m_Rotation.x += -val; + m_Rotation.x = glm::clamp(m_Rotation.x, -glm::half_pi(), glm::half_pi()); + //m_Rotation = m_Rotation * glm::angleAxis(-val, glm::vec3(1.f, 0, 0)); + return true; + } + + if (e.Command == "Yaw") { + float val = glm::radians(e.Value); + m_Rotation.y += -val; + //m_Rotation = glm::angleAxis(-val, glm::vec3(0, 1.f, 0)) * m_Rotation; + return true; + } + + if (e.Command == "Forward" || e.Command == "Right") { + if (e.Command == "Forward") { + float val = glm::clamp(e.Value, -1.f, 1.f); + m_Movement.z = -val; + return true; + } + if (e.Command == "Right") { + float val = glm::clamp(e.Value, -1.f, 1.f); + m_Movement.x = val; + return true; + } + if (glm::length2(m_Movement) > 0) { + m_Movement = glm::normalize(m_Movement); + } + } + + return false; +} + +template +bool FirstPersonInputController::OnUnlockMouse(const Events::UnlockMouse& e) +{ + m_MouseLocked = false; + return true; +} + +template +bool FirstPersonInputController::OnLockMouse(const Events::LockMouse& e) +{ + m_MouseLocked = true; + return true; +} From 32f73201c5cc1dfca7513722889c9e332e905fdc Mon Sep 17 00:00:00 2001 From: sippeangelo Date: Sat, 23 Jan 2016 12:15:24 +0100 Subject: [PATCH 18/24] Basic jumping! --- .../Engine/Input/FirstPersonInputController.h | 93 +++++++++++++++++++ .../Input/FirstPersonInputController.cpp | 85 ----------------- src/Game/Systems/PlayerMovementSystem.cpp | 9 ++ 3 files changed, 102 insertions(+), 85 deletions(-) diff --git a/include/Engine/Input/FirstPersonInputController.h b/include/Engine/Input/FirstPersonInputController.h index 4a55bf39..426670c4 100644 --- a/include/Engine/Input/FirstPersonInputController.h +++ b/include/Engine/Input/FirstPersonInputController.h @@ -13,6 +13,8 @@ public: virtual const glm::vec3 Movement() const { return m_Movement; } virtual const glm::vec3 Rotation() const { return m_Rotation; } + virtual bool Jumping() const { return m_Jumping; } + virtual bool Crouching() const { return m_Crouching; } void LockMouse(); void UnlockMouse(); @@ -24,6 +26,8 @@ protected: bool m_MouseLocked = false; glm::vec3 m_Rotation; glm::vec3 m_Movement; + bool m_Jumping = false; + bool m_Crouching = false; EventRelay m_ELockMouse; bool OnLockMouse(const Events::LockMouse& e); @@ -31,4 +35,93 @@ protected: bool OnUnlockMouse(const Events::UnlockMouse& e); }; +template +FirstPersonInputController::FirstPersonInputController(EventBroker* eventBroker, int playerID) + : InputController(eventBroker) + , m_PlayerID(playerID) +{ + EVENT_SUBSCRIBE_MEMBER(m_ELockMouse, &FirstPersonInputController::OnLockMouse); + EVENT_SUBSCRIBE_MEMBER(m_EUnlockMouse, &FirstPersonInputController::OnUnlockMouse); +} + +template +void FirstPersonInputController::Reset() +{ + m_Rotation = glm::vec3(0.f, 0.f, 0.f); + m_Jumping = false; +} + +template +void FirstPersonInputController::LockMouse() +{ + Events::LockMouse e; + m_EventBroker->Publish(e); + m_MouseLocked = true; +} + +template +void FirstPersonInputController::UnlockMouse() +{ + Events::UnlockMouse e; + m_EventBroker->Publish(e); + m_MouseLocked = false; +} + +template +bool FirstPersonInputController::OnCommand(const Events::InputCommand& e) +{ + if (m_PlayerID != e.PlayerID) { + return false; + } + + if (e.Command == "Pitch") { + float val = glm::radians(e.Value); + m_Rotation.x += -val; + //m_Rotation.x = glm::clamp(m_Rotation.x, -glm::half_pi(), glm::half_pi()); + } + + if (e.Command == "Yaw") { + float val = glm::radians(e.Value); + m_Rotation.y += -val; + } + + if (e.Command == "Forward" || e.Command == "Right") { + if (e.Command == "Forward") { + float val = glm::clamp(e.Value, -1.f, 1.f); + m_Movement.z = -val; + } + if (e.Command == "Right") { + float val = glm::clamp(e.Value, -1.f, 1.f); + m_Movement.x = val; + } + if (glm::length2(m_Movement) > 0) { + m_Movement = glm::normalize(m_Movement); + } + } + + if (e.Command == "Jump") { + m_Jumping = e.Value > 0; + } + + if (e.Command == "Crouch") { + m_Crouching = e.Value > 0; + } + + return true; +} + +template +bool FirstPersonInputController::OnUnlockMouse(const Events::UnlockMouse& e) +{ + m_MouseLocked = false; + return true; +} + +template +bool FirstPersonInputController::OnLockMouse(const Events::LockMouse& e) +{ + m_MouseLocked = true; + return true; +} + #endif \ No newline at end of file diff --git a/src/Engine/Input/FirstPersonInputController.cpp b/src/Engine/Input/FirstPersonInputController.cpp index cdacc606..d3757dd0 100644 --- a/src/Engine/Input/FirstPersonInputController.cpp +++ b/src/Engine/Input/FirstPersonInputController.cpp @@ -1,87 +1,2 @@ #include "Input/FirstPersonInputController.h" -template -FirstPersonInputController::FirstPersonInputController(EventBroker* eventBroker, int playerID) - : InputController(eventBroker) - , m_PlayerID(playerID) -{ - EVENT_SUBSCRIBE_MEMBER(m_ELockMouse, &FirstPersonInputController::OnLockMouse); - EVENT_SUBSCRIBE_MEMBER(m_EUnlockMouse, &FirstPersonInputController::OnUnlockMouse); -} - -template -void FirstPersonInputController::Reset() -{ - m_Rotation = glm::vec3(0.f, 0.f, 0.f); -} - -template -void FirstPersonInputController::LockMouse() -{ - Events::LockMouse e; - m_EventBroker->Publish(e); - m_MouseLocked = true; -} - -template -void FirstPersonInputController::UnlockMouse() -{ - Events::UnlockMouse e; - m_EventBroker->Publish(e); - m_MouseLocked = false; -} - -template -bool FirstPersonInputController::OnCommand(const Events::InputCommand& e) -{ - if (m_PlayerID != e.PlayerID) { - return false; - } - - if (e.Command == "Pitch") { - float val = glm::radians(e.Value); - m_Rotation.x += -val; - m_Rotation.x = glm::clamp(m_Rotation.x, -glm::half_pi(), glm::half_pi()); - //m_Rotation = m_Rotation * glm::angleAxis(-val, glm::vec3(1.f, 0, 0)); - return true; - } - - if (e.Command == "Yaw") { - float val = glm::radians(e.Value); - m_Rotation.y += -val; - //m_Rotation = glm::angleAxis(-val, glm::vec3(0, 1.f, 0)) * m_Rotation; - return true; - } - - if (e.Command == "Forward" || e.Command == "Right") { - if (e.Command == "Forward") { - float val = glm::clamp(e.Value, -1.f, 1.f); - m_Movement.z = -val; - return true; - } - if (e.Command == "Right") { - float val = glm::clamp(e.Value, -1.f, 1.f); - m_Movement.x = val; - return true; - } - if (glm::length2(m_Movement) > 0) { - m_Movement = glm::normalize(m_Movement); - } - } - - return false; -} - -template -bool FirstPersonInputController::OnUnlockMouse(const Events::UnlockMouse& e) -{ - m_MouseLocked = false; - return true; -} - -template -bool FirstPersonInputController::OnLockMouse(const Events::LockMouse& e) -{ - m_MouseLocked = true; - return true; -} diff --git a/src/Game/Systems/PlayerMovementSystem.cpp b/src/Game/Systems/PlayerMovementSystem.cpp index 843601e8..10fc29f6 100644 --- a/src/Game/Systems/PlayerMovementSystem.cpp +++ b/src/Game/Systems/PlayerMovementSystem.cpp @@ -28,6 +28,8 @@ void PlayerMovementSystem::Update(double dt) if (cameraEntity.Valid()) { glm::vec3& cameraOrientation = cameraEntity["Transform"]["Orientation"]; cameraOrientation.x += controller->Rotation().x; + // Limit camera pitch so we don't break our necks + cameraOrientation.x = glm::clamp(cameraOrientation.x, -glm::half_pi(), glm::half_pi()); } ComponentWrapper& cTransform = player["Transform"]; @@ -36,6 +38,13 @@ void PlayerMovementSystem::Update(double dt) glm::vec3& pos = cTransform["Position"]; pos += controller->Movement() * glm::inverse(glm::quat(ori)) * (float)player["Player"]["MovementSpeed"] * (float)dt; + + if (player.HasComponent("Physics")) { + if (controller->Jumping()) { + glm::vec3& velocity = player["Physics"]["Velocity"]; + velocity.y += 10.f; + } + } controller->Reset(); } From 482689fd486ef4303759169e16dc3aef478ad094 Mon Sep 17 00:00:00 2001 From: sippeangelo Date: Sat, 23 Jan 2016 12:16:40 +0100 Subject: [PATCH 19/24] fixup! Moved FirstPersonInputController implementation out of header --- src/Engine/Input/FirstPersonInputController.cpp | 2 -- 1 file changed, 2 deletions(-) delete mode 100644 src/Engine/Input/FirstPersonInputController.cpp diff --git a/src/Engine/Input/FirstPersonInputController.cpp b/src/Engine/Input/FirstPersonInputController.cpp deleted file mode 100644 index d3757dd0..00000000 --- a/src/Engine/Input/FirstPersonInputController.cpp +++ /dev/null @@ -1,2 +0,0 @@ -#include "Input/FirstPersonInputController.h" - From b83d7736276ca64f31abd7e9f0f0243408f79e9d Mon Sep 17 00:00:00 2001 From: sippeangelo Date: Sat, 23 Jan 2016 15:06:41 +0100 Subject: [PATCH 20/24] Infinite respawning for now --- include/Game/Systems/PlayerSpawnSystem.h | 1 + src/Game/Systems/PlayerSpawnSystem.cpp | 9 +++++++++ 2 files changed, 10 insertions(+) diff --git a/include/Game/Systems/PlayerSpawnSystem.h b/include/Game/Systems/PlayerSpawnSystem.h index eb4d3c97..b0ff1d79 100644 --- a/include/Game/Systems/PlayerSpawnSystem.h +++ b/include/Game/Systems/PlayerSpawnSystem.h @@ -22,6 +22,7 @@ private: bool m_NetworkEnabled = false; std::vector m_SpawnRequests; + std::map m_PlayerEntities; EventRelay m_OnInputCommand; bool OnInputCommand(const Events::InputCommand& e); diff --git a/src/Game/Systems/PlayerSpawnSystem.cpp b/src/Game/Systems/PlayerSpawnSystem.cpp index f18808cc..fe377866 100644 --- a/src/Game/Systems/PlayerSpawnSystem.cpp +++ b/src/Game/Systems/PlayerSpawnSystem.cpp @@ -72,6 +72,12 @@ bool PlayerSpawnSystem::OnPlayerSpawned(Events::PlayerSpawned& e) { // When a player is actually spawned (since the actual spawning is handled on the server) + // Check if a player already exists + if (m_PlayerEntities.count(e.PlayerID) != 0) { + // TODO: Disallow infinite respawning here + m_World->DeleteEntity(m_PlayerEntities[e.PlayerID].ID); + } + // Set the camera to the correct entity EntityWrapper cameraEntity = e.Player.FirstChildByName("Camera"); if (cameraEntity.Valid()) { @@ -80,5 +86,8 @@ bool PlayerSpawnSystem::OnPlayerSpawned(Events::PlayerSpawned& e) m_EventBroker->Publish(e); } + // Store the player for future reference + m_PlayerEntities[e.PlayerID] = e.Player; + return true; } \ No newline at end of file From 666ef6589e2082751a4d7e3a5f23842d3f70f569 Mon Sep 17 00:00:00 2001 From: sippeangelo Date: Sat, 23 Jan 2016 15:06:47 +0100 Subject: [PATCH 21/24] Crouching! --- resources/Schema/Components/Player.xml | 3 +- resources/Schema/Components/Player.xsd | 1 + resources/Schema/Entities/MovementTest.xml | 4 +++ resources/Schema/Entities/Player.xml | 37 +++++++++++++++++++--- src/Game/Systems/PlayerMovementSystem.cpp | 23 +++++++++++--- 5 files changed, 59 insertions(+), 9 deletions(-) diff --git a/resources/Schema/Components/Player.xml b/resources/Schema/Components/Player.xml index a9ecc6be..b51326aa 100644 --- a/resources/Schema/Components/Player.xml +++ b/resources/Schema/Components/Player.xml @@ -1,4 +1,5 @@ - 0.2 + 3 + 1.5 \ No newline at end of file diff --git a/resources/Schema/Components/Player.xsd b/resources/Schema/Components/Player.xsd index 89c4a398..13948dc2 100644 --- a/resources/Schema/Components/Player.xsd +++ b/resources/Schema/Components/Player.xsd @@ -10,6 +10,7 @@ + diff --git a/resources/Schema/Entities/MovementTest.xml b/resources/Schema/Entities/MovementTest.xml index 9ea1ae68..00f94120 100644 --- a/resources/Schema/Entities/MovementTest.xml +++ b/resources/Schema/Entities/MovementTest.xml @@ -13,6 +13,7 @@ Models/Core/UnitCube.obj + false @@ -93,6 +94,7 @@ Models/Core/UnitCube.obj + false @@ -107,6 +109,7 @@ Models/Core/UnitCube.obj + false @@ -121,6 +124,7 @@ Models/Core/UnitCube.obj + false diff --git a/resources/Schema/Entities/Player.xml b/resources/Schema/Entities/Player.xml index fa8b7686..4398dcc1 100644 --- a/resources/Schema/Entities/Player.xml +++ b/resources/Schema/Entities/Player.xml @@ -7,6 +7,9 @@ + + + 3 @@ -17,7 +20,7 @@ - + @@ -27,19 +30,18 @@ - - Fonts/DroidSans.ttf,100 + false - + @@ -85,6 +87,33 @@ + + + + Models/Core/UnitCube.obj + + false + + + + + + + + + + + + Models/Core/UnitCube.obj + + false + + + + + + + diff --git a/src/Game/Systems/PlayerMovementSystem.cpp b/src/Game/Systems/PlayerMovementSystem.cpp index 10fc29f6..c5b55cde 100644 --- a/src/Game/Systems/PlayerMovementSystem.cpp +++ b/src/Game/Systems/PlayerMovementSystem.cpp @@ -37,12 +37,27 @@ void PlayerMovementSystem::Update(double dt) ori.y += controller->Rotation().y; glm::vec3& pos = cTransform["Position"]; - pos += controller->Movement() * glm::inverse(glm::quat(ori)) * (float)player["Player"]["MovementSpeed"] * (float)dt; + float speed; + if (controller->Crouching()) { + speed = player["Player"]["CrouchSpeed"]; + } else { + speed = player["Player"]["MovementSpeed"]; + } + pos += controller->Movement() * glm::inverse(glm::quat(ori)) * speed * (float)dt; if (player.HasComponent("Physics")) { - if (controller->Jumping()) { - glm::vec3& velocity = player["Physics"]["Velocity"]; - velocity.y += 10.f; + glm::vec3& velocity = player["Physics"]["Velocity"]; + if (controller->Jumping() && !controller->Crouching() && velocity.y == 0.f) { + velocity.y += 4.f; + } + } + + if (player.HasComponent("AABB")) { + glm::vec3& size = player["AABB"]["Size"]; + if (controller->Crouching()) { + size = glm::vec3(1.f, 1.f, 1.f); + } else { + size = glm::vec3(1.f, 1.6f, 1.f); } } From 1ce9128da8c76220f19f37e0df4037a4cfc6613b Mon Sep 17 00:00:00 2001 From: sippeangelo Date: Sat, 23 Jan 2016 19:45:23 +0100 Subject: [PATCH 22/24] Source-like movement --- include/Game/Systems/PlayerMovementSystem.h | 1 + resources/Schema/Entities/Player.xml | 13 ++-- src/Game/Systems/PlayerMovementSystem.cpp | 67 +++++++++++++++------ 3 files changed, 56 insertions(+), 25 deletions(-) diff --git a/include/Game/Systems/PlayerMovementSystem.h b/include/Game/Systems/PlayerMovementSystem.h index 72f3b879..f39740ec 100644 --- a/include/Game/Systems/PlayerMovementSystem.h +++ b/include/Game/Systems/PlayerMovementSystem.h @@ -3,6 +3,7 @@ #include "Core/System.h" #include "Core/EPlayerSpawned.h" #include "Input/FirstPersonInputController.h" +#include class PlayerMovementSystem : public ImpureSystem, PureSystem { diff --git a/resources/Schema/Entities/Player.xml b/resources/Schema/Entities/Player.xml index 4398dcc1..58550357 100644 --- a/resources/Schema/Entities/Player.xml +++ b/resources/Schema/Entities/Player.xml @@ -6,13 +6,12 @@ - - - - - + + + false + - 3 + 7 @@ -20,7 +19,7 @@ - + diff --git a/src/Game/Systems/PlayerMovementSystem.cpp b/src/Game/Systems/PlayerMovementSystem.cpp index c5b55cde..ae54d684 100644 --- a/src/Game/Systems/PlayerMovementSystem.cpp +++ b/src/Game/Systems/PlayerMovementSystem.cpp @@ -36,29 +36,51 @@ void PlayerMovementSystem::Update(double dt) glm::vec3& ori = cTransform["Orientation"]; ori.y += controller->Rotation().y; - glm::vec3& pos = cTransform["Position"]; - float speed; - if (controller->Crouching()) { - speed = player["Player"]["CrouchSpeed"]; - } else { - speed = player["Player"]["MovementSpeed"]; - } - pos += controller->Movement() * glm::inverse(glm::quat(ori)) * speed * (float)dt; - if (player.HasComponent("Physics")) { - glm::vec3& velocity = player["Physics"]["Velocity"]; - if (controller->Jumping() && !controller->Crouching() && velocity.y == 0.f) { - velocity.y += 4.f; - } - } + ComponentWrapper cPhysics = player["Physics"]; - if (player.HasComponent("AABB")) { - glm::vec3& size = player["AABB"]["Size"]; + glm::vec3 wishDirection = controller->Movement() * glm::inverse(glm::quat(ori)); + float wishSpeed; if (controller->Crouching()) { - size = glm::vec3(1.f, 1.f, 1.f); + wishSpeed = player["Player"]["CrouchSpeed"]; } else { - size = glm::vec3(1.f, 1.6f, 1.f); + wishSpeed = player["Player"]["MovementSpeed"]; } + glm::vec3& velocity = cPhysics["Velocity"]; + ImGui::Text("velocity: (%f, %f, %f)", velocity.x, velocity.y, velocity.z); + ImGui::Text("wishDirection: (%f, %f, %f)", wishDirection.x, wishDirection.y, wishDirection.z); + float currentSpeedProj = glm::dot(velocity, wishDirection); + float addSpeed = wishSpeed - currentSpeedProj; + ImGui::Text("currentSpeedProj: %f", currentSpeedProj); + ImGui::Text("wishSpeed: %f", wishSpeed); + ImGui::Text("addSpeed: %f", addSpeed); + + if (addSpeed > 0) { + static float accel = 15.f; + ImGui::InputFloat("accel", &accel); + float actualAccel = accel; + static float surfaceFriction = 1.f; + ImGui::InputFloat("surfaceFriction", &surfaceFriction); + float accelerationSpeed = actualAccel * (float)dt * wishSpeed * surfaceFriction; + accelerationSpeed = glm::min(accelerationSpeed, addSpeed); + velocity += accelerationSpeed * wishDirection; + ImGui::Text("velocity: (%f, %f, %f) |%f|", velocity.x, velocity.y, velocity.z, glm::length(velocity)); + } + //pos += controller->Movement() * glm::inverse(glm::quat(ori)) * speed * (float)dt; + + //glm::vec3& velocity = player["Physics"]["Velocity"]; + //if (controller->Jumping() && !controller->Crouching() && velocity.y == 0.f) { + // velocity.y += 4.f; + //} + + //if (player.HasComponent("AABB")) { + // glm::vec3& size = player["AABB"]["Size"]; + // if (controller->Crouching()) { + // size = glm::vec3(1.f, 1.f, 1.f); + // } else { + // size = glm::vec3(1.f, 1.6f, 1.f); + // } + //} } controller->Reset(); @@ -78,6 +100,15 @@ void PlayerMovementSystem::UpdateComponent(EntityWrapper& entity, ComponentWrapp velocity.y -= 9.82f * (float)dt; } + // Ground friction + float speed = glm::length(velocity); + static float groundFriction = 7.f; + ImGui::InputFloat("groundFriction", &groundFriction); + if (speed > 0) { + float drop = speed * groundFriction * (float)dt; + velocity *= glm::max(speed - drop, 0.f) / speed; + } + glm::vec3& position = cTransform["Position"]; position += velocity * (float)dt; } From 373bb33cf0f58934d55db75f950b2addcf5ce907 Mon Sep 17 00:00:00 2001 From: sippeangelo Date: Sun, 24 Jan 2016 15:20:34 +0100 Subject: [PATCH 23/24] Player jumping taking air acceleration into account --- resources/Schema/Entities/Player.xml | 9 +++-- src/Engine/Collision/CollisionSystem.cpp | 2 +- src/Game/Systems/PlayerMovementSystem.cpp | 42 ++++++++++++++--------- 3 files changed, 33 insertions(+), 20 deletions(-) diff --git a/resources/Schema/Entities/Player.xml b/resources/Schema/Entities/Player.xml index 58550357..00d2e295 100644 --- a/resources/Schema/Entities/Player.xml +++ b/resources/Schema/Entities/Player.xml @@ -6,12 +6,13 @@ + - false + - 7 + 5 @@ -19,7 +20,8 @@ - + + @@ -29,6 +31,7 @@ + diff --git a/src/Engine/Collision/CollisionSystem.cpp b/src/Engine/Collision/CollisionSystem.cpp index 0c77c306..ba841e36 100644 --- a/src/Engine/Collision/CollisionSystem.cpp +++ b/src/Engine/Collision/CollisionSystem.cpp @@ -31,7 +31,7 @@ void CollisionSystem::UpdateComponent(EntityWrapper& entity, ComponentWrapper& c } if (Collision::AABBVsAABB(boxA, boxB, resolutionVector)) { (glm::vec3&)cTransform["Position"] += resolutionVector; - cPhysics["Velocity"] = glm::vec3(0, 0, 0); + ((glm::vec3&)cPhysics["Velocity"]).y = 0.f; } } diff --git a/src/Game/Systems/PlayerMovementSystem.cpp b/src/Game/Systems/PlayerMovementSystem.cpp index ae54d684..5c75a673 100644 --- a/src/Game/Systems/PlayerMovementSystem.cpp +++ b/src/Game/Systems/PlayerMovementSystem.cpp @@ -48,8 +48,12 @@ void PlayerMovementSystem::Update(double dt) } glm::vec3& velocity = cPhysics["Velocity"]; ImGui::Text("velocity: (%f, %f, %f)", velocity.x, velocity.y, velocity.z); - ImGui::Text("wishDirection: (%f, %f, %f)", wishDirection.x, wishDirection.y, wishDirection.z); - float currentSpeedProj = glm::dot(velocity, wishDirection); + glm::vec3 groundVelocity(0.f, 0.f, 0.f); + groundVelocity.x = glm::dot(velocity, glm::vec3(1.f, 0.f, 0.f)); + groundVelocity.z = glm::dot(velocity, glm::vec3(0.f, 0.f, 1.f)); + ImGui::Text("groundVelocity: (%f, %f, %f) |%f|", groundVelocity.x, groundVelocity.y, groundVelocity.z, glm::length(wishDirection)); + ImGui::Text("wishDirection: (%f, %f, %f) |%f|", wishDirection.x, wishDirection.y, wishDirection.z, glm::length(wishDirection)); + float currentSpeedProj = glm::dot(groundVelocity, wishDirection); float addSpeed = wishSpeed - currentSpeedProj; ImGui::Text("currentSpeedProj: %f", currentSpeedProj); ImGui::Text("wishSpeed: %f", wishSpeed); @@ -58,20 +62,20 @@ void PlayerMovementSystem::Update(double dt) if (addSpeed > 0) { static float accel = 15.f; ImGui::InputFloat("accel", &accel); - float actualAccel = accel; - static float surfaceFriction = 1.f; + static float airAccel = 0.5f; + ImGui::InputFloat("airAccel", &airAccel); + float actualAccel = (velocity.y != 0) ? airAccel : accel; + static float surfaceFriction = 5.f; ImGui::InputFloat("surfaceFriction", &surfaceFriction); float accelerationSpeed = actualAccel * (float)dt * wishSpeed * surfaceFriction; accelerationSpeed = glm::min(accelerationSpeed, addSpeed); velocity += accelerationSpeed * wishDirection; ImGui::Text("velocity: (%f, %f, %f) |%f|", velocity.x, velocity.y, velocity.z, glm::length(velocity)); } - //pos += controller->Movement() * glm::inverse(glm::quat(ori)) * speed * (float)dt; - //glm::vec3& velocity = player["Physics"]["Velocity"]; - //if (controller->Jumping() && !controller->Crouching() && velocity.y == 0.f) { - // velocity.y += 4.f; - //} + if (controller->Jumping() && !controller->Crouching() && velocity.y == 0.f) { + velocity.y += 4.f; + } //if (player.HasComponent("AABB")) { // glm::vec3& size = player["AABB"]["Size"]; @@ -93,20 +97,26 @@ void PlayerMovementSystem::UpdateComponent(EntityWrapper& entity, ComponentWrapp if (!entity.HasComponent("Physics")) { return; } - ComponentWrapper& cPhysics = entity["Physics"]; + ComponentWrapper& cPhysics = entity["Physics"]; glm::vec3& velocity = cPhysics["Velocity"]; - if (cPhysics["Gravity"]) { - velocity.y -= 9.82f * (float)dt; - } // Ground friction float speed = glm::length(velocity); - static float groundFriction = 7.f; + static float groundFriction = 7.f; ImGui::InputFloat("groundFriction", &groundFriction); + static float airFriction = 0.f; + ImGui::InputFloat("airFriction", &airFriction); + float friction = (velocity.y != 0) ? airFriction : groundFriction; if (speed > 0) { - float drop = speed * groundFriction * (float)dt; - velocity *= glm::max(speed - drop, 0.f) / speed; + float drop = speed * friction * (float)dt; + float multiplier = glm::max(speed - drop, 0.f) / speed; + velocity.x *= multiplier; + velocity.z *= multiplier; + } + + if (cPhysics["Gravity"]) { + velocity.y -= 9.82f * (float)dt; } glm::vec3& position = cTransform["Position"]; From 3261e21d9663e31a56025a2d00185dac99bec15a Mon Sep 17 00:00:00 2001 From: sippeangelo Date: Sun, 24 Jan 2016 15:46:01 +0100 Subject: [PATCH 24/24] Coloring players depending on team and created a blue spawn in MovementTest --- resources/Schema/Entities/MovementTest.xml | 47 +++++++++++++++++++++- src/Game/Systems/PlayerSpawnSystem.cpp | 22 +++++++++- 2 files changed, 66 insertions(+), 3 deletions(-) diff --git a/resources/Schema/Entities/MovementTest.xml b/resources/Schema/Entities/MovementTest.xml index 00f94120..26d25edb 100644 --- a/resources/Schema/Entities/MovementTest.xml +++ b/resources/Schema/Entities/MovementTest.xml @@ -22,7 +22,7 @@ - + @@ -133,6 +133,51 @@ + + + + + Schema/Entities/Player.xml + + + + + + + + + + + + + + + + + Models/Assault.obj + + + + + + + + + + + + + Models/Assault.obj + + + + + + + + + + diff --git a/src/Game/Systems/PlayerSpawnSystem.cpp b/src/Game/Systems/PlayerSpawnSystem.cpp index fe377866..84dce05c 100644 --- a/src/Game/Systems/PlayerSpawnSystem.cpp +++ b/src/Game/Systems/PlayerSpawnSystem.cpp @@ -78,6 +78,9 @@ bool PlayerSpawnSystem::OnPlayerSpawned(Events::PlayerSpawned& e) m_World->DeleteEntity(m_PlayerEntities[e.PlayerID].ID); } + // Store the player for future reference + m_PlayerEntities[e.PlayerID] = e.Player; + // Set the camera to the correct entity EntityWrapper cameraEntity = e.Player.FirstChildByName("Camera"); if (cameraEntity.Valid()) { @@ -86,8 +89,23 @@ bool PlayerSpawnSystem::OnPlayerSpawned(Events::PlayerSpawned& e) m_EventBroker->Publish(e); } - // Store the player for future reference - m_PlayerEntities[e.PlayerID] = e.Player; + // HACK: Set the player model color to team color + EntityWrapper playerModel = e.Player.FirstChildByName("PlayerModel"); + if (playerModel.Valid() && e.Player.HasComponent("Team")) { + ComponentWrapper cTeam = e.Player["Team"]; + ComponentWrapper cModel = playerModel["Model"]; + if ((ComponentInfo::EnumType)cTeam["Team"] == cTeam["Team"].Enum("Red")) { + cModel["Color"] = glm::vec3(1.f, 0.f, 0.f); + } else if ((ComponentInfo::EnumType)cTeam["Team"] == cTeam["Team"].Enum("Blue")) { + cModel["Color"] = glm::vec3(0.f, 0.25f, 1.f); + } + } + + // TODO: Set the player name to whatever + //EntityWrapper playerName = e.Player.FirstChildByName("PlayerName"); + //if (playerName.Valid()) { + // playerName["Text"]["Content"] = ???; + //} return true; } \ No newline at end of file