Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Prop anims with 'eventlock' now remain active if player leaves vehicle (+multiplayer). #2949

Merged
merged 2 commits into from
Oct 11, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions source/main/GameContext.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1684,5 +1684,11 @@ void GameContext::UpdateTruckInputEvents(float dt)
{
m_player_actor->getTyrePressure().UpdateInputEvents(dt);
}

m_player_actor->UpdatePropAnimInputEvents();
for (Actor* linked_actor : m_player_actor->getAllLinkedActors())
{
linked_actor->UpdatePropAnimInputEvents();
}
}

59 changes: 15 additions & 44 deletions source/main/gfx/GfxActor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1694,6 +1694,13 @@ void RoR::GfxActor::UpdateSimDataBuffer()
m_simbuf.simbuf_commandkey[i].simbuf_cmd_value = m_actor->ar_command_key[i].commandValue;
}

// Elements: Prop animation keys
m_simbuf.simbuf_prop_anim_keys.resize(m_actor->m_prop_anim_key_states.size());
for (size_t i = 0; i < m_actor->m_prop_anim_key_states.size(); ++i)
{
m_simbuf.simbuf_prop_anim_keys[i].simbuf_anim_active = m_actor->m_prop_anim_key_states[i].anim_active;
}

// Elements: Aeroengines
m_simbuf.simbuf_aeroengines.resize(m_actor->ar_num_aeroengines);
for (int i = 0; i < m_actor->ar_num_aeroengines; ++i)
Expand Down Expand Up @@ -2754,8 +2761,10 @@ void RoR::GfxActor::CalcPropAnimation(const int flag_state, float& cstate, int&
}
}

void RoR::GfxActor::UpdatePropAnimations(float dt, bool is_player_connected)
void RoR::GfxActor::UpdatePropAnimations(float dt)
{
int prop_anim_key_index = 0;

for (Prop& prop: m_props)
{
int animnum = 0;
Expand All @@ -2773,50 +2782,12 @@ void RoR::GfxActor::UpdatePropAnimations(float dt, bool is_player_connected)

this->CalcPropAnimation(anim.animFlags, cstate, div, dt, lower_limit, upper_limit, animOpt3);

// key triggered animations
if ((anim.animFlags & ANIM_FLAG_EVENT) && anim.animKey != -1 && is_player_connected)
// key triggered animations - state determined in simulation
if (anim.animFlags & ANIM_FLAG_EVENT)
{
// TODO: Keys shouldn't be queried from here, but buffered in sim. loop ~ only_a_ptr, 06/2018
if (RoR::App::GetInputEngine()->getEventValue(anim.animKey))
{
// keystatelock is disabled then set cstate
if (anim.animKeyState == -1.0f)
{
// TODO: Keys shouldn't be queried from here, but buffered in sim. loop ~ only_a_ptr, 06/2018
cstate += RoR::App::GetInputEngine()->getEventValue(anim.animKey);
}
else if (!anim.animKeyState)
{
// a key was pressed and a toggle was done already, so bypass
//toggle now
if (!anim.lastanimKS)
{
anim.lastanimKS = 1.0f;
// use animkey as bool to determine keypress / release state of inputengine
anim.animKeyState = 1.0f;
}
else
{
anim.lastanimKS = 0.0f;
// use animkey as bool to determine keypress / release state of inputengine
anim.animKeyState = 1.0f;
}
}
else
{
// bypas mode, get the last set position and set it
cstate += anim.lastanimKS;
}
}
else
{
// keyevent exists and keylock is enabled but the key isnt pressed right now = get lastanimkeystatus for cstate and reset keypressed bool animkey
if (anim.animKeyState != -1.0f)
{
cstate += anim.lastanimKS;
anim.animKeyState = 0.0f;
}
}
ROR_ASSERT(prop_anim_key_index < (int)m_simbuf.simbuf_prop_anim_keys.size());
const bool anim_active = m_simbuf.simbuf_prop_anim_keys[prop_anim_key_index++].simbuf_anim_active;
cstate += (float)anim_active;
}

//propanimation placed here to avoid interference with existing hydros(cstate) and permanent prop animation
Expand Down
2 changes: 1 addition & 1 deletion source/main/gfx/GfxActor.h
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ class GfxActor
void UpdateWingMeshes();
void UpdateBeaconFlare(Prop & prop, float dt, bool is_player_actor);
void UpdateProps(float dt, bool is_player_actor);
void UpdatePropAnimations(float dt, bool is_player_connected);
void UpdatePropAnimations(float dt);
void UpdateAirbrakes();
void UpdateCParticles();
void UpdateAeroEngines();
Expand Down
3 changes: 0 additions & 3 deletions source/main/gfx/GfxData.h
Original file line number Diff line number Diff line change
Expand Up @@ -118,9 +118,6 @@ struct PropAnim
PropAnimMode animMode = {};
float animOpt3 = 0; //!< Various purposes
float animOpt5 = 0;
int animKey = 0;
int animKeyState = 0;
int lastanimKS = 0;
float lower_limit = 0; //!< The lower limit for the animation
float upper_limit = 0; //!< The upper limit for the animation
};
Expand Down
5 changes: 1 addition & 4 deletions source/main/gfx/GfxScene.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -98,11 +98,9 @@ void GfxScene::UpdateScene(float dt_sec)

// Var
GfxActor* player_gfx_actor = nullptr;
std::set<GfxActor*> player_connected_gfx_actors;
if (m_simbuf.simbuf_player_actor != nullptr)
{
player_gfx_actor = m_simbuf.simbuf_player_actor->GetGfxActor();
player_connected_gfx_actors = player_gfx_actor->GetLinkedGfxActors();
}

// FOV
Expand Down Expand Up @@ -211,7 +209,6 @@ void GfxScene::UpdateScene(float dt_sec)
// Actors - update misc visuals
for (GfxActor* gfx_actor: m_all_gfx_actors)
{
bool is_player_connected = (player_connected_gfx_actors.find(gfx_actor) != player_connected_gfx_actors.end());
if (gfx_actor->IsActorLive())
{
gfx_actor->UpdateRods();
Expand All @@ -220,7 +217,7 @@ void GfxScene::UpdateScene(float dt_sec)
gfx_actor->UpdateAirbrakes();
gfx_actor->UpdateCParticles();
gfx_actor->UpdateAeroEngines();
gfx_actor->UpdatePropAnimations(dt_sec, (gfx_actor == player_gfx_actor) || is_player_connected);
gfx_actor->UpdatePropAnimations(dt_sec);
gfx_actor->UpdateRenderdashRTT();
}
// Beacon flares must always be updated
Expand Down
6 changes: 6 additions & 0 deletions source/main/gfx/SimBuffers.h
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,11 @@ struct CommandKeySB
float simbuf_cmd_value;
};

struct PropAnimKeySB
{
bool simbuf_anim_active;
};

struct AeroEngineSB
{
AeroEngineType simbuf_ae_type;
Expand Down Expand Up @@ -129,6 +134,7 @@ struct ActorSB
std::vector<NodeSB> simbuf_nodes;
std::vector<ScrewpropSB> simbuf_screwprops;
std::vector<CommandKeySB> simbuf_commandkey;
std::vector<PropAnimKeySB> simbuf_prop_anim_keys;
std::vector<AeroEngineSB> simbuf_aeroengines;
std::vector<AirbrakeSB> simbuf_airbrakes;

Expand Down
2 changes: 1 addition & 1 deletion source/main/network/RoRnet.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ namespace RoRnet {
#define RORNET_LAN_BROADCAST_PORT 13000 //!< port used to send the broadcast announcement in LAN mode
#define RORNET_MAX_USERNAME_LEN 40 //!< port used to send the broadcast announcement in LAN mode

#define RORNET_VERSION "RoRnet_2.43"
#define RORNET_VERSION "RoRnet_2.44"

enum MessageType
{
Expand Down
50 changes: 47 additions & 3 deletions source/main/physics/Actor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -347,7 +347,7 @@ void Actor::pushNetwork(char* data, int size)
update.wheel_data.resize(ar_num_wheels * sizeof(float));

// check if the size of the data matches to what we expected
if ((unsigned int)size == (m_net_buffer_size + sizeof(RoRnet::VehicleState)))
if ((unsigned int)size == (m_net_total_buffer_size + sizeof(RoRnet::VehicleState)))
{
// we walk through the incoming data and separate it a bit
char* ptr = data;
Expand All @@ -367,6 +367,15 @@ void Actor::pushNetwork(char* data, int size)
update.wheel_data[i] = wspeed;
ptr += sizeof(float);
}

// then process the prop animation keys
for (size_t i = 0; i < m_prop_anim_key_states.size(); i++)
{
// Unpack bit array
char byte = *(ptr + (i / 8));
char mask = char(1) << (7 - (i % 8));
m_prop_anim_key_states[i].anim_active = (byte & mask);
}
}
else
{
Expand Down Expand Up @@ -1897,7 +1906,7 @@ void Actor::sendStreamData()
ar_net_last_update_time = ar_net_timer.getMilliseconds();

//look if the packet is too big first
if (m_net_buffer_size + sizeof(RoRnet::VehicleState) > 8192)
if (m_net_total_buffer_size + sizeof(RoRnet::VehicleState) > RORNET_MAX_MESSAGE_LENGTH)
{
ErrorUtils::ShowError(_L("Actor is too big to be sent over the net."), _L("Network error!"));
exit(126);
Expand Down Expand Up @@ -2006,7 +2015,7 @@ void Actor::sendStreamData()
{
char* ptr = send_buffer + sizeof(RoRnet::VehicleState);
float* send_nodes = (float *)ptr;
packet_len += m_net_buffer_size;
packet_len += m_net_total_buffer_size;

// copy data into the buffer
int i;
Expand Down Expand Up @@ -2037,6 +2046,19 @@ void Actor::sendStreamData()
{
wfbuf[i] = ar_wheels[i].wh_net_rp;
}
ptr += ar_num_wheels * sizeof(float);

// Then the anim key states
for (size_t i = 0; i < m_prop_anim_key_states.size(); i++)
{
if (m_prop_anim_key_states[i].anim_active)
{
// Pack as bit array, starting with most signifficant bit
char& dst_byte = *(ptr + (i / 8));
char mask = ((char)m_prop_anim_key_states[i].anim_active) << (7 - (i % 8));
dst_byte |= mask;
}
}
}

App::GetNetwork()->AddPacket(ar_net_stream_id, MSG2_STREAM_DATA_DISCARDABLE, packet_len, send_buffer);
Expand Down Expand Up @@ -4606,3 +4628,25 @@ void Actor::WriteDiagnosticDump(std::string const& fileName)
outStream->write(text.c_str(), text.length());
Ogre::ResourceGroupManager::getSingleton().destroyResourceGroup(rgName);
}

void Actor::UpdatePropAnimInputEvents()
{
for (PropAnimKeyState& state : m_prop_anim_key_states)
{
bool ev_active = App::GetInputEngine()->getEventValue(state.event_id);
if (state.eventlock_present)
{
// Toggle-mode
if (ev_active && (ev_active != state.event_active_prev))
{
state.anim_active = !state.anim_active;
}
}
else
{
// Direct-mode
state.anim_active = ev_active;
}
state.event_active_prev = ev_active;
}
}
23 changes: 16 additions & 7 deletions source/main/physics/Actor.h
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,7 @@ class Actor : public ZeroedMemoryAllocator
void toggleBlinkType(BlinkType blink);
BlinkType getBlinkType();
void setBlinkType(BlinkType blink);
std::vector<Actor*> getAllLinkedActors() { return m_linked_actors; }; //!< Returns a list of all connected (hooked) actors
std::vector<Actor*>& getAllLinkedActors() { return m_linked_actors; }; //!< Returns a list of all connected (hooked) actors
//! @}

/// @name Visual state updates
Expand Down Expand Up @@ -218,6 +218,7 @@ class Actor : public ZeroedMemoryAllocator
Ogre::Real getMinimalCameraRadius();
float GetFFbHydroForces() const { return m_force_sensors.out_hydros_forces; }
bool isBeingReset() const { return m_ongoing_reset; };
void UpdatePropAnimInputEvents();
#ifdef USE_ANGELSCRIPT
// we have to add this to be able to use the class as reference inside scripts
void addRef() {};
Expand Down Expand Up @@ -492,8 +493,6 @@ class Actor : public ZeroedMemoryAllocator
Ogre::Vector3 m_mouse_grab_pos;
float m_mouse_grab_move_force;
float m_spawn_rotation;
Ogre::UTFString m_net_username;
int m_net_color_num;
Ogre::Timer m_reset_timer;
Ogre::Vector3 m_rotation_request_center;
float m_rotation_request; //!< Accumulator
Expand All @@ -510,10 +509,6 @@ class Actor : public ZeroedMemoryAllocator
Differential* m_wheel_diffs[MAX_WHEELS/2];//!< Physics
int m_num_wheel_diffs; //!< Physics attr
TransferCase* m_transfer_case; //!< Physics
float m_net_node_compression; //!< Sim attr;
int m_net_first_wheel_node; //!< Network attr; Determines data buffer layout
int m_net_node_buf_size; //!< Network attr; buffer size
int m_net_buffer_size; //!< Network attr; buffer size
int m_wheel_node_count; //!< Static attr; filled at spawn
int m_previous_gear; //!< Sim state; land vehicle shifting
float m_handbrake_force; //!< Physics attr; defined in truckfile
Expand All @@ -536,6 +531,20 @@ class Actor : public ZeroedMemoryAllocator
bool m_has_axles_section; //!< Temporary (legacy parsing helper) until central diffs are implemented
TyrePressure m_tyre_pressure;
std::vector<std::string> m_description;
std::vector<PropAnimKeyState> m_prop_anim_key_states;

/// @name Networking
/// @{
size_t m_net_node_buf_size; //!< For incoming/outgoing traffic; calculated on spawn
size_t m_net_wheel_buf_size; //!< For incoming/outgoing traffic; calculated on spawn
size_t m_net_propanimkey_buf_size; //!< For incoming/outgoing traffic; calculated on spawn
size_t m_net_total_buffer_size; //!< For incoming/outgoing traffic; calculated on spawn
float m_net_node_compression; //!< For incoming/outgoing traffic; calculated on spawn
int m_net_first_wheel_node; //!< Network attr; Determines data buffer layout; calculated on spawn

Ogre::UTFString m_net_username;
int m_net_color_num;
/// @}

/// @name Light states
/// @{
Expand Down
15 changes: 11 additions & 4 deletions source/main/physics/ActorManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -286,13 +286,20 @@ Actor* ActorManager::CreateNewActor(ActorSpawnRequest rq, RigDef::DocumentPtr de
if (App::mp_state->getEnum<MpState>() == RoR::MpState::CONNECTED)
{
// network buffer layout (without RoRnet::VehicleState):
//
// -----------------------------------------------------

// - 3 floats (x,y,z) for the reference node 0
// - ar_num_nodes - 1 times 3 short ints (compressed position info)
// - ar_num_wheels times a float for the wheel rotation
//
actor->m_net_node_buf_size = sizeof(float) * 3 + (actor->m_net_first_wheel_node - 1) * sizeof(short int) * 3;
actor->m_net_buffer_size = actor->m_net_node_buf_size + actor->ar_num_wheels * sizeof(float);
actor->m_net_total_buffer_size += actor->m_net_node_buf_size;
// - ar_num_wheels times a float for the wheel rotation
actor->m_net_wheel_buf_size = actor->ar_num_wheels * sizeof(float);
actor->m_net_total_buffer_size += actor->m_net_wheel_buf_size;
// - bit array (made of ints) for the prop animation key states
actor->m_net_propanimkey_buf_size =
(actor->m_prop_anim_key_states.size() / 8) + // whole chars
(size_t)(actor->m_prop_anim_key_states.size() % 8 != 0); // remainder: 0 or 1 chars
actor->m_net_total_buffer_size += actor->m_net_propanimkey_buf_size;

if (rq.asr_origin == ActorSpawnRequest::Origin::NETWORK)
{
Expand Down
Loading