Add missile launcher and missile controller projects
[SEScripts.git] / MiningRover / Program.cs
1 using Sandbox.Game.EntityComponents;
2 using Sandbox.ModAPI.Ingame;
3 using Sandbox.ModAPI.Interfaces;
4
5 using SpaceEngineers.Game.ModAPI.Ingame;
6
7 using System;
8 using System.Collections;
9 using System.Collections.Generic;
10 using System.Collections.Immutable;
11 using System.Linq;
12 using System.Text;
13
14 using VRage;
15 using VRage.Collections;
16 using VRage.Game;
17 using VRage.Game.Components;
18 using VRage.Game.GUI.TextPanel;
19 using VRage.Game.ModAPI.Ingame;
20 using VRage.Game.ModAPI.Ingame.Utilities;
21 using VRage.Game.ObjectBuilders.Definitions;
22
23 using VRageMath;
24
25 namespace IngameScript
26 {
27 partial class Program : MyGridProgram
28 {
29 enum State
30 {
31 DEFAULT,
32 PACKING,
33 UNPACKING,
34 }
35
36 const float EPSILON = 0.05f;
37 const float EPSILON_RAD = (float)(Math.PI / 64);
38
39 State currentState = State.DEFAULT;
40
41 IMyMotorAdvancedStator rotor01;
42 IMyMotorAdvancedStator rotor02;
43 IMyMotorAdvancedStator hinge01;
44 IMyMotorAdvancedStator hinge02;
45 IMyMotorAdvancedStator hinge03;
46 IMyExtendedPistonBase piston01;
47
48 List<IMyExtendedPistonBase> pistons = new List<IMyExtendedPistonBase>();
49 List<string> pistonsNames = new List<string> { "Piston 02", "Piston 03", "Piston 04", "Piston 05", "Piston 06", "Piston 07", };
50
51 IMyLandingGear magneticPlateArm;
52 IMyLandingGear lockPlate;
53 IMyExtendedPistonBase lockPiston;
54
55 IMyTextSurface output;
56
57 public void Print(string text)
58 {
59 this.output.WriteText((this.output.GetText() != "" ? Environment.NewLine : "") + text, true);
60 }
61
62 public void PrintError(string text)
63 {
64 this.Print($"Error: {text}");
65 }
66
67 public Program()
68 {
69 this.output = this.Me.GetSurface(0);
70 this.output.ContentType = ContentType.TEXT_AND_IMAGE;
71 this.output.WriteText("");
72
73 this.Me.CustomData = "Packing";
74
75 this.Print("Mining rover system starting...");
76
77 var stators = new List<IMyMotorAdvancedStator>();
78 GridTerminalSystem.GetBlocksOfType(stators);
79
80 foreach (var s in stators)
81 {
82 if (s.DisplayNameText.Contains("Rotor 01"))
83 this.rotor01 = s;
84 else if (s.DisplayNameText.Contains("Rotor 02"))
85 this.rotor02 = s;
86 else if (s.DisplayNameText.Contains("Hinge 01"))
87 this.hinge01 = s;
88 else if (s.DisplayNameText.Contains("Hinge 02"))
89 this.hinge02 = s;
90 else if (s.DisplayNameText.Contains("Hinge 03"))
91 this.hinge03 = s;
92 }
93
94 var pistons = new List<IMyExtendedPistonBase>();
95 GridTerminalSystem.GetBlocksOfType(pistons);
96
97 foreach (var p in pistons)
98 {
99 if (p.DisplayNameText.Contains("Piston 01"))
100 {
101 this.piston01 = p;
102 }
103 else if (p.DisplayNameText.Contains("Lock Piston"))
104 {
105 this.lockPiston = p;
106 }
107 else
108 {
109 foreach (var name in pistonsNames)
110 {
111 if (p.DisplayNameText.Contains(name))
112 {
113 this.pistons.Add(p);
114 break;
115 }
116 }
117 }
118 }
119
120 var magneticPlates = new List<IMyLandingGear>();
121 GridTerminalSystem.GetBlocksOfType(magneticPlates);
122 foreach (var magneticPlate in magneticPlates)
123 {
124 if (magneticPlate.DisplayNameText.Contains("Magnetic Plate arm"))
125 {
126 this.magneticPlateArm = magneticPlate;
127 }
128 else if (magneticPlate.DisplayNameText.Contains("Lock Plate"))
129 {
130 this.lockPlate = magneticPlate;
131 }
132 }
133
134 if (this.rotor01 == null)
135 {
136 this.PrintError("Can't find 'Rotor 01'");
137 return;
138 }
139
140 if (this.rotor02 == null)
141 {
142 this.PrintError("Can't find 'Rotor 02'");
143 return;
144 }
145
146 if (this.hinge01 == null)
147 {
148 this.PrintError("Can't find 'Hinge 01'");
149 return;
150 }
151
152 if (this.hinge02 == null)
153 {
154 this.PrintError("Can't find 'Hinge 02'");
155 return;
156 }
157
158 if (this.magneticPlateArm == null)
159 {
160 this.PrintError("Can't find 'Magnetic Plate arm'");
161 return;
162 }
163
164 if (this.lockPlate == null)
165 {
166 this.PrintError("Can't find 'Lock Plate'");
167 return;
168 }
169
170 if (this.piston01 == null)
171 {
172 this.PrintError("Can't find 'Piston 01'");
173 return;
174 }
175
176 if (this.lockPiston == null)
177 {
178 this.PrintError("Can't find 'Lock Piston'");
179 return;
180 }
181
182
183 this.Runtime.UpdateFrequency = UpdateFrequency.Update100;
184
185 this.Print("Mining rover system has started");
186 }
187
188 public void Save()
189 {
190 }
191
192 /// <summary>
193 /// Always returns an angle between 0 and pi/2.
194 /// </summary>
195 /// <param name="a1"></param>
196 /// <param name="a2"></param>
197 /// <returns></returns>
198 float SumAngles(float a1, float a2)
199 {
200 var r = (float)((a1 + a2) % (2 * Math.PI));
201
202 if (r < 0)
203 return (float)(r + 2 * Math.PI);
204 else
205 return r;
206 }
207
208 // Return 'true' if the rotor is in place.
209 bool SetRotorVelocity(float targetAngle, IMyMotorAdvancedStator rotor, float tolerance = (float)(Math.PI / 64))
210 {
211 //if (rotor.Angle)
212 return false;
213 }
214
215 void UpdateState()
216 {
217 if (this.currentState == State.UNPACKING)
218 {
219 if (!this.piston01.Enabled)
220 {
221 this.piston01.Enabled = true;
222 foreach (var p in this.pistons)
223 p.Enabled = true;
224 }
225
226 bool finished = true;
227 //bool roverLocked = false;
228
229 if (this.magneticPlateArm.IsLocked)
230 this.magneticPlateArm.Unlock();
231
232 this.rotor01.TargetVelocityRPM = 0.0f;
233
234 if (this.lockPiston.CurrentPosition <= EPSILON)
235 {
236 finished = false;
237 this.lockPiston.Velocity = 0.5f;
238 }
239 else if (this.lockPiston.CurrentPosition >= this.lockPiston.MaxLimit - EPSILON)
240 {
241 //roverLocked = true;
242 if (!this.lockPlate.IsLocked)
243 this.lockPlate.Lock();
244 this.lockPiston.Velocity = 0.0f;
245 }
246
247 if (this.hinge01.Angle <= -Math.PI / 8)
248 {
249 this.hinge01.TargetVelocityRPM = 0.0f;
250 }
251 else // if (roverLocked)
252 {
253 this.hinge01.TargetVelocityRPM = -1.5f;
254 finished = false;
255 }
256
257 if (this.hinge02.Angle <= -Math.PI / 3)
258 {
259 this.hinge02.TargetVelocityRPM = 0.0f;
260 }
261 else // if (roverLocked)
262 {
263 this.hinge02.TargetVelocityRPM = -1.5f;
264 finished = false;
265 }
266
267 if (this.piston01.CurrentPosition <= this.piston01.MaxLimit - EPSILON /*&& roverLocked*/)
268 {
269 this.piston01.Velocity = 1.0f;
270 finished = false;
271 }
272 else
273 {
274 this.piston01.Velocity = 0.0f;
275 }
276
277 if (finished)
278 {
279 this.rotor01.RotorLock = false;
280 this.currentState = State.DEFAULT;
281 this.Print("Unpacking terminated");
282 }
283 }
284 else if (this.currentState == State.PACKING)
285 {
286 bool finished = true;
287
288 var rotor01InPlace = this.rotor01.Angle >= 2 * Math.PI - EPSILON_RAD || this.rotor01.Angle <= EPSILON_RAD;
289 if (rotor01InPlace)
290 {
291 this.rotor01.RotorLock = true;
292 this.rotor01.TargetVelocityRPM = 0.0f;
293 }
294 else if (this.rotor01.Angle >= Math.PI)
295 {
296 this.rotor01.TargetVelocityRPM = 1.0f;
297 finished = false;
298 }
299 else // if (this.rotor01.Angle <= Math.PI)
300 {
301 this.rotor01.TargetVelocityRPM = -1.0f;
302 finished = false;
303 }
304
305 //this.Print($"Hinge 01 angle: {this.hinge01.Angle}");
306 if (this.hinge01.Angle <= Math.PI / 4.0 || rotor01InPlace && this.hinge01.Angle <= Math.PI / 2.0 - Math.PI / 32.0)
307 {
308 this.hinge01.TargetVelocityRPM = 1.5f;
309 finished = false;
310 }
311 else
312 {
313 this.hinge01.TargetVelocityRPM = 0f;
314 }
315
316 if (this.hinge02.Angle <= -Math.PI / 32.0)
317 {
318 this.hinge02.TargetVelocityRPM = 1.5f;
319 finished = false;
320 }
321 else
322 {
323 this.hinge02.TargetVelocityRPM = 0f;
324 }
325
326 if (this.piston01.CurrentPosition >= EPSILON)
327 {
328 this.piston01.Velocity = -1.0f;
329 finished = false;
330 }
331 else
332 {
333 this.piston01.Velocity = 0.0f;
334 }
335
336 //var rotor2TargetAngle = 2 * Math.PI - Math.PI / 4; // 315°.
337
338 if (finished)
339 {
340 if (!this.magneticPlateArm.IsLocked)
341 this.magneticPlateArm.Lock();
342
343 if (this.lockPlate.IsLocked)
344 {
345 this.lockPlate.Unlock();
346 this.lockPiston.Velocity = -0.5f;
347 }
348
349 this.piston01.Enabled = false;
350 foreach (var p in this.pistons)
351 p.Enabled = false;
352
353 this.currentState = State.DEFAULT;
354 this.Print("Packing terminated");
355 }
356 }
357 }
358
359 /*
360 enum RotateDirection
361 {
362 RIGHT,
363 LEFT,
364 }
365
366 enum ElevationDirection
367 {
368 UP,
369 DOWN,
370 }
371
372 const double SPEED_ROTATION = 1.0;
373 const double SPEED_HINGE = 1.0;
374 const double SPEED_EXTEND_1 = 1.0;
375 const double SPEED_EXTEND_2 = 1.0;
376
377 void Rotate(RotateDirection direction)
378 {
379 //if (this.rotor01.)
380 }
381
382 void ChangeElevation(ElevationDirection direction)
383 {
384
385 }
386
387 void LockUnlock()
388 {
389 if (rotor01.Base)
390 }*/
391
392 public void Main(string argument, UpdateType updateSource)
393 {
394 if ((updateSource & UpdateType.Update100) != 0)
395 {
396 this.UpdateState();
397 }
398 else if ((updateSource & (UpdateType.Terminal | UpdateType.Trigger)) != 0)
399 {
400 switch (argument)
401 {
402 case "UNPACK":
403 this.Print("Unpacking...");
404 this.currentState = State.UNPACKING;
405 break;
406
407 case "PACK":
408 this.Print("Packing...");
409 this.currentState = State.PACKING;
410 break;
411
412 case "STOP":
413 this.currentState = State.DEFAULT;
414 break;
415
416 /*
417 case "LOCK OR UNLOCK":
418 LockUnlock();
419 break;
420
421 case "DOWN":
422 ChangeElevation(ElevationDirection.DOWN);
423 break;
424
425 case "UP":
426 ChangeElevation(ElevationDirection.UP);
427 break;
428
429 case "LEFT":
430 Rotate(RotateDirection.LEFT);
431 break;
432
433 case "RIGHT":
434 Rotate(RotateDirection.RIGHT);
435 break;*/
436
437 default:
438 Echo($"Uknown command: {argument}");
439 break;
440 }
441 }
442 }
443 }
444 }
445