Compare commits
No commits in common. "d3848169e859681a3a9bd33f61d8b8b03ed1755c" and "bef976abe652b9521060d035fd822a3e7b337cad" have entirely different histories.
d3848169e8
...
bef976abe6
@ -132,12 +132,10 @@ set(CLIENT_ONLY_SOURCES
|
|||||||
)
|
)
|
||||||
|
|
||||||
set(SERVER_ONLY_SOURCES
|
set(SERVER_ONLY_SOURCES
|
||||||
"src/game/animal.hpp"
|
|
||||||
"src/game/animal.cpp"
|
|
||||||
"src/game/character.hpp"
|
"src/game/character.hpp"
|
||||||
"src/game/character.cpp"
|
"src/game/character.cpp"
|
||||||
"src/game/cow.hpp"
|
"src/game/controllable_character.hpp"
|
||||||
"src/game/cow.cpp"
|
"src/game/controllable_character.cpp"
|
||||||
"src/game/destroyed_object.hpp"
|
"src/game/destroyed_object.hpp"
|
||||||
"src/game/destroyed_object.cpp"
|
"src/game/destroyed_object.cpp"
|
||||||
"src/game/drivable_vehicle.hpp"
|
"src/game/drivable_vehicle.hpp"
|
||||||
@ -148,8 +146,6 @@ set(SERVER_ONLY_SOURCES
|
|||||||
"src/game/entity.cpp"
|
"src/game/entity.cpp"
|
||||||
"src/game/game.hpp"
|
"src/game/game.hpp"
|
||||||
"src/game/game.cpp"
|
"src/game/game.cpp"
|
||||||
"src/game/human_character.hpp"
|
|
||||||
"src/game/human_character.cpp"
|
|
||||||
"src/game/mapinstance.hpp"
|
"src/game/mapinstance.hpp"
|
||||||
"src/game/mapinstance.cpp"
|
"src/game/mapinstance.cpp"
|
||||||
"src/game/marker.hpp"
|
"src/game/marker.hpp"
|
||||||
@ -164,8 +160,6 @@ set(SERVER_ONLY_SOURCES
|
|||||||
"src/game/player.cpp"
|
"src/game/player.cpp"
|
||||||
"src/game/remote_menu.hpp"
|
"src/game/remote_menu.hpp"
|
||||||
"src/game/remote_menu.cpp"
|
"src/game/remote_menu.cpp"
|
||||||
"src/game/rideable.hpp"
|
|
||||||
"src/game/rideable.cpp"
|
|
||||||
"src/game/simple_entity.hpp"
|
"src/game/simple_entity.hpp"
|
||||||
"src/game/simple_entity.cpp"
|
"src/game/simple_entity.cpp"
|
||||||
"src/game/tuning_world.hpp"
|
"src/game/tuning_world.hpp"
|
||||||
|
|||||||
@ -1,66 +0,0 @@
|
|||||||
#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) + ")");
|
|
||||||
}
|
|
||||||
@ -1,31 +0,0 @@
|
|||||||
#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,7 +9,9 @@ game::Character::Character(World& world, const CharacterTuning& tuning)
|
|||||||
{
|
{
|
||||||
z_offset_ = tuning_.shape.height * 0.5f + tuning_.shape.radius - 0.05f;
|
z_offset_ = tuning_.shape.height * 0.5f + tuning_.shape.radius - 0.05f;
|
||||||
|
|
||||||
sk_ = SkeletonInstance(assets::CacheManager::GetSkeleton("data/" + tuning.model_name + ".sk"), &root_);
|
sk_ = SkeletonInstance(assets::CacheManager::GetSkeleton("data/human.sk"), &root_);
|
||||||
|
animstate_.idle_anim_idx = GetAnim("idle");
|
||||||
|
animstate_.walk_anim_idx = GetAnim("walk");
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool Turn(float& angle, float target, float step)
|
static bool Turn(float& angle, float target, float step)
|
||||||
@ -50,9 +52,6 @@ void game::Character::SendInitData(Player& player, net::OutMessage& msg) const
|
|||||||
{
|
{
|
||||||
Super::SendInitData(player, msg);
|
Super::SendInitData(player, msg);
|
||||||
|
|
||||||
// write model name
|
|
||||||
msg.Write(net::ModelName(tuning_.model_name));
|
|
||||||
|
|
||||||
// write clothes
|
// write clothes
|
||||||
msg.Write<net::NumClothes>(tuning_.clothes.size());
|
msg.Write<net::NumClothes>(tuning_.clothes.size());
|
||||||
for (const auto& clothes : tuning_.clothes)
|
for (const auto& clothes : tuning_.clothes)
|
||||||
@ -84,7 +83,7 @@ void game::Character::EnablePhysics(bool enable)
|
|||||||
{
|
{
|
||||||
if (enable && !controller_)
|
if (enable && !controller_)
|
||||||
{
|
{
|
||||||
controller_ = std::make_unique<CharacterPhysicsController>(*this, world_.GetBtWorld(), bt_shape_);
|
controller_ = std::make_unique<CharacterPhysicsController>(world_.GetBtWorld(), bt_shape_);
|
||||||
SyncControllerTransform();
|
SyncControllerTransform();
|
||||||
}
|
}
|
||||||
else if (!enable && controller_)
|
else if (!enable && controller_)
|
||||||
@ -101,27 +100,43 @@ void game::Character::SetInput(CharacterInputType type, bool enable)
|
|||||||
in_ &= ~(1 << type);
|
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)
|
void game::Character::SetPosition(const glm::vec3& position)
|
||||||
{
|
{
|
||||||
root_.local.position = position;
|
root_.local.position = position;
|
||||||
SyncControllerTransform();
|
SyncControllerTransform();
|
||||||
}
|
}
|
||||||
|
|
||||||
void game::Character::SetIdleAnim(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);
|
||||||
}
|
}
|
||||||
|
|
||||||
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()
|
void game::Character::SyncControllerTransform()
|
||||||
{
|
{
|
||||||
if (!controller_)
|
if (!controller_)
|
||||||
@ -285,13 +300,48 @@ game::CharacterSyncFieldFlags game::Character::WriteState(net::OutMessage& msg,
|
|||||||
return fields;
|
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
|
assets::AnimIdx game::Character::GetAnim(const std::string& name) const
|
||||||
{
|
{
|
||||||
return sk_.GetSkeleton()->GetAnimationIdx(name);
|
return sk_.GetSkeleton()->GetAnimationIdx(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
game::CharacterPhysicsController::CharacterPhysicsController(Character& character, btDynamicsWorld& bt_world, btCapsuleShapeZ& bt_shape)
|
game::CharacterPhysicsController::CharacterPhysicsController(btDynamicsWorld& bt_world, btCapsuleShapeZ& bt_shape)
|
||||||
: character_(character), bt_world_(bt_world), bt_character_(&bt_ghost_, &bt_shape, 0.3f, btVector3(0, 0, 1))
|
: bt_world_(bt_world), bt_character_(&bt_ghost_, &bt_shape, 0.3f, btVector3(0, 0, 1))
|
||||||
{
|
{
|
||||||
btTransform start_transform;
|
btTransform start_transform;
|
||||||
start_transform.setIdentity();
|
start_transform.setIdentity();
|
||||||
@ -299,8 +349,6 @@ game::CharacterPhysicsController::CharacterPhysicsController(Character& characte
|
|||||||
bt_ghost_.setCollisionShape(&bt_shape);
|
bt_ghost_.setCollisionShape(&bt_shape);
|
||||||
bt_ghost_.setCollisionFlags(btCollisionObject::CF_CHARACTER_OBJECT);
|
bt_ghost_.setCollisionFlags(btCollisionObject::CF_CHARACTER_OBJECT);
|
||||||
|
|
||||||
collision::SetObjectInfo(&bt_ghost_, collision::OT_ENTITY, 0, &character);
|
|
||||||
|
|
||||||
bt_world_.addCollisionObject(&bt_ghost_, btBroadphaseProxy::CharacterFilter,
|
bt_world_.addCollisionObject(&bt_ghost_, btBroadphaseProxy::CharacterFilter,
|
||||||
btBroadphaseProxy::StaticFilter | btBroadphaseProxy::DefaultFilter);
|
btBroadphaseProxy::StaticFilter | btBroadphaseProxy::DefaultFilter);
|
||||||
// bt_world.addCollisionObject(&bt_ghost_);
|
// bt_world.addCollisionObject(&bt_ghost_);
|
||||||
|
|||||||
@ -23,12 +23,10 @@ enum CharacterInputType
|
|||||||
CIN_SPRINT,
|
CIN_SPRINT,
|
||||||
};
|
};
|
||||||
|
|
||||||
class Character;
|
|
||||||
|
|
||||||
class CharacterPhysicsController
|
class CharacterPhysicsController
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
CharacterPhysicsController(Character& character, btDynamicsWorld& bt_world, btCapsuleShapeZ& bt_shape);
|
CharacterPhysicsController(btDynamicsWorld& bt_world, btCapsuleShapeZ& bt_shape);
|
||||||
DELETE_COPY_MOVE(CharacterPhysicsController)
|
DELETE_COPY_MOVE(CharacterPhysicsController)
|
||||||
|
|
||||||
btKinematicCharacterController& GetBtController() { return bt_character_; }
|
btKinematicCharacterController& GetBtController() { return bt_character_; }
|
||||||
@ -39,7 +37,6 @@ public:
|
|||||||
~CharacterPhysicsController();
|
~CharacterPhysicsController();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Character& character_;
|
|
||||||
btDynamicsWorld& bt_world_;
|
btDynamicsWorld& bt_world_;
|
||||||
btPairCachingGhostObject bt_ghost_;
|
btPairCachingGhostObject bt_ghost_;
|
||||||
btKinematicCharacterController bt_character_;
|
btKinematicCharacterController bt_character_;
|
||||||
@ -60,20 +57,16 @@ public:
|
|||||||
const CharacterTuning& GetTuning() const { return tuning_; }
|
const CharacterTuning& GetTuning() const { return tuning_; }
|
||||||
|
|
||||||
void EnablePhysics(bool enable);
|
void EnablePhysics(bool enable);
|
||||||
CharacterPhysicsController* GetController() { return controller_.get(); }
|
|
||||||
|
|
||||||
void SetInput(CharacterInputType type, bool enable);
|
void SetInput(CharacterInputType type, bool enable);
|
||||||
void SetInputs(CharacterInputFlags inputs) { in_ = inputs; }
|
void SetInputs(CharacterInputFlags inputs) { in_ = inputs; }
|
||||||
|
|
||||||
void SetForwardYaw(float yaw) { forward_yaw_ = yaw; }
|
void SetForwardYaw(float yaw) { forward_yaw_ = yaw; }
|
||||||
float GetForwardYaw() const { return forward_yaw_; }
|
|
||||||
void SetYaw(float yaw) { yaw_ = yaw; }
|
void SetYaw(float yaw) { yaw_ = yaw; }
|
||||||
|
|
||||||
void SetPosition(const glm::vec3& position);
|
void SetPosition(const glm::vec3& position);
|
||||||
|
|
||||||
void SetIdleAnim(const std::string& anim_name);
|
void SetMainAnim(const std::string& anim_name);
|
||||||
void SetWalkAnim(const std::string& anim_name);
|
|
||||||
void SetRunAnim(const std::string& anim_name);
|
|
||||||
|
|
||||||
~Character() override = default;
|
~Character() override = default;
|
||||||
|
|
||||||
@ -86,6 +79,8 @@ private:
|
|||||||
void SendUpdateMsg();
|
void SendUpdateMsg();
|
||||||
CharacterSyncFieldFlags WriteState(net::OutMessage& msg, const CharacterSyncState& base) const;
|
CharacterSyncFieldFlags WriteState(net::OutMessage& msg, const CharacterSyncState& base) const;
|
||||||
|
|
||||||
|
void Move(glm::vec3& velocity, float t);
|
||||||
|
|
||||||
assets::AnimIdx GetAnim(const std::string& name) const;
|
assets::AnimIdx GetAnim(const std::string& name) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|||||||
@ -22,8 +22,7 @@ struct CharacterConfigClothes
|
|||||||
|
|
||||||
struct CharacterTuning
|
struct CharacterTuning
|
||||||
{
|
{
|
||||||
CharacterShape shape = CharacterShape(0.3f, 0.75f);
|
CharacterShape shape = CharacterShape(0.3f, 0.75f);
|
||||||
std::string model_name;
|
|
||||||
std::vector<CharacterConfigClothes> clothes;
|
std::vector<CharacterConfigClothes> clothes;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
54
src/game/controllable_character.cpp
Normal file
54
src/game/controllable_character.cpp
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
#include "controllable_character.hpp"
|
||||||
|
#include "drivable_vehicle.hpp"
|
||||||
|
|
||||||
|
game::ControllableCharacter::ControllableCharacter(World& world, const CharacterTuning& tuning) : Character(world, tuning) {}
|
||||||
|
|
||||||
|
void game::ControllableCharacter::SetVehicle(DrivableVehicle* vehicle, uint32_t seat)
|
||||||
|
{
|
||||||
|
if ((vehicle && vehicle_) || (!vehicle && !vehicle_))
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (vehicle)
|
||||||
|
{
|
||||||
|
if (!vehicle->SetPassenger(seat, this))
|
||||||
|
return;
|
||||||
|
|
||||||
|
auto seat_loc = vehicle->GetModel()->GetLocation("seat" + std::to_string(seat));
|
||||||
|
if (seat_loc)
|
||||||
|
SetPosition(seat_loc->position);
|
||||||
|
|
||||||
|
EnablePhysics(false);
|
||||||
|
Attach(vehicle->GetEntNum());
|
||||||
|
SetMainAnim(seat == 0 ? "vehicle_drive" : "vehicle_passenger");
|
||||||
|
SetYaw(0.5f * glm::pi<float>());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
vehicle_->SetPassenger(seat_idx_, nullptr);
|
||||||
|
|
||||||
|
EnablePhysics(true);
|
||||||
|
|
||||||
|
glm::vec3 seat_loc = vehicle_->GetModel()->GetLocation("seat" + std::to_string(seat_idx_))->position;
|
||||||
|
seat_loc.x += glm::sign(seat_loc.x) * 0.5f; // to the side
|
||||||
|
glm::vec3 pos = vehicle_->GetRoot().matrix * glm::vec4(seat_loc, 1.0f);
|
||||||
|
pos.z += 0.5f;
|
||||||
|
SetPosition(pos);
|
||||||
|
|
||||||
|
Attach(0);
|
||||||
|
SetMainAnim("idle");
|
||||||
|
// SetYaw(0.0f);
|
||||||
|
}
|
||||||
|
|
||||||
|
vehicle_ = vehicle;
|
||||||
|
seat_idx_ = seat;
|
||||||
|
is_driver_ = vehicle && seat == 0;
|
||||||
|
VehicleChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
game::ControllableCharacter::~ControllableCharacter()
|
||||||
|
{
|
||||||
|
if (vehicle_)
|
||||||
|
{
|
||||||
|
vehicle_->SetPassenger(seat_idx_, nullptr);
|
||||||
|
}
|
||||||
|
}
|
||||||
32
src/game/controllable_character.hpp
Normal file
32
src/game/controllable_character.hpp
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "character.hpp"
|
||||||
|
|
||||||
|
namespace game
|
||||||
|
{
|
||||||
|
|
||||||
|
class DrivableVehicle;
|
||||||
|
|
||||||
|
class ControllableCharacter : public Character
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
using Super = Character;
|
||||||
|
|
||||||
|
ControllableCharacter(World& world, const CharacterTuning& tuning);
|
||||||
|
|
||||||
|
void SetVehicle(DrivableVehicle* vehicle, uint32_t seat);
|
||||||
|
|
||||||
|
DrivableVehicle* GetVehicle() const { return vehicle_; }
|
||||||
|
bool IsDriver() const { return is_driver_; }
|
||||||
|
|
||||||
|
~ControllableCharacter() override;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual void VehicleChanged() = 0;
|
||||||
|
|
||||||
|
size_t seat_idx_ = 0;
|
||||||
|
bool is_driver_ = false;
|
||||||
|
DrivableVehicle* vehicle_ = nullptr;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
@ -1,20 +0,0 @@
|
|||||||
#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");
|
|
||||||
}
|
|
||||||
@ -1,20 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include "animal.hpp"
|
|
||||||
|
|
||||||
namespace game
|
|
||||||
{
|
|
||||||
|
|
||||||
class Cow : public Animal
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
Cow(World& world, const glm::vec3& position, float yaw);
|
|
||||||
|
|
||||||
private:
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
@ -1,9 +1,8 @@
|
|||||||
#include "drivable_vehicle.hpp"
|
#include "drivable_vehicle.hpp"
|
||||||
#include "player_character.hpp"
|
#include "player_character.hpp"
|
||||||
#include "utils/random.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)
|
game::DrivableVehicle::DrivableVehicle(World& world, const VehicleTuning& tuning) : Vehicle(world, tuning), Usable(GetRoot().matrix)
|
||||||
{
|
{
|
||||||
InitSeats();
|
InitSeats();
|
||||||
OnPhysicsChanged();
|
OnPhysicsChanged();
|
||||||
@ -12,7 +11,7 @@ game::DrivableVehicle::DrivableVehicle(World& world, const VehicleTuning& tuning
|
|||||||
void game::DrivableVehicle::Update()
|
void game::DrivableVehicle::Update()
|
||||||
{
|
{
|
||||||
float daytime = world_.GetDayTime();
|
float daytime = world_.GetDayTime();
|
||||||
SetLightsOn(GetPassenger(0) && (daytime < 6.0f || daytime > 18.0f));
|
SetLightsOn(seats_[0].occupant && (daytime < 6.0f || daytime > 18.0f));
|
||||||
|
|
||||||
Super::Update();
|
Super::Update();
|
||||||
|
|
||||||
@ -32,13 +31,13 @@ void game::DrivableVehicle::OnPhysicsChanged()
|
|||||||
|
|
||||||
bool game::DrivableVehicle::QueryUseTarget(PlayerCharacter& character, uint32_t target_id, UseTargetQueryResult& res)
|
bool game::DrivableVehicle::QueryUseTarget(PlayerCharacter& character, uint32_t target_id, UseTargetQueryResult& res)
|
||||||
{
|
{
|
||||||
if (character.GetRideable())
|
if (character.GetVehicle())
|
||||||
return false; // already in something
|
return false; // already in vehicle
|
||||||
|
|
||||||
res.enabled = true;
|
res.enabled = true;
|
||||||
res.error_text = nullptr;
|
res.error_text = nullptr;
|
||||||
|
|
||||||
bool seat_occupied = GetPassenger(target_id) != nullptr;
|
bool seat_occupied = seats_[target_id].occupant != nullptr;
|
||||||
res.delay = seat_occupied ? 2.0f : 0.25f;
|
res.delay = seat_occupied ? 2.0f : 0.25f;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@ -46,25 +45,52 @@ bool game::DrivableVehicle::QueryUseTarget(PlayerCharacter& character, uint32_t
|
|||||||
|
|
||||||
void game::DrivableVehicle::Use(PlayerCharacter& character, uint32_t target_id)
|
void game::DrivableVehicle::Use(PlayerCharacter& character, uint32_t target_id)
|
||||||
{
|
{
|
||||||
if (target_id >= GetNumSeats())
|
if (target_id >= seats_.size())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
character.Ride(this, target_id);
|
character.SetVehicle(this, target_id); // seat idx is same as target_id
|
||||||
PlaySound("cardoor", 1.0f, RandomFloat(0.9f, 1.1f));
|
PlaySound("cardoor", 1.0f, RandomFloat(0.9f, 1.1f));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool game::DrivableVehicle::SetPassenger(uint32_t seat_idx, ControllableCharacter* character)
|
||||||
void game::DrivableVehicle::SetRideableInput(PlayerInputFlags in)
|
|
||||||
{
|
{
|
||||||
SetInputs(MapPlayerInputToVehicleInput(in));
|
if (seat_idx >= seats_.size())
|
||||||
}
|
return false;
|
||||||
|
|
||||||
void game::DrivableVehicle::OnPassengerChanged(size_t seat_idx, HumanCharacter* passenger)
|
auto& seat_info = seats_[seat_idx];
|
||||||
{
|
|
||||||
if (seat_idx == 0 && !passenger)
|
if (seat_info.occupant == character)
|
||||||
|
return true; // already sitting here
|
||||||
|
|
||||||
|
if (seat_info.occupant && character)
|
||||||
{
|
{
|
||||||
// driver left
|
seat_info.occupant->SetVehicle(nullptr, 0); // remove current occupant
|
||||||
SetInputs(0);
|
}
|
||||||
|
|
||||||
|
seat_info.occupant = character;
|
||||||
|
|
||||||
|
if (seat_idx == 0)
|
||||||
|
{
|
||||||
|
if (!character)
|
||||||
|
{
|
||||||
|
// clear inputs
|
||||||
|
SetInputs(0);
|
||||||
|
SetSteering(false, 0.0f);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
game::DrivableVehicle::~DrivableVehicle()
|
||||||
|
{
|
||||||
|
// remove occupants
|
||||||
|
for (auto& seat : seats_)
|
||||||
|
{
|
||||||
|
if (seat.occupant)
|
||||||
|
seat.occupant->SetVehicle(nullptr, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -94,11 +120,13 @@ void game::DrivableVehicle::InitSeats()
|
|||||||
if (!trans)
|
if (!trans)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
auto position = trans->position;
|
VehicleSeat seat{};
|
||||||
size_t seat_idx = AddSeat(position);
|
seat.position = trans->position;
|
||||||
|
seat.position.z += 1.0f; // the original pos is for animated character which is under vehicle
|
||||||
|
seats_.emplace_back(seat);
|
||||||
|
|
||||||
position.z += 1.0f; // the original pos is for animated character which is under vehicle
|
uint32_t id = seats_.size() - 1;
|
||||||
use_targets_.emplace_back(this, static_cast<uint32_t>(seat_idx), position, std::string());
|
use_targets_.emplace_back(this, id, seat.position, std::string());
|
||||||
}
|
}
|
||||||
|
|
||||||
UpdateUseTargetNames();
|
UpdateUseTargetNames();
|
||||||
|
|||||||
@ -2,13 +2,18 @@
|
|||||||
|
|
||||||
#include "vehicle.hpp"
|
#include "vehicle.hpp"
|
||||||
#include "usable.hpp"
|
#include "usable.hpp"
|
||||||
#include "rideable.hpp"
|
#include "controllable_character.hpp"
|
||||||
#include "human_character.hpp"
|
|
||||||
|
|
||||||
namespace game
|
namespace game
|
||||||
{
|
{
|
||||||
|
|
||||||
class DrivableVehicle : public Vehicle, public Usable, public Rideable
|
struct VehicleSeat
|
||||||
|
{
|
||||||
|
glm::vec3 position;
|
||||||
|
ControllableCharacter* occupant;
|
||||||
|
};
|
||||||
|
|
||||||
|
class DrivableVehicle : public Vehicle, public Usable
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
using Super = Vehicle;
|
using Super = Vehicle;
|
||||||
@ -24,15 +29,19 @@ public:
|
|||||||
virtual bool QueryUseTarget(PlayerCharacter& character, uint32_t target_id, UseTargetQueryResult& res) override;
|
virtual bool QueryUseTarget(PlayerCharacter& character, uint32_t target_id, UseTargetQueryResult& res) override;
|
||||||
virtual void Use(PlayerCharacter& character, uint32_t target_id) override;
|
virtual void Use(PlayerCharacter& character, uint32_t target_id) override;
|
||||||
|
|
||||||
virtual void SetRideableInput(PlayerInputFlags in) override;
|
bool SetPassenger(uint32_t seat_idx, ControllableCharacter* character);
|
||||||
|
|
||||||
protected:
|
size_t GetNumSeats() const { return seats_.size(); }
|
||||||
virtual void OnPassengerChanged(size_t seat_idx, HumanCharacter* passenger) override;
|
ControllableCharacter* GetPassenger(size_t idx) const { return seats_[idx].occupant; }
|
||||||
|
|
||||||
|
~DrivableVehicle() override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void InitSeats();
|
void InitSeats();
|
||||||
void UpdateUseTargetNames();
|
void UpdateUseTargetNames();
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::vector<VehicleSeat> seats_;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -5,7 +5,7 @@
|
|||||||
|
|
||||||
game::EnterableWorld::EnterableWorld(std::string mapname) : World(std::move(mapname)) {}
|
game::EnterableWorld::EnterableWorld(std::string mapname) : World(std::move(mapname)) {}
|
||||||
|
|
||||||
game::PlayerCharacter& game::EnterableWorld::InsertPlayer(Player& player, const HumanCharacterTuning& tuning, const glm::vec3& pos, float yaw)
|
game::PlayerCharacter& game::EnterableWorld::InsertPlayer(Player& player, const CharacterTuning& tuning, const glm::vec3& pos, float yaw)
|
||||||
{
|
{
|
||||||
return CreatePlayerCharacter(player, tuning, pos, yaw);
|
return CreatePlayerCharacter(player, tuning, pos, yaw);
|
||||||
}
|
}
|
||||||
@ -23,8 +23,8 @@ void game::EnterableWorld::PlayerInput(Player& player, PlayerInputType type, boo
|
|||||||
// case IN_DEBUG1:
|
// case IN_DEBUG1:
|
||||||
// if (enabled)
|
// if (enabled)
|
||||||
// {
|
// {
|
||||||
// if (character->GetVehicleOld())
|
// if (character->GetVehicle())
|
||||||
// character->GetVehicleOld()->SetPosition({100.0f, 100.0f, 5.0f});
|
// character->GetVehicle()->SetPosition({100.0f, 100.0f, 5.0f});
|
||||||
// else
|
// else
|
||||||
// character->SetPosition({100.0f, 100.0f, 5.0f});
|
// character->SetPosition({100.0f, 100.0f, 5.0f});
|
||||||
// }
|
// }
|
||||||
@ -62,7 +62,7 @@ game::PlayerCharacter* game::EnterableWorld::GetPlayerCharacter(Player& player)
|
|||||||
return it->second;
|
return it->second;
|
||||||
}
|
}
|
||||||
|
|
||||||
game::PlayerCharacter& game::EnterableWorld::CreatePlayerCharacter(Player& player, const HumanCharacterTuning& tuning, const glm::vec3& position, float yaw)
|
game::PlayerCharacter& game::EnterableWorld::CreatePlayerCharacter(Player& player, const CharacterTuning& tuning, const glm::vec3& position, float yaw)
|
||||||
{
|
{
|
||||||
RemovePlayerCharacter(player);
|
RemovePlayerCharacter(player);
|
||||||
|
|
||||||
|
|||||||
@ -7,7 +7,7 @@ namespace game
|
|||||||
|
|
||||||
class Player;
|
class Player;
|
||||||
class PlayerCharacter;
|
class PlayerCharacter;
|
||||||
class HumanCharacterTuning;
|
class CharacterTuning;
|
||||||
class DrivableVehicle;
|
class DrivableVehicle;
|
||||||
|
|
||||||
class EnterableWorld : public World
|
class EnterableWorld : public World
|
||||||
@ -16,7 +16,7 @@ public:
|
|||||||
EnterableWorld(std::string mapname);
|
EnterableWorld(std::string mapname);
|
||||||
|
|
||||||
// events
|
// events
|
||||||
virtual PlayerCharacter& InsertPlayer(Player& player, const HumanCharacterTuning& tuning, const glm::vec3& pos, float yaw);
|
virtual PlayerCharacter& InsertPlayer(Player& player, const CharacterTuning& tuning, const glm::vec3& pos, float yaw);
|
||||||
virtual void PlayerInput(Player& player, PlayerInputType type, bool enabled);
|
virtual void PlayerInput(Player& player, PlayerInputType type, bool enabled);
|
||||||
virtual void PlayerViewAnglesChanged(Player& player, float yaw, float pitch);
|
virtual void PlayerViewAnglesChanged(Player& player, float yaw, float pitch);
|
||||||
virtual void RemovePlayer(Player& player);
|
virtual void RemovePlayer(Player& player);
|
||||||
@ -28,7 +28,7 @@ public:
|
|||||||
PlayerCharacter* GetPlayerCharacter(Player& player);
|
PlayerCharacter* GetPlayerCharacter(Player& player);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
PlayerCharacter& CreatePlayerCharacter(Player& player, const HumanCharacterTuning& tuning, const glm::vec3& position, float yaw);
|
PlayerCharacter& CreatePlayerCharacter(Player& player, const CharacterTuning& tuning, const glm::vec3& position, float yaw);
|
||||||
void RemovePlayerCharacter(Player& player);
|
void RemovePlayerCharacter(Player& player);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|||||||
@ -52,7 +52,7 @@ void game::Game::PlayerJoined(Player& player)
|
|||||||
player_info.world = openworld_.get();
|
player_info.world = openworld_.get();
|
||||||
player.SetWorld(openworld_.get());
|
player.SetWorld(openworld_.get());
|
||||||
|
|
||||||
HumanCharacterTuning tuning{};
|
CharacterTuning tuning{};
|
||||||
tuning.clothes.push_back({"tshirt", GetRandomColor24()});
|
tuning.clothes.push_back({"tshirt", GetRandomColor24()});
|
||||||
tuning.clothes.push_back({"shorts", 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_world = *player_info.world;
|
||||||
|
|
||||||
auto old_character = old_world.GetPlayerCharacter(player);
|
auto old_character = old_world.GetPlayerCharacter(player);
|
||||||
auto& tuning = old_character->GetHumanTuning();
|
auto& tuning = old_character->GetTuning();
|
||||||
old_world.RemovePlayer(player);
|
old_world.RemovePlayer(player);
|
||||||
|
|
||||||
player.SetWorld(&new_world);
|
player.SetWorld(&new_world);
|
||||||
@ -180,7 +180,7 @@ void game::Game::MoveVehicleToWorld(DrivableVehicle& vehicle, EnterableWorld& ne
|
|||||||
auto& player_info = GetPlayerInfo(*player);
|
auto& player_info = GetPlayerInfo(*player);
|
||||||
|
|
||||||
auto& new_character = MovePlayerToWorld(player_info, new_world, glm::vec3(0.0f), 0.0f);
|
auto& new_character = MovePlayerToWorld(player_info, new_world, glm::vec3(0.0f), 0.0f);
|
||||||
new_character.Ride(&new_vehicle, i);
|
new_character.SetVehicle(&new_vehicle, i);
|
||||||
}
|
}
|
||||||
|
|
||||||
vehicle.Remove();
|
vehicle.Remove();
|
||||||
|
|||||||
@ -1,74 +0,0 @@
|
|||||||
#include "human_character.hpp"
|
|
||||||
#include "drivable_vehicle.hpp"
|
|
||||||
|
|
||||||
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)
|
|
||||||
{
|
|
||||||
if (rideable == rideable_ && seat_idx == seat_idx_)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (rideable)
|
|
||||||
{
|
|
||||||
SetPosition(rideable->GetSeatOffset(seat_idx));
|
|
||||||
EnablePhysics(false);
|
|
||||||
|
|
||||||
Attach(rideable->GetEntity().GetEntNum());
|
|
||||||
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
|
|
||||||
{
|
|
||||||
EnablePhysics(true);
|
|
||||||
|
|
||||||
glm::vec3 seat_loc = rideable_->GetSeatOffset(seat_idx_);
|
|
||||||
seat_loc.x += glm::sign(seat_loc.x) * 0.5f; // to the side
|
|
||||||
|
|
||||||
glm::vec3 pos = rideable_->GetEntity().GetRoot().matrix * glm::vec4(seat_loc, 1.0f);
|
|
||||||
pos.z += 0.5f;
|
|
||||||
SetPosition(pos);
|
|
||||||
|
|
||||||
Attach(0);
|
|
||||||
SetIdleAnim("idle");
|
|
||||||
}
|
|
||||||
|
|
||||||
rideable_ = rideable;
|
|
||||||
vehicle_ = dynamic_cast<DrivableVehicle*>(rideable);
|
|
||||||
seat_idx_ = seat_idx;
|
|
||||||
is_driver_ = rideable && seat_idx_ == 0;
|
|
||||||
|
|
||||||
OnRideableChanged();
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void game::HumanCharacter::Ride(Rideable* rideable, size_t seat_idx)
|
|
||||||
{
|
|
||||||
if (rideable_)
|
|
||||||
{
|
|
||||||
rideable_->SetPassenger(seat_idx_, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (rideable)
|
|
||||||
{
|
|
||||||
rideable->SetPassenger(seat_idx, this);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
game::HumanCharacter::~HumanCharacter()
|
|
||||||
{
|
|
||||||
Ride(nullptr, 0); // exit rideable
|
|
||||||
}
|
|
||||||
@ -1,48 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include "character.hpp"
|
|
||||||
|
|
||||||
namespace game
|
|
||||||
{
|
|
||||||
|
|
||||||
struct HumanCharacterTuning
|
|
||||||
{
|
|
||||||
std::vector<CharacterConfigClothes> clothes;
|
|
||||||
};
|
|
||||||
|
|
||||||
class Rideable;
|
|
||||||
class DrivableVehicle;
|
|
||||||
|
|
||||||
class HumanCharacter : public Character
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
using Super = Character;
|
|
||||||
|
|
||||||
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);
|
|
||||||
|
|
||||||
Rideable* GetRideable() const { return rideable_; }
|
|
||||||
DrivableVehicle* GetVehicle() const { return vehicle_; }
|
|
||||||
|
|
||||||
size_t GeatSeatIdx() const { return seat_idx_; }
|
|
||||||
bool IsDriver() const { return is_driver_; }
|
|
||||||
|
|
||||||
virtual ~HumanCharacter() override;
|
|
||||||
|
|
||||||
protected:
|
|
||||||
virtual void OnRideableChanged() {}
|
|
||||||
|
|
||||||
private:
|
|
||||||
HumanCharacterTuning human_tuning_;
|
|
||||||
|
|
||||||
Rideable* rideable_ = nullptr;
|
|
||||||
DrivableVehicle* vehicle_ = nullptr;
|
|
||||||
size_t seat_idx_ = 0;
|
|
||||||
bool is_driver_ = false;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
@ -1,52 +0,0 @@
|
|||||||
#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,24 +5,11 @@
|
|||||||
#include <array>
|
#include <array>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
game::NpcCharacter::NpcCharacter(World& world, const HumanCharacterTuning& tuning) : Super(world, tuning) {
|
game::NpcCharacter::NpcCharacter(World& world, const CharacterTuning& tuning) : Super(world, tuning) {
|
||||||
UpdateVehicleState();
|
VehicleChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
void game::NpcCharacter::Update()
|
void game::NpcCharacter::VehicleChanged()
|
||||||
{
|
|
||||||
Super::Update();
|
|
||||||
|
|
||||||
if (GetVehicle() && IsDriver())
|
|
||||||
VehicleThink();
|
|
||||||
}
|
|
||||||
|
|
||||||
void game::NpcCharacter::OnRideableChanged()
|
|
||||||
{
|
|
||||||
UpdateVehicleState();
|
|
||||||
}
|
|
||||||
|
|
||||||
void game::NpcCharacter::UpdateVehicleState()
|
|
||||||
{
|
{
|
||||||
roads_ = nullptr;
|
roads_ = nullptr;
|
||||||
path_.clear();
|
path_.clear();
|
||||||
@ -98,11 +85,9 @@ static float GetTurnAngle(const glm::vec3& pos, const glm::quat& rot, const glm:
|
|||||||
|
|
||||||
void game::NpcCharacter::VehicleThink()
|
void game::NpcCharacter::VehicleThink()
|
||||||
{
|
{
|
||||||
if (!roads_)
|
if (!IsDriver() || !GetVehicle() || !roads_)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
auto vehicle = GetVehicle();
|
|
||||||
|
|
||||||
if (vehicle_state_ == NVT_REVERSING)
|
if (vehicle_state_ == NVT_REVERSING)
|
||||||
{
|
{
|
||||||
if (reversing_frames_ > 0)
|
if (reversing_frames_ > 0)
|
||||||
@ -113,13 +98,13 @@ void game::NpcCharacter::VehicleThink()
|
|||||||
{
|
{
|
||||||
vehicle_state_ = NVT_NORMAL;
|
vehicle_state_ = NVT_NORMAL;
|
||||||
stuck_counter_ = 0;
|
stuck_counter_ = 0;
|
||||||
vehicle->SetInput(game::VIN_BACKWARD, false);
|
vehicle_->SetInput(game::VIN_BACKWARD, false);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const auto& vehicle_trans = vehicle->GetRootTransform();
|
const auto& vehicle_trans = GetVehicle()->GetRootTransform();
|
||||||
|
|
||||||
const glm::vec3& pos = vehicle_trans.position;
|
const glm::vec3& pos = vehicle_trans.position;
|
||||||
const glm::quat& rot = vehicle_trans.rotation;
|
const glm::quat& rot = vehicle_trans.rotation;
|
||||||
@ -235,13 +220,13 @@ void game::NpcCharacter::VehicleThink()
|
|||||||
// BotThink(s);
|
// BotThink(s);
|
||||||
//});
|
//});
|
||||||
|
|
||||||
vehicle->SetSteering(true, -angle); // try turn away while reversing
|
vehicle_->SetSteering(true, -angle); // try turn away while reversing
|
||||||
vehicle->SetInputs(0); // stop
|
vehicle_->SetInputs(0); // stop
|
||||||
vehicle->SetInput(game::VIN_BACKWARD, true);
|
vehicle_->SetInput(game::VIN_BACKWARD, true);
|
||||||
vehicle_state_ = NVT_REVERSING;
|
vehicle_state_ = NVT_REVERSING;
|
||||||
reversing_frames_ = 50; // reverse for 50 frames
|
reversing_frames_ = 50; // reverse for 50 frames
|
||||||
|
|
||||||
// GetVehicleOld()->SetInputs(0); // stop
|
// GetVehicle()->SetInputs(0); // stop
|
||||||
// is_driver_ = false; // TODO: fix
|
// is_driver_ = false; // TODO: fix
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -252,11 +237,11 @@ void game::NpcCharacter::VehicleThink()
|
|||||||
last_pos_ = pos;
|
last_pos_ = pos;
|
||||||
}
|
}
|
||||||
|
|
||||||
vehicle->SetSteering(true, angle);
|
GetVehicle()->SetSteering(true, angle);
|
||||||
|
|
||||||
game::VehicleInputFlags vin = 0;
|
game::VehicleInputFlags vin = 0;
|
||||||
|
|
||||||
float speed = vehicle->GetSpeed();
|
float speed = GetVehicle()->GetSpeed();
|
||||||
|
|
||||||
// if (glm::distance(pos, target) < 10.0f)
|
// if (glm::distance(pos, target) < 10.0f)
|
||||||
// {
|
// {
|
||||||
@ -282,5 +267,5 @@ void game::NpcCharacter::VehicleThink()
|
|||||||
vin |= 1 << game::VIN_BACKWARD;
|
vin |= 1 << game::VIN_BACKWARD;
|
||||||
}
|
}
|
||||||
|
|
||||||
vehicle->SetInputs(vin);
|
GetVehicle()->SetInputs(vin);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "assets/map.hpp"
|
#include "assets/map.hpp"
|
||||||
#include "human_character.hpp"
|
#include "controllable_character.hpp"
|
||||||
|
|
||||||
namespace game
|
namespace game
|
||||||
{
|
{
|
||||||
@ -14,20 +14,24 @@ enum NpcVehicleThinkState
|
|||||||
NVT_REVERSING,
|
NVT_REVERSING,
|
||||||
};
|
};
|
||||||
|
|
||||||
class NpcCharacter : public HumanCharacter
|
class NpcCharacter : public ControllableCharacter
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
using Super = HumanCharacter;
|
using Super = ControllableCharacter;
|
||||||
|
|
||||||
NpcCharacter(World& world, const HumanCharacterTuning& tuning);
|
NpcCharacter(World& world, const CharacterTuning& tuning);
|
||||||
|
|
||||||
virtual void Update() override;
|
virtual void VehicleChanged() override;
|
||||||
|
|
||||||
protected:
|
|
||||||
virtual void OnRideableChanged() override;
|
virtual void Update() override
|
||||||
|
{
|
||||||
|
Super::Update();
|
||||||
|
|
||||||
|
VehicleThink();
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void UpdateVehicleState();
|
|
||||||
void SelectNextNode();
|
void SelectNextNode();
|
||||||
void VehicleThink();
|
void VehicleThink();
|
||||||
|
|
||||||
|
|||||||
@ -11,7 +11,6 @@
|
|||||||
#include "marker.hpp"
|
#include "marker.hpp"
|
||||||
#include "tuning_world.hpp"
|
#include "tuning_world.hpp"
|
||||||
#include "game.hpp"
|
#include "game.hpp"
|
||||||
#include "cow.hpp"
|
|
||||||
|
|
||||||
namespace game
|
namespace game
|
||||||
{
|
{
|
||||||
@ -88,9 +87,6 @@ game::OpenWorld::OpenWorld(Game& game) : EnterableWorld("openworld"), game_(game
|
|||||||
CreateTuningGarage(loc.transform.position, glm::eulerAngles(loc.transform.rotation).x);
|
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)
|
void game::OpenWorld::Update(int64_t delta_time)
|
||||||
@ -173,12 +169,12 @@ 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});
|
||||||
|
|
||||||
HumanCharacterTuning npc_tuning;
|
CharacterTuning npc_tuning;
|
||||||
npc_tuning.clothes.push_back({ "tshirt", GetRandomColor24() });
|
npc_tuning.clothes.push_back({ "tshirt", GetRandomColor24() });
|
||||||
npc_tuning.clothes.push_back({ "shorts", GetRandomColor24() });
|
npc_tuning.clothes.push_back({ "shorts", GetRandomColor24() });
|
||||||
|
|
||||||
auto& driver = Spawn<NpcCharacter>(npc_tuning);
|
auto& driver = Spawn<NpcCharacter>(npc_tuning);
|
||||||
driver.Ride(&vehicle, 0);
|
driver.SetVehicle(&vehicle, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void game::OpenWorld::CreateTuningGarage(const glm::vec3& position, float yaw)
|
void game::OpenWorld::CreateTuningGarage(const glm::vec3& position, float yaw)
|
||||||
|
|||||||
@ -1,12 +1,13 @@
|
|||||||
#include "player_character.hpp"
|
#include "player_character.hpp"
|
||||||
#include "world.hpp"
|
#include "world.hpp"
|
||||||
#include "input_mapping.hpp"
|
|
||||||
|
|
||||||
game::PlayerCharacter::PlayerCharacter(World& world, Player& player, const HumanCharacterTuning& tuning) : Super(world, tuning), player_(&player)
|
game::PlayerCharacter::PlayerCharacter(World& world, Player& player, const CharacterTuning& tuning) : Super(world, tuning), player_(&player)
|
||||||
{
|
{
|
||||||
EnablePhysics(true);
|
EnablePhysics(true);
|
||||||
UpdatePlayerCamera();
|
VehicleChanged();
|
||||||
|
|
||||||
SetNametag(player.GetName());
|
SetNametag(player.GetName());
|
||||||
|
|
||||||
SendUseTargetInfo();
|
SendUseTargetInfo();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -14,11 +15,23 @@ void game::PlayerCharacter::Update()
|
|||||||
{
|
{
|
||||||
UpdateUseTarget();
|
UpdateUseTarget();
|
||||||
Super::Update();
|
Super::Update();
|
||||||
|
}
|
||||||
|
|
||||||
if (GetRideable() && IsDriver())
|
void game::PlayerCharacter::VehicleChanged()
|
||||||
|
{
|
||||||
|
if (!player_)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (vehicle_)
|
||||||
{
|
{
|
||||||
GetRideable()->SetRideableYaw(GetForwardYaw());
|
player_->SetCamera(vehicle_->GetEntNum());
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
player_->SetCamera(GetEntNum());
|
||||||
|
}
|
||||||
|
|
||||||
|
UpdateInputs();
|
||||||
}
|
}
|
||||||
|
|
||||||
void game::PlayerCharacter::ProcessInput(PlayerInputType type, bool enabled)
|
void game::PlayerCharacter::ProcessInput(PlayerInputType type, bool enabled)
|
||||||
@ -40,43 +53,58 @@ void game::PlayerCharacter::DetachFromPlayer()
|
|||||||
player_ = nullptr;
|
player_ = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void game::PlayerCharacter::OnRideableChanged()
|
|
||||||
{
|
|
||||||
UpdatePlayerCamera();
|
|
||||||
UpdateInputs();
|
|
||||||
}
|
|
||||||
|
|
||||||
void game::PlayerCharacter::UpdatePlayerCamera()
|
|
||||||
{
|
|
||||||
if (!player_)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (auto rideable = GetRideable(); rideable)
|
|
||||||
{
|
|
||||||
player_->SetCamera(rideable->GetEntity().GetEntNum());
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
player_->SetCamera(GetEntNum());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void game::PlayerCharacter::UpdateInputs()
|
void game::PlayerCharacter::UpdateInputs()
|
||||||
{
|
{
|
||||||
auto in = player_ ? player_->GetInput() : 0;
|
auto in = player_ ? player_->GetInput() : 0;
|
||||||
|
CharacterInputFlags c_in = 0;
|
||||||
|
VehicleInputFlags v_in = 0;
|
||||||
|
|
||||||
if (auto rideable = GetRideable(); rideable)
|
if (in & (1 << IN_FORWARD))
|
||||||
|
{
|
||||||
|
c_in |= 1 << CIN_FORWARD;
|
||||||
|
v_in |= 1 << VIN_FORWARD;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (in & (1 << IN_BACKWARD))
|
||||||
|
{
|
||||||
|
c_in |= 1 << CIN_BACKWARD;
|
||||||
|
v_in |= 1 << VIN_BACKWARD;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (in & (1 << IN_LEFT))
|
||||||
|
{
|
||||||
|
c_in |= 1 << CIN_LEFT;
|
||||||
|
v_in |= 1 << VIN_LEFT;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (in & (1 << IN_RIGHT))
|
||||||
|
{
|
||||||
|
c_in |= 1 << CIN_RIGHT;
|
||||||
|
v_in |= 1 << VIN_RIGHT;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (in & (1 << IN_JUMP))
|
||||||
|
{
|
||||||
|
c_in |= 1 << CIN_JUMP;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (in & (1 << IN_SPRINT))
|
||||||
|
{
|
||||||
|
c_in |= 1 << CIN_SPRINT;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (vehicle_)
|
||||||
{
|
{
|
||||||
SetInputs(0);
|
SetInputs(0);
|
||||||
|
|
||||||
if (IsDriver())
|
if (is_driver_)
|
||||||
{
|
{
|
||||||
rideable->SetRideableInput(in);
|
vehicle_->SetInputs(v_in);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
SetInputs(MapPlayerInputToCharacterInput(in));
|
SetInputs(c_in);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -114,9 +142,8 @@ void game::PlayerCharacter::UseChanged(bool enabled)
|
|||||||
{
|
{
|
||||||
if (!use_target_)
|
if (!use_target_)
|
||||||
{
|
{
|
||||||
// exit rideable if not target
|
if (vehicle_ && enabled)
|
||||||
if (enabled && GetRideable())
|
SetVehicle(nullptr, 0);// no use target and in vehicle -> exit
|
||||||
Ride(nullptr, 0);
|
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
#include "human_character.hpp"
|
#include "controllable_character.hpp"
|
||||||
|
|
||||||
#include "drivable_vehicle.hpp"
|
#include "drivable_vehicle.hpp"
|
||||||
#include "player.hpp"
|
#include "player.hpp"
|
||||||
@ -7,26 +7,24 @@
|
|||||||
namespace game
|
namespace game
|
||||||
{
|
{
|
||||||
|
|
||||||
class PlayerCharacter : public HumanCharacter
|
class PlayerCharacter : public ControllableCharacter
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
using Super = HumanCharacter;
|
using Super = ControllableCharacter;
|
||||||
|
|
||||||
PlayerCharacter(World& world, Player& player, const HumanCharacterTuning& tuning);
|
PlayerCharacter(World& world, Player& player, const CharacterTuning& tuning);
|
||||||
|
|
||||||
virtual void Update() override;
|
virtual void Update() override;
|
||||||
|
|
||||||
|
virtual void VehicleChanged() override;
|
||||||
|
|
||||||
void ProcessInput(PlayerInputType type, bool enabled);
|
void ProcessInput(PlayerInputType type, bool enabled);
|
||||||
|
|
||||||
void DetachFromPlayer();
|
void DetachFromPlayer();
|
||||||
|
|
||||||
Player* GetPlayer() const { return player_; }
|
Player* GetPlayer() const { return player_; }
|
||||||
|
|
||||||
protected:
|
|
||||||
virtual void OnRideableChanged() override;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void UpdatePlayerCamera();
|
|
||||||
void UpdateInputs();
|
void UpdateInputs();
|
||||||
|
|
||||||
void UpdateUseTarget();
|
void UpdateUseTarget();
|
||||||
|
|||||||
@ -1,69 +0,0 @@
|
|||||||
#include "rideable.hpp"
|
|
||||||
|
|
||||||
#include <stdexcept>
|
|
||||||
|
|
||||||
game::Rideable::Rideable(Entity& entity, RideableType type) : entity_(entity), type_(type) {}
|
|
||||||
|
|
||||||
void game::Rideable::SetPassenger(size_t seat_idx, HumanCharacter* passenger)
|
|
||||||
{
|
|
||||||
if (seat_idx >= seats_.size())
|
|
||||||
throw std::runtime_error("Invalid seat index");
|
|
||||||
|
|
||||||
auto& seat = seats_[seat_idx];
|
|
||||||
|
|
||||||
if (seat.passenger == passenger)
|
|
||||||
return; // already sitting here
|
|
||||||
|
|
||||||
if (seat.passenger)
|
|
||||||
{
|
|
||||||
seat.passenger->SetRideable(nullptr, 0); // remove current passenger
|
|
||||||
}
|
|
||||||
|
|
||||||
seat.passenger = passenger;
|
|
||||||
|
|
||||||
if (passenger)
|
|
||||||
{
|
|
||||||
passenger->SetRideable(this, seat_idx);
|
|
||||||
}
|
|
||||||
|
|
||||||
OnPassengerChanged(seat_idx, passenger);
|
|
||||||
}
|
|
||||||
|
|
||||||
game::HumanCharacter* game::Rideable::GetPassenger(size_t seat_idx)
|
|
||||||
{
|
|
||||||
if (seat_idx >= seats_.size())
|
|
||||||
return nullptr;
|
|
||||||
|
|
||||||
return seats_[seat_idx].passenger;
|
|
||||||
}
|
|
||||||
|
|
||||||
const glm::vec3& game::Rideable::GetSeatOffset(size_t seat_idx)
|
|
||||||
{
|
|
||||||
if (seat_idx >= seats_.size())
|
|
||||||
throw std::runtime_error("Invalid seat index");
|
|
||||||
|
|
||||||
return seats_[seat_idx].offset;
|
|
||||||
}
|
|
||||||
|
|
||||||
void game::Rideable::KickAll()
|
|
||||||
{
|
|
||||||
for (size_t i = 0; i < seats_.size(); ++i)
|
|
||||||
{
|
|
||||||
if (seats_[i].passenger)
|
|
||||||
SetPassenger(i, nullptr);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
game::Rideable::~Rideable()
|
|
||||||
{
|
|
||||||
// kick passengers
|
|
||||||
KickAll();
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t game::Rideable::AddSeat(const glm::vec3& offset)
|
|
||||||
{
|
|
||||||
RideableSeat seat{};
|
|
||||||
seat.offset = offset;
|
|
||||||
seats_.emplace_back(seat);
|
|
||||||
return seats_.size() - 1;
|
|
||||||
}
|
|
||||||
@ -1,54 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include "human_character.hpp"
|
|
||||||
#include "player_input.hpp"
|
|
||||||
|
|
||||||
namespace game
|
|
||||||
{
|
|
||||||
|
|
||||||
enum RideableType
|
|
||||||
{
|
|
||||||
RIDEABLE_NONE,
|
|
||||||
RIDEABLE_VEHICLE,
|
|
||||||
RIDEABLE_ANIMAL,
|
|
||||||
};
|
|
||||||
|
|
||||||
struct RideableSeat
|
|
||||||
{
|
|
||||||
glm::vec3 offset;
|
|
||||||
HumanCharacter* passenger;
|
|
||||||
};
|
|
||||||
|
|
||||||
class Rideable
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
Rideable(Entity& entity, RideableType type);
|
|
||||||
|
|
||||||
void SetPassenger(size_t seat_idx, HumanCharacter* passenger);
|
|
||||||
HumanCharacter* GetPassenger(size_t seat_idx);
|
|
||||||
const glm::vec3& GetSeatOffset(size_t seat_idx);
|
|
||||||
size_t GetNumSeats() const { return seats_.size(); }
|
|
||||||
void KickAll();
|
|
||||||
|
|
||||||
virtual void SetRideableInput(PlayerInputFlags in) {}
|
|
||||||
virtual void SetRideableYaw(float yaw) {}
|
|
||||||
|
|
||||||
RideableType GetRideableType() const { return type_; }
|
|
||||||
|
|
||||||
Entity& GetEntity() { return entity_; }
|
|
||||||
const Entity& GetEntity() const { return entity_; }
|
|
||||||
|
|
||||||
virtual ~Rideable();
|
|
||||||
|
|
||||||
protected:
|
|
||||||
size_t AddSeat(const glm::vec3& offset);
|
|
||||||
virtual void OnPassengerChanged(size_t seat_idx, HumanCharacter* passenger) {}
|
|
||||||
|
|
||||||
private:
|
|
||||||
Entity& entity_;
|
|
||||||
RideableType type_;
|
|
||||||
std::vector<RideableSeat> seats_;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
@ -29,6 +29,8 @@ public:
|
|||||||
private:
|
private:
|
||||||
void Setup();
|
void Setup();
|
||||||
|
|
||||||
|
void AddTuningGroupSelect(game::RemoteMenu& menu, const VehicleTuningGroup& group);
|
||||||
|
|
||||||
void OpenMainTuningMenu();
|
void OpenMainTuningMenu();
|
||||||
void OpenGroupMenu(const VehicleTuningGroup& group);
|
void OpenGroupMenu(const VehicleTuningGroup& group);
|
||||||
std::string GetCurrentPartId(const std::string& group_id);
|
std::string GetCurrentPartId(const std::string& group_id);
|
||||||
|
|||||||
@ -112,11 +112,11 @@ struct UseTargetAabbCallback : public btBroadphaseAabbCallback
|
|||||||
|
|
||||||
UseTargetAabbCallback(game::PlayerCharacter& character, game::UseTargetQueryResult& res) : character(character), pos(character.GetRoot().GetGlobalPosition()), best_res(res)
|
UseTargetAabbCallback(game::PlayerCharacter& character, game::UseTargetQueryResult& res) : character(character), pos(character.GetRoot().GetGlobalPosition()), best_res(res)
|
||||||
{
|
{
|
||||||
auto rideable_entity = dynamic_cast<game::Entity*>(character.GetRideable());
|
auto vehicle = character.GetVehicle();
|
||||||
if (rideable_entity)
|
if (vehicle)
|
||||||
{
|
{
|
||||||
radius = 5.0f;
|
radius = 5.0f;
|
||||||
pos = rideable_entity->GetRoot().GetGlobalPosition();
|
pos = vehicle->GetRoot().GetGlobalPosition();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -245,9 +245,6 @@ void game::World::HandleContacts()
|
|||||||
|
|
||||||
void game::World::DestroyObject(net::ObjNum objnum)
|
void game::World::DestroyObject(net::ObjNum objnum)
|
||||||
{
|
{
|
||||||
if (destroyed_objs_.contains(objnum))
|
|
||||||
return;
|
|
||||||
|
|
||||||
SendObjDestroyedMsg(objnum);
|
SendObjDestroyedMsg(objnum);
|
||||||
destroyed_objs_.insert(objnum);
|
destroyed_objs_.insert(objnum);
|
||||||
|
|
||||||
|
|||||||
@ -6,12 +6,7 @@
|
|||||||
|
|
||||||
game::view::CharacterView::CharacterView(WorldView& world, net::InMessage& msg) : EntityView(world, msg), ubo_(sk_)
|
game::view::CharacterView::CharacterView(WorldView& world, net::InMessage& msg) : EntityView(world, msg), ubo_(sk_)
|
||||||
{
|
{
|
||||||
// read model name
|
basemodel_ = assets::CacheManager::GetModel("data/human.mdl");
|
||||||
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_);
|
sk_ = SkeletonInstance(basemodel_->GetSkeleton(), &root_);
|
||||||
ubo_.Update();
|
ubo_.Update();
|
||||||
ubo_valid_ = true;
|
ubo_valid_ = true;
|
||||||
@ -95,17 +90,17 @@ void game::view::CharacterView::Draw(const DrawArgs& args)
|
|||||||
//args.dlist.AddBeam(start, end, 0xFF007700, 0.05f);
|
//args.dlist.AddBeam(start, end, 0xFF007700, 0.05f);
|
||||||
|
|
||||||
//// draw bones debug
|
//// draw bones debug
|
||||||
const auto& bone_nodes = sk_.GetBoneNodes();
|
// const auto& bone_nodes = sk_.GetBoneNodes();
|
||||||
for (const auto& bone_node : bone_nodes)
|
// for (const auto& bone_node : bone_nodes)
|
||||||
{
|
//{
|
||||||
if (!bone_node.parent)
|
// if (!bone_node.parent)
|
||||||
continue;
|
// continue;
|
||||||
|
|
||||||
glm::vec3 p0 = bone_node.parent->matrix[3];
|
// glm::vec3 p0 = bone_node.parent->matrix[3];
|
||||||
glm::vec3 p1 = bone_node.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
|
// update skinning matrices
|
||||||
if (!ubo_valid_)
|
if (!ubo_valid_)
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user