From: Niki Roo Date: Sat, 12 Apr 2025 21:24:21 +0000 (+0200) Subject: tower_base step 2 + bits X-Git-Url: http://git.nikiroo.be/?a=commitdiff_plain;h=c32010171ec1f12bb4e626458abbc9b87480d161;p=tdef.git tower_base step 2 + bits --- diff --git a/src/tdef/enemy.c b/src/tdef/enemy.c index b2940ed..b60ee60 100644 --- a/src/tdef/enemy.c +++ b/src/tdef/enemy.c @@ -43,6 +43,7 @@ int init_enemy(enemy_t *self, int id, size_t start_tick) { self->hp = 1; self->speed = 1; self->index = -1; + self->bits = 0; self->alive = 0; return 1; diff --git a/src/tdef/enemy.h b/src/tdef/enemy.h index 3f19626..cb783cd 100644 --- a/src/tdef/enemy.h +++ b/src/tdef/enemy.h @@ -14,6 +14,13 @@ #include +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 * @@ -24,8 +31,12 @@ typedef struct { 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; diff --git a/src/tdef/engine.c b/src/tdef/engine.c index 6ba12ae..e2f23a3 100644 --- a/src/tdef/engine.c +++ b/src/tdef/engine.c @@ -45,11 +45,13 @@ int init_engine(engine_t *self, map_t *map) { 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; } @@ -76,11 +78,11 @@ void uninit_engine(engine_t *self) { 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) @@ -99,7 +101,6 @@ void engine_tick(engine_t *self) { while (enemy) { map_enemy_enters(self->map, enemy, self->events); - enemy = wave_next_enemy(wave, self->current_tick); } @@ -107,33 +108,71 @@ void engine_tick(engine_t *self) { 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) @@ -145,13 +184,15 @@ int setup_wave(engine_t *self, int start_tick, int bits) { 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) { diff --git a/src/tdef/engine.h b/src/tdef/engine.h index 969909a..0de52a1 100644 --- a/src/tdef/engine.h +++ b/src/tdef/engine.h @@ -28,6 +28,8 @@ typedef struct { 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; @@ -81,13 +83,15 @@ void uninit_engine(engine_t *self); // 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); diff --git a/src/tdef/event.c b/src/tdef/event.c index 8aed395..c3d07c1 100644 --- a/src/tdef/event.c +++ b/src/tdef/event.c @@ -60,6 +60,7 @@ void uninit_event(event_t *self) { 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" ; @@ -82,9 +83,17 @@ void event_output(event_t *self, cstring_t *out) { 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; diff --git a/src/tdef/event.h b/src/tdef/event.h index f647bfd..48f37ca 100644 --- a/src/tdef/event.h +++ b/src/tdef/event.h @@ -21,6 +21,7 @@ * blablabla */ typedef enum { + BITS, FIRE, HIT, ENTER, diff --git a/src/tdef/map.c b/src/tdef/map.c index 372ce1f..811a735 100644 --- a/src/tdef/map.c +++ b/src/tdef/map.c @@ -26,7 +26,7 @@ #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)); @@ -159,11 +159,13 @@ 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) { +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); @@ -172,6 +174,8 @@ void map_hit_1(map_t *self, int current_tick, array_t *events) { prev = p; } + + return bits; } void move(map_t *self, enemy_t *enemy, array_t *events, int reverse) { @@ -219,11 +223,12 @@ 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; @@ -234,6 +239,8 @@ void hit(map_t *self, proj_t *proj, array_t *events) { e->alive = 0; path->enemy = NULL; init_event(&event, DIE); + bits = e->bits; + event.move_to_x = bits; } else { init_event(&event, HIT); } @@ -242,5 +249,7 @@ void hit(map_t *self, proj_t *proj, array_t *events) { event.y = path->y; array_push(events, &event); } + + return bits; } diff --git a/src/tdef/map.h b/src/tdef/map.h index cf1f49e..a6f0416 100644 --- a/src/tdef/map.h +++ b/src/tdef/map.h @@ -85,7 +85,8 @@ void map_move_1(map_t *self, array_t *events); 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 */ diff --git a/src/tdef/tdef.c b/src/tdef/tdef.c index abc50a7..14319ad 100644 --- a/src/tdef/tdef.c +++ b/src/tdef/tdef.c @@ -41,7 +41,13 @@ void display(map_t *self) { 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"); @@ -73,24 +79,9 @@ int process_cmd(command_t *cmd, engine_t *engine) { 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*) { @@ -125,6 +116,21 @@ int process_cmd(command_t *cmd, engine_t *engine) { 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; } @@ -158,18 +164,14 @@ int main(int argc, char **argv) { 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); diff --git a/src/tdef/tower.c b/src/tdef/tower.c index 32817c9..dc0956b 100644 --- a/src/tdef/tower.c +++ b/src/tdef/tower.c @@ -67,6 +67,7 @@ void uninit_tower(tower_t *self) { 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)); diff --git a/src/tdef/tower.h b/src/tdef/tower.h index 6a30bc6..2ad6fa4 100644 --- a/src/tdef/tower.h +++ b/src/tdef/tower.h @@ -26,6 +26,7 @@ typedef struct { 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; @@ -47,7 +48,7 @@ typedef struct { 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; diff --git a/src/tdef/wave.c b/src/tdef/wave.c index 332c9a3..9f12a2d 100644 --- a/src/tdef/wave.c +++ b/src/tdef/wave.c @@ -69,10 +69,12 @@ void uninit_wave(wave_t *self) { 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) { diff --git a/src/tdef/wave.h b/src/tdef/wave.h index 38bd41e..58b7cfa 100644 --- a/src/tdef/wave.h +++ b/src/tdef/wave.h @@ -73,7 +73,7 @@ void free_wave(wave_t *self); */ 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);