X-Git-Url: https://plomlompom.com/repos/feed.xml?a=blobdiff_plain;f=src%2Froguelike.c;h=f20bfe18e1b123ce7cb5d4ef592b59e30923a96c;hb=5dfbb430e0aed478ced7cdc32c1777745a435532;hp=0d1e96b60966338f4b5e7bba283cd4e64d49334d;hpb=d7c46fb1de25edd8782fbc7642be71e5e54deab2;p=plomrogue diff --git a/src/roguelike.c b/src/roguelike.c index 0d1e96b..f20bfe1 100644 --- a/src/roguelike.c +++ b/src/roguelike.c @@ -20,14 +20,25 @@ uint16_t rrand(char use_seed, uint32_t new_seed) { return (seed / 65536); } // Ignore least significant 16 bits (they are less random). void update_log (struct World * world, char * text) { -// Update log with new text to be appended. +// Update log by appending text, or by appending a "." if text is the same as the last one. + static char * last_msg; + if (0 == last_msg) + last_msg = calloc(1, sizeof(char)); char * new_text; uint16_t len_old = strlen(world->log); - uint16_t len_new = strlen(text); - uint16_t len_whole = len_old + len_new + 1; - new_text = calloc(len_whole, sizeof(char)); - memcpy(new_text, world->log, len_old); - memcpy(new_text + len_old, text, len_new); + if (0 == strcmp(last_msg, text)) { + uint16_t len_whole = len_old + 1; + new_text = calloc(len_whole + 1, sizeof(char)); + memcpy(new_text, world->log, len_old); + memcpy(new_text + len_old, ".", 1); } + else { + uint16_t len_new = strlen(text); + uint16_t len_whole = len_old + len_new + 1; + new_text = calloc(len_whole, sizeof(char)); + memcpy(new_text, world->log, len_old); + memcpy(new_text + len_old, text, len_new); + last_msg = calloc(len_new + 1, sizeof(char)); + memcpy(last_msg, text, len_new); } free(world->log); world->log = new_text; } @@ -83,14 +94,18 @@ void save_game(struct World * world) { FILE * file = fopen("savefile", "w"); write_uint32_bigendian(world->seed, file); write_uint32_bigendian(world->turn, file); - write_uint16_bigendian(world->player->pos.y, file); - write_uint16_bigendian(world->player->pos.x, file); - write_uint16_bigendian(world->monster->pos.y, file); - write_uint16_bigendian(world->monster->pos.x, file); - write_uint16_bigendian(world->monster->next->pos.y, file); - write_uint16_bigendian(world->monster->next->pos.x, file); - write_uint16_bigendian(world->monster->next->next->pos.y, file); - write_uint16_bigendian(world->monster->next->next->pos.x, file); + write_uint16_bigendian(world->player->pos.y + 1, file); + write_uint16_bigendian(world->player->pos.x + 1, file); + struct Monster * monster; + for (monster = world->monster; monster != 0; monster = monster->next) { + write_uint16_bigendian(monster->pos.y + 1, file); + write_uint16_bigendian(monster->pos.x + 1, file); } + write_uint16_bigendian(0, file); + struct Item * item; + for (item = world->item; item != 0; item = item->next) { + write_uint16_bigendian(item->pos.y + 1, file); + write_uint16_bigendian(item->pos.x + 1, file); } + write_uint16_bigendian(0, file); fclose(file); } void toggle_window (struct WinMeta * win_meta, struct Win * win) { @@ -186,21 +201,15 @@ int main (int argc, char *argv[]) { default: exit(EXIT_FAILURE); } } - // Initialize log, player and monsters. + // Initialize log, player, monsters and items. world.log = calloc(1, sizeof(char)); update_log (&world, " "); struct Player player; world.player = &player; - struct Monster monster1; - struct Monster monster2; - struct Monster monster3; - world.monster = &monster1; - monster1.next = &monster2; - monster2.next = &monster3; - monster3.next = 0; - monster1.name = 'A'; - monster2.name = 'B'; - monster3.name = 'C'; + struct Monster * monster; + struct Item * item; + uint16_t test; + char start; // For interactive mode, try to load world state from savefile. FILE * file; @@ -208,17 +217,47 @@ int main (int argc, char *argv[]) { file = fopen("savefile", "r"); world.seed = read_uint32_bigendian(file); world.turn = read_uint32_bigendian(file); - player.pos.y = read_uint16_bigendian(file); - player.pos.x = read_uint16_bigendian(file); - monster1.pos.y = read_uint16_bigendian(file); - monster1.pos.x = read_uint16_bigendian(file); - monster2.pos.y = read_uint16_bigendian(file); - monster2.pos.x = read_uint16_bigendian(file); - monster3.pos.y = read_uint16_bigendian(file); - monster3.pos.x = read_uint16_bigendian(file); + player.pos.y = read_uint16_bigendian(file) - 1; + player.pos.x = read_uint16_bigendian(file) - 1; + start = 1; + world.monster = 0; + while (1) { + test = read_uint16_bigendian(file); + if (0 == test) + break; + if (start) { + monster = malloc(sizeof(struct Monster)); + world.monster = monster; + start = 0; } + else { + monster->next = malloc(sizeof(struct Monster)); + monster = monster->next; } + monster->name = 'M'; + monster->pos.y = test - 1; + monster->pos.x = read_uint16_bigendian(file) - 1; } + if (!start) + monster->next = 0; + start = 1; + world.item = 0; + while (1) { + test = read_uint16_bigendian(file); + if (0 == test) + break; + if (start) { + item = malloc(sizeof(struct Item)); + world.item = item; + start = 0; } + else { + item->next = malloc(sizeof(struct Item)); + item = item->next; } + item->name = '#'; + item->pos.y = test - 1; + item->pos.x = read_uint16_bigendian(file) - 1; } + if (!start) + item->next = 0; fclose(file); } - // For non-interactive mode, try to load world state from frecord file. + // For non-interactive mode, try to load world state from record file. else { world.turn = 1; if (0 == world.interactive) { @@ -237,14 +276,44 @@ int main (int argc, char *argv[]) { struct Map map = init_map(); world.map = ↦ if (1 == world.turn) { - for (player.pos.y = player.pos.x = 0; 0 == is_passable(&map, player.pos.y, player.pos.x);) { + for (player.pos.y = player.pos.x = 0; 0 == is_passable(&map, player.pos);) { player.pos.y = rrand(0, 0) % map.size.y; player.pos.x = rrand(0, 0) % map.size.x; } - struct Monster * monster; - for (monster = world.monster; monster != 0; monster = monster->next) - for (monster->pos.y = monster->pos.x = 0; 0 == is_passable(&map, monster->pos.y, monster->pos.x);) { + unsigned char n_monsters = rrand(0, 0) % 16; + unsigned char n_items = rrand(0, 0) % 48; + unsigned char i; + start = 1; + world.monster = 0; + for (i = 0; i < n_monsters; i++) { + if (start) { + monster = malloc(sizeof(struct Monster)); + world.monster = monster; + start = 0; } + else { + monster->next = malloc(sizeof(struct Monster)); + monster = monster->next; } + for (monster->pos.y = monster->pos.x = 0; 0 == is_passable(&map, monster->pos);) { monster->pos.y = rrand(0, 0) % map.size.y; - monster->pos.x = rrand(0, 0) % map.size.x; } } + monster->pos.x = rrand(0, 0) % map.size.x; } + monster->name = 'M'; } + if (!start) + monster->next = 0; + start = 1; + world.item = 0; + for (i = 0; i < n_items; i++) { + if (start) { + item = malloc(sizeof(struct Item)); + world.item = item; + start = 0; } + else { + item->next = malloc(sizeof(struct Item)); + item = item->next; } + for (item->pos.y = item->pos.x = 0; 0 == is_passable(&map, item->pos);) { + item->pos.y = rrand(0, 0) % map.size.y; + item->pos.x = rrand(0, 0) % map.size.x; } + item->name = '#'; } + if (!start) + item->next = 0; } // Initialize window system and windows. WINDOW * screen = initscr();