124 lines
2.9 KiB
C++
124 lines
2.9 KiB
C++
#ifndef _WORLD_HPP
|
|
#define _WORLD_HPP
|
|
#include "generic.pb.h"
|
|
|
|
#include <vector>
|
|
#include <memory>
|
|
#include <cmath>
|
|
#include <boost/asio/awaitable.hpp>
|
|
|
|
|
|
|
|
namespace Connection {
|
|
class Client;
|
|
class Global;
|
|
}
|
|
|
|
namespace World {
|
|
class Room;
|
|
|
|
|
|
void fillSettings(Generic::Settings& settings);
|
|
|
|
|
|
struct Vector2 {
|
|
float x, y;
|
|
|
|
inline static Vector2 makeFromGeneric(const Generic::Vector2& generic) {
|
|
return {generic.x(), generic.y()};
|
|
}
|
|
void fromGeneric(const Generic::Vector2& generic) {
|
|
x = generic.x();
|
|
y = generic.y();
|
|
}
|
|
auto toGeneric() const {
|
|
Generic::Vector2 fres;
|
|
fres.set_x(x);
|
|
fres.set_y(y);
|
|
return fres;
|
|
}
|
|
|
|
float getDistanceTo(const Vector2& o) const {
|
|
return fabs(x - o.x) + fabs(y - o.y);
|
|
}
|
|
};
|
|
|
|
|
|
struct LocalRobot {
|
|
Generic::Robot generic;
|
|
uint64_t stateTimer = 0;
|
|
|
|
auto& operator *() {
|
|
return generic;
|
|
}
|
|
auto operator ->() {
|
|
return &generic;
|
|
}
|
|
const auto& operator *() const {
|
|
return generic;
|
|
}
|
|
const auto operator ->() const {
|
|
return &generic;
|
|
}
|
|
};
|
|
|
|
|
|
class Playfield {
|
|
Room& room;
|
|
std::vector<LocalRobot> robots;
|
|
uint64_t turn = 0;
|
|
|
|
public:
|
|
Playfield(Room& room, const std::vector<std::shared_ptr<Connection::Client>>& clients, const Generic::Settings& settings)
|
|
: room(room) {}
|
|
|
|
boost::asio::awaitable<void> reset();
|
|
boost::asio::awaitable<void> updateRobot(const Connection::Client *sender, Generic::Robot& newRobot);
|
|
LocalRobot& getLocalRobot(const Connection::Client *sender, unsigned robot);
|
|
|
|
float getDistanceBetween(const Generic::Robot& a, const Generic::Robot& b) {
|
|
return Vector2::makeFromGeneric(a.position()).getDistanceTo(Vector2::makeFromGeneric(b.position()));
|
|
}
|
|
|
|
auto getPlayfieldSync() const {
|
|
Generic::PlayfieldSync fres;
|
|
for (const auto& robot : robots) {
|
|
*fres.add_robots() = robot.generic;
|
|
}
|
|
return fres;
|
|
}
|
|
auto getTurn() const {
|
|
return turn;
|
|
}
|
|
};
|
|
|
|
struct Room {
|
|
Connection::Global &global;
|
|
Generic::RoomInfo info;
|
|
std::vector<std::shared_ptr<Connection::Client>> clients;
|
|
std::unique_ptr<Playfield> playfield = nullptr;
|
|
|
|
Room(Connection::Global& global)
|
|
: global(global) {}
|
|
|
|
Generic::RoomInfo getFullRoomInfo() const;
|
|
boost::asio::awaitable<void> addClient(const std::shared_ptr<Connection::Client>& client);
|
|
boost::asio::awaitable<void> removeClient(const std::shared_ptr<Connection::Client>& client);
|
|
void removeRoom();
|
|
boost::asio::awaitable<void> removeAllClients();
|
|
|
|
bool isMasterClient(const Connection::Client *client) const {
|
|
return client == clients.front().get();
|
|
}
|
|
bool isFull() const {
|
|
return clients.size() >= info.settings().maxplayers();
|
|
}
|
|
bool isRunning() const {
|
|
return bool(playfield);
|
|
}
|
|
bool isOpen() const {
|
|
return !isFull() && !isRunning();
|
|
}
|
|
};
|
|
}
|
|
#endif
|