research(vfx): pin retail projectile and effect oracle

Establish the executable-backed PhysicsDesc, sequence-gate, PhysicsScript, CreateBlocking, particle-anchor, projectile, and Hidden-state behavior before changing runtime code. Correct stale blocking/threshold claims and synchronize the project instructions with the current UI architecture and matching retail binary.

Add copyright-safe packet and DAT-container fixtures plus a failing installed-DAT conformance audit for projectile shapes, typed tables, recall motion, default scripts, and raw CreateBlocking inventory.

Co-Authored-By: Codex <noreply@openai.com>
This commit is contained in:
Erik 2026-07-13 22:40:42 +02:00
parent bb5acab9e6
commit d53fe30ffe
14 changed files with 1545 additions and 53 deletions

View file

@ -69,7 +69,13 @@ Both carry a single `uint EmitterId` (lines 27-30 of respective generated files)
### `CreateBlockingParticleHook`
Source: `Generated/Types/CreateBlockingParticleHook.generated.cs:22-37`**empty body** in the dat. The "blocking" variant is a runtime behavior flag, not a data field.
The generated package type has an empty body, but that is a schema defect, not
the retail DAT layout. Retail `CreateBlockingParticleHook::Execute`
(`0x00526EF0`) reads the complete inherited `CreateParticleHook` payload:
emitter DID, part index, full offset frame, and logical emitter ID. At runtime
`ParticleManager::CreateBlockingParticleEmitter` (`0x0051B8A0`) suppresses the
create only while the same nonzero logical emitter ID is already live. It does
not pause animation progression.
### Companion: `ParticleEmitter` / `ParticleEmitterInfo` (DB_TYPE_PARTICLE_EMITTER, `0x32000000..0x3200FFFF`)
@ -105,11 +111,14 @@ Source: `Generated/DBObjs/PhysicsScriptTable.generated.cs:22-59`.
```csharp
Dictionary<PlayScript, PhysicsScriptTableData> ScriptTable;
// PlayScript enum = Create, Destroy, Die, Hit, Dodge, etc. (62 values)
// PhysicsScriptTableData = List<ScriptAndModData> Scripts (weighted variants)
// PhysicsScriptTableData = List<ScriptAndModData> Scripts (stored-order thresholds)
// ScriptAndModData = { float Mod; QualifiedDataId<PhysicsScript> ScriptId; }
```
Used by PhysicsObj (`desc.PhsTableID` → 0x2C-tagged). Enables "when I die, pick a death-sound script with weight = Mod". Not relevant for sky, but relevant for NPC/monster/spell PES.
Used by PhysicsObj (`desc.PhsTableID` → 0x2C-tagged). Retail walks entries in
stored DAT order and returns the first whose `intensity <= Mod`; `Mod` is an
upper threshold, not a random weight. Equality matches, and there is no
sorting or fallback-to-first. This is relevant for NPC/monster/spell PES.
### Retail factory registration (chunk_00410000.c:13439-13451)