From 871b6e92d6e47ed011ecaa48295124eae719920d Mon Sep 17 00:00:00 2001 From: Niki Date: Wed, 16 Apr 2025 08:35:54 +0200 Subject: [PATCH] improve command system and add some --- src/tdef/command.c | 12 +++++++++- src/tdef/command.h | 5 ++++ src/tdef/engine.c | 28 ++++++++++++++++++---- src/tdef/engine.h | 11 ++++----- src/tdef/event.c | 4 ++++ src/tdef/event.h | 5 ++++ src/tdef/reader.c | 11 +++++++-- src/tdef/setup.c | 10 ++++++++ src/tdef/tdef.c | 58 ++++++++++++++++++++++++++++------------------ 9 files changed, 109 insertions(+), 35 deletions(-) diff --git a/src/tdef/command.c b/src/tdef/command.c index 4a249f8..6280cf8 100644 --- a/src/tdef/command.c +++ b/src/tdef/command.c @@ -207,6 +207,16 @@ int command_read_file(command_t *self,const char line[],int pstart,int pstop) { return ok; } +char *command_get(command_t *self, int i) { + char **p = array_get(self->data, i); + return *p; +} + +int command_get_int(command_t *self, int i) { + char **p = array_get(self->data, i); + return atoi(*p); +} + array_t *read_word(command_t *self,const char line[],int pstart,int pstop) { array_t *tmp = new_array(sizeof(char *), 1); @@ -265,7 +275,7 @@ array_t *read_word(command_t *self,const char line[],int pstart,int pstop) { howmany_read++; } - if ((pstop >= 0) && (tmp->count != (pstop - pstart))) { + if ((pstop >= 0) && (tmp->count != ((pstop - pstart) + 1))) { free_array(tmp); tmp = NULL; } diff --git a/src/tdef/command.h b/src/tdef/command.h index d290162..84e2054 100644 --- a/src/tdef/command.h +++ b/src/tdef/command.h @@ -21,6 +21,7 @@ * blablabla */ typedef enum { + COMMAND_COMMENT, COMMAND_TICK, COMMAND_DISPLAY, COMMAND_READFILE, @@ -102,5 +103,9 @@ int command_read_int(command_t *self,const char line[],int pstart,int pstop); int command_read_file(command_t *self,const char line[],int pstart,int pstop); +char *command_get(command_t *self, int i); + +int command_get_int(command_t *self, int i); + #endif /* COMMAND_H */ diff --git a/src/tdef/engine.c b/src/tdef/engine.c index bee6ddd..85ba3c9 100644 --- a/src/tdef/engine.c +++ b/src/tdef/engine.c @@ -25,9 +25,9 @@ int tickit(); -engine_t *new_engine(map_t *map) { +engine_t *new_engine() { engine_t *self = malloc(sizeof(engine_t)); - if (!init_engine(self, map)) { + if (!init_engine(self)) { free(self); self = NULL; } @@ -35,13 +35,13 @@ engine_t *new_engine(map_t *map) { return self; } -int init_engine(engine_t *self, map_t *map) { +int init_engine(engine_t *self) { size_t sz = sizeof(self->CNAME); strncpy(self->CNAME, "[engine ", sz); self->CNAME[sz - 2] = ']'; self->CNAME[sz - 1] = '\0'; - self->map = map; + self->map = NULL; self->current_tick = 0; self->waves = new_array(sizeof(wave_t) , 10); self->events = new_array(sizeof(event_t), 20); @@ -82,7 +82,27 @@ void uninit_engine(engine_t *self) { free_array(self->ebases) ; self->ebases = NULL; } +int engine_reset_map(engine_t *self, int width, int height) { + if (self->map) + free_map(self->map); + self->current_tick = 0; + self->current_wave = 0; + self->last_enemy = NULL; + self->map = new_map(width, height); + + return !!self->map; +} + void engine_tick(engine_t *self) { + if (!self->map) { + event_t event; + init_event(&event, ERROR); + event.x = EEVENT_NOMAP; + array_push(self->events, &event); + + return; + } + // Note that multiple ennemies per tick will trigger the backfill array_loop_i (self->waves, wave, wave_t, i) { if (wave->done) diff --git a/src/tdef/engine.h b/src/tdef/engine.h index cd97f02..15642f0 100644 --- a/src/tdef/engine.h +++ b/src/tdef/engine.h @@ -39,8 +39,6 @@ typedef struct { /** * Create a new engine. * - * @param map the game map (will be owned by this engine) - * * @note always identical to malloc + init_engine * * @see malloc() @@ -48,14 +46,12 @@ typedef struct { * * @return a new engine (you must later call `free_engine()`) */ -engine_t *new_engine(map_t *map); +engine_t *new_engine(); /** * Initialise a new engine. - * - * @param map the game map (will be owned by this engine) */ -int init_engine(engine_t *self, map_t *map); +int init_engine(engine_t *self); /** * Free the resources held for the given engine: you must not use it any more. @@ -80,6 +76,9 @@ void free_engine(engine_t *self); */ void uninit_engine(engine_t *self); +// @param map the game map (will be owned by this engine) +int engine_reset_map(engine_t *self, int width, int height); + // will clear events on start! void engine_tick(engine_t *self); diff --git a/src/tdef/event.c b/src/tdef/event.c index c3d07c1..150c2b2 100644 --- a/src/tdef/event.c +++ b/src/tdef/event.c @@ -71,6 +71,7 @@ const char *event_name(event_t *self) { case WAVE : return "WAVE" ; case WIN : return "WIN" ; case LOOSE : return "LOOSE" ; + case ERROR : return "ERROR" ; } return "Unknown"; } @@ -100,6 +101,9 @@ void event_output(event_t *self, cstring_t *out) { case WIN: case LOOSE: cstring_addp(out, "EVENT:%s\n", name); break; + case ERROR: + cstring_addp(out, "ERROR: %d\n", self->x); + break; } } diff --git a/src/tdef/event.h b/src/tdef/event.h index 48f37ca..ff7c63f 100644 --- a/src/tdef/event.h +++ b/src/tdef/event.h @@ -32,8 +32,13 @@ typedef enum { WAVE, WIN, LOOSE, + ERROR, } event_type; +typedef enum { + EEVENT_NOMAP, +} eevent_type; + /** * @brief bla * diff --git a/src/tdef/reader.c b/src/tdef/reader.c index d3b2184..b9649a1 100644 --- a/src/tdef/reader.c +++ b/src/tdef/reader.c @@ -27,6 +27,8 @@ // KEYWORD // or: // KEYWORD: [parameters] +// or: +// # comment... (mostly used for data files) // // Parameters are given in the form of: // int_parameter1, int_parameter2... @@ -58,6 +60,9 @@ int is_cmd(cstring_t *line, const char cmd[]) { char car = line->string[first_non_space]; if ((car == ':') || (car == '\0')) return 1; + // Special empty line/comment check: + if (!cmd[0] && car == '#') + return 1; } return 0; @@ -73,7 +78,9 @@ command_t *reader_readnext(FILE *file) { if (cstring_readline(line, file)) { cmd = new_command(COMMAND_UNKNOWN); - if (is_cmd(line, ".")) { + if (is_cmd(line, "")) { // also checks for "#" + cmd->type = COMMAND_COMMENT; + } else if (is_cmd(line, ".")) { cmd->type = COMMAND_TICK; if (command_read_count(cmd, line->string)) cmd->type = COMMAND_INVALID; @@ -92,7 +99,7 @@ command_t *reader_readnext(FILE *file) { cmd->type = COMMAND_MAP; if (!command_read_int(cmd, line->string, 0, 1)) cmd->type = COMMAND_INVALID; - if (command_read_count(cmd, line->string) > 2) + if (command_read_count(cmd, line->string) != 2) cmd->type = COMMAND_INVALID; } else if (is_cmd(line, "life")) { cmd->type = COMMAND_LIFE; diff --git a/src/tdef/setup.c b/src/tdef/setup.c index c75989a..db0d6b7 100644 --- a/src/tdef/setup.c +++ b/src/tdef/setup.c @@ -21,6 +21,7 @@ #include #include "setup.h" +#include "event.h" tower_base_t *setup_tower_base(engine_t *self, int type, int cost) { tower_base_t *base = engine_get_tower_base(self, type); @@ -57,6 +58,15 @@ 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; + array_push(self->events, &event); + + return 0; + } + return map_add_path(self->map, x, y); } diff --git a/src/tdef/tdef.c b/src/tdef/tdef.c index 84c2e22..110ca65 100644 --- a/src/tdef/tdef.c +++ b/src/tdef/tdef.c @@ -79,6 +79,8 @@ int process_cmd(command_t *cmd, engine_t *engine) { out = new_cstring(); switch(cmd->type) { + case COMMAND_COMMENT: + break; case COMMAND_TICK: engine_tick(engine); break; @@ -102,6 +104,30 @@ int process_cmd(command_t *cmd, engine_t *engine) { fprintf(stdout, "Done reading: %s\n",subname); } break; + case COMMAND_MAP: + engine_reset_map( + engine, + command_get_int(cmd, 0), + command_get_int(cmd, 1) + ); + break; + case COMMAND_LIFE: + engine->life = command_get_int(cmd, 0); + break; + case COMMAND_BITS: + engine->bits = command_get_int(cmd, 0); + break; + case COMMAND_PATH: + setup_path( + engine, + command_get_int(cmd, 0), + command_get_int(cmd, 1) + ); + break; + case COMMAND_QUIT: + return 0; + + // Error management: case COMMAND_FILE404: fprintf(stderr, "Unknown file(s):\n"); array_loop_i (cmd->data, ptr, char*, i) { @@ -114,8 +140,6 @@ int process_cmd(command_t *cmd, engine_t *engine) { case COMMAND_INVALID: fprintf(stderr, "Invalid command\n"); break; - case COMMAND_QUIT: - return 0; } // Process all events @@ -151,30 +175,20 @@ void read_commands(engine_t *engine, FILE *file) { } int main(int argc, char **argv) { - map_t *map = new_map(6, 4); - engine_t *engine = new_engine(map); - if (!map || !engine) { + engine_t *engine = new_engine(); + if (!engine) { fprintf(stderr, "Allocation error"); return 1; } - setup_path(engine, 0, 0); - setup_path(engine, 1, 0); - setup_path(engine, 2, 0); - setup_path(engine, 3, 0); - setup_path(engine, 3, 1); - setup_path(engine, 3, 2); - setup_path(engine, 4, 2); - setup_path(engine, 5, 2); - - setup_tower_base(engine, 0, 10); - - enemy_t *enemy = setup_enemy(engine, 0, 0, 0); - enemy->speed = 2; - enemy->bits = 5; - - engine->bits = 100; - engine_add_tower(engine, 0, 2, 1); + /* DEBUG */ + command_t debug; + init_command(&debug, COMMAND_READFILE); + debug.data = new_array(sizeof(char **), 1); + char **ptr = array_new(debug.data); + *ptr = cstring_convert(cstring_clone("setup.debug")); + process_cmd(&debug, engine); + /* */ read_commands(engine, stdin); -- 2.27.0