Properly handle map collisions when placing/destroying buildings
This commit is contained in:
@@ -508,7 +508,19 @@ bool bzTileMapHasCollision(BzTileMap *map, i32 x, i32 y) {
|
||||
i32 idx = y * map->width + x;
|
||||
return map->collisionMap[idx];
|
||||
}
|
||||
void bzTileMapSetCollisions(BzTileMap *map, bool collision, i32 startX, i32 startY, i32 sizeX, i32 sizeY) {
|
||||
i32 endX = startX + sizeX;
|
||||
i32 endY = startY + sizeY;
|
||||
BZ_ASSERT(map->collisionMap);
|
||||
BZ_ASSERT(startX >= 0 && endX <= map->width &&
|
||||
startY >= 0 && endY <= map->height);
|
||||
|
||||
for (i32 y = startY; y < endY; y++) {
|
||||
for (i32 x = startX; x < endX; x++) {
|
||||
map->collisionMap[y * map->width + x] = collision;
|
||||
}
|
||||
}
|
||||
}
|
||||
void bzTileMapUpdateCollisions(BzTileMap *map, i32 x, i32 y, i32 sizeX, i32 sizeY) {
|
||||
if (!map->collisionMap) return;
|
||||
updateCollisionMap(map, x, y, x + sizeX, y + sizeY);
|
||||
|
||||
@@ -131,6 +131,7 @@ bool bzTileMapCanRayCastLine(BzTileMap *map, Vector2 from, Vector2 to);
|
||||
void bzTileMapDraw(BzTileMap *map);
|
||||
void bzTileMapDrawCollisions(BzTileMap *map);
|
||||
bool bzTileMapHasCollision(BzTileMap *map, i32 x, i32 y);
|
||||
void bzTileMapSetCollisions(BzTileMap *map, bool collision, i32 startX, i32 startY, i32 sizeX, i32 sizeY);
|
||||
void bzTileMapUpdateCollisions(BzTileMap *map, i32 x, i32 y, i32 sizeX, i32 sizeY);
|
||||
|
||||
|
||||
|
||||
@@ -34,7 +34,7 @@ bool canPlaceBuilding(Game *game, BuildingType type, BzTile tileX, BzTile tileY)
|
||||
}
|
||||
|
||||
ecs_entity_t placeBuilding(Game *game, BuildingType type,
|
||||
BzTile tileX, BzTile tileY, Owner owner) {
|
||||
BzTile posX, BzTile posY, Owner owner) {
|
||||
if (type <= BUILDING_NONE || type >= BUILDING_COUNT)
|
||||
return 0;
|
||||
i32 sizeX, sizeY;
|
||||
@@ -45,9 +45,15 @@ ecs_entity_t placeBuilding(Game *game, BuildingType type,
|
||||
|
||||
// Create entity
|
||||
ecs_entity_t building = entityCreateEmpty();
|
||||
ecs_add_id(ECS, building, Selectable);
|
||||
ecs_set(ECS, building, Building, {
|
||||
.type = type,
|
||||
.pos = (Vec2i) { posX, posY },
|
||||
.size = (Vec2i) { sizeX, sizeY }
|
||||
});
|
||||
Position pos = {
|
||||
.x = tileX * tileWidth + sizeX * tileWidth * 0.5f,
|
||||
.y = tileY * tileHeight + sizeY * tileHeight * 0.5f
|
||||
.x = posX * tileWidth + sizeX * tileWidth * 0.5f,
|
||||
.y = posY * tileHeight + sizeY * tileHeight * 0.5f
|
||||
};
|
||||
Size size = {
|
||||
.x = sizeX * tileWidth,
|
||||
@@ -72,6 +78,8 @@ ecs_entity_t placeBuilding(Game *game, BuildingType type,
|
||||
region.rec.height *= sizeY;
|
||||
ecs_set_ptr(ECS, building, TextureRegion, ®ion);
|
||||
|
||||
bzTileMapSetCollisions(&game->map, true, posX, posY, sizeX, sizeY);
|
||||
|
||||
switch (type) {
|
||||
case BUILDING_KEEP:
|
||||
ecs_add_id(ECS, building, Storage);
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
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);
|
||||
ecs_entity_t placeBuilding(Game *game, BuildingType type, i32 posX, i32 posY, Owner owner);
|
||||
|
||||
Vector2 getPositionNearBuilding(ecs_entity_t building, Vector2 fromPos);
|
||||
|
||||
|
||||
@@ -33,6 +33,7 @@ ECS_TAG_DECLARE(Selectable);
|
||||
ECS_TAG_DECLARE(Selected);
|
||||
|
||||
ECS_COMPONENT_DECLARE(Worker);
|
||||
ECS_COMPONENT_DECLARE(Building);
|
||||
ECS_COMPONENT_DECLARE(Unit);
|
||||
ECS_TAG_DECLARE(Storage);
|
||||
ECS_TAG_DECLARE(Harvestable);
|
||||
@@ -71,6 +72,7 @@ void initComponentIDs(ecs_world_t *ecs) {
|
||||
ECS_TAG_DEFINE(ecs, Selected);
|
||||
|
||||
ECS_COMPONENT_DEFINE(ecs, Worker);
|
||||
ECS_COMPONENT_DEFINE(ecs, Building);
|
||||
ECS_COMPONENT_DEFINE(ecs, Unit);
|
||||
ECS_TAG_DEFINE(ecs, Storage);
|
||||
ECS_TAG_DEFINE(ecs, Harvestable);
|
||||
|
||||
@@ -189,6 +189,12 @@ typedef struct Unit {
|
||||
f32 deceleration;
|
||||
} Unit;
|
||||
extern ECS_COMPONENT_DECLARE(Unit);
|
||||
typedef struct Building {
|
||||
BuildingType type;
|
||||
Vec2i pos;
|
||||
Vec2i size;
|
||||
} Building;
|
||||
extern ECS_COMPONENT_DECLARE(Building);
|
||||
extern ECS_TAG_DECLARE(Storage);
|
||||
extern ECS_TAG_DECLARE(Harvestable);
|
||||
extern ECS_TAG_DECLARE(Buildable);
|
||||
|
||||
10
game/main.c
10
game/main.c
@@ -645,6 +645,12 @@ void igInspectWindow(ecs_entity_t entity, bool *open) {
|
||||
char buf[64];
|
||||
snprintf(buf, sizeof(buf), "Entity: %ld", entity);
|
||||
if (igBegin(buf, open, 0)) {
|
||||
if (igSmallButton("Destroy")) {
|
||||
ecs_delete(ECS, entity);
|
||||
igEnd();
|
||||
*open = false;
|
||||
return;
|
||||
}
|
||||
if (igCollapsingHeader_TreeNodeFlags("Tags", 0)) {
|
||||
//igTagCheckbox("GameEntity", ECS, entity, GameEntity);
|
||||
igTagCheckbox("Selectable", ECS, entity, Selectable);
|
||||
@@ -711,7 +717,6 @@ void imguiRender(float dt, void *userData) {
|
||||
case INPUT_SELECTED_UNITS:
|
||||
case INPUT_SELECTED_OBJECT:
|
||||
case INPUT_SELECTED_BUILDING: {
|
||||
ecs_defer_begin(ECS);
|
||||
ecs_iter_t it = ecs_query_iter(ECS, input->queries.selected);
|
||||
while (ecs_iter_next(&it)) {
|
||||
for (i32 i = 0; i < it.count; i++) {
|
||||
@@ -719,7 +724,6 @@ void imguiRender(float dt, void *userData) {
|
||||
igText("Entity: %ld", entity);
|
||||
}
|
||||
}
|
||||
ecs_defer_end(ECS);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
@@ -761,6 +765,7 @@ void imguiRender(float dt, void *userData) {
|
||||
}
|
||||
igEnd();
|
||||
|
||||
ecs_defer_begin(ECS);
|
||||
i32 inspectLen = bzArraySize(game->debug.inspecting);
|
||||
for (i32 i = inspectLen - 1; i >= 0; i--) {
|
||||
bool open = true;
|
||||
@@ -769,5 +774,6 @@ void imguiRender(float dt, void *userData) {
|
||||
bzArrayDelSwap(game->debug.inspecting, i);
|
||||
}
|
||||
}
|
||||
ecs_defer_end(ECS);
|
||||
}
|
||||
|
||||
|
||||
@@ -75,7 +75,17 @@ ECS_DTOR(Arms, arms, {
|
||||
})
|
||||
ECS_MOVE(Arms, dst, src, {
|
||||
*dst = *src;
|
||||
});
|
||||
})
|
||||
|
||||
ECS_DTOR(Building, building, {
|
||||
Vec2i pos = building->pos;
|
||||
Vec2i size = building->size;
|
||||
Game *game = ecs_singleton_get_mut(ECS, Game);
|
||||
bzTileMapSetCollisions(&game->map, false, pos.x, pos.y, size.x, size.y);
|
||||
})
|
||||
ECS_MOVE(Building, dst, src, {
|
||||
*dst = *src;
|
||||
})
|
||||
|
||||
void setupSystems() {
|
||||
ecs_set_hooks(ECS, SpatialGridID, {
|
||||
@@ -90,6 +100,10 @@ void setupSystems() {
|
||||
.dtor = ecs_dtor(Arms),
|
||||
.move_dtor = ecs_move(Arms)
|
||||
});
|
||||
ecs_set_hooks(ECS, Building, {
|
||||
.dtor = ecs_dtor(Building),
|
||||
.move_dtor = ecs_move(Building)
|
||||
});
|
||||
|
||||
ECS_OBSERVER(ECS, entityPathRemove, EcsOnRemove, Path);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user