aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorXavier Del Campo Romero <xavi.dcr@tutanota.com>2022-03-30 08:28:47 +0200
committerXavier Del Campo Romero <xavi.dcr@tutanota.com>2022-03-30 08:28:47 +0200
commit1950fe7b0679c6b6486cc7b25bef813db2b1bb4e (patch)
treec2098c9ec65f9a9e5fada68c0b51b0217f14b00c /src
parent06056a9b5e900f67702c509ce1ba2e2351357fb7 (diff)
downloadjancity-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.txt2
-rw-r--r--src/building/inc/building.h2
-rw-r--r--src/building/src/building.c13
-rw-r--r--src/game/src/game.c7
-rw-r--r--src/resource/inc/resource.h1
-rw-r--r--src/resource/src/resource.c20
-rw-r--r--src/terrain/CMakeLists.txt2
-rw-r--r--src/terrain/inc/terrain.h9
-rw-r--r--src/terrain/src/terrain.c55
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))