FireControl.Apply now switches on the frozen shot.Fuse: a null fuse keeps 12.3's lane path (ApplyDirectHit), a proximity fuse detonates at arrival with no roll, and a contact or delayed fuse detonates only on a committed hit (ApplyBlastHit), locating P through Lane and the new Reach owner (moved verbatim from Apply's own inline penetration clip; the delayed fuse point reads the identical rule). Step has no damage branch left. Detonate (FireControl.cs) is the one owner of blast damage: candidates by centre-plus-half-diagonal, exact circle/cell overlap shares computed once, every blast's shield decided live per Q12-9 = A (including the host of a contact/delayed blast -- Commit now gates its own shield decision on shot.Fuse == null), armour absorbed per cell, and each item's covered cells pooled into one ItemAbsorb call. Entity.Absorb and FireControl.Splash are deleted; Entity gains ToSchematicPoint/ToWorldPoint for the point conversion Detonate and the delayed fuse point need. Mine.Explode now calls Detonate. Existing Splash/Absorb-era tests across Cut4/5/6/11/123 are rewritten or retargeted to the new public owners; behavioural coverage for the blast model itself lands separately. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
63 lines
2.2 KiB
C#
63 lines
2.2 KiB
C#
using System.Collections;
|
|
using UnityEngine;
|
|
using static CultMath.math;
|
|
|
|
// Cut 3 (docs/fire-control-cut.md): the raycast, shield branch and SendHit are deleted -- FireControl already
|
|
// decided this shot's fate before this object was ever spawned (R8). What is left is pure flight-path
|
|
// presentation: fly, and disappear at Range or ShotId's resolution, whichever comes first.
|
|
// Cut 6b, 6.2 (12.4(b): Apply's own switch on the frozen Fuse decides this now, not Step): the flak-round
|
|
// blast resolves in the simulation, through FireControl.Detonate -- a MonoBehaviour calling it would be
|
|
// exactly the authority Cut 3 spent itself deleting, so the blast-distance/blast-radius fields this object
|
|
// used to carry for that are gone. This object's job stays fly-and-disappear.
|
|
public class Projectile : MonoBehaviour
|
|
{
|
|
public TrailRenderer Trail;
|
|
public float Gravity;
|
|
public float Drag = .1f;
|
|
public Prototype HitEffect;
|
|
|
|
private bool _alive;
|
|
|
|
// Cut 3: FireControl.Fire's ShotId -- this projectile's handle onto Zone.ShotCommitted/ShotResolved.
|
|
public int ShotId { get; set; }
|
|
public Zone Zone { get; set; }
|
|
|
|
public Vector3 StartPosition { get; set; }
|
|
public Vector3 Velocity { get; set; }
|
|
public Entity SourceEntity { get; set; }
|
|
public float Range { get; set; }
|
|
|
|
private void OnEnable()
|
|
{
|
|
_alive = true;
|
|
}
|
|
|
|
// Update is called once per frame
|
|
void Update()
|
|
{
|
|
if (SourceEntity == null) return;
|
|
|
|
if(_alive)
|
|
{
|
|
var t = transform;
|
|
Velocity -= Vector3.up * (Gravity * Time.deltaTime);
|
|
Velocity *= max(0, 1 - Drag * Time.deltaTime);
|
|
t.forward = Velocity.normalized;
|
|
|
|
transform.position += Velocity * Time.deltaTime;
|
|
var distanceTraveled = (transform.position - StartPosition).magnitude;
|
|
if(distanceTraveled > Range)
|
|
StartCoroutine(Kill());
|
|
}
|
|
}
|
|
|
|
IEnumerator Kill()
|
|
{
|
|
_alive = false;
|
|
var startTime = Time.time;
|
|
var lifetime = Trail.time;
|
|
while (Time.time - startTime < lifetime)
|
|
yield return null;
|
|
GetComponent<Prototype>().ReturnToPool();
|
|
}
|
|
}
|