Convert buildings to entities (partially)
This commit is contained in:
@@ -11,8 +11,11 @@ add_subdirectory(engine/)
|
|||||||
add_executable(PixelDefense
|
add_executable(PixelDefense
|
||||||
${lib_sources}
|
${lib_sources}
|
||||||
|
|
||||||
game/main.c
|
game/utils/buildings.h
|
||||||
|
|
||||||
game/common.h
|
game/common.h
|
||||||
|
game/components.h
|
||||||
|
game/main.c
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -19,9 +19,15 @@ bool bzTileObjectsClear(BzTileObjectGroup *objectGroup, BzTileObject *objects, i
|
|||||||
BzTileLayerFunc BZ_TILE_LAYER_CLEAR = bzTileLayerClear;
|
BzTileLayerFunc BZ_TILE_LAYER_CLEAR = bzTileLayerClear;
|
||||||
BzTileObjectsFunc BZ_TILE_OBJECTS_CLEAR = bzTileObjectsClear;
|
BzTileObjectsFunc BZ_TILE_OBJECTS_CLEAR = bzTileObjectsClear;
|
||||||
|
|
||||||
int16_t bzTileLayerGetTile(BzTileLayer *layer, i32 x, i32 y) {
|
BzTile bzTileLayerGetTile(BzTileLayer *layer, i32 x, i32 y) {
|
||||||
return layer->data[layer->width * y + x];
|
return layer->data[layer->width * y + x];
|
||||||
}
|
}
|
||||||
|
BzTileset *bzTileLayerGetTileset(BzTileMap *map, BzTileLayer *layer) {
|
||||||
|
i32 idx = layer->tilesetIdx;
|
||||||
|
if (idx < 0 || idx >= map->tilesetCount)
|
||||||
|
return NULL;
|
||||||
|
return &map->tilesets[idx];
|
||||||
|
}
|
||||||
|
|
||||||
static void handleTileLayer(BzTileLayer *layer, cute_tiled_layer_t *cuteLayer) {
|
static void handleTileLayer(BzTileLayer *layer, cute_tiled_layer_t *cuteLayer) {
|
||||||
layer->id = cuteLayer->id;
|
layer->id = cuteLayer->id;
|
||||||
@@ -313,6 +319,15 @@ static void drawObjectLayer(BzTileObjectGroup *objectLayer) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BzTileLayer *bzTileMapGetLayer(BzTileMap *map, i32 slotID) {
|
||||||
|
BZ_ASSERT(slotID >= 0 && slotID < map->layerCount);
|
||||||
|
return &map->layers[slotID];
|
||||||
|
}
|
||||||
|
BzTileObjectGroup *bzTileMapGetObjects(BzTileMap *map, i32 slotID) {
|
||||||
|
BZ_ASSERT(slotID >= 0 && slotID < map->objectGroupCount);
|
||||||
|
return &map->objectGroups[slotID];
|
||||||
|
}
|
||||||
|
|
||||||
void bzTileMapDraw(BzTileMap *map) {
|
void bzTileMapDraw(BzTileMap *map) {
|
||||||
for (i32 i = 0; i < map->layerCount; i++) {
|
for (i32 i = 0; i < map->layerCount; i++) {
|
||||||
BzTileLayer *layer = map->layers + i;
|
BzTileLayer *layer = map->layers + i;
|
||||||
|
|||||||
@@ -97,14 +97,15 @@ typedef struct BzTileMap {
|
|||||||
|
|
||||||
extern BzTileMap BZ_TILEMAP_INVALID;
|
extern BzTileMap BZ_TILEMAP_INVALID;
|
||||||
|
|
||||||
// Return true, if you want to override data (you are responsible for cleanup, if you override)
|
// Return true, if you want to override data pointer (you are responsible for cleanup, if you override)
|
||||||
typedef bool (*BzTileLayerFunc)(BzTileLayer *layer, BzTile *data, i32 dataCount);
|
typedef bool (*BzTileLayerFunc)(BzTileLayer *layer, BzTile *data, i32 dataCount);
|
||||||
typedef bool (*BzTileObjectsFunc)(BzTileObjectGroup *objectGroup, BzTileObject *objects, i32 objectsCount);
|
typedef bool (*BzTileObjectsFunc)(BzTileObjectGroup *objectGroup, BzTileObject *objects, i32 objectsCount);
|
||||||
|
|
||||||
extern BzTileLayerFunc BZ_TILE_LAYER_CLEAR;
|
extern BzTileLayerFunc BZ_TILE_LAYER_CLEAR;
|
||||||
extern BzTileObjectsFunc BZ_TILE_OBJECTS_CLEAR;
|
extern BzTileObjectsFunc BZ_TILE_OBJECTS_CLEAR;
|
||||||
|
|
||||||
int16_t bzTileLayerGetTile(BzTileLayer *layer, i32 x, i32 y);
|
BzTile bzTileLayerGetTile(BzTileLayer *layer, i32 x, i32 y);
|
||||||
|
BzTileset *bzTileLayerGetTileset(BzTileMap *map, BzTileLayer *layer);
|
||||||
|
|
||||||
BzTileMap bzTileMapCreate(const BzTileMapDesc *desc);
|
BzTileMap bzTileMapCreate(const BzTileMapDesc *desc);
|
||||||
void bzTileMapDestroy(BzTileMap *map);
|
void bzTileMapDestroy(BzTileMap *map);
|
||||||
@@ -112,6 +113,9 @@ void bzTileMapDestroy(BzTileMap *map);
|
|||||||
void bzTileMapOverrideLayer(BzTileMap *map, i32 slotID, BzTileLayerFunc func);
|
void bzTileMapOverrideLayer(BzTileMap *map, i32 slotID, BzTileLayerFunc func);
|
||||||
void bzTileMapOverrideObjectGroup(BzTileMap *map, i32 slotID, BzTileObjectsFunc func);
|
void bzTileMapOverrideObjectGroup(BzTileMap *map, i32 slotID, BzTileObjectsFunc func);
|
||||||
|
|
||||||
|
BzTileLayer *bzTileMapGetLayer(BzTileMap *map, i32 slotID);
|
||||||
|
BzTileObjectGroup *bzTileMapGetObjects(BzTileMap *map, i32 slotID);
|
||||||
|
|
||||||
void bzTileMapDraw(BzTileMap *map);
|
void bzTileMapDraw(BzTileMap *map);
|
||||||
void bzTileMapDrawColliders(BzTileMap *map);
|
void bzTileMapDrawColliders(BzTileMap *map);
|
||||||
BzTileCollider bzTileMapGetCollider(BzTileMap *map, i32 x, i32 y);
|
BzTileCollider bzTileMapGetCollider(BzTileMap *map, i32 x, i32 y);
|
||||||
|
|||||||
@@ -78,6 +78,11 @@ BzTileset bzTilesetCreate(const BzTilesetDesc *desc) {
|
|||||||
return tileset;
|
return tileset;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BzTile bzTilesetGetTile(BzTileset *tileset, BzTile tile) {
|
||||||
|
tile = tile - tileset->startID;
|
||||||
|
BZ_ASSERT(tile >= tile && tile < tileset->tileCount);
|
||||||
|
return tile;
|
||||||
|
}
|
||||||
Rectangle bzTilesetGetTileRegion(BzTileset *tileset, BzTile tileID) {
|
Rectangle bzTilesetGetTileRegion(BzTileset *tileset, BzTile tileID) {
|
||||||
tileID = tileID - tileset->startID;
|
tileID = tileID - tileset->startID;
|
||||||
if (tileID < 0 || tileID >= tileset->tileCount) {
|
if (tileID < 0 || tileID >= tileset->tileCount) {
|
||||||
|
|||||||
@@ -46,6 +46,7 @@ extern BzTileset BZ_TILESET_INVALID;
|
|||||||
|
|
||||||
BzTileset bzTilesetCreate(const BzTilesetDesc *desc);
|
BzTileset bzTilesetCreate(const BzTilesetDesc *desc);
|
||||||
|
|
||||||
|
BzTile bzTilesetGetTile(BzTileset *tileset, BzTile tile);
|
||||||
Rectangle bzTilesetGetTileRegion(BzTileset *tileset, BzTile tileID);
|
Rectangle bzTilesetGetTileRegion(BzTileset *tileset, BzTile tileID);
|
||||||
BzTileShape bzTilesetGetTileCollider(BzTileset *tileset, BzTile tileID);
|
BzTileShape bzTilesetGetTileCollider(BzTileset *tileset, BzTile tileID);
|
||||||
|
|
||||||
|
|||||||
@@ -3,9 +3,14 @@
|
|||||||
|
|
||||||
#include <breeze.h>
|
#include <breeze.h>
|
||||||
|
|
||||||
typedef struct {
|
typedef struct TilePosition {
|
||||||
f32 x;
|
BzTile x;
|
||||||
f32 y;
|
BzTile y;
|
||||||
} Position, Velocity;
|
} TilePosition;
|
||||||
|
|
||||||
|
typedef struct TileSize {
|
||||||
|
BzTile w;
|
||||||
|
BzTile h;
|
||||||
|
} TileSize;
|
||||||
|
|
||||||
#endif //PIXELDEFENSE_COMPONENTS_H
|
#endif //PIXELDEFENSE_COMPONENTS_H
|
||||||
|
|||||||
88
game/main.c
88
game/main.c
@@ -5,6 +5,23 @@
|
|||||||
#define BZ_ENTRYPOINT
|
#define BZ_ENTRYPOINT
|
||||||
#include <breeze.h>
|
#include <breeze.h>
|
||||||
|
|
||||||
|
#include "utils/buildings.h"
|
||||||
|
|
||||||
|
#include "components.h"
|
||||||
|
|
||||||
|
typedef enum Layers {
|
||||||
|
LAYER_TERRAIN = 0,
|
||||||
|
LAYER_FOLIAGE,
|
||||||
|
LAYER_TREES,
|
||||||
|
LAYER_TREES2,
|
||||||
|
LAYER_BUILDINGS,
|
||||||
|
LAYER_BUILDING_OWNER,
|
||||||
|
} Layers;
|
||||||
|
|
||||||
|
typedef enum ObjectGroup {
|
||||||
|
OBJECTS_GAME = 0,
|
||||||
|
OBJECTS_ENTITIES,
|
||||||
|
} ObjectGroup;
|
||||||
|
|
||||||
typedef struct Game {
|
typedef struct Game {
|
||||||
Camera2D camera;
|
Camera2D camera;
|
||||||
@@ -27,12 +44,64 @@ bool handleGameObjects(BzTileObjectGroup *objectLayer, BzTileObject *objects, i3
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool prepareBuildingLayer(BzTileLayer *layer, BzTile *data, i32 dataCount) {
|
||||||
|
BzTileset *tileset = bzTileLayerGetTileset(&GAME.map, layer);
|
||||||
|
for (i32 i = 0; i < dataCount; i++) {
|
||||||
|
BzTile tile = bzTilesetGetTile(tileset, data[i]);
|
||||||
|
data[i] = getTileBuilding(tile);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void detectSize(BzTile *const data, BzTile * const ownData,
|
||||||
|
const BzTile tile, const BzTile ownerTile,
|
||||||
|
const i32 width, const i32 height,
|
||||||
|
BzTile x, BzTile y, TileSize * const max) {
|
||||||
|
if (x >= width || y >= height) return;
|
||||||
|
|
||||||
|
BzTile *curTile = data + y * width + x;
|
||||||
|
BzTile *curOwn = ownData + y * width + x;
|
||||||
|
|
||||||
|
if (*curTile != tile || *curOwn != ownerTile) return;
|
||||||
|
|
||||||
|
max->w = max->w > x ? max->w : x;
|
||||||
|
max->h = max->h > y ? max->h : y;
|
||||||
|
|
||||||
|
*curTile = 0;
|
||||||
|
*curOwn = 0;
|
||||||
|
|
||||||
|
detectSize(data, ownData, tile, ownerTile, width, height, x + 1, y, max);
|
||||||
|
detectSize(data, ownData, tile, ownerTile, width, height, x, y + 1, max);
|
||||||
|
}
|
||||||
|
|
||||||
bool handleBuildLayer(BzTileLayer *layer, BzTile *data, i32 dataCount) {
|
bool handleBuildLayer(BzTileLayer *layer, BzTile *data, i32 dataCount) {
|
||||||
|
ECS_COMPONENT(ECS, TilePosition);
|
||||||
|
ECS_COMPONENT(ECS, TileSize);
|
||||||
|
|
||||||
|
BzTileMap *map = &GAME.map;
|
||||||
|
BzTileLayer *ownershipLayer = bzTileMapGetLayer(map, LAYER_BUILDING_OWNER);
|
||||||
|
BzTile *ownData = ownershipLayer->data;
|
||||||
|
|
||||||
for (i32 y = 0; y < layer->height; y++) {
|
for (i32 y = 0; y < layer->height; y++) {
|
||||||
for (i32 x = 0; x < layer->width; x++) {
|
for (i32 x = 0; x < layer->width; x++) {
|
||||||
BzTile *tile = data + y * layer->width + x;
|
BzTile *tile = data + y * layer->width + x;
|
||||||
|
BzTile *ownTile = ownData + y * layer->width + x;
|
||||||
if (*tile == 0) continue;
|
if (*tile == 0) continue;
|
||||||
*tile = 0;
|
// We have a building
|
||||||
|
TileSize size = {.w=(BzTile)x, .h=(BzTile)y};
|
||||||
|
if (*tile != BUILDINGS_ROAD) {
|
||||||
|
detectSize(data, ownData, *tile, *ownTile,
|
||||||
|
layer->width, layer->height, (BzTile) x, (BzTile) y, &size);
|
||||||
|
}
|
||||||
|
size.w -= x - 1;
|
||||||
|
size.h -= y - 1;
|
||||||
|
|
||||||
|
bzLogInfo("Got size: %2d %2d", size.w, size.h);
|
||||||
|
|
||||||
|
ecs_entity_t e = ecs_new_id(ECS);
|
||||||
|
ecs_set(ECS, e, TilePosition, {.x=x, .y=y});
|
||||||
|
ecs_set(ECS, e, TileSize, {.w=0, .h=0});
|
||||||
|
|
||||||
bzTileMapUpdateCollider(&GAME.map, x, y);
|
bzTileMapUpdateCollider(&GAME.map, x, y);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -49,7 +118,6 @@ bool canBuildOn(BzTileMap *map, i32 tileX, i32 tileY, i32 sizeX, i32 sizeY) {
|
|||||||
sizeX * map->tileWidth, sizeY * map->tileHeight};
|
sizeX * map->tileWidth, sizeY * map->tileHeight};
|
||||||
|
|
||||||
// Need to check neighbour tiles
|
// Need to check neighbour tiles
|
||||||
// FIXME: Can't place right next to obstacle
|
|
||||||
tileX -= 1;
|
tileX -= 1;
|
||||||
tileY -= 1;
|
tileY -= 1;
|
||||||
sizeX += 2;
|
sizeX += 2;
|
||||||
@@ -90,20 +158,6 @@ bool canBuildOn(BzTileMap *map, i32 tileX, i32 tileY, i32 sizeX, i32 sizeY) {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef enum Layers {
|
|
||||||
LAYER_TERRAIN = 0,
|
|
||||||
LAYER_FOLIAGE,
|
|
||||||
LAYER_TREES,
|
|
||||||
LAYER_TREES2,
|
|
||||||
LAYER_BUILDINGS,
|
|
||||||
LAYER_BUILDING_OWNER,
|
|
||||||
} Layers;
|
|
||||||
|
|
||||||
typedef enum ObjectGroup {
|
|
||||||
OBJECTS_GAME = 0,
|
|
||||||
OBJECTS_ENTITIES,
|
|
||||||
} ObjectGroup;
|
|
||||||
|
|
||||||
bool init(Game *game) {
|
bool init(Game *game) {
|
||||||
int screenWidth = 1280;
|
int screenWidth = 1280;
|
||||||
int screenHeight = 720;
|
int screenHeight = 720;
|
||||||
@@ -139,6 +193,7 @@ bool init(Game *game) {
|
|||||||
.objectGroups[OBJECTS_ENTITIES]=(BzTileObjectsDesc ) {"Entities"}
|
.objectGroups[OBJECTS_ENTITIES]=(BzTileObjectsDesc ) {"Entities"}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
bzTileMapOverrideLayer(&game->map, LAYER_BUILDINGS, prepareBuildingLayer);
|
||||||
bzTileMapOverrideLayer(&game->map, LAYER_BUILDINGS, handleBuildLayer);
|
bzTileMapOverrideLayer(&game->map, LAYER_BUILDINGS, handleBuildLayer);
|
||||||
bzTileMapOverrideLayer(&game->map, LAYER_BUILDING_OWNER, BZ_TILE_LAYER_CLEAR);
|
bzTileMapOverrideLayer(&game->map, LAYER_BUILDING_OWNER, BZ_TILE_LAYER_CLEAR);
|
||||||
|
|
||||||
@@ -223,6 +278,7 @@ bool bzMain(BzAppDesc *appDesc, int argc, const char **argv) {
|
|||||||
|
|
||||||
appDesc->userData = &GAME;
|
appDesc->userData = &GAME;
|
||||||
appDesc->useNuklear = true;
|
appDesc->useNuklear = true;
|
||||||
|
appDesc->useFlecs = true;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
114
game/utils/buildings.h
Normal file
114
game/utils/buildings.h
Normal file
@@ -0,0 +1,114 @@
|
|||||||
|
// This file was generated by: extract_tileset_classes.py
|
||||||
|
|
||||||
|
#include <breeze.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
|
||||||
|
typedef enum BUILDINGS {
|
||||||
|
BUILDINGS_NONE,
|
||||||
|
BUILDINGS_KEEP,
|
||||||
|
BUILDINGS_GRANARY,
|
||||||
|
BUILDINGS_ARMORY,
|
||||||
|
BUILDINGS_WAREHOUSE,
|
||||||
|
BUILDINGS_MINE,
|
||||||
|
BUILDINGS_BARACKS,
|
||||||
|
BUILDINGS_ORCHARD,
|
||||||
|
BUILDINGS_ANIMAL_FARM,
|
||||||
|
BUILDINGS_FLETCHER,
|
||||||
|
BUILDINGS_SMITHY,
|
||||||
|
BUILDINGS_WORKSHOP,
|
||||||
|
BUILDINGS_FARM,
|
||||||
|
BUILDINGS_ROAD,
|
||||||
|
BUILDINGS_WALL,
|
||||||
|
BUILDINGS_GATEHOUSE,
|
||||||
|
BUILDINGS_TOWER,
|
||||||
|
BUILDINGS_SMALL_TOWER,
|
||||||
|
BUILDINGS_COUNT
|
||||||
|
} BUILDINGS;
|
||||||
|
|
||||||
|
|
||||||
|
static bool getTileBuilding(BzTile tile) {
|
||||||
|
switch (tile) {
|
||||||
|
case 0:
|
||||||
|
case 1:
|
||||||
|
case 2:
|
||||||
|
case 32:
|
||||||
|
case 33:
|
||||||
|
case 34:
|
||||||
|
case 64:
|
||||||
|
case 65:
|
||||||
|
case 66:
|
||||||
|
return BUILDINGS_KEEP;
|
||||||
|
case 3:
|
||||||
|
return BUILDINGS_GRANARY;
|
||||||
|
case 4:
|
||||||
|
return BUILDINGS_ARMORY;
|
||||||
|
case 5:
|
||||||
|
return BUILDINGS_WAREHOUSE;
|
||||||
|
case 6:
|
||||||
|
case 7:
|
||||||
|
return BUILDINGS_MINE;
|
||||||
|
case 8:
|
||||||
|
case 9:
|
||||||
|
case 40:
|
||||||
|
case 41:
|
||||||
|
return BUILDINGS_BARACKS;
|
||||||
|
case 10:
|
||||||
|
case 11:
|
||||||
|
case 42:
|
||||||
|
case 43:
|
||||||
|
return BUILDINGS_ORCHARD;
|
||||||
|
case 12:
|
||||||
|
case 13:
|
||||||
|
case 44:
|
||||||
|
case 45:
|
||||||
|
return BUILDINGS_ANIMAL_FARM;
|
||||||
|
case 35:
|
||||||
|
case 36:
|
||||||
|
return BUILDINGS_FLETCHER;
|
||||||
|
case 67:
|
||||||
|
case 68:
|
||||||
|
return BUILDINGS_SMITHY;
|
||||||
|
case 72:
|
||||||
|
case 73:
|
||||||
|
return BUILDINGS_WORKSHOP;
|
||||||
|
case 74:
|
||||||
|
return BUILDINGS_FARM;
|
||||||
|
case 96:
|
||||||
|
return BUILDINGS_ROAD;
|
||||||
|
case 97:
|
||||||
|
return BUILDINGS_WALL;
|
||||||
|
case 98:
|
||||||
|
return BUILDINGS_GATEHOUSE;
|
||||||
|
case 128:
|
||||||
|
case 129:
|
||||||
|
case 160:
|
||||||
|
case 161:
|
||||||
|
return BUILDINGS_TOWER;
|
||||||
|
case 130:
|
||||||
|
return BUILDINGS_SMALL_TOWER;
|
||||||
|
default:
|
||||||
|
return BUILDINGS_NONE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static BUILDINGS getBuildingFromStr(const char *str) {
|
||||||
|
if (strncmp("keep", str, 4)) return BUILDINGS_KEEP;
|
||||||
|
if (strncmp("granary", str, 7)) return BUILDINGS_GRANARY;
|
||||||
|
if (strncmp("armory", str, 6)) return BUILDINGS_ARMORY;
|
||||||
|
if (strncmp("warehouse", str, 9)) return BUILDINGS_WAREHOUSE;
|
||||||
|
if (strncmp("mine", str, 4)) return BUILDINGS_MINE;
|
||||||
|
if (strncmp("baracks", str, 7)) return BUILDINGS_BARACKS;
|
||||||
|
if (strncmp("orchard", str, 7)) return BUILDINGS_ORCHARD;
|
||||||
|
if (strncmp("animal_farm", str, 11)) return BUILDINGS_ANIMAL_FARM;
|
||||||
|
if (strncmp("fletcher", str, 8)) return BUILDINGS_FLETCHER;
|
||||||
|
if (strncmp("smithy", str, 6)) return BUILDINGS_SMITHY;
|
||||||
|
if (strncmp("workshop", str, 8)) return BUILDINGS_WORKSHOP;
|
||||||
|
if (strncmp("farm", str, 4)) return BUILDINGS_FARM;
|
||||||
|
if (strncmp("road", str, 4)) return BUILDINGS_ROAD;
|
||||||
|
if (strncmp("wall", str, 4)) return BUILDINGS_WALL;
|
||||||
|
if (strncmp("gatehouse", str, 9)) return BUILDINGS_GATEHOUSE;
|
||||||
|
if (strncmp("tower", str, 5)) return BUILDINGS_TOWER;
|
||||||
|
if (strncmp("small_tower", str, 11)) return BUILDINGS_SMALL_TOWER;
|
||||||
|
else return BUILDINGS_NONE;
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user