tower_base step 2 + bits
authorNiki Roo <niki@nikiroo.be>
Sat, 12 Apr 2025 21:24:21 +0000 (23:24 +0200)
committerNiki Roo <niki@nikiroo.be>
Sat, 12 Apr 2025 21:24:21 +0000 (23:24 +0200)
13 files changed:
src/tdef/enemy.c
src/tdef/enemy.h
src/tdef/engine.c
src/tdef/engine.h
src/tdef/event.c
src/tdef/event.h
src/tdef/map.c
src/tdef/map.h
src/tdef/tdef.c
src/tdef/tower.c
src/tdef/tower.h
src/tdef/wave.c
src/tdef/wave.h

index b2940edaf3994b8a129c0d8740c7008d71291114..b60ee60214f5643642930446c227fd0303b34bba 100644 (file)
@@ -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;
index 3f196261330e8af2e788c940f6c9d7fe308b0eb4..cb783cd769818dfadec5991e037c51491838d2d7 100644 (file)
 
 #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
  *
@@ -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;
 
index 6ba12ae838e156708ca714dc650706d73901f1db..e2f23a33b4fbd9fce2e639faa7c2cef2f1d1ae8e 100644 (file)
@@ -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) {
index 969909a866dd0ffc4fb72d427f606b0536423e60..0de52a1e8a6a4348b8e650f56f59e2a9d0eafef6 100644 (file)
@@ -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);
 
index 8aed3952f602426e825c0f9053628f311cfb6aca..c3d07c10729de313a4a1b0a1656ab3b9b9cbdfc9 100644 (file)
@@ -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;
index f647bfd95063168df101ee342e22ff85952e0fa1..48f37ca915a13baa30e9aa68dbdd51bf27bc265c 100644 (file)
@@ -21,6 +21,7 @@
  * blablabla
  */
 typedef enum {
+       BITS,
        FIRE,
        HIT,
        ENTER,
index 372ce1fe1cc45daa7686654b1e0d571790ca1c7d..811a73558575a05d10e8add92f61f6b3875c2002 100644 (file)
@@ -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;
 }
 
index cf1f49ee2c9a7640ad3a7c1f300c0bbffd2606b7..a6f041629d26d0eaef68d8fadc3ef8d139c9de85 100644 (file)
@@ -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 */
 
index abc50a77fb864a1879d96ac562624707992529d4..14319adf840a16e676a4cec27031575352ef4ed4 100644 (file)
@@ -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);
        
index 32817c9c14ad420cd9d1c2e93ccaf8d45b6f41e3..dc0956b0d8270154a9f08431861da2957e913efd 100644 (file)
@@ -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));
index 6a30bc6078be567af95f43c6ec5b813fd0b910df..2ad6fa481f485d67b55ec7d09b61a801a723f4ae 100644 (file)
@@ -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;
 
index 332c9a3bf76f0a95819f2d3da9c9011e2e70c9ed..9f12a2d6fe3a84e70a00f8d926fd409345a67a44 100644 (file)
@@ -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) {
index 38bd41eabc99300114564f1a5472f97816effb2c..58b7cfac9230083d0ac85e51a1baceb0b9a5c780 100644 (file)
@@ -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);