UPD: Refactor BuildingSystem
This commit is contained in:
parent
c3a0fa662c
commit
36900334d0
@ -153,8 +153,25 @@ add_executable(Dicewars_Siedler src/main.cpp
|
||||
src/game/ui/components/factorys/RessourceWidgetFactory.h
|
||||
src/game/ui/components/UiInventoryContainer.cpp
|
||||
src/game/ui/components/UiInventoryContainer.h
|
||||
src/game/hexWorld/building/BuildingDefinition.h
|
||||
src/game/hexWorld/building/TemporaryBuildingDefinitionFactory.h
|
||||
src/game/hexWorld/building/BuildingRules.cpp
|
||||
src/game/hexWorld/building/BuildingRules.h
|
||||
src/game/hexWorld/building/BuildingFactory.cpp
|
||||
src/game/hexWorld/building/BuildingFactory.h
|
||||
src/game/hexWorld/building/BuildingConfig.cpp
|
||||
src/game/hexWorld/building/BuildingConfig.h
|
||||
src/engine/toolbox/util.h
|
||||
)
|
||||
|
||||
target_compile_options(Dicewars_Siedler PRIVATE
|
||||
-Wall
|
||||
-Wextra
|
||||
-Wpedantic
|
||||
-Werror=return-type
|
||||
)
|
||||
|
||||
|
||||
target_include_directories(Dicewars_Siedler PRIVATE
|
||||
lib/glfw/include
|
||||
lib/glm
|
||||
|
||||
@ -9,7 +9,6 @@
|
||||
void UiImage::onCollectRenderData(UiRenderBundle& renderBundle) {
|
||||
if (!visible) return;
|
||||
Dimensions dims = uiPositioner.screenSpace;
|
||||
std::cout << "Child Y: " << uiPositioner.screenSpace.y << "Height " << uiPositioner.screenSpace.height <<std::endl;
|
||||
GUITexture texture(textureID, glm::vec2(dims.x, dims.y), glm::vec2(dims.width, dims.height));
|
||||
renderBundle.addGUITexture(std::make_shared<GUITexture>(texture));;
|
||||
}
|
||||
|
||||
15
src/engine/toolbox/util.h
Normal file
15
src/engine/toolbox/util.h
Normal file
@ -0,0 +1,15 @@
|
||||
//
|
||||
// Created by sebastian on 13.02.26.
|
||||
//
|
||||
|
||||
#ifndef DICEWARS_SIEDLER_UTIL_H
|
||||
#define DICEWARS_SIEDLER_UTIL_H
|
||||
#include <algorithm>
|
||||
|
||||
namespace util {
|
||||
template<typename Range, typename T>
|
||||
bool contains(const Range& range, const T& value) {
|
||||
return std::find(range.begin(), range.end(), value) != range.end();
|
||||
}
|
||||
}
|
||||
#endif //DICEWARS_SIEDLER_UTIL_H
|
||||
@ -74,10 +74,6 @@ void GameLayer::onUpdate()
|
||||
if (InputManager::isKeyPressed(GLFW_KEY_A)) moveDir.x -= 1.0f;
|
||||
if (InputManager::isKeyPressed(GLFW_KEY_D)) moveDir.x += 1.0f;
|
||||
|
||||
if (InputManager::isKeyPressed(GLFW_KEY_F)) {
|
||||
gameMode->getPlayerInventory(gameMode->getCurrentPlayer()).add(RessourceType::FOOD, 10);
|
||||
}
|
||||
|
||||
|
||||
camera->move(moveDir, 0.5f);
|
||||
tileHighlightSystem->update(*entityManager, *mousePicker, *camera);
|
||||
|
||||
@ -22,6 +22,13 @@ bool GameMode::canBuild(PlayerID player, BuildingType buildingType) {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool GameMode::canAfford(const PlayerID player_id, RessourceType ressource, int amount) const {
|
||||
if (players.contains(player_id)) {
|
||||
return players.at(player_id).getInventory()->getAmount(ressource) >= amount;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void GameMode::build(PlayerID player, EntityID tileEntity, BuildingType buildingType) {
|
||||
if (canBuild(player, buildingType)) {
|
||||
players[player].getInventory()->spend(RessourceType::WOOD, 10);
|
||||
@ -41,4 +48,10 @@ PlayerInventory& GameMode::getPlayerInventory(PlayerID playerID) {
|
||||
return *players[playerID].getInventory();
|
||||
}
|
||||
|
||||
void GameMode::pay(PlayerID playerID, const std::unordered_map<RessourceType, int> &costs) {
|
||||
for (const auto &[resourceType, amount] : costs) {
|
||||
players[playerID].getInventory()->spend(resourceType, amount);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -13,6 +13,9 @@ class GameMode {
|
||||
public:
|
||||
GameMode();
|
||||
bool canBuild(EntityID player, BuildingType buildingType);
|
||||
|
||||
bool canAfford(PlayerID player_id, RessourceType ressource, int amount) const;
|
||||
|
||||
void build(EntityID player, EntityID tileEntity, BuildingType buildingType);
|
||||
|
||||
void addPlayer(PlayerID playerID, std::string name);
|
||||
@ -20,6 +23,8 @@ public:
|
||||
PlayerID getCurrentPlayer();
|
||||
PlayerInventory& getPlayerInventory(PlayerID playerID);
|
||||
|
||||
void pay(PlayerID uint32, const std::unordered_map<RessourceType, int> & pairs);
|
||||
|
||||
private:
|
||||
std::unordered_map<PlayerID, Player> players;
|
||||
|
||||
|
||||
15
src/game/hexWorld/building/BuildingConfig.cpp
Normal file
15
src/game/hexWorld/building/BuildingConfig.cpp
Normal file
@ -0,0 +1,15 @@
|
||||
//
|
||||
// Created by sebastian on 13.02.26.
|
||||
//
|
||||
|
||||
#include "BuildingConfig.h"
|
||||
|
||||
#include "TemporaryBuildingDefinitionFactory.h"
|
||||
|
||||
const BuildingDefinition & BuildingConfig::get(BuildingType type) {
|
||||
if (type == BuildingType::FOREST_HUT) {
|
||||
static const BuildingDefinition def = TemporaryBuildingDefinitionFactory::createForestHutDefinition();
|
||||
return def;
|
||||
}
|
||||
std::__throw_runtime_error("Unknown BuildingType");
|
||||
}
|
||||
16
src/game/hexWorld/building/BuildingConfig.h
Normal file
16
src/game/hexWorld/building/BuildingConfig.h
Normal file
@ -0,0 +1,16 @@
|
||||
//
|
||||
// Created by sebastian on 13.02.26.
|
||||
//
|
||||
|
||||
#ifndef DICEWARS_SIEDLER_BUILDINGCONFIG_H
|
||||
#define DICEWARS_SIEDLER_BUILDINGCONFIG_H
|
||||
#include "BuildingDefinition.h"
|
||||
|
||||
|
||||
class BuildingConfig {
|
||||
public:
|
||||
static const BuildingDefinition& get(BuildingType type);
|
||||
};
|
||||
|
||||
|
||||
#endif //DICEWARS_SIEDLER_BUILDINGCONFIG_H
|
||||
18
src/game/hexWorld/building/BuildingDefinition.h
Normal file
18
src/game/hexWorld/building/BuildingDefinition.h
Normal file
@ -0,0 +1,18 @@
|
||||
//
|
||||
// Created by sebastian on 13.02.26.
|
||||
//
|
||||
|
||||
#ifndef DICEWARS_SIEDLER_BUILDINGDEFINITION_H
|
||||
#define DICEWARS_SIEDLER_BUILDINGDEFINITION_H
|
||||
#include "../ecs/components/BuildingComponent.h"
|
||||
|
||||
struct BuildingDefinition {
|
||||
BuildingType type;
|
||||
|
||||
std::vector<RessourceType> allowedTileResources;
|
||||
std::unordered_map<RessourceType, int> resourceCosts;
|
||||
|
||||
std::string model;
|
||||
};
|
||||
|
||||
#endif //DICEWARS_SIEDLER_BUILDINGDEFINITION_H
|
||||
27
src/game/hexWorld/building/BuildingFactory.cpp
Normal file
27
src/game/hexWorld/building/BuildingFactory.cpp
Normal file
@ -0,0 +1,27 @@
|
||||
//
|
||||
// Created by sebastian on 13.02.26.
|
||||
//
|
||||
|
||||
#include "BuildingFactory.h"
|
||||
|
||||
#include "../../../engine/core/ECS/ModelComponent.h"
|
||||
#include "../../../engine/core/ECS/TransformComponent.h"
|
||||
#include "../../../engine/renderer/model/AssetManager.h"
|
||||
|
||||
EntityID BuildingFactory::create(EntityManager &em, const BuildingDefinition &def,
|
||||
const TransformComponent &tileTransform, EntityID tileEntity, PlayerID owner) {
|
||||
|
||||
EntityID e = em.createEntity();
|
||||
|
||||
em.addComponent(e, std::make_shared<ModelComponent>(AssetManager::getModel(def.model)));
|
||||
|
||||
em.addComponent(e, std::make_shared<TransformComponent>(
|
||||
tileTransform.position, glm::vec3(0), 1.f
|
||||
));
|
||||
|
||||
em.addComponent(e, std::make_shared<BuildingComponent>(def.type, tileEntity));
|
||||
|
||||
em.addComponent(e, std::make_shared<OwnerComponent>(owner));
|
||||
|
||||
return e;
|
||||
}
|
||||
17
src/game/hexWorld/building/BuildingFactory.h
Normal file
17
src/game/hexWorld/building/BuildingFactory.h
Normal file
@ -0,0 +1,17 @@
|
||||
//
|
||||
// Created by sebastian on 13.02.26.
|
||||
//
|
||||
|
||||
#ifndef DICEWARS_SIEDLER_BUILDINGFACTORY_H
|
||||
#define DICEWARS_SIEDLER_BUILDINGFACTORY_H
|
||||
#include "BuildingDefinition.h"
|
||||
#include "../../../engine/core/ECS/EntityManager.h"
|
||||
|
||||
|
||||
class BuildingFactory {
|
||||
public:
|
||||
static EntityID create(EntityManager& em, const BuildingDefinition& def, const TransformComponent& tileTransform, EntityID tileEntity, PlayerID owner);
|
||||
};
|
||||
|
||||
|
||||
#endif //DICEWARS_SIEDLER_BUILDINGFACTORY_H
|
||||
23
src/game/hexWorld/building/BuildingRules.cpp
Normal file
23
src/game/hexWorld/building/BuildingRules.cpp
Normal file
@ -0,0 +1,23 @@
|
||||
//
|
||||
// Created by sebastian on 13.02.26.
|
||||
//
|
||||
|
||||
#include "BuildingRules.h"
|
||||
#include <algorithm>
|
||||
|
||||
#include "../../../engine/toolbox/util.h"
|
||||
#include "../ecs/components/TileGameplayComponent.h"
|
||||
|
||||
bool BuildingRules::canPlace(const BuildingDefinition &def, const TileGameplayComponent &tile, const GameMode &gameMode,
|
||||
PlayerID playerID) {
|
||||
|
||||
if (tile.hasBuilding()) return false;
|
||||
|
||||
if (!util::contains(def.allowedTileResources, tile.ressourceType)) return false;
|
||||
|
||||
for (auto& [type, costs] : def.resourceCosts) {
|
||||
if (!gameMode.canAfford(playerID, type, costs)) return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
17
src/game/hexWorld/building/BuildingRules.h
Normal file
17
src/game/hexWorld/building/BuildingRules.h
Normal file
@ -0,0 +1,17 @@
|
||||
//
|
||||
// Created by sebastian on 13.02.26.
|
||||
//
|
||||
|
||||
#ifndef DICEWARS_SIEDLER_BUILDINGRULES_H
|
||||
#define DICEWARS_SIEDLER_BUILDINGRULES_H
|
||||
#include "BuildingDefinition.h"
|
||||
#include "../../GameMode.h"
|
||||
|
||||
|
||||
class BuildingRules {
|
||||
public:
|
||||
static bool canPlace(const BuildingDefinition& def, const TileGameplayComponent& tile, const GameMode& gameMode, PlayerID playerID);
|
||||
};
|
||||
|
||||
|
||||
#endif //DICEWARS_SIEDLER_BUILDINGRULES_H
|
||||
@ -0,0 +1,23 @@
|
||||
//
|
||||
// Created by sebastian on 13.02.26.
|
||||
//
|
||||
|
||||
#ifndef DICEWARS_SIEDLER_TEMPORARYBUILDINGDEFINITIONFACTORY_H
|
||||
#define DICEWARS_SIEDLER_TEMPORARYBUILDINGDEFINITIONFACTORY_H
|
||||
#include "BuildingDefinition.h"
|
||||
|
||||
namespace TemporaryBuildingDefinitionFactory {
|
||||
static inline BuildingDefinition createForestHutDefinition() {
|
||||
auto allowedTileResources = std::vector<RessourceType>{RessourceType::WOOD};
|
||||
auto resourceCosts = std::unordered_map<RessourceType, int>{};
|
||||
resourceCosts[RessourceType::WOOD] = 10;
|
||||
return {
|
||||
BuildingType::FOREST_HUT,
|
||||
allowedTileResources,
|
||||
resourceCosts,
|
||||
"cabin"
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
#endif //DICEWARS_SIEDLER_TEMPORARYBUILDINGDEFINITIONFACTORY_H
|
||||
@ -11,6 +11,9 @@
|
||||
#include "../../../../engine/core/ECS/TransformComponent.h"
|
||||
#include "../../../../engine/platform/glfw/InputManager.h"
|
||||
#include "../../../../engine/renderer/model/AssetManager.h"
|
||||
#include "../../building/BuildingConfig.h"
|
||||
#include "../../building/BuildingFactory.h"
|
||||
#include "../../building/BuildingRules.h"
|
||||
#include "../components/BuildingComponent.h"
|
||||
#include "../components/TileGameplayComponent.h"
|
||||
#include "GLFW/glfw3.h"
|
||||
@ -21,28 +24,26 @@ void BuildingPlacementSystem::update(EntityManager& entityManager, GameMode& gam
|
||||
}
|
||||
|
||||
for (EntityID entityID : entityManager.getAllEntities()) {
|
||||
auto transformComponent = entityManager.getComponent<TransformComponent>(entityID);
|
||||
auto tileGameplayComponent = entityManager.getComponent<TileGameplayComponent>(entityID);
|
||||
auto tileRenderComponent = entityManager.getComponent<TileRenderComponent>(entityID);
|
||||
auto transform = entityManager.getComponent<TransformComponent>(entityID);
|
||||
auto gameplay = entityManager.getComponent<TileGameplayComponent>(entityID);
|
||||
auto render = entityManager.getComponent<TileRenderComponent>(entityID);
|
||||
|
||||
if (!transformComponent || !tileGameplayComponent || !tileRenderComponent) continue;
|
||||
if (!transform || !gameplay || !render) continue;
|
||||
if (!render->isHighlighted) continue;
|
||||
|
||||
// Tile is not in focus or tile has already a building
|
||||
if (!tileRenderComponent->isHighlighted || tileGameplayComponent->hasBuilding()) continue;
|
||||
const auto &def = BuildingConfig::get(BuildingType::FOREST_HUT);
|
||||
|
||||
if (!gameMode.canBuild(player, BuildingType::FOREST_HUT)) continue;
|
||||
if (!BuildingRules::canPlace(def, *gameplay, gameMode, player)) continue;
|
||||
|
||||
gameMode.build(player, entityID, BuildingType::FOREST_HUT);
|
||||
for (auto oldID : tileGameplayComponent->entitiesOnTile) {
|
||||
entityManager.destroyEntity(oldID);
|
||||
gameMode.pay(player, def.resourceCosts);
|
||||
|
||||
for (auto e : gameplay->entitiesOnTile) {
|
||||
entityManager.destroyEntity(e);
|
||||
}
|
||||
tileGameplayComponent->entitiesOnTile.clear();
|
||||
gameplay->entitiesOnTile.clear();
|
||||
|
||||
EntityID buildingEntity = entityManager.createEntity();
|
||||
entityManager.addComponent(buildingEntity, std::make_shared<ModelComponent>(AssetManager::getModel("cabin")));
|
||||
entityManager.addComponent(buildingEntity, std::make_shared<TransformComponent>(transformComponent->position, glm::vec3(0), 1.f));
|
||||
entityManager.addComponent(buildingEntity, std::make_shared<BuildingComponent>(BuildingType::FOREST_HUT, entityID));
|
||||
entityManager.addComponent(buildingEntity, std::make_shared<OwnerComponent>(player));
|
||||
tileGameplayComponent->buildingEntityID = buildingEntity;
|
||||
}
|
||||
const EntityID buildingEntity = BuildingFactory::create(entityManager, def, *transform, entityID, player);
|
||||
gameplay->buildingEntityID = buildingEntity;
|
||||
break;
|
||||
}
|
||||
};
|
||||
|
||||
Loading…
Reference in New Issue
Block a user