Attachable entities, no physics characters, basic vehicle drivers
This commit is contained in:
parent
fd3f981ec0
commit
bbf2788627
@ -1,25 +1,13 @@
|
||||
#include "character.hpp"
|
||||
#include "world.hpp"
|
||||
#include "net/utils.hpp"
|
||||
#include "assets/cache.hpp"
|
||||
#include "net/utils.hpp"
|
||||
#include "utils/math.hpp"
|
||||
#include "world.hpp"
|
||||
|
||||
game::Character::Character(World& world, const CharacterInfo& info)
|
||||
: Super(world, net::ET_CHARACTER), shape_(info.shape), bt_shape_(shape_.radius, shape_.height),
|
||||
bt_character_(&bt_ghost_, &bt_shape_, 0.3f, btVector3(0, 0, 1))
|
||||
: Super(world, net::ET_CHARACTER), shape_(info.shape), bt_shape_(shape_.radius, shape_.height)
|
||||
{
|
||||
btTransform start_transform;
|
||||
start_transform.setIdentity();
|
||||
bt_ghost_.setWorldTransform(start_transform);
|
||||
bt_ghost_.setCollisionShape(&bt_shape_);
|
||||
bt_ghost_.setCollisionFlags(btCollisionObject::CF_CHARACTER_OBJECT);
|
||||
|
||||
|
||||
btDynamicsWorld& bt_world = world_.GetBtWorld();
|
||||
bt_world.addCollisionObject(&bt_ghost_, btBroadphaseProxy::CharacterFilter,
|
||||
btBroadphaseProxy::StaticFilter | btBroadphaseProxy::DefaultFilter);
|
||||
// bt_world.addCollisionObject(&bt_ghost_);
|
||||
bt_world.addAction(&bt_character_);
|
||||
z_offset_ = shape_.height * 0.5f + shape_.radius - 0.05f;
|
||||
|
||||
sk_ = SkeletonInstance(assets::CacheManager::GetSkeleton("data/human.sk"), &root_);
|
||||
animstate_.idle_anim_idx = GetAnim("idle");
|
||||
@ -50,9 +38,8 @@ void game::Character::Update()
|
||||
{
|
||||
Super::Update();
|
||||
|
||||
auto bt_trans = bt_ghost_.getWorldTransform();
|
||||
root_.local.SetBtTransform(bt_trans);
|
||||
root_.local.position.z -= shape_.height * 0.5f + shape_.radius - 0.05f; // foot pos
|
||||
SyncTransformFromController();
|
||||
root_.UpdateMatrix();
|
||||
|
||||
UpdateMovement();
|
||||
|
||||
@ -80,6 +67,19 @@ void game::Character::SendInitData(Player& player, net::OutMessage& msg) const
|
||||
msg.WriteAt(fields_pos, fields);
|
||||
}
|
||||
|
||||
void game::Character::EnablePhysics(bool enable)
|
||||
{
|
||||
if (enable && !controller_)
|
||||
{
|
||||
controller_ = std::make_unique<CharacterPhysicsController>(world_.GetBtWorld(), bt_shape_);
|
||||
SyncControllerTransform();
|
||||
}
|
||||
else if (!enable && controller_)
|
||||
{
|
||||
controller_.reset();
|
||||
}
|
||||
}
|
||||
|
||||
void game::Character::SetInput(CharacterInputType type, bool enable)
|
||||
{
|
||||
if (enable)
|
||||
@ -116,9 +116,8 @@ void game::Character::SetInput(CharacterInputType type, bool enable)
|
||||
|
||||
void game::Character::SetPosition(const glm::vec3& position)
|
||||
{
|
||||
auto trans = bt_ghost_.getWorldTransform();
|
||||
trans.setOrigin(btVector3(position.x, position.y, position.z));
|
||||
bt_ghost_.setWorldTransform(trans);
|
||||
root_.local.position = position;
|
||||
SyncControllerTransform();
|
||||
}
|
||||
|
||||
void game::Character::AddClothes(std::string name, const glm::vec3& color)
|
||||
@ -126,11 +125,31 @@ void game::Character::AddClothes(std::string name, const glm::vec3& color)
|
||||
clothes_.emplace_back(std::move(name), color);
|
||||
}
|
||||
|
||||
game::Character::~Character()
|
||||
void game::Character::SetMainAnim(const std::string& anim_name)
|
||||
{
|
||||
btDynamicsWorld& bt_world = world_.GetBtWorld();
|
||||
bt_world.removeAction(&bt_character_);
|
||||
bt_world.removeCollisionObject(&bt_ghost_);
|
||||
animstate_.idle_anim_idx = GetAnim(anim_name);
|
||||
}
|
||||
|
||||
void game::Character::SyncControllerTransform()
|
||||
{
|
||||
if (!controller_)
|
||||
return;
|
||||
|
||||
auto& position = root_.local.position;
|
||||
auto& bt_ghost = controller_->GetBtGhost();
|
||||
auto trans = bt_ghost.getWorldTransform();
|
||||
trans.setOrigin(btVector3(position.x, position.y, position.z + z_offset_));
|
||||
bt_ghost.setWorldTransform(trans);
|
||||
}
|
||||
|
||||
void game::Character::SyncTransformFromController()
|
||||
{
|
||||
if (!controller_)
|
||||
return;
|
||||
|
||||
auto bt_trans = controller_->GetBtGhost().getWorldTransform();
|
||||
root_.local.SetBtTransform(bt_trans);
|
||||
root_.local.position.z -= z_offset_; // foot pos
|
||||
}
|
||||
|
||||
void game::Character::UpdateMovement()
|
||||
@ -163,11 +182,15 @@ void game::Character::UpdateMovement()
|
||||
walkdir = forward_dir * walk_speed_ * dt;
|
||||
}
|
||||
|
||||
bt_character_.setWalkDirection(btVector3(walkdir.x, walkdir.y, walkdir.z));
|
||||
|
||||
if (in_ & (1 << CIN_JUMP) && bt_character_.canJump())
|
||||
if (controller_)
|
||||
{
|
||||
bt_character_.jump(btVector3(0.0f, 0.0f, 10.0f));
|
||||
auto& bt_character = controller_->GetBtController();
|
||||
bt_character.setWalkDirection(btVector3(walkdir.x, walkdir.y, walkdir.z));
|
||||
|
||||
if (in_ & (1 << CIN_JUMP) && bt_character.canJump())
|
||||
{
|
||||
bt_character.jump(btVector3(0.0f, 0.0f, 10.0f));
|
||||
}
|
||||
}
|
||||
|
||||
// update anim
|
||||
@ -193,8 +216,6 @@ void game::Character::UpdateSyncState()
|
||||
state.run_anim = animstate_.run_anim_idx;
|
||||
state.loco_phase.Encode(animstate_.loco_phase);
|
||||
state.loco_blend.Encode(animstate_.loco_blend);
|
||||
|
||||
|
||||
}
|
||||
|
||||
void game::Character::SendUpdateMsg()
|
||||
@ -300,3 +321,24 @@ 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))
|
||||
{
|
||||
btTransform start_transform;
|
||||
start_transform.setIdentity();
|
||||
bt_ghost_.setWorldTransform(start_transform);
|
||||
bt_ghost_.setCollisionShape(&bt_shape);
|
||||
bt_ghost_.setCollisionFlags(btCollisionObject::CF_CHARACTER_OBJECT);
|
||||
|
||||
bt_world_.addCollisionObject(&bt_ghost_, btBroadphaseProxy::CharacterFilter,
|
||||
btBroadphaseProxy::StaticFilter | btBroadphaseProxy::DefaultFilter);
|
||||
// bt_world.addCollisionObject(&bt_ghost_);
|
||||
bt_world_.addAction(&bt_character_);
|
||||
}
|
||||
|
||||
game::CharacterPhysicsController::~CharacterPhysicsController()
|
||||
{
|
||||
bt_world_.removeAction(&bt_character_);
|
||||
bt_world_.removeCollisionObject(&bt_ghost_);
|
||||
}
|
||||
|
||||
@ -1,10 +1,11 @@
|
||||
#pragma once
|
||||
|
||||
#include "entity.hpp"
|
||||
#include "BulletCollision/CollisionDispatch/btGhostObject.h"
|
||||
#include "BulletDynamics/Character/btKinematicCharacterController.h"
|
||||
#include <btBulletDynamicsCommon.h>
|
||||
#include <BulletCollision/CollisionDispatch/btGhostObject.h>
|
||||
#include <BulletDynamics/Character/btKinematicCharacterController.h>
|
||||
#include "character_anim_state.hpp"
|
||||
#include "character_sync.hpp"
|
||||
#include "entity.hpp"
|
||||
|
||||
namespace game
|
||||
{
|
||||
@ -39,6 +40,25 @@ struct CharacterClothes
|
||||
glm::vec3 color;
|
||||
};
|
||||
|
||||
class CharacterPhysicsController
|
||||
{
|
||||
public:
|
||||
CharacterPhysicsController(btDynamicsWorld& bt_world, btCapsuleShapeZ& bt_shape);
|
||||
DELETE_COPY_MOVE(CharacterPhysicsController)
|
||||
|
||||
btKinematicCharacterController& GetBtController() { return bt_character_; }
|
||||
const btKinematicCharacterController& GetBtController() const { return bt_character_; }
|
||||
btGhostObject& GetBtGhost() { return bt_ghost_; }
|
||||
const btGhostObject& GetBtGhost() const { return bt_ghost_; }
|
||||
|
||||
~CharacterPhysicsController();
|
||||
|
||||
private:
|
||||
btDynamicsWorld& bt_world_;
|
||||
btPairCachingGhostObject bt_ghost_;
|
||||
btKinematicCharacterController bt_character_;
|
||||
};
|
||||
|
||||
class Character : public Entity
|
||||
{
|
||||
public:
|
||||
@ -49,18 +69,26 @@ public:
|
||||
virtual void Update() override;
|
||||
virtual void SendInitData(Player& player, net::OutMessage& msg) const override;
|
||||
|
||||
void EnablePhysics(bool enable);
|
||||
|
||||
void SetInput(CharacterInputType type, bool enable);
|
||||
void SetInputs(CharacterInputFlags inputs) { in_ = inputs; }
|
||||
|
||||
void SetForwardYaw(float yaw) { forward_yaw_ = yaw; }
|
||||
void SetYaw(float yaw) { yaw_ = yaw; }
|
||||
|
||||
void SetPosition(const glm::vec3& position);
|
||||
|
||||
void AddClothes(std::string name, const glm::vec3& color);
|
||||
|
||||
~Character() override;
|
||||
void SetMainAnim(const std::string& anim_name);
|
||||
|
||||
~Character() override = default;
|
||||
|
||||
private:
|
||||
void SyncControllerTransform();
|
||||
void SyncTransformFromController();
|
||||
|
||||
void UpdateMovement();
|
||||
void UpdateSyncState();
|
||||
void SendUpdateMsg();
|
||||
@ -79,9 +107,8 @@ private:
|
||||
CharacterInputFlags in_ = 0;
|
||||
|
||||
btCapsuleShapeZ bt_shape_;
|
||||
btPairCachingGhostObject bt_ghost_;
|
||||
|
||||
btKinematicCharacterController bt_character_;
|
||||
float z_offset_ = 0.0f; // offset of controller from root
|
||||
std::unique_ptr<CharacterPhysicsController> controller_;
|
||||
|
||||
float yaw_ = 0.0f;
|
||||
float forward_yaw_ = 0.0f;
|
||||
|
||||
@ -4,15 +4,40 @@
|
||||
|
||||
game::Entity::Entity(World& world, net::EntType viewtype) : Scheduler(world.GetTime()), world_(world), entnum_(world.GetNewEntnum()), viewtype_(viewtype) {}
|
||||
|
||||
void game::Entity::Update()
|
||||
{
|
||||
ResetMsg();
|
||||
RunTasks();
|
||||
}
|
||||
|
||||
void game::Entity::SendInitData(Player& player, net::OutMessage& msg) const
|
||||
{
|
||||
WriteNametag(msg);
|
||||
WriteAttach(msg);
|
||||
}
|
||||
|
||||
void game::Entity::Update()
|
||||
{
|
||||
ResetMsg();
|
||||
|
||||
upd_time_ = world_.GetTime();
|
||||
|
||||
// ensure parent is updated
|
||||
parent_ = nullptr;
|
||||
if (parentnum_)
|
||||
{
|
||||
parent_ = world_.GetEntity(parentnum_);
|
||||
parent_->TryUpdate();
|
||||
}
|
||||
|
||||
// update transform parent
|
||||
root_.parent = parent_ ? &parent_->GetRoot() : nullptr;
|
||||
|
||||
RunTasks();
|
||||
}
|
||||
|
||||
bool game::Entity::TryUpdate()
|
||||
{
|
||||
int64_t time = world_.GetTime();
|
||||
if (time == upd_time_)
|
||||
return false;
|
||||
|
||||
Update();
|
||||
return true;
|
||||
}
|
||||
|
||||
void game::Entity::SetNametag(const std::string& nametag)
|
||||
@ -21,6 +46,12 @@ void game::Entity::SetNametag(const std::string& nametag)
|
||||
SendNametagMsg(); // notify viewers
|
||||
}
|
||||
|
||||
void game::Entity::Attach(net::EntNum parentnum)
|
||||
{
|
||||
parentnum_ = parentnum;
|
||||
SendAttachMsg();
|
||||
}
|
||||
|
||||
void game::Entity::WriteNametag(net::OutMessage& msg) const
|
||||
{
|
||||
msg.Write(net::NameTag{nametag_});
|
||||
@ -32,6 +63,17 @@ void game::Entity::SendNametagMsg()
|
||||
WriteNametag(msg);
|
||||
}
|
||||
|
||||
void game::Entity::WriteAttach(net::OutMessage& msg) const
|
||||
{
|
||||
msg.Write(parentnum_);
|
||||
}
|
||||
|
||||
void game::Entity::SendAttachMsg()
|
||||
{
|
||||
auto msg = BeginEntMsg(net::EMSG_ATTACH);
|
||||
WriteAttach(msg);
|
||||
}
|
||||
|
||||
net::OutMessage game::Entity::BeginEntMsg(net::EntMsgType type)
|
||||
{
|
||||
auto msg = BeginMsg(net::MSG_ENTMSG);
|
||||
|
||||
@ -22,14 +22,21 @@ public:
|
||||
net::EntNum GetEntNum() const { return entnum_; }
|
||||
net::EntType GetViewType() const { return viewtype_; }
|
||||
|
||||
virtual void Update();
|
||||
virtual void SendInitData(Player& player, net::OutMessage& msg) const;
|
||||
|
||||
virtual void Update();
|
||||
bool TryUpdate(); // if not already updated
|
||||
int64_t GetUpdateTime() const { return upd_time_; }
|
||||
|
||||
void SetNametag(const std::string& nametag);
|
||||
|
||||
void Attach(net::EntNum parentnum);
|
||||
net::EntNum GetParentNum() const { return parentnum_; }
|
||||
|
||||
void Remove() { removed_ = true; }
|
||||
bool IsRemoved() const { return removed_; }
|
||||
|
||||
const TransformNode& GetRoot() const { return root_; }
|
||||
const Transform& GetRootTransform() const { return root_.local; }
|
||||
float GetMaxDistance() const { return max_distance_; }
|
||||
|
||||
@ -37,9 +44,11 @@ public:
|
||||
|
||||
private:
|
||||
void WriteNametag(net::OutMessage& msg) const;
|
||||
|
||||
void SendNametagMsg();
|
||||
|
||||
void WriteAttach(net::OutMessage& msg) const;
|
||||
void SendAttachMsg();
|
||||
|
||||
protected:
|
||||
net::OutMessage BeginEntMsg(net::EntMsgType type);
|
||||
|
||||
@ -49,13 +58,16 @@ protected:
|
||||
const net::EntType viewtype_;
|
||||
|
||||
TransformNode root_;
|
||||
Entity* parent_ = nullptr;
|
||||
|
||||
float max_distance_ = 700.0f;
|
||||
std::string nametag_;
|
||||
|
||||
|
||||
bool removed_ = false;
|
||||
|
||||
private:
|
||||
int64_t upd_time_ = -1;
|
||||
std::string nametag_;
|
||||
net::EntNum parentnum_ = 0;
|
||||
};
|
||||
|
||||
}
|
||||
@ -247,19 +247,28 @@ static glm::vec3 GetRandomColor()
|
||||
return color;
|
||||
}
|
||||
|
||||
void game::OpenWorld::SpawnCharacter(Player& player)
|
||||
game::Character& game::OpenWorld::SpawnRandomCharacter()
|
||||
{
|
||||
RemoveCharacter(player);
|
||||
|
||||
CharacterInfo cinfo;
|
||||
auto& character = Spawn<Character>(cinfo);
|
||||
character.SetNametag("player (" + std::to_string(character.GetEntNum()) + ")");
|
||||
character.SetPosition({ 100.0f, 100.0f, 5.0f });
|
||||
|
||||
// add clothes
|
||||
character.AddClothes("tshirt", GetRandomColor());
|
||||
character.AddClothes("shorts", GetRandomColor());
|
||||
|
||||
return character;
|
||||
}
|
||||
|
||||
|
||||
void game::OpenWorld::SpawnCharacter(Player& player)
|
||||
{
|
||||
RemoveCharacter(player);
|
||||
|
||||
auto& character = SpawnRandomCharacter();
|
||||
character.SetNametag("player (" + std::to_string(character.GetEntNum()) + ")");
|
||||
character.SetPosition({ 100.0f, 100.0f, 5.0f });
|
||||
character.EnablePhysics(true);
|
||||
|
||||
player.SetCamera(character.GetEntNum());
|
||||
|
||||
player_characters_[&player] = &character;
|
||||
@ -572,6 +581,13 @@ void game::OpenWorld::SpawnBot()
|
||||
vehicle.Schedule(rand() % 500, [think_state]() {
|
||||
//BotNametagThink(think_state);
|
||||
} );
|
||||
|
||||
// spawn driver
|
||||
auto& driver = SpawnRandomCharacter();
|
||||
driver.Attach(vehicle.GetEntNum());
|
||||
driver.SetPosition(glm::vec3(0.0f, 0.0f, 0.0f));
|
||||
driver.SetMainAnim("vehicle_drive");
|
||||
driver.SetYaw(0.5f * glm::pi<float>());
|
||||
}
|
||||
|
||||
void game::OpenWorld::SpawnVehicle(Player& player)
|
||||
|
||||
@ -23,6 +23,8 @@ private:
|
||||
void SpawnVehicle(Player& player);
|
||||
void RemoveVehicle(Player& player);
|
||||
|
||||
Character& SpawnRandomCharacter();
|
||||
|
||||
void SpawnCharacter(Player& player);
|
||||
void RemoveCharacter(Player& player);
|
||||
|
||||
|
||||
@ -43,7 +43,7 @@ void game::Player::Update()
|
||||
auto cam_ent = world_->GetEntity(cam_ent_);
|
||||
if (cam_ent)
|
||||
{
|
||||
cull_pos_ = cam_ent->GetRootTransform().position;
|
||||
cull_pos_ = cam_ent->GetRoot().GetGlobalPosition();
|
||||
}
|
||||
}
|
||||
|
||||
@ -143,7 +143,7 @@ bool game::Player::ShouldSeeEntity(const Entity& entity) const
|
||||
{
|
||||
// max distance check
|
||||
float max_dist = entity.GetMaxDistance();
|
||||
if (glm::distance2(entity.GetRootTransform().position, cull_pos_) > (max_dist * max_dist))
|
||||
if (glm::distance2(entity.GetRoot().GetGlobalPosition(), cull_pos_) > (max_dist * max_dist))
|
||||
return false;
|
||||
|
||||
// TODO: custom callback
|
||||
|
||||
@ -24,6 +24,11 @@ namespace game
|
||||
matrix = parent->matrix * matrix;
|
||||
}
|
||||
}
|
||||
|
||||
glm::vec3 GetGlobalPosition() const
|
||||
{
|
||||
return matrix[3];
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
@ -97,6 +97,8 @@ void game::Vehicle::Update()
|
||||
{
|
||||
Super::Update();
|
||||
|
||||
root_.UpdateMatrix();
|
||||
|
||||
flags_ = 0;
|
||||
ProcessInput();
|
||||
UpdateWheels();
|
||||
|
||||
@ -41,7 +41,7 @@ void game::World::Update(int64_t delta_time)
|
||||
// update entities
|
||||
for (auto it = ents_.begin(); it != ents_.end();)
|
||||
{
|
||||
it->second->Update();
|
||||
it->second->TryUpdate();
|
||||
|
||||
if (it->second->IsRemoved())
|
||||
it = ents_.erase(it);
|
||||
|
||||
@ -53,6 +53,8 @@ bool game::view::CharacterView::ProcessMsg(net::EntMsgType type, net::InMessage&
|
||||
|
||||
void game::view::CharacterView::Update(const UpdateInfo& info)
|
||||
{
|
||||
Super::Update(info);
|
||||
|
||||
// interpolate states
|
||||
float tps = 25.0f;
|
||||
float t = (info.time - update_time_) * tps * 0.8f; // assume some jitter, interpolate for longer
|
||||
|
||||
@ -10,7 +10,8 @@ game::view::EntityView::EntityView(WorldView& world, net::InMessage& msg) :
|
||||
audioplayer_(world_.GetAudioMaster()),
|
||||
nametag_text_(assets::CacheManager::GetFont("data/comic32.font"), 0xFFFFFFFF)
|
||||
{
|
||||
if (!ReadNametag(msg))
|
||||
// read nametag and attachment info
|
||||
if (!ReadNametag(msg) || !ReadAttach(msg))
|
||||
throw EntityInitError();
|
||||
}
|
||||
|
||||
@ -20,13 +21,38 @@ bool game::view::EntityView::ProcessMsg(net::EntMsgType type, net::InMessage& ms
|
||||
{
|
||||
case net::EMSG_NAMETAG:
|
||||
return ReadNametag(msg);
|
||||
case net::EMSG_ATTACH:
|
||||
return ReadAttach(msg);
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
bool game::view::EntityView::TryUpdate(const UpdateInfo& info)
|
||||
{
|
||||
float time = world_.GetTime();
|
||||
if (time == upd_time_)
|
||||
return false;
|
||||
|
||||
Update(info);
|
||||
return true;
|
||||
}
|
||||
|
||||
void game::view::EntityView::Update(const UpdateInfo& info)
|
||||
{
|
||||
upd_time_ = world_.GetTime();
|
||||
|
||||
// ensure parent is updated
|
||||
parent_ = nullptr;
|
||||
if (parentnum_)
|
||||
{
|
||||
parent_ = world_.GetEntity(parentnum_);
|
||||
parent_->TryUpdate(info);
|
||||
}
|
||||
|
||||
// update transform parent
|
||||
root_.parent = parent_ ? &parent_->GetRoot() : nullptr;
|
||||
|
||||
audioplayer_.Update();
|
||||
}
|
||||
|
||||
@ -49,6 +75,11 @@ bool game::view::EntityView::ReadNametag(net::InMessage& msg)
|
||||
return true;
|
||||
}
|
||||
|
||||
bool game::view::EntityView::ReadAttach(net::InMessage& msg)
|
||||
{
|
||||
return msg.Read(parentnum_);
|
||||
}
|
||||
|
||||
void game::view::EntityView::DrawNametag(const DrawArgs& args)
|
||||
{
|
||||
if (nametag_.empty())
|
||||
|
||||
@ -36,17 +36,20 @@ public:
|
||||
DELETE_COPY_MOVE(EntityView)
|
||||
|
||||
virtual bool ProcessMsg(net::EntMsgType type, net::InMessage& msg);
|
||||
|
||||
bool TryUpdate(const UpdateInfo& info); // if not updated already
|
||||
virtual void Update(const UpdateInfo& info);
|
||||
|
||||
virtual void Draw(const DrawArgs& args);
|
||||
|
||||
Sphere GetBoundingSphere() const { return Sphere{root_.local.position, radius_}; }
|
||||
|
||||
Sphere GetBoundingSphere() const { return Sphere{root_.GetGlobalPosition(), radius_}; }
|
||||
const TransformNode& GetRoot() const { return root_; }
|
||||
|
||||
virtual ~EntityView() = default;
|
||||
|
||||
private:
|
||||
bool ReadNametag(net::InMessage& msg);
|
||||
bool ReadAttach(net::InMessage& msg);
|
||||
|
||||
void DrawNametag(const DrawArgs& args);
|
||||
void DrawAxes(const DrawArgs& args);
|
||||
@ -55,13 +58,20 @@ protected:
|
||||
WorldView& world_;
|
||||
|
||||
TransformNode root_;
|
||||
|
||||
EntityView* parent_ = nullptr;
|
||||
|
||||
float radius_ = 1.0f;
|
||||
|
||||
audio::Player audioplayer_;
|
||||
|
||||
private:
|
||||
std::string nametag_;
|
||||
gfx::Text nametag_text_;
|
||||
gfx::HudPosition nametag_pos_;
|
||||
|
||||
net::EntNum parentnum_ = 0;
|
||||
float upd_time_ = 0.0f;
|
||||
};
|
||||
|
||||
} // namespace game::view
|
||||
@ -38,7 +38,7 @@ void game::view::WorldView::Update(const UpdateInfo& info)
|
||||
|
||||
for (const auto& [entnum, ent] : ents_)
|
||||
{
|
||||
ent->Update(info);
|
||||
ent->TryUpdate(info);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -75,6 +75,7 @@ enum EntMsgType : uint8_t
|
||||
EMSG_NONE,
|
||||
|
||||
EMSG_NAMETAG,
|
||||
EMSG_ATTACH,
|
||||
EMSG_UPDATE,
|
||||
};
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user