Move usetargets to world from openworld

This commit is contained in:
zbyv 2026-03-18 19:39:44 +01:00
parent 564343ff79
commit 6341db8ff0
10 changed files with 52 additions and 54 deletions

View File

@ -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) + ")");
}
}

View File

@ -5,7 +5,7 @@
#include <array>
#include <iostream>
game::NpcCharacter::NpcCharacter(World& world, OpenWorld& openworld) : Super(world) {
game::NpcCharacter::NpcCharacter(World& world) : Super(world) {
VehicleChanged();
}

View File

@ -13,7 +13,7 @@ class NpcCharacter : public ControllableCharacter
public:
using Super = ControllableCharacter;
NpcCharacter(World& world, OpenWorld& openworld);
NpcCharacter(World& world);
virtual void VehicleChanged() override;

View File

@ -124,42 +124,10 @@ void game::OpenWorld::DestructibleDestroyed(net::ObjNum num, std::unique_ptr<Map
});
}
std::optional<std::pair<game::Usable&, const game::UseTarget&>> game::OpenWorld::GetBestUseTarget(const glm::vec3& pos) const
{
std::optional<std::pair<Usable*, const UseTarget*>> best_target;
float best_dist = std::numeric_limits<float>::max();
// TODO: spatial query
for (const auto& [entnum, ent] : GetEntities())
{
auto usable = dynamic_cast<Usable*>(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 <class T, typename... TArgs>
static T& SpawnRandomCharacter(game::OpenWorld& world, TArgs&&... args)
{
auto& character = world.Spawn<T>(world, std::forward<TArgs>(args)...);
auto& character = world.Spawn<T>(std::forward<TArgs>(args)...);
// add clothes
character.AddClothes("tshirt", GetRandomColor());

View File

@ -27,8 +27,6 @@ public:
virtual void DestructibleDestroyed(net::ObjNum num, std::unique_ptr<MapObjectCollision> col) override;
std::optional<std::pair<Usable&, const UseTarget&>> GetBestUseTarget(const glm::vec3& pos) const;
private:
void CreatePlayerCharacter(Player& player);
void RemovePlayerCharacter(Player& player);

View File

@ -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

View File

@ -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_;
};

View File

@ -7,11 +7,19 @@
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;
@ -25,8 +33,6 @@ public:
protected:
std::vector<UseTarget> use_targets_;
};
}
} // namespace game

View File

@ -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<float>::max();
// TODO: spatial query
for (const auto& [entnum, ent] : GetEntities())
{
auto usable = dynamic_cast<Usable*>(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 = &target;
}
}
}
return best_target;
}
void game::World::HandleContacts()
{
auto& bt_world = GetBtWorld();

View File

@ -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<net::EntNum, std::unique_ptr<Entity>>& GetEntities() const { return ents_; }