ADD: GameMode and PlayerInventory

This commit is contained in:
sebastian 2026-02-08 20:05:48 +01:00
parent 8e2024e5dc
commit 0f9655b742
16 changed files with 233 additions and 22 deletions

View File

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

View File

@ -9,6 +9,8 @@
#include <unordered_map>
#include <vector>
#include "../../../game/hexWorld/ecs/components/OwnerComponent.h"
class BuildingComponent;
// Forward Declarations (KEINE includes hier!)
class TransformComponent;
@ -30,6 +32,7 @@ private:
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<BuildingComponent>> buildings;
std::unordered_map<EntityID, std::shared_ptr<OwnerComponent>> owners;
public:
EntityID createEntity();
@ -49,6 +52,8 @@ public:
mapEntityComponents[entity] = component;
} else if constexpr (std::is_same_v<T, BuildingComponent>) {
buildings[entity] = component;
} else if constexpr (std::is_same_v<T, OwnerComponent>) {
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<T, BuildingComponent>) {
auto it = buildings.find(entity);
return (it != buildings.end()) ? it->second : nullptr;
} else if constexpr (std::is_same_v<T, OwnerComponent>) {
auto it = owners.find(entity);
return (it != owners.end()) ? it->second : nullptr;
} else {
static_assert(sizeof(T) == 0, "Component-Typ nicht unterstützt");
}

View File

@ -7,5 +7,8 @@
#include "GameLayer.h"
DicewarsApp::DicewarsApp() {
pushLayer(new GameLayer());
gameMode = std::make_shared<GameMode>();
GameLayer* gamelayer = new GameLayer();
gamelayer->setGameMode(gameMode);
pushLayer(gamelayer);
}

View File

@ -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> gameMode;
public:
DicewarsApp();
};

View File

@ -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> gameMode) {
this->gameMode = gameMode;
}

View File

@ -26,7 +26,11 @@ public:
void onDetach() override;
void onUpdate() override;
void setGameMode(std::shared_ptr<GameMode> gameMode);
private:
std::shared_ptr<GameMode> gameMode;
Loader loader;
TexturedModel texturedModel;
std::unique_ptr<Camera> camera;

38
src/game/GameMode.cpp Normal file
View File

@ -0,0 +1,38 @@
//
// Created by sebastian on 08.02.26.
//
#include "GameMode.h"
#include <iostream>
#include <bits/ostream.tcc>
#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<PlayerID>(players.size());
players[id] = Player(id, name);
}
PlayerID GameMode::getCurrentPlayer() {
return 0;
}

29
src/game/GameMode.h Normal file
View File

@ -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<PlayerID, Player> players;
};
#endif //GAMEMODE_H

View File

@ -0,0 +1,22 @@
//
// Created by sebastian on 08.02.26.
//
#include "PlayerInventory.h"
#include <cstdio>
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;
}

View File

@ -0,0 +1,25 @@
//
// Created by sebastian on 08.02.26.
//
#ifndef PLAYERINVENTORY_H
#define PLAYERINVENTORY_H
#include <unordered_map>
#include "hexWorld/RessourceType.h"
class PlayerInventory {
private:
std::unordered_map<RessourceType, int> resources;
public:
bool hasEnough(RessourceType resourceType, int amount) const;
void spend(RessourceType resourceType, int amount);
void add(RessourceType resourceType, int amount);
};
#endif //PLAYERINVENTORY_H

View File

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

View File

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

View File

@ -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<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);
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);
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<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;
}
}

View File

@ -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);
};

View File

@ -0,0 +1,9 @@
//
// Created by sebastian on 08.02.26.
//
#include "Player.h"
const std::unique_ptr<PlayerInventory> & Player::getInventory() const {
return inventory;
}

33
src/game/player/Player.h Normal file
View File

@ -0,0 +1,33 @@
//
// Created by sebastian on 08.02.26.
//
#ifndef PLAYER_H
#define PLAYER_H
#include <cstdint>
#include <memory>
#include <string>
#include "../PlayerInventory.h"
using PlayerID = std::uint32_t;
class Player {
private:
PlayerID playerID;
std::string name;
std::unique_ptr<PlayerInventory> inventory = std::make_unique<PlayerInventory>();
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<PlayerInventory> &getInventory() const;
};
#endif //PLAYER_H