mirror of
https://github.com/DarkflameUniverse/DarkflameServer.git
synced 2026-10-02 10:53:44 +00:00
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:
@@ -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;
|
||||
|
||||
@@ -36,6 +36,10 @@ public:
|
||||
* @param originator the entity that triggered the event
|
||||
*/
|
||||
void OnCancelRailMovement(Entity* originator);
|
||||
|
||||
bool GetDamageImmune() const { return m_DamageImmune; }
|
||||
bool GetNoAggro() const { return m_NoAggro; }
|
||||
bool GetShowNameBillboard() const { return m_ShowNameBillboard; }
|
||||
private:
|
||||
/**
|
||||
* The entities that are currently traversing the rail
|
||||
|
||||
@@ -2,6 +2,7 @@ set(DCOMPONENTS_TESTS
|
||||
"DeletionRestrictionTests.cpp"
|
||||
"InventorySaveTests.cpp"
|
||||
"DestroyableLevelConfigTests.cpp"
|
||||
"RailActivatorComponentTests.cpp"
|
||||
"VendorBuybackTests.cpp"
|
||||
"RacingWrongWayTests.cpp"
|
||||
"DestroyableComponentTests.cpp"
|
||||
|
||||
@@ -0,0 +1,59 @@
|
||||
#include "GameDependencies.h"
|
||||
|
||||
#include "CDClientManager.h"
|
||||
#include "CDComponentsRegistryTable.h"
|
||||
#include "CDRailActivatorComponent.h"
|
||||
#include "Entity.h"
|
||||
#include "RailActivatorComponent.h"
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
// The rider flags come from the RailActivatorComponent row; a level key, when there, replaces the row's value.
|
||||
class RailActivatorComponentTests : public GameDependenciesTest {
|
||||
protected:
|
||||
static constexpr int32_t COMPONENT_ID = 9999;
|
||||
std::unique_ptr<Entity> entity;
|
||||
|
||||
void SetUp() override {
|
||||
SetUpDependencies();
|
||||
CDRailActivatorComponent row{};
|
||||
row.id = COMPONENT_ID;
|
||||
row.damageImmune = true;
|
||||
row.noAggro = true;
|
||||
row.showNameBillboard = true;
|
||||
CDClientManager::GetEntriesMutable<CDRailActivatorComponentTable>().push_back(row);
|
||||
|
||||
// The entity's own LOT has no components, so it doesn't look anything up in a database
|
||||
CDClientManager::GetEntriesMutable<CDComponentsRegistryTable>().insert_or_assign(static_cast<uint64_t>(info.lot), 0);
|
||||
entity = std::make_unique<Entity>(1, info);
|
||||
}
|
||||
|
||||
void TearDown() override {
|
||||
entity.reset();
|
||||
CDClientManager::GetEntriesMutable<CDRailActivatorComponentTable>().clear();
|
||||
TearDownDependencies();
|
||||
}
|
||||
};
|
||||
|
||||
TEST_F(RailActivatorComponentTests, WithoutLevelKeysTheRowIsUsed) {
|
||||
const auto* const rail = entity->AddComponent<RailActivatorComponent>(COMPONENT_ID);
|
||||
EXPECT_TRUE(rail->GetDamageImmune());
|
||||
EXPECT_TRUE(rail->GetNoAggro());
|
||||
EXPECT_TRUE(rail->GetShowNameBillboard());
|
||||
}
|
||||
|
||||
TEST_F(RailActivatorComponentTests, LevelKeysReplaceTheRow) {
|
||||
entity->SetVar<bool>(u"rail_activator_damage_immune", false);
|
||||
entity->SetVar<bool>(u"rail_no_aggro", false);
|
||||
entity->SetVar<bool>(u"rail_show_name_billboard", false);
|
||||
const auto* const rail = entity->AddComponent<RailActivatorComponent>(COMPONENT_ID);
|
||||
EXPECT_FALSE(rail->GetDamageImmune());
|
||||
EXPECT_FALSE(rail->GetNoAggro());
|
||||
EXPECT_FALSE(rail->GetShowNameBillboard());
|
||||
}
|
||||
|
||||
TEST_F(RailActivatorComponentTests, NoRowAndNoKeysIsNotImmune) {
|
||||
const auto* const rail = entity->AddComponent<RailActivatorComponent>(COMPONENT_ID + 1);
|
||||
EXPECT_FALSE(rail->GetDamageImmune());
|
||||
EXPECT_FALSE(rail->GetNoAggro());
|
||||
}
|
||||
Reference in New Issue
Block a user