self->hp = 1;
self->speed = 1;
self->index = -1;
+ self->bits = 0;
self->alive = 0;
return 1;
#include <stddef.h>
+typedef struct {
+ int type; // identify the unique enemy type
+ int speed; // paths per tick
+ int index; // index in paths
+ int bits; // on death
+} enemy_base_t;
+
/**
* @brief bla
*
size_t start_tick;
int id; // unique per wave
int hp;
+
+ // should move to enemy_base_t
int speed; // paths per tick
int index; // index in paths
+ int bits; // on death
+
int alive;
} enemy_t;
self->current_tick = 0;
self->waves = new_array(sizeof(wave_t) , 10);
self->events = new_array(sizeof(event_t), 20);
+ self->tbases = new_array(sizeof(tower_base_t), 10);
+ self->ebases = new_array(sizeof(enemy_base_t), 10);
self->current_wave = -1;
self->life = 10;
self->bits = 0;
- if (!self->waves || !self->events) {
+ if (!self->waves || !self->events || !self->tbases || !self->ebases) {
uninit_engine(self);
return 0;
}
free_map(self->map) ; self->map = NULL;
free_array(self->events) ; self->events = NULL;
free_array(self->waves) ; self->waves = NULL;
+ free_array(self->tbases) ; self->tbases = NULL;
+ free_array(self->ebases) ; self->ebases = NULL;
}
void engine_tick(engine_t *self) {
- array_clear(self->events);
-
// Note that multiple ennemies per tick will trigger the backfill
array_loop_i (self->waves, wave, wave_t, i) {
if (wave->done)
while (enemy) {
map_enemy_enters(self->map, enemy, self->events);
-
enemy = wave_next_enemy(wave, self->current_tick);
}
map_move_1(self->map, self->events);
map_fire_1(self->map, self->current_tick, self->events);
- map_hit_1(self->map, self->current_tick, self->events);
+ int bits = map_hit_1(self->map, self->current_tick, self->events);
+
+ if (bits) {
+ self->bits += bits;
+
+ event_t event;
+ init_event(&event, BITS);
+ event.x = bits;
+ event.move_to_x = self->bits;
+ array_push(self->events, &event);
+ }
self->current_tick++;
}
-int engine_add_tower(engine_t *self, tower_t *tower) {
- int x = tower->x;
- int y = tower->y;
+int engine_add_tower(engine_t *self, int type, int x, int y) {
if (x < 0 || y < 0)
return 0;
if (x >= self->map->width || y >= self->map->height)
return 0;
if (self->map->data[y * self->map->width + x])
return 0;
+
+ tower_base_t *base = engine_get_tower_base(self, type);
+ if (!base)
+ return 0;
+
+ if (self->bits < base->cost)
+ return 0;
tower_t **ptr = array_new(self->map->towers);
- *ptr = tower;
+ *ptr = new_tower(base, x, y);
+
+ self->bits -= base->cost;
+
+ event_t event;
+ init_event(&event, BITS);
+ event.x = -base->cost;
+ event.move_to_x = self->bits;
+ array_push(self->events, &event);
- self->map->data[y * self->map->width + x] = tower2any(tower);
+ self->map->data[y * self->map->width + x] = tower2any(*ptr);
return 1;
}
-tower_base_t *setup_tower_base(engine_t *self) {
- //TODO
+tower_base_t *engine_get_tower_base(engine_t *self, int type) {
+ array_loop (self->tbases, base, tower_base_t) {
+ if (base->type == type)
+ return base;
+ }
+
return NULL;
}
+tower_base_t *setup_tower_base(engine_t *self, int type, int cost) {
+ tower_base_t *base = engine_get_tower_base(self, type);
+ if (base) // already configured
+ return NULL;
+
+ base = array_new(self->tbases);
+ init_tower_base(base, type);
+ base->cost = cost;
+ return base;
+}
+
int setup_wave(engine_t *self, int start_tick, int bits) {
wave_t *wave = array_new(self->waves);
if (!wave)
return 1;
}
-int setup_enemy(engine_t *self, enemy_t *enemy) {
+enemy_t *setup_enemy(engine_t *self, int type, int id, size_t start_tick) {
if (!self->waves->count)
if (!setup_wave(self, 0, 0))
return 0;
+ //TODO: type and eney_base_t
+
wave_t *wave = array_last(self->waves);
- return wave_add_enemy(wave, enemy);
+ return wave_add_enemy(wave, id, start_tick);
}
int setup_path(engine_t *self, int x, int y) {
size_t current_tick;
array_t *waves; // wave_t
array_t *events; // event_t
+ array_t *tbases; // tower_base_t
+ array_t *ebases; // enemy_base_t
enemy_t *last_enemy;
int current_wave;
int life;
// will clear events on start!
void engine_tick(engine_t *self);
-int engine_add_tower(engine_t *self, tower_t *tower);
+int engine_add_tower(engine_t *self, int type, int x, int y);
-tower_base_t *setup_tower_base(engine_t *self);
+tower_base_t *engine_get_tower_base(engine_t *self, int type);
+
+tower_base_t *setup_tower_base(engine_t *self, int type, int cost);
int setup_wave(engine_t *self, int start_tick, int bits);
-int setup_enemy(engine_t *self, enemy_t *enemy);
+enemy_t *setup_enemy(engine_t *self, int type, int id, size_t start_tick);
int setup_path(engine_t *self, int x, int y);
const char *event_name(event_t *self) {
switch (self->type) {
+ case BITS : return "BITS" ;
case FIRE : return "FIRE" ;
case HIT : return "HIT" ;
case ENTER : return "ENTER" ;
cstring_addp(out, "EVENT:%s,%d,%d,%d,%d\n", name,
self->x, self->y, self->move_to_x, self->move_to_y);
break;
- case BACKFILL: case DIE: case BREACH:
+ case BACKFILL: case BREACH:
cstring_addp(out, "EVENT:%s,%d,%d\n", name, self->x, self->y);
break;
+ case DIE:
+ cstring_addp(out, "EVENT:%s,%d,%d,%d\n", name,
+ self->x, self->y, self->move_to_x);
+ break;
+ case BITS:
+ cstring_addp(out, "EVENT:%s,%d,%d\n", name,
+ self->x, self->move_to_x);
+ break;
case ENTER: case WAVE:
cstring_addp(out, "EVENT:%s,%d\n", name, self->x);
break;
* blablabla
*/
typedef enum {
+ BITS,
FIRE,
HIT,
ENTER,
#include "proj.h"
void move(map_t *self, enemy_t *enemy, array_t *events, int reverse);
-void hit(map_t *self, proj_t *proj, array_t *events);
+int hit(map_t *self, proj_t *proj, array_t *events);
map_t *new_map(int width, int height) {
map_t *self = malloc(sizeof(map_t));
}
}
-void map_hit_1(map_t *self, int current_tick, array_t *events) {
+int map_hit_1(map_t *self, int current_tick, array_t *events) {
+ int bits = 0;
+
proj_t *prev = self->projs;
for (proj_t *p = prev->next ; p ; p = p->next) {
if (p->boom_tick <= current_tick) {
- hit(self, p, events);
+ bits += hit(self, p, events);
prev->next = p->next;
free_proj(p);
prev = p;
}
+
+ return bits;
}
void move(map_t *self, enemy_t *enemy, array_t *events, int reverse) {
return;
}
-void hit(map_t *self, proj_t *proj, array_t *events) {
+int hit(map_t *self, proj_t *proj, array_t *events) {
// TODO: loop through alive for radius? tower needs the same
any_t *any = self->data[proj->y * self->width + proj->x];
path_t *path = anypath(any);
enemy_t *e = (path) ? path->enemy : NULL;
+ int bits = 0;
if (e && e->hp > 0) {
e->hp -= proj->desc.damage;
e->alive = 0;
path->enemy = NULL;
init_event(&event, DIE);
+ bits = e->bits;
+ event.move_to_x = bits;
} else {
init_event(&event, HIT);
}
event.y = path->y;
array_push(events, &event);
}
+
+ return bits;
}
void map_fire_1(map_t *self, int current_tick, array_t *events);
-void map_hit_1(map_t *self, int current_tick, array_t *events);
+// returns bits gained
+int map_hit_1(map_t *self, int current_tick, array_t *events);
#endif /* MAP_H */
path_t *path = anypath(any);
tower_t *tower = anytower(any);
if (tower) {
- fprintf(stderr, "T");
+ char t = 'T';
+ if ((tower->base->type >= 0)
+ && (tower->base->type <= 9)) {
+ t = '0' + tower->base->type;
+ }
+
+ fprintf(stderr, "%c", t);
} else if (path) {
if (path->enemy) {
fprintf(stderr, "e");
switch(cmd->type) {
case TICK:
engine_tick(engine);
- array_loop(engine->events, event, event_t) {
- event_output(event, out);
- fprintf(stdout, "%s", out->string);
- cstring_clear(out);
- }
- if (displayMode) {
- fprintf(stderr,
- "Tick is: %zu\n", engine->current_tick);
- display(engine->map);
- }
break;
case DISPLAY:
displayMode = !displayMode;
- if (displayMode) {
- fprintf(stderr,
- "Tick is: %zu\n", engine->current_tick);
- display(engine->map);
- }
break;
case READFILE:
array_loop (cmd->data, ptr, char*) {
return 0;
}
+ // Process all events
+ array_loop(engine->events, event, event_t) {
+ event_output(event, out);
+ fprintf(stdout, "%s", out->string);
+ cstring_clear(out);
+ }
+ array_clear(engine->events);
+
+ // display mode
+ if ((cmd->type == TICK || cmd->type == DISPLAY) && (displayMode)) {
+ fprintf(stderr,
+ "Tick is: %zu\n", engine->current_tick);
+ display(engine->map);
+ }
+
return 1;
}
setup_path(engine, 4, 2);
setup_path(engine, 5, 2);
- tower_base_t base;
- init_tower_base(&base, 0);
+ setup_tower_base(engine, 0, 10);
- tower_t *tower = new_tower(&base, 2, 1);
- // TODO: fix setup_tower_base
- // TODO: use the tower base array (0 or 1.. instead of base)
- // TODO: use bits
- engine_add_tower(engine, tower);
+ enemy_t *enemy = setup_enemy(engine, 0, 0, 0);
+ enemy->speed = 2;
+ enemy->bits = 5;
- enemy_t *enemy = new_enemy(0, 1);
- enemy->speed = 1;
- setup_enemy(engine, enemy);
+ engine->bits = 100;
+ engine_add_tower(engine, 0, 2, 1);
read_commands(engine, stdin);
int init_tower_base(tower_base_t *self, int type) {
self->type = type;
self->stats_sz = 0;
+ self->cost = 0;
self->super_cost = 0;
self->super_power = 0;
memset(self->stats, '\0', sizeof(self->stats));
int type; // identify the unique tower type
tower_lvl_t stats[6];
int stats_sz; // how many are used
+ int cost; // base cost
int super_cost;
int super_power;
} tower_base_t;
int proj_speed; // speed of the proj in locs per tick
int super;
int fire_delayed; // in ticks still to wait
- int cost; // total cost in bits
+ int cost; // total *resell* cost in bits (all upgrades included)
proj_desc_t projectile;
} tower_t;
self->last_enemy = NULL;
}
-int wave_add_enemy(wave_t *self, enemy_t *enemy) {
- if (!array_push(self->enemies, enemy))
- return 0;
- return 1;
+enemy_t *wave_add_enemy(wave_t *self, int id, size_t start_tick) {
+ enemy_t *enemy = array_new(self->enemies);
+ if (!enemy)
+ return NULL;
+ init_enemy(enemy, id, start_tick);
+ return enemy;
}
enemy_t *wave_next_enemy(wave_t *self, int tick) {
*/
void uninit_wave(wave_t *self);
-int wave_add_enemy(wave_t *self, enemy_t *enemy);
+enemy_t *wave_add_enemy(wave_t *self, int id, size_t start_tick);
enemy_t *wave_next_enemy(wave_t *self, int tick);