6.1 (Soul finding 6): Commit builds a local CultMath.Random from (Zone.CombatSeed, shot.ShotId) instead of reading and writing the shared ItemManager.Random stream. Zone exposes CombatSeed (the same expression that already seeds its own _random), so a shot's outcome is a pure function of zone identity and shot id -- immune to whatever else drew from the shared stream in between. 6.2 (Soul finding 5): airburst is wired into the simulation instead of back into Projectile.cs. PendingShot gains BurstPosition/BurstRadius, frozen at Fire time from PredictedIntercept and the weapon's authored WeaponItemData.AirburstRange when WeaponModifiers carries Airburst. FireControl.Step resolves such a shot via Splash instead of Apply, never both. Projectile.cs/ProjectileManager.cs drop the dead AirburstDistance/AirburstRange fields and write-back. Tests: FireControlCut6Tests.cs pins both rules (208 baseline + 5 new, all green). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
32 lines
1.3 KiB
C#
32 lines
1.3 KiB
C#
using System.Collections;
|
|
using System.Collections.Generic;
|
|
using UnityEngine;
|
|
using Random = UnityEngine.Random;
|
|
|
|
public class ProjectileManager : InstantWeaponEffectManager
|
|
{
|
|
public Prototype ProjectilePrototype;
|
|
public bool InheritVelocity;
|
|
|
|
public override void Fire(InstantWeapon weapon, EquippedItem item, EntityInstance source, EntityInstance target, int shotId)
|
|
{
|
|
var p = ProjectilePrototype.Instantiate<Projectile>();
|
|
var hp = source.Entity.Hardpoints[item.Position.x, item.Position.y];
|
|
var barrel = source.GetBarrel(hp);
|
|
var angle = weapon.Spread / 2;
|
|
p.ShotId = shotId;
|
|
p.SourceEntity = source.Entity;
|
|
p.Velocity = Quaternion.Euler(
|
|
Random.Range(-angle, angle),
|
|
Random.Range(-angle, angle),
|
|
Random.Range(-angle, angle)) *
|
|
barrel.forward *
|
|
weapon.Velocity;
|
|
p.StartPosition = p.transform.position = barrel.position + p.Velocity * (Random.value * Time.deltaTime);
|
|
if(InheritVelocity)
|
|
p.Velocity += new Vector3(source.Entity.Velocity.x, 0, source.Entity.Velocity.y);
|
|
p.Range = weapon.Range;
|
|
p.Zone = source.Entity.Zone;
|
|
p.Trail.Clear();
|
|
}
|
|
}
|