Introduce CharacterTuning to make migration of characters between worlds possible

This commit is contained in:
tovjemam 2026-03-21 16:50:08 +01:00
parent ba0bb5a827
commit cc8bc9313c
11 changed files with 61 additions and 69 deletions

View File

@ -4,10 +4,10 @@
#include "utils/math.hpp" #include "utils/math.hpp"
#include "world.hpp" #include "world.hpp"
game::Character::Character(World& world, const CharacterInfo& info) game::Character::Character(World& world, const CharacterTuning& tuning)
: Super(world, net::ET_CHARACTER), shape_(info.shape), bt_shape_(shape_.radius, shape_.height) : Super(world, net::ET_CHARACTER), tuning_(tuning), bt_shape_(tuning_.shape.radius, tuning_.shape.height)
{ {
z_offset_ = shape_.height * 0.5f + shape_.radius - 0.05f; z_offset_ = tuning_.shape.height * 0.5f + tuning_.shape.radius - 0.05f;
sk_ = SkeletonInstance(assets::CacheManager::GetSkeleton("data/human.sk"), &root_); sk_ = SkeletonInstance(assets::CacheManager::GetSkeleton("data/human.sk"), &root_);
animstate_.idle_anim_idx = GetAnim("idle"); animstate_.idle_anim_idx = GetAnim("idle");
@ -53,8 +53,8 @@ void game::Character::SendInitData(Player& player, net::OutMessage& msg) const
Super::SendInitData(player, msg); Super::SendInitData(player, msg);
// write clothes // write clothes
msg.Write<net::NumClothes>(clothes_.size()); msg.Write<net::NumClothes>(tuning_.clothes.size());
for (const auto& clothes : clothes_) for (const auto& clothes : tuning_.clothes)
{ {
msg.Write(net::ClothesName(clothes.name)); msg.Write(net::ClothesName(clothes.name));
net::WriteRGB(msg, clothes.color); net::WriteRGB(msg, clothes.color);
@ -120,11 +120,6 @@ void game::Character::SetPosition(const glm::vec3& position)
SyncControllerTransform(); SyncControllerTransform();
} }
void game::Character::AddClothes(std::string name, const glm::vec3& color)
{
clothes_.emplace_back(std::move(name), color);
}
void game::Character::SetMainAnim(const std::string& anim_name) void game::Character::SetMainAnim(const std::string& anim_name)
{ {
animstate_.idle_anim_idx = GetAnim(anim_name); animstate_.idle_anim_idx = GetAnim(anim_name);

View File

@ -6,6 +6,7 @@
#include "character_anim_state.hpp" #include "character_anim_state.hpp"
#include "character_sync.hpp" #include "character_sync.hpp"
#include "entity.hpp" #include "entity.hpp"
#include "character_tuning.hpp"
namespace game namespace game
{ {
@ -22,25 +23,6 @@ enum CharacterInputType
CIN_SPRINT, CIN_SPRINT,
}; };
struct CapsuleShape
{
float radius;
float height;
CapsuleShape(float radius, float height) : radius(radius), height(height) {}
};
struct CharacterInfo
{
CapsuleShape shape = CapsuleShape(0.3f, 0.75f);
};
struct CharacterClothes
{
std::string name;
glm::vec3 color;
};
class CharacterPhysicsController class CharacterPhysicsController
{ {
public: public:
@ -65,11 +47,13 @@ class Character : public Entity
public: public:
using Super = Entity; using Super = Entity;
Character(World& world, const CharacterInfo& info); Character(World& world, const CharacterTuning& tuning);
virtual void Update() override; virtual void Update() override;
virtual void SendInitData(Player& player, net::OutMessage& msg) const override; virtual void SendInitData(Player& player, net::OutMessage& msg) const override;
const CharacterTuning& GetTuning() const { return tuning_; }
void EnablePhysics(bool enable); void EnablePhysics(bool enable);
void SetInput(CharacterInputType type, bool enable); void SetInput(CharacterInputType type, bool enable);
@ -80,8 +64,6 @@ public:
void SetPosition(const glm::vec3& position); void SetPosition(const glm::vec3& position);
void AddClothes(std::string name, const glm::vec3& color);
void SetMainAnim(const std::string& anim_name); void SetMainAnim(const std::string& anim_name);
~Character() override = default; ~Character() override = default;
@ -100,7 +82,7 @@ private:
assets::AnimIdx GetAnim(const std::string& name) const; assets::AnimIdx GetAnim(const std::string& name) const;
private: private:
CapsuleShape shape_; CharacterTuning tuning_;
// glm::vec3 position_ = glm::vec3(0.0f); // glm::vec3 position_ = glm::vec3(0.0f);
// glm::vec3 velocity_ = glm::vec3(0.0f); // glm::vec3 velocity_ = glm::vec3(0.0f);
@ -121,8 +103,6 @@ private:
CharacterSyncState sync_[2]; CharacterSyncState sync_[2];
size_t sync_current_ = 0; size_t sync_current_ = 0;
std::vector<CharacterClothes> clothes_;
}; };
} // namespace game } // namespace game

View File

@ -0,0 +1,30 @@
#pragma once
#include <string>
#include <vector>
namespace game
{
struct CharacterShape
{
float radius;
float height;
CharacterShape(float radius, float height) : radius(radius), height(height) {}
};
struct CharacterConfigClothes
{
std::string name;
uint32_t color = 0xFFFFFF;
};
struct CharacterTuning
{
CharacterShape shape = CharacterShape(0.3f, 0.75f);
std::vector<CharacterConfigClothes> clothes;
};
}

View File

@ -1,7 +1,7 @@
#include "controllable_character.hpp" #include "controllable_character.hpp"
#include "drivable_vehicle.hpp" #include "drivable_vehicle.hpp"
game::ControllableCharacter::ControllableCharacter(World& world) : Character(world, CharacterInfo{}) {} game::ControllableCharacter::ControllableCharacter(World& world, const CharacterTuning& tuning) : Character(world, tuning) {}
void game::ControllableCharacter::SetVehicle(DrivableVehicle* vehicle, uint32_t seat) void game::ControllableCharacter::SetVehicle(DrivableVehicle* vehicle, uint32_t seat)
{ {

View File

@ -12,7 +12,7 @@ class ControllableCharacter : public Character
public: public:
using Super = Character; using Super = Character;
ControllableCharacter(World& world); ControllableCharacter(World& world, const CharacterTuning& tuning);
void SetVehicle(DrivableVehicle* vehicle, uint32_t seat); void SetVehicle(DrivableVehicle* vehicle, uint32_t seat);

View File

@ -1,18 +1,13 @@
#include "enterable_world.hpp" #include "enterable_world.hpp"
#include "player_character.hpp" #include "player_character.hpp"
static glm::vec3 GetRandomColor() static uint32_t GetRandomColor24()
{ {
glm::vec3 color; uint8_t r,g,b;
// shittiest way to do it r = rand() % 256;
for (int i = 0; i < 3; ++i) g = rand() % 256;
{ b = rand() % 256;
net::ColorQ qcol; return (b << 16) | (g << 8) | r;
qcol.value = rand() % 256;
color[i] = qcol.Decode();
}
return color;
} }
game::EnterableWorld::EnterableWorld(std::string mapname) : World(std::move(mapname)) {} game::EnterableWorld::EnterableWorld(std::string mapname) : World(std::move(mapname)) {}
@ -74,11 +69,11 @@ game::PlayerCharacter& game::EnterableWorld::CreatePlayerCharacter(Player& playe
{ {
RemovePlayerCharacter(player); RemovePlayerCharacter(player);
auto& character = Spawn<PlayerCharacter>(player); CharacterTuning tuning{};
character.AddClothes("tshirt", GetRandomColor()); tuning.clothes.push_back({ "tshirt", GetRandomColor24() });
character.AddClothes("shorts", GetRandomColor()); tuning.clothes.push_back({ "shorts", GetRandomColor24() });
// character.SetNametag("player (" + std::to_string(character.GetEntNum()) + ")"); auto& character = Spawn<PlayerCharacter>(player, tuning);
character.SetPosition(position); character.SetPosition(position);
character.SetYaw(yaw); character.SetYaw(yaw);

View File

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

View File

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

View File

@ -79,18 +79,6 @@ game::OpenWorld::OpenWorld() : EnterableWorld("openworld")
} }
template <class T, typename... TArgs>
static T& SpawnRandomCharacter(game::OpenWorld& world, TArgs&&... args)
{
auto& character = world.Spawn<T>(std::forward<TArgs>(args)...);
// add clothes
character.AddClothes("tshirt", GetRandomColor());
character.AddClothes("shorts", GetRandomColor());
return character;
}
game::DrivableVehicle& game::OpenWorld::SpawnRandomVehicle() game::DrivableVehicle& game::OpenWorld::SpawnRandomVehicle()
{ {
game::VehicleTuning tuning; game::VehicleTuning tuning;
@ -117,6 +105,10 @@ void game::OpenWorld::SpawnBot()
auto& vehicle = SpawnRandomVehicle(); auto& vehicle = SpawnRandomVehicle();
vehicle.SetPosition(roads->nodes[start_node].position + glm::vec3{0.0f, 0.0f, 5.0f}); vehicle.SetPosition(roads->nodes[start_node].position + glm::vec3{0.0f, 0.0f, 5.0f});
auto& driver = SpawnRandomCharacter<NpcCharacter>(*this); CharacterTuning npc_tuning;
npc_tuning.clothes.push_back({ "tshirt", GetRandomColor24() });
npc_tuning.clothes.push_back({ "shorts", GetRandomColor24() });
auto& driver = Spawn<NpcCharacter>(npc_tuning);
driver.SetVehicle(&vehicle, 0); driver.SetVehicle(&vehicle, 0);
} }

View File

@ -1,7 +1,7 @@
#include "player_character.hpp" #include "player_character.hpp"
#include "world.hpp" #include "world.hpp"
game::PlayerCharacter::PlayerCharacter(World& world, Player& player) : Super(world), player_(player) game::PlayerCharacter::PlayerCharacter(World& world, Player& player, const CharacterTuning& tuning) : Super(world, tuning), player_(player)
{ {
EnablePhysics(true); EnablePhysics(true);
VehicleChanged(); VehicleChanged();

View File

@ -12,7 +12,7 @@ class PlayerCharacter : public ControllableCharacter
public: public:
using Super = ControllableCharacter; using Super = ControllableCharacter;
PlayerCharacter(World& world, Player& player); PlayerCharacter(World& world, Player& player, const CharacterTuning& tuning);
virtual void Update() override; virtual void Update() override;