aboutsummaryrefslogtreecommitdiff
path: root/src/resource
diff options
context:
space:
mode:
authorXavier Del Campo Romero <xavi.dcr@tutanota.com>2021-07-03 00:49:03 +0200
committerXavier Del Campo Romero <xavi.dcr@tutanota.com>2022-03-30 08:20:20 +0200
commit6b9f686913efc3725b2690033cd4f398e07076ba (patch)
treee9aa91a6b9f617d78123ebe7ad272fc42a60d306 /src/resource
parentc9e6ae44a9aeb89b3f48f3443d6baa80103f7445 (diff)
downloadjancity-6b9f686913efc3725b2690033cd4f398e07076ba.tar.gz
Add project source code
Diffstat (limited to 'src/resource')
-rw-r--r--src/resource/CMakeLists.txt3
-rw-r--r--src/resource/inc/resource.h57
-rw-r--r--src/resource/inc/resource_type.h21
-rw-r--r--src/resource/src/resource.c139
4 files changed, 220 insertions, 0 deletions
diff --git a/src/resource/CMakeLists.txt b/src/resource/CMakeLists.txt
new file mode 100644
index 0000000..1591e58
--- /dev/null
+++ b/src/resource/CMakeLists.txt
@@ -0,0 +1,3 @@
+add_library(resource "src/resource.c")
+target_include_directories(resource PUBLIC "inc")
+target_link_libraries(resource PUBLIC camera gfx instance util)
diff --git a/src/resource/inc/resource.h b/src/resource/inc/resource.h
new file mode 100644
index 0000000..56da45e
--- /dev/null
+++ b/src/resource/inc/resource.h
@@ -0,0 +1,57 @@
+#ifndef RESOURCE_H
+#define RESOURCE_H
+
+#include <camera.h>
+#include <container.h>
+#include <gfx.h>
+#include <instance.h>
+#include <resource_type.h>
+#include <util.h>
+#include <stdbool.h>
+#include <stddef.h>
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+enum {RESOURCE_GOLD_CAPACITY = 2};
+
+struct resource
+{
+ struct instance instance;
+ enum resource_type type;
+
+ union
+ {
+ struct resource_gold
+ {
+ struct instance *miners[RESOURCE_GOLD_CAPACITY];
+ size_t n_miners;
+ } gold;
+ } res;
+};
+
+UTIL_STATIC_ASSERT(!offsetof(struct resource, instance), "must be at offset zero");
+
+struct resource_cfg
+{
+ enum resource_type type;
+ unsigned long x, y;
+};
+
+const struct container_list *resource_res(void);
+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);
+bool resource_harvested(struct instance *i, instance_hp ap);
+instance_hp resource_maxhp(const struct resource *res);
+const char *resource_str(const struct resource *res);
+
+extern struct sprite resource_sprites[MAX_RESOURCE_TYPES];
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* RESOURCE_H */
diff --git a/src/resource/inc/resource_type.h b/src/resource/inc/resource_type.h
new file mode 100644
index 0000000..8a41148
--- /dev/null
+++ b/src/resource/inc/resource_type.h
@@ -0,0 +1,21 @@
+#ifndef RESOURCE_TYPE_H
+#define RESOURCE_TYPE_H
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+enum resource_type
+{
+ RESOURCE_TYPE_WOOD,
+ RESOURCE_TYPE_GOLD,
+
+ MAX_RESOURCE_TYPES
+};
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* RESOURCE_TYPE_H */
diff --git a/src/resource/src/resource.c b/src/resource/src/resource.c
new file mode 100644
index 0000000..dd59bac
--- /dev/null
+++ b/src/resource/src/resource.c
@@ -0,0 +1,139 @@
+#include <resource.h>
+#include <gfx.h>
+#include <instance.h>
+#include <stdbool.h>
+#include <stddef.h>
+
+struct sprite resource_sprites[MAX_RESOURCE_TYPES];
+
+static bool gold_shelter(struct instance *const self,
+ struct instance *const other)
+{
+ struct resource *const res = (struct resource *)self;
+ struct resource_gold *const g = &res->res.gold;
+
+ for (size_t i = 0; i < sizeof g->miners / sizeof *g->miners; i++)
+ {
+ struct instance **const ins = &g->miners[i];
+
+ if (!*ins)
+ {
+ *ins = other;
+ g->n_miners++;
+ return true;
+ }
+ }
+
+ return false;
+}
+
+instance_sheltered_cb resource_shelter(const struct resource *res)
+{
+ static const instance_sheltered_cb s[] =
+ {
+ [RESOURCE_TYPE_GOLD] = gold_shelter
+ };
+
+ return s[res->type];
+}
+
+bool resource_harvested(struct instance *const self, const instance_hp ap)
+{
+ return instance_attacked(self, ap);
+}
+
+instance_hp resource_maxhp(const struct resource *const res)
+{
+ static const instance_hp hp[] =
+ {
+ [RESOURCE_TYPE_GOLD] = 1000,
+ [RESOURCE_TYPE_WOOD] = 45,
+ };
+
+ return hp[res->type];
+}
+
+int resource_render(const struct resource *const res,
+ const struct camera *const cam, const bool sel)
+{
+ const struct instance *const in = &res->instance;
+
+ if (!in->alive)
+ return 0;
+
+ struct sprite *const s = sprite_get();
+
+ if (!s || sprite_clone(&resource_sprites[res->type], s))
+ return -1;
+
+ if (res->type == RESOURCE_TYPE_GOLD)
+ {
+ s->h = in->r.h;
+
+ if (res->res.gold.n_miners)
+ s->v += s->h;
+ }
+
+ const struct instance_render_cfg cfg =
+ {
+ .i = &res->instance,
+ .prim_type = INSTANCE_RENDER_CFG_SPRITE,
+ .prim = {.s = s},
+ .cam = cam,
+ .sel = sel,
+ .max_hp = resource_maxhp(res)
+ };
+
+ return instance_render(&cfg);
+}
+
+static void get_dimensions(const enum resource_type type, short *const w,
+ short *const h)
+{
+ static const struct dim
+ {
+ short w, h;
+ } dim[] =
+ {
+ [RESOURCE_TYPE_GOLD] = {.w = 96, .h = 96},
+ [RESOURCE_TYPE_WOOD] = {.w = 32, .h = 46}
+ };
+
+ const struct dim *const d = &dim[type];
+ *w = d->w;
+ *h = d->h;
+}
+
+int resource_create(const struct resource_cfg *const cfg, struct resource *const list,
+ const size_t n)
+{
+ for (size_t i = 0; i < n; i++)
+ {
+ struct resource *const r = &list[i];
+ struct instance *const in = &r->instance;
+
+ if (!in->alive)
+ {
+ get_dimensions(cfg->type, &in->r.w, &in->r.h);
+ r->type = cfg->type;
+ in->r.x = cfg->x;
+ in->r.y = cfg->y;
+ in->alive = true;
+ in->hp = resource_maxhp(r);
+ return 0;
+ }
+ }
+
+ return -1;
+}
+
+const char *resource_str(const struct resource *const res)
+{
+ static const char *const str[] =
+ {
+ [RESOURCE_TYPE_GOLD] = "Gold mine",
+ [RESOURCE_TYPE_WOOD] = "Pine tree"
+ };
+
+ return str[res->type];
+}