feat(vfx): port retail effect scheduling and delivery

This commit is contained in:
Erik 2026-07-14 09:25:44 +02:00
parent 363e046112
commit 96ddfdf175
28 changed files with 2473 additions and 691 deletions

View file

@ -47,22 +47,29 @@ public static class LandblockLoader
// legacy starting-from-1 monotonic Ids — compatible with their assertions
// which check uniqueness within a single landblock.
//
// Latent: if a landblock has >256 stabs (rare), nextId overflows the
// low byte and bleeds into the lbY byte → cross-LB collision. Same
// pattern + same limitation as scenery/interior. Document but don't
// fix in this commit — out of scope for the Tier 1 cache bug fix.
// The low byte reserves 0 for the namespace base and 1..255 for
// entities. Never wrap into the Y byte: a collision here would corrupt
// every renderer/physics/effect table keyed by WorldEntity.Id.
uint stabIdBase = landblockId == 0
? 0u
: 0xC0000000u | ((landblockId >> 24) & 0xFFu) << 16 | ((landblockId >> 16) & 0xFFu) << 8;
uint nextId = stabIdBase == 0 ? 1u : stabIdBase + 1u;
uint AllocateId()
{
if (stabIdBase != 0 && nextId > stabIdBase + 0xFFu)
throw new InvalidDataException(
$"Landblock 0x{landblockId:X8} exceeds the 255-entry static stab id namespace.");
return nextId++;
}
foreach (var stab in info.Objects)
{
if (!IsSupported(stab.Id))
continue;
var stabEntity = new WorldEntity
{
Id = nextId++,
Id = AllocateId(),
SourceGfxObjOrSetupId = stab.Id,
Position = stab.Frame.Origin,
Rotation = stab.Frame.Orientation,
@ -78,7 +85,7 @@ public static class LandblockLoader
continue;
var buildingEntity = new WorldEntity
{
Id = nextId++,
Id = AllocateId(),
SourceGfxObjOrSetupId = building.ModelId,
Position = building.Frame.Origin,
Rotation = building.Frame.Orientation,