aboutsummaryrefslogtreecommitdiff
path: root/gst
diff options
context:
space:
mode:
authorjacopo grandi <jak.sk8@hotmail.it>2021-02-18 14:14:23 +0100
committerjacopo grandi <jak.sk8@hotmail.it>2021-02-18 14:14:23 +0100
commit5f0fce4191309e9526b7109a0d87c092ce6a4193 (patch)
tree105257f876551814aa74a0760ec116bd1bf307a5 /gst
parentead78d51e662057467b79d3a65b20c4ba83cbf07 (diff)
main
Diffstat (limited to 'gst')
-rw-r--r--gst/gst.c82
-rw-r--r--gst/gst.h30
-rw-r--r--gst/info.c754
-rw-r--r--gst/info.h116
-rw-r--r--gst/map.c19
-rw-r--r--gst/map.h16
-rw-r--r--gst/units.c212
-rw-r--r--gst/units.h40
8 files changed, 1269 insertions, 0 deletions
diff --git a/gst/gst.c b/gst/gst.c
new file mode 100644
index 0000000..56db22f
--- /dev/null
+++ b/gst/gst.c
@@ -0,0 +1,82 @@
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <float.h>
+
+#include <gst.h>
+
+void gst_init (gamestate *gst) {
+ map_init(&gst->map_editor, MAXMAP, MAXMAP, 32);
+ army_init(gst->army_bp, &gst->map_editor);
+ gst->playernum = 1;
+ gst->state = 0;
+ gst->starttime = FLT_MAX;
+ gst->turn = 0;
+ gst->coveredtime = 0;
+ gst->turnspeed = 0.35f;
+}
+
+void gst_destroy (gamestate *gst) {
+ army_destory(gst->army_bp+0);
+ map_destroy(&gst->map_editor);
+}
+
+void gst_get_maparmy(gamestate *gst, map **m, army **ar) {
+ if (gst->state == 0) {
+ *m = &gst->map_editor;
+ *ar = gst->army_bp+0;
+ }
+ if (gst->state == 1) {
+ *m = &gst->map_battle;
+ *ar = &gst->ar;
+ }
+}
+
+void gst_tobattle (gamestate *gst) {
+ if (gst->playernum == 1) {
+ //info_load_army(gst->army_bp+1, "army");
+ gst->army_bp[1] = gst->army_bp[0];
+ gst->playernum = 2;
+ }
+ gst->state = 1;
+ int maxx = MAXMAP, maxy = MAXMAP;
+ int dx = 5, dy = 10;
+ int sx = dx*2+maxx, sy = dy+maxy*2;
+ map_init(&gst->map_battle, sx, sy, 32);
+ army_init(&gst->ar, &gst->map_battle);
+ unit u;
+ for (int i=0; i<gst->playernum; i++) {
+ for (int j=0; j<gst->army_bp[i].uslen; j++) {
+ u = gst->army_bp[i].us[j];
+ u.owner = i;
+ if (i==0) {
+ u.gridpos[0] += dx;
+ u.gridpos[1] += dy+maxy;
+ }
+ if (i==1) {
+ u.gridpos[0] = maxx-u.gridpos[0]+dx;
+ u.gridpos[1] = maxy-u.gridpos[1];
+ }
+ u.pos[0] = u.gridpos[0]*gst->map_battle.ts;
+ u.pos[1] = u.gridpos[1]*gst->map_battle.ts;
+ army_spawn(&gst->ar, &gst->map_battle, u);
+ gst->ar.us[gst->ar.uslen].owner = i;
+ }
+ }
+ gst->starttime = FLT_MAX;
+ gst->turn = 0;
+ gst->coveredtime = 0;
+}
+
+void gst_process (gamestate *gst, infos *info, float t) {
+ if (gst->starttime > t) gst->starttime = t;
+ float t_elapsed = t-gst->starttime;
+ if (t_elapsed > gst->coveredtime) {
+ gst->coveredtime += gst->turnspeed;
+ gst->turn ++;
+ map *m; army *ar;
+ gst_get_maparmy(gst, &m, &ar);
+ army_move(info, ar, m);
+ army_fire(info, ar, m);
+ }
+} \ No newline at end of file
diff --git a/gst/gst.h b/gst/gst.h
new file mode 100644
index 0000000..8acb699
--- /dev/null
+++ b/gst/gst.h
@@ -0,0 +1,30 @@
+#ifndef GST_H
+#define GST_H
+
+#include <info.h>
+#include <units.h>
+#include <map.h>
+
+#define MAXMAP 10
+
+typedef struct {
+ map map_editor;
+ army army_bp[8];
+ int playernum;
+ map map_battle;
+ army ar;
+ int state;
+ float cam[2];
+ float starttime;
+ float coveredtime;
+ int turn;
+ float turnspeed;
+} gamestate;
+
+void gst_init (gamestate *gst);
+void gst_destroy (gamestate *gst);
+void gst_get_maparmy(gamestate *gst, map **m, army **ar);
+void gst_tobattle (gamestate *gst);
+void gst_process (gamestate *gst, infos *info, float t);
+
+#endif \ No newline at end of file
diff --git a/gst/info.c b/gst/info.c
new file mode 100644
index 0000000..82f1550
--- /dev/null
+++ b/gst/info.c
@@ -0,0 +1,754 @@
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <math.h>
+
+#include <units.h>
+#include <info.h>
+
+#include <vec.h>
+#include <jsmn.h>
+#include <jsonparse.h>
+
+int type_damage_map (char strdmg[][32]) {
+ strcpy(strdmg[0], "pierce");
+ strcpy(strdmg[1], "laser");
+ strcpy(strdmg[2], "impact");
+ strcpy(strdmg[3], "fusion");
+ strcpy(strdmg[4], "explosive");
+ strcpy(strdmg[5], "emp");
+ strcpy(strdmg[6], "spread");
+}
+
+int damage_type_map (char *strdmg) {
+ if (strcmp(strdmg, "pierce") == 0) return 0;
+ if (strcmp(strdmg, "laser") == 0) return 1;
+ if (strcmp(strdmg, "impact") == 0) return 2;
+ if (strcmp(strdmg, "fusion") == 0) return 3;
+ if (strcmp(strdmg, "explosive") == 0) return 4;
+ if (strcmp(strdmg, "emp") == 0) return 5;
+ if (strcmp(strdmg, "spread") == 0) return 6;
+ printf("info: damage type unknown\n"); return -1;
+}
+
+
+void info_unit_init (info_unit *u) {
+ strcpy(u->name, "nameless");
+ u->chassis = -1;
+ u->battery = -1;
+ u->brain = -1;
+ for(int i=0; i<8; u->weapons[i] = -1, u->armor[i] = -1, i++);
+ for(int i=0; i<16; u->augs[i] = -1, i++);
+ for(int i=0; i<34; u->levels[i] = 0, i++);
+}
+
+float info_unit_get_weight (infos *info, info_unit *u) {
+ float sum = 0;
+ if (u->battery != -1) {
+ sum += info->batteries[u->battery].weight;
+ }
+ for(int i=0; i<8; i++) {
+ if (u->weapons[i] != -1 && i<info->chassis[u->chassis].slot_weapon) {
+ sum += info->weapons[u->weapons[i]].weight;
+ }
+ if (u->armor[i] != -1 && i<info->chassis[u->chassis].slot_armor) {
+ sum += info->armors[u->armor[i]].weight;
+ }
+ }
+ for(int i=0; i<16; i++) {
+ if (u->augs[i] != -1 && info->chassis[u->chassis].slot_aug) {
+ sum += info->augs[u->augs[i]].weight;
+ }
+ }
+ return sum;
+}
+
+float info_unit_get_dps (infos *info, info_unit *u) {
+ float sum = 0;
+ for(int i=0; i<8; i++) {
+ if (u->weapons[i] != -1 && i<info->chassis[u->chassis].slot_weapon) {
+ info_weapon *w = info->weapons+u->weapons[i];
+ float damage = info_unit_get_damage(info, u, i);
+ sum += damage/w->cooldown;
+ }
+ }
+ return sum;
+}
+
+float info_unit_get_health(infos *info, info_unit *u) {
+ float sum = 0;
+ for(int i=0; i<16; i++) {
+ if (u->augs[i] != -1 && info->chassis[u->chassis].slot_aug) {
+ sum += info->augs[u->augs[i]].add_hp;
+ }
+ }
+ sum += info->chassis[u->chassis].hp;
+ return sum;
+}
+
+float info_unit_get_speed(infos *info, info_unit *u) {
+ float sum = 0;
+ for(int i=0; i<16; i++) {
+ if (u->augs[i] != -1 && info->chassis[u->chassis].slot_aug) {
+ sum += info->augs[u->augs[i]].add_speed;
+ }
+ }
+ sum += info->chassis[u->chassis].speed;
+ return sum;
+}
+
+float info_unit_get_damage (infos *info, info_unit *u, int w) {
+ int damage_type = info->weapons[u->weapons[w]].damage_type;
+ float sum = 0;
+ for(int i=0; i<16; i++) {
+ if (u->augs[i] != -1 && info->chassis[u->chassis].slot_aug) {
+ sum += info->augs[u->augs[i]].add_damage[damage_type];
+ }
+ }
+ float mult = (1 + sum/100.0f);
+ if (mult < 0) mult = 0;
+ float dam = info->weapons[u->weapons[w]].damage * mult;
+ return dam;
+}
+
+float info_unit_get_damage_target (infos *info, info_unit *u, int w,
+ info_unit *t)
+{
+ // u shoots at t with w, which is lol
+ int damage_type = info->weapons[u->weapons[w]].damage_type;
+ float reduction_perc = info_unit_get_armor(info, t, damage_type);
+ float damage = info_unit_get_damage(info, u, w);
+ float mult = (1 - reduction_perc / 100.0f);
+ return damage * mult;
+}
+
+float info_unit_get_cooldown(infos *info, info_unit *u, int w) {
+ float sum = 0;
+ for(int i=0; i<16; i++) {
+ if (u->augs[i] != -1 && info->chassis[u->chassis].slot_aug) {
+ sum += info->augs[u->augs[i]].add_cooldown;
+ }
+ }
+ sum += info->weapons[u->weapons[w]].cooldown;
+ return sum;
+}
+
+float info_unit_get_range(infos *info, info_unit *u, int w) {
+ float sum = 0;
+ for(int i=0; i<16; i++) {
+ if (u->augs[i] != -1 && info->chassis[u->chassis].slot_aug) {
+ sum += info->augs[u->augs[i]].add_range;
+ }
+ }
+ sum += info->weapons[u->weapons[w]].range;
+ return sum;
+}
+
+float info_unit_get_armor(infos *info, info_unit *u, int d) {
+ float sum = 0;
+ for(int i=0; i<8; i++) {
+ if (u->armor[i] != -1 && i<info->chassis[u->chassis].slot_armor) {
+ sum += info->armors[u->armor[i]].armor[d];
+ }
+ }
+ for(int i=0; i<16; i++) {
+ if (u->augs[i] != -1 && info->chassis[u->chassis].slot_aug) {
+ sum += info->augs[u->augs[i]].add_armor[d];
+ }
+ }
+ return sum;
+}
+
+
+void weapon_init (info_weapon *w) {
+ strcpy(w->name, "nameless");
+ w->damage_type = 0;
+ w->weight = 0; w->cooldown = 1;
+ w->damage = 0; w->range = 0; w->aoe = 0;
+ w->knockback = 0; w->stun = 0;
+ for (int i=0; i<7; i++) { w->reduce_armor[i]=0; }
+}
+
+void chassis_init (info_chassis *c) {
+ strcpy(c->name, "nameless");
+ c->slot_weapon = 0; c->slot_armor = 0; c->slot_aug = 0;
+ c->weight_max = 0; c->hp = 0;
+}
+
+void battery_init (info_battery *b) {
+ strcpy(b->name, "nameless");
+ b->weight = 0; b->capacity = 0; b->recharge = 0;
+}
+
+void armor_init (info_armor *a) {
+ strcpy(a->name, "nameless");
+ a->weight = 0;
+ for (int i=0; i<7; i++) { a->armor[i]=0; }
+}
+
+void aug_init (info_aug *a) {
+ strcpy(a->name, "nameless");
+ a->weight = 0;
+ for (int i=0; i<7; i++) { a->add_damage[i]=0; }
+ for (int i=0; i<7; i++) { a->add_armor[i]=0; }
+ a->add_range = 0;
+ a->add_cooldown = 0;
+ a->add_speed = 0;
+ a->add_hp = 0;
+}
+
+void brain_init (info_brain *a) {
+ strcpy(a->name, "nameless");
+}
+
+
+void info_unit_parse (char *json, info_unit *u, jsmntok_t *t, int r) {
+ info_unit_init(u);
+ int obj_i = 0, dict_i = -1;
+ for (int i=0; i<r; i+=2) {
+ if (t[i].type == JSMN_STRING) {
+ char key[32]; substr_token(json, key, t+i);
+ if (strcmp(key, "name") == 0) {
+ substr_token(json, u->name, t+i+1);
+ }
+ if (strcmp(key, "chassis") == 0) {
+ char val[32]; substr_token(json, val, t+i+1);
+ u->chassis = atoi(val);
+ }
+ if (strcmp(key, "brain") == 0) {
+ char val[32]; substr_token(json, val, t+i+1);
+ u->brain = atoi(val);
+ }
+ if (strcmp(key, "battery") == 0) {
+ char val[32]; substr_token(json, val, t+i+1);
+ u->battery = atoi(val);
+ }
+ if (strcmp(key, "weapons") == 0) {
+ int rt = json_parse_subtokens(json, t, r, i+1);
+ json_parse_array(json, u->weapons, t+i+2, rt-1, 'c');
+ }
+ if (strcmp(key, "armor") == 0) {
+ int rt = json_parse_subtokens(json, t, r, i+1);
+ json_parse_array(json, u->armor, t+i+2, rt-1, 'c');
+ }
+ if (strcmp(key, "augs") == 0) {
+ int rt = json_parse_subtokens(json, t, r, i+1);
+ json_parse_array(json, u->augs, t+i+2, rt-1, 'c');
+ }
+ if (strcmp(key, "levels") == 0) {
+ int rt = json_parse_subtokens(json, t, r, i+1);
+ json_parse_array(json, u->levels, t+i+2, rt-1, 'c');
+ }
+ }
+ }
+}
+
+void info_weapon_parse (char *json, info_weapon *w, jsmntok_t *t, int r) {
+ weapon_init(w);
+ int obj_i = 0, dict_i = -1;
+ for (int i=0; i<r; i+=2) {
+ if (t[i].type == JSMN_STRING) {
+ char key[32]; substr_token(json, key, t+i);
+ if (strcmp(key, "name") == 0) {
+ substr_token(json, w->name, t+i+1);
+ }
+ if (strcmp(key, "damage_type") == 0) {
+ char val[32]; substr_token(json, val, t+i+1);
+ w->damage_type = damage_type_map(val);
+ }
+ if (strcmp(key, "weight") == 0) {
+ char val[32]; substr_token(json, val, t+i+1);
+ w->weight = atof(val);
+ }
+ if (strcmp(key, "cooldown") == 0) {
+ char val[32]; substr_token(json, val, t+i+1);
+ w->cooldown = atof(val);
+ }
+ if (strcmp(key, "damage") == 0) {
+ char val[32]; substr_token(json, val, t+i+1);
+ w->damage = atof(val);
+ }
+ if (strcmp(key, "range") == 0) {
+ char val[32]; substr_token(json, val, t+i+1);
+ w->range = atof(val);
+ }
+ if (strcmp(key, "aoe") == 0) {
+ char val[32]; substr_token(json, val, t+i+1);
+ w->aoe = atof(val);
+ }
+ if (strcmp(key, "knockback") == 0) {
+ char val[32]; substr_token(json, val, t+i+1);
+ w->knockback = atoi(val);
+ }
+ if (strcmp(key, "damage_battery") == 0) {
+ char val[32]; substr_token(json, val, t+i+1);
+ w->damage_battery = atof(val);
+ }
+ if (strcmp(key, "stun") == 0) {
+ char val[32]; substr_token(json, val, t+i+1);
+ w->stun = atoi(val);
+ }
+ if (strcmp(key, "reduce_pierce") == 0) {
+ char val[32]; substr_token(json, val, t+i+1);
+ w->reduce_armor[0] = atof(val);
+ }
+ if (strcmp(key, "reduce_laser") == 0) {
+ char val[32]; substr_token(json, val, t+i+1);
+ w->reduce_armor[1] = atof(val);
+ }
+ if (strcmp(key, "reduce_impact") == 0) {
+ char val[32]; substr_token(json, val, t+i+1);
+ w->reduce_armor[2] = atof(val);
+ }
+ if (strcmp(key, "reduce_fusion") == 0) {
+ char val[32]; substr_token(json, val, t+i+1);
+ w->reduce_armor[3] = atof(val);
+ }
+ if (strcmp(key, "reduce_explosive") == 0) {
+ char val[32]; substr_token(json, val, t+i+1);
+ w->reduce_armor[4] = atof(val);
+ }
+ if (strcmp(key, "reduce_emp") == 0) {
+ char val[32]; substr_token(json, val, t+i+1);
+ w->reduce_armor[5] = atof(val);
+ }
+ if (strcmp(key, "reduce_spread") == 0) {
+ char val[32]; substr_token(json, val, t+i+1);
+ w->reduce_armor[6] = atof(val);
+ }
+ }
+ }
+}
+
+void info_chassis_parse (char *json, info_chassis *c, jsmntok_t *t, int r) {
+ chassis_init(c);
+ int obj_i = 0, dict_i = -1;
+ for (int i=0; i<r; i+=2) {
+ if (t[i].type == JSMN_STRING) {
+ char key[32]; substr_token(json, key, t+i);
+ if (strcmp(key, "name") == 0) {
+ substr_token(json, c->name, t+i+1);
+ }
+ if (strcmp(key, "slot_weapon") == 0) {
+ char val[32]; substr_token(json, val, t+i+1);
+ c->slot_weapon = atoi(val);
+ }
+ if (strcmp(key, "slot_armor") == 0) {
+ char val[32]; substr_token(json, val, t+i+1);
+ c->slot_armor = atoi(val);
+ }
+ if (strcmp(key, "slot_aug") == 0) {
+ char val[32]; substr_token(json, val, t+i+1);
+ c->slot_aug = atoi(val);
+ }
+ if (strcmp(key, "weight_max") == 0) {
+ char val[32]; substr_token(json, val, t+i+1);
+ c->weight_max = atof(val);
+ }
+ if (strcmp(key, "hp") == 0) {
+ char val[32]; substr_token(json, val, t+i+1);
+ c->hp = atof(val);
+ }
+ if (strcmp(key, "speed") == 0) {
+ char val[32]; substr_token(json, val, t+i+1);
+ c->speed = atof(val);
+ }
+ }
+ }
+}
+
+void info_battery_parse (char *json, info_battery *b, jsmntok_t *t, int r) {
+ battery_init(b);
+ int obj_i = 0, dict_i = -1;
+ for (int i=0; i<r; i+=2) {
+ if (t[i].type == JSMN_STRING) {
+ char key[32]; substr_token(json, key, t+i);
+ if (strcmp(key, "name") == 0) {
+ substr_token(json, b->name, t+i+1);
+ }
+ if (strcmp(key, "weight") == 0) {
+ char val[32]; substr_token(json, val, t+i+1);
+ b->weight = atof(val);
+ }
+ if (strcmp(key, "capacity") == 0) {
+ char val[32]; substr_token(json, val, t+i+1);
+ b->capacity = atof(val);
+ }
+ if (strcmp(key, "recharge") == 0) {
+ char val[32]; substr_token(json, val, t+i+1);
+ b->recharge = atoi(val);
+ }
+ }
+ }
+}
+
+void info_armor_parse (char *json, info_armor *a, jsmntok_t *t, int r) {
+ armor_init(a);
+ int obj_i = 0, dict_i = -1;
+ for (int i=0; i<r; i+=2) {
+ if (t[i].type == JSMN_STRING) {
+ char key[32]; substr_token(json, key, t+i);
+ if (strcmp(key, "name") == 0) {
+ substr_token(json, a->name, t+i+1);
+ }
+ if (strcmp(key, "weight") == 0) {
+ char val[32]; substr_token(json, val, t+i+1);
+ a->weight = atof(val);
+ }
+ if (strcmp(key, "pierce") == 0) {
+ char val[32]; substr_token(json, val, t+i+1);
+ a->armor[0] = atof(val);
+ }
+ if (strcmp(key, "laser") == 0) {
+ char val[32]; substr_token(json, val, t+i+1);
+ a->armor[1] = atof(val);
+ }
+ if (strcmp(key, "impact") == 0) {
+ char val[32]; substr_token(json, val, t+i+1);
+ a->armor[2] = atof(val);
+ }
+ if (strcmp(key, "fusion") == 0) {
+ char val[32]; substr_token(json, val, t+i+1);
+ a->armor[3] = atof(val);
+ }
+ if (strcmp(key, "explosive") == 0) {
+ char val[32]; substr_token(json, val, t+i+1);
+ a->armor[4] = atof(val);
+ }
+ if (strcmp(key, "emp") == 0) {
+ char val[32]; substr_token(json, val, t+i+1);
+ a->armor[5] = atof(val);
+ }
+ if (strcmp(key, "spread") == 0) {
+ char val[32]; substr_token(json, val, t+i+1);
+ a->armor[6] = atof(val);
+ }
+ }
+ }
+}
+
+void info_aug_parse (char *json, info_aug *a, jsmntok_t *t, int r) {
+ aug_init(a);
+ int obj_i = 0, dict_i = -1;
+ for (int i=0; i<r; i+=2) {
+ if (t[i].type == JSMN_STRING) {
+ char key[32]; substr_token(json, key, t+i);
+ if (strcmp(key, "name") == 0) {
+ substr_token(json, a->name, t+i+1);
+ }
+ if (strcmp(key, "weight") == 0) {
+ char val[32]; substr_token(json, val, t+i+1);
+ a->weight = atof(val);
+ }
+ if (strcmp(key, "damage_pierce") == 0) {
+ char val[32]; substr_token(json, val, t+i+1);
+ a->add_damage[0] = atof(val);
+ }
+ if (strcmp(key, "damage_laser") == 0) {
+ char val[32]; substr_token(json, val, t+i+1);
+ a->add_damage[1] = atof(val);
+ }
+ if (strcmp(key, "damage_impact") == 0) {
+ char val[32]; substr_token(json, val, t+i+1);
+ a->add_damage[2] = atof(val);
+ }
+ if (strcmp(key, "damage_fusion") == 0) {
+ char val[32]; substr_token(json, val, t+i+1);
+ a->add_damage[3] = atof(val);
+ }
+ if (strcmp(key, "damage_explosive") == 0) {
+ char val[32]; substr_token(json, val, t+i+1);
+ a->add_damage[4] = atof(val);
+ }
+ if (strcmp(key, "damage_emp") == 0) {
+ char val[32]; substr_token(json, val, t+i+1);
+ a->add_damage[5] = atof(val);
+ }
+ if (strcmp(key, "add_spread") == 0) {
+ char val[32]; substr_token(json, val, t+i+1);
+ a->add_damage[6] = atof(val);
+ }
+ if (strcmp(key, "armor_pierce") == 0) {
+ char val[32]; substr_token(json, val, t+i+1);
+ a->add_armor[0] = atof(val);
+ }
+ if (strcmp(key, "armor_laser") == 0) {
+ char val[32]; substr_token(json, val, t+i+1);
+ a->add_armor[1] = atof(val);
+ }
+ if (strcmp(key, "armor_impact") == 0) {
+ char val[32]; substr_token(json, val, t+i+1);
+ a->add_armor[2] = atof(val);
+ }
+ if (strcmp(key, "armor_fusion") == 0) {
+ char val[32]; substr_token(json, val, t+i+1);
+ a->add_armor[3] = atof(val);
+ }
+ if (strcmp(key, "armor_explosive") == 0) {
+ char val[32]; substr_token(json, val, t+i+1);
+ a->add_armor[4] = atof(val);
+ }
+ if (strcmp(key, "armor_emp") == 0) {
+ char val[32]; substr_token(json, val, t+i+1);
+ a->add_armor[5] = atof(val);
+ }
+ if (strcmp(key, "armor_spread") == 0) {
+ char val[32]; substr_token(json, val, t+i+1);
+ a->add_armor[6] = atof(val);
+ }
+ if (strcmp(key, "add_range") == 0) {
+ char val[32]; substr_token(json, val, t+i+1);
+ a->add_range = atof(val);
+ }
+ if (strcmp(key, "add_cooldown") == 0) {
+ char val[32]; substr_token(json, val, t+i+1);
+ a->add_cooldown = atof(val);
+ }
+ if (strcmp(key, "add_hp") == 0) {
+ char val[32]; substr_token(json, val, t+i+1);
+ a->add_hp = atof(val);
+ }
+ }
+ }
+}
+
+void info_brain_parse (char *json, info_brain *a, jsmntok_t *t, int r) {
+ brain_init(a);
+ int obj_i = 0, dict_i = -1;
+ for (int i=0; i<r; i+=2) {
+ if (t[i].type == JSMN_STRING) {
+ char key[32]; substr_token(json, key, t+i);
+ if (strcmp(key, "name") == 0) {
+ substr_token(json, a->name, t+i+1);
+ }
+ }
+ }
+}
+
+void info_parse_json (infos *info, char *json, char *obj) {
+ jsmn_parser p; jsmn_init(&p);
+ jsmntok_t t[MAXTOKENS];
+ int r = jsmn_parse(&p, json, strlen(json), t, MAXTOKENS);
+ int index = 0;
+ for (int i=1; i<r; i++) { // i=1: ignore outer []
+ if (t[i].type == JSMN_OBJECT) {
+ int rt = json_parse_subtokens(json, t, r, i);
+ if (strcmp(obj, "template") == 0) {
+ info_unit_parse(json, info->templates+index, t+i+1, rt);
+ info->templateslen = index+1;
+ }
+ if (strcmp(obj, "weapon") == 0) {
+ info_weapon_parse(json, info->weapons+index, t+i+1, rt);
+ info->weaponslen = index+1;
+ }
+ if (strcmp(obj, "chassis") == 0) {
+ info_chassis_parse(json, info->chassis+index, t+i+1, rt);
+ info->chassislen = index+1;
+ }
+ if (strcmp(obj, "battery") == 0) {
+ info_battery_parse(json, info->batteries+index, t+i+1, rt);
+ info->batterieslen = index+1;
+ }
+ if (strcmp(obj, "armor") == 0) {
+ info_armor_parse(json, info->armors+index, t+i+1, rt);
+ info->armorslen = index+1;
+ }
+ if (strcmp(obj, "aug") == 0) {
+ info_aug_parse(json, info->augs+index, t+i+1, rt);
+ info->augslen = index+1;
+ }
+ if (strcmp(obj, "brain") == 0) {
+ info_brain_parse(json, info->brains+index, t+i+1, rt);
+ info->brainslen = index+1;
+ }
+ index ++;
+ i += rt-1;
+ }
+ }
+}
+
+int info_read_file (char *dst, char *name, int size) {
+ memset(dst, 0, size*sizeof(char));
+ FILE *f = fopen(name, "rb");
+ fseek(f, 0, SEEK_END);
+ long fsize = ftell(f);
+ fseek(f, 0, SEEK_SET);
+ fread(dst, 1, fsize, f);
+ fclose(f);
+ dst[fsize] = '\0';
+ return fsize;
+}
+
+void info_load (infos *info) {
+ int size = 1024*64;
+ char json[size];
+ type_damage_map(info->damage_types);
+ info->augslen = 0;
+ info_read_file(json, "content/weapons.txt", size);
+ info_parse_json(info, json, "weapon");
+ info_read_file(json, "content/chassis.txt", size);
+ info_parse_json(info, json, "chassis");
+ info_read_file(json, "content/batteries.txt", size);
+ info_parse_json(info, json, "battery");
+ info_read_file(json, "content/armor.txt", size);
+ info_parse_json(info, json, "armor");
+ info_read_file(json, "content/augments.txt", size);
+ info_parse_json(info, json, "aug");
+ info_read_file(json, "content/brains.txt", size);
+ info_parse_json(info, json, "brain");
+
+ info_read_file(json, "content/templates/default.txt", size);
+ info_parse_json(info, json, "template");
+ /*
+ for (int i=0; i<info->unitslen; i++) {
+ printf("name: %s\n", info->units[i].name);
+ printf(" hp: %f\n", info->units[i].hp);
+ printf(" damage: %f\n", info->units[i].damage);
+ printf(" range: %f\n", info->units[i].range);
+ }*/
+ /*
+ for (int i=0; i<info->weaponslen; i++) {
+ printf("name: %s\n", info->weapons[i].name);
+ printf(" damage_type: %d\n", info->weapons[i].damage_type);
+ printf(" weight: %f\n", info->weapons[i].weight);
+ printf(" cooldown: %f\n", info->weapons[i].cooldown);
+ printf(" damage: %f\n", info->weapons[i].damage);
+ printf(" range: %f\n", info->weapons[i].range);
+ printf(" aoe: %f\n", info->weapons[i].aoe);
+ printf(" knockback: %d\n", info->weapons[i].knockback);
+ printf(" damage_battery: %f\n", info->weapons[i].damage_battery);
+ printf(" stun: %d\n", info->weapons[i].stun);
+ float sum = 0; for (int j=0; j<7; j++) {
+ sum += info->weapons[i].reduce_armor[j];
+ }
+ if (sum > 0) {
+ printf(" red pierce: %f\n", info->weapons[i].reduce_armor[0]);
+ printf(" red laser: %f\n", info->weapons[i].reduce_armor[1]);
+ printf(" red impact: %f\n", info->weapons[i].reduce_armor[2]);
+ printf(" red fusion: %f\n", info->weapons[i].reduce_armor[3]);
+ printf(" red explosive: %f\n", info->weapons[i].reduce_armor[4]);
+ printf(" red emp: %f\n", info->weapons[i].reduce_armor[5]);
+ printf(" red spread: %f\n", info->weapons[i].reduce_armor[6]);
+ }
+ }*/
+ /*
+ for (int i=0; i<info->chassislen; i++) {
+ printf("name: %s\n", info->chassis[i].name);
+ printf(" slot_weapon: %d\n", info->chassis[i].slot_weapon);
+ printf(" slot_armor: %d\n", info->chassis[i].slot_armor);
+ printf(" slot_aug: %d\n", info->chassis[i].slot_aug);
+ printf(" weight_max: %f\n", info->chassis[i].weight_max);
+ printf(" hp: %f\n", info->chassis[i].hp);
+ }*/
+ /*
+ for (int i=0; i<info->batterieslen; i++) {
+ printf("name: %s\n", info->batteries[i].name);
+ printf(" weight: %f\n", info->batteries[i].weight);
+ printf(" capacity: %f\n", info->batteries[i].capacity);
+ printf(" recharge: %d\n", info->batteries[i].recharge);
+ }*/
+ /*
+ for (int i=0; i<info->armorslen; i++) {
+ printf("name: %s\n", info->armors[i].name);
+ printf(" weight: %f\n", info->armors[i].weight);
+ printf(" pierce: %f\n", info->armors[i].armor[0]);
+ printf(" laser: %f\n", info->armors[i].armor[1]);
+ printf(" impact: %f\n", info->armors[i].armor[2]);
+ printf(" fusion: %f\n", info->armors[i].armor[3]);
+ printf(" explosive: %f\n", info->armors[i].armor[4]);
+ printf(" emp: %f\n", info->armors[i].armor[5]);
+ printf(" spread: %f\n", info->armors[i].armor[6]);
+ }*/
+}
+
+void info_dump_json_templates (infos *info, char *str) {
+ int len = 0;
+ sprintf(str+len, "[ \n"); len = strlen(str);
+ for (int i=0; i<info->templateslen; i++) {
+ info_unit *u = info->templates+i;
+ sprintf(str+len, " { \n \"name\": \"%s\",\n", u->name);
+ len = strlen(str);
+ sprintf(str+len, " \"chassis\": \"%d\",\n", u->chassis);
+ len = strlen(str);
+ sprintf(str+len, " \"brain\": \"%d\",\n", u->brain);
+ len = strlen(str);
+ sprintf(str+len, " \"battery\": \"%d\",\n", u->battery);
+ len = strlen(str);
+ char w0[64]; json_dump_array(w0, u->weapons, 8, 'c');
+ sprintf(str+len, " \"weapons\": %s,\n", w0);
+ len = strlen(str);
+ char w1[64]; json_dump_array(w1, u->armor, 8, 'c');
+ sprintf(str+len, " \"armor\": %s,\n", w1);
+ len = strlen(str);
+ char w2[64]; json_dump_array(w2, u->augs, 8, 'c');
+ sprintf(str+len, " \"augs\": %s,\n", w2);
+ len = strlen(str);
+ char w3[128]; json_dump_array(w3, u->levels, 34, 'c');
+ sprintf(str+len, " \"levels\": %s\n", w3);
+ len = strlen(str);
+ char comma = ','; if(i==info->templateslen-1) comma = ' ';
+ sprintf(str+len, " }%c\n", comma);
+ len = strlen(str);
+ }
+ sprintf(str+len, "]"); len = strlen(str);
+}
+
+void info_save_templates (infos *info, char *filename) {
+ char src[1024*64];
+ info_dump_json_templates(info, src);
+ char pathname[64]; sprintf(pathname, "content/templates/%s.txt", filename);
+ FILE *f = fopen(pathname, "wb");
+ fwrite(src, 1, strlen(src)*sizeof(char), f);
+ fclose(f);
+}
+
+void info_template_add (infos *info, info_unit *temp) {
+ if (info->templateslen < MAXTEMPLATES) {
+ info->templates[info->templateslen] = *temp;
+ info->templateslen++;
+ }
+}
+
+void info_load_army(struct army_ *ar, char *filename) {
+ char buf[1024*64];
+ char pathname[64]; sprintf(pathname, "army/%s.txt", filename);
+ int len = info_read_file(buf, pathname, 1024*64);
+ memcpy(ar, buf, len-1);
+ ar->grid = NULL;
+ army_grid_init(ar);
+}
+
+void info_save_army(struct army_ *ar, char *filename) {
+ char pathname[64]; sprintf(pathname, "army/%s.txt", filename);
+ FILE *f = fopen(pathname, "wb");
+ fwrite(ar, 1, sizeof(army), f);
+ fclose(f);
+}
+
+
+void info_load_playername(char n[]) {
+ char buf[1024];
+ int len = info_read_file(buf, "player.txt", 1024);
+ memcpy(n, buf, sizeof(char)*len);
+}
+
+void info_save_playername(char n[]) {
+ FILE *f = fopen("player.txt", "wb");
+ fwrite(n, 1, strlen(n)*sizeof(char), f); fclose(f);
+}
+
+
+#include <plibsys.h>
+int info_army_get_list (char l[][32]) {
+ int len = 0;
+ PDirEntry *entry;
+ PDir *dir = p_dir_new ("army/", NULL);
+ while ((entry = p_dir_get_next_entry (dir, NULL)) != NULL) {
+ if (entry->type == P_DIR_ENTRY_TYPE_FILE) {
+ strcpy(l[len], entry->name);
+ l[len][strlen(l[len])-4] = '\0'; // del .txt
+ len++;
+ }
+ }
+ return len;
+}
diff --git a/gst/info.h b/gst/info.h
new file mode 100644
index 0000000..3ec17f9
--- /dev/null
+++ b/gst/info.h
@@ -0,0 +1,116 @@
+#ifndef INFO_H
+#define INFO_H
+
+#define MAXTEMPLATES 128
+
+#include <stdint.h>
+
+typedef struct {
+ char name[32];
+ // indexes of info.*
+ int8_t chassis;
+ int8_t brain;
+ int8_t weapons[8];
+ int8_t armor[8];
+ int8_t augs[16];
+ int8_t battery;
+ int8_t levels[34];
+} info_unit;
+
+typedef struct {
+ char name[32];
+ int damage_type;
+ float weight;
+ float cooldown;
+ float damage;
+ float range;
+ float aoe;
+ int knockback;
+ float damage_battery;
+ int stun;
+ float reduce_armor[7];
+} info_weapon;
+
+typedef struct {
+ char name[32];
+ int slot_weapon;
+ int slot_armor;
+ int slot_aug;
+ float weight_max;
+ float hp;
+ float speed;
+} info_chassis;
+
+typedef struct {
+ char name[32];
+ float weight;
+ float capacity;
+ int recharge;
+} info_battery;
+
+typedef struct {
+ char name[32];
+ float weight;
+ float armor[7];
+} info_armor;
+
+typedef struct {
+ char name[32];
+ float weight;
+ float add_damage[7];
+ float add_armor[7];
+ float add_range;
+ float add_cooldown;
+ float add_speed;
+ float add_hp;
+} info_aug;
+
+typedef struct {
+ char name[32];
+} info_brain;
+
+typedef struct {
+ char damage_types[7][32];
+ info_unit templates[MAXTEMPLATES];
+ int templateslen;
+ info_weapon weapons[64];
+ int weaponslen;
+ info_chassis chassis[32];
+ int chassislen;
+ info_battery batteries[32];
+ int batterieslen;
+ info_armor armors[32];
+ int armorslen;
+ info_aug augs[32];
+ int augslen;
+ info_brain brains[32];
+ int brainslen;
+} infos;
+
+void info_unit_init (info_unit *u);
+float info_unit_get_weight (infos *info, info_unit *u);
+float info_unit_get_dps (infos *info, info_unit *u);
+float info_unit_get_health(infos *info, info_unit *u);
+float info_unit_get_speed(infos *info, info_unit *u);
+float info_unit_get_damage(infos *info, info_unit *u, int w);
+float info_unit_get_damage_target(infos *info, info_unit *u, int w,
+ info_unit *t);
+float info_unit_get_cooldown(infos *info, info_unit *u, int w);
+float info_unit_get_range(infos *info, info_unit *u, int w);
+float info_unit_get_armor(infos *info, info_unit *u, int d);
+
+void info_load (infos *info);
+
+void info_save_templates (infos *info, char *filename);
+void info_template_add (infos *info, info_unit *temp);
+
+
+void info_load_army(struct army_ *ar, char *filename);
+void info_save_army(struct army_ *ar, char *filename);
+
+int info_army_get_list(char l[][32]);
+
+void info_load_playername(char n[]);
+void info_save_playername(char n[]);
+
+#endif \ No newline at end of file
diff --git a/gst/map.c b/gst/map.c
new file mode 100644
index 0000000..59d1ad1
--- /dev/null
+++ b/gst/map.c
@@ -0,0 +1,19 @@
+#include <stdlib.h>
+#include <stdio.h>
+#include <units.h>
+#include <string.h>
+
+#include <map.h>
+
+int ptoi (map *m, int *p) { return p[0]+p[1]*m->sx; }
+int xytoi (map *m, int x, int y) { return x+y*m->sx; }
+
+void map_init (map *m, int sx, int sy, int ts) {
+ m->t = (int*)malloc(sizeof(int)*sx*sy);
+ m->sx = sx; m->sy = sy; m->ts = ts;
+ memset(m->t, 0, sizeof(int)*sx*sy);
+}
+
+void map_destroy (map *m) {
+ free(m->t);
+} \ No newline at end of file
diff --git a/gst/map.h b/gst/map.h
new file mode 100644
index 0000000..415281a
--- /dev/null
+++ b/gst/map.h
@@ -0,0 +1,16 @@
+#ifndef MAP_H
+#define MAP_H
+
+typedef struct {
+ int *t;
+ int sx;
+ int sy;
+ int ts;
+} map;
+
+int ptoi (map *m, int *p);
+int xytoi (map *m, int x, int y);
+void map_init (map *m, int sx, int sy, int ts);
+void map_destroy (map *m);
+
+#endif \ No newline at end of file
diff --git a/gst/units.c b/gst/units.c
new file mode 100644
index 0000000..72089f2
--- /dev/null
+++ b/gst/units.c
@@ -0,0 +1,212 @@
+#include <stdlib.h>
+#include <stdio.h>
+#include <units.h>
+#include <string.h>
+
+#include <vec.h>
+#include <jsonparse.h>
+
+void army_grid_init(army *ar) {
+ if (ar->grid != NULL) free(ar->grid);
+ ar->grid = (unit**)malloc(sizeof(unit*)*ar->sx*ar->sy);
+ memset(ar->grid, NULL, sizeof(unit*)*ar->sx*ar->sy);
+ for (int i=0; i<ar->uslen; i++) {
+ unit *u = ar->us+i;
+ // not using ptoi, don't have map, why have map anyway?
+ ar->grid[ar->sx*u->gridpos[1]+u->gridpos[0]] = u;
+ }
+}
+
+void army_init (army *ar, map *m) {
+ ar->uslen = 0;
+ ar->sx = m->sx; ar->sy = m->sy;
+ army_grid_init(ar);
+}
+
+void army_destory(army *ar) {
+ free(ar->grid);
+}
+
+void unit_init (infos *info, army *ar, map *m,
+ int x, int y, info_unit *iu, int owner, unit *u)
+{
+ u->pos[0] = x*m->ts; u->pos[1] = y*m->ts;
+ u->gridpos[0] = x; u->gridpos[1] = y;
+ u->info = *iu;
+ u->owner = owner;
+ u->hp = info_unit_get_health(info, iu);
+ u->move_points = 0;
+ for (int i=0; i<8; u->cooldown[i] = 1, i++);
+}
+
+void army_spawn (army *ar, map *m, unit u) {
+ ar->us[ar->uslen] = u;
+ ar->grid[ptoi(m, u.gridpos)] = ar->us+ar->uslen;
+ ar->uslen++;
+}
+
+void unit_move (army *ar, map *m, unit *u, int *dest) {
+ ar->grid[ptoi(m, u->gridpos)] = NULL;
+ u->gridpos[0] = dest[0];
+ u->gridpos[1] = dest[1];
+ ar->grid[ptoi(m, u->gridpos)] = u;
+ u->pos[0] = dest[0]*m->ts;
+ u->pos[1] = dest[1]*m->ts;
+}
+
+void unit_remove (army *ar, map *m, unit *u) {
+ unit *t = ar->us+ar->uslen-1;
+ int ux = u->gridpos[0], uy = u->gridpos[1];
+ int tx = t->gridpos[0], ty = t->gridpos[1];
+ *u = *t;
+ ar->uslen--;
+ ar->grid[xytoi(m, tx, ty)] = u;
+ ar->grid[xytoi(m, ux, uy)] = NULL;
+ printf("ar->uslen: %d\n", ar->uslen);
+}
+
+void unit_dead (army *ar, map *m, unit *u) {
+ ar->grid[ptoi(m, u->gridpos)] = NULL;
+}
+
+void unit_search (infos *info, army *ar, map *m, unit *u,
+ unit **t, float range)
+{
+ for (int f=0; f<32; t[f] = NULL, f++);
+ int mult[4][2] = { {1, 1},{1,-1},{-1,-1},{-1,1} }, x, y, dx, dy, tmp;
+ *t = NULL;
+ for (int r=1; r<range*1.42 && *t==NULL; r++) {
+ for (int k=0; k<4 && *t==NULL; k++) {
+ for (int j=0; j<r && *t==NULL; j++) {
+ if (k%2==1) { // invert them if k=1 || k=3
+ dx = (j)*mult[k][0]; dy = (r-j)*mult[k][1];
+ } else {
+ dx = (r-j)*mult[k][0]; dy = (j)*mult[k][1];
+ }
+ x = u->gridpos[0]+dx; y = u->gridpos[1]+dy;
+ //printf(" (%d, %d) -> (%d, %d), %d, %d, %d\n", u->gridpos[0], u->gridpos[1], x, y, r, k, j);
+ if (!(x>=0 && y>=0 && x<m->sx && y<m->sy)) continue; // oob
+ *t = ar->grid[xytoi(m, x, y)];
+ if (*t!=NULL && (*t)->owner == u->owner) *t = NULL; // owner check
+ if (*t!=NULL && (*t)->hp <= 0) *t = NULL; // owner check
+ if (*t!=NULL) {
+ // range check
+ float diff[2] = {
+ u->gridpos[0] - (*t)->gridpos[0],
+ u->gridpos[1] - (*t)->gridpos[1]
+ }; float mag = vec2_mag(diff);
+ if (mag > range) *t = NULL;
+ }
+ }}}
+}
+
+
+typedef struct { unit *u; int *dir; int done; } mcom;
+int army_move_step (infos *info, army *ar, map *m) {
+ int dirs[4][2] = { {1, 0},{0, 1},{-1,0},{0,-1} };
+ mcom mcs[ar->uslen];
+ int mclen = 0;
+ float diff[2];
+ int orders = 0;
+ // planning
+ for (int i=0; i<ar->uslen; i++) {
+ unit *u = ar->us+i;
+ if (u->move_points <= 0) continue;
+ if (u->hp <= 0) continue;
+ // search target
+ unit *t[32];
+ unit_search(info, ar, m, u, t, 100);
+ if (t[0] != NULL) {
+ // in range to shoot
+ diff[0] = u->gridpos[0] - t[0]->gridpos[0];
+ diff[1] = u->gridpos[1] - t[0]->gridpos[1];
+ if (vec2_mag(diff) > /*info->units[u->who].range*/1) {
+ // movement command issued
+ float dist[4] = { 9999, 9999, 9999, 9999 };
+ for (int j=0; j<4; j++) {
+ diff[0] = u->gridpos[0]+dirs[j][0]
+ - t[0]->gridpos[0];
+ diff[1] = u->gridpos[1]+dirs[j][1]
+ - t[0]->gridpos[1];
+ dist[j] = vec2_mag(diff);
+ }
+ float min = dist[0]; int minj = 0;
+ for (int j=1; j<4; j++) {
+ if (dist[j] < min) { min = dist[j]; minj = j; }
+ }
+ mcs[mclen].u = u;
+ mcs[mclen].dir = dirs[minj];
+ mcs[mclen].done = 0;
+ mclen++;
+ }
+ }
+ }
+ // execution
+ int sum = 0, lastsum = -1, step = 0;
+ for (; step<MAXSOLVESTEPS; step++) {
+ if (sum == lastsum) { break; }
+ lastsum = sum;
+ sum = 0;
+ for (int i=0; i<mclen; i++) {
+ int dest[2] = {
+ mcs[i].u->gridpos[0]+mcs[i].dir[0],
+ mcs[i].u->gridpos[1]+mcs[i].dir[1]
+ };
+ if (!mcs[i].done && ar->grid[ptoi(m, dest)] == NULL) {
+ unit_move(ar, m, mcs[i].u, dest);
+ mcs[i].done = 1;
+ mcs[i].u->move_points -= 1;
+ orders++;
+ }
+ sum += mcs[i].done;
+ }
+ }
+ if (step == MAXSOLVESTEPS) { printf("army: max steps reached\n"); }
+ if (orders > 0) return 0;
+ else return 1;
+}
+
+void army_move (infos *info, army *ar, map *m) {
+ for (int i=0; i<ar->uslen; i++) {
+ ar->us[i].move_points += info_unit_get_speed(info, &ar->us[i].info);
+ }
+ int iter = 0, finished = 0;
+ for (; iter<5 && !finished; iter++) {
+ finished = army_move_step(info, ar, m);
+ }
+ //printf("stepped %d %d\n", iter, finished);
+}
+
+void army_fire (infos *info, army *ar, map *m) {
+ for (int i=0; i<ar->uslen; i++) {
+ unit *u = ar->us+i;
+ for (int j=0; j<info->chassis[u->info.chassis].slot_weapon; j++) {
+ u->cooldown[j] += 1;
+ }
+ }
+ struct dmg { unit *u; float dam; } dmgs[1024*8]; int dmgslen = 0;
+ unit *t[32];
+ for (int i=0; i<ar->uslen; i++) {
+ unit *u = ar->us+i;
+ if (u->hp <= 0) continue;
+ for (int j=0; j<info->chassis[u->info.chassis].slot_weapon; j++) {
+ if (u->info.weapons[j] == -1) continue;
+ if (u->cooldown[j] <= 0) continue;
+ float range = info_unit_get_range(info, &u->info, j);
+ unit_search(info, ar, m, u, t, range);
+ if (t[0]!=NULL) {
+ dmgs[dmgslen].u = t[0];
+ dmgs[dmgslen].dam = info_unit_get_damage_target(
+ info, &u->info, j, &t[0]->info);
+ dmgslen++;
+ u->cooldown[j] -= info_unit_get_cooldown(info, &u->info, j);
+ }
+ }
+ }
+ for (int i=0; i<dmgslen; i++) {
+ dmgs[i].u->hp -= dmgs[i].dam;
+ if (dmgs[i].u->hp <= 0) {
+ unit_dead(ar, m, dmgs[i].u);
+ }
+ }
+} \ No newline at end of file
diff --git a/gst/units.h b/gst/units.h
new file mode 100644
index 0000000..86f7fd7
--- /dev/null
+++ b/gst/units.h
@@ -0,0 +1,40 @@
+#ifndef UNITS_H
+#define UNITS_H
+
+#define MAXUNITS 128
+#define MAXSOLVESTEPS 128
+
+#include <info.h>
+
+typedef struct unit_ {
+ float pos[2];
+ int gridpos[2];
+ info_unit info;
+ int owner;
+ float hp;
+ float move_points;
+ float cooldown[8];
+ float charge;
+} unit;
+
+typedef struct army_ {
+ unit us[MAXUNITS];
+ unit **grid;
+ int uslen;
+ int sx, sy;
+} army;
+
+
+#include <map.h>
+
+void unit_init (infos *info, army *ar, map *m,
+ int x, int y, info_unit *iu, int owner, unit *u);
+void unit_remove (army *ar, map *m, unit *u);
+void army_grid_init(army *ar);
+void army_init (army *ar, map *m);
+void army_destory(army *ar);
+void army_spawn (army *ar, map *m, unit u);
+void army_move (infos *info, army *ar, map *m);
+void army_fire (infos *info, army *ar, map *m);
+
+#endif \ No newline at end of file