diff --git a/src/game/drivable_vehicle.cpp b/src/game/drivable_vehicle.cpp index 31e652b..326e0f1 100644 --- a/src/game/drivable_vehicle.cpp +++ b/src/game/drivable_vehicle.cpp @@ -68,10 +68,7 @@ void game::DrivableVehicle::InitSeats() seat.position = trans->position; seats_.emplace_back(seat); - UseTarget use_target{}; - use_target.id = seats_.size() - 1; - use_target.position = seat.position; - use_target.desc = "vlízt do " + GetModelName() + " (místo " + std::to_string(use_target.id) + ")"; - use_targets_.emplace_back(use_target); + uint32_t id = seats_.size() - 1; + use_targets_.emplace_back(this, id, seat.position, "vlízt do " + GetModelName() + " (místo " + std::to_string(id) + ")"); } } diff --git a/src/game/npc_character.cpp b/src/game/npc_character.cpp index 16273b5..90301d4 100644 --- a/src/game/npc_character.cpp +++ b/src/game/npc_character.cpp @@ -5,7 +5,7 @@ #include #include -game::NpcCharacter::NpcCharacter(World& world, OpenWorld& openworld) : Super(world) { +game::NpcCharacter::NpcCharacter(World& world) : Super(world) { VehicleChanged(); } diff --git a/src/game/npc_character.hpp b/src/game/npc_character.hpp index 2fc4c5f..d0b8b35 100644 --- a/src/game/npc_character.hpp +++ b/src/game/npc_character.hpp @@ -13,7 +13,7 @@ class NpcCharacter : public ControllableCharacter public: using Super = ControllableCharacter; - NpcCharacter(World& world, OpenWorld& openworld); + NpcCharacter(World& world); virtual void VehicleChanged() override; diff --git a/src/game/openworld.cpp b/src/game/openworld.cpp index 0396a07..16f5c3b 100644 --- a/src/game/openworld.cpp +++ b/src/game/openworld.cpp @@ -124,42 +124,10 @@ void game::OpenWorld::DestructibleDestroyed(net::ObjNum num, std::unique_ptr> game::OpenWorld::GetBestUseTarget(const glm::vec3& pos) const -{ - std::optional> best_target; - float best_dist = std::numeric_limits::max(); - - // TODO: spatial query - for (const auto& [entnum, ent] : GetEntities()) - { - auto usable = dynamic_cast(ent.get()); - if (!usable) - continue; - - for (const auto& target : usable->GetUseTargets()) - { - glm::vec3 pos_world = ent->GetRoot().matrix * glm::vec4(target.position, 1.0f); - - float dist = glm::distance(pos, pos_world); - if (dist < 3.0f && dist < best_dist) - { - best_dist = dist; - best_target = std::make_pair(usable, &target); - } - } - } - - if (best_target) - return std::make_pair(std::ref(*best_target->first), *best_target->second); - else - return std::nullopt; - -} - template static T& SpawnRandomCharacter(game::OpenWorld& world, TArgs&&... args) { - auto& character = world.Spawn(world, std::forward(args)...); + auto& character = world.Spawn(std::forward(args)...); // add clothes character.AddClothes("tshirt", GetRandomColor()); diff --git a/src/game/openworld.hpp b/src/game/openworld.hpp index 7b385f1..aaaa53a 100644 --- a/src/game/openworld.hpp +++ b/src/game/openworld.hpp @@ -27,8 +27,6 @@ public: virtual void DestructibleDestroyed(net::ObjNum num, std::unique_ptr col) override; - std::optional> GetBestUseTarget(const glm::vec3& pos) const; - private: void CreatePlayerCharacter(Player& player); void RemovePlayerCharacter(Player& player); diff --git a/src/game/player_character.cpp b/src/game/player_character.cpp index c6c5687..93f15c1 100644 --- a/src/game/player_character.cpp +++ b/src/game/player_character.cpp @@ -1,7 +1,7 @@ #include "player_character.hpp" #include "openworld.hpp" -game::PlayerCharacter::PlayerCharacter(World& world, OpenWorld& openworld, Player& player) : Super(world), world_(openworld), player_(player) +game::PlayerCharacter::PlayerCharacter(World& world, Player& player) : Super(world), player_(player) { EnablePhysics(true); VehicleChanged(); @@ -39,11 +39,10 @@ void game::PlayerCharacter::ProcessInput(PlayerInputType type, bool enabled) { if (!vehicle_) { - auto use_target_opt = world_.GetBestUseTarget(GetRootTransform().position); - if (use_target_opt) + auto use_target = world_.GetBestUseTarget(GetRootTransform().position); + if (use_target) { - auto& [usable, use_target] = *use_target_opt; - usable.Use(*this, use_target.id); + use_target->usable->Use(*this, use_target->id); } } else diff --git a/src/game/player_character.hpp b/src/game/player_character.hpp index 9c36b21..efb665f 100644 --- a/src/game/player_character.hpp +++ b/src/game/player_character.hpp @@ -13,7 +13,7 @@ class PlayerCharacter : public ControllableCharacter public: using Super = ControllableCharacter; - PlayerCharacter(World& world, OpenWorld& openworld, Player& player); + PlayerCharacter(World& world, Player& player); virtual void Update() override; @@ -26,7 +26,6 @@ private: void UpdateUseTarget(); private: - OpenWorld& world_; Player& player_; }; diff --git a/src/game/usable.hpp b/src/game/usable.hpp index e54e89d..67a00bc 100644 --- a/src/game/usable.hpp +++ b/src/game/usable.hpp @@ -7,26 +7,32 @@ namespace game { +class Usable; + struct UseTarget { + Usable* usable; uint32_t id = 0; glm::vec3 position; std::string desc; + + UseTarget(Usable* usable, uint32_t id, const glm::vec3& position, std::string desc) + : usable(usable), id(id), position(position), desc(std::move(desc)) + { + } }; class PlayerCharacter; class Usable { -public: - const std::vector& GetUseTargets() const { return use_targets_; } +public: + const std::vector& GetUseTargets() const { return use_targets_; } virtual void Use(PlayerCharacter& character, uint32_t target_id) = 0; protected: std::vector use_targets_; - }; - -} \ No newline at end of file +} // namespace game \ No newline at end of file diff --git a/src/game/world.cpp b/src/game/world.cpp index 740d7e8..d14e397 100644 --- a/src/game/world.cpp +++ b/src/game/world.cpp @@ -96,6 +96,34 @@ void game::World::RespawnObj(net::ObjNum objnum) } } +const game::UseTarget* game::World::GetBestUseTarget(const glm::vec3& pos) const +{ + const UseTarget* best_target = nullptr; + float best_dist = std::numeric_limits::max(); + + // TODO: spatial query + for (const auto& [entnum, ent] : GetEntities()) + { + auto usable = dynamic_cast(ent.get()); + if (!usable) + continue; + + for (const auto& target : usable->GetUseTargets()) + { + glm::vec3 pos_world = ent->GetRoot().matrix * glm::vec4(target.position, 1.0f); + + float dist = glm::distance(pos, pos_world); + if (dist < 3.0f && dist < best_dist) + { + best_dist = dist; + best_target = ⌖ + } + } + } + + return best_target; +} + void game::World::HandleContacts() { auto& bt_world = GetBtWorld(); diff --git a/src/game/world.hpp b/src/game/world.hpp index cedc60f..311916c 100644 --- a/src/game/world.hpp +++ b/src/game/world.hpp @@ -8,6 +8,7 @@ #include "entity.hpp" #include "net/defs.hpp" #include "player_input.hpp" +#include "usable.hpp" namespace game { @@ -48,6 +49,8 @@ public: void RespawnObj(net::ObjNum objnum); + const UseTarget* GetBestUseTarget(const glm::vec3& pos) const; + const assets::Map& GetMap() const { return map_.GetMap(); } const std::string& GetMapName() const { return map_.GetName(); } const std::map>& GetEntities() const { return ents_; }