#include "game_level.hpp" #include "components.hpp" #include "worldbuilder.hpp" #include "constants.hpp" #include "save.hpp" #include "systems.hpp" #include "components.hpp" #include "rituals.hpp" using lighting::LightRender; using std::shared_ptr, std::make_shared; using namespace components; struct LevelScaling { int map_width=20; int map_height=20; }; struct LevelManager { public: std::vector levels; size_t current_level = 0; }; inline shared_ptr clone_load_world(shared_ptr prev_world) { auto world = make_shared(); if(prev_world == nullptr) { save::load_configs(*world); } else { prev_world->clone_into(*world); } return world; } namespace Game { using std::shared_ptr, std::string, std::make_shared; shared_ptr LMGR; bool initialized = false; void init() { components::init(); textures::init(); if(!initialized) { LMGR = make_shared(); initialized = true; new_level(NULL); } } LevelScaling scale_level() { return { INITIAL_MAP_W + int(LMGR->current_level * 2), INITIAL_MAP_H + int(LMGR->current_level * 2) }; } shared_ptr current_world() { dbc::check(initialized, "Forgot to call Game::init()"); return current().world; } shared_ptr create_bossfight() { dbc::check(initialized, "Forgot to call Game::init()"); auto prev_world = current_world(); dbc::check(prev_world != nullptr, "Starter world for boss fights can't be null."); auto world = clone_load_world(prev_world); auto& config = prev_world->get_the(); // BUG: the jank is too strong here auto boss_names = config.bosses.keys(); auto& level_name = boss_names[LMGR->current_level % boss_names.size()]; auto& boss_data = config.bosses[level_name]; auto boss_id = world->entity(); components::configure_entity(*world, boss_id, boss_data["components"]); return make_shared(world, boss_id); } size_t new_level(std::shared_ptr prev_world) { dbc::check(initialized, "Forgot to call Game::init()"); auto world = clone_load_world(prev_world); auto scaling = scale_level(); auto map = make_shared(scaling.map_width, scaling.map_height); auto collision = std::make_shared(); WorldBuilder builder(*map, *collision); builder.generate(*world); size_t index = LMGR->levels.size(); auto player = world->get_the(); LMGR->levels.emplace_back(index, player.entity, map, world, make_shared(map->tiles()), collision); dbc::check(index == LMGR->levels.size() - 1, "Level index is not the same as LMGR->levels.size() - 1, off by one error"); return index; } GameLevel& create_level() { dbc::log("current_level"); size_t level = new_level(current_world()); dbc::check(level == LMGR->current_level + 1, "new level index is wrong"); auto& the_level = next(); dbc::check(level == LMGR->current_level, "level didn't update?!"); return the_level; } GameLevel &next() { dbc::check(initialized, "Forgot to call Game::init()"); dbc::check(LMGR->current_level < LMGR->levels.size(), "attempt to get next level when at end"); LMGR->current_level++; return LMGR->levels.at(LMGR->current_level); } GameLevel &previous() { dbc::check(initialized, "Forgot to call Game::init()"); dbc::check(LMGR->current_level > 0, "attempt to go to previous level when at 0"); LMGR->current_level--; return LMGR->levels.at(LMGR->current_level); } GameLevel ¤t() { dbc::check(initialized, "Forgot to call Game::init()"); return LMGR->levels.at(LMGR->current_level); } size_t current_index() { dbc::check(initialized, "Forgot to call Game::init()"); return LMGR->current_level; } GameLevel &get(size_t index) { dbc::check(initialized, "Forgot to call Game::init()"); return LMGR->levels.at(index); } DinkyECS::Entity spawn_enemy(const std::string& named) { (void)named; dbc::check(initialized, "Forgot to call Game::init()"); dbc::sentinel("THIS IS BROKEN"); } components::Position& player_position() { dbc::check(initialized, "Forgot to call Game::init()"); auto world = current_world(); auto& player = world->get_the(); return world->get(player.entity); } DinkyECS::Entity the_player() { dbc::check(initialized, "Forgot to call Game::init()"); return current().player; } }