Compare commits
74 Commits
Transparancyfix
...
Sound
| Author | SHA1 | Date | |
|---|---|---|---|
| 9df7b32ca1 | |||
| 3d4a7de59d | |||
| 1cdcbf9b32 | |||
| 9e8d2b99df | |||
| ba4877c3f7 | |||
| af39b892cd | |||
| 1ed5107d9b | |||
| 2ce7179d19 | |||
| eb7b22c757 | |||
| b48d491ad7 | |||
| 47f4711b85 | |||
| 78e318c032 | |||
| bb66f95d43 | |||
| cc422cf73a | |||
| 2e5ee633ce | |||
| 1e04244590 | |||
| f146971db0 | |||
| 60b2c9bc9b | |||
| d357e365cb | |||
| a8a3366e8a | |||
| 7de76376cf | |||
| 422bedb844 | |||
| 1da432ba23 | |||
| 787eecce26 | |||
| 215b1b1aa4 | |||
| f49cacf167 | |||
| a15e01596a | |||
| a5168bd1c2 | |||
| 784e1eb69b | |||
| b5e372896f | |||
| a54156fab3 | |||
| a20707739e | |||
| 4f7a17ff62 | |||
| 987dafb44a | |||
| 47053285c8 | |||
| bee0630a26 | |||
| 1dc3756533 | |||
| 196469299f | |||
| b9ea314232 | |||
| 71533b52ae | |||
| 6442254575 | |||
| 021c4e36d7 | |||
| fb5164221f | |||
| 88c7c57671 | |||
| 5295133311 | |||
| 3b42f5dbf4 | |||
| 0370775820 | |||
| a36ed76a4e | |||
| e24a84c52d | |||
| 30f454e6a4 | |||
| c1860ae383 | |||
| 70f4002d70 | |||
| b66e3d3630 | |||
| 055f6517a1 | |||
| afd9e24df6 | |||
| 851418b1de | |||
| fee50ba3b6 | |||
| 49d4a45ef8 | |||
| e0c3a32e66 | |||
| fa2e556ab2 | |||
| eb244f87c4 | |||
| ec54b1298d | |||
| 95fa1f4bbd | |||
| 7cbdc33f84 | |||
| 9645169797 | |||
| 4f2ad3ad00 | |||
| 2ec30fd2b2 | |||
| d2ed293183 | |||
| fccd8c64e7 | |||
| ba9419b342 | |||
| 88d7b79cd3 | |||
| 9232b24a7b | |||
| 7bf4f5c30e | |||
| e133791369 |
+1
-1
Submodule assets updated: 078e014f3d...1e7adc749e
@@ -13,6 +13,8 @@
|
|||||||
#include "Network/Network.h"
|
#include "Network/Network.h"
|
||||||
#include "Network/MessageType.h"
|
#include "Network/MessageType.h"
|
||||||
#include "Network/PlayerDefinition.h"
|
#include "Network/PlayerDefinition.h"
|
||||||
|
#include "Network/UDPClient.h"
|
||||||
|
#include "Network/TCPClient.h"
|
||||||
#include "Network/SnapshotDefinitions.h"
|
#include "Network/SnapshotDefinitions.h"
|
||||||
#include "Core/World.h"
|
#include "Core/World.h"
|
||||||
#include "Core/EventBroker.h"
|
#include "Core/EventBroker.h"
|
||||||
@@ -33,17 +35,15 @@ public:
|
|||||||
void Connect(std::string address, int port);
|
void Connect(std::string address, int port);
|
||||||
void Update() override;
|
void Update() override;
|
||||||
|
|
||||||
private:
|
std::vector<Events::PlayerSpawned> m_PlayerSpawnEvents;
|
||||||
|
void parseSpawnEvents();
|
||||||
|
// Save for children
|
||||||
std::unique_ptr<SnapshotFilter> m_SnapshotFilter = nullptr;
|
std::unique_ptr<SnapshotFilter> m_SnapshotFilter = nullptr;
|
||||||
|
|
||||||
// Assio UDP logic
|
std::string m_Address;
|
||||||
boost::asio::ip::udp::endpoint m_ReceiverEndpoint;
|
int m_Port = 0;
|
||||||
boost::asio::io_service m_IOService;
|
|
||||||
boost::asio::ip::udp::socket m_Socket;
|
|
||||||
|
|
||||||
// Sending message to server logic
|
// Sending message to server logic
|
||||||
size_t bytesRead = 0;
|
size_t bytesRead = 0;
|
||||||
char readBuf[INPUTSIZE] = { 0 };
|
|
||||||
|
|
||||||
// Packet loss logic
|
// Packet loss logic
|
||||||
PacketID m_PacketID = 0;
|
PacketID m_PacketID = 0;
|
||||||
@@ -72,16 +72,14 @@ private:
|
|||||||
std::vector<Events::InputCommand> m_InputCommandBuffer;
|
std::vector<Events::InputCommand> m_InputCommandBuffer;
|
||||||
|
|
||||||
// Private member functions
|
// Private member functions
|
||||||
void readFromServer();
|
|
||||||
size_t receive(char* data);
|
size_t receive(char* data);
|
||||||
void send(Packet& packet);
|
|
||||||
void connect();
|
|
||||||
void disconnect();
|
void disconnect();
|
||||||
void parseMessageType(Packet& packet);
|
void parseMessageType(Packet& packet);
|
||||||
void updateFields(Packet& packet, const ComponentInfo& componentInfo, const EntityID& entityID);
|
void updateFields(Packet& packet, const ComponentInfo& componentInfo, const EntityID& entityID);
|
||||||
SharedComponentWrapper createSharedComponent(Packet& packet, EntityID entityID, const ComponentInfo& componentInfo);
|
SharedComponentWrapper createSharedComponent(Packet& packet, EntityID entityID, const ComponentInfo& componentInfo);
|
||||||
void ignoreFields(Packet& packet, const ComponentInfo& componentInfo);
|
void ignoreFields(Packet& packet, const ComponentInfo& componentInfo);
|
||||||
void parseConnect(Packet& packet);
|
void parseUDPConnect(Packet& packet);
|
||||||
|
void parseTCPConnect(Packet& packet);
|
||||||
void parsePlayerConnected(Packet& packet);
|
void parsePlayerConnected(Packet& packet);
|
||||||
void parsePing();
|
void parsePing();
|
||||||
void parseKick();
|
void parseKick();
|
||||||
@@ -91,7 +89,7 @@ private:
|
|||||||
void InterpolateFields(Packet & packet, const ComponentInfo & componentInfo, const EntityID & entityID, const std::string & componentType);
|
void InterpolateFields(Packet & packet, const ComponentInfo & componentInfo, const EntityID & entityID, const std::string & componentType);
|
||||||
void parseSnapshot(Packet& packet);
|
void parseSnapshot(Packet& packet);
|
||||||
void identifyPacketLoss();
|
void identifyPacketLoss();
|
||||||
bool hasServerTimedOut();
|
void hasServerTimedOut();
|
||||||
EntityID createPlayer();
|
EntityID createPlayer();
|
||||||
void sendInputCommands();
|
void sendInputCommands();
|
||||||
void sendLocalPlayerTransform();
|
void sendLocalPlayerTransform();
|
||||||
@@ -111,6 +109,10 @@ private:
|
|||||||
bool OnPlayerDamage(const Events::PlayerDamage& e);
|
bool OnPlayerDamage(const Events::PlayerDamage& e);
|
||||||
EventRelay<Client, Events::PlayerSpawned> m_EPlayerSpawned;
|
EventRelay<Client, Events::PlayerSpawned> m_EPlayerSpawned;
|
||||||
bool OnPlayerSpawned(const Events::PlayerSpawned& e);
|
bool OnPlayerSpawned(const Events::PlayerSpawned& e);
|
||||||
|
void parsePlayerDamage(Packet& packet);
|
||||||
|
private:
|
||||||
|
UDPClient m_Unreliable;
|
||||||
|
TCPClient m_Reliable;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -0,0 +1,13 @@
|
|||||||
|
#ifndef HybridClient_h__
|
||||||
|
#define HybridClient_h__
|
||||||
|
|
||||||
|
class HybridClient
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
HybridClient();
|
||||||
|
~HybridClient();
|
||||||
|
private:
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
#ifndef HybridServer_h__
|
||||||
|
#define HybridServer_h__
|
||||||
|
|
||||||
|
class HybridServer
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
HybridServer();
|
||||||
|
~HybridServer();
|
||||||
|
private:
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -18,7 +18,8 @@ enum class MessageType
|
|||||||
OnPlayerSpawned,
|
OnPlayerSpawned,
|
||||||
EntityDeleted,
|
EntityDeleted,
|
||||||
ComponentDeleted,
|
ComponentDeleted,
|
||||||
PlayerTransform
|
PlayerTransform,
|
||||||
|
Invalid
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -12,7 +12,7 @@
|
|||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
#define INPUTSIZE 32000
|
#define BUFFERSIZE 32000
|
||||||
typedef unsigned int PlayerID;
|
typedef unsigned int PlayerID;
|
||||||
typedef unsigned int PacketID;
|
typedef unsigned int PacketID;
|
||||||
|
|
||||||
@@ -35,6 +35,8 @@ protected:
|
|||||||
std::clock_t m_SaveDataTimer;
|
std::clock_t m_SaveDataTimer;
|
||||||
unsigned int m_MaxConnections;
|
unsigned int m_MaxConnections;
|
||||||
double m_TimeoutMs;
|
double m_TimeoutMs;
|
||||||
|
void logSentData(int bytesSent);
|
||||||
|
void logReceivedData(int bytesReceived);
|
||||||
void saveToFile();
|
void saveToFile();
|
||||||
void updateNetworkData();
|
void updateNetworkData();
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -0,0 +1,21 @@
|
|||||||
|
#ifndef NetworkClient_h__
|
||||||
|
#define NetworkClient_h__
|
||||||
|
|
||||||
|
#include "Network/Packet.h"
|
||||||
|
#define BUFFERSIZE 32000
|
||||||
|
typedef unsigned int PlayerID;
|
||||||
|
typedef unsigned int PacketID;
|
||||||
|
|
||||||
|
class NetworkClient
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual void Connect(std::string playerName, std::string address, int port) = 0;
|
||||||
|
virtual void Disconnect() = 0;
|
||||||
|
virtual void Receive(Packet& packet) = 0;
|
||||||
|
virtual void Send(Packet & packet) = 0;
|
||||||
|
virtual bool IsSocketAvailable() = 0;
|
||||||
|
protected:
|
||||||
|
char m_ReadBuffer[BUFFERSIZE] = { 0 };
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
#ifndef NetworkServer_h__
|
||||||
|
#define NetworkServer_h__
|
||||||
|
#include <boost/asio.hpp>
|
||||||
|
#include "Network/Packet.h"
|
||||||
|
#include "Network/PlayerDefinition.h"
|
||||||
|
#define BUFFERSIZE 32000
|
||||||
|
typedef unsigned int PlayerID;
|
||||||
|
typedef unsigned int PacketID;
|
||||||
|
|
||||||
|
class NetworkServer
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual void AcceptNewConnections(int& nextPlayerID, std::map<PlayerID, PlayerDefinition>& connectedPlayers) = 0;
|
||||||
|
virtual void Receive(Packet & packet, PlayerDefinition & playerDefinition) = 0;
|
||||||
|
virtual void Send(Packet & packet, PlayerDefinition & playerDefinition) = 0;
|
||||||
|
virtual void Send(Packet & packet) = 0;
|
||||||
|
protected:
|
||||||
|
char m_ReadBuffer[BUFFERSIZE] = { 0 };
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -49,10 +49,15 @@ public:
|
|||||||
void WriteData(char* data, int sizeOfData);
|
void WriteData(char* data, int sizeOfData);
|
||||||
// Pops the first element as if it was a string.
|
// Pops the first element as if it was a string.
|
||||||
std::string ReadString();
|
std::string ReadString();
|
||||||
|
// Construct a packet
|
||||||
|
void ReconstructFromData(char* data, size_t SizeOfData);
|
||||||
|
// Update size of packet variable in header
|
||||||
|
void UpdateSize();
|
||||||
char* ReadData(int SizeOfData);
|
char* ReadData(int SizeOfData);
|
||||||
void ChangePacketID(unsigned int& packetID);
|
void ChangePacketID(unsigned int& packetID);
|
||||||
size_t Size() { return m_Offset; };
|
size_t Size() { return m_Offset; };
|
||||||
char* Data() { return m_Data; };
|
char* Data() { return m_Data; };
|
||||||
|
MessageType GetMessageType();
|
||||||
size_t DataReadSize() { return m_ReturnDataOffset; }
|
size_t DataReadSize() { return m_ReturnDataOffset; }
|
||||||
size_t MaxSize() { return m_MaxPacketSize; }
|
size_t MaxSize() { return m_MaxPacketSize; }
|
||||||
size_t HeaderSize() { return m_HeaderSize; }
|
size_t HeaderSize() { return m_HeaderSize; }
|
||||||
@@ -64,6 +69,7 @@ private:
|
|||||||
size_t m_MaxPacketSize = 512;
|
size_t m_MaxPacketSize = 512;
|
||||||
size_t m_HeaderSize = 0;
|
size_t m_HeaderSize = 0;
|
||||||
void resizeData();
|
void resizeData();
|
||||||
|
void resizeData(int size);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
@@ -2,6 +2,7 @@
|
|||||||
#define PlayerDefinition_h__
|
#define PlayerDefinition_h__
|
||||||
#include <string>
|
#include <string>
|
||||||
#include "../Core/Entity.h"
|
#include "../Core/Entity.h"
|
||||||
|
#include <boost/asio.hpp>
|
||||||
|
|
||||||
struct PlayerDefinition {
|
struct PlayerDefinition {
|
||||||
::EntityID EntityID = EntityID_Invalid;
|
::EntityID EntityID = EntityID_Invalid;
|
||||||
@@ -9,6 +10,10 @@ struct PlayerDefinition {
|
|||||||
boost::asio::ip::udp::endpoint Endpoint;
|
boost::asio::ip::udp::endpoint Endpoint;
|
||||||
unsigned int PacketID;
|
unsigned int PacketID;
|
||||||
std::clock_t StopTime;
|
std::clock_t StopTime;
|
||||||
|
boost::asio::ip::address TCPAddress;
|
||||||
|
unsigned short TCPPort;
|
||||||
|
// use for tcp connections
|
||||||
|
boost::shared_ptr<boost::asio::ip::tcp::socket> TCPSocket;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -5,8 +5,9 @@
|
|||||||
#include <ctime>
|
#include <ctime>
|
||||||
|
|
||||||
#include <glm/common.hpp>
|
#include <glm/common.hpp>
|
||||||
#include <boost/asio/ip/udp.hpp>
|
|
||||||
|
|
||||||
|
#include "Network/TCPServer.h"
|
||||||
|
#include "Network/UDPServer.h"
|
||||||
#include "Network/MessageType.h"
|
#include "Network/MessageType.h"
|
||||||
#include "Network/PlayerDefinition.h"
|
#include "Network/PlayerDefinition.h"
|
||||||
#include "Core/World.h"
|
#include "Core/World.h"
|
||||||
@@ -28,28 +29,29 @@ public:
|
|||||||
void Update() override;
|
void Update() override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
// Network channels
|
||||||
|
TCPServer m_Reliable;
|
||||||
|
UDPServer m_Unreliable;
|
||||||
|
// dont forget to set these in the childrens receive logic
|
||||||
|
boost::asio::ip::address m_Address;
|
||||||
int m_Port = 27666;
|
int m_Port = 27666;
|
||||||
// UDP logic
|
|
||||||
boost::asio::ip::udp::endpoint m_ReceiverEndpoint;
|
|
||||||
boost::asio::io_service m_IOService;
|
|
||||||
std::unique_ptr<boost::asio::ip::udp::socket> m_Socket;
|
|
||||||
|
|
||||||
// Sending messages to client logic
|
// Sending messages to client logic
|
||||||
std::map<PlayerID, PlayerDefinition> m_ConnectedPlayers;
|
std::map<PlayerID, PlayerDefinition> m_ConnectedPlayers;
|
||||||
|
std::vector<PlayerID> m_PlayersToDisconnect;
|
||||||
// HACK: Fix INPUTSIZE
|
// HACK: Fix INPUTSIZE
|
||||||
char readBuffer[INPUTSIZE] = { 0 };
|
char readBuffer[BUFFERSIZE] = { 0 };
|
||||||
size_t bytesRead = 0;
|
size_t bytesRead = 0;
|
||||||
// time for previouse message
|
// time for previouse message
|
||||||
std::clock_t previousePingMessage = std::clock();
|
std::clock_t previousePingMessage = std::clock();
|
||||||
std::clock_t previousSnapshotMessage = std::clock();
|
std::clock_t previousSnapshotMessage = std::clock();
|
||||||
std::clock_t timOutTimer = std::clock();
|
std::clock_t timOutTimer = std::clock();
|
||||||
|
|
||||||
// How often we send messages (milliseconds)
|
// How often we send messages (milliseconds)
|
||||||
float pingIntervalMs;
|
float pingIntervalMs;
|
||||||
float snapshotInterval;
|
float snapshotInterval;
|
||||||
int checkTimeOutInterval = 100;
|
int checkTimeOutInterval = 100;
|
||||||
int m_NextPlayerID = 0;
|
int m_NextPlayerID = 0;
|
||||||
std::vector<Events::InputCommand> m_InputCommandsToBroadcast;
|
std::vector<Events::InputCommand> m_InputCommandsToBroadcast;
|
||||||
|
|
||||||
//Timers
|
//Timers
|
||||||
std::clock_t m_StartPingTime;
|
std::clock_t m_StartPingTime;
|
||||||
|
|
||||||
@@ -58,11 +60,9 @@ private:
|
|||||||
PacketID m_PreviousPacketID = 0;
|
PacketID m_PreviousPacketID = 0;
|
||||||
|
|
||||||
// Private member functions
|
// Private member functions
|
||||||
size_t receive(char* data);
|
//int receive(char* data);
|
||||||
void readFromClients();
|
void reliableBroadcast(Packet& packet);
|
||||||
void send(PlayerID player, Packet& packet);
|
void unreliableBroadcast(Packet& packet);
|
||||||
void send(Packet& packet);
|
|
||||||
void broadcast(Packet& packet);
|
|
||||||
void sendSnapshot();
|
void sendSnapshot();
|
||||||
void addChildrenToPacket(Packet& packet, EntityID entityID);
|
void addChildrenToPacket(Packet& packet, EntityID entityID);
|
||||||
void addInputCommandsToPacket(Packet& packet);
|
void addInputCommandsToPacket(Packet& packet);
|
||||||
@@ -70,15 +70,19 @@ private:
|
|||||||
void checkForTimeOuts();
|
void checkForTimeOuts();
|
||||||
void disconnect(PlayerID playerID);
|
void disconnect(PlayerID playerID);
|
||||||
void parseMessageType(Packet& packet);
|
void parseMessageType(Packet& packet);
|
||||||
void parseOnInputCommand(Packet& packet);
|
|
||||||
void parseOnPlayerDamage(Packet& packet);
|
void parseOnPlayerDamage(Packet& packet);
|
||||||
void parseConnect(Packet& packet);
|
|
||||||
void parseDisconnect();
|
|
||||||
void parseClientPing();
|
|
||||||
void parsePing();
|
|
||||||
void identifyPacketLoss();
|
void identifyPacketLoss();
|
||||||
void kick(PlayerID player);
|
void kick(PlayerID player);
|
||||||
PlayerID GetPlayerIDFromEndpoint(boost::asio::ip::udp::endpoint endpoint);
|
PlayerID GetPlayerIDFromEndpoint();
|
||||||
|
void parsePlayerTransform(Packet& packet);
|
||||||
|
void parseOnInputCommand(Packet& packet);
|
||||||
|
void parseClientPing();
|
||||||
|
void parsePing();
|
||||||
|
void parseUDPConnect(Packet & packet);
|
||||||
|
void parseTCPConnect(Packet & packet);
|
||||||
|
void parseDisconnect();
|
||||||
|
bool shouldSendToClient(EntityWrapper childEntity);
|
||||||
|
|
||||||
// Debug event
|
// Debug event
|
||||||
EventRelay<Server, Events::InputCommand> m_EInputCommand;
|
EventRelay<Server, Events::InputCommand> m_EInputCommand;
|
||||||
bool OnInputCommand(const Events::InputCommand& e);
|
bool OnInputCommand(const Events::InputCommand& e);
|
||||||
@@ -88,7 +92,8 @@ private:
|
|||||||
bool OnEntityDeleted(const Events::EntityDeleted& e);
|
bool OnEntityDeleted(const Events::EntityDeleted& e);
|
||||||
EventRelay<Server, Events::ComponentDeleted> m_EComponentDeleted;
|
EventRelay<Server, Events::ComponentDeleted> m_EComponentDeleted;
|
||||||
bool OnComponentDeleted(const Events::ComponentDeleted& e);
|
bool OnComponentDeleted(const Events::ComponentDeleted& e);
|
||||||
void parsePlayerTransform(Packet& packet);
|
EventRelay<Server, Events::PlayerDamage> m_EPlayerDamage;
|
||||||
|
bool OnPlayerDamage(const Events::PlayerDamage& e);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -0,0 +1,28 @@
|
|||||||
|
#ifndef TCPClient_h__
|
||||||
|
#define TCPClient_h__
|
||||||
|
|
||||||
|
#include <boost/asio.hpp>
|
||||||
|
#include "NetworkClient.h"
|
||||||
|
|
||||||
|
class TCPClient : public NetworkClient
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
TCPClient();
|
||||||
|
~TCPClient();
|
||||||
|
|
||||||
|
void Connect(std::string playerName, std::string address, int port);
|
||||||
|
void Disconnect();
|
||||||
|
void Receive(Packet& packet);
|
||||||
|
void Send(Packet & packet);
|
||||||
|
bool IsSocketAvailable();
|
||||||
|
private:
|
||||||
|
// Assio TCP logic
|
||||||
|
boost::asio::ip::tcp::endpoint m_Endpoint;
|
||||||
|
boost::asio::io_service m_IOService;
|
||||||
|
std::unique_ptr<boost::asio::ip::tcp::socket> m_Socket;
|
||||||
|
size_t readBuffer(char* data);
|
||||||
|
PacketID m_SendPacketID = 0;
|
||||||
|
bool m_IsConnected = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,31 @@
|
|||||||
|
#ifndef TCPServer_h__
|
||||||
|
#define TCPServer_h__
|
||||||
|
|
||||||
|
#include <boost/asio.hpp>
|
||||||
|
#include <boost/bind.hpp>
|
||||||
|
#include <map>
|
||||||
|
#include "NetworkServer.h"
|
||||||
|
|
||||||
|
class TCPServer : public NetworkServer
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
TCPServer();
|
||||||
|
~TCPServer();
|
||||||
|
void AcceptNewConnections(int& nextPlayerID, std::map<PlayerID, PlayerDefinition>& connectedPlayers);
|
||||||
|
void Receive(Packet & packet, PlayerDefinition & playerDefinition);
|
||||||
|
void Send(Packet & packet, PlayerDefinition & playerDefinition);
|
||||||
|
void Send(Packet & packet);
|
||||||
|
void Disconnect();
|
||||||
|
private:
|
||||||
|
// TCP logic
|
||||||
|
boost::asio::io_service m_IOService;
|
||||||
|
std::unique_ptr<boost::asio::ip::tcp::acceptor> acceptor;
|
||||||
|
boost::shared_ptr<boost::asio::ip::tcp::socket> lastReceivedSocket;
|
||||||
|
|
||||||
|
void handle_accept(boost::shared_ptr<boost::asio::ip::tcp::socket> socket,
|
||||||
|
int& nextPlayerID, std::map<PlayerID, PlayerDefinition>& connectedPlayers,
|
||||||
|
const boost::system::error_code& error);
|
||||||
|
int readBuffer(char* data, PlayerDefinition& playerDefinition);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,27 @@
|
|||||||
|
#ifndef UDPClient_h__
|
||||||
|
#define UDPClient_h__
|
||||||
|
|
||||||
|
#include <boost/asio.hpp>
|
||||||
|
#include "Network/NetworkClient.h"
|
||||||
|
|
||||||
|
class UDPClient : public NetworkClient
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
UDPClient();
|
||||||
|
~UDPClient();
|
||||||
|
|
||||||
|
void Connect(std::string playerName, std::string address, int port);
|
||||||
|
void Disconnect();
|
||||||
|
void Receive(Packet& packet);
|
||||||
|
void Send(Packet & packet);
|
||||||
|
bool IsSocketAvailable();
|
||||||
|
private:
|
||||||
|
// Assio UDP logic
|
||||||
|
boost::asio::io_service m_IOService;
|
||||||
|
boost::asio::ip::udp::endpoint m_ReceiverEndpoint;
|
||||||
|
boost::shared_ptr<boost::asio::ip::udp::socket> m_Socket;
|
||||||
|
int readBuffer(char* data);
|
||||||
|
PacketID m_SendPacketID = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
#ifndef UDPServer_h__
|
||||||
|
#define UDPServer_h__
|
||||||
|
|
||||||
|
#include "NetworkServer.h"
|
||||||
|
#include <boost/asio/ip/udp.hpp>
|
||||||
|
|
||||||
|
class UDPServer : public NetworkServer
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
UDPServer();
|
||||||
|
~UDPServer();
|
||||||
|
void AcceptNewConnections(int& nextPlayerID, std::map<PlayerID, PlayerDefinition>& connectedPlayers);
|
||||||
|
void Receive(Packet & packet, PlayerDefinition & playerDefinition);
|
||||||
|
void Send(Packet & packet, PlayerDefinition & playerDefinition);
|
||||||
|
void Send(Packet & packet);
|
||||||
|
bool IsSocketAvailable();
|
||||||
|
private:
|
||||||
|
// UDP logic
|
||||||
|
boost::asio::io_service m_IOService;
|
||||||
|
boost::asio::ip::udp::endpoint m_ReceiverEndpoint;
|
||||||
|
std::unique_ptr<boost::asio::ip::udp::socket> m_Socket;
|
||||||
|
int readBuffer(char* data);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
#ifndef MiniDump_h__
|
||||||
|
#define MiniDump_h__
|
||||||
|
|
||||||
|
#include <Windows.h>
|
||||||
|
|
||||||
|
void WINAPI Create_Dump(PEXCEPTION_POINTERS pException, BOOL File_Flag, BOOL Show_Flag);
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
#ifndef AmmunitionHUDSystem_h__
|
||||||
|
#define AmmunitionHUDSystem_h__
|
||||||
|
|
||||||
|
#include "../../Engine/Core/System.h"
|
||||||
|
#include "../../Engine/GLM.h"
|
||||||
|
|
||||||
|
class AmmunitionHUDSystem : public ImpureSystem
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
AmmunitionHUDSystem(SystemParams params)
|
||||||
|
: System(params)
|
||||||
|
{ }
|
||||||
|
|
||||||
|
virtual void Update(double dt) override;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -3,13 +3,11 @@
|
|||||||
|
|
||||||
#include "../../Engine/Core/System.h"
|
#include "../../Engine/Core/System.h"
|
||||||
#include "../../Engine/GLM.h"
|
#include "../../Engine/GLM.h"
|
||||||
#include "../../Engine/Rendering/ESetCamera.h"
|
|
||||||
#include <imgui/imgui.h>
|
|
||||||
|
|
||||||
class PlayerHUDSystem : public ImpureSystem
|
class HealthHUDSystem : public ImpureSystem
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
PlayerHUDSystem(SystemParams params)
|
HealthHUDSystem(SystemParams params)
|
||||||
: System(params)
|
: System(params)
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
@@ -9,7 +9,8 @@
|
|||||||
#include "Core/EPlayerDamage.h"
|
#include "Core/EPlayerDamage.h"
|
||||||
#include "Core/EPlayerHealthPickup.h"
|
#include "Core/EPlayerHealthPickup.h"
|
||||||
#include "Core/EPlayerDeath.h"
|
#include "Core/EPlayerDeath.h"
|
||||||
#include "../Engine/Input/EInputCommand.h"
|
#include "Core/ConfigFile.h"
|
||||||
|
#include "Input/EInputCommand.h"
|
||||||
|
|
||||||
#include <tuple>
|
#include <tuple>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
@@ -24,6 +25,8 @@ public:
|
|||||||
virtual void UpdateComponent(EntityWrapper& entity, ComponentWrapper& component, double dt) override;
|
virtual void UpdateComponent(EntityWrapper& entity, ComponentWrapper& component, double dt) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
bool m_NetworkEnabled;
|
||||||
|
|
||||||
//methods which will take care of specific events
|
//methods which will take care of specific events
|
||||||
EventRelay<HealthSystem, Events::PlayerDamage> m_EPlayerDamage;
|
EventRelay<HealthSystem, Events::PlayerDamage> m_EPlayerDamage;
|
||||||
bool HealthSystem::OnPlayerDamaged(Events::PlayerDamage& e);
|
bool HealthSystem::OnPlayerDamaged(Events::PlayerDamage& e);
|
||||||
@@ -34,7 +37,7 @@ private:
|
|||||||
|
|
||||||
//vector which will keep track of health changes
|
//vector which will keep track of health changes
|
||||||
std::vector<std::tuple<EntityID, double>> m_DeltaHealthVector;
|
std::vector<std::tuple<EntityID, double>> m_DeltaHealthVector;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
@@ -0,0 +1,39 @@
|
|||||||
|
#ifndef KillFeedSystem_h__
|
||||||
|
#define KillFeedSystem_h__
|
||||||
|
|
||||||
|
#include "../../Engine/Core/System.h"
|
||||||
|
#include "../../Engine/GLM.h"
|
||||||
|
#include "Core/EPlayerDeath.h"
|
||||||
|
|
||||||
|
class KillFeedSystem : public ImpureSystem
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
KillFeedSystem(SystemParams params)
|
||||||
|
: System(params)
|
||||||
|
{
|
||||||
|
EVENT_SUBSCRIBE_MEMBER(m_EPlayerDeath, &KillFeedSystem::OnPlayerDeath);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void Update(double dt) override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
EventRelay<KillFeedSystem, Events::PlayerDeath> m_EPlayerDeath;
|
||||||
|
bool KillFeedSystem::OnPlayerDeath(Events::PlayerDeath& e);
|
||||||
|
|
||||||
|
struct KillFeedInfo
|
||||||
|
{
|
||||||
|
std::string Content;
|
||||||
|
glm::vec4 Color;
|
||||||
|
float TimeToLive = 5.f;
|
||||||
|
};
|
||||||
|
|
||||||
|
std::list<KillFeedInfo> m_DeathQueue;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -1,11 +1,13 @@
|
|||||||
#include "Sound/EPlaySoundOnEntity.h"
|
#include "Sound/EPlaySoundOnEntity.h"
|
||||||
#include "Collision/Collision.h"
|
#include "Collision/Collision.h"
|
||||||
#include "Rendering/AnimationSystem.h"
|
#include "Rendering/AnimationSystem.h"
|
||||||
|
#include "Core/ConfigFile.h"
|
||||||
#include "WeaponBehaviour.h"
|
#include "WeaponBehaviour.h"
|
||||||
#include "../SpawnerSystem.h"
|
#include "../SpawnerSystem.h"
|
||||||
#include "Core/EPlayerDamage.h"
|
#include "Core/EPlayerDamage.h"
|
||||||
#include "Core/EShoot.h"
|
#include "Core/EShoot.h"
|
||||||
|
|
||||||
|
|
||||||
class AssaultWeaponBehaviour : public WeaponBehaviour
|
class AssaultWeaponBehaviour : public WeaponBehaviour
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@@ -19,11 +21,13 @@ public:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
EntityWrapper m_FirstPersonModel;
|
EntityWrapper m_FirstPersonModel;
|
||||||
|
EntityWrapper m_ThirdPersonModel;
|
||||||
// State
|
// State
|
||||||
bool m_Firing = false;
|
bool m_Firing = false;
|
||||||
bool m_Reloading = false;
|
bool m_Reloading = false;
|
||||||
double m_ReloadTimer = 0.0;
|
double m_ReloadTimer = 0.0;
|
||||||
EntityWrapper m_ReloadImpersonator;
|
EntityWrapper m_FirstPersonReloadImpersonator;
|
||||||
|
EntityWrapper m_ThirdPersonReloadImpersonator;
|
||||||
double m_TimeSinceLastFire = 0.0;
|
double m_TimeSinceLastFire = 0.0;
|
||||||
|
|
||||||
EventRelay<WeaponBehaviour, Events::AnimationComplete> m_EAnimationComplete;
|
EventRelay<WeaponBehaviour, Events::AnimationComplete> m_EAnimationComplete;
|
||||||
@@ -33,7 +37,8 @@ private:
|
|||||||
void fireRound();
|
void fireRound();
|
||||||
void spawnTracer();
|
void spawnTracer();
|
||||||
float traceRayDistance(glm::vec3 origin, glm::vec3 direction);
|
float traceRayDistance(glm::vec3 origin, glm::vec3 direction);
|
||||||
void playSound();
|
void playFireSound();
|
||||||
|
void playEmptySound();
|
||||||
void viewPunch();
|
void viewPunch();
|
||||||
void finishReload();
|
void finishReload();
|
||||||
void playShootAnimation();
|
void playShootAnimation();
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ StartNetwork=false
|
|||||||
IsServer=false
|
IsServer=false
|
||||||
Name=Bob
|
Name=Bob
|
||||||
Address=127.0.0.1
|
Address=127.0.0.1
|
||||||
Port=13
|
Port=27666
|
||||||
MaxConnections=8
|
MaxConnections=8
|
||||||
SnapshotInterval=0.05
|
SnapshotInterval=0.05
|
||||||
SendInputIntervalMs=33
|
SendInputIntervalMs=33
|
||||||
|
|||||||
@@ -40,4 +40,6 @@
|
|||||||
<xs:include schemaLocation="Components/Sprite.xsd"/>
|
<xs:include schemaLocation="Components/Sprite.xsd"/>
|
||||||
<xs:include schemaLocation="Components/Shielded.xsd"/>
|
<xs:include schemaLocation="Components/Shielded.xsd"/>
|
||||||
<xs:include schemaLocation="Components/CapturePointHUD.xsd"/>
|
<xs:include schemaLocation="Components/CapturePointHUD.xsd"/>
|
||||||
|
<xs:include schemaLocation="Components/AmmunitionHUD.xsd"/>
|
||||||
|
<xs:include schemaLocation="Components/KillFeed.xsd"/>
|
||||||
</xs:schema>
|
</xs:schema>
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
|
||||||
|
<AmmunitionHUD xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="AmmunitionHUD.xsd">
|
||||||
|
</AmmunitionHUD>
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
<?xml version="1.0"?>
|
||||||
|
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:t="types">
|
||||||
|
<xs:import schemaLocation="../Types.xsd" namespace="types"/>
|
||||||
|
<xs:include schemaLocation="../Types/TeamEnum.xsd"/>
|
||||||
|
<xs:element name="AmmunitionHUD">
|
||||||
|
<xs:annotation>
|
||||||
|
<xs:documentation>Hud element for tracking ammunition from parent with AssaultWeapon component. Child with the name "MagazineAmmo" tracks clip ammunition. Child with the name "Ammo" tracks ammo.</xs:documentation>
|
||||||
|
</xs:annotation>
|
||||||
|
</xs:element>
|
||||||
|
</xs:schema>
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
|
||||||
|
<KillFeed xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="KillFeed.xsd">
|
||||||
|
</KillFeed>
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
<?xml version="1.0"?>
|
||||||
|
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:t="types">
|
||||||
|
<xs:import schemaLocation="../Types.xsd" namespace="types"/>
|
||||||
|
<xs:element name="KillFeed">
|
||||||
|
<xs:annotation>
|
||||||
|
<xs:documentation>HUD element for tracking the 3 last kills, printed on the children with the names "KillFeed1", "KillFeed2", "KillFeed3"</xs:documentation>
|
||||||
|
</xs:annotation>
|
||||||
|
</xs:element>
|
||||||
|
</xs:schema>
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
|
<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
|
||||||
<Text xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="Text.xsd">
|
<Text xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="Text.xsd">
|
||||||
<Content>Text</Content>
|
<Content></Content>
|
||||||
<Resource></Resource>
|
<Resource></Resource>
|
||||||
<Color R="1" G="1" B="1" A="1"/>
|
<Color R="1" G="1" B="1" A="1"/>
|
||||||
<Visible>true</Visible>
|
<Visible>true</Visible>
|
||||||
|
|||||||
@@ -0,0 +1,98 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
|
||||||
|
<Entity name="AmmunitionHUD" xmlns:c="components" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../Types/Entity.xsd">
|
||||||
|
|
||||||
|
<Components>
|
||||||
|
<c:AmmunitionHUD/>
|
||||||
|
<c:Transform>
|
||||||
|
<Position X="-0.0430000015" Y="0.131501317" Z="-0.0670000017"/>
|
||||||
|
<Scale X="0.400000006" Y="0.400000006" Z="0.400000006"/>
|
||||||
|
</c:Transform>
|
||||||
|
</Components>
|
||||||
|
|
||||||
|
<Children>
|
||||||
|
<Entity name="AmmunitionHUDBackground">
|
||||||
|
<Components>
|
||||||
|
<c:Sprite>
|
||||||
|
<DiffuseTexture>Textures/Core/UnitHexagon.png</DiffuseTexture>
|
||||||
|
<Color A="0.588235319" B="0" G="0" R="0"/>
|
||||||
|
</c:Sprite>
|
||||||
|
<c:Transform>
|
||||||
|
<Position X="0" Y="0" Z="-0.00200000009"/>
|
||||||
|
<Scale X="0.119999997" Y="0.119999997" Z="0.119999997"/>
|
||||||
|
</c:Transform>
|
||||||
|
</Components>
|
||||||
|
<Children/>
|
||||||
|
</Entity>
|
||||||
|
<Entity>
|
||||||
|
<Components>
|
||||||
|
<c:Transform/>
|
||||||
|
</Components>
|
||||||
|
<Children>
|
||||||
|
<Entity name="MagazineAmmo">
|
||||||
|
<Components>
|
||||||
|
<c:Text>
|
||||||
|
<Content>0</Content>
|
||||||
|
<Resource>Fonts/DroidSans.ttf,64</Resource>
|
||||||
|
<Color A="1" B="3.92156863" G="1.17647064" R="0"/>
|
||||||
|
</c:Text>
|
||||||
|
<c:Transform>
|
||||||
|
<Scale X="0.0599999987" Y="0.0599999987" Z="0.0599999987"/>
|
||||||
|
</c:Transform>
|
||||||
|
</Components>
|
||||||
|
<Children/>
|
||||||
|
</Entity>
|
||||||
|
<Entity name="Ammo">
|
||||||
|
<Components>
|
||||||
|
<c:Text>
|
||||||
|
<Content>360</Content>
|
||||||
|
<Resource>Fonts/DroidSans.ttf,64</Resource>
|
||||||
|
<Color A="1" B="3.92156863" G="1.17647064" R="0"/>
|
||||||
|
</c:Text>
|
||||||
|
<c:Transform>
|
||||||
|
<Position X="5.2833886e-05" Y="-0.0407950208" Z="0"/>
|
||||||
|
<Scale X="0.0399999991" Y="0.0399999991" Z="0.0399999991"/>
|
||||||
|
</c:Transform>
|
||||||
|
</Components>
|
||||||
|
<Children/>
|
||||||
|
</Entity>
|
||||||
|
</Children>
|
||||||
|
</Entity>
|
||||||
|
<Entity>
|
||||||
|
<Components>
|
||||||
|
<c:Transform>
|
||||||
|
<Position X="-0.00200000009" Y="0.00400000019" Z="-0.00100000005"/>
|
||||||
|
</c:Transform>
|
||||||
|
</Components>
|
||||||
|
<Children>
|
||||||
|
<Entity name="MagazineAmmo">
|
||||||
|
<Components>
|
||||||
|
<c:Text>
|
||||||
|
<Content>0</Content>
|
||||||
|
<Resource>Fonts/DroidSans.ttf,64</Resource>
|
||||||
|
<Color A="1" B="0" G="0" R="0"/>
|
||||||
|
</c:Text>
|
||||||
|
<c:Transform>
|
||||||
|
<Scale X="0.0599999987" Y="0.0599999987" Z="0.0599999987"/>
|
||||||
|
</c:Transform>
|
||||||
|
</Components>
|
||||||
|
<Children/>
|
||||||
|
</Entity>
|
||||||
|
<Entity name="Ammo">
|
||||||
|
<Components>
|
||||||
|
<c:Text>
|
||||||
|
<Content>360</Content>
|
||||||
|
<Resource>Fonts/DroidSans.ttf,64</Resource>
|
||||||
|
<Color A="1" B="0" G="0" R="0"/>
|
||||||
|
</c:Text>
|
||||||
|
<c:Transform>
|
||||||
|
<Position X="5.2833886e-05" Y="-0.0407950208" Z="0"/>
|
||||||
|
<Scale X="0.0399999991" Y="0.0399999991" Z="0.0399999991"/>
|
||||||
|
</c:Transform>
|
||||||
|
</Components>
|
||||||
|
<Children/>
|
||||||
|
</Entity>
|
||||||
|
</Children>
|
||||||
|
</Entity>
|
||||||
|
</Children>
|
||||||
|
|
||||||
|
</Entity>
|
||||||
@@ -0,0 +1,62 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
|
||||||
|
<Entity name="AmmunitionHUD" xmlns:c="components" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../Types/Entity.xsd">
|
||||||
|
|
||||||
|
<Components>
|
||||||
|
<c:AmmunitionHUD/>
|
||||||
|
<c:Transform>
|
||||||
|
<Position X="-0.0430000015" Y="0.131501317" Z="-0.0670000017"/>
|
||||||
|
<Scale X="0.400000006" Y="0.400000006" Z="0.400000006"/>
|
||||||
|
</c:Transform>
|
||||||
|
</Components>
|
||||||
|
|
||||||
|
<Children>
|
||||||
|
<Entity name="AmmunitionHUDBackground">
|
||||||
|
<Components>
|
||||||
|
<c:Sprite>
|
||||||
|
<DiffuseTexture>Textures/Core/UnitHexagon.png</DiffuseTexture>
|
||||||
|
<Color A="0.588235319" B="0" G="0" R="0"/>
|
||||||
|
</c:Sprite>
|
||||||
|
<c:Transform>
|
||||||
|
<Position X="0" Y="0" Z="-0.00200000009"/>
|
||||||
|
<Scale X="0.119999997" Y="0.119999997" Z="0.119999997"/>
|
||||||
|
</c:Transform>
|
||||||
|
</Components>
|
||||||
|
<Children/>
|
||||||
|
</Entity>
|
||||||
|
<Entity name="AmmunitionText">
|
||||||
|
<Components>
|
||||||
|
<c:Transform/>
|
||||||
|
</Components>
|
||||||
|
<Children>
|
||||||
|
<Entity name="MagazineAmmo">
|
||||||
|
<Components>
|
||||||
|
<c:Text>
|
||||||
|
<Content>32</Content>
|
||||||
|
<Resource>Fonts/DroidSans.ttf,64</Resource>
|
||||||
|
<Color A="1" B="3.92156863" G="1.17647064" R="0"/>
|
||||||
|
</c:Text>
|
||||||
|
<c:Transform>
|
||||||
|
<Scale X="0.0599999987" Y="0.0599999987" Z="0.0599999987"/>
|
||||||
|
</c:Transform>
|
||||||
|
</Components>
|
||||||
|
<Children/>
|
||||||
|
</Entity>
|
||||||
|
<Entity name="Ammo">
|
||||||
|
<Components>
|
||||||
|
<c:Text>
|
||||||
|
<Content>360</Content>
|
||||||
|
<Resource>Fonts/DroidSans.ttf,64</Resource>
|
||||||
|
<Color A="1" B="3.92156863" G="1.17647064" R="0"/>
|
||||||
|
</c:Text>
|
||||||
|
<c:Transform>
|
||||||
|
<Position X="5.2833886e-05" Y="-0.0407950208" Z="0"/>
|
||||||
|
<Scale X="0.0399999991" Y="0.0399999991" Z="0.0399999991"/>
|
||||||
|
</c:Transform>
|
||||||
|
</Components>
|
||||||
|
<Children/>
|
||||||
|
</Entity>
|
||||||
|
</Children>
|
||||||
|
</Entity>
|
||||||
|
</Children>
|
||||||
|
|
||||||
|
</Entity>
|
||||||
+3
-2
@@ -1,9 +1,10 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
|
<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
|
||||||
<Entity name="HudOrigin" xmlns:c="components" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../Types/Entity.xsd">
|
<Entity name="CapturePointHUD" xmlns:c="components" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../Types/Entity.xsd">
|
||||||
|
|
||||||
<Components>
|
<Components>
|
||||||
<c:Transform>
|
<c:Transform>
|
||||||
<Position X="-24.3529072" Y="0" Z="6.95243597"/>
|
<Position X="0" Y="0.190541431" Z="0"/>
|
||||||
|
<Scale X="0.0599999987" Y="0.0599999987" Z="0.0599999987"/>
|
||||||
</c:Transform>
|
</c:Transform>
|
||||||
</Components>
|
</Components>
|
||||||
|
|
||||||
@@ -0,0 +1,255 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
|
||||||
|
<Entity name="Player" xmlns:c="components" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../Types/Entity.xsd">
|
||||||
|
|
||||||
|
<Components>
|
||||||
|
<c:AABB>
|
||||||
|
<Origin X="0" Y="0.772000015" Z="0"/>
|
||||||
|
<Size X="1" Y="1.60000002" Z="1"/>
|
||||||
|
</c:AABB>
|
||||||
|
<c:AssaultWeapon>
|
||||||
|
<RPM>600</RPM>
|
||||||
|
</c:AssaultWeapon>
|
||||||
|
<c:Collidable/>
|
||||||
|
<c:DashAbility/>
|
||||||
|
<c:Health/>
|
||||||
|
<c:Physics>
|
||||||
|
<Velocity X="2.30999646e-23" Y="0" Z="1.05272533e-23"/>
|
||||||
|
</c:Physics>
|
||||||
|
<c:Player>
|
||||||
|
<MovementSpeed>5</MovementSpeed>
|
||||||
|
</c:Player>
|
||||||
|
<c:Team>
|
||||||
|
<Team>
|
||||||
|
<Red/>
|
||||||
|
</Team>
|
||||||
|
</c:Team>
|
||||||
|
<c:Transform>
|
||||||
|
<Position X="0" Y="0.0288832653" Z="2.64837074"/>
|
||||||
|
</c:Transform>
|
||||||
|
</Components>
|
||||||
|
|
||||||
|
<Children>
|
||||||
|
<Entity name="Camera">
|
||||||
|
<Components>
|
||||||
|
<c:Camera/>
|
||||||
|
<c:Transform>
|
||||||
|
<Position X="0" Y="1.27700007" Z="0"/>
|
||||||
|
</c:Transform>
|
||||||
|
</Components>
|
||||||
|
<Children>
|
||||||
|
<Entity name="PlayerName">
|
||||||
|
<Components>
|
||||||
|
<c:Text>
|
||||||
|
<Resource>Fonts/DroidSans.ttf,100</Resource>
|
||||||
|
<Color A="1" B="0" G="1" R="0"/>
|
||||||
|
</c:Text>
|
||||||
|
<c:Transform>
|
||||||
|
<Position X="0.100000001" Y="0.248000011" Z="-0.248000011"/>
|
||||||
|
<Scale X="0.100000001" Y="0.113000005" Z="0.5"/>
|
||||||
|
<Orientation X="0" Y="3.14199996" Z="0"/>
|
||||||
|
</c:Transform>
|
||||||
|
</Components>
|
||||||
|
<Children/>
|
||||||
|
</Entity>
|
||||||
|
<Entity name="CameraModel">
|
||||||
|
<Components>
|
||||||
|
<c:Model>
|
||||||
|
<Resource>Models/Widgets/Camera.mesh</Resource>
|
||||||
|
<Visible>false</Visible>
|
||||||
|
</c:Model>
|
||||||
|
<c:Transform>
|
||||||
|
<Position X="0" Y="0.0331346765" Z="-0.0792061687"/>
|
||||||
|
<Scale X="1.30000007" Y="1.50000012" Z="1"/>
|
||||||
|
</c:Transform>
|
||||||
|
</Components>
|
||||||
|
<Children/>
|
||||||
|
</Entity>
|
||||||
|
<Entity name="HUD">
|
||||||
|
<Components>
|
||||||
|
<c:Transform>
|
||||||
|
<Position X="0" Y="0" Z="-0.5"/>
|
||||||
|
</c:Transform>
|
||||||
|
</Components>
|
||||||
|
<Children>
|
||||||
|
<Entity name="HealthBar">
|
||||||
|
<Components>
|
||||||
|
<c:Fill>
|
||||||
|
<Percentage>1</Percentage>
|
||||||
|
<Color A="0" B="1" G="0" R="0"/>
|
||||||
|
</c:Fill>
|
||||||
|
<c:HealthHUD/>
|
||||||
|
<c:Model>
|
||||||
|
<Resource>Models/Core/UnitHexagon.mesh</Resource>
|
||||||
|
<Color A="1" B="0.70588237" G="0.70588237" R="0.70588237"/>
|
||||||
|
</c:Model>
|
||||||
|
<c:Transform>
|
||||||
|
<Position X="-0.383000016" Y="-0.185000002" Z="0"/>
|
||||||
|
<Scale X="0.150000006" Y="0.150000006" Z="0.150000006"/>
|
||||||
|
<Orientation X="0" Y="0.594000041" Z="0"/>
|
||||||
|
</c:Transform>
|
||||||
|
</Components>
|
||||||
|
<Children/>
|
||||||
|
</Entity>
|
||||||
|
<Entity name="Crosshair">
|
||||||
|
<Components>
|
||||||
|
<c:Sprite>
|
||||||
|
<DiffuseTexture>Textures/Weapons/Crosshair/SmallThickHoleDot.png</DiffuseTexture>
|
||||||
|
<DepthSort>false</DepthSort>
|
||||||
|
</c:Sprite>
|
||||||
|
<c:Transform>
|
||||||
|
<Position X="0" Y="0" Z="0.200000003"/>
|
||||||
|
<Scale X="0.0250000004" Y="0.0250000004" Z="0"/>
|
||||||
|
</c:Transform>
|
||||||
|
</Components>
|
||||||
|
<Children/>
|
||||||
|
</Entity>
|
||||||
|
</Children>
|
||||||
|
</Entity>
|
||||||
|
<Entity name="Hands">
|
||||||
|
<Components>
|
||||||
|
<c:Animation>
|
||||||
|
<AnimationName1>Idle</AnimationName1>
|
||||||
|
<Time1>0.28963486380924053</Time1>
|
||||||
|
<Speed1>1</Speed1>
|
||||||
|
</c:Animation>
|
||||||
|
<c:Model>
|
||||||
|
<Resource>Models/Characters/Assault/FirstPerson.mesh</Resource>
|
||||||
|
<Transparent>true</Transparent>
|
||||||
|
</c:Model>
|
||||||
|
<c:Transform/>
|
||||||
|
</Components>
|
||||||
|
<Children>
|
||||||
|
<Entity name="WeaponModel">
|
||||||
|
<Components>
|
||||||
|
<c:BoneAttachment>
|
||||||
|
<BoneName>R_Arm_Weapon_Joint</BoneName>
|
||||||
|
</c:BoneAttachment>
|
||||||
|
<c:Model>
|
||||||
|
<Resource>Models/Weapons/Blue/AssaultWeaponBlue.mesh</Resource>
|
||||||
|
<Transparent>true</Transparent>
|
||||||
|
</c:Model>
|
||||||
|
<c:Transform>
|
||||||
|
<Position X="0.120430455" Y="-0.231800437" Z="-0.181454748"/>
|
||||||
|
<Orientation X="0.0104047749" Y="-0.00268166233" Z="0.042844031"/>
|
||||||
|
</c:Transform>
|
||||||
|
</Components>
|
||||||
|
<Children>
|
||||||
|
<Entity name="WeaponMuzzle">
|
||||||
|
<Components>
|
||||||
|
<c:Spawner>
|
||||||
|
<EntityFile>Schema/Entities/RayBlue.xml</EntityFile>
|
||||||
|
</c:Spawner>
|
||||||
|
<c:Transform>
|
||||||
|
<Position X="0.00325386273" Y="0.0970000029" Z="-0.843000054"/>
|
||||||
|
</c:Transform>
|
||||||
|
</Components>
|
||||||
|
<Children/>
|
||||||
|
</Entity>
|
||||||
|
</Children>
|
||||||
|
</Entity>
|
||||||
|
<Entity name="FirstPersonReloadSpawner">
|
||||||
|
<Components>
|
||||||
|
<c:Spawner>
|
||||||
|
<EntityFile>Schema/Entities/WeaponReloadEffect.xml</EntityFile>
|
||||||
|
</c:Spawner>
|
||||||
|
<c:Transform/>
|
||||||
|
</Components>
|
||||||
|
<Children/>
|
||||||
|
</Entity>
|
||||||
|
</Children>
|
||||||
|
</Entity>
|
||||||
|
</Children>
|
||||||
|
</Entity>
|
||||||
|
<Entity name="ThirdPersonCamera">
|
||||||
|
<Components>
|
||||||
|
<c:Camera/>
|
||||||
|
<c:Model>
|
||||||
|
<Resource>Models/Widgets/Camera.mesh</Resource>
|
||||||
|
<Visible>false</Visible>
|
||||||
|
</c:Model>
|
||||||
|
<c:Transform>
|
||||||
|
<Position X="-0.284000009" Y="1.83800006" Z="1.18900001"/>
|
||||||
|
<Orientation X="5.95600033" Y="0" Z="0"/>
|
||||||
|
</c:Transform>
|
||||||
|
</Components>
|
||||||
|
<Children/>
|
||||||
|
</Entity>
|
||||||
|
<Entity name="PlayerModel">
|
||||||
|
<Components>
|
||||||
|
<c:Animation>
|
||||||
|
<AnimationName1>Idle</AnimationName1>
|
||||||
|
<Time1>0.42156525436696768</Time1>
|
||||||
|
<Speed1>1</Speed1>
|
||||||
|
</c:Animation>
|
||||||
|
<c:AnimationOffset>
|
||||||
|
<AnimationName>AimRifle</AnimationName>
|
||||||
|
<Time>0.5</Time>
|
||||||
|
</c:AnimationOffset>
|
||||||
|
<c:HiddenForLocalPlayer/>
|
||||||
|
<c:Model>
|
||||||
|
<Resource>Models/Characters/Assault/AssaultAnimations.mesh</Resource>
|
||||||
|
<Color A="1" B="0" G="0" R="1"/>
|
||||||
|
</c:Model>
|
||||||
|
<c:Transform/>
|
||||||
|
</Components>
|
||||||
|
<Children>
|
||||||
|
<Entity name="ThirdPersonWeaponModel">
|
||||||
|
<Components>
|
||||||
|
<c:BoneAttachment>
|
||||||
|
<BoneName>R_Arm_Weapon_Joint</BoneName>
|
||||||
|
</c:BoneAttachment>
|
||||||
|
<c:Model>
|
||||||
|
<Resource>Models/Weapons/Blue/AssaultWeaponBlue.mesh</Resource>
|
||||||
|
<Visible>false</Visible>
|
||||||
|
</c:Model>
|
||||||
|
<c:Transform>
|
||||||
|
<Position X="0.160716802" Y="1.02800739" Z="-0.215931982"/>
|
||||||
|
<Orientation X="-0.0627654716" Y="-0.0450839326" Z="0.119217664"/>
|
||||||
|
</c:Transform>
|
||||||
|
</Components>
|
||||||
|
<Children>
|
||||||
|
<Entity name="ThirdPersonWeaponMuzzle">
|
||||||
|
<Components>
|
||||||
|
<c:Spawner>
|
||||||
|
<EntityFile>Schema/Entities/RayBlue.xml</EntityFile>
|
||||||
|
</c:Spawner>
|
||||||
|
<c:Transform>
|
||||||
|
<Position X="0.00644115033" Y="0.096679531" Z="-0.436609417"/>
|
||||||
|
</c:Transform>
|
||||||
|
</Components>
|
||||||
|
<Children/>
|
||||||
|
</Entity>
|
||||||
|
</Children>
|
||||||
|
</Entity>
|
||||||
|
</Children>
|
||||||
|
</Entity>
|
||||||
|
<Entity name="AABBStanding">
|
||||||
|
<Components>
|
||||||
|
<c:Model>
|
||||||
|
<Resource>Models/Core/UnitCube.mesh</Resource>
|
||||||
|
<Color A="0.427450985" B="1" G="1" R="1"/>
|
||||||
|
<Visible>false</Visible>
|
||||||
|
</c:Model>
|
||||||
|
<c:Transform>
|
||||||
|
<Position X="0" Y="0.772000015" Z="0"/>
|
||||||
|
<Scale X="1" Y="1.60000002" Z="1"/>
|
||||||
|
</c:Transform>
|
||||||
|
</Components>
|
||||||
|
<Children/>
|
||||||
|
</Entity>
|
||||||
|
<Entity name="AABBCrouching">
|
||||||
|
<Components>
|
||||||
|
<c:Model>
|
||||||
|
<Resource>Models/Core/UnitCube.mesh</Resource>
|
||||||
|
<Color A="0.745098054" B="1" G="0" R="1"/>
|
||||||
|
<Visible>false</Visible>
|
||||||
|
</c:Model>
|
||||||
|
<c:Transform>
|
||||||
|
<Position X="0" Y="0.772000015" Z="0"/>
|
||||||
|
</c:Transform>
|
||||||
|
</Components>
|
||||||
|
<Children/>
|
||||||
|
</Entity>
|
||||||
|
</Children>
|
||||||
|
|
||||||
|
</Entity>
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -2,27 +2,26 @@
|
|||||||
<Entity xmlns:c="components" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../Types/Entity.xsd">
|
<Entity xmlns:c="components" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../Types/Entity.xsd">
|
||||||
|
|
||||||
<Components>
|
<Components>
|
||||||
<c:Model>
|
|
||||||
<Resource>Models/Effects/JumpEffectHexagon.mesh</Resource>
|
|
||||||
<Color A="0.576470613" B="500" G="255" R="0.854901969"/>
|
|
||||||
<Transparent>true</Transparent>
|
|
||||||
</c:Model>
|
|
||||||
<c:Transform>
|
|
||||||
<Position X="0.600000024" Y="0.800000012" Z="0"/>
|
|
||||||
<Scale X="0.50000012" Y="0.50000019" Z="0.50000014"/>
|
|
||||||
</c:Transform>
|
|
||||||
<c:Lifetime>
|
<c:Lifetime>
|
||||||
<Lifetime>0.5</Lifetime>
|
<Lifetime>0.5</Lifetime>
|
||||||
</c:Lifetime>
|
</c:Lifetime>
|
||||||
<c:ExplosionEffect>
|
<c:ExplosionEffect>
|
||||||
<ColorByDistance>true</ColorByDistance>
|
<ColorByDistance>true</ColorByDistance>
|
||||||
<Velocity X="0" Y="-7.76300049" Z="0"/>
|
<Velocity X="3.60000014" Y="3.93700027" Z="0"/>
|
||||||
<ExplosionOrigin X="0" Y="2.67900002" Z="0"/>
|
|
||||||
<ExponentialAccelaration>true</ExponentialAccelaration>
|
<ExponentialAccelaration>true</ExponentialAccelaration>
|
||||||
<ExplosionDuration>0.5</ExplosionDuration>
|
<ExplosionDuration>0.5</ExplosionDuration>
|
||||||
<EndColor A="0" B="0" G="0" R="1"/>
|
<EndColor A="0" B="1" G="1" R="1"/>
|
||||||
<Randomness>true</Randomness>
|
<Randomness>true</Randomness>
|
||||||
</c:ExplosionEffect>
|
</c:ExplosionEffect>
|
||||||
|
<c:Model>
|
||||||
|
<Resource>Models/Effects/JumpEffectHexagon.mesh</Resource>
|
||||||
|
<Color A="0.545098066" B="500" G="255" R="0.854901969"/>
|
||||||
|
<Transparent>true</Transparent>
|
||||||
|
</c:Model>
|
||||||
|
<c:Transform>
|
||||||
|
<Position X="0.600000024" Y="0.800000012" Z="0"/>
|
||||||
|
<Scale X="0.500000119" Y="0.500000179" Z="0.500000119"/>
|
||||||
|
</c:Transform>
|
||||||
</Components>
|
</Components>
|
||||||
|
|
||||||
<Children/>
|
<Children/>
|
||||||
|
|||||||
@@ -0,0 +1,50 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
|
||||||
|
<Entity name="HealthHUD" xmlns:c="components" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../Types/Entity.xsd">
|
||||||
|
|
||||||
|
<Components>
|
||||||
|
<c:Transform/>
|
||||||
|
</Components>
|
||||||
|
|
||||||
|
<Children>
|
||||||
|
<Entity name="HealthText">
|
||||||
|
<Components>
|
||||||
|
<c:Fill>
|
||||||
|
<Percentage>1</Percentage>
|
||||||
|
<Color A="1" B="1" G="0" R="0"/>
|
||||||
|
</c:Fill>
|
||||||
|
<c:HealthHUD/>
|
||||||
|
<c:Text>
|
||||||
|
<Content>100/100</Content>
|
||||||
|
<Resource>Fonts/DroidSans.ttf,64</Resource>
|
||||||
|
<Color A="0.392156869" B="1" G="0" R="0"/>
|
||||||
|
</c:Text>
|
||||||
|
<c:Transform>
|
||||||
|
<Position X="-0.355000019" Y="-0.203000009" Z="0.0410000011"/>
|
||||||
|
<Scale X="0.0350000001" Y="0.0350000001" Z="0.0350000001"/>
|
||||||
|
<Orientation X="0" Y="0.410000026" Z="0"/>
|
||||||
|
</c:Transform>
|
||||||
|
</Components>
|
||||||
|
<Children/>
|
||||||
|
</Entity>
|
||||||
|
<Entity name="HealthBar">
|
||||||
|
<Components>
|
||||||
|
<c:Fill>
|
||||||
|
<Percentage>1</Percentage>
|
||||||
|
<Color A="0.196078435" B="1" G="0" R="0"/>
|
||||||
|
</c:Fill>
|
||||||
|
<c:Sprite>
|
||||||
|
<DiffuseTexture>Textures/HealthHUD3.png</DiffuseTexture>
|
||||||
|
<Color A="0.588235319" B="0" G="0" R="0"/>
|
||||||
|
</c:Sprite>
|
||||||
|
<c:HealthHUD/>
|
||||||
|
<c:Transform>
|
||||||
|
<Position X="-0.263000011" Y="-0.185000002" Z="0"/>
|
||||||
|
<Scale X="0.106000006" Y="0.333000004" Z="0.150000006"/>
|
||||||
|
<Orientation X="5.87300014" Y="0" Z="4.71200037"/>
|
||||||
|
</c:Transform>
|
||||||
|
</Components>
|
||||||
|
<Children/>
|
||||||
|
</Entity>
|
||||||
|
</Children>
|
||||||
|
|
||||||
|
</Entity>
|
||||||
@@ -89,6 +89,7 @@
|
|||||||
<c:Collidable/>
|
<c:Collidable/>
|
||||||
<c:Model>
|
<c:Model>
|
||||||
<Resource>Models/Props/Highground5.mesh</Resource>
|
<Resource>Models/Props/Highground5.mesh</Resource>
|
||||||
|
<Color A="1" B="7.84313726" G="7.84313726" R="7.84313726"/>
|
||||||
</c:Model>
|
</c:Model>
|
||||||
<c:Transform/>
|
<c:Transform/>
|
||||||
</Components>
|
</Components>
|
||||||
@@ -99,6 +100,7 @@
|
|||||||
<c:Collidable/>
|
<c:Collidable/>
|
||||||
<c:Model>
|
<c:Model>
|
||||||
<Resource>Models/Props/Highground6.mesh</Resource>
|
<Resource>Models/Props/Highground6.mesh</Resource>
|
||||||
|
<Color A="1" B="7.84313726" G="7.84313726" R="7.84313726"/>
|
||||||
</c:Model>
|
</c:Model>
|
||||||
<c:Transform/>
|
<c:Transform/>
|
||||||
</Components>
|
</Components>
|
||||||
@@ -368,7 +370,7 @@
|
|||||||
<Components>
|
<Components>
|
||||||
<c:Collidable/>
|
<c:Collidable/>
|
||||||
<c:Model>
|
<c:Model>
|
||||||
<Resource>Models/Props/Pillars/SciFiPillar2.mesh</Resource>
|
<Resource>Models/Props/Pillars/SciFiPillar2Blue.mesh</Resource>
|
||||||
</c:Model>
|
</c:Model>
|
||||||
<c:Transform>
|
<c:Transform>
|
||||||
<Position X="55.0098839" Y="0" Z="80.7891693"/>
|
<Position X="55.0098839" Y="0" Z="80.7891693"/>
|
||||||
@@ -381,7 +383,7 @@
|
|||||||
<Components>
|
<Components>
|
||||||
<c:Collidable/>
|
<c:Collidable/>
|
||||||
<c:Model>
|
<c:Model>
|
||||||
<Resource>Models/Props/Pillars/SciFiPillar2.mesh</Resource>
|
<Resource>Models/Props/Pillars/SciFiPillar2Red.mesh</Resource>
|
||||||
</c:Model>
|
</c:Model>
|
||||||
<c:Transform>
|
<c:Transform>
|
||||||
<Position X="-57.6669235" Y="-0.0117412386" Z="-84.8278427"/>
|
<Position X="-57.6669235" Y="-0.0117412386" Z="-84.8278427"/>
|
||||||
@@ -1515,6 +1517,7 @@
|
|||||||
<c:Collidable/>
|
<c:Collidable/>
|
||||||
<c:Model>
|
<c:Model>
|
||||||
<Resource>Models/Props/Flora/SpecialRoot.mesh</Resource>
|
<Resource>Models/Props/Flora/SpecialRoot.mesh</Resource>
|
||||||
|
<Color A="1" B="1" G="7.84313726" R="7.84313726"/>
|
||||||
</c:Model>
|
</c:Model>
|
||||||
<c:Transform>
|
<c:Transform>
|
||||||
<Position X="-37.5227966" Y="-0.41070056" Z="38.790432"/>
|
<Position X="-37.5227966" Y="-0.41070056" Z="38.790432"/>
|
||||||
@@ -1885,7 +1888,7 @@
|
|||||||
<Components>
|
<Components>
|
||||||
<c:Collidable/>
|
<c:Collidable/>
|
||||||
<c:Model>
|
<c:Model>
|
||||||
<Resource>Models/Props/Bridges/SciFiBridge.mesh</Resource>
|
<Resource>Models/Props/Bridges/SciFiBridge1Red.mesh</Resource>
|
||||||
</c:Model>
|
</c:Model>
|
||||||
<c:Transform>
|
<c:Transform>
|
||||||
<Position X="45.3988762" Y="6.10456753" Z="-73.9011993"/>
|
<Position X="45.3988762" Y="6.10456753" Z="-73.9011993"/>
|
||||||
@@ -2004,7 +2007,7 @@
|
|||||||
<Components>
|
<Components>
|
||||||
<c:Collidable/>
|
<c:Collidable/>
|
||||||
<c:Model>
|
<c:Model>
|
||||||
<Resource>Models/Props/Bridges/SciFiBridge.mesh</Resource>
|
<Resource>Models/Props/Bridges/SciFiBridge1Blue.mesh</Resource>
|
||||||
</c:Model>
|
</c:Model>
|
||||||
<c:Transform>
|
<c:Transform>
|
||||||
<Position X="-41.0066338" Y="6.08244133" Z="75.8575821"/>
|
<Position X="-41.0066338" Y="6.08244133" Z="75.8575821"/>
|
||||||
@@ -2138,7 +2141,7 @@
|
|||||||
<Components>
|
<Components>
|
||||||
<c:Collidable/>
|
<c:Collidable/>
|
||||||
<c:Model>
|
<c:Model>
|
||||||
<Resource>Models/Props/Bridges/SciFiBridge.mesh</Resource>
|
<Resource>Models/Props/Bridges/SciFiBridge1Blue.mesh</Resource>
|
||||||
</c:Model>
|
</c:Model>
|
||||||
<c:Transform>
|
<c:Transform>
|
||||||
<Position X="-47.6850471" Y="7.0585866" Z="38.1646194"/>
|
<Position X="-47.6850471" Y="7.0585866" Z="38.1646194"/>
|
||||||
@@ -2151,7 +2154,7 @@
|
|||||||
<Components>
|
<Components>
|
||||||
<c:Collidable/>
|
<c:Collidable/>
|
||||||
<c:Model>
|
<c:Model>
|
||||||
<Resource>Models/Props/Bridges/SciFiBridge.mesh</Resource>
|
<Resource>Models/Props/Bridges/SciFiBridge1Blue.mesh</Resource>
|
||||||
</c:Model>
|
</c:Model>
|
||||||
<c:Transform>
|
<c:Transform>
|
||||||
<Position X="-25.9571095" Y="6.43997049" Z="41.7452164"/>
|
<Position X="-25.9571095" Y="6.43997049" Z="41.7452164"/>
|
||||||
@@ -2178,7 +2181,7 @@
|
|||||||
<Components>
|
<Components>
|
||||||
<c:Collidable/>
|
<c:Collidable/>
|
||||||
<c:Model>
|
<c:Model>
|
||||||
<Resource>Models/Props/Bridges/SciFiBridge.mesh</Resource>
|
<Resource>Models/Props/Bridges/SciFiBridge1Red.mesh</Resource>
|
||||||
</c:Model>
|
</c:Model>
|
||||||
<c:Transform>
|
<c:Transform>
|
||||||
<Position X="46.3167992" Y="6.36057663" Z="-37.5957794"/>
|
<Position X="46.3167992" Y="6.36057663" Z="-37.5957794"/>
|
||||||
@@ -2191,7 +2194,7 @@
|
|||||||
<Components>
|
<Components>
|
||||||
<c:Collidable/>
|
<c:Collidable/>
|
||||||
<c:Model>
|
<c:Model>
|
||||||
<Resource>Models/Props/Bridges/SciFiBridge.mesh</Resource>
|
<Resource>Models/Props/Bridges/SciFiBridge1Red.mesh</Resource>
|
||||||
</c:Model>
|
</c:Model>
|
||||||
<c:Transform>
|
<c:Transform>
|
||||||
<Position X="25.2147388" Y="6.4451251" Z="-41.7257042"/>
|
<Position X="25.2147388" Y="6.4451251" Z="-41.7257042"/>
|
||||||
@@ -2730,6 +2733,7 @@
|
|||||||
<c:Collidable/>
|
<c:Collidable/>
|
||||||
<c:Model>
|
<c:Model>
|
||||||
<Resource>Models/Props/Flora/SpecialRoot.mesh</Resource>
|
<Resource>Models/Props/Flora/SpecialRoot.mesh</Resource>
|
||||||
|
<Color A="1" B="1" G="7.84313726" R="7.84313726"/>
|
||||||
</c:Model>
|
</c:Model>
|
||||||
<c:Transform>
|
<c:Transform>
|
||||||
<Position X="36.8391495" Y="0.354240507" Z="-36.1228752"/>
|
<Position X="36.8391495" Y="0.354240507" Z="-36.1228752"/>
|
||||||
@@ -2948,6 +2952,7 @@
|
|||||||
<c:Collidable/>
|
<c:Collidable/>
|
||||||
<c:Model>
|
<c:Model>
|
||||||
<Resource>Models/Props/Flora/SpecialRoot.mesh</Resource>
|
<Resource>Models/Props/Flora/SpecialRoot.mesh</Resource>
|
||||||
|
<Color A="1" B="1" G="7.84313726" R="7.84313726"/>
|
||||||
</c:Model>
|
</c:Model>
|
||||||
<c:Transform>
|
<c:Transform>
|
||||||
<Position X="-15.8430891" Y="2.84977508" Z="55.3108711"/>
|
<Position X="-15.8430891" Y="2.84977508" Z="55.3108711"/>
|
||||||
@@ -3061,6 +3066,7 @@
|
|||||||
<c:Collidable/>
|
<c:Collidable/>
|
||||||
<c:Model>
|
<c:Model>
|
||||||
<Resource>Models/Props/Flora/SpecialRoot.mesh</Resource>
|
<Resource>Models/Props/Flora/SpecialRoot.mesh</Resource>
|
||||||
|
<Color A="1" B="1" G="7.84313726" R="7.84313726"/>
|
||||||
</c:Model>
|
</c:Model>
|
||||||
<c:Transform>
|
<c:Transform>
|
||||||
<Position X="16.3593407" Y="4.03186893" Z="-54.4961166"/>
|
<Position X="16.3593407" Y="4.03186893" Z="-54.4961166"/>
|
||||||
@@ -4058,21 +4064,7 @@
|
|||||||
<Orientation X="0" Y="1.93500006" Z="0"/>
|
<Orientation X="0" Y="1.93500006" Z="0"/>
|
||||||
</c:Transform>
|
</c:Transform>
|
||||||
</Components>
|
</Components>
|
||||||
<Children>
|
<Children/>
|
||||||
<Entity>
|
|
||||||
<Components>
|
|
||||||
<c:Collidable/>
|
|
||||||
<c:Model>
|
|
||||||
<Resource>Models/Props/PickUps/HealthPickUp.mesh</Resource>
|
|
||||||
</c:Model>
|
|
||||||
<c:Transform>
|
|
||||||
<Position X="0" Y="2.53721571" Z="0"/>
|
|
||||||
<Scale X="0.800000012" Y="0.800000012" Z="0.800000012"/>
|
|
||||||
</c:Transform>
|
|
||||||
</Components>
|
|
||||||
<Children/>
|
|
||||||
</Entity>
|
|
||||||
</Children>
|
|
||||||
</Entity>
|
</Entity>
|
||||||
<Entity>
|
<Entity>
|
||||||
<Components>
|
<Components>
|
||||||
@@ -4925,7 +4917,7 @@
|
|||||||
<Components>
|
<Components>
|
||||||
<c:PlayerSpawn/>
|
<c:PlayerSpawn/>
|
||||||
<c:Spawner>
|
<c:Spawner>
|
||||||
<EntityFile>Schema/Entities/Player.xml</EntityFile>
|
<EntityFile>Schema/Entities/PlayerRed.xml</EntityFile>
|
||||||
</c:Spawner>
|
</c:Spawner>
|
||||||
<c:Team>
|
<c:Team>
|
||||||
<Team>
|
<Team>
|
||||||
@@ -4933,7 +4925,7 @@
|
|||||||
</Team>
|
</Team>
|
||||||
</c:Team>
|
</c:Team>
|
||||||
<c:Transform>
|
<c:Transform>
|
||||||
<Position X="0" Y="6.69097853" Z="0"/>
|
<Position X="-60.3695679" Y="2.14482641" Z="-79.3789597"/>
|
||||||
</c:Transform>
|
</c:Transform>
|
||||||
</Components>
|
</Components>
|
||||||
<Children>
|
<Children>
|
||||||
@@ -4942,9 +4934,10 @@
|
|||||||
<c:SpawnPoint/>
|
<c:SpawnPoint/>
|
||||||
<c:Model>
|
<c:Model>
|
||||||
<Resource>Models/Characters/Assault/AssaultTPose.mesh</Resource>
|
<Resource>Models/Characters/Assault/AssaultTPose.mesh</Resource>
|
||||||
|
<Visible>false</Visible>
|
||||||
</c:Model>
|
</c:Model>
|
||||||
<c:Transform>
|
<c:Transform>
|
||||||
<Position X="1" Y="0" Z="0"/>
|
<Position X="9.3347702" Y="2.70210314" Z="2.33294678"/>
|
||||||
</c:Transform>
|
</c:Transform>
|
||||||
</Components>
|
</Components>
|
||||||
<Children/>
|
<Children/>
|
||||||
@@ -4954,9 +4947,10 @@
|
|||||||
<c:SpawnPoint/>
|
<c:SpawnPoint/>
|
||||||
<c:Model>
|
<c:Model>
|
||||||
<Resource>Models/Characters/Assault/AssaultTPose.mesh</Resource>
|
<Resource>Models/Characters/Assault/AssaultTPose.mesh</Resource>
|
||||||
|
<Visible>false</Visible>
|
||||||
</c:Model>
|
</c:Model>
|
||||||
<c:Transform>
|
<c:Transform>
|
||||||
<Position X="-1" Y="0" Z="0"/>
|
<Position X="5.59104443" Y="2.14147282" Z="6.07936668"/>
|
||||||
</c:Transform>
|
</c:Transform>
|
||||||
</Components>
|
</Components>
|
||||||
<Children/>
|
<Children/>
|
||||||
@@ -4966,9 +4960,10 @@
|
|||||||
<c:SpawnPoint/>
|
<c:SpawnPoint/>
|
||||||
<c:Model>
|
<c:Model>
|
||||||
<Resource>Models/Characters/Assault/AssaultTPose.mesh</Resource>
|
<Resource>Models/Characters/Assault/AssaultTPose.mesh</Resource>
|
||||||
|
<Visible>false</Visible>
|
||||||
</c:Model>
|
</c:Model>
|
||||||
<c:Transform>
|
<c:Transform>
|
||||||
<Position X="0" Y="0" Z="1"/>
|
<Position X="-2.2788806" Y="0" Z="3.17202592"/>
|
||||||
</c:Transform>
|
</c:Transform>
|
||||||
</Components>
|
</Components>
|
||||||
<Children/>
|
<Children/>
|
||||||
@@ -4978,15 +4973,245 @@
|
|||||||
<c:SpawnPoint/>
|
<c:SpawnPoint/>
|
||||||
<c:Model>
|
<c:Model>
|
||||||
<Resource>Models/Characters/Assault/AssaultTPose.mesh</Resource>
|
<Resource>Models/Characters/Assault/AssaultTPose.mesh</Resource>
|
||||||
|
<Visible>false</Visible>
|
||||||
</c:Model>
|
</c:Model>
|
||||||
<c:Transform>
|
<c:Transform>
|
||||||
<Position X="0" Y="0" Z="-1"/>
|
<Position X="1.14053249" Y="0" Z="-1.67306876"/>
|
||||||
</c:Transform>
|
</c:Transform>
|
||||||
</Components>
|
</Components>
|
||||||
<Children/>
|
<Children/>
|
||||||
</Entity>
|
</Entity>
|
||||||
</Children>
|
</Children>
|
||||||
</Entity>
|
</Entity>
|
||||||
|
<Entity name="SpawnerBlueTeam">
|
||||||
|
<Components>
|
||||||
|
<c:PlayerSpawn/>
|
||||||
|
<c:Spawner>
|
||||||
|
<EntityFile>Schema/Entities/Player.xml</EntityFile>
|
||||||
|
</c:Spawner>
|
||||||
|
<c:Team>
|
||||||
|
<Team>
|
||||||
|
<Blue/>
|
||||||
|
</Team>
|
||||||
|
</c:Team>
|
||||||
|
<c:Transform>
|
||||||
|
<Position X="60.0169258" Y="2.37972379" Z="76.2893906"/>
|
||||||
|
</c:Transform>
|
||||||
|
</Components>
|
||||||
|
<Children>
|
||||||
|
<Entity name="SpawnPointRedTeam">
|
||||||
|
<Components>
|
||||||
|
<c:SpawnPoint/>
|
||||||
|
<c:Model>
|
||||||
|
<Resource>Models/Characters/Assault/AssaultTPose.mesh</Resource>
|
||||||
|
<Visible>false</Visible>
|
||||||
|
</c:Model>
|
||||||
|
<c:Transform>
|
||||||
|
<Position X="2.02889442" Y="0.194165871" Z="-1.17950201"/>
|
||||||
|
</c:Transform>
|
||||||
|
</Components>
|
||||||
|
<Children/>
|
||||||
|
</Entity>
|
||||||
|
<Entity name="SpawnPointRedTeam">
|
||||||
|
<Components>
|
||||||
|
<c:SpawnPoint/>
|
||||||
|
<c:Model>
|
||||||
|
<Resource>Models/Characters/Assault/AssaultTPose.mesh</Resource>
|
||||||
|
<Visible>false</Visible>
|
||||||
|
</c:Model>
|
||||||
|
<c:Transform>
|
||||||
|
<Position X="-9.04242706" Y="1.82531989" Z="-0.421615779"/>
|
||||||
|
</c:Transform>
|
||||||
|
</Components>
|
||||||
|
<Children/>
|
||||||
|
</Entity>
|
||||||
|
<Entity name="SpawnPointRedTeam">
|
||||||
|
<Components>
|
||||||
|
<c:SpawnPoint/>
|
||||||
|
<c:Model>
|
||||||
|
<Resource>Models/Characters/Assault/AssaultTPose.mesh</Resource>
|
||||||
|
<Visible>false</Visible>
|
||||||
|
</c:Model>
|
||||||
|
<c:Transform>
|
||||||
|
<Position X="1.64179754" Y="0.634559035" Z="4.27690458"/>
|
||||||
|
</c:Transform>
|
||||||
|
</Components>
|
||||||
|
<Children/>
|
||||||
|
</Entity>
|
||||||
|
<Entity name="SpawnPointRedTeam">
|
||||||
|
<Components>
|
||||||
|
<c:SpawnPoint/>
|
||||||
|
<c:Model>
|
||||||
|
<Resource>Models/Characters/Assault/AssaultTPose.mesh</Resource>
|
||||||
|
<Visible>false</Visible>
|
||||||
|
</c:Model>
|
||||||
|
<c:Transform>
|
||||||
|
<Position X="-6.58577824" Y="1.97348273" Z="-2.86768818"/>
|
||||||
|
</c:Transform>
|
||||||
|
</Components>
|
||||||
|
<Children/>
|
||||||
|
</Entity>
|
||||||
|
</Children>
|
||||||
|
</Entity>
|
||||||
|
<Entity name="HealthPickups">
|
||||||
|
<Components>
|
||||||
|
<c:Transform/>
|
||||||
|
</Components>
|
||||||
|
<Children>
|
||||||
|
<Entity>
|
||||||
|
<Components>
|
||||||
|
<c:HealthPickup/>
|
||||||
|
<c:Model>
|
||||||
|
<Resource>Models/Props/PickUps/HealthPickUp.mesh</Resource>
|
||||||
|
</c:Model>
|
||||||
|
<c:RaptorCopter>
|
||||||
|
<Speed>0.10000000149011612</Speed>
|
||||||
|
<Axis X="0" Y="1" Z="0"/>
|
||||||
|
</c:RaptorCopter>
|
||||||
|
<c:Transform>
|
||||||
|
<Position X="48.9189453" Y="7.06223536" Z="-78.9347992"/>
|
||||||
|
<Scale X="0.300000012" Y="0.300000012" Z="0.300000012"/>
|
||||||
|
<Orientation X="0" Y="22.6496716" Z="0"/>
|
||||||
|
</c:Transform>
|
||||||
|
<c:Trigger/>
|
||||||
|
</Components>
|
||||||
|
<Children/>
|
||||||
|
</Entity>
|
||||||
|
<Entity>
|
||||||
|
<Components>
|
||||||
|
<c:AmmoPickup/>
|
||||||
|
<c:Model>
|
||||||
|
<Resource>Models/Props/PickUps/AmmoPickUp.mesh</Resource>
|
||||||
|
</c:Model>
|
||||||
|
<c:RaptorCopter>
|
||||||
|
<Speed>0.10000000149011612</Speed>
|
||||||
|
<Axis X="0" Y="1" Z="0"/>
|
||||||
|
</c:RaptorCopter>
|
||||||
|
<c:Transform>
|
||||||
|
<Position X="-59.3499641" Y="7.46932745" Z="-20.6276321"/>
|
||||||
|
<Scale X="0.300000012" Y="0.300000012" Z="0.300000012"/>
|
||||||
|
<Orientation X="0" Y="19.304081" Z="0"/>
|
||||||
|
</c:Transform>
|
||||||
|
<c:Trigger/>
|
||||||
|
</Components>
|
||||||
|
<Children/>
|
||||||
|
</Entity>
|
||||||
|
<Entity>
|
||||||
|
<Components>
|
||||||
|
<c:HealthPickup/>
|
||||||
|
<c:Model>
|
||||||
|
<Resource>Models/Props/PickUps/HealthPickUp.mesh</Resource>
|
||||||
|
</c:Model>
|
||||||
|
<c:RaptorCopter>
|
||||||
|
<Speed>0.10000000149011612</Speed>
|
||||||
|
<Axis X="0" Y="1" Z="0"/>
|
||||||
|
</c:RaptorCopter>
|
||||||
|
<c:Transform>
|
||||||
|
<Position X="-1.13644195" Y="1.38919806" Z="38.9768829"/>
|
||||||
|
<Scale X="0.300000012" Y="0.300000012" Z="0.300000012"/>
|
||||||
|
<Orientation X="0" Y="16.9120293" Z="0"/>
|
||||||
|
</c:Transform>
|
||||||
|
<c:Trigger/>
|
||||||
|
</Components>
|
||||||
|
<Children/>
|
||||||
|
</Entity>
|
||||||
|
<Entity>
|
||||||
|
<Components>
|
||||||
|
<c:HealthPickup/>
|
||||||
|
<c:Model>
|
||||||
|
<Resource>Models/Props/PickUps/HealthPickUp.mesh</Resource>
|
||||||
|
</c:Model>
|
||||||
|
<c:RaptorCopter>
|
||||||
|
<Speed>0.10000000149011612</Speed>
|
||||||
|
<Axis X="0" Y="1" Z="0"/>
|
||||||
|
</c:RaptorCopter>
|
||||||
|
<c:Transform>
|
||||||
|
<Position X="54.7225227" Y="6.51863909" Z="29.0052128"/>
|
||||||
|
<Scale X="0.300000012" Y="0.300000012" Z="0.300000012"/>
|
||||||
|
<Orientation X="0" Y="17.2259693" Z="0"/>
|
||||||
|
</c:Transform>
|
||||||
|
<c:Trigger/>
|
||||||
|
</Components>
|
||||||
|
<Children/>
|
||||||
|
</Entity>
|
||||||
|
<Entity>
|
||||||
|
<Components>
|
||||||
|
<c:AmmoPickup/>
|
||||||
|
<c:Model>
|
||||||
|
<Resource>Models/Props/PickUps/AmmoPickUp.mesh</Resource>
|
||||||
|
</c:Model>
|
||||||
|
<c:RaptorCopter>
|
||||||
|
<Speed>0.10000000149011612</Speed>
|
||||||
|
<Axis X="0" Y="1" Z="0"/>
|
||||||
|
</c:RaptorCopter>
|
||||||
|
<c:Transform>
|
||||||
|
<Position X="-51.6792374" Y="8.44526482" Z="32.5153465"/>
|
||||||
|
<Scale X="0.300000012" Y="0.300000012" Z="0.300000012"/>
|
||||||
|
<Orientation X="0" Y="16.6746445" Z="0"/>
|
||||||
|
</c:Transform>
|
||||||
|
<c:Trigger/>
|
||||||
|
</Components>
|
||||||
|
<Children/>
|
||||||
|
</Entity>
|
||||||
|
<Entity>
|
||||||
|
<Components>
|
||||||
|
<c:HealthPickup/>
|
||||||
|
<c:Model>
|
||||||
|
<Resource>Models/Props/PickUps/HealthPickUp.mesh</Resource>
|
||||||
|
</c:Model>
|
||||||
|
<c:RaptorCopter>
|
||||||
|
<Speed>0.10000000149011612</Speed>
|
||||||
|
<Axis X="0" Y="1" Z="0"/>
|
||||||
|
</c:RaptorCopter>
|
||||||
|
<c:Transform>
|
||||||
|
<Position X="-42.3974304" Y="7.28327894" Z="81.9305344"/>
|
||||||
|
<Scale X="0.300000012" Y="0.300000012" Z="0.300000012"/>
|
||||||
|
<Orientation X="0" Y="14.8039036" Z="0"/>
|
||||||
|
</c:Transform>
|
||||||
|
<c:Trigger/>
|
||||||
|
</Components>
|
||||||
|
<Children/>
|
||||||
|
</Entity>
|
||||||
|
<Entity>
|
||||||
|
<Components>
|
||||||
|
<c:AmmoPickup/>
|
||||||
|
<c:Model>
|
||||||
|
<Resource>Models/Props/PickUps/AmmoPickUp.mesh</Resource>
|
||||||
|
</c:Model>
|
||||||
|
<c:RaptorCopter>
|
||||||
|
<Speed>0.10000000149011612</Speed>
|
||||||
|
<Axis X="0" Y="1" Z="0"/>
|
||||||
|
</c:RaptorCopter>
|
||||||
|
<c:Transform>
|
||||||
|
<Position X="-9.85184956" Y="8.25567532" Z="39.6119232"/>
|
||||||
|
<Scale X="0.300000012" Y="0.300000012" Z="0.300000012"/>
|
||||||
|
<Orientation X="0" Y="13.8527527" Z="0"/>
|
||||||
|
</c:Transform>
|
||||||
|
<c:Trigger/>
|
||||||
|
</Components>
|
||||||
|
<Children/>
|
||||||
|
</Entity>
|
||||||
|
<Entity>
|
||||||
|
<Components>
|
||||||
|
<c:AmmoPickup/>
|
||||||
|
<c:Model>
|
||||||
|
<Resource>Models/Props/PickUps/AmmoPickUp.mesh</Resource>
|
||||||
|
</c:Model>
|
||||||
|
<c:RaptorCopter>
|
||||||
|
<Speed>0.10000000149011612</Speed>
|
||||||
|
<Axis X="0" Y="1" Z="0"/>
|
||||||
|
</c:RaptorCopter>
|
||||||
|
<c:Transform>
|
||||||
|
<Position X="49.2257118" Y="7.39368248" Z="-31.1810112"/>
|
||||||
|
<Scale X="0.300000012" Y="0.300000012" Z="0.300000012"/>
|
||||||
|
<Orientation X="0" Y="11.0639687" Z="0"/>
|
||||||
|
</c:Transform>
|
||||||
|
<c:Trigger/>
|
||||||
|
</Components>
|
||||||
|
<Children/>
|
||||||
|
</Entity>
|
||||||
|
</Children>
|
||||||
|
</Entity>
|
||||||
</Children>
|
</Children>
|
||||||
|
|
||||||
</Entity>
|
</Entity>
|
||||||
|
|||||||
@@ -24,7 +24,7 @@
|
|||||||
</Team>
|
</Team>
|
||||||
</c:Team>
|
</c:Team>
|
||||||
<c:Transform>
|
<c:Transform>
|
||||||
<Position X="0" Y="0.0288832653" Z="2.64837074"/>
|
<Position X="0" Y="0.0288832653" Z="0"/>
|
||||||
</c:Transform>
|
</c:Transform>
|
||||||
</Components>
|
</Components>
|
||||||
|
|
||||||
@@ -71,25 +71,6 @@
|
|||||||
</c:Transform>
|
</c:Transform>
|
||||||
</Components>
|
</Components>
|
||||||
<Children>
|
<Children>
|
||||||
<Entity name="HealthBar">
|
|
||||||
<Components>
|
|
||||||
<c:Fill>
|
|
||||||
<Percentage>1</Percentage>
|
|
||||||
<Color A="0" B="1" G="0" R="0"/>
|
|
||||||
</c:Fill>
|
|
||||||
<c:HealthHUD/>
|
|
||||||
<c:Model>
|
|
||||||
<Resource>Models/Core/UnitHexagon.mesh</Resource>
|
|
||||||
<Color A="1" B="0.70588237" G="0.70588237" R="0.70588237"/>
|
|
||||||
</c:Model>
|
|
||||||
<c:Transform>
|
|
||||||
<Position X="-0.383000016" Y="-0.185000002" Z="0"/>
|
|
||||||
<Scale X="0.150000006" Y="0.150000006" Z="0.150000006"/>
|
|
||||||
<Orientation X="0" Y="0.594000041" Z="0"/>
|
|
||||||
</c:Transform>
|
|
||||||
</Components>
|
|
||||||
<Children/>
|
|
||||||
</Entity>
|
|
||||||
<Entity name="Crosshair">
|
<Entity name="Crosshair">
|
||||||
<Components>
|
<Components>
|
||||||
<c:Sprite>
|
<c:Sprite>
|
||||||
@@ -112,17 +93,284 @@
|
|||||||
</Components>
|
</Components>
|
||||||
<Children/>
|
<Children/>
|
||||||
</Entity>
|
</Entity>
|
||||||
|
<Entity name="HealthHUD">
|
||||||
|
<Components>
|
||||||
|
<c:Transform/>
|
||||||
|
</Components>
|
||||||
|
<Children>
|
||||||
|
<Entity name="HealthText">
|
||||||
|
<Components>
|
||||||
|
<c:Fill>
|
||||||
|
<Percentage>1</Percentage>
|
||||||
|
<Color A="1" B="1" G="0" R="0"/>
|
||||||
|
</c:Fill>
|
||||||
|
<c:HealthHUD/>
|
||||||
|
<c:Text>
|
||||||
|
<Content>100/100</Content>
|
||||||
|
<Resource>Fonts/DroidSans.ttf,64</Resource>
|
||||||
|
<Color A="0.505882382" B="3.92156863" G="1.17647064" R="0"/>
|
||||||
|
</c:Text>
|
||||||
|
<c:Transform>
|
||||||
|
<Position X="-0.355000019" Y="-0.203000009" Z="0.0410000011"/>
|
||||||
|
<Scale X="0.0350000001" Y="0.0350000001" Z="0.0350000001"/>
|
||||||
|
<Orientation X="0" Y="0.410000026" Z="0"/>
|
||||||
|
</c:Transform>
|
||||||
|
</Components>
|
||||||
|
<Children/>
|
||||||
|
</Entity>
|
||||||
|
<Entity name="HealthBar">
|
||||||
|
<Components>
|
||||||
|
<c:Fill>
|
||||||
|
<Percentage>1</Percentage>
|
||||||
|
<Color A="0.301960796" B="1" G="0" R="0"/>
|
||||||
|
</c:Fill>
|
||||||
|
<c:Sprite>
|
||||||
|
<DiffuseTexture>Textures/HealthHUD3.png</DiffuseTexture>
|
||||||
|
<Color A="0.588235319" B="0" G="0" R="0"/>
|
||||||
|
</c:Sprite>
|
||||||
|
<c:HealthHUD/>
|
||||||
|
<c:Transform>
|
||||||
|
<Position X="-0.263000011" Y="-0.185000002" Z="0"/>
|
||||||
|
<Scale X="0.106000006" Y="0.333000004" Z="0.150000006"/>
|
||||||
|
<Orientation X="5.87300014" Y="0" Z="4.71200037"/>
|
||||||
|
</c:Transform>
|
||||||
|
</Components>
|
||||||
|
<Children/>
|
||||||
|
</Entity>
|
||||||
|
</Children>
|
||||||
|
</Entity>
|
||||||
|
<Entity name="CapturePointHUD">
|
||||||
|
<Components>
|
||||||
|
<c:Transform>
|
||||||
|
<Position X="0" Y="0.190541431" Z="0"/>
|
||||||
|
<Scale X="0.0599999987" Y="0.0599999987" Z="0.0599999987"/>
|
||||||
|
</c:Transform>
|
||||||
|
</Components>
|
||||||
|
<Children>
|
||||||
|
<Entity name="BackgroundHexagon">
|
||||||
|
<Components>
|
||||||
|
<c:Sprite>
|
||||||
|
<DiffuseTexture>Textures/Core/UnitHexagon.png</DiffuseTexture>
|
||||||
|
<Color A="0.300000012" B="1" G="1" R="1"/>
|
||||||
|
</c:Sprite>
|
||||||
|
<c:Transform>
|
||||||
|
<Position X="0" Y="0.919596612" Z="0"/>
|
||||||
|
</c:Transform>
|
||||||
|
</Components>
|
||||||
|
<Children>
|
||||||
|
<Entity name="ProgressionHexagon">
|
||||||
|
<Components>
|
||||||
|
<c:CapturePointHUD>
|
||||||
|
<CapturePointNumber>2</CapturePointNumber>
|
||||||
|
</c:CapturePointHUD>
|
||||||
|
<c:Fill>
|
||||||
|
<Color A="0.699999988" B="1" G="0.200000003" R="0"/>
|
||||||
|
</c:Fill>
|
||||||
|
<c:Sprite>
|
||||||
|
<DiffuseTexture>Textures/Core/UnitHexagon_Rotated.png</DiffuseTexture>
|
||||||
|
</c:Sprite>
|
||||||
|
<c:Transform>
|
||||||
|
<Position X="0" Y="0" Z="0.00999999978"/>
|
||||||
|
<Scale X="0.800000012" Y="0.800000012" Z="0.800000012"/>
|
||||||
|
<Orientation X="0" Y="0" Z="1.57079637"/>
|
||||||
|
</c:Transform>
|
||||||
|
</Components>
|
||||||
|
<Children/>
|
||||||
|
</Entity>
|
||||||
|
</Children>
|
||||||
|
</Entity>
|
||||||
|
<Entity name="BackgroundHexagon">
|
||||||
|
<Components>
|
||||||
|
<c:Sprite>
|
||||||
|
<DiffuseTexture>Textures/Core/UnitHexagon.png</DiffuseTexture>
|
||||||
|
<Color A="0.300000012" B="1" G="1" R="1"/>
|
||||||
|
</c:Sprite>
|
||||||
|
<c:Transform>
|
||||||
|
<Position X="0.811270177" Y="0.440691769" Z="-0.100000001"/>
|
||||||
|
</c:Transform>
|
||||||
|
</Components>
|
||||||
|
<Children>
|
||||||
|
<Entity name="ProgressionHexagon">
|
||||||
|
<Components>
|
||||||
|
<c:CapturePointHUD>
|
||||||
|
<CapturePointNumber>3</CapturePointNumber>
|
||||||
|
</c:CapturePointHUD>
|
||||||
|
<c:Fill>
|
||||||
|
<Percentage>0.80222018197612788</Percentage>
|
||||||
|
<Color A="0.699999988" B="1" G="0.200000003" R="0"/>
|
||||||
|
</c:Fill>
|
||||||
|
<c:Sprite>
|
||||||
|
<DiffuseTexture>Textures/Core/UnitHexagon_Rotated.png</DiffuseTexture>
|
||||||
|
</c:Sprite>
|
||||||
|
<c:Transform>
|
||||||
|
<Position X="0" Y="0" Z="0.00999999978"/>
|
||||||
|
<Scale X="0.800000012" Y="0.800000012" Z="0.800000012"/>
|
||||||
|
<Orientation X="0" Y="0" Z="1.57079637"/>
|
||||||
|
</c:Transform>
|
||||||
|
</Components>
|
||||||
|
<Children/>
|
||||||
|
</Entity>
|
||||||
|
</Children>
|
||||||
|
</Entity>
|
||||||
|
<Entity name="BackgroundHexagon">
|
||||||
|
<Components>
|
||||||
|
<c:Sprite>
|
||||||
|
<DiffuseTexture>Textures/Core/UnitHexagon.png</DiffuseTexture>
|
||||||
|
<Color A="0.699999988" B="1" G="0.200000003" R="0"/>
|
||||||
|
</c:Sprite>
|
||||||
|
<c:Transform>
|
||||||
|
<Position X="1.62788737" Y="0.919596612" Z="0"/>
|
||||||
|
</c:Transform>
|
||||||
|
</Components>
|
||||||
|
<Children>
|
||||||
|
<Entity name="ProgressionHexagon">
|
||||||
|
<Components>
|
||||||
|
<c:CapturePointHUD>
|
||||||
|
<CapturePointNumber>4</CapturePointNumber>
|
||||||
|
</c:CapturePointHUD>
|
||||||
|
<c:Fill>
|
||||||
|
<Color A="0.699999988" B="1" G="0.200000003" R="0"/>
|
||||||
|
</c:Fill>
|
||||||
|
<c:Sprite>
|
||||||
|
<DiffuseTexture>Textures/Core/UnitHexagon_Rotated.png</DiffuseTexture>
|
||||||
|
</c:Sprite>
|
||||||
|
<c:Transform>
|
||||||
|
<Position X="0" Y="0" Z="0.00999999978"/>
|
||||||
|
<Scale X="0.800000012" Y="0.800000012" Z="0.800000012"/>
|
||||||
|
<Orientation X="0" Y="0" Z="1.57079637"/>
|
||||||
|
</c:Transform>
|
||||||
|
</Components>
|
||||||
|
<Children/>
|
||||||
|
</Entity>
|
||||||
|
</Children>
|
||||||
|
</Entity>
|
||||||
|
<Entity name="BackgroundHexagon">
|
||||||
|
<Components>
|
||||||
|
<c:Sprite>
|
||||||
|
<DiffuseTexture>Textures/Core/UnitHexagon.png</DiffuseTexture>
|
||||||
|
<Color A="0.300000012" B="1" G="1" R="1"/>
|
||||||
|
</c:Sprite>
|
||||||
|
<c:Transform>
|
||||||
|
<Position X="-0.820431828" Y="0.441878349" Z="-0.100000001"/>
|
||||||
|
</c:Transform>
|
||||||
|
</Components>
|
||||||
|
<Children>
|
||||||
|
<Entity name="ProgressionHexagon">
|
||||||
|
<Components>
|
||||||
|
<c:CapturePointHUD>
|
||||||
|
<CapturePointNumber>1</CapturePointNumber>
|
||||||
|
</c:CapturePointHUD>
|
||||||
|
<c:Fill>
|
||||||
|
<Color A="0.699999988" B="1" G="0.200000003" R="0"/>
|
||||||
|
</c:Fill>
|
||||||
|
<c:Sprite>
|
||||||
|
<DiffuseTexture>Textures/Core/UnitHexagon_Rotated.png</DiffuseTexture>
|
||||||
|
</c:Sprite>
|
||||||
|
<c:Transform>
|
||||||
|
<Position X="0" Y="0" Z="0.00999999978"/>
|
||||||
|
<Scale X="0.800000012" Y="0.800000012" Z="0.800000012"/>
|
||||||
|
<Orientation X="0" Y="0" Z="1.57079637"/>
|
||||||
|
</c:Transform>
|
||||||
|
</Components>
|
||||||
|
<Children/>
|
||||||
|
</Entity>
|
||||||
|
</Children>
|
||||||
|
</Entity>
|
||||||
|
<Entity name="BackgroundHexagon">
|
||||||
|
<Components>
|
||||||
|
<c:Sprite>
|
||||||
|
<DiffuseTexture>Textures/Core/UnitHexagon.png</DiffuseTexture>
|
||||||
|
<Color A="0.699999988" B="0" G="0.200000003" R="1"/>
|
||||||
|
</c:Sprite>
|
||||||
|
<c:Transform>
|
||||||
|
<Position X="-1.58304751" Y="0.919596612" Z="0"/>
|
||||||
|
</c:Transform>
|
||||||
|
</Components>
|
||||||
|
<Children>
|
||||||
|
<Entity name="ProgressionHexagon">
|
||||||
|
<Components>
|
||||||
|
<c:CapturePointHUD/>
|
||||||
|
<c:Fill>
|
||||||
|
<Color A="0.699999988" B="1" G="0.200000003" R="0"/>
|
||||||
|
</c:Fill>
|
||||||
|
<c:Sprite>
|
||||||
|
<DiffuseTexture>Textures/Core/UnitHexagon_Rotated.png</DiffuseTexture>
|
||||||
|
</c:Sprite>
|
||||||
|
<c:Transform>
|
||||||
|
<Position X="0" Y="0" Z="0.00999999978"/>
|
||||||
|
<Scale X="0.800000012" Y="0.800000012" Z="0.800000012"/>
|
||||||
|
<Orientation X="0" Y="0" Z="1.57079637"/>
|
||||||
|
</c:Transform>
|
||||||
|
</Components>
|
||||||
|
<Children/>
|
||||||
|
</Entity>
|
||||||
|
</Children>
|
||||||
|
</Entity>
|
||||||
|
</Children>
|
||||||
|
</Entity>
|
||||||
|
<Entity name="KillFeed">
|
||||||
|
<Components>
|
||||||
|
<c:KillFeed/>
|
||||||
|
<c:Transform>
|
||||||
|
<Position X="0.486000031" Y="0.26000002" Z="0"/>
|
||||||
|
<Scale X="0.0149999997" Y="0.0149999997" Z="0.0149999997"/>
|
||||||
|
</c:Transform>
|
||||||
|
</Components>
|
||||||
|
<Children>
|
||||||
|
<Entity name="KillFeed1">
|
||||||
|
<Components>
|
||||||
|
<c:Text>
|
||||||
|
<Resource>Fonts/DroidSans.ttf,64</Resource>
|
||||||
|
<Alignment>
|
||||||
|
<Right/>
|
||||||
|
</Alignment>
|
||||||
|
</c:Text>
|
||||||
|
<c:Transform/>
|
||||||
|
</Components>
|
||||||
|
<Children/>
|
||||||
|
</Entity>
|
||||||
|
<Entity name="KillFeed2">
|
||||||
|
<Components>
|
||||||
|
<c:Text>
|
||||||
|
<Resource>Fonts/DroidSans.ttf,64</Resource>
|
||||||
|
<Alignment>
|
||||||
|
<Right/>
|
||||||
|
</Alignment>
|
||||||
|
</c:Text>
|
||||||
|
<c:Transform>
|
||||||
|
<Position X="0" Y="-1" Z="0"/>
|
||||||
|
</c:Transform>
|
||||||
|
</Components>
|
||||||
|
<Children/>
|
||||||
|
</Entity>
|
||||||
|
<Entity name="KillFeed3">
|
||||||
|
<Components>
|
||||||
|
<c:Text>
|
||||||
|
<Resource>Fonts/DroidSans.ttf,64</Resource>
|
||||||
|
<Alignment>
|
||||||
|
<Right/>
|
||||||
|
</Alignment>
|
||||||
|
</c:Text>
|
||||||
|
<c:Transform>
|
||||||
|
<Position X="0" Y="-2" Z="0"/>
|
||||||
|
</c:Transform>
|
||||||
|
</Components>
|
||||||
|
<Children/>
|
||||||
|
</Entity>
|
||||||
|
</Children>
|
||||||
|
</Entity>
|
||||||
</Children>
|
</Children>
|
||||||
</Entity>
|
</Entity>
|
||||||
<Entity name="Hands">
|
<Entity name="Hands">
|
||||||
<Components>
|
<Components>
|
||||||
<c:Animation>
|
<c:Animation>
|
||||||
<AnimationName1>Idle</AnimationName1>
|
<AnimationName1>Idle</AnimationName1>
|
||||||
<Time1>0.1719161089749548</Time1>
|
<Time1>1.6050530664521858</Time1>
|
||||||
<Speed1>1</Speed1>
|
<Speed1>1</Speed1>
|
||||||
</c:Animation>
|
</c:Animation>
|
||||||
<c:Model>
|
<c:Model>
|
||||||
<Resource>Models/Characters/Assault/FirstPerson.mesh</Resource>
|
<Resource>Models/Characters/Assault/FirstPerson.mesh</Resource>
|
||||||
|
<Color A="1" B="1" G="0.309803933" R="0"/>
|
||||||
<Transparent>true</Transparent>
|
<Transparent>true</Transparent>
|
||||||
</c:Model>
|
</c:Model>
|
||||||
<c:Transform/>
|
<c:Transform/>
|
||||||
@@ -138,8 +386,8 @@
|
|||||||
<Transparent>true</Transparent>
|
<Transparent>true</Transparent>
|
||||||
</c:Model>
|
</c:Model>
|
||||||
<c:Transform>
|
<c:Transform>
|
||||||
<Position X="0.120747983" Y="-0.228997007" Z="-0.151475653"/>
|
<Position X="0.12043035" Y="-0.234149337" Z="-0.181454644"/>
|
||||||
<Orientation X="0.0104046585" Y="-0.00268164417" Z="0.0428441912"/>
|
<Orientation X="0.0104045281" Y="-0.00268131681" Z="0.0428438708"/>
|
||||||
</c:Transform>
|
</c:Transform>
|
||||||
</Components>
|
</Components>
|
||||||
<Children>
|
<Children>
|
||||||
@@ -154,17 +402,75 @@
|
|||||||
</Components>
|
</Components>
|
||||||
<Children/>
|
<Children/>
|
||||||
</Entity>
|
</Entity>
|
||||||
|
<Entity name="FirstPersonReloadSpawner">
|
||||||
|
<Components>
|
||||||
|
<c:Spawner>
|
||||||
|
<EntityFile>Schema/Entities/ReloadEffectView.xml</EntityFile>
|
||||||
|
</c:Spawner>
|
||||||
|
<c:Transform/>
|
||||||
|
</Components>
|
||||||
|
<Children/>
|
||||||
|
</Entity>
|
||||||
|
<Entity name="AmmunitionHUD">
|
||||||
|
<Components>
|
||||||
|
<c:AmmunitionHUD/>
|
||||||
|
<c:Transform>
|
||||||
|
<Position X="-0.0430000015" Y="0.131501317" Z="-0.0670000017"/>
|
||||||
|
<Scale X="0.400000006" Y="0.400000006" Z="0.400000006"/>
|
||||||
|
</c:Transform>
|
||||||
|
</Components>
|
||||||
|
<Children>
|
||||||
|
<Entity name="AmmunitionHUDBackground">
|
||||||
|
<Components>
|
||||||
|
<c:Sprite>
|
||||||
|
<DiffuseTexture>Textures/Core/UnitHexagon.png</DiffuseTexture>
|
||||||
|
<Color A="0.588235319" B="0" G="0" R="0"/>
|
||||||
|
</c:Sprite>
|
||||||
|
<c:Transform>
|
||||||
|
<Position X="0" Y="0" Z="-0.00200000009"/>
|
||||||
|
<Scale X="0.119999997" Y="0.119999997" Z="0.119999997"/>
|
||||||
|
</c:Transform>
|
||||||
|
</Components>
|
||||||
|
<Children/>
|
||||||
|
</Entity>
|
||||||
|
<Entity name="AmmunitionText">
|
||||||
|
<Components>
|
||||||
|
<c:Transform/>
|
||||||
|
</Components>
|
||||||
|
<Children>
|
||||||
|
<Entity name="MagazineAmmo">
|
||||||
|
<Components>
|
||||||
|
<c:Text>
|
||||||
|
<Content>32</Content>
|
||||||
|
<Resource>Fonts/DroidSans.ttf,64</Resource>
|
||||||
|
<Color A="1" B="3.92156863" G="1.17647064" R="0"/>
|
||||||
|
</c:Text>
|
||||||
|
<c:Transform>
|
||||||
|
<Scale X="0.0599999987" Y="0.0599999987" Z="0.0599999987"/>
|
||||||
|
</c:Transform>
|
||||||
|
</Components>
|
||||||
|
<Children/>
|
||||||
|
</Entity>
|
||||||
|
<Entity name="Ammo">
|
||||||
|
<Components>
|
||||||
|
<c:Text>
|
||||||
|
<Content>360</Content>
|
||||||
|
<Resource>Fonts/DroidSans.ttf,64</Resource>
|
||||||
|
<Color A="1" B="3.92156863" G="1.17647064" R="0"/>
|
||||||
|
</c:Text>
|
||||||
|
<c:Transform>
|
||||||
|
<Position X="5.2833886e-05" Y="-0.0407950208" Z="0"/>
|
||||||
|
<Scale X="0.0399999991" Y="0.0399999991" Z="0.0399999991"/>
|
||||||
|
</c:Transform>
|
||||||
|
</Components>
|
||||||
|
<Children/>
|
||||||
|
</Entity>
|
||||||
|
</Children>
|
||||||
|
</Entity>
|
||||||
|
</Children>
|
||||||
|
</Entity>
|
||||||
</Children>
|
</Children>
|
||||||
</Entity>
|
</Entity>
|
||||||
<Entity name="FirstPersonReloadSpawner">
|
|
||||||
<Components>
|
|
||||||
<c:Spawner>
|
|
||||||
<EntityFile>Schema/Entities/WeaponReloadEffect.xml</EntityFile>
|
|
||||||
</c:Spawner>
|
|
||||||
<c:Transform/>
|
|
||||||
</Components>
|
|
||||||
<Children/>
|
|
||||||
</Entity>
|
|
||||||
</Children>
|
</Children>
|
||||||
</Entity>
|
</Entity>
|
||||||
</Children>
|
</Children>
|
||||||
@@ -187,7 +493,7 @@
|
|||||||
<Components>
|
<Components>
|
||||||
<c:Animation>
|
<c:Animation>
|
||||||
<AnimationName1>Idle</AnimationName1>
|
<AnimationName1>Idle</AnimationName1>
|
||||||
<Time1>1.8038469763698401</Time1>
|
<Time1>1.620305457513453</Time1>
|
||||||
<Speed1>1</Speed1>
|
<Speed1>1</Speed1>
|
||||||
</c:Animation>
|
</c:Animation>
|
||||||
<c:AnimationOffset>
|
<c:AnimationOffset>
|
||||||
@@ -198,6 +504,7 @@
|
|||||||
<c:Model>
|
<c:Model>
|
||||||
<Resource>Models/Characters/Assault/AssaultAnimations.mesh</Resource>
|
<Resource>Models/Characters/Assault/AssaultAnimations.mesh</Resource>
|
||||||
<Color A="1" B="1" G="0.309803933" R="0"/>
|
<Color A="1" B="1" G="0.309803933" R="0"/>
|
||||||
|
<Visible>false</Visible>
|
||||||
</c:Model>
|
</c:Model>
|
||||||
<c:Transform/>
|
<c:Transform/>
|
||||||
</Components>
|
</Components>
|
||||||
@@ -209,11 +516,10 @@
|
|||||||
</c:BoneAttachment>
|
</c:BoneAttachment>
|
||||||
<c:Model>
|
<c:Model>
|
||||||
<Resource>Models/Weapons/Blue/AssaultWeaponBlue.mesh</Resource>
|
<Resource>Models/Weapons/Blue/AssaultWeaponBlue.mesh</Resource>
|
||||||
<Visible>false</Visible>
|
|
||||||
</c:Model>
|
</c:Model>
|
||||||
<c:Transform>
|
<c:Transform>
|
||||||
<Position X="0.15859656" Y="1.02875519" Z="-0.21540691"/>
|
<Position X="0.160351232" Y="1.02591991" Z="-0.215102971"/>
|
||||||
<Orientation X="-0.0626692101" Y="-0.0361935496" Z="0.120095037"/>
|
<Orientation X="-0.0627480298" Y="-0.0432248674" Z="0.119431816"/>
|
||||||
</c:Transform>
|
</c:Transform>
|
||||||
</Components>
|
</Components>
|
||||||
<Children>
|
<Children>
|
||||||
@@ -228,6 +534,15 @@
|
|||||||
</Components>
|
</Components>
|
||||||
<Children/>
|
<Children/>
|
||||||
</Entity>
|
</Entity>
|
||||||
|
<Entity name="ThirdPersonReloadSpawner">
|
||||||
|
<Components>
|
||||||
|
<c:Spawner>
|
||||||
|
<EntityFile>Schema/Entities/ReloadEffectWorld.xml</EntityFile>
|
||||||
|
</c:Spawner>
|
||||||
|
<c:Transform/>
|
||||||
|
</Components>
|
||||||
|
<Children/>
|
||||||
|
</Entity>
|
||||||
</Children>
|
</Children>
|
||||||
</Entity>
|
</Entity>
|
||||||
</Children>
|
</Children>
|
||||||
|
|||||||
@@ -2,9 +2,7 @@
|
|||||||
<Entity name="Explosion" xmlns:c="components" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../Types/Entity.xsd">
|
<Entity name="Explosion" xmlns:c="components" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../Types/Entity.xsd">
|
||||||
|
|
||||||
<Components>
|
<Components>
|
||||||
<c:Animation>
|
<c:Animation/>
|
||||||
<Name>Hold Pos</Name>
|
|
||||||
</c:Animation>
|
|
||||||
<c:Lifetime>
|
<c:Lifetime>
|
||||||
<Lifetime>2.5</Lifetime>
|
<Lifetime>2.5</Lifetime>
|
||||||
</c:Lifetime>
|
</c:Lifetime>
|
||||||
|
|||||||
@@ -0,0 +1,576 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
|
||||||
|
<Entity name="Player" xmlns:c="components" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../Types/Entity.xsd">
|
||||||
|
|
||||||
|
<Components>
|
||||||
|
<c:AABB>
|
||||||
|
<Origin X="0" Y="0.772000015" Z="0"/>
|
||||||
|
<Size X="1" Y="1.60000002" Z="1"/>
|
||||||
|
</c:AABB>
|
||||||
|
<c:AssaultWeapon>
|
||||||
|
<RPM>600</RPM>
|
||||||
|
</c:AssaultWeapon>
|
||||||
|
<c:Collidable/>
|
||||||
|
<c:DashAbility/>
|
||||||
|
<c:Health/>
|
||||||
|
<c:Physics>
|
||||||
|
<Velocity X="2.30999646e-23" Y="0" Z="1.05272533e-23"/>
|
||||||
|
</c:Physics>
|
||||||
|
<c:Player>
|
||||||
|
<MovementSpeed>5</MovementSpeed>
|
||||||
|
</c:Player>
|
||||||
|
<c:Team>
|
||||||
|
<Team>
|
||||||
|
<Red/>
|
||||||
|
</Team>
|
||||||
|
</c:Team>
|
||||||
|
<c:Transform/>
|
||||||
|
</Components>
|
||||||
|
|
||||||
|
<Children>
|
||||||
|
<Entity name="Camera">
|
||||||
|
<Components>
|
||||||
|
<c:Camera/>
|
||||||
|
<c:Transform>
|
||||||
|
<Position X="0" Y="1.27700007" Z="0"/>
|
||||||
|
</c:Transform>
|
||||||
|
</Components>
|
||||||
|
<Children>
|
||||||
|
<Entity name="PlayerName">
|
||||||
|
<Components>
|
||||||
|
<c:Text>
|
||||||
|
<Resource>Fonts/DroidSans.ttf,100</Resource>
|
||||||
|
<Color A="1" B="0" G="1" R="0"/>
|
||||||
|
</c:Text>
|
||||||
|
<c:Transform>
|
||||||
|
<Position X="0.100000001" Y="0.248000011" Z="-0.248000011"/>
|
||||||
|
<Scale X="0.100000001" Y="0.113000005" Z="0.5"/>
|
||||||
|
<Orientation X="0" Y="3.14199996" Z="0"/>
|
||||||
|
</c:Transform>
|
||||||
|
</Components>
|
||||||
|
<Children/>
|
||||||
|
</Entity>
|
||||||
|
<Entity name="CameraModel">
|
||||||
|
<Components>
|
||||||
|
<c:Model>
|
||||||
|
<Resource>Models/Widgets/Camera.mesh</Resource>
|
||||||
|
<Visible>false</Visible>
|
||||||
|
</c:Model>
|
||||||
|
<c:Transform>
|
||||||
|
<Position X="0" Y="0.0331346765" Z="-0.0792061687"/>
|
||||||
|
<Scale X="1.30000007" Y="1.50000012" Z="1"/>
|
||||||
|
</c:Transform>
|
||||||
|
</Components>
|
||||||
|
<Children/>
|
||||||
|
</Entity>
|
||||||
|
<Entity name="HUD">
|
||||||
|
<Components>
|
||||||
|
<c:Transform>
|
||||||
|
<Position X="0" Y="0" Z="-0.5"/>
|
||||||
|
</c:Transform>
|
||||||
|
</Components>
|
||||||
|
<Children>
|
||||||
|
<Entity name="Crosshair">
|
||||||
|
<Components>
|
||||||
|
<c:Sprite>
|
||||||
|
<DiffuseTexture>Textures/Weapons/Crosshair/SmallThickHoleDot.png</DiffuseTexture>
|
||||||
|
<DepthSort>false</DepthSort>
|
||||||
|
</c:Sprite>
|
||||||
|
<c:Transform>
|
||||||
|
<Position X="0" Y="0" Z="0.200000003"/>
|
||||||
|
<Scale X="0.0250000004" Y="0.0250000004" Z="0"/>
|
||||||
|
</c:Transform>
|
||||||
|
</Components>
|
||||||
|
<Children/>
|
||||||
|
</Entity>
|
||||||
|
<Entity name="HitMarkerSpawner">
|
||||||
|
<Components>
|
||||||
|
<c:Spawner>
|
||||||
|
<EntityFile>Schema/Entities/HitMarker.xml</EntityFile>
|
||||||
|
</c:Spawner>
|
||||||
|
<c:Transform/>
|
||||||
|
</Components>
|
||||||
|
<Children/>
|
||||||
|
</Entity>
|
||||||
|
<Entity name="HealthHUD">
|
||||||
|
<Components>
|
||||||
|
<c:Transform/>
|
||||||
|
</Components>
|
||||||
|
<Children>
|
||||||
|
<Entity name="HealthText">
|
||||||
|
<Components>
|
||||||
|
<c:Fill>
|
||||||
|
<Percentage>1</Percentage>
|
||||||
|
<Color A="1" B="1" G="0" R="0"/>
|
||||||
|
</c:Fill>
|
||||||
|
<c:HealthHUD/>
|
||||||
|
<c:Text>
|
||||||
|
<Content>100/100</Content>
|
||||||
|
<Resource>Fonts/DroidSans.ttf,64</Resource>
|
||||||
|
<Color A="0.505882382" B="3.92156863" G="1.17647064" R="0"/>
|
||||||
|
</c:Text>
|
||||||
|
<c:Transform>
|
||||||
|
<Position X="-0.355000019" Y="-0.203000009" Z="0.0410000011"/>
|
||||||
|
<Scale X="0.0350000001" Y="0.0350000001" Z="0.0350000001"/>
|
||||||
|
<Orientation X="0" Y="0.410000026" Z="0"/>
|
||||||
|
</c:Transform>
|
||||||
|
</Components>
|
||||||
|
<Children/>
|
||||||
|
</Entity>
|
||||||
|
<Entity name="HealthBar">
|
||||||
|
<Components>
|
||||||
|
<c:Fill>
|
||||||
|
<Percentage>1</Percentage>
|
||||||
|
<Color A="0.301960796" B="1" G="0" R="0"/>
|
||||||
|
</c:Fill>
|
||||||
|
<c:Sprite>
|
||||||
|
<DiffuseTexture>Textures/HealthHUD3.png</DiffuseTexture>
|
||||||
|
<Color A="0.588235319" B="0" G="0" R="0"/>
|
||||||
|
</c:Sprite>
|
||||||
|
<c:HealthHUD/>
|
||||||
|
<c:Transform>
|
||||||
|
<Position X="-0.263000011" Y="-0.185000002" Z="0"/>
|
||||||
|
<Scale X="0.106000006" Y="0.333000004" Z="0.150000006"/>
|
||||||
|
<Orientation X="5.87300014" Y="0" Z="4.71200037"/>
|
||||||
|
</c:Transform>
|
||||||
|
</Components>
|
||||||
|
<Children/>
|
||||||
|
</Entity>
|
||||||
|
</Children>
|
||||||
|
</Entity>
|
||||||
|
<Entity name="CapturePointHUD">
|
||||||
|
<Components>
|
||||||
|
<c:Transform>
|
||||||
|
<Position X="0" Y="0.190541431" Z="0"/>
|
||||||
|
<Scale X="0.0599999987" Y="0.0599999987" Z="0.0599999987"/>
|
||||||
|
</c:Transform>
|
||||||
|
</Components>
|
||||||
|
<Children>
|
||||||
|
<Entity name="BackgroundHexagon">
|
||||||
|
<Components>
|
||||||
|
<c:Sprite>
|
||||||
|
<DiffuseTexture>Textures/Core/UnitHexagon.png</DiffuseTexture>
|
||||||
|
<Color A="0.300000012" B="1" G="1" R="1"/>
|
||||||
|
</c:Sprite>
|
||||||
|
<c:Transform>
|
||||||
|
<Position X="0" Y="0.919596612" Z="0"/>
|
||||||
|
</c:Transform>
|
||||||
|
</Components>
|
||||||
|
<Children>
|
||||||
|
<Entity name="ProgressionHexagon">
|
||||||
|
<Components>
|
||||||
|
<c:CapturePointHUD>
|
||||||
|
<CapturePointNumber>2</CapturePointNumber>
|
||||||
|
</c:CapturePointHUD>
|
||||||
|
<c:Fill>
|
||||||
|
<Color A="0.699999988" B="1" G="0.200000003" R="0"/>
|
||||||
|
</c:Fill>
|
||||||
|
<c:Sprite>
|
||||||
|
<DiffuseTexture>Textures/Core/UnitHexagon_Rotated.png</DiffuseTexture>
|
||||||
|
</c:Sprite>
|
||||||
|
<c:Transform>
|
||||||
|
<Position X="0" Y="0" Z="0.00999999978"/>
|
||||||
|
<Scale X="0.800000012" Y="0.800000012" Z="0.800000012"/>
|
||||||
|
<Orientation X="0" Y="0" Z="1.57079637"/>
|
||||||
|
</c:Transform>
|
||||||
|
</Components>
|
||||||
|
<Children/>
|
||||||
|
</Entity>
|
||||||
|
</Children>
|
||||||
|
</Entity>
|
||||||
|
<Entity name="BackgroundHexagon">
|
||||||
|
<Components>
|
||||||
|
<c:Sprite>
|
||||||
|
<DiffuseTexture>Textures/Core/UnitHexagon.png</DiffuseTexture>
|
||||||
|
<Color A="0.300000012" B="1" G="1" R="1"/>
|
||||||
|
</c:Sprite>
|
||||||
|
<c:Transform>
|
||||||
|
<Position X="0.811270177" Y="0.440691769" Z="-0.100000001"/>
|
||||||
|
</c:Transform>
|
||||||
|
</Components>
|
||||||
|
<Children>
|
||||||
|
<Entity name="ProgressionHexagon">
|
||||||
|
<Components>
|
||||||
|
<c:CapturePointHUD>
|
||||||
|
<CapturePointNumber>3</CapturePointNumber>
|
||||||
|
</c:CapturePointHUD>
|
||||||
|
<c:Fill>
|
||||||
|
<Percentage>0.80222018197612788</Percentage>
|
||||||
|
<Color A="0.699999988" B="1" G="0.200000003" R="0"/>
|
||||||
|
</c:Fill>
|
||||||
|
<c:Sprite>
|
||||||
|
<DiffuseTexture>Textures/Core/UnitHexagon_Rotated.png</DiffuseTexture>
|
||||||
|
</c:Sprite>
|
||||||
|
<c:Transform>
|
||||||
|
<Position X="0" Y="0" Z="0.00999999978"/>
|
||||||
|
<Scale X="0.800000012" Y="0.800000012" Z="0.800000012"/>
|
||||||
|
<Orientation X="0" Y="0" Z="1.57079637"/>
|
||||||
|
</c:Transform>
|
||||||
|
</Components>
|
||||||
|
<Children/>
|
||||||
|
</Entity>
|
||||||
|
</Children>
|
||||||
|
</Entity>
|
||||||
|
<Entity name="BackgroundHexagon">
|
||||||
|
<Components>
|
||||||
|
<c:Sprite>
|
||||||
|
<DiffuseTexture>Textures/Core/UnitHexagon.png</DiffuseTexture>
|
||||||
|
<Color A="0.699999988" B="1" G="0.200000003" R="0"/>
|
||||||
|
</c:Sprite>
|
||||||
|
<c:Transform>
|
||||||
|
<Position X="1.62788737" Y="0.919596612" Z="0"/>
|
||||||
|
</c:Transform>
|
||||||
|
</Components>
|
||||||
|
<Children>
|
||||||
|
<Entity name="ProgressionHexagon">
|
||||||
|
<Components>
|
||||||
|
<c:CapturePointHUD>
|
||||||
|
<CapturePointNumber>4</CapturePointNumber>
|
||||||
|
</c:CapturePointHUD>
|
||||||
|
<c:Fill>
|
||||||
|
<Color A="0.699999988" B="1" G="0.200000003" R="0"/>
|
||||||
|
</c:Fill>
|
||||||
|
<c:Sprite>
|
||||||
|
<DiffuseTexture>Textures/Core/UnitHexagon_Rotated.png</DiffuseTexture>
|
||||||
|
</c:Sprite>
|
||||||
|
<c:Transform>
|
||||||
|
<Position X="0" Y="0" Z="0.00999999978"/>
|
||||||
|
<Scale X="0.800000012" Y="0.800000012" Z="0.800000012"/>
|
||||||
|
<Orientation X="0" Y="0" Z="1.57079637"/>
|
||||||
|
</c:Transform>
|
||||||
|
</Components>
|
||||||
|
<Children/>
|
||||||
|
</Entity>
|
||||||
|
</Children>
|
||||||
|
</Entity>
|
||||||
|
<Entity name="BackgroundHexagon">
|
||||||
|
<Components>
|
||||||
|
<c:Sprite>
|
||||||
|
<DiffuseTexture>Textures/Core/UnitHexagon.png</DiffuseTexture>
|
||||||
|
<Color A="0.300000012" B="1" G="1" R="1"/>
|
||||||
|
</c:Sprite>
|
||||||
|
<c:Transform>
|
||||||
|
<Position X="-0.820431828" Y="0.441878349" Z="-0.100000001"/>
|
||||||
|
</c:Transform>
|
||||||
|
</Components>
|
||||||
|
<Children>
|
||||||
|
<Entity name="ProgressionHexagon">
|
||||||
|
<Components>
|
||||||
|
<c:CapturePointHUD>
|
||||||
|
<CapturePointNumber>1</CapturePointNumber>
|
||||||
|
</c:CapturePointHUD>
|
||||||
|
<c:Fill>
|
||||||
|
<Color A="0.699999988" B="1" G="0.200000003" R="0"/>
|
||||||
|
</c:Fill>
|
||||||
|
<c:Sprite>
|
||||||
|
<DiffuseTexture>Textures/Core/UnitHexagon_Rotated.png</DiffuseTexture>
|
||||||
|
</c:Sprite>
|
||||||
|
<c:Transform>
|
||||||
|
<Position X="0" Y="0" Z="0.00999999978"/>
|
||||||
|
<Scale X="0.800000012" Y="0.800000012" Z="0.800000012"/>
|
||||||
|
<Orientation X="0" Y="0" Z="1.57079637"/>
|
||||||
|
</c:Transform>
|
||||||
|
</Components>
|
||||||
|
<Children/>
|
||||||
|
</Entity>
|
||||||
|
</Children>
|
||||||
|
</Entity>
|
||||||
|
<Entity name="BackgroundHexagon">
|
||||||
|
<Components>
|
||||||
|
<c:Sprite>
|
||||||
|
<DiffuseTexture>Textures/Core/UnitHexagon.png</DiffuseTexture>
|
||||||
|
<Color A="0.699999988" B="0" G="0.200000003" R="1"/>
|
||||||
|
</c:Sprite>
|
||||||
|
<c:Transform>
|
||||||
|
<Position X="-1.58304751" Y="0.919596612" Z="0"/>
|
||||||
|
</c:Transform>
|
||||||
|
</Components>
|
||||||
|
<Children>
|
||||||
|
<Entity name="ProgressionHexagon">
|
||||||
|
<Components>
|
||||||
|
<c:CapturePointHUD/>
|
||||||
|
<c:Fill>
|
||||||
|
<Color A="0.699999988" B="1" G="0.200000003" R="0"/>
|
||||||
|
</c:Fill>
|
||||||
|
<c:Sprite>
|
||||||
|
<DiffuseTexture>Textures/Core/UnitHexagon_Rotated.png</DiffuseTexture>
|
||||||
|
</c:Sprite>
|
||||||
|
<c:Transform>
|
||||||
|
<Position X="0" Y="0" Z="0.00999999978"/>
|
||||||
|
<Scale X="0.800000012" Y="0.800000012" Z="0.800000012"/>
|
||||||
|
<Orientation X="0" Y="0" Z="1.57079637"/>
|
||||||
|
</c:Transform>
|
||||||
|
</Components>
|
||||||
|
<Children/>
|
||||||
|
</Entity>
|
||||||
|
</Children>
|
||||||
|
</Entity>
|
||||||
|
</Children>
|
||||||
|
</Entity>
|
||||||
|
<Entity name="KillFeed">
|
||||||
|
<Components>
|
||||||
|
<c:KillFeed/>
|
||||||
|
<c:Transform>
|
||||||
|
<Position X="0.486000031" Y="0.26000002" Z="0"/>
|
||||||
|
<Scale X="0.0149999997" Y="0.0149999997" Z="0.0149999997"/>
|
||||||
|
</c:Transform>
|
||||||
|
</Components>
|
||||||
|
<Children>
|
||||||
|
<Entity name="KillFeed1">
|
||||||
|
<Components>
|
||||||
|
<c:Text>
|
||||||
|
<Resource>Fonts/DroidSans.ttf,64</Resource>
|
||||||
|
<Alignment>
|
||||||
|
<Right/>
|
||||||
|
</Alignment>
|
||||||
|
</c:Text>
|
||||||
|
<c:Transform/>
|
||||||
|
</Components>
|
||||||
|
<Children/>
|
||||||
|
</Entity>
|
||||||
|
<Entity name="KillFeed2">
|
||||||
|
<Components>
|
||||||
|
<c:Text>
|
||||||
|
<Resource>Fonts/DroidSans.ttf,64</Resource>
|
||||||
|
<Alignment>
|
||||||
|
<Right/>
|
||||||
|
</Alignment>
|
||||||
|
</c:Text>
|
||||||
|
<c:Transform>
|
||||||
|
<Position X="0" Y="-1" Z="0"/>
|
||||||
|
</c:Transform>
|
||||||
|
</Components>
|
||||||
|
<Children/>
|
||||||
|
</Entity>
|
||||||
|
<Entity name="KillFeed3">
|
||||||
|
<Components>
|
||||||
|
<c:Text>
|
||||||
|
<Resource>Fonts/DroidSans.ttf,64</Resource>
|
||||||
|
<Alignment>
|
||||||
|
<Right/>
|
||||||
|
</Alignment>
|
||||||
|
</c:Text>
|
||||||
|
<c:Transform>
|
||||||
|
<Position X="0" Y="-2" Z="0"/>
|
||||||
|
</c:Transform>
|
||||||
|
</Components>
|
||||||
|
<Children/>
|
||||||
|
</Entity>
|
||||||
|
</Children>
|
||||||
|
</Entity>
|
||||||
|
</Children>
|
||||||
|
</Entity>
|
||||||
|
<Entity name="Hands">
|
||||||
|
<Components>
|
||||||
|
<c:Animation>
|
||||||
|
<AnimationName1>Idle</AnimationName1>
|
||||||
|
<Time1>1.6050530664521858</Time1>
|
||||||
|
<Speed1>1</Speed1>
|
||||||
|
</c:Animation>
|
||||||
|
<c:Model>
|
||||||
|
<Resource>Models/Characters/Assault/FirstPerson.mesh</Resource>
|
||||||
|
<Color A="1" B="0" G="0" R="1"/>
|
||||||
|
<Transparent>true</Transparent>
|
||||||
|
</c:Model>
|
||||||
|
<c:Transform/>
|
||||||
|
</Components>
|
||||||
|
<Children>
|
||||||
|
<Entity name="WeaponModel">
|
||||||
|
<Components>
|
||||||
|
<c:BoneAttachment>
|
||||||
|
<BoneName>R_Arm_Weapon_Joint</BoneName>
|
||||||
|
</c:BoneAttachment>
|
||||||
|
<c:Model>
|
||||||
|
<Resource>Models/Weapons/Red/AssaultWeaponRed.mesh</Resource>
|
||||||
|
<Transparent>true</Transparent>
|
||||||
|
</c:Model>
|
||||||
|
<c:Transform>
|
||||||
|
<Position X="0.12043035" Y="-0.234149337" Z="-0.181454644"/>
|
||||||
|
<Orientation X="0.0104045281" Y="-0.00268131681" Z="0.0428438708"/>
|
||||||
|
</c:Transform>
|
||||||
|
</Components>
|
||||||
|
<Children>
|
||||||
|
<Entity name="WeaponMuzzle">
|
||||||
|
<Components>
|
||||||
|
<c:Spawner>
|
||||||
|
<EntityFile>Schema/Entities/RayRed.xml</EntityFile>
|
||||||
|
</c:Spawner>
|
||||||
|
<c:Transform>
|
||||||
|
<Position X="0.00325386273" Y="0.0970000029" Z="-0.843000054"/>
|
||||||
|
</c:Transform>
|
||||||
|
</Components>
|
||||||
|
<Children/>
|
||||||
|
</Entity>
|
||||||
|
<Entity name="FirstPersonReloadSpawner">
|
||||||
|
<Components>
|
||||||
|
<c:Spawner>
|
||||||
|
<EntityFile>Schema/Entities/ReloadEffectViewRed.xml</EntityFile>
|
||||||
|
</c:Spawner>
|
||||||
|
<c:Transform/>
|
||||||
|
</Components>
|
||||||
|
<Children/>
|
||||||
|
</Entity>
|
||||||
|
<Entity name="AmmunitionHUD">
|
||||||
|
<Components>
|
||||||
|
<c:AmmunitionHUD/>
|
||||||
|
<c:Transform>
|
||||||
|
<Position X="-0.0430000015" Y="0.131501317" Z="-0.0670000017"/>
|
||||||
|
<Scale X="0.400000006" Y="0.400000006" Z="0.400000006"/>
|
||||||
|
</c:Transform>
|
||||||
|
</Components>
|
||||||
|
<Children>
|
||||||
|
<Entity name="AmmunitionHUDBackground">
|
||||||
|
<Components>
|
||||||
|
<c:Sprite>
|
||||||
|
<DiffuseTexture>Textures/Core/UnitHexagon.png</DiffuseTexture>
|
||||||
|
<Color A="0.588235319" B="0" G="0" R="0"/>
|
||||||
|
</c:Sprite>
|
||||||
|
<c:Transform>
|
||||||
|
<Position X="0" Y="0" Z="-0.00200000009"/>
|
||||||
|
<Scale X="0.119999997" Y="0.119999997" Z="0.119999997"/>
|
||||||
|
</c:Transform>
|
||||||
|
</Components>
|
||||||
|
<Children/>
|
||||||
|
</Entity>
|
||||||
|
<Entity name="AmmunitionText">
|
||||||
|
<Components>
|
||||||
|
<c:Transform/>
|
||||||
|
</Components>
|
||||||
|
<Children>
|
||||||
|
<Entity name="MagazineAmmo">
|
||||||
|
<Components>
|
||||||
|
<c:Text>
|
||||||
|
<Content>32</Content>
|
||||||
|
<Resource>Fonts/DroidSans.ttf,64</Resource>
|
||||||
|
<Color A="1" B="3.92156863" G="1.17647064" R="0"/>
|
||||||
|
</c:Text>
|
||||||
|
<c:Transform>
|
||||||
|
<Scale X="0.0599999987" Y="0.0599999987" Z="0.0599999987"/>
|
||||||
|
</c:Transform>
|
||||||
|
</Components>
|
||||||
|
<Children/>
|
||||||
|
</Entity>
|
||||||
|
<Entity name="Ammo">
|
||||||
|
<Components>
|
||||||
|
<c:Text>
|
||||||
|
<Content>360</Content>
|
||||||
|
<Resource>Fonts/DroidSans.ttf,64</Resource>
|
||||||
|
<Color A="1" B="3.92156863" G="1.17647064" R="0"/>
|
||||||
|
</c:Text>
|
||||||
|
<c:Transform>
|
||||||
|
<Position X="5.2833886e-05" Y="-0.0407950208" Z="0"/>
|
||||||
|
<Scale X="0.0399999991" Y="0.0399999991" Z="0.0399999991"/>
|
||||||
|
</c:Transform>
|
||||||
|
</Components>
|
||||||
|
<Children/>
|
||||||
|
</Entity>
|
||||||
|
</Children>
|
||||||
|
</Entity>
|
||||||
|
</Children>
|
||||||
|
</Entity>
|
||||||
|
</Children>
|
||||||
|
</Entity>
|
||||||
|
</Children>
|
||||||
|
</Entity>
|
||||||
|
</Children>
|
||||||
|
</Entity>
|
||||||
|
<Entity name="ThirdPersonCamera">
|
||||||
|
<Components>
|
||||||
|
<c:Camera/>
|
||||||
|
<c:Model>
|
||||||
|
<Resource>Models/Widgets/Camera.mesh</Resource>
|
||||||
|
<Visible>false</Visible>
|
||||||
|
</c:Model>
|
||||||
|
<c:Transform>
|
||||||
|
<Position X="-0.284000009" Y="1.83800006" Z="1.18900001"/>
|
||||||
|
<Orientation X="5.95600033" Y="0" Z="0"/>
|
||||||
|
</c:Transform>
|
||||||
|
</Components>
|
||||||
|
<Children/>
|
||||||
|
</Entity>
|
||||||
|
<Entity name="PlayerModel">
|
||||||
|
<Components>
|
||||||
|
<c:Animation>
|
||||||
|
<AnimationName1>Idle</AnimationName1>
|
||||||
|
<Time1>1.620305457513453</Time1>
|
||||||
|
<Speed1>1</Speed1>
|
||||||
|
</c:Animation>
|
||||||
|
<c:AnimationOffset>
|
||||||
|
<AnimationName>AimRifle</AnimationName>
|
||||||
|
<Time>0.5</Time>
|
||||||
|
</c:AnimationOffset>
|
||||||
|
<c:HiddenForLocalPlayer/>
|
||||||
|
<c:Model>
|
||||||
|
<Resource>Models/Characters/Assault/AssaultAnimations.mesh</Resource>
|
||||||
|
<Color A="1" B="0" G="0" R="1"/>
|
||||||
|
</c:Model>
|
||||||
|
<c:Transform/>
|
||||||
|
</Components>
|
||||||
|
<Children>
|
||||||
|
<Entity name="ThirdPersonWeaponModel">
|
||||||
|
<Components>
|
||||||
|
<c:BoneAttachment>
|
||||||
|
<BoneName>R_Arm_Weapon_Joint</BoneName>
|
||||||
|
</c:BoneAttachment>
|
||||||
|
<c:Model>
|
||||||
|
<Resource>Models/Weapons/Red/AssaultWeaponRed.mesh</Resource>
|
||||||
|
</c:Model>
|
||||||
|
<c:Transform>
|
||||||
|
<Position X="0.160351232" Y="1.02591991" Z="-0.215102971"/>
|
||||||
|
<Orientation X="-0.0627480298" Y="-0.0432248674" Z="0.119431816"/>
|
||||||
|
</c:Transform>
|
||||||
|
</Components>
|
||||||
|
<Children>
|
||||||
|
<Entity name="ThirdPersonWeaponMuzzle">
|
||||||
|
<Components>
|
||||||
|
<c:Spawner>
|
||||||
|
<EntityFile>Schema/Entities/RayRed.xml</EntityFile>
|
||||||
|
</c:Spawner>
|
||||||
|
<c:Transform>
|
||||||
|
<Position X="0.00644115033" Y="0.096679531" Z="-0.436609417"/>
|
||||||
|
</c:Transform>
|
||||||
|
</Components>
|
||||||
|
<Children/>
|
||||||
|
</Entity>
|
||||||
|
<Entity name="ThirdPersonReloadSpawner">
|
||||||
|
<Components>
|
||||||
|
<c:Spawner>
|
||||||
|
<EntityFile>Schema/Entities/ReloadEffectWorldRed.xml</EntityFile>
|
||||||
|
</c:Spawner>
|
||||||
|
<c:Transform/>
|
||||||
|
</Components>
|
||||||
|
<Children/>
|
||||||
|
</Entity>
|
||||||
|
</Children>
|
||||||
|
</Entity>
|
||||||
|
</Children>
|
||||||
|
</Entity>
|
||||||
|
<Entity name="AABBStanding">
|
||||||
|
<Components>
|
||||||
|
<c:Model>
|
||||||
|
<Resource>Models/Core/UnitCube.mesh</Resource>
|
||||||
|
<Color A="0.427450985" B="1" G="1" R="1"/>
|
||||||
|
<Visible>false</Visible>
|
||||||
|
</c:Model>
|
||||||
|
<c:Transform>
|
||||||
|
<Position X="0" Y="0.772000015" Z="0"/>
|
||||||
|
<Scale X="1" Y="1.60000002" Z="1"/>
|
||||||
|
</c:Transform>
|
||||||
|
</Components>
|
||||||
|
<Children/>
|
||||||
|
</Entity>
|
||||||
|
<Entity name="AABBCrouching">
|
||||||
|
<Components>
|
||||||
|
<c:Model>
|
||||||
|
<Resource>Models/Core/UnitCube.mesh</Resource>
|
||||||
|
<Color A="0.745098054" B="1" G="0" R="1"/>
|
||||||
|
<Visible>false</Visible>
|
||||||
|
</c:Model>
|
||||||
|
<c:Transform>
|
||||||
|
<Position X="0" Y="0.772000015" Z="0"/>
|
||||||
|
</c:Transform>
|
||||||
|
</Components>
|
||||||
|
<Children/>
|
||||||
|
</Entity>
|
||||||
|
</Children>
|
||||||
|
|
||||||
|
</Entity>
|
||||||
@@ -6,12 +6,12 @@
|
|||||||
<Lifetime>0.25</Lifetime>
|
<Lifetime>0.25</Lifetime>
|
||||||
</c:Lifetime>
|
</c:Lifetime>
|
||||||
<c:Model>
|
<c:Model>
|
||||||
<Resource>Models/Weapons/CylinderBullet.mesh</Resource>
|
<Resource>Models/Effects/CylinderShot.mesh</Resource>
|
||||||
<Color A="0.156862751" B="0" G="0.525490224" R="39.2156868"/>
|
<Color A="0.149019614" B="0" G="0" R="39.2156868"/>
|
||||||
<Transparent>true</Transparent>
|
<Transparent>true</Transparent>
|
||||||
</c:Model>
|
</c:Model>
|
||||||
<c:Transform>
|
<c:Transform>
|
||||||
<Scale X="0.0110000009" Y="0.029000001" Z="100"/>
|
<Scale X="0.0690000057" Y="0.0690000057" Z="100"/>
|
||||||
</c:Transform>
|
</c:Transform>
|
||||||
</Components>
|
</Components>
|
||||||
|
|
||||||
|
|||||||
+1
-8
@@ -2,9 +2,6 @@
|
|||||||
<Entity name="WeaponModel" xmlns:c="components" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../Types/Entity.xsd">
|
<Entity name="WeaponModel" xmlns:c="components" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../Types/Entity.xsd">
|
||||||
|
|
||||||
<Components>
|
<Components>
|
||||||
<c:BoneAttachment>
|
|
||||||
<BoneName>R_Arm_Weapon_Joint</BoneName>
|
|
||||||
</c:BoneAttachment>
|
|
||||||
<c:Lifetime>
|
<c:Lifetime>
|
||||||
<Lifetime>2</Lifetime>
|
<Lifetime>2</Lifetime>
|
||||||
</c:Lifetime>
|
</c:Lifetime>
|
||||||
@@ -18,12 +15,8 @@
|
|||||||
</c:ExplosionEffect>
|
</c:ExplosionEffect>
|
||||||
<c:Model>
|
<c:Model>
|
||||||
<Resource>Models/Weapons/Blue/AssaultWeaponBlue.mesh</Resource>
|
<Resource>Models/Weapons/Blue/AssaultWeaponBlue.mesh</Resource>
|
||||||
<Transparent>true</Transparent>
|
|
||||||
</c:Model>
|
</c:Model>
|
||||||
<c:Transform>
|
<c:Transform/>
|
||||||
<Position X="0.120747991" Y="-0.229502052" Z="-0.151475638"/>
|
|
||||||
<Orientation X="0.0104046296" Y="-0.00268167513" Z="0.0428442545"/>
|
|
||||||
</c:Transform>
|
|
||||||
</Components>
|
</Components>
|
||||||
|
|
||||||
<Children/>
|
<Children/>
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
|
||||||
|
<Entity name="WeaponModel" xmlns:c="components" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../Types/Entity.xsd">
|
||||||
|
|
||||||
|
<Components>
|
||||||
|
<c:Lifetime>
|
||||||
|
<Lifetime>2</Lifetime>
|
||||||
|
</c:Lifetime>
|
||||||
|
<c:ExplosionEffect>
|
||||||
|
<ColorByDistance>true</ColorByDistance>
|
||||||
|
<Velocity X="3.33300018" Y="0.0320000015" Z="0"/>
|
||||||
|
<ExplosionOrigin X="0" Y="0.0790000036" Z="-0.329000026"/>
|
||||||
|
<ExponentialAccelaration>true</ExponentialAccelaration>
|
||||||
|
<EndColor A="0" B="1" G="1" R="19.6078434"/>
|
||||||
|
<Randomness>true</Randomness>
|
||||||
|
</c:ExplosionEffect>
|
||||||
|
<c:Model>
|
||||||
|
<Resource>Models/Weapons/Red/AssaultWeaponRed.mesh</Resource>
|
||||||
|
</c:Model>
|
||||||
|
<c:Transform/>
|
||||||
|
</Components>
|
||||||
|
|
||||||
|
<Children/>
|
||||||
|
|
||||||
|
</Entity>
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
|
||||||
|
<Entity name="WeaponModel" xmlns:c="components" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../Types/Entity.xsd">
|
||||||
|
|
||||||
|
<Components>
|
||||||
|
<c:Lifetime>
|
||||||
|
<Lifetime>2</Lifetime>
|
||||||
|
</c:Lifetime>
|
||||||
|
<c:ExplosionEffect>
|
||||||
|
<ColorByDistance>true</ColorByDistance>
|
||||||
|
<Velocity X="1.63300014" Y="0.0320000015" Z="0"/>
|
||||||
|
<ExplosionOrigin X="0" Y="0.0790000036" Z="-0.329000026"/>
|
||||||
|
<ExponentialAccelaration>true</ExponentialAccelaration>
|
||||||
|
<EndColor A="0" B="19.6078434" G="19.6078434" R="0"/>
|
||||||
|
<Randomness>true</Randomness>
|
||||||
|
</c:ExplosionEffect>
|
||||||
|
<c:Model>
|
||||||
|
<Resource>Models/Weapons/Blue/AssaultWeaponBlue.mesh</Resource>
|
||||||
|
<Transparent>true</Transparent>
|
||||||
|
</c:Model>
|
||||||
|
<c:Transform/>
|
||||||
|
</Components>
|
||||||
|
|
||||||
|
<Children/>
|
||||||
|
|
||||||
|
</Entity>
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
|
||||||
|
<Entity name="WeaponModel" xmlns:c="components" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../Types/Entity.xsd">
|
||||||
|
|
||||||
|
<Components>
|
||||||
|
<c:Lifetime>
|
||||||
|
<Lifetime>2</Lifetime>
|
||||||
|
</c:Lifetime>
|
||||||
|
<c:ExplosionEffect>
|
||||||
|
<ColorByDistance>true</ColorByDistance>
|
||||||
|
<Velocity X="1.63300014" Y="0.0320000015" Z="0"/>
|
||||||
|
<ExplosionOrigin X="0" Y="0.0790000036" Z="-0.329000026"/>
|
||||||
|
<ExponentialAccelaration>true</ExponentialAccelaration>
|
||||||
|
<EndColor A="0" B="1" G="1" R="19.6078434"/>
|
||||||
|
<Randomness>true</Randomness>
|
||||||
|
</c:ExplosionEffect>
|
||||||
|
<c:Model>
|
||||||
|
<Resource>Models/Weapons/Red/AssaultWeaponRed.mesh</Resource>
|
||||||
|
<Transparent>true</Transparent>
|
||||||
|
</c:Model>
|
||||||
|
<c:Transform/>
|
||||||
|
</Components>
|
||||||
|
|
||||||
|
<Children/>
|
||||||
|
|
||||||
|
</Entity>
|
||||||
@@ -0,0 +1,38 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
|
||||||
|
<Entity xmlns:c="components" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../Types/Entity.xsd">
|
||||||
|
|
||||||
|
<Components>
|
||||||
|
<c:Transform/>
|
||||||
|
</Components>
|
||||||
|
|
||||||
|
<Children>
|
||||||
|
<Entity name="MagazineAmmo">
|
||||||
|
<Components>
|
||||||
|
<c:Text>
|
||||||
|
<Content>0</Content>
|
||||||
|
<Resource>Fonts/DroidSans.ttf,64</Resource>
|
||||||
|
<Color A="1" B="3.92156863" G="1.17647064" R="0"/>
|
||||||
|
</c:Text>
|
||||||
|
<c:Transform>
|
||||||
|
<Scale X="0.0599999987" Y="0.0599999987" Z="0.0599999987"/>
|
||||||
|
</c:Transform>
|
||||||
|
</Components>
|
||||||
|
<Children/>
|
||||||
|
</Entity>
|
||||||
|
<Entity name="Ammo">
|
||||||
|
<Components>
|
||||||
|
<c:Text>
|
||||||
|
<Content>360</Content>
|
||||||
|
<Resource>Fonts/DroidSans.ttf,64</Resource>
|
||||||
|
<Color A="1" B="3.92156863" G="1.17647064" R="0"/>
|
||||||
|
</c:Text>
|
||||||
|
<c:Transform>
|
||||||
|
<Position X="5.2833886e-05" Y="-0.0407950208" Z="0"/>
|
||||||
|
<Scale X="0.0399999991" Y="0.0399999991" Z="0.0399999991"/>
|
||||||
|
</c:Transform>
|
||||||
|
</Components>
|
||||||
|
<Children/>
|
||||||
|
</Entity>
|
||||||
|
</Children>
|
||||||
|
|
||||||
|
</Entity>
|
||||||
@@ -43,6 +43,10 @@
|
|||||||
<xs:element ref="c:Shield" minOccurs="0"/>
|
<xs:element ref="c:Shield" minOccurs="0"/>
|
||||||
<xs:element ref="c:Shielded" minOccurs="0"/>
|
<xs:element ref="c:Shielded" minOccurs="0"/>
|
||||||
<xs:element ref="c:CapturePointHUD" minOccurs="0"/>
|
<xs:element ref="c:CapturePointHUD" minOccurs="0"/>
|
||||||
|
<xs:element ref="c:AmmunitionHUD" minOccurs="0"/>
|
||||||
|
<xs:element ref="c:KillFeed" minOccurs="0"/>
|
||||||
|
<xs:element ref="c:Sprite" minOccurs="0"/>
|
||||||
|
<xs:element ref="c:AnimationOffset" minOccurs="0"/>
|
||||||
</xs:all>
|
</xs:all>
|
||||||
</xs:complexType>
|
</xs:complexType>
|
||||||
</xs:element>
|
</xs:element>
|
||||||
|
|||||||
+142
-95
@@ -1,10 +1,8 @@
|
|||||||
#include "Network/Client.h"
|
#include "Network/Client.h"
|
||||||
|
|
||||||
using namespace boost::asio::ip;
|
using namespace boost::asio::ip;
|
||||||
|
|
||||||
Client::Client(World* world, EventBroker* eventBroker)
|
Client::Client(World* world, EventBroker* eventBroker)
|
||||||
: Network(world, eventBroker)
|
: Network(world, eventBroker)
|
||||||
, m_Socket(m_IOService)
|
|
||||||
{
|
{
|
||||||
// Asumes root node is EntityID_Invalid
|
// Asumes root node is EntityID_Invalid
|
||||||
insertIntoServerClientMaps(EntityID_Invalid, EntityID_Invalid);
|
insertIntoServerClientMaps(EntityID_Invalid, EntityID_Invalid);
|
||||||
@@ -14,7 +12,6 @@ Client::Client(World* world, EventBroker* eventBroker)
|
|||||||
auto config = ResourceManager::Load<ConfigFile>("Config.ini");
|
auto config = ResourceManager::Load<ConfigFile>("Config.ini");
|
||||||
m_PlayerName = config->Get<std::string>("Networking.Name", "Raptorcopter");
|
m_PlayerName = config->Get<std::string>("Networking.Name", "Raptorcopter");
|
||||||
m_SendInputIntervalMs = config->Get<int>("Networking.SendInputIntervalMs", 33);
|
m_SendInputIntervalMs = config->Get<int>("Networking.SendInputIntervalMs", 33);
|
||||||
|
|
||||||
LOG_INFO("Client initialized");
|
LOG_INFO("Client initialized");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -26,70 +23,77 @@ Client::Client(World* world, EventBroker* eventBroker, std::unique_ptr<SnapshotF
|
|||||||
|
|
||||||
Client::~Client()
|
Client::~Client()
|
||||||
{ }
|
{ }
|
||||||
|
// Need to call connect at start
|
||||||
void Client::Connect(std::string address, int port)
|
void Client::Connect(std::string address, int port)
|
||||||
{
|
{
|
||||||
// Subscribe to events
|
// Subscribe to events
|
||||||
EVENT_SUBSCRIBE_MEMBER(m_EInputCommand, &Client::OnInputCommand);
|
EVENT_SUBSCRIBE_MEMBER(m_EInputCommand, &Client::OnInputCommand);
|
||||||
EVENT_SUBSCRIBE_MEMBER(m_EPlayerDamage, &Client::OnPlayerDamage);
|
EVENT_SUBSCRIBE_MEMBER(m_EPlayerDamage, &Client::OnPlayerDamage);
|
||||||
EVENT_SUBSCRIBE_MEMBER(m_EPlayerSpawned, &Client::OnPlayerSpawned);
|
EVENT_SUBSCRIBE_MEMBER(m_EPlayerSpawned, &Client::OnPlayerSpawned);
|
||||||
|
|
||||||
auto config = ResourceManager::Load<ConfigFile>("Config.ini");
|
auto config = ResourceManager::Load<ConfigFile>("Config.ini");
|
||||||
|
m_Address = address;
|
||||||
if (address.empty()) {
|
if (address.empty()) {
|
||||||
address = config->Get<std::string>("Networking.Address", "127.0.0.1");
|
m_Address = config->Get<std::string>("Networking.Address", "127.0.0.1");
|
||||||
}
|
}
|
||||||
|
m_Port = port;
|
||||||
if (port == 0) {
|
if (port == 0) {
|
||||||
port = config->Get<int>("Networking.Port", 27666);
|
m_Port = config->Get<int>("Networking.Port", 27666);
|
||||||
}
|
}
|
||||||
|
|
||||||
m_ReceiverEndpoint = udp::endpoint(boost::asio::ip::address::from_string(address), port);
|
|
||||||
LOG_INFO("Client connecting...");
|
|
||||||
m_Socket.connect(m_ReceiverEndpoint);
|
|
||||||
connect();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Client::Update()
|
void Client::Update()
|
||||||
{
|
{
|
||||||
m_EventBroker->Process<Client>();
|
m_EventBroker->Process<Client>();
|
||||||
readFromServer();
|
while (m_Unreliable.IsSocketAvailable()) {
|
||||||
|
// Packet will get real data in receive
|
||||||
|
Packet packet(MessageType::Invalid);
|
||||||
|
m_Unreliable.Receive(packet);
|
||||||
|
if (packet.GetMessageType() == MessageType::Connect) {
|
||||||
|
parseUDPConnect(packet);
|
||||||
|
} else {
|
||||||
|
parseMessageType(packet);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
while (m_Reliable.IsSocketAvailable()) {
|
||||||
|
// Packet will get real data in receive
|
||||||
|
Packet packet(MessageType::Invalid);
|
||||||
|
m_Reliable.Receive(packet);
|
||||||
|
if (packet.GetMessageType() == MessageType::Connect) {
|
||||||
|
parseTCPConnect(packet);
|
||||||
|
} else {
|
||||||
|
parseMessageType(packet);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
if (m_IsConnected) {
|
if (m_IsConnected) {
|
||||||
hasServerTimedOut();
|
// Don't send 1 input in 1 packet, bunch em up.
|
||||||
// Don't sent 1 input in 1 packet, bunch em up.
|
|
||||||
if (m_SendInputIntervalMs < (1000 * (std::clock() - m_TimeSinceSentInputs) / (double)CLOCKS_PER_SEC)) {
|
if (m_SendInputIntervalMs < (1000 * (std::clock() - m_TimeSinceSentInputs) / (double)CLOCKS_PER_SEC)) {
|
||||||
sendInputCommands();
|
sendInputCommands();
|
||||||
m_TimeSinceSentInputs = std::clock();
|
m_TimeSinceSentInputs = std::clock();
|
||||||
}
|
}
|
||||||
// HACK: Send absolute player positions for now to avoid desync until we have reliable messages
|
// HACK: Send absolute player positions for now to avoid desync until we have reliable messages
|
||||||
sendLocalPlayerTransform();
|
sendLocalPlayerTransform();
|
||||||
}
|
|
||||||
Network::Update();
|
|
||||||
}
|
|
||||||
|
|
||||||
void Client::readFromServer()
|
hasServerTimedOut();
|
||||||
{
|
|
||||||
while (m_Socket.available()) {
|
|
||||||
bytesRead = receive(readBuf);
|
|
||||||
if (bytesRead > 0) {
|
|
||||||
Packet packet(readBuf, bytesRead);
|
|
||||||
parseMessageType(packet);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
//Network::Update();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Client::parseMessageType(Packet& packet)
|
void Client::parseMessageType(Packet& packet)
|
||||||
{
|
{
|
||||||
|
// Pop packetSize which is used by TCP Client to
|
||||||
|
// create a packet of the correct size
|
||||||
|
packet.ReadPrimitive<int>();
|
||||||
int messageType = packet.ReadPrimitive<int>();
|
int messageType = packet.ReadPrimitive<int>();
|
||||||
if (messageType == -1)
|
if (messageType == -1)
|
||||||
return;
|
return;
|
||||||
// Read packet ID
|
// Read packet ID
|
||||||
m_PreviousPacketID = m_PacketID; // Set previous packet id
|
m_PreviousPacketID = m_PacketID; // Set previous packet id
|
||||||
m_PacketID = packet.ReadPrimitive<int>(); //Read new packet id
|
m_PacketID = packet.ReadPrimitive<int>(); //Read new packet id
|
||||||
identifyPacketLoss();
|
//identifyPacketLoss();
|
||||||
|
|
||||||
switch (static_cast<MessageType>(messageType)) {
|
switch (static_cast<MessageType>(messageType)) {
|
||||||
case MessageType::Connect:
|
|
||||||
parseConnect(packet);
|
|
||||||
break;
|
|
||||||
case MessageType::Ping:
|
case MessageType::Ping:
|
||||||
parsePing();
|
parsePing();
|
||||||
break;
|
break;
|
||||||
@@ -115,17 +119,40 @@ void Client::parseMessageType(Packet& packet)
|
|||||||
case MessageType::ComponentDeleted:
|
case MessageType::ComponentDeleted:
|
||||||
parseComponentDeletion(packet);
|
parseComponentDeletion(packet);
|
||||||
break;
|
break;
|
||||||
|
case MessageType::OnPlayerDamage:
|
||||||
|
parsePlayerDamage(packet);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Client::parseConnect(Packet& packet)
|
void Client::parseUDPConnect(Packet& packet)
|
||||||
{
|
{
|
||||||
// Map ServerEntityID and your PlayerID
|
// Map ServerEntityID and your PlayerID
|
||||||
LOG_INFO("I be connected PogChamp");
|
LOG_INFO("I be connected PogChamp");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Client::parseTCPConnect(Packet& packet)
|
||||||
|
{
|
||||||
|
LOG_INFO("Received TCP connect from server");
|
||||||
|
// Pop size of message int
|
||||||
|
packet.ReadPrimitive<int>();
|
||||||
|
int messageType = packet.ReadPrimitive<int>();
|
||||||
|
// Read packet ID
|
||||||
|
m_PreviousPacketID = m_PacketID; // Set previous packet id
|
||||||
|
m_PacketID = packet.ReadPrimitive<int>(); //Read new packet id
|
||||||
|
// parse player id and other stuff
|
||||||
|
m_PlayerID = packet.ReadPrimitive<int>();
|
||||||
|
m_PlayerID = packet.ReadPrimitive<int>();
|
||||||
|
LOG_INFO("A Player connected");
|
||||||
|
Packet UnreliablePacket(MessageType::Connect, m_SendPacketID);
|
||||||
|
// Add player id and other stuff
|
||||||
|
packet.WritePrimitive(m_PlayerID);
|
||||||
|
m_Unreliable.Send(packet);
|
||||||
|
LOG_INFO("Sent UDP Connect Server");
|
||||||
|
}
|
||||||
|
|
||||||
void Client::parsePlayerConnected(Packet & packet)
|
void Client::parsePlayerConnected(Packet & packet)
|
||||||
{
|
{
|
||||||
// Map ServerEntityID and other player's PlayerID
|
// Map ServerEntityID and other player's PlayerID
|
||||||
@@ -143,7 +170,7 @@ void Client::parsePing()
|
|||||||
|
|
||||||
Packet packet(MessageType::Ping, m_SendPacketID);
|
Packet packet(MessageType::Ping, m_SendPacketID);
|
||||||
packet.WriteString("Ping recieved");
|
packet.WriteString("Ping recieved");
|
||||||
send(packet);
|
m_Reliable.Send(packet);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Client::parseKick()
|
void Client::parseKick()
|
||||||
@@ -152,14 +179,41 @@ void Client::parseKick()
|
|||||||
m_IsConnected = false;
|
m_IsConnected = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Client::parseSpawnEvents()
|
||||||
|
{
|
||||||
|
std::vector<Events::PlayerSpawned> tempSpawn;
|
||||||
|
for (int i = 0; i < m_PlayerSpawnEvents.size(); i++) {
|
||||||
|
Events::PlayerSpawned e;
|
||||||
|
if (!serverClientMapsHasEntity(m_PlayerSpawnEvents.at(i).Player.ID)) {
|
||||||
|
tempSpawn.push_back(m_PlayerSpawnEvents.at(i));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
e.Player = EntityWrapper(m_World, m_ServerIDToClientID.at(m_PlayerSpawnEvents.at(i).Player.ID));
|
||||||
|
//e.Spawner = EntityWrapper(m_World, m_ServerIDToClientID.at(m_PlayerSpawnEvents.at(i).Spawner.ID));
|
||||||
|
e.PlayerID = -1;
|
||||||
|
e.PlayerName = m_PlayerSpawnEvents.at(i).PlayerName;
|
||||||
|
m_EventBroker->Publish(e);
|
||||||
|
}
|
||||||
|
m_PlayerSpawnEvents = tempSpawn;
|
||||||
|
// m_PlayerSpawnEvents.clear();
|
||||||
|
}
|
||||||
|
|
||||||
void Client::parsePlayersSpawned(Packet& packet)
|
void Client::parsePlayersSpawned(Packet& packet)
|
||||||
{
|
{
|
||||||
|
//Events::PlayerSpawned e;
|
||||||
|
//e.Player = EntityWrapper(m_World, m_ServerIDToClientID[packet.ReadPrimitive<EntityID>()]);
|
||||||
|
//e.Spawner = EntityWrapper(m_World, m_ServerIDToClientID[packet.ReadPrimitive<EntityID>()]);
|
||||||
|
//e.PlayerID = -1;
|
||||||
|
//e.PlayerName = packet.ReadString();
|
||||||
|
//m_EventBroker->Publish(e);
|
||||||
|
|
||||||
Events::PlayerSpawned e;
|
Events::PlayerSpawned e;
|
||||||
e.Player = EntityWrapper(m_World, m_ServerIDToClientID[packet.ReadPrimitive<EntityID>()]);
|
e.Player = EntityWrapper(m_World, packet.ReadPrimitive<EntityID>());
|
||||||
e.Spawner = EntityWrapper(m_World, m_ServerIDToClientID[packet.ReadPrimitive<EntityID>()]);
|
e.Spawner = EntityWrapper(m_World, packet.ReadPrimitive<EntityID>());
|
||||||
e.PlayerID = -1;
|
e.PlayerID = -1;
|
||||||
e.PlayerName = packet.ReadString();
|
e.PlayerName = packet.ReadString();
|
||||||
m_EventBroker->Publish(e);
|
m_PlayerSpawnEvents.push_back(e);
|
||||||
|
parseSpawnEvents();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Client::parseEntityDeletion(Packet & packet)
|
void Client::parseEntityDeletion(Packet & packet)
|
||||||
@@ -235,10 +289,15 @@ void Client::parseSnapshot(Packet& packet)
|
|||||||
for (std::size_t i = 0; i < numInputCommands; ++i) {
|
for (std::size_t i = 0; i < numInputCommands; ++i) {
|
||||||
Events::InputCommand e;
|
Events::InputCommand e;
|
||||||
e.PlayerID = packet.ReadPrimitive<EntityID>();
|
e.PlayerID = packet.ReadPrimitive<EntityID>();
|
||||||
e.Player = EntityWrapper(m_World, m_ServerIDToClientID.at(packet.ReadPrimitive<EntityID>()));
|
EntityID player = packet.ReadPrimitive<EntityID>();
|
||||||
e.Command = packet.ReadString();
|
std::string command = packet.ReadString();
|
||||||
e.Value = packet.ReadPrimitive<float>();
|
float value = packet.ReadPrimitive<float>();
|
||||||
m_EventBroker->Publish(e);
|
if (m_ServerIDToClientID.find(player) != m_ServerIDToClientID.end()) {
|
||||||
|
e.Player = EntityWrapper(m_World, m_ServerIDToClientID.at(player));
|
||||||
|
e.Command = command;
|
||||||
|
e.Value = value;
|
||||||
|
m_EventBroker->Publish(e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Read world state
|
// Read world state
|
||||||
@@ -297,56 +356,17 @@ void Client::parseSnapshot(Packet& packet)
|
|||||||
m_World->SetParent(localEntityID, m_ServerIDToClientID.at(serverParentID));
|
m_World->SetParent(localEntityID, m_ServerIDToClientID.at(serverParentID));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
parseSpawnEvents();
|
||||||
|
|
||||||
size_t Client::receive(char* data)
|
|
||||||
{
|
|
||||||
boost::system::error_code error;
|
|
||||||
|
|
||||||
size_t bytesReceived = m_Socket.receive_from(boost
|
|
||||||
::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());
|
|
||||||
}
|
|
||||||
return bytesReceived;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Client::send(Packet& packet)
|
|
||||||
{
|
|
||||||
m_Socket.send_to(boost::asio::buffer(
|
|
||||||
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()
|
|
||||||
{
|
|
||||||
Packet packet(MessageType::Connect, m_SendPacketID);
|
|
||||||
packet.WriteString(m_PlayerName);
|
|
||||||
m_StartPingTime = std::clock();
|
|
||||||
send(packet);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Client::disconnect()
|
void Client::disconnect()
|
||||||
{
|
{
|
||||||
|
m_IsConnected = false;
|
||||||
m_PreviousPacketID = 0;
|
m_PreviousPacketID = 0;
|
||||||
m_PacketID = 0;
|
m_PacketID = 0;
|
||||||
Packet packet(MessageType::Disconnect, m_SendPacketID);
|
Packet packet(MessageType::Disconnect, m_SendPacketID);
|
||||||
send(packet);
|
m_Reliable.Send(packet);
|
||||||
|
m_Reliable.Disconnect();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Client::OnInputCommand(const Events::InputCommand & e)
|
bool Client::OnInputCommand(const Events::InputCommand & e)
|
||||||
@@ -357,7 +377,8 @@ bool Client::OnInputCommand(const Events::InputCommand & e)
|
|||||||
|
|
||||||
if (e.Command == "ConnectToServer") { // Connect for now
|
if (e.Command == "ConnectToServer") { // Connect for now
|
||||||
if (e.Value > 0) {
|
if (e.Value > 0) {
|
||||||
connect();
|
m_Reliable.Connect(m_PlayerName, m_Address, m_Port);
|
||||||
|
m_Unreliable.Connect(m_PlayerName, m_Address, m_Port);
|
||||||
}
|
}
|
||||||
//LOG_DEBUG("Client::OnInputCommand: Command is %s. Value is %f. PlayerID is %i.", e.Command.c_str(), e.Value, e.PlayerID);
|
//LOG_DEBUG("Client::OnInputCommand: Command is %s. Value is %f. PlayerID is %i.", e.Command.c_str(), e.Value, e.PlayerID);
|
||||||
return true;
|
return true;
|
||||||
@@ -380,7 +401,9 @@ bool Client::OnInputCommand(const Events::InputCommand & e)
|
|||||||
m_SaveDataTimer = std::clock();
|
m_SaveDataTimer = std::clock();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
m_InputCommandBuffer.push_back(e);
|
if (m_IsConnected) {
|
||||||
|
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);
|
//LOG_DEBUG("Client::OnInputCommand: Command is %s. Value is %f. PlayerID is %i.", e.Command.c_str(), e.Value, e.PlayerID);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -389,12 +412,17 @@ bool Client::OnInputCommand(const Events::InputCommand & e)
|
|||||||
|
|
||||||
bool Client::OnPlayerDamage(const Events::PlayerDamage & e)
|
bool Client::OnPlayerDamage(const Events::PlayerDamage & e)
|
||||||
{
|
{
|
||||||
|
if (e.Inflictor != m_LocalPlayer) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
Packet packet(MessageType::OnPlayerDamage, m_SendPacketID);
|
Packet packet(MessageType::OnPlayerDamage, m_SendPacketID);
|
||||||
packet.WritePrimitive(m_ClientIDToServerID.at(e.Inflictor.ID));
|
packet.WritePrimitive(m_ClientIDToServerID.at(e.Inflictor.ID));
|
||||||
packet.WritePrimitive(m_ClientIDToServerID.at(e.Victim.ID));
|
packet.WritePrimitive(m_ClientIDToServerID.at(e.Victim.ID));
|
||||||
packet.WritePrimitive(e.Damage);
|
packet.WritePrimitive(e.Damage);
|
||||||
send(packet);
|
m_Reliable.Send(packet);
|
||||||
return false;
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Client::OnPlayerSpawned(const Events::PlayerSpawned& e)
|
bool Client::OnPlayerSpawned(const Events::PlayerSpawned& e)
|
||||||
@@ -405,23 +433,45 @@ bool Client::OnPlayerSpawned(const Events::PlayerSpawned& e)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Client::parsePlayerDamage(Packet& packet)
|
||||||
|
{
|
||||||
|
Events::PlayerDamage e;
|
||||||
|
e.Inflictor = EntityWrapper(m_World, m_ServerIDToClientID.at(packet.ReadPrimitive<EntityID>()));
|
||||||
|
e.Victim = EntityWrapper(m_World, m_ServerIDToClientID.at(packet.ReadPrimitive<EntityID>()));
|
||||||
|
e.Damage = packet.ReadPrimitive<double>();
|
||||||
|
// Don't rebroadcast our own player damage events or we'll have an infinite loop!
|
||||||
|
if (e.Inflictor != m_LocalPlayer) {
|
||||||
|
m_EventBroker->Publish(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void Client::sendLocalPlayerTransform()
|
void Client::sendLocalPlayerTransform()
|
||||||
{
|
{
|
||||||
if (!m_LocalPlayer.Valid()) {
|
if (!m_LocalPlayer.Valid()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Packet packet(MessageType::PlayerTransform, m_SendPacketID);
|
||||||
|
|
||||||
ComponentWrapper cTransform = m_LocalPlayer["Transform"];
|
ComponentWrapper cTransform = m_LocalPlayer["Transform"];
|
||||||
glm::vec3& position = cTransform["Position"];
|
glm::vec3& position = cTransform["Position"];
|
||||||
glm::vec3& orientation = cTransform["Orientation"];
|
glm::vec3& orientation = cTransform["Orientation"];
|
||||||
Packet packet(MessageType::PlayerTransform, m_SendPacketID);
|
|
||||||
packet.WritePrimitive(position.x);
|
packet.WritePrimitive(position.x);
|
||||||
packet.WritePrimitive(position.y);
|
packet.WritePrimitive(position.y);
|
||||||
packet.WritePrimitive(position.z);
|
packet.WritePrimitive(position.z);
|
||||||
packet.WritePrimitive(orientation.x);
|
packet.WritePrimitive(orientation.x);
|
||||||
packet.WritePrimitive(orientation.y);
|
packet.WritePrimitive(orientation.y);
|
||||||
packet.WritePrimitive(orientation.z);
|
packet.WritePrimitive(orientation.z);
|
||||||
send(packet);
|
|
||||||
|
bool hasAssaultWeapon = m_LocalPlayer.HasComponent("AssaultWeapon");
|
||||||
|
packet.WritePrimitive(hasAssaultWeapon);
|
||||||
|
if (hasAssaultWeapon) {
|
||||||
|
ComponentWrapper cAssaultWeapon = m_LocalPlayer["AssaultWeapon"];
|
||||||
|
packet.WritePrimitive((int)cAssaultWeapon["MagazineAmmo"]);
|
||||||
|
packet.WritePrimitive((int)cAssaultWeapon["Ammo"]);
|
||||||
|
}
|
||||||
|
|
||||||
|
m_Unreliable.Send(packet);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Client::identifyPacketLoss()
|
void Client::identifyPacketLoss()
|
||||||
@@ -433,17 +483,15 @@ void Client::identifyPacketLoss()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Client::hasServerTimedOut()
|
void Client::hasServerTimedOut()
|
||||||
{
|
{
|
||||||
// Time in ms
|
// Time in ms
|
||||||
double timeSincePing = 1000 * (std::clock() - m_StartPingTime) / static_cast<double>(CLOCKS_PER_SEC);
|
double timeSincePing = 1000 * (std::clock() - m_StartPingTime) / static_cast<double>(CLOCKS_PER_SEC);
|
||||||
if (timeSincePing > m_TimeoutMs) {
|
if (timeSincePing > m_TimeoutMs) {
|
||||||
// Clear everything and go to menu.
|
// Clear everything and go to menu.
|
||||||
LOG_INFO("Server has timed out, returning to menu, Beep Boop.");
|
LOG_INFO("Server has timed out, returning to menu, Beep Boop.");
|
||||||
m_IsConnected = false;
|
disconnect();
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
EntityID Client::createPlayer()
|
EntityID Client::createPlayer()
|
||||||
@@ -464,7 +512,7 @@ void Client::sendInputCommands()
|
|||||||
packet.WriteString(m_InputCommandBuffer[i].Command);
|
packet.WriteString(m_InputCommandBuffer[i].Command);
|
||||||
packet.WritePrimitive(m_InputCommandBuffer[i].Value);
|
packet.WritePrimitive(m_InputCommandBuffer[i].Value);
|
||||||
}
|
}
|
||||||
send(packet);
|
m_Reliable.Send(packet);
|
||||||
m_InputCommandBuffer.clear();
|
m_InputCommandBuffer.clear();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -472,7 +520,7 @@ void Client::sendInputCommands()
|
|||||||
void Client::becomePlayer()
|
void Client::becomePlayer()
|
||||||
{
|
{
|
||||||
Packet packet = Packet(MessageType::BecomePlayer, m_SendPacketID);
|
Packet packet = Packet(MessageType::BecomePlayer, m_SendPacketID);
|
||||||
send(packet);
|
m_Reliable.Send(packet);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Client::clientServerMapsHasEntity(EntityID clientEntityID)
|
bool Client::clientServerMapsHasEntity(EntityID clientEntityID)
|
||||||
@@ -503,7 +551,6 @@ void Client::insertIntoServerClientMaps(EntityID serverEntityID, EntityID client
|
|||||||
{
|
{
|
||||||
m_ServerIDToClientID.insert(std::make_pair(serverEntityID, clientEntityID));
|
m_ServerIDToClientID.insert(std::make_pair(serverEntityID, clientEntityID));
|
||||||
m_ClientIDToServerID.insert(std::make_pair(clientEntityID, serverEntityID));
|
m_ClientIDToServerID.insert(std::make_pair(clientEntityID, serverEntityID));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Client::deleteFromServerClientMaps(EntityID serverEntityID, EntityID clientEntityID)
|
void Client::deleteFromServerClientMaps(EntityID serverEntityID, EntityID clientEntityID)
|
||||||
|
|||||||
@@ -0,0 +1,10 @@
|
|||||||
|
#include "Network/HybridClient.h"
|
||||||
|
|
||||||
|
|
||||||
|
HybridClient::HybridClient()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
HybridClient::~HybridClient()
|
||||||
|
{
|
||||||
|
}
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
#include "Network/HybridServer.h"
|
||||||
|
|
||||||
|
HybridServer::HybridServer()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
HybridServer::~HybridServer()
|
||||||
|
{
|
||||||
|
}
|
||||||
@@ -14,6 +14,21 @@ void Network::Update()
|
|||||||
updateNetworkData();
|
updateNetworkData();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Network::logSentData(int bytesSent)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void Network::logReceivedData(int bytesReceived)
|
||||||
|
{
|
||||||
|
// Network Debug data
|
||||||
|
if (isReadingData) {
|
||||||
|
m_NetworkData.TotalDataReceived += bytesReceived;
|
||||||
|
m_NetworkData.DataReceivedThisInterval += bytesReceived;
|
||||||
|
m_NetworkData.AmountOfMessagesReceived++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void Network::saveToFile()
|
void Network::saveToFile()
|
||||||
{
|
{
|
||||||
std::ofstream outfile;
|
std::ofstream outfile;
|
||||||
|
|||||||
@@ -34,10 +34,12 @@ void Packet::Init(MessageType type, unsigned int & packetID)
|
|||||||
m_ReturnDataOffset = 0;
|
m_ReturnDataOffset = 0;
|
||||||
m_Offset = 0;
|
m_Offset = 0;
|
||||||
// Create message header
|
// Create message header
|
||||||
|
// allocate memory for size of packet(only used in tcp)
|
||||||
|
WritePrimitive<int>(0);
|
||||||
// Add message type
|
// Add message type
|
||||||
int messageType = static_cast<int>(type);
|
int messageType = static_cast<int>(type);
|
||||||
Packet::WritePrimitive<int>(messageType);
|
WritePrimitive<int>(messageType);
|
||||||
Packet::WritePrimitive<int>(packetID);
|
WritePrimitive<int>(packetID);
|
||||||
packetID++;
|
packetID++;
|
||||||
m_HeaderSize = m_Offset;
|
m_HeaderSize = m_Offset;
|
||||||
}
|
}
|
||||||
@@ -56,9 +58,12 @@ void Packet::WriteString(const std::string& str)
|
|||||||
|
|
||||||
void Packet::WriteData(char * data, int sizeOfData)
|
void Packet::WriteData(char * data, int sizeOfData)
|
||||||
{
|
{
|
||||||
|
|
||||||
if (m_Offset + sizeOfData > m_MaxPacketSize) {
|
if (m_Offset + sizeOfData > m_MaxPacketSize) {
|
||||||
//LOG_WARNING("Packet::WriteData(): Data size in packet exceeded maximum packet size. New size is %i bytes\n", m_MaxPacketSize*2);
|
//LOG_WARNING("Packet::WriteData(): Data size in packet exceeded maximum packet size. New size is %i bytes\n", m_MaxPacketSize*2);
|
||||||
resizeData();
|
while (m_Offset + sizeOfData > m_MaxPacketSize) {
|
||||||
|
resizeData();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
memcpy(m_Data + m_Offset, data, sizeOfData);
|
memcpy(m_Data + m_Offset, data, sizeOfData);
|
||||||
m_Offset += sizeOfData;
|
m_Offset += sizeOfData;
|
||||||
@@ -76,14 +81,35 @@ std::string Packet::ReadString()
|
|||||||
return returnValue;
|
return returnValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
char * Packet::ReadData(int SizeOfData)
|
void Packet::ReconstructFromData(char * data, size_t sizeOfData)
|
||||||
{
|
{
|
||||||
if (m_Offset < m_ReturnDataOffset + SizeOfData) {
|
if (sizeOfData > m_MaxPacketSize) {
|
||||||
|
// Delete our data
|
||||||
|
delete[] m_Data;
|
||||||
|
// Set new max size
|
||||||
|
m_MaxPacketSize = sizeOfData;
|
||||||
|
m_Data = new char[m_MaxPacketSize];
|
||||||
|
// while we resized the old data container.
|
||||||
|
}
|
||||||
|
memcpy(m_Data, data, sizeOfData);
|
||||||
|
m_Offset = sizeOfData;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void Packet::UpdateSize()
|
||||||
|
{
|
||||||
|
int whatisoffset = m_Offset;
|
||||||
|
memcpy(m_Data, &m_Offset, sizeof(int));
|
||||||
|
}
|
||||||
|
|
||||||
|
char * Packet::ReadData(int sizeOfData)
|
||||||
|
{
|
||||||
|
if (m_Offset < m_ReturnDataOffset + sizeOfData) {
|
||||||
//LOG_WARNING("packet ReadData(): Oh no! You are trying to remove things outside my memory kingdom");
|
//LOG_WARNING("packet ReadData(): Oh no! You are trying to remove things outside my memory kingdom");
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
size_t oldReturnDataOffset = m_ReturnDataOffset;
|
size_t oldReturnDataOffset = m_ReturnDataOffset;
|
||||||
m_ReturnDataOffset += SizeOfData;
|
m_ReturnDataOffset += sizeOfData;
|
||||||
return (m_Data + oldReturnDataOffset);
|
return (m_Data + oldReturnDataOffset);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -91,25 +117,36 @@ void Packet::ChangePacketID(unsigned int & packetID)
|
|||||||
{
|
{
|
||||||
packetID = packetID + 1;
|
packetID = packetID + 1;
|
||||||
// Overwrite old PacketID
|
// Overwrite old PacketID
|
||||||
memcpy(m_Data + sizeof(int), &packetID, sizeof(int));
|
memcpy(m_Data + 2*sizeof(int), &packetID, sizeof(int));
|
||||||
|
}
|
||||||
|
|
||||||
|
MessageType Packet::GetMessageType()
|
||||||
|
{
|
||||||
|
MessageType messagType;
|
||||||
|
memcpy(&messagType, m_Data + sizeof(int), sizeof(int));
|
||||||
|
return messagType;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Packet::resizeData()
|
void Packet::resizeData()
|
||||||
{
|
{
|
||||||
|
resizeData(m_MaxPacketSize * 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Packet::resizeData(int size)
|
||||||
|
{
|
||||||
// Allocate memory to store our data in
|
// Allocate memory to store our data in
|
||||||
char* holdData = new char[m_MaxPacketSize];
|
char* holdData = new char[m_MaxPacketSize];
|
||||||
// Copy our data to the newly allocated memory
|
// Copy our data to the newly allocated memory
|
||||||
memcpy(holdData, m_Data, m_Offset);
|
memcpy(holdData, m_Data, m_Offset);
|
||||||
// Increase max packet size
|
// Increase max packet size
|
||||||
m_MaxPacketSize = m_MaxPacketSize * 2;
|
m_MaxPacketSize = size;
|
||||||
// Delete our data
|
// Delete our data
|
||||||
delete m_Data;
|
delete[] m_Data;
|
||||||
// Allocate twice the memory we had before
|
// Allocate memory
|
||||||
m_Data = new char[m_MaxPacketSize];
|
m_Data = new char[m_MaxPacketSize];
|
||||||
// Copy our data to new location
|
// Copy our data to new location
|
||||||
memcpy(m_Data, holdData, m_Offset);
|
memcpy(m_Data, holdData, m_Offset);
|
||||||
// Delete the memory allocated to hold our data
|
// Delete the memory allocated to hold our data
|
||||||
// while we resized the old data container.
|
// while we resized the old data container.
|
||||||
delete holdData;
|
delete[] holdData;
|
||||||
}
|
}
|
||||||
|
|||||||
+259
-207
@@ -6,19 +6,18 @@ Server::Server(World* world, EventBroker* eventBroker, int port)
|
|||||||
ConfigFile* config = ResourceManager::Load<ConfigFile>("Config.ini");
|
ConfigFile* config = ResourceManager::Load<ConfigFile>("Config.ini");
|
||||||
snapshotInterval = 1000 * config->Get<float>("Networking.SnapshotInterval", 0.05f);
|
snapshotInterval = 1000 * config->Get<float>("Networking.SnapshotInterval", 0.05f);
|
||||||
pingIntervalMs = config->Get<float>("Networking.PingIntervalMs", 1000);
|
pingIntervalMs = config->Get<float>("Networking.PingIntervalMs", 1000);
|
||||||
|
|
||||||
// Subscribe to events
|
// Subscribe to events
|
||||||
EVENT_SUBSCRIBE_MEMBER(m_EInputCommand, &Server::OnInputCommand);
|
EVENT_SUBSCRIBE_MEMBER(m_EInputCommand, &Server::OnInputCommand);
|
||||||
EVENT_SUBSCRIBE_MEMBER(m_EPlayerSpawned, &Server::OnPlayerSpawned);
|
EVENT_SUBSCRIBE_MEMBER(m_EPlayerSpawned, &Server::OnPlayerSpawned);
|
||||||
EVENT_SUBSCRIBE_MEMBER(m_EEntityDeleted, &Server::OnEntityDeleted);
|
EVENT_SUBSCRIBE_MEMBER(m_EEntityDeleted, &Server::OnEntityDeleted);
|
||||||
EVENT_SUBSCRIBE_MEMBER(m_EComponentDeleted, &Server::OnComponentDeleted);
|
EVENT_SUBSCRIBE_MEMBER(m_EComponentDeleted, &Server::OnComponentDeleted);
|
||||||
|
EVENT_SUBSCRIBE_MEMBER(m_EPlayerDamage, &Server::OnPlayerDamage);
|
||||||
|
|
||||||
// Bind
|
// Bind
|
||||||
if (port == 0) {
|
if (port == 0) {
|
||||||
port = config->Get<float>("Networking.Port", 27666);
|
port = config->Get<float>("Networking.Port", 27666);
|
||||||
}
|
}
|
||||||
m_Port = port;
|
m_Port = port;
|
||||||
m_Socket = std::make_unique<boost::asio::ip::udp::socket>(m_IOService, boost::asio::ip::udp::endpoint(boost::asio::ip::udp::v4(), port));
|
|
||||||
LOG_INFO("Server initialized and bound to port %i", port);
|
LOG_INFO("Server initialized and bound to port %i", port);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -29,7 +28,58 @@ Server::~Server()
|
|||||||
|
|
||||||
void Server::Update()
|
void Server::Update()
|
||||||
{
|
{
|
||||||
readFromClients();
|
PlayerDefinition pd;
|
||||||
|
|
||||||
|
m_Reliable.AcceptNewConnections(m_NextPlayerID, m_ConnectedPlayers);
|
||||||
|
for (auto& kv : m_ConnectedPlayers) {
|
||||||
|
while (kv.second.TCPSocket->available()) {
|
||||||
|
// Packet will get real data in receive
|
||||||
|
Packet packet(MessageType::Invalid);
|
||||||
|
m_Reliable.Receive(packet, kv.second);
|
||||||
|
m_Address = kv.second.TCPSocket->remote_endpoint().address();
|
||||||
|
m_Port = kv.second.TCPSocket->remote_endpoint().port();
|
||||||
|
if (packet.GetMessageType() == MessageType::Connect) {
|
||||||
|
parseTCPConnect(packet);
|
||||||
|
} else {
|
||||||
|
parseMessageType(packet);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
while (m_Unreliable.IsSocketAvailable()) {
|
||||||
|
// Packet will get real data in receive
|
||||||
|
Packet packet(MessageType::Invalid);
|
||||||
|
m_Unreliable.Receive(packet, pd);
|
||||||
|
m_Address = pd.Endpoint.address();
|
||||||
|
m_Port = pd.Endpoint.port();
|
||||||
|
if (packet.GetMessageType() == MessageType::Connect) {
|
||||||
|
parseUDPConnect(packet);
|
||||||
|
} else {
|
||||||
|
parseMessageType(packet);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Check if players have disconnected
|
||||||
|
for (int i = 0; i < m_PlayersToDisconnect.size(); i++) {
|
||||||
|
disconnect(m_PlayersToDisconnect.at(i));
|
||||||
|
}
|
||||||
|
m_PlayersToDisconnect.clear();
|
||||||
|
|
||||||
|
std::clock_t currentTime = std::clock();
|
||||||
|
// Send snapshot
|
||||||
|
if (snapshotInterval < (1000 * (currentTime - previousSnapshotMessage) / (double)CLOCKS_PER_SEC)) {
|
||||||
|
sendSnapshot();
|
||||||
|
previousSnapshotMessage = currentTime;
|
||||||
|
}
|
||||||
|
// Send pings each
|
||||||
|
if (pingIntervalMs < (1000 * (currentTime - previousePingMessage) / (double)CLOCKS_PER_SEC)) {
|
||||||
|
sendPing();
|
||||||
|
previousePingMessage = currentTime;
|
||||||
|
}
|
||||||
|
// Time out logic
|
||||||
|
if (checkTimeOutInterval < (1000 * (currentTime - timOutTimer) / (double)CLOCKS_PER_SEC)) {
|
||||||
|
checkForTimeOuts();
|
||||||
|
timOutTimer = currentTime;
|
||||||
|
}
|
||||||
m_EventBroker->Process<Server>();
|
m_EventBroker->Process<Server>();
|
||||||
if (isReadingData) {
|
if (isReadingData) {
|
||||||
Network::Update();
|
Network::Update();
|
||||||
@@ -37,48 +87,20 @@ void Server::Update()
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Server::readFromClients()
|
|
||||||
{
|
|
||||||
while (m_Socket->available()) {
|
|
||||||
try {
|
|
||||||
bytesRead = receive(readBuffer);
|
|
||||||
Packet packet(readBuffer, bytesRead);
|
|
||||||
parseMessageType(packet);
|
|
||||||
} catch (const std::exception&) {
|
|
||||||
//LOG_ERROR("%i: Read from client crashed %s", m_PacketID, err.what());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
std::clock_t currentTime = std::clock();
|
|
||||||
// Send snapshot
|
|
||||||
if (snapshotInterval < (1000 * (currentTime - previousSnapshotMessage) / (double)CLOCKS_PER_SEC)) {
|
|
||||||
sendSnapshot();
|
|
||||||
previousSnapshotMessage = currentTime;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Send pings each
|
|
||||||
if (pingIntervalMs < (1000 * (currentTime - previousePingMessage) / (double)CLOCKS_PER_SEC)) {
|
|
||||||
sendPing();
|
|
||||||
previousePingMessage = currentTime;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Time out logic
|
|
||||||
if (checkTimeOutInterval < (1000 * (currentTime - timOutTimer) / (double)CLOCKS_PER_SEC)) {
|
|
||||||
checkForTimeOuts();
|
|
||||||
timOutTimer = currentTime;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Server::parseMessageType(Packet& packet)
|
void Server::parseMessageType(Packet& packet)
|
||||||
{
|
{
|
||||||
int messageType = packet.ReadPrimitive<int>(); // Read what type off message was sent from server
|
// Pop packetSize which is used by TCP Client to
|
||||||
|
// create a packet of the correct size
|
||||||
|
packet.ReadPrimitive<int>();
|
||||||
|
|
||||||
|
int messageType = packet.ReadPrimitive<int>(); // Read what type off message was sent from server
|
||||||
// Read packet ID
|
// Read packet ID
|
||||||
m_PreviousPacketID = m_PacketID; // Set previous packet id
|
m_PreviousPacketID = m_PacketID; // Set previous packet id
|
||||||
m_PacketID = packet.ReadPrimitive<int>(); //Read new packet id
|
m_PacketID = packet.ReadPrimitive<int>(); //Read new packet id
|
||||||
//identifyPacketLoss();
|
//identifyPacketLoss();
|
||||||
switch (static_cast<MessageType>(messageType)) {
|
switch (static_cast<MessageType>(messageType)) {
|
||||||
case MessageType::Connect:
|
case MessageType::Connect:
|
||||||
parseConnect(packet);
|
//parseConnect(packet);
|
||||||
break;
|
break;
|
||||||
case MessageType::Ping:
|
case MessageType::Ping:
|
||||||
parsePing();
|
parsePing();
|
||||||
@@ -104,60 +126,19 @@ void Server::parseMessageType(Packet& packet)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t Server::receive(char * data)
|
void Server::reliableBroadcast(Packet& packet)
|
||||||
{
|
|
||||||
size_t length = m_Socket->receive_from(
|
|
||||||
boost::asio::buffer((void*)data
|
|
||||||
, INPUTSIZE)
|
|
||||||
, m_ReceiverEndpoint, 0);
|
|
||||||
// Network Debug data
|
|
||||||
if (isReadingData) {
|
|
||||||
m_NetworkData.TotalDataReceived += length;
|
|
||||||
m_NetworkData.DataReceivedThisInterval += length;
|
|
||||||
m_NetworkData.AmountOfMessagesReceived++;
|
|
||||||
}
|
|
||||||
return length;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Server::send(PlayerID player, Packet& packet)
|
|
||||||
{
|
|
||||||
try {
|
|
||||||
size_t bytesSent = m_Socket->send_to(
|
|
||||||
boost::asio::buffer(packet.Data(), packet.Size()),
|
|
||||||
m_ConnectedPlayers[player].Endpoint,
|
|
||||||
0);
|
|
||||||
// Network Debug data
|
|
||||||
if (isReadingData) {
|
|
||||||
m_NetworkData.TotalDataSent += packet.Size();
|
|
||||||
m_NetworkData.DataSentThisInterval += packet.Size();
|
|
||||||
m_NetworkData.AmountOfMessagesSent++;
|
|
||||||
}
|
|
||||||
} catch (const boost::system::system_error&) {
|
|
||||||
// TODO: Clean up invalid endpoints out of m_ConnectedPlayers later
|
|
||||||
m_ConnectedPlayers[player].Endpoint = boost::asio::ip::udp::endpoint();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Server::send(Packet & packet)
|
|
||||||
{
|
|
||||||
m_Socket->send_to(
|
|
||||||
boost::asio::buffer(
|
|
||||||
packet.Data(),
|
|
||||||
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)
|
|
||||||
{
|
{
|
||||||
for (auto& kv : m_ConnectedPlayers) {
|
for (auto& kv : m_ConnectedPlayers) {
|
||||||
packet.ChangePacketID(kv.second.PacketID);
|
packet.ChangePacketID(kv.second.PacketID);
|
||||||
send(kv.first, packet);
|
m_Reliable.Send(packet, kv.second);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Server::unreliableBroadcast(Packet& packet)
|
||||||
|
{
|
||||||
|
for (auto& kv : m_ConnectedPlayers) {
|
||||||
|
packet.ChangePacketID(kv.second.PacketID);
|
||||||
|
m_Unreliable.Send(packet, kv.second);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -167,7 +148,7 @@ void Server::sendSnapshot()
|
|||||||
Packet packet(MessageType::Snapshot);
|
Packet packet(MessageType::Snapshot);
|
||||||
addInputCommandsToPacket(packet);
|
addInputCommandsToPacket(packet);
|
||||||
addChildrenToPacket(packet, EntityID_Invalid);
|
addChildrenToPacket(packet, EntityID_Invalid);
|
||||||
broadcast(packet);
|
unreliableBroadcast(packet);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Server::addInputCommandsToPacket(Packet& packet)
|
void Server::addInputCommandsToPacket(Packet& packet)
|
||||||
@@ -190,6 +171,12 @@ void Server::addChildrenToPacket(Packet & packet, EntityID entityID)
|
|||||||
// Loop through every child
|
// Loop through every child
|
||||||
for (auto it = itPair.first; it != itPair.second; it++) {
|
for (auto it = itPair.first; it != itPair.second; it++) {
|
||||||
EntityID childEntityID = it->second;
|
EntityID childEntityID = it->second;
|
||||||
|
// HACK: Only sync players for now, since the map turned out to be TOO LARGE to send in one snapshot and Simon's computer shits itself
|
||||||
|
EntityWrapper childEntity(m_World, childEntityID);
|
||||||
|
if (!shouldSendToClient(childEntity)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
// Write EntityID and parentsID and Entity name
|
// Write EntityID and parentsID and Entity name
|
||||||
packet.WritePrimitive(childEntityID);
|
packet.WritePrimitive(childEntityID);
|
||||||
packet.WritePrimitive(entityID);
|
packet.WritePrimitive(entityID);
|
||||||
@@ -241,7 +228,7 @@ void Server::sendPing()
|
|||||||
// Time message
|
// Time message
|
||||||
m_StartPingTime = std::clock();
|
m_StartPingTime = std::clock();
|
||||||
// Send message
|
// Send message
|
||||||
broadcast(packet);
|
reliableBroadcast(packet);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Server::checkForTimeOuts()
|
void Server::checkForTimeOuts()
|
||||||
@@ -249,16 +236,91 @@ void Server::checkForTimeOuts()
|
|||||||
double startPing = 1000 * m_StartPingTime
|
double startPing = 1000 * m_StartPingTime
|
||||||
/ static_cast<double>(CLOCKS_PER_SEC);
|
/ static_cast<double>(CLOCKS_PER_SEC);
|
||||||
|
|
||||||
for (int i = 0; i < m_ConnectedPlayers.size(); i++) {
|
std::vector<PlayerID> playersToRemove;
|
||||||
if (m_ConnectedPlayers[i].Endpoint.address() != boost::asio::ip::address()) {
|
for (auto& kv : m_ConnectedPlayers) {
|
||||||
double stopPing = 1000 * m_ConnectedPlayers[i].StopTime /
|
if (kv.second.TCPAddress != boost::asio::ip::address()) {
|
||||||
|
int stopPing = 1000 * kv.second.StopTime /
|
||||||
static_cast<double>(CLOCKS_PER_SEC);
|
static_cast<double>(CLOCKS_PER_SEC);
|
||||||
if (startPing > stopPing + m_TimeoutMs) {
|
if (startPing > stopPing + m_TimeoutMs) {
|
||||||
//LOG_INFO("User %i timed out!", i);
|
LOG_INFO("User %i timed out!", kv.second.Name);
|
||||||
//disconnect(i);
|
playersToRemove.push_back(kv.first);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
for (size_t i = 0; i < playersToRemove.size(); i++) {
|
||||||
|
disconnect(playersToRemove.at(i));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Server::parseUDPConnect(Packet & packet)
|
||||||
|
{
|
||||||
|
// Pop size of message int
|
||||||
|
packet.ReadPrimitive<int>();
|
||||||
|
int messageType = packet.ReadPrimitive<int>();
|
||||||
|
// Read packet ID
|
||||||
|
m_PreviousPacketID = m_PacketID; // Set previous packet id
|
||||||
|
m_PacketID = packet.ReadPrimitive<int>(); //Read new packet id
|
||||||
|
// parse player id and other stuff
|
||||||
|
PlayerID playerID = packet.ReadPrimitive<int>();
|
||||||
|
// Do something here?
|
||||||
|
boost::asio::ip::udp::endpoint endpoint(m_Address, m_Port);
|
||||||
|
m_ConnectedPlayers.at(playerID).Endpoint = endpoint;
|
||||||
|
LOG_INFO("parseUDPConnect: Spectator \"%s\" connected on IP: %s", m_ConnectedPlayers.at(playerID).Name.c_str(), m_ConnectedPlayers.at(playerID).Endpoint.address().to_string().c_str());
|
||||||
|
// Send a message to the player that connected
|
||||||
|
Packet connnectPacket(MessageType::Connect, m_ConnectedPlayers.at(playerID).PacketID);
|
||||||
|
m_Unreliable.Send(connnectPacket);
|
||||||
|
LOG_INFO("UDP Connect sent to client");
|
||||||
|
}
|
||||||
|
|
||||||
|
void Server::parseTCPConnect(Packet & packet)
|
||||||
|
{
|
||||||
|
// Pop size of message int
|
||||||
|
packet.ReadPrimitive<int>();
|
||||||
|
int messageType = packet.ReadPrimitive<int>();
|
||||||
|
// Read packet ID
|
||||||
|
m_PreviousPacketID = m_PacketID; // Set previous packet id
|
||||||
|
m_PacketID = packet.ReadPrimitive<int>(); //Read new packet id
|
||||||
|
|
||||||
|
LOG_INFO("Parsing connections");
|
||||||
|
// Check if player is already connected
|
||||||
|
// Ska vara till lagd i TCPServer receive
|
||||||
|
PlayerID playerID = GetPlayerIDFromEndpoint();
|
||||||
|
if (playerID == -1) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// Create a new player
|
||||||
|
m_ConnectedPlayers.at(playerID).EntityID = 0; // Overlook this
|
||||||
|
m_ConnectedPlayers.at(playerID).Name = packet.ReadString();
|
||||||
|
m_ConnectedPlayers.at(playerID).PacketID = 0;
|
||||||
|
m_ConnectedPlayers.at(playerID).StopTime = std::clock();
|
||||||
|
m_ConnectedPlayers.at(playerID).TCPAddress = m_Address;
|
||||||
|
m_ConnectedPlayers.at(playerID).TCPPort = m_Port;
|
||||||
|
|
||||||
|
LOG_INFO("parseTCPConnect: Spectator \"%s\" connected on IP: %s", m_ConnectedPlayers.at(playerID).Name.c_str(),
|
||||||
|
m_ConnectedPlayers.at(playerID).TCPAddress.to_string().c_str());
|
||||||
|
|
||||||
|
// Send a message to the player that connected
|
||||||
|
Packet connnectPacket(MessageType::Connect, m_ConnectedPlayers.at(playerID).PacketID);
|
||||||
|
// Write playerID to packet
|
||||||
|
connnectPacket.WritePrimitive(playerID);
|
||||||
|
m_Reliable.Send(connnectPacket);
|
||||||
|
|
||||||
|
// Send notification that a player has connected
|
||||||
|
//Packet notificationPacket(MessageType::PlayerConnected);
|
||||||
|
//broadcast(notificationPacket);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Server::parseDisconnect()
|
||||||
|
{
|
||||||
|
LOG_INFO("%i: Parsing disconnect", m_PacketID);
|
||||||
|
|
||||||
|
for (auto& kv : m_ConnectedPlayers) {
|
||||||
|
if (kv.second.TCPAddress == m_Address &&
|
||||||
|
kv.second.TCPPort == m_Port) {
|
||||||
|
m_PlayersToDisconnect.push_back(kv.first);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Server::disconnect(PlayerID playerID)
|
void Server::disconnect(PlayerID playerID)
|
||||||
@@ -267,33 +329,14 @@ void Server::disconnect(PlayerID playerID)
|
|||||||
LOG_INFO("User %s disconnected/timed out", m_ConnectedPlayers[playerID].Name.c_str());
|
LOG_INFO("User %s disconnected/timed out", m_ConnectedPlayers[playerID].Name.c_str());
|
||||||
// Remove enteties and stuff (When we can remove entity, remove it and tell clients to remove the copy they have)
|
// Remove enteties and stuff (When we can remove entity, remove it and tell clients to remove the copy they have)
|
||||||
Events::PlayerDisconnected e;
|
Events::PlayerDisconnected e;
|
||||||
e.Entity = m_ConnectedPlayers[playerID].EntityID;
|
e.Entity = m_ConnectedPlayers.at(playerID).EntityID;
|
||||||
e.PlayerID = playerID;
|
e.PlayerID = playerID;
|
||||||
m_EventBroker->Publish(e);
|
m_EventBroker->Publish(e);
|
||||||
|
//m_World->DeleteEntity(m_ConnectedPlayers[playerID].EntityID);
|
||||||
|
m_ConnectedPlayers[playerID].TCPSocket->shutdown(boost::asio::ip::tcp::socket::shutdown_both);
|
||||||
|
m_ConnectedPlayers[playerID].TCPSocket->close();
|
||||||
m_ConnectedPlayers.erase(playerID);
|
m_ConnectedPlayers.erase(playerID);
|
||||||
}
|
// Send disconnect to the other players.
|
||||||
|
|
||||||
void Server::parseOnInputCommand(Packet& packet)
|
|
||||||
{
|
|
||||||
PlayerID player = -1;
|
|
||||||
// Check which player it was who sent the message
|
|
||||||
player = GetPlayerIDFromEndpoint(m_ReceiverEndpoint);
|
|
||||||
if (player != -1) {
|
|
||||||
while (packet.DataReadSize() < packet.Size()) {
|
|
||||||
Events::InputCommand e;
|
|
||||||
e.Command = packet.ReadString();
|
|
||||||
e.PlayerID = player; // Set correct player id
|
|
||||||
e.Player = EntityWrapper(m_World, m_ConnectedPlayers.at(player).EntityID);
|
|
||||||
e.Value = packet.ReadPrimitive<float>();
|
|
||||||
m_EventBroker->Publish(e);
|
|
||||||
|
|
||||||
if (e.Command == "PrimaryFire") {
|
|
||||||
m_InputCommandsToBroadcast.push_back(e);
|
|
||||||
}
|
|
||||||
//LOG_INFO("Server::parseOnInputCommand: Command is %s. Value is %f. PlayerID is %i.", e.Command.c_str(), e.Value, e.PlayerID);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Server::parseOnPlayerDamage(Packet & packet)
|
void Server::parseOnPlayerDamage(Packet & packet)
|
||||||
@@ -306,75 +349,6 @@ void Server::parseOnPlayerDamage(Packet & packet)
|
|||||||
//LOG_DEBUG("Server::parseOnPlayerDamage: Command is %s. Value is %f. PlayerID is %i.", e.DamageAmount, e.PlayerDamagedID, e.TypeOfDamage.c_str());
|
//LOG_DEBUG("Server::parseOnPlayerDamage: Command is %s. Value is %f. PlayerID is %i.", e.DamageAmount, e.PlayerDamagedID, e.TypeOfDamage.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
void Server::parseConnect(Packet& packet)
|
|
||||||
{
|
|
||||||
LOG_INFO("Parsing connections");
|
|
||||||
// Check if player is already connected
|
|
||||||
if (GetPlayerIDFromEndpoint(m_ReceiverEndpoint) != -1) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
for (auto& kv : m_ConnectedPlayers) {
|
|
||||||
if (kv.second.Endpoint.address() == m_ReceiverEndpoint.address() &&
|
|
||||||
kv.second.Endpoint.port() == m_ReceiverEndpoint.port()) {
|
|
||||||
// Already connected
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Create a new player
|
|
||||||
PlayerDefinition pd;
|
|
||||||
pd.EntityID = 0; // Overlook this
|
|
||||||
pd.Endpoint = m_ReceiverEndpoint;
|
|
||||||
pd.Name = packet.ReadString();
|
|
||||||
pd.PacketID = 0;
|
|
||||||
pd.StopTime = std::clock();
|
|
||||||
m_ConnectedPlayers[m_NextPlayerID++] = pd;
|
|
||||||
LOG_INFO("Spectator \"%s\" connected on IP: %s", pd.Name.c_str(), pd.Endpoint.address().to_string().c_str());
|
|
||||||
|
|
||||||
// Send a message to the player that connected
|
|
||||||
Packet connnectPacket(MessageType::Connect, pd.PacketID);
|
|
||||||
send(connnectPacket);
|
|
||||||
|
|
||||||
// Send notification that a player has connected
|
|
||||||
Packet notificationPacket(MessageType::PlayerConnected);
|
|
||||||
broadcast(notificationPacket);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Server::parseDisconnect()
|
|
||||||
{
|
|
||||||
LOG_INFO("%i: Parsing disconnect", m_PacketID);
|
|
||||||
|
|
||||||
for (auto& kv : m_ConnectedPlayers) {
|
|
||||||
if (kv.second.Endpoint.address() == m_ReceiverEndpoint.address() &&
|
|
||||||
kv.second.Endpoint.port() == m_ReceiverEndpoint.port()) {
|
|
||||||
disconnect(kv.first);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Server::parseClientPing()
|
|
||||||
{
|
|
||||||
LOG_INFO("%i: Parsing ping", m_PacketID);
|
|
||||||
PlayerID player = GetPlayerIDFromEndpoint(m_ReceiverEndpoint);
|
|
||||||
if (player == -1) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
// Return ping
|
|
||||||
Packet packet(MessageType::Ping, m_ConnectedPlayers[player].PacketID);
|
|
||||||
packet.WriteString("Ping received");
|
|
||||||
send(packet);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Server::parsePing()
|
|
||||||
{
|
|
||||||
for (int i = 0; i < m_ConnectedPlayers.size(); i++) {
|
|
||||||
if (m_ConnectedPlayers[i].Endpoint.address() == m_ReceiverEndpoint.address()) {
|
|
||||||
m_ConnectedPlayers[i].StopTime = std::clock();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Server::identifyPacketLoss()
|
void Server::identifyPacketLoss()
|
||||||
{
|
{
|
||||||
// if no packets lost, difference should be equal to 1
|
// if no packets lost, difference should be equal to 1
|
||||||
@@ -388,18 +362,7 @@ void Server::kick(PlayerID player)
|
|||||||
{
|
{
|
||||||
disconnect(player);
|
disconnect(player);
|
||||||
Packet packet = Packet(MessageType::Kick);
|
Packet packet = Packet(MessageType::Kick);
|
||||||
send(packet);
|
m_Reliable.Send(packet);
|
||||||
}
|
|
||||||
|
|
||||||
PlayerID Server::GetPlayerIDFromEndpoint(boost::asio::ip::udp::endpoint endpoint)
|
|
||||||
{
|
|
||||||
for (auto& kv : m_ConnectedPlayers) {
|
|
||||||
if (kv.second.Endpoint.address() == endpoint.address() &&
|
|
||||||
kv.second.Endpoint.port() == endpoint.port()) {
|
|
||||||
return kv.first;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return -1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Server::OnInputCommand(const Events::InputCommand & e)
|
bool Server::OnInputCommand(const Events::InputCommand & e)
|
||||||
@@ -428,7 +391,7 @@ bool Server::OnPlayerSpawned(const Events::PlayerSpawned & e)
|
|||||||
packet.WritePrimitive<EntityID>(e.Spawner.ID);
|
packet.WritePrimitive<EntityID>(e.Spawner.ID);
|
||||||
// We don't send PlayerID here because it will always be set to -1
|
// We don't send PlayerID here because it will always be set to -1
|
||||||
packet.WriteString(m_ConnectedPlayers[e.PlayerID].Name);
|
packet.WriteString(m_ConnectedPlayers[e.PlayerID].Name);
|
||||||
send(e.PlayerID, packet);
|
m_Reliable.Send(packet, m_ConnectedPlayers[e.PlayerID]);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -437,7 +400,7 @@ bool Server::OnEntityDeleted(const Events::EntityDeleted & e)
|
|||||||
if (!e.Cascaded) {
|
if (!e.Cascaded) {
|
||||||
Packet packet = Packet(MessageType::EntityDeleted);
|
Packet packet = Packet(MessageType::EntityDeleted);
|
||||||
packet.WritePrimitive<EntityID>(e.DeletedEntity);
|
packet.WritePrimitive<EntityID>(e.DeletedEntity);
|
||||||
broadcast(packet);
|
reliableBroadcast(packet);
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -445,14 +408,72 @@ bool Server::OnEntityDeleted(const Events::EntityDeleted & e)
|
|||||||
bool Server::OnComponentDeleted(const Events::ComponentDeleted & e)
|
bool Server::OnComponentDeleted(const Events::ComponentDeleted & e)
|
||||||
{
|
{
|
||||||
if (!e.Cascaded) {
|
if (!e.Cascaded) {
|
||||||
Packet packet = Packet(MessageType::ComponentDeleted);
|
if (shouldSendToClient(EntityWrapper(m_World, e.Entity))) {
|
||||||
packet.WritePrimitive<EntityID>(e.Entity);
|
Packet packet = Packet(MessageType::ComponentDeleted);
|
||||||
packet.WriteString(e.ComponentType);
|
packet.WritePrimitive<EntityID>(e.Entity);
|
||||||
broadcast(packet);
|
packet.WriteString(e.ComponentType);
|
||||||
|
reliableBroadcast(packet);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Server::OnPlayerDamage(const Events::PlayerDamage& e)
|
||||||
|
{
|
||||||
|
Packet packet(MessageType::OnPlayerDamage);
|
||||||
|
packet.WritePrimitive(e.Inflictor.ID);
|
||||||
|
packet.WritePrimitive(e.Victim.ID);
|
||||||
|
packet.WritePrimitive(e.Damage);
|
||||||
|
reliableBroadcast(packet);
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Server::parseClientPing()
|
||||||
|
{
|
||||||
|
LOG_INFO("%i: Parsing ping", m_PacketID);
|
||||||
|
PlayerID player = GetPlayerIDFromEndpoint();
|
||||||
|
if (player == -1) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// Return ping
|
||||||
|
Packet packet(MessageType::Ping, m_ConnectedPlayers[player].PacketID);
|
||||||
|
packet.WriteString("Ping received");
|
||||||
|
m_Reliable.Send(packet);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Server::parsePing()
|
||||||
|
{
|
||||||
|
for (auto& kv : m_ConnectedPlayers) {
|
||||||
|
if (kv.second.TCPAddress == m_Address &&
|
||||||
|
kv.second.TCPPort == m_Port) {
|
||||||
|
kv.second.StopTime = std::clock();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Server::parseOnInputCommand(Packet& packet)
|
||||||
|
{
|
||||||
|
PlayerID player = -1;
|
||||||
|
// Check which player it was who sent the message
|
||||||
|
player = GetPlayerIDFromEndpoint();
|
||||||
|
if (player != -1) {
|
||||||
|
while (packet.DataReadSize() < packet.Size()) {
|
||||||
|
Events::InputCommand e;
|
||||||
|
e.Command = packet.ReadString();
|
||||||
|
e.PlayerID = player; // Set correct player id
|
||||||
|
e.Player = EntityWrapper(m_World, m_ConnectedPlayers.at(player).EntityID);
|
||||||
|
e.Value = packet.ReadPrimitive<float>();
|
||||||
|
m_EventBroker->Publish(e);
|
||||||
|
if (e.Command == "PrimaryFire" || e.Command == "Reload") {
|
||||||
|
m_InputCommandsToBroadcast.push_back(e);
|
||||||
|
}
|
||||||
|
//LOG_INFO("Server::parseOnInputCommand: Command is %s. Value is %f. PlayerID is %i.", e.Command.c_str(), e.Value, e.PlayerID);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void Server::parsePlayerTransform(Packet& packet)
|
void Server::parsePlayerTransform(Packet& packet)
|
||||||
{
|
{
|
||||||
glm::vec3 position;
|
glm::vec3 position;
|
||||||
@@ -464,11 +485,42 @@ void Server::parsePlayerTransform(Packet& packet)
|
|||||||
orientation.y = packet.ReadPrimitive<float>();
|
orientation.y = packet.ReadPrimitive<float>();
|
||||||
orientation.z = packet.ReadPrimitive<float>();
|
orientation.z = packet.ReadPrimitive<float>();
|
||||||
|
|
||||||
PlayerID playerID = GetPlayerIDFromEndpoint(m_ReceiverEndpoint);
|
PlayerID playerID = GetPlayerIDFromEndpoint();
|
||||||
EntityWrapper player(m_World, m_ConnectedPlayers.at(playerID).EntityID);
|
bool hasAssaultWeapon = packet.ReadPrimitive<bool>();
|
||||||
|
int magazineAmmo;
|
||||||
|
int ammo;
|
||||||
|
if (hasAssaultWeapon) {
|
||||||
|
magazineAmmo = packet.ReadPrimitive<int>();
|
||||||
|
ammo = packet.ReadPrimitive<int>();
|
||||||
|
}
|
||||||
|
|
||||||
|
EntityWrapper player(m_World, m_ConnectedPlayers.at(playerID).EntityID);
|
||||||
if (player.Valid()) {
|
if (player.Valid()) {
|
||||||
player["Transform"]["Position"] = position;
|
player["Transform"]["Position"] = position;
|
||||||
player["Transform"]["Orientation"] = orientation;
|
player["Transform"]["Orientation"] = orientation;
|
||||||
|
|
||||||
|
if (hasAssaultWeapon) {
|
||||||
|
player["AssaultWeapon"]["MagazineAmmo"] = magazineAmmo;
|
||||||
|
player["AssaultWeapon"]["Ammo"] = ammo;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Server::shouldSendToClient(EntityWrapper childEntity)
|
||||||
|
{
|
||||||
|
return childEntity.HasComponent("Player") || childEntity.FirstParentWithComponent("Player").Valid();
|
||||||
|
}
|
||||||
|
|
||||||
|
PlayerID Server::GetPlayerIDFromEndpoint()
|
||||||
|
{
|
||||||
|
// check both tcp and udp connection
|
||||||
|
for (auto& kv : m_ConnectedPlayers) {
|
||||||
|
if ((kv.second.TCPAddress == m_Address
|
||||||
|
&& kv.second.TCPPort == m_Port)
|
||||||
|
|| (kv.second.Endpoint.address() == m_Address
|
||||||
|
&& kv.second.Endpoint.port() == m_Port)) {
|
||||||
|
return kv.first;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
@@ -0,0 +1,107 @@
|
|||||||
|
#include "Network/TCPClient.h"
|
||||||
|
|
||||||
|
using namespace boost::asio::ip;
|
||||||
|
|
||||||
|
TCPClient::TCPClient()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
TCPClient::~TCPClient()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void TCPClient::Connect(std::string playerName, std::string address, int port)
|
||||||
|
{
|
||||||
|
if (m_Socket) {
|
||||||
|
if (m_IsConnected) {
|
||||||
|
Packet packet(MessageType::Connect, m_SendPacketID);
|
||||||
|
packet.WriteString(playerName);
|
||||||
|
Send(packet);
|
||||||
|
LOG_INFO("Connect message sent again!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (!m_IsConnected) {
|
||||||
|
boost::system::error_code error = boost::asio::error::host_not_found;
|
||||||
|
m_Endpoint = tcp::endpoint(boost::asio::ip::address::from_string(address), port);
|
||||||
|
m_Socket = std::unique_ptr<tcp::socket>(new tcp::socket(m_IOService));
|
||||||
|
m_Socket->connect(m_Endpoint, error);
|
||||||
|
tcp::no_delay option(true);
|
||||||
|
m_Socket->set_option(option);
|
||||||
|
LOG_INFO(error.message().c_str());
|
||||||
|
if (!error) {
|
||||||
|
m_IsConnected = true;
|
||||||
|
Packet packet(MessageType::Connect, m_SendPacketID);
|
||||||
|
packet.WriteString(playerName);
|
||||||
|
Send(packet);
|
||||||
|
LOG_INFO("Connect message sent!");
|
||||||
|
}
|
||||||
|
// If error
|
||||||
|
else {
|
||||||
|
m_Socket->close();
|
||||||
|
m_Socket = nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void TCPClient::Disconnect()
|
||||||
|
{
|
||||||
|
if (!m_IsConnected) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
m_Socket->shutdown(boost::asio::ip::tcp::socket::shutdown_both);
|
||||||
|
m_Socket->close();
|
||||||
|
m_Socket = nullptr;
|
||||||
|
m_IsConnected = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void TCPClient::Receive(Packet& packet)
|
||||||
|
{
|
||||||
|
size_t bytesRead = readBuffer(m_ReadBuffer);
|
||||||
|
if (bytesRead > 0) {
|
||||||
|
packet.ReconstructFromData(m_ReadBuffer, bytesRead);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t TCPClient::readBuffer(char* data)
|
||||||
|
{
|
||||||
|
if (!m_Socket) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
boost::system::error_code error;
|
||||||
|
// Read size of packet
|
||||||
|
size_t bytesReceived = m_Socket->read_some(boost
|
||||||
|
::asio::buffer((void*)data, sizeof(int)),
|
||||||
|
error);
|
||||||
|
int sizeOfPacket = 0;
|
||||||
|
memcpy(&sizeOfPacket, data, sizeof(int));
|
||||||
|
|
||||||
|
// Read the rest of the message
|
||||||
|
bytesReceived += m_Socket->read_some(boost
|
||||||
|
::asio::buffer((void*)(data + bytesReceived), sizeOfPacket - bytesReceived),
|
||||||
|
error);
|
||||||
|
if (error) {
|
||||||
|
//LOG_ERROR("receive: %s", error.message().c_str());
|
||||||
|
}
|
||||||
|
return bytesReceived;
|
||||||
|
}
|
||||||
|
|
||||||
|
void TCPClient::Send(Packet & packet)
|
||||||
|
{
|
||||||
|
if (!m_Socket) {
|
||||||
|
LOG_WARNING("TCPClient::Send: Socket is null");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
packet.UpdateSize();
|
||||||
|
boost::system::error_code error;
|
||||||
|
m_Socket->send(boost::asio::buffer(
|
||||||
|
packet.Data(),
|
||||||
|
packet.Size()), 0, error);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool TCPClient::IsSocketAvailable()
|
||||||
|
{
|
||||||
|
if (!m_Socket) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return m_Socket->available();
|
||||||
|
}
|
||||||
@@ -0,0 +1,110 @@
|
|||||||
|
#include "Network/TCPServer.h"
|
||||||
|
using namespace boost::asio::ip;
|
||||||
|
|
||||||
|
TCPServer::TCPServer()
|
||||||
|
{
|
||||||
|
acceptor = std::unique_ptr<tcp::acceptor>(new tcp::acceptor(m_IOService, tcp::endpoint(tcp::v4(), 27666)));
|
||||||
|
}
|
||||||
|
|
||||||
|
TCPServer::~TCPServer()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void TCPServer::AcceptNewConnections(int& nextPlayerID, std::map<PlayerID, PlayerDefinition>& connectedPlayers)
|
||||||
|
{
|
||||||
|
boost::shared_ptr<tcp::socket> newSocket = boost::shared_ptr<tcp::socket>(new tcp::socket(m_IOService));
|
||||||
|
m_IOService.poll();
|
||||||
|
acceptor->async_accept(*newSocket,
|
||||||
|
boost::bind(&TCPServer::handle_accept, this, newSocket, boost::ref(nextPlayerID), boost::ref(connectedPlayers),
|
||||||
|
boost::asio::placeholders::error));
|
||||||
|
}
|
||||||
|
|
||||||
|
PlayerID GetPlayerIDFromEndpoint(const std::map<PlayerID, PlayerDefinition>& connectedPlayers,
|
||||||
|
boost::asio::ip::address address, unsigned short port)
|
||||||
|
{
|
||||||
|
for (auto& kv : connectedPlayers) {
|
||||||
|
if (kv.second.TCPAddress == address &&
|
||||||
|
kv.second.TCPPort == port) {
|
||||||
|
return kv.first;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void TCPServer::handle_accept(boost::shared_ptr<tcp::socket> socket,
|
||||||
|
int& nextPlayerID, std::map<PlayerID, PlayerDefinition>& connectedPlayers,
|
||||||
|
const boost::system::error_code& error)
|
||||||
|
{
|
||||||
|
if (!error && GetPlayerIDFromEndpoint(connectedPlayers, socket->remote_endpoint().address(),
|
||||||
|
socket->remote_endpoint().port()) == -1) {
|
||||||
|
// Add tcp socket to connections
|
||||||
|
boost::asio::ip::tcp::no_delay option(true);
|
||||||
|
socket->set_option(option);
|
||||||
|
PlayerDefinition pd;
|
||||||
|
pd.StopTime = std::clock();
|
||||||
|
pd.TCPSocket = socket;
|
||||||
|
pd.TCPAddress = socket.get()->remote_endpoint().address();
|
||||||
|
pd.TCPPort = socket.get()->remote_endpoint().port();
|
||||||
|
connectedPlayers[nextPlayerID++] = pd;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void TCPServer::Send(Packet & packet, PlayerDefinition & playerDefinition)
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
packet.UpdateSize();
|
||||||
|
int bytesSent = playerDefinition.TCPSocket->send(
|
||||||
|
boost::asio::buffer(packet.Data(), packet.Size()),
|
||||||
|
0);
|
||||||
|
} catch (const boost::system::system_error& e) {
|
||||||
|
// TODO: Clean up invalid endpoints out of m_ConnectedPlayers later
|
||||||
|
playerDefinition.Endpoint = boost::asio::ip::udp::endpoint();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void TCPServer::Send(Packet & packet)
|
||||||
|
{
|
||||||
|
packet.UpdateSize();
|
||||||
|
lastReceivedSocket->send(
|
||||||
|
boost::asio::buffer(
|
||||||
|
packet.Data(),
|
||||||
|
packet.Size()),
|
||||||
|
0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void TCPServer::Disconnect()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void TCPServer::Receive(Packet & packet, PlayerDefinition & playerDefinition)
|
||||||
|
{
|
||||||
|
int bytesRead = readBuffer(m_ReadBuffer, playerDefinition);
|
||||||
|
if (bytesRead > 0) {
|
||||||
|
packet.ReconstructFromData(m_ReadBuffer, bytesRead);
|
||||||
|
}
|
||||||
|
lastReceivedSocket = playerDefinition.TCPSocket;
|
||||||
|
}
|
||||||
|
|
||||||
|
int TCPServer::readBuffer(char* data, PlayerDefinition & playerDefinition)
|
||||||
|
{
|
||||||
|
if (!playerDefinition.TCPSocket) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
boost::system::error_code error;
|
||||||
|
// Read size of packet
|
||||||
|
size_t bytesReceived = playerDefinition.TCPSocket->read_some(boost
|
||||||
|
::asio::buffer((void*)data, sizeof(int)),
|
||||||
|
error);
|
||||||
|
int sizeOfPacket = 0;
|
||||||
|
memcpy(&sizeOfPacket, data, sizeof(int));
|
||||||
|
|
||||||
|
// Read the rest of the message
|
||||||
|
bytesReceived += playerDefinition.TCPSocket->read_some(boost
|
||||||
|
::asio::buffer((void*)(data + bytesReceived), sizeOfPacket - bytesReceived),
|
||||||
|
error);
|
||||||
|
if (error) {
|
||||||
|
//LOG_ERROR("receive: %s", error.message().c_str());
|
||||||
|
}
|
||||||
|
return bytesReceived;
|
||||||
|
}
|
||||||
@@ -0,0 +1,66 @@
|
|||||||
|
#include "Network/UDPClient.h"
|
||||||
|
|
||||||
|
using namespace boost::asio::ip;
|
||||||
|
|
||||||
|
UDPClient::UDPClient()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
UDPClient::~UDPClient()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void UDPClient::Connect(std::string playerName, std::string address, int port)
|
||||||
|
{
|
||||||
|
if (m_Socket) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
m_ReceiverEndpoint = udp::endpoint(boost::asio::ip::address::from_string(address), port);
|
||||||
|
m_Socket = boost::shared_ptr<boost::asio::ip::udp::socket>(new boost::asio::ip::udp::socket(m_IOService));
|
||||||
|
m_Socket->connect(m_ReceiverEndpoint);
|
||||||
|
}
|
||||||
|
|
||||||
|
void UDPClient::Disconnect()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void UDPClient::Receive(Packet& packet)
|
||||||
|
{
|
||||||
|
int bytesRead = readBuffer(m_ReadBuffer);
|
||||||
|
if (bytesRead > 0) {
|
||||||
|
packet.ReconstructFromData(m_ReadBuffer, bytesRead);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int UDPClient::readBuffer(char* data)
|
||||||
|
{
|
||||||
|
if (!m_Socket) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
boost::system::error_code error;
|
||||||
|
int bytesReceived = m_Socket->receive_from(boost
|
||||||
|
::asio::buffer((void*)data, BUFFERSIZE),
|
||||||
|
m_ReceiverEndpoint,
|
||||||
|
0, error);
|
||||||
|
if (error) {
|
||||||
|
//LOG_ERROR("receive: %s", error.message().c_str());
|
||||||
|
}
|
||||||
|
return bytesReceived;
|
||||||
|
}
|
||||||
|
|
||||||
|
void UDPClient::Send(Packet& packet)
|
||||||
|
{
|
||||||
|
m_Socket->send_to(boost::asio::buffer(
|
||||||
|
packet.Data(),
|
||||||
|
packet.Size()),
|
||||||
|
m_ReceiverEndpoint, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool UDPClient::IsSocketAvailable()
|
||||||
|
{
|
||||||
|
if (!m_Socket) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return m_Socket->available();
|
||||||
|
}
|
||||||
@@ -0,0 +1,62 @@
|
|||||||
|
#include "Network/UDPServer.h"
|
||||||
|
|
||||||
|
UDPServer::UDPServer()
|
||||||
|
{
|
||||||
|
m_Socket = std::unique_ptr<boost::asio::ip::udp::socket>(new boost::asio::ip::udp::socket(m_IOService, boost::asio::ip::udp::endpoint(boost::asio::ip::udp::v4(), 27666)));
|
||||||
|
}
|
||||||
|
|
||||||
|
UDPServer::~UDPServer()
|
||||||
|
{ }
|
||||||
|
|
||||||
|
void UDPServer::Send(Packet& packet, PlayerDefinition & playerDefinition)
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
int bytesSent = m_Socket->send_to(
|
||||||
|
boost::asio::buffer(packet.Data(), packet.Size()),
|
||||||
|
playerDefinition.Endpoint,
|
||||||
|
0);
|
||||||
|
} catch (const boost::system::system_error& e) {
|
||||||
|
// TODO: Clean up invalid endpoints out of m_ConnectedPlayers later
|
||||||
|
playerDefinition.Endpoint = boost::asio::ip::udp::endpoint();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Send back to endpoint of received packet
|
||||||
|
void UDPServer::Send(Packet & packet)
|
||||||
|
{
|
||||||
|
m_Socket->send_to(
|
||||||
|
boost::asio::buffer(
|
||||||
|
packet.Data(),
|
||||||
|
packet.Size()),
|
||||||
|
m_ReceiverEndpoint,
|
||||||
|
0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void UDPServer::Receive(Packet & packet, PlayerDefinition & playerDefinition)
|
||||||
|
{
|
||||||
|
int bytesRead = readBuffer(m_ReadBuffer);
|
||||||
|
if (bytesRead > 0) {
|
||||||
|
packet.ReconstructFromData(m_ReadBuffer, bytesRead);
|
||||||
|
}
|
||||||
|
playerDefinition.Endpoint = m_ReceiverEndpoint;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool UDPServer::IsSocketAvailable()
|
||||||
|
{
|
||||||
|
return m_Socket->available();
|
||||||
|
}
|
||||||
|
|
||||||
|
int UDPServer::readBuffer(char* data)
|
||||||
|
{
|
||||||
|
boost::system::error_code error = boost::asio::error::host_not_found;
|
||||||
|
unsigned int length = m_Socket->receive_from(
|
||||||
|
boost::asio::buffer((void*)data
|
||||||
|
, BUFFERSIZE)
|
||||||
|
, m_ReceiverEndpoint, 0, error);
|
||||||
|
if (error) {
|
||||||
|
LOG_WARNING(error.message().c_str());
|
||||||
|
}
|
||||||
|
return length;
|
||||||
|
}
|
||||||
|
|
||||||
|
void UDPServer::AcceptNewConnections(int& nextPlayerID, std::map<PlayerID, PlayerDefinition>& connectedPlayers)
|
||||||
|
{ }
|
||||||
@@ -42,22 +42,22 @@ void PickingPass::InitializeShaderPrograms()
|
|||||||
m_PickingProgram->BindFragDataLocation(0, "TextureFragment");
|
m_PickingProgram->BindFragDataLocation(0, "TextureFragment");
|
||||||
m_PickingProgram->Link();
|
m_PickingProgram->Link();
|
||||||
|
|
||||||
m_PickingSkinnedProgram = ResourceManager::Load<ShaderProgram>("#PickingSkinnedProgram");
|
m_PickingSkinnedProgram = ResourceManager::Load<ShaderProgram>("#PickingSkinnedProgram");
|
||||||
|
|
||||||
m_PickingSkinnedProgram->AddShader(std::shared_ptr<Shader>(new VertexShader("Shaders/PickingSkinned.vert.glsl")));
|
m_PickingSkinnedProgram->AddShader(std::shared_ptr<Shader>(new VertexShader("Shaders/PickingSkinned.vert.glsl")));
|
||||||
m_PickingSkinnedProgram->AddShader(std::shared_ptr<Shader>(new FragmentShader("Shaders/Picking.frag.glsl")));
|
m_PickingSkinnedProgram->AddShader(std::shared_ptr<Shader>(new FragmentShader("Shaders/Picking.frag.glsl")));
|
||||||
m_PickingSkinnedProgram->Compile();
|
m_PickingSkinnedProgram->Compile();
|
||||||
m_PickingSkinnedProgram->BindFragDataLocation(0, "TextureFragment");
|
m_PickingSkinnedProgram->BindFragDataLocation(0, "TextureFragment");
|
||||||
m_PickingSkinnedProgram->Link();
|
m_PickingSkinnedProgram->Link();
|
||||||
}
|
}
|
||||||
|
|
||||||
void PickingPass::Draw(RenderScene& scene)
|
void PickingPass::Draw(RenderScene& scene)
|
||||||
{
|
{
|
||||||
PickingPassState* state = new PickingPassState(m_PickingBuffer.GetHandle());
|
PickingPassState* state = new PickingPassState(m_PickingBuffer.GetHandle());
|
||||||
|
|
||||||
//TODO: Render: Add code for more jobs than modeljobs.
|
//TODO: Render: Add code for more jobs than modeljobs.
|
||||||
GLuint shaderHandle = m_PickingProgram->GetHandle();
|
GLuint shaderHandle = m_PickingProgram->GetHandle();
|
||||||
GLuint shaderSkinnedHandle = m_PickingSkinnedProgram->GetHandle();
|
GLuint shaderSkinnedHandle = m_PickingSkinnedProgram->GetHandle();
|
||||||
m_PickingProgram->Bind();
|
m_PickingProgram->Bind();
|
||||||
|
|
||||||
if (scene.ClearDepth) {
|
if (scene.ClearDepth) {
|
||||||
@@ -92,15 +92,14 @@ void PickingPass::Draw(RenderScene& scene)
|
|||||||
|
|
||||||
m_PickingColorsToEntity[glm::ivec2(pickColor[0], pickColor[1])] = pickInfo;
|
m_PickingColorsToEntity[glm::ivec2(pickColor[0], pickColor[1])] = pickInfo;
|
||||||
|
|
||||||
if (modelJob->Model->IsSkinned())
|
if (modelJob->Model->IsSkinned()) {
|
||||||
{
|
m_PickingSkinnedProgram->Bind();
|
||||||
m_PickingSkinnedProgram->Bind();
|
glUniformMatrix4fv(glGetUniformLocation(shaderSkinnedHandle, "M"), 1, GL_FALSE, glm::value_ptr(modelJob->Matrix));
|
||||||
glUniformMatrix4fv(glGetUniformLocation(shaderSkinnedHandle, "M"), 1, GL_FALSE, glm::value_ptr(modelJob->Matrix));
|
glUniformMatrix4fv(glGetUniformLocation(shaderSkinnedHandle, "V"), 1, GL_FALSE, glm::value_ptr(scene.Camera->ViewMatrix()));
|
||||||
glUniformMatrix4fv(glGetUniformLocation(shaderSkinnedHandle, "V"), 1, GL_FALSE, glm::value_ptr(scene.Camera->ViewMatrix()));
|
glUniformMatrix4fv(glGetUniformLocation(shaderSkinnedHandle, "P"), 1, GL_FALSE, glm::value_ptr(scene.Camera->ProjectionMatrix()));
|
||||||
glUniformMatrix4fv(glGetUniformLocation(shaderSkinnedHandle, "P"), 1, GL_FALSE, glm::value_ptr(scene.Camera->ProjectionMatrix()));
|
glUniform2fv(glGetUniformLocation(shaderSkinnedHandle, "PickingColor"), 1, glm::value_ptr(glm::vec2(pickColor[0], pickColor[1])));
|
||||||
glUniform2fv(glGetUniformLocation(shaderSkinnedHandle, "PickingColor"), 1, glm::value_ptr(glm::vec2(pickColor[0], pickColor[1])));
|
|
||||||
|
|
||||||
if (modelJob->Model->m_RawModel->m_Skeleton != nullptr) {
|
if (modelJob->Model->m_RawModel->m_Skeleton != nullptr) {
|
||||||
|
|
||||||
std::vector<glm::mat4> frameBones;
|
std::vector<glm::mat4> frameBones;
|
||||||
if (modelJob->AnimationOffset.animation != nullptr) {
|
if (modelJob->AnimationOffset.animation != nullptr) {
|
||||||
@@ -109,15 +108,14 @@ void PickingPass::Draw(RenderScene& scene)
|
|||||||
frameBones = modelJob->Skeleton->GetFrameBones(modelJob->Animations);
|
frameBones = modelJob->Skeleton->GetFrameBones(modelJob->Animations);
|
||||||
}
|
}
|
||||||
glUniformMatrix4fv(glGetUniformLocation(shaderSkinnedHandle, "Bones"), frameBones.size(), GL_FALSE, glm::value_ptr(frameBones[0]));
|
glUniformMatrix4fv(glGetUniformLocation(shaderSkinnedHandle, "Bones"), frameBones.size(), GL_FALSE, glm::value_ptr(frameBones[0]));
|
||||||
|
}
|
||||||
}
|
} else {
|
||||||
} else {
|
|
||||||
m_PickingProgram->Bind();
|
m_PickingProgram->Bind();
|
||||||
glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "M"), 1, GL_FALSE, glm::value_ptr(modelJob->Matrix));
|
glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "M"), 1, GL_FALSE, glm::value_ptr(modelJob->Matrix));
|
||||||
glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "V"), 1, GL_FALSE, glm::value_ptr(scene.Camera->ViewMatrix()));
|
glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "V"), 1, GL_FALSE, glm::value_ptr(scene.Camera->ViewMatrix()));
|
||||||
glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "P"), 1, GL_FALSE, glm::value_ptr(scene.Camera->ProjectionMatrix()));
|
glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "P"), 1, GL_FALSE, glm::value_ptr(scene.Camera->ProjectionMatrix()));
|
||||||
glUniform2fv(glGetUniformLocation(shaderHandle, "PickingColor"), 1, glm::value_ptr(glm::vec2(pickColor[0], pickColor[1])));
|
glUniform2fv(glGetUniformLocation(shaderHandle, "PickingColor"), 1, glm::value_ptr(glm::vec2(pickColor[0], pickColor[1])));
|
||||||
}
|
}
|
||||||
|
|
||||||
glBindVertexArray(modelJob->Model->VAO);
|
glBindVertexArray(modelJob->Model->VAO);
|
||||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, modelJob->Model->ElementBuffer);
|
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, modelJob->Model->ElementBuffer);
|
||||||
@@ -207,7 +205,7 @@ void PickingPass::Draw(RenderScene& scene)
|
|||||||
|
|
||||||
m_PickingColorsToEntity[glm::ivec2(pickColor[0], pickColor[1])] = pickInfo;
|
m_PickingColorsToEntity[glm::ivec2(pickColor[0], pickColor[1])] = pickInfo;
|
||||||
|
|
||||||
if(modelJob->Model->IsSkinned()) {
|
if (modelJob->Model->IsSkinned()) {
|
||||||
m_PickingSkinnedProgram->Bind();
|
m_PickingSkinnedProgram->Bind();
|
||||||
glUniformMatrix4fv(glGetUniformLocation(shaderSkinnedHandle, "M"), 1, GL_FALSE, glm::value_ptr(modelJob->Matrix));
|
glUniformMatrix4fv(glGetUniformLocation(shaderSkinnedHandle, "M"), 1, GL_FALSE, glm::value_ptr(modelJob->Matrix));
|
||||||
glUniformMatrix4fv(glGetUniformLocation(shaderSkinnedHandle, "V"), 1, GL_FALSE, glm::value_ptr(scene.Camera->ViewMatrix()));
|
glUniformMatrix4fv(glGetUniformLocation(shaderSkinnedHandle, "V"), 1, GL_FALSE, glm::value_ptr(scene.Camera->ViewMatrix()));
|
||||||
@@ -266,7 +264,7 @@ void PickingPass::Draw(RenderScene& scene)
|
|||||||
|
|
||||||
if (modelJob->Model->IsSkinned()) {
|
if (modelJob->Model->IsSkinned()) {
|
||||||
m_PickingSkinnedProgram->Bind();
|
m_PickingSkinnedProgram->Bind();
|
||||||
|
|
||||||
|
|
||||||
glUniformMatrix4fv(glGetUniformLocation(shaderSkinnedHandle, "M"), 1, GL_FALSE, glm::value_ptr(modelJob->Matrix));
|
glUniformMatrix4fv(glGetUniformLocation(shaderSkinnedHandle, "M"), 1, GL_FALSE, glm::value_ptr(modelJob->Matrix));
|
||||||
glUniformMatrix4fv(glGetUniformLocation(shaderSkinnedHandle, "V"), 1, GL_FALSE, glm::value_ptr(scene.Camera->ViewMatrix()));
|
glUniformMatrix4fv(glGetUniformLocation(shaderSkinnedHandle, "V"), 1, GL_FALSE, glm::value_ptr(scene.Camera->ViewMatrix()));
|
||||||
@@ -293,7 +291,7 @@ void PickingPass::Draw(RenderScene& scene)
|
|||||||
glUniform2fv(glGetUniformLocation(shaderHandle, "PickingColor"), 1, glm::value_ptr(glm::vec2(pickColor[0], pickColor[1])));
|
glUniform2fv(glGetUniformLocation(shaderHandle, "PickingColor"), 1, glm::value_ptr(glm::vec2(pickColor[0], pickColor[1])));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
glBindVertexArray(modelJob->Model->VAO);
|
glBindVertexArray(modelJob->Model->VAO);
|
||||||
@@ -301,7 +299,7 @@ void PickingPass::Draw(RenderScene& scene)
|
|||||||
glDrawElements(GL_TRIANGLES, modelJob->EndIndex - modelJob->StartIndex + 1, GL_UNSIGNED_INT, (void*)(modelJob->StartIndex * sizeof(unsigned int)));
|
glDrawElements(GL_TRIANGLES, modelJob->EndIndex - modelJob->StartIndex + 1, GL_UNSIGNED_INT, (void*)(modelJob->StartIndex * sizeof(unsigned int)));
|
||||||
}
|
}
|
||||||
}*/
|
}*/
|
||||||
|
|
||||||
m_PickingBuffer.Unbind();
|
m_PickingBuffer.Unbind();
|
||||||
GLERROR("PickingPass Error");
|
GLERROR("PickingPass Error");
|
||||||
|
|
||||||
|
|||||||
@@ -79,7 +79,6 @@ void RenderSystem::fillSprites(std::list<std::shared_ptr<RenderJob>>& jobs, Worl
|
|||||||
|
|
||||||
bool RenderSystem::isEntityVisible(EntityWrapper& entity)
|
bool RenderSystem::isEntityVisible(EntityWrapper& entity)
|
||||||
{
|
{
|
||||||
|
|
||||||
// Only render children of a camera if that camera is currently active
|
// Only render children of a camera if that camera is currently active
|
||||||
if (isChildOfACamera(entity) && !isChildOfCurrentCamera(entity)) {
|
if (isChildOfACamera(entity) && !isChildOfCurrentCamera(entity)) {
|
||||||
return false;
|
return false;
|
||||||
@@ -87,7 +86,11 @@ bool RenderSystem::isEntityVisible(EntityWrapper& entity)
|
|||||||
|
|
||||||
// Hide things parented to local player if they have the HiddenFromLocalPlayer component
|
// Hide things parented to local player if they have the HiddenFromLocalPlayer component
|
||||||
bool outOfBodyExperience = ResourceManager::Load<ConfigFile>("Config.ini")->Get<bool>("Debug.OutOfBodyExperience", false);
|
bool outOfBodyExperience = ResourceManager::Load<ConfigFile>("Config.ini")->Get<bool>("Debug.OutOfBodyExperience", false);
|
||||||
if (entity.HasComponent("HiddenForLocalPlayer") && (entity == m_LocalPlayer || entity.IsChildOf(m_LocalPlayer)) && !outOfBodyExperience) {
|
if (
|
||||||
|
(entity.HasComponent("HiddenForLocalPlayer") || entity.FirstParentWithComponent("HiddenForLocalPlayer").Valid())
|
||||||
|
&& (entity == m_LocalPlayer || entity.IsChildOf(m_LocalPlayer))
|
||||||
|
&& !outOfBodyExperience
|
||||||
|
) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -168,6 +168,7 @@ void Renderer::SortRenderJobsByDepth(RenderScene &scene)
|
|||||||
//Sort all forward jobs so transparency is good.
|
//Sort all forward jobs so transparency is good.
|
||||||
scene.Jobs.TransparentObjects.sort(Renderer::DepthSort);
|
scene.Jobs.TransparentObjects.sort(Renderer::DepthSort);
|
||||||
scene.Jobs.SpriteJob.sort(Renderer::DepthSort);
|
scene.Jobs.SpriteJob.sort(Renderer::DepthSort);
|
||||||
|
scene.Jobs.Text.sort(Renderer::DepthSort);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Renderer::GenerateTexture(GLuint* texture, GLenum wrapping, GLenum filtering, glm::vec2 dimensions, GLint internalFormat, GLint format, GLenum type)
|
void Renderer::GenerateTexture(GLuint* texture, GLenum wrapping, GLenum filtering, glm::vec2 dimensions, GLint internalFormat, GLint format, GLenum type)
|
||||||
|
|||||||
@@ -36,6 +36,7 @@ source_group(Network FILES ${SOURCE_FILES_Network})
|
|||||||
set(SOURCE_FILES
|
set(SOURCE_FILES
|
||||||
${SOURCE_FILES}
|
${SOURCE_FILES}
|
||||||
"Game.cpp"
|
"Game.cpp"
|
||||||
|
"MiniDump.cpp"
|
||||||
${SOURCE_FILES_Systems}
|
${SOURCE_FILES_Systems}
|
||||||
${SOURCE_FILES_Systems_Weapon}
|
${SOURCE_FILES_Systems_Weapon}
|
||||||
${SOURCE_FILES_Events}
|
${SOURCE_FILES_Events}
|
||||||
|
|||||||
+7
-2
@@ -18,12 +18,15 @@
|
|||||||
#include "Game/Systems/DamageIndicatorSystem.h"
|
#include "Game/Systems/DamageIndicatorSystem.h"
|
||||||
#include "Game/Systems/Weapon/WeaponSystem.h"
|
#include "Game/Systems/Weapon/WeaponSystem.h"
|
||||||
#include "Rendering/AnimationSystem.h"
|
#include "Rendering/AnimationSystem.h"
|
||||||
#include "Game/Systems/PlayerHUDSystem.h"
|
#include "Game/Systems/HealthHUDSystem.h"
|
||||||
#include "Rendering/BoneAttachmentSystem.h"
|
#include "Rendering/BoneAttachmentSystem.h"
|
||||||
#include "Game/Systems/LifetimeSystem.h"
|
#include "Game/Systems/LifetimeSystem.h"
|
||||||
#include "../Engine/Core/UniformScaleSystem.h"
|
#include "../Engine/Core/UniformScaleSystem.h"
|
||||||
#include "Rendering/AnimationSystem.h"
|
#include "Rendering/AnimationSystem.h"
|
||||||
#include "Network/MultiplayerSnapshotFilter.h"
|
#include "Network/MultiplayerSnapshotFilter.h"
|
||||||
|
#include "Game/Systems/AmmunitionHUDSystem.h"
|
||||||
|
#include "Game/Systems/KillFeedSystem.h"
|
||||||
|
|
||||||
|
|
||||||
Game::Game(int argc, char* argv[])
|
Game::Game(int argc, char* argv[])
|
||||||
{
|
{
|
||||||
@@ -127,6 +130,8 @@ Game::Game(int argc, char* argv[])
|
|||||||
m_SystemPipeline->AddSystem<PickupSpawnSystem>(updateOrderLevel);
|
m_SystemPipeline->AddSystem<PickupSpawnSystem>(updateOrderLevel);
|
||||||
m_SystemPipeline->AddSystem<AmmoPickupSystem>(updateOrderLevel);
|
m_SystemPipeline->AddSystem<AmmoPickupSystem>(updateOrderLevel);
|
||||||
m_SystemPipeline->AddSystem<DamageIndicatorSystem>(updateOrderLevel);
|
m_SystemPipeline->AddSystem<DamageIndicatorSystem>(updateOrderLevel);
|
||||||
|
m_SystemPipeline->AddSystem<AmmunitionHUDSystem>(updateOrderLevel);
|
||||||
|
m_SystemPipeline->AddSystem<KillFeedSystem>(updateOrderLevel);
|
||||||
// Populate Octree with collidables
|
// Populate Octree with collidables
|
||||||
++updateOrderLevel;
|
++updateOrderLevel;
|
||||||
m_SystemPipeline->AddSystem<FillOctreeSystem>(updateOrderLevel, m_OctreeCollision, "Collidable");
|
m_SystemPipeline->AddSystem<FillOctreeSystem>(updateOrderLevel, m_OctreeCollision, "Collidable");
|
||||||
@@ -134,8 +139,8 @@ Game::Game(int argc, char* argv[])
|
|||||||
m_SystemPipeline->AddSystem<FillFrustumOctreeSystem>(updateOrderLevel, m_OctreeFrustrumCulling);
|
m_SystemPipeline->AddSystem<FillFrustumOctreeSystem>(updateOrderLevel, m_OctreeFrustrumCulling);
|
||||||
m_SystemPipeline->AddSystem<AnimationSystem>(updateOrderLevel);
|
m_SystemPipeline->AddSystem<AnimationSystem>(updateOrderLevel);
|
||||||
m_SystemPipeline->AddSystem<UniformScaleSystem>(updateOrderLevel);
|
m_SystemPipeline->AddSystem<UniformScaleSystem>(updateOrderLevel);
|
||||||
|
m_SystemPipeline->AddSystem<HealthHUDSystem>(updateOrderLevel);
|
||||||
m_SystemPipeline->AddSystem<PlayerDeathSystem>(updateOrderLevel);
|
m_SystemPipeline->AddSystem<PlayerDeathSystem>(updateOrderLevel);
|
||||||
m_SystemPipeline->AddSystem<PlayerHUDSystem>(updateOrderLevel);
|
|
||||||
// Collision and TriggerSystem should update after player.
|
// Collision and TriggerSystem should update after player.
|
||||||
++updateOrderLevel;
|
++updateOrderLevel;
|
||||||
m_SystemPipeline->AddSystem<BoneAttachmentSystem>(updateOrderLevel);
|
m_SystemPipeline->AddSystem<BoneAttachmentSystem>(updateOrderLevel);
|
||||||
|
|||||||
@@ -0,0 +1,110 @@
|
|||||||
|
/*
|
||||||
|
Author: Vladimir Sedach.
|
||||||
|
|
||||||
|
Purpose: demo of Call Stack creation by our own means,
|
||||||
|
and with MiniDumpWriteDump() function of DbgHelp.dll.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
#include <ctime>
|
||||||
|
|
||||||
|
#include <windows.h>
|
||||||
|
#include <tlhelp32.h>
|
||||||
|
//#include "dbghelp.h"
|
||||||
|
|
||||||
|
//#define DEBUG_DPRINTF 1 //allow d()
|
||||||
|
//#include "wfun.h"
|
||||||
|
|
||||||
|
#pragma optimize("y", off) //generate stack frame pointers for all functions - same as /Oy- in the project
|
||||||
|
#pragma warning(disable: 4200) //nonstandard extension used : zero-sized array in struct/union
|
||||||
|
#pragma warning(disable: 4100) //unreferenced formal parameter
|
||||||
|
|
||||||
|
// In case you don't have dbghelp.h.
|
||||||
|
#ifndef _DBGHELP_
|
||||||
|
|
||||||
|
typedef struct _MINIDUMP_EXCEPTION_INFORMATION {
|
||||||
|
DWORD ThreadId;
|
||||||
|
PEXCEPTION_POINTERS ExceptionPointers;
|
||||||
|
BOOL ClientPointers;
|
||||||
|
} MINIDUMP_EXCEPTION_INFORMATION, *PMINIDUMP_EXCEPTION_INFORMATION;
|
||||||
|
|
||||||
|
typedef enum _MINIDUMP_TYPE {
|
||||||
|
MiniDumpNormal = 0x00000000,
|
||||||
|
MiniDumpWithDataSegs = 0x00000001,
|
||||||
|
} MINIDUMP_TYPE;
|
||||||
|
|
||||||
|
typedef BOOL (WINAPI * MINIDUMP_WRITE_DUMP)(
|
||||||
|
IN HANDLE hProcess,
|
||||||
|
IN DWORD ProcessId,
|
||||||
|
IN HANDLE hFile,
|
||||||
|
IN MINIDUMP_TYPE DumpType,
|
||||||
|
IN CONST PMINIDUMP_EXCEPTION_INFORMATION ExceptionParam, OPTIONAL
|
||||||
|
IN PVOID UserStreamParam, OPTIONAL
|
||||||
|
IN PVOID CallbackParam OPTIONAL
|
||||||
|
);
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
typedef BOOL (WINAPI * MINIDUMP_WRITE_DUMP)(
|
||||||
|
IN HANDLE hProcess,
|
||||||
|
IN DWORD ProcessId,
|
||||||
|
IN HANDLE hFile,
|
||||||
|
IN MINIDUMP_TYPE DumpType,
|
||||||
|
IN CONST PMINIDUMP_EXCEPTION_INFORMATION ExceptionParam, OPTIONAL
|
||||||
|
IN PMINIDUMP_USER_STREAM_INFORMATION UserStreamParam, OPTIONAL
|
||||||
|
IN PMINIDUMP_CALLBACK_INFORMATION CallbackParam OPTIONAL
|
||||||
|
);
|
||||||
|
#endif //#ifndef _DBGHELP_
|
||||||
|
|
||||||
|
HMODULE hDbgHelp;
|
||||||
|
MINIDUMP_WRITE_DUMP MiniDumpWriteDump_;
|
||||||
|
|
||||||
|
// Tool Help functions.
|
||||||
|
typedef HANDLE (WINAPI * CREATE_TOOL_HELP32_SNAPSHOT)(DWORD dwFlags, DWORD th32ProcessID);
|
||||||
|
|
||||||
|
//*************************************************************************************
|
||||||
|
void WINAPI Create_Dump(PEXCEPTION_POINTERS pException, BOOL File_Flag, BOOL Show_Flag)
|
||||||
|
//*************************************************************************************
|
||||||
|
// Create dump.
|
||||||
|
// pException can be either GetExceptionInformation() or NULL.
|
||||||
|
// If File_Flag = TRUE - write dump files (.dmz and .dmp) with the name of the current process.
|
||||||
|
// If Show_Flag = TRUE - show message with Get_Exception_Info() dump.
|
||||||
|
{
|
||||||
|
// Try to get MiniDumpWriteDump() address.
|
||||||
|
hDbgHelp = LoadLibrary("DBGHELP.DLL");
|
||||||
|
MiniDumpWriteDump_ = (MINIDUMP_WRITE_DUMP)GetProcAddress(hDbgHelp, "MiniDumpWriteDump");
|
||||||
|
|
||||||
|
// If MiniDumpWriteDump() of DbgHelp.dll available.
|
||||||
|
if (MiniDumpWriteDump_)
|
||||||
|
{
|
||||||
|
HANDLE hDump_File;
|
||||||
|
CHAR Dump_Path[MAX_PATH];
|
||||||
|
|
||||||
|
GetModuleFileName(NULL, Dump_Path, sizeof(Dump_Path)); //path of current process
|
||||||
|
std::time_t t = std::time(NULL);
|
||||||
|
char tStr[16];
|
||||||
|
std::strftime(tStr, 32, " %a %H-%M-%S", std::localtime(&t));
|
||||||
|
std::string time(tStr);
|
||||||
|
std::string path(Dump_Path);
|
||||||
|
path = path.substr(0, path.length() - 4);
|
||||||
|
path += time + ".dmp";
|
||||||
|
|
||||||
|
MINIDUMP_EXCEPTION_INFORMATION M;
|
||||||
|
M.ThreadId = GetCurrentThreadId();
|
||||||
|
M.ExceptionPointers = pException;
|
||||||
|
M.ClientPointers = 0;
|
||||||
|
|
||||||
|
hDump_File = CreateFile(path.c_str(), GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
|
||||||
|
|
||||||
|
MiniDumpWriteDump_(GetCurrentProcess(), GetCurrentProcessId(), hDump_File,
|
||||||
|
MiniDumpNormal, (pException) ? &M : NULL, NULL, NULL);
|
||||||
|
|
||||||
|
CloseHandle(hDump_File);
|
||||||
|
|
||||||
|
std::cout << "Memory dumped to: \"" << path.c_str() << "\"";
|
||||||
|
MessageBox(NULL, ("Application crashed, memory dumped to: " + path).c_str(), "MiniDump", MB_ICONHAND | MB_OK);
|
||||||
|
} else {
|
||||||
|
MessageBox(NULL, "Application crashed, memory dump failed.", "MiniDump", MB_ICONHAND | MB_OK);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@@ -9,7 +9,15 @@ MultiplayerSnapshotFilter::MultiplayerSnapshotFilter(EventBroker* eventBroker)
|
|||||||
bool MultiplayerSnapshotFilter::FilterComponent(EntityWrapper entity, SharedComponentWrapper& component)
|
bool MultiplayerSnapshotFilter::FilterComponent(EntityWrapper entity, SharedComponentWrapper& component)
|
||||||
{
|
{
|
||||||
if (entity == m_LocalPlayer || entity.IsChildOf(m_LocalPlayer)) {
|
if (entity == m_LocalPlayer || entity.IsChildOf(m_LocalPlayer)) {
|
||||||
return false;
|
if (
|
||||||
|
component.Info.Name == "Transform"
|
||||||
|
|| component.Info.Name == "Physics"
|
||||||
|
|| component.Info.Name == "AssaultWeapon"
|
||||||
|
|| component.Info.Name == "Animation"
|
||||||
|
|| component.Info.Name == "AnimationOffset"
|
||||||
|
) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (component.Info.Name == "Physics") {
|
if (component.Info.Name == "Physics") {
|
||||||
|
|||||||
@@ -0,0 +1,36 @@
|
|||||||
|
#include "Game/Systems/AmmunitionHUDSystem.h"
|
||||||
|
|
||||||
|
void AmmunitionHUDSystem::Update(double dt)
|
||||||
|
{
|
||||||
|
//Hud element for tracking ammunition from parent with AssaultWeapon component.Child with the name "MagazineAmmo" tracks clip ammunition.Child with the name "Ammo" tracks ammo.</xs:documentation>
|
||||||
|
|
||||||
|
auto ammunitionHUDs = m_World->GetComponents("AmmunitionHUD");
|
||||||
|
if (ammunitionHUDs == nullptr) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (auto& ammunitionHUDComponent : *ammunitionHUDs) {
|
||||||
|
EntityWrapper entity = EntityWrapper(m_World, ammunitionHUDComponent.EntityID);
|
||||||
|
|
||||||
|
EntityWrapper playerEntity = entity.FirstParentWithComponent("AssaultWeapon");
|
||||||
|
|
||||||
|
if (!playerEntity.Valid()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
EntityWrapper magazineAmmo = entity.FirstChildByName("MagazineAmmo");
|
||||||
|
if(magazineAmmo.Valid()) {
|
||||||
|
if(magazineAmmo.HasComponent("Text")) {
|
||||||
|
(std::string&)magazineAmmo["Text"]["Content"] = std::to_string((int)playerEntity["AssaultWeapon"]["MagazineAmmo"]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
EntityWrapper ammo = entity.FirstChildByName("Ammo");
|
||||||
|
if (ammo.Valid()) {
|
||||||
|
if (ammo.HasComponent("Text")) {
|
||||||
|
(std::string&)ammo["Text"]["Content"] = std::to_string((int)playerEntity["AssaultWeapon"]["Ammo"]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -20,6 +20,10 @@ void CapturePointHUDSystem::Update(double dt)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(!CapturePointHUDElements) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
for (auto& cCapturePointHUD : *CapturePointHUDElements) {
|
for (auto& cCapturePointHUD : *CapturePointHUDElements) {
|
||||||
int HUD_ID = cCapturePointHUD["CapturePointNumber"];
|
int HUD_ID = cCapturePointHUD["CapturePointNumber"];
|
||||||
EntityWrapper entityHUD = EntityWrapper(m_World, cCapturePointHUD.EntityID);
|
EntityWrapper entityHUD = EntityWrapper(m_World, cCapturePointHUD.EntityID);
|
||||||
@@ -39,14 +43,14 @@ void CapturePointHUDSystem::Update(double dt)
|
|||||||
}
|
}
|
||||||
//Color hud with team color
|
//Color hud with team color
|
||||||
auto capturePointTeam = (int)teamComponent["Team"];
|
auto capturePointTeam = (int)teamComponent["Team"];
|
||||||
entityHUDparent["Sprite"]["Color"] = capturePointTeam == blueTeam ? glm::vec4(0, 0.2f, 1, 0.7) : capturePointTeam == redTeam ? glm::vec4(1, 0.2f, 0, 0.7) : glm::vec4(1, 1, 1, 0.3);
|
entityHUDparent["Sprite"]["Color"] = capturePointTeam == blueTeam ? glm::vec4(0, 0.2f, 1, 0.7f) : capturePointTeam == redTeam ? glm::vec4(1, 0.0f, 0, 0.7f) : glm::vec4(1, 1, 1, 0.3f);
|
||||||
|
|
||||||
//Progress is scaled with time
|
//Progress is scaled with time
|
||||||
double currentCaptureTime = (double)entityCP["CapturePoint"]["CaptureTimer"];
|
double currentCaptureTime = (double)entityCP["CapturePoint"]["CaptureTimer"];
|
||||||
double progress = glm::abs(currentCaptureTime)/15.0;
|
double progress = glm::abs(currentCaptureTime)/15.0;
|
||||||
int currentCapturingTeam = currentCaptureTime > 0 ? redTeam : currentCaptureTime < 0 ? blueTeam : spectatorTeam;
|
int currentCapturingTeam = currentCaptureTime > 0 ? redTeam : currentCaptureTime < 0 ? blueTeam : spectatorTeam;
|
||||||
((glm::vec3&)entityHUD["Transform"]["Orientation"]).z = currentCapturingTeam == redTeam ? glm::half_pi<float>()+glm::pi<float>() : glm::half_pi<float>();
|
((glm::vec3&)entityHUD["Transform"]["Orientation"]).z = currentCapturingTeam == redTeam ? glm::half_pi<float>()+glm::pi<float>() : glm::half_pi<float>();
|
||||||
glm::vec4 fillColor = currentCapturingTeam == redTeam ? glm::vec4(1, 0.2f, 0, 0.7) : glm::vec4(0, 0.2f, 1, 0.7);
|
glm::vec4 fillColor = currentCapturingTeam == redTeam ? glm::vec4(1, 0.f, 0, 0.7f) : glm::vec4(0, 0.2f, 1, 0.7f);
|
||||||
entityHUD["Fill"]["Color"] = fillColor;
|
entityHUD["Fill"]["Color"] = fillColor;
|
||||||
entityHUD["Fill"]["Percentage"] = progress;
|
entityHUD["Fill"]["Percentage"] = progress;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,15 +6,21 @@ CapturePointSystem::CapturePointSystem(SystemParams params)
|
|||||||
, PureSystem("CapturePoint")
|
, PureSystem("CapturePoint")
|
||||||
{
|
{
|
||||||
//subscribe/listenTo playerdamage,healthpickup events (using the eventBroker)
|
//subscribe/listenTo playerdamage,healthpickup events (using the eventBroker)
|
||||||
EVENT_SUBSCRIBE_MEMBER(m_ETriggerTouch, &CapturePointSystem::OnTriggerTouch);
|
if (IsClient) {
|
||||||
EVENT_SUBSCRIBE_MEMBER(m_ETriggerLeave, &CapturePointSystem::OnTriggerLeave);
|
EVENT_SUBSCRIBE_MEMBER(m_ETriggerTouch, &CapturePointSystem::OnTriggerTouch);
|
||||||
EVENT_SUBSCRIBE_MEMBER(m_ECaptured, &CapturePointSystem::OnCaptured);
|
EVENT_SUBSCRIBE_MEMBER(m_ETriggerLeave, &CapturePointSystem::OnTriggerLeave);
|
||||||
|
EVENT_SUBSCRIBE_MEMBER(m_ECaptured, &CapturePointSystem::OnCaptured);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//here all capturepoints will update their component
|
//here all capturepoints will update their component
|
||||||
//NOTE: needs to run each frame, since we're possibly modifying the captureTimer for the capturePoints by dt
|
//NOTE: needs to run each frame, since we're possibly modifying the captureTimer for the capturePoints by dt
|
||||||
void CapturePointSystem::UpdateComponent(EntityWrapper& capturePointEntity, ComponentWrapper& cCapturePoint, double dt)
|
void CapturePointSystem::UpdateComponent(EntityWrapper& capturePointEntity, ComponentWrapper& cCapturePoint, double dt)
|
||||||
{
|
{
|
||||||
|
if (!IsClient) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (m_WinnerWasFound) {
|
if (m_WinnerWasFound) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,12 +18,15 @@ bool DamageIndicatorSystem::OnPlayerDamage(Events::PlayerDamage& e)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (e.Victim != LocalPlayer) {
|
//if (e.Victim != LocalPlayer) {
|
||||||
|
// return false;
|
||||||
|
//}
|
||||||
|
if (e.Victim != LocalPlayer && !e.Victim.IsChildOf(LocalPlayer)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!e.Inflictor.Valid() || !e.Victim.Valid()) {
|
if (!e.Inflictor.Valid() || !e.Victim.Valid()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
//grab players direction
|
//grab players direction
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
#include "Game/Systems/PlayerHUDSystem.h"
|
#include "Game/Systems/HealthHUDSystem.h"
|
||||||
|
|
||||||
void PlayerHUDSystem::Update(double dt)
|
void HealthHUDSystem::Update(double dt)
|
||||||
{
|
{
|
||||||
auto healthHUDs = m_World->GetComponents("HealthHUD");
|
auto healthHUDs = m_World->GetComponents("HealthHUD");
|
||||||
if (healthHUDs == nullptr) {
|
if (healthHUDs == nullptr) {
|
||||||
@@ -27,13 +27,13 @@ void PlayerHUDSystem::Update(double dt)
|
|||||||
s = s + "/";
|
s = s + "/";
|
||||||
s = s + std::to_string((int)(double)entityIDParent["Health"]["MaxHealth"]);
|
s = s + std::to_string((int)(double)entityIDParent["Health"]["MaxHealth"]);
|
||||||
float healthPercentage = (double)entityIDParent["Health"]["Health"]/(double)entityIDParent["Health"]["MaxHealth"];
|
float healthPercentage = (double)entityIDParent["Health"]["Health"]/(double)entityIDParent["Health"]["MaxHealth"];
|
||||||
(glm::vec4&)entity["Text"]["Color"] = glm::vec4(1.0 - healthPercentage, 0.f, healthPercentage, 1.f);
|
//(glm::vec4&)entity["Text"]["Color"] = glm::vec4(1.0 - healthPercentage, 0.f, healthPercentage, glm::vec4(entity["Text"]["Color"]).a);
|
||||||
entity["Text"]["Content"] = s;
|
entity["Text"]["Content"] = s;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(entity.HasComponent("Fill")) {
|
if(entity.HasComponent("Fill")) {
|
||||||
float healthPercentage = (double)entityIDParent["Health"]["Health"]/(double)entityIDParent["Health"]["MaxHealth"];
|
float healthPercentage = (double)entityIDParent["Health"]["Health"]/(double)entityIDParent["Health"]["MaxHealth"];
|
||||||
(glm::vec4&)entity["Fill"]["Color"] = glm::vec4(1.0 - healthPercentage, 0.f, healthPercentage, 0.f);
|
(glm::vec4&)entity["Fill"]["Color"] = glm::vec4(1.0 - healthPercentage, 0.f, healthPercentage, glm::vec4(entity["Fill"]["Color"]).a);
|
||||||
(double&)entity["Fill"]["Percentage"] = healthPercentage;
|
(double&)entity["Fill"]["Percentage"] = healthPercentage;
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -8,25 +8,30 @@ HealthSystem::HealthSystem(SystemParams params)
|
|||||||
EVENT_SUBSCRIBE_MEMBER(m_EPlayerDamage, &HealthSystem::OnPlayerDamaged);
|
EVENT_SUBSCRIBE_MEMBER(m_EPlayerDamage, &HealthSystem::OnPlayerDamaged);
|
||||||
EVENT_SUBSCRIBE_MEMBER(m_EPlayerHealthPickup, &HealthSystem::OnPlayerHealthPickup);
|
EVENT_SUBSCRIBE_MEMBER(m_EPlayerHealthPickup, &HealthSystem::OnPlayerHealthPickup);
|
||||||
EVENT_SUBSCRIBE_MEMBER(m_InputCommand, &HealthSystem::OnInputCommand);
|
EVENT_SUBSCRIBE_MEMBER(m_InputCommand, &HealthSystem::OnInputCommand);
|
||||||
|
m_NetworkEnabled = ResourceManager::Load<ConfigFile>("Config.ini")->Get("Networking.StartNetwork", false);
|
||||||
}
|
}
|
||||||
|
|
||||||
void HealthSystem::UpdateComponent(EntityWrapper& entity, ComponentWrapper& component, double dt)
|
void HealthSystem::UpdateComponent(EntityWrapper& entity, ComponentWrapper& cHealth, double dt)
|
||||||
{
|
{
|
||||||
|
double& health = cHealth["Health"];
|
||||||
|
if (health <= 0.0) {
|
||||||
|
Events::PlayerDeath ePlayerDeath;
|
||||||
|
ePlayerDeath.Player = entity;
|
||||||
|
m_EventBroker->Publish(ePlayerDeath);
|
||||||
|
//Note: we will delete the entity in PlayerDeathSystem
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool HealthSystem::OnPlayerDamaged(Events::PlayerDamage& e)
|
bool HealthSystem::OnPlayerDamaged(Events::PlayerDamage& e)
|
||||||
{
|
{
|
||||||
|
if (!IsServer && m_NetworkEnabled) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
ComponentWrapper cHealth = e.Victim["Health"];
|
ComponentWrapper cHealth = e.Victim["Health"];
|
||||||
double& health = cHealth["Health"];
|
double& health = cHealth["Health"];
|
||||||
health -= e.Damage;
|
health -= e.Damage;
|
||||||
|
|
||||||
if (health <= 0.0) {
|
|
||||||
Events::PlayerDeath ePlayerDeath;
|
|
||||||
ePlayerDeath.Player = e.Victim;
|
|
||||||
m_EventBroker->Publish(ePlayerDeath);
|
|
||||||
//Note: we will delete the entity in PlayerDeathSystem
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,80 @@
|
|||||||
|
#include "Game/Systems/KillFeedSystem.h"
|
||||||
|
|
||||||
|
void KillFeedSystem::Update(double dt)
|
||||||
|
{
|
||||||
|
auto killFeeds = m_World->GetComponents("KillFeed");
|
||||||
|
if (killFeeds == nullptr) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (auto& killFeedComponent : *killFeeds) {
|
||||||
|
EntityWrapper entity = EntityWrapper(m_World, killFeedComponent.EntityID);
|
||||||
|
|
||||||
|
for (int i = 1; i <= 3; i++) {
|
||||||
|
EntityWrapper child = entity.FirstChildByName("KillFeed" + std::to_string(i));
|
||||||
|
if (child.HasComponent("Text")) {
|
||||||
|
(std::string&)child["Text"]["Content"] = "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
int feedIndex = 1;
|
||||||
|
for (auto it = m_DeathQueue.begin(); it != m_DeathQueue.end(); ) {
|
||||||
|
bool remove = false;
|
||||||
|
|
||||||
|
EntityWrapper child = entity.FirstChildByName("KillFeed" + std::to_string(feedIndex));
|
||||||
|
|
||||||
|
if (child.HasComponent("Text")) {
|
||||||
|
(std::string&)child["Text"]["Content"] = (*it).Content;
|
||||||
|
(glm::vec4&)child["Text"]["Color"] = (*it).Color;
|
||||||
|
|
||||||
|
(*it).TimeToLive -= dt;
|
||||||
|
|
||||||
|
if ((*it).TimeToLive <= 0.f) {
|
||||||
|
(std::string&)child["Text"]["Content"] = "";
|
||||||
|
(glm::vec4&)child["Text"]["Color"] = (*it).Color;
|
||||||
|
remove = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
feedIndex++;
|
||||||
|
if(feedIndex > 3) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(remove) {
|
||||||
|
it = m_DeathQueue.erase(it);
|
||||||
|
} else {
|
||||||
|
it++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool KillFeedSystem::OnPlayerDeath(Events::PlayerDeath& e)
|
||||||
|
{
|
||||||
|
KillFeedInfo kfInfo;
|
||||||
|
|
||||||
|
if (e.Player.HasComponent("Team")) {
|
||||||
|
int red = e.Player["Team"].Enum("Team", "Red");
|
||||||
|
int blue = e.Player["Team"].Enum("Team", "Blue");
|
||||||
|
|
||||||
|
if ((int)e.Player["Team"]["Team"] == red) {
|
||||||
|
kfInfo.Content = "Blue Player killed Red Player";
|
||||||
|
kfInfo.Color = glm::vec4(0.f, 0.2f, 1.f, 0.8f);
|
||||||
|
m_DeathQueue.push_back(kfInfo);
|
||||||
|
} else if ((int)e.Player["Team"]["Team"] == blue) {
|
||||||
|
kfInfo.Content = "Red Player killed blue Player";
|
||||||
|
kfInfo.Color = glm::vec4(1.f, 0.f, 0.f, 0.8f);
|
||||||
|
m_DeathQueue.push_back(kfInfo);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if(m_DeathQueue.size() > 3) {
|
||||||
|
m_DeathQueue.pop_front();
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
@@ -40,7 +40,8 @@ void PlayerMovementSystem::updateMovementControllers(double dt)
|
|||||||
EntityWrapper playerModel = player.FirstChildByName("PlayerModel");
|
EntityWrapper playerModel = player.FirstChildByName("PlayerModel");
|
||||||
if (playerModel.Valid()) {
|
if (playerModel.Valid()) {
|
||||||
ComponentWrapper cAnimationOffset = playerModel["AnimationOffset"];
|
ComponentWrapper cAnimationOffset = playerModel["AnimationOffset"];
|
||||||
double time = (cameraOrientation.x + glm::half_pi<float>()) / glm::pi<float>();
|
float pitch = cameraOrientation.x + 0.2;
|
||||||
|
double time = (pitch + glm::half_pi<float>()) / glm::pi<float>();
|
||||||
cAnimationOffset["Time"] = time;
|
cAnimationOffset["Time"] = time;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -113,15 +114,17 @@ void PlayerMovementSystem::updateMovementControllers(double dt)
|
|||||||
if (isOnGround) {
|
if (isOnGround) {
|
||||||
controller->SetDoubleJumping(false);
|
controller->SetDoubleJumping(false);
|
||||||
} else {
|
} else {
|
||||||
//put a hexagon at the players feet
|
if (IsClient) {
|
||||||
auto hexagonEffect = ResourceManager::Load<EntityFile>("Schema/Entities/DoubleJumpHexagon.xml");
|
//put a hexagon at the players feet
|
||||||
EntityFileParser parser(hexagonEffect);
|
auto hexagonEffect = ResourceManager::Load<EntityFile>("Schema/Entities/DoubleJumpHexagon.xml");
|
||||||
EntityID hexagonEffectID = parser.MergeEntities(m_World);
|
EntityFileParser parser(hexagonEffect);
|
||||||
EntityWrapper hexagonEW = EntityWrapper(m_World, hexagonEffectID);
|
EntityID hexagonEffectID = parser.MergeEntities(m_World);
|
||||||
hexagonEW["Transform"]["Position"] = (glm::vec3)player["Transform"]["Position"];
|
EntityWrapper hexagonEW = EntityWrapper(m_World, hexagonEffectID);
|
||||||
controller->SetDoubleJumping(true);
|
hexagonEW["Transform"]["Position"] = (glm::vec3)player["Transform"]["Position"];
|
||||||
Events::DoubleJump e;
|
controller->SetDoubleJumping(true);
|
||||||
m_EventBroker->Publish(e);
|
Events::DoubleJump e;
|
||||||
|
m_EventBroker->Publish(e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
velocity.y = 4.f;
|
velocity.y = 4.f;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -126,11 +126,12 @@ bool PlayerSpawnSystem::OnPlayerSpawned(Events::PlayerSpawned& e)
|
|||||||
m_PlayerIDs[e.Player.ID] = e.PlayerID;
|
m_PlayerIDs[e.Player.ID] = e.PlayerID;
|
||||||
|
|
||||||
// When a player is actually spawned (since the actual spawning is handled on the server)
|
// When a player is actually spawned (since the actual spawning is handled on the server)
|
||||||
|
// Hack should be moved.
|
||||||
|
|
||||||
if (!IsClient) {
|
if (!IsClient) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Set the camera to the correct entity
|
// Set the camera to the correct entity
|
||||||
EntityWrapper cameraEntity = e.Player.FirstChildByName("Camera");
|
EntityWrapper cameraEntity = e.Player.FirstChildByName("Camera");
|
||||||
bool outOfBodyExperience = ResourceManager::Load<ConfigFile>("Config.ini")->Get<bool>("Debug.OutOfBodyExperience", false);
|
bool outOfBodyExperience = ResourceManager::Load<ConfigFile>("Config.ini")->Get<bool>("Debug.OutOfBodyExperience", false);
|
||||||
@@ -175,8 +176,15 @@ bool PlayerSpawnSystem::OnPlayerDeath(Events::PlayerDeath& e)
|
|||||||
if ((ComponentInfo::EnumType)cTeam["Team"] == cTeam["Team"].Enum("Spectator")) {
|
if ((ComponentInfo::EnumType)cTeam["Team"] == cTeam["Team"].Enum("Spectator")) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
SpawnRequest req;
|
|
||||||
req.PlayerID = m_PlayerIDs.at(e.Player.ID);
|
if (m_PlayerIDs.count(e.Player.ID) == 0) {
|
||||||
req.Team = cTeam["Team"];
|
return false;
|
||||||
m_SpawnRequests.push_back(req);
|
}
|
||||||
|
|
||||||
|
SpawnRequest req;
|
||||||
|
req.PlayerID = m_PlayerIDs.at(e.Player.ID);
|
||||||
|
req.Team = cTeam["Team"];
|
||||||
|
m_SpawnRequests.push_back(req);
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,13 +6,15 @@ SoundSystem::SoundSystem(SystemParams params)
|
|||||||
{
|
{
|
||||||
ConfigFile* config = ResourceManager::Load<ConfigFile>("Config.ini");
|
ConfigFile* config = ResourceManager::Load<ConfigFile>("Config.ini");
|
||||||
m_Announcer = ResourceManager::Load<ConfigFile>("Config.ini")->Get<std::string>("Sound.Announcer", "female");
|
m_Announcer = ResourceManager::Load<ConfigFile>("Config.ini")->Get<std::string>("Sound.Announcer", "female");
|
||||||
EVENT_SUBSCRIBE_MEMBER(m_EPlayerSpawned, &SoundSystem::OnPlayerSpawned);
|
if (IsClient) {
|
||||||
EVENT_SUBSCRIBE_MEMBER(m_InputCommand, &SoundSystem::OnInputCommand);
|
EVENT_SUBSCRIBE_MEMBER(m_EPlayerSpawned, &SoundSystem::OnPlayerSpawned);
|
||||||
EVENT_SUBSCRIBE_MEMBER(m_EDoubleJump, &SoundSystem::OnDoubleJump);
|
EVENT_SUBSCRIBE_MEMBER(m_InputCommand, &SoundSystem::OnInputCommand);
|
||||||
EVENT_SUBSCRIBE_MEMBER(m_EDashAbility, &SoundSystem::OnDashAbility);
|
EVENT_SUBSCRIBE_MEMBER(m_EDoubleJump, &SoundSystem::OnDoubleJump);
|
||||||
EVENT_SUBSCRIBE_MEMBER(m_EPlayerDamage, &SoundSystem::OnPlayerDamage);
|
EVENT_SUBSCRIBE_MEMBER(m_EDashAbility, &SoundSystem::OnDashAbility);
|
||||||
EVENT_SUBSCRIBE_MEMBER(m_ECaptured, &SoundSystem::OnCaptured);
|
EVENT_SUBSCRIBE_MEMBER(m_EPlayerDamage, &SoundSystem::OnPlayerDamage);
|
||||||
EVENT_SUBSCRIBE_MEMBER(m_ETriggerTouch, &SoundSystem::OnTriggerTouch);
|
EVENT_SUBSCRIBE_MEMBER(m_ECaptured, &SoundSystem::OnCaptured);
|
||||||
|
EVENT_SUBSCRIBE_MEMBER(m_ETriggerTouch, &SoundSystem::OnTriggerTouch);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SoundSystem::UpdateComponent(EntityWrapper& entity, ComponentWrapper& cComponent, double dt)
|
void SoundSystem::UpdateComponent(EntityWrapper& entity, ComponentWrapper& cComponent, double dt)
|
||||||
@@ -20,6 +22,10 @@ void SoundSystem::UpdateComponent(EntityWrapper& entity, ComponentWrapper& cComp
|
|||||||
|
|
||||||
void SoundSystem::Update(double dt)
|
void SoundSystem::Update(double dt)
|
||||||
{
|
{
|
||||||
|
if (!IsClient) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Temp for play test.
|
// Temp for play test.
|
||||||
if (m_DrumsIsPlaying) {
|
if (m_DrumsIsPlaying) {
|
||||||
m_DrumsIsPlaying = !drumTimer(dt);
|
m_DrumsIsPlaying = !drumTimer(dt);
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ AssaultWeaponBehaviour::AssaultWeaponBehaviour(SystemParams systemParams, IRende
|
|||||||
: WeaponBehaviour(systemParams, renderer, collisionOctree, player)
|
: WeaponBehaviour(systemParams, renderer, collisionOctree, player)
|
||||||
{
|
{
|
||||||
m_FirstPersonModel = m_Player.FirstChildByName("Hands");
|
m_FirstPersonModel = m_Player.FirstChildByName("Hands");
|
||||||
|
m_ThirdPersonModel = m_Player.FirstChildByName("PlayerModel");
|
||||||
EVENT_SUBSCRIBE_MEMBER(m_EAnimationComplete, &AssaultWeaponBehaviour::OnAnimationComplete);
|
EVENT_SUBSCRIBE_MEMBER(m_EAnimationComplete, &AssaultWeaponBehaviour::OnAnimationComplete);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -37,12 +38,18 @@ void AssaultWeaponBehaviour::Reload()
|
|||||||
|
|
||||||
// Don't reload if we're completly out of ammo
|
// Don't reload if we're completly out of ammo
|
||||||
if (ammo == 0) {
|
if (ammo == 0) {
|
||||||
|
playEmptySound();
|
||||||
|
m_TimeSinceLastFire = -0.0f; // HACK: To make empty sound play with interval
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_Reloading = true;
|
m_Reloading = true;
|
||||||
m_ReloadTimer = cAssaultWeapon["ReloadTime"];
|
m_ReloadTimer = cAssaultWeapon["ReloadTime"];
|
||||||
playReloadAnimation();
|
playReloadAnimation();
|
||||||
|
Events::PlaySoundOnEntity e;
|
||||||
|
e.EmitterID = cAssaultWeapon.EntityID;
|
||||||
|
e.FilePath = "Audio/weapon/reload.wav";
|
||||||
|
m_EventBroker->Publish(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AssaultWeaponBehaviour::Update(double dt)
|
void AssaultWeaponBehaviour::Update(double dt)
|
||||||
@@ -50,9 +57,14 @@ void AssaultWeaponBehaviour::Update(double dt)
|
|||||||
if (m_Reloading) {
|
if (m_Reloading) {
|
||||||
m_ReloadTimer -= dt;
|
m_ReloadTimer -= dt;
|
||||||
// Re-enable glow on reload impersonator half-way through the animation
|
// Re-enable glow on reload impersonator half-way through the animation
|
||||||
if (m_ReloadTimer <= (double)m_Player["AssaultWeapon"]["ReloadTime"] / 2.0) {
|
if (IsClient) {
|
||||||
if (m_ReloadImpersonator.Valid()) {
|
if (m_ReloadTimer <= (double)m_Player["AssaultWeapon"]["ReloadTime"] / 2.0) {
|
||||||
m_ReloadImpersonator["Model"]["GlowMap"] = true;
|
if (m_FirstPersonReloadImpersonator.Valid()) {
|
||||||
|
m_FirstPersonReloadImpersonator["Model"]["GlowMap"] = true;
|
||||||
|
}
|
||||||
|
if (m_ThirdPersonReloadImpersonator.Valid()) {
|
||||||
|
m_ThirdPersonReloadImpersonator["Model"]["GlowMap"] = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (m_ReloadTimer <= 0) {
|
if (m_ReloadTimer <= 0) {
|
||||||
@@ -69,14 +81,18 @@ void AssaultWeaponBehaviour::Update(double dt)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!m_Firing && !m_Reloading) {
|
if (!m_Firing && !m_Reloading) {
|
||||||
playIdleAnimation();
|
if (IsClient) {
|
||||||
|
playIdleAnimation();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Disable glow map on weapon if it's out of ammo
|
// Disable glow map on weapon if it's out of ammo
|
||||||
// Make real first person weapon model visible again
|
// Make real first person weapon model visible again
|
||||||
EntityWrapper firstPersonWeaponModel = m_Player.FirstChildByName("WeaponModel");
|
if (IsClient) {
|
||||||
if (firstPersonWeaponModel.Valid()) {
|
EntityWrapper firstPersonWeaponModel = m_Player.FirstChildByName("WeaponModel");
|
||||||
firstPersonWeaponModel["Model"]["GlowMap"] = hasAmmo();
|
if (firstPersonWeaponModel.Valid()) {
|
||||||
|
firstPersonWeaponModel["Model"]["GlowMap"] = hasAmmo();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -117,20 +133,23 @@ void AssaultWeaponBehaviour::fireRound()
|
|||||||
if (magAmmo <= 0) {
|
if (magAmmo <= 0) {
|
||||||
Reload();
|
Reload();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fire
|
// Fire
|
||||||
magAmmo -= 1;
|
magAmmo -= 1;
|
||||||
spawnTracer();
|
|
||||||
playSound();
|
|
||||||
viewPunch();
|
|
||||||
playShootAnimation();
|
|
||||||
bool hit = shoot(cAssaultWeapon["BaseDamage"]);
|
|
||||||
if (hit) {
|
|
||||||
showHitMarker();
|
|
||||||
}
|
|
||||||
|
|
||||||
m_TimeSinceLastFire = 0.0;
|
m_TimeSinceLastFire = 0.0;
|
||||||
|
|
||||||
|
// Effects
|
||||||
|
if (IsClient) {
|
||||||
|
spawnTracer();
|
||||||
|
playFireSound();
|
||||||
|
viewPunch();
|
||||||
|
playShootAnimation();
|
||||||
|
bool hit = shoot(cAssaultWeapon["BaseDamage"]);
|
||||||
|
if (hit) {
|
||||||
|
showHitMarker();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void AssaultWeaponBehaviour::spawnTracer()
|
void AssaultWeaponBehaviour::spawnTracer()
|
||||||
@@ -140,7 +159,8 @@ void AssaultWeaponBehaviour::spawnTracer()
|
|||||||
}
|
}
|
||||||
|
|
||||||
EntityWrapper spawner;
|
EntityWrapper spawner;
|
||||||
if (m_Player == LocalPlayer) {
|
bool outOfBodyExperience = ResourceManager::Load<ConfigFile>("Config.ini")->Get<bool>("Debug.OutOfBodyExperience", false);
|
||||||
|
if (m_Player == LocalPlayer && !outOfBodyExperience) {
|
||||||
spawner = m_Player.FirstChildByName("WeaponMuzzle");
|
spawner = m_Player.FirstChildByName("WeaponMuzzle");
|
||||||
} else {
|
} else {
|
||||||
spawner = m_Player.FirstChildByName("ThirdPersonWeaponMuzzle");
|
spawner = m_Player.FirstChildByName("ThirdPersonWeaponMuzzle");
|
||||||
@@ -168,7 +188,7 @@ float AssaultWeaponBehaviour::traceRayDistance(glm::vec3 origin, glm::vec3 direc
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void AssaultWeaponBehaviour::playSound()
|
void AssaultWeaponBehaviour::playFireSound()
|
||||||
{
|
{
|
||||||
if (!IsClient) {
|
if (!IsClient) {
|
||||||
return;
|
return;
|
||||||
@@ -180,6 +200,19 @@ void AssaultWeaponBehaviour::playSound()
|
|||||||
m_EventBroker->Publish(e);
|
m_EventBroker->Publish(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void AssaultWeaponBehaviour::playEmptySound()
|
||||||
|
{
|
||||||
|
if (!IsClient) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Events::PlaySoundOnEntity e;
|
||||||
|
e.EmitterID = m_Player.ID;
|
||||||
|
e.FilePath = "Audio/weapon/zeroAmmo.wav";
|
||||||
|
m_EventBroker->Publish(e);
|
||||||
|
}
|
||||||
|
|
||||||
void AssaultWeaponBehaviour::viewPunch()
|
void AssaultWeaponBehaviour::viewPunch()
|
||||||
{
|
{
|
||||||
EntityWrapper playerCamera = m_Player.FirstChildByName("Camera");
|
EntityWrapper playerCamera = m_Player.FirstChildByName("Camera");
|
||||||
@@ -206,7 +239,13 @@ void AssaultWeaponBehaviour::finishReload()
|
|||||||
|
|
||||||
// Make real first person weapon model visible again
|
// Make real first person weapon model visible again
|
||||||
EntityWrapper firstPersonWeaponModel = m_Player.FirstChildByName("WeaponModel");
|
EntityWrapper firstPersonWeaponModel = m_Player.FirstChildByName("WeaponModel");
|
||||||
firstPersonWeaponModel["Model"]["Visible"] = true;
|
if (firstPersonWeaponModel.Valid()) {
|
||||||
|
firstPersonWeaponModel["Model"]["Visible"] = true;
|
||||||
|
}
|
||||||
|
EntityWrapper thirdPersonWeaponModel = m_Player.FirstChildByName("ThirdPersonWeaponModel");
|
||||||
|
if (thirdPersonWeaponModel.Valid()) {
|
||||||
|
thirdPersonWeaponModel["Model"]["Visible"] = true;
|
||||||
|
}
|
||||||
|
|
||||||
m_Reloading = false;
|
m_Reloading = false;
|
||||||
}
|
}
|
||||||
@@ -259,19 +298,45 @@ void AssaultWeaponBehaviour::playIdleAnimation()
|
|||||||
void AssaultWeaponBehaviour::playReloadAnimation()
|
void AssaultWeaponBehaviour::playReloadAnimation()
|
||||||
{
|
{
|
||||||
// Play animation
|
// Play animation
|
||||||
ComponentWrapper cAnimation = m_FirstPersonModel["Animation"];
|
// First person
|
||||||
cAnimation["AnimationName1"] = "ReloadSwitch";
|
if (IsClient)
|
||||||
cAnimation["Weight1"] = 1.0;
|
{
|
||||||
cAnimation["Time1"] = 0.0;
|
ComponentWrapper cAnimation = m_FirstPersonModel["Animation"];
|
||||||
cAnimation["Speed1"] = 0.5;
|
cAnimation["AnimationName1"] = "ReloadSwitch";
|
||||||
cAnimation["Loop1"] = true;
|
cAnimation["Weight1"] = 1.0;
|
||||||
|
cAnimation["Time1"] = 0.0;
|
||||||
|
cAnimation["Speed1"] = 0.5;
|
||||||
|
cAnimation["Loop1"] = true;
|
||||||
|
}
|
||||||
|
// TODO: Third person
|
||||||
|
//{
|
||||||
|
// ComponentWrapper cAnimation = m_ThirdPersonModel["Animation"];
|
||||||
|
// cAnimation["AnimationName1"] = "ReloadSwitch";
|
||||||
|
// cAnimation["Weight1"] = 1.0;
|
||||||
|
// cAnimation["Time1"] = 0.0;
|
||||||
|
// cAnimation["Speed1"] = 0.5;
|
||||||
|
// cAnimation["Loop1"] = true;
|
||||||
|
//}
|
||||||
|
|
||||||
// Hide weapon model and spawn the exploding version
|
// Hide weapon model and spawn the exploding version
|
||||||
EntityWrapper firstPersonWeaponModel = m_Player.FirstChildByName("WeaponModel");
|
{
|
||||||
EntityWrapper reloadSpawner = m_Player.FirstChildByName("FirstPersonReloadSpawner");
|
EntityWrapper firstPersonWeaponModel = m_Player.FirstChildByName("WeaponModel");
|
||||||
m_ReloadImpersonator = SpawnerSystem::Spawn(reloadSpawner, reloadSpawner);
|
EntityWrapper reloadSpawner = m_Player.FirstChildByName("FirstPersonReloadSpawner");
|
||||||
firstPersonWeaponModel["Model"].Copy(m_ReloadImpersonator["Model"]);
|
if (IsClient) {
|
||||||
firstPersonWeaponModel["Model"]["Visible"] = false;
|
m_FirstPersonReloadImpersonator = SpawnerSystem::Spawn(reloadSpawner, reloadSpawner);
|
||||||
|
firstPersonWeaponModel["Model"].Copy(m_FirstPersonReloadImpersonator["Model"]);
|
||||||
|
}
|
||||||
|
firstPersonWeaponModel["Model"]["Visible"] = false;
|
||||||
|
}
|
||||||
|
{
|
||||||
|
EntityWrapper thirdPersonWeaponModel = m_Player.FirstChildByName("ThirdPersonWeaponModel");
|
||||||
|
EntityWrapper reloadSpawner = m_Player.FirstChildByName("ThirdPersonReloadSpawner");
|
||||||
|
if (IsClient) {
|
||||||
|
m_ThirdPersonReloadImpersonator = SpawnerSystem::Spawn(reloadSpawner, reloadSpawner);
|
||||||
|
thirdPersonWeaponModel["Model"].Copy(m_ThirdPersonReloadImpersonator["Model"]);
|
||||||
|
}
|
||||||
|
thirdPersonWeaponModel["Model"]["Visible"] = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AssaultWeaponBehaviour::shoot(double damage)
|
bool AssaultWeaponBehaviour::shoot(double damage)
|
||||||
@@ -302,6 +367,9 @@ bool AssaultWeaponBehaviour::shoot(double damage)
|
|||||||
}
|
}
|
||||||
|
|
||||||
EntityWrapper victim(m_World, pickData.Entity);
|
EntityWrapper victim(m_World, pickData.Entity);
|
||||||
|
if (!victim.Valid()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
// Don't let us shoot ourselves in the foot
|
// Don't let us shoot ourselves in the foot
|
||||||
if (victim == LocalPlayer) {
|
if (victim == LocalPlayer) {
|
||||||
@@ -337,5 +405,9 @@ void AssaultWeaponBehaviour::showHitMarker()
|
|||||||
EntityWrapper hitMarkerSpawner = m_Player.FirstChildByName("HitMarkerSpawner");
|
EntityWrapper hitMarkerSpawner = m_Player.FirstChildByName("HitMarkerSpawner");
|
||||||
if (hitMarkerSpawner.Valid()) {
|
if (hitMarkerSpawner.Valid()) {
|
||||||
SpawnerSystem::Spawn(hitMarkerSpawner, hitMarkerSpawner);
|
SpawnerSystem::Spawn(hitMarkerSpawner, hitMarkerSpawner);
|
||||||
|
Events::PlaySoundOnEntity e;
|
||||||
|
e.EmitterID = m_Player.ID;
|
||||||
|
e.FilePath = "Audio/weapon/hitclick.wav";
|
||||||
|
m_EventBroker->Publish(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+18
-4
@@ -1,11 +1,25 @@
|
|||||||
#include "Game.h"
|
#include "Game.h"
|
||||||
|
#include "MiniDump.h"
|
||||||
|
|
||||||
|
LONG WINAPI CrashHandler(EXCEPTION_POINTERS* pException);
|
||||||
|
|
||||||
int main(int argc, char* argv[])
|
int main(int argc, char* argv[])
|
||||||
{
|
{
|
||||||
Game game(argc, argv);
|
::SetUnhandledExceptionFilter(CrashHandler);
|
||||||
while (game.Running()) {
|
|
||||||
game.Tick();
|
Game game(argc, argv);
|
||||||
}
|
while (game.Running()) {
|
||||||
|
game.Tick();
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
LONG WINAPI CrashHandler(EXCEPTION_POINTERS* pException)
|
||||||
|
{
|
||||||
|
//Take minidump. path should be bin/TacticalZ.dmp
|
||||||
|
//Then show MessageBox, and exit application.
|
||||||
|
Create_Dump(pException, 1, 1);
|
||||||
|
|
||||||
|
return EXCEPTION_EXECUTE_HANDLER;// EXCEPTION_CONTINUE_SEARCH
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user