From fc4eacadb09914ec03452a501e0f9eed9a5b6785 Mon Sep 17 00:00:00 2001 From: "Zed A. Shaw" Date: Wed, 6 Aug 2025 11:43:39 -0400 Subject: [PATCH] There's now a Collision component that determines collision if its set. Closes #72. --- assets/enemies.json | 6 ++++++ components.cpp | 1 + components.hpp | 5 +++++ systems.cpp | 16 +++++++++++----- systems.hpp | 2 ++ worldbuilder.cpp | 10 ++-------- 6 files changed, 27 insertions(+), 13 deletions(-) diff --git a/assets/enemies.json b/assets/enemies.json index cfb673f..3ad2eac 100644 --- a/assets/enemies.json +++ b/assets/enemies.json @@ -8,6 +8,7 @@ }, {"_type": "Combat", "hp": 200, "max_hp": 200, "damage": 10, "dead": false}, {"_type": "Motion", "dx": 0, "dy": 0, "random": false}, + {"_type": "Collision", "has": true}, {"_type": "LightSource", "strength": 35, "radius": 2.0} ] }, @@ -18,6 +19,7 @@ "background": "color:transparent" }, {"_type": "Combat", "hp": 20, "max_hp": 20, "damage": 1, "dead": false}, + {"_type": "Collision", "has": true}, {"_type": "Motion", "dx": 0, "dy": 0, "random": false}, {"_type": "EnemyConfig", "ai_script": "Enemy::actions", "ai_start_name": "Enemy::initial_state", "ai_goal_name": "Enemy::final_state"}, {"_type": "Personality", "hearing_distance": 5, "tough": false}, @@ -33,6 +35,7 @@ "background": "color:transparent" }, {"_type": "Combat", "hp": 20, "max_hp": 20, "damage": 1, "dead": false}, + {"_type": "Collision", "has": true}, {"_type": "Motion", "dx": 0, "dy": 0, "random": false}, {"_type": "EnemyConfig", "ai_script": "Enemy::actions", "ai_start_name": "Enemy::initial_state", "ai_goal_name": "Enemy::final_state"}, {"_type": "Personality", "hearing_distance": 5, "tough": true}, @@ -48,6 +51,7 @@ "background": "color:transparent" }, {"_type": "Combat", "hp": 40, "max_hp": 40, "damage": 10, "dead": false}, + {"_type": "Collision", "has": true}, {"_type": "Motion", "dx": 0, "dy": 0, "random": true}, {"_type": "EnemyConfig", "ai_script": "Enemy::actions", "ai_start_name": "Enemy::initial_state", "ai_goal_name": "Enemy::final_state"}, {"_type": "Personality", "hearing_distance": 5, "tough": true}, @@ -63,6 +67,7 @@ "background": "color:transparent" }, {"_type": "Combat", "hp": 50, "max_hp": 50, "damage": 2, "dead": false}, + {"_type": "Collision", "has": true}, {"_type": "Motion", "dx": 0, "dy": 0, "random": false}, {"_type": "EnemyConfig", "ai_script": "Enemy::actions", "ai_start_name": "Enemy::initial_state", "ai_goal_name": "Enemy::final_state"}, {"_type": "Personality", "hearing_distance": 5, "tough": false}, @@ -78,6 +83,7 @@ "background": "color:transparent" }, {"_type": "Combat", "hp": 20, "max_hp": 20, "damage": 20, "dead": false}, + {"_type": "Collision", "has": true}, {"_type": "Motion", "dx": 0, "dy": 0, "random": false}, {"_type": "EnemyConfig", "ai_script": "Enemy::actions", "ai_start_name": "Enemy::initial_state", "ai_goal_name": "Enemy::final_state"}, {"_type": "Personality", "hearing_distance": 5, "tough": true}, diff --git a/components.cpp b/components.cpp index 7f21c81..db32b01 100644 --- a/components.cpp +++ b/components.cpp @@ -29,6 +29,7 @@ namespace components { components::enroll(MAP); components::enroll(MAP); components::enroll(MAP); + components::enroll(MAP); MAP_configured = true; } } diff --git a/components.hpp b/components.hpp index e1bbd56..0dfd885 100644 --- a/components.hpp +++ b/components.hpp @@ -26,6 +26,10 @@ namespace components { std::shared_ptr effect; }; + struct Collision { + bool has = true; + }; + struct Position { Point location{0,0}; Point aiming_at{0,0}; @@ -151,6 +155,7 @@ namespace components { ENROLL_COMPONENT(Animation, scale, simple, frames, speed, easing, ease_rate, stationary); ENROLL_COMPONENT(Sound, attack, death); + ENROLL_COMPONENT(Collision, has); template COMPONENT convert(nlohmann::json &data) { COMPONENT result; diff --git a/systems.cpp b/systems.cpp index a2ae0cf..c959385 100644 --- a/systems.cpp +++ b/systems.cpp @@ -23,6 +23,12 @@ using namespace components; using namespace DinkyECS; using lighting::LightSource; +void System::set_position(World& world, SpatialMap& collision, Entity entity, Position pos) { + world.set(entity, pos); + bool has_collision = world.has(entity); + collision.insert(pos.location, entity, has_collision); +} + void System::lighting(GameLevel &level) { auto &light = *level.lights; auto &world = *level.world; @@ -162,8 +168,9 @@ void System::distribute_loot(GameLevel &level, Position target_pos) { world.set(junk_entity, pile); // BUG: inventory_count here isn't really used to remove it world.set(junk_entity, {inventory_count, entity_data}); - world.set(junk_entity, target_pos); - level.collision->insert(target_pos.location, junk_entity, false); + + set_position(world, *level.collision, junk_entity, target_pos); + level.world->send(Events::GUI::ENTITY_SPAWN, junk_entity, {}); } else { dbc::log("DEAD BODY NOT IMPLEMENTED, for now just removing enemy"); @@ -442,7 +449,6 @@ Entity System::spawn_item(World& world, const std::string& name) { void System::drop_item(GameLevel& level, Entity item) { auto& world = *level.world; auto& map = *level.map; - auto& collision = *level.collision; auto player_pos = world.get(level.player); @@ -453,8 +459,8 @@ void System::drop_item(GameLevel& level, Entity item) { // if they're aiming at a wall then drop at their feet if(!map.can_move(drop_spot.location)) drop_spot = player_pos; - world.set(item, drop_spot); - collision.insert(drop_spot.location, item, false); + set_position(world, *level.collision, item, drop_spot); + level.world->not_constant(item); level.world->send(Events::GUI::ENTITY_SPAWN, item, {}); } diff --git a/systems.hpp b/systems.hpp index 7a04982..46dcc51 100644 --- a/systems.hpp +++ b/systems.hpp @@ -40,4 +40,6 @@ namespace System { void draw_map(GameLevel& level, Matrix& grid, EntityGrid& entity_map); void render_map(Matrix& tiles, EntityGrid& entity_map, sf::RenderTexture& render, int compass_dir, wchar_t player_display); + + void set_position(DinkyECS::World& world, SpatialMap& collision, Entity entity, Position pos); } diff --git a/worldbuilder.cpp b/worldbuilder.cpp index a800f5f..696b40a 100644 --- a/worldbuilder.cpp +++ b/worldbuilder.cpp @@ -88,23 +88,18 @@ DinkyECS::Entity WorldBuilder::configure_entity_in_map(DinkyECS::World &world, j dbc::check(found, "Failed to find a place for this thing."); auto item = world.entity(); - // NOTE: aiming_at is set by the rayview since it knows that - world.set(item, {pos.x, pos.y}); - // BUG: See #72, but this will change to a setting for collision int inv_count = entity_data.contains("inventory_count") ? (int)entity_data["inventory_count"] : 0; - bool has_collision = true; if(inv_count > 0) { world.set(item, {entity_data["inventory_count"], entity_data}); - has_collision = false; } if(entity_data.contains("components")) { components::configure_entity(world, item, entity_data["components"]); } - $collision.insert(pos, item, has_collision); + System::set_position(world, $collision, item, {pos.x, pos.y}); return item; } @@ -209,8 +204,7 @@ void WorldBuilder::place_entities(DinkyECS::World &world) { placed = find_open_spot(player_pos.location); dbc::check(placed, "WorldBuild.find_open_spot also failed to position player"); - world.set(player.entity, player_pos); - $collision.insert(player_pos.location, player.entity, true); + System::set_position(world, $collision, player.entity, player_pos); } else { auto player_data = config.enemies["PLAYER_TILE"]; auto player_ent = configure_entity_in_room(world, player_data, 0);