diff --git a/CMakeLists.txt b/CMakeLists.txt index 5b934ef..27d08e3 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -97,6 +97,10 @@ add_executable(Dicewars_Siedler src/main.cpp src/game/hexWorld/RessourceType.h src/game/hexWorld/ecs/systems/TileHighlightSystem.cpp src/game/hexWorld/ecs/systems/TileHighlightSystem.h + src/game/hexWorld/ecs/components/BuildingComponent.cpp + src/game/hexWorld/ecs/components/BuildingComponent.h + src/game/hexWorld/ecs/systems/BuildingPlacementSystem.cpp + src/game/hexWorld/ecs/systems/BuildingPlacementSystem.h ) target_include_directories(Dicewars_Siedler PRIVATE diff --git a/src/engine/core/ECS/EntityManager.cpp b/src/engine/core/ECS/EntityManager.cpp index bad73ca..4facb46 100644 --- a/src/engine/core/ECS/EntityManager.cpp +++ b/src/engine/core/ECS/EntityManager.cpp @@ -14,4 +14,7 @@ void EntityManager::destroyEntity(EntityID entity) { entities.erase(std::remove(entities.begin(), entities.end(), entity), entities.end()); transforms.erase(entity); models.erase(entity); + tileRenderComponents.erase(entity); + tileGameplayComponents.erase(entity); + buildings.erase(entity); } diff --git a/src/engine/core/ECS/EntityManager.h b/src/engine/core/ECS/EntityManager.h index d1e4b3f..f1c574f 100644 --- a/src/engine/core/ECS/EntityManager.h +++ b/src/engine/core/ECS/EntityManager.h @@ -9,6 +9,7 @@ #include #include +class BuildingComponent; // Forward Declarations (KEINE includes hier!) class TransformComponent; class ModelComponent; @@ -28,6 +29,7 @@ private: std::unordered_map> tileRenderComponents; std::unordered_map> tileGameplayComponents; std::unordered_map> mapEntityComponents; + std::unordered_map> buildings; public: EntityID createEntity(); @@ -45,6 +47,8 @@ public: tileGameplayComponents[entity] = component; } else if constexpr (std::is_same_v) { mapEntityComponents[entity] = component; + } else if constexpr (std::is_same_v) { + buildings[entity] = component; } else { static_assert(sizeof(T) == 0, "Component-Typ nicht unterstützt"); } @@ -67,6 +71,9 @@ public: } else if constexpr (std::is_same_v) { auto it = mapEntityComponents.find(entity); return (it != mapEntityComponents.end()) ? it->second : nullptr; + } else if constexpr (std::is_same_v) { + auto it = buildings.find(entity); + return (it != buildings.end()) ? it->second : nullptr; } else { static_assert(sizeof(T) == 0, "Component-Typ nicht unterstützt"); } diff --git a/src/game/GameLayer.cpp b/src/game/GameLayer.cpp index 7f1b35c..c62fcb0 100644 --- a/src/game/GameLayer.cpp +++ b/src/game/GameLayer.cpp @@ -75,6 +75,7 @@ void GameLayer::onUpdate() camera->move(moveDir, 0.5f); tileHighlightSystem->update(*entityManager, *mousePicker, *camera); + buildingPlacementSystem->update(*entityManager); renderSystem->render(*entityManager, *renderer); renderer->render(*light, *camera); diff --git a/src/game/GameLayer.h b/src/game/GameLayer.h index 1dd9cbf..f5a6b9b 100644 --- a/src/game/GameLayer.h +++ b/src/game/GameLayer.h @@ -13,6 +13,7 @@ #include "../engine/layer/entities/Camera.h" #include "../engine/renderer/MasterRenderer.h" #include "hexWorld/Map.h" +#include "hexWorld/ecs/systems/BuildingPlacementSystem.h" #include "hexWorld/ecs/systems/TileHighlightSystem.h" @@ -42,6 +43,7 @@ private: std::unique_ptr renderSystem = std::make_unique(); std::unique_ptr tileHighlightSystem = std::make_unique(); + std::unique_ptr buildingPlacementSystem = std::make_unique(); std::unique_ptr entityManager = std::make_unique(); std::unique_ptr map; diff --git a/src/game/hexWorld/MapGenerator.cpp b/src/game/hexWorld/MapGenerator.cpp index c3da366..41cf5a0 100644 --- a/src/game/hexWorld/MapGenerator.cpp +++ b/src/game/hexWorld/MapGenerator.cpp @@ -36,10 +36,11 @@ void MapGenerator::generateHexMap(Map &map, int width, int height, EntityManager float randomValue = random.randomFloat(0.0f, 1.0f); RessourceType resourceType = RessourceType::NONE; std::shared_ptr hexModel = AssetManager::getModel("hexModelNone"); + std::vector tileEntities; if (randomValue < 0.5f) { resourceType = RessourceType::WOOD; ForestTileGenerator forestTileGenerator; - std::vector entities = forestTileGenerator.generateHexTile(entityManager, random, worldPos); + tileEntities = forestTileGenerator.generateHexTile(entityManager, random, worldPos); hexModel = AssetManager::getModel("hexModelWood"); } else if (randomValue < 0.75f) { resourceType = RessourceType::STONE; @@ -51,6 +52,7 @@ void MapGenerator::generateHexMap(Map &map, int width, int height, EntityManager const auto modelComponent = std::make_shared(hexModel); const auto tileHighlightComponent = std::make_shared(false); const auto tileGameplayComponent = std::make_shared(q, r, radius, resourceType); + tileGameplayComponent->entitiesOnTile = tileEntities; entityManager.addComponent(entityID, transformComponent); entityManager.addComponent(entityID, modelComponent); diff --git a/src/game/hexWorld/ecs/components/BuildingComponent.cpp b/src/game/hexWorld/ecs/components/BuildingComponent.cpp new file mode 100644 index 0000000..dad9f90 --- /dev/null +++ b/src/game/hexWorld/ecs/components/BuildingComponent.cpp @@ -0,0 +1,5 @@ +// +// Created by sebastian on 08.02.26. +// + +#include "BuildingComponent.h" diff --git a/src/game/hexWorld/ecs/components/BuildingComponent.h b/src/game/hexWorld/ecs/components/BuildingComponent.h new file mode 100644 index 0000000..6f18a66 --- /dev/null +++ b/src/game/hexWorld/ecs/components/BuildingComponent.h @@ -0,0 +1,25 @@ +// +// Created by sebastian on 08.02.26. +// + +#ifndef BUILDINGCOMPONENT_H +#define BUILDINGCOMPONENT_H +#include "../../../../engine/core/ECS/EntityManager.h" + +enum class BuildingType { + FOREST_HUT +}; + + +class BuildingComponent { +public: + BuildingType type; + + EntityID tileEntity; + + BuildingComponent(BuildingType type, EntityID tileEntity): type(type), tileEntity(tileEntity) {}; +}; + + + +#endif //BUILDINGCOMPONENT_H diff --git a/src/game/hexWorld/ecs/components/TileGameplayComponent.h b/src/game/hexWorld/ecs/components/TileGameplayComponent.h index 0bb081a..5505dcc 100644 --- a/src/game/hexWorld/ecs/components/TileGameplayComponent.h +++ b/src/game/hexWorld/ecs/components/TileGameplayComponent.h @@ -22,6 +22,7 @@ public: TileGameplayComponent(int q, int r, float radius, RessourceType ressourceType) : q(q), r(r), radius(radius), ressourceType(ressourceType) {}; + bool hasBuilding() const { return buildingEntityID != 0; } }; diff --git a/src/game/hexWorld/ecs/systems/BuildingPlacementSystem.cpp b/src/game/hexWorld/ecs/systems/BuildingPlacementSystem.cpp new file mode 100644 index 0000000..c978232 --- /dev/null +++ b/src/game/hexWorld/ecs/systems/BuildingPlacementSystem.cpp @@ -0,0 +1,51 @@ +// +// Created by sebastian on 08.02.26. +// + +#include "BuildingPlacementSystem.h" + +#include "../../RessourceType.h" +#include "../../../../engine/core/ECS/ModelComponent.h" +#include "../../../../engine/core/ECS/TileRenderComponent.h" +#include "../../../../engine/core/ECS/TransformComponent.h" +#include "../../../../engine/platform/glfw/InputManager.h" +#include "../../../../engine/renderer/model/AssetManager.h" +#include "../components/BuildingComponent.h" +#include "../components/TileGameplayComponent.h" +#include "GLFW/glfw3.h" + +void BuildingPlacementSystem::update(EntityManager& entityManager) { + if (!InputManager::isMouseButtonPressed(GLFW_MOUSE_BUTTON_LEFT)) { + return; + } + + for (EntityID entityID : entityManager.getAllEntities()) { + 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); + + entityManager.addComponent(buildingEntity, buildingModel); + entityManager.addComponent(buildingEntity, buildingTransform); + entityManager.addComponent(buildingEntity, buildingComponent); + + tileGameplayComponent->buildingEntityID = buildingEntity; + + for (EntityID id : tileGameplayComponent->entitiesOnTile) { + entityManager.destroyEntity(id); + } + tileGameplayComponent->entitiesOnTile.clear(); + } + } + } + + } +} diff --git a/src/game/hexWorld/ecs/systems/BuildingPlacementSystem.h b/src/game/hexWorld/ecs/systems/BuildingPlacementSystem.h new file mode 100644 index 0000000..e62bf24 --- /dev/null +++ b/src/game/hexWorld/ecs/systems/BuildingPlacementSystem.h @@ -0,0 +1,17 @@ +// +// Created by sebastian on 08.02.26. +// + +#ifndef BUILDINGPLACEMENTSYSTEM_H +#define BUILDINGPLACEMENTSYSTEM_H +#include "../../../../engine/core/ECS/EntityManager.h" + + +class BuildingPlacementSystem { +public: + void update(EntityManager& entityManager); +}; + + + +#endif //BUILDINGPLACEMENTSYSTEM_H