From 82216b83073671b2fe5240179ad3f4b982a9565b Mon Sep 17 00:00:00 2001 From: "Zed A. Shaw" Date: Mon, 27 Jan 2025 13:48:20 -0500 Subject: [PATCH] World copying with facts and constants is working so now new levels are possible, but need to work on previous level motion. --- assets/config.json | 2 +- dinkyecs.hpp | 24 +++++++++++++++++------- levelmanager.cpp | 28 ++++------------------------ status.txt | 1 + tests/dinkyecs.cpp | 28 ++++++++++++++++++++++++++++ worldbuilder.cpp | 1 + 6 files changed, 52 insertions(+), 32 deletions(-) diff --git a/assets/config.json b/assets/config.json index 009c4f9..1b202d3 100644 --- a/assets/config.json +++ b/assets/config.json @@ -8,6 +8,6 @@ "worldgen": { "enemy_probability": 20, "empty_room_probability": 10, - "device_probability": 100 + "device_probability": 30 } } diff --git a/dinkyecs.hpp b/dinkyecs.hpp index ade2e87..0d77ccc 100644 --- a/dinkyecs.hpp +++ b/dinkyecs.hpp @@ -14,7 +14,7 @@ namespace DinkyECS { typedef unsigned long Entity; - typedef std::unordered_map EntityMap; + using EntityMap = std::unordered_map; struct Event { int event = 0; @@ -29,20 +29,30 @@ namespace DinkyECS { std::unordered_map $components; std::unordered_map $facts; std::unordered_map $events; - std::vector constants; + std::vector $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 EntityMap& entity_map_for() { diff --git a/levelmanager.cpp b/levelmanager.cpp index f51ea6c..8441298 100644 --- a/levelmanager.cpp +++ b/levelmanager.cpp @@ -15,33 +15,14 @@ LevelManager::LevelManager() { size_t LevelManager::create_level(shared_ptr prev_world) { auto world = make_shared(); - save::load_configs(*world); - - auto map = make_shared(GAME_MAP_X, GAME_MAP_Y); if(prev_world != nullptr) { - auto& player = prev_world->get_the(); - player.entity = world->entity(); - world->set_the(player); - - auto inventory = prev_world->get(player.entity); - world->set(player.entity, inventory); - - auto light = prev_world->get(player.entity); - world->set(player.entity, light); - - world->set_the(prev_world->get_the()); - auto& combat = prev_world->get(player.entity); - world->set(player.entity, combat); - - auto& motion = prev_world->get(player.entity); - world->set(player.entity, motion); - - auto& tile = prev_world->get(player.entity); - - world->set(player.entity, tile); + prev_world->clone_into(*world); + } else { + save::load_configs(*world); } + auto map = make_shared(GAME_MAP_X, GAME_MAP_Y); WorldBuilder builder(*map); builder.generate(*world); @@ -49,7 +30,6 @@ size_t LevelManager::create_level(shared_ptr prev_world) { auto collider = make_shared(); // not sure if this is still needed - world->set_the(*collider); System::init_positions(*world, *collider); $levels.emplace_back(index, map, world, diff --git a/status.txt b/status.txt index 951f01a..5ef5fa9 100644 --- a/status.txt +++ b/status.txt @@ -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. diff --git a/tests/dinkyecs.cpp b/tests/dinkyecs.cpp index 730bca9..194a824 100644 --- a/tests/dinkyecs.cpp +++ b/tests/dinkyecs.cpp @@ -152,3 +152,31 @@ TEST_CASE("confirm that the event system works", "[ecs]") { ready = world.has_event(); REQUIRE(ready == false); } + + +TEST_CASE("confirm copying and constants", "[ecs-constants]") { + DinkyECS::World world1; + + Player player_info{"Zed", world1.entity()}; + world1.set_the(player_info); + + world1.set(player_info.eid, {10,10}); + world1.make_constant(player_info.eid); + + DinkyECS::World world2; + world1.clone_into(world2); + + auto &test1 = world1.get(player_info.eid); + auto &test2 = world2.get(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(); + REQUIRE(player2.eid == player_info.eid); +} diff --git a/worldbuilder.cpp b/worldbuilder.cpp index 9e157d1..5cccc79 100644 --- a/worldbuilder.cpp +++ b/worldbuilder.cpp @@ -247,6 +247,7 @@ void WorldBuilder::place_entities(DinkyECS::World &world) { Player player{player_ent}; world.set_the(player); world.set(player.entity, {5}); + world.make_constant(player.entity); } randomize_entities(world, config);