diff options
| author | Xavier Del Campo Romero <xavi.dcr@tutanota.com> | 2022-03-30 08:28:47 +0200 |
|---|---|---|
| committer | Xavier Del Campo Romero <xavi.dcr@tutanota.com> | 2022-03-30 08:28:47 +0200 |
| commit | 1950fe7b0679c6b6486cc7b25bef813db2b1bb4e (patch) | |
| tree | c2098c9ec65f9a9e5fada68c0b51b0217f14b00c /src | |
| parent | 06056a9b5e900f67702c509ce1ba2e2351357fb7 (diff) | |
| download | jancity-1950fe7b0679c6b6486cc7b25bef813db2b1bb4e.tar.gz | |
Implement sub-tile collboxes
These will be later used by the pathfinding algorithm.
Diffstat (limited to 'src')
| -rw-r--r-- | src/building/CMakeLists.txt | 2 | ||||
| -rw-r--r-- | src/building/inc/building.h | 2 | ||||
| -rw-r--r-- | src/building/src/building.c | 13 | ||||
| -rw-r--r-- | src/game/src/game.c | 7 | ||||
| -rw-r--r-- | src/resource/inc/resource.h | 1 | ||||
| -rw-r--r-- | src/resource/src/resource.c | 20 | ||||
| -rw-r--r-- | src/terrain/CMakeLists.txt | 2 | ||||
| -rw-r--r-- | src/terrain/inc/terrain.h | 9 | ||||
| -rw-r--r-- | src/terrain/src/terrain.c | 55 |
9 files changed, 104 insertions, 7 deletions
diff --git a/src/building/CMakeLists.txt b/src/building/CMakeLists.txt index 3eb352e..5bfa674 100644 --- a/src/building/CMakeLists.txt +++ b/src/building/CMakeLists.txt @@ -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) diff --git a/src/building/inc/building.h b/src/building/inc/building.h index 7763b7d..a0ab539 100644 --- a/src/building/inc/building.h +++ b/src/building/inc/building.h @@ -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); diff --git a/src/building/src/building.c b/src/building/src/building.c index 5b94ee3..5ff9183 100644 --- a/src/building/src/building.c +++ b/src/building/src/building.c @@ -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) diff --git a/src/game/src/game.c b/src/game/src/game.c index 3145c91..b583c5c 100644 --- a/src/game/src/game.c +++ b/src/game/src/game.c @@ -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) { diff --git a/src/resource/inc/resource.h b/src/resource/inc/resource.h index 56da45e..aa7f1bd 100644 --- a/src/resource/inc/resource.h +++ b/src/resource/inc/resource.h @@ -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); diff --git a/src/resource/src/resource.c b/src/resource/src/resource.c index ae0b528..40f2301 100644 --- a/src/resource/src/resource.c +++ b/src/resource/src/resource.c @@ -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[] = diff --git a/src/terrain/CMakeLists.txt b/src/terrain/CMakeLists.txt index c74de94..7a0e5bd 100644 --- a/src/terrain/CMakeLists.txt +++ b/src/terrain/CMakeLists.txt @@ -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) diff --git a/src/terrain/inc/terrain.h b/src/terrain/inc/terrain.h index 508fe25..fbe8af8 100644 --- a/src/terrain/inc/terrain.h +++ b/src/terrain/inc/terrain.h @@ -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; diff --git a/src/terrain/src/terrain.c b/src/terrain/src/terrain.c index 23c4015..8f1924c 100644 --- a/src/terrain/src/terrain.c +++ b/src/terrain/src/terrain.c @@ -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)) |
