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