ADD: Building Placement System

This commit is contained in:
sebastian 2026-02-08 19:04:15 +01:00
parent fe376e9c0f
commit 8e2024e5dc
11 changed files with 119 additions and 1 deletions

View File

@ -97,6 +97,10 @@ add_executable(Dicewars_Siedler src/main.cpp
src/game/hexWorld/RessourceType.h src/game/hexWorld/RessourceType.h
src/game/hexWorld/ecs/systems/TileHighlightSystem.cpp src/game/hexWorld/ecs/systems/TileHighlightSystem.cpp
src/game/hexWorld/ecs/systems/TileHighlightSystem.h 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 target_include_directories(Dicewars_Siedler PRIVATE

View File

@ -14,4 +14,7 @@ void EntityManager::destroyEntity(EntityID entity) {
entities.erase(std::remove(entities.begin(), entities.end(), entity), entities.end()); entities.erase(std::remove(entities.begin(), entities.end(), entity), entities.end());
transforms.erase(entity); transforms.erase(entity);
models.erase(entity); models.erase(entity);
tileRenderComponents.erase(entity);
tileGameplayComponents.erase(entity);
buildings.erase(entity);
} }

View File

@ -9,6 +9,7 @@
#include <unordered_map> #include <unordered_map>
#include <vector> #include <vector>
class BuildingComponent;
// Forward Declarations (KEINE includes hier!) // Forward Declarations (KEINE includes hier!)
class TransformComponent; class TransformComponent;
class ModelComponent; class ModelComponent;
@ -28,6 +29,7 @@ private:
std::unordered_map<EntityID, std::shared_ptr<TileRenderComponent>> tileRenderComponents; std::unordered_map<EntityID, std::shared_ptr<TileRenderComponent>> tileRenderComponents;
std::unordered_map<EntityID, std::shared_ptr<TileGameplayComponent>> tileGameplayComponents; std::unordered_map<EntityID, std::shared_ptr<TileGameplayComponent>> tileGameplayComponents;
std::unordered_map<EntityID, std::shared_ptr<MapEntityComponent>> mapEntityComponents; std::unordered_map<EntityID, std::shared_ptr<MapEntityComponent>> mapEntityComponents;
std::unordered_map<EntityID, std::shared_ptr<BuildingComponent>> buildings;
public: public:
EntityID createEntity(); EntityID createEntity();
@ -45,6 +47,8 @@ public:
tileGameplayComponents[entity] = component; tileGameplayComponents[entity] = component;
} else if constexpr (std::is_same_v<T, MapEntityComponent>) { } else if constexpr (std::is_same_v<T, MapEntityComponent>) {
mapEntityComponents[entity] = component; mapEntityComponents[entity] = component;
} else if constexpr (std::is_same_v<T, BuildingComponent>) {
buildings[entity] = component;
} else { } else {
static_assert(sizeof(T) == 0, "Component-Typ nicht unterstützt"); static_assert(sizeof(T) == 0, "Component-Typ nicht unterstützt");
} }
@ -67,6 +71,9 @@ public:
} else if constexpr (std::is_same_v<T, MapEntityComponent>) { } else if constexpr (std::is_same_v<T, MapEntityComponent>) {
auto it = mapEntityComponents.find(entity); auto it = mapEntityComponents.find(entity);
return (it != mapEntityComponents.end()) ? it->second : nullptr; return (it != mapEntityComponents.end()) ? it->second : nullptr;
} else if constexpr (std::is_same_v<T, BuildingComponent>) {
auto it = buildings.find(entity);
return (it != buildings.end()) ? it->second : nullptr;
} else { } else {
static_assert(sizeof(T) == 0, "Component-Typ nicht unterstützt"); static_assert(sizeof(T) == 0, "Component-Typ nicht unterstützt");
} }

View File

@ -75,6 +75,7 @@ void GameLayer::onUpdate()
camera->move(moveDir, 0.5f); camera->move(moveDir, 0.5f);
tileHighlightSystem->update(*entityManager, *mousePicker, *camera); tileHighlightSystem->update(*entityManager, *mousePicker, *camera);
buildingPlacementSystem->update(*entityManager);
renderSystem->render(*entityManager, *renderer); renderSystem->render(*entityManager, *renderer);
renderer->render(*light, *camera); renderer->render(*light, *camera);

View File

@ -13,6 +13,7 @@
#include "../engine/layer/entities/Camera.h" #include "../engine/layer/entities/Camera.h"
#include "../engine/renderer/MasterRenderer.h" #include "../engine/renderer/MasterRenderer.h"
#include "hexWorld/Map.h" #include "hexWorld/Map.h"
#include "hexWorld/ecs/systems/BuildingPlacementSystem.h"
#include "hexWorld/ecs/systems/TileHighlightSystem.h" #include "hexWorld/ecs/systems/TileHighlightSystem.h"
@ -42,6 +43,7 @@ private:
std::unique_ptr<RenderSystem> renderSystem = std::make_unique<RenderSystem>(); std::unique_ptr<RenderSystem> renderSystem = std::make_unique<RenderSystem>();
std::unique_ptr<TileHighlightSystem> tileHighlightSystem = std::make_unique<TileHighlightSystem>(); std::unique_ptr<TileHighlightSystem> tileHighlightSystem = std::make_unique<TileHighlightSystem>();
std::unique_ptr<BuildingPlacementSystem> buildingPlacementSystem = std::make_unique<BuildingPlacementSystem>();
std::unique_ptr<EntityManager> entityManager = std::make_unique<EntityManager>(); std::unique_ptr<EntityManager> entityManager = std::make_unique<EntityManager>();
std::unique_ptr<Map> map; std::unique_ptr<Map> map;

View File

@ -36,10 +36,11 @@ void MapGenerator::generateHexMap(Map &map, int width, int height, EntityManager
float randomValue = random.randomFloat(0.0f, 1.0f); float randomValue = random.randomFloat(0.0f, 1.0f);
RessourceType resourceType = RessourceType::NONE; RessourceType resourceType = RessourceType::NONE;
std::shared_ptr<TexturedModel> hexModel = AssetManager::getModel("hexModelNone"); std::shared_ptr<TexturedModel> hexModel = AssetManager::getModel("hexModelNone");
std::vector<EntityID> tileEntities;
if (randomValue < 0.5f) { if (randomValue < 0.5f) {
resourceType = RessourceType::WOOD; resourceType = RessourceType::WOOD;
ForestTileGenerator forestTileGenerator; ForestTileGenerator forestTileGenerator;
std::vector<EntityID> entities = forestTileGenerator.generateHexTile(entityManager, random, worldPos); tileEntities = forestTileGenerator.generateHexTile(entityManager, random, worldPos);
hexModel = AssetManager::getModel("hexModelWood"); hexModel = AssetManager::getModel("hexModelWood");
} else if (randomValue < 0.75f) { } else if (randomValue < 0.75f) {
resourceType = RessourceType::STONE; resourceType = RessourceType::STONE;
@ -51,6 +52,7 @@ void MapGenerator::generateHexMap(Map &map, int width, int height, EntityManager
const auto modelComponent = std::make_shared<ModelComponent>(hexModel); const auto modelComponent = std::make_shared<ModelComponent>(hexModel);
const auto tileHighlightComponent = std::make_shared<TileRenderComponent>(false); const auto tileHighlightComponent = std::make_shared<TileRenderComponent>(false);
const auto tileGameplayComponent = std::make_shared<TileGameplayComponent>(q, r, radius, resourceType); const auto tileGameplayComponent = std::make_shared<TileGameplayComponent>(q, r, radius, resourceType);
tileGameplayComponent->entitiesOnTile = tileEntities;
entityManager.addComponent(entityID, transformComponent); entityManager.addComponent(entityID, transformComponent);
entityManager.addComponent(entityID, modelComponent); entityManager.addComponent(entityID, modelComponent);

View File

@ -0,0 +1,5 @@
//
// Created by sebastian on 08.02.26.
//
#include "BuildingComponent.h"

View File

@ -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

View File

@ -22,6 +22,7 @@ public:
TileGameplayComponent(int q, int r, float radius, RessourceType ressourceType) : q(q), r(r), radius(radius), ressourceType(ressourceType) {}; TileGameplayComponent(int q, int r, float radius, RessourceType ressourceType) : q(q), r(r), radius(radius), ressourceType(ressourceType) {};
bool hasBuilding() const { return buildingEntityID != 0; }
}; };

View File

@ -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<TransformComponent>(entityID);
auto tileGameplayComponent = entityManager.getComponent<TileGameplayComponent>(entityID);
auto tileRenderComponent = entityManager.getComponent<TileRenderComponent>(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<ModelComponent>(AssetManager::getModel("cabin"));
auto buildingTransform = std::make_shared<TransformComponent>(transformComponent->position, glm::vec3(0), 1.0f);
auto buildingComponent = std::make_shared<BuildingComponent>(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();
}
}
}
}
}

View File

@ -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