30 Commits

Author SHA1 Message Date
98fcb30f68 update color interface
All checks were successful
Linux arm64 / Build (push) Successful in 24m2s
2024-04-09 19:19:51 +02:00
048812090b fix assimp version
All checks were successful
Linux arm64 / Build (push) Successful in 22m33s
2024-04-09 10:08:43 +02:00
ad71bbbdf7 network: add error status
All checks were successful
Linux arm64 / Build (push) Successful in 6m15s
2024-04-06 12:28:45 +02:00
0bb7d28da8 fix join game freeze 2024-04-06 12:24:52 +02:00
8e13bac9d1 fix: build with glew only on CI
All checks were successful
Linux arm64 / Build (push) Successful in 4m55s
2024-04-03 11:09:20 +02:00
76b3057271 fix Android warnings 2024-04-03 10:59:16 +02:00
df4b1641d5 remove unsed assets
All checks were successful
Linux arm64 / Build (push) Successful in 5m42s
2024-04-02 22:46:09 +02:00
7daf2bae0c don't move player when menu is opened
All checks were successful
Linux arm64 / Build (push) Successful in 5m53s
2024-04-02 22:30:58 +02:00
a7b235da38 Possibilité de changer la cadence de tir (#33)
Some checks failed
Linux arm64 / Build (push) Has been cancelled
ajout d'un changement pour la cadence de tir

Co-authored-by: Morph01 <145839520+Morph01@users.noreply.github.com>
Co-authored-by: Persson-dev <sim16.prib@gmail.com>
Reviewed-on: #33
Reviewed-by: Simon Pribylski <sim16.prib@gmail.com>
Co-authored-by: Morph01 <thibaut6969delastreet@gmail.com>
Co-committed-by: Morph01 <thibaut6969delastreet@gmail.com>
2024-04-02 22:25:47 +02:00
e27cc29eb0 Réglage de la gravité (#31)
All checks were successful
Linux arm64 / Build (push) Successful in 5m4s
Fix #6

Co-authored-by: Morph01 <145839520+Morph01@users.noreply.github.com>
Reviewed-on: #31
Co-authored-by: Persson-dev <sim16.prib@gmail.com>
Co-committed-by: Persson-dev <sim16.prib@gmail.com>
2024-03-30 19:38:17 +01:00
d59467dd23 Le laser sort de la main à la première personne (#30)
Some checks are pending
Linux arm64 / Build (push) Waiting to run
Fix #25

Reviewed-on: #30
Co-authored-by: Persson-dev <sim16.prib@gmail.com>
Co-committed-by: Persson-dev <sim16.prib@gmail.com>
2024-03-30 19:37:40 +01:00
0ed577bbc2 On sait quand on gagne (#29)
Some checks are pending
Linux arm64 / Build (push) Waiting to run
L'écran de fin est mis à jour correctement selon si la victoire nous appartient ou non.
Le cas d'égalité n'est cependant pas traité ! Seulement un joueur peut gagner à l'état actuel

Reviewed-on: #29
Co-authored-by: Persson-dev <sim16.prib@gmail.com>
Co-committed-by: Persson-dev <sim16.prib@gmail.com>
2024-03-30 19:37:08 +01:00
aa29b9d718 use Vec3 for PlayerController members
All checks were successful
Linux arm64 / Build (push) Successful in 4m39s
2024-03-30 11:53:07 +01:00
1cce7fcd35 remove unused variable
All checks were successful
Linux arm64 / Build (push) Successful in 4m38s
2024-03-30 09:55:07 +01:00
9e93c1a1de better trail effect
All checks were successful
Linux arm64 / Build (push) Successful in 4m43s
2024-03-29 09:11:19 +01:00
4119fe37cc fix run dir 2024-03-29 09:11:01 +01:00
0511511702 Update BlitzClient.lua
All checks were successful
Linux arm64 / Build (push) Successful in 4m41s
2024-03-28 22:35:54 +01:00
2484eb5377 Chemtrails (#28)
All checks were successful
Linux arm64 / Build (push) Successful in 4m37s
Co-authored-by: Morph01 <145839520+Morph01@users.noreply.github.com>
Reviewed-on: #28
Co-authored-by: Persson-dev <sim16.prib@gmail.com>
Co-committed-by: Persson-dev <sim16.prib@gmail.com>
2024-03-28 21:42:26 +01:00
61ae530238 fiiiiiiiiiiiiiiix
All checks were successful
Linux arm64 / Build (push) Successful in 5m4s
2024-03-28 21:35:41 +01:00
Morph01
7c90ecfbd3 Refactor ServerGui.cpp: Remove unused variables
Some checks failed
Linux arm64 / Build (push) Has been cancelled
2024-03-28 21:33:39 +01:00
6e47fa6996 Add admin window and server duration settings (#27)
Some checks failed
Linux arm64 / Build (push) Failing after 3m33s
Fix #11

Co-authored-by: Morph01 <145839520+Morph01@users.noreply.github.com>
Reviewed-on: #27
2024-03-28 21:17:24 +01:00
83649ddbab fix linux build
Some checks failed
Linux arm64 / Build (push) Has been cancelled
2024-03-28 18:42:40 +01:00
Morph01
83c4599aa3 add finish screen
Some checks failed
Linux arm64 / Build (push) Failing after 2m55s
2024-03-28 18:29:52 +01:00
0247ee3cc1 add delay timer
All checks were successful
Linux arm64 / Build (push) Successful in 4m38s
2024-03-28 17:48:59 +01:00
Morph01
58b401f257 Update types of texture variables
All checks were successful
Linux arm64 / Build (push) Successful in 4m56s
2024-03-28 16:40:41 +01:00
c5b07e2ae6 fix network test for windows
All checks were successful
Linux arm64 / Build (push) Successful in 5m19s
2024-03-28 16:30:51 +01:00
507946a0f4 fix operator- for Vector
All checks were successful
Linux arm64 / Build (push) Successful in 4m41s
2024-03-28 16:14:01 +01:00
f9b79b0d64 Ajout d'états de jeu (#26)
All checks were successful
Linux arm64 / Build (push) Successful in 4m42s
La partie est d'abord en mode "Attente de joueurs"
Lorsque 2 joueurs sont présents, la partie passe en mode "Préparation" et un décompte de 10s commence
La partie passe ensuite en mode "Jeu" pendant 3 min
Pour finir, la partie passe en mode "Fin" pendant 30s pour rebasculer en mode "Jeu" si le nombre de joueurs est toujours suffisant.

Reviewed-on: #26
Co-authored-by: Persson-dev <sim16.prib@gmail.com>
Co-committed-by: Persson-dev <sim16.prib@gmail.com>
2024-03-28 15:58:39 +01:00
Morph01
78d68446f2 Fix data type inconsistencies lets cook
All checks were successful
Linux arm64 / Build (push) Successful in 4m39s
2024-03-28 15:32:08 +01:00
255eafa35e fix return type
All checks were successful
Linux arm64 / Build (push) Successful in 4m44s
2024-03-26 20:25:15 +01:00
67 changed files with 909 additions and 333 deletions

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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();
}
};

View 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

View File

@@ -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

View File

@@ -102,6 +102,10 @@ class Player {
m_IsBot = true;
}
const PlayerStats& GetStats() const {
return m_Stats;
}
PlayerStats& GetStats() {
return m_Stats;
}

View File

@@ -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>

View File

@@ -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

View File

@@ -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);
};

View File

@@ -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) {}
};

View File

@@ -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"

View File

@@ -14,7 +14,9 @@ class PlayerLoginPacket;
class PlayerPositionAndRotationPacket;
class PlayerShootPacket;
class PlayerStatsPacket;
class ServerConfigPacket;
class ServerTpsPacket;
class UpdateGameStatePacket;
class UpdateHealthPacket;
} // namespace protocol

View File

@@ -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

View 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

View 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

View File

@@ -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;
}

View File

@@ -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();

View File

@@ -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;

View File

@@ -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();

View File

@@ -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);
};

View File

@@ -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();

View File

@@ -7,7 +7,7 @@ namespace gui {
class CrossHair : public GuiWidget {
private:
int m_CrossHairTexture;
std::uint64_t m_CrossHairTexture;
public:
CrossHair(Client* client);

View File

@@ -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;
};

View File

@@ -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

View File

@@ -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;
};

View File

@@ -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();
};

View File

@@ -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);

View File

@@ -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>

View File

@@ -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();
}

View File

@@ -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

View File

@@ -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

View 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

View File

@@ -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;

View File

@@ -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;

View File

@@ -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

View File

@@ -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>

View File

@@ -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;
}

View File

@@ -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;

View File

@@ -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));

View File

@@ -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>(),

View File

@@ -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

View File

@@ -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;

View 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

View 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

View File

@@ -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) {

View File

@@ -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()},
};

View File

@@ -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__

View File

@@ -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});

View File

@@ -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

View File

@@ -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

View File

@@ -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);
{

View File

@@ -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

View File

@@ -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

View File

@@ -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")) {

View File

@@ -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();
}
}

View File

@@ -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();
}

View File

@@ -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};

View File

@@ -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();
}
}

View File

@@ -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)));
}
}

View File

@@ -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 !");

View File

@@ -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);
}
)";

View File

@@ -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) {

View File

@@ -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);

View File

@@ -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

View File

@@ -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;

View File

@@ -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