Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 5cfdd63cb6 |
@@ -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
|
||||
4
.vscode/c_cpp_properties.json
vendored
4
.vscode/c_cpp_properties.json
vendored
@@ -3,9 +3,7 @@
|
||||
{
|
||||
"name": "Blitz",
|
||||
"cppStandard": "c++17",
|
||||
"includePath": [
|
||||
"include"
|
||||
],
|
||||
"includePath": ["include"],
|
||||
"compileCommands": ".vscode/compile_commands.json"
|
||||
}
|
||||
],
|
||||
|
||||
7
.vscode/launch.json
vendored
7
.vscode/launch.json
vendored
@@ -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 |
BIN
assets/cube.glb
BIN
assets/cube.glb
Binary file not shown.
Binary file not shown.
|
Before Width: | Height: | Size: 218 KiB |
BIN
assets/jp.png
BIN
assets/jp.png
Binary file not shown.
|
Before Width: | Height: | Size: 78 KiB |
40
assets/player.obj
Normal file
40
assets/player.obj
Normal 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
37
assets/void_map.obj
Normal 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
38
assets/void_map2.obj
Normal 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
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
@@ -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);
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
29
include/blitz/game/World.h
Normal file
29
include/blitz/game/World.h
Normal 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
|
||||
46
include/blitz/game/entity/Entity.h
Normal file
46
include/blitz/game/entity/Entity.h
Normal 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
|
||||
21
include/blitz/game/entity/HitScanBullet.h
Normal file
21
include/blitz/game/entity/HitScanBullet.h
Normal 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
|
||||
54
include/blitz/game/entity/Player.h
Normal file
54
include/blitz/game/entity/Player.h
Normal 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
|
||||
@@ -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
|
||||
@@ -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);
|
||||
@@ -1,6 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
#include "blitz/maths/Vector.h"
|
||||
#include "blitz/common/Vector.h"
|
||||
#include <string>
|
||||
|
||||
namespace blitz {
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
#include "blitz/maths/Vector.h"
|
||||
#include "blitz/common/Vector.h"
|
||||
#include "blitz/protocol/Protocol.h"
|
||||
#include <vector>
|
||||
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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();
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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);
|
||||
};
|
||||
|
||||
@@ -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();
|
||||
|
||||
24
include/client/game/ClientWorld.h
Normal file
24
include/client/game/ClientWorld.h
Normal 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
|
||||
@@ -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
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
30
include/server/game/ServerWorld.h
Normal file
30
include/server/game/ServerWorld.h
Normal 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
|
||||
@@ -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) {
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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
37
src/blitz/game/World.cpp
Normal 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
|
||||
@@ -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
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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));
|
||||
|
||||
@@ -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>(),
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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)
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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__
|
||||
|
||||
@@ -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});
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
8
src/client/game/ClientWorld.cpp
Normal file
8
src/client/game/ClientWorld.cpp
Normal 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
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
|
||||
@@ -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
Reference in New Issue
Block a user