Implement sub-tile collboxes

These will be later used by the pathfinding algorithm.
This commit is contained in:
Xavier Del Campo Romero 2022-03-30 08:28:47 +02:00
parent 638dbd0af1
commit 82c61e3d1d
9 changed files with 104 additions and 7 deletions

View File

@ -1,3 +1,3 @@
add_library(building "src/building.c")
target_include_directories(building PUBLIC "inc")
target_link_libraries(building PUBLIC gfx instance camera)
target_link_libraries(building PUBLIC gfx instance camera util)

View File

@ -5,6 +5,7 @@
#include <camera.h>
#include <gfx.h>
#include <instance.h>
#include <util.h>
#include <stdbool.h>
#include <stddef.h>
@ -28,6 +29,7 @@ struct building_cfg
};
void building_create(const struct building_cfg *cfg, struct building *b);
void building_set_alive_cb(void (*f)(const struct util_rect *dim, bool alive, void *p), void *p);
int building_render(const struct building *b, const struct camera *cam, bool sel);
instance_hp building_maxhp(const struct building *b);
const char *building_str(const struct building *b);

View File

@ -56,6 +56,9 @@ static void get_dimensions(const enum building_type type, short *const w,
*h = d->h;
}
static void *op;
static void (*cb)(const struct util_rect *, bool, void *);
void building_create(const struct building_cfg *const cfg,
struct building *const b)
{
@ -67,6 +70,16 @@ void building_create(const struct building_cfg *const cfg,
i->r.y = cfg->y;
i->alive = true;
i->hp = building_maxhp(b);
if (cb)
cb(&i->r, i->alive, op);
}
void building_set_alive_cb(void (*const f)(const struct util_rect *, bool, void *),
void *const p)
{
cb = f;
op = p;
}
const char *building_str(const struct building *const b)

View File

@ -17,6 +17,10 @@ int game(void)
enum {HUMAN_PLAYERS = 1, MAP_RESOURCES = 3};
struct human_player humans[HUMAN_PLAYERS];
struct terrain_map map;
terrain_init(&map);
building_set_alive_cb(terrain_block_update, &map);
for (size_t i = 0; i < sizeof humans / sizeof *humans; i++)
{
@ -36,10 +40,9 @@ int game(void)
goto end;
}
struct terrain_map map;
struct resource res[MAP_RESOURCES] = {0};
terrain_init(&map);
resource_set_alive_cb(terrain_block_update, &map);
if (resource_create(&(const struct resource_cfg)
{

View File

@ -41,6 +41,7 @@ struct resource_cfg
};
const struct container_list *resource_res(void);
void resource_set_alive_cb(void (*f)(const struct util_rect *dim, bool alive, void *p), void *p);
int resource_create(const struct resource_cfg *cfg, struct resource *list, size_t n);
int resource_render(const struct resource *res, const struct camera *cam, bool sel);
instance_sheltered_cb resource_shelter(const struct resource *res);

View File

@ -5,6 +5,8 @@
#include <stddef.h>
struct sprite resource_sprites[MAX_RESOURCE_TYPES];
static void (*cb)(const struct util_rect *, bool, void *);
static void *op;
static bool gold_shelter(struct instance *const self,
struct instance *const other)
@ -39,7 +41,12 @@ instance_sheltered_cb resource_shelter(const struct resource *res)
bool resource_harvested(struct instance *const self, const instance_hp ap)
{
return instance_attacked(self, ap);
const bool ret = instance_attacked(self, ap);
if (ret && cb)
cb(&self->r, self->alive, op);
return ret;
}
instance_hp resource_maxhp(const struct resource *const res)
@ -120,6 +127,10 @@ int resource_create(const struct resource_cfg *const cfg, struct resource *const
in->r.y = cfg->y;
in->alive = true;
in->hp = resource_maxhp(r);
if (cb)
cb(&in->r, in->alive, op);
return 0;
}
}
@ -127,6 +138,13 @@ int resource_create(const struct resource_cfg *const cfg, struct resource *const
return -1;
}
void resource_set_alive_cb(void (*const f)(const struct util_rect *, bool, void *),
void *const p)
{
cb = f;
op = p;
}
const char *resource_str(const struct resource *const res)
{
static const char *const str[] =

View File

@ -1,3 +1,3 @@
add_library(terrain "src/terrain.c")
target_include_directories(terrain PUBLIC "inc")
target_link_libraries(terrain PUBLIC container camera gfx)
target_link_libraries(terrain PUBLIC container camera gfx util)

View File

@ -3,6 +3,7 @@
#include <camera.h>
#include <gfx.h>
#include <util.h>
#include <stddef.h>
#ifdef __cplusplus
@ -25,13 +26,19 @@ enum terrain_type
struct terrain_map
{
enum terrain_type m[MAP_TILES][MAP_TILES];
struct terrain_tile
{
enum terrain_type t;
unsigned char bl;
} m[MAP_TILES][MAP_TILES];
int nx, ny, last_w, last_h;
};
void terrain_init(struct terrain_map *map);
void terrain_update(struct terrain_map *map);
int terrain_render(const struct terrain_map *map, const struct camera *cam);
void terrain_block_update(const struct util_rect *dim, bool alive, void *p);
extern struct sprite grass_sprite;

View File

@ -1,6 +1,7 @@
#include <terrain.h>
#include <camera.h>
#include <gfx.h>
#include <util.h>
#include <stddef.h>
#include <stdlib.h>
#include <string.h>
@ -26,6 +27,56 @@ void terrain_update(struct terrain_map *const map)
}
}
struct block
{
size_t x0, x1, y0, y1;
};
void terrain_block_update(const struct util_rect *const dim, const bool alive,
void *const p)
{
const struct block b =
{
.x0 = dim->x / TERRAIN_SZ,
.x1 = (dim->x + dim->w) / TERRAIN_SZ,
.y0 = dim->y / TERRAIN_SZ,
.y1 = (dim->y + dim->h) / TERRAIN_SZ
};
for (size_t x = b.x0; x <= b.x1; x++)
for (size_t y = b.y0; y <= b.y1; y++)
for (size_t i = 0; i < 2; i++)
for (size_t j = 0; j < 2; j++)
{
const struct util_rect sub =
{
.x = x * TERRAIN_SZ + i * (TERRAIN_SZ / 2),
.y = y * TERRAIN_SZ + j * (TERRAIN_SZ / 2),
.w = TERRAIN_SZ / 2,
.h = TERRAIN_SZ / 2
};
if (util_collision(dim, &sub))
{
const enum
{
NO_SUB = 0,
UPPER_LEFT = 1 << 0,
UPPER_RIGHT = 1 << 1,
LOWER_LEFT = 1 << 2,
LOWER_RIGHT = 1 << 3,
ALL_BLOCKS = UPPER_LEFT | UPPER_RIGHT
| LOWER_LEFT | LOWER_RIGHT
} sub = 1 << (i + j * 2);
struct terrain_map *const map = p;
unsigned char *const bl = &map->m[y][x].bl;
*bl = alive ? *bl | sub : *bl & ~sub;
}
}
}
int terrain_render(const struct terrain_map *const map,
const struct camera *const cam)
{
@ -54,9 +105,11 @@ int terrain_render(const struct terrain_map *const map,
for (struct m y = {.i = start_y, .p = remy};
y.i < ny + start_y; y.i++, y.p += TERRAIN_SZ)
{
const struct terrain_tile *const t = &map->m[y.i][x.i];
sprite_get_or_ret(s, -1);
switch (map->m[y.i][x.i])
switch (t->t)
{
case TERRAIN_TYPE_GRASS:
if (sprite_clone(&grass_sprite, s))