From 0a268591c22181f9f40b7e1f9e9e38ea59fe44a7 Mon Sep 17 00:00:00 2001 From: "Zed A. Shaw" Date: Thu, 7 Nov 2024 00:29:06 -0500 Subject: [PATCH] Started working on the loot system which will eventually become the inventory/improved collision system. --- components.hpp | 4 +-- dinkyecs.hpp | 7 ++++++ main.cpp | 4 +-- systems.cpp | 63 +++++++++++++++++++++++++++++----------------- tests/dinkyecs.cpp | 2 ++ 5 files changed, 53 insertions(+), 27 deletions(-) diff --git a/components.hpp b/components.hpp index eb49511..25e90bf 100644 --- a/components.hpp +++ b/components.hpp @@ -22,9 +22,9 @@ namespace components { DEFINE_SERIALIZABLE(Motion, dx, dy); }; - struct Treasure { + struct Loot { int amount; - DEFINE_SERIALIZABLE(Treasure, amount); + DEFINE_SERIALIZABLE(Loot, amount); }; struct Tile { diff --git a/dinkyecs.hpp b/dinkyecs.hpp index c8d8190..a79ceb4 100644 --- a/dinkyecs.hpp +++ b/dinkyecs.hpp @@ -74,6 +74,13 @@ namespace DinkyECS { return std::any_cast(res); } + template + bool has(Entity ent) { + EntityMap &map = entity_map_for(); + // use .at for bounds checking + return map.contains(ent); + } + template void query(std::function cb) { EntityMap &map = entity_map_for(); diff --git a/main.cpp b/main.cpp index 1cdb14a..19458d6 100644 --- a/main.cpp +++ b/main.cpp @@ -41,8 +41,8 @@ void configure_world(DinkyECS::World &world, Map &game_map) { world.set(enemy2, {"*"}); auto gold = world.entity(); - world.set(gold, {game_map.place_entity(game_map.room_count() - 1)}); - world.set(gold, {100}); + world.set(gold, {game_map.place_entity(3)}); + world.set(gold, {100}); world.set(gold, {"$"}); } diff --git a/systems.cpp b/systems.cpp index e43f29b..a18b5ae 100644 --- a/systems.cpp +++ b/systems.cpp @@ -7,6 +7,7 @@ #include "events.hpp" #include "ftxui/screen/color.hpp" #include "ftxui/screen/terminal.hpp" // for SetColorSupport, Color, TrueColor +#include "dbc.hpp" using std::string; using namespace fmt; @@ -40,9 +41,13 @@ void System::init_positions(DinkyECS::World &world) { collider.insert(pos.location, ent); } }); + + world.query([&](const auto &ent, auto &pos, auto &loot) { + collider.insert(pos.location, ent); + }); } -inline void move_entity(spatial_map &collider, Map &game_map, Position &position, Motion &motion, DinkyECS::Entity ent) { +inline bool move_entity(spatial_map &collider, Map &game_map, Position &position, Motion &motion, DinkyECS::Entity ent) { Point move_to = { position.location.x + motion.dx, position.location.y + motion.dy @@ -50,25 +55,31 @@ inline void move_entity(spatial_map &collider, Map &game_map, Position &position motion = {0,0}; // clear it after getting it if(game_map.inmap(move_to.x, move_to.y) && - !game_map.iswall(move_to.x, move_to.y) && - !collider.occupied(move_to)) + !game_map.iswall(move_to.x, move_to.y)) { - collider.move(position.location, move_to, ent); - position.location = move_to; + if(collider.occupied(move_to)) { + return true; + } else { + collider.move(position.location, move_to, ent); + position.location = move_to; + return false; + } + } else { + return false; } } void System::motion(DinkyECS::World &world, Map &game_map) { auto &collider = world.get_the(); - auto &player = world.get_the(); - auto &player_position = world.get(player.entity); - auto &player_motion = world.get(player.entity); - move_entity(collider, game_map, player_position, player_motion, player.entity); world.query([&](const auto &ent, auto &position, auto &motion) { // don't process entities that don't move if(motion.dx != 0 || motion.dy != 0) { - move_entity(collider, game_map, position, motion, ent); + // if there's a collision + if(move_entity(collider, game_map, position, motion, ent)) { + // send a collision event? + println("hit it!"); + } } }); } @@ -99,25 +110,31 @@ void System::combat(DinkyECS::World &world, Player &player) { if(found) { for(auto entity : nearby) { - auto& enemy_combat = world.get(entity); - int player_dmg = player_combat.attack(enemy_combat); + if(world.has(entity)) { + auto& enemy_combat = world.get(entity); + int player_dmg = player_combat.attack(enemy_combat); - if(player_dmg > 0) { - world.send(Events::GUI::HIT, entity); - } else { - world.send(Events::GUI::MISS, entity); - } + if(player_dmg > 0) { + world.send(Events::GUI::HIT, entity); + } else { + world.send(Events::GUI::MISS, entity); + } - if(enemy_combat.hp > 0) { - int enemy_dmg = enemy_combat.attack(player_combat); + if(enemy_combat.hp > 0) { + int enemy_dmg = enemy_combat.attack(player_combat); - if(enemy_dmg > 0) { - world.send(Events::GUI::HIT, player.entity); + if(enemy_dmg > 0) { + world.send(Events::GUI::HIT, player.entity); + } else { + world.send(Events::GUI::MISS, player.entity); + } } else { - world.send(Events::GUI::MISS, player.entity); + world.send(Events::GUI::DEAD, entity); } + } else if(world.has(entity)) { + println("YOU FOUND LOOT"); } else { - world.send(Events::GUI::DEAD, entity); + println("UNKNOWN COLLISION TYPE {}", entity); } } } diff --git a/tests/dinkyecs.cpp b/tests/dinkyecs.cpp index ac39422..fe8967d 100644 --- a/tests/dinkyecs.cpp +++ b/tests/dinkyecs.cpp @@ -111,8 +111,10 @@ TEST_CASE("confirm ECS system works", "[ecs]") { }); // now remove Velocity + REQUIRE(world.has(test)); world.remove(test); REQUIRE_THROWS(world.get(test)); + REQUIRE(!world.has(test)); println("--- After remove test, should only result in test2:"); world.query([&](const auto &ent, auto &pos, auto &vel) {