Commit Graph

222 Commits

Author SHA1 Message Date
Aaron Kimbrell
0138d45c58 fix(component): the zone control object constructs as on live
Minigame control (50) is an activity component in the client
(LWOMinigameComponent) and is made from the registry, so the zone control
object (LOT 2365, registry id 0) has one; it sends what an activity sends
(dirty, no players), not a fixed 0x40000000 (which nothing sent: the old
id > 0 check never made it). The zone's script on that object is server
only: the client makes no script component for it, so it sends nothing.
DLU's zone control construction now equals live's byte for byte (209
captures, e.g. GruntMonkey world2); the decoder reads 50 as an activity.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-01 14:29:02 -05:00
Aaron Kimbrell
4bfdeec369 refactor(component): the quickbuild is an activity component, as in the client
LWOQuickBuildComponent uses the activity component's functions; DLU's
QuickBuildComponent now derives ActivityComponent. Its RebuildComponent row
(the activity among it) loads in LoadDataFromTemplate and the level's
overrides in LoadConfigData, out of Entity::Initialize. It still writes its
own replica data (same construction and update bytes) and spawns its
activator as before.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-01 14:19:49 -05:00
Aaron Kimbrell
d786290803 refactor(entity): models get their physics in the client's model case
ObjectLoader2::LoadModelBehaviorsComponent: a model without physics gets simple
physics 4247 (with behaviors: controllable 4246 for modelType 0, else simple,
or the registry's id, which the simple physics case leaves to it), and
modelType 0 gets pathfinding control. This replaces the BBB model (LOT 14)
special case, which now loads through the registry like any object (same
bytes as live LOT 14 constructions); the 17 other model LOTs without
physics in the registry now get the simple physics the client makes for them.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-01 11:49:38 -05:00
Aaron Kimbrell
9da7b11456 feat(entity): the client's spawner component (10) on spawner objects
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-01 10:19:18 -05:00
Aaron Kimbrell
2f01b85d8a feat(entity): combat AI objects get the client's proximity monitor and pathfinding control
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-01 09:39:52 -05:00
Aaron Kimbrell
aea4949cf3 feat(entity): script objects get the client's proximity monitor and pathfinding control
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-01 09:38:46 -05:00
Aaron Kimbrell
4a546607f7 feat(entity): the client's pathfinding control component (86) on pets
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-01 09:37:17 -05:00
Aaron Kimbrell
c65f559b39 feat(entity): the client's physics system component (47)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-01 09:01:25 -05:00
Aaron Kimbrell
5f77dca7e7 feat(entity): the client's vehicle physics component (46)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-01 09:01:25 -05:00
Aaron Kimbrell
589a91a1f0 feat(entity): the client's projectile physics component (18)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-01 09:01:25 -05:00
Aaron Kimbrell
029e601e07 refactor(component): the destroyable loads itself in the client's phases
The DestructibleComponent row moves from Entity::Initialize into
LoadDataFromTemplate and the level keys into LoadConfigData; a character's
save loads after both. Like the client (LWODestroyableComponent::LoadConfigData
reads them for every destroyable), the destroyables added for models and
quickbuilds now also read set_faction, is_smashable and the level loot matrix;
their live defaults become their template. Nothing changes for objects without
those keys.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-01 08:52:10 -05:00
Aaron Kimbrell
7a0dba22a5 refactor(component): use is a RequestUse message handler
Components no longer have a virtual OnUse; each component that reacts to a
use registers a RequestUse handler, like the client's components. The entity
runs the INTERACT trigger and the script, then delivers a RequestUseEvent
(carrying the user) to the handlers. The mission choice of a multi-interact
use goes only to the mission offer, as before. Switches keep a direct
EnterIfResponding for touches and pets.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-01 07:55:55 -05:00
Aaron Kimbrell
50bfa623ca refactor(component): the client's component lifecycle
Components get the client's per-component functions: LoadDataFromTemplate,
PrepareConfigData, LoadConfigData, LoadFromSaveData, Startup, Run,
OnEnterScope, OnLeaveScope, Preshutdown and Shutdown, called by the entity in
the client's order. Update is renamed Run, LoadFromXml LoadFromSaveData and
UpdateXml WriteSaveData. Nothing sent changes.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-01 07:45:16 -05:00
Aaron Kimbrell
e8406cc829 feat(entity): the client's property plaque component (113)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-01 07:23:03 -05:00
Aaron Kimbrell
0cdf3afe3d feat(entity): the client's roller component (105)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-01 07:21:13 -05:00
Aaron Kimbrell
e585a035e0 feat(entity): the client's gate rush component (103)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-01 07:19:31 -05:00
Aaron Kimbrell
d1a778a140 feat(entity): the client's faction trigger component (72)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-01 07:17:47 -05:00
Aaron Kimbrell
a6381be720 feat(entity): the client's rocket landing component (68)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-01 07:15:54 -05:00
Aaron Kimbrell
8c5e7ee0e1 feat(entity): the client's generic activator component (64)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-01 07:14:12 -05:00
Aaron Kimbrell
a286bea854 feat(entity): the client's showcase model handler component (62)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-01 07:12:31 -05:00
Aaron Kimbrell
4dba9c2aeb feat(entity): the client's custom build assembly component (59)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-01 07:10:50 -05:00
Aaron Kimbrell
6628aa2d45 feat(entity): the client's package component (53)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-01 07:09:10 -05:00
Aaron Kimbrell
464dd759fa feat(entity): the client's choice build component (52)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-01 07:06:54 -05:00
Aaron Kimbrell
bd6e419290 feat(entity): the client's changeling component (51)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-01 07:05:18 -05:00
Aaron Kimbrell
912f5998ae feat(entity): the client's spring pad component (41)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-01 07:03:00 -05:00
Aaron Kimbrell
b4c25a2512 feat(entity): the client's model builder component (38)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-01 07:01:24 -05:00
Aaron Kimbrell
6d185b6e2f feat(entity): the client's arcade component (29)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-01 06:59:38 -05:00
Aaron Kimbrell
0e37994d6c feat(entity): the client's module (a car or rocket part) component (28)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-01 06:57:54 -05:00
Aaron Kimbrell
62c770aa56 feat(entity): the client's blueprint component (24)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-01 06:56:19 -05:00
Aaron Kimbrell
e2b2c4c48d feat(entity): the client's chest component (22)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-01 06:54:42 -05:00
Aaron Kimbrell
939e30e6a8 feat(entity): the client's rebuild activator component (14)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-01 06:53:03 -05:00
Aaron Kimbrell
d4cd459747 feat(entity): the client's build controller component (13)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-01 06:51:13 -05:00
Aaron Kimbrell
60aaa9ec3f feat(entity): the client's modular build (rocket and car building) component (12)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-01 06:49:28 -05:00
Aaron Kimbrell
b9ad46a52e feat(entity): the client's platform boundary component (27)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-01 06:46:20 -05:00
Aaron Kimbrell
a9c4a2fe26 feat(entity): the client's culling plane component (116)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-01 06:43:53 -05:00
Aaron Kimbrell
e37f919700 feat(entity): the client's 3D ambient sound component (56)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-01 06:41:32 -05:00
Aaron Kimbrell
ba748d17d2 feat(entity): the client's 2D ambient sound component (55)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-01 06:39:41 -05:00
Aaron Kimbrell
b971d91a25 feat(entity): the client's sound repeater component (54)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-01 06:38:00 -05:00
Aaron Kimbrell
ee86102e97 feat(entity): NPC minifigures have the client's minifig component
The client makes LWOMiniFigComponent (35) from the registry; DLU had nothing for it. It sends nothing (the client reads the MinifigComponent row itself), so constructions are unchanged; 488 LOTs gain it (LoaderSnapshotTest).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-01 06:35:45 -05:00
Aaron Kimbrell
822aba4194 fix(entity): a model's destroyable has armor 1, as live sent it
Live constructions of models on a Raven Bluff property (LOT 14, LOT 8069) carry the destroyable with health 1 / 1.0, armor 1 / 0, faction -1, smashable; DLU's had armor 0.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-01 06:33:25 -05:00
Aaron Kimbrell
3bd299d682 fix(entity): a quick build without a destroyable gets one, as the client makes it
DoObjectComponentLoad adds a destroyable (componentID -1) to a quick build that has none and marks it smashable. DLU's quick build wrote three empty flags instead. The construction's destroyable now matches live field for field (AG LOT 7804: health 1 / 1.0, armor 1 / 0, faction -1, smashable). 117 LOTs gain it; nothing else changes (LoaderSnapshotTest).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-01 06:31:19 -05:00
Aaron Kimbrell
cc337a298d fix(entity): models get their item component, as the client makes it
The client makes the registry's item component for models too (only a pet takes it away); DLU skipped it and the model component wrote the item block itself, for the 30 model LOTs without an item row as well, and with the object id as ug_id. Live (Raven Bluff property capture): the item block carries the userModelID for brick built models (LOT 14) and 0 for reward models (LOT 8069). 1,455 LOTs gain the item component; nothing else changes (LoaderSnapshotTest).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-01 06:27:36 -05:00
Aaron Kimbrell
b2192e158c refactor(entity): components are made in the client's load order
Entity::Initialize walks ComponentOrderVector::Initialize's list (0x0101f8e0) as ObjectLoader2::DoObjectComponentLoad does; ids a component needs from a later one come from the registry; the trigger is added after the walk. All 15,962 LOTs get the same components as before (LoaderSnapshotTest).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-01 06:17:06 -05:00
Aaron Kimbrell
c11fd81154 fix(entity): a proximity monitor row with one radius no longer crashes the world (LOT 9833)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-01 06:13:18 -05:00
Aaron Kimbrell
c6f6aa5d2b fix(scripts): AG elevator, bus door and property platform drive their movers as their live scripts did
StopPathing, StartPathing and GoToWaypoint instead of hand-made resyncs; a built platform starts before the scripts hear of it so a script can stop it; the FV tree platform's resync hack is gone.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-30 23:36:00 -05:00
Aaron Kimbrell
72efae54eb feat(moving platform): simple movers and rotaters, chosen as the client chooses
The subcomponent comes from the platformIsMover, platformIsSimpleMover and
platformIsRotater settings; with none set, a platform without a registry
component is a mover and one with a registry component a simple mover (also
when it has an attached path, so the registry ID is passed then too). All
flags set false means no subcomponent.

A simple mover reads its MovingPlatforms row and the platformMove* settings,
is always constructed with its starting point and state as live did, and
travels between its start and start + platformMove in platformMoveTime.
A rotater is written as type 6 with a mover's data.

On arrival platforms fire OnWaypointReached, then OnArrivedAtDesiredWaypoint
at the waypoint they were sent to and OnPlatformAtLastWaypoint at an end.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-30 09:59:55 -05:00
Aaron Kimbrell
898ae024f0 feat(loot): a picked up item says which object it dropped from
Live's AddItemToInventoryClientSync for a picked up drop had
_Metric_Souce_LOT_Int in its extra info on all 2,344 live pickups: the LOT
of the DropClientLoot's source object, 1 when a player was the source
(activity rewards and chests, which drop from the player). DLU sent none.

The drop remembers its source object's LOT when it is registered for the
player, and the pickup sends it. A source object already gone when it drops sends
no key. Package contents keep sending none, as live's did.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-30 07:45:59 -05:00
Aaron Kimbrell
d4e9423264 feat(servers): time the main loops' phases and the known heavy spots
Frames and phase scopes in the world, auth, chat and UGC loops (packets per type, entities, physics, ghosting, replica, spawners, log flush, saves, web requests by route). Scopes at LoadPlayer, CreateEntity, each component's construction, InventoryComponent::LoadXml, script timers and a world's zone load; game database queries in the query helpers; CDClient statements timed through sqlite3_trace_v2 as CDClient <table> (CppSQLite3DB gets a handle accessor). Task 96.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-29 22:26:17 -05:00
Aaron Kimbrell
e017c11aa2 feat(combat): destroyables keep their attack priority
DestructibleComponent.attack_priority is loaded onto the DestroyableComponent as a signed value. The client's
LWODestroyableComponent (LoadDataFromTemplate, 0x00c9f900) starts it at 1 and keeps 1 when the column is empty, and
answers GetAttackPriority with it; the server now does the same so TacArcs can order their targets by it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-29 21:44:48 -05:00
Aaron Kimbrell
e74a7ea701 docs(quickbuild): why the level's activityID wins over the template's
The client reads RebuildComponent.activityID over a level's activityID
unless the level sets actIDovrd, but live followed the level's: the AM
Center draw bridge (LOT 12047) has activityID 12047 without actIDovrd and
dropped no loot in 4 of 4 live completions, where the template's activity 6
would have dropped quickbuild rewards. DLU already does what live did.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-29 13:06:37 -05:00