+using Sandbox.Game.Entities.Cube;
+using Sandbox.Game.EntityComponents;
+//using Sandbox.ModAPI;
+using Sandbox.ModAPI.Ingame;
+using Sandbox.ModAPI.Interfaces;
+
+using SpaceEngineers.Game.ModAPI.Ingame;
+
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.Collections.Immutable;
+using System.Linq;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+using System.Text;
+
+using VRage;
+using VRage.Collections;
+using VRage.Game;
+using VRage.Game.Components;
+using VRage.Game.GUI.TextPanel;
+using VRage.Game.ModAPI.Ingame;
+using VRage.Game.ModAPI.Ingame.Utilities;
+using VRage.Game.ObjectBuilders.Definitions;
+
+using VRageMath;
+
+namespace IngameScript
+{
+ partial class Program : MyGridProgram
+ {
+ const string MISSILE_GRID_PREFIX = "[PM]";
+
+ const float EPSILON = 0.05f;
+ const double DELAY_BEFORE_TRAVELLING_MODE = 3000; // [ms].
+ const double AUTO_DESTRUCTION_AFTER = 60000; // [ms] (1 min).
+
+
+ enum State
+ {
+ NORMAL,
+ LAUNCHING,
+ TRAVELLING,
+ }
+
+ State currentState = State.NORMAL;
+
+ readonly Output output;
+
+ int tickFromStart;
+ IMyThrust forwardThruster;
+ IMyFlightMovementBlock aiMove;
+ IMyOffensiveCombatBlock aiCombat;
+ IMySensorBlock sensor;
+ List<IMyWarhead> warheads = new List<IMyWarhead>();
+ IMyGasTank gasTank;
+ IMyLightingBlock light;
+
+ public Program()
+ {
+ var output = this.Me.GetSurface(0);
+ this.output = new Output(output);
+
+ this.output.Print("Missile controller system starting...");
+
+ this.Runtime.UpdateFrequency = UpdateFrequency.Update10;
+
+ this.output.Print("Missile controller system started");
+ }
+
+ void UpdateState10()
+ {
+ if (this.forwardThruster == null)
+ this.forwardThruster = this.GridTerminalSystem.GetBlockWithName("[PM] Hydrogen Thruster 01") as IMyThrust;
+ if (this.forwardThruster == null)
+ {
+ this.output.Print("Error: Cannot find forward thruster");
+ return;
+ }
+
+ if (this.aiMove == null)
+ this.aiMove = this.GridTerminalSystem.GetBlockWithName("[PM] AI Flight (Move)") as IMyFlightMovementBlock;
+ if (this.aiMove == null)
+ {
+ this.output.Print("Error: Cannot find AI move");
+ return;
+ }
+
+ if (this.aiCombat == null)
+ this.aiCombat = this.GridTerminalSystem.GetBlockWithName("[PM] AI Offensive (Combat)") as IMyOffensiveCombatBlock;
+ if (this.aiCombat == null)
+ {
+ this.output.Print("Error: Cannot find AI combat");
+ return;
+ }
+
+ if (this.sensor == null)
+ this.sensor = this.GridTerminalSystem.GetBlockWithName("[PM] Sensor") as IMySensorBlock;
+ if (this.sensor == null)
+ {
+ this.output.Print("Error: Cannot find sensor");
+ return;
+ }
+
+ if (this.warheads.Count == 0)
+ this.GridTerminalSystem.GetBlockGroupWithName("[PM] Warheads").GetBlocksOfType(this.warheads);
+ if (this.warheads.Count == 0)
+ {
+ this.output.Print("Error: Cannot find any warhead");
+ return;
+ }
+
+ if (this.gasTank == null)
+ this.gasTank = this.GridTerminalSystem.GetBlockWithName("[PM] Hydrogen Tank") as IMyGasTank;
+ if (this.gasTank == null)
+ {
+ this.output.Print("Error: Cannot find gas tank");
+ return;
+ }
+
+ if (this.light == null)
+ this.light = this.GridTerminalSystem.GetBlockWithName("[PM] Light") as IMyLightingBlock;
+ if (this.light == null)
+ {
+ this.output.Print("Error: Cannot find light");
+ return;
+ }
+
+ switch (this.currentState)
+ {
+ case State.LAUNCHING:
+ // this.output.Print($"Tick: {this.tickFromStart}");
+ //this.forwardThruster.ove
+ this.forwardThruster.ThrustOverridePercentage = 1;
+ if (this.MsSinceLaunch > DELAY_BEFORE_TRAVELLING_MODE)
+ {
+ this.forwardThruster.ThrustOverridePercentage = 0;
+ this.aiMove.Enabled = true;
+ this.aiCombat.Enabled = true;
+
+ foreach (var warhead in this.warheads)
+ warhead.IsArmed = true;
+
+ this.output.Print($"Travelling mode");
+ this.currentState = State.TRAVELLING;
+ }
+ break;
+
+ case State.TRAVELLING:
+ var detectedEntity = this.sensor.LastDetectedEntity;
+
+ if (this.MsSinceLaunch > AUTO_DESTRUCTION_AFTER - 3000)
+ this.light.BlinkIntervalSeconds = 0.5f;
+
+ if (this.gasTank.FilledRatio <= EPSILON || detectedEntity.Type != MyDetectedEntityType.None || this.MsSinceLaunch > AUTO_DESTRUCTION_AFTER)
+ {
+ Detonate();
+ }
+ break;
+
+ case State.NORMAL:
+ break; // Nothing;
+ }
+ }
+
+ void Detonate()
+ {
+ foreach (var warhead in this.warheads)
+ warhead.Detonate();
+ }
+
+ public void Save()
+ {
+ }
+
+ double MsSinceLaunch
+ {
+ get { return (double)this.tickFromStart / 60 * 1000; }
+ }
+
+ public void Main(string argument, UpdateType updateSource)
+ {
+ if ((updateSource & UpdateType.Update10) != 0)
+ {
+ this.tickFromStart += 10;
+ this.UpdateState10();
+ }
+ else if ((updateSource & (UpdateType.Script | UpdateType.Terminal | UpdateType.Trigger)) != 0)
+ {
+ switch (argument)
+ {
+ case "START":
+ this.output.Print("Launching mode");
+ this.tickFromStart = 0;
+ this.currentState = State.LAUNCHING;
+ break;
+
+ default:
+ this.output.Print($"Uknown command: {argument}");
+ break;
+ }
+ }
+ }
+ }
+}