ADD: Upgrade buildings
This commit is contained in:
parent
a582ddc519
commit
398414a43d
@ -248,6 +248,12 @@ add_executable(Dicewars_Siedler src/main.cpp
|
|||||||
src/game/ui/components/buildingMenu/UiBuildingMenuCostContainer.h
|
src/game/ui/components/buildingMenu/UiBuildingMenuCostContainer.h
|
||||||
src/game/hexWorld/events/BuildingTypeSelectEvent.cpp
|
src/game/hexWorld/events/BuildingTypeSelectEvent.cpp
|
||||||
src/game/hexWorld/events/BuildingTypeSelectEvent.h
|
src/game/hexWorld/events/BuildingTypeSelectEvent.h
|
||||||
|
src/game/hexWorld/ecs/components/UpgradeComponent.cpp
|
||||||
|
src/game/hexWorld/ecs/components/UpgradeComponent.h
|
||||||
|
src/game/hexWorld/ecs/systems/UpgradeSystem.cpp
|
||||||
|
src/game/hexWorld/ecs/systems/UpgradeSystem.h
|
||||||
|
src/game/hexWorld/ecs/systems/SelectionSystem.cpp
|
||||||
|
src/game/hexWorld/ecs/systems/SelectionSystem.h
|
||||||
)
|
)
|
||||||
|
|
||||||
target_compile_options(Dicewars_Siedler PRIVATE
|
target_compile_options(Dicewars_Siedler PRIVATE
|
||||||
|
|||||||
@ -6,23 +6,16 @@
|
|||||||
{
|
{
|
||||||
"name": "cabin-base",
|
"name": "cabin-base",
|
||||||
"filename": "cabin.obj",
|
"filename": "cabin.obj",
|
||||||
"conditionKey": "fillRatio",
|
"conditionKey": "level",
|
||||||
"minValue": 0.0,
|
"minValue": 1,
|
||||||
"maxValue": 0.1
|
"maxValue": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "cabin-one",
|
"name": "cabin-level2",
|
||||||
"filename": "cabin_1.obj",
|
"filename": "cabin2.obj",
|
||||||
"conditionKey": "fillRatio",
|
"conditionKey": "level",
|
||||||
"minValue": 0.1,
|
"minValue": 2,
|
||||||
"maxValue": 0.2
|
"maxValue": 2
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "cabin-two",
|
|
||||||
"filename": "cabin_2.obj",
|
|
||||||
"conditionKey": "fillRatio",
|
|
||||||
"minValue": 0.2,
|
|
||||||
"maxValue": 1.0
|
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
12
assets/buildings/forest_hut/cabin2.mtl
Normal file
12
assets/buildings/forest_hut/cabin2.mtl
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
# Blender 5.0.1 MTL File: 'None'
|
||||||
|
# www.blender.org
|
||||||
|
|
||||||
|
newmtl Material.001
|
||||||
|
Ns 250.000000
|
||||||
|
Ka 1.000000 1.000000 1.000000
|
||||||
|
Ks 0.500000 0.500000 0.500000
|
||||||
|
Ke 0.000000 0.000000 0.000000
|
||||||
|
Ni 1.500000
|
||||||
|
d 1.000000
|
||||||
|
illum 2
|
||||||
|
map_Kd cabin.jpg
|
||||||
150935
assets/buildings/forest_hut/cabin2.obj
Normal file
150935
assets/buildings/forest_hut/cabin2.obj
Normal file
File diff suppressed because it is too large
Load Diff
BIN
assets/buildings/forest_hut/level2/cabin.jpg
Normal file
BIN
assets/buildings/forest_hut/level2/cabin.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 2.8 MiB |
14
assets/buildings/forest_hut/level2/cabin.json
Normal file
14
assets/buildings/forest_hut/level2/cabin.json
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
{
|
||||||
|
"name": "cabin2",
|
||||||
|
"allowedTileResources" : ["stone"],
|
||||||
|
"cost" : {"wood": 15},
|
||||||
|
"modelStages": [
|
||||||
|
{
|
||||||
|
"name": "cabin2-base",
|
||||||
|
"filename": "cabin2.obj",
|
||||||
|
"conditionKey": "fillRatio",
|
||||||
|
"minValue": 0.0,
|
||||||
|
"maxValue": 0.1
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
12
assets/buildings/forest_hut/level2/cabin2.mtl
Normal file
12
assets/buildings/forest_hut/level2/cabin2.mtl
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
# Blender 5.0.1 MTL File: 'None'
|
||||||
|
# www.blender.org
|
||||||
|
|
||||||
|
newmtl Material.001
|
||||||
|
Ns 250.000000
|
||||||
|
Ka 1.000000 1.000000 1.000000
|
||||||
|
Ks 0.500000 0.500000 0.500000
|
||||||
|
Ke 0.000000 0.000000 0.000000
|
||||||
|
Ni 1.500000
|
||||||
|
d 1.000000
|
||||||
|
illum 2
|
||||||
|
map_Kd cabin.jpg
|
||||||
150935
assets/buildings/forest_hut/level2/cabin2.obj
Normal file
150935
assets/buildings/forest_hut/level2/cabin2.obj
Normal file
File diff suppressed because it is too large
Load Diff
@ -52,6 +52,14 @@ public:
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
void removeComponent(EntityID entity) {
|
||||||
|
auto it = components.find(typeid(T));
|
||||||
|
if (it != components.end()) {
|
||||||
|
it->second.erase(entity);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const std::vector<EntityID>& getAllEntities() const { return entities; }
|
const std::vector<EntityID>& getAllEntities() const { return entities; }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -7,6 +7,7 @@
|
|||||||
#include <cassert>
|
#include <cassert>
|
||||||
#include <filesystem>
|
#include <filesystem>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
|
#include <iostream>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
|
||||||
#include "json.hpp"
|
#include "json.hpp"
|
||||||
|
|||||||
@ -25,6 +25,8 @@
|
|||||||
#include "hexWorld/ecs/components/ProducingComponent.h"
|
#include "hexWorld/ecs/components/ProducingComponent.h"
|
||||||
#include "hexWorld/ecs/systems/CollectResourceSystem.h"
|
#include "hexWorld/ecs/systems/CollectResourceSystem.h"
|
||||||
#include "hexWorld/ecs/systems/ProducingSystem.h"
|
#include "hexWorld/ecs/systems/ProducingSystem.h"
|
||||||
|
#include "hexWorld/ecs/systems/SelectionSystem.h"
|
||||||
|
#include "hexWorld/ecs/systems/UpgradeSystem.h"
|
||||||
#include "hexWorld/events/BuildingTypeSelectEvent.h"
|
#include "hexWorld/events/BuildingTypeSelectEvent.h"
|
||||||
#include "hexWorld/events/TurnChangedEvent.h"
|
#include "hexWorld/events/TurnChangedEvent.h"
|
||||||
|
|
||||||
@ -60,6 +62,7 @@ void GameLayer::onAttach()
|
|||||||
|
|
||||||
AssetManager::loadAsset("assets/buildings/stone_mason/stone_mason.json", loader);
|
AssetManager::loadAsset("assets/buildings/stone_mason/stone_mason.json", loader);
|
||||||
AssetManager::loadAsset("assets/buildings/forest_hut/cabin.json", loader);
|
AssetManager::loadAsset("assets/buildings/forest_hut/cabin.json", loader);
|
||||||
|
AssetManager::loadAsset("assets/buildings/forest_hut/level2/cabin.json", loader);
|
||||||
|
|
||||||
auto modelTexture = AssetManager::loadTexture("warning", "assets/worldIcons/warning.png", loader);
|
auto modelTexture = AssetManager::loadTexture("warning", "assets/worldIcons/warning.png", loader);
|
||||||
AssetManager::loadTexture("error", "assets/worldIcons/error.png", loader);
|
AssetManager::loadTexture("error", "assets/worldIcons/error.png", loader);
|
||||||
@ -111,6 +114,8 @@ void GameLayer::onUpdate()
|
|||||||
camera->move(moveDir, 0.5f);
|
camera->move(moveDir, 0.5f);
|
||||||
if (gameInputUser->isMouseEnabled()) {
|
if (gameInputUser->isMouseEnabled()) {
|
||||||
tileHighlightSystem->update(*entityManager, *mousePicker, *camera, *gameMode);
|
tileHighlightSystem->update(*entityManager, *mousePicker, *camera, *gameMode);
|
||||||
|
SelectionSystem::update(*entityManager, *gameInputUser, *mousePicker);
|
||||||
|
UpgradeSystem::tryUpdate(*entityManager, *gameMode, gameMode->getCurrentPlayer(), *turnState);
|
||||||
} else {
|
} else {
|
||||||
tileHighlightSystem->reset(*entityManager);
|
tileHighlightSystem->reset(*entityManager);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -6,6 +6,14 @@
|
|||||||
#define DICEWARS_SIEDLER_BUILDINGDEFINITION_H
|
#define DICEWARS_SIEDLER_BUILDINGDEFINITION_H
|
||||||
#include "../ecs/components/BuildingComponent.h"
|
#include "../ecs/components/BuildingComponent.h"
|
||||||
|
|
||||||
|
struct BuildingLevelData {
|
||||||
|
float productionMultiplier;
|
||||||
|
int workforce;
|
||||||
|
int maxStorageBonus;
|
||||||
|
|
||||||
|
std::unordered_map<RessourceType, int> upgradeCosts;
|
||||||
|
};
|
||||||
|
|
||||||
struct BuildingDefinition {
|
struct BuildingDefinition {
|
||||||
BuildingType type;
|
BuildingType type;
|
||||||
|
|
||||||
@ -18,6 +26,8 @@ struct BuildingDefinition {
|
|||||||
int baseAmountPerTurn;
|
int baseAmountPerTurn;
|
||||||
|
|
||||||
RessourceType produces;
|
RessourceType produces;
|
||||||
|
|
||||||
|
std::vector<BuildingLevelData> levels;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif //DICEWARS_SIEDLER_BUILDINGDEFINITION_H
|
#endif //DICEWARS_SIEDLER_BUILDINGDEFINITION_H
|
||||||
@ -11,12 +11,18 @@ namespace TemporaryBuildingDefinitionFactory {
|
|||||||
auto allowedTileResources = std::vector<RessourceType>{RessourceType::WOOD};
|
auto allowedTileResources = std::vector<RessourceType>{RessourceType::WOOD};
|
||||||
auto resourceCosts = std::unordered_map<RessourceType, int>{};
|
auto resourceCosts = std::unordered_map<RessourceType, int>{};
|
||||||
resourceCosts[RessourceType::WOOD] = 10;
|
resourceCosts[RessourceType::WOOD] = 10;
|
||||||
|
std::vector<BuildingLevelData> levels = {};
|
||||||
|
auto upgradeCosts = std::unordered_map<RessourceType, int>{};
|
||||||
|
upgradeCosts[RessourceType::WOOD] = 15;
|
||||||
|
levels.push_back({
|
||||||
|
1.2, 3, 5, upgradeCosts
|
||||||
|
});
|
||||||
return {
|
return {
|
||||||
BuildingType::FOREST_HUT,
|
BuildingType::FOREST_HUT,
|
||||||
allowedTileResources,
|
allowedTileResources,
|
||||||
resourceCosts,
|
resourceCosts,
|
||||||
"cabin",
|
"cabin",
|
||||||
20, 1, RessourceType::WOOD
|
20, 1, RessourceType::WOOD, levels
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -25,12 +31,14 @@ namespace TemporaryBuildingDefinitionFactory {
|
|||||||
auto resourceCosts = std::unordered_map<RessourceType, int>{};
|
auto resourceCosts = std::unordered_map<RessourceType, int>{};
|
||||||
resourceCosts[RessourceType::WOOD] = 15;
|
resourceCosts[RessourceType::WOOD] = 15;
|
||||||
resourceCosts[RessourceType::STONE] = 10;
|
resourceCosts[RessourceType::STONE] = 10;
|
||||||
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
BuildingType::FOREST_HUT,
|
BuildingType::FOREST_HUT,
|
||||||
allowedTileResources,
|
allowedTileResources,
|
||||||
resourceCosts,
|
resourceCosts,
|
||||||
"stoneMason",
|
"stoneMason",
|
||||||
20, 1, RessourceType::STONE
|
20, 1, RessourceType::STONE,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
7
src/game/hexWorld/ecs/components/UpgradeComponent.cpp
Normal file
7
src/game/hexWorld/ecs/components/UpgradeComponent.cpp
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
//
|
||||||
|
// Created by sebastian on 20.02.26.
|
||||||
|
//
|
||||||
|
|
||||||
|
#include "UpgradeComponent.h"
|
||||||
|
|
||||||
|
void UpgradeComponent::setMaxLevel(int maxLevel) {this->maxLevel = maxLevel;}
|
||||||
29
src/game/hexWorld/ecs/components/UpgradeComponent.h
Normal file
29
src/game/hexWorld/ecs/components/UpgradeComponent.h
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
//
|
||||||
|
// Created by sebastian on 20.02.26.
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef DICEWARS_SIEDLER_UPGRADECOMPONENT_H
|
||||||
|
#define DICEWARS_SIEDLER_UPGRADECOMPONENT_H
|
||||||
|
#include "../../../../engine/core/ECS/Component.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
class UpgradeComponent : public Component {
|
||||||
|
public:
|
||||||
|
UpgradeComponent(int currentLevel = 1, int maxLevel = 1): currentLevel(currentLevel), maxLevel(maxLevel) {}
|
||||||
|
|
||||||
|
[[nodiscard]] int getCurrentLevel() const {return currentLevel;}
|
||||||
|
[[nodiscard]] int getMaxLevel() const {return maxLevel;}
|
||||||
|
|
||||||
|
[[nodiscard]] bool canUpgrade() const {return currentLevel < maxLevel;}
|
||||||
|
void upgrade() {currentLevel++;}
|
||||||
|
void setMaxLevel(int maxLevel);
|
||||||
|
|
||||||
|
public:
|
||||||
|
private:
|
||||||
|
int currentLevel = 1;
|
||||||
|
int maxLevel = 1;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#endif //DICEWARS_SIEDLER_UPGRADECOMPONENT_H
|
||||||
@ -17,6 +17,7 @@
|
|||||||
#include "../../gameplay/TurnState.h"
|
#include "../../gameplay/TurnState.h"
|
||||||
#include "../components/BuildingComponent.h"
|
#include "../components/BuildingComponent.h"
|
||||||
#include "../components/TileGameplayComponent.h"
|
#include "../components/TileGameplayComponent.h"
|
||||||
|
#include "../components/UpgradeComponent.h"
|
||||||
#include "GLFW/glfw3.h"
|
#include "GLFW/glfw3.h"
|
||||||
|
|
||||||
void BuildingPlacementSystem::update(EntityManager& entityManager, GameMode& gameMode, PlayerID player, const TurnState& turnState) {
|
void BuildingPlacementSystem::update(EntityManager& entityManager, GameMode& gameMode, PlayerID player, const TurnState& turnState) {
|
||||||
@ -58,6 +59,12 @@ void BuildingPlacementSystem::update(EntityManager& entityManager, GameMode& gam
|
|||||||
|
|
||||||
const EntityID buildingEntity = BuildingFactory::create(entityManager, def, *transform, entityID, player);
|
const EntityID buildingEntity = BuildingFactory::create(entityManager, def, *transform, entityID, player);
|
||||||
gameplay->buildingEntityID = buildingEntity;
|
gameplay->buildingEntityID = buildingEntity;
|
||||||
|
|
||||||
|
if (!def.levels.empty()) {
|
||||||
|
std::cerr << "Adding upgrade component" << std::endl;
|
||||||
|
UpgradeComponent upgrade_component = UpgradeComponent(1, static_cast<int>(def.levels.size() + 1));
|
||||||
|
entityManager.addComponent(buildingEntity, std::make_shared<UpgradeComponent>(upgrade_component));
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@ -21,39 +21,11 @@ std::vector<StorageStatus> ProducingSystem::storageIcons = {
|
|||||||
|
|
||||||
void ProducingSystem::onTurnEnded(EntityManager &em) {
|
void ProducingSystem::onTurnEnded(EntityManager &em) {
|
||||||
for (const EntityID e : em.getAllEntities()) {
|
for (const EntityID e : em.getAllEntities()) {
|
||||||
const auto prod = em.getComponent<ProducingComponent>(e);
|
if (!isValidProducer(em, e)) continue;
|
||||||
const auto modelState = em.getComponent<ModelStateComponent>(e);
|
|
||||||
|
|
||||||
if (!prod || !modelState) {
|
handleProduction(em, e);
|
||||||
continue;
|
updateFillRatio(em, e);
|
||||||
}
|
updateStorageIcon(em, e);
|
||||||
|
|
||||||
if (prod->isBlocked()) {
|
|
||||||
std::cout << "Producing is blocked for entity " << e << std::endl;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
const int produced = prod->getAmountPerTurn();
|
|
||||||
prod->setStorage(std::min(prod->getStorage() + produced, prod->getMaxStorage()));
|
|
||||||
|
|
||||||
float fillRatio = static_cast<float>(prod->getStorage()) / static_cast<float>(prod->getMaxStorage());
|
|
||||||
modelState->params["fillRatio"] = fillRatio;
|
|
||||||
|
|
||||||
// -- Icon / Animation Logik
|
|
||||||
for (const auto& status : storageIcons) {
|
|
||||||
if (fillRatio >= status.minRatio && fillRatio <= status.maxRatio) {
|
|
||||||
auto spriteComp = em.getComponent<WorldSpriteComponent>(e);
|
|
||||||
if (spriteComp) {
|
|
||||||
if (spriteComp->iconName != status.iconName) {
|
|
||||||
spriteComp->iconName = status.iconName;
|
|
||||||
spriteComp->texture = AssetManager::getTexture(status.iconName);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
createWorldSprite(em, e, status.iconName);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -86,3 +58,48 @@ void ProducingSystem::createWorldSprite(EntityManager &em, EntityID e, const std
|
|||||||
em.addComponent(e, anim);
|
em.addComponent(e, anim);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool ProducingSystem::isValidProducer(EntityManager &em, EntityID e) {
|
||||||
|
const auto prod = em.getComponent<ProducingComponent>(e);
|
||||||
|
const auto modelState = em.getComponent<ModelStateComponent>(e);
|
||||||
|
|
||||||
|
return prod && modelState && !prod->isBlocked();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ProducingSystem::handleProduction(EntityManager &em, EntityID e) {
|
||||||
|
auto prod = em.getComponent<ProducingComponent>(e);
|
||||||
|
|
||||||
|
const int produced = prod->getAmountPerTurn();
|
||||||
|
prod->setStorage(std::min(prod->getStorage() + produced, prod->getMaxStorage()));
|
||||||
|
}
|
||||||
|
|
||||||
|
void ProducingSystem::updateFillRatio(EntityManager &em, EntityID e) {
|
||||||
|
const auto prod = em.getComponent<ProducingComponent>(e);
|
||||||
|
const auto modelState = em.getComponent<ModelStateComponent>(e);
|
||||||
|
|
||||||
|
float fillRatio = static_cast<float>(prod->getStorage()) / static_cast<float>(prod->getMaxStorage());
|
||||||
|
modelState->params["fillRatio"] = fillRatio;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ProducingSystem::updateStorageIcon(EntityManager &em, EntityID e) {
|
||||||
|
const auto prod = em.getComponent<ProducingComponent>(e);
|
||||||
|
float fillRatio = static_cast<float>(prod->getStorage()) / static_cast<float>(prod->getMaxStorage());
|
||||||
|
|
||||||
|
for (const auto& status : storageIcons) {
|
||||||
|
if (fillRatio >= status.minRatio && fillRatio <= status.maxRatio) {
|
||||||
|
applyIcon(em, e, status.iconName);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ProducingSystem::applyIcon(EntityManager &em, EntityID e, const std::string &iconName) {
|
||||||
|
if (const auto spriteComp = em.getComponent<WorldSpriteComponent>(e)) {
|
||||||
|
if (spriteComp->iconName != iconName) {
|
||||||
|
spriteComp->iconName = iconName;
|
||||||
|
spriteComp->texture = AssetManager::getTexture(iconName);
|
||||||
|
} else {
|
||||||
|
createWorldSprite(em, e, iconName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@ -6,6 +6,7 @@
|
|||||||
#define DICEWARS_SIEDLER_PRODUCINGSYSTEM_H
|
#define DICEWARS_SIEDLER_PRODUCINGSYSTEM_H
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
#include "../../../../engine/core/ECS/EntityManager.h"
|
||||||
#include "../../../../engine/core/ECS/WorldSpriteComponent.h"
|
#include "../../../../engine/core/ECS/WorldSpriteComponent.h"
|
||||||
#include "../../../player/Player.h"
|
#include "../../../player/Player.h"
|
||||||
|
|
||||||
@ -25,6 +26,13 @@ private:
|
|||||||
static std::vector<StorageStatus> storageIcons;
|
static std::vector<StorageStatus> storageIcons;
|
||||||
|
|
||||||
static void createWorldSprite(EntityManager &em, uint32_t e, const std::string &iconName);
|
static void createWorldSprite(EntityManager &em, uint32_t e, const std::string &iconName);
|
||||||
|
|
||||||
|
static bool isValidProducer(EntityManager &em, EntityID e);
|
||||||
|
static void handleProduction(EntityManager &em, EntityID e);
|
||||||
|
static void updateFillRatio(EntityManager &em, EntityID e);
|
||||||
|
static void updateStorageIcon(EntityManager &em, EntityID e);
|
||||||
|
static void applyIcon(EntityManager &em, EntityID e, const std::string &iconName);
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
38
src/game/hexWorld/ecs/systems/SelectionSystem.cpp
Normal file
38
src/game/hexWorld/ecs/systems/SelectionSystem.cpp
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
//
|
||||||
|
// Created by sebastian on 20.02.26.
|
||||||
|
//
|
||||||
|
|
||||||
|
#include "SelectionSystem.h"
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
#include <ostream>
|
||||||
|
|
||||||
|
#include "../../../../engine/core/ECS/TileRenderComponent.h"
|
||||||
|
#include "../components/TileGameplayComponent.h"
|
||||||
|
|
||||||
|
EntityID SelectionSystem::selectedEntity = 0;
|
||||||
|
|
||||||
|
void SelectionSystem::update(EntityManager &em, GameInputUser& input, MousePicker& picker) {
|
||||||
|
//Todo: Move Logic to select tile to highlight here?
|
||||||
|
if (!input.isMouseEnabled()) return;
|
||||||
|
|
||||||
|
if (!Application::getInstance().mouse->isButtonDown(MouseButton::LEFT)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (EntityID e : em.getAllEntities()) {
|
||||||
|
const auto tileRenderComponent = em.getComponent<TileRenderComponent>(e);
|
||||||
|
const auto gameplayComponent = em.getComponent<TileGameplayComponent>(e);
|
||||||
|
|
||||||
|
if (tileRenderComponent && gameplayComponent && tileRenderComponent->isHighlighted) {
|
||||||
|
//Todo: Store focused Entity in TileHighlightSystem and fetch it?
|
||||||
|
selectedEntity = e;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Application::getInstance().mouse->isReleaseEvent(MouseButton::LEFT)) {
|
||||||
|
selectedEntity = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
20
src/game/hexWorld/ecs/systems/SelectionSystem.h
Normal file
20
src/game/hexWorld/ecs/systems/SelectionSystem.h
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
//
|
||||||
|
// Created by sebastian on 20.02.26.
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef DICEWARS_SIEDLER_SELECTIONSYSTEM_H
|
||||||
|
#define DICEWARS_SIEDLER_SELECTIONSYSTEM_H
|
||||||
|
#include "../../../../engine/core/inputsOutputs/stateControl/inputUser/GameInputUser.h"
|
||||||
|
|
||||||
|
|
||||||
|
class EntityManager;
|
||||||
|
|
||||||
|
class SelectionSystem {
|
||||||
|
public:
|
||||||
|
static EntityID selectedEntity;
|
||||||
|
public:
|
||||||
|
static void update(EntityManager& em, GameInputUser& input, MousePicker& picker);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#endif //DICEWARS_SIEDLER_SELECTIONSYSTEM_H
|
||||||
80
src/game/hexWorld/ecs/systems/UpgradeSystem.cpp
Normal file
80
src/game/hexWorld/ecs/systems/UpgradeSystem.cpp
Normal file
@ -0,0 +1,80 @@
|
|||||||
|
//
|
||||||
|
// Created by sebastian on 20.02.26.
|
||||||
|
//
|
||||||
|
|
||||||
|
#include "UpgradeSystem.h"
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
#include <ostream>
|
||||||
|
|
||||||
|
#include "SelectionSystem.h"
|
||||||
|
#include "../../building/BuildingConfig.h"
|
||||||
|
#include "../components/UpgradeComponent.h"
|
||||||
|
#include "../components/BuildingComponent.h"
|
||||||
|
#include "../components/ProducingComponent.h"
|
||||||
|
#include "../../../../engine/core/ECS/TileRenderComponent.h"
|
||||||
|
#include "../../../../engine/core/ECS/ModelComponent.h"
|
||||||
|
#include "../../../../engine/core/ECS/ModelStateComponent.h"
|
||||||
|
#include "../components/TileGameplayComponent.h"
|
||||||
|
|
||||||
|
void UpgradeSystem::tryUpdate(EntityManager &em, GameMode &gm, PlayerID player, const TurnState &turnState) {
|
||||||
|
EntityID tileEntityID = SelectionSystem::selectedEntity;
|
||||||
|
|
||||||
|
auto tileComponent = em.getComponent<TileGameplayComponent>(tileEntityID);
|
||||||
|
if (!tileComponent || !tileComponent->hasBuilding()) return;
|
||||||
|
|
||||||
|
EntityID entityID = tileComponent->buildingEntityID;
|
||||||
|
auto buildingComponent = em.getComponent<BuildingComponent>(entityID);
|
||||||
|
auto tileHighlightComponent = em.getComponent<TileRenderComponent>(tileEntityID);
|
||||||
|
auto modelComponent = em.getComponent<ModelStateComponent>(entityID);
|
||||||
|
|
||||||
|
|
||||||
|
if (buildingComponent && tileHighlightComponent && tileHighlightComponent->isHighlighted && modelComponent) {
|
||||||
|
UpgradeResult result = canUpgrade(em, player, gm, entityID, turnState);
|
||||||
|
|
||||||
|
if (result != UpgradeResult::Ok) return;
|
||||||
|
|
||||||
|
auto tier = em.getComponent<UpgradeComponent>(entityID);
|
||||||
|
auto building = em.getComponent<BuildingComponent>(entityID);
|
||||||
|
auto prod = em.getComponent<ProducingComponent>(entityID);
|
||||||
|
|
||||||
|
const auto& def = BuildingConfig::get(building->type);
|
||||||
|
const BuildingLevelData& nextTierData = def.levels.at(tier->getCurrentLevel() -1);
|
||||||
|
|
||||||
|
gm.pay(player, nextTierData.upgradeCosts);
|
||||||
|
|
||||||
|
tier->upgrade();
|
||||||
|
prod->setMaxStorage(def.maxStorage + nextTierData.maxStorageBonus);
|
||||||
|
//Todo: Workforce
|
||||||
|
|
||||||
|
//Todo: Change Model Component
|
||||||
|
modelComponent->params["level"] = 2.f;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
UpgradeResult UpgradeSystem::canUpgrade(EntityManager &em, PlayerID player, GameMode& gameMode, EntityID buildingEntity, const TurnState &turnState) {
|
||||||
|
if (!gameMode.hasTurn(player, turnState.currentTurn)) return UpgradeResult::NotPlayersTurn;
|
||||||
|
|
||||||
|
auto tier = em.getComponent<UpgradeComponent>(buildingEntity);
|
||||||
|
auto type = em.getComponent<BuildingComponent>(buildingEntity);
|
||||||
|
|
||||||
|
if (!tier) return UpgradeResult::NoTierComponent;
|
||||||
|
if (!type) return UpgradeResult::InvalidTarget;
|
||||||
|
|
||||||
|
const auto& def = BuildingConfig::get(BuildingType::FOREST_HUT);
|
||||||
|
|
||||||
|
int nextTier = tier->getCurrentLevel() -1;
|
||||||
|
if (nextTier > static_cast<int>(def.levels.size()+1)) return UpgradeResult::MaxTierReached;
|
||||||
|
|
||||||
|
if (!tier->canUpgrade()) return UpgradeResult::ResearchLocked; // maybe move check to special research system
|
||||||
|
|
||||||
|
const BuildingLevelData& nextTierData = def.levels.at(tier->getCurrentLevel() -1);
|
||||||
|
for (const auto& [resource, cost] : def.levels.at(nextTier).upgradeCosts) {
|
||||||
|
if (!gameMode.canAfford(player, resource, cost)) return UpgradeResult::NotEnoughResources;
|
||||||
|
}
|
||||||
|
|
||||||
|
return UpgradeResult::Ok;
|
||||||
|
}
|
||||||
29
src/game/hexWorld/ecs/systems/UpgradeSystem.h
Normal file
29
src/game/hexWorld/ecs/systems/UpgradeSystem.h
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
//
|
||||||
|
// Created by sebastian on 20.02.26.
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef DICEWARS_SIEDLER_UPGRADESYSTEM_H
|
||||||
|
#define DICEWARS_SIEDLER_UPGRADESYSTEM_H
|
||||||
|
#include "../../../GameMode.h"
|
||||||
|
#include "../../gameplay/TurnState.h"
|
||||||
|
enum class UpgradeResult {
|
||||||
|
Ok,
|
||||||
|
NotPlayersTurn,
|
||||||
|
NoTierComponent,
|
||||||
|
MaxTierReached,
|
||||||
|
ResearchLocked,
|
||||||
|
NotEnoughResources,
|
||||||
|
InvalidTarget
|
||||||
|
};
|
||||||
|
|
||||||
|
class EntityManager;
|
||||||
|
|
||||||
|
class UpgradeSystem {
|
||||||
|
public:
|
||||||
|
static void tryUpdate(EntityManager &em, GameMode &gm, PlayerID player, const TurnState &turnState);
|
||||||
|
|
||||||
|
static UpgradeResult canUpgrade(EntityManager &em, PlayerID player, GameMode &gameMode, EntityID buildingEntity, const TurnState &turnState);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#endif //DICEWARS_SIEDLER_UPGRADESYSTEM_H
|
||||||
Loading…
Reference in New Issue
Block a user