added option to read level data from file

This commit is contained in:
2024-07-21 00:42:10 -04:00
parent 25477c2cf8
commit 401b5b00b5
14 changed files with 366 additions and 58 deletions

View File

@ -1,9 +1,11 @@
#include "cc3k.h"
#include <iostream>
#include <fstream>
#include "constants.h"
CC3K::CC3K(const feature enabled_features,
input *in, output *out, RNG *rng):
input *in, output *out, RNG *rng, std::ifstream &data):
enabled_features{enabled_features},
in{in}, out{out}, rng{rng} {
curr_menu = std::make_unique<menu>(enabled_features);
@ -11,6 +13,9 @@ CC3K::CC3K(const feature enabled_features,
curr_menu->print(out, rng->get_init_seed());
out->render();
gresult.status = game_status::MAIN_MENU;
if (enabled_features & FEATURE_READ_MAP)
proc_lvls(data);
}
game_status CC3K::run() {
@ -28,7 +33,8 @@ game_status CC3K::run() {
curr_game =
std::make_unique<game>(static_cast<race>(tmp),
enabled_features,
in, out, rng);
in, out, rng,
lvls);
out->clear();
curr_game->print();
out->render();
@ -91,3 +97,148 @@ game_status CC3K::run() {
return TERMINATED;
}
void CC3K::proc_lvls(std::ifstream &data) {
lvls.reserve(DEFAULT_LVL_CNT);
for (int i = 0; i < DEFAULT_LVL_CNT; ++i) {
level_data tmp = {POS_NIL, {}, {}, {}, {}, POS_NIL};
std::string buffer;
for (int y = 0; y < MAP_HEIGHT; ++y) {
getline(data, buffer);
for (int x = 0; x < MAP_WIDTH; ++x)
push_tile(buffer[x], {x, y}, tmp);
}
number_rooms(tmp);
lvls.push_back(tmp);
}
}
size_t CC3K::remap_pos(const position &pos) {
return pos.x + pos.y * MAP_WIDTH;
}
void CC3K::number_rooms(level_data &lvl) {
int curr_room_cnt = 0;
for (int y = 0; y < MAP_HEIGHT; ++y)
for (int x = 0; x < MAP_WIDTH; ++x)
if (lvl.map_data[remap_pos({x, y})] == '.') {
number_block(lvl.map_data, {x, y}, curr_room_cnt);
++curr_room_cnt;
}
}
bool CC3K::in_bounds(const position &pos) {
return pos.x >= 0 && pos.x < MAP_WIDTH &&
pos.y >= 0 && pos.y < MAP_HEIGHT;
}
void CC3K::number_block(std::string &map_data, const position &pos, int num) {
if (map_data[remap_pos(pos)] != '.')
return;
map_data[remap_pos(pos)] = num + '0';
for (int i = 0; i < DIRECTION_CNT; ++i)
if (in_bounds(pos + MOVE[i]) &&
map_data[remap_pos(pos + MOVE[i])] == '.')
number_block(map_data, pos + MOVE[i], num);
}
void CC3K::push_tile(const char ch, const position &pos, level_data &lvl) {
switch (ch) {
case '-':
case '|':
case ' ':
case '+':
case '#':
lvl.map_data += ch;
return;
case '@':
lvl.pc_pos = pos;
break;
case '\\':
lvl.stairs = pos;
break;
case '0':
lvl.potions.push_back({RESTORE_HEALTH, pos});
break;
case '1':
lvl.potions.push_back({BOOST_ATK, pos});
break;
case '2':
lvl.potions.push_back({BOOST_DEF, pos});
break;
case '3':
lvl.potions.push_back({POISON_HEALTH, pos});
break;
case '4':
lvl.potions.push_back({WOUND_ATK, pos});
break;
case '5':
lvl.potions.push_back({WOUND_DEF, pos});
break;
case '6':
lvl.gold_piles.push_back({pos, GOLD_NORMAL});
break;
case '7':
lvl.gold_piles.push_back({pos, GOLD_SMALL});
break;
case '8':
lvl.gold_piles.push_back({pos, GOLD_MERCHANT});
break;
case '9':
lvl.gold_piles.push_back({pos, GOLD_DRAGON});
break;
case 'H':
lvl.enemies.push_back({HUMAN, pos});
break;
case 'W':
lvl.enemies.push_back({DWARF, pos});
break;
case 'E':
lvl.enemies.push_back({ELF, pos});
break;
case 'O':
lvl.enemies.push_back({ORC, pos});
break;
case 'M':
lvl.enemies.push_back({MERCHANT, pos});
break;
case 'D':
lvl.enemies.push_back({DRAGON, pos});
break;
case 'L':
lvl.enemies.push_back({HALFLING, pos});
break;
default:
break;
}
lvl.map_data += '.';
}