From e6029eb1c480a8d4d55ed81fa20da9145c6064d9 Mon Sep 17 00:00:00 2001 From: Frederik <frederik@prasch.de> Date: Mon, 3 Feb 2025 00:17:16 +0100 Subject: [PATCH 01/12] Setup player class --- src/game/Player.cpp | 23 +++++++++++++++++++++++ src/game/Player.hpp | 33 +++++++++++++++++++++++++++++++++ 2 files changed, 56 insertions(+) create mode 100644 src/game/Player.cpp create mode 100644 src/game/Player.hpp diff --git a/src/game/Player.cpp b/src/game/Player.cpp new file mode 100644 index 0000000..8e6edf6 --- /dev/null +++ b/src/game/Player.cpp @@ -0,0 +1,23 @@ +#include "Player.hpp" + +namespace advanced_wars +{ + +Player::Player() {} + +Player::~Player() {} + +void Player::startTurn() +{ + // TODO reset availability of all allied units (all others are unavailable) + // TODO add calculated money to this player + // TODO set this player as the current active player +} + +void Player::endTurn() +{ + // TODO set all allied units as unavailable + // TODO set this player as inactive +} + +} // namespace advanced_wars \ No newline at end of file diff --git a/src/game/Player.hpp b/src/game/Player.hpp new file mode 100644 index 0000000..dafdcb7 --- /dev/null +++ b/src/game/Player.hpp @@ -0,0 +1,33 @@ +#pragma once + +#include "Unit.hpp" + +namespace advanced_wars +{ + +enum class PlayerFaction +{ + RED, + BLUE, + GREEN, + YELLOW, + PURPLE +}; + +class Player +{ + private: + int money; + bool alive; + bool activeTurn; + PlayerFaction faction; + + public: + Player(/* args */); + ~Player(); + + void startTurn(); + void endTurn(); +}; + +} // namespace advanced_wars -- GitLab From 7274b1d43e8fea598d7ccdd0d7f0b296dd4c9f99 Mon Sep 17 00:00:00 2001 From: Frederik Keens <frederik@prasch.de> Date: Mon, 3 Feb 2025 14:14:09 +0100 Subject: [PATCH 02/12] Add getter and setter for relevant data to Player --- src/game/Building.cpp | 5 +++++ src/game/Building.hpp | 2 ++ src/game/Unit.cpp | 10 ++++++++++ src/game/Unit.hpp | 4 ++++ 4 files changed, 21 insertions(+) diff --git a/src/game/Building.cpp b/src/game/Building.cpp index efa12b6..4cbbec8 100644 --- a/src/game/Building.cpp +++ b/src/game/Building.cpp @@ -28,4 +28,9 @@ void Building::render(Engine& engine, int scale) &dst, 0, NULL, SDL_FLIP_NONE); } +BuildingFaction Building::getFaction() +{ + return this->m_faction; +} + } // namespace advanced_wars \ No newline at end of file diff --git a/src/game/Building.hpp b/src/game/Building.hpp index 031c315..429e024 100644 --- a/src/game/Building.hpp +++ b/src/game/Building.hpp @@ -36,6 +36,8 @@ class Building BuildingFaction m_faction; void render(Engine& engine, int scale); + + BuildingFaction getFaction(); }; } // namespace advanced_wars \ No newline at end of file diff --git a/src/game/Unit.cpp b/src/game/Unit.cpp index 657f24c..b85ccb8 100644 --- a/src/game/Unit.cpp +++ b/src/game/Unit.cpp @@ -216,4 +216,14 @@ bool Unit::inRange(Unit& enemy) return false; } +UnitFaction Unit::getFaction() +{ + return this->m_faction; +} + +void Unit::setState(UnitState state) +{ + this->m_state = state; +} + } // namespace advanced_wars \ No newline at end of file diff --git a/src/game/Unit.hpp b/src/game/Unit.hpp index 544c3d9..285ac13 100644 --- a/src/game/Unit.hpp +++ b/src/game/Unit.hpp @@ -116,6 +116,10 @@ class Unit */ void on_left_click(SDL_Event event); + UnitFaction getFaction(); + + void setState(UnitState state); + private: UnitFaction m_faction; UnitId m_id; -- GitLab From 6a6442bf638dc0e6bfb6581243807c6e51f07863 Mon Sep 17 00:00:00 2001 From: Frederik Keens <frederik@prasch.de> Date: Mon, 3 Feb 2025 14:31:44 +0100 Subject: [PATCH 03/12] Implement player class --- src/game/Player.cpp | 136 +++++++++++++++++++++++++++++++++++++++++--- src/game/Player.hpp | 29 ++++++++-- 2 files changed, 151 insertions(+), 14 deletions(-) diff --git a/src/game/Player.cpp b/src/game/Player.cpp index 8e6edf6..92584f7 100644 --- a/src/game/Player.cpp +++ b/src/game/Player.cpp @@ -7,17 +7,137 @@ Player::Player() {} Player::~Player() {} -void Player::startTurn() +void Player::startTurn( + std::unordered_map<int, Unit> lvUnits, std::unordered_map<int, Building> lvBuildings) { - // TODO reset availability of all allied units (all others are unavailable) - // TODO add calculated money to this player - // TODO set this player as the current active player + for (auto& [id, unit] : lvUnits) + { + switch (m_faction) + { + case PlayerFaction::RED: + if (unit.getFaction() == UnitFaction::URED) + { + unit.setState(UnitState::IDLE); + } + break; + case PlayerFaction::BLUE: + if (unit.getFaction() == UnitFaction::UBLUE) + { + unit.setState(UnitState::IDLE); + } + break; + case PlayerFaction::GREEN: + if (unit.getFaction() == UnitFaction::UGREEN) + { + unit.setState(UnitState::IDLE); + } + break; + case PlayerFaction::YELLOW: + if (unit.getFaction() == UnitFaction::UYELLOW) + { + unit.setState(UnitState::IDLE); + } + break; + case PlayerFaction::PURPLE: + if (unit.getFaction() == UnitFaction::UPURPLE) + { + unit.setState(UnitState::IDLE); + } + break; + + default: + break; + } + } + + int underControl = 0; + + for (auto& [id, building] : lvBuildings) + { + switch (m_faction) + { + case PlayerFaction::RED: + if (building.getFaction() == BuildingFaction::RED) + { + underControl++; + } + break; + case PlayerFaction::BLUE: + if (building.getFaction() == BuildingFaction::BLUE) + { + underControl++; + } + break; + case PlayerFaction::GREEN: + if (building.getFaction() == BuildingFaction::GREEN) + { + underControl++; + } + break; + case PlayerFaction::YELLOW: + if (building.getFaction() == BuildingFaction::YELLOW) + { + underControl++; + } + break; + case PlayerFaction::PURPLE: + if (building.getFaction() == BuildingFaction::PURPLE) + { + underControl++; + } + break; + + default: + break; + } + } + + m_money += 1000 * underControl; + + m_activeTurn = true; } -void Player::endTurn() +void Player::endTurn(std::unordered_map<int, Unit> lvUnits) { - // TODO set all allied units as unavailable - // TODO set this player as inactive -} + for (auto& [id, unit] : lvUnits) + { + switch (m_faction) + { + case PlayerFaction::RED: + if (unit.getFaction() == UnitFaction::URED) + { + unit.setState(UnitState::UNAVAILABLE); + } + break; + case PlayerFaction::BLUE: + if (unit.getFaction() == UnitFaction::UBLUE) + { + unit.setState(UnitState::UNAVAILABLE); + } + break; + case PlayerFaction::GREEN: + if (unit.getFaction() == UnitFaction::UGREEN) + { + unit.setState(UnitState::UNAVAILABLE); + } + break; + case PlayerFaction::YELLOW: + if (unit.getFaction() == UnitFaction::UYELLOW) + { + unit.setState(UnitState::UNAVAILABLE); + } + break; + case PlayerFaction::PURPLE: + if (unit.getFaction() == UnitFaction::UPURPLE) + { + unit.setState(UnitState::UNAVAILABLE); + } + break; + default: + break; + } + } + m_activeTurn = false; +} } // namespace advanced_wars \ No newline at end of file diff --git a/src/game/Player.hpp b/src/game/Player.hpp index dafdcb7..27f6921 100644 --- a/src/game/Player.hpp +++ b/src/game/Player.hpp @@ -1,6 +1,8 @@ #pragma once +#include "Building.hpp" #include "Unit.hpp" +#include <unordered_map> namespace advanced_wars { @@ -17,17 +19,32 @@ enum class PlayerFaction class Player { private: - int money; - bool alive; - bool activeTurn; - PlayerFaction faction; + int m_money; + bool m_alive; + bool m_activeTurn; + PlayerFaction m_faction; public: Player(/* args */); ~Player(); - void startTurn(); - void endTurn(); + /** + * Sets all units of the players faction to idle, adds money for each building under the + * players control and sets them as the active player. + * + * @param lvUnits All current units of a level + * @param lvBuildings All buildings of a level + */ + void startTurn( + std::unordered_map<int, Unit> lvUnits, std::unordered_map<int, Building> lvBuildings); + + /** + * Sets all units of the players faction to unavailable and sets them as no longer being the + * active player. + * + * @param lvUnits All current units of a level + */ + void endTurn(std::unordered_map<int, Unit> lvUnits); }; } // namespace advanced_wars -- GitLab From 5207e5adc295eb98c1c9dd923c370a589a03de96 Mon Sep 17 00:00:00 2001 From: Frederik Keens <frederik@prasch.de> Date: Mon, 3 Feb 2025 14:34:34 +0100 Subject: [PATCH 04/12] Implement player turn queue and a change turn function --- src/game/Level.cpp | 12 ++++++++++++ src/game/Level.hpp | 5 +++++ 2 files changed, 17 insertions(+) diff --git a/src/game/Level.cpp b/src/game/Level.cpp index 67e35e5..01f1e31 100644 --- a/src/game/Level.cpp +++ b/src/game/Level.cpp @@ -380,4 +380,16 @@ Effect Level::removeEffect(int id) return value; } +void Level::changeTurn() +{ + Player temp = m_turnQ.front(); + + temp.endTurn(m_units); + + // Cycle Player at end of queue + m_turnQ.pop(); + m_turnQ.push(temp); + + m_turnQ.front().startTurn(m_units, m_buildings); +} } // namespace advanced_wars diff --git a/src/game/Level.hpp b/src/game/Level.hpp index 49c076f..de691c5 100644 --- a/src/game/Level.hpp +++ b/src/game/Level.hpp @@ -3,11 +3,13 @@ #include "Building.hpp" #include "Effect.hpp" #include "Engine.hpp" +#include "Player.hpp" #include "Scene.hpp" #include "Tile.hpp" #include "Unit.hpp" #include "ui/Contextmenu.hpp" #include <SDL.h> +#include <queue> #include <string> #include <unordered_map> #include <vector> @@ -52,6 +54,7 @@ class Level : public Scene std::unordered_map<int, Building> m_buildings; std::unordered_map<int, Unit> m_units; std::unordered_map<int, Effect> m_effects; + std::queue<Player> m_turnQ; int m_selectedUnit; int m_targetedUnit; @@ -68,6 +71,8 @@ class Level : public Scene bool clickCheckLeft(int mouseX, int mouseY); bool clickCheckRight(int mouseX, int mouseY); + + void changeTurn(); }; } // namespace advanced_wars -- GitLab From 121307a45c54d527d1373fadb7748e2478ccb98d Mon Sep 17 00:00:00 2001 From: TheUltimateOptimist <digitalConfidence@web.de> Date: Mon, 3 Feb 2025 23:50:45 +0100 Subject: [PATCH 05/12] switched green and yellow around to match order of building faction enum --- src/game/Player.cpp | 26 +++++++++++++------------- src/game/Player.hpp | 2 +- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/src/game/Player.cpp b/src/game/Player.cpp index 92584f7..069f00d 100644 --- a/src/game/Player.cpp +++ b/src/game/Player.cpp @@ -26,14 +26,14 @@ void Player::startTurn( unit.setState(UnitState::IDLE); } break; - case PlayerFaction::GREEN: - if (unit.getFaction() == UnitFaction::UGREEN) + case PlayerFaction::YELLOW: + if (unit.getFaction() == UnitFaction::UYELLOW) { unit.setState(UnitState::IDLE); } break; - case PlayerFaction::YELLOW: - if (unit.getFaction() == UnitFaction::UYELLOW) + case PlayerFaction::GREEN: + if (unit.getFaction() == UnitFaction::UGREEN) { unit.setState(UnitState::IDLE); } @@ -68,14 +68,14 @@ void Player::startTurn( underControl++; } break; - case PlayerFaction::GREEN: - if (building.getFaction() == BuildingFaction::GREEN) + case PlayerFaction::YELLOW: + if (building.getFaction() == BuildingFaction::YELLOW) { underControl++; } - break; - case PlayerFaction::YELLOW: - if (building.getFaction() == BuildingFaction::YELLOW) + break; + case PlayerFaction::GREEN: + if (building.getFaction() == BuildingFaction::GREEN) { underControl++; } @@ -115,14 +115,14 @@ void Player::endTurn(std::unordered_map<int, Unit> lvUnits) unit.setState(UnitState::UNAVAILABLE); } break; - case PlayerFaction::GREEN: - if (unit.getFaction() == UnitFaction::UGREEN) + case PlayerFaction::YELLOW: + if (unit.getFaction() == UnitFaction::UYELLOW) { unit.setState(UnitState::UNAVAILABLE); } break; - case PlayerFaction::YELLOW: - if (unit.getFaction() == UnitFaction::UYELLOW) + case PlayerFaction::GREEN: + if (unit.getFaction() == UnitFaction::UGREEN) { unit.setState(UnitState::UNAVAILABLE); } diff --git a/src/game/Player.hpp b/src/game/Player.hpp index 27f6921..0dd5223 100644 --- a/src/game/Player.hpp +++ b/src/game/Player.hpp @@ -11,8 +11,8 @@ enum class PlayerFaction { RED, BLUE, - GREEN, YELLOW, + GREEN, PURPLE }; -- GitLab From bb099e4ade147abe287f6404144f73ee2dd6a996 Mon Sep 17 00:00:00 2001 From: TheUltimateOptimist <digitalConfidence@web.de> Date: Tue, 4 Feb 2025 00:46:28 +0100 Subject: [PATCH 06/12] enabled creation of turnQ in loadLevel function --- src/game/Level.cpp | 28 ++++++++++++++++++++++------ src/game/Level.hpp | 5 +++-- src/game/Player.cpp | 5 +++-- src/game/Player.hpp | 2 +- src/game/ui/Menu.cpp | 13 +++++++------ 5 files changed, 36 insertions(+), 17 deletions(-) diff --git a/src/game/Level.cpp b/src/game/Level.cpp index 01f1e31..70eb70c 100644 --- a/src/game/Level.cpp +++ b/src/game/Level.cpp @@ -21,9 +21,10 @@ const int RENDERING_SCALE = 3; Level::Level( std::string name, int width, int height, std::vector<Tile> tiles, - std::vector<Building> buildings, std::vector<Unit> units, std::vector<Effect> effects) - : m_name(name), m_width(width), m_height(height), m_tiles(tiles), m_contextMenu(ContextMenu()), - m_contextMenuActive(false), m_id(0) + std::vector<Building> buildings, std::vector<Unit> units, std::vector<Effect> effects, + std::queue<Player> turnQ) + : m_name(name), m_width(width), m_height(height), m_tiles(tiles), m_turnQ(turnQ), + m_contextMenu(ContextMenu()), m_contextMenuActive(false), m_id(0) { m_contextMenu.setOptions({"Move", "Info", "Wait"}); @@ -49,7 +50,7 @@ Level::Level( } }; -Level Level::loadLevel(std::string path) +std::shared_ptr<Level> Level::loadLevel(std::string path) { HighFive::File file(path, HighFive::File::ReadOnly); @@ -73,6 +74,7 @@ Level Level::loadLevel(std::string path) std::vector<Tile> tiles; std::vector<Building> buildings; tiles.reserve(width * height); + bool has_factions[] = {false, false, false, false, false}; for (int i = 0; i < level_tilesarray.size(); i++) { int x = i % width; @@ -83,6 +85,10 @@ Level Level::loadLevel(std::string path) BuildingId building_id = static_cast<BuildingId>((level_tilesarray[i] - 50) % 5); BuildingFaction faction_id = static_cast<BuildingFaction>((level_tilesarray[i] - 50) / 5); + if (building_id == BuildingId::HEADQUARTER) + { + has_factions[static_cast<int>(faction_id)] = true; + } buildings.push_back(Building(x, y, building_id, faction_id)); } else @@ -92,7 +98,18 @@ Level Level::loadLevel(std::string path) } } - return Level(name, width, height, tiles, buildings, {}, {}); + // create turnQ from has_factions array + std::queue<Player> turnQ; + for (int i = 0; i < 5; i++) + { + if (has_factions[i]) + { + turnQ.push(Player(2000, static_cast<PlayerFaction>(i))); + } + } + + return std::make_shared<Level>( + name, width, height, tiles, buildings, std::vector<Unit>{}, std::vector<Effect>{}, turnQ); }; bool Level::clickCheckLeft(int tileX, int tileY) @@ -279,7 +296,6 @@ void Level::handleEvent(Engine& engine, SDL_Event& event) void Level::render(Engine& engine) { - // Iterate over all events while (!engine.events().empty()) { diff --git a/src/game/Level.hpp b/src/game/Level.hpp index de691c5..979233d 100644 --- a/src/game/Level.hpp +++ b/src/game/Level.hpp @@ -25,9 +25,10 @@ class Level : public Scene public: Level( std::string name, int width, int height, std::vector<Tile> tiles, - std::vector<Building> buildings, std::vector<Unit> units, std::vector<Effect>); + std::vector<Building> buildings, std::vector<Unit> units, + std::vector<Effect> effects, std::queue<Player> turnQ); - static Level loadLevel(std::string path); + static std::shared_ptr<Level> loadLevel(std::string path); void render(Engine& engine); diff --git a/src/game/Player.cpp b/src/game/Player.cpp index 069f00d..d521a78 100644 --- a/src/game/Player.cpp +++ b/src/game/Player.cpp @@ -1,9 +1,10 @@ #include "Player.hpp" +#include <iostream> namespace advanced_wars { -Player::Player() {} +Player::Player(int money, PlayerFaction faction) : m_money(money), m_faction(faction) {} Player::~Player() {} @@ -73,7 +74,7 @@ void Player::startTurn( { underControl++; } - break; + break; case PlayerFaction::GREEN: if (building.getFaction() == BuildingFaction::GREEN) { diff --git a/src/game/Player.hpp b/src/game/Player.hpp index 0dd5223..06f50d7 100644 --- a/src/game/Player.hpp +++ b/src/game/Player.hpp @@ -25,7 +25,7 @@ class Player PlayerFaction m_faction; public: - Player(/* args */); + Player(int money, PlayerFaction faction); ~Player(); /** diff --git a/src/game/ui/Menu.cpp b/src/game/ui/Menu.cpp index 392209b..62e6c02 100644 --- a/src/game/ui/Menu.cpp +++ b/src/game/ui/Menu.cpp @@ -71,7 +71,7 @@ void Menu::render(Engine& engine) { SDL_Texture* titleTexture = SDL_CreateTextureFromSurface(engine.renderer(), titleSurface); SDL_Rect titleRect = { - static_cast<int>((800 - titleSurface->w) / 2), 50, titleSurface->w, titleSurface->h}; + static_cast<int>((800 - titleSurface->w) / 2), 50, titleSurface->w, titleSurface->h}; SDL_RenderCopy(engine.renderer(), titleTexture, nullptr, &titleRect); SDL_DestroyTexture(titleTexture); SDL_FreeSurface(titleSurface); @@ -88,8 +88,8 @@ void Menu::render(Engine& engine) SDL_Texture* textTexture = SDL_CreateTextureFromSurface(engine.renderer(), textSurface); SDL_Rect textRect = { - static_cast<int>((800 - textSurface->w) / 2), static_cast<int>(150 + i * 50), - textSurface->w, textSurface->h}; + static_cast<int>((800 - textSurface->w) / 2), static_cast<int>(150 + i * 50), + textSurface->w, textSurface->h}; SDL_RenderCopy(engine.renderer(), textTexture, nullptr, &textRect); SDL_DestroyTexture(textTexture); @@ -197,10 +197,11 @@ void Menu::handleEvent(Engine& engine, SDL_Event& event) Effect(5, 15, EffectId::AIR_EXPLOSION, true), Effect(5, 18, EffectId::NAVAL_EXPLOSION, true)}); - std::shared_ptr<Level> level = - std::make_shared<Level>("Osnabrück", 20, 20, tiles, buildings, units, effects); + // std::shared_ptr<Level> level = + // std::make_shared<Level>("Osnabrück", 20, 20, tiles, buildings, units, + // effects, std::queue<Player>{}); - engine.pushScene(level); + engine.pushScene(Level::loadLevel("../res/level.h5")); } else if (m_options[m_selectedOption] == "Options") { -- GitLab From f0d7034418dcf1f64058cf35c59043d07a91221f Mon Sep 17 00:00:00 2001 From: TheUltimateOptimist <digitalConfidence@web.de> Date: Tue, 4 Feb 2025 18:53:29 +0100 Subject: [PATCH 07/12] every headquarter receives infantery at start --- src/game/Level.cpp | 12 ++++++++++-- src/game/Unit.hpp | 2 +- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/src/game/Level.cpp b/src/game/Level.cpp index 70eb70c..e9293b8 100644 --- a/src/game/Level.cpp +++ b/src/game/Level.cpp @@ -70,9 +70,10 @@ std::shared_ptr<Level> Level::loadLevel(std::string path) int height = pt.get<int>("level.height"); std::string name = pt.get<std::string>("level.name"); - // create tiles and buildings vector from tiles array + // create tiles, buildings and units vector from tiles array std::vector<Tile> tiles; std::vector<Building> buildings; + std::vector<Unit> units; tiles.reserve(width * height); bool has_factions[] = {false, false, false, false, false}; for (int i = 0; i < level_tilesarray.size(); i++) @@ -87,6 +88,13 @@ std::shared_ptr<Level> Level::loadLevel(std::string path) static_cast<BuildingFaction>((level_tilesarray[i] - 50) / 5); if (building_id == BuildingId::HEADQUARTER) { + int index = static_cast<int>(faction_id); + if (!has_factions[index]) + { + units.push_back(Unit( + x, y, static_cast<UnitFaction>(faction_id), UnitId::INFANTERY, + UnitState::IDLE)); + } has_factions[static_cast<int>(faction_id)] = true; } buildings.push_back(Building(x, y, building_id, faction_id)); @@ -109,7 +117,7 @@ std::shared_ptr<Level> Level::loadLevel(std::string path) } return std::make_shared<Level>( - name, width, height, tiles, buildings, std::vector<Unit>{}, std::vector<Effect>{}, turnQ); + name, width, height, tiles, buildings, units, std::vector<Effect>{}, turnQ); }; bool Level::clickCheckLeft(int tileX, int tileY) diff --git a/src/game/Unit.hpp b/src/game/Unit.hpp index 285ac13..707e157 100644 --- a/src/game/Unit.hpp +++ b/src/game/Unit.hpp @@ -12,8 +12,8 @@ enum class UnitFaction { URED = 0, UBLUE = 1, - UGREEN = 2, UYELLOW = 3, + UGREEN = 2, UPURPLE = 4, }; -- GitLab From fccb56ed521aff32ed1bd5c7cb71e79eb582c8da Mon Sep 17 00:00:00 2001 From: Frederik <frederik@prasch.de> Date: Thu, 6 Feb 2025 02:42:11 +0100 Subject: [PATCH 08/12] Add the proper test Level to test more gameplay --- res/level.h5 | Bin 0 -> 6310 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 res/level.h5 diff --git a/res/level.h5 b/res/level.h5 new file mode 100644 index 0000000000000000000000000000000000000000..aa5ba5b60aae9dc4927a4e818e5bb480796ee5a0 GIT binary patch literal 6310 zcmeD5aB<`1lHy_j0S*oZ76t(j3y%Lo!7>Sm5S05L!ed}afHD}NbO)4P!31G2GJqfh z15`VMAk=(xbs<5nt_%!}3^4OyG{h7J1_Krd3uX?4H%g9_5b$ty3;_8x0z@z{Fla#O z6VP-9<uc@^mL#SmmL$UXC7C&?#fe2liIor$SUNR;a0!x(3~UTwJzxTqLOH;Cpj-xK z1_`jdBqJj@WrK1LL=K{km4O2+&%^|#7&xFgftis3q5!N5Y$TWvf(nDoXtth_&cFc6 zDPZXVCxZR_T^Jddpsr+KP+-RIBv^i}V8yR)q{(8YD@aH&GJ;~BfngdnKwva8g8(=I z;Z9#nV2z0MB>*uHZW6>m%=Fa&kr*XMWC-LiFfa%}OCnGLa(DLk0nxBx3Cw0-U;wED z1(1z>MQ)BlS!z*nW`3TnlA)e~l0s@;a(+r?Ub?MPX-S%{g_6A;mrYJ;S!#}*O?hTY zNrs)Fsf|8_Ws{MbnVwN%XJ}xf4`tfqCFZ8uIp!2(B--eM**5wR-5~p5xPTwV8l^`= zU^E0qLtr!nMnhmU1V%$(Gz3ONU^E0qLtr!nMnhmU1SkywCT3=4CMFQc4DR|ffyVck znVFdxpabwA3z(Tf1ECDyp;sRtV~`R?29O{~l7X3l!IF`gfx(D@fx*WY#08C9nS<pR iz{)_fP%Z;AGc!mp6I?sUBC!1o%uGzoOw5eTOiTdvhGZfD literal 0 HcmV?d00001 -- GitLab From fe879173d854c3cd572a4536d8a9eca048693e9d Mon Sep 17 00:00:00 2001 From: Frederik <frederik@prasch.de> Date: Thu, 6 Feb 2025 02:42:38 +0100 Subject: [PATCH 09/12] Fix tilemarker not reaching leftmost tile --- src/game/ui/TileMarker.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/game/ui/TileMarker.cpp b/src/game/ui/TileMarker.cpp index cfffcc6..1ad9d6a 100644 --- a/src/game/ui/TileMarker.cpp +++ b/src/game/ui/TileMarker.cpp @@ -62,7 +62,7 @@ void TileMarker::handleEvent(Engine& engine, SDL_Event& event) newX = m_x - 16 * m_renderingScale; std::cout << "New X: " << newX << std::endl; - if (newX <= 0) + if (newX < 0) { break; } @@ -82,7 +82,8 @@ std::pair<int, int> TileMarker::getPosition() return {tileX, tileY}; } -void TileMarker::setPosition(int tileX, int tileY){ +void TileMarker::setPosition(int tileX, int tileY) +{ m_x = tileX * 16 * m_renderingScale; m_y = tileY * 16 * m_renderingScale + (16 * m_renderingScale - m_height); } -- GitLab From 03e2d6bd2e1bcc59f9493a9141c410045016f69d Mon Sep 17 00:00:00 2001 From: Frederik <frederik@prasch.de> Date: Thu, 6 Feb 2025 02:43:10 +0100 Subject: [PATCH 10/12] Fix stuff broken by merge --- src/game/Level.cpp | 8 ++++---- src/game/Level.hpp | 20 ++++++++++---------- src/game/Player.cpp | 10 +++++----- src/game/Unit.cpp | 16 +++------------- src/game/ui/Menu.cpp | 11 +++++------ 5 files changed, 27 insertions(+), 38 deletions(-) diff --git a/src/game/Level.cpp b/src/game/Level.cpp index a41458d..eebaf33 100644 --- a/src/game/Level.cpp +++ b/src/game/Level.cpp @@ -23,12 +23,12 @@ const int RENDERING_SCALE = 3; Level::Level( std::string name, int width, int height, std::vector<Tile> tiles, - std::vector<Building> buildings, std::vector<Unit> units, std::vector<Effect> effects + std::vector<Building> buildings, std::vector<Unit> units, std::vector<Effect> effects, std::queue<Player> turnQ) : m_name(name), m_width(width), m_height(height), m_tiles(tiles), m_selectedUnit(-1), m_selectedBuilding(-1), m_contextMenu(ContextMenu()), m_id(0), m_state(LevelState::SELECTING_STATE), - m_currentPos(TileMarker(RENDERING_SCALE, 1, 1, m_width, m_height), m_turnQ(turnQ)) + m_currentPos(TileMarker(RENDERING_SCALE, 1, 1, m_width, m_height)), m_turnQ(turnQ) { m_contextMenu.setOptions({"Move", "Info", "Wait"}); @@ -57,7 +57,7 @@ Level::Level( m_selectedUnit = -1; }; -std::shared_ptr<Level> Level::loadLevel(std::string path) +std::shared_ptr<Level> Level::loadLevel(std::string path, Engine& engine) { HighFive::File file(path, HighFive::File::ReadOnly); @@ -100,7 +100,7 @@ std::shared_ptr<Level> Level::loadLevel(std::string path) { units.push_back(Unit( x, y, static_cast<UnitFaction>(faction_id), UnitId::INFANTERY, - UnitState::IDLE)); + UnitState::IDLE, engine.getUnitConfig())); } has_factions[static_cast<int>(faction_id)] = true; } diff --git a/src/game/Level.hpp b/src/game/Level.hpp index 909223c..6e2aeea 100644 --- a/src/game/Level.hpp +++ b/src/game/Level.hpp @@ -11,8 +11,8 @@ #include "ui/Recruitingmenu.hpp" #include "ui/TileMarker.hpp" #include <SDL.h> -#include <queue> #include <array> +#include <queue> #include <string> #include <unordered_map> #include <unordered_set> @@ -77,10 +77,10 @@ class Level : public Scene public: Level( std::string name, int width, int height, std::vector<Tile> tiles, - std::vector<Building> buildings, std::vector<Unit> units, - std::vector<Effect> effects, std::queue<Player> turnQ); + std::vector<Building> buildings, std::vector<Unit> units, std::vector<Effect> effects, + std::queue<Player> turnQ); - static std::shared_ptr<Level> loadLevel(std::string path); + static std::shared_ptr<Level> loadLevel(std::string path, Engine& engine); void render(Engine& engine); @@ -131,12 +131,12 @@ class Level : public Scene std::unordered_map<int, Effect> m_effects; std::queue<Player> m_turnQ; - int m_selectedUnit; - int m_selectedBuilding; - ContextMenu m_contextMenu; - RecruitingMenu m_recruitingMenu; - int m_id; - LevelState m_state; + int m_selectedUnit; + int m_selectedBuilding; + ContextMenu m_contextMenu; + RecruitingMenu m_recruitingMenu; + int m_id; + LevelState m_state; std::pair<int, int> calcTilePos(int mouseX, int mouseY); void selectEntity(int x, int y); diff --git a/src/game/Player.cpp b/src/game/Player.cpp index d521a78..ee8a248 100644 --- a/src/game/Player.cpp +++ b/src/game/Player.cpp @@ -58,31 +58,31 @@ void Player::startTurn( switch (m_faction) { case PlayerFaction::RED: - if (building.getFaction() == BuildingFaction::RED) + if (building.getFaction() == BuildingFaction::URED) { underControl++; } break; case PlayerFaction::BLUE: - if (building.getFaction() == BuildingFaction::BLUE) + if (building.getFaction() == BuildingFaction::UBLUE) { underControl++; } break; case PlayerFaction::YELLOW: - if (building.getFaction() == BuildingFaction::YELLOW) + if (building.getFaction() == BuildingFaction::UYELLOW) { underControl++; } break; case PlayerFaction::GREEN: - if (building.getFaction() == BuildingFaction::GREEN) + if (building.getFaction() == BuildingFaction::UGREEN) { underControl++; } break; case PlayerFaction::PURPLE: - if (building.getFaction() == BuildingFaction::PURPLE) + if (building.getFaction() == BuildingFaction::UPURPLE) { underControl++; } diff --git a/src/game/Unit.cpp b/src/game/Unit.cpp index 9797603..f5d85a3 100644 --- a/src/game/Unit.cpp +++ b/src/game/Unit.cpp @@ -42,8 +42,6 @@ Unit::Unit(int x, int y, UnitFaction faction, UnitId id, UnitState state, Config m_secondaryWeapon = Weapon(config.getUnitSecondaryWeapon(id), secondaryDamage); } - - void Unit::render(Engine& engine, int scale) { Spritesheet* spritesheet = engine.getSpritesheet(); @@ -149,9 +147,9 @@ void Unit::attack(Unit& enemy) int Unit::calculateDamage(Unit& target) { // Pointers to Weapon objects - Weapon* primaryWeapon = &m_primaryWeapon; + Weapon* primaryWeapon = &m_primaryWeapon; Weapon* secondaryWeapon = &m_secondaryWeapon; - + // Find the corresponding damage values auto primary_damage_it = primaryWeapon->m_damage.find(target.m_id); auto secondary_damage_it = secondaryWeapon->m_damage.find(target.m_id); @@ -181,8 +179,6 @@ int Unit::calculateDamage(Unit& target) return damage_value; } - - void Unit::performAttack(Unit& target, int damage) { int effective_damage = damage * (static_cast<float>(m_health) / m_maxHealth); @@ -244,7 +240,7 @@ std::vector<Unit*> Unit::getUnitsInRangeWithDamagePotential(const std::vector<Un std::vector<Unit*> unitsInRangeWithDamage; for (Unit* unit : allUnits) - { //Iterate over all units + { // Iterate over all units // except itself if (unit == this) { @@ -254,7 +250,6 @@ std::vector<Unit*> Unit::getUnitsInRangeWithDamagePotential(const std::vector<Un int distanceX = std::abs(unit->m_x - m_x); int distanceY = std::abs(unit->m_y - m_y); - int distance = distanceX + distanceY; if (distance >= m_minRange && distance <= m_maxRange) { @@ -285,11 +280,6 @@ std::vector<Unit*> Unit::getUnitsInRangeWithDamagePotential(const std::vector<Un return unitsInRangeWithDamage; } -UnitFaction Unit::getFaction() -{ - return this->m_faction; -} - void Unit::renderHP(Engine& engine, int scale) { Spritesheet* spritesheet = engine.getSpritesheet(); diff --git a/src/game/ui/Menu.cpp b/src/game/ui/Menu.cpp index d2e5891..770a153 100644 --- a/src/game/ui/Menu.cpp +++ b/src/game/ui/Menu.cpp @@ -1,7 +1,7 @@ #include "Menu.hpp" #include "../Building.hpp" -#include "../Level.hpp" #include "../Config.hpp" +#include "../Level.hpp" #include "../Spritesheet.hpp" #include "../Tile.hpp" #include "../Unit.hpp" @@ -72,7 +72,7 @@ void Menu::render(Engine& engine) { SDL_Texture* titleTexture = SDL_CreateTextureFromSurface(engine.renderer(), titleSurface); SDL_Rect titleRect = { - static_cast<int>((800 - titleSurface->w) / 2), 50, titleSurface->w, titleSurface->h}; + static_cast<int>((800 - titleSurface->w) / 2), 50, titleSurface->w, titleSurface->h}; SDL_RenderCopy(engine.renderer(), titleTexture, nullptr, &titleRect); SDL_DestroyTexture(titleTexture); SDL_FreeSurface(titleSurface); @@ -89,8 +89,8 @@ void Menu::render(Engine& engine) SDL_Texture* textTexture = SDL_CreateTextureFromSurface(engine.renderer(), textSurface); SDL_Rect textRect = { - static_cast<int>((800 - textSurface->w) / 2), static_cast<int>(150 + i * 50), - textSurface->w, textSurface->h}; + static_cast<int>((800 - textSurface->w) / 2), static_cast<int>(150 + i * 50), + textSurface->w, textSurface->h}; SDL_RenderCopy(engine.renderer(), textTexture, nullptr, &textRect); SDL_DestroyTexture(textTexture); @@ -126,7 +126,6 @@ void Menu::handleEvent(Engine& engine, SDL_Event& event) { std::cout << "Starting game..." << std::endl; - // Construct a level std::vector<Tile> tiles; for (int y = 0; y < 20; y++) @@ -203,7 +202,7 @@ void Menu::handleEvent(Engine& engine, SDL_Event& event) // std::make_shared<Level>("Osnabrück", 20, 20, tiles, buildings, units, // effects, std::queue<Player>{}); - engine.pushScene(Level::loadLevel("../res/level.h5")); + engine.pushScene(Level::loadLevel("../res/level.h5", engine)); } else if (m_options[m_selectedOption] == "Options") { -- GitLab From a048952d54803cb2c20ef16c447be87b617395ee Mon Sep 17 00:00:00 2001 From: Frederik <frederik@prasch.de> Date: Thu, 6 Feb 2025 03:40:29 +0100 Subject: [PATCH 11/12] Fix Bug with start and end turn and start the first turn immeadiatly after loading --- src/game/Level.cpp | 8 +++++--- src/game/Player.cpp | 9 ++++++--- src/game/Player.hpp | 4 ++-- 3 files changed, 13 insertions(+), 8 deletions(-) diff --git a/src/game/Level.cpp b/src/game/Level.cpp index eebaf33..15318c5 100644 --- a/src/game/Level.cpp +++ b/src/game/Level.cpp @@ -123,9 +123,11 @@ std::shared_ptr<Level> Level::loadLevel(std::string path, Engine& engine) } } - return std::make_shared<Level>( - name, width, height, tiles, buildings, units, std::vector<Effect>{}, turnQ); -}; + Level level(name, width, height, tiles, buildings, units, std::vector<Effect>{}, turnQ); + + level.m_turnQ.front().startTurn(level.m_units, level.m_buildings); + return std::make_shared<Level>(level); +} std::pair<int, int> Level::calcTilePos(int mouseX, int mouseY) { diff --git a/src/game/Player.cpp b/src/game/Player.cpp index ee8a248..9bd7bad 100644 --- a/src/game/Player.cpp +++ b/src/game/Player.cpp @@ -4,12 +4,15 @@ namespace advanced_wars { -Player::Player(int money, PlayerFaction faction) : m_money(money), m_faction(faction) {} +Player::Player(int money, PlayerFaction faction) + : m_money(money), m_alive(true), m_activeTurn(false), m_faction(faction) +{ +} Player::~Player() {} void Player::startTurn( - std::unordered_map<int, Unit> lvUnits, std::unordered_map<int, Building> lvBuildings) + std::unordered_map<int, Unit>& lvUnits, std::unordered_map<int, Building>& lvBuildings) { for (auto& [id, unit] : lvUnits) { @@ -98,7 +101,7 @@ void Player::startTurn( m_activeTurn = true; } -void Player::endTurn(std::unordered_map<int, Unit> lvUnits) +void Player::endTurn(std::unordered_map<int, Unit>& lvUnits) { for (auto& [id, unit] : lvUnits) { diff --git a/src/game/Player.hpp b/src/game/Player.hpp index 06f50d7..f77bb6c 100644 --- a/src/game/Player.hpp +++ b/src/game/Player.hpp @@ -36,7 +36,7 @@ class Player * @param lvBuildings All buildings of a level */ void startTurn( - std::unordered_map<int, Unit> lvUnits, std::unordered_map<int, Building> lvBuildings); + std::unordered_map<int, Unit>& lvUnits, std::unordered_map<int, Building>& lvBuildings); /** * Sets all units of the players faction to unavailable and sets them as no longer being the @@ -44,7 +44,7 @@ class Player * * @param lvUnits All current units of a level */ - void endTurn(std::unordered_map<int, Unit> lvUnits); + void endTurn(std::unordered_map<int, Unit>& lvUnits); }; } // namespace advanced_wars -- GitLab From e9f846cd2bfbfa6845ab2df21a1399267e5a8629 Mon Sep 17 00:00:00 2001 From: Frederik <frederik@prasch.de> Date: Thu, 6 Feb 2025 03:41:36 +0100 Subject: [PATCH 12/12] Fix missing config needed for unit construction and set starting units to spawn in unavailable state --- src/game/Level.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/game/Level.cpp b/src/game/Level.cpp index 15318c5..53e8448 100644 --- a/src/game/Level.cpp +++ b/src/game/Level.cpp @@ -100,7 +100,7 @@ std::shared_ptr<Level> Level::loadLevel(std::string path, Engine& engine) { units.push_back(Unit( x, y, static_cast<UnitFaction>(faction_id), UnitId::INFANTERY, - UnitState::IDLE, engine.getUnitConfig())); + UnitState::UNAVAILABLE, engine.getUnitConfig())); } has_factions[static_cast<int>(faction_id)] = true; } -- GitLab