Add missile launcher and missile controller projects
[SEScripts.git] / MissileController / Program.cs
1 using Sandbox.Game.Entities.Cube;
2 using Sandbox.Game.EntityComponents;
3 //using Sandbox.ModAPI;
4 using Sandbox.ModAPI.Ingame;
5 using Sandbox.ModAPI.Interfaces;
6
7 using SpaceEngineers.Game.ModAPI.Ingame;
8
9 using System;
10 using System.Collections;
11 using System.Collections.Generic;
12 using System.Collections.Immutable;
13 using System.Linq;
14 using System.Runtime.CompilerServices;
15 using System.Runtime.InteropServices;
16 using System.Text;
17
18 using VRage;
19 using VRage.Collections;
20 using VRage.Game;
21 using VRage.Game.Components;
22 using VRage.Game.GUI.TextPanel;
23 using VRage.Game.ModAPI.Ingame;
24 using VRage.Game.ModAPI.Ingame.Utilities;
25 using VRage.Game.ObjectBuilders.Definitions;
26
27 using VRageMath;
28
29 namespace IngameScript
30 {
31 partial class Program : MyGridProgram
32 {
33 const string MISSILE_GRID_PREFIX = "[PM]";
34
35 const float EPSILON = 0.05f;
36 const double DELAY_BEFORE_TRAVELLING_MODE = 3000; // [ms].
37 const double AUTO_DESTRUCTION_AFTER = 60000; // [ms] (1 min).
38
39
40 enum State
41 {
42 NORMAL,
43 LAUNCHING,
44 TRAVELLING,
45 }
46
47 State currentState = State.NORMAL;
48
49 readonly Output output;
50
51 int tickFromStart;
52 IMyThrust forwardThruster;
53 IMyFlightMovementBlock aiMove;
54 IMyOffensiveCombatBlock aiCombat;
55 IMySensorBlock sensor;
56 List<IMyWarhead> warheads = new List<IMyWarhead>();
57 IMyGasTank gasTank;
58 IMyLightingBlock light;
59
60 public Program()
61 {
62 var output = this.Me.GetSurface(0);
63 this.output = new Output(output);
64
65 this.output.Print("Missile controller system starting...");
66
67 this.Runtime.UpdateFrequency = UpdateFrequency.Update10;
68
69 this.output.Print("Missile controller system started");
70 }
71
72 void UpdateState10()
73 {
74 if (this.forwardThruster == null)
75 this.forwardThruster = this.GridTerminalSystem.GetBlockWithName("[PM] Hydrogen Thruster 01") as IMyThrust;
76 if (this.forwardThruster == null)
77 {
78 this.output.Print("Error: Cannot find forward thruster");
79 return;
80 }
81
82 if (this.aiMove == null)
83 this.aiMove = this.GridTerminalSystem.GetBlockWithName("[PM] AI Flight (Move)") as IMyFlightMovementBlock;
84 if (this.aiMove == null)
85 {
86 this.output.Print("Error: Cannot find AI move");
87 return;
88 }
89
90 if (this.aiCombat == null)
91 this.aiCombat = this.GridTerminalSystem.GetBlockWithName("[PM] AI Offensive (Combat)") as IMyOffensiveCombatBlock;
92 if (this.aiCombat == null)
93 {
94 this.output.Print("Error: Cannot find AI combat");
95 return;
96 }
97
98 if (this.sensor == null)
99 this.sensor = this.GridTerminalSystem.GetBlockWithName("[PM] Sensor") as IMySensorBlock;
100 if (this.sensor == null)
101 {
102 this.output.Print("Error: Cannot find sensor");
103 return;
104 }
105
106 if (this.warheads.Count == 0)
107 this.GridTerminalSystem.GetBlockGroupWithName("[PM] Warheads").GetBlocksOfType(this.warheads);
108 if (this.warheads.Count == 0)
109 {
110 this.output.Print("Error: Cannot find any warhead");
111 return;
112 }
113
114 if (this.gasTank == null)
115 this.gasTank = this.GridTerminalSystem.GetBlockWithName("[PM] Hydrogen Tank") as IMyGasTank;
116 if (this.gasTank == null)
117 {
118 this.output.Print("Error: Cannot find gas tank");
119 return;
120 }
121
122 if (this.light == null)
123 this.light = this.GridTerminalSystem.GetBlockWithName("[PM] Light") as IMyLightingBlock;
124 if (this.light == null)
125 {
126 this.output.Print("Error: Cannot find light");
127 return;
128 }
129
130 switch (this.currentState)
131 {
132 case State.LAUNCHING:
133 // this.output.Print($"Tick: {this.tickFromStart}");
134 //this.forwardThruster.ove
135 this.forwardThruster.ThrustOverridePercentage = 1;
136 if (this.MsSinceLaunch > DELAY_BEFORE_TRAVELLING_MODE)
137 {
138 this.forwardThruster.ThrustOverridePercentage = 0;
139 this.aiMove.Enabled = true;
140 this.aiCombat.Enabled = true;
141
142 foreach (var warhead in this.warheads)
143 warhead.IsArmed = true;
144
145 this.output.Print($"Travelling mode");
146 this.currentState = State.TRAVELLING;
147 }
148 break;
149
150 case State.TRAVELLING:
151 var detectedEntity = this.sensor.LastDetectedEntity;
152
153 if (this.MsSinceLaunch > AUTO_DESTRUCTION_AFTER - 3000)
154 this.light.BlinkIntervalSeconds = 0.5f;
155
156 if (this.gasTank.FilledRatio <= EPSILON || detectedEntity.Type != MyDetectedEntityType.None || this.MsSinceLaunch > AUTO_DESTRUCTION_AFTER)
157 {
158 Detonate();
159 }
160 break;
161
162 case State.NORMAL:
163 break; // Nothing;
164 }
165 }
166
167 void Detonate()
168 {
169 foreach (var warhead in this.warheads)
170 warhead.Detonate();
171 }
172
173 public void Save()
174 {
175 }
176
177 double MsSinceLaunch
178 {
179 get { return (double)this.tickFromStart / 60 * 1000; }
180 }
181
182 public void Main(string argument, UpdateType updateSource)
183 {
184 if ((updateSource & UpdateType.Update10) != 0)
185 {
186 this.tickFromStart += 10;
187 this.UpdateState10();
188 }
189 else if ((updateSource & (UpdateType.Script | UpdateType.Terminal | UpdateType.Trigger)) != 0)
190 {
191 switch (argument)
192 {
193 case "START":
194 this.output.Print("Launching mode");
195 this.tickFromStart = 0;
196 this.currentState = State.LAUNCHING;
197 break;
198
199 default:
200 this.output.Print($"Uknown command: {argument}");
201 break;
202 }
203 }
204 }
205 }
206 }