refactor(entity): each component type has an allocator, as the client

DoObjectComponentLoad walks the client's load order and calls the type's
allocator from a table, like ObjectLoader2, instead of one 76-case switch.
Components with rules of their own have a static Allocator (the client's
LWOxComponent::Allocator); the rest share a registry allocator. The load
state moves to ObjectLoadState.h so the allocators can take it.

Construction bytes are identical for all 15,962 LOTs.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Aaron Kimbrell
2026-10-02 08:11:58 -05:00
parent 3a79286666
commit 260e6cb1b1
52 changed files with 634 additions and 684 deletions

View File

@@ -32,6 +32,7 @@
#include "StringifiedEnum.h"
#include "Amf3.h"
#include "EconomyLedger.h"
#include "ObjectLoadState.h"
QuickBuildComponent::QuickBuildComponent(Entity* const entity, const int32_t componentID) : ActivityComponent{ entity, componentID } {
RegisterMsg(&QuickBuildComponent::OnRequestUse);
@@ -779,3 +780,16 @@ bool QuickBuildComponent::OnGetObjectReportInfo(GameMessages::GetObjectReportInf
quickbuild.PushDebug<AMFStringValue>("Builder", "LWOOBJID") = std::to_string(m_Builder);
return true;
}
void QuickBuildComponent::Allocator(Entity& entity, ObjectLoadState& state) {
const auto quickBuildComponentID = state.GetComponentID(eReplicaComponentType::QUICK_BUILD);
if (quickBuildComponentID > 0) {
entity.AddComponent<QuickBuildComponent>(quickBuildComponentID);
// A quick build without a destroyable gets one (componentID -1) and is smashable, as the client makes it
// (DoObjectComponentLoad); live: health 1 / 1.0, armor 1 / 0, faction -1, smashable (AG LOT 7804)
if (!entity.HasComponent(eReplicaComponentType::DESTROYABLE)) {
entity.AddComponent<DestroyableComponent>(-1, true);
}
}
}