Now all of the old LevelManager code is gone. Next phase is to rename the Game:: to something better then test the shit out of it.

This commit is contained in:
Zed A. Shaw 2025-08-20 13:31:02 -04:00
parent a83ee77eea
commit c46927ea10
7 changed files with 91 additions and 126 deletions

View file

@ -16,128 +16,49 @@ struct LevelScaling {
int map_height=20;
};
class LevelManager {
struct LevelManager {
public:
std::vector<GameLevel> $levels;
size_t $current_level = 0;
LevelManager();
shared_ptr<gui::BossFightUI> create_bossfight(shared_ptr<DinkyECS::World> prev_world);
size_t create_level(shared_ptr<DinkyECS::World> prev_world = nullptr);
GameLevel &next();
GameLevel &previous();
GameLevel &current();
size_t current_index() { return $current_level; }
GameLevel &get(size_t index);
LevelScaling scale_level();
DinkyECS::Entity spawn_enemy(const std::string& named);
std::vector<GameLevel> levels;
size_t current_level = 0;
};
LevelManager::LevelManager() {
create_level();
}
LevelScaling LevelManager::scale_level() {
return {
INITIAL_MAP_W + int($current_level * 2),
INITIAL_MAP_H + int($current_level * 2)
};
}
inline shared_ptr<DinkyECS::World> clone_load_world(shared_ptr<DinkyECS::World> prev_world)
{
auto world = make_shared<DinkyECS::World>();
if(prev_world != nullptr) {
prev_world->clone_into(*world);
} else {
if(prev_world == nullptr) {
save::load_configs(*world);
} else {
prev_world->clone_into(*world);
}
return world;
}
shared_ptr<gui::BossFightUI> LevelManager::create_bossfight(shared_ptr<DinkyECS::World> prev_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<GameConfig>();
// BUG: the jank is too strong here
auto boss_names = config.bosses.keys();
auto& level_name = boss_names[$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<gui::BossFightUI>(world, boss_id);
}
DinkyECS::Entity LevelManager::spawn_enemy(const std::string& named) {
(void)named;
dbc::log("THIS FUNCTION NEEDS A REWRITE");
return 0;
}
size_t LevelManager::create_level(shared_ptr<DinkyECS::World> prev_world) {
auto world = clone_load_world(prev_world);
auto scaling = scale_level();
auto map = make_shared<Map>(scaling.map_width, scaling.map_height);
auto collision = std::make_shared<SpatialMap>();
WorldBuilder builder(*map, *collision);
builder.generate(*world);
size_t index = $levels.size();
auto player = world->get_the<Player>();
$levels.emplace_back(index, player.entity, map, world,
make_shared<LightRender>(map->tiles()), collision);
dbc::check(index == $levels.size() - 1, "Level index is not the same as $levels.size() - 1, off by one error");
return index;
}
GameLevel &LevelManager::next() {
dbc::check($current_level < $levels.size(), "attempt to get next level when at end");
$current_level++;
return $levels.at($current_level);
}
GameLevel &LevelManager::previous() {
dbc::check($current_level > 0, "attempt to go to previous level when at 0");
$current_level--;
return $levels.at($current_level);
}
GameLevel &LevelManager::current() {
return $levels.at($current_level);
}
GameLevel &LevelManager::get(size_t index) {
return $levels.at(index);
}
namespace Game {
using std::shared_ptr, std::string, std::make_shared;
shared_ptr<LevelManager> LEVELS;
shared_ptr<LevelManager> LMGR;
bool initialized = false;
void init() {
components::init();
textures::init();
if(!initialized) {
LEVELS = make_shared<LevelManager>();
LMGR = make_shared<LevelManager>();
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<DinkyECS::World> current_world() {
dbc::check(initialized, "Forgot to call Game::init()");
return current().world;
@ -145,43 +66,88 @@ namespace Game {
shared_ptr<gui::BossFightUI> create_bossfight() {
dbc::check(initialized, "Forgot to call Game::init()");
return LEVELS->create_bossfight(current_world());
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<GameConfig>();
// 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<gui::BossFightUI>(world, boss_id);
}
size_t new_level(std::shared_ptr<DinkyECS::World> 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<Map>(scaling.map_width, scaling.map_height);
auto collision = std::make_shared<SpatialMap>();
WorldBuilder builder(*map, *collision);
builder.generate(*world);
size_t index = LMGR->levels.size();
auto player = world->get_the<Player>();
LMGR->levels.emplace_back(index, player.entity, map, world,
make_shared<LightRender>(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::check(initialized, "Forgot to call Game::init()");
LEVELS->create_level(current_world());
return next();
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()");
return LEVELS->next();
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()");
return LEVELS->previous();
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 &current() {
dbc::check(initialized, "Forgot to call Game::init()");
return LEVELS->current();
return LMGR->levels.at(LMGR->current_level);
}
size_t current_index() {
dbc::check(initialized, "Forgot to call Game::init()");
return LEVELS->current_index();
return LMGR->current_level;
}
GameLevel &get(size_t index) {
dbc::check(initialized, "Forgot to call Game::init()");
return LEVELS->get(index);
return LMGR->levels.at(index);
}
DinkyECS::Entity spawn_enemy(const std::string& named) {
(void)named;
dbc::check(initialized, "Forgot to call Game::init()");
return LEVELS->spawn_enemy(named);
dbc::sentinel("THIS IS BROKEN");
}
components::Position& player_position() {