Manage players from a sepeate class.
This commit is contained in:
parent
230408e2fc
commit
75906f2353
8 changed files with 188 additions and 214 deletions
|
@ -4,17 +4,23 @@ cmake_minimum_required(VERSION 3.3)
|
|||
|
||||
set(CMAKE_C_COMPILER /usr/bin/clang)
|
||||
set(CMAKE_CXX_COMPILER /usr/bin/clang++)
|
||||
add_definitions(-std=c++11)
|
||||
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
|
||||
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/build/lib)
|
||||
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/build/bin)
|
||||
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/build/bin)
|
||||
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${PROJECT_SOURCE_DIR}/cmake")
|
||||
|
||||
|
||||
find_library(SDL2_LIB SDL2)
|
||||
find_library(SDL2_GFX_LIB SDL2_gfx)
|
||||
find_library(SDL2_IMAGE_LIB SDL2_image)
|
||||
find_library(SDL2_TTF_LIB SDL2_ttf)
|
||||
find_library(BOOST_UUID_LIB boost/uuid)
|
||||
find_program(CTEST_MEMORYCHECK_COMMAND valgrind)
|
||||
|
||||
enable_testing()
|
||||
add_test(NAME memtest COMMAND /usr/bin/valgrind -v --trace-children=yes --tool=memcheck ${CMAKE_BINARY_DIR}/build/bin/Bob)
|
||||
add_test(NAME calltest COMMAND /usr/bin/valgrind -v --trace-children=yes --tool=callgrind ${CMAKE_BINARY_DIR}/build/bin/Bob)
|
||||
|
||||
add_subdirectory(src)
|
79
src/Bob.cpp
79
src/Bob.cpp
|
@ -146,10 +146,6 @@ void Game::handle_event(SDL_Event *event)
|
|||
{
|
||||
this->upgrade_box->handle_event(event);
|
||||
}
|
||||
for (Player *p : this->players)
|
||||
{
|
||||
p->handle_event(event);
|
||||
}
|
||||
}
|
||||
if (event->type == BOB_NEXTROUNDEVENT || event->type == BOB_FIELDUPDATEEVENT
|
||||
|| event->type == BOB_FIELDUPGRADEVENT || event->type == BOB_NEXTTURNEVENT)
|
||||
|
@ -157,26 +153,20 @@ void Game::handle_event(SDL_Event *event)
|
|||
this->grid->handle_event(event);
|
||||
this->field_box->handle_event(event);
|
||||
this->upgrade_box->handle_event(event);
|
||||
for (Player *p : this->players)
|
||||
{
|
||||
p->handle_event(event);
|
||||
}
|
||||
}
|
||||
else if (event->type == BOB_FIELDSELECTEDEVENT && !this->started)
|
||||
{
|
||||
FieldMeta *field = (FieldMeta *) event->user.data1;
|
||||
if (event->user.code == 0 && this->adding != nullptr)
|
||||
if (event->user.code == 0 && this->adding != pm->default_player)
|
||||
{
|
||||
if (this->grid->place(this->adding, field))
|
||||
{
|
||||
this->players.push_back(this->adding);
|
||||
prompt << "Added Player: " << this->adding->get_name();
|
||||
this->adding = nullptr;
|
||||
PlayerManager::pm->add_player(this->adding);
|
||||
prompt << "Added Player: " << this->adding.get_name();
|
||||
}
|
||||
else
|
||||
{
|
||||
prompt << "Failed to add Player: " << this->adding->get_name();
|
||||
delete this->adding;
|
||||
prompt << "Failed to add Player: " << this->adding.get_name();
|
||||
}
|
||||
}
|
||||
this->text_input_box->prompt(prompt.str());
|
||||
|
@ -206,7 +196,7 @@ void Game::command(std::string input)
|
|||
if (this->started)
|
||||
{
|
||||
this->next_turn();
|
||||
prompt << "Next player is: " << (Player::current_player)->get_name();
|
||||
prompt << "Next player is: " << PlayerManager::pm->get_current().get_name();
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -215,31 +205,23 @@ void Game::command(std::string input)
|
|||
}
|
||||
else if (input == "surrender")
|
||||
{
|
||||
this->grid->surrender(Player::current_player);
|
||||
prompt << "Player " << Player::current_player->get_name() << " surrendered!\n";
|
||||
for (int i = 0; i < this->players.size(); i++)
|
||||
{
|
||||
if (this->players[i] == Player::current_player)
|
||||
{
|
||||
delete this->players[i];
|
||||
this->players.erase(this->players.begin() + i);
|
||||
}
|
||||
}
|
||||
Player current = PlayerManager::pm->get_current();
|
||||
PlayerManager::pm->surrender(current, this->grid);
|
||||
prompt << "Player " << current.get_name() << " surrendered!\n";
|
||||
this->next_turn();
|
||||
}
|
||||
else if (input.substr(0, 10) == "add player")
|
||||
{
|
||||
if (!this->started)
|
||||
{
|
||||
if (this->adding != nullptr)
|
||||
if (this->adding != pm->default_player)
|
||||
{
|
||||
this->grid->set_selecting(false);
|
||||
prompt << "Failed to add player " << this->adding->get_name() << "!df\n";
|
||||
delete this->adding;
|
||||
prompt << "Failed to add player " << this->adding.get_name() << "!df\n";
|
||||
}
|
||||
this->grid->set_selecting(true);
|
||||
this->adding = new Player(input.substr(11, std::string::npos));
|
||||
prompt << "Select a place for " << this->adding->get_name() << ", please!";
|
||||
this->adding = Player(input.substr(11, std::string::npos));
|
||||
prompt << "Select a place for " << this->adding.get_name() << ", please!";
|
||||
this->text_input_box->stop();
|
||||
}
|
||||
else
|
||||
|
@ -249,7 +231,7 @@ void Game::command(std::string input)
|
|||
}
|
||||
else if (input == "start")
|
||||
{
|
||||
if (this->players.size() < 2)
|
||||
if (PlayerManager::pm->get_num_players() < 2)
|
||||
{
|
||||
prompt << "Please add at least one player, before starting the game.";
|
||||
}
|
||||
|
@ -269,37 +251,14 @@ void Game::command(std::string input)
|
|||
|
||||
void Game::start()
|
||||
{
|
||||
this->players.erase(players.begin()); // remove default player from vector
|
||||
std::random_shuffle(players.begin(), players.end());
|
||||
this->turn = 0;
|
||||
Player::current_player = players[0];
|
||||
trigger_event(BOB_NEXTROUNDEVENT, 0, nullptr, (void *) Player::current_player);
|
||||
trigger_event(BOB_NEXTTURNEVENT, 0, nullptr, (void *) Player::current_player);
|
||||
PlayerManager::pm->shuffle();
|
||||
}
|
||||
|
||||
void Game::next_turn()
|
||||
{
|
||||
if (!this->players.empty())
|
||||
if (this->started)
|
||||
{
|
||||
Player *last_player = Player::current_player;
|
||||
this->turn = (this->turn + 1) % players.size();
|
||||
Player::current_player = players[turn];
|
||||
if (this->turn == 0)
|
||||
{
|
||||
trigger_event(BOB_NEXTTURNEVENT, 0, (void *) last_player, (void *) Player::current_player);
|
||||
trigger_event(BOB_NEXTROUNDEVENT, 0, (void *) last_player, (void *) Player::current_player);
|
||||
}
|
||||
else
|
||||
{
|
||||
trigger_event(BOB_NEXTTURNEVENT, 0, (void *) last_player, (void *) Player::current_player);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Player *def = new Player();
|
||||
Player::current_player = def;
|
||||
this->players.push_back(def);
|
||||
this->started = false;
|
||||
pm->next_turn();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -374,6 +333,7 @@ void init_ttf()
|
|||
|
||||
int main(int, char **)
|
||||
{
|
||||
PlayerManager::init();
|
||||
try
|
||||
{
|
||||
init_sdl(SDL_INIT_VIDEO);
|
||||
|
@ -387,11 +347,12 @@ int main(int, char **)
|
|||
SDL_Rect bounds;
|
||||
SDL_GetDisplayBounds(0, &bounds);
|
||||
SDL_Rect window_dimensions = {SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 600, 600};
|
||||
Game *game = new Game(&window_dimensions, 10);
|
||||
int exit_status = 1;
|
||||
Game *game = new Game(&window_dimensions, 10, PlayerManager::pm);
|
||||
exit_status = game->game_loop();
|
||||
delete game;
|
||||
TTF_Quit();
|
||||
SDL_Quit();
|
||||
PlayerManager::destroy();
|
||||
TTF_Quit();
|
||||
return exit_status;
|
||||
}
|
36
src/Bob.hpp
36
src/Bob.hpp
|
@ -18,9 +18,10 @@ class Game
|
|||
{
|
||||
|
||||
public:
|
||||
Game(SDL_Rect *window_dimensions, Sint16 size)
|
||||
Game(SDL_Rect *window_dimensions, Sint16 size, PlayerManager *pm)
|
||||
: pm(pm)
|
||||
{
|
||||
this->adding = nullptr;
|
||||
this->adding = pm->default_player;
|
||||
this->started = false;
|
||||
this->layout = new Layout(pointy_orientation, 20,
|
||||
{window_dimensions->w / 2, window_dimensions->h / 2},
|
||||
|
@ -31,9 +32,6 @@ public:
|
|||
}
|
||||
this->quit = false;
|
||||
SDL_Color fg = {0x00, 0x00, 0x00, 0xff};
|
||||
this->players = std::vector<Player *>();
|
||||
Player *default_player = new Player();
|
||||
this->players.push_back(default_player);
|
||||
try
|
||||
{
|
||||
this->font = load_font_from_file("/usr/share/fonts/dejavu/DejaVuSans.ttf", 20);
|
||||
|
@ -45,9 +43,6 @@ public:
|
|||
FieldMeta *center = this->grid->get_field({0, 0, 0});
|
||||
this->field_box = new FieldBox(this->renderer, {0, 0, 200, 100}, fg, this->font, center);
|
||||
this->upgrade_box = new UpgradeBox(this->renderer, {0, 0, 200, 20}, fg, this->font, center);
|
||||
this->next_turn_button = new NextTurnButtonBox(this->renderer,
|
||||
{window_size.x - 100, window_size.y - 100, 1, 1}, fg,
|
||||
this->font, &(this->players));
|
||||
int font_height = TTF_FontHeight(this->font);
|
||||
this->text_input_box = new TextInputBox(this->renderer, {0, 0, window_size.x, font_height}, fg, this->font);
|
||||
this->text_input_box->stop();
|
||||
|
@ -58,18 +53,16 @@ public:
|
|||
}
|
||||
this->frame_timer = new Timer();
|
||||
this->move_timer = new Timer();
|
||||
this->turn = 0;
|
||||
Player::current_player = this->players[turn];
|
||||
//Player::current_player = this->players[turn];
|
||||
}
|
||||
|
||||
~Game()
|
||||
{
|
||||
for (auto player : this->players)
|
||||
/*for (auto player : this->players)
|
||||
{
|
||||
delete player;
|
||||
}
|
||||
}*/
|
||||
delete text_input_box;
|
||||
delete this->next_turn_button;
|
||||
delete this->upgrade_box;
|
||||
delete this->field_box;
|
||||
delete this->move_timer;
|
||||
|
@ -78,11 +71,12 @@ public:
|
|||
delete this->renderer;
|
||||
delete this->window;
|
||||
delete this->layout;
|
||||
if (this->adding != nullptr)
|
||||
}
|
||||
|
||||
PlayerManager *get_player_manager()
|
||||
{
|
||||
delete this->adding;
|
||||
}
|
||||
}
|
||||
return this->pm;
|
||||
};
|
||||
|
||||
void start();
|
||||
|
||||
|
@ -98,11 +92,10 @@ public:
|
|||
|
||||
private:
|
||||
bool started;
|
||||
Player *adding;
|
||||
Uint64 turn;
|
||||
Player adding;
|
||||
TextInputBox *text_input_box;
|
||||
std::vector<Player *> players;
|
||||
NextTurnButtonBox *next_turn_button;
|
||||
//std::vector<Player *> players;
|
||||
PlayerManager *pm;
|
||||
UpgradeBox *upgrade_box;
|
||||
FieldBox *field_box;
|
||||
TTF_Font *font;
|
||||
|
@ -110,7 +103,6 @@ private:
|
|||
Renderer *renderer;
|
||||
HexagonGrid *grid;
|
||||
Layout *layout;
|
||||
Container *side_bar;
|
||||
bool move[4];
|
||||
bool quit;
|
||||
Timer *frame_timer;
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
add_executable(Bob Bob.cpp Bob.hpp Gameplay.cpp Gameplay.hpp Gui.hpp Gui.cpp Events.cpp Exceptions.hpp Pixelmask.h Wrapper.hpp Wrapper.cpp)
|
||||
add_executable(Bob Bob.cpp Gameplay.cpp Gui.cpp Events.cpp Wrapper.cpp Bots.hpp Bots.cpp)
|
||||
target_link_libraries(Bob ${SDL2_LIB} ${SDL2_GFX_LIB} ${SDL2_TTF_LIB} ${Boost_LIBRARIES})
|
128
src/Gameplay.cpp
128
src/Gameplay.cpp
|
@ -1,6 +1,6 @@
|
|||
#include "Gameplay.hpp"
|
||||
|
||||
Player *Player::current_player = nullptr;
|
||||
PlayerManager *PlayerManager::pm = nullptr;
|
||||
|
||||
SDL_Point operator+(SDL_Point left, SDL_Point right)
|
||||
{
|
||||
|
@ -232,7 +232,7 @@ Cluster HexagonGrid::get_cluster(FieldMeta *field)
|
|||
{
|
||||
FieldMeta *neighbor = this->get_neighbor(current, i);
|
||||
// neighbor is unvisited, unseen and inside same cluster
|
||||
if (neighbor != nullptr && *(neighbor->get_owner()) == *(current->get_owner())
|
||||
if (neighbor != nullptr && neighbor->get_owner() == current->get_owner()
|
||||
&& visited.find(neighbor) == visited.end() && seen.find(neighbor) == seen.end())
|
||||
{
|
||||
seen.insert(neighbor); // discovered an unseen neighbor, will visit later
|
||||
|
@ -265,7 +265,7 @@ bool Player::fight(FieldMeta *field)
|
|||
{
|
||||
bool is_neighbor = false; // player has a field around here
|
||||
// friendly fire or owned by default player
|
||||
if (*this == *(field->get_owner()) || field->get_owner()->get_id() == boost::uuids::nil_uuid())
|
||||
if (*this == field->get_owner() || field->get_owner().get_id() == boost::uuids::nil_uuid())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
@ -281,14 +281,14 @@ bool Player::fight(FieldMeta *field)
|
|||
{
|
||||
continue;
|
||||
}
|
||||
if (*(neighbor->get_owner()) == *this) // comparison by UUID, attacking player
|
||||
if (neighbor->get_owner() == *this) // comparison by UUID, attacking player
|
||||
{
|
||||
Cluster temp_attackers_cluster = neighbor->get_grid()->get_cluster(neighbor);
|
||||
attackers_cluster.insert(temp_attackers_cluster.begin(), temp_attackers_cluster.end());
|
||||
power_level -= neighbor->get_offense();
|
||||
is_neighbor = true;
|
||||
}
|
||||
else if (*(neighbor->get_owner()) == *(field->get_owner())) // attacked player
|
||||
else if (neighbor->get_owner() == field->get_owner()) // attacked player
|
||||
{
|
||||
power_level += neighbor->get_defense();
|
||||
}
|
||||
|
@ -300,7 +300,7 @@ bool Player::fight(FieldMeta *field)
|
|||
{
|
||||
field->get_grid()->consume_resources_of_cluster(&attackers_cluster, costs);
|
||||
field->get_grid()->consume_resources_of_cluster(&defenders_cluster, costs);
|
||||
field->set_owner(this);
|
||||
field->set_owner(*this);
|
||||
return true;
|
||||
}
|
||||
else // lost
|
||||
|
@ -326,7 +326,7 @@ void FieldMeta::load(SDL_Renderer *renderer, Layout *layout)
|
|||
location.x = (int) precise_location.x;
|
||||
location.y = (int) precise_location.y;
|
||||
std::vector<Point> polygon = this->field.field_to_polygon(layout);
|
||||
SDL_Color color = this->owner->get_color();
|
||||
SDL_Color color = this->owner.get_color();
|
||||
Sint16 vx[6];
|
||||
Sint16 vy[6];
|
||||
for (int i = 0; i < 6; i++)
|
||||
|
@ -334,16 +334,12 @@ void FieldMeta::load(SDL_Renderer *renderer, Layout *layout)
|
|||
vx[i] = (Sint16) polygon[i].x;
|
||||
vy[i] = (Sint16) polygon[i].y;
|
||||
}
|
||||
if (this->owner->get_id().is_nil())
|
||||
color = {0x77, 0x77, 0x77, 0xff};
|
||||
if (this->owner.get_id().is_nil())
|
||||
color = {0x22, 0x22, 0x22, 0xff};
|
||||
if (this->get_grid()->get_attack_marker() == this)
|
||||
color = {0x0, 0x77, 0x77, 0xff};
|
||||
filledPolygonRGBA(renderer, vx, vy, 6, color.r, color.g, color.b, 0x77);
|
||||
SDL_Color inverse;
|
||||
inverse.r = (Uint8) (color.r + 0x77);
|
||||
inverse.g = (Uint8) (color.g + 0x77);
|
||||
inverse.b = (Uint8) (color.b + 0x77);
|
||||
inverse.a = 0xff;
|
||||
filledPolygonRGBA(renderer, vx, vy, 6, color.r, color.g, color.b, 0xff);
|
||||
SDL_Color fg = {0xff, 0xff, 0xff, 0xff};
|
||||
double resource_size = layout->size / 4;
|
||||
if (this->resources_base.triangle > 0)
|
||||
{
|
||||
|
@ -355,12 +351,12 @@ void FieldMeta::load(SDL_Renderer *renderer, Layout *layout)
|
|||
vx[i] = (Sint16) (location.x + (trigon[i].x * resource_size));
|
||||
vy[i] = (Sint16) (location.y + (trigon[i].y * resource_size));
|
||||
}
|
||||
trigonRGBA(renderer, vx[0], vy[0], vx[1], vy[1], vx[2], vy[2], inverse.r, inverse.g, inverse.b, inverse.a);
|
||||
trigonRGBA(renderer, vx[0], vy[0], vx[1], vy[1], vx[2], vy[2], fg.r, fg.g, fg.b, fg.a);
|
||||
}
|
||||
if (this->resources_base.circle > 0)
|
||||
{
|
||||
circleRGBA(renderer, (Sint16) (location.x), Sint16(location.y), (Sint16) resource_size, inverse.r, inverse.g,
|
||||
inverse.b, inverse.a);
|
||||
circleRGBA(renderer, (Sint16) (location.x), Sint16(location.y), (Sint16) resource_size, fg.r, fg.g,
|
||||
fg.b, fg.a);
|
||||
}
|
||||
if (this->resources_base.square > 0)
|
||||
{
|
||||
|
@ -373,7 +369,7 @@ void FieldMeta::load(SDL_Renderer *renderer, Layout *layout)
|
|||
vx[i] = (Sint16) (location.x + square[i].x * resource_size);
|
||||
vy[i] = (Sint16) (location.y + square[i].y * resource_size);
|
||||
}
|
||||
polygonRGBA(renderer, vx, vy, 4, inverse.r, inverse.g, inverse.b, inverse.a);
|
||||
polygonRGBA(renderer, vx, vy, 4, fg.r, fg.g, fg.b, fg.a);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -504,7 +500,7 @@ void HexagonGrid::handle_event(SDL_Event *event)
|
|||
{
|
||||
if (this->attack_marker == this->marker)
|
||||
{
|
||||
Player::current_player->fight(this->attack_marker);
|
||||
PlayerManager::pm->get_current().fight(this->attack_marker);
|
||||
}
|
||||
this->attack_marker = nullptr;
|
||||
}
|
||||
|
@ -526,7 +522,7 @@ void HexagonGrid::handle_event(SDL_Event *event)
|
|||
field.second->regenerate_resources();
|
||||
}
|
||||
}
|
||||
else if (event->type == BOB_NEXTTURNEVENT)
|
||||
if (event->type == BOB_NEXTTURNEVENT || event->type == BOB_NEXTROUNDEVENT)
|
||||
{
|
||||
std::default_random_engine generator;
|
||||
std::normal_distribution<double> distribution(0.0, 1.0);
|
||||
|
@ -534,13 +530,12 @@ void HexagonGrid::handle_event(SDL_Event *event)
|
|||
for (auto pair : this->fields)
|
||||
{
|
||||
FieldMeta *field = pair.second;
|
||||
if (*(field->get_owner()) == *(Player::current_player))
|
||||
if (field->get_owner() == PlayerManager::pm->get_current())
|
||||
{
|
||||
for (Uint8 i = 0; i < 6; i++)
|
||||
{
|
||||
|
||||
FieldMeta *neighbor = field->get_neighbor(i);
|
||||
if (neighbor != nullptr && neighbor->get_owner()->get_id() == boost::uuids::nil_uuid()
|
||||
if (neighbor != nullptr && neighbor->get_owner() == PlayerManager::pm->default_player
|
||||
&& (neighbor->get_reproduction() > distribution(generator)))
|
||||
{
|
||||
aquired.insert(neighbor);
|
||||
|
@ -550,7 +545,7 @@ void HexagonGrid::handle_event(SDL_Event *event)
|
|||
}
|
||||
for (auto foo : aquired)
|
||||
{
|
||||
foo->set_owner(Player::current_player);
|
||||
foo->set_owner(PlayerManager::pm->get_current());
|
||||
foo->set_defense(1);
|
||||
foo->set_offense(1);
|
||||
}
|
||||
|
@ -650,14 +645,14 @@ bool inside_target(const SDL_Rect *box, const SDL_Point *position)
|
|||
box->y + box->h > position->y;
|
||||
}
|
||||
|
||||
bool HexagonGrid::place(Player *player, FieldMeta *center)
|
||||
bool HexagonGrid::place(Player &player, FieldMeta *center)
|
||||
{
|
||||
std::vector<FieldMeta *> selected;
|
||||
selected.push_back(center);
|
||||
for (Uint8 i = 0; i < 6; i++)
|
||||
{
|
||||
FieldMeta *neighbor = center->get_neighbor(i);
|
||||
if (neighbor->get_owner()->get_id() == boost::uuids::nil_uuid())
|
||||
if (neighbor != nullptr && neighbor->get_owner().get_id() == boost::uuids::nil_uuid())
|
||||
{
|
||||
selected.push_back(neighbor);
|
||||
}
|
||||
|
@ -693,17 +688,88 @@ void Player::handle_event(SDL_Event *event)
|
|||
}
|
||||
}
|
||||
|
||||
void HexagonGrid::surrender(Player *player)
|
||||
void HexagonGrid::free(Player &player)
|
||||
{
|
||||
for (std::pair<Field, FieldMeta *> pair : this->fields)
|
||||
{
|
||||
if (pair.second != nullptr && *(pair.second->get_owner()) == *player)
|
||||
if (pair.second != nullptr && pair.second->get_owner() == player)
|
||||
{
|
||||
Field old_field = pair.second->get_field();
|
||||
delete pair.second;
|
||||
this->fields.erase(pair.first);
|
||||
FieldMeta *new_field = new FieldMeta(this, old_field, this->default_player);
|
||||
fields.erase(old_field);
|
||||
FieldMeta *new_field = new FieldMeta(this, old_field, PlayerManager::pm->default_player);
|
||||
this->fields.insert({old_field, new_field});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Player &PlayerManager::get_current()
|
||||
{
|
||||
if (players.empty())
|
||||
{
|
||||
return default_player;
|
||||
}
|
||||
else
|
||||
{
|
||||
return *current_player;
|
||||
}
|
||||
}
|
||||
|
||||
void PlayerManager::next_turn()
|
||||
{
|
||||
current_player += 1;
|
||||
if (current_player == players.end())
|
||||
{
|
||||
current_player = players.begin();
|
||||
trigger_event(BOB_NEXTROUNDEVENT, 0, nullptr, nullptr);
|
||||
}
|
||||
else
|
||||
{
|
||||
trigger_event(BOB_NEXTTURNEVENT, 0, nullptr, nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
void PlayerManager::shuffle()
|
||||
{
|
||||
std::random_shuffle(players.begin(), players.end());
|
||||
current_player = players.begin();
|
||||
trigger_event(BOB_NEXTROUNDEVENT, 0, nullptr, nullptr);
|
||||
}
|
||||
|
||||
void PlayerManager::add_player(Player &player)
|
||||
{
|
||||
players.push_back(player);
|
||||
current_player = players.begin();
|
||||
}
|
||||
|
||||
void PlayerManager::surrender(Player &player, HexagonGrid *grid)
|
||||
{
|
||||
grid->free(player);
|
||||
//players.erase(std::remove(players.begin(), players.end(), player), players.end());
|
||||
}
|
||||
|
||||
bool PlayerManager::init()
|
||||
{
|
||||
pm = new PlayerManager();
|
||||
if (pm)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool PlayerManager::destroy()
|
||||
{
|
||||
if (pm != nullptr)
|
||||
{
|
||||
delete pm;
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
|
@ -532,10 +532,10 @@ class FieldMeta;
|
|||
|
||||
class Player
|
||||
{
|
||||
|
||||
public:
|
||||
Player()
|
||||
: name("Default Player"), uuid(boost::uuids::nil_uuid()) { }
|
||||
|
||||
Player(std::string name_)
|
||||
: name(name_), uuid(boost::uuids::basic_random_generator<boost::mt19937>()())
|
||||
{
|
||||
|
@ -570,9 +570,6 @@ public:
|
|||
}
|
||||
|
||||
void handle_event(SDL_Event *event);
|
||||
|
||||
static Player *current_player;
|
||||
|
||||
private:
|
||||
boost::uuids::uuid uuid;
|
||||
SDL_Color color;
|
||||
|
@ -586,7 +583,7 @@ class HexagonGrid;
|
|||
class FieldMeta
|
||||
{
|
||||
public:
|
||||
FieldMeta(HexagonGrid *grid_, Field field_, Player *owner_)
|
||||
FieldMeta(HexagonGrid *grid_, Field field_, Player &owner_)
|
||||
: grid(grid_), field(field_), owner(owner_), changed(true)
|
||||
{
|
||||
std::default_random_engine generator;
|
||||
|
@ -631,39 +628,27 @@ public:
|
|||
}
|
||||
|
||||
void set_offense(int off) { this->offense = off; }
|
||||
|
||||
void set_defense(int def) { this->defense = def; }
|
||||
|
||||
Field get_field() { return this->field; }
|
||||
|
||||
Player *get_owner() { return this->owner; }
|
||||
|
||||
void set_owner(Player *player) { this->owner = player; }
|
||||
Player &get_owner() { return this->owner; }
|
||||
|
||||
void set_owner(Player &player) { this->owner = player; }
|
||||
void load(SDL_Renderer *renderer, Layout *layout);
|
||||
|
||||
Resource get_resources() { return this->resources; }
|
||||
|
||||
UpgradeFlags get_upgrades() { return this->upgrades; }
|
||||
|
||||
void consume_resources(Resource costs);
|
||||
|
||||
void regenerate_resources();
|
||||
|
||||
bool upgrade(Upgrade upgrade);
|
||||
|
||||
void handle_event(const SDL_Event *event);
|
||||
|
||||
FieldMeta *get_neighbor(Uint8 direction);
|
||||
|
||||
double get_reproduction() { return this->reproduction; }
|
||||
|
||||
private:
|
||||
double reproduction;
|
||||
bool changed;
|
||||
const Field field;
|
||||
HexagonGrid *grid;
|
||||
Player *owner;
|
||||
Player owner;
|
||||
UpgradeFlags upgrades;
|
||||
Resource resources_base; // without upgrades applied, used as basis of regeneration
|
||||
Resource resources; // actual current resources
|
||||
|
@ -673,6 +658,42 @@ private:
|
|||
|
||||
typedef std::unordered_set<FieldMeta *> Cluster;
|
||||
|
||||
class HexagonGrid;
|
||||
|
||||
class PlayerManager
|
||||
{
|
||||
public:
|
||||
PlayerManager()
|
||||
{
|
||||
players = std::vector<Player>();
|
||||
current_player = players.begin();
|
||||
default_player = Player();
|
||||
}
|
||||
|
||||
Player &get_current();
|
||||
|
||||
void next_turn();
|
||||
|
||||
void shuffle();
|
||||
|
||||
void surrender(Player &player, HexagonGrid *grid);
|
||||
|
||||
void add_player(Player &player);
|
||||
|
||||
long get_num_players() { return players.size(); }
|
||||
|
||||
Player default_player;
|
||||
static PlayerManager *pm;
|
||||
|
||||
static bool init();
|
||||
|
||||
static bool destroy();
|
||||
|
||||
private:
|
||||
std::vector<Player> players;
|
||||
std::vector<Player>::iterator current_player;
|
||||
};
|
||||
|
||||
class HexagonGrid
|
||||
{
|
||||
public:
|
||||
|
@ -683,7 +704,6 @@ public:
|
|||
this->texture = nullptr;
|
||||
this->panning = false;
|
||||
std::unordered_map<Field, FieldMeta *> fields = std::unordered_map<Field, FieldMeta *>();
|
||||
this->default_player = new Player();
|
||||
// first lower half, then upper half
|
||||
Field new_field = {0, 0, 0};
|
||||
for (Sint16 x = -grid_radius; x <= grid_radius; x++)
|
||||
|
@ -694,11 +714,11 @@ public:
|
|||
{
|
||||
Sint16 z = -x - y;
|
||||
new_field = {x, y, z};
|
||||
FieldMeta *meta = new FieldMeta(this, new_field, this->default_player);
|
||||
FieldMeta *meta = new FieldMeta(this, new_field, PlayerManager::pm->default_player);
|
||||
this->fields.insert({new_field, meta});
|
||||
}
|
||||
}
|
||||
this->marker = new FieldMeta(this, new_field, this->default_player);
|
||||
this->marker = new FieldMeta(this, new_field, PlayerManager::pm->default_player);
|
||||
this->load();
|
||||
}
|
||||
|
||||
|
@ -708,46 +728,28 @@ public:
|
|||
{
|
||||
delete elem.second;
|
||||
}
|
||||
delete this->default_player;
|
||||
SDL_DestroyTexture(this->texture);
|
||||
}
|
||||
|
||||
FieldMeta *get_neighbor(FieldMeta *field, Uint8 direction);
|
||||
|
||||
Cluster get_cluster(FieldMeta *field);
|
||||
|
||||
void render(Renderer *renderer);
|
||||
|
||||
void load();
|
||||
|
||||
Sint16 get_radius() { return radius * layout->size; }
|
||||
|
||||
void move(SDL_Point move);
|
||||
|
||||
void update_marker();
|
||||
|
||||
void update_dimensions(SDL_Point dimensions);
|
||||
|
||||
Resource get_resources_of_cluster(Cluster *cluster);
|
||||
|
||||
Resource consume_resources_of_cluster(Cluster *cluster, Resource costs);
|
||||
|
||||
FieldMeta *point_to_field(const Point p);
|
||||
|
||||
Point field_to_point(FieldMeta *field);
|
||||
|
||||
FieldMeta *get_field(Field field);
|
||||
|
||||
void handle_event(SDL_Event *event);
|
||||
|
||||
bool place(Player *player, FieldMeta *center);
|
||||
|
||||
bool place(Player &player, FieldMeta *center);
|
||||
void set_selecting(bool state) { this->placing = state; }
|
||||
|
||||
FieldMeta *get_attack_marker() { return this->attack_marker; }
|
||||
|
||||
void surrender(Player *player);
|
||||
|
||||
void free(Player &player);
|
||||
private:
|
||||
bool changed;
|
||||
bool placing;
|
||||
|
@ -758,9 +760,7 @@ private:
|
|||
Layout *layout;
|
||||
FieldMeta *marker;
|
||||
bool panning;
|
||||
Player *default_player;
|
||||
Sint16 radius;
|
||||
|
||||
bool on_rectangle(SDL_Rect *rect);
|
||||
};
|
||||
|
||||
|
|
34
src/Gui.cpp
34
src/Gui.cpp
|
@ -99,7 +99,7 @@ void FieldBox::update()
|
|||
Resource cluster_resources = grid->get_resources_of_cluster(&cluster);
|
||||
Resource field_resources = this->field->get_resources();
|
||||
std::ostringstream output;
|
||||
output << this->field->get_owner()->get_name() << "\n"
|
||||
output << this->field->get_owner().get_name() << "\n"
|
||||
<< "off " << this->field->get_offense() << "\ndef " << this->field->get_defense() << "\n"
|
||||
<< "● " << (int) cluster_resources.circle << " (" << (int) field_resources.circle << ")" << "\n"
|
||||
<< "▲ " << (int) cluster_resources.triangle << " (" << (int) field_resources.triangle << ")" << "\n"
|
||||
|
@ -210,7 +210,7 @@ void UpgradeButtonBox::handle_event(const SDL_Event *event)
|
|||
if (inside_target(&(this->dimensions), &pos))
|
||||
{
|
||||
FieldMeta *field = this->box->get_field();
|
||||
if (*(Player::current_player) == *(field->get_owner()))
|
||||
if (PlayerManager::pm->get_current() == field->get_owner())
|
||||
{
|
||||
field->upgrade(this->upgrade);
|
||||
changed = true;
|
||||
|
@ -301,34 +301,6 @@ void FieldBox::update_position(SDL_Point point)
|
|||
this->dimensions.y = point.y - this->dimensions.h - 6;
|
||||
}
|
||||
|
||||
void NextTurnButtonBox::handle_event(const SDL_Event *event)
|
||||
{
|
||||
if (event->type == SDL_MOUSEBUTTONDOWN)
|
||||
{
|
||||
SDL_Point mouse;
|
||||
SDL_GetMouseState(&(mouse.x), &(mouse.y));
|
||||
if (inside_target(&(this->dimensions), &mouse))
|
||||
{
|
||||
Player *last_player = Player::current_player;
|
||||
this->current_player = this->current_player + 1;
|
||||
if (this->current_player == players->end())
|
||||
{
|
||||
this->current_player = players->begin();
|
||||
trigger_event(BOB_NEXTROUNDEVENT, 0, last_player, Player::current_player);
|
||||
}
|
||||
else
|
||||
{
|
||||
trigger_event(BOB_NEXTTURNEVENT, 0, last_player, Player::current_player);
|
||||
}
|
||||
Player::current_player = *(this->current_player);
|
||||
std::ostringstream text;
|
||||
text << "NEXT TURN" << "\n\n" << Player::current_player->get_name();
|
||||
this->load_text(text.str());
|
||||
this->changed = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void TextInputBox::start()
|
||||
{
|
||||
this->visible = true;
|
||||
|
@ -397,7 +369,7 @@ void TextInputBox::handle_event(const SDL_Event *event)
|
|||
|
||||
void TextInputBox::prompt(std::string message)
|
||||
{
|
||||
this->output << this->input.str() << "\n" << message << "\n" << Player::current_player->get_name() << "# ";
|
||||
this->output << this->input.str() << "\n" << message << "\n" << PlayerManager::pm->get_current().get_name() << "# ";
|
||||
this->lines += 2;
|
||||
this->load_text(output.str());
|
||||
if (lines > 20)
|
||||
|
|
25
src/Gui.hpp
25
src/Gui.hpp
|
@ -82,7 +82,7 @@ public:
|
|||
: TextBox(renderer_, dimensions_, color_, font_), input("")
|
||||
{
|
||||
this->visible = false;
|
||||
this->output << Player::current_player->get_name() << "# ";
|
||||
this->output << PlayerManager::pm->get_current().get_name() << "# ";
|
||||
this->load();
|
||||
this->load_text(output.str());
|
||||
}
|
||||
|
@ -145,29 +145,6 @@ private:
|
|||
bool active; // this upgrade has been unlocked
|
||||
};
|
||||
|
||||
class NextTurnButtonBox : public TextBox
|
||||
{
|
||||
public:
|
||||
NextTurnButtonBox(Renderer *renderer, SDL_Rect dimensions, SDL_Color color, TTF_Font *font_,
|
||||
std::vector<Player *> *players_)
|
||||
: TextBox(renderer, dimensions, color, font_), players(players_)
|
||||
{
|
||||
this->current_player = this->players->begin();
|
||||
Player::current_player = *(this->current_player);
|
||||
std::ostringstream text;
|
||||
// Warning, next line looks ugly @.@
|
||||
text << "NEXT TURN" << "\n\n" << (*(this->current_player))->get_name();
|
||||
this->load_text(text.str());
|
||||
this->visible = true;
|
||||
}
|
||||
|
||||
void handle_event(const SDL_Event *event);
|
||||
|
||||
private:
|
||||
std::vector<Player *> *players;
|
||||
std::vector<Player *>::iterator current_player;
|
||||
};
|
||||
|
||||
class UpgradeBox : public Box
|
||||
{
|
||||
public:
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue