Compare commits
30 Commits
e254452a6c
...
hitmark
| Author | SHA1 | Date | |
|---|---|---|---|
| 98fcb30f68 | |||
| 048812090b | |||
| ad71bbbdf7 | |||
| 0bb7d28da8 | |||
| 8e13bac9d1 | |||
| 76b3057271 | |||
| df4b1641d5 | |||
| 7daf2bae0c | |||
| a7b235da38 | |||
| e27cc29eb0 | |||
| d59467dd23 | |||
| 0ed577bbc2 | |||
| aa29b9d718 | |||
| 1cce7fcd35 | |||
| 9e93c1a1de | |||
| 4119fe37cc | |||
| 0511511702 | |||
| 2484eb5377 | |||
| 61ae530238 | |||
|
|
7c90ecfbd3 | ||
| 6e47fa6996 | |||
| 83649ddbab | |||
|
|
83c4599aa3 | ||
| 0247ee3cc1 | |||
|
|
58b401f257 | ||
| c5b07e2ae6 | |||
| 507946a0f4 | |||
| f9b79b0d64 | |||
|
|
78d68446f2 | ||
| 255eafa35e |
@@ -1,40 +0,0 @@
|
||||
# Blender 3.6.4
|
||||
# www.blender.org
|
||||
mtllib untitled.mtl
|
||||
o Cube
|
||||
v 1.000000 3.829521 -1.000000
|
||||
v 1.000000 -1.000000 -1.000000
|
||||
v 1.000000 3.829521 1.000000
|
||||
v 1.000000 -1.000000 1.000000
|
||||
v -1.000000 3.829521 -1.000000
|
||||
v -1.000000 -1.000000 -1.000000
|
||||
v -1.000000 3.829521 1.000000
|
||||
v -1.000000 -1.000000 1.000000
|
||||
vn -0.0000 1.0000 -0.0000
|
||||
vn -0.0000 -0.0000 1.0000
|
||||
vn -1.0000 -0.0000 -0.0000
|
||||
vn -0.0000 -1.0000 -0.0000
|
||||
vn 1.0000 -0.0000 -0.0000
|
||||
vn -0.0000 -0.0000 -1.0000
|
||||
vt 0.625000 0.500000
|
||||
vt 0.875000 0.500000
|
||||
vt 0.875000 0.750000
|
||||
vt 0.625000 0.750000
|
||||
vt 0.375000 0.750000
|
||||
vt 0.625000 1.000000
|
||||
vt 0.375000 1.000000
|
||||
vt 0.375000 0.000000
|
||||
vt 0.625000 0.000000
|
||||
vt 0.625000 0.250000
|
||||
vt 0.375000 0.250000
|
||||
vt 0.125000 0.500000
|
||||
vt 0.375000 0.500000
|
||||
vt 0.125000 0.750000
|
||||
s 0
|
||||
usemtl Material
|
||||
f 1/1/1 5/2/1 7/3/1 3/4/1
|
||||
f 4/5/2 3/4/2 7/6/2 8/7/2
|
||||
f 8/8/3 7/9/3 5/10/3 6/11/3
|
||||
f 6/12/4 2/13/4 4/5/4 8/14/4
|
||||
f 2/13/5 1/1/5 3/4/5 4/5/5
|
||||
f 6/11/6 5/10/6 1/1/6 2/13/6
|
||||
@@ -1,37 +0,0 @@
|
||||
# Blender 3.6.4
|
||||
# www.blender.org
|
||||
mtllib void_map.mtl
|
||||
o Plane
|
||||
v -30.0 0.000000 30.0
|
||||
v 30.0 0.000000 30.0
|
||||
v -30.0 0.000000 -30.0
|
||||
v 30.0 0.000000 -30.0
|
||||
v -30.0 0.000000 30.0
|
||||
v -30.0 0.000000 -30.0
|
||||
v -30.0 0.000000 30.0
|
||||
v -30.0 0.000000 -30.0
|
||||
v -30.0 15.0 30.0
|
||||
v -30.0 15.0 -30.0
|
||||
v -30.0 15.0 -30.0
|
||||
v 30.0 15.0 -30.0
|
||||
v 30.0 15.0 30.0
|
||||
v 30.0 15.0 -30.0
|
||||
v -30.0 15.0 30.0
|
||||
v 30.0 15.0 30.0
|
||||
vn -0.0000 1.0000 -0.0000
|
||||
vn 1.0000 -0.0000 -0.0000
|
||||
vn -0.0000 -0.0000 1.0000
|
||||
vn -1.0000 -0.0000 -0.0000
|
||||
vn -0.0000 -0.0000 -1.0000
|
||||
vt 0.000000 0.000000
|
||||
vt 1.000000 0.000000
|
||||
vt 1.000000 1.000000
|
||||
vt 0.000000 1.000000
|
||||
s 0
|
||||
f 1/1/1 2/2/1 4/3/1 3/4/1
|
||||
f 1/1/1 3/4/1 6/4/1 5/1/1
|
||||
f 5/1/1 6/4/1 8/4/1 7/1/1
|
||||
f 7/1/2 8/4/2 10/4/2 9/1/2
|
||||
f 3/4/3 4/3/3 12/3/3 11/4/3
|
||||
f 4/3/4 2/2/4 13/2/4 14/3/4
|
||||
f 2/2/5 1/1/5 15/1/5 16/2/5
|
||||
@@ -1,38 +0,0 @@
|
||||
# Blender 3.6.4
|
||||
# www.blender.org
|
||||
mtllib void_map2.mtl
|
||||
o Plane
|
||||
v -31.562399 0.000000 31.562399
|
||||
v 31.562399 0.000000 31.562399
|
||||
v -31.562399 0.000000 -31.562399
|
||||
v 31.562399 0.000000 -31.562399
|
||||
v -31.562399 0.000000 31.562399
|
||||
v -31.562399 0.000000 -31.562399
|
||||
v -31.562399 0.000000 31.562399
|
||||
v -31.562399 0.000000 -31.562399
|
||||
v -31.562399 12.947957 31.562399
|
||||
v -31.562399 12.947957 -31.562399
|
||||
v -31.562399 12.885334 -31.562399
|
||||
v 31.562399 12.885334 -31.562399
|
||||
v 31.562399 12.806857 31.562399
|
||||
v 31.562399 12.806857 -31.562399
|
||||
v -31.562399 12.847334 31.562399
|
||||
v 31.562399 12.847334 31.562399
|
||||
vn -0.0000 1.0000 -0.0000
|
||||
vn 1.0000 -0.0000 -0.0000
|
||||
vn -0.0000 -0.0000 1.0000
|
||||
vn -1.0000 -0.0000 -0.0000
|
||||
vn -0.0000 -0.0000 -1.0000
|
||||
vt 0.000000 0.000000
|
||||
vt 1.000000 0.000000
|
||||
vt 1.000000 1.000000
|
||||
vt 0.000000 1.000000
|
||||
s 0
|
||||
usemtl carrelage
|
||||
f 1/1/1 2/2/1 4/3/1 3/4/1
|
||||
f 1/1/1 3/4/1 6/4/1 5/1/1
|
||||
f 5/1/1 6/4/1 8/4/1 7/1/1
|
||||
f 7/1/2 8/4/2 10/4/2 9/1/2
|
||||
f 3/4/3 4/3/3 12/3/3 11/4/3
|
||||
f 4/3/4 2/2/4 13/2/4 14/3/4
|
||||
f 2/2/5 1/1/5 15/1/5 16/2/5
|
||||
@@ -1,6 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "Player.h"
|
||||
#include "blitz/misc/Time.h"
|
||||
#include <map>
|
||||
|
||||
namespace blitz {
|
||||
@@ -8,12 +9,28 @@ namespace game {
|
||||
|
||||
typedef std::map<PlayerID, Player> PlayerMap;
|
||||
|
||||
enum GameState : std::uint8_t {
|
||||
gsNone = 0,
|
||||
gsWaiting,
|
||||
gsPreparing,
|
||||
gsGame,
|
||||
gsEnd,
|
||||
};
|
||||
|
||||
struct GameConfig {
|
||||
float Gravity;
|
||||
int FiringRate;
|
||||
};
|
||||
|
||||
class Game {
|
||||
private:
|
||||
protected:
|
||||
PlayerMap m_Players;
|
||||
GameState m_GameState;
|
||||
utils::Timer m_GameTimer;
|
||||
GameConfig m_Config;
|
||||
|
||||
public:
|
||||
Game() {}
|
||||
Game() : m_GameState(gsNone) {}
|
||||
|
||||
virtual void Tick(std::uint64_t delta) = 0;
|
||||
|
||||
@@ -28,8 +45,24 @@ class Game {
|
||||
return m_Players;
|
||||
}
|
||||
|
||||
GameState GetGameState() const {
|
||||
return m_GameState;
|
||||
}
|
||||
|
||||
void LoadConfig(const GameConfig& config) {
|
||||
m_Config = config;
|
||||
}
|
||||
|
||||
const game::GameConfig& GetGameConfig() const {
|
||||
return m_Config;
|
||||
}
|
||||
|
||||
virtual void AddPlayer(PlayerID player, const std::string& name);
|
||||
virtual void RemovePlayer(PlayerID player);
|
||||
|
||||
std::uint64_t GetGameStateRemainingTime() const {
|
||||
return m_GameTimer.GetTimeRemaining();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
25
include/blitz/game/LeaderBoard.h
Normal file
25
include/blitz/game/LeaderBoard.h
Normal file
@@ -0,0 +1,25 @@
|
||||
#pragma once
|
||||
|
||||
#include "blitz/game/Player.h"
|
||||
#include <vector>
|
||||
|
||||
namespace blitz {
|
||||
namespace game {
|
||||
|
||||
class LeaderBoard {
|
||||
private:
|
||||
std::vector<Player*> m_Players;
|
||||
|
||||
public:
|
||||
void AddPlayer(Player* player);
|
||||
void RemovePlayer(PlayerID player);
|
||||
|
||||
void Update();
|
||||
|
||||
const std::vector<Player*>& GetPlayers() const {
|
||||
return m_Players;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace game
|
||||
} // namespace blitz
|
||||
@@ -1,8 +1,19 @@
|
||||
#pragma once
|
||||
|
||||
#include "blitz/common/Defines.h"
|
||||
#include "blitz/maths/Vector.h"
|
||||
#include <vector>
|
||||
|
||||
namespace blitz {
|
||||
|
||||
namespace protocol {
|
||||
|
||||
struct ColoredPart;
|
||||
typedef std::vector<ColoredPart> ColoredText;
|
||||
|
||||
} // namespace protocol
|
||||
|
||||
|
||||
namespace game {
|
||||
|
||||
class PlayerInputListener {
|
||||
@@ -11,5 +22,13 @@ class PlayerInputListener {
|
||||
virtual void OnLocalPlayerShoot(const Vec3f& position, float yaw, float pitch) {}
|
||||
};
|
||||
|
||||
class ClientListener {
|
||||
public:
|
||||
virtual void OnTextChatReceived(const protocol::ColoredText& text) {}
|
||||
virtual void OnSpectatorChange(game::PlayerID player) {}
|
||||
virtual void OnPlayerShoot(PlayerID player, const Vec3f& position, float yaw, float pitch) {}
|
||||
virtual void OnGameConfigUpdate() {}
|
||||
};
|
||||
|
||||
} // namespace game
|
||||
} // namespace blitz
|
||||
|
||||
@@ -102,6 +102,10 @@ class Player {
|
||||
m_IsBot = true;
|
||||
}
|
||||
|
||||
const PlayerStats& GetStats() const {
|
||||
return m_Stats;
|
||||
}
|
||||
|
||||
PlayerStats& GetStats() {
|
||||
return m_Stats;
|
||||
}
|
||||
|
||||
@@ -120,7 +120,7 @@ constexpr Vec2<T> operator-(const Vec2<T>& vect) {
|
||||
|
||||
template <typename T>
|
||||
constexpr Vec2<T> operator-(const Vec2<T>& vect, const Vec2<T>& other) {
|
||||
return vect + (-other);
|
||||
return {vect.x - other.x, vect.y - other.y};
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
@@ -251,7 +251,7 @@ Vec4<T>& operator+=(Vec4<T>& vect, const Vec4<T>& other) {
|
||||
|
||||
template <typename T>
|
||||
constexpr Vec4<T> operator-(const Vec4<T>& vect, const Vec4<T>& other) {
|
||||
return vect + (-other);
|
||||
return {vect.x - other.x, vect.y - other.y, vect.z - other.z, vect.w - other.w};
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
#include <algorithm>
|
||||
#include <cstdint>
|
||||
#include <functional>
|
||||
|
||||
@@ -59,6 +60,15 @@ class Timer {
|
||||
bool Update(std::uint64_t delta);
|
||||
|
||||
void Reset();
|
||||
// void ResetSoft(); // don't trigger the timer
|
||||
|
||||
std::uint64_t GetTimeRemaining() const {
|
||||
return m_Interval - m_InternalTime;
|
||||
}
|
||||
|
||||
std::uint64_t GetTimeElapsed() const {
|
||||
return m_InternalTime;
|
||||
}
|
||||
|
||||
void SetInterval(std::uint64_t newInterval) {
|
||||
m_Interval = newInterval;
|
||||
@@ -104,5 +114,40 @@ class CooldownTimer {
|
||||
}
|
||||
};
|
||||
|
||||
// utililty class to trigger update at regular period of time with a cooldown
|
||||
template <typename T>
|
||||
class DelayTimer {
|
||||
private:
|
||||
T m_DelayTime;
|
||||
T m_InternalTime;
|
||||
|
||||
public:
|
||||
DelayTimer() : m_DelayTime(0), m_InternalTime(0) {}
|
||||
DelayTimer(T delay) : m_DelayTime(delay), m_InternalTime(delay) {}
|
||||
|
||||
/**
|
||||
* \brief Returns true whether the delay has been passed.
|
||||
*/
|
||||
bool Update(T delta) {
|
||||
m_InternalTime = std::max<T>(static_cast<T>(0), static_cast<T>(m_InternalTime - delta));
|
||||
return m_InternalTime == 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Resets the timer
|
||||
*/
|
||||
void Reset() {
|
||||
m_InternalTime = m_DelayTime;
|
||||
}
|
||||
|
||||
void SetDelay(T newDelay) {
|
||||
m_DelayTime = newDelay;
|
||||
}
|
||||
|
||||
T GetDelay() const {
|
||||
return m_DelayTime;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace utils
|
||||
} // namespace blitz
|
||||
|
||||
@@ -41,28 +41,28 @@ class Connexion : public protocol::PacketHandler, private NonCopyable {
|
||||
|
||||
/**
|
||||
* \brief Default destructor
|
||||
*/
|
||||
*/
|
||||
virtual ~Connexion();
|
||||
|
||||
/**
|
||||
* \brief Reads socket and process a Packet, if any
|
||||
*/
|
||||
* \brief Reads socket and process a Packet, if any
|
||||
*/
|
||||
virtual bool UpdateSocket();
|
||||
|
||||
|
||||
/**
|
||||
* \brief Closes the connexion
|
||||
*/
|
||||
*/
|
||||
void CloseConnection();
|
||||
|
||||
/**
|
||||
* \brief Tries to connect the socket at the specified address and port
|
||||
* \return Wether this action was succesfull
|
||||
*/
|
||||
virtual bool Connect(const std::string& address, std::uint16_t port);
|
||||
*/
|
||||
bool Connect(const std::string& address, std::uint16_t port);
|
||||
|
||||
/**
|
||||
* \brief Returns the TCPSocket::Status of the internal socket
|
||||
*/
|
||||
*/
|
||||
TCPSocket::Status GetSocketStatus() const {
|
||||
return m_Socket.GetStatus();
|
||||
}
|
||||
@@ -70,7 +70,7 @@ class Connexion : public protocol::PacketHandler, private NonCopyable {
|
||||
/**
|
||||
* \brief Sends the protocol::Packet over the network to the remote
|
||||
* \param packet The protocol::Packet to send
|
||||
*/
|
||||
*/
|
||||
void SendPacket(const protocol::Packet* packet);
|
||||
};
|
||||
|
||||
|
||||
@@ -31,7 +31,9 @@ class PacketHandler {
|
||||
virtual void HandlePacket(const PlayerPositionAndRotationPacket* packet) {}
|
||||
virtual void HandlePacket(const PlayerShootPacket* packet) {}
|
||||
virtual void HandlePacket(const PlayerStatsPacket* packet) {}
|
||||
virtual void HandlePacket(const ServerConfigPacket* packet) {}
|
||||
virtual void HandlePacket(const ServerTpsPacket* packet) {}
|
||||
virtual void HandlePacket(const UpdateGameStatePacket* packet) {}
|
||||
virtual void HandlePacket(const UpdateHealthPacket* packet) {}
|
||||
};
|
||||
|
||||
|
||||
@@ -9,5 +9,7 @@
|
||||
#include "packets/PlayerPositionAndRotationPacket.h"
|
||||
#include "packets/PlayerShootPacket.h"
|
||||
#include "packets/PlayerStatsPacket.h"
|
||||
#include "packets/ServerConfigPacket.h"
|
||||
#include "packets/ServerTpsPacket.h"
|
||||
#include "packets/UpdateGameStatePacket.h"
|
||||
#include "packets/UpdateHealthPacket.h"
|
||||
|
||||
@@ -14,7 +14,9 @@ class PlayerLoginPacket;
|
||||
class PlayerPositionAndRotationPacket;
|
||||
class PlayerShootPacket;
|
||||
class PlayerStatsPacket;
|
||||
class ServerConfigPacket;
|
||||
class ServerTpsPacket;
|
||||
class UpdateGameStatePacket;
|
||||
class UpdateHealthPacket;
|
||||
|
||||
} // namespace protocol
|
||||
|
||||
@@ -24,12 +24,14 @@ enum class PacketType : std::uint8_t {
|
||||
|
||||
// client <-- server
|
||||
|
||||
ConnexionInfo, /**< Corresponds to ConnexionInfoPacket */
|
||||
PlayerJoin, /**< Corresponds to PlayerJoinPacket */
|
||||
PlayerLeave, /**< Corresponds to PlayerLeavePacket */
|
||||
PlayerList, /**< Corresponds to PlayerListPacket */
|
||||
PlayerStats, /**< Corresponds to PlayerStatsPacket */
|
||||
ServerTps, /**< Corresponds to ServerTpsPacket */
|
||||
ConnexionInfo, /**< Corresponds to ConnexionInfoPacket */
|
||||
PlayerJoin, /**< Corresponds to PlayerJoinPacket */
|
||||
PlayerLeave, /**< Corresponds to PlayerLeavePacket */
|
||||
PlayerList, /**< Corresponds to PlayerListPacket */
|
||||
PlayerStats, /**< Corresponds to PlayerStatsPacket */
|
||||
ServerConfig, /**< Corresponds to ServerConfigPacket*/
|
||||
ServerTps, /**< Corresponds to ServerTpsPacket */
|
||||
UpdateGameState, /**< Corresponds to UpdateGameStatePacket */
|
||||
|
||||
// client <--> server
|
||||
|
||||
|
||||
32
include/blitz/protocol/packets/ServerConfigPacket.h
Normal file
32
include/blitz/protocol/packets/ServerConfigPacket.h
Normal file
@@ -0,0 +1,32 @@
|
||||
#pragma once
|
||||
|
||||
#include "blitz/game/Game.h"
|
||||
#include "blitz/protocol/Protocol.h"
|
||||
|
||||
namespace blitz {
|
||||
namespace protocol {
|
||||
|
||||
class ServerConfigPacket : public Packet {
|
||||
private:
|
||||
game::GameConfig m_GameConfig;
|
||||
|
||||
public:
|
||||
ServerConfigPacket() {}
|
||||
ServerConfigPacket(const game::GameConfig& GameConfig) : m_GameConfig(GameConfig) {}
|
||||
virtual ~ServerConfigPacket() {}
|
||||
|
||||
virtual DataBuffer Serialize(bool packetID = true) const;
|
||||
virtual void Deserialize(DataBuffer& data);
|
||||
virtual void Dispatch(PacketHandler* handler) const;
|
||||
|
||||
game::GameConfig GetGameConfig() const {
|
||||
return m_GameConfig;
|
||||
}
|
||||
|
||||
virtual PacketType GetType() const {
|
||||
return PacketType::ServerConfig;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace protocol
|
||||
} // namespace blitz
|
||||
38
include/blitz/protocol/packets/UpdateGameStatePacket.h
Normal file
38
include/blitz/protocol/packets/UpdateGameStatePacket.h
Normal file
@@ -0,0 +1,38 @@
|
||||
#pragma once
|
||||
|
||||
#include "blitz/game/Game.h"
|
||||
#include "blitz/protocol/Protocol.h"
|
||||
|
||||
namespace blitz {
|
||||
namespace protocol {
|
||||
|
||||
class UpdateGameStatePacket : public Packet {
|
||||
private:
|
||||
game::GameState m_GameState;
|
||||
std::uint64_t m_TimeRemaining;
|
||||
|
||||
public:
|
||||
UpdateGameStatePacket() {}
|
||||
UpdateGameStatePacket(game::GameState a_GameState, std::uint64_t a_TimeRemaining = 0) :
|
||||
m_GameState(a_GameState), m_TimeRemaining(a_TimeRemaining) {}
|
||||
virtual ~UpdateGameStatePacket() {}
|
||||
|
||||
virtual DataBuffer Serialize(bool packetID = true) const;
|
||||
virtual void Deserialize(DataBuffer& data);
|
||||
virtual void Dispatch(PacketHandler* handler) const;
|
||||
|
||||
game::GameState GetGameState() const {
|
||||
return m_GameState;
|
||||
}
|
||||
|
||||
std::uint64_t GetTimeRemaining() const {
|
||||
return m_TimeRemaining;
|
||||
}
|
||||
|
||||
virtual PacketType GetType() const {
|
||||
return PacketType::UpdateGameState;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace protocol
|
||||
} // namespace blitz
|
||||
@@ -18,7 +18,7 @@ class UpdateHealthPacket : public Packet {
|
||||
virtual void Deserialize(DataBuffer& data);
|
||||
virtual void Dispatch(PacketHandler* handler) const;
|
||||
|
||||
std::uint8_t GetNewHealth() const {
|
||||
float GetNewHealth() const {
|
||||
return m_NewHealth;
|
||||
}
|
||||
|
||||
|
||||
@@ -23,15 +23,10 @@ namespace server {
|
||||
class Server;
|
||||
} // namespace server
|
||||
|
||||
class GuiListener {
|
||||
public:
|
||||
virtual void OnTextChatReceived(const protocol::ColoredText& text) {}
|
||||
virtual void OnSpectatorChange(game::PlayerID player) {}
|
||||
virtual void OnPlayerShoot(game::PlayerID player, const Vec3f& position, float yaw, float pitch) {}
|
||||
};
|
||||
|
||||
|
||||
// Singleton
|
||||
class Client : public utils::ObjectNotifier<GuiListener>, public game::PlayerInputListener {
|
||||
class Client : public utils::ObjectNotifier<game::ClientListener>, public game::PlayerInputListener {
|
||||
private:
|
||||
std::unique_ptr<server::Server> m_Server;
|
||||
std::unique_ptr<client::ClientConnexion> m_Connexion;
|
||||
@@ -75,6 +70,8 @@ class Client : public utils::ObjectNotifier<GuiListener>, public game::PlayerInp
|
||||
return m_Server.get();
|
||||
}
|
||||
|
||||
void UpdateServerConfig();
|
||||
|
||||
private:
|
||||
void Reset();
|
||||
|
||||
|
||||
@@ -24,7 +24,7 @@ class ClientConnexion : public network::Connexion {
|
||||
virtual void HandlePacket(const protocol::ChatPacket* packet) override;
|
||||
virtual void HandlePacket(const protocol::ConnexionInfoPacket* packet) override;
|
||||
|
||||
virtual bool Connect(const std::string& pseudo, const std::string& address, std::uint16_t port);
|
||||
bool Connect(const std::string& pseudo, const std::string& address, std::uint16_t port);
|
||||
|
||||
game::PlayerID GetPlayerID() const {
|
||||
return m_PlayerID;
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
#include "blitz/game/Game.h"
|
||||
#include <array>
|
||||
#include <string>
|
||||
|
||||
@@ -10,6 +11,7 @@ enum KeyAction {
|
||||
kaReculer,
|
||||
kaDroite,
|
||||
kaGauche,
|
||||
kaFenetreAdmin,
|
||||
kaMax,
|
||||
};
|
||||
|
||||
@@ -18,11 +20,11 @@ typedef std::array<int, kaMax> Keybinds;
|
||||
class BlitzConfig {
|
||||
private:
|
||||
std::array<char, 256> m_Pseudo;
|
||||
game::GameConfig m_ServerConfig;
|
||||
bool m_VSync;
|
||||
bool m_DisplayFps;
|
||||
KeyAction m_CurrentAction;
|
||||
Keybinds m_Keybinds{};
|
||||
|
||||
float m_MouseSpeed;
|
||||
|
||||
public:
|
||||
BlitzConfig();
|
||||
@@ -52,6 +54,18 @@ class BlitzConfig {
|
||||
return m_Keybinds;
|
||||
}
|
||||
|
||||
float GetMouseSpeed() const {
|
||||
return m_MouseSpeed;
|
||||
}
|
||||
|
||||
void SetMouseSpeed(float MouseSpeed) {
|
||||
m_MouseSpeed = MouseSpeed;
|
||||
}
|
||||
|
||||
game::GameConfig& GetServerConfig() {
|
||||
return m_ServerConfig;
|
||||
}
|
||||
|
||||
private:
|
||||
void LoadConfig();
|
||||
void LoadDefaultConfig();
|
||||
|
||||
@@ -17,27 +17,17 @@ class Player;
|
||||
|
||||
namespace input {
|
||||
|
||||
class PlayerController : public utils::ObjectNotifier<game::PlayerInputListener> {
|
||||
class PlayerController : public utils::ObjectNotifier<game::PlayerInputListener>, game::ClientListener {
|
||||
private:
|
||||
game::Player* m_Player;
|
||||
Client* m_Client;
|
||||
utils::CooldownTimer<float> m_ShootTimer{1.0f};
|
||||
EMASmoother m_DxSmoother;
|
||||
EMASmoother m_DySmoother;
|
||||
/// current (target) x-axis velocity
|
||||
float m_Dx;
|
||||
/// current (target) y-axis velocity
|
||||
float m_Dy;
|
||||
/// current z-axis velocity
|
||||
float m_Dz;
|
||||
// current (target) velocity
|
||||
Vec3f m_Velocity;
|
||||
/// maximum x-axis velocity
|
||||
float m_MaxDx;
|
||||
/// maximum (target) y-axis velocity
|
||||
float m_MaxDy;
|
||||
/// maximum z-axis velocity (velocity at initial keypress)
|
||||
float m_MaxDz;
|
||||
/// individual gravitational force
|
||||
float m_G;
|
||||
Vec3f m_MaxVelocity;
|
||||
/// this is reset when the player touches the ground
|
||||
bool m_OnGround;
|
||||
|
||||
@@ -46,6 +36,8 @@ class PlayerController : public utils::ObjectNotifier<game::PlayerInputListener>
|
||||
|
||||
void Update(float delta);
|
||||
|
||||
virtual void OnGameConfigUpdate() override;
|
||||
|
||||
void SetAttachedPlayer(game::Player* a_Player) {
|
||||
m_Player = a_Player;
|
||||
}
|
||||
@@ -55,6 +47,7 @@ class PlayerController : public utils::ObjectNotifier<game::PlayerInputListener>
|
||||
}
|
||||
|
||||
private:
|
||||
void UpdateShootTimer(int bpm);
|
||||
void MouseMotionEvent(int, int);
|
||||
void UpdatePosition(float delta);
|
||||
};
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
#pragma once
|
||||
|
||||
#include "blitz/game/Game.h"
|
||||
#include "blitz/game/LeaderBoard.h"
|
||||
#include "blitz/protocol/PacketHandler.h"
|
||||
#include <vector>
|
||||
|
||||
namespace blitz {
|
||||
|
||||
@@ -12,6 +14,7 @@ namespace client {
|
||||
class ClientGame : public game::Game, public protocol::PacketHandler {
|
||||
private:
|
||||
Client* m_Client;
|
||||
game::LeaderBoard m_LeaderBoard;
|
||||
|
||||
public:
|
||||
ClientGame(Client* client, protocol::PacketDispatcher* dispatcher);
|
||||
@@ -26,6 +29,15 @@ class ClientGame : public game::Game, public protocol::PacketHandler {
|
||||
virtual void HandlePacket(const protocol::PlayerShootPacket* packet) override;
|
||||
virtual void HandlePacket(const protocol::UpdateHealthPacket* packet) override;
|
||||
virtual void HandlePacket(const protocol::PlayerStatsPacket* packet) override;
|
||||
virtual void HandlePacket(const protocol::UpdateGameStatePacket* packet) override;
|
||||
virtual void HandlePacket(const protocol::ServerConfigPacket* packet) override;
|
||||
|
||||
virtual void AddPlayer(game::PlayerID player, const std::string& name) override;
|
||||
virtual void RemovePlayer(game::PlayerID player) override;
|
||||
|
||||
const game::LeaderBoard& GetLeaderBoard() const {
|
||||
return m_LeaderBoard;
|
||||
}
|
||||
|
||||
private:
|
||||
void RegisterHandlers();
|
||||
|
||||
@@ -7,7 +7,7 @@ namespace gui {
|
||||
|
||||
class CrossHair : public GuiWidget {
|
||||
private:
|
||||
int m_CrossHairTexture;
|
||||
std::uint64_t m_CrossHairTexture;
|
||||
|
||||
public:
|
||||
CrossHair(Client* client);
|
||||
|
||||
@@ -9,7 +9,7 @@ namespace blitz {
|
||||
|
||||
namespace gui {
|
||||
|
||||
class GameChatGui : public GuiWidget, GuiListener {
|
||||
class GameChatGui : public GuiWidget, game::ClientListener {
|
||||
private:
|
||||
char InputBuf[256];
|
||||
std::vector<protocol::ColoredText> m_Lines;
|
||||
@@ -26,7 +26,8 @@ class GameChatGui : public GuiWidget, GuiListener {
|
||||
|
||||
public:
|
||||
GameChatGui(GuiWidget* parent, Client* client);
|
||||
virtual void OnTextChatReceived(const protocol::ColoredText& text);
|
||||
|
||||
virtual void OnTextChatReceived(const protocol::ColoredText& text) override;
|
||||
|
||||
virtual void Render() override;
|
||||
};
|
||||
|
||||
@@ -7,18 +7,26 @@ namespace blitz {
|
||||
|
||||
class Client;
|
||||
|
||||
namespace game {
|
||||
class Player;
|
||||
} // namespace game
|
||||
|
||||
namespace gui {
|
||||
class Hud : public GuiWidget {
|
||||
private:
|
||||
/* data */
|
||||
|
||||
void Draw(const char* title, bool* p_open);
|
||||
unsigned int m_GunTexture;
|
||||
unsigned int m_JP;
|
||||
std::uint64_t m_GunTexture;
|
||||
std::uint64_t m_JPTexture;
|
||||
utils::DelayTimer<float> m_Timer{5.0f};
|
||||
|
||||
public:
|
||||
Hud(GuiWidget* parent, Client* client);
|
||||
virtual void Render() override;
|
||||
|
||||
private:
|
||||
std::string FormatString();
|
||||
void Draw(const char* title, bool* p_open);
|
||||
void DrawFinishScreen(bool win);
|
||||
void RenderTime(float, float);
|
||||
};
|
||||
|
||||
} // namespace gui
|
||||
|
||||
@@ -6,13 +6,14 @@
|
||||
namespace blitz {
|
||||
|
||||
namespace gui {
|
||||
class LeaderBoard : public GuiWidget {
|
||||
class LeaderBoardGui : public GuiWidget {
|
||||
private:
|
||||
void Draw(const char* title, bool* p_open);
|
||||
utils::DelayTimer<float> m_Timer{5.0f};
|
||||
|
||||
public:
|
||||
LeaderBoard(GuiWidget* parent, Client* client);
|
||||
~LeaderBoard();
|
||||
LeaderBoardGui(GuiWidget* parent, Client* client);
|
||||
~LeaderBoardGui();
|
||||
|
||||
virtual void Render() override;
|
||||
};
|
||||
@@ -28,14 +28,13 @@ class BulletRenderer {
|
||||
std::vector<Trail> m_Trails;
|
||||
ModelLoader::Model m_BulletModel;
|
||||
std::unique_ptr<shader::BulletShader> m_Shader;
|
||||
unsigned int m_Vbo;
|
||||
const Camera& m_Camera;
|
||||
|
||||
public:
|
||||
BulletRenderer(const Camera& cam);
|
||||
~BulletRenderer();
|
||||
|
||||
void AddBullet(const Vec3f& origin, float yaw, float pitch);
|
||||
void AddBullet(const Vec3f& origin, float yaw, float pitch, bool firstPersson);
|
||||
void Update(float delta);
|
||||
void Render();
|
||||
};
|
||||
|
||||
@@ -20,7 +20,7 @@ class GunShader;
|
||||
|
||||
namespace render {
|
||||
|
||||
class MainRenderer : public GuiListener, public game::PlayerInputListener {
|
||||
class MainRenderer : public game::ClientListener, public game::PlayerInputListener {
|
||||
private:
|
||||
Client* m_Client;
|
||||
ModelLoader::Model m_PlayerModel;
|
||||
@@ -43,6 +43,8 @@ class MainRenderer : public GuiListener, public game::PlayerInputListener {
|
||||
virtual void OnPlayerShoot(game::PlayerID player, const Vec3f& position, float yaw, float pitch) override;
|
||||
virtual void OnLocalPlayerShoot(const Vec3f& position, float yaw, float pitch) override;
|
||||
|
||||
virtual void OnGameConfigUpdate() override;
|
||||
|
||||
void Update();
|
||||
void Render();
|
||||
void RenderEntity(const GL::VertexArray& vao, const Vec3f& position, float yaw);
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
#ifndef BLITZ_GL_LOADER_GLBNIDING
|
||||
#ifdef BLITZ_GL_LOADER_GLEW
|
||||
#include <GL/glew.h>
|
||||
#else
|
||||
#include <glbinding/gl/gl.h>
|
||||
|
||||
@@ -70,7 +70,7 @@ class VertexArray : private NonCopyable {
|
||||
VertexArray(ElementBuffer&& indicies);
|
||||
~VertexArray();
|
||||
|
||||
unsigned int GetVertexCount() const {
|
||||
std::size_t GetVertexCount() const {
|
||||
return m_ElementBuffer.GetTriangleCount();
|
||||
}
|
||||
|
||||
|
||||
@@ -48,7 +48,7 @@ class ServerConnexion : public network::Connexion {
|
||||
return m_ID;
|
||||
}
|
||||
|
||||
virtual bool UpdateSocket();
|
||||
virtual bool UpdateSocket() override;
|
||||
|
||||
private:
|
||||
void RegisterHandlers();
|
||||
@@ -57,6 +57,8 @@ class ServerConnexion : public network::Connexion {
|
||||
void InitConnection();
|
||||
void InitPlayerChatColor();
|
||||
void SendPlayers();
|
||||
void SendGameState();
|
||||
void SendServerConfig();
|
||||
};
|
||||
|
||||
} // namespace server
|
||||
|
||||
@@ -1,17 +1,23 @@
|
||||
#pragma once
|
||||
|
||||
#include "blitz/game/Game.h"
|
||||
#include "blitz/misc/Time.h"
|
||||
|
||||
namespace blitz {
|
||||
namespace server {
|
||||
|
||||
struct ServerDuration {
|
||||
std::uint64_t m_GameDuration = 1000 * 3 * 60;
|
||||
std::uint64_t m_PrepDuration = 1000 * 10;
|
||||
std::uint64_t m_EndDuration = 1000 * 30;
|
||||
};
|
||||
|
||||
class Server;
|
||||
|
||||
class ServerGame : public game::Game {
|
||||
private:
|
||||
Server* m_Server;
|
||||
utils::Timer m_PositionTimer;
|
||||
ServerDuration m_ServerDuration;
|
||||
|
||||
public:
|
||||
ServerGame(Server* server);
|
||||
@@ -24,11 +30,22 @@ class ServerGame : public game::Game {
|
||||
|
||||
void Tick(std::uint64_t delta) override;
|
||||
|
||||
void SetGameState(game::GameState gameState, std::uint64_t duration);
|
||||
|
||||
ServerDuration& GetServerDuration() {
|
||||
return m_ServerDuration;
|
||||
}
|
||||
|
||||
void SendServerConfig();
|
||||
|
||||
private:
|
||||
void SendPlayerPositions();
|
||||
void DamagePlayer(game::Player& player, game::Player& shooter);
|
||||
void UpdateHP(game::Player& player, float newHP);
|
||||
void UpdatePlayerStats();
|
||||
void StartGame(); // when at least 2 players joined
|
||||
void CancelGame(); // when not enough players are left
|
||||
void ResetPlayerStats();
|
||||
};
|
||||
|
||||
} // namespace server
|
||||
|
||||
29
src/blitz/game/LeaderBoard.cpp
Normal file
29
src/blitz/game/LeaderBoard.cpp
Normal file
@@ -0,0 +1,29 @@
|
||||
#include "blitz/game/LeaderBoard.h"
|
||||
|
||||
namespace blitz {
|
||||
namespace game {
|
||||
|
||||
void LeaderBoard::AddPlayer(Player* player) {
|
||||
m_Players.push_back(player);
|
||||
Update();
|
||||
}
|
||||
|
||||
void LeaderBoard::RemovePlayer(PlayerID player) {
|
||||
auto it = std::find_if(m_Players.begin(), m_Players.end(), [player](game::Player* p) { return p->GetID() == player; });
|
||||
if (it != m_Players.end())
|
||||
m_Players.erase(it);
|
||||
}
|
||||
|
||||
void LeaderBoard::Update() {
|
||||
std::sort(m_Players.begin(), m_Players.end(), [](Player* a, Player* b) {
|
||||
std::uint16_t killsA = a->GetStats().m_Kills;
|
||||
std::uint16_t killsB = b->GetStats().m_Kills;
|
||||
if (killsA == killsB) {
|
||||
return a->GetStats().m_Deaths < b->GetStats().m_Deaths;
|
||||
}
|
||||
return killsA > killsB;
|
||||
});
|
||||
}
|
||||
|
||||
} // namespace game
|
||||
} // namespace blitz
|
||||
@@ -59,7 +59,7 @@ Mat4f Inverse(const Mat4f& mat) {
|
||||
|
||||
assert(det != 0 && "Determinant equals 0 !");
|
||||
|
||||
float invdet = 1.0 / det;
|
||||
float invdet = 1.0f / det;
|
||||
|
||||
Mat4f result;
|
||||
|
||||
|
||||
@@ -14,7 +14,7 @@ static DataBuffer Inflate(const std::uint8_t* source, std::size_t size, std::siz
|
||||
result.Resize(uncompressedSize);
|
||||
|
||||
uncompress(reinterpret_cast<Bytef*>(result.data()), reinterpret_cast<uLongf*>(&uncompressedSize),
|
||||
reinterpret_cast<const Bytef*>(source), size);
|
||||
reinterpret_cast<const Bytef*>(source), static_cast<uLong>(size));
|
||||
|
||||
assert(result.GetSize() == uncompressedSize);
|
||||
return result;
|
||||
@@ -25,7 +25,8 @@ static DataBuffer Deflate(const std::uint8_t* source, std::size_t size) {
|
||||
uLongf compressedSize;
|
||||
|
||||
result.Resize(size); // Resize for the compressed data to fit into
|
||||
compress(reinterpret_cast<Bytef*>(result.data()), &compressedSize, reinterpret_cast<const Bytef*>(source), size);
|
||||
compress(
|
||||
reinterpret_cast<Bytef*>(result.data()), &compressedSize, reinterpret_cast<const Bytef*>(source), static_cast<uLong>(size));
|
||||
result.Resize(compressedSize); // Resize to cut useless data
|
||||
|
||||
return result;
|
||||
|
||||
@@ -10,122 +10,126 @@ namespace utils {
|
||||
/* Sine functions */
|
||||
|
||||
float EaseInSine(float x) {
|
||||
return 1.0f - std::cos((x * maths::PI) / 2.0f);
|
||||
return static_cast<float>(1.0 - std::cos((x * maths::PI) / 2.0));
|
||||
}
|
||||
|
||||
float EaseOutSine(float x) {
|
||||
return std::sin((x * maths::PI) / 2.0f);
|
||||
return static_cast<float>(std::sin((x * maths::PI) / 2.0));
|
||||
}
|
||||
|
||||
float EaseInOutSine(float x) {
|
||||
return -(std::cos(maths::PI * x) - 1.0f) / 2.0f;
|
||||
return static_cast<float>(-(std::cos(maths::PI * x) - 1.0) / 2.0);
|
||||
}
|
||||
|
||||
/* Cubic functions */
|
||||
|
||||
float EaseInCubic(float x) {
|
||||
return x * EaseInQuad(x);
|
||||
return static_cast<float>(x * EaseInQuad(x));
|
||||
}
|
||||
|
||||
float EaseOutCubic(float x) {
|
||||
return 1 - std::pow(1 - x, 3);
|
||||
return static_cast<float>(1 - std::pow(1 - x, 3));
|
||||
}
|
||||
|
||||
float EaseInOutCubic(float x) {
|
||||
return x < 0.5 ? 4 * EaseInCubic(x) : 1 - std::pow(-2 * x + 2, 3) / 2.0f;
|
||||
return static_cast<float>(x < 0.5 ? 4 * EaseInCubic(x) : 1 - std::pow(-2 * x + 2, 3) / 2.0);
|
||||
}
|
||||
|
||||
/* Quint functions */
|
||||
|
||||
float EaseInQuint(float x) {
|
||||
return x * EaseInQuart(x);
|
||||
return static_cast<float>(x * EaseInQuart(x));
|
||||
}
|
||||
|
||||
float EaseOutQuint(float x) {
|
||||
return 1 - std::pow(1 - x, 5);
|
||||
return static_cast<float>(1 - std::pow(1 - x, 5));
|
||||
}
|
||||
|
||||
float EaseInOutQuint(float x) {
|
||||
return x < 0.5 ? 16 * EaseInQuint(x) : 1 - std::pow(-2 * x + 2, 5) / 2.0f;
|
||||
return static_cast<float>(x < 0.5 ? 16 * EaseInQuint(x) : 1 - std::pow(-2 * x + 2, 5) / 2.0);
|
||||
}
|
||||
|
||||
/* Circ functions */
|
||||
|
||||
float EaseInCirc(float x) {
|
||||
return 1 - std::sqrt(1 - std::pow(x, 2));
|
||||
return static_cast<float>(1 - std::sqrt(1 - std::pow(x, 2)));
|
||||
}
|
||||
|
||||
float EaseOutCirc(float x) {
|
||||
return std::sqrt(1 - std::pow(x - 1, 2));
|
||||
return static_cast<float>(std::sqrt(1 - std::pow(x - 1, 2)));
|
||||
}
|
||||
|
||||
float EaseInOutCirc(float x) {
|
||||
return x < 0.5 ? (1 - std::sqrt(1 - std::pow(2 * x, 2))) / 2.0f : (std::sqrt(1 - std::pow(-2 * x + 2, 2)) + 1) / 2.0f;
|
||||
return static_cast<float>(
|
||||
x < 0.5 ? (1 - std::sqrt(1 - std::pow(2 * x, 2))) / 2.0 : (std::sqrt(1 - std::pow(-2 * x + 2, 2)) + 1) / 2.0);
|
||||
}
|
||||
|
||||
/* Elastic functions */
|
||||
|
||||
float EaseInElastic(float x) {
|
||||
const float c4 = (2 * maths::PI) / 3.0f;
|
||||
const float c4 = (2 * maths::PI) / 3.0;
|
||||
|
||||
return x == 0 ? 0 : x == 1 ? 1 : -std::pow(2, 10 * x - 10) * std::sin((x * 10 - 10.75) * c4);
|
||||
return static_cast<float>(x == 0 ? 0 : x == 1 ? 1 : -std::pow(2, 10 * x - 10) * std::sin((x * 10 - 10.75) * c4));
|
||||
}
|
||||
|
||||
float EaseOutElastic(float x) {
|
||||
const float c4 = (2 * maths::PI) / 3.0f;
|
||||
const float c4 = (2 * maths::PI) / 3.0;
|
||||
|
||||
return x == 0 ? 0 : x == 1 ? 1 : std::pow(2, -10 * x) * std::sin((x * 10 - 0.75) * c4) + 1;
|
||||
return static_cast<float>(x == 0 ? 0 : x == 1 ? 1 : std::pow(2, -10 * x) * std::sin((x * 10 - 0.75) * c4) + 1);
|
||||
}
|
||||
|
||||
float EaseInOutElastic(float x) {
|
||||
const float c5 = (2 * maths::PI) / 4.5;
|
||||
|
||||
return x == 0 ? 0
|
||||
: x == 1 ? 1
|
||||
: x < 0.5 ? -(std::pow(2, 20 * x - 10) * std::sin((20 * x - 11.125) * c5)) / 2.0f
|
||||
: (std::pow(2, -20 * x + 10) * std::sin((20 * x - 11.125) * c5)) / 2.0f + 1;
|
||||
return static_cast<float>(x == 0 ? 0
|
||||
: x == 1 ? 1
|
||||
: x < 0.5 ? -(std::pow(2, 20 * x - 10) * std::sin((20 * x - 11.125) * c5)) / 2.0
|
||||
: (std::pow(2, -20 * x + 10) * std::sin((20 * x - 11.125) * c5)) / 2.0 + 1);
|
||||
}
|
||||
|
||||
/* Quad functions */
|
||||
|
||||
float EaseInQuad(float x) {
|
||||
return x * x;
|
||||
return static_cast<float>(x * x);
|
||||
}
|
||||
|
||||
float EaseOutQuad(float x) {
|
||||
return 1 - (1 - x) * (1 - x);
|
||||
return static_cast<float>(1 - (1 - x) * (1 - x));
|
||||
}
|
||||
|
||||
float EaseInOutQuad(float x) {
|
||||
return x < 0.5 ? 2 * x * x : 1 - std::pow(-2 * x + 2, 2) / 2.0f;
|
||||
return static_cast<float>(x < 0.5 ? 2 * x * x : 1 - std::pow(-2 * x + 2, 2) / 2.0);
|
||||
}
|
||||
|
||||
/* Quart functions */
|
||||
|
||||
float EaseInQuart(float x) {
|
||||
return x * EaseInCubic(x);
|
||||
return static_cast<float>(x * EaseInCubic(x));
|
||||
}
|
||||
|
||||
float EaseOutQuart(float x) {
|
||||
return 1 - std::pow(1 - x, 4);
|
||||
return static_cast<float>(1 - std::pow(1 - x, 4));
|
||||
}
|
||||
|
||||
float EaseInOutQuart(float x) {
|
||||
return x < 0.5 ? 8 * EaseInQuart(x) : 1 - std::pow(-2 * x + 2, 4) / 2.0f;
|
||||
return static_cast<float>(x < 0.5 ? 8 * EaseInQuart(x) : 1 - std::pow(-2 * x + 2, 4) / 2.0);
|
||||
}
|
||||
|
||||
/* Expo functions */
|
||||
|
||||
float EaseInExpo(float x) {
|
||||
return x == 0 ? 0 : std::pow(2, 10 * x - 10);
|
||||
return static_cast<float>(x == 0 ? 0 : std::pow(2, 10 * x - 10));
|
||||
}
|
||||
|
||||
float EaseOutExpo(float x) {
|
||||
return x == 1 ? 1 : 1 - std::pow(2, -10 * x);
|
||||
return static_cast<float>(x == 1 ? 1 : 1 - std::pow(2, -10 * x));
|
||||
}
|
||||
|
||||
float EaseInOutExpo(float x) {
|
||||
return x == 0 ? 0 : x == 1 ? 1 : x < 0.5 ? std::pow(2, 20 * x - 10) / 2.0f : (2 - std::pow(2, -20 * x + 10)) / 2.0f;
|
||||
return static_cast<float>(x == 0 ? 0
|
||||
: x == 1 ? 1
|
||||
: x < 0.5 ? std::pow(2, 20 * x - 10) / 2.0
|
||||
: (2 - std::pow(2, -20 * x + 10)) / 2.0);
|
||||
}
|
||||
|
||||
/* Back functions */
|
||||
@@ -134,28 +138,28 @@ float EaseInBack(float x) {
|
||||
const float c1 = 1.70158;
|
||||
const float c3 = c1 + 1;
|
||||
|
||||
return c3 * EaseInCubic(x) - c1 * EaseInQuad(x);
|
||||
return static_cast<float>(c3 * EaseInCubic(x) - c1 * EaseInQuad(x));
|
||||
}
|
||||
|
||||
float EaseOutBack(float x) {
|
||||
const float c1 = 1.70158;
|
||||
const float c3 = c1 + 1;
|
||||
|
||||
return 1 + c3 * std::pow(x - 1, 3) + c1 * std::pow(x - 1, 2);
|
||||
return static_cast<float>(1 + c3 * std::pow(x - 1, 3) + c1 * std::pow(x - 1, 2));
|
||||
}
|
||||
|
||||
float EaseInOutBack(float x) {
|
||||
const float c1 = 1.70158;
|
||||
const float c2 = c1 * 1.525;
|
||||
|
||||
return x < 0.5 ? (std::pow(2 * x, 2) * ((c2 + 1) * 2 * x - c2)) / 2.0f
|
||||
: (std::pow(2 * x - 2, 2) * ((c2 + 1) * (x * 2 - 2) + c2) + 2) / 2.0f;
|
||||
return static_cast<float>(x < 0.5 ? (std::pow(2 * x, 2) * ((c2 + 1) * 2 * x - c2)) / 2.0
|
||||
: (std::pow(2 * x - 2, 2) * ((c2 + 1) * (x * 2 - 2) + c2) + 2) / 2.0);
|
||||
}
|
||||
|
||||
/* Bounce functions */
|
||||
|
||||
float EaseInBounce(float x) {
|
||||
return 1 - EaseOutBounce(1 - x);
|
||||
return static_cast<float>(1 - EaseOutBounce(1 - x));
|
||||
}
|
||||
|
||||
float EaseOutBounce(float x) {
|
||||
@@ -163,21 +167,21 @@ float EaseOutBounce(float x) {
|
||||
const float d1 = 2.75;
|
||||
|
||||
if (x < 1 / d1) {
|
||||
return n1 * EaseInQuad(x);
|
||||
return static_cast<float>(n1 * EaseInQuad(x));
|
||||
} else if (x < 2 / d1) {
|
||||
x -= 1.5;
|
||||
return n1 * (x / d1) * x + 0.75;
|
||||
return static_cast<float>(n1 * (x / d1) * x + 0.75);
|
||||
} else if (x < 2.5 / d1) {
|
||||
x -= 2.25;
|
||||
return n1 * (x / d1) * x + 0.9375;
|
||||
return static_cast<float>(n1 * (x / d1) * x + 0.9375);
|
||||
} else {
|
||||
x -= 2.625;
|
||||
return n1 * (x / d1) * x + 0.984375;
|
||||
return static_cast<float>(n1 * (x / d1) * x + 0.984375);
|
||||
}
|
||||
}
|
||||
|
||||
float EaseInOutBounce(float x) {
|
||||
return x < 0.5 ? (1 - EaseOutBounce(1 - 2 * x)) / 2.0f : (1 + EaseOutBounce(2 * x - 1)) / 2.0f;
|
||||
return static_cast<float>(x < 0.5 ? (1 - EaseOutBounce(1 - 2 * x)) / 2.0 : (1 + EaseOutBounce(2 * x - 1)) / 2.0);
|
||||
}
|
||||
|
||||
} // namespace utils
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
#include "blitz/misc/Log.h"
|
||||
|
||||
#if defined(__ANDROID__) and not defined(BLITZ_HEADLESS)
|
||||
#define BLITZ_ANDROID_LOGGING
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef BLITZ_ANDROID_LOGGING
|
||||
#include <android/log.h>
|
||||
|
||||
@@ -6,7 +6,7 @@ namespace blitz {
|
||||
namespace utils {
|
||||
|
||||
void TickCounter::Reset() {
|
||||
m_TPS = m_TargetTPS;
|
||||
m_TPS = static_cast<float>(m_TargetTPS);
|
||||
m_LastTPSTime = utils::GetTime();
|
||||
m_TickCount = 0;
|
||||
}
|
||||
|
||||
@@ -11,14 +11,14 @@
|
||||
namespace blitz {
|
||||
namespace network {
|
||||
|
||||
TCPListener::TCPListener() : m_Handle(INVALID_SOCKET), m_Port(0), m_MaxConnections(0) {}
|
||||
TCPListener::TCPListener() : m_Handle(static_cast<blitz::network::SocketHandle>(INVALID_SOCKET)), m_Port(0), m_MaxConnections(0) {}
|
||||
|
||||
TCPListener::~TCPListener() {
|
||||
Destroy();
|
||||
}
|
||||
|
||||
bool TCPListener::Listen(std::uint16_t port, int maxConnections) {
|
||||
if ((m_Handle = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) {
|
||||
if ((m_Handle = static_cast<SocketHandle>(socket(AF_INET, SOCK_STREAM, IPPROTO_TCP))) < 0) {
|
||||
utils::LOGE("[TCPListener] Failed to create server socket !");
|
||||
return false;
|
||||
}
|
||||
@@ -47,8 +47,8 @@ bool TCPListener::Listen(std::uint16_t port, int maxConnections) {
|
||||
bool TCPListener::Accept(TCPSocket& newSocket) {
|
||||
int addrlen = sizeof(newSocket.m_RemoteAddr);
|
||||
|
||||
newSocket.m_Handle =
|
||||
accept(m_Handle, reinterpret_cast<sockaddr*>(&newSocket.m_RemoteAddr), reinterpret_cast<socklen_t*>(&addrlen));
|
||||
newSocket.m_Handle = static_cast<SocketHandle>(
|
||||
accept(m_Handle, reinterpret_cast<sockaddr*>(&newSocket.m_RemoteAddr), reinterpret_cast<socklen_t*>(&addrlen)));
|
||||
|
||||
if (newSocket.m_Handle < 0)
|
||||
return false;
|
||||
|
||||
@@ -83,12 +83,14 @@ bool TCPSocket::Connect(const std::string& host, unsigned short port) {
|
||||
return false;
|
||||
}
|
||||
|
||||
m_Handle = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
|
||||
m_Handle = static_cast<SocketHandle>(socket(AF_INET, SOCK_STREAM, IPPROTO_TCP));
|
||||
if (m_Handle < 0) {
|
||||
utils::LOGE("[TCPSocket] Failed to create socket !");
|
||||
return false;
|
||||
}
|
||||
|
||||
SetBlocking(m_Blocking);
|
||||
|
||||
struct addrinfo* ptr = nullptr;
|
||||
for (ptr = result; ptr != nullptr; ptr = ptr->ai_next) {
|
||||
struct sockaddr* sockaddr = ptr->ai_addr;
|
||||
@@ -120,9 +122,10 @@ size_t TCPSocket::Send(const unsigned char* data, size_t size) {
|
||||
std::size_t sent = 0;
|
||||
|
||||
while (sent < size) {
|
||||
int cur = send(m_Handle, reinterpret_cast<const char*>(data + sent), size - sent, 0);
|
||||
int cur = send(m_Handle, reinterpret_cast<const char*>(data + sent), static_cast<int>(size - sent), 0);
|
||||
if (cur <= 0) {
|
||||
Disconnect();
|
||||
m_Status = Status::Error;
|
||||
return 0;
|
||||
}
|
||||
sent += static_cast<std::size_t>(cur);
|
||||
@@ -135,7 +138,7 @@ std::size_t TCPSocket::Receive(DataBuffer& buffer, std::size_t amount) {
|
||||
buffer.Resize(amount);
|
||||
buffer.SetReadOffset(0);
|
||||
|
||||
int recvAmount = recv(m_Handle, reinterpret_cast<char*>(buffer.data()), amount, 0);
|
||||
int recvAmount = recv(m_Handle, reinterpret_cast<char*>(buffer.data()), static_cast<int>(amount), 0);
|
||||
if (recvAmount <= 0) {
|
||||
#if defined(_WIN32) || defined(WIN32)
|
||||
int err = WSAGetLastError();
|
||||
@@ -149,6 +152,7 @@ std::size_t TCPSocket::Receive(DataBuffer& buffer, std::size_t amount) {
|
||||
|
||||
Disconnect();
|
||||
buffer.Clear();
|
||||
m_Status = Status::Error;
|
||||
return 0;
|
||||
}
|
||||
buffer.Resize(static_cast<std::size_t>(recvAmount));
|
||||
|
||||
@@ -20,7 +20,9 @@ static std::array<PacketPtr, static_cast<std::size_t>(PacketType::PACKET_COUNT)>
|
||||
std::make_unique<PlayerLeavePacket>(),
|
||||
std::make_unique<PlayerListPacket>(),
|
||||
std::make_unique<PlayerStatsPacket>(),
|
||||
std::make_unique<ServerConfigPacket>(),
|
||||
std::make_unique<ServerTpsPacket>(),
|
||||
std::make_unique<UpdateGameStatePacket>(),
|
||||
std::make_unique<KeepAlivePacket>(),
|
||||
std::make_unique<DisconnectPacket>(),
|
||||
std::make_unique<ChatPacket>(),
|
||||
|
||||
@@ -27,6 +27,8 @@ REGISTER_DISPATCH_CLASS(PlayerPositionAndRotationPacket)
|
||||
REGISTER_DISPATCH_CLASS(PlayerShootPacket);
|
||||
REGISTER_DISPATCH_CLASS(UpdateHealthPacket);
|
||||
REGISTER_DISPATCH_CLASS(PlayerStatsPacket);
|
||||
REGISTER_DISPATCH_CLASS(UpdateGameStatePacket);
|
||||
REGISTER_DISPATCH_CLASS(ServerConfigPacket);
|
||||
|
||||
} // namespace protocol
|
||||
} // namespace blitz
|
||||
|
||||
@@ -83,7 +83,7 @@ ColoredText ChatPacket::ColorizeText(const std::string& text) {
|
||||
static_cast<float>(std::stoul(green, nullptr, 16)) / 255.0f,
|
||||
static_cast<float>(std::stoul(blue, nullptr, 16)) / 255.0f, 1.0f};
|
||||
cursor += 6;
|
||||
} catch (std::exception& e) {
|
||||
} catch (std::exception&) {
|
||||
utils::LOG("[ChatPacket] warning ! wrong color providen !");
|
||||
}
|
||||
break;
|
||||
|
||||
19
src/blitz/protocol/packets/ServerConfigPacket.cpp
Normal file
19
src/blitz/protocol/packets/ServerConfigPacket.cpp
Normal file
@@ -0,0 +1,19 @@
|
||||
#include "blitz/protocol/packets/ServerConfigPacket.h"
|
||||
|
||||
namespace blitz {
|
||||
namespace protocol {
|
||||
|
||||
DataBuffer ServerConfigPacket::Serialize(bool packetID) const {
|
||||
DataBuffer data;
|
||||
|
||||
WritePacketID(data, packetID);
|
||||
data << m_GameConfig;
|
||||
return data;
|
||||
}
|
||||
|
||||
void ServerConfigPacket::Deserialize(DataBuffer& data) {
|
||||
data >> m_GameConfig;
|
||||
}
|
||||
|
||||
} // namespace protocol
|
||||
} // namespace blitz
|
||||
19
src/blitz/protocol/packets/UpdateGameStatePacket.cpp
Normal file
19
src/blitz/protocol/packets/UpdateGameStatePacket.cpp
Normal file
@@ -0,0 +1,19 @@
|
||||
#include "blitz/protocol/packets/UpdateGameStatePacket.h"
|
||||
|
||||
namespace blitz {
|
||||
namespace protocol {
|
||||
|
||||
DataBuffer UpdateGameStatePacket::Serialize(bool packetID) const {
|
||||
DataBuffer data;
|
||||
|
||||
WritePacketID(data, packetID);
|
||||
data << m_GameState << m_TimeRemaining;
|
||||
return data;
|
||||
}
|
||||
|
||||
void UpdateGameStatePacket::Deserialize(DataBuffer& data) {
|
||||
data >> m_GameState >> m_TimeRemaining;
|
||||
}
|
||||
|
||||
} // namespace protocol
|
||||
} // namespace blitz
|
||||
@@ -36,6 +36,12 @@ bool Client::JoinGame(const std::string& pseudo, const std::string& address, std
|
||||
return m_Connexion->Connect(pseudo, address, port);
|
||||
}
|
||||
|
||||
void Client::UpdateServerConfig() {
|
||||
m_Server->GetGame().LoadConfig(m_Config.GetServerConfig());
|
||||
|
||||
m_Server->GetGame().SendServerConfig();
|
||||
}
|
||||
|
||||
bool Client::CreateGame(std::uint16_t port, const std::string& pseudo) {
|
||||
if (!m_Server->Start(port, false))
|
||||
return false;
|
||||
@@ -45,6 +51,8 @@ bool Client::CreateGame(std::uint16_t port, const std::string& pseudo) {
|
||||
return false;
|
||||
}
|
||||
|
||||
UpdateServerConfig();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -71,7 +79,7 @@ void Client::SendChatText(const std::string& text) {
|
||||
}
|
||||
|
||||
void Client::ChatTextReceived(const protocol::ColoredText& text) {
|
||||
NotifyListeners(&GuiListener::OnTextChatReceived, text);
|
||||
NotifyListeners(&game::ClientListener::OnTextChatReceived, text);
|
||||
}
|
||||
|
||||
void Client::SendPlayerPosAndLook(const Vec3f& position, float yaw, float pitch) {
|
||||
|
||||
@@ -37,10 +37,13 @@ void BlitzConfig::LoadConfig() {
|
||||
std::memcpy(m_Pseudo.data(), pseudo.data(), pseudo.size() + 1);
|
||||
jsonInput.at("vsync").get_to<bool>(m_VSync);
|
||||
jsonInput.at("fps").get_to<bool>(m_DisplayFps);
|
||||
jsonInput.at("sensitivity").get_to<float>(m_MouseSpeed);
|
||||
jsonInput.at("gravity").get_to<float>(m_ServerConfig.Gravity);
|
||||
jsonInput.at("firingrate").get_to<int>(m_ServerConfig.FiringRate);
|
||||
jsonInput.at("keys").get_to<Keybinds>(m_Keybinds);
|
||||
|
||||
utils::LOG("[BlitzConfig] Restored config !");
|
||||
} catch (std::exception& e) {
|
||||
} catch (std::exception&) {
|
||||
utils::LOGE("[BlitzConfig] Failed to load config !");
|
||||
}
|
||||
}
|
||||
@@ -50,7 +53,10 @@ void BlitzConfig::LoadDefaultConfig() {
|
||||
m_VSync = true;
|
||||
const char defaultPseudo[] = "Pseudo";
|
||||
std::memcpy(m_Pseudo.data(), defaultPseudo, sizeof(defaultPseudo));
|
||||
m_Keybinds = {ImGuiKey_Z, ImGuiKey_S, ImGuiKey_D, ImGuiKey_Q};
|
||||
m_MouseSpeed = 0.0025f;
|
||||
m_ServerConfig.Gravity = 20.0f;
|
||||
m_ServerConfig.FiringRate = 60;
|
||||
m_Keybinds = {ImGuiKey_Z, ImGuiKey_S, ImGuiKey_D, ImGuiKey_Q, ImGuiKey_P};
|
||||
}
|
||||
|
||||
void BlitzConfig::SaveConfig() {
|
||||
@@ -64,6 +70,9 @@ void BlitzConfig::SaveConfig() {
|
||||
{"pseudo", GetPseudo().data()},
|
||||
{"vsync", IsVSyncEnabled()},
|
||||
{"fps", IsFPSDisplayEnabled()},
|
||||
{"sensitivity", GetMouseSpeed()},
|
||||
{"gravity", GetServerConfig().Gravity},
|
||||
{"firingrate", GetServerConfig().FiringRate},
|
||||
{"keys", GetKeys()},
|
||||
};
|
||||
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
|
||||
#include "client/gui/BlitzGui.h"
|
||||
|
||||
#ifndef BLITZ_GL_LOADER_GLBNIDING
|
||||
#ifdef BLITZ_GL_LOADER_GLEW
|
||||
#include <GL/glew.h>
|
||||
#else
|
||||
#include <glbinding/glbinding.h>
|
||||
@@ -97,7 +97,7 @@ bool Display::Create() {
|
||||
SDL_GL_MakeCurrent(m_Window, m_GL_Context);
|
||||
SDL_GL_SetSwapInterval(1);
|
||||
|
||||
#ifndef BLITZ_GL_LOADER_GLBNIDING
|
||||
#ifdef BLITZ_GL_LOADER_GLEW
|
||||
GLenum error = glewInit();
|
||||
if (error != GLEW_OK) {
|
||||
utils::LOGE(utils::Format("[Display] Failed to initialise glew : %s", glewGetErrorString(error)));
|
||||
@@ -218,11 +218,12 @@ void Display::InitImGui() {
|
||||
ImGui_ImplOpenGL3_Init();
|
||||
|
||||
ImFontConfig c;
|
||||
c.SizePixels = 25;
|
||||
c.SizePixels = 25.0f;
|
||||
ImGui::GetIO().Fonts->AddFontDefault(&c);
|
||||
// doom font
|
||||
DataBuffer doomFontFile = utils::AssetsManager::GetAsset("doom.ttf");
|
||||
auto* doomFont = ImGui::GetIO().Fonts->AddFontFromMemoryTTF(doomFontFile.HeapAllocatedData(), doomFontFile.GetSize(), 25);
|
||||
auto* doomFont =
|
||||
ImGui::GetIO().Fonts->AddFontFromMemoryTTF(doomFontFile.HeapAllocatedData(), static_cast<int>(doomFontFile.GetSize()), 25.0f);
|
||||
ImGui::GetIO().FontDefault = doomFont;
|
||||
|
||||
#ifndef __ANDROID__
|
||||
|
||||
@@ -3,9 +3,10 @@
|
||||
#include "blitz/game/Player.h"
|
||||
#include "blitz/maths/Maths.h"
|
||||
#include "blitz/misc/Log.h"
|
||||
#include "blitz/maths/Maths.h"
|
||||
#include "client/Client.h"
|
||||
#include "client/config/BlitzConfig.h"
|
||||
#include "client/display/InputManager.h"
|
||||
#include "client/game/ClientGame.h"
|
||||
#include "imgui.h"
|
||||
#include <algorithm>
|
||||
#include <iostream>
|
||||
@@ -14,7 +15,6 @@ namespace blitz {
|
||||
namespace input {
|
||||
|
||||
static constexpr float DEFAULT_JUMP_VEL = 7.5;
|
||||
static constexpr float DEFAULT_GRAVITY = 20.0;
|
||||
static constexpr float DEFAULT_MAX_LR_SPEED = 10.;
|
||||
static constexpr float DEFAULT_MAX_FB_SPEED = 10.;
|
||||
static constexpr float DEFAULT_LR_SPEED_SMOOTHING_TIME = 1.0;
|
||||
@@ -23,13 +23,8 @@ static constexpr float DEFAULT_FB_SPEED_SMOOTHING_TIME = 1.0;
|
||||
PlayerController::PlayerController(Client* client) :
|
||||
m_Player(nullptr),
|
||||
m_Client(client),
|
||||
m_Dx(0.0),
|
||||
m_Dy(0.0),
|
||||
m_Dz(0.0),
|
||||
m_MaxDx(DEFAULT_MAX_LR_SPEED),
|
||||
m_MaxDy(DEFAULT_MAX_FB_SPEED),
|
||||
m_MaxDz(DEFAULT_JUMP_VEL),
|
||||
m_G(DEFAULT_GRAVITY),
|
||||
m_Velocity({}),
|
||||
m_MaxVelocity(DEFAULT_MAX_LR_SPEED, DEFAULT_MAX_FB_SPEED, DEFAULT_JUMP_VEL),
|
||||
m_OnGround(true) {
|
||||
m_DxSmoother.Current = 0.0f;
|
||||
m_DySmoother.Current = 0.0f;
|
||||
@@ -37,13 +32,23 @@ PlayerController::PlayerController(Client* client) :
|
||||
m_DySmoother.SetSmoothingTime(DEFAULT_FB_SPEED_SMOOTHING_TIME);
|
||||
InputManager::BindMouseMoveCallback(
|
||||
std::bind(&PlayerController::MouseMotionEvent, this, std::placeholders::_1, std::placeholders::_2));
|
||||
client->BindListener(this);
|
||||
}
|
||||
|
||||
void PlayerController::OnGameConfigUpdate() {
|
||||
UpdateShootTimer(m_Client->GetGame()->GetGameConfig().FiringRate);
|
||||
}
|
||||
|
||||
void PlayerController::UpdateShootTimer(int bpm) {
|
||||
m_ShootTimer.SetCooldown(60.0f / static_cast<float>(bpm));
|
||||
m_ShootTimer.Reset();
|
||||
}
|
||||
|
||||
void PlayerController::MouseMotionEvent(int deltaX, int deltaY) {
|
||||
if (!m_Player || !InputManager::MouseGrabbed())
|
||||
return;
|
||||
|
||||
static const float MouseSpeed = 0.0025f;
|
||||
float MouseSpeed = m_Client->GetConfig()->GetMouseSpeed();
|
||||
|
||||
m_Player->AddYaw(deltaX * MouseSpeed);
|
||||
m_Player->AddPitch(deltaY * -MouseSpeed);
|
||||
@@ -64,20 +69,22 @@ void PlayerController::Update(float delta) {
|
||||
// scale values in such a way that clamps ||(lr, fb)|| to 1.0
|
||||
float scale = 1.0f / std::max(sqrt(lr * lr + fb * fb), 1.0f);
|
||||
|
||||
m_Dx = lr * m_MaxDx * scale;
|
||||
m_Dy = fb * m_MaxDy * scale;
|
||||
m_Velocity.x = lr * m_MaxVelocity.x * scale;
|
||||
m_Velocity.y = fb * m_MaxVelocity.y * scale;
|
||||
|
||||
if (ImGui::IsKeyDown(ImGuiKey::ImGuiKey_Space) && m_OnGround) {
|
||||
m_Dz = m_MaxDz;
|
||||
m_Velocity.z = m_MaxVelocity.z;
|
||||
NotifyListeners(&game::PlayerInputListener::OnLocalPlayerJump);
|
||||
}
|
||||
|
||||
bool canShoot = m_ShootTimer.Update(delta);
|
||||
bool canShoot = m_ShootTimer.Update(ImGui::GetIO().DeltaTime);
|
||||
if (ImGui::IsMouseDown(ImGuiMouseButton_Left) && canShoot) {
|
||||
NotifyListeners(
|
||||
&game::PlayerInputListener::OnLocalPlayerShoot, m_Player->GetPosition(), m_Player->GetYaw(), m_Player->GetPitch());
|
||||
m_ShootTimer.ApplyCooldown();
|
||||
}
|
||||
} else {
|
||||
m_Velocity.x = m_Velocity.y = 0.0f;
|
||||
}
|
||||
|
||||
UpdatePosition(delta);
|
||||
@@ -89,8 +96,8 @@ void PlayerController::UpdatePosition(const float delta) {
|
||||
float sine = std::sin(yaw);
|
||||
float cosine = std::cos(yaw);
|
||||
|
||||
m_DxSmoother.Tick(m_Dx, delta);
|
||||
m_DySmoother.Tick(m_Dy, delta);
|
||||
m_DxSmoother.Tick(m_Velocity.x, delta);
|
||||
m_DySmoother.Tick(m_Velocity.y, delta);
|
||||
|
||||
float dx_smooth = m_DxSmoother.Current;
|
||||
float dy_smooth = m_DySmoother.Current;
|
||||
@@ -98,7 +105,7 @@ void PlayerController::UpdatePosition(const float delta) {
|
||||
float dx = (dx_smooth * cosine + dy_smooth * sine) * delta;
|
||||
float dy = (dx_smooth * sine - dy_smooth * cosine) * delta;
|
||||
|
||||
float dz = m_Dz * delta;
|
||||
float dz = m_Velocity.z * delta;
|
||||
|
||||
// the floor here is y-level zero, once downwards collision lands it will be dynmicallly calculated
|
||||
// assumed to be a negative number
|
||||
@@ -106,9 +113,9 @@ void PlayerController::UpdatePosition(const float delta) {
|
||||
|
||||
if ((m_OnGround = (dz <= floor_dist))) {
|
||||
dz = floor_dist;
|
||||
m_Dz = 0.0f;
|
||||
m_Velocity.z = 0.0f;
|
||||
} else {
|
||||
m_Dz -= m_G * delta;
|
||||
m_Velocity.z -= m_Client->GetGame()->GetGameConfig().Gravity * 1.0f * delta;
|
||||
}
|
||||
|
||||
m_Player->AddPosition({dx, dz, dy});
|
||||
|
||||
@@ -9,6 +9,8 @@
|
||||
#include "blitz/protocol/packets/PlayerPositionAndRotationPacket.h"
|
||||
#include "blitz/protocol/packets/PlayerShootPacket.h"
|
||||
#include "blitz/protocol/packets/PlayerStatsPacket.h"
|
||||
#include "blitz/protocol/packets/ServerConfigPacket.h"
|
||||
#include "blitz/protocol/packets/UpdateGameStatePacket.h"
|
||||
#include "blitz/protocol/packets/UpdateHealthPacket.h"
|
||||
#include "client/Client.h"
|
||||
|
||||
@@ -24,6 +26,15 @@ ClientGame::~ClientGame() {
|
||||
GetDispatcher()->UnregisterHandler(this);
|
||||
}
|
||||
|
||||
void ClientGame::AddPlayer(game::PlayerID player, const std::string& name) {
|
||||
Game::AddPlayer(player, name);
|
||||
m_LeaderBoard.AddPlayer(GetPlayerById(player));
|
||||
}
|
||||
void ClientGame::RemovePlayer(game::PlayerID player) {
|
||||
Game::RemovePlayer(player);
|
||||
m_LeaderBoard.RemovePlayer(player);
|
||||
}
|
||||
|
||||
void ClientGame::RegisterHandlers() {
|
||||
GetDispatcher()->RegisterHandler(protocol::PacketType::PlayerJoin, this);
|
||||
GetDispatcher()->RegisterHandler(protocol::PacketType::PlayerLeave, this);
|
||||
@@ -31,7 +42,9 @@ void ClientGame::RegisterHandlers() {
|
||||
GetDispatcher()->RegisterHandler(protocol::PacketType::PlayerPositionAndRotation, this);
|
||||
GetDispatcher()->RegisterHandler(protocol::PacketType::PlayerShoot, this);
|
||||
GetDispatcher()->RegisterHandler(protocol::PacketType::PlayerStats, this);
|
||||
GetDispatcher()->RegisterHandler(protocol::PacketType::UpdateGameState, this);
|
||||
GetDispatcher()->RegisterHandler(protocol::PacketType::UpdateHealth, this);
|
||||
GetDispatcher()->RegisterHandler(protocol::PacketType::ServerConfig, this);
|
||||
}
|
||||
|
||||
void ClientGame::HandlePacket(const protocol::PlayerJoinPacket* packet) {
|
||||
@@ -39,7 +52,7 @@ void ClientGame::HandlePacket(const protocol::PlayerJoinPacket* packet) {
|
||||
|
||||
// Initialize camera
|
||||
if (packet->GetPlayerID() == m_Client->GetPlayerID()) {
|
||||
m_Client->NotifyListeners(&GuiListener::OnSpectatorChange, packet->GetPlayerID());
|
||||
m_Client->NotifyListeners(&game::ClientListener::OnSpectatorChange, packet->GetPlayerID());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -57,6 +70,8 @@ void ClientGame::HandlePacket(const protocol::PlayerStatsPacket* packet) {
|
||||
game::Player* player = m_Client->GetGame()->GetPlayerById(packet->GetPlayerID());
|
||||
assert(player);
|
||||
player->SetStats(packet->GetPlayerStats());
|
||||
|
||||
m_LeaderBoard.Update();
|
||||
}
|
||||
|
||||
void ClientGame::HandlePacket(const protocol::UpdateHealthPacket* packet) {
|
||||
@@ -69,10 +84,20 @@ void ClientGame::HandlePacket(const protocol::UpdateHealthPacket* packet) {
|
||||
}
|
||||
}
|
||||
|
||||
void ClientGame::HandlePacket(const protocol::UpdateGameStatePacket* packet) {
|
||||
m_GameState = packet->GetGameState();
|
||||
m_GameTimer.SetInterval(packet->GetTimeRemaining());
|
||||
m_GameTimer.Reset();
|
||||
}
|
||||
|
||||
void ClientGame::HandlePacket(const protocol::ServerConfigPacket* packet) {
|
||||
m_Config = packet->GetGameConfig();
|
||||
m_Client->NotifyListeners(&game::ClientListener::OnGameConfigUpdate);
|
||||
}
|
||||
|
||||
void ClientGame::HandlePacket(const protocol::PlayerShootPacket* packet) {
|
||||
m_Client->NotifyListeners(
|
||||
&GuiListener::OnPlayerShoot, packet->GetPlayer(), packet->GetPosition(), packet->GetYaw(), packet->GetPitch());
|
||||
&game::ClientListener::OnPlayerShoot, packet->GetPlayer(), packet->GetPosition(), packet->GetYaw(), packet->GetPitch());
|
||||
}
|
||||
|
||||
void ClientGame::HandlePacket(const protocol::PlayerPositionAndRotationPacket* packet) {
|
||||
@@ -93,6 +118,11 @@ void ClientGame::Tick(std::uint64_t delta) {
|
||||
for (auto& [playerId, player] : GetPlayers()) {
|
||||
player.SetPosition(player.GetPosition() + player.GetVelocity() * (static_cast<float>(delta) / 100.0f));
|
||||
}
|
||||
if (m_GameTimer.GetInterval() > 0) {
|
||||
if (m_GameTimer.Update(delta)) {
|
||||
m_GameTimer.SetInterval(0); // disables the timer so it does not loop
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace client
|
||||
|
||||
@@ -3,8 +3,8 @@
|
||||
#include "client/gui/Crosshair.h"
|
||||
#include "client/gui/GameChatGui.h"
|
||||
#include "client/gui/Hud.h"
|
||||
#include "client/gui/LeaderBoardGui.h"
|
||||
#include "client/gui/MainMenu.h"
|
||||
#include "client/gui/LeaderBoard.h"
|
||||
#include "client/gui/ServerGui.h"
|
||||
#include <imgui.h>
|
||||
|
||||
@@ -17,7 +17,7 @@ BlitzGui::BlitzGui(Client* client) : GuiWidget(nullptr, client) {
|
||||
AddWidget(std::make_unique<MainMenu>(client));
|
||||
AddWidget(std::make_unique<CrossHair>(client));
|
||||
AddWidget(std::make_unique<Hud>(this, client));
|
||||
AddWidget(std::make_unique<LeaderBoard>(this, client));
|
||||
AddWidget(std::make_unique<LeaderBoardGui>(this, client));
|
||||
AddWidget(std::make_unique<ServerGui>(this, client));
|
||||
SetCustomTheme();
|
||||
}
|
||||
@@ -31,6 +31,10 @@ void BlitzGui::SetCustomTheme() {
|
||||
const static ImVec4 colorButtonHover = {0.56f, 0.02f, 0.02f, 1.0f};
|
||||
const static ImVec4 colorButtonActive = {0.36f, 0.03f, 0.03f, 1.0f};
|
||||
const static ImVec4 colorCheckMark = {1.0f, 1.0f, 1.0f, 1.0f};
|
||||
const static ImVec4 colorTab = {0.38f, 0.02f, 0.02f, 1.0f};
|
||||
const static ImVec4 colorTabHover = {0.74f, 0.0f, 0.0f, 0.73f};
|
||||
const static ImVec4 colorTabActive = {1.0f, 0.0f, 0.0f, 0.73f};
|
||||
|
||||
|
||||
ImGui::GetStyle().Colors[ImGuiCol_Button] = colorButton;
|
||||
ImGui::GetStyle().Colors[ImGuiCol_ButtonActive] = colorButtonActive;
|
||||
@@ -39,6 +43,15 @@ void BlitzGui::SetCustomTheme() {
|
||||
ImGui::GetStyle().Colors[ImGuiCol_FrameBg] = colorButton;
|
||||
ImGui::GetStyle().Colors[ImGuiCol_FrameBgActive] = colorButtonActive;
|
||||
ImGui::GetStyle().Colors[ImGuiCol_FrameBgHovered] = colorButtonHover;
|
||||
ImGui::GetStyle().Colors[ImGuiCol_Tab] = colorTab;
|
||||
ImGui::GetStyle().Colors[ImGuiCol_TabHovered] = colorTabHover;
|
||||
ImGui::GetStyle().Colors[ImGuiCol_TabActive] = colorTabActive;
|
||||
ImGui::GetStyle().Colors[ImGuiCol_TitleBgActive] = colorTabActive;
|
||||
ImGui::GetStyle().Colors[ImGuiCol_SliderGrab] = colorButton;
|
||||
ImGui::GetStyle().Colors[ImGuiCol_SliderGrabActive] = colorButton;
|
||||
ImGui::GetStyle().Colors[ImGuiCol_HeaderActive] = colorTab;
|
||||
ImGui::GetStyle().Colors[ImGuiCol_HeaderHovered] = colorTabActive;
|
||||
ImGui::GetStyle().Colors[ImGuiCol_Header] = colorTabActive;
|
||||
}
|
||||
|
||||
} // namespace gui
|
||||
|
||||
@@ -22,9 +22,9 @@ GameChatGui::GameChatGui(GuiWidget* parent, Client* client) : GuiWidget(parent,
|
||||
|
||||
void GameChatGui::Draw(const char* title, bool* p_open) {
|
||||
HistoryPos = -1;
|
||||
static int chat_width = 620;
|
||||
static int chat_height = 450;
|
||||
static int chatInput_width = 590;
|
||||
static float chat_width = 620.0f;
|
||||
static float chat_height = 450.0f;
|
||||
static float chatInput_width = 590.0f;
|
||||
ImGui::SetNextWindowPos(ImVec2(0, ImGui::GetIO().DisplaySize.y - 2 * chat_height));
|
||||
ImGui::SetNextWindowSize(ImVec2(chat_width, chat_height));
|
||||
// const float footer_height_to_reserve = ImGui::GetStyle().ItemSpacing.y + ImGui::GetFrameHeightWithSpacing();
|
||||
@@ -60,9 +60,9 @@ void GameChatGui::Draw(const char* title, bool* p_open) {
|
||||
}
|
||||
|
||||
void GameChatGui::DrawMini(const char* title, bool* p_open) {
|
||||
static int chat_width = 620;
|
||||
static int chat_height = 225;
|
||||
ImGui::SetNextWindowPos(ImVec2(0, ImGui::GetIO().DisplaySize.y - 3.5 * chat_height));
|
||||
static float chat_width = 620.0f;
|
||||
static float chat_height = 225.0f;
|
||||
ImGui::SetNextWindowPos(ImVec2(0.0f, ImGui::GetIO().DisplaySize.y - 3.5f * chat_height));
|
||||
ImGui::SetNextWindowSize(ImVec2(chat_width, chat_height));
|
||||
ImGui::Begin(title, p_open, GetWindowFullScreenFlags() | ImGuiWindowFlags_NoNav);
|
||||
{
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
#include "client/Client.h"
|
||||
#include "client/game/ClientGame.h"
|
||||
#include "client/gui/ColorFulText.h"
|
||||
#include "client/gui/GuiWidget.h"
|
||||
#include "client/render/loader/TextureLoader.h"
|
||||
#include <imgui.h>
|
||||
@@ -11,7 +12,7 @@ namespace gui {
|
||||
|
||||
Hud::Hud(GuiWidget* parent, Client* client) : GuiWidget(parent, client) {
|
||||
m_GunTexture = TextureLoader::LoadGLTexture("fingergun.png");
|
||||
m_JP = TextureLoader::LoadGLTexture("jp.png");
|
||||
m_JPTexture = TextureLoader::LoadGLTexture("jp.png");
|
||||
}
|
||||
|
||||
void Hud::Draw(const char* title, bool* p_open) {
|
||||
@@ -20,7 +21,6 @@ void Hud::Draw(const char* title, bool* p_open) {
|
||||
ImGui::Begin(title, nullptr, GetWindowFullScreenFlags() | ImGuiWindowFlags_NoInputs);
|
||||
|
||||
auto displaySize = ImGui::GetIO().DisplaySize;
|
||||
ImVec2 center = ImGui::GetMainViewport()->GetCenter();
|
||||
|
||||
const static ImVec2 buttonSize = {300, 60};
|
||||
const static ImVec2 fingergunSize = {256, 134.5};
|
||||
@@ -34,17 +34,16 @@ void Hud::Draw(const char* title, bool* p_open) {
|
||||
displaySize.x - fingergunSize.x - paddingHeight, displaySize.y - fingergunSize.y + 1.0f / 2.5f * paddingHeight};
|
||||
ImVec2 spacing = ImGui::GetStyle().ItemInnerSpacing;
|
||||
|
||||
const float timetextWidth = ImGui::CalcTextSize("03 : 00").x;
|
||||
const float timetextHeight = ImGui::CalcTextSize("03 : 00").y;
|
||||
|
||||
ImGui::SetCursorPosX(center.x - timetextWidth / 2);
|
||||
ImGui::SetCursorPosY(timetextHeight / 2);
|
||||
ImGui::Text("03 : 00");
|
||||
std::string timeFormated = FormatString();
|
||||
ImVec2 center = ImGui::GetMainViewport()->GetCenter();
|
||||
const float timetextWidth = ImGui::CalcTextSize(timeFormated.c_str()).x;
|
||||
const float timetextHeight = ImGui::CalcTextSize(timeFormated.c_str()).y;
|
||||
RenderTime(center.x - timetextWidth / 2, timetextHeight / 2);
|
||||
|
||||
ImGui::SetCursorPosX(3 * paddingHeight);
|
||||
ImGui::SetCursorPosY(pvBarPos.y - 2 * paddingHeight);
|
||||
ImGui::BeginGroup();
|
||||
ImGui::Image(reinterpret_cast<ImTextureID>(m_JP), jpSize);
|
||||
ImGui::Image(reinterpret_cast<ImTextureID>(m_JPTexture), jpSize);
|
||||
|
||||
ImGui::SameLine(0.0f, paddingHeight);
|
||||
|
||||
@@ -78,11 +77,87 @@ void Hud::Draw(const char* title, bool* p_open) {
|
||||
ImGui::End();
|
||||
}
|
||||
|
||||
std::string Hud::FormatString() {
|
||||
std::string timeFormated;
|
||||
|
||||
std::uint64_t timeRemaining = m_Client->GetGame()->GetGameStateRemainingTime();
|
||||
|
||||
if (timeRemaining == 0) {
|
||||
timeFormated = "En attente de joueurs ...";
|
||||
} else {
|
||||
timeRemaining += 1000;
|
||||
|
||||
int seconds = timeRemaining / 1000 % 60;
|
||||
int minutes = static_cast<int>(timeRemaining) / 1000 / 60;
|
||||
|
||||
timeFormated = (minutes < 10 ? "0" + std::to_string(minutes) : std::to_string(minutes)) + " : " +
|
||||
(seconds < 10 ? "0" + std::to_string(seconds) : std::to_string(seconds));
|
||||
}
|
||||
|
||||
return timeFormated;
|
||||
}
|
||||
|
||||
void Hud::RenderTime(float positionX, float positionY) {
|
||||
std::string timeFormated = FormatString();
|
||||
|
||||
ImGui::SetCursorPosX(positionX);
|
||||
ImGui::SetCursorPosY(positionY);
|
||||
ImGui::Text("%s", timeFormated.c_str());
|
||||
}
|
||||
|
||||
void Hud::DrawFinishScreen(bool win) {
|
||||
SetNextWindowFullScreen();
|
||||
ImGui::Begin("FinishScreen", nullptr, GetWindowFullScreenFlags() | ImGuiWindowFlags_NoInputs);
|
||||
{
|
||||
std::string timeFormated = FormatString();
|
||||
ImVec2 center = ImGui::GetMainViewport()->GetCenter();
|
||||
const float timetextWidth = ImGui::CalcTextSize(timeFormated.c_str()).x;
|
||||
|
||||
std::string nextPartyString = "Prochaine partie dans";
|
||||
const float nextPartyTextWidth = ImGui::CalcTextSize(nextPartyString.c_str()).x;
|
||||
|
||||
std::string victoryString = "VICTOIRE";
|
||||
std::string defeatString = "DEFAITE";
|
||||
|
||||
ImGui::SetCursorPos({center.x - nextPartyTextWidth / 2, (8.5f / 10.0f) * ImGui::GetIO().DisplaySize.y});
|
||||
ImGui::Text("%s", nextPartyString.c_str());
|
||||
|
||||
RenderTime(center.x - timetextWidth / 2, (9.0f / 10.0f) * ImGui::GetIO().DisplaySize.y);
|
||||
|
||||
if (!m_Timer.Update(ImGui::GetIO().DeltaTime)) {
|
||||
ImGui::SetWindowFontScale(3.0f);
|
||||
const float victoryTextWidth = ImGui::CalcTextSize(victoryString.c_str()).x;
|
||||
const float defeatTextWidth = ImGui::CalcTextSize(defeatString.c_str()).x;
|
||||
|
||||
if (win) {
|
||||
ImGui::SetCursorPos({center.x - victoryTextWidth / 2, center.y - victoryTextWidth / 2});
|
||||
ImGui::TextColored(ImVec4(0.0f, 1.0f, 0.0f, 1.0f), "VICTOIRE");
|
||||
} else {
|
||||
ImGui::SetCursorPos({center.x - defeatTextWidth / 2, center.y - defeatTextWidth / 2});
|
||||
ImGui::TextColored(ImVec4(1.0f, 0.0f, 0.0f, 1.0f), "DEFAITE");
|
||||
}
|
||||
ImGui::SetWindowFontScale(1.0f);
|
||||
}
|
||||
}
|
||||
ImGui::End();
|
||||
}
|
||||
|
||||
void Hud::Render() {
|
||||
if (!m_Client->IsConnected())
|
||||
return;
|
||||
|
||||
Draw("Hud Blitz", nullptr);
|
||||
switch (m_Client->GetGame()->GetGameState()) {
|
||||
case game::GameState::gsEnd: {
|
||||
game::Player* firstPlayer = m_Client->GetGame()->GetLeaderBoard().GetPlayers().front();
|
||||
if (!firstPlayer)
|
||||
return;
|
||||
DrawFinishScreen(firstPlayer->GetID() == m_Client->GetPlayerID());
|
||||
break;
|
||||
}
|
||||
default:
|
||||
Draw("Hud Blitz", nullptr);
|
||||
break;
|
||||
}
|
||||
}
|
||||
} // namespace gui
|
||||
} // namespace blitz
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#include "client/gui/LeaderBoard.h"
|
||||
#include "client/gui/LeaderBoardGui.h"
|
||||
|
||||
#include "blitz/misc/Format.h"
|
||||
#include "blitz/misc/Log.h"
|
||||
@@ -10,13 +10,13 @@
|
||||
namespace blitz {
|
||||
namespace gui {
|
||||
|
||||
LeaderBoard::LeaderBoard(GuiWidget* parent, Client* client) : GuiWidget(parent, client) {}
|
||||
LeaderBoardGui::LeaderBoardGui(GuiWidget* parent, Client* client) : GuiWidget(parent, client) {}
|
||||
|
||||
LeaderBoard::~LeaderBoard() {}
|
||||
LeaderBoardGui::~LeaderBoardGui() {}
|
||||
|
||||
void LeaderBoard::Draw(const char* title, bool* p_open) {
|
||||
static int leaderboard_width = 640;
|
||||
static int leaderboard_height = 450;
|
||||
void LeaderBoardGui::Draw(const char* title, bool* p_open) {
|
||||
static float leaderboard_width = 640.0f;
|
||||
static float leaderboard_height = 450.0f;
|
||||
|
||||
ImGuiWindowFlags leaderboard_flags =
|
||||
ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoSavedSettings | ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoResize;
|
||||
@@ -31,20 +31,21 @@ void LeaderBoard::Draw(const char* title, bool* p_open) {
|
||||
std::string deathsLeaderBoard = "Deaths";
|
||||
std::string kdLeaderBoard = "K/D";
|
||||
std::string precisionLeaderBoard = "Accuracy";
|
||||
for (auto [id, player] : m_Client->GetGame()->GetPlayers()) {
|
||||
playerLeaderBoard += utils::Format("\n%s", player.GetName().c_str());
|
||||
killsLeaderBoard += utils::Format("\n%i", player.GetStats().m_Kills);
|
||||
deathsLeaderBoard += utils::Format("\n%i", player.GetStats().m_Deaths);
|
||||
for (game::Player* player : m_Client->GetGame()->GetLeaderBoard().GetPlayers()) {
|
||||
playerLeaderBoard += utils::Format("\n%s", player->GetName().c_str());
|
||||
killsLeaderBoard += utils::Format("\n%i", player->GetStats().m_Kills);
|
||||
deathsLeaderBoard += utils::Format("\n%i", player->GetStats().m_Deaths);
|
||||
|
||||
// Check if the denominator is zero before calculating K/D ratio
|
||||
float kdRatio =
|
||||
(player.GetStats().m_Deaths != 0) ? static_cast<float>(player.GetStats().m_Kills) / player.GetStats().m_Deaths : 0.0f;
|
||||
float kdRatio = (player->GetStats().m_Deaths != 0)
|
||||
? static_cast<float>(player->GetStats().m_Kills) / player->GetStats().m_Deaths
|
||||
: 0.0f;
|
||||
kdLeaderBoard += utils::Format("\n%.2f", kdRatio);
|
||||
|
||||
// Check if the denominator is zero before calculating precision percentage
|
||||
float precisionPercentage =
|
||||
(player.GetStats().m_ShootCount != 0)
|
||||
? static_cast<float>(player.GetStats().m_ShootSuccessCount) / player.GetStats().m_ShootCount * 100.0f
|
||||
(player->GetStats().m_ShootCount != 0)
|
||||
? static_cast<float>(player->GetStats().m_ShootSuccessCount) / player->GetStats().m_ShootCount * 100.0f
|
||||
: 0.0f;
|
||||
precisionLeaderBoard += utils::Format("\n%.2f%%", precisionPercentage);
|
||||
}
|
||||
@@ -61,13 +62,21 @@ void LeaderBoard::Draw(const char* title, bool* p_open) {
|
||||
ImGui::End();
|
||||
}
|
||||
|
||||
void LeaderBoard::Render() {
|
||||
void LeaderBoardGui::Render() {
|
||||
if (!m_Client->IsConnected())
|
||||
return;
|
||||
|
||||
if (ImGui::IsKeyDown(ImGuiKey_Tab)) {
|
||||
if (ImGui::IsKeyDown(ImGuiKey_Tab) && !(m_Client->GetGame()->GetGameState() == game::GameState::gsEnd)) {
|
||||
Draw("Leaderboard", nullptr);
|
||||
}
|
||||
|
||||
if (m_Client->GetGame()->GetGameState() == game::GameState::gsEnd) {
|
||||
if (m_Timer.Update(ImGui::GetIO().DeltaTime)) {
|
||||
Draw("Leaderboard", nullptr);
|
||||
}
|
||||
} else {
|
||||
m_Timer.Reset();
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace gui
|
||||
@@ -16,6 +16,7 @@ static std::string ActionNames[kaMax] = {
|
||||
"Reculer",
|
||||
"Droite",
|
||||
"Gauche",
|
||||
"Fenetre Admin",
|
||||
};
|
||||
|
||||
|
||||
@@ -75,7 +76,7 @@ void OptionsMenu::HotkeyBindingPopUp() {
|
||||
ImGui::SameLine();
|
||||
ImGui::TextColored(ImVec4(1.0f, 1.0f, 0.0f, 1.0f), "%s", GetKeyActionCodeName(m_CurrentAction).c_str());
|
||||
|
||||
if (m_KeyPopupShouldClose && m_Timer.Update(ImGui::GetIO().DeltaTime * 1000)) {
|
||||
if (m_KeyPopupShouldClose && m_Timer.Update(static_cast<std::uint64_t>(ImGui::GetIO().DeltaTime * 1000.0f))) {
|
||||
m_KeyPopupShouldClose = false;
|
||||
m_IsKeyPopupOpen = false;
|
||||
ImGui::CloseCurrentPopup();
|
||||
@@ -163,12 +164,14 @@ void OptionsMenu::Render() {
|
||||
ImGuiTabBarFlags tab_bar_flags = ImGuiTabBarFlags_None;
|
||||
if (ImGui::BeginTabBar("OPTIONS", tab_bar_flags)) {
|
||||
if (ImGui::BeginTabItem("CONTROLES")) {
|
||||
// Always center this window when appearing
|
||||
ImVec2 center = ImGui::GetMainViewport()->GetCenter();
|
||||
ImGui::SetNextWindowPos(center, ImGuiCond_Appearing, ImVec2(0.5f, 0.5f));
|
||||
|
||||
HotkeyBindingButton();
|
||||
HotkeyBindingPopUp();
|
||||
float sensitivity = m_Client->GetConfig()->GetMouseSpeed() * 200.0f;
|
||||
ImGui::SetNextItemWidth(300.0f);
|
||||
if (ImGui::DragFloat("Sensibilite", &sensitivity, 0.005f, 0.001f, 10.0f, "%.3f")) {
|
||||
sensitivity = std::clamp(sensitivity, 0.001f, 10.0f);
|
||||
m_Client->GetConfig()->SetMouseSpeed(sensitivity / 200.0f);
|
||||
}
|
||||
ImGui::EndTabItem();
|
||||
}
|
||||
if (ImGui::BeginTabItem("GRAPHISMES")) {
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
#include "client/gui/ServerGui.h"
|
||||
|
||||
#include "client/Client.h"
|
||||
#include "client/display/InputManager.h"
|
||||
#include "server/Server.h"
|
||||
#include "server/game/ServerGame.h"
|
||||
#include <imgui.h>
|
||||
|
||||
namespace blitz {
|
||||
@@ -13,17 +15,112 @@ void ServerGui::Render() {
|
||||
if (!m_Client->IsAdmin())
|
||||
return;
|
||||
|
||||
if (ImGui::IsKeyPressed(ImGuiKey_P)) {
|
||||
ImGui::OpenPopup("Admin panel");
|
||||
Keybinds keys = m_Client->GetConfig()->GetKeys();
|
||||
if (ImGui::IsKeyPressed(ImGuiKey(keys[kaFenetreAdmin])) && InputManager::MouseGrabbed()) {
|
||||
ImGui::OpenPopup("FENETRE D'ADMIN");
|
||||
}
|
||||
|
||||
static bool popup_opened = true;
|
||||
ImGuiWindowFlags servergui_flags =
|
||||
ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoSavedSettings | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoScrollbar;
|
||||
ImVec2 center = ImGui::GetMainViewport()->GetCenter();
|
||||
static float servergui_width = 640.0f;
|
||||
static float servergui_height = 640.0f;
|
||||
|
||||
// this is uggly but okay for now
|
||||
if (ImGui::BeginPopupModal("Admin panel", &popup_opened)) {
|
||||
if (ImGui::Button("Add Bot")) {
|
||||
const static ImVec2 buttonSize = {300, 60};
|
||||
|
||||
ImGui::SetNextWindowPos(center, ImGuiCond_Appearing, ImVec2(0.5f, 0.5f));
|
||||
ImGui::SetNextWindowSize(ImVec2(servergui_width, servergui_height));
|
||||
if (ImGui::BeginPopupModal("FENETRE D'ADMIN", nullptr, servergui_flags)) {
|
||||
InputManager::GrabMouse(false);
|
||||
|
||||
ImGui::BeginChild("Mutateurs PARTIE", ImVec2(servergui_width * (5.0f / 10.0f), 0.0f), true);
|
||||
ImGui::Text("PARTIE");
|
||||
ImGui::NewLine();
|
||||
|
||||
if (ImGui::Button("Ajouter Bot", buttonSize)) {
|
||||
m_Client->GetServer()->AddBot();
|
||||
}
|
||||
|
||||
ImGui::NewLine();
|
||||
ImGui::Text("GRAVITE");
|
||||
float gravity[] = {20.0f, 7.0f, 40.0f};
|
||||
const char* planetes[] = {"Terrestre", "Lunaire", "Solaire"};
|
||||
static int item_current_idx;
|
||||
float currentGravity = m_Client->GetConfig()->GetServerConfig().Gravity;
|
||||
for (int n = 0; n < IM_ARRAYSIZE(planetes); n++) {
|
||||
if (gravity[n] == currentGravity) {
|
||||
item_current_idx = n;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (ImGui::BeginListBox("##Gravity", ImVec2(300.0f, 100.0f))) {
|
||||
for (int n = 0; n < IM_ARRAYSIZE(planetes); n++) {
|
||||
const bool is_selected = (item_current_idx == n);
|
||||
if (ImGui::Selectable(planetes[n], is_selected)) {
|
||||
item_current_idx = n;
|
||||
m_Client->GetConfig()->GetServerConfig().Gravity = gravity[n];
|
||||
m_Client->UpdateServerConfig();
|
||||
}
|
||||
|
||||
if (is_selected)
|
||||
ImGui::SetItemDefaultFocus();
|
||||
}
|
||||
ImGui::EndListBox();
|
||||
}
|
||||
|
||||
ImGui::NewLine();
|
||||
int& firingrate = m_Client->GetConfig()->GetServerConfig().FiringRate;
|
||||
ImGui::SetNextItemWidth(300.0f);
|
||||
if (ImGui::DragInt("##CADENCE TIR", &firingrate, 1, 1, 1000)) {
|
||||
firingrate = std::clamp(firingrate, 1, 1000);
|
||||
m_Client->UpdateServerConfig();
|
||||
}
|
||||
ImGui::Text("Cpm/Rpm %i", firingrate);
|
||||
|
||||
ImGui::SetCursorPosY(servergui_height - 2.0f * buttonSize.y);
|
||||
if (ImGui::Button("Retour", buttonSize)) {
|
||||
ImGui::CloseCurrentPopup();
|
||||
InputManager::GrabMouse(true);
|
||||
}
|
||||
ImGui::EndChild();
|
||||
|
||||
ImGui::SameLine();
|
||||
|
||||
ImGui::BeginChild("MUTATEUR TEMPS", ImVec2(servergui_width * (4.5f / 10.0f), 0.0f), true);
|
||||
static int gameDurMin = static_cast<int>(m_Client->GetServer()->GetGame().GetServerDuration().m_GameDuration / 1000) / 60;
|
||||
static int gameDurSec = static_cast<int>(m_Client->GetServer()->GetGame().GetServerDuration().m_GameDuration / 1000) % 60;
|
||||
|
||||
ImGui::Text("TEMPS");
|
||||
ImGui::NewLine();
|
||||
|
||||
ImGui::Text("DUREE PARTIE");
|
||||
std::string min = "Min";
|
||||
std::string sec = "Sec";
|
||||
|
||||
for (std::size_t i = 0; i < 2; ++i) {
|
||||
ImGui::PushID(static_cast<int>(i));
|
||||
if (i == 0) {
|
||||
ImGui::Text("%s", min.c_str());
|
||||
ImGui::SameLine();
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_GrabMinSize, 40);
|
||||
if (ImGui::VSliderInt("##Min", ImVec2(40, 160), &gameDurMin, 1, 10)) {
|
||||
m_Client->GetServer()->GetGame().GetServerDuration().m_GameDuration = (gameDurMin * 60 + gameDurSec) * 1000;
|
||||
}
|
||||
ImGui::PopStyleVar();
|
||||
} else {
|
||||
ImGui::SameLine(0.0f, ImGui::GetStyle().ItemInnerSpacing.x * 10);
|
||||
ImGui::Text("%s", sec.c_str());
|
||||
ImGui::SameLine();
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_GrabMinSize, 40);
|
||||
if (ImGui::VSliderInt("##Sec", ImVec2(40, 160), &gameDurSec, 0, 59)) {
|
||||
m_Client->GetServer()->GetGame().GetServerDuration().m_GameDuration = (gameDurMin * 60 + gameDurSec) * 1000;
|
||||
}
|
||||
ImGui::PopStyleVar();
|
||||
}
|
||||
ImGui::PopID();
|
||||
}
|
||||
|
||||
ImGui::EndChild();
|
||||
ImGui::EndPopup();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,7 +23,7 @@ BulletRenderer::BulletRenderer(const Camera& camera) : m_Camera(camera) {
|
||||
|
||||
BulletRenderer::~BulletRenderer() {}
|
||||
|
||||
void BulletRenderer::AddBullet(const Vec3f& origin, float yaw, float pitch) {
|
||||
void BulletRenderer::AddBullet(const Vec3f& origin, float yaw, float pitch, bool firstPersson) {
|
||||
static const float TRAIL_LENGHT = 50;
|
||||
|
||||
Vec3f direction = {
|
||||
@@ -34,8 +34,17 @@ void BulletRenderer::AddBullet(const Vec3f& origin, float yaw, float pitch) {
|
||||
|
||||
Vec3f middle = origin + direction * (TRAIL_LENGHT / 2.0f);
|
||||
|
||||
Mat4f rotate = maths::Dot(maths::RotateX(-pitch), maths::RotateY(yaw + maths::PI / 2));
|
||||
Mat4f scale = maths::Scale({0.01, 0.01, TRAIL_LENGHT / 2.0f - 0.2f});
|
||||
static const float RotateXClient = 0.0008f;
|
||||
static const float RotateYClient = 0.0025f;
|
||||
static const float TrailCutClient = 0.4f;
|
||||
|
||||
float rotateX = firstPersson ? RotateXClient : 0.0f;
|
||||
float rotateY = firstPersson ? RotateYClient : 0.0f;
|
||||
float trailCut = firstPersson ? TrailCutClient : 0.2f;
|
||||
|
||||
|
||||
Mat4f rotate = maths::Dot(maths::RotateX(-pitch - rotateX), maths::RotateY(yaw + maths::PI / 2 - rotateY));
|
||||
Mat4f scale = maths::Scale({0.01f, 0.01f, TRAIL_LENGHT / 2.0f - trailCut});
|
||||
Mat4f translate = maths::Translate(middle);
|
||||
|
||||
Mat4f transform = maths::Dot(scale, maths::Dot(rotate, translate));
|
||||
@@ -70,7 +79,7 @@ void BulletRenderer::Render() {
|
||||
for (Trail& trail : m_Trails) {
|
||||
m_Shader->SetDecay(trail.m_Decay / BULLET_DECAY_TIME);
|
||||
m_Shader->SetTransform(trail.m_Transform);
|
||||
glDrawElements(GL_TRIANGLES, vao->GetVertexCount(), GL_UNSIGNED_INT, nullptr);
|
||||
glDrawElements(GL_TRIANGLES, static_cast<GLsizei>(vao->GetVertexCount()), GL_UNSIGNED_INT, nullptr);
|
||||
}
|
||||
vao->Unbind();
|
||||
}
|
||||
|
||||
@@ -10,8 +10,8 @@ namespace render {
|
||||
static const float EyeHeight = 1.25f;
|
||||
|
||||
void Camera::Update(float delta) {
|
||||
int windowWidth = ImGui::GetIO().DisplaySize.x;
|
||||
int windowHeight = ImGui::GetIO().DisplaySize.y;
|
||||
int windowWidth = static_cast<int>(ImGui::GetIO().DisplaySize.x);
|
||||
int windowHeight = static_cast<int>(ImGui::GetIO().DisplaySize.y);
|
||||
|
||||
if (windowWidth != m_LastWindowSize.x || windowHeight != m_LastWindowSize.y) {
|
||||
m_LastWindowSize = {windowWidth, windowHeight};
|
||||
|
||||
@@ -21,8 +21,8 @@
|
||||
namespace blitz {
|
||||
namespace render {
|
||||
|
||||
static const Vec4f SkyColor = {0.6, 0.8, 1, 1};
|
||||
static const Vec4f MenuColor = {0, 0, 0, 0};
|
||||
static const Vec4f SkyColor = {0.6f, 0.8f, 1.0f, 1.0f};
|
||||
static const Vec4f MenuColor = {0.0f, 0.0f, 0.0f, 0.0f};
|
||||
|
||||
MainRenderer::MainRenderer(Client* client) :
|
||||
m_Client(client), m_PlayerController(m_Client), m_ShootTime(0), m_BulletRenderer(m_Camera) {
|
||||
@@ -69,14 +69,14 @@ void MainRenderer::RenderEntity(const GL::VertexArray& vao, const Vec3f& positio
|
||||
m_EntityShader->Start();
|
||||
m_EntityShader->SetModelTransform(maths::Dot(maths::RotateY(yaw - maths::PI / 2.0f), maths::Translate(position)));
|
||||
vao.Bind();
|
||||
glDrawElements(GL_TRIANGLES, vao.GetVertexCount(), GL_UNSIGNED_INT, nullptr);
|
||||
glDrawElements(GL_TRIANGLES, static_cast<GLsizei>(vao.GetVertexCount()), GL_UNSIGNED_INT, nullptr);
|
||||
vao.Unbind();
|
||||
}
|
||||
|
||||
void MainRenderer::RenderWorld(const GL::VertexArray& vao) {
|
||||
m_WorldShader->Start();
|
||||
vao.Bind();
|
||||
glDrawElements(GL_TRIANGLES, vao.GetVertexCount(), GL_UNSIGNED_INT, nullptr);
|
||||
glDrawElements(GL_TRIANGLES, static_cast<GLsizei>(vao.GetVertexCount()), GL_UNSIGNED_INT, nullptr);
|
||||
vao.Unbind();
|
||||
}
|
||||
|
||||
@@ -106,12 +106,18 @@ void MainRenderer::RenderPlayers() {
|
||||
}
|
||||
}
|
||||
|
||||
void MainRenderer::OnGameConfigUpdate() {
|
||||
// we need to do that in order to prevent the animation from glitching
|
||||
m_ShootTime = 0.0f;
|
||||
}
|
||||
|
||||
void MainRenderer::OnLocalPlayerShoot(const Vec3f& position, float yaw, float pitch) {
|
||||
m_ShootTime = 1.0f;
|
||||
m_ShootTime = 60.0f / static_cast<float>(m_Client->GetGame()->GetGameConfig().FiringRate);
|
||||
}
|
||||
|
||||
void MainRenderer::OnPlayerShoot(game::PlayerID player, const Vec3f& position, float yaw, float pitch) {
|
||||
m_BulletRenderer.AddBullet(position + Vec3f{0.0f, Camera::GetPlayerEyeHeight(), 0.0f}, yaw, pitch);
|
||||
m_BulletRenderer.AddBullet(
|
||||
position + Vec3f{0.0f, Camera::GetPlayerEyeHeight(), 0.0f}, yaw, pitch, player == m_Client->GetPlayerID());
|
||||
}
|
||||
|
||||
void MainRenderer::RenderGun() {
|
||||
@@ -120,7 +126,7 @@ void MainRenderer::RenderGun() {
|
||||
|
||||
m_GunShader->Start();
|
||||
|
||||
float progression = 1.0f - m_ShootTime;
|
||||
float progression = 1.0f - (m_ShootTime / static_cast<float>(60.0f / m_Client->GetGame()->GetGameConfig().FiringRate));
|
||||
|
||||
float angle = progression * progression * progression * 7 - progression * progression * 11 + progression * 4;
|
||||
|
||||
@@ -129,7 +135,7 @@ void MainRenderer::RenderGun() {
|
||||
|
||||
for (auto& Vao : m_GunModel.mVaos) {
|
||||
Vao->Bind();
|
||||
glDrawElements(GL_TRIANGLES, Vao->GetVertexCount(), GL_UNSIGNED_INT, nullptr);
|
||||
glDrawElements(GL_TRIANGLES, static_cast<GLsizei>(Vao->GetVertexCount()), GL_UNSIGNED_INT, nullptr);
|
||||
Vao->Unbind();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -69,7 +69,7 @@ void VertexBuffer::BindVertexAttribs() const {
|
||||
for (const VertexAttribPointer& pointer : m_VertexAttribs) {
|
||||
glEnableVertexAttribArray(pointer.m_Index);
|
||||
glVertexAttribPointer(pointer.m_Index, static_cast<GLint>(pointer.m_Size), GL_FLOAT, false, m_DataStride * sizeof(float),
|
||||
reinterpret_cast<void*>(pointer.m_Offset));
|
||||
reinterpret_cast<GLvoid*>(static_cast<std::size_t>(pointer.m_Offset)));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -16,7 +16,8 @@ unsigned int LoadGLTexture(const std::string& fileName) {
|
||||
|
||||
DataBuffer buffer = utils::AssetsManager::GetAsset(fileName.c_str());
|
||||
|
||||
const unsigned char* image = stbi_load_from_memory(buffer.data(), buffer.GetSize(), &width, &height, &comp, STBI_default);
|
||||
const unsigned char* image =
|
||||
stbi_load_from_memory(buffer.data(), static_cast<int>(buffer.GetSize()), &width, &height, &comp, STBI_default);
|
||||
|
||||
if (image == nullptr) {
|
||||
utils::LOGE("[TextureLoader] Erreur lors du chargement de la texture !");
|
||||
|
||||
@@ -6,31 +6,32 @@ namespace shader {
|
||||
static const std::string vertexSource = ShaderProgram::GetShaderHeader() + R"(
|
||||
|
||||
layout(location = 0) in vec3 position;
|
||||
layout(location = 1) in float decay;
|
||||
|
||||
uniform mat4 viewMatrix;
|
||||
uniform mat4 projectionMatrix;
|
||||
uniform mat4 modelMatrix;
|
||||
|
||||
out float pass_decay;
|
||||
out float pass_position;
|
||||
|
||||
void main(void){
|
||||
vec4 worldPos = modelMatrix * vec4(position, 1.0);
|
||||
pass_decay = decay;
|
||||
pass_position = position.z;
|
||||
gl_Position = projectionMatrix * viewMatrix * worldPos;
|
||||
}
|
||||
)";
|
||||
|
||||
static const std::string fragmentSource = ShaderProgram::GetShaderHeader() + R"(
|
||||
|
||||
in float pass_decay;
|
||||
in float pass_position;
|
||||
|
||||
out vec4 out_color;
|
||||
|
||||
uniform float alpha;
|
||||
|
||||
void main(void){
|
||||
out_color = vec4(1.0, 0.0, 0.0, alpha);
|
||||
float red = cos(pass_position * 100.0 - alpha * 100.0);
|
||||
float capped = (red + 1.0) / 2.0 + 0.5;
|
||||
out_color = vec4(1.0, 0.0, 0.0, alpha * capped);
|
||||
}
|
||||
)";
|
||||
|
||||
|
||||
@@ -33,7 +33,7 @@ void Server::ServerLoop() {
|
||||
if (delta >= SERVER_TICK) {
|
||||
Tick(delta);
|
||||
lastTime = utils::GetTime();
|
||||
m_TickCounter.SetMSPT(lastTime - time);
|
||||
m_TickCounter.SetMSPT(static_cast<float>(lastTime - time));
|
||||
std::uint64_t sleepTime = SERVER_TICK - (delta - SERVER_TICK);
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(sleepTime));
|
||||
}
|
||||
@@ -105,7 +105,7 @@ void Server::Accept() {
|
||||
if (m_Listener.Accept(newSocket)) {
|
||||
game::PlayerID newPlayerID = GetNewPlayerID();
|
||||
auto con = std::make_unique<ServerConnexion>(this, newSocket, newPlayerID);
|
||||
m_Connections.insert(std::move(ConnexionMap::value_type{newPlayerID, std::move(con)}));
|
||||
m_Connections.insert(ConnexionMap::value_type{newPlayerID, std::move(con)});
|
||||
m_Connections[newPlayerID]->Start();
|
||||
newPlayerID++;
|
||||
}
|
||||
@@ -119,7 +119,7 @@ game::PlayerID Server::GetNewPlayerID() {
|
||||
}
|
||||
|
||||
void Server::UpdateSockets() {
|
||||
static std::vector<std::int16_t> closeConnexions;
|
||||
static std::vector<std::uint8_t> closeConnexions;
|
||||
for (auto& connection : m_Connections) {
|
||||
auto& con = connection.second;
|
||||
if (con->GetSocketStatus() != network::TCPSocket::Status::Connected) {
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
#include "blitz/protocol/packets/PlayerLoginPacket.h"
|
||||
#include "blitz/protocol/packets/PlayerPositionAndRotationPacket.h"
|
||||
#include "blitz/protocol/packets/PlayerShootPacket.h"
|
||||
#include "blitz/protocol/packets/ServerConfigPacket.h"
|
||||
#include "blitz/protocol/packets/UpdateGameStatePacket.h"
|
||||
#include "client/gui/ColorFulText.h"
|
||||
#include "server/Server.h"
|
||||
#include <unordered_map>
|
||||
@@ -94,6 +96,8 @@ void ServerConnexion::InitPlayerChatColor() {
|
||||
void ServerConnexion::HandlePacket(const protocol::PlayerLoginPacket* packet) {
|
||||
|
||||
SendPlayers();
|
||||
SendGameState();
|
||||
SendServerConfig();
|
||||
|
||||
m_Server->GetGame().AddPlayer(m_ID, packet->GetPlayerName());
|
||||
|
||||
@@ -143,6 +147,11 @@ void ServerConnexion::Start() {
|
||||
SendKeepAlive();
|
||||
}
|
||||
|
||||
void ServerConnexion::SendGameState() {
|
||||
protocol::UpdateGameStatePacket packet(m_Server->GetGame().GetGameState(), m_Server->GetGame().GetGameStateRemainingTime());
|
||||
SendPacket(&packet);
|
||||
}
|
||||
|
||||
void ServerConnexion::SendPlayers() {
|
||||
protocol::PlayerList list;
|
||||
|
||||
@@ -154,6 +163,11 @@ void ServerConnexion::SendPlayers() {
|
||||
SendPacket(&packet);
|
||||
}
|
||||
|
||||
void ServerConnexion::SendServerConfig() {
|
||||
protocol::ServerConfigPacket packet(m_Server->GetGame().GetGameConfig());
|
||||
SendPacket(&packet);
|
||||
}
|
||||
|
||||
void ServerConnexion::InitConnection() {
|
||||
protocol::ConnexionInfoPacket conPacket(m_ID);
|
||||
SendPacket(&conPacket);
|
||||
|
||||
@@ -8,6 +8,8 @@
|
||||
#include "blitz/protocol/packets/PlayerJoinPacket.h"
|
||||
#include "blitz/protocol/packets/PlayerPositionAndRotationPacket.h"
|
||||
#include "blitz/protocol/packets/PlayerStatsPacket.h"
|
||||
#include "blitz/protocol/packets/ServerConfigPacket.h"
|
||||
#include "blitz/protocol/packets/UpdateGameStatePacket.h"
|
||||
#include "blitz/protocol/packets/UpdateHealthPacket.h"
|
||||
#include "server/Server.h"
|
||||
#include <cmath>
|
||||
@@ -15,14 +17,48 @@
|
||||
namespace blitz {
|
||||
namespace server {
|
||||
|
||||
ServerGame::ServerGame(Server* server) : m_Server(server), m_PositionTimer(SERVER_TPS) {}
|
||||
ServerGame::ServerGame(Server* server) : m_Server(server), m_PositionTimer(SERVER_TPS) {
|
||||
CancelGame();
|
||||
}
|
||||
|
||||
ServerGame::~ServerGame() {}
|
||||
|
||||
void ServerGame::StartGame() {
|
||||
SetGameState(game::gsPreparing, m_ServerDuration.m_PrepDuration);
|
||||
m_Server->BroadcastChatMessage(protocol::ChatPacket::GetTextColor(protocol::AQUA) + "La partie commence dans 10s !");
|
||||
}
|
||||
|
||||
void ServerGame::CancelGame() {
|
||||
SetGameState(game::gsWaiting, 0);
|
||||
}
|
||||
|
||||
void ServerGame::Tick(std::uint64_t delta) {
|
||||
if (m_PositionTimer.Update(delta)) {
|
||||
SendPlayerPositions();
|
||||
}
|
||||
if (m_GameState != game::gsWaiting && m_GameTimer.Update(delta)) {
|
||||
switch (m_GameState) {
|
||||
case game::gsPreparing:
|
||||
SetGameState(game::gsGame, m_ServerDuration.m_GameDuration);
|
||||
break;
|
||||
|
||||
case game::gsGame:
|
||||
SetGameState(game::gsEnd, m_ServerDuration.m_EndDuration);
|
||||
break;
|
||||
|
||||
case game::gsEnd: {
|
||||
if (m_Players.size() > 1) {
|
||||
SetGameState(game::gsGame, m_ServerDuration.m_GameDuration);
|
||||
} else {
|
||||
SetGameState(game::gsWaiting, 0);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ServerGame::SendPlayerPositions() {
|
||||
@@ -70,10 +106,18 @@ void ServerGame::AddPlayer(game::PlayerID player, const std::string& name) {
|
||||
|
||||
utils::LOG("[Server] " + joinMessage);
|
||||
m_Server->BroadcastChatMessage(protocol::ChatPacket::GetTextColor(protocol::YELLOW) + joinMessage);
|
||||
|
||||
if (m_GameState == game::gsWaiting && m_Players.size() > 1) {
|
||||
StartGame();
|
||||
}
|
||||
}
|
||||
|
||||
void ServerGame::RemovePlayer(game::PlayerID player) {
|
||||
Game::RemovePlayer(player);
|
||||
|
||||
if (m_GameState == game::gsGame && m_Players.size() <= 1) {
|
||||
CancelGame();
|
||||
}
|
||||
}
|
||||
|
||||
void ServerGame::DamagePlayer(game::Player& player, game::Player& shooter) {
|
||||
@@ -110,5 +154,31 @@ void ServerGame::UpdatePlayerStats() {
|
||||
}
|
||||
}
|
||||
|
||||
void ServerGame::ResetPlayerStats() {
|
||||
for (auto& [playerId, player] : GetPlayers()) {
|
||||
player.GetStats() = {};
|
||||
}
|
||||
}
|
||||
|
||||
void ServerGame::SetGameState(game::GameState gameState, std::uint64_t duration) {
|
||||
m_GameState = gameState;
|
||||
m_GameTimer.SetInterval(duration);
|
||||
m_GameTimer.Reset();
|
||||
|
||||
if (gameState == game::gsGame) {
|
||||
ResetPlayerStats();
|
||||
UpdatePlayerStats();
|
||||
}
|
||||
|
||||
protocol::UpdateGameStatePacket packet(gameState, duration);
|
||||
m_Server->BroadcastPacket(&packet);
|
||||
}
|
||||
|
||||
void ServerGame::SendServerConfig() {
|
||||
protocol::ServerConfigPacket packet(m_Config);
|
||||
m_Server->BroadcastPacket(&packet);
|
||||
}
|
||||
|
||||
|
||||
} // namespace server
|
||||
} // namespace blitz
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
#include "blitz/misc/Test.h"
|
||||
|
||||
#include "blitz/misc/Random.h"
|
||||
#include "blitz/network/Network.h"
|
||||
#include "blitz/network/TCPListener.h"
|
||||
#include "blitz/network/TCPSocket.h"
|
||||
#include "blitz/misc/Random.h"
|
||||
|
||||
// Test the connection and disconnection of a TCPSocket
|
||||
void ConnectDisconnect() {
|
||||
@@ -40,6 +41,7 @@ void Listener() {
|
||||
}
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
blitz::network::NetworkInitializer network;
|
||||
ConnectDisconnect();
|
||||
Listener();
|
||||
return BLITZ_TEST_SUCCESSFUL;
|
||||
|
||||
@@ -1,7 +1,15 @@
|
||||
includes("Blitz.lua")
|
||||
|
||||
-- This should be temporary
|
||||
opengl = "glbinding"
|
||||
if is_plat("linux") and is_arch("arm64-v8a") then
|
||||
opengl = "glew"
|
||||
add_defines("BLITZ_GL_LOADER_GLEW")
|
||||
end
|
||||
|
||||
add_requires("libsdl 2.28.3", {configs = {sdlmain = false}})
|
||||
add_requires("glew", "assimp", "nlohmann_json")
|
||||
add_requires(opengl, "assimp 5.3.1", "nlohmann_json")
|
||||
|
||||
|
||||
-- Client binary (default)
|
||||
target("BlitzClient")
|
||||
@@ -18,7 +26,7 @@ target("BlitzClient")
|
||||
|
||||
-- Libraries
|
||||
add_deps("Blitz")
|
||||
add_packages("libsdl", "glew", "assimp", "nlohmann_json")
|
||||
add_packages("libsdl", opengl, "assimp", "nlohmann_json")
|
||||
|
||||
add_includedirs("../libs", "../libs/imgui")
|
||||
add_files("../libs/imgui/**.cpp")
|
||||
@@ -35,7 +43,7 @@ target("BlitzClient")
|
||||
-- Valgrind test
|
||||
if is_mode("valgrind") then
|
||||
on_run(function (target)
|
||||
os.cd("../assets")
|
||||
os.cd("assets")
|
||||
os.execv("valgrind", {"-s", "--leak-check=full", target:targetfile()})
|
||||
end)
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user