From d3848169e859681a3a9bd33f61d8b8b03ed1755c Mon Sep 17 00:00:00 2001 From: tovjemam Date: Fri, 5 Jun 2026 20:36:52 +0200 Subject: [PATCH] Generalize characters for animals, cow --- CMakeLists.txt | 4 ++ src/game/animal.cpp | 66 +++++++++++++++++++++++++ src/game/animal.hpp | 31 ++++++++++++ src/game/character.cpp | 88 ++++++++-------------------------- src/game/character.hpp | 13 +++-- src/game/character_tuning.hpp | 3 +- src/game/cow.cpp | 20 ++++++++ src/game/cow.hpp | 20 ++++++++ src/game/drivable_vehicle.cpp | 28 ++++------- src/game/drivable_vehicle.hpp | 5 +- src/game/enterable_world.cpp | 4 +- src/game/enterable_world.hpp | 6 +-- src/game/game.cpp | 4 +- src/game/human_character.cpp | 22 +++++++-- src/game/human_character.hpp | 11 ++++- src/game/input_mapping.hpp | 52 ++++++++++++++++++++ src/game/npc_character.cpp | 2 +- src/game/npc_character.hpp | 2 +- src/game/openworld.cpp | 6 ++- src/game/player_character.cpp | 36 ++++---------- src/game/player_character.hpp | 2 +- src/gameview/characterview.cpp | 25 ++++++---- 22 files changed, 305 insertions(+), 145 deletions(-) create mode 100644 src/game/animal.cpp create mode 100644 src/game/animal.hpp create mode 100644 src/game/cow.cpp create mode 100644 src/game/cow.hpp create mode 100644 src/game/input_mapping.hpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 14f2ad4..b65fd1b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -132,8 +132,12 @@ set(CLIENT_ONLY_SOURCES ) set(SERVER_ONLY_SOURCES + "src/game/animal.hpp" + "src/game/animal.cpp" "src/game/character.hpp" "src/game/character.cpp" + "src/game/cow.hpp" + "src/game/cow.cpp" "src/game/destroyed_object.hpp" "src/game/destroyed_object.cpp" "src/game/drivable_vehicle.hpp" diff --git a/src/game/animal.cpp b/src/game/animal.cpp new file mode 100644 index 0000000..cc42bc8 --- /dev/null +++ b/src/game/animal.cpp @@ -0,0 +1,66 @@ +#include "animal.hpp" + +#include "player_character.hpp" +#include "input_mapping.hpp" + +game::Animal::Animal(World& world, const CharacterTuning& tuning, const glm::vec3& position, float yaw) + : Character(world, tuning), Usable(root_.matrix), Rideable(*this, RIDEABLE_ANIMAL) +{ + SetPosition(position); + SetYaw(yaw); + EnablePhysics(true); + + collision::AddObjectFlags(&GetController()->GetBtGhost(), collision::OF_USABLE); +} + +bool game::Animal::QueryUseTarget(PlayerCharacter& character, uint32_t target_id, UseTargetQueryResult& res) +{ + if (character.GetRideable()) + return false; // already in something + + res.enabled = true; + res.error_text = nullptr; + + bool seat_occupied = GetPassenger(target_id) != nullptr; + res.delay = seat_occupied ? 2.0f : 0.25f; + + return true; +} + +void game::Animal::Use(PlayerCharacter& character, uint32_t target_id) +{ + if (target_id >= GetNumSeats()) + return; + + character.Ride(this, target_id); +} + +void game::Animal::SetRideableInput(PlayerInputFlags in) +{ + SetInputs(MapPlayerInputToCharacterInput(in)); +} + +void game::Animal::SetRideableYaw(float yaw) +{ + SetForwardYaw(yaw); +} + +void game::Animal::OnPassengerChanged(size_t seat_idx, HumanCharacter* passenger) +{ + if (seat_idx == 0 && !passenger) + { + SetInputs(0); + } +} + +void game::Animal::SetUseMessage(const std::string& message) +{ + use_message_ = message; +} + +void game::Animal::AddAnimalSeat(const glm::vec3& offset) +{ + size_t seat_idx = AddSeat(offset); + use_targets_.emplace_back(this, static_cast(seat_idx), offset + glm::vec3(0.0f, 0.0f, 1.0f), + use_message_ + " (místo " + std::to_string(seat_idx + 1) + ")"); +} diff --git a/src/game/animal.hpp b/src/game/animal.hpp new file mode 100644 index 0000000..dc0a286 --- /dev/null +++ b/src/game/animal.hpp @@ -0,0 +1,31 @@ +#pragma once + +#include "character.hpp" +#include "usable.hpp" +#include "rideable.hpp" + +namespace game +{ + +class Animal : public Character, public Usable, public Rideable +{ +public: + Animal(World& world, const CharacterTuning& tuning, const glm::vec3& position, float yaw); + + virtual bool QueryUseTarget(PlayerCharacter& character, uint32_t target_id, UseTargetQueryResult& res) override; + virtual void Use(PlayerCharacter& character, uint32_t target_id) override; + + virtual void SetRideableInput(PlayerInputFlags in) override; + virtual void SetRideableYaw(float yaw) override; + +protected: + virtual void OnPassengerChanged(size_t seat_idx, HumanCharacter* passenger) override; + void SetUseMessage(const std::string& message); + void AddAnimalSeat(const glm::vec3& offset); + +private: + std::string use_message_; + +}; + +} \ No newline at end of file diff --git a/src/game/character.cpp b/src/game/character.cpp index cea70df..9ad36c7 100644 --- a/src/game/character.cpp +++ b/src/game/character.cpp @@ -9,9 +9,7 @@ game::Character::Character(World& world, const CharacterTuning& tuning) { z_offset_ = tuning_.shape.height * 0.5f + tuning_.shape.radius - 0.05f; - sk_ = SkeletonInstance(assets::CacheManager::GetSkeleton("data/human.sk"), &root_); - animstate_.idle_anim_idx = GetAnim("idle"); - animstate_.walk_anim_idx = GetAnim("walk"); + sk_ = SkeletonInstance(assets::CacheManager::GetSkeleton("data/" + tuning.model_name + ".sk"), &root_); } static bool Turn(float& angle, float target, float step) @@ -52,6 +50,9 @@ void game::Character::SendInitData(Player& player, net::OutMessage& msg) const { Super::SendInitData(player, msg); + // write model name + msg.Write(net::ModelName(tuning_.model_name)); + // write clothes msg.Write(tuning_.clothes.size()); for (const auto& clothes : tuning_.clothes) @@ -83,7 +84,7 @@ void game::Character::EnablePhysics(bool enable) { if (enable && !controller_) { - controller_ = std::make_unique(world_.GetBtWorld(), bt_shape_); + controller_ = std::make_unique(*this, world_.GetBtWorld(), bt_shape_); SyncControllerTransform(); } else if (!enable && controller_) @@ -100,43 +101,27 @@ void game::Character::SetInput(CharacterInputType type, bool enable) in_ &= ~(1 << type); } -// static bool SweepCapsule(btCollisionWorld& world, const btCapsuleShapeZ& shape, const glm::vec3& start, -// const glm::vec3& end, float& hit_fraction, glm::vec3& hit_normal) -// { -// btVector3 bt_start(start.x, start.y, start.z); -// btVector3 bt_end(end.x, end.y, end.z); - -// static const btMatrix3x3 bt_basis(1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f); - -// btTransform start_transform(bt_basis, bt_start); -// btTransform end_transform(bt_basis, bt_end); - -// btCollisionWorld::ClosestConvexResultCallback result_callback(bt_start, bt_end); -// world.convexSweepTest(&shape, start_transform, end_transform, result_callback); - -// if (result_callback.hasHit()) -// { -// hit_fraction = result_callback.m_closestHitFraction; -// hit_normal = glm::vec3(result_callback.m_hitNormalWorld.x(), result_callback.m_hitNormalWorld.y(), -// result_callback.m_hitNormalWorld.z()); - -// return true; -// } - -// return false; -// } - void game::Character::SetPosition(const glm::vec3& position) { root_.local.position = position; SyncControllerTransform(); } -void game::Character::SetMainAnim(const std::string& anim_name) +void game::Character::SetIdleAnim(const std::string& anim_name) { animstate_.idle_anim_idx = GetAnim(anim_name); } +void game::Character::SetWalkAnim(const std::string& anim_name) +{ + animstate_.walk_anim_idx = GetAnim(anim_name); +} + +void game::Character::SetRunAnim(const std::string& anim_name) +{ + animstate_.run_anim_idx = GetAnim(anim_name); +} + void game::Character::SyncControllerTransform() { if (!controller_) @@ -300,48 +285,13 @@ game::CharacterSyncFieldFlags game::Character::WriteState(net::OutMessage& msg, return fields; } -void game::Character::Move(glm::vec3& velocity, float t) -{ - // glm::vec3 u = velocity * t; // Calculate the movement vector - - // btCollisionWorld& bt_world = world_.GetBtWorld(); - // btCapsuleShapeZ bt_shape(shape_.radius, shape_.height); - - // const int MAX_ITERS = 16; - // for (size_t i = 0; i < MAX_ITERS && glm::dot(u, u) > 0.0f; ++i) - // { - // // printf("Entity::Move: Iteration %zu, u = (%f, %f, %f)\n", i, u.x, u.y, u.z); - - // glm::vec3 to = position_ + u; - - // float hit_fraction = 1.0f; - // glm::vec3 hit_normal; - - // bool hit = SweepCapsule(bt_world, bt_shape, position_, to, hit_fraction, hit_normal); - - // // Update the position based on the hit fraction - // position_ += hit_fraction * u; - - // if (!hit) - // break; - - // // hit_normal *= -1.0f; // Invert the normal to point outwards - // // printf("Entity::Move: Hit detected, hit_fraction = %f, hit_normal = (%f, %f, %f)\n", hit_fraction, - // // hit_normal.x, hit_normal.y, hit_normal.z); - - // u -= hit_fraction * u; // Reduce the movement vector by the hit fraction - // u -= glm::dot(u, hit_normal) * hit_normal; // Reflect the velocity along the hit normal - // velocity -= glm::dot(velocity, hit_normal) * hit_normal; // Adjust the velocity - // } -} - assets::AnimIdx game::Character::GetAnim(const std::string& name) const { return sk_.GetSkeleton()->GetAnimationIdx(name); } -game::CharacterPhysicsController::CharacterPhysicsController(btDynamicsWorld& bt_world, btCapsuleShapeZ& bt_shape) - : bt_world_(bt_world), bt_character_(&bt_ghost_, &bt_shape, 0.3f, btVector3(0, 0, 1)) +game::CharacterPhysicsController::CharacterPhysicsController(Character& character, btDynamicsWorld& bt_world, btCapsuleShapeZ& bt_shape) + : character_(character), bt_world_(bt_world), bt_character_(&bt_ghost_, &bt_shape, 0.3f, btVector3(0, 0, 1)) { btTransform start_transform; start_transform.setIdentity(); @@ -349,6 +299,8 @@ game::CharacterPhysicsController::CharacterPhysicsController(btDynamicsWorld& bt bt_ghost_.setCollisionShape(&bt_shape); bt_ghost_.setCollisionFlags(btCollisionObject::CF_CHARACTER_OBJECT); + collision::SetObjectInfo(&bt_ghost_, collision::OT_ENTITY, 0, &character); + bt_world_.addCollisionObject(&bt_ghost_, btBroadphaseProxy::CharacterFilter, btBroadphaseProxy::StaticFilter | btBroadphaseProxy::DefaultFilter); // bt_world.addCollisionObject(&bt_ghost_); diff --git a/src/game/character.hpp b/src/game/character.hpp index 9ece261..72d8cb8 100644 --- a/src/game/character.hpp +++ b/src/game/character.hpp @@ -23,10 +23,12 @@ enum CharacterInputType CIN_SPRINT, }; +class Character; + class CharacterPhysicsController { public: - CharacterPhysicsController(btDynamicsWorld& bt_world, btCapsuleShapeZ& bt_shape); + CharacterPhysicsController(Character& character, btDynamicsWorld& bt_world, btCapsuleShapeZ& bt_shape); DELETE_COPY_MOVE(CharacterPhysicsController) btKinematicCharacterController& GetBtController() { return bt_character_; } @@ -37,6 +39,7 @@ public: ~CharacterPhysicsController(); private: + Character& character_; btDynamicsWorld& bt_world_; btPairCachingGhostObject bt_ghost_; btKinematicCharacterController bt_character_; @@ -57,16 +60,20 @@ public: const CharacterTuning& GetTuning() const { return tuning_; } void EnablePhysics(bool enable); + CharacterPhysicsController* GetController() { return controller_.get(); } void SetInput(CharacterInputType type, bool enable); void SetInputs(CharacterInputFlags inputs) { in_ = inputs; } void SetForwardYaw(float yaw) { forward_yaw_ = yaw; } + float GetForwardYaw() const { return forward_yaw_; } void SetYaw(float yaw) { yaw_ = yaw; } void SetPosition(const glm::vec3& position); - void SetMainAnim(const std::string& anim_name); + void SetIdleAnim(const std::string& anim_name); + void SetWalkAnim(const std::string& anim_name); + void SetRunAnim(const std::string& anim_name); ~Character() override = default; @@ -79,8 +86,6 @@ private: void SendUpdateMsg(); CharacterSyncFieldFlags WriteState(net::OutMessage& msg, const CharacterSyncState& base) const; - void Move(glm::vec3& velocity, float t); - assets::AnimIdx GetAnim(const std::string& name) const; private: diff --git a/src/game/character_tuning.hpp b/src/game/character_tuning.hpp index 6d7f569..4319b49 100644 --- a/src/game/character_tuning.hpp +++ b/src/game/character_tuning.hpp @@ -22,7 +22,8 @@ struct CharacterConfigClothes struct CharacterTuning { - CharacterShape shape = CharacterShape(0.3f, 0.75f); + CharacterShape shape = CharacterShape(0.3f, 0.75f); + std::string model_name; std::vector clothes; }; diff --git a/src/game/cow.cpp b/src/game/cow.cpp new file mode 100644 index 0000000..ecc6def --- /dev/null +++ b/src/game/cow.cpp @@ -0,0 +1,20 @@ +#include "cow.hpp" + +static game::CharacterTuning GetCowTuning() +{ + game::CharacterTuning ct{}; + ct.shape = game::CharacterShape(0.3f, 0.75f); + ct.model_name = "cow"; + return ct; +} + +game::Cow::Cow(World& world, const glm::vec3& position, float yaw) : Animal(world, GetCowTuning(), position, yaw) +{ + SetUseMessage("vlízt na krávu"); + + AddAnimalSeat(glm::vec3(0.0f, -0.098926f, 0.447576f)); + AddAnimalSeat(glm::vec3(0.0f, 0.394027f, 0.458536f)); + + SetIdleAnim("idle"); + SetWalkAnim("walk"); +} diff --git a/src/game/cow.hpp b/src/game/cow.hpp new file mode 100644 index 0000000..acc89c8 --- /dev/null +++ b/src/game/cow.hpp @@ -0,0 +1,20 @@ +#pragma once + +#include "animal.hpp" + +namespace game +{ + +class Cow : public Animal +{ +public: + Cow(World& world, const glm::vec3& position, float yaw); + +private: + + + +}; + + +} \ No newline at end of file diff --git a/src/game/drivable_vehicle.cpp b/src/game/drivable_vehicle.cpp index c048d4a..f3b7048 100644 --- a/src/game/drivable_vehicle.cpp +++ b/src/game/drivable_vehicle.cpp @@ -1,6 +1,7 @@ #include "drivable_vehicle.hpp" #include "player_character.hpp" #include "utils/random.hpp" +#include "input_mapping.hpp" game::DrivableVehicle::DrivableVehicle(World& world, const VehicleTuning& tuning) : Vehicle(world, tuning), Usable(GetRoot().matrix), Rideable(*this, RIDEABLE_VEHICLE) { @@ -52,30 +53,21 @@ void game::DrivableVehicle::Use(PlayerCharacter& character, uint32_t target_id) PlaySound("cardoor", 1.0f, RandomFloat(0.9f, 1.1f)); } -static game::CharacterInputFlags MapPlayerInputToVehicleInput(game::PlayerInputFlags in) -{ - game::VehicleInputFlags vin = 0; - - if (in & (1 << game::IN_FORWARD)) - vin |= 1 << game::VIN_FORWARD; - - if (in & (1 << game::IN_BACKWARD)) - vin |= 1 << game::VIN_BACKWARD; - - if (in & (1 << game::IN_LEFT)) - vin |= 1 << game::VIN_LEFT; - - if (in & (1 << game::IN_RIGHT)) - vin |= 1 << game::VIN_RIGHT; - - return vin; -} void game::DrivableVehicle::SetRideableInput(PlayerInputFlags in) { SetInputs(MapPlayerInputToVehicleInput(in)); } +void game::DrivableVehicle::OnPassengerChanged(size_t seat_idx, HumanCharacter* passenger) +{ + if (seat_idx == 0 && !passenger) + { + // driver left + SetInputs(0); + } +} + static char HexChar(uint32_t val) { if (val < 10) diff --git a/src/game/drivable_vehicle.hpp b/src/game/drivable_vehicle.hpp index ca4fd6c..1f8bcc8 100644 --- a/src/game/drivable_vehicle.hpp +++ b/src/game/drivable_vehicle.hpp @@ -24,7 +24,10 @@ public: virtual bool QueryUseTarget(PlayerCharacter& character, uint32_t target_id, UseTargetQueryResult& res) override; virtual void Use(PlayerCharacter& character, uint32_t target_id) override; - virtual void SetRideableInput(PlayerInputFlags in); + virtual void SetRideableInput(PlayerInputFlags in) override; + +protected: + virtual void OnPassengerChanged(size_t seat_idx, HumanCharacter* passenger) override; private: void InitSeats(); diff --git a/src/game/enterable_world.cpp b/src/game/enterable_world.cpp index 1a19fa5..70956a2 100644 --- a/src/game/enterable_world.cpp +++ b/src/game/enterable_world.cpp @@ -5,7 +5,7 @@ game::EnterableWorld::EnterableWorld(std::string mapname) : World(std::move(mapname)) {} -game::PlayerCharacter& game::EnterableWorld::InsertPlayer(Player& player, const CharacterTuning& tuning, const glm::vec3& pos, float yaw) +game::PlayerCharacter& game::EnterableWorld::InsertPlayer(Player& player, const HumanCharacterTuning& tuning, const glm::vec3& pos, float yaw) { return CreatePlayerCharacter(player, tuning, pos, yaw); } @@ -62,7 +62,7 @@ game::PlayerCharacter* game::EnterableWorld::GetPlayerCharacter(Player& player) return it->second; } -game::PlayerCharacter& game::EnterableWorld::CreatePlayerCharacter(Player& player, const CharacterTuning& tuning, const glm::vec3& position, float yaw) +game::PlayerCharacter& game::EnterableWorld::CreatePlayerCharacter(Player& player, const HumanCharacterTuning& tuning, const glm::vec3& position, float yaw) { RemovePlayerCharacter(player); diff --git a/src/game/enterable_world.hpp b/src/game/enterable_world.hpp index 66685a7..e40b471 100644 --- a/src/game/enterable_world.hpp +++ b/src/game/enterable_world.hpp @@ -7,7 +7,7 @@ namespace game class Player; class PlayerCharacter; -class CharacterTuning; +class HumanCharacterTuning; class DrivableVehicle; class EnterableWorld : public World @@ -16,7 +16,7 @@ public: EnterableWorld(std::string mapname); // events - virtual PlayerCharacter& InsertPlayer(Player& player, const CharacterTuning& tuning, const glm::vec3& pos, float yaw); + virtual PlayerCharacter& InsertPlayer(Player& player, const HumanCharacterTuning& tuning, const glm::vec3& pos, float yaw); virtual void PlayerInput(Player& player, PlayerInputType type, bool enabled); virtual void PlayerViewAnglesChanged(Player& player, float yaw, float pitch); virtual void RemovePlayer(Player& player); @@ -28,7 +28,7 @@ public: PlayerCharacter* GetPlayerCharacter(Player& player); private: - PlayerCharacter& CreatePlayerCharacter(Player& player, const CharacterTuning& tuning, const glm::vec3& position, float yaw); + PlayerCharacter& CreatePlayerCharacter(Player& player, const HumanCharacterTuning& tuning, const glm::vec3& position, float yaw); void RemovePlayerCharacter(Player& player); private: diff --git a/src/game/game.cpp b/src/game/game.cpp index cfc1260..322593c 100644 --- a/src/game/game.cpp +++ b/src/game/game.cpp @@ -52,7 +52,7 @@ void game::Game::PlayerJoined(Player& player) player_info.world = openworld_.get(); player.SetWorld(openworld_.get()); - CharacterTuning tuning{}; + HumanCharacterTuning tuning{}; tuning.clothes.push_back({"tshirt", GetRandomColor24()}); tuning.clothes.push_back({"shorts", GetRandomColor24()}); @@ -142,7 +142,7 @@ game::PlayerCharacter& game::Game::MovePlayerToWorld(PlayerGameInfo& player_info auto& old_world = *player_info.world; auto old_character = old_world.GetPlayerCharacter(player); - auto& tuning = old_character->GetTuning(); + auto& tuning = old_character->GetHumanTuning(); old_world.RemovePlayer(player); player.SetWorld(&new_world); diff --git a/src/game/human_character.cpp b/src/game/human_character.cpp index d9d7ba5..d184ace 100644 --- a/src/game/human_character.cpp +++ b/src/game/human_character.cpp @@ -1,7 +1,21 @@ #include "human_character.hpp" #include "drivable_vehicle.hpp" -game::HumanCharacter::HumanCharacter(World& world, const CharacterTuning& tuning) : Character(world, tuning) {} +static game::CharacterTuning GetCharacterTuning(const game::HumanCharacterTuning& tuning) +{ + game::CharacterTuning ct{}; + ct.shape = game::CharacterShape(0.3f, 0.75f); + ct.model_name = "human"; + ct.clothes = tuning.clothes; + + return ct; +} + +game::HumanCharacter::HumanCharacter(World& world, const HumanCharacterTuning& tuning) : Character(world, GetCharacterTuning(tuning)), human_tuning_(tuning) +{ + SetIdleAnim("idle"); + SetWalkAnim("walk"); +} void game::HumanCharacter::SetRideable(Rideable* rideable, size_t seat_idx) { @@ -14,8 +28,8 @@ void game::HumanCharacter::SetRideable(Rideable* rideable, size_t seat_idx) EnablePhysics(false); Attach(rideable->GetEntity().GetEntNum()); - SetMainAnim(seat_idx == 0 ? "vehicle_drive" : "vehicle_passenger"); - SetYaw(0.5f * glm::pi()); + SetIdleAnim((rideable->GetRideableType() == RIDEABLE_VEHICLE && seat_idx == 0) ? "vehicle_drive" : "vehicle_passenger"); + SetYaw(rideable->GetRideableType() == RIDEABLE_VEHICLE ? 0.5f * glm::pi() : 1.0f * glm::pi()); } else { @@ -29,7 +43,7 @@ void game::HumanCharacter::SetRideable(Rideable* rideable, size_t seat_idx) SetPosition(pos); Attach(0); - SetMainAnim("idle"); + SetIdleAnim("idle"); } rideable_ = rideable; diff --git a/src/game/human_character.hpp b/src/game/human_character.hpp index 33623ff..efb2c42 100644 --- a/src/game/human_character.hpp +++ b/src/game/human_character.hpp @@ -5,6 +5,11 @@ namespace game { +struct HumanCharacterTuning +{ + std::vector clothes; +}; + class Rideable; class DrivableVehicle; @@ -13,8 +18,10 @@ class HumanCharacter : public Character public: using Super = Character; - HumanCharacter(World& world, const CharacterTuning& tuning); + HumanCharacter(World& world, const HumanCharacterTuning& tuning); + const HumanCharacterTuning& GetHumanTuning() const { return human_tuning_; } + void SetRideable(Rideable* rideable, size_t seat_idx); // called by Rideable!! void Ride(Rideable* rideable, size_t seat_idx); @@ -30,6 +37,8 @@ protected: virtual void OnRideableChanged() {} private: + HumanCharacterTuning human_tuning_; + Rideable* rideable_ = nullptr; DrivableVehicle* vehicle_ = nullptr; size_t seat_idx_ = 0; diff --git a/src/game/input_mapping.hpp b/src/game/input_mapping.hpp new file mode 100644 index 0000000..f2d8d84 --- /dev/null +++ b/src/game/input_mapping.hpp @@ -0,0 +1,52 @@ +#include "player_input.hpp" +#include "vehicle.hpp" +#include "character.hpp" + +namespace game +{ + +inline game::CharacterInputFlags MapPlayerInputToCharacterInput(game::PlayerInputFlags in) +{ + game::CharacterInputFlags c_in = 0; + + if (in & (1 << game::IN_FORWARD)) + c_in |= 1 << game::CIN_FORWARD; + + if (in & (1 << game::IN_BACKWARD)) + c_in |= 1 << game::CIN_BACKWARD; + + if (in & (1 << game::IN_LEFT)) + c_in |= 1 << game::CIN_LEFT; + + if (in & (1 << game::IN_RIGHT)) + c_in |= 1 << game::CIN_RIGHT; + + if (in & (1 << game::IN_JUMP)) + c_in |= 1 << game::CIN_JUMP; + + if (in & (1 << game::IN_SPRINT)) + c_in |= 1 << game::CIN_SPRINT; + + return c_in; +} + +static game::VehicleInputFlags MapPlayerInputToVehicleInput(game::PlayerInputFlags in) +{ + game::VehicleInputFlags vin = 0; + + if (in & (1 << game::IN_FORWARD)) + vin |= 1 << game::VIN_FORWARD; + + if (in & (1 << game::IN_BACKWARD)) + vin |= 1 << game::VIN_BACKWARD; + + if (in & (1 << game::IN_LEFT)) + vin |= 1 << game::VIN_LEFT; + + if (in & (1 << game::IN_RIGHT)) + vin |= 1 << game::VIN_RIGHT; + + return vin; +} + +} \ No newline at end of file diff --git a/src/game/npc_character.cpp b/src/game/npc_character.cpp index a98d9bd..1254cfb 100644 --- a/src/game/npc_character.cpp +++ b/src/game/npc_character.cpp @@ -5,7 +5,7 @@ #include #include -game::NpcCharacter::NpcCharacter(World& world, const CharacterTuning& tuning) : Super(world, tuning) { +game::NpcCharacter::NpcCharacter(World& world, const HumanCharacterTuning& tuning) : Super(world, tuning) { UpdateVehicleState(); } diff --git a/src/game/npc_character.hpp b/src/game/npc_character.hpp index 7cc4fad..c7bdb78 100644 --- a/src/game/npc_character.hpp +++ b/src/game/npc_character.hpp @@ -19,7 +19,7 @@ class NpcCharacter : public HumanCharacter public: using Super = HumanCharacter; - NpcCharacter(World& world, const CharacterTuning& tuning); + NpcCharacter(World& world, const HumanCharacterTuning& tuning); virtual void Update() override; diff --git a/src/game/openworld.cpp b/src/game/openworld.cpp index f78eea6..7379648 100644 --- a/src/game/openworld.cpp +++ b/src/game/openworld.cpp @@ -11,6 +11,7 @@ #include "marker.hpp" #include "tuning_world.hpp" #include "game.hpp" +#include "cow.hpp" namespace game { @@ -87,6 +88,9 @@ game::OpenWorld::OpenWorld(Game& game) : EnterableWorld("openworld"), game_(game CreateTuningGarage(loc.transform.position, glm::eulerAngles(loc.transform.rotation).x); } + // cow + auto& cow = Spawn(glm::vec3(0.0f, 0.0f, 2.0f), 0.0f); + cow.SetNametag("no ty krávo"); } void game::OpenWorld::Update(int64_t delta_time) @@ -169,7 +173,7 @@ void game::OpenWorld::SpawnBot() auto& vehicle = SpawnRandomVehicle(); vehicle.SetPosition(roads->nodes[start_node].position + glm::vec3{0.0f, 0.0f, 5.0f}); - CharacterTuning npc_tuning; + HumanCharacterTuning npc_tuning; npc_tuning.clothes.push_back({ "tshirt", GetRandomColor24() }); npc_tuning.clothes.push_back({ "shorts", GetRandomColor24() }); diff --git a/src/game/player_character.cpp b/src/game/player_character.cpp index 771d1b8..0d58541 100644 --- a/src/game/player_character.cpp +++ b/src/game/player_character.cpp @@ -1,7 +1,8 @@ #include "player_character.hpp" #include "world.hpp" +#include "input_mapping.hpp" -game::PlayerCharacter::PlayerCharacter(World& world, Player& player, const CharacterTuning& tuning) : Super(world, tuning), player_(&player) +game::PlayerCharacter::PlayerCharacter(World& world, Player& player, const HumanCharacterTuning& tuning) : Super(world, tuning), player_(&player) { EnablePhysics(true); UpdatePlayerCamera(); @@ -13,6 +14,11 @@ void game::PlayerCharacter::Update() { UpdateUseTarget(); Super::Update(); + + if (GetRideable() && IsDriver()) + { + GetRideable()->SetRideableYaw(GetForwardYaw()); + } } void game::PlayerCharacter::ProcessInput(PlayerInputType type, bool enabled) @@ -40,31 +46,6 @@ void game::PlayerCharacter::OnRideableChanged() UpdateInputs(); } -static game::CharacterInputFlags MapPlayerInputToCharacterInput(game::PlayerInputFlags in) -{ - game::CharacterInputFlags c_in = 0; - - if (in & (1 << game::IN_FORWARD)) - c_in |= 1 << game::CIN_FORWARD; - - if (in & (1 << game::IN_BACKWARD)) - c_in |= 1 << game::CIN_BACKWARD; - - if (in & (1 << game::IN_LEFT)) - c_in |= 1 << game::CIN_LEFT; - - if (in & (1 << game::IN_RIGHT)) - c_in |= 1 << game::CIN_RIGHT; - - if (in & (1 << game::IN_JUMP)) - c_in |= 1 << game::CIN_JUMP; - - if (in & (1 << game::IN_SPRINT)) - c_in |= 1 << game::CIN_SPRINT; - - return c_in; -} - void game::PlayerCharacter::UpdatePlayerCamera() { if (!player_) @@ -80,7 +61,6 @@ void game::PlayerCharacter::UpdatePlayerCamera() } } - void game::PlayerCharacter::UpdateInputs() { auto in = player_ ? player_->GetInput() : 0; @@ -90,7 +70,9 @@ void game::PlayerCharacter::UpdateInputs() SetInputs(0); if (IsDriver()) + { rideable->SetRideableInput(in); + } } else { diff --git a/src/game/player_character.hpp b/src/game/player_character.hpp index f139c6b..ceeca3a 100644 --- a/src/game/player_character.hpp +++ b/src/game/player_character.hpp @@ -12,7 +12,7 @@ class PlayerCharacter : public HumanCharacter public: using Super = HumanCharacter; - PlayerCharacter(World& world, Player& player, const CharacterTuning& tuning); + PlayerCharacter(World& world, Player& player, const HumanCharacterTuning& tuning); virtual void Update() override; diff --git a/src/gameview/characterview.cpp b/src/gameview/characterview.cpp index 6c69e5f..251398e 100644 --- a/src/gameview/characterview.cpp +++ b/src/gameview/characterview.cpp @@ -6,7 +6,12 @@ game::view::CharacterView::CharacterView(WorldView& world, net::InMessage& msg) : EntityView(world, msg), ubo_(sk_) { - basemodel_ = assets::CacheManager::GetModel("data/human.mdl"); + // read model name + net::ModelName model_name; + if (!msg.Read(model_name)) + throw EntityInitError();; + + basemodel_ = assets::CacheManager::GetModel("data/" + std::string(model_name) + ".mdl"); sk_ = SkeletonInstance(basemodel_->GetSkeleton(), &root_); ubo_.Update(); ubo_valid_ = true; @@ -90,17 +95,17 @@ void game::view::CharacterView::Draw(const DrawArgs& args) //args.dlist.AddBeam(start, end, 0xFF007700, 0.05f); //// draw bones debug - // const auto& bone_nodes = sk_.GetBoneNodes(); - // for (const auto& bone_node : bone_nodes) - //{ - // if (!bone_node.parent) - // continue; + const auto& bone_nodes = sk_.GetBoneNodes(); + for (const auto& bone_node : bone_nodes) + { + if (!bone_node.parent) + continue; - // glm::vec3 p0 = bone_node.parent->matrix[3]; - // glm::vec3 p1 = bone_node.matrix[3]; + glm::vec3 p0 = bone_node.parent->matrix[3]; + glm::vec3 p1 = bone_node.matrix[3]; - // args.dlist.AddBeam(p0, p1, 0xFF00EEEE, 0.01f); - //} + args.dlist.AddBeam(p0, p1, 0xFF00EEEE, 0.01f); + } // update skinning matrices if (!ubo_valid_)