World copying with facts and constants is working so now new levels are possible, but need to work on previous level motion.

main
Zed A. Shaw 11 months ago
parent 2735a0ac1f
commit 82216b8307
  1. 2
      assets/config.json
  2. 24
      dinkyecs.hpp
  3. 28
      levelmanager.cpp
  4. 1
      status.txt
  5. 28
      tests/dinkyecs.cpp
  6. 1
      worldbuilder.cpp

@ -8,6 +8,6 @@
"worldgen": {
"enemy_probability": 20,
"empty_room_probability": 10,
"device_probability": 100
"device_probability": 30
}
}

@ -14,7 +14,7 @@ namespace DinkyECS {
typedef unsigned long Entity;
typedef std::unordered_map<Entity, std::any> EntityMap;
using EntityMap = std::unordered_map<Entity, std::any>;
struct Event {
int event = 0;
@ -29,20 +29,30 @@ namespace DinkyECS {
std::unordered_map<std::type_index, EntityMap> $components;
std::unordered_map<std::type_index, std::any> $facts;
std::unordered_map<std::type_index, EventQueue> $events;
std::vector<Entity> constants;
std::vector<Entity> $constants;
Entity entity() {
return ++entity_count;
}
/*
void clone_into(DinkyECS::World &from_world, DinkyECS::World &to_world) {
}
void clone_into(DinkyECS::World &to_world) {
to_world.$constants = $constants;
to_world.$facts = $facts;
to_world.entity_count = entity_count;
void update_constants(DinkyECS::World &from_world, DinkyECS::World &to_world) {
for(auto eid : $constants) {
for(const auto &[tid, eid_map] : $components) {
auto& their_map = to_world.$components[tid];
if(eid_map.contains(eid)) {
their_map.insert_or_assign(eid, eid_map.at(eid));
}
}
}
}
void make_constant(DinkyECS::Entity entity) {
$constants.push_back(entity);
}
*/
template <typename Comp>
EntityMap& entity_map_for() {

@ -15,33 +15,14 @@ LevelManager::LevelManager() {
size_t LevelManager::create_level(shared_ptr<DinkyECS::World> prev_world) {
auto world = make_shared<DinkyECS::World>();
save::load_configs(*world);
auto map = make_shared<Map>(GAME_MAP_X, GAME_MAP_Y);
if(prev_world != nullptr) {
auto& player = prev_world->get_the<Player>();
player.entity = world->entity();
world->set_the<Player>(player);
auto inventory = prev_world->get<Inventory>(player.entity);
world->set<Inventory>(player.entity, inventory);
auto light = prev_world->get<LightSource>(player.entity);
world->set<LightSource>(player.entity, light);
world->set_the<Debug>(prev_world->get_the<Debug>());
auto& combat = prev_world->get<Combat>(player.entity);
world->set<Combat>(player.entity, combat);
auto& motion = prev_world->get<Motion>(player.entity);
world->set<Motion>(player.entity, motion);
auto& tile = prev_world->get<Tile>(player.entity);
world->set<Tile>(player.entity, tile);
prev_world->clone_into(*world);
} else {
save::load_configs(*world);
}
auto map = make_shared<Map>(GAME_MAP_X, GAME_MAP_Y);
WorldBuilder builder(*map);
builder.generate(*world);
@ -49,7 +30,6 @@ size_t LevelManager::create_level(shared_ptr<DinkyECS::World> prev_world) {
auto collider = make_shared<SpatialMap>();
// not sure if this is still needed
world->set_the<SpatialMap>(*collider);
System::init_positions(*world, *collider);
$levels.emplace_back(index, map, world,

@ -1,5 +1,6 @@
TODO:
* Items are doubled in inventory.
* What's the result of out of memory error with shared/unique ptr?
* Config is all over the place. Can I get rid of constant.hpp? Or most of it? Also renderer.cpp:RenderConfig is weird too. Too much indirection all around.
* GUI needs to become a statemachine now. Too many panels open at too many times.

@ -152,3 +152,31 @@ TEST_CASE("confirm that the event system works", "[ecs]") {
ready = world.has_event<GUIEvent>();
REQUIRE(ready == false);
}
TEST_CASE("confirm copying and constants", "[ecs-constants]") {
DinkyECS::World world1;
Player player_info{"Zed", world1.entity()};
world1.set_the<Player>(player_info);
world1.set<Position>(player_info.eid, {10,10});
world1.make_constant(player_info.eid);
DinkyECS::World world2;
world1.clone_into(world2);
auto &test1 = world1.get<Position>(player_info.eid);
auto &test2 = world2.get<Position>(player_info.eid);
REQUIRE(test2.x == test1.x);
REQUIRE(test2.y == test1.y);
// check for accidental reference
test1.x = 100;
REQUIRE(test2.x != test1.x);
// test the facts copy over
auto &player2 = world2.get_the<Player>();
REQUIRE(player2.eid == player_info.eid);
}

@ -247,6 +247,7 @@ void WorldBuilder::place_entities(DinkyECS::World &world) {
Player player{player_ent};
world.set_the<Player>(player);
world.set<Inventory>(player.entity, {5});
world.make_constant(player.entity);
}
randomize_entities(world, config);