From 241ca67fdc69bbabf277d33e0ba444e4e88c4aff Mon Sep 17 00:00:00 2001 From: Niki Date: Wed, 16 Apr 2025 18:57:29 +0200 Subject: [PATCH] event/error fix prefix, add new commands --- src/tdef/command.h | 8 +++++ src/tdef/engine.c | 18 +++++++---- src/tdef/event.c | 58 +++++++++++++++++++++-------------- src/tdef/event.h | 32 ++++++++++++-------- src/tdef/map.c | 14 ++++----- src/tdef/reader.c | 75 ++++++++++++++++++++++++++++++++++++++++------ src/tdef/setup.c | 15 +++++++--- src/tdef/tdef.c | 43 ++++++++++++++++++++++++-- 8 files changed, 198 insertions(+), 65 deletions(-) diff --git a/src/tdef/command.h b/src/tdef/command.h index 84e2054..59ee55d 100644 --- a/src/tdef/command.h +++ b/src/tdef/command.h @@ -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: diff --git a/src/tdef/engine.c b/src/tdef/engine.c index 85ba3c9..3bf1a7f 100644 --- a/src/tdef/engine.c +++ b/src/tdef/engine.c @@ -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); diff --git a/src/tdef/event.c b/src/tdef/event.c index 150c2b2..896e605 100644 --- a/src/tdef/event.c +++ b/src/tdef/event.c @@ -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; } } diff --git a/src/tdef/event.h b/src/tdef/event.h index ff7c63f..71b88bb 100644 --- a/src/tdef/event.h +++ b/src/tdef/event.h @@ -21,22 +21,25 @@ * 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 */ diff --git a/src/tdef/map.c b/src/tdef/map.c index 5cf7a17..fa385b6 100644 --- a/src/tdef/map.c +++ b/src/tdef/map.c @@ -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; diff --git a/src/tdef/reader.c b/src/tdef/reader.c index b9649a1..a6e0bdb 100644 --- a/src/tdef/reader.c +++ b/src/tdef/reader.c @@ -37,15 +37,50 @@ // // 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)) diff --git a/src/tdef/setup.c b/src/tdef/setup.c index db0d6b7..19426c6 100644 --- a/src/tdef/setup.c +++ b/src/tdef/setup.c @@ -25,8 +25,14 @@ 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; diff --git a/src/tdef/tdef.c b/src/tdef/tdef.c index 110ca65..ebf1195 100644 --- a/src/tdef/tdef.c +++ b/src/tdef/tdef.c @@ -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: -- 2.27.0