From fb064ffbf12c18bf4bbd623180da932c3c49cb78 Mon Sep 17 00:00:00 2001 From: "Zed A. Shaw" Date: Mon, 23 Jun 2025 01:33:09 -0400 Subject: [PATCH] Loot boxes now have ritual items and you can click on them, or the enemy just dies. --- assets/devices.json | 4 +-- components.hpp | 1 + gui/main_ui.cpp | 8 ++++-- save.cpp | 3 +- systems.cpp | 67 +++++++++++++++++++++++++++------------------ systems.hpp | 4 +-- 6 files changed, 53 insertions(+), 34 deletions(-) diff --git a/assets/devices.json b/assets/devices.json index f34c902..4b412f2 100644 --- a/assets/devices.json +++ b/assets/devices.json @@ -60,14 +60,12 @@ {"_type": "Device", "config": {}, "events": ["LOOT_CONTAINER"]}, {"_type": "Sprite", "name": "barrel_small", "width": 256, "height": 256, "scale": 1.0}, {"_type": "Sound", "attack": "pickup", "death": "blank"} - ], - "inventory_count": 0 + ] }, "GRAVE_STONE": { "id": "GRAVE_STONE", "name": "Grave Stone", "description": "Something died here. Was this your doing?", - "inventory_count": 0, "components": [ {"_type": "Tile", "display": 8687, "foreground": [32, 123, 164], diff --git a/components.hpp b/components.hpp index dbb9862..f0e3011 100644 --- a/components.hpp +++ b/components.hpp @@ -49,6 +49,7 @@ namespace components { Config tiles; Config devices; Config bosses; + Config rituals; }; struct Personality { diff --git a/gui/main_ui.cpp b/gui/main_ui.cpp index 5e0695e..4581a2d 100644 --- a/gui/main_ui.cpp +++ b/gui/main_ui.cpp @@ -90,8 +90,12 @@ namespace gui { } void MainUI::dead_entity(DinkyECS::Entity entity) { - auto &sprite = $level.world->get(entity); - $rayview.update_sprite(entity, sprite); + // BUG: this is kind of weird, but I think when I switch to dead bodies for things + // (see System::distribute_loot) then this can be fixed or improved + if($level.world->has(entity)) { + auto &sprite = $level.world->get(entity); + $rayview.update_sprite(entity, sprite); + } } void MainUI::update_level(GameLevel level) { diff --git a/save.cpp b/save.cpp index 881f6f7..e91f21a 100644 --- a/save.cpp +++ b/save.cpp @@ -15,8 +15,9 @@ void save::load_configs(DinkyECS::World &world) { Config tiles("./assets/tiles.json"); Config devices("./assets/devices.json"); Config bosses("./assets/bosses.json"); + Config rituals("./assets/rituals.json"); world.set_the({ - game, enemies, items, tiles, devices, bosses + game, enemies, items, tiles, devices, bosses, rituals }); } diff --git a/systems.cpp b/systems.cpp index 6419271..ce7ff96 100644 --- a/systems.cpp +++ b/systems.cpp @@ -147,34 +147,49 @@ void System::motion(GameLevel &level) { }); } -void System::distribute_loot(World &world, Entity& ent, nlohmann::json& entity_data) { - dbc::log("!!!!!!!!!!!!! THIS is where you update the dead body contents"); - int inventory_count = entity_data["inventory_count"]; - world.set(ent, {inventory_count, entity_data}); - // use the inventory_level to fill the blanket with new items +void System::distribute_loot(GameLevel &level, Entity& ent) { + auto& world = *level.world; + + // BUG: I constantly open a config when I have GameConfig already + auto& config = world.get_the(); - Config config("assets/rituals.json"); ritual::JunkPile pile; - auto& junk = config["junk"]; + auto& junk = config.rituals["junk"]; ritual::JunkPile select_from; for(auto& el : junk.items()) { select_from.contents.push_back(el.key()); } - for(int i = 0; i < inventory_count; i++) { - size_t max_junk = select_from.contents.size(); - auto& item = select_from.contents.at(Random::uniform(size_t(0), max_junk-1)); - pile.contents.push_back(item); - } + int inventory_count = Random::uniform(0, 3); + if(inventory_count > 0) { + for(int i = 0; i < inventory_count; i++) { + size_t max_junk = select_from.contents.size(); + auto& item = select_from.contents.at(Random::uniform(size_t(0), max_junk-1)); + pile.contents.push_back(item); + } - world.set(ent, pile); + auto entity_data = config.devices["GRAVE_STONE"]; + components::configure_entity(world, ent, entity_data["components"]); + world.set(ent, pile); + // BUG: inventory_count here isn't really used to remove it + world.set(ent, {inventory_count, entity_data}); + } else { + dbc::log("DEAD BODY NOT IMPLEMENTED, for now just removing enemy"); + remove_from_world(level, ent); + // BUG: should maybe add a component to the world for "dead thing no loot" that + // has no collision or goes away after some kind of animation + // Something like: + // auto entity_data = config.devices["DEAD_BODY"]; + // components::configure_entity(world, ent, entity_data["components"]); + // then give it a collision device that makes it go away and make a sound + // or maybe you can walk over dead bodies and they make a noise + } } void System::death(GameLevel &level) { auto &world = *level.world; auto player = world.get_the(); - auto& config = world.get_the(); std::vector dead_things; world.query([&](auto ent, auto &combat) { @@ -209,18 +224,14 @@ void System::death(GameLevel &level) { world.remove(ent); world.remove(ent); world.remove(ent); + world.remove(ent); if(auto snd = world.get_if(ent)) { sound::stop(snd->attack); sound::play(snd->death); } - auto entity_data = config.devices["GRAVE_STONE"]; - components::configure_entity(world, ent, entity_data["components"]); - if(entity_data["inventory_count"] > 0) { - dbc::sentinel("BOOM! this is where you fill in the dead bodies."); - System::distribute_loot(world, ent, entity_data); - } + System::distribute_loot(level, ent); } } @@ -322,6 +333,15 @@ void System::collision(GameLevel &level) { } } +void System::remove_from_world(GameLevel &level, Entity entity) { + auto& item_pos = level.world->get(entity); + level.collision->remove(item_pos.location); + level.world->remove(entity); + // if you don't do this you get the bug that you can pickup + // an item and it'll also be in your inventory + level.world->remove(entity); +} + void System::pickup(GameLevel &level, Entity entity) { auto &world = *level.world; auto player = world.get_the(); @@ -329,12 +349,7 @@ void System::pickup(GameLevel &level, Entity entity) { if(world.has(entity)) { // NOTE: this might need to be a separate system so that people can leave stuff alone auto item = world.get(entity); - auto& item_pos = world.get(entity); - level.collision->remove(item_pos.location); - world.remove(entity); - // if you don't do this you get the bug that you can pickup - // an item and it'll also be in your inventory - world.remove(entity); + remove_from_world(level, entity); if(world.has(entity)) { auto& pile = world.get(entity); diff --git a/systems.hpp b/systems.hpp index 0642dbf..a6adbff 100644 --- a/systems.hpp +++ b/systems.hpp @@ -28,12 +28,12 @@ namespace System { std::shared_ptr sprite_effect(GameLevel &level, Entity entity); void player_status(GameLevel &level); - void distribute_loot(World &world, Entity& ent, nlohmann::json& entity_data); + void distribute_loot(GameLevel &level, Entity& ent); void pickup(GameLevel &level, Entity entity); bool place_in_container(World& world, Entity cont_id, const string& name, Entity world_entity); void remove_from_container(World& world, Entity cont_id, const string& name); - + void remove_from_world(GameLevel &level, Entity entity); }