From 0f9655b742db5dd75460bd5b04f36d3100ae942a Mon Sep 17 00:00:00 2001 From: sebastian Date: Sun, 8 Feb 2026 20:05:48 +0100 Subject: [PATCH] ADD: GameMode and PlayerInventory --- CMakeLists.txt | 8 ++++ src/engine/core/ECS/EntityManager.h | 8 ++++ src/game/DicewarsApp.cpp | 5 ++- src/game/DicewarsApp.h | 4 ++ src/game/GameLayer.cpp | 7 +++- src/game/GameLayer.h | 4 ++ src/game/GameMode.cpp | 38 +++++++++++++++++++ src/game/GameMode.h | 29 ++++++++++++++ src/game/PlayerInventory.cpp | 22 +++++++++++ src/game/PlayerInventory.h | 25 ++++++++++++ .../ecs/components/OwnerComponent.cpp | 5 +++ .../hexWorld/ecs/components/OwnerComponent.h | 21 ++++++++++ .../ecs/systems/BuildingPlacementSystem.cpp | 34 ++++++++--------- .../ecs/systems/BuildingPlacementSystem.h | 3 +- src/game/player/Player.cpp | 9 +++++ src/game/player/Player.h | 33 ++++++++++++++++ 16 files changed, 233 insertions(+), 22 deletions(-) create mode 100644 src/game/GameMode.cpp create mode 100644 src/game/GameMode.h create mode 100644 src/game/PlayerInventory.cpp create mode 100644 src/game/PlayerInventory.h create mode 100644 src/game/hexWorld/ecs/components/OwnerComponent.cpp create mode 100644 src/game/hexWorld/ecs/components/OwnerComponent.h create mode 100644 src/game/player/Player.cpp create mode 100644 src/game/player/Player.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 27d08e3..c3c2c46 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -101,6 +101,14 @@ add_executable(Dicewars_Siedler src/main.cpp src/game/hexWorld/ecs/components/BuildingComponent.h src/game/hexWorld/ecs/systems/BuildingPlacementSystem.cpp src/game/hexWorld/ecs/systems/BuildingPlacementSystem.h + src/game/GameMode.cpp + src/game/GameMode.h + src/game/PlayerInventory.cpp + src/game/PlayerInventory.h + src/game/player/Player.cpp + src/game/player/Player.h + src/game/hexWorld/ecs/components/OwnerComponent.cpp + src/game/hexWorld/ecs/components/OwnerComponent.h ) target_include_directories(Dicewars_Siedler PRIVATE diff --git a/src/engine/core/ECS/EntityManager.h b/src/engine/core/ECS/EntityManager.h index f1c574f..7231eae 100644 --- a/src/engine/core/ECS/EntityManager.h +++ b/src/engine/core/ECS/EntityManager.h @@ -9,6 +9,8 @@ #include #include +#include "../../../game/hexWorld/ecs/components/OwnerComponent.h" + class BuildingComponent; // Forward Declarations (KEINE includes hier!) class TransformComponent; @@ -30,6 +32,7 @@ private: std::unordered_map> tileGameplayComponents; std::unordered_map> mapEntityComponents; std::unordered_map> buildings; + std::unordered_map> owners; public: EntityID createEntity(); @@ -49,6 +52,8 @@ public: mapEntityComponents[entity] = component; } else if constexpr (std::is_same_v) { buildings[entity] = component; + } else if constexpr (std::is_same_v) { + owners[entity] = component; } else { static_assert(sizeof(T) == 0, "Component-Typ nicht unterstützt"); } @@ -74,6 +79,9 @@ public: } else if constexpr (std::is_same_v) { auto it = buildings.find(entity); return (it != buildings.end()) ? it->second : nullptr; + } else if constexpr (std::is_same_v) { + auto it = owners.find(entity); + return (it != owners.end()) ? it->second : nullptr; } else { static_assert(sizeof(T) == 0, "Component-Typ nicht unterstützt"); } diff --git a/src/game/DicewarsApp.cpp b/src/game/DicewarsApp.cpp index a8c80c7..fd62ec4 100644 --- a/src/game/DicewarsApp.cpp +++ b/src/game/DicewarsApp.cpp @@ -7,5 +7,8 @@ #include "GameLayer.h" DicewarsApp::DicewarsApp() { - pushLayer(new GameLayer()); + gameMode = std::make_shared(); + GameLayer* gamelayer = new GameLayer(); + gamelayer->setGameMode(gameMode); + pushLayer(gamelayer); } diff --git a/src/game/DicewarsApp.h b/src/game/DicewarsApp.h index be44e63..53d97b9 100644 --- a/src/game/DicewarsApp.h +++ b/src/game/DicewarsApp.h @@ -4,11 +4,15 @@ #ifndef DICEWARS_SIEDLER_DICEWARSAPP_H #define DICEWARS_SIEDLER_DICEWARSAPP_H +#include "GameLayer.h" +#include "GameMode.h" #include "../engine/core/Application.h" class DicewarsApp: public Application { +private: + std::shared_ptr gameMode; public: DicewarsApp(); }; diff --git a/src/game/GameLayer.cpp b/src/game/GameLayer.cpp index c62fcb0..652d1a2 100644 --- a/src/game/GameLayer.cpp +++ b/src/game/GameLayer.cpp @@ -64,6 +64,7 @@ void GameLayer::onDetach() void GameLayer::onUpdate() { + PlayerID player = gameMode->getCurrentPlayer(); mousePicker->update(*camera); //printf("Mouse Ray: %f, %f, %f\n", mousePicker->getCurrentRay().x, mousePicker->getCurrentRay().y, mousePicker->getCurrentRay().z); glm::vec3 moveDir = glm::vec3(0,0,0); @@ -75,10 +76,14 @@ void GameLayer::onUpdate() camera->move(moveDir, 0.5f); tileHighlightSystem->update(*entityManager, *mousePicker, *camera); - buildingPlacementSystem->update(*entityManager); + buildingPlacementSystem->update(*entityManager, *gameMode, 0); renderSystem->render(*entityManager, *renderer); renderer->render(*light, *camera); } +void GameLayer::setGameMode(std::shared_ptr gameMode) { + this->gameMode = gameMode; +} + diff --git a/src/game/GameLayer.h b/src/game/GameLayer.h index f5a6b9b..57a7476 100644 --- a/src/game/GameLayer.h +++ b/src/game/GameLayer.h @@ -26,7 +26,11 @@ public: void onDetach() override; void onUpdate() override; + void setGameMode(std::shared_ptr gameMode); + private: + std::shared_ptr gameMode; + Loader loader; TexturedModel texturedModel; std::unique_ptr camera; diff --git a/src/game/GameMode.cpp b/src/game/GameMode.cpp new file mode 100644 index 0000000..cf7fe8c --- /dev/null +++ b/src/game/GameMode.cpp @@ -0,0 +1,38 @@ +// +// Created by sebastian on 08.02.26. +// + +#include "GameMode.h" + +#include +#include + +#include "player/Player.h" + +GameMode::GameMode() { + addPlayer(0, "Player 1"); +} + +bool GameMode::canBuild(PlayerID player, BuildingType buildingType) { + int woodCost = 10; + if (!players[player].getInventory()->hasEnough(RessourceType::WOOD, woodCost)) { + std::cout << "Not enough wood" << std::endl; + return false; + } + return true; +} + +void GameMode::build(PlayerID player, EntityID tileEntity, BuildingType buildingType) { + if (canBuild(player, buildingType)) { + players[player].getInventory()->spend(RessourceType::WOOD, 10); + } +} + +void GameMode::addPlayer(PlayerID playerID, std::string name) { + PlayerID id = static_cast(players.size()); + players[id] = Player(id, name); +} + +PlayerID GameMode::getCurrentPlayer() { + return 0; +} diff --git a/src/game/GameMode.h b/src/game/GameMode.h new file mode 100644 index 0000000..337327e --- /dev/null +++ b/src/game/GameMode.h @@ -0,0 +1,29 @@ +// +// Created by sebastian on 08.02.26. +// + +#ifndef GAMEMODE_H +#define GAMEMODE_H +#include "../engine/core/ECS/EntityManager.h" +#include "hexWorld/ecs/components/BuildingComponent.h" +#include "player/Player.h" + + +class GameMode { +public: + GameMode(); + bool canBuild(EntityID player, BuildingType buildingType); + void build(EntityID player, EntityID tileEntity, BuildingType buildingType); + + void addPlayer(PlayerID playerID, std::string name); + + PlayerID getCurrentPlayer(); + +private: + std::unordered_map players; + +}; + + + +#endif //GAMEMODE_H diff --git a/src/game/PlayerInventory.cpp b/src/game/PlayerInventory.cpp new file mode 100644 index 0000000..fc6aabb --- /dev/null +++ b/src/game/PlayerInventory.cpp @@ -0,0 +1,22 @@ +// +// Created by sebastian on 08.02.26. +// + +#include "PlayerInventory.h" + +#include + +bool PlayerInventory::hasEnough(RessourceType resourceType, int amount) const { + auto it = resources.find(resourceType); + return it != resources.end() && it->second >= amount; +} + +void PlayerInventory::spend(RessourceType resourceType, int amount) { + if (hasEnough(resourceType, amount)) { + resources[resourceType] -= amount; + } +} + +void PlayerInventory::add(RessourceType resourceType, int amount) { + resources[resourceType] += amount; +} diff --git a/src/game/PlayerInventory.h b/src/game/PlayerInventory.h new file mode 100644 index 0000000..d3f2263 --- /dev/null +++ b/src/game/PlayerInventory.h @@ -0,0 +1,25 @@ +// +// Created by sebastian on 08.02.26. +// + +#ifndef PLAYERINVENTORY_H +#define PLAYERINVENTORY_H +#include + +#include "hexWorld/RessourceType.h" + + +class PlayerInventory { +private: + std::unordered_map resources; + +public: + bool hasEnough(RessourceType resourceType, int amount) const; + void spend(RessourceType resourceType, int amount); + void add(RessourceType resourceType, int amount); + +}; + + + +#endif //PLAYERINVENTORY_H diff --git a/src/game/hexWorld/ecs/components/OwnerComponent.cpp b/src/game/hexWorld/ecs/components/OwnerComponent.cpp new file mode 100644 index 0000000..9a0c69f --- /dev/null +++ b/src/game/hexWorld/ecs/components/OwnerComponent.cpp @@ -0,0 +1,5 @@ +// +// Created by sebastian on 08.02.26. +// + +#include "OwnerComponent.h" diff --git a/src/game/hexWorld/ecs/components/OwnerComponent.h b/src/game/hexWorld/ecs/components/OwnerComponent.h new file mode 100644 index 0000000..f1ba9d5 --- /dev/null +++ b/src/game/hexWorld/ecs/components/OwnerComponent.h @@ -0,0 +1,21 @@ +// +// Created by sebastian on 08.02.26. +// + +#ifndef OWNERCOMPONENT_H +#define OWNERCOMPONENT_H +#include "../../../../engine/core/ECS/Component.h" +#include "../../../player/Player.h" + + +class OwnerComponent : public Component{ +private: + PlayerID playerID; + + public: + OwnerComponent(PlayerID playerID) : playerID(playerID) {}; +}; + + + +#endif //OWNERCOMPONENT_H diff --git a/src/game/hexWorld/ecs/systems/BuildingPlacementSystem.cpp b/src/game/hexWorld/ecs/systems/BuildingPlacementSystem.cpp index c978232..7157f46 100644 --- a/src/game/hexWorld/ecs/systems/BuildingPlacementSystem.cpp +++ b/src/game/hexWorld/ecs/systems/BuildingPlacementSystem.cpp @@ -14,7 +14,7 @@ #include "../components/TileGameplayComponent.h" #include "GLFW/glfw3.h" -void BuildingPlacementSystem::update(EntityManager& entityManager) { +void BuildingPlacementSystem::update(EntityManager& entityManager, GameMode& gameMode, PlayerID player) { if (!InputManager::isMouseButtonPressed(GLFW_MOUSE_BUTTON_LEFT)) { return; } @@ -23,29 +23,25 @@ void BuildingPlacementSystem::update(EntityManager& entityManager) { auto transformComponent = entityManager.getComponent(entityID); auto tileGameplayComponent = entityManager.getComponent(entityID); auto tileRenderComponent = entityManager.getComponent(entityID); - if (tileGameplayComponent && tileRenderComponent && transformComponent) { - if (tileRenderComponent->isHighlighted && !tileGameplayComponent->hasBuilding()) { - // later we have to check for building to be compatible with ressource type. Fore the moment we only have forest huts - if (tileGameplayComponent->ressourceType == RessourceType::WOOD) { - EntityID buildingEntity = entityManager.createEntity(); - auto buildingModel = std::make_shared(AssetManager::getModel("cabin")); - auto buildingTransform = std::make_shared(transformComponent->position, glm::vec3(0), 1.0f); - auto buildingComponent = std::make_shared(BuildingType::FOREST_HUT, entityID); + if (!transformComponent || !tileGameplayComponent || !tileRenderComponent) continue; - entityManager.addComponent(buildingEntity, buildingModel); - entityManager.addComponent(buildingEntity, buildingTransform); - entityManager.addComponent(buildingEntity, buildingComponent); + // Tile is not in focus or tile has already a building + if (!tileRenderComponent->isHighlighted || tileGameplayComponent->hasBuilding()) continue; - tileGameplayComponent->buildingEntityID = buildingEntity; + if (!gameMode.canBuild(player, BuildingType::FOREST_HUT)) continue; - for (EntityID id : tileGameplayComponent->entitiesOnTile) { - entityManager.destroyEntity(id); - } - tileGameplayComponent->entitiesOnTile.clear(); - } - } + gameMode.build(player, entityID, BuildingType::FOREST_HUT); + for (auto oldID : tileGameplayComponent->entitiesOnTile) { + entityManager.destroyEntity(oldID); } + tileGameplayComponent->entitiesOnTile.clear(); + EntityID buildingEntity = entityManager.createEntity(); + entityManager.addComponent(buildingEntity, std::make_shared(AssetManager::getModel("cabin"))); + entityManager.addComponent(buildingEntity, std::make_shared(transformComponent->position, glm::vec3(0), 1.f)); + entityManager.addComponent(buildingEntity, std::make_shared(BuildingType::FOREST_HUT, entityID)); + entityManager.addComponent(buildingEntity, std::make_shared(player)); + tileGameplayComponent->buildingEntityID = buildingEntity; } } diff --git a/src/game/hexWorld/ecs/systems/BuildingPlacementSystem.h b/src/game/hexWorld/ecs/systems/BuildingPlacementSystem.h index e62bf24..88edc85 100644 --- a/src/game/hexWorld/ecs/systems/BuildingPlacementSystem.h +++ b/src/game/hexWorld/ecs/systems/BuildingPlacementSystem.h @@ -4,12 +4,13 @@ #ifndef BUILDINGPLACEMENTSYSTEM_H #define BUILDINGPLACEMENTSYSTEM_H +#include "../../../GameMode.h" #include "../../../../engine/core/ECS/EntityManager.h" class BuildingPlacementSystem { public: - void update(EntityManager& entityManager); + void update(EntityManager &entityManager, GameMode &gameMode, EntityID player); }; diff --git a/src/game/player/Player.cpp b/src/game/player/Player.cpp new file mode 100644 index 0000000..dd3a43c --- /dev/null +++ b/src/game/player/Player.cpp @@ -0,0 +1,9 @@ +// +// Created by sebastian on 08.02.26. +// + +#include "Player.h" + +const std::unique_ptr & Player::getInventory() const { + return inventory; +} diff --git a/src/game/player/Player.h b/src/game/player/Player.h new file mode 100644 index 0000000..9d706d4 --- /dev/null +++ b/src/game/player/Player.h @@ -0,0 +1,33 @@ +// +// Created by sebastian on 08.02.26. +// + +#ifndef PLAYER_H +#define PLAYER_H +#include +#include +#include + +#include "../PlayerInventory.h" + +using PlayerID = std::uint32_t; + +class Player { +private: + PlayerID playerID; + std::string name; + std::unique_ptr inventory = std::make_unique(); + bool isAI = false; + +public: + Player() = default; + Player(const PlayerID playerID, const std::string& name) : playerID(playerID), name(std::move(name)) { + inventory->add(RessourceType::WOOD, 100); + }; + + const std::unique_ptr &getInventory() const; +}; + + + +#endif //PLAYER_H