feat(physics): port retail projectile integration
Add a pure Core projectile driver for retail clock quanta, final-state acceleration, 50-unit velocity clamping, world-space angular integration, full-3D AlignPath, and oriented Setup-local sphere sweeps. Preserve exact success versus set_frame-only failure semantics, independent Contact/OnWalkable state, and full-cell identity across all landblock directions. Port OBJECTINFO::missile_ignore with explicit weenie/creature metadata, remove the invented transition-step cap, retain PathClipped without arming PerfectClip, and keep authoritative target identity optional. Add malformed-shape/clock, thin-wall, terrain, target-exclusion, frame-spike, failure-state, and boundary conformance coverage. Retire TS-2 and synchronize the architecture, milestones, roadmap, research oracle, and durable physics memory. Co-Authored-By: Codex <noreply@openai.com>
This commit is contained in:
parent
542dcfc384
commit
f02b995e4f
21 changed files with 1669 additions and 263 deletions
|
|
@ -15,7 +15,7 @@ namespace AcDream.Core.Tests.Physics;
|
|||
/// as <c>HasPhysicsBSP = 0x00010000</c>.
|
||||
///
|
||||
/// <para>
|
||||
/// For non-PvP, non-missile movers (M1.5 scope — walking-vs-static), an
|
||||
/// After the whole-object PvP and missile exemption gates, an
|
||||
/// entity with HAS_PHYSICS_BSP_PS in its state tests its BSP exclusively
|
||||
/// — the foot cyl is NEVER tested. The closed cottage door (state
|
||||
/// <c>0x10008</c> = <c>STATIC | REPORT_COLLISIONS | HAS_PHYSICS_BSP</c>)
|
||||
|
|
@ -59,8 +59,8 @@ public class A6P7DispatchRulesTests
|
|||
/// else
|
||||
/// → BSP-only path
|
||||
/// </code>
|
||||
/// For M1.5 scope <c>ebp_1</c> (PvP-target-player) and <c>eax_12</c>
|
||||
/// (missile_ignore) are treated as false. The predicate reduces to:
|
||||
/// The PvP and missile terms are whole-object early exits in the port.
|
||||
/// Once shape dispatch is reached, the predicate is therefore:
|
||||
/// "BSP-only iff <c>HAS_PHYSICS_BSP_PS</c> is set".
|
||||
/// </summary>
|
||||
[Theory]
|
||||
|
|
@ -76,44 +76,28 @@ public class A6P7DispatchRulesTests
|
|||
Assert.Equal(expected, Transition.BspOnlyDispatch(entityState));
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
// W1 (2026-06-24) — named PvP/missile terms are false in M1.5
|
||||
// -----------------------------------------------------------------------
|
||||
|
||||
/// <summary>
|
||||
/// W1: <see cref="Transition.PvpExempt"/> must return false in M1.5.
|
||||
/// When PK ships (M2+) this stub will accept mover + target state;
|
||||
/// the test pins the current named-false value as a guard.
|
||||
/// Retail oracle: <c>CPhysicsObj::FindObjCollisions</c> pc:276808–276841.
|
||||
/// </summary>
|
||||
[Fact]
|
||||
public void W1_PvpExempt_ReturnsFalseInM15Scope()
|
||||
{
|
||||
// PvP hasn't shipped (M1.5); the stub always returns false.
|
||||
Assert.False(Transition.PvpExempt());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// W1: <see cref="Transition.MissileIgnore"/> must return false in M1.5.
|
||||
/// When missiles ship (F.3) this stub will accept mover OBJECTINFO +
|
||||
/// target state; the test pins the current named-false value as a guard.
|
||||
/// A non-missile mover does not trigger the retail missile exemption.
|
||||
/// Retail oracle: <c>OBJECTINFO::missile_ignore</c> pc:274385;
|
||||
/// dispatch use pc:276858–276861.
|
||||
/// </summary>
|
||||
[Fact]
|
||||
public void W1_MissileIgnore_ReturnsFalseInM15Scope()
|
||||
public void NonMissileMover_DoesNotIgnoreOrdinaryTarget()
|
||||
{
|
||||
// Missiles haven't shipped (M1.5); the stub always returns false.
|
||||
Assert.False(Transition.MissileIgnore());
|
||||
var mover = new ObjectInfo();
|
||||
Assert.False(mover.MissileIgnore(
|
||||
targetEntityId: 1u,
|
||||
targetPhysicsState: 0u,
|
||||
targetFlags: EntityCollisionFlags.HasWeenie));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Guard: with both W1 terms false, a BSP-flagged entity still
|
||||
/// dispatches BSP-only — A6.P7 door behavior is unchanged after W1.
|
||||
/// Guard: a BSP-flagged entity that reaches shape dispatch still uses
|
||||
/// only its BSP — A6.P7 door behavior remains unchanged.
|
||||
/// This protects the A6.P7 cottage-door / dungeon-wall fix.
|
||||
/// </summary>
|
||||
[Fact]
|
||||
public void W1_BspOnlyDispatch_DoorStateStillDispatchesBspOnly()
|
||||
public void BspOnlyDispatch_DoorStateStillDispatchesBspOnly()
|
||||
{
|
||||
// Cottage door state from A6.P7 investigation: 0x10008 = STATIC | REPORT | HAS_BSP
|
||||
const uint doorState = 0x00010008u;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue