1 Commits

Author SHA1 Message Date
5cfdd63cb6 entitities 2024-03-09 14:53:48 +01:00
117 changed files with 723 additions and 2693 deletions

View File

@@ -1,38 +0,0 @@
name: Linux arm64
run-name: Build And Test
on: [push]
jobs:
Build:
runs-on: ubuntu-latest
steps:
- name: Install deps
run : |
apt update
apt install -y libsdl2-dev libassimp-dev libglew-dev
- name: Check out repository code
uses: actions/checkout@v3
- name: Prepare XMake
uses: xmake-io/github-action-setup-xmake@v1
with:
xmake-version: latest
actions-cache-folder: '.xmake-cache'
actions-cache-key: 'ubuntu'
- name: Packages cache
uses: actions/cache@v4
with:
path: ~/.xmake
key: 'ubuntu-packages'
- name: XMake config
run: xmake f -p linux -y --root
- name: Build
run: xmake --root
- name: Test
run: xmake test --root

View File

@@ -3,9 +3,7 @@
{
"name": "Blitz",
"cppStandard": "c++17",
"includePath": [
"include"
],
"includePath": ["include"],
"compileCommands": ".vscode/compile_commands.json"
}
],

7
.vscode/launch.json vendored
View File

@@ -2,13 +2,6 @@
// Xmake debug
"version": "0.2.0",
"configurations": [
{
"type": "xmake",
"request": "launch",
"name": "debug intersects test",
"target": "test_intersects",
"cwd": "",
},
{
"type": "xmake",
"request": "launch",

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.1 KiB

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 218 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 78 KiB

40
assets/player.obj Normal file
View File

@@ -0,0 +1,40 @@
# 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

37
assets/void_map.obj Normal file
View File

@@ -0,0 +1,37 @@
# 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

38
assets/void_map2.obj Normal file
View File

@@ -0,0 +1,38 @@
# 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

@@ -10,7 +10,6 @@
#include <cstring>
#include <string>
#include <vector>
#include <cstdint>
namespace blitz {
@@ -181,10 +180,6 @@ class DataBuffer {
std::memcpy(newBuffer, data(), GetSize());
return newBuffer;
}
bool operator==(const DataBuffer& other) const{
return m_Buffer == other.m_Buffer;
}
};
std::ostream& operator<<(std::ostream& os, const DataBuffer& buffer);

View File

@@ -10,11 +10,17 @@
namespace blitz {
namespace game {
/**
* \typedef EntityID
* \brief Represents the identifier of an Entity
*/
typedef std::uint32_t EntityID;
/**
* \typedef PlayerID
* \brief Represents the identifier of a Player
*/
typedef std::uint8_t PlayerID;
typedef EntityID PlayerID;
} // namespace game
} // namespace blitz

View File

@@ -1,7 +1,5 @@
#pragma once
#include <algorithm>
#include <cmath>
#include <cstddef>
namespace blitz {
@@ -25,6 +23,10 @@ struct Vec2 {
constexpr Vec2(T X = 0, T Y = 0) : x(X), y(Y) {}
};
template <typename T>
struct Vec3 {
union {
@@ -45,6 +47,10 @@ struct Vec3 {
constexpr Vec3(T X = 0, T Y = 0, T Z = 0) : x(X), y(Y), z(Z) {}
};
template <typename T>
struct Vec4 {
union {
@@ -71,6 +77,10 @@ struct Vec4 {
constexpr Vec4(T X = 0, T Y = 0, T Z = 0, T W = 0) : x(X), y(Y), z(Z), w(W) {}
};
using Vec2uc = Vec2<unsigned char>;
using Vec2i = Vec2<int>;
using Vec2u = Vec2<unsigned int>;
@@ -120,7 +130,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.x - other.x, vect.y - other.y};
return vect + (-other);
}
template <typename T>
@@ -168,7 +178,7 @@ Vec3<T>& operator+=(Vec3<T>& vect, const Vec3<T>& other) {
template <typename T>
constexpr Vec3<T> operator-(const Vec3<T>& vect, const Vec3<T>& other) {
return {vect.x - other.x, vect.y - other.y, vect.z - other.z};
return vect + (-other);
}
template <typename T>
@@ -187,44 +197,9 @@ constexpr Vec3<T> operator*(T mult, const Vec3<T>& vect) {
return vect * mult;
}
template <typename T>
constexpr Vec3<T> operator*=(const Vec3<T>& vect, T mult) {
vect = vect * mult;
return vect;
}
template <typename T>
constexpr Vec3<T> operator*=(T mult, const Vec3<T>& vect) {
vect = vect * mult;
return vect;
}
template <typename T>
constexpr Vec3<T> operator*(const Vec3<T>& vect, const Vec3<T>& other) {
return {vect.x * other.x, vect.y * other.y, vect.z * other.z};
}
template <typename T>
Vec3<T>& operator*=(Vec3<T>& vect, const Vec3<T>& other) {
vect = vect * other;
return vect;
}
template <typename T>
constexpr Vec3<T> operator/(const Vec3<T>& vect, const Vec3<T>& other) {
return {vect.x / other.x, vect.y / other.y, vect.z / other.z};
}
template <typename T>
Vec3<T>& operator/=(Vec3<T>& vect, const Vec3<T>& other) {
vect = vect / other;
return vect;
}
template <typename T>
constexpr bool operator<(const Vec3<T>& vec3, const Vec3<T>& other) {
return vec3.x < other.x && vec3.y < other.y && vec3.z < other.z;
}
// Vec4
@@ -251,7 +226,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.x - other.x, vect.y - other.y, vect.z - other.z, vect.w - other.w};
return vect + (-other);
}
template <typename T>
@@ -270,6 +245,10 @@ constexpr Vec4<T> operator*(T mult, const Vec4<T>& vect) {
return vect * mult;
}
//////////////////////////////////////////////////////////////////
// Matrix //
//////////////////////////////////////////////////////////////////
@@ -308,10 +287,18 @@ struct Mat4 {
}
};
typedef Mat4<float> Mat4f;
typedef Mat4<int> Mat4i;
typedef Mat4<double> Mat4d;
template <typename T>
bool operator==(const Mat4<T>& mat, const Mat4<T>& other) {
return mat.x0 == other.x0 && mat.y0 == other.y0 && mat.z0 == other.z0 && mat.w0 == other.w0 && mat.x1 == other.x1 &&
@@ -319,4 +306,5 @@ bool operator==(const Mat4<T>& mat, const Mat4<T>& other) {
mat.z2 == other.z2 && mat.w2 == other.w2 && mat.x3 == other.x3 && mat.y3 == other.y3 && mat.z3 == other.z3 &&
mat.w3 == other.w3;
}
} // namespace blitz

View File

@@ -1,36 +1,22 @@
#pragma once
#include "Player.h"
#include "blitz/misc/Time.h"
#include "World.h"
#include <map>
namespace blitz {
namespace game {
typedef std::map<PlayerID, Player> PlayerMap;
class Player;
enum GameState : std::uint8_t {
gsNone = 0,
gsWaiting,
gsPreparing,
gsGame,
gsEnd,
};
struct GameConfig {
float Gravity;
int FiringRate;
};
typedef std::map<PlayerID, Player*> PlayerMap;
class Game {
protected:
private:
PlayerMap m_Players;
GameState m_GameState;
utils::Timer m_GameTimer;
GameConfig m_Config;
World* m_World;
public:
Game() : m_GameState(gsNone) {}
Game(World* world) : m_World(world) {}
virtual void Tick(std::uint64_t delta) = 0;
@@ -45,24 +31,8 @@ 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();
}
Player* AddPlayer(PlayerID player, const std::string& name);
void RemovePlayer(PlayerID player);
};

View File

@@ -1,25 +0,0 @@
#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,33 +1,14 @@
#pragma once
#include "blitz/common/Defines.h"
#include "blitz/maths/Vector.h"
#include <vector>
#include "blitz/common/Vector.h"
namespace blitz {
namespace protocol {
struct ColoredPart;
typedef std::vector<ColoredPart> ColoredText;
} // namespace protocol
namespace game {
class PlayerInputListener {
public:
virtual void OnLocalPlayerJump() {}
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() {}
virtual void OnPlayerJump() {}
virtual void OnPlayerShoot(const Vec3f& position, float yaw, float pitch) {}
};
} // namespace game

View File

@@ -1,120 +0,0 @@
#pragma once
#include "blitz/common/Defines.h"
#include "blitz/maths/Vector.h"
#include <cstdint>
#include <string>
namespace blitz {
namespace game {
struct PlayerStats {
std::uint16_t m_Deaths;
std::uint16_t m_Kills;
std::uint32_t m_ShootCount;
std::uint32_t m_ShootSuccessCount;
};
class Player {
private:
PlayerID m_ID;
std::string m_Name;
Vec3f m_Position;
Vec3f m_Velocity;
float m_Yaw;
float m_Pitch;
float m_HP;
bool m_IsBot;
public:
Player(PlayerID id) : m_ID(id), m_Yaw(0), m_Pitch(0), m_HP(100), m_IsBot(false) {}
PlayerStats m_Stats{};
PlayerID GetID() const {
return m_ID;
}
const std::string& GetName() const {
return m_Name;
}
void SetName(const std::string& name) {
m_Name = name;
}
const Vec3f& GetPosition() const {
return m_Position;
}
void SetPosition(const Vec3f& newPos) {
m_Position = newPos;
}
void AddPosition(const Vec3f& dPos) {
m_Position += dPos;
}
const Vec3f& GetVelocity() const {
return m_Velocity;
}
void SetVelocity(const Vec3f& newVelocity) {
m_Velocity = newVelocity;
}
float GetYaw() const {
return m_Yaw;
}
void SetYaw(float yaw) {
m_Yaw = yaw;
}
void AddYaw(float dYaw) {
m_Yaw += dYaw;
}
float GetPitch() const {
return m_Pitch;
}
void SetPitch(float pitch) {
m_Pitch = pitch;
}
void AddPitch(float dPitch) {
m_Pitch += dPitch;
}
float GetHP() const {
return m_HP;
}
void SetHP(float hp) {
m_HP = hp;
}
bool IsBot() const {
return m_IsBot;
}
void SetBot() {
m_IsBot = true;
}
const PlayerStats& GetStats() const {
return m_Stats;
}
PlayerStats& GetStats() {
return m_Stats;
}
void SetStats(const PlayerStats& stats) {
m_Stats = stats;
}
};
} // namespace game
} // namespace blitz

View File

@@ -0,0 +1,29 @@
#pragma once
#include "blitz/game/entity/Entity.h"
#include <memory>
#include <vector>
namespace blitz {
namespace game {
class Player;
typedef std::unique_ptr<Entity> EntityPtr;
typedef std::vector<EntityPtr> EntityList;
class World {
protected:
EntityList m_Entities;
public:
World() {}
game::Player* CreatePlayer(PlayerID id);
Entity* GetEntityByID(EntityID id);
const Entity* GetEntityByID(EntityID id) const;
};
} // namespace game
} // namespace blitz

View File

@@ -0,0 +1,46 @@
#pragma once
#include "blitz/common/Defines.h"
#include "blitz/common/Vector.h"
namespace blitz {
namespace game {
class Entity {
protected:
EntityID m_ID;
Vec3f m_Position{};
Vec3f m_Velocity{};
Entity(EntityID id) : m_ID(id) {}
public:
virtual ~Entity() {}
EntityID GetID() const {
return m_ID;
}
const Vec3f& GetPosition() const {
return m_Position;
}
void SetPosition(const Vec3f& newPos) {
m_Position = newPos;
}
void AddPosition(const Vec3f& dPos) {
m_Position += dPos;
}
const Vec3f& GetVelocity() const {
return m_Velocity;
}
void SetVelocity(const Vec3f& newVelocity) {
m_Velocity = newVelocity;
}
};
} // namespace game
} // namespace blitz

View File

@@ -0,0 +1,21 @@
#pragma once
#include "Entity.h"
namespace blitz {
namespace game {
class HitScanBullet : public Entity {
private:
PlayerID m_Shooter;
public:
HitScanBullet(EntityID id, PlayerID shooter) : Entity(id), m_Shooter(shooter) {}
PlayerID GetShooter() const {
return m_Shooter;
}
};
} // namespace game
} // namespace blitz

View File

@@ -0,0 +1,54 @@
#pragma once
#include "blitz/game/entity/Entity.h"
#include <cstdint>
#include <string>
namespace blitz {
namespace game {
class Player : public Entity {
private:
std::string m_Name;
float m_Yaw;
float m_Pitch;
public:
Player(PlayerID id) : Entity(id), m_Yaw(0), m_Pitch(0) {}
const std::string& GetName() const {
return m_Name;
}
void SetName(const std::string& name) {
m_Name = name;
}
float GetYaw() const {
return m_Yaw;
}
void SetYaw(float yaw) {
m_Yaw = yaw;
}
void AddYaw(float dYaw) {
m_Yaw += dYaw;
}
float GetPitch() const {
return m_Pitch;
}
void SetPitch(float pitch) {
m_Pitch = pitch;
}
void AddPitch(float dPitch) {
m_Pitch += dPitch;
}
};
} // namespace game
} // namespace blitz

View File

@@ -1,30 +0,0 @@
#pragma once
#include "blitz/maths/Vector.h"
namespace blitz {
namespace maths {
struct Ray {
Vec3f origin;
Vec3f direction;
};
struct AABB {
Vec3f from;
Vec3f to;
};
inline AABB operator+(const AABB& aabb, const Vec3f& offset) {
AABB result = aabb;
result.from += offset;
result.to += offset;
return result;
}
float Distance(const Ray& ray, const AABB& aabb);
bool Intersects(const Ray& ray, const AABB& aabb);
} // namespace maths
} // namespace blitz

View File

@@ -1,6 +1,6 @@
#pragma once
#include "blitz/maths/Vector.h"
#include "blitz/common/Vector.h"
#include <cmath>
namespace blitz {
@@ -8,22 +8,6 @@ namespace maths {
static constexpr float PI = 3.141592653f;
template <typename T>
/**
* @brief returns the amount of overlap between the ranges [a1 ; b1] and [a2 ; b2]
*/
T RangesOverlap(T& a1, T& b1, T& a2, T& b2) {
return std::min(std::max(a1, b1), std::max(a2, b2)) - std::max(std::min(a1, b1), std::min(a2, b2));
}
template <typename T>
/**
* @brief returns whether the ranges [a1 ; b1] and [a2 ; b2] overlap
*/
bool RangesOverlapping(T& a1, T& b1, T& a2, T& b2) {
return RangesOverlap(a1, a2, b1, b2) >= 0;
}
//////////////////////////////////////////////////////////////////
// Vectors //
//////////////////////////////////////////////////////////////////
@@ -71,100 +55,6 @@ T Distance(const Vec3<T>& vect, const Vec3<T>& other) {
return Length(vect - other);
}
// it seems that `std::{min, max}`'s behavior conflicts with that of `cmath`'s `f{min, max}[f]`
// Why? Like I fucking know dude
template <typename T>
T ReduceMin(const Vec3<T>& vect) {
return std::min(std::min(vect.x, vect.y), vect.z);
}
template <typename T>
T ReduceMax(const Vec3<T>& vect) {
return std::max(std::max(vect.x, vect.y), vect.z);
}
/**
* @brief returns the (signed) minimal coordinate of the vector
*
* @param v
* @return constexpr T
*/
template <>
inline float ReduceMin<float>(const Vec3f& v) {
return std::fminf(std::fminf(v.x, v.y), v.z);
}
/**
* @brief returns the (signed) maximal coordinate of the vector
*
* @param v
* @return constexpr T
*/
template <>
inline float ReduceMax<float>(const Vec3f& v) {
return std::fmaxf(std::fmaxf(v.x, v.y), v.z);
}
/**
* @brief returns the (signed) minimal coordinate of the vector
*
* @param v
* @return constexpr T
*/
template <>
inline double ReduceMin<double>(const Vec3d& v) {
return std::fmin(std::fmin(v.x, v.y), v.z);
}
/**
* @brief returns the (signed) maximal coordinate of the vector
*
* @param v
* @return constexpr T
*/
template <>
inline double ReduceMax<double>(const Vec3d& v) {
return std::fmax(std::fmax(v.x, v.y), v.z);
}
/**
* @brief returns the coordinate-wise minimum of the given vectors,
* where a coordinate in the returned vector is NAN iff any of the two compared ones are NAN
*
* @tparam T
* @param self
* @param other
* @return constexpr Vec3f
*/
template <typename T>
constexpr Vec3<T> Min(const Vec3<T>& self, const Vec3<T>& other) {
return {
std::min(self.x, other.x),
std::min(self.y, other.y),
std::min(self.z, other.z),
};
}
/**
* @brief returns the coordinate-wise maximum of the given vectors,
* where a coordinate in the returned vector is NAN iff any of the two compared ones are NAN
*
* @tparam T
* @param self
* @param other
* @return constexpr Vec3f
*/
template <typename T>
constexpr Vec3<T> Max(const Vec3<T>& self, const Vec3<T>& other) {
return {
std::max(self.x, other.x),
std::max(self.y, other.y),
std::max(self.z, other.z),
};
}
//////////////////////////////////////////////////////////////////
// Matricies //
//////////////////////////////////////////////////////////////////
@@ -235,8 +125,6 @@ Mat4f Inverse(const Mat4f& mat);
Mat4f Translate(const Vec3f& translation);
Mat4f Scale(const Vec3f& axisFactor);
Mat4f RotateX(float angle);
Mat4f RotateY(float angle);
Mat4f RotateZ(float angle);

View File

@@ -1,6 +1,6 @@
#pragma once
#include "blitz/maths/Vector.h"
#include "blitz/common/Vector.h"
#include <string>
namespace blitz {

View File

@@ -1,6 +1,5 @@
#pragma once
#include <algorithm>
#include <cstdint>
#include <functional>
@@ -60,15 +59,6 @@ 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;
@@ -114,40 +104,5 @@ 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

@@ -58,7 +58,7 @@ class Connexion : public protocol::PacketHandler, private NonCopyable {
* \brief Tries to connect the socket at the specified address and port
* \return Wether this action was succesfull
*/
bool Connect(const std::string& address, std::uint16_t port);
virtual bool Connect(const std::string& address, std::uint16_t port);
/**
* \brief Returns the TCPSocket::Status of the internal socket

View File

@@ -30,11 +30,7 @@ class PacketHandler {
virtual void HandlePacket(const PlayerLoginPacket* packet) {}
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) {}
};
} // namespace protocol

View File

@@ -8,8 +8,4 @@
#include "packets/PlayerLoginPacket.h"
#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

@@ -13,11 +13,7 @@ class PlayerListPacket;
class PlayerLoginPacket;
class PlayerPositionAndRotationPacket;
class PlayerShootPacket;
class PlayerStatsPacket;
class ServerConfigPacket;
class ServerTpsPacket;
class UpdateGameStatePacket;
class UpdateHealthPacket;
} // namespace protocol
} // namespace blitz

View File

@@ -20,7 +20,6 @@ enum class PacketType : std::uint8_t {
// client --> server
PlayerLogin = 0, /**< Corresponds to PlayerLoginPacket */
UpdateHealth, /**< Corresponds to UpdateHealthPacket */
// client <-- server
@@ -28,10 +27,7 @@ enum class PacketType : std::uint8_t {
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

@@ -1,6 +1,6 @@
#pragma once
#include "blitz/maths/Vector.h"
#include "blitz/common/Vector.h"
#include "blitz/protocol/Protocol.h"
#include <vector>

View File

@@ -2,6 +2,7 @@
#include <map>
#include "blitz/common/Defines.h"
#include "blitz/protocol/Protocol.h"
namespace blitz {
@@ -11,7 +12,7 @@ struct PlayerInfo {
std::string name;
};
typedef std::map<std::uint8_t, PlayerInfo> PlayerList;
typedef std::map<game::PlayerID, PlayerInfo> PlayerList;
class PlayerListPacket : public Packet {
private:

View File

@@ -1,7 +1,7 @@
#pragma once
#include "blitz/common/Defines.h"
#include "blitz/maths/Vector.h"
#include "blitz/common/Vector.h"
#include "blitz/protocol/Protocol.h"
namespace blitz {

View File

@@ -1,6 +1,6 @@
#pragma once
#include "blitz/game/Player.h"
#include "blitz/game/entity/Player.h"
#include "blitz/protocol/Protocol.h"
namespace blitz {
@@ -15,29 +15,13 @@ class PlayerShootPacket : public Packet {
public:
PlayerShootPacket() {}
PlayerShootPacket(Vec3f position, float yaw, float pitch, game::PlayerID player = 0) :
m_Player(player), m_Position(position), m_Yaw(yaw), m_Pitch(pitch) {}
m_Position(position), m_Yaw(yaw), m_Pitch(pitch), m_Player(player) {}
virtual ~PlayerShootPacket() {}
virtual DataBuffer Serialize(bool packetID = true) const;
virtual void Deserialize(DataBuffer& data);
virtual void Dispatch(PacketHandler* handler) const;
const Vec3f& GetPosition() const {
return m_Position;
}
float GetYaw() const {
return m_Yaw;
}
float GetPitch() const {
return m_Pitch;
}
game::PlayerID GetPlayer() const {
return m_Player;
}
virtual PacketType GetType() const {
return PacketType::PlayerShoot;
}

View File

@@ -1,46 +0,0 @@
#pragma once
#include "blitz/common/Defines.h"
#include "blitz/game/Player.h"
#include "blitz/protocol/Protocol.h"
namespace blitz {
namespace protocol {
class PlayerStatsPacket : public Packet {
private:
game::PlayerID m_PlayerID;
game::PlayerStats m_PlayerStats;
public:
PlayerStatsPacket() {}
PlayerStatsPacket(game::PlayerID playerID, const game::PlayerStats& stats) : m_PlayerID(playerID), m_PlayerStats(stats) {}
virtual ~PlayerStatsPacket() {}
virtual DataBuffer Serialize(bool packetID = true) const;
virtual void Deserialize(DataBuffer& data);
virtual void Dispatch(PacketHandler* handler) const;
/**
* \brief Getter of the player id
* \return The ID of the player
*/
game::PlayerID GetPlayerID() const {
return m_PlayerID;
}
/**
* \brief Getter of the player stats
* \return The stats of the player
*/
const game::PlayerStats& GetPlayerStats() const {
return m_PlayerStats;
}
virtual PacketType GetType() const {
return PacketType::PlayerStats;
}
};
} // namespace protocol
} // namespace blitz

View File

@@ -1,32 +0,0 @@
#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

@@ -1,38 +0,0 @@
#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

@@ -1,31 +0,0 @@
#pragma once
#include "blitz/protocol/Protocol.h"
namespace blitz {
namespace protocol {
class UpdateHealthPacket : public Packet {
private:
float m_NewHealth;
public:
UpdateHealthPacket() {}
UpdateHealthPacket(float newHealth) : m_NewHealth(newHealth) {}
virtual ~UpdateHealthPacket() {}
virtual DataBuffer Serialize(bool packetID = true) const;
virtual void Deserialize(DataBuffer& data);
virtual void Dispatch(PacketHandler* handler) const;
float GetNewHealth() const {
return m_NewHealth;
}
virtual PacketType GetType() const {
return PacketType::UpdateHealth;
}
};
} // namespace protocol
} // namespace blitz

View File

@@ -23,10 +23,14 @@ namespace server {
class Server;
} // namespace server
class GuiListener {
public:
virtual void OnTextChatReceived(const protocol::ColoredText& text) {}
virtual void OnSpectatorChange(const game::PlayerID player) {}
};
// Singleton
class Client : public utils::ObjectNotifier<game::ClientListener>, public game::PlayerInputListener {
class Client : public utils::ObjectNotifier<GuiListener>, public game::PlayerInputListener {
private:
std::unique_ptr<server::Server> m_Server;
std::unique_ptr<client::ClientConnexion> m_Connexion;
@@ -52,7 +56,7 @@ class Client : public utils::ObjectNotifier<game::ClientListener>, public game::
void SendPlayerPosAndLook(const Vec3f& position, float yaw, float pitch);
virtual void OnLocalPlayerShoot(const Vec3f& position, float yaw, float pitch) override;
virtual void OnPlayerShoot(const Vec3f& position, float yaw, float pitch) override;
game::PlayerID GetPlayerID() const;
@@ -64,14 +68,6 @@ class Client : public utils::ObjectNotifier<game::ClientListener>, public game::
return &m_Config;
}
bool IsAdmin() const;
server::Server* GetServer() {
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;
bool Connect(const std::string& pseudo, const std::string& address, std::uint16_t port);
virtual bool Connect(const std::string& pseudo, const std::string& address, std::uint16_t port);
game::PlayerID GetPlayerID() const {
return m_PlayerID;

View File

@@ -1,30 +1,15 @@
#pragma once
#include "blitz/game/Game.h"
#include <array>
#include <string>
namespace blitz {
enum KeyAction {
kaAvancer = 0,
kaReculer,
kaDroite,
kaGauche,
kaFenetreAdmin,
kaMax,
};
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;
Keybinds m_Keybinds{};
float m_MouseSpeed;
public:
BlitzConfig();
@@ -50,22 +35,6 @@ class BlitzConfig {
m_DisplayFps = display;
}
Keybinds& GetKeys() {
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

@@ -6,9 +6,6 @@
#include "blitz/misc/Time.h"
namespace blitz {
class Client;
namespace game {
class Player;
@@ -17,27 +14,34 @@ class Player;
namespace input {
class PlayerController : public utils::ObjectNotifier<game::PlayerInputListener>, game::ClientListener {
class PlayerController : public utils::ObjectNotifier<game::PlayerInputListener> {
private:
game::Player* m_Player;
Client* m_Client;
utils::CooldownTimer<float> m_ShootTimer{1.0f};
EMASmoother m_DxSmoother;
EMASmoother m_DySmoother;
// current (target) velocity
Vec3f m_Velocity;
/// maximum x-axis velocity
Vec3f m_MaxVelocity;
float m_MaxDx;
/// current (target) x-axis velocity
float m_Dx;
EMASmoother m_DySmoother;
/// maximum (target) y-axis velocity
float m_MaxDy;
/// current (target) y-axis velocity
float m_Dy;
/// current z-axis velocity
float m_Dz;
/// maximum z-axis velocity (velocity at initial keypress)
float m_MaxDz;
/// individual gravitational force
float m_G;
/// this is reset when the player touches the ground
bool m_OnGround;
public:
PlayerController(Client* client);
PlayerController();
void Update(float delta);
virtual void OnGameConfigUpdate() override;
void SetAttachedPlayer(game::Player* a_Player) {
m_Player = a_Player;
}
@@ -47,7 +51,6 @@ class PlayerController : public utils::ObjectNotifier<game::PlayerInputListener>
}
private:
void UpdateShootTimer(int bpm);
void MouseMotionEvent(int, int);
void UpdatePosition(float delta);
};

View File

@@ -1,9 +1,8 @@
#pragma once
#include "blitz/game/Game.h"
#include "blitz/game/LeaderBoard.h"
#include "blitz/protocol/PacketHandler.h"
#include <vector>
#include "client/game/ClientWorld.h"
namespace blitz {
@@ -14,7 +13,7 @@ namespace client {
class ClientGame : public game::Game, public protocol::PacketHandler {
private:
Client* m_Client;
game::LeaderBoard m_LeaderBoard;
ClientWorld m_World;
public:
ClientGame(Client* client, protocol::PacketDispatcher* dispatcher);
@@ -26,18 +25,6 @@ class ClientGame : public game::Game, public protocol::PacketHandler {
virtual void HandlePacket(const protocol::PlayerLeavePacket* packet) override;
virtual void HandlePacket(const protocol::PlayerListPacket* packet) override;
virtual void HandlePacket(const protocol::PlayerPositionAndRotationPacket* packet) override;
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

@@ -0,0 +1,24 @@
#pragma once
#include "blitz/game/Listeners.h"
#include "blitz/game/World.h"
namespace blitz {
namespace game {
class Player;
class HitScanBullet;
} // namespace game
namespace client {
class ClientWorld : public game::World {
public:
ClientWorld() {}
// game::Player& CreatePlayer();
// game::HitScanBullet& CreateHitScanBullet();
};
} // namespace client
} // namespace blitz

View File

@@ -1,19 +0,0 @@
#pragma once
#include "GuiWidget.h"
namespace blitz {
namespace gui {
class CrossHair : public GuiWidget {
private:
std::uint64_t m_CrossHairTexture;
public:
CrossHair(Client* client);
virtual void Render() override;
};
} // namespace gui
} // namespace blitz

View File

@@ -9,15 +9,12 @@ namespace blitz {
namespace gui {
class GameChatGui : public GuiWidget, game::ClientListener {
class GameChatGui : public GuiWidget, GuiListener {
private:
char InputBuf[256];
std::vector<protocol::ColoredText> m_Lines;
std::vector<protocol::ColoredText> m_TempLines;
bool m_FocusRequested = false;
int HistoryPos; // -1: new line, 0..History.Size-1 browsing history.
bool ScrollToBottom = false;
bool AutoScroll = true;
float m_ChatDisplay = 0;
@@ -26,8 +23,7 @@ class GameChatGui : public GuiWidget, game::ClientListener {
public:
GameChatGui(GuiWidget* parent, Client* client);
virtual void OnTextChatReceived(const protocol::ColoredText& text) override;
virtual void OnTextChatReceived(const protocol::ColoredText& text);
virtual void Render() override;
};

View File

@@ -1,33 +0,0 @@
#pragma once
#include "GuiWidget.h"
#include "client/Client.h"
namespace blitz {
class Client;
namespace game {
class Player;
} // namespace game
namespace gui {
class Hud : public GuiWidget {
private:
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
} // namespace blitz

View File

@@ -1,22 +0,0 @@
#pragma once
#include "GuiWidget.h"
#include "client/Client.h"
namespace blitz {
namespace gui {
class LeaderBoardGui : public GuiWidget {
private:
void Draw(const char* title, bool* p_open);
utils::DelayTimer<float> m_Timer{5.0f};
public:
LeaderBoardGui(GuiWidget* parent, Client* client);
~LeaderBoardGui();
virtual void Render() override;
};
} // namespace gui
} // namespace blitz

View File

@@ -1,10 +1,6 @@
#pragma once
#include "GuiWidget.h"
#include "blitz/misc/Time.h"
#include "client/config/BlitzConfig.h"
#include <array>
#include <string>
namespace blitz {
@@ -16,10 +12,6 @@ class OptionsMenu : public GuiWidget {
private:
bool m_ShowFPS;
bool m_VSync;
bool m_IsKeyPopupOpen;
bool m_KeyPopupShouldClose;
utils::Timer m_Timer{100};
KeyAction m_CurrentAction;
public:
OptionsMenu(GuiWidget* parent, Client* client);
@@ -27,11 +19,6 @@ class OptionsMenu : public GuiWidget {
virtual void Render() override;
void OnKeyEvent(int key);
private:
std::string GetKeyActionCodeName(KeyAction);
void HotkeyBindingButton();
void HotkeyBindingPopUp();
};
} // namespace gui

View File

@@ -1,16 +0,0 @@
#pragma once
#include "GuiWidget.h"
namespace blitz {
namespace gui {
class ServerGui : public GuiWidget {
public:
ServerGui(GuiWidget* parent, Client* client);
virtual void Render() override;
};
} // namespace gui
} // namespace blitz

View File

@@ -1,43 +0,0 @@
#pragma once
#include "blitz/maths/Vector.h"
#include "client/render/loader/ModelLoader.h"
#include <memory>
#include <vector>
namespace blitz {
namespace shader {
class BulletShader;
} // namespace shader
namespace render {
class Camera;
struct Trail {
Mat4f m_Transform;
float m_Decay;
};
class BulletRenderer {
private:
std::vector<Trail> m_Trails;
ModelLoader::Model m_BulletModel;
std::unique_ptr<shader::BulletShader> m_Shader;
const Camera& m_Camera;
public:
BulletRenderer(const Camera& cam);
~BulletRenderer();
void AddBullet(const Vec3f& origin, float yaw, float pitch, bool firstPersson);
void Update(float delta);
void Render();
};
} // namespace render
} // namespace blitz

View File

@@ -1,7 +1,7 @@
#pragma once
#include "blitz/game/Player.h"
#include "blitz/maths/Vector.h"
#include "blitz/common/Vector.h"
#include "blitz/game/entity/Player.h"
#include <cstdint>
namespace blitz {
@@ -19,8 +19,6 @@ class Camera {
void Update(float delta);
static float GetPlayerEyeHeight();
void SetAttachedPlayer(game::Player* a_Player) {
m_Player = a_Player;
}

View File

@@ -2,7 +2,6 @@
#include "client/Client.h"
#include "client/display/PlayerController.h"
#include "client/render/BulletRenderer.h"
#include "client/render/Camera.h"
#include "client/render/loader/GLLoader.h"
#include "client/render/loader/ModelLoader.h"
@@ -20,7 +19,7 @@ class GunShader;
namespace render {
class MainRenderer : public game::ClientListener, public game::PlayerInputListener {
class MainRenderer : public GuiListener, public game::PlayerInputListener {
private:
Client* m_Client;
ModelLoader::Model m_PlayerModel;
@@ -33,17 +32,14 @@ class MainRenderer : public game::ClientListener, public game::PlayerInputListen
unsigned int m_Texture;
float m_ShootTime;
Camera m_Camera;
BulletRenderer m_BulletRenderer;
public:
MainRenderer(Client* client);
~MainRenderer();
virtual void OnSpectatorChange(game::PlayerID player) override;
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 OnSpectatorChange(const game::PlayerID player) override;
virtual void OnGameConfigUpdate() override;
virtual void OnPlayerShoot(const Vec3f& position, float yaw, float pitch) override;
void Update();
void Render();

View File

@@ -1,8 +0,0 @@
#pragma once
#ifdef BLITZ_GL_LOADER_GLEW
#include <GL/glew.h>
#else
#include <glbinding/gl/gl.h>
using namespace gl;
#endif

View File

@@ -70,7 +70,7 @@ class VertexArray : private NonCopyable {
VertexArray(ElementBuffer&& indicies);
~VertexArray();
std::size_t GetVertexCount() const {
unsigned int GetVertexCount() const {
return m_ElementBuffer.GetTriangleCount();
}

View File

@@ -1,30 +0,0 @@
#pragma once
#include "ShaderProgram.h"
namespace blitz {
namespace shader {
class BulletShader : public ShaderProgram {
private:
unsigned int m_LocationProjectionMatrix = 0;
unsigned int m_LocationViewMatrix = 0;
unsigned int m_LocationAlpha = 0;
unsigned int m_LocationTransform = 0;
protected:
virtual void GetAllUniformLocation() override;
public:
BulletShader();
bool LoadShader();
void SetProjectionMatrix(const Mat4f& proj) const;
void SetViewMatrix(const Mat4f& view) const;
void SetTransform(const Mat4f& trans) const;
void SetDecay(float decay) const;
};
} // namespace shader
} // namespace blitz

View File

@@ -1,7 +1,8 @@
#pragma once
#include "blitz/maths/Vector.h"
#include "client/render/OpenGL.h"
#include "blitz/common/Vector.h"
#include <glbinding/SharedBitfield.h>
#include <glbinding/gl/enum.h>
#include <string>
namespace blitz {
@@ -36,7 +37,7 @@ class ShaderProgram {
unsigned int m_VertexShaderID;
unsigned int m_FragmentShaderID;
int LoadShader(const std::string& source, GLenum type);
int LoadShader(const std::string& source, gl::GLenum type);
};
} // namespace shader

View File

@@ -36,8 +36,6 @@ class Server {
void Restart();
void AddBot();
void RemoveConnexion(std::uint8_t connexionID);
void BroadcastPacket(const protocol::Packet* packet);
@@ -69,8 +67,6 @@ class Server {
std::uint16_t GetListeningPort();
game::PlayerID GetNewPlayerID();
private:
void Accept();
void UpdateSockets();

View File

@@ -48,7 +48,7 @@ class ServerConnexion : public network::Connexion {
return m_ID;
}
virtual bool UpdateSocket() override;
virtual bool UpdateSocket();
private:
void RegisterHandlers();
@@ -57,8 +57,6 @@ class ServerConnexion : public network::Connexion {
void InitConnection();
void InitPlayerChatColor();
void SendPlayers();
void SendGameState();
void SendServerConfig();
};
} // namespace server

View File

@@ -1,51 +1,32 @@
#pragma once
#include "blitz/game/Game.h"
#include "blitz/misc/Time.h"
#include "server/game/ServerWorld.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;
ServerWorld m_World;
public:
ServerGame(Server* server);
virtual ~ServerGame();
void CheckShoot(game::PlayerID player, Vec3f position, float yaw, float pitch);
void AddPlayer(game::PlayerID player, const std::string& name) override;
void RemovePlayer(game::PlayerID player) override;
game::PlayerID GetNextPlayerID() {
return m_World.GetNextEntityID();
}
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,30 @@
#pragma once
#include "blitz/game/Listeners.h"
#include "blitz/game/World.h"
namespace blitz {
namespace game {
class Player;
class HitScanBullet;
} // namespace game
namespace server {
class ServerWorld : public game::World {
private:
game::EntityID m_CurrentID;
public:
ServerWorld() : m_CurrentID(0) {}
game::EntityID GetNextEntityID() {
return m_CurrentID++;
}
game::Player* CreateEmptyPlayer();
game::HitScanBullet* CreateEmptyHitScanBullet(game::PlayerID shooter);
};
} // namespace server
} // namespace blitz

View File

@@ -30,7 +30,7 @@ DataBuffer& operator<<(DataBuffer& out, const VarInt& var) {
DataBuffer& operator>>(DataBuffer& in, VarInt& var) {
var.m_Value = 0;
unsigned int position = 0;
int position = 0;
std::uint8_t currentByte;
while (true) {

View File

@@ -1,5 +1,7 @@
#include "blitz/game/Game.h"
#include "blitz/game/entity/Player.h"
namespace blitz {
namespace game {
@@ -9,7 +11,7 @@ Player* Game::GetPlayerById(PlayerID id) {
if (it == m_Players.end())
return nullptr;
return &it->second;
return it->second;
}
const Player* Game::GetPlayerById(PlayerID id) const {
@@ -18,17 +20,16 @@ const Player* Game::GetPlayerById(PlayerID id) const {
if (it == m_Players.end())
return nullptr;
return &it->second;
return it->second;
}
void Game::AddPlayer(PlayerID player, const std::string& name) {
static float MAX_HP = 100;
Player* Game::AddPlayer(PlayerID playerID, const std::string& name) {
game::Player* player = m_World->CreatePlayer(playerID);
player->SetName(name);
game::Player newPlayer{player};
newPlayer.SetName(name);
newPlayer.SetHP(MAX_HP);
GetPlayers().insert({playerID, player});
GetPlayers().insert({player, newPlayer});
return player;
}
void Game::RemovePlayer(PlayerID player) {

View File

@@ -1,29 +0,0 @@
#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

37
src/blitz/game/World.cpp Normal file
View File

@@ -0,0 +1,37 @@
#include "blitz/game/World.h"
#include "blitz/game/entity/Player.h"
#include <algorithm>
namespace blitz {
namespace game {
Player* World::CreatePlayer(PlayerID id) {
m_Entities.push_back(std::make_unique<Player>(id));
return dynamic_cast<game::Player*>(m_Entities.back().get());
}
Entity* World::GetEntityByID(EntityID id) {
auto it = std::find_if(m_Entities.begin(), m_Entities.end(), [id](const EntityPtr& ptr) {
return ptr->GetID() == id;
});
if (it == m_Entities.end())
return nullptr;
return it->get();
}
const Entity* World::GetEntityByID(EntityID id) const {
auto it = std::find_if(m_Entities.begin(), m_Entities.end(), [id](const EntityPtr& ptr) {
return ptr->GetID() == id;
});
if (it == m_Entities.end())
return nullptr;
return it->get();
}
} // namespace game
} // namespace blitz

View File

@@ -1,68 +0,0 @@
#include "blitz/maths/Physics.h"
#include "blitz/maths/Maths.h"
#include <cmath>
namespace blitz {
namespace maths {
/**
* @brief Returns `true` if the half-line `ray` _strictly_ intersects with `aabb`,
* and `false` if it _strictly_ doesn't intersect.
* Note that if it only intersects with corners, edges, or sides of the box,
* or if any coordinate in `ray` is `NAN` or `inf` or if any coordinate in
* `aabb` is `NAN` the result is unspecified.
* */
float Distance(const Ray& ray, const AABB& aabb) {
// This function calculates smallest interval I = ] a, b [, for strictly positive a and b
// such that for all t in I, for all l, r, o, d corresponding
// coordinates in aabb.from, aabb.to, ray.origin, ray.direction, respectively
//
// min(l, r) < o + t * d < max(l, r)
//
// and returns true if it's non-empty i.e. a < b
// m = min(l, r), M = max(l, r)
// m < o + t * d < M
Vec3f l = Min(aabb.from, aabb.to);
Vec3f r = Max(aabb.to, aabb.from);
// m - o < t * d < M - o
l -= ray.origin;
r -= ray.origin;
// (m - o) / d < t < (M - o) / d
l /= ray.direction;
r /= ray.direction;
// but if d is negative the inequality is flipped
Vec3f u = Min(l, r);
r = Max(l, r);
l = u;
float tmin = ReduceMax(l);
float tmax = ReduceMin(r);
// Since Min propagates NANs and ReduceMin doesn't, and since NAN !< <any float>
// the inequality becomes ignored for coordinates where a NAN is involved
// (as a result of 0.0 / 0.0). If all coordinates are NAN, this means
// that the box is reduced to a point and the ray has direction 0,
// in which case this returns -1
if (tmax >= 0.0f && tmin <= tmax) {
return std::fmaxf(tmin, 0.0f);
}
return -1.0f;
}
bool Intersects(const AABB& aabb1, const AABB& aabb2) {
return false;
}
bool Intersects(const Ray& ray, const AABB& aabb) {
return Distance(ray, aabb) >= 0.0f;
}
} // namespace maths
} // namespace blitz

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), static_cast<uLong>(size));
reinterpret_cast<const Bytef*>(source), size);
assert(result.GetSize() == uncompressedSize);
return result;
@@ -25,8 +25,7 @@ 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), static_cast<uLong>(size));
compress(reinterpret_cast<Bytef*>(result.data()), &compressedSize, reinterpret_cast<const Bytef*>(source), size);
result.Resize(compressedSize); // Resize to cut useless data
return result;

View File

@@ -1,6 +1,6 @@
#include "blitz/misc/Easing.h"
#include "blitz/maths/Maths.h"
#include "blitz/misc/Maths.h"
namespace blitz {
namespace utils {
@@ -10,126 +10,122 @@ namespace utils {
/* Sine functions */
float EaseInSine(float x) {
return static_cast<float>(1.0 - std::cos((x * maths::PI) / 2.0));
return 1.0f - std::cos((x * maths::PI) / 2.0f);
}
float EaseOutSine(float x) {
return static_cast<float>(std::sin((x * maths::PI) / 2.0));
return std::sin((x * maths::PI) / 2.0f);
}
float EaseInOutSine(float x) {
return static_cast<float>(-(std::cos(maths::PI * x) - 1.0) / 2.0);
return -(std::cos(maths::PI * x) - 1.0f) / 2.0f;
}
/* Cubic functions */
float EaseInCubic(float x) {
return static_cast<float>(x * EaseInQuad(x));
return x * EaseInQuad(x);
}
float EaseOutCubic(float x) {
return static_cast<float>(1 - std::pow(1 - x, 3));
return 1 - std::pow(1 - x, 3);
}
float EaseInOutCubic(float x) {
return static_cast<float>(x < 0.5 ? 4 * EaseInCubic(x) : 1 - std::pow(-2 * x + 2, 3) / 2.0);
return x < 0.5 ? 4 * EaseInCubic(x) : 1 - std::pow(-2 * x + 2, 3) / 2.0f;
}
/* Quint functions */
float EaseInQuint(float x) {
return static_cast<float>(x * EaseInQuart(x));
return x * EaseInQuart(x);
}
float EaseOutQuint(float x) {
return static_cast<float>(1 - std::pow(1 - x, 5));
return 1 - std::pow(1 - x, 5);
}
float EaseInOutQuint(float x) {
return static_cast<float>(x < 0.5 ? 16 * EaseInQuint(x) : 1 - std::pow(-2 * x + 2, 5) / 2.0);
return x < 0.5 ? 16 * EaseInQuint(x) : 1 - std::pow(-2 * x + 2, 5) / 2.0f;
}
/* Circ functions */
float EaseInCirc(float x) {
return static_cast<float>(1 - std::sqrt(1 - std::pow(x, 2)));
return 1 - std::sqrt(1 - std::pow(x, 2));
}
float EaseOutCirc(float x) {
return static_cast<float>(std::sqrt(1 - std::pow(x - 1, 2)));
return std::sqrt(1 - std::pow(x - 1, 2));
}
float EaseInOutCirc(float x) {
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);
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;
}
/* Elastic functions */
float EaseInElastic(float x) {
const float c4 = (2 * maths::PI) / 3.0;
const float c4 = (2 * maths::PI) / 3.0f;
return static_cast<float>(x == 0 ? 0 : x == 1 ? 1 : -std::pow(2, 10 * x - 10) * std::sin((x * 10 - 10.75) * c4));
return 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.0;
const float c4 = (2 * maths::PI) / 3.0f;
return static_cast<float>(x == 0 ? 0 : x == 1 ? 1 : std::pow(2, -10 * x) * std::sin((x * 10 - 0.75) * c4) + 1);
return 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 static_cast<float>(x == 0 ? 0
return 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);
: 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;
}
/* Quad functions */
float EaseInQuad(float x) {
return static_cast<float>(x * x);
return x * x;
}
float EaseOutQuad(float x) {
return static_cast<float>(1 - (1 - x) * (1 - x));
return 1 - (1 - x) * (1 - x);
}
float EaseInOutQuad(float x) {
return static_cast<float>(x < 0.5 ? 2 * x * x : 1 - std::pow(-2 * x + 2, 2) / 2.0);
return x < 0.5 ? 2 * x * x : 1 - std::pow(-2 * x + 2, 2) / 2.0f;
}
/* Quart functions */
float EaseInQuart(float x) {
return static_cast<float>(x * EaseInCubic(x));
return x * EaseInCubic(x);
}
float EaseOutQuart(float x) {
return static_cast<float>(1 - std::pow(1 - x, 4));
return 1 - std::pow(1 - x, 4);
}
float EaseInOutQuart(float x) {
return static_cast<float>(x < 0.5 ? 8 * EaseInQuart(x) : 1 - std::pow(-2 * x + 2, 4) / 2.0);
return x < 0.5 ? 8 * EaseInQuart(x) : 1 - std::pow(-2 * x + 2, 4) / 2.0f;
}
/* Expo functions */
float EaseInExpo(float x) {
return static_cast<float>(x == 0 ? 0 : std::pow(2, 10 * x - 10));
return x == 0 ? 0 : std::pow(2, 10 * x - 10);
}
float EaseOutExpo(float x) {
return static_cast<float>(x == 1 ? 1 : 1 - std::pow(2, -10 * x));
return x == 1 ? 1 : 1 - std::pow(2, -10 * x);
}
float EaseInOutExpo(float x) {
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);
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;
}
/* Back functions */
@@ -138,28 +134,28 @@ float EaseInBack(float x) {
const float c1 = 1.70158;
const float c3 = c1 + 1;
return static_cast<float>(c3 * EaseInCubic(x) - c1 * EaseInQuad(x));
return c3 * EaseInCubic(x) - c1 * EaseInQuad(x);
}
float EaseOutBack(float x) {
const float c1 = 1.70158;
const float c3 = c1 + 1;
return static_cast<float>(1 + c3 * std::pow(x - 1, 3) + c1 * std::pow(x - 1, 2));
return 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 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);
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;
}
/* Bounce functions */
float EaseInBounce(float x) {
return static_cast<float>(1 - EaseOutBounce(1 - x));
return 1 - EaseOutBounce(1 - x);
}
float EaseOutBounce(float x) {
@@ -167,21 +163,21 @@ float EaseOutBounce(float x) {
const float d1 = 2.75;
if (x < 1 / d1) {
return static_cast<float>(n1 * EaseInQuad(x));
return n1 * EaseInQuad(x);
} else if (x < 2 / d1) {
x -= 1.5;
return static_cast<float>(n1 * (x / d1) * x + 0.75);
return n1 * (x / d1) * x + 0.75;
} else if (x < 2.5 / d1) {
x -= 2.25;
return static_cast<float>(n1 * (x / d1) * x + 0.9375);
return n1 * (x / d1) * x + 0.9375;
} else {
x -= 2.625;
return static_cast<float>(n1 * (x / d1) * x + 0.984375);
return n1 * (x / d1) * x + 0.984375;
}
}
float EaseInOutBounce(float x) {
return static_cast<float>(x < 0.5 ? (1 - EaseOutBounce(1 - 2 * x)) / 2.0 : (1 + EaseOutBounce(2 * x - 1)) / 2.0);
return x < 0.5 ? (1 - EaseOutBounce(1 - 2 * x)) / 2.0f : (1 + EaseOutBounce(2 * x - 1)) / 2.0f;
}
} // namespace utils

View File

@@ -1,6 +1,8 @@
#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

@@ -1,4 +1,4 @@
#include "blitz/maths/Maths.h"
#include "blitz/misc/Maths.h"
#include <cassert>
@@ -59,7 +59,7 @@ Mat4f Inverse(const Mat4f& mat) {
assert(det != 0 && "Determinant equals 0 !");
float invdet = 1.0f / det;
float invdet = 1.0 / det;
Mat4f result;
@@ -91,22 +91,10 @@ Mat4f Translate(const Vec3f& translation) {
Vec4f vh {translation.x, translation.y, translation.z, 1.0};
mat.at(3, 0) = vh.x;
mat.at(3, 1) = vh.y;
mat.at(3, 2) = vh.z;
mat.at(3, 3) = vh.w;
return mat;
}
Mat4f Scale(const Vec3f& axisFactor) {
Mat4f mat{};
mat.at(0, 0) = axisFactor.x;
mat.at(1, 1) = axisFactor.y;
mat.at(2, 2) = axisFactor.z;
mat.at(3, 3) = 1.0f;
mat.at(3, 0) = Dot(Vec4f{mat.at(0, 0), mat.at(1, 0), mat.at(2, 0), mat.at(3, 0)}, vh);
mat.at(3, 1) = Dot(Vec4f{mat.at(0, 1), mat.at(1, 1), mat.at(2, 1), mat.at(3, 1)}, vh);
mat.at(3, 2) = Dot(Vec4f{mat.at(0, 2), mat.at(1, 2), mat.at(2, 2), mat.at(3, 2)}, vh);
mat.at(3, 3) = Dot(Vec4f{mat.at(0, 3), mat.at(1, 3), mat.at(2, 3), mat.at(3, 3)}, vh);
return mat;
}

View File

@@ -6,7 +6,7 @@ namespace blitz {
namespace utils {
void TickCounter::Reset() {
m_TPS = static_cast<float>(m_TargetTPS);
m_TPS = m_TargetTPS;
m_LastTPSTime = utils::GetTime();
m_TickCount = 0;
}

View File

@@ -11,14 +11,14 @@
namespace blitz {
namespace network {
TCPListener::TCPListener() : m_Handle(static_cast<blitz::network::SocketHandle>(INVALID_SOCKET)), m_Port(0), m_MaxConnections(0) {}
TCPListener::TCPListener() : m_Handle(INVALID_SOCKET), m_Port(0), m_MaxConnections(0) {}
TCPListener::~TCPListener() {
Destroy();
}
bool TCPListener::Listen(std::uint16_t port, int maxConnections) {
if ((m_Handle = static_cast<SocketHandle>(socket(AF_INET, SOCK_STREAM, IPPROTO_TCP))) < 0) {
if ((m_Handle = 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 = static_cast<SocketHandle>(
accept(m_Handle, reinterpret_cast<sockaddr*>(&newSocket.m_RemoteAddr), reinterpret_cast<socklen_t*>(&addrlen)));
newSocket.m_Handle =
accept(m_Handle, reinterpret_cast<sockaddr*>(&newSocket.m_RemoteAddr), reinterpret_cast<socklen_t*>(&addrlen));
if (newSocket.m_Handle < 0)
return false;

View File

@@ -16,7 +16,7 @@ namespace blitz {
namespace network {
TCPSocket::TCPSocket() :
m_Blocking(false), m_Status(Status::Disconnected), m_Handle(static_cast<SocketHandle>(INVALID_SOCKET)), m_Port(0) {}
m_Blocking(false), m_Status(Status::Disconnected), m_Port(0), m_Handle(static_cast<SocketHandle>(INVALID_SOCKET)) {}
TCPSocket::TCPSocket(TCPSocket&& other) {
@@ -83,14 +83,12 @@ bool TCPSocket::Connect(const std::string& host, unsigned short port) {
return false;
}
m_Handle = static_cast<SocketHandle>(socket(AF_INET, SOCK_STREAM, IPPROTO_TCP));
m_Handle = 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;
@@ -122,10 +120,9 @@ 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), static_cast<int>(size - sent), 0);
int cur = send(m_Handle, reinterpret_cast<const char*>(data + sent), size - sent, 0);
if (cur <= 0) {
Disconnect();
m_Status = Status::Error;
return 0;
}
sent += static_cast<std::size_t>(cur);
@@ -138,7 +135,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()), static_cast<int>(amount), 0);
int recvAmount = recv(m_Handle, reinterpret_cast<char*>(buffer.data()), amount, 0);
if (recvAmount <= 0) {
#if defined(_WIN32) || defined(WIN32)
int err = WSAGetLastError();
@@ -152,7 +149,6 @@ 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

@@ -14,15 +14,11 @@ typedef std::unique_ptr<Packet> PacketPtr;
static std::array<PacketPtr, static_cast<std::size_t>(PacketType::PACKET_COUNT)> Packets = {
std::make_unique<PlayerLoginPacket>(),
std::make_unique<UpdateHealthPacket>(),
std::make_unique<ConnexionInfoPacket>(),
std::make_unique<PlayerJoinPacket>(),
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

@@ -25,10 +25,6 @@ REGISTER_DISPATCH_CLASS(ServerTpsPacket)
REGISTER_DISPATCH_CLASS(ChatPacket)
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

@@ -1,6 +1,6 @@
#include "blitz/protocol/packets/ChatPacket.h"
#include "blitz/maths/Vector.h"
#include "blitz/common/Vector.h"
#include "blitz/misc/Log.h"
#include <map>
#include <sstream>
@@ -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&) {
} catch (std::exception& e) {
utils::LOG("[ChatPacket] warning ! wrong color providen !");
}
break;

View File

@@ -20,7 +20,7 @@ void PlayerListPacket::Deserialize(DataBuffer& data) {
VarInt playerCount;
data >> playerCount;
for (std::size_t i = 0; i < playerCount.GetValue(); i++) {
for (int i = 0; i < playerCount.GetValue(); i++) {
std::uint8_t playerID;
PlayerInfo playerInfo;
data >> playerID >> playerInfo.name;

View File

@@ -1,19 +0,0 @@
#include "blitz/protocol/packets/PlayerStatsPacket.h"
namespace blitz {
namespace protocol {
DataBuffer PlayerStatsPacket::Serialize(bool packetID) const {
DataBuffer data;
WritePacketID(data, packetID);
data << m_PlayerID << m_PlayerStats;
return data;
}
void PlayerStatsPacket::Deserialize(DataBuffer& data) {
data >> m_PlayerID >> m_PlayerStats;
}
} // namespace protocol
} // namespace blitz

View File

@@ -1,19 +0,0 @@
#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

@@ -1,19 +0,0 @@
#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

@@ -1,19 +0,0 @@
#include "blitz/protocol/packets/UpdateHealthPacket.h"
namespace blitz {
namespace protocol {
DataBuffer UpdateHealthPacket::Serialize(bool packetID) const {
DataBuffer data;
WritePacketID(data, packetID);
data << m_NewHealth;
return data;
}
void UpdateHealthPacket::Deserialize(DataBuffer& data) {
data >> m_NewHealth;
}
} // namespace protocol
} // namespace blitz

View File

@@ -36,12 +36,6 @@ 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;
@@ -51,8 +45,6 @@ bool Client::CreateGame(std::uint16_t port, const std::string& pseudo) {
return false;
}
UpdateServerConfig();
return true;
}
@@ -79,7 +71,7 @@ void Client::SendChatText(const std::string& text) {
}
void Client::ChatTextReceived(const protocol::ColoredText& text) {
NotifyListeners(&game::ClientListener::OnTextChatReceived, text);
NotifyListeners(&GuiListener::OnTextChatReceived, text);
}
void Client::SendPlayerPosAndLook(const Vec3f& position, float yaw, float pitch) {
@@ -88,7 +80,7 @@ void Client::SendPlayerPosAndLook(const Vec3f& position, float yaw, float pitch)
}
void Client::OnLocalPlayerShoot(const Vec3f& position, float yaw, float pitch) {
void Client::OnPlayerShoot(const Vec3f& position, float yaw, float pitch) {
protocol::PlayerShootPacket packet(position, yaw, pitch);
m_Connexion->SendPacket(&packet);
}
@@ -102,10 +94,6 @@ bool Client::IsConnected() {
return m_Connexion->GetSocketStatus() == network::TCPSocket::Status::Connected;
}
bool Client::IsAdmin() const {
return m_Server->IsRunning();
}
void Client::UpdatePosition(std::uint64_t delta) {
// send position every tick (50 ms)

View File

@@ -1,7 +1,6 @@
#include "client/config/BlitzConfig.h"
#include "blitz/misc/Log.h"
#include "imgui.h"
#include <fstream>
#include <nlohmann/json.hpp>
@@ -37,13 +36,9 @@ 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&) {
} catch (std::exception& e) {
utils::LOGE("[BlitzConfig] Failed to load config !");
}
}
@@ -53,10 +48,6 @@ void BlitzConfig::LoadDefaultConfig() {
m_VSync = true;
const char defaultPseudo[] = "Pseudo";
std::memcpy(m_Pseudo.data(), defaultPseudo, sizeof(defaultPseudo));
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() {
@@ -70,10 +61,6 @@ void BlitzConfig::SaveConfig() {
{"pseudo", GetPseudo().data()},
{"vsync", IsVSyncEnabled()},
{"fps", IsFPSDisplayEnabled()},
{"sensitivity", GetMouseSpeed()},
{"gravity", GetServerConfig().Gravity},
{"firingrate", GetServerConfig().FiringRate},
{"keys", GetKeys()},
};
file << jsonOutput;

View File

@@ -1,10 +1,11 @@
#include "client/display/Display.h"
#include "client/display/InputManager.h"
#include "client/render/OpenGL.h"
#include <SDL2/SDL.h>
#include <backends/imgui_impl_opengl3.h>
#include <backends/imgui_impl_sdl2.h>
#include <glbinding/gl/gl.h>
#include <glbinding/glbinding.h>
#include "blitz/misc/Format.h"
#include "blitz/misc/Log.h"
@@ -12,21 +13,17 @@
#include "client/gui/BlitzGui.h"
#ifdef BLITZ_GL_LOADER_GLEW
#include <GL/glew.h>
#else
#include <glbinding/glbinding.h>
#endif
using namespace gl;
namespace blitz {
Display::Display(int width, int height, const std::string& windowName, Client* client) :
m_WindowWidth(width),
m_WindowHeight(height),
m_AspectRatio(m_WindowHeight / static_cast<float>(m_WindowWidth)),
m_WindowName(windowName),
m_ShouldClose(false),
m_FullScreen(false),
m_AspectRatio(m_WindowHeight / static_cast<float>(m_WindowWidth)),
m_Client(client),
m_BlitzGui(nullptr) {}
@@ -97,15 +94,7 @@ bool Display::Create() {
SDL_GL_MakeCurrent(m_Window, m_GL_Context);
SDL_GL_SetSwapInterval(1);
#ifdef BLITZ_GL_LOADER_GLEW
GLenum error = glewInit();
if (error != GLEW_OK) {
utils::LOGE(utils::Format("[Display] Failed to initialise glew : %s", glewGetErrorString(error)));
return false;
}
#else
glbinding::initialize(reinterpret_cast<glbinding::ProcAddress (*)(const char*)>(SDL_GL_GetProcAddress));
#endif
InitImGui();
return true;
@@ -218,12 +207,11 @@ void Display::InitImGui() {
ImGui_ImplOpenGL3_Init();
ImFontConfig c;
c.SizePixels = 25.0f;
c.SizePixels = 25;
ImGui::GetIO().Fonts->AddFontDefault(&c);
// doom font
DataBuffer doomFontFile = utils::AssetsManager::GetAsset("doom.ttf");
auto* doomFont =
ImGui::GetIO().Fonts->AddFontFromMemoryTTF(doomFontFile.HeapAllocatedData(), static_cast<int>(doomFontFile.GetSize()), 25.0f);
auto* doomFont = ImGui::GetIO().Fonts->AddFontFromMemoryTTF(doomFontFile.HeapAllocatedData(), doomFontFile.GetSize(), 25);
ImGui::GetIO().FontDefault = doomFont;
#ifndef __ANDROID__

View File

@@ -1,12 +1,9 @@
#include "client/display/PlayerController.h"
#include "blitz/game/Player.h"
#include "blitz/maths/Maths.h"
#include "blitz/game/entity/Player.h"
#include "blitz/misc/Log.h"
#include "client/Client.h"
#include "client/config/BlitzConfig.h"
#include "blitz/misc/Maths.h"
#include "client/display/InputManager.h"
#include "client/game/ClientGame.h"
#include "imgui.h"
#include <algorithm>
#include <iostream>
@@ -15,16 +12,21 @@ 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;
static constexpr float DEFAULT_FB_SPEED_SMOOTHING_TIME = 1.0;
PlayerController::PlayerController(Client* client) :
PlayerController::PlayerController() :
m_Player(nullptr),
m_Client(client),
m_Velocity({}),
m_MaxVelocity(DEFAULT_MAX_LR_SPEED, DEFAULT_MAX_FB_SPEED, DEFAULT_JUMP_VEL),
m_Dx(0.0),
m_Dy(0.0),
m_MaxDx(DEFAULT_MAX_LR_SPEED),
m_MaxDy(DEFAULT_MAX_FB_SPEED),
m_MaxDz(DEFAULT_JUMP_VEL),
m_Dz(0.0),
m_G(DEFAULT_GRAVITY),
m_OnGround(true) {
m_DxSmoother.Current = 0.0f;
m_DySmoother.Current = 0.0f;
@@ -32,23 +34,13 @@ 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;
float MouseSpeed = m_Client->GetConfig()->GetMouseSpeed();
static const float MouseSpeed = 0.0025f;
m_Player->AddYaw(deltaX * MouseSpeed);
m_Player->AddPitch(deltaY * -MouseSpeed);
@@ -60,31 +52,26 @@ void PlayerController::Update(float delta) {
return;
if (InputManager::MouseGrabbed()) {
Keybinds keys = m_Client->GetConfig()->GetKeys();
float lr = static_cast<float>(ImGui::IsKeyDown((ImGuiKey(keys[kaAvancer])))) -
static_cast<float>(ImGui::IsKeyDown((ImGuiKey(keys[kaReculer]))));
float fb = static_cast<float>(ImGui::IsKeyDown((ImGuiKey(keys[kaGauche])))) -
static_cast<float>(ImGui::IsKeyDown((ImGuiKey(keys[kaDroite]))));
float lr = static_cast<float>(ImGui::IsKeyDown(ImGuiKey_Z)) - static_cast<float>(ImGui::IsKeyDown(ImGuiKey_S));
float fb = static_cast<float>(ImGui::IsKeyDown(ImGuiKey_Q)) - static_cast<float>(ImGui::IsKeyDown(ImGuiKey_D));
// 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_Velocity.x = lr * m_MaxVelocity.x * scale;
m_Velocity.y = fb * m_MaxVelocity.y * scale;
m_Dx = lr * m_MaxDx * scale;
m_Dy = fb * m_MaxDy * scale;
if (ImGui::IsKeyDown(ImGuiKey::ImGuiKey_Space) && m_OnGround) {
m_Velocity.z = m_MaxVelocity.z;
NotifyListeners(&game::PlayerInputListener::OnLocalPlayerJump);
m_Dz = m_MaxDz;
NotifyListeners(&game::PlayerInputListener::OnPlayerJump);
}
bool canShoot = m_ShootTimer.Update(ImGui::GetIO().DeltaTime);
bool canShoot = m_ShootTimer.Update(delta);
if (ImGui::IsMouseDown(ImGuiMouseButton_Left) && canShoot) {
NotifyListeners(
&game::PlayerInputListener::OnLocalPlayerShoot, m_Player->GetPosition(), m_Player->GetYaw(), m_Player->GetPitch());
&game::PlayerInputListener::OnPlayerShoot, m_Player->GetPosition(), m_Player->GetYaw(), m_Player->GetPitch());
m_ShootTimer.ApplyCooldown();
}
} else {
m_Velocity.x = m_Velocity.y = 0.0f;
}
UpdatePosition(delta);
@@ -96,8 +83,8 @@ void PlayerController::UpdatePosition(const float delta) {
float sine = std::sin(yaw);
float cosine = std::cos(yaw);
m_DxSmoother.Tick(m_Velocity.x, delta);
m_DySmoother.Tick(m_Velocity.y, delta);
m_DxSmoother.Tick(m_Dx, delta);
m_DySmoother.Tick(m_Dy, delta);
float dx_smooth = m_DxSmoother.Current;
float dy_smooth = m_DySmoother.Current;
@@ -105,17 +92,17 @@ 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_Velocity.z * delta;
float dz = m_Dz * delta;
// the floor here is y-level zero, once downwards collision lands it will be dynmicallly calculated
// assumed to be a negative number
const float floor_dist = 0.0f - m_Player->GetPosition().y;
if ((m_OnGround = (dz <= floor_dist))) {
if (m_OnGround = dz <= floor_dist) {
dz = floor_dist;
m_Velocity.z = 0.0f;
m_Dz = 0.0f;
} else {
m_Velocity.z -= m_Client->GetGame()->GetGameConfig().Gravity * 1.0f * delta;
m_Dz -= m_G * delta;
}
m_Player->AddPosition({dx, dz, dy});

View File

@@ -1,24 +1,19 @@
#include "client/game/ClientGame.h"
#include "blitz/game/entity/Player.h"
#include "blitz/misc/Log.h"
#include "blitz/misc/Random.h"
#include "blitz/protocol/PacketDispatcher.h"
#include "blitz/protocol/packets/PlayerJoinPacket.h"
#include "blitz/protocol/packets/PlayerLeavePacket.h"
#include "blitz/protocol/packets/PlayerListPacket.h"
#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"
namespace blitz {
namespace client {
ClientGame::ClientGame(Client* client, protocol::PacketDispatcher* dispatcher) :
protocol::PacketHandler(dispatcher), m_Client(client) {
protocol::PacketHandler(dispatcher), game::Game(&m_World), m_Client(client) {
RegisterHandlers();
}
@@ -26,25 +21,11 @@ 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);
GetDispatcher()->RegisterHandler(protocol::PacketType::PlayerList, this);
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) {
@@ -52,7 +33,7 @@ void ClientGame::HandlePacket(const protocol::PlayerJoinPacket* packet) {
// Initialize camera
if (packet->GetPlayerID() == m_Client->GetPlayerID()) {
m_Client->NotifyListeners(&game::ClientListener::OnSpectatorChange, packet->GetPlayerID());
m_Client->NotifyListeners(&GuiListener::OnSpectatorChange, packet->GetPlayerID());
}
}
@@ -66,40 +47,6 @@ void ClientGame::HandlePacket(const protocol::PlayerListPacket* packet) {
}
}
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) {
game::Player* player = m_Client->GetGame()->GetPlayerById(m_Client->GetPlayerID());
player->SetHP(packet->GetNewHealth());
// we are dead
if (player->GetHP() <= 0.0f) {
player->SetPosition({utils::GetRandomReal(-10.0f, 10.0f), 0, utils::GetRandomReal(-10.0f, 10.0f)});
}
}
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(
&game::ClientListener::OnPlayerShoot, packet->GetPlayer(), packet->GetPosition(), packet->GetYaw(), packet->GetPitch());
}
void ClientGame::HandlePacket(const protocol::PlayerPositionAndRotationPacket* packet) {
if (packet->GetPlayer() == m_Client->GetPlayerID())
return;
@@ -115,13 +62,9 @@ void ClientGame::HandlePacket(const protocol::PlayerPositionAndRotationPacket* p
}
void ClientGame::Tick(std::uint64_t delta) {
float deltaTime = static_cast<float>(delta) / 1000.0f;
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
}
player->SetPosition(player->GetPosition() + player->GetVelocity() * (static_cast<float>(delta) / 100.0f));
}
}

View File

@@ -0,0 +1,8 @@
#include "client/game/ClientWorld.h"
#include "blitz/game/entity/HitScanBullet.h"
#include "blitz/game/entity/Player.h"
namespace blitz {
namespace client {} // namespace client
} // namespace blitz

View File

@@ -1,11 +1,7 @@
#include "client/gui/BlitzGui.h"
#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/ServerGui.h"
#include <imgui.h>
namespace blitz {
@@ -15,10 +11,6 @@ BlitzGui::BlitzGui(Client* client) : GuiWidget(nullptr, client) {
Enable();
AddWidget(std::make_unique<GameChatGui>(this, client));
AddWidget(std::make_unique<MainMenu>(client));
AddWidget(std::make_unique<CrossHair>(client));
AddWidget(std::make_unique<Hud>(this, client));
AddWidget(std::make_unique<LeaderBoardGui>(this, client));
AddWidget(std::make_unique<ServerGui>(this, client));
SetCustomTheme();
}
@@ -31,10 +23,6 @@ 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;
@@ -43,15 +31,6 @@ 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

@@ -1,20 +1,13 @@
#include "client/gui/ColorFulText.h"
#include <imgui.h>
#include <imgui_internal.h>
namespace blitz {
namespace gui {
void RenderColorfulText(const protocol::ColoredText& parts, float alpha) {
ImGuiContext& g = *ImGui::GetCurrentContext();
for (auto& part : parts) {
const bool need_backup = (g.CurrentWindow->DC.TextWrapPos < 0.0f); // Keep existing wrap position if one is already set
if (need_backup)
ImGui::PushTextWrapPos(0.0f);
ImGui::TextColored({part.color.r, part.color.g, part.color.b, alpha}, "%s", part.text.c_str());
if (need_backup)
ImGui::PopTextWrapPos();
ImGui::SameLine();
ImGui::SetCursorPosX(ImGui::GetCursorPosX() - ImGui::CalcTextSize(".").x);
}

View File

@@ -18,9 +18,6 @@ void CreateGameMenu::Render() {
SetNextWindowFullScreen();
static int InputPort = 0;
const static ImVec2 buttonSize = {300, 60};
auto displaySize = ImGui::GetIO().DisplaySize;
const static int paddingHeight = 40;
ImGui::Begin("CreateWindow", nullptr, GetWindowFullScreenFlags());
{
@@ -43,9 +40,7 @@ void CreateGameMenu::Render() {
}
}
ImGui::SetCursorPosX(displaySize.x - buttonSize.x - paddingHeight);
ImGui::SetCursorPosY(displaySize.y - buttonSize.y - paddingHeight);
if (ImGui::Button("Retour", buttonSize) || ImGui::IsKeyPressed(ImGuiKey_Escape)) {
if (ImGui::Button("Retour") || ImGui::IsKeyPressed(ImGuiKey_Escape)) {
Disable();
m_Parent->Enable();
}

View File

@@ -1,29 +0,0 @@
#include "client/gui/Crosshair.h"
#include "client/Client.h"
#include "client/render/loader/TextureLoader.h"
#include <imgui.h>
namespace blitz {
namespace gui {
CrossHair::CrossHair(Client* client) : GuiWidget(nullptr, client) {
m_CrossHairTexture = TextureLoader::LoadGLTexture("crosshair.png");
}
void CrossHair::Render() {
if (!m_Client->IsConnected())
return;
static const ImVec2 crossHairSize = {40, 40};
ImGui::SetNextWindowPos({0, 0});
ImGui::Begin("CrossHair", nullptr, GetWindowFullScreenFlags() | ImGuiWindowFlags_NoInputs);
ImGui::SetCursorPosX(ImGui::GetIO().DisplaySize.x / 2.0f - crossHairSize.x / 2.0f);
ImGui::SetCursorPosY(ImGui::GetIO().DisplaySize.y / 2.0f - crossHairSize.y / 2.0f);
ImGui::Image(reinterpret_cast<ImTextureID>(m_CrossHairTexture), crossHairSize);
ImGui::End();
}
} // namespace gui
} // namespace blitz

View File

@@ -21,15 +21,22 @@ GameChatGui::GameChatGui(GuiWidget* parent, Client* client) : GuiWidget(parent,
}
void GameChatGui::Draw(const char* title, bool* p_open) {
HistoryPos = -1;
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));
static int chat_width = 620;
static int chat_height = 450;
static int chatInput_width = 590;
static int scrolling_width = chat_height - 90;
ImGui::SetNextWindowPos(ImVec2(0, ImGui::GetIO().DisplaySize.y - chat_height));
ImGui::SetNextWindowSize(ImVec2(chat_width, chat_height));
// const float footer_height_to_reserve = ImGui::GetStyle().ItemSpacing.y + ImGui::GetFrameHeightWithSpacing();
ImGui::Begin(title, p_open, GetWindowFullScreenFlags());
{
ImGui::PushStyleColor(ImGuiCol_Text, ImVec4(1.0f, 0.0f, 0.0f, 0.73f));
if (ImGui::BeginChild("ChatContent", ImVec2(0, chat_height - 90), false, ImGuiWindowFlags_AlwaysVerticalScrollbar)) {
for (const auto& line : m_Lines) {
RenderColorfulText(line, 1);
}
}
ImGui::PopStyleColor();
ImGui::EndChild();
ImGuiInputTextFlags input_text_flags = ImGuiInputTextFlags_EnterReturnsTrue | ImGuiInputTextFlags_EscapeClearsAll;
if (m_FocusRequested) {
@@ -37,10 +44,6 @@ void GameChatGui::Draw(const char* title, bool* p_open) {
m_FocusRequested = false;
}
for (const auto& line : m_Lines) {
RenderColorfulText(line, 1);
}
const static ImVec4 chatColorInputText = {1.0f, 0.0f, 0.0f, 0.27f};
ImGui::SetNextItemWidth(chatInput_width);
ImGui::PushStyleColor(ImGuiCol_FrameBg, chatColorInputText);
@@ -48,11 +51,6 @@ void GameChatGui::Draw(const char* title, bool* p_open) {
m_Client->SendChatText(InputBuf);
InputBuf[0] = '\0';
}
if (ScrollToBottom || (AutoScroll && ImGui::GetScrollY() >= ImGui::GetScrollMaxY()))
ImGui::SetScrollHereY(1.0f);
ScrollToBottom = false;
ImGui::PopStyleColor();
}
@@ -60,19 +58,15 @@ void GameChatGui::Draw(const char* title, bool* p_open) {
}
void GameChatGui::DrawMini(const char* title, bool* p_open) {
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));
static int chat_width = 620;
static int chat_height = 110;
ImGui::SetNextWindowPos(ImVec2(0, ImGui::GetIO().DisplaySize.y - chat_height));
ImGui::SetNextWindowSize(ImVec2(chat_width, chat_height));
ImGui::Begin(title, p_open, GetWindowFullScreenFlags() | ImGuiWindowFlags_NoNav);
{
for (const auto& line : m_TempLines) {
RenderColorfulText(line, utils::EaseOutCubic(m_ChatDisplay / ChatFadeTime));
}
if (ScrollToBottom || (AutoScroll && ImGui::GetScrollY() >= ImGui::GetScrollMaxY()))
ImGui::SetScrollHereY(1.0f);
ScrollToBottom = false;
}
ImGui::End();
}

View File

@@ -1,163 +0,0 @@
#include "client/gui/Hud.h"
#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>
namespace blitz {
namespace gui {
Hud::Hud(GuiWidget* parent, Client* client) : GuiWidget(parent, client) {
m_GunTexture = TextureLoader::LoadGLTexture("fingergun.png");
m_JPTexture = TextureLoader::LoadGLTexture("jp.png");
}
void Hud::Draw(const char* title, bool* p_open) {
SetNextWindowFullScreen();
ImGui::Begin(title, nullptr, GetWindowFullScreenFlags() | ImGuiWindowFlags_NoInputs);
auto displaySize = ImGui::GetIO().DisplaySize;
const static ImVec2 buttonSize = {300, 60};
const static ImVec2 fingergunSize = {256, 134.5};
const static ImVec2 jpSize = {256 / 2, 256 / 2};
const static int paddingHeight = 40;
const static ImVec2 pvBarPos = {displaySize.x / 2.2f, displaySize.y - 3 * paddingHeight};
const static ImVec2 progressSize = {100.0f, 30.0f};
const static ImVec2 currentWeaponPos = {
displaySize.x - buttonSize.x - 3 * paddingHeight, displaySize.y - buttonSize.y - 1.5f * paddingHeight};
const static ImVec2 currentWeaponPosImage = {
displaySize.x - fingergunSize.x - paddingHeight, displaySize.y - fingergunSize.y + 1.0f / 2.5f * paddingHeight};
ImVec2 spacing = ImGui::GetStyle().ItemInnerSpacing;
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_JPTexture), jpSize);
ImGui::SameLine(0.0f, paddingHeight);
ImGui::BeginGroup();
{
game::Player* player = m_Client->GetGame()->GetPlayerById(m_Client->GetPlayerID());
if (player) {
ImGui::Text("PV : %.0f", player->GetHP());
ImGui::ProgressBar(static_cast<float>(player->GetHP() / 100.0f), progressSize, "");
}
}
ImGui::EndGroup();
ImGui::EndGroup();
ImGui::SetCursorPosX(currentWeaponPos.x);
ImGui::SetCursorPosY(currentWeaponPos.y);
ImGui::BeginGroup();
{
ImGui::Text("FingerGun");
ImGui::SameLine(0.0f, spacing.x * 50);
ImGui::Text("3 | 9");
ImGui::SetCursorPosX(currentWeaponPosImage.x);
ImGui::SetCursorPosY(currentWeaponPosImage.y);
ImGui::Image(reinterpret_cast<ImTextureID>(m_GunTexture), fingergunSize);
}
ImGui::EndGroup();
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;
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

@@ -17,9 +17,6 @@ void JoinGameMenu::Render() {
SetNextWindowFullScreen();
static int InputPort = 25565;
const static ImVec2 buttonSize = {300, 60};
auto displaySize = ImGui::GetIO().DisplaySize;
const static int paddingHeight = 40;
ImGui::Begin("JoinWindow", nullptr, GetWindowFullScreenFlags());
{
@@ -47,9 +44,7 @@ void JoinGameMenu::Render() {
}
}
ImGui::SetCursorPosX(displaySize.x - buttonSize.x - paddingHeight);
ImGui::SetCursorPosY(displaySize.y - buttonSize.y - paddingHeight);
if (ImGui::Button("Retour", buttonSize) || ImGui::IsKeyPressed(ImGuiKey_Escape)) {
if (ImGui::Button("Retour") || ImGui::IsKeyPressed(ImGuiKey_Escape)) {
Disable();
m_Parent->Enable();
}

View File

@@ -1,83 +0,0 @@
#include "client/gui/LeaderBoardGui.h"
#include "blitz/misc/Format.h"
#include "blitz/misc/Log.h"
#include "client/Client.h"
#include "client/game/ClientGame.h"
#include "client/gui/GuiWidget.h"
#include <imgui.h>
namespace blitz {
namespace gui {
LeaderBoardGui::LeaderBoardGui(GuiWidget* parent, Client* client) : GuiWidget(parent, client) {}
LeaderBoardGui::~LeaderBoardGui() {}
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;
ImVec2 center = ImGui::GetMainViewport()->GetCenter();
ImGui::SetNextWindowPos(center, ImGuiCond_Appearing, ImVec2(0.5f, 0.5f));
ImGui::SetNextWindowSize(ImVec2(leaderboard_width, leaderboard_height));
ImGui::Begin(title, p_open, leaderboard_flags);
{
std::string playerLeaderBoard = "Player";
std::string killsLeaderBoard = "Kills";
std::string deathsLeaderBoard = "Deaths";
std::string kdLeaderBoard = "K/D";
std::string precisionLeaderBoard = "Accuracy";
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;
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
: 0.0f;
precisionLeaderBoard += utils::Format("\n%.2f%%", precisionPercentage);
}
ImGui::Text("%s", playerLeaderBoard.c_str());
ImGui::SameLine(0.0f, ImGui::GetStyle().ItemInnerSpacing.x * 10);
ImGui::Text("%s", killsLeaderBoard.c_str());
ImGui::SameLine(0.0f, ImGui::GetStyle().ItemInnerSpacing.x * 10);
ImGui::Text("%s", deathsLeaderBoard.c_str());
ImGui::SameLine(0.0f, ImGui::GetStyle().ItemInnerSpacing.x * 10);
ImGui::Text("%s", kdLeaderBoard.c_str());
ImGui::SameLine(0.0f, ImGui::GetStyle().ItemInnerSpacing.x * 10);
ImGui::Text("%s", precisionLeaderBoard.c_str());
}
ImGui::End();
}
void LeaderBoardGui::Render() {
if (!m_Client->IsConnected())
return;
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
} // namespace blitz

View File

@@ -1,7 +1,5 @@
#include "client/gui/OptionsMenu.h"
#include "blitz/misc/Format.h"
#include "blitz/misc/Log.h"
#include "client/Client.h"
#include "client/display/InputManager.h"
#include "client/gui/FPSMenu.h"
@@ -11,87 +9,7 @@
namespace blitz {
namespace gui {
static std::string ActionNames[kaMax] = {
"Avancer",
"Reculer",
"Droite",
"Gauche",
"Fenetre Admin",
};
static std::string GetActionName(KeyAction action) {
return ActionNames[action];
}
static std::string GetImGuiKeyName(int key) {
if (key == ImGuiKey_None) {
return "?";
}
return ImGui::GetKeyName(static_cast<ImGuiKey>(key));
}
void OptionsMenu::HotkeyBindingButton() {
for (std::size_t i = 0; i < m_Client->GetConfig()->GetKeys().size(); i++) {
if (ImGui::Button(utils::Format("%s##%i", GetKeyActionCodeName(KeyAction(i)).c_str(), i).c_str())) {
m_IsKeyPopupOpen = true;
m_CurrentAction = KeyAction(i);
ImGui::OpenPopup("Changer de touche");
}
ImGui::SameLine();
ImGui::Text("%s", GetActionName(KeyAction(i)).c_str());
}
}
void OptionsMenu::HotkeyBindingPopUp() {
// Always center this window when appearing
ImVec2 center = ImGui::GetMainViewport()->GetCenter();
ImGui::SetNextWindowPos(center, ImGuiCond_Appearing, ImVec2(0.5f, 0.5f));
if (ImGui::BeginPopupModal("Changer de touche", NULL, ImGuiWindowFlags_AlwaysAutoResize)) {
ImGui::Text("Entrez la touche pour : ");
ImGui::SameLine();
ImGui::TextColored(ImVec4(1.0f, 1.0f, 0.0f, 1.0f), "%s", GetActionName(m_CurrentAction).c_str());
ImGui::Text("Si vous voulez annulez cette action, appuyez sur Echap !");
ImGui::Dummy({0, 40});
ImGui::Text("La touche pour ");
ImGui::TextColored(ImVec4(1.0f, 1.0f, 0.0f, 1.0f), "%s", GetActionName(m_CurrentAction).c_str());
ImGui::SameLine();
ImGui::Text(" est : ");
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(static_cast<std::uint64_t>(ImGui::GetIO().DeltaTime * 1000.0f))) {
m_KeyPopupShouldClose = false;
m_IsKeyPopupOpen = false;
ImGui::CloseCurrentPopup();
}
ImGui::EndPopup();
}
}
OptionsMenu::OptionsMenu(GuiWidget* parent, Client* client) :
GuiWidget(parent, client), m_IsKeyPopupOpen(false), m_KeyPopupShouldClose(false) {
OptionsMenu::OptionsMenu(GuiWidget* parent, Client* client) : GuiWidget(parent, client) {
AddWidget(std::make_unique<FPSMenu>(this, client));
InputManager::BindKeyDownCallback(std::bind(&OptionsMenu::OnKeyEvent, this, std::placeholders::_1));
@@ -102,37 +20,7 @@ OptionsMenu::OptionsMenu(GuiWidget* parent, Client* client) :
SDL_GL_SetSwapInterval(m_VSync);
}
void OptionsMenu::OnKeyEvent(int key) {
if (!m_IsKeyPopupOpen)
return;
if (key == ImGuiKey_Escape) {
m_KeyPopupShouldClose = true;
ImGui::GetIO().ClearInputKeys(); // releases the Escape key
return;
}
m_Client->GetConfig()->GetKeys()[static_cast<std::size_t>(m_CurrentAction)] = key;
m_KeyPopupShouldClose = true;
utils::LOG(std::to_string(key));
}
std::string OptionsMenu::GetKeyActionCodeName(KeyAction act) {
return GetImGuiKeyName(static_cast<int>(m_Client->GetConfig()->GetKeys()[act]));
}
void OptionsMenu::OnKeyEvent(int key) {}
void OptionsMenu::Render() {
GuiWidget::Render();
@@ -146,8 +34,6 @@ void OptionsMenu::Render() {
if (!IsEnabled())
return;
const static ImVec2 buttonSize = {300, 60};
auto displaySize = ImGui::GetIO().DisplaySize;
const static int paddingHeight = 40;
const static int startPos = 15;
@@ -161,20 +47,6 @@ void OptionsMenu::Render() {
ImGui::NewLine();
ImGuiTabBarFlags tab_bar_flags = ImGuiTabBarFlags_None;
if (ImGui::BeginTabBar("OPTIONS", tab_bar_flags)) {
if (ImGui::BeginTabItem("CONTROLES")) {
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")) {
if (ImGui::Checkbox("AFFICHER LES FPS", &m_ShowFPS)) {
m_SubWidgets[0]->SetState(m_ShowFPS);
m_Client->GetConfig()->SetFPSDisplay(m_ShowFPS);
@@ -184,23 +56,8 @@ void OptionsMenu::Render() {
SDL_GL_SetSwapInterval(m_VSync);
m_Client->GetConfig()->SetVSync(m_VSync);
}
ImGui::EndTabItem();
}
if (ImGui::BeginTabItem("AUDIO")) {
ImGui::EndTabItem();
}
ImGui::EndTabBar();
if (m_Client->IsConnected()) {
ImGui::SetCursorPosX(displaySize.x - buttonSize.x - paddingHeight);
ImGui::SetCursorPosY(displaySize.y - 2 * buttonSize.y - paddingHeight);
} else {
ImGui::SetCursorPosX(displaySize.x - buttonSize.x - paddingHeight);
ImGui::SetCursorPosY(displaySize.y - buttonSize.y - paddingHeight);
}
ImGui::BeginGroup();
{
if (ImGui::Button("Retour", buttonSize) || ImGui::IsKeyPressed(ImGuiKey_Escape)) {
if (ImGui::Button("Retour") || ImGui::IsKeyPressed(ImGuiKey_Escape)) {
Disable();
if (m_Client->IsConnected()) {
InputManager::GrabMouse(true);
@@ -208,17 +65,15 @@ void OptionsMenu::Render() {
m_Parent->Enable();
}
}
if (m_Client->IsConnected()) {
if (ImGui::Button("Quitter la partie", buttonSize)) {
if (ImGui::Button("Quitter la partie")) {
m_Client->Disconnect();
Disable();
m_Parent->Enable();
}
}
}
ImGui::EndGroup();
}
}
ImGui::End();
}

View File

@@ -1,129 +0,0 @@
#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 {
namespace gui {
ServerGui::ServerGui(GuiWidget* parent, Client* client) : GuiWidget(parent, client) {}
void ServerGui::Render() {
if (!m_Client->IsAdmin())
return;
Keybinds keys = m_Client->GetConfig()->GetKeys();
if (ImGui::IsKeyPressed(ImGuiKey(keys[kaFenetreAdmin])) && InputManager::MouseGrabbed()) {
ImGui::OpenPopup("FENETRE D'ADMIN");
}
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;
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();
}
}
} // namespace gui
} // namespace blitz

View File

@@ -1,88 +0,0 @@
#include "client/render/BulletRenderer.h"
#include "blitz/maths/Maths.h"
#include "blitz/misc/Log.h"
#include "blitz/misc/Test.h"
#include "client/render/Camera.h"
#include "client/render/OpenGL.h"
#include "client/render/loader/GLLoader.h"
#include "client/render/shader/BulletShader.h"
#include <imgui.h>
namespace blitz {
namespace render {
static const float BULLET_DECAY_TIME = 5.0f;
BulletRenderer::BulletRenderer(const Camera& camera) : m_Camera(camera) {
m_Shader = std::make_unique<shader::BulletShader>();
blitz_debug_assert(m_Shader->LoadShader());
m_BulletModel = ModelLoader::LoadModel("cube.glb");
}
BulletRenderer::~BulletRenderer() {}
void BulletRenderer::AddBullet(const Vec3f& origin, float yaw, float pitch, bool firstPersson) {
static const float TRAIL_LENGHT = 50;
Vec3f direction = {
std::cos(yaw) * std::cos(pitch),
std::sin(pitch),
std::sin(yaw) * std::cos(pitch),
};
Vec3f middle = origin + direction * (TRAIL_LENGHT / 2.0f);
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));
Trail trail{transform, BULLET_DECAY_TIME};
m_Trails.push_back(trail);
}
void BulletRenderer::Update(float delta) {
for (Trail& trail : m_Trails) {
trail.m_Decay -= delta;
}
for (std::size_t i = 0; i < m_Trails.size(); i++) {
if (m_Trails[i].m_Decay < 0) {
m_Trails.erase(m_Trails.begin() + i);
}
}
m_Shader->Start();
m_Shader->SetProjectionMatrix(m_Camera.GetPerspectiveMatrix());
m_Shader->SetViewMatrix(m_Camera.GetViewMatrix());
}
void BulletRenderer::Render() {
m_Shader->Start();
// un peu frauduleux
ModelLoader::VaoPtr& vao = m_BulletModel.mVaos[0];
vao->Bind();
for (Trail& trail : m_Trails) {
m_Shader->SetDecay(trail.m_Decay / BULLET_DECAY_TIME);
m_Shader->SetTransform(trail.m_Transform);
glDrawElements(GL_TRIANGLES, static_cast<GLsizei>(vao->GetVertexCount()), GL_UNSIGNED_INT, nullptr);
}
vao->Unbind();
}
} // namespace render
} // namespace blitz

View File

@@ -1,17 +1,17 @@
#include "client/render/Camera.h"
#include "blitz/game/Player.h"
#include "blitz/maths/Maths.h"
#include "blitz/game/entity/Player.h"
#include "blitz/misc/Maths.h"
#include "imgui.h"
namespace blitz {
namespace render {
static const float EyeHeight = 1.25f;
static const float eyeHeight = 1.25f;
void Camera::Update(float delta) {
int windowWidth = static_cast<int>(ImGui::GetIO().DisplaySize.x);
int windowHeight = static_cast<int>(ImGui::GetIO().DisplaySize.y);
int windowWidth = ImGui::GetIO().DisplaySize.x;
int windowHeight = ImGui::GetIO().DisplaySize.y;
if (windowWidth != m_LastWindowSize.x || windowHeight != m_LastWindowSize.y) {
m_LastWindowSize = {windowWidth, windowHeight};
@@ -21,10 +21,6 @@ void Camera::Update(float delta) {
}
}
float Camera::GetPlayerEyeHeight() {
return EyeHeight;
}
Mat4f Camera::GetViewMatrix() const {
Vec3f front = {
std::cos(m_Player->GetYaw()) * std::cos(m_Player->GetPitch()),
@@ -32,7 +28,7 @@ Mat4f Camera::GetViewMatrix() const {
std::sin(m_Player->GetYaw()) * std::cos(m_Player->GetPitch()),
};
return maths::Look(m_Player->GetPosition() + Vec3f{0, EyeHeight, 0}, front, {0, 1, 0});
return maths::Look(m_Player->GetPosition() + Vec3f{0, eyeHeight, 0}, front, {0, 1, 0});
}
} // namespace render

View File

@@ -1,31 +1,31 @@
#include "client/render/MainRenderer.h"
#include "blitz/maths/Maths.h"
#include "blitz/misc/Easing.h"
#include "blitz/misc/Format.h"
#include "blitz/misc/Log.h"
#include "blitz/misc/Maths.h"
#include "blitz/misc/Test.h"
#include "blitz/misc/Time.h"
#include "client/Client.h"
#include "client/game/ClientGame.h"
#include "client/render/OpenGL.h"
#include "client/render/loader/GLLoader.h"
#include "client/render/loader/ModelLoader.h"
#include "client/render/loader/TextureLoader.h"
#include "client/render/shader/BulletShader.h"
#include "client/render/shader/EntityShader.h"
#include "client/render/shader/GunShader.h"
#include "client/render/shader/WorldShader.h"
#include "imgui.h"
#include <glbinding/gl/gl.h>
using namespace gl;
namespace blitz {
namespace render {
static const Vec4f SkyColor = {0.6f, 0.8f, 1.0f, 1.0f};
static const Vec4f MenuColor = {0.0f, 0.0f, 0.0f, 0.0f};
static const Vec4f SkyColor = {0.6, 0.8, 1, 1};
static const Vec4f MenuColor = {0, 0, 0, 0};
MainRenderer::MainRenderer(Client* client) :
m_Client(client), m_PlayerController(m_Client), m_ShootTime(0), m_BulletRenderer(m_Camera) {
MainRenderer::MainRenderer(Client* client) : m_Client(client), m_ShootTime(0) {
LoadModels();
@@ -49,9 +49,6 @@ MainRenderer::MainRenderer(Client* client) :
glEnable(GL_CULL_FACE);
glCullFace(GL_FRONT);
glFrontFace(GL_CW);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
}
MainRenderer::~MainRenderer() {}
@@ -69,14 +66,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, static_cast<GLsizei>(vao.GetVertexCount()), GL_UNSIGNED_INT, nullptr);
glDrawElements(GL_TRIANGLES, vao.GetVertexCount(), GL_UNSIGNED_INT, nullptr);
vao.Unbind();
}
void MainRenderer::RenderWorld(const GL::VertexArray& vao) {
m_WorldShader->Start();
vao.Bind();
glDrawElements(GL_TRIANGLES, static_cast<GLsizei>(vao.GetVertexCount()), GL_UNSIGNED_INT, nullptr);
glDrawElements(GL_TRIANGLES, vao.GetVertexCount(), GL_UNSIGNED_INT, nullptr);
vao.Unbind();
}
@@ -92,32 +89,20 @@ void MainRenderer::Render() {
RenderWorld();
RenderPlayers();
RenderGun();
m_BulletRenderer.Render();
}
void MainRenderer::RenderPlayers() {
for (const auto& [playerId, player] : m_Client->GetGame()->GetPlayers()) {
if (playerId != m_Client->GetPlayerID()) {
for (auto& Vao : m_PlayerModel.mVaos) {
RenderEntity(*Vao.get(), player.GetPosition(), player.GetYaw());
RenderEntity(*Vao.get(), player->GetPosition(), player->GetYaw());
}
}
}
}
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 = 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, player == m_Client->GetPlayerID());
void MainRenderer::OnPlayerShoot(const Vec3f& position, float yaw, float pitch) {
m_ShootTime = 1.0f;
}
void MainRenderer::RenderGun() {
@@ -126,7 +111,7 @@ void MainRenderer::RenderGun() {
m_GunShader->Start();
float progression = 1.0f - (m_ShootTime / static_cast<float>(60.0f / m_Client->GetGame()->GetGameConfig().FiringRate));
float progression = 1.0f - m_ShootTime;
float angle = progression * progression * progression * 7 - progression * progression * 11 + progression * 4;
@@ -135,7 +120,7 @@ void MainRenderer::RenderGun() {
for (auto& Vao : m_GunModel.mVaos) {
Vao->Bind();
glDrawElements(GL_TRIANGLES, static_cast<GLsizei>(Vao->GetVertexCount()), GL_UNSIGNED_INT, nullptr);
glDrawElements(GL_TRIANGLES, Vao->GetVertexCount(), GL_UNSIGNED_INT, nullptr);
Vao->Unbind();
}
}
@@ -160,21 +145,17 @@ void MainRenderer::Update() {
m_PlayerController.Update(delta);
m_Camera.Update(delta);
m_BulletRenderer.Update(delta);
Mat4f projectionMatrix = m_Camera.GetPerspectiveMatrix();
Mat4f viewMatrix = m_Camera.GetViewMatrix();
m_EntityShader->Start();
m_EntityShader->SetProjectionMatrix(projectionMatrix);
m_EntityShader->SetViewMatrix(viewMatrix);
m_EntityShader->SetProjectionMatrix(m_Camera.GetPerspectiveMatrix());
m_EntityShader->SetViewMatrix(m_Camera.GetViewMatrix());
m_WorldShader->Start();
m_WorldShader->SetProjectionMatrix(projectionMatrix);
m_WorldShader->SetViewMatrix(viewMatrix);
m_WorldShader->SetProjectionMatrix(m_Camera.GetPerspectiveMatrix());
m_WorldShader->SetViewMatrix(m_Camera.GetViewMatrix());
m_GunShader->Start();
m_GunShader->SetProjectionMatrix(projectionMatrix);
m_GunShader->SetProjectionMatrix(m_Camera.GetPerspectiveMatrix());
m_ShootTime = std::max(0.0f, m_ShootTime - delta);
}

Some files were not shown because too many files have changed in this diff Show More