fix(rails): rider flags default to the RailActivatorComponent row

StartRailMovement's bDamageImmune, bNoAggro and bShowNameBillboard came
only from the level keys rail_activator_damage_immune, rail_no_aggro and
rail_show_name_billboard, which 23 of the 80 level rails do not have, so
those rails sent false. The client reads the same flags from the
RailActivatorComponent row (DamageImmune, NoAggro, ShowNameBillboard; all
11 rows are 1) in LWOPlayerForcedMovementComponent::LoadRailData
(0x00c85dc0), and the message's values replace the row's unless bUseDB
(msgStartRailMovement 0x00ccd9c0). The server now takes the row's value
and lets a level key replace it when the key is there. Wire format is
unchanged; only the flag values sent for the 23 rails change (to true,
matching the 5 live samples).

In game: ride the 23 rails without the keys, all in the Ninjago earth gauntlet
(earthgauntlet levels: dart spinners, 8 spinners, millstones, boss) near enemies: you are not
damaged or targeted while riding, and name billboards behave as on the
other rails.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Aaron Kimbrell
2026-09-28 23:34:42 -05:00
parent 54cd9abd7a
commit 7440e5744d
4 changed files with 73 additions and 3 deletions

View File

@@ -33,10 +33,16 @@ RailActivatorComponent::RailActivatorComponent(Entity* parent, const int32_t com
m_LoopEffect = tableData.loopEffectID;
m_StopEffect = tableData.stopEffectID;
m_DamageImmune = parent->GetVar<bool>(u"rail_activator_damage_immune");
m_NoAggro = parent->GetVar<bool>(u"rail_no_aggro");
// The RailActivatorComponent row gives these (the client reads DamageImmune, NoAggro and ShowNameBillboard in
// LWOPlayerForcedMovementComponent::LoadRailData 0x00c85dc0); a level key, when there, replaces the row's value
// as StartRailMovement's flags replace the row's in msgStartRailMovement (0x00ccd9c0) unless bUseDB is set.
const auto levelOr = [parent](const std::u16string& key, const bool tableValue) {
return parent->HasVar(key) ? parent->GetVar<bool>(key) : tableValue;
};
m_DamageImmune = levelOr(u"rail_activator_damage_immune", tableData.damageImmune);
m_NoAggro = levelOr(u"rail_no_aggro", tableData.noAggro);
m_NotifyArrived = parent->GetVar<bool>(u"rail_notify_activator_arrived");
m_ShowNameBillboard = parent->GetVar<bool>(u"rail_show_name_billboard");
m_ShowNameBillboard = levelOr(u"rail_show_name_billboard", tableData.showNameBillboard);
m_UseDB = parent->GetVar<bool>(u"rail_use_db");
m_CameraLocked = tableData.cameraLocked;
m_CollisionEnabled = tableData.playerCollision;