Place buildings

This commit is contained in:
2023-11-11 07:01:49 +01:00
parent 7513ecc7eb
commit 1908150635
8 changed files with 173 additions and 27 deletions

4
.gitignore vendored
View File

@@ -2,8 +2,8 @@
*~
.idea/
cmake-build-debug/
tiled/PixelDefense.tiled-session
venv/
tiled/PixelDefense.tiled-session
imgui.ini

View File

@@ -9,9 +9,6 @@ add_subdirectory(engine/)
add_executable(PixelDefense
${lib_sources}
game/utils/buildings.h
game/common.h
game/components.h

View File

@@ -5,7 +5,7 @@
#include <raylib.h>
typedef i16 BzTile;
typedef i32 BzTile;
typedef struct BzTilesetDesc {
const char *path;

View File

@@ -1,5 +1,7 @@
project(BreezeTests)
set(CMAKE_C_STANDARD 11)
add_executable(window_test window_test.c)
target_link_libraries(window_test LINK_PRIVATE Breeze)

View File

@@ -2,9 +2,7 @@
#include <breeze.h>
#include <raylib.h>
#define CIMGUI_DEFINE_ENUMS_AND_STRUCTS
#include <rlImGui.h>
#include <cimgui.h>
bool init(int *game) {
rlImGuiSetup(true);

View File

@@ -1,12 +1,12 @@
#include <stdio.h>
#include <flecs.h>
#define BZ_ENTRYPOINT
#include <breeze.h>
#include "utils/buildings.h"
#include <raylib.h>
#include <rlImGui.h>
#include "utils/building_types.h"
#include "components.h"
typedef enum Layers {
@@ -31,6 +31,7 @@ typedef struct Game {
} Game;
static Game GAME = {};
static int selectedBuilding = 0;
bool handleGameObjects(BzTileObjectGroup *objectLayer, BzTileObject *objects, i32 objectCount) {
for (i32 i = 0; i < objectLayer->objectCount; i++) {
@@ -152,7 +153,40 @@ bool canBuildOn(BzTileMap *map, i32 tileX, i32 tileY, i32 sizeX, i32 sizeY) {
return true;
}
void placeBuilding(BzTileMap *map, BuildingType type, i32 posX, i32 posY, i32 sizeX, i32 sizeY) {
ECS_COMPONENT(ECS, TilePosition);
ECS_COMPONENT(ECS, TileSize);
ECS_COMPONENT(ECS, Owner);
BzTileLayer *buildingLayer = bzTileMapGetLayer(map, LAYER_BUILDINGS);
BzTileset *buildingTileset = bzTileLayerGetTileset(map, buildingLayer);
BzTile buildingTile = getBuildingTile(type);
BZ_ASSERT(buildingTile != -1);
// Create entity
ecs_entity_t e = ecs_new_id(ECS);
ecs_set(ECS, e, TilePosition, {.x=posX, .y=posY});
ecs_set(ECS, e, TileSize, {.w=sizeX, .h=sizeY});
ecs_set(ECS, e, Owner, {.playerID=BUILDINGS_PLAYER_RED});
for (i32 y = posY; y < posY + sizeY; y++) {
for (i32 x = posX; x < posX + sizeX; x++) {
BzTile layerTile = buildingTile + buildingTileset->startID;
bzTileLayerSetTile(buildingLayer, layerTile, x, y, 1, 1);
buildingTile++;
entityMap[y * buildingLayer->width + x] = e;
bzTileMapUpdateCollider(map, x, y);
}
buildingTile += buildingTileset->width - sizeX;
}
}
bool init(Game *game) {
rlImGuiSetup(true);
int screenWidth = 1280;
int screenHeight = 720;
@@ -199,11 +233,9 @@ void deinit(Game *game) {
bzTilesetDestroy(&game->terrainTileset);
bzTilesetDestroy(&game->buildingsTileset);
bzTileMapDestroy(&game->map);
rlImGuiShutdown();
}
int sizeX = 1;
int sizeY = 1;
void render(float dt, Game *game) {
Camera2D *camera = &game->camera;
@@ -227,15 +259,42 @@ void render(float dt, Game *game) {
int tileX = (int) worldPos.x / 16;
int tileY = (int) worldPos.y / 16;
bool canPlace = canBuildOn(&game->map, tileX, tileY, sizeX, sizeY);
Color placeColor = canPlace ?
(Color) {0, 255, 0, 200} :
(Color) {255, 0, 0, 200};
if (selectedBuilding) {
BzTile sizeX = 0, sizeY = 0;
getBuildingSize(selectedBuilding, &sizeX, &sizeY);
DrawRectangleLines(tileX * 16, tileY * 16, sizeX * 16, sizeY * 16, placeColor);
bool canPlace = canBuildOn(&game->map, tileX, tileY, sizeX, sizeY);
Color placeColor = canPlace ?
(Color) {0, 255, 0, 200} :
(Color) {255, 0, 0, 200};
DrawRectangleLines(tileX * 16, tileY * 16, sizeX * 16, sizeY * 16, placeColor);
if (canPlace && IsMouseButtonPressed(MOUSE_BUTTON_LEFT)) {
placeBuilding(&game->map, selectedBuilding, tileX, tileY, sizeX, sizeY);
}
}
EndMode2D();
rlImGuiBegin();
igSetNextWindowSize((ImVec2){300, 400}, ImGuiCond_FirstUseEver);
igBegin("Debug Menu", NULL, 0);
if (igCollapsingHeader_TreeNodeFlags("BuildMenu", 0)) {
for (int i = 0; i < BUILDINGS_COUNT; i++) {
if (igSelectable_Bool(getBuildingStr(i), selectedBuilding == i, 0, (ImVec2){0,0}))
selectedBuilding = i;
}
}
if (igCollapsingHeader_TreeNodeFlags("Entities", 0)) {
}
igEnd();
igShowDemoWindow(NULL);
rlImGuiEnd();
}

View File

@@ -100,6 +100,31 @@ static BuildingType getTileBuilding(BzTile tile) {
}
}
static BzTile getBuildingTile(BuildingType type) {
switch (type) {
case BUILDINGS_KEEP: return 0;
case BUILDINGS_GRANARY: return 3;
case BUILDINGS_ARMORY: return 4;
case BUILDINGS_WAREHOUSE: return 5;
case BUILDINGS_MINE: return 6;
case BUILDINGS_BARACKS: return 8;
case BUILDINGS_ORCHARD: return 10;
case BUILDINGS_ANIMAL_FARM: return 12;
case BUILDINGS_PLAYER_RED: return 31;
case BUILDINGS_FLETCHER: return 35;
case BUILDINGS_PLAYER_BLUE: return 63;
case BUILDINGS_SMITHY: return 67;
case BUILDINGS_WORKSHOP: return 72;
case BUILDINGS_FARM: return 74;
case BUILDINGS_ROAD: return 96;
case BUILDINGS_WALL: return 97;
case BUILDINGS_GATEHOUSE: return 98;
case BUILDINGS_TOWER: return 128;
case BUILDINGS_SMALL_TOWER: return 130;
default: return -1;
}
}
static BuildingType getBuildingFromStr(const char *str) {
if (strncmp("keep", str, 4) == 0) return BUILDINGS_KEEP;
if (strncmp("granary", str, 7) == 0) return BUILDINGS_GRANARY;
@@ -122,6 +147,32 @@ static BuildingType getBuildingFromStr(const char *str) {
if (strncmp("small_tower", str, 11) == 0) return BUILDINGS_SMALL_TOWER;
else return BUILDINGS_NONE;
}
static const char *getBuildingStr(BuildingType type) {
switch (type) {
case BUILDINGS_NONE: return "none";
case BUILDINGS_KEEP: return "keep";
case BUILDINGS_GRANARY: return "granary";
case BUILDINGS_ARMORY: return "armory";
case BUILDINGS_WAREHOUSE: return "warehouse";
case BUILDINGS_MINE: return "mine";
case BUILDINGS_BARACKS: return "baracks";
case BUILDINGS_ORCHARD: return "orchard";
case BUILDINGS_ANIMAL_FARM: return "animal_farm";
case BUILDINGS_PLAYER_RED: return "player_red";
case BUILDINGS_FLETCHER: return "fletcher";
case BUILDINGS_PLAYER_BLUE: return "player_blue";
case BUILDINGS_SMITHY: return "smithy";
case BUILDINGS_WORKSHOP: return "workshop";
case BUILDINGS_FARM: return "farm";
case BUILDINGS_ROAD: return "road";
case BUILDINGS_WALL: return "wall";
case BUILDINGS_GATEHOUSE: return "gatehouse";
case BUILDINGS_TOWER: return "tower";
case BUILDINGS_SMALL_TOWER: return "small_tower";
default: return NULL;
}
}
static void getBuildingSize(BuildingType type, BzTile *outWidth, BzTile *outHeight) {
switch (type) {
case BUILDINGS_KEEP:

View File

@@ -23,10 +23,10 @@ for tile in tiles:
type = tile["type"]
types[type].append(id)
enum_identifier = os.path.basename(path).split(".")[0].capitalize()
enum_name = enum_identifier.upper()
enum_type = os.path.basename(path).split(".")[0].capitalize()
enum_name = enum_type.upper()
if sys.argv[2]:
enum_identifier = sys.argv[2]
enum_type = sys.argv[2]
indent_level = 0
indent_offset = 4
@@ -53,21 +53,21 @@ print()
enum_none = enum_string("none")
enum_count = enum_string("count")
print(f"{indent()}typedef enum {enum_identifier} {{")
print(f"{indent()}typedef enum {enum_type} {{")
indent_level += indent_offset
print(f"{indent()}{enum_none},")
for enum in types:
print(f"{indent()}{enum_string(enum)},")
print(f"{indent()}{enum_count}")
indent_level -= indent_offset
print(f"{indent()}}} {enum_identifier};")
print(f"{indent()}}} {enum_type};")
print()
print()
# ============================
print(f"{indent()}static {enum_identifier} getTileBuilding(BzTile tile) {{")
print(f"{indent()}static {enum_type} getTileBuilding(BzTile tile) {{")
indent_level += indent_offset
print(f"{indent()}switch (tile) {{")
for enum, ids in types.items():
@@ -95,7 +95,26 @@ print()
# ============================
print(f"{indent()}static {enum_identifier} getBuildingFromStr(const char *str) {{")
print(f"{indent()}static BzTile getBuildingTile({enum_type} type) {{")
indent_level += indent_offset
print(f"{indent()}switch (type) {{")
indent_level += indent_offset
for type, ids in types.items():
min_id = min(ids)
print(f"{indent()}case {enum_string(type)}: return {min_id};")
print(f"{indent()}default: return -1;")
indent_level -= indent_offset
print(f"{indent()}}}")
indent_level -= indent_offset
print(f"{indent()}}}")
print()
# ============================
print(f"{indent()}static {enum_type} getBuildingFromStr(const char *str) {{")
indent_level += indent_offset
# trie would be much better
@@ -108,7 +127,27 @@ print(f"{indent()}}}")
# ============================
print(f"{indent()}static void getBuildingSize({enum_identifier} type, BzTile *outWidth, BzTile *outHeight) {{")
print(f"{indent()}static const char *getBuildingStr({enum_type} type) {{")
indent_level += indent_offset
print(f"{indent()}switch (type) {{")
indent_level += indent_offset
print(f"{indent()}case {enum_string('none')}: return \"none\";")
for type in types:
print(f"{indent()}case {enum_string(type)}: return \"{type}\";")
print(f"{indent()}default: return NULL;")
indent_level -= indent_offset
print(f"{indent()}}}")
indent_level -= indent_offset
print(f"{indent()}}}")
print()
# ============================
print(f"{indent()}static void getBuildingSize({enum_type} type, BzTile *outWidth, BzTile *outHeight) {{")
indent_level += indent_offset
print(f"{indent()} switch (type) {{")
indent_level += indent_offset