event/error fix prefix, add new commands
authorNiki <niki@nikiroo.be>
Wed, 16 Apr 2025 16:57:29 +0000 (18:57 +0200)
committerNiki <niki@nikiroo.be>
Wed, 16 Apr 2025 16:57:29 +0000 (18:57 +0200)
src/tdef/command.h
src/tdef/engine.c
src/tdef/event.c
src/tdef/event.h
src/tdef/map.c
src/tdef/reader.c
src/tdef/setup.c
src/tdef/tdef.c

index 84e2054997e3cdbd627f987d2dd8e16ef7d62bc2..59ee55da669d863b5efcb20255a38f207f0b8647 100644 (file)
@@ -29,6 +29,14 @@ typedef enum {
        COMMAND_LIFE,
        COMMAND_BITS,
        COMMAND_PATH,
+       COMMAND_TOWER,
+       COMMAND_TOWER_LVL,
+       COMMAND_TOWER_SP,
+       COMMAND_WAVE,
+       COMMAND_ENEMY,
+       
+       COMMAND_ADD_TOWER,
+
        COMMAND_QUIT,
        
        // error management:
index 85ba3c92c66b9c1cd078157ef9ef62fac3f846d2..3bf1a7fc7740916526d97f98cddd0c88269576ea 100644 (file)
@@ -96,8 +96,8 @@ int engine_reset_map(engine_t *self, int width, int height) {
 void engine_tick(engine_t *self) {
        if (!self->map) {
                event_t event;
-               init_event(&event, ERROR);
-               event.x = EEVENT_NOMAP;
+               init_event(&event, EVENT_ERROR);
+               event.error = EEVENT_MAP_NOT_INITIALISED;
                array_push(self->events, &event);
 
                return;
@@ -114,7 +114,7 @@ void engine_tick(engine_t *self) {
                if (enemy && (cw < 0 || cw < i)) {
                        self->current_wave = i;
                        event_t event;
-                       init_event(&event, WAVE);
+                       init_event(&event, EVENT_WAVE);
                        event.x = i,
                        array_push(self->events, &event);
                }
@@ -134,7 +134,7 @@ void engine_tick(engine_t *self) {
                self->bits += bits;
                
                event_t event;
-               init_event(&event, BITS);
+               init_event(&event, EVENT_BITS);
                event.x = bits;
                event.move_to_x = self->bits;
                array_push(self->events, &event);
@@ -155,8 +155,14 @@ int engine_add_tower(engine_t *self, int type, int x, int y) {
        if (!base)
                return 0;
        
-       if (self->bits < base->cost)
+       if (self->bits < base->cost) {
+               event_t event;
+               init_event(&event, EVENT_ERROR);
+               event.error = EEVENT_NOT_ENOUGH_BITS;
+               array_push(self->events, &event);
+
                return 0;
+       }
 
        tower_t **ptr = array_new(self->map->towers);
        *ptr = new_tower(base, x, y);
@@ -164,7 +170,7 @@ int engine_add_tower(engine_t *self, int type, int x, int y) {
        self->bits -= base->cost;
        
        event_t event;
-       init_event(&event, BITS);
+       init_event(&event, EVENT_BITS);
        event.x = -base->cost;
        event.move_to_x = self->bits;
        array_push(self->events, &event);
index 150c2b23f6acc496acdd6c1ab835b37238ce9baa..896e605fd1447505401e4a609e0670e452a6d291 100644 (file)
@@ -38,9 +38,10 @@ int init_event(event_t *self, event_type type) {
        self->CNAME[sz - 2] = ']';
        self->CNAME[sz - 1] = '\0';
        
-       self->type = type;
-       self->x = -1;
-       self->y = -1;
+       self->type      = type;
+       self->error     = EEVENT_SUCCESS;
+       self->x         = -1;
+       self->y         = -1;
        self->move_to_x = -1;
        self->move_to_y = -1;
        
@@ -60,49 +61,60 @@ 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"   ;
-       case BACKFILL: return "BACKFILL";
-       case MOVE    : return "MOVE"    ;
-       case DIE     : return "DIE"     ;
-       case BREACH  : return "BREACH"  ;
-       case WAVE    : return "WAVE"    ;
-       case WIN     : return "WIN"     ;
-       case LOOSE   : return "LOOSE"   ;
-       case ERROR   : return "ERROR"   ;
+       case EVENT_BITS    : return "BITS"    ; 
+       case EVENT_FIRE    : return "FIRE"    ; 
+       case EVENT_HIT     : return "HIT"     ;
+       case EVENT_ENTER   : return "ENTER"   ;
+       case EVENT_BACKFILL: return "BACKFILL";
+       case EVENT_MOVE    : return "MOVE"    ;
+       case EVENT_DIE     : return "DIE"     ;
+       case EVENT_BREACH  : return "BREACH"  ;
+       case EVENT_WAVE    : return "WAVE"    ;
+       case EVENT_WIN     : return "WIN"     ;
+       case EVENT_LOOSE   : return "LOOSE"   ;
+       case EVENT_ERROR   : return "ERROR"   ;
        }
        return "Unknown";
 }
 
+const char *event_ename(event_t *self) {
+       switch(self->x) {
+       case EEVENT_SUCCESS             : return "SUCCESS"            ;
+       case EEVENT_MAP_NOT_INITIALISED : return "MAP_NOT_INITIALISED";
+       case EEVENT_ALREADY_CONFIGURED  : return "ALREADY_CONFIGURED" ;
+       case EEVENT_NOT_ENOUGH_BITS     : return "NOT_ENOUGH_BITS"    ;
+       }
+       
+       return "Unknown";
+}
+
 void event_output(event_t *self, cstring_t *out) {
        const char *name = event_name(self);
        
        switch (self->type) {
-       case FIRE: case HIT: case MOVE: 
+       case EVENT_FIRE: case EVENT_HIT: case EVENT_MOVE: 
                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 BREACH:
+       case EVENT_BACKFILL: case EVENT_BREACH:
                cstring_addp(out, "EVENT:%s,%d,%d\n", name, self->x, self->y);
                break;
-       case DIE:
+       case EVENT_DIE:
                cstring_addp(out, "EVENT:%s,%d,%d,%d\n", name, 
                        self->x, self->y, self->move_to_x);
                break;
-       case BITS:
+       case EVENT_BITS:
                cstring_addp(out, "EVENT:%s,%d,%d\n", name, 
                        self->x, self->move_to_x);
                break;
-       case ENTER: case WAVE:
+       case EVENT_ENTER: case EVENT_WAVE:
                cstring_addp(out, "EVENT:%s,%d\n", name, self->x);
                break;
-       case WIN: case LOOSE:
+       case EVENT_WIN: case EVENT_LOOSE:
                cstring_addp(out, "EVENT:%s\n", name);
                break;
-       case ERROR:
-               cstring_addp(out, "ERROR: %d\n", self->x);
+       case EVENT_ERROR:
+               cstring_addp(out, "ERROR: %s\n", event_ename(self));
                break;
        }
 }
index ff7c63f7ddd07b79565bc29a8f15b172a9a5ce47..71b88bb6da770355ab3878960d612af728d46930 100644 (file)
  * blablabla
  */
 typedef enum {
-       BITS,
-       FIRE,
-       HIT,
-       ENTER,
-       BACKFILL,
-       MOVE,
-       DIE,
-       BREACH,
-       WAVE,
-       WIN,
-       LOOSE,
-       ERROR,
+       EVENT_BITS,
+       EVENT_FIRE,
+       EVENT_HIT,
+       EVENT_ENTER,
+       EVENT_BACKFILL,
+       EVENT_MOVE,
+       EVENT_DIE,
+       EVENT_BREACH,
+       EVENT_WAVE,
+       EVENT_WIN,
+       EVENT_LOOSE,
+       EVENT_ERROR,
 } event_type;
 
 typedef enum {
-       EEVENT_NOMAP,
+       EEVENT_SUCCESS,
+       EEVENT_MAP_NOT_INITIALISED,
+       EEVENT_ALREADY_CONFIGURED,
+       EEVENT_NOT_ENOUGH_BITS,
 } eevent_type;
 
 /**
@@ -47,6 +50,7 @@ typedef enum {
 typedef struct {
        char CNAME[10];
        event_type type;
+       eevent_type error;
        int x;
        int y;
        int move_to_x;
@@ -97,6 +101,8 @@ void uninit_event(event_t *self);
 
 const char *event_name(event_t *self);
 
+const char *event_ename(event_t *self);
+
 void event_output(event_t *self, cstring_t *out);
 
 #endif /* EVENT_H */
index 5cf7a17025c07a219cfea5007193a1cca17f0f4d..fa385b6ddda401acbe44db0b36d5ffbbc64eff5f 100644 (file)
@@ -121,7 +121,7 @@ void map_enemy_enters(map_t *self, enemy_t *enemy, array_t *events) {
        array_push(self->alive, &enemy);
        
        event_t event;
-       init_event(&event, ENTER);
+       init_event(&event, EVENT_ENTER);
        event.x = enemy->id;
        array_push(events, &event);
        
@@ -156,7 +156,7 @@ void map_move_1(map_t *self, array_t *events) {
 
 void map_fire_1(map_t *self, int current_tick, array_t *events) {
        event_t event;
-       init_event(&event, FIRE);
+       init_event(&event, EVENT_FIRE);
        
        array_loop(self->towers, ptr, tower_t*) {
                tower_t *tower = *ptr;
@@ -201,7 +201,7 @@ void move(map_t *self, enemy_t *enemy, array_t *events, int reverse) {
        int source = enemy->index;
        int target = source >= 0 ? source+1 : 0;
        event_t event;
-       init_event(&event, MOVE);
+       init_event(&event, EVENT_MOVE);
        
        path_t *path_from = NULL;
        if (enemy->index >= 0) {
@@ -216,7 +216,7 @@ void move(map_t *self, enemy_t *enemy, array_t *events, int reverse) {
                if (target == -1) { // backfill
                        enemy->alive = 0;
                        array_push(self->backfill, &enemy);
-                       event.type = BACKFILL;
+                       event.type = EVENT_BACKFILL;
                        array_push(events, &event);
                        return;
                }
@@ -234,7 +234,7 @@ void move(map_t *self, enemy_t *enemy, array_t *events, int reverse) {
        } else { // breached
                enemy->alive = 0;
                array_push(self->breached, &enemy);
-               event.type = BREACH;
+               event.type = EVENT_BREACH;
        }
        
        array_push(events, &event);
@@ -257,11 +257,11 @@ int hit(map_t *self, proj_t *proj, array_t *events) {
                        e->hp = 0;
                        e->alive = 0;
                        path->enemy = NULL;
-                       init_event(&event, DIE);
+                       init_event(&event, EVENT_DIE);
                        bits = e->bits;
                        event.move_to_x = bits;
                } else {
-                       init_event(&event, HIT);
+                       init_event(&event, EVENT_HIT);
                }
                
                event.x = path->x;
index b9649a122b88e36b57a9da2b97a4e9443b11d6e8..a6e0bdb804d0182dd86f51ca79e57ecdde9fc50c 100644 (file)
 //
 // Note that white space around the separators (':' or ',') are allowed.
 //
-// Known commands:
-// > .                        = will process a tick in the game engine
-// > display                  = will toggle display (debug) mode
-// > readfile : "file1..."    = will read commands from the given file(s)
-// > map      : width, height = will setup the map (and reset the path)
-// > life     : lives         = will set the number of life points
-// > bits     : bit_amount    = will set the current bits (money) balance
-// > path     : x1,y1,x2,y2.. = will setup the enemies path (cumulative)
-// > quit                     = will immediately exit the game
+// Engine commands:
+// * .        : will process a tick in the game engine
+// * readfile : will read commands from the given file(s) -- one minimum
+//   > (n) "file1..."
+//
+// Setup commands:
+// * map      : will setup the map (and reset the path)
+//   > (0) width
+//   > (1) height
+// * life     : will set the number of life points
+//   > (0) lives
+// * bits     : will set the current bits (money) balance
+//   > (0) bits_amount
+// * path     : will setup the enemies path (cumulative and ordered)
+//   > (n) x1,y1, x2,y2...
+// * tower    : will setup a new tower type
+//   > (0) type      : the unique identifier for this tower type
+//   > (1) base_cost
+// * tower_lvl: will configure a tower upgrade level
+//   > (0) type      : the unique identifier for this tower type
+//   > (1) attack    : how many points dealt to enemies
+//   > (2) speed     : the time needed to rearm after having fired
+//   > (3) range     : the range in locations ("path")
+//   > (4) cost      : upgrade cost for this level (for each of atk, spd, rng)
+// * tower_sp : set the Super Power of a tower
+//   > (0) type      : the unique identifier for this tower type
+//   > (1) super_cost
+//   > (2) super_power
+// * wave            : configure a new wave TODO
+// * enemy : add a new enemy in the current wave (can create the first one)
+//   > type          : the enemy type
+//   > id            : the *unique* id of this enemy
+//   > start_tick    : the tick at which it will appear (wave-relative)
+//
+// Runtime commands:
+// * add_tower: add a new tower on the map (will cost bits)
+//   > (0) type      : the type of tower to add
+//   > (1) X position: the X coordinate
+//   > (2) Y position: the Y coordinate
+//
+// Other commands:
+// * display  : will toggle display (debug) mode
+// * quit     : will immediately exit the game
+// 
 
 // TODO: configuration:
 // tower: configTower('1', ...)
@@ -119,6 +154,28 @@ command_t *reader_readnext(FILE *file) {
                                cmd->type = COMMAND_INVALID;
                        if ((command_read_count(cmd, line->string) % 2) == 1)
                                cmd->type = COMMAND_INVALID;
+               } else if (is_cmd(line, "tower")) {
+                       cmd->type = COMMAND_TOWER;
+                       if (!command_read_int(cmd, line->string, 0, 1))
+                               cmd->type = COMMAND_INVALID;
+               } else if (is_cmd(line, "tower_lvl")) {
+                       cmd->type = COMMAND_TOWER_LVL;
+                       if (!command_read_int(cmd, line->string, 0, 4))
+                               cmd->type = COMMAND_INVALID;
+               } else if (is_cmd(line, "tower_sp")) {
+                       cmd->type = COMMAND_TOWER_SP;
+                       // TODO
+               } else if (is_cmd(line, "wave")) {
+                       cmd->type = COMMAND_WAVE;
+                       // TODO
+               } else if (is_cmd(line, "enemy")) {
+                       cmd->type = COMMAND_ENEMY;
+                       if (!command_read_int(cmd, line->string, 0, 2))
+                               cmd->type = COMMAND_INVALID;
+               } else if (is_cmd(line, "add_tower")) {
+                       cmd->type = COMMAND_ADD_TOWER;
+                       if (!command_read_int(cmd, line->string, 0, 2))
+                               cmd->type = COMMAND_INVALID;
                } else if (is_cmd(line, "quit")) {
                        cmd->type = COMMAND_QUIT;
                        if (command_read_count(cmd, line->string))
index db0d6b7b2bb2bc866a355e7e24cedeecf5bb6c52..19426c61b226744fda79856bf4e605b778c02858 100644 (file)
 
 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
+       if (base) { // already configured
+               event_t event;
+               init_event(&event, EVENT_ERROR);
+               event.error = EEVENT_ALREADY_CONFIGURED;
+               array_push(self->events, &event);
+               
                return NULL;
+       }
        
        base = array_new(self->tbases);
        init_tower_base(base, type);
@@ -51,7 +57,8 @@ enemy_t *setup_enemy(engine_t *self, int type, int id, size_t start_tick) {
                if (!setup_wave(self, 0, 0))
                        return 0;
        
-       //TODO: type and eney_base_t
+       //TODO: type and enemy_base_t
+       //TODO: id must be unique (total, not only per wave)
        
        wave_t *wave = array_last(self->waves);
        return wave_add_enemy(wave, id, start_tick);
@@ -60,8 +67,8 @@ 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) {
        if (!self->map) {
                event_t event;
-               init_event(&event, ERROR);
-               event.x = EEVENT_NOMAP;
+               init_event(&event, EVENT_ERROR);
+               event.error = EEVENT_MAP_NOT_INITIALISED;
                array_push(self->events, &event);
 
                return 0;
index 110ca654bf2d6ddbb91a66c2dd8658a7abf664dd..ebf11950286aabd46f1df8060c3c28bce9fcf9e7 100644 (file)
@@ -119,9 +119,46 @@ int process_cmd(command_t *cmd, engine_t *engine) {
                break;
        case COMMAND_PATH:
                setup_path(
-                               engine,
-                               command_get_int(cmd, 0),
-                               command_get_int(cmd, 1)
+                       engine,
+                       command_get_int(cmd, 0),
+                       command_get_int(cmd, 1)
+               );
+               break;
+       case COMMAND_TOWER:
+               setup_tower_base(
+                       engine,
+                       command_get_int(cmd, 0),
+                       command_get_int(cmd, 1)
+               );
+               break;
+       case COMMAND_TOWER_LVL:
+               break;
+       case COMMAND_TOWER_SP:
+               // TODO
+               printf("TODO: command_tower_sp\n");
+               break;
+       case COMMAND_WAVE:
+               // TODO
+               printf("TODO: command_wave\n");
+               break;
+       case COMMAND_ENEMY:
+               ;enemy_t *enemy = setup_enemy(
+                       engine,
+                       command_get_int(cmd, 0),
+                       command_get_int(cmd, 1),
+                       command_get_int(cmd, 2)
+               );
+               // TODO: enemy_base:
+               enemy->speed = 2;
+               enemy->bits = 5;
+               // end-of-TODO
+               break;
+       case COMMAND_ADD_TOWER:
+               engine_add_tower(
+                       engine,
+                       command_get_int(cmd, 0),
+                       command_get_int(cmd, 1),
+                       command_get_int(cmd, 2)
                );
                break;
        case COMMAND_QUIT: