Proper build UI
This commit is contained in:
@@ -13,6 +13,9 @@ bool canPlaceBuilding(Game *game, BuildingType type, BzTile tileX, BzTile tileY)
|
|||||||
getBuildingSize(type, &sizeX, &sizeY);
|
getBuildingSize(type, &sizeX, &sizeY);
|
||||||
if (sizeX == 0 || sizeY == 0) return false;
|
if (sizeX == 0 || sizeY == 0) return false;
|
||||||
|
|
||||||
|
if (!canAffordBuilding(type, game->playerResources[game->player]))
|
||||||
|
return false;
|
||||||
|
|
||||||
BzTileMap *map = &game->map;
|
BzTileMap *map = &game->map;
|
||||||
// Ensure that it is within the map
|
// Ensure that it is within the map
|
||||||
if (tileX < 0 || tileX + sizeX > map->width ||
|
if (tileX < 0 || tileX + sizeX > map->width ||
|
||||||
@@ -92,6 +95,67 @@ ecs_entity_t placeBuilding(Game *game, BuildingType type,
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void getBuildingCost(BuildingType type, i32 cost[RES_COUNT]) {
|
||||||
|
for (i32 i = 0; i < RES_COUNT; i++) {
|
||||||
|
cost[i] = 0;
|
||||||
|
}
|
||||||
|
switch (type) {
|
||||||
|
case BUILDING_ARCHERY_RANGE:
|
||||||
|
cost[RES_WOOD] = 400;
|
||||||
|
cost[RES_FOOD] = 400;
|
||||||
|
cost[RES_GOLD] = 200;
|
||||||
|
break;
|
||||||
|
case BUILDING_BARRACKS:
|
||||||
|
cost[RES_WOOD] = 200;
|
||||||
|
cost[RES_FOOD] = 400;
|
||||||
|
cost[RES_GOLD] = 500;
|
||||||
|
break;
|
||||||
|
case BUILDING_GRANARY:
|
||||||
|
cost[RES_WOOD] = 80;
|
||||||
|
break;
|
||||||
|
case BUILDING_HOUSE_01:
|
||||||
|
case BUILDING_HOUSE_02:
|
||||||
|
case BUILDING_HOUSE_03:
|
||||||
|
case BUILDING_HOUSE_04:
|
||||||
|
case BUILDING_HOUSE_05:
|
||||||
|
case BUILDING_HOUSE_06:
|
||||||
|
case BUILDING_HOUSE_07:
|
||||||
|
case BUILDING_HOUSE_08:
|
||||||
|
case BUILDING_HOUSE_09:
|
||||||
|
case BUILDING_HOUSE_10:
|
||||||
|
case BUILDING_HOUSE_11:
|
||||||
|
case BUILDING_HOUSE_12:
|
||||||
|
cost[RES_WOOD] = 50;
|
||||||
|
break;
|
||||||
|
case BUILDING_MARKET:
|
||||||
|
cost[RES_WOOD] = 200;
|
||||||
|
cost[RES_FOOD] = 200;
|
||||||
|
cost[RES_GOLD] = 200;
|
||||||
|
break;
|
||||||
|
case BUILDING_MILL:
|
||||||
|
cost[RES_WOOD] = 200;
|
||||||
|
cost[RES_GOLD] = 50;
|
||||||
|
break;
|
||||||
|
case BUILDING_WAREHOUSE:
|
||||||
|
cost[RES_WOOD] = 100;
|
||||||
|
break;
|
||||||
|
case BUILDING_NONE:
|
||||||
|
case BUILDING_KEEP:
|
||||||
|
case BUILDING_COUNT:
|
||||||
|
// NA
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
bool canAffordBuilding(BuildingType type, PlayerResources res) {
|
||||||
|
i32 needed[RES_COUNT] = {0, };
|
||||||
|
getBuildingCost(type, needed);
|
||||||
|
|
||||||
|
if (needed[RES_WOOD] > res.wood) return false;
|
||||||
|
if (needed[RES_FOOD] > res.food) return false;
|
||||||
|
if (needed[RES_GOLD] > res.gold) return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
Vector2 getPositionNearBuilding(ecs_entity_t building, Vector2 fromPos) {
|
Vector2 getPositionNearBuilding(ecs_entity_t building, Vector2 fromPos) {
|
||||||
BZ_ASSERT(ecs_is_alive(ECS, building));
|
BZ_ASSERT(ecs_is_alive(ECS, building));
|
||||||
BZ_ASSERT(ecs_has(ECS, building, Position));
|
BZ_ASSERT(ecs_has(ECS, building, Position));
|
||||||
|
|||||||
@@ -7,11 +7,16 @@
|
|||||||
#include "components.h"
|
#include "components.h"
|
||||||
#include "game_tileset.h"
|
#include "game_tileset.h"
|
||||||
|
|
||||||
|
#include "game_state.h"
|
||||||
|
|
||||||
typedef struct Game Game;
|
typedef struct Game Game;
|
||||||
|
|
||||||
bool canPlaceBuilding(Game *game, BuildingType type, i32 tileX, i32 tileY);
|
bool canPlaceBuilding(Game *game, BuildingType type, i32 tileX, i32 tileY);
|
||||||
ecs_entity_t placeBuilding(Game *game, BuildingType type, i32 posX, i32 posY, Owner owner);
|
ecs_entity_t placeBuilding(Game *game, BuildingType type, i32 posX, i32 posY, Owner owner);
|
||||||
|
|
||||||
|
void getBuildingCost(BuildingType type, i32 cost[RES_COUNT]);
|
||||||
|
bool canAffordBuilding(BuildingType type, PlayerResources res);
|
||||||
|
|
||||||
Vector2 getPositionNearBuilding(ecs_entity_t building, Vector2 fromPos);
|
Vector2 getPositionNearBuilding(ecs_entity_t building, Vector2 fromPos);
|
||||||
|
|
||||||
#endif //PIXELDEFENSE_BUILDINGS_H
|
#endif //PIXELDEFENSE_BUILDINGS_H
|
||||||
|
|||||||
@@ -4,6 +4,7 @@
|
|||||||
#include <breeze.h>
|
#include <breeze.h>
|
||||||
#include <flecs.h>
|
#include <flecs.h>
|
||||||
|
|
||||||
|
#include "constants.h"
|
||||||
#include "game_tileset.h"
|
#include "game_tileset.h"
|
||||||
|
|
||||||
// Needed, so we can clean up all game created entities
|
// Needed, so we can clean up all game created entities
|
||||||
@@ -33,12 +34,6 @@ typedef struct Resource {
|
|||||||
} Resource;
|
} Resource;
|
||||||
extern ECS_COMPONENT_DECLARE(Resource);
|
extern ECS_COMPONENT_DECLARE(Resource);
|
||||||
|
|
||||||
typedef enum Player {
|
|
||||||
PLAYER_RED = 0,
|
|
||||||
PLAYER_BLUE = 1,
|
|
||||||
PLAYER_COUNT
|
|
||||||
} Player;
|
|
||||||
|
|
||||||
typedef struct Owner {
|
typedef struct Owner {
|
||||||
Player player;
|
Player player;
|
||||||
} Owner;
|
} Owner;
|
||||||
|
|||||||
@@ -7,4 +7,11 @@ enum {
|
|||||||
COLL_LAYER_TRANSPARENCY = 7,
|
COLL_LAYER_TRANSPARENCY = 7,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
typedef enum Player {
|
||||||
|
PLAYER_RED = 0,
|
||||||
|
PLAYER_BLUE = 1,
|
||||||
|
PLAYER_COUNT
|
||||||
|
} Player;
|
||||||
|
|
||||||
|
|
||||||
#endif //PIXELDEFENSE_CONSTANTS_H
|
#endif //PIXELDEFENSE_CONSTANTS_H
|
||||||
|
|||||||
@@ -42,6 +42,14 @@ static Options getDefaultOptions() {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
typedef struct PlayerResources {
|
||||||
|
i64 wood;
|
||||||
|
i64 food;
|
||||||
|
i64 gold;
|
||||||
|
i64 pop;
|
||||||
|
i64 popCapacity;
|
||||||
|
} PlayerResources;
|
||||||
|
|
||||||
typedef struct Game {
|
typedef struct Game {
|
||||||
GameScreen screen;
|
GameScreen screen;
|
||||||
GameScreen nextScreen;
|
GameScreen nextScreen;
|
||||||
@@ -56,13 +64,8 @@ typedef struct Game {
|
|||||||
|
|
||||||
Options options;
|
Options options;
|
||||||
|
|
||||||
struct {
|
PlayerResources playerResources[PLAYER_COUNT];
|
||||||
i64 wood;
|
Player player;
|
||||||
i64 iron;
|
|
||||||
i64 food;
|
|
||||||
i64 gold;
|
|
||||||
i64 pop;
|
|
||||||
} resources;
|
|
||||||
BzStackAlloc stackAlloc;
|
BzStackAlloc stackAlloc;
|
||||||
struct {
|
struct {
|
||||||
BzBTNode *workerHarvest;
|
BzBTNode *workerHarvest;
|
||||||
|
|||||||
11
game/main.c
11
game/main.c
@@ -616,11 +616,12 @@ void imguiRender(float dt, void *userData) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
if (igCollapsingHeader_TreeNodeFlags("Resources", 0)) {
|
if (igCollapsingHeader_TreeNodeFlags("Resources", 0)) {
|
||||||
igText("Wood: %lld", game->resources.wood);
|
PlayerResources resources = game->playerResources[game->player];
|
||||||
igText("Iron: %lld", game->resources.iron);
|
igText("Wood: %lld", resources.wood);
|
||||||
igText("Food: %lld", game->resources.food);
|
igText("Food: %lld", resources.food);
|
||||||
igText("Gold: %lld", game->resources.gold);
|
igText("Gold: %lld", resources.gold);
|
||||||
igText("Population: %lld", game->resources.pop);
|
igText("Pop: %lld", resources.pop);
|
||||||
|
igText("Pop Capacity: %lld", resources.pop);
|
||||||
}
|
}
|
||||||
if (igCollapsingHeader_TreeNodeFlags("BuildMenu", 0)) {
|
if (igCollapsingHeader_TreeNodeFlags("BuildMenu", 0)) {
|
||||||
for (int i = BUILDING_NONE; i < BUILDING_COUNT; i++) {
|
for (int i = BUILDING_NONE; i < BUILDING_COUNT; i++) {
|
||||||
|
|||||||
@@ -4,6 +4,7 @@
|
|||||||
#include "../input.h"
|
#include "../input.h"
|
||||||
#include "../map_init.h"
|
#include "../map_init.h"
|
||||||
#include "../ui_widgets.h"
|
#include "../ui_widgets.h"
|
||||||
|
#include "../buildings.h"
|
||||||
|
|
||||||
void drawGameUI(Game *game, f32 dt) {
|
void drawGameUI(Game *game, f32 dt) {
|
||||||
// UI
|
// UI
|
||||||
@@ -37,15 +38,15 @@ void drawGameUI(Game *game, f32 dt) {
|
|||||||
});
|
});
|
||||||
BzTileset *tileset = &game->tileset;
|
BzTileset *tileset = &game->tileset;
|
||||||
Rectangle woodRec = bzTilesetGetTileRegion(tileset, getEntityTile(ENTITY_WOOD));
|
Rectangle woodRec = bzTilesetGetTileRegion(tileset, getEntityTile(ENTITY_WOOD));
|
||||||
Rectangle stoneRec = bzTilesetGetTileRegion(tileset, getEntityTile(ENTITY_STONE));
|
|
||||||
Rectangle foodRec = bzTilesetGetTileRegion(tileset, getEntityTile(ENTITY_APPLE));
|
Rectangle foodRec = bzTilesetGetTileRegion(tileset, getEntityTile(ENTITY_APPLE));
|
||||||
Rectangle goldRec = bzTilesetGetTileRegion(tileset, getEntityTile(ENTITY_GOLD));
|
Rectangle goldRec = bzTilesetGetTileRegion(tileset, getEntityTile(ENTITY_GOLD));
|
||||||
Rectangle popRec = bzTilesetGetTileRegion(tileset, getEntityTile(ENTITY_POP));
|
Rectangle popRec = bzTilesetGetTileRegion(tileset, getEntityTile(ENTITY_POP));
|
||||||
uiGameResCount(100, -1, woodRec, tileset->tiles);
|
|
||||||
uiGameResCount(100, -1, stoneRec, tileset->tiles);
|
PlayerResources resources = game->playerResources[game->player];
|
||||||
uiGameResCount(100, -1, foodRec, tileset->tiles);
|
uiGameResCount(resources.wood, -1, woodRec, tileset->tiles);
|
||||||
uiGameResCount(250, -1, goldRec, tileset->tiles);
|
uiGameResCount(resources.food, -1, foodRec, tileset->tiles);
|
||||||
uiGameResCount(1, 10, popRec, tileset->tiles);
|
uiGameResCount(resources.gold, -1, goldRec, tileset->tiles);
|
||||||
|
uiGameResCount(resources.pop, resources.popCapacity, popRec, tileset->tiles);
|
||||||
bzUIPopParent(UI);
|
bzUIPopParent(UI);
|
||||||
|
|
||||||
|
|
||||||
@@ -97,7 +98,11 @@ void drawGameUI(Game *game, f32 dt) {
|
|||||||
rec.height *= sizeY;
|
rec.height *= sizeY;
|
||||||
Texture2D tex = tileset->tiles;
|
Texture2D tex = tileset->tiles;
|
||||||
bool selected = input->building == buildingOrder[i];
|
bool selected = input->building == buildingOrder[i];
|
||||||
uiGameBuild(buildingNames[i], rec, tex, &selected);
|
PlayerResources *res = &game->playerResources[game->player];
|
||||||
|
bool canAfford = canAffordBuilding(buildingType, *res);
|
||||||
|
uiGameBuild(buildingNames[i], rec, tex, canAfford, &selected);
|
||||||
|
if (!canAfford)
|
||||||
|
selected = false;
|
||||||
if (selected) {
|
if (selected) {
|
||||||
input->building = buildingOrder[i];
|
input->building = buildingOrder[i];
|
||||||
input->state = INPUT_BUILDING;
|
input->state = INPUT_BUILDING;
|
||||||
|
|||||||
@@ -242,7 +242,7 @@ void uiGameResCount(i32 amount, i32 capacity, Rectangle icon, Texture2D texture)
|
|||||||
bzUIPopParent(UI);
|
bzUIPopParent(UI);
|
||||||
}
|
}
|
||||||
|
|
||||||
void uiGameBuild(const char *label, Rectangle rec, Texture2D tex, bool *selected) {
|
void uiGameBuild(const char *label, Rectangle rec, Texture2D tex, bool canAfford, bool *selected) {
|
||||||
f32 scl = uiGetScale();
|
f32 scl = uiGetScale();
|
||||||
BzUINode *btn = bzUINodeMake(UI, bzUIKeyFromString(label), &(BzUINodeDesc) {
|
BzUINode *btn = bzUINodeMake(UI, bzUIKeyFromString(label), &(BzUINodeDesc) {
|
||||||
.flags = BZ_UI_CLICKABLE | BZ_UI_ALIGN_CENTER | BZ_UI_DRAW_BORDER,
|
.flags = BZ_UI_CLICKABLE | BZ_UI_ALIGN_CENTER | BZ_UI_DRAW_BORDER,
|
||||||
@@ -255,10 +255,10 @@ void uiGameBuild(const char *label, Rectangle rec, Texture2D tex, bool *selected
|
|||||||
|
|
||||||
BzUIInteraction inter = bzUIGetInteraction(UI, btn);
|
BzUIInteraction inter = bzUIGetInteraction(UI, btn);
|
||||||
|
|
||||||
Color bgColor = DARKBROWN;
|
Color bgColor = canAfford ? DARKBROWN : MAROON;
|
||||||
if (*selected || inter.hovering)
|
if (*selected || inter.hovering)
|
||||||
bgColor = BROWN;
|
bgColor = canAfford ? BROWN : RED;
|
||||||
if (inter.clicked)
|
if (inter.clicked && canAfford)
|
||||||
*selected = true;
|
*selected = true;
|
||||||
|
|
||||||
bzUISetBackgroundStyle(UI, btn, (BzUIBackgroundStyle) {
|
bzUISetBackgroundStyle(UI, btn, (BzUIBackgroundStyle) {
|
||||||
|
|||||||
@@ -27,6 +27,6 @@ void uiSettingsSlider(const char *txt, f32 *value);
|
|||||||
|
|
||||||
void uiGameResCount(i32 amount, i32 capacity, Rectangle icon, Texture2D texture);
|
void uiGameResCount(i32 amount, i32 capacity, Rectangle icon, Texture2D texture);
|
||||||
|
|
||||||
void uiGameBuild(const char *label, Rectangle rec, Texture2D tex, bool *selected);
|
void uiGameBuild(const char *label, Rectangle rec, Texture2D tex, bool canAfford, bool *selected);
|
||||||
|
|
||||||
#endif //PIXELDEFENSE_UI_WIDGETS_H
|
#endif //PIXELDEFENSE_UI_WIDGETS_H
|
||||||
|
|||||||
Reference in New Issue
Block a user