Buildings as entities instead of map layer
This commit is contained in:
@@ -288,9 +288,11 @@ void bzTileMapDestroy(BzTileMap *map) {
|
||||
}
|
||||
|
||||
|
||||
void bzTileMapPosToTile(BzTileMap *map, Vector2 pos, BzTile *x, BzTile *y) {
|
||||
if (x) *x = (BzTile) (pos.x / (f32) map->tileWidth);
|
||||
if (y) *y = (BzTile) (pos.y / (f32) map->tileHeight);
|
||||
Vec2i bzTileMapPosToTile(BzTileMap *map, Vector2 pos) {
|
||||
return (Vec2i) {
|
||||
.x = (i32) (pos.x / (f32) map->tileWidth),
|
||||
.y = (i32) (pos.y / (f32) map->tileHeight)
|
||||
};
|
||||
}
|
||||
|
||||
void bzTileMapOverrideLayer(BzTileMap *map, i32 slotID, BzTileLayerFunc func) {
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
#define BREEZE_MAP_H
|
||||
|
||||
#include "tileset.h"
|
||||
#include "../math/vec2i.h"
|
||||
#include "../util/string.h"
|
||||
|
||||
#define BZ_MAP_MAX_LAYERS 8
|
||||
@@ -116,7 +117,7 @@ BzTileset *bzTileObjectGroupGetTileset(BzTileMap *map, BzTileObjectGroup *object
|
||||
BzTileMap bzTileMapCreate(const BzTileMapDesc *desc);
|
||||
void bzTileMapDestroy(BzTileMap *map);
|
||||
|
||||
void bzTileMapPosToTile(BzTileMap *map, Vector2 pos, BzTile *x, BzTile *y);
|
||||
Vec2i bzTileMapPosToTile(BzTileMap *map, Vector2 pos);
|
||||
|
||||
void bzTileMapOverrideLayer(BzTileMap *map, i32 slotID, BzTileLayerFunc func);
|
||||
void bzTileMapOverrideObjectGroup(BzTileMap *map, i32 slotID, BzTileObjectsFunc func);
|
||||
|
||||
@@ -4,14 +4,16 @@
|
||||
#include "entity_factory.h"
|
||||
#include "game_state.h"
|
||||
#include "map_layers.h"
|
||||
#include "systems/systems.h"
|
||||
|
||||
#include <raymath.h>
|
||||
|
||||
bool canPlaceBuilding(BzTileMap *map, BuildingType type, BzTile tileX, BzTile tileY) {
|
||||
bool canPlaceBuilding(Game *game, BuildingType type, BzTile tileX, BzTile tileY) {
|
||||
i32 sizeX, sizeY;
|
||||
getBuildingSize(type, &sizeX, &sizeY);
|
||||
if (sizeX == 0 || sizeY == 0) return false;
|
||||
|
||||
BzTileMap *map = &game->map;
|
||||
// Ensure that it is within the map
|
||||
if (tileX < 0 || tileX + sizeX > map->width ||
|
||||
tileY < 0 || tileY + sizeY > map->height)
|
||||
@@ -20,60 +22,65 @@ bool canPlaceBuilding(BzTileMap *map, BuildingType type, BzTile tileX, BzTile ti
|
||||
Rectangle buildArea = {tileX * map->tileWidth, tileY * map->tileHeight,
|
||||
sizeX * map->tileWidth, sizeY * map->tileHeight};
|
||||
|
||||
// Need to check neighbour tiles
|
||||
//tileX -= 1;
|
||||
//tileY -= 1;
|
||||
//sizeX += 2;
|
||||
//sizeY += 2;
|
||||
BzSpatialGridIter it = bzSpatialGridIter(game->entityGrid, buildArea.x, buildArea.y, buildArea.width, buildArea.height);
|
||||
while (bzSpatialGridQueryNext(&it)) { ecs_entity_t entity = *(ecs_entity_t *) it.data;
|
||||
Rectangle bounds;
|
||||
if (!getEntityBounds(entity, NULL, NULL, &bounds)) continue;
|
||||
|
||||
BzTileLayer *buildLayer = bzTileMapGetLayer(map, LAYER_BUILDINGS);
|
||||
BzTileset *tileset = bzTileLayerGetTileset(map, buildLayer);
|
||||
|
||||
for (i32 y = tileY; y < tileY + sizeY; y++) {
|
||||
for (i32 x = tileX; x < tileX + sizeX; x++) {
|
||||
BzTile tile = bzTileLayerGetTile(buildLayer, x, y);
|
||||
tile = bzTilesetGetTileID(tileset, tile);
|
||||
tile = getTileBuilding(tile);
|
||||
//if (tile == BUILDINGS_ROAD)
|
||||
// return false;
|
||||
if (bzTileMapHasCollision(map, x, y)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (CheckCollisionRecs(buildArea, bounds))
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
ecs_entity_t placeBuilding(BzTileMap *map, BuildingType type, BzTile tileX, BzTile tileY) {
|
||||
Game *game = ecs_singleton_get_mut(ECS, Game);
|
||||
ecs_entity_t placeBuilding(Game *game, BuildingType type,
|
||||
BzTile tileX, BzTile tileY, Owner owner) {
|
||||
if (type <= BUILDING_NONE || type >= BUILDING_COUNT)
|
||||
return 0;
|
||||
i32 sizeX, sizeY;
|
||||
getBuildingSize(type, &sizeX, &sizeY);
|
||||
|
||||
BzTileLayer *buildingLayer = bzTileMapGetLayer(map, LAYER_BUILDINGS);
|
||||
BzTileset *buildingTileset = bzTileLayerGetTileset(map, buildingLayer);
|
||||
BzTile buildingTile = getBuildingTile(type);
|
||||
BZ_ASSERT(buildingTile != -1);
|
||||
const i32 tileWidth = game->map.tileWidth;
|
||||
const i32 tileHeight = game->map.tileHeight;
|
||||
|
||||
// Create entity
|
||||
ecs_entity_t e = entityCreateEmpty();
|
||||
ecs_entity_t building = entityCreateEmpty();
|
||||
Position pos = {
|
||||
.x = tileX * tileWidth + sizeX * tileWidth * 0.5f,
|
||||
.y = tileY * tileHeight + sizeY * tileHeight * 0.5f
|
||||
};
|
||||
Size size = {
|
||||
.x = sizeX * tileWidth,
|
||||
.y = sizeY * tileHeight
|
||||
};
|
||||
|
||||
ecs_set(ECS, e, TilePosition, { .x = tileX, .y = tileY });
|
||||
ecs_set(ECS, e, TileSize, { .sizeX = sizeX, .sizeY = sizeY });
|
||||
//ecs_set(ECS, e, Owner, { .playerID = BUILDINGS_PLAYER_RED });
|
||||
ecs_set_ptr(ECS, building, Position, &pos);
|
||||
ecs_set_ptr(ECS, building, Size, &size);
|
||||
ecs_set(ECS, building, Rotation, {0});
|
||||
|
||||
for (i32 y = tileY; y < tileY + sizeY; y++) {
|
||||
for (i32 x = tileX; x < tileX + sizeX; x++) {
|
||||
BzTile layerTile = buildingTile + buildingTileset->startID;
|
||||
bzTileLayerSetTile(buildingLayer, layerTile, x, y, 1, 1);
|
||||
buildingTile++;
|
||||
SpatialGridID gridID = bzSpatialGridInsert(game->entityGrid, &building,
|
||||
pos.x, pos.y,
|
||||
size.x, size.y);
|
||||
ecs_set_ptr(ECS, building, SpatialGridID, &gridID);
|
||||
ecs_set_ptr(ECS, building, Owner, &owner);
|
||||
BzTileset *tileset = &game->tileset;
|
||||
TextureRegion region = {
|
||||
tileset->tiles,
|
||||
bzTilesetGetTileRegion(tileset, getBuildingTile(type))
|
||||
};
|
||||
region.rec.width *= sizeX;
|
||||
region.rec.height *= sizeY;
|
||||
ecs_set_ptr(ECS, building, TextureRegion, ®ion);
|
||||
|
||||
bzTileMapUpdateCollisions(map, x, y, 1, 1);
|
||||
}
|
||||
buildingTile += buildingTileset->width - sizeX;
|
||||
switch (type) {
|
||||
case BUILDING_KEEP:
|
||||
ecs_add_id(ECS, building, Storage);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return e;
|
||||
return building;
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -4,10 +4,13 @@
|
||||
#include <breeze.h>
|
||||
#include <flecs.h>
|
||||
|
||||
#include "components.h"
|
||||
#include "game_tileset.h"
|
||||
|
||||
bool canPlaceBuilding(BzTileMap *map, BuildingType type, i32 tileX, i32 tileY);
|
||||
ecs_entity_t placeBuilding(BzTileMap *map, BuildingType type, i32 tileX, i32 tileY);
|
||||
typedef struct Game Game;
|
||||
|
||||
bool canPlaceBuilding(Game *game, BuildingType type, i32 tileX, i32 tileY);
|
||||
ecs_entity_t placeBuilding(Game *game, BuildingType type, i32 tileX, i32 tileY, Owner owner);
|
||||
|
||||
Vector2 getPositionNearBuilding(ecs_entity_t building, Vector2 fromPos);
|
||||
|
||||
|
||||
@@ -7,8 +7,6 @@ ECS_TAG_DECLARE(GameEntity);
|
||||
|
||||
ECS_COMPONENT_DECLARE(Resource);
|
||||
|
||||
ECS_COMPONENT_DECLARE(TilePosition);
|
||||
ECS_COMPONENT_DECLARE(TileSize);
|
||||
ECS_COMPONENT_DECLARE(Owner);
|
||||
|
||||
ECS_COMPONENT_DECLARE(SpatialGridID);
|
||||
@@ -47,8 +45,6 @@ void initComponentIDs(ecs_world_t *ecs) {
|
||||
|
||||
ECS_COMPONENT_DEFINE(ecs, Resource);
|
||||
|
||||
ECS_COMPONENT_DEFINE(ecs, TilePosition);
|
||||
ECS_COMPONENT_DEFINE(ecs, TileSize);
|
||||
ECS_COMPONENT_DEFINE(ecs, Owner);
|
||||
|
||||
ECS_COMPONENT_DEFINE(ecs, SpatialGridID);
|
||||
@@ -106,18 +102,6 @@ void igResource(ecs_world_t *ecs,
|
||||
res->type = curType;
|
||||
igInputInt("Amount", &res->amount, 1, 10, 0);
|
||||
}
|
||||
void igTilePosition(ecs_world_t *ecs,
|
||||
ecs_entity_t entity, ecs_entity_t comp) {
|
||||
TilePosition *tilePos = ecs_get_mut_id(ecs, entity, comp);
|
||||
igInputInt("X", &tilePos->x, 1, 4, 0);
|
||||
igInputInt("Y", &tilePos->y, 1, 4, 0);
|
||||
}
|
||||
void igTileSize(ecs_world_t *ecs,
|
||||
ecs_entity_t entity, ecs_entity_t comp) {
|
||||
TileSize *tileSize = ecs_get_mut_id(ecs, entity, comp);
|
||||
igInputInt("X", &tileSize->sizeX, 1, 1, 0);
|
||||
igInputInt("Y", &tileSize->sizeY, 1, 1, 0);
|
||||
}
|
||||
void igOwner(ecs_world_t *ecs,
|
||||
ecs_entity_t entity, ecs_entity_t comp) {
|
||||
Owner *owner = ecs_get_mut_id(ecs, entity, comp);
|
||||
|
||||
@@ -33,18 +33,6 @@ typedef struct Resource {
|
||||
} Resource;
|
||||
extern ECS_COMPONENT_DECLARE(Resource);
|
||||
|
||||
typedef struct TilePosition {
|
||||
BzTile x;
|
||||
BzTile y;
|
||||
} TilePosition;
|
||||
extern ECS_COMPONENT_DECLARE(TilePosition);
|
||||
|
||||
typedef struct TileSize {
|
||||
BzTile sizeX;
|
||||
BzTile sizeY;
|
||||
} TileSize;
|
||||
extern ECS_COMPONENT_DECLARE(TileSize);
|
||||
|
||||
typedef struct Owner {
|
||||
int32_t playerID;
|
||||
} Owner;
|
||||
@@ -215,10 +203,6 @@ void igTagCheckbox(const char *label, ecs_world_t *ecs,
|
||||
typedef void(*ImGuiCompFn)(ecs_world_t *ecs, ecs_entity_t entity, ecs_entity_t comp);
|
||||
void igResource(ecs_world_t *ecs,
|
||||
ecs_entity_t entity, ecs_entity_t comp);
|
||||
void igTilePosition(ecs_world_t *ecs,
|
||||
ecs_entity_t entity, ecs_entity_t comp);
|
||||
void igTileSize(ecs_world_t *ecs,
|
||||
ecs_entity_t entity, ecs_entity_t comp);
|
||||
void igOwner(ecs_world_t *ecs,
|
||||
ecs_entity_t entity, ecs_entity_t comp);
|
||||
|
||||
|
||||
@@ -17,8 +17,8 @@ typedef struct AnimationFrame {
|
||||
} AnimationFrame;
|
||||
|
||||
typedef enum TerrainType {
|
||||
TERRAIN_NONE = -1,
|
||||
TERRAIN_COUNT,
|
||||
TERRAIN_NONE,
|
||||
} TerrainType;
|
||||
|
||||
static bool terrainHasAnimation(BzTileID tile) {
|
||||
@@ -257,9 +257,9 @@ static AnimationFrame terrainGetAnimationFrame(BzTileID tile, i32 frameIdx) {
|
||||
|
||||
|
||||
typedef enum BuildingType {
|
||||
BUILDING_NONE = -1,
|
||||
BUILDING_KEEP,
|
||||
BUILDING_COUNT,
|
||||
BUILDING_NONE,
|
||||
} BuildingType;
|
||||
|
||||
static BuildingType getTileBuilding(BzTileID tile) {
|
||||
@@ -275,7 +275,7 @@ static BuildingType getTileBuilding(BzTileID tile) {
|
||||
case 6406:
|
||||
return BUILDING_KEEP;
|
||||
default:
|
||||
return BUILDING_NONE;
|
||||
return BUILDING_COUNT;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -288,7 +288,7 @@ static BzTileID getBuildingTile(BuildingType type) {
|
||||
|
||||
static BuildingType getBuildingFromStr(const char *str) {
|
||||
if (strncmp("keep", str, 4) == 0) return BUILDING_KEEP;
|
||||
return BUILDING_NONE;
|
||||
return BUILDING_COUNT;
|
||||
}
|
||||
|
||||
static const char *getBuildingStr(BuildingType type) {
|
||||
@@ -313,6 +313,7 @@ static BuildingType getBuildingSize(BuildingType type, BzTileID *outWidth, BzTil
|
||||
|
||||
|
||||
typedef enum EntityType {
|
||||
ENTITY_NONE = -1,
|
||||
ENTITY_WORKER,
|
||||
ENTITY_WOOD,
|
||||
ENTITY_STONE,
|
||||
@@ -320,7 +321,6 @@ typedef enum EntityType {
|
||||
ENTITY_GOLD,
|
||||
ENTITY_POP,
|
||||
ENTITY_COUNT,
|
||||
ENTITY_NONE,
|
||||
} EntityType;
|
||||
|
||||
typedef enum AnimType {
|
||||
@@ -329,7 +329,7 @@ typedef enum AnimType {
|
||||
ANIM_HURT,
|
||||
ANIM_DIE,
|
||||
ANIM_COUNT,
|
||||
ANIM_NONE,
|
||||
ANIM_NONE = -1,
|
||||
} AnimType;
|
||||
|
||||
static BzTileID getEntityTile(EntityType type) {
|
||||
@@ -394,6 +394,7 @@ static AnimationFrame entityGetAnimationFrame(EntityType entity, AnimType type,
|
||||
}
|
||||
|
||||
typedef enum ItemType {
|
||||
ITEM_NONE = -1,
|
||||
ITEM_STAFF,
|
||||
ITEM_PICKAXE,
|
||||
ITEM_AXE,
|
||||
@@ -415,7 +416,6 @@ typedef enum ItemType {
|
||||
ITEM_SPEAR,
|
||||
ITEM_TRIDENT,
|
||||
ITEM_COUNT,
|
||||
ITEM_NONE,
|
||||
} ItemType;
|
||||
|
||||
static BzTileID getItemTile(ItemType type) {
|
||||
|
||||
@@ -50,8 +50,8 @@ typedef struct InputState {
|
||||
// INPUT_BUILDING
|
||||
int building;
|
||||
bool buildingCanPlace;
|
||||
TilePosition buildingPos;
|
||||
TileSize buildingSize;
|
||||
Vec2i buildingPos;
|
||||
Vec2i buildingSize;
|
||||
// SELECTED_UNITS
|
||||
Rectangle pickArea;
|
||||
|
||||
|
||||
19
game/main.c
19
game/main.c
@@ -103,9 +103,9 @@ void loadMap(Game *game, const char *path) {
|
||||
.layers[LAYER_TERRAIN]=(BzTileLayerDesc) {"terrain", .renderer=terrainRender, .applyColliders=true},
|
||||
.layers[LAYER_ROCKS]=(BzTileLayerDesc) {"rocks"},
|
||||
.layers[LAYER_ROCKS2]=(BzTileLayerDesc) {"rocks_s"},
|
||||
.layers[LAYER_TREES]=(BzTileLayerDesc) {"trees"},
|
||||
.layers[LAYER_TREES2]=(BzTileLayerDesc) {"trees_s"},
|
||||
.layers[LAYER_BUILDINGS]=(BzTileLayerDesc) {"buildings", .applyColliders=true},
|
||||
.layers[LAYER_TREES]=(BzTileLayerDesc) {"trees", BZ_TILE_LAYER_SKIP_RENDER},
|
||||
.layers[LAYER_TREES2]=(BzTileLayerDesc) {"trees_s", BZ_TILE_LAYER_SKIP_RENDER},
|
||||
.layers[LAYER_BUILDINGS]=(BzTileLayerDesc) {"buildings", BZ_TILE_LAYER_SKIP_RENDER},
|
||||
.layers[LAYER_BUILDING_OWNER]=(BzTileLayerDesc) {"building_ownership", BZ_TILE_LAYER_SKIP_RENDER},
|
||||
|
||||
.objectGroups[OBJECTS_GAME]=(BzTileObjectsDesc) {"game"},
|
||||
@@ -129,6 +129,7 @@ void loadMap(Game *game, const char *path) {
|
||||
bzTileMapOverrideLayer(&game->map, LAYER_TREES2, initTreesLayer);
|
||||
|
||||
bzTileMapOverrideLayer(&game->map, LAYER_BUILDING_OWNER, initBuildingsLayer);
|
||||
bzTileMapOverrideLayer(&game->map, LAYER_BUILDINGS, BZ_TILE_LAYER_CLEAR);
|
||||
|
||||
bzTileMapOverrideObjectGroup(&game->map, OBJECTS_GAME, initGameObjectsLayer);
|
||||
bzTileMapOverrideObjectGroup(&game->map, OBJECTS_ENTITIES, initEntityObjectsLayer);
|
||||
@@ -197,6 +198,8 @@ bool init(void *userData) {
|
||||
{ecs_id(Selected)}
|
||||
}
|
||||
});
|
||||
|
||||
input->building = BUILDING_NONE;
|
||||
}
|
||||
{
|
||||
InitAudioDevice();
|
||||
@@ -652,8 +655,6 @@ void igInspectWindow(ecs_entity_t entity, bool *open) {
|
||||
igTagCheckbox("Attackable", ECS, entity, Attackable);
|
||||
}
|
||||
igInspectComp("Resource", entity, ecs_id(Resource), igResource);
|
||||
igInspectComp("TilePosition", entity, ecs_id(TilePosition), igTilePosition);
|
||||
igInspectComp("TileSize", entity, ecs_id(TileSize), igTileSize);
|
||||
igInspectComp("Owner", entity, ecs_id(Owner), igOwner);
|
||||
igInspectComp("SpatialGridID", entity, ecs_id(SpatialGridID), igSpatialGridID);
|
||||
igInspectComp("Position", entity, ecs_id(Position), igVec2Comp);
|
||||
@@ -735,11 +736,13 @@ void imguiRender(float dt, void *userData) {
|
||||
igText("Population: %lld", game->resources.pop);
|
||||
}
|
||||
if (igCollapsingHeader_TreeNodeFlags("BuildMenu", 0)) {
|
||||
for (int i = 0; i < BUILDING_COUNT; i++) {
|
||||
if (igSelectable_Bool(getBuildingStr(i), input->building == i, 0, (ImVec2){0, 0}))
|
||||
for (int i = BUILDING_NONE; i < BUILDING_COUNT; i++) {
|
||||
const char *buildingStr = getBuildingStr(i);
|
||||
if (!buildingStr) buildingStr = "NONE";
|
||||
if (igSelectable_Bool(buildingStr, input->building == i, 0, (ImVec2){0, 0}))
|
||||
input->building = i;
|
||||
}
|
||||
if (input->building)
|
||||
if (input->building > BUILDING_NONE && input->building < BUILDING_COUNT)
|
||||
input->state = INPUT_BUILDING;
|
||||
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
#include <flecs.h>
|
||||
|
||||
#include "buildings.h"
|
||||
#include "components.h"
|
||||
#include "entity_factory.h"
|
||||
#include "game_state.h"
|
||||
@@ -60,40 +61,24 @@ bool initBuildingsLayer(BzTileMap *map, BzTileLayer *layer) {
|
||||
BzTileset *buildingTileset = bzTileLayerGetTileset(map, buildingLayer);
|
||||
BzTile *data = layer->data;
|
||||
BzTile *buildingData = buildingLayer->data;
|
||||
BZ_ASSERT(ownershipLayer->tilesetIdx == buildingLayer->tilesetIdx);
|
||||
|
||||
for (i32 y = 0; y < layer->height; y++) {
|
||||
for (i32 x = 0; x < layer->width; x++) {
|
||||
BzTile ownerTile = data[y * layer->width + x];
|
||||
BzTile ownerRawTile = data[y * layer->width + x];
|
||||
BzTileID owner = bzTilesetGetTileID(buildingTileset, ownerRawTile);
|
||||
BzTile buildingRawTile = buildingData[y * layer->width + x];
|
||||
BzTile buildingTile = bzTilesetGetTileID(buildingTileset, buildingRawTile);
|
||||
buildingTile = getTileBuilding(buildingTile);
|
||||
if (buildingTile == BUILDING_NONE || ownerTile == 0) continue;
|
||||
// We have a building
|
||||
TileSize tileSize = {};
|
||||
getBuildingSize(buildingTile, &tileSize.sizeX, &tileSize.sizeY);
|
||||
bzTileLayerSetTile(ownershipLayer, 0, x, y, tileSize.sizeX, tileSize.sizeY);
|
||||
BzTile buildingType = bzTilesetGetTileID(buildingTileset, buildingRawTile);
|
||||
buildingType = getTileBuilding(buildingType);
|
||||
if (buildingType <= BUILDING_NONE || buildingType >= BUILDING_COUNT)
|
||||
continue;
|
||||
placeBuilding(game, buildingType, x, y, (Owner) {owner});
|
||||
|
||||
const i32 tileWidth = map->tileWidth;
|
||||
const i32 tileHeight = map->tileHeight;
|
||||
ecs_entity_t e = entityCreateEmpty();
|
||||
Size size = {.x = tileSize.sizeX * tileWidth, .y = tileSize.sizeY * tileHeight };
|
||||
ecs_set_ptr(ECS, e, Size, &size);
|
||||
ecs_set(ECS, e, Position, {
|
||||
.x = x * tileWidth + size.x * 0.5f,
|
||||
.y = y * tileHeight + size.y * 0.5f
|
||||
});
|
||||
ownerTile = bzTilesetGetTileID(buildingTileset, ownerTile);
|
||||
ownerTile = getTileBuilding(ownerTile);
|
||||
ecs_set(ECS, e, Owner, {.playerID=ownerTile});
|
||||
ecs_add_id(ECS, e, Selectable);
|
||||
//if (buildingTile == BUILDINGS_WAREHOUSE) {
|
||||
// ecs_set(ECS, e, Storage, {});
|
||||
//}
|
||||
if (buildingTile == BUILDING_KEEP) {
|
||||
ecs_add_id(ECS, e, Storage);
|
||||
}
|
||||
|
||||
//bzTileMapUpdateCollider(&GAME.map, x, y);
|
||||
i32 sizeX = 1;
|
||||
i32 sizeY = 1;
|
||||
getBuildingSize(buildingType, &sizeX, &sizeY);
|
||||
x += sizeX - 1;
|
||||
y += sizeY - 1;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
#include <raymath.h>
|
||||
|
||||
static i32 dst(TilePosition a, TilePosition b) {
|
||||
static i32 dst(Vec2i a, Vec2i b) {
|
||||
//i32 dX = a.x - b.x;
|
||||
//i32 dY = a.y - b.y;
|
||||
//return dX * dX + dY * dY;
|
||||
@@ -126,9 +126,8 @@ bool pathfindAStar(const PathfindingDesc *desc) {
|
||||
BZ_ASSERT(desc->alloc);
|
||||
BzTileMap *map = desc->map;
|
||||
|
||||
TilePosition start = {0}, target = {0};
|
||||
bzTileMapPosToTile(map, desc->start, &start.x, &start.y);
|
||||
bzTileMapPosToTile(map, desc->target, &target.x, &target.y);
|
||||
Vec2i start = bzTileMapPosToTile(map, desc->start);
|
||||
Vec2i target = bzTileMapPosToTile(map, desc->target);
|
||||
BZ_ASSERT(start.x >= 0 && start.x < map->width);
|
||||
BZ_ASSERT(start.y >= 0 && start.y < map->height);
|
||||
|
||||
@@ -178,7 +177,7 @@ bool pathfindAStar(const PathfindingDesc *desc) {
|
||||
foundPath = true;
|
||||
break;
|
||||
}
|
||||
TilePosition pos = node.pos;
|
||||
Vec2i pos = node.pos;
|
||||
PathNodeRecord *nodeRecord = &closedSet[pos.y * map->width + pos.x];
|
||||
nodeRecord->visited = true;
|
||||
nodeRecord->open = false;
|
||||
@@ -199,7 +198,7 @@ bool pathfindAStar(const PathfindingDesc *desc) {
|
||||
if (curRecord->visited)
|
||||
continue;
|
||||
|
||||
TilePosition curPos = {x, y};
|
||||
Vec2i curPos = {x, y};
|
||||
i32 gCost = node.gCost + dst(node.pos, curPos);
|
||||
if (curRecord->open) {
|
||||
i32 nodeIdx = curRecord->nodeIdx;
|
||||
@@ -234,7 +233,7 @@ bool pathfindAStar(const PathfindingDesc *desc) {
|
||||
|
||||
i32 pathLen = 0;
|
||||
if (foundPath && desc->outPath) {
|
||||
TilePosition pos = target;
|
||||
Vec2i pos = target;
|
||||
Path *out = desc->outPath;
|
||||
out->curWaypoint = 0;
|
||||
BZ_ASSERT(desc->pool);
|
||||
@@ -282,8 +281,8 @@ static void heapSwap(Heap *heap, i32 left, i32 right) {
|
||||
heap->arr[left] = heap->arr[right];
|
||||
heap->arr[right] = tmp;
|
||||
|
||||
TilePosition leftPos = heap->arr[left].pos;
|
||||
TilePosition rightPos = heap->arr[right].pos;
|
||||
Vec2i leftPos = heap->arr[left].pos;
|
||||
Vec2i rightPos = heap->arr[right].pos;
|
||||
|
||||
i32 leftIdx = leftPos.y * heap->mapWidth + leftPos.x;
|
||||
i32 rightIdx = rightPos.y * heap->mapWidth + rightPos.x;
|
||||
@@ -339,7 +338,7 @@ static void heapPush(Heap *heap, PathNode node) {
|
||||
heap->arr[heap->size] = node;
|
||||
heap->size++;
|
||||
|
||||
TilePosition pos = node.pos;
|
||||
Vec2i pos = node.pos;
|
||||
PathNodeRecord *record = &heap->records[pos.y * heap->mapWidth + pos.x];
|
||||
record->nodeIdx = heap->size - 1;
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@ typedef struct PathNode {
|
||||
i32 weight; // fCost = g + h
|
||||
i32 gCost; // from start cost
|
||||
i32 hCost; // to target cost
|
||||
TilePosition pos;
|
||||
Vec2i pos;
|
||||
} PathNode;
|
||||
|
||||
typedef struct PathNodeRecord {
|
||||
|
||||
@@ -11,9 +11,6 @@
|
||||
#include <raymath.h>
|
||||
#include <rlgl.h>
|
||||
|
||||
Rectangle calculateEntityBounds(Position pos, Size size);
|
||||
bool getEntityBounds(ecs_entity_t entity, Position *outPos, Size *outSize, Rectangle *outBounds);
|
||||
|
||||
ecs_entity_t queryEntity(BzSpatialGrid *entityGrid, Vector2 point, ecs_entity_t tag);
|
||||
|
||||
bool selectEntity(BzSpatialGrid *entityGrid, Vector2 point, ecs_entity_t tag);
|
||||
@@ -29,7 +26,7 @@ void placeUnits(i32 numUnits, f32 unitSpacing, Vector2 start, Vector2 end, BzTil
|
||||
void resetInputState(InputState *input) {
|
||||
input->cursor = CURSOR_NONE;
|
||||
input->state = INPUT_NONE;
|
||||
input->building = 0;
|
||||
input->building = BUILDING_NONE;
|
||||
}
|
||||
|
||||
void inputPrimaryAction(Game *game, InputState *input) {
|
||||
@@ -218,8 +215,9 @@ void updatePlayerInput() {
|
||||
|
||||
BzTileMap *map = &game->map;
|
||||
|
||||
BzTile tileX = 0, tileY = 0;
|
||||
bzTileMapPosToTile(map, input->mouseWorld, &tileX, &tileY);
|
||||
Vec2i tileXY = bzTileMapPosToTile(map, input->mouseWorld);
|
||||
BzTile tileX = tileXY.x;
|
||||
BzTile tileY = tileXY.y;
|
||||
|
||||
const MouseButton primaryBtn = input->mapping.primaryBtn;
|
||||
const MouseButton secondaryBtn = input->mapping.secondaryBtn;
|
||||
@@ -230,16 +228,19 @@ void updatePlayerInput() {
|
||||
break;
|
||||
}
|
||||
case INPUT_BUILDING: {
|
||||
BZ_ASSERT(input->building);
|
||||
if (input->building <= BUILDING_NONE || input->building >= BUILDING_COUNT) {
|
||||
input->state = INPUT_NONE;
|
||||
return;
|
||||
}
|
||||
BzTile sizeX = 0, sizeY = 0;
|
||||
getBuildingSize(input->building, &sizeX, &sizeY);
|
||||
bool canPlace = canPlaceBuilding(&game->map, input->building, tileX, tileY);
|
||||
bool canPlace = canPlaceBuilding(game, input->building, tileX, tileY);
|
||||
if (canPlace && isInputBtnDown(input, primaryBtn)) {
|
||||
placeBuilding(&game->map, input->building, tileX, tileY);
|
||||
placeBuilding(game, input->building, tileX, tileY, (Owner) {-1});
|
||||
}
|
||||
input->buildingCanPlace = canPlace;
|
||||
input->buildingPos = (TilePosition) {tileX, tileY};
|
||||
input->buildingSize = (TileSize) {sizeX, sizeY};
|
||||
input->buildingPos = (Vec2i) {tileX, tileY};
|
||||
input->buildingSize = (Vec2i) {sizeX, sizeY};
|
||||
break;
|
||||
}
|
||||
case INPUT_SELECTED_UNITS: {
|
||||
@@ -278,8 +279,8 @@ void drawPlayerInputUIGround() {
|
||||
const BzTile height = game->map.tileHeight;
|
||||
DrawRectangleLines(input->buildingPos.x * width,
|
||||
input->buildingPos.y * height,
|
||||
input->buildingSize.sizeX * width,
|
||||
input->buildingSize.sizeY * height, placeColor);
|
||||
input->buildingSize.x * width,
|
||||
input->buildingSize.y * height, placeColor);
|
||||
break;
|
||||
}
|
||||
default: break;
|
||||
@@ -323,41 +324,6 @@ void drawPlayerInputUI() {
|
||||
|
||||
}
|
||||
|
||||
|
||||
Rectangle calculateEntityBounds(Position pos, Size size) {
|
||||
return (Rectangle) {
|
||||
pos.x - size.x * 0.5f,
|
||||
pos.y - size.x * 0.5f,
|
||||
size.x, size.y
|
||||
};
|
||||
}
|
||||
|
||||
bool getEntityBounds(ecs_entity_t entity, Position *outPos, Size *outSize, Rectangle *outBounds) {
|
||||
if (!ecs_is_alive(ECS, entity))
|
||||
return false;
|
||||
const Position *pos = ecs_get(ECS, entity, Position);
|
||||
if (!pos)
|
||||
return false;
|
||||
const Size *size = ecs_get(ECS, entity, Size);
|
||||
if (!size)
|
||||
return false;
|
||||
|
||||
if (outPos) {
|
||||
*outPos = *pos;
|
||||
}
|
||||
if (outSize) {
|
||||
*outSize = *size;
|
||||
}
|
||||
if (outBounds) {
|
||||
*outBounds = (Rectangle) {
|
||||
pos->x - size->x * 0.5f,
|
||||
pos->y - size->y * 0.5f,
|
||||
size->x, size->y
|
||||
};
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
ecs_entity_t queryEntity(BzSpatialGrid *entityGrid, Vector2 point, ecs_entity_t tag) {
|
||||
BzSpatialGridIter it = bzSpatialGridIter(entityGrid, point.x, point.y, 0.0f, 0.0f);
|
||||
f32 closestDst = INFINITY;
|
||||
|
||||
@@ -2,6 +2,40 @@
|
||||
|
||||
#include "../game_state.h"
|
||||
|
||||
Rectangle calculateEntityBounds(Position pos, Size size) {
|
||||
return (Rectangle) {
|
||||
pos.x - size.x * 0.5f,
|
||||
pos.y - size.x * 0.5f,
|
||||
size.x, size.y
|
||||
};
|
||||
}
|
||||
|
||||
bool getEntityBounds(ecs_entity_t entity, Position *outPos, Size *outSize, Rectangle *outBounds) {
|
||||
if (!ecs_is_alive(ECS, entity))
|
||||
return false;
|
||||
const Position *pos = ecs_get(ECS, entity, Position);
|
||||
if (!pos)
|
||||
return false;
|
||||
const Size *size = ecs_get(ECS, entity, Size);
|
||||
if (!size)
|
||||
return false;
|
||||
|
||||
if (outPos) {
|
||||
*outPos = *pos;
|
||||
}
|
||||
if (outSize) {
|
||||
*outSize = *size;
|
||||
}
|
||||
if (outBounds) {
|
||||
*outBounds = (Rectangle) {
|
||||
pos->x - size->x * 0.5f,
|
||||
pos->y - size->y * 0.5f,
|
||||
size->x, size->y
|
||||
};
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
ecs_entity_t renderCollidersSystem;
|
||||
ecs_entity_t renderOrientDirSystem;
|
||||
ecs_entity_t renderArmPositionSystem;
|
||||
@@ -37,6 +71,7 @@ ECS_DTOR(Arms, arms, {
|
||||
ecs_delete(ECS, arms->secondary);
|
||||
arms->secondary = 0;
|
||||
}
|
||||
|
||||
})
|
||||
ECS_MOVE(Arms, dst, src, {
|
||||
*dst = *src;
|
||||
|
||||
@@ -171,6 +171,13 @@ void drawPlayerInputUI();
|
||||
* UI systems
|
||||
**********************************/
|
||||
|
||||
/**********************************
|
||||
* Utils
|
||||
**********************************/
|
||||
|
||||
Rectangle calculateEntityBounds(Position pos, Size size);
|
||||
bool getEntityBounds(ecs_entity_t entity, Position *outPos, Size *outSize, Rectangle *outBounds);
|
||||
|
||||
/**********************************
|
||||
* MISC
|
||||
**********************************/
|
||||
|
||||
@@ -5,7 +5,10 @@
|
||||
#include <stdio.h>
|
||||
|
||||
f32 uiGetScale() {
|
||||
return GetScreenHeight() / 720.0f;
|
||||
// Assuming 16:9 aspect
|
||||
f32 scaleX = GetScreenWidth() / 1280.0f;
|
||||
f32 scaleY = GetScreenHeight() / 720.0f;
|
||||
return BZ_MIN(scaleX, scaleY);
|
||||
}
|
||||
|
||||
Font getFont() {
|
||||
|
||||
@@ -62,7 +62,10 @@ class ExtractFileWriter:
|
||||
def enum_list(self, name, enums):
|
||||
self.enum_start(name)
|
||||
for enum in enums:
|
||||
self.content += f"{self.indention}{enum},\n"
|
||||
if enum.endswith("_NONE"):
|
||||
self.content += f"{self.indention}{enum} = -1,\n"
|
||||
else:
|
||||
self.content += f"{self.indention}{enum},\n"
|
||||
self.enum_stop(name)
|
||||
|
||||
def enum_dict(self, name, enums):
|
||||
@@ -107,9 +110,9 @@ class EnumWriter:
|
||||
self.all_tiles = tiles
|
||||
self.tiles = group_by_class(tiles)
|
||||
self.enums = []
|
||||
self.enums.append(self.to_enum("none"))
|
||||
self.enums += [self.to_enum(x) for x in self.tiles.keys()]
|
||||
self.enums.append(self.to_enum("count"))
|
||||
self.enums.append(self.to_enum("none"))
|
||||
self.enum_type = f"{prefix.capitalize()}Type"
|
||||
if anim_prefix:
|
||||
self.anim_prefix = anim_prefix
|
||||
|
||||
Reference in New Issue
Block a user