feat(entity): the object's interaction distance, preconditions and world state, as the client

LWOGameObject loads these itself: interactionDistance from its Objects row
(16 without one) and the level's interaction_distance over it,
CheckPrecondition and objectWorldState from the level config, before its
components load theirs. The quickbuild, the pet and the race instancer read
them from the object; the race instancer now uses the Objects row's
distance like the client does, instead of a fixed 16.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Aaron Kimbrell
2026-10-02 08:44:53 -05:00
parent 0c215de446
commit 6f4fd4054a
10 changed files with 47 additions and 7 deletions

View File

@@ -436,6 +436,18 @@ void Entity::DoObjectComponentLoad(ObjectLoadState& state) {
if (!triggerInfo.empty()) AddComponent<TriggerComponent>(-1, triggerInfo);
}
void Entity::LoadTemplateData() {
const auto& object = CDClientManager::GetTable<CDObjectsTable>()->GetByID(m_TemplateID);
if (object.id == m_TemplateID && object.interactionDistance >= 0.0f) m_InteractionDistance = object.interactionDistance;
}
// The client erases interaction_distance from the config once read; server scripts still read it, so it stays
void Entity::LoadConfigData() {
if (HasVar(u"interaction_distance")) m_InteractionDistance = GetVarAs<float>(u"interaction_distance");
if (HasVar(u"objectWorldState")) m_ObjectWorldState = GetVarAs<int32_t>(u"objectWorldState");
if (HasVar(u"CheckPrecondition")) m_CheckPrecondition = GetVar<std::u16string>(u"CheckPrecondition");
}
void Entity::Initialize() {
RegisterMsg(&Entity::MsgRequestServerObjectInfo);
RegisterMsg(&Entity::MsgDropClientLoot);
@@ -464,13 +476,16 @@ void Entity::Initialize() {
m_ParentEntity->AddChild(this);
}
LoadTemplateData();
m_LoadingComponents = true;
auto loadState = DoObjectPreLoad();
DoObjectComponentLoad(loadState);
m_LoadingComponents = false;
// LWOGameObject::MakeReadyForSerialization (0x0101c230): every component exists; each loads the object's config,
// then a character's save, in the order they were made
// LWOGameObject::MakeReadyForSerialization (0x0101c230): every component exists; the object loads its config, then
// each component the config and a character's save, in the order they were made
LoadConfigData();
for (auto* const component : m_ComponentList) {
component->LoadConfigData();
if (m_Character) component->LoadFromSaveData(m_Character->GetXMLDoc());