Move player character creation to EnterableWorld & route player events via Game
This commit is contained in:
parent
d0b30ed56b
commit
ba0bb5a827
@ -130,6 +130,8 @@ set(SERVER_ONLY_SOURCES
|
||||
"src/game/destroyed_object.cpp"
|
||||
"src/game/drivable_vehicle.hpp"
|
||||
"src/game/drivable_vehicle.cpp"
|
||||
"src/game/enterable_world.hpp"
|
||||
"src/game/enterable_world.cpp"
|
||||
"src/game/entity.hpp"
|
||||
"src/game/entity.cpp"
|
||||
"src/game/game.hpp"
|
||||
|
||||
97
src/game/enterable_world.cpp
Normal file
97
src/game/enterable_world.cpp
Normal file
@ -0,0 +1,97 @@
|
||||
#include "enterable_world.hpp"
|
||||
#include "player_character.hpp"
|
||||
|
||||
static glm::vec3 GetRandomColor()
|
||||
{
|
||||
glm::vec3 color;
|
||||
// shittiest way to do it
|
||||
for (int i = 0; i < 3; ++i)
|
||||
{
|
||||
net::ColorQ qcol;
|
||||
qcol.value = rand() % 256;
|
||||
color[i] = qcol.Decode();
|
||||
}
|
||||
|
||||
return color;
|
||||
}
|
||||
|
||||
game::EnterableWorld::EnterableWorld(std::string mapname) : World(std::move(mapname)) {}
|
||||
|
||||
void game::EnterableWorld::InsertPlayer(Player& player, const glm::vec3& pos, float yaw)
|
||||
{
|
||||
CreatePlayerCharacter(player, pos, yaw);
|
||||
}
|
||||
|
||||
void game::EnterableWorld::PlayerInput(Player& player, PlayerInputType type, bool enabled)
|
||||
{
|
||||
auto it = player_characters_.find(&player);
|
||||
if (it == player_characters_.end())
|
||||
return;
|
||||
|
||||
auto character = it->second;
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case IN_DEBUG1:
|
||||
if (enabled)
|
||||
{
|
||||
if (character->GetVehicle())
|
||||
character->GetVehicle()->SetPosition({100.0f, 100.0f, 5.0f});
|
||||
else
|
||||
character->SetPosition({100.0f, 100.0f, 5.0f});
|
||||
}
|
||||
break;
|
||||
|
||||
case IN_DEBUG2:
|
||||
if (enabled)
|
||||
CreatePlayerCharacter(player, glm::vec3(100.0f, 100.0f, 5.0f), 0.0f);
|
||||
break;
|
||||
|
||||
default:
|
||||
character->ProcessInput(type, enabled);
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void game::EnterableWorld::PlayerViewAnglesChanged(Player& player, float yaw, float pitch)
|
||||
{
|
||||
auto it = player_characters_.find(&player);
|
||||
if (it == player_characters_.end())
|
||||
return;
|
||||
|
||||
auto character = it->second;
|
||||
|
||||
character->SetForwardYaw(yaw);
|
||||
}
|
||||
|
||||
void game::EnterableWorld::RemovePlayer(Player& player)
|
||||
{
|
||||
RemovePlayerCharacter(player);
|
||||
}
|
||||
|
||||
game::PlayerCharacter& game::EnterableWorld::CreatePlayerCharacter(Player& player, const glm::vec3& position, float yaw)
|
||||
{
|
||||
RemovePlayerCharacter(player);
|
||||
|
||||
auto& character = Spawn<PlayerCharacter>(player);
|
||||
character.AddClothes("tshirt", GetRandomColor());
|
||||
character.AddClothes("shorts", GetRandomColor());
|
||||
|
||||
// character.SetNametag("player (" + std::to_string(character.GetEntNum()) + ")");
|
||||
character.SetPosition(position);
|
||||
character.SetYaw(yaw);
|
||||
|
||||
player_characters_[&player] = &character;
|
||||
return character;
|
||||
}
|
||||
|
||||
void game::EnterableWorld::RemovePlayerCharacter(Player& player)
|
||||
{
|
||||
auto it = player_characters_.find(&player);
|
||||
if (it != player_characters_.end())
|
||||
{
|
||||
it->second->Remove();
|
||||
player_characters_.erase(it);
|
||||
}
|
||||
}
|
||||
34
src/game/enterable_world.hpp
Normal file
34
src/game/enterable_world.hpp
Normal file
@ -0,0 +1,34 @@
|
||||
#pragma once
|
||||
|
||||
#include "world.hpp"
|
||||
#include "drivable_vehicle.hpp"
|
||||
|
||||
namespace game
|
||||
{
|
||||
|
||||
class Player;
|
||||
class PlayerCharacter;
|
||||
|
||||
class EnterableWorld : public World
|
||||
{
|
||||
public:
|
||||
EnterableWorld(std::string mapname);
|
||||
|
||||
// events
|
||||
virtual void InsertPlayer(Player& player, const glm::vec3& pos, float yaw);
|
||||
virtual void PlayerInput(Player& player, PlayerInputType type, bool enabled);
|
||||
virtual void PlayerViewAnglesChanged(Player& player, float yaw, float pitch);
|
||||
virtual void RemovePlayer(Player& player);
|
||||
|
||||
private:
|
||||
PlayerCharacter& CreatePlayerCharacter(Player& player, const glm::vec3& position, float yaw);
|
||||
void RemovePlayerCharacter(Player& player);
|
||||
|
||||
private:
|
||||
std::map<Player*, PlayerCharacter*> player_characters_;
|
||||
|
||||
|
||||
};
|
||||
|
||||
|
||||
}
|
||||
@ -5,43 +5,76 @@
|
||||
|
||||
game::Game::Game()
|
||||
{
|
||||
default_world_ = std::make_shared<OpenWorld>();
|
||||
|
||||
openworld_ = std::make_shared<OpenWorld>();
|
||||
all_worlds_.push_back(openworld_.get());
|
||||
}
|
||||
|
||||
void game::Game::Update()
|
||||
{
|
||||
default_world_->Update(40);
|
||||
for (auto world : all_worlds_)
|
||||
{
|
||||
world->Update(40);
|
||||
}
|
||||
}
|
||||
|
||||
void game::Game::FinishFrame()
|
||||
{
|
||||
default_world_->FinishFrame();
|
||||
for (auto world : all_worlds_)
|
||||
{
|
||||
world->FinishFrame();
|
||||
}
|
||||
}
|
||||
|
||||
void game::Game::PlayerJoined(Player& player)
|
||||
{
|
||||
player.SetWorld(default_world_);
|
||||
|
||||
players_.insert(&player);
|
||||
BroadcastChat(player.GetName() + "^r se připoojil jupí jupí jupííí");
|
||||
|
||||
players_.insert({ &player, PlayerGameInfo(player) });
|
||||
auto& player_info = players_.at(&player);
|
||||
player_info.world = openworld_.get();
|
||||
player.SetWorld(openworld_);
|
||||
|
||||
openworld_->InsertPlayer(player, glm::vec3(100.0f, 100.0f, 5.0f), 0.0f);
|
||||
}
|
||||
|
||||
void game::Game::PlayerViewAnglesChanged(Player& player, float yaw, float pitch)
|
||||
{
|
||||
auto world = FindPlayerWorld(player);
|
||||
if (world)
|
||||
world->PlayerViewAnglesChanged(player, yaw, pitch);
|
||||
}
|
||||
|
||||
void game::Game::PlayerInput(Player& player, PlayerInputType type, bool enabled)
|
||||
{
|
||||
auto world = FindPlayerWorld(player);
|
||||
if (world)
|
||||
world->PlayerInput(player, type, enabled);
|
||||
}
|
||||
|
||||
void game::Game::PlayerLeft(Player& player)
|
||||
{
|
||||
players_.erase(&player);
|
||||
BroadcastChat(player.GetName() + "^r se vodpojil zmrd");
|
||||
}
|
||||
auto world = FindPlayerWorld(player);
|
||||
if (world)
|
||||
world->RemovePlayer(player);
|
||||
|
||||
bool game::Game::PlayerInput(Player& player, PlayerInputType type, bool enabled)
|
||||
{
|
||||
return false; // not handled here
|
||||
players_.erase(&player);
|
||||
|
||||
BroadcastChat(player.GetName() + "^r se vodpojil zmrd");
|
||||
}
|
||||
|
||||
void game::Game::BroadcastChat(const std::string& text)
|
||||
{
|
||||
for (auto player : players_)
|
||||
for (auto& [player, info] : players_)
|
||||
{
|
||||
player->SendChat(text);
|
||||
}
|
||||
}
|
||||
|
||||
game::EnterableWorld* game::Game::FindPlayerWorld(Player& player) const
|
||||
{
|
||||
auto it = players_.find(&player);
|
||||
if (it == players_.end())
|
||||
return nullptr;
|
||||
|
||||
return it->second.world;
|
||||
}
|
||||
|
||||
@ -1,15 +1,23 @@
|
||||
#pragma once
|
||||
|
||||
#include <map>
|
||||
#include <set>
|
||||
|
||||
#include "world.hpp"
|
||||
#include "enterable_world.hpp"
|
||||
#include "openworld.hpp"
|
||||
|
||||
namespace game
|
||||
{
|
||||
|
||||
class Player;
|
||||
|
||||
struct PlayerGameInfo
|
||||
{
|
||||
Player& player;
|
||||
EnterableWorld* world = nullptr;
|
||||
|
||||
PlayerGameInfo(Player& player) : player(player) {}
|
||||
};
|
||||
|
||||
class Game
|
||||
{
|
||||
public:
|
||||
@ -19,15 +27,21 @@ public:
|
||||
void FinishFrame();
|
||||
|
||||
void PlayerJoined(Player& player);
|
||||
void PlayerViewAnglesChanged(Player& player, float yaw, float pitch);
|
||||
void PlayerInput(Player& player, PlayerInputType type, bool enabled);
|
||||
void PlayerLeft(Player& player);
|
||||
bool PlayerInput(Player& player, PlayerInputType type, bool enabled);
|
||||
|
||||
private:
|
||||
void BroadcastChat(const std::string& text);
|
||||
|
||||
EnterableWorld* FindPlayerWorld(Player& player) const;
|
||||
|
||||
private:
|
||||
std::shared_ptr<World> default_world_;
|
||||
std::set<Player*> players_;
|
||||
std::shared_ptr<OpenWorld> openworld_;
|
||||
|
||||
|
||||
std::vector<World*> all_worlds_; // for common update etc.
|
||||
std::map<Player*, PlayerGameInfo> players_;
|
||||
|
||||
};
|
||||
|
||||
|
||||
@ -45,10 +45,8 @@ static uint32_t GetRandomColor24()
|
||||
return (b << 16) | (g << 8) | r;
|
||||
}
|
||||
|
||||
game::OpenWorld::OpenWorld() : World("openworld")
|
||||
game::OpenWorld::OpenWorld() : EnterableWorld("openworld")
|
||||
{
|
||||
srand(time(NULL));
|
||||
|
||||
// spawn bots
|
||||
for (size_t i = 0; i < 100; ++i)
|
||||
{
|
||||
@ -81,64 +79,6 @@ game::OpenWorld::OpenWorld() : World("openworld")
|
||||
|
||||
}
|
||||
|
||||
void game::OpenWorld::Update(int64_t delta_time)
|
||||
{
|
||||
World::Update(delta_time);
|
||||
|
||||
}
|
||||
|
||||
void game::OpenWorld::PlayerJoined(Player& player)
|
||||
{
|
||||
CreatePlayerCharacter(player);
|
||||
}
|
||||
|
||||
void game::OpenWorld::PlayerInput(Player& player, PlayerInputType type, bool enabled)
|
||||
{
|
||||
auto character = player_characters_.at(&player);
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case IN_DEBUG1:
|
||||
if (enabled)
|
||||
{
|
||||
if (character->GetVehicle())
|
||||
character->GetVehicle()->SetPosition({100.0f, 100.0f, 5.0f});
|
||||
else
|
||||
character->SetPosition({100.0f, 100.0f, 5.0f});
|
||||
}
|
||||
break;
|
||||
|
||||
case IN_DEBUG2:
|
||||
if (enabled)
|
||||
CreatePlayerCharacter(player);
|
||||
break;
|
||||
|
||||
default:
|
||||
character->ProcessInput(type, enabled);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void game::OpenWorld::PlayerViewAnglesChanged(Player& player, float yaw, float pitch)
|
||||
{
|
||||
auto character = player_characters_.at(&player);
|
||||
character->SetForwardYaw(yaw);
|
||||
}
|
||||
|
||||
void game::OpenWorld::PlayerLeft(Player& player)
|
||||
{
|
||||
RemovePlayerCharacter(player);
|
||||
}
|
||||
|
||||
void game::OpenWorld::DestructibleDestroyed(net::ObjNum num, std::unique_ptr<MapObjectCollision> col)
|
||||
{
|
||||
auto& destroyed_obj = Spawn<DestroyedObject>(std::move(col));
|
||||
|
||||
Schedule(120000, [this, num] {
|
||||
RespawnObj(num);
|
||||
});
|
||||
}
|
||||
|
||||
template <class T, typename... TArgs>
|
||||
static T& SpawnRandomCharacter(game::OpenWorld& world, TArgs&&... args)
|
||||
{
|
||||
@ -151,27 +91,6 @@ static T& SpawnRandomCharacter(game::OpenWorld& world, TArgs&&... args)
|
||||
return character;
|
||||
}
|
||||
|
||||
void game::OpenWorld::CreatePlayerCharacter(Player& player)
|
||||
{
|
||||
RemovePlayerCharacter(player);
|
||||
|
||||
auto& character = SpawnRandomCharacter<PlayerCharacter>(*this, player);
|
||||
// character.SetNametag("player (" + std::to_string(character.GetEntNum()) + ")");
|
||||
character.SetPosition({100.0f, 100.0f, 5.0f});
|
||||
|
||||
player_characters_[&player] = &character;
|
||||
}
|
||||
|
||||
void game::OpenWorld::RemovePlayerCharacter(Player& player)
|
||||
{
|
||||
auto it = player_characters_.find(&player);
|
||||
if (it != player_characters_.end())
|
||||
{
|
||||
it->second->Remove();
|
||||
player_characters_.erase(it);
|
||||
}
|
||||
}
|
||||
|
||||
game::DrivableVehicle& game::OpenWorld::SpawnRandomVehicle()
|
||||
{
|
||||
game::VehicleTuning tuning;
|
||||
|
||||
@ -1,42 +1,21 @@
|
||||
#pragma once
|
||||
|
||||
#include "world.hpp"
|
||||
#include "vehicle.hpp"
|
||||
#include "character.hpp"
|
||||
#include "usable.hpp"
|
||||
#include "drivable_vehicle.hpp"
|
||||
|
||||
#include <optional>
|
||||
#include "enterable_world.hpp"
|
||||
#include "npc_character.hpp"
|
||||
|
||||
namespace game
|
||||
{
|
||||
|
||||
class PlayerCharacter;
|
||||
class NpcCharacter;
|
||||
|
||||
class OpenWorld : public World
|
||||
class OpenWorld : public EnterableWorld
|
||||
{
|
||||
public:
|
||||
OpenWorld();
|
||||
|
||||
virtual void Update(int64_t delta_time) override;
|
||||
|
||||
virtual void PlayerJoined(Player& player) override;
|
||||
virtual void PlayerInput(Player& player, PlayerInputType type, bool enabled) override;
|
||||
virtual void PlayerViewAnglesChanged(Player& player, float yaw, float pitch) override;
|
||||
virtual void PlayerLeft(Player& player) override;
|
||||
|
||||
virtual void DestructibleDestroyed(net::ObjNum num, std::unique_ptr<MapObjectCollision> col) override;
|
||||
|
||||
private:
|
||||
void CreatePlayerCharacter(Player& player);
|
||||
void RemovePlayerCharacter(Player& player);
|
||||
|
||||
private:
|
||||
game::DrivableVehicle& SpawnRandomVehicle();
|
||||
void SpawnBot();
|
||||
|
||||
private:
|
||||
std::map<Player*, PlayerCharacter*> player_characters_;
|
||||
std::vector<NpcCharacter*> npcs_;
|
||||
};
|
||||
|
||||
|
||||
@ -6,6 +6,7 @@
|
||||
#include <glm/gtx/norm.hpp>
|
||||
|
||||
#include "world.hpp"
|
||||
#include "game.hpp"
|
||||
|
||||
game::Player::Player(Game& game, std::string name) : game_(game), name_(std::move(name))
|
||||
{
|
||||
@ -48,13 +49,7 @@ void game::Player::SetWorld(std::shared_ptr<World> world)
|
||||
if (world == world_)
|
||||
return;
|
||||
|
||||
if (world_)
|
||||
world_->PlayerLeft(*this);
|
||||
|
||||
world_ = std::move(world);
|
||||
|
||||
if (world_)
|
||||
world_->PlayerJoined(*this);
|
||||
}
|
||||
|
||||
void game::Player::SetCamera(net::EntNum entnum)
|
||||
@ -74,7 +69,6 @@ void game::Player::SendChat(const std::string& text)
|
||||
|
||||
game::Player::~Player()
|
||||
{
|
||||
SetWorld(nullptr);
|
||||
game_.PlayerLeft(*this);
|
||||
}
|
||||
|
||||
@ -247,9 +241,7 @@ bool game::Player::ProcessViewAnglesMsg(net::InMessage& msg)
|
||||
view_yaw_ = yaw_q.Decode();
|
||||
view_pitch_ = pitch_q.Decode();
|
||||
|
||||
if (world_)
|
||||
world_->PlayerViewAnglesChanged(*this, view_yaw_, view_pitch_);
|
||||
|
||||
game_.PlayerViewAnglesChanged(*this, view_yaw_, view_pitch_);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -260,10 +252,6 @@ void game::Player::Input(PlayerInputType type, bool enabled)
|
||||
else
|
||||
in_ &= ~(1 << type);
|
||||
|
||||
if (!game_.PlayerInput(*this, type, enabled))
|
||||
{
|
||||
if (world_)
|
||||
world_->PlayerInput(*this, type, enabled);
|
||||
}
|
||||
game_.PlayerInput(*this, type, enabled);
|
||||
}
|
||||
|
||||
|
||||
@ -1,20 +1,23 @@
|
||||
#pragma once
|
||||
|
||||
#include <set>
|
||||
#include <memory>
|
||||
|
||||
#include <glm/glm.hpp>
|
||||
|
||||
#include "net/defs.hpp"
|
||||
#include "net/inmessage.hpp"
|
||||
#include "net/msg_producer.hpp"
|
||||
#include "utils/defs.hpp"
|
||||
|
||||
#include "player_input.hpp"
|
||||
#include "game.hpp"
|
||||
|
||||
namespace game
|
||||
{
|
||||
|
||||
class Game;
|
||||
class World;
|
||||
class Entity;
|
||||
class Vehicle;
|
||||
|
||||
class Player : public net::MsgProducer
|
||||
{
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
#include "player_character.hpp"
|
||||
#include "openworld.hpp"
|
||||
#include "world.hpp"
|
||||
|
||||
game::PlayerCharacter::PlayerCharacter(World& world, Player& player) : Super(world), player_(player)
|
||||
{
|
||||
|
||||
@ -2,12 +2,11 @@
|
||||
|
||||
#include "drivable_vehicle.hpp"
|
||||
#include "player.hpp"
|
||||
#include "world.hpp"
|
||||
|
||||
namespace game
|
||||
{
|
||||
|
||||
class OpenWorld;
|
||||
|
||||
class PlayerCharacter : public ControllableCharacter
|
||||
{
|
||||
public:
|
||||
|
||||
@ -6,6 +6,7 @@
|
||||
#include "assets/cache.hpp"
|
||||
#include "utils/allocnum.hpp"
|
||||
#include "collision/object_info.hpp"
|
||||
#include "destroyed_object.hpp"
|
||||
|
||||
game::World::World(std::string mapname) : Scheduler(time_ms_), map_(*this, std::move(mapname))
|
||||
{
|
||||
@ -78,6 +79,15 @@ void game::World::FinishFrame()
|
||||
|
||||
}
|
||||
|
||||
void game::World::DestructibleDestroyed(net::ObjNum num, std::unique_ptr<MapObjectCollision> col)
|
||||
{
|
||||
auto& destroyed_obj = Spawn<DestroyedObject>(std::move(col));
|
||||
|
||||
Schedule(120000, [this, num] {
|
||||
RespawnObj(num);
|
||||
});
|
||||
}
|
||||
|
||||
game::Entity* game::World::GetEntity(net::EntNum entnum)
|
||||
{
|
||||
auto it = ents_.find(entnum);
|
||||
|
||||
@ -37,13 +37,7 @@ public:
|
||||
virtual void Update(int64_t delta_time);
|
||||
void FinishFrame();
|
||||
|
||||
// events
|
||||
virtual void PlayerJoined(Player& player) {}
|
||||
virtual void PlayerInput(Player& player, PlayerInputType type, bool enabled) {}
|
||||
virtual void PlayerViewAnglesChanged(Player& player, float yaw, float pitch) {}
|
||||
virtual void PlayerLeft(Player& player) {}
|
||||
|
||||
virtual void DestructibleDestroyed(net::ObjNum num, std::unique_ptr<MapObjectCollision> col) {}
|
||||
virtual void DestructibleDestroyed(net::ObjNum num, std::unique_ptr<MapObjectCollision> col);
|
||||
|
||||
Entity* GetEntity(net::EntNum entnum);
|
||||
|
||||
|
||||
@ -17,6 +17,8 @@ void sv::Server::Run()
|
||||
{
|
||||
using namespace std::chrono_literals;
|
||||
|
||||
srand(time(NULL));
|
||||
|
||||
auto t_start = std::chrono::steady_clock::now();
|
||||
auto t_next = t_start;
|
||||
auto t_prev = t_start;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user