private static void LaunchMissiles(ProjectileOptions projectileOptions, ref float startTime, Vector3 sourcePosition, ref int missilesRemaining) { if (projectileOptions.targetLocations == null) { Log.Error($"projectileOptions.targetLocations is null!"); missilesRemaining = 0; return; } if (projectileOptions.targetLocations.Count == 0) { Log.Error($"projectileOptions.targetLocations.Count == 0!"); missilesRemaining = 0; return; } TrackedProjectile lastProjectileAdded = null; TrackedProjectile firstProjectileAdded = null; foreach (Vector3 location in projectileOptions.targetLocations) { // projectileOptions.kind (ToVolume, DistributeAmongAllTargets, or EachTarget) // projectileOptions.fireCollisionEventOn (FirstImpact, EachImpact, LastImpact) if (projectileOptions.kind == ProjectileKind.EachTarget) { Log.Debug($"ProjectileKind.EachTarget..."); float saveStartTime = startTime; for (int i = 0; i < projectileOptions.count; i++) { Log.Vector("Target's intended location", location); lastProjectileAdded = AddProjectile(projectileOptions, startTime, sourcePosition, location); if (firstProjectileAdded == null) { firstProjectileAdded = lastProjectileAdded; } startTime += projectileOptions.launchTimeVariance * TimeVariance; } startTime = (startTime + saveStartTime) / 2; } else if (projectileOptions.kind == ProjectileKind.ToVolume) { Log.Debug($"ProjectileKind.ToVolume..."); Log.Error($"Cannot project to volume yet - we need to know the shape!"); } else if (projectileOptions.kind == ProjectileKind.DistributeAmongAllTargets) { Log.Debug($"ProjectileKind.DistributeAmongAllTargets..."); missilesRemaining--; lastProjectileAdded = AddProjectile(projectileOptions, startTime, sourcePosition, location); if (firstProjectileAdded == null) { firstProjectileAdded = lastProjectileAdded; } startTime += projectileOptions.launchTimeVariance * TimeVariance; if (missilesRemaining <= 0) { break; } } } firstProjectileAdded.IsFirst = true; if (lastProjectileAdded != null) { lastProjectileAdded.IsLast = true; } }