Had to refactor the GameDB to use a list of levels instead of a vector of levels. If you get a _reference_ to an element of a vector, and then resize the vector, you'll get a crash if the realoc moves the data buffer. Using a list is actually what we want.
This commit is contained in:
parent
bf8ce7e16b
commit
0456c73e4f
6 changed files with 53 additions and 37 deletions
|
|
@ -6,6 +6,7 @@
|
|||
#include "components.hpp"
|
||||
#include "rituals.hpp"
|
||||
#include "textures.hpp"
|
||||
#include <list>
|
||||
|
||||
using lighting::LightRender;
|
||||
using std::shared_ptr, std::make_shared;
|
||||
|
|
@ -20,11 +21,11 @@ namespace GameDB {
|
|||
using std::shared_ptr, std::string, std::make_shared;
|
||||
|
||||
struct LevelDB {
|
||||
std::vector<GameDB::Level> levels;
|
||||
std::list<GameDB::Level> levels;
|
||||
size_t current_level = 0;
|
||||
};
|
||||
|
||||
shared_ptr<LevelDB> LDB;
|
||||
shared_ptr<LevelDB> LDB = nullptr;
|
||||
bool initialized = false;
|
||||
|
||||
LevelScaling scale_level() {
|
||||
|
|
@ -46,8 +47,18 @@ namespace GameDB {
|
|||
return world;
|
||||
}
|
||||
|
||||
void register_level(Level level) {
|
||||
// size BEFORE push to get the correct index
|
||||
level.index = LDB->levels.size();
|
||||
|
||||
size_t new_level(std::shared_ptr<DinkyECS::World> prev_world) {
|
||||
LDB->levels.push_back(level);
|
||||
|
||||
dbc::check(level.index == LDB->levels.size() - 1, "Level index is not the same as LDB->levels.size() - 1, off by one error");
|
||||
|
||||
LDB->current_level = level.index;
|
||||
}
|
||||
|
||||
void new_level(std::shared_ptr<DinkyECS::World> prev_world) {
|
||||
dbc::check(initialized, "Forgot to call GameDB::init()");
|
||||
auto world = clone_load_world(prev_world);
|
||||
|
||||
|
|
@ -59,16 +70,16 @@ namespace GameDB {
|
|||
WorldBuilder builder(*map, *collision);
|
||||
builder.generate(*world);
|
||||
|
||||
size_t index = LDB->levels.size();
|
||||
auto lights = make_shared<LightRender>(map->tiles());
|
||||
|
||||
auto player = world->get_the<Player>();
|
||||
|
||||
LDB->levels.emplace_back(index, player.entity, map, world,
|
||||
make_shared<LightRender>(map->tiles()), collision);
|
||||
|
||||
dbc::check(index == LDB->levels.size() - 1, "Level index is not the same as LDB->levels.size() - 1, off by one error");
|
||||
|
||||
return index;
|
||||
register_level({
|
||||
.player=player.entity,
|
||||
.map=map,
|
||||
.world=world,
|
||||
.lights=lights,
|
||||
.collision=collision});
|
||||
}
|
||||
|
||||
void init() {
|
||||
|
|
@ -89,18 +100,15 @@ namespace GameDB {
|
|||
|
||||
Level& create_level() {
|
||||
dbc::check(initialized, "Forgot to call GameDB::init()");
|
||||
dbc::check(LDB->current_level < LDB->levels.size(), "attempt to get next level when at end");
|
||||
|
||||
size_t level = new_level(current_world());
|
||||
dbc::check(level == LDB->current_level + 1, "new level index is wrong");
|
||||
new_level(current_world());
|
||||
|
||||
LDB->current_level++;
|
||||
return LDB->levels.at(LDB->current_level);
|
||||
return LDB->levels.back();
|
||||
}
|
||||
|
||||
Level ¤t_level() {
|
||||
dbc::check(initialized, "Forgot to call GameDB::init()");
|
||||
return LDB->levels.at(LDB->current_level);
|
||||
return LDB->levels.back();
|
||||
}
|
||||
|
||||
components::Position& player_position() {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue