fekalnigtacko/src/game/simple_entity.cpp
2026-03-01 16:40:57 +01:00

89 lines
2.4 KiB
C++

#include "simple_entity.hpp"
#include "net/utils.hpp"
game::SimpleEntity::SimpleEntity(World& world, const std::string& modelname) : Super(world, net::ET_SIMPLE), modelname_(modelname)
{
UpdateSyncState();
}
void game::SimpleEntity::SendInitData(Player& player, net::OutMessage& msg) const
{
Super::SendInitData(player, msg);
msg.Write(net::ModelName(modelname_));
// write state against default
static const SimpleEntitySyncState default_state;
size_t fields_pos = msg.Reserve<SimpleEntitySyncFieldFlags>();
auto fields = WriteState(msg, default_state);
msg.WriteAt(fields_pos, fields);
}
void game::SimpleEntity::Update()
{
Super::Update();
UpdatePreSync(); // chance to update state before sent
sync_current_ = 1 - sync_current_;
UpdateSyncState();
SendUpdateMsg();
}
void game::SimpleEntity::UpdateSyncState()
{
SimpleEntitySyncState& state = sync_[sync_current_];
net::EncodePosition(root_.local.position, state.pos);
net::EncodeRotation(root_.local.rotation, state.rot);
}
game::SimpleEntitySyncFieldFlags game::SimpleEntity::WriteState(net::OutMessage& msg, const SimpleEntitySyncState& base) const
{
SimpleEntitySyncFieldFlags fields = 0;
const SimpleEntitySyncState& curr = sync_[sync_current_];
if (curr.pos.x.value != base.pos.x.value ||
curr.pos.y.value != base.pos.y.value ||
curr.pos.z.value != base.pos.z.value)
{
fields |= SESF_POSITION;
net::WriteDelta(msg, curr.pos.x, base.pos.x);
net::WriteDelta(msg, curr.pos.y, base.pos.y);
net::WriteDelta(msg, curr.pos.z, base.pos.z);
}
if (curr.rot.x.value != base.rot.x.value ||
curr.rot.y.value != base.rot.y.value ||
curr.rot.z.value != base.rot.z.value)
{
fields |= SESF_ROTATION;
net::WriteDelta(msg, curr.rot.x, base.rot.x);
net::WriteDelta(msg, curr.rot.y, base.rot.y);
net::WriteDelta(msg, curr.rot.z, base.rot.z);
}
return fields;
}
void game::SimpleEntity::SendUpdateMsg()
{
auto msg = BeginUpdateMsg();
// write state against previous
const SimpleEntitySyncState& prev = sync_[1 - sync_current_];
size_t fields_pos = msg.Reserve<SimpleEntitySyncFieldFlags>();
auto fields = WriteState(msg, prev);
if (fields == 0)
{
DiscardUpdateMsg();
return;
}
msg.WriteAt(fields_pos, fields);
}