Generalize characters for animals, cow
This commit is contained in:
parent
c136ccf26d
commit
d3848169e8
@ -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"
|
||||
|
||||
66
src/game/animal.cpp
Normal file
66
src/game/animal.cpp
Normal file
@ -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<uint32_t>(seat_idx), offset + glm::vec3(0.0f, 0.0f, 1.0f),
|
||||
use_message_ + " (místo " + std::to_string(seat_idx + 1) + ")");
|
||||
}
|
||||
31
src/game/animal.hpp
Normal file
31
src/game/animal.hpp
Normal file
@ -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_;
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
@ -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<net::NumClothes>(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<CharacterPhysicsController>(world_.GetBtWorld(), bt_shape_);
|
||||
controller_ = std::make_unique<CharacterPhysicsController>(*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_);
|
||||
|
||||
@ -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:
|
||||
|
||||
@ -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<CharacterConfigClothes> clothes;
|
||||
};
|
||||
|
||||
|
||||
20
src/game/cow.cpp
Normal file
20
src/game/cow.cpp
Normal file
@ -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");
|
||||
}
|
||||
20
src/game/cow.hpp
Normal file
20
src/game/cow.hpp
Normal file
@ -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:
|
||||
|
||||
|
||||
|
||||
};
|
||||
|
||||
|
||||
}
|
||||
@ -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)
|
||||
|
||||
@ -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();
|
||||
|
||||
@ -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);
|
||||
|
||||
|
||||
@ -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:
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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<float>());
|
||||
SetIdleAnim((rideable->GetRideableType() == RIDEABLE_VEHICLE && seat_idx == 0) ? "vehicle_drive" : "vehicle_passenger");
|
||||
SetYaw(rideable->GetRideableType() == RIDEABLE_VEHICLE ? 0.5f * glm::pi<float>() : 1.0f * glm::pi<float>());
|
||||
}
|
||||
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;
|
||||
|
||||
@ -5,6 +5,11 @@
|
||||
namespace game
|
||||
{
|
||||
|
||||
struct HumanCharacterTuning
|
||||
{
|
||||
std::vector<CharacterConfigClothes> 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;
|
||||
|
||||
52
src/game/input_mapping.hpp
Normal file
52
src/game/input_mapping.hpp
Normal file
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
@ -5,7 +5,7 @@
|
||||
#include <array>
|
||||
#include <iostream>
|
||||
|
||||
game::NpcCharacter::NpcCharacter(World& world, const CharacterTuning& tuning) : Super(world, tuning) {
|
||||
game::NpcCharacter::NpcCharacter(World& world, const HumanCharacterTuning& tuning) : Super(world, tuning) {
|
||||
UpdateVehicleState();
|
||||
}
|
||||
|
||||
|
||||
@ -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;
|
||||
|
||||
|
||||
@ -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<Cow>(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() });
|
||||
|
||||
|
||||
@ -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
|
||||
{
|
||||
|
||||
@ -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;
|
||||
|
||||
|
||||
@ -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_)
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user