using System.Collections.Generic; using CounterDrone.Core; using CounterDrone.Core.Algorithms; using CounterDrone.Core.Models; using CounterDrone.Core.Simulation; using UnityEngine; using AVector3 = CounterDrone.Core.Algorithms.Vector3; namespace CounterDrone.Unity { [ExecuteAlways] public class ManagerVerification : MonoBehaviour { [ContextMenu("Run Full Verification")] void Run() { Debug.Log("===== Manager Verification Start ====="); var paths = new UnityPathProvider(); if (System.IO.File.Exists(paths.GetMainDbPath())) System.IO.File.Delete(paths.GetMainDbPath()); if (System.IO.Directory.Exists(paths.GetFramesDir())) System.IO.Directory.Delete(paths.GetFramesDir(), true); var modelMgr = gameObject.AddComponent(); modelMgr.Awake(); Debug.Log("1. ModelManager OK"); var scenarioMgr = gameObject.AddComponent(); scenarioMgr.Awake(); var task = scenarioMgr.CreateTask("Verification", ""); var taskId = task.Id; Debug.Log($"2. ScenarioManager OK. Task: {taskId}"); scenarioMgr.SaveScene(taskId, new CombatScene { WindSpeed = 0 }); scenarioMgr.SaveTarget(taskId, new TargetConfig { GroupId = "default", TargetType = (int)TargetType.Piston, PowerType = (int)PowerType.Piston, Quantity = 1, TypicalSpeed = 200, TypicalAltitude = 500, }); scenarioMgr.SaveRoute(taskId, "default", new RoutePlan { FormationMode = (int)FormationMode.Single }, new List { new Waypoint { PosX = 0, PosY = 500, PosZ = 0 }, new Waypoint { PosX = 10000, PosY = 500, PosZ = 0 }, }); scenarioMgr.UpdateStep(taskId, 3); Debug.Log("3. Scenario configured"); var db = new DatabaseManager(paths).OpenMainDb(); SqliteConnectionTracker.Track(db); foreach (var a in DefaultAmmunition.GetAll()) db.Insert(a); var ammoCatalog = db.Table().ToList(); var detail = scenarioMgr.GetDetail(taskId); var droneGroup = new DroneGroup { GroupId = "default", Target = detail.Targets[0], Route = detail.Routes[0], Waypoints = detail.WaypointGroups["default"], }; var fireUnits = new List(); for (int i = 0; i < 8; i++) fireUnits.Add(new FireUnit { Id = $"u{i}", Type = PlatformType.GroundBased, Position = new AVector3(5000 + i * 50, 0, 50), MuzzleVelocity = 800, TotalMunitions = 3, AmmoTypes = new() { AerosolType.InertGas, AerosolType.ActiveMaterial, AerosolType.ActiveFuel }, }); var result = new DefensePlanner(ammoCatalog, PlannerConfig.Load(paths)).Plan(fireUnits, new List { droneGroup }, detail.Scene, new List()); scenarioMgr.SaveCloud(taskId, new CloudDispersal { PositionX = (droneGroup.Waypoints[0].PosX + droneGroup.Waypoints[^1].PosX) / 2, PositionY = (droneGroup.Waypoints[0].PosY + droneGroup.Waypoints[^1].PosY) / 2, PositionZ = (droneGroup.Waypoints[0].PosZ + droneGroup.Waypoints[^1].PosZ) / 2, DisperseHeight = droneGroup.Target.TypicalAltitude, }); var equips = new List(); foreach (var u in fireUnits) equips.Add(new EquipmentDeployment { EquipmentRole = (int)EquipmentRole.LaunchPlatform, PlatformType = (int)u.Type, Quantity = 1, PositionX = u.Position.X, PositionY = u.Position.Y, PositionZ = u.Position.Z, AerosolType = (int)u.AmmoTypes[0], MunitionCount = u.TotalMunitions, Cooldown = u.Cooldown, MuzzleVelocity = u.MuzzleVelocity, CruiseSpeed = u.CruiseSpeed > 0 ? u.CruiseSpeed : null, ReleaseAltitude = u.ReleaseAltitude > 0 ? u.ReleaseAltitude : null, }); scenarioMgr.SaveDeployment(taskId, equips); SqliteConnectionTracker.Untrack(db); db.Dispose(); var plan = result.Best; Debug.Log($"4. Plan: {plan.ThreatsEngaged} threats engaged, {plan.MergedSchedule.Count} rounds, prob={plan.OverallProbability:P0}"); var runner = gameObject.AddComponent(); runner.Awake(); runner.LoadAndStart(taskId); runner.Engine.TimeScale = 10f; float endTime = Time.realtimeSinceStartup + 60f; int frameCount = 0; float tickDt = 1f / 20f; while (runner.Engine.State == SimulationState.Running && Time.realtimeSinceStartup < endTime) { runner.Engine.Tick(tickDt); frameCount++; } Debug.Log($"5. Simulation done. State={runner.Engine.State}, DroneStatus={runner.Engine.Drones[0].Status}, HP={runner.Engine.Drones[0].Hp:F2}, Frames={frameCount}"); runner.Stop(); var reportMgr = gameObject.AddComponent(); reportMgr.Awake(); detail = scenarioMgr.GetDetail(taskId); var simEvents = new List(runner.Engine.Events); var status = runner.Engine.Drones.Count > 0 ? runner.Engine.Drones[0].Status.ToString() : "Unknown"; var report = reportMgr.Generate(taskId, detail, simEvents, status, runner.Engine.SimulationTime); var path = reportMgr.Export(report.Id); Debug.Log($"6. Report OK. Exported: {path}"); var replay = gameObject.AddComponent(); replay.Awake(); replay.LoadReplay(taskId); Debug.Log($"7. Replay OK. {replay.TotalFrames} frames, {replay.CurrentFrames.Count} records"); Debug.Log("===== ALL MANAGERS VERIFIED ====="); } } }