![](https://static.wixstatic.com/media/ea798a_0da9900d64a54afb86fb4f8d28386a7a~mv2.jpg/v1/fill/w_1920,h_1080,al_c,q_90,enc_avif,quality_auto/ea798a_0da9900d64a54afb86fb4f8d28386a7a~mv2.jpg)
ミサイルステーション(ランチャー)
![20190526165931_1.jpg](https://static.wixstatic.com/media/ea798a_f56e518fbb864122b1ea750c58c7c826~mv2.jpg/v1/fill/w_355,h_197,al_c,q_80,usm_0.66_1.00_0.01,enc_avif,quality_auto/20190526165931_1.jpg)
1| IMyProjector pj;
2| IMyLaserAntenna ant;
3| IMyShipMergeBlock mb;
4| IMyPistonBase PJPiston;
5| IMyBlockGroup PistonGroup;
6| IMyProgrammableBlock PBMissile;
7| List<IMyTerminalBlock> pistons = new List<IMyTerminalBlock>();
8| List<IMyShipWelder> welders = new List<IMyShipWelder>();
9| string status = "Ready";
10|
11| public Program()
12| {
13| ant = GridTerminalSystem.GetBlockWithName("LA 1") as IMyLaserAntenna;
14| pj = GridTerminalSystem.GetBlockWithName("Projector") as IMyProjector;
15| PJPiston = GridTerminalSystem.GetBlockWithName("PJ Piston") as IMyPistonBase;
16| mb = GridTerminalSystem.GetBlockWithName("MBStation") as IMyShipMergeBlock;
17| PBMissile = GridTerminalSystem.GetBlockWithName("pbMissile") as IMyProgrammableBlock;
18| PistonGroup = GridTerminalSystem.GetBlockGroupWithName("Stage Pistons");
19| PistonGroup.GetBlocks(pistons);
20| GridTerminalSystem.GetBlocksOfType(welders);
21| }
22|
23| public void Main(string argument, UpdateType updateSource)
24| {
25| var com = argument.Split(',');
26|
27| switch (com[0]){
28| case "Launch":
29| if (mb.IsConnected == true){
30| PBMissile = GridTerminalSystem.GetBlockWithName("pbMissile") as IMyProgrammableBlock;
31| if (PBMissile.TryRun("MissileLaunch") == true)
32| ant.TransmitMessage("Ready for Launch,0,false");
33| }
34| break;
35| case "Build":
36| Runtime.UpdateFrequency = UpdateFrequency.Update10;
37| status = "ProjectorON";
38| break;
39| case "Launchable":
40| ant.TransmitMessage("Ready for Launch,0," + (!pj.Enabled && mb.IsConnected).ToString());
41| break;
42| }
43|
44| switch (status){
45| case "ProjectorON":
46| pj.ApplyAction("OnOff_On");
47| status = "DownStage";
48| PJPiston.Extend();
49| break;
50| case "DownStage":
51| bool extended = true;
52| foreach (IMyPistonBase piston in pistons){
53| piston.Velocity = 5f;
54| if (piston.Status != PistonStatus.Extended)
55| extended = false;
56| }
57| if (extended)
58| status = "Welding";
59| break;
60| case "Welding":
61| foreach(var welder in welders)
62| welder.ApplyAction("OnOff_On");
63| status = "UpStage";
64| break;
65| case "UpStage":
66| foreach (IMyPistonBase piston in pistons)
67| piston.Velocity = -2.5f;
68| if ((pistons[0] as IMyPistonBase).Status == PistonStatus.Retracted){
69| Runtime.UpdateFrequency = UpdateFrequency.None;
70| pj.ApplyAction("OnOff_Off");
71| foreach(var welder in welders)
72| welder.ApplyAction("OnOff_Off");
73| foreach (IMyPistonBase piston in pistons)
74| piston.Velocity = 0f;
75| ant.TransmitMessage("Ready for Launch,0,true");
76| status = "Ready";
77| }
78| break;
79| }
80| }
Main メソッド前半では、コマンドライン引数として渡される3種類のコマンドの処理を行います。"Launch" コマンドは、"MissileLaunch" をコマンドライン引数として、ミサイル本体にある別のプログラムを実行します(31 行)。その後、ステーションコントローラーに「発射可能状態でない」ことを通知します(32 行)。
28| case "Launch":
29| if (mb.IsConnected == true){
30| PBMissile = GridTerminalSystem.GetBlockWithName("pbMissile") as IMyProgrammableBlock;
31| if (PBMissile.TryRun("MissileLaunch") == true)
32| ant.TransmitMessage("Ready for Launch,0,false");
33| }
34| break;
2つ目の "Build" コマンドは、ミサイルが発射後にステーションが空になったことをセンサーブロックが検出すると送信されるコマンドです。これによりステーションの status が "Ready" から "ProjectorON" に変わり(37 行)、Main メソッド後半でのミサイル建造プロセスに入ります。
35| case "Build":
36| Runtime.UpdateFrequency = UpdateFrequency.Update10;
37| status = "ProjectorON";
38| break;
3つ目の "Launchable" コマンドは、ステーションコントローラーからのミサイル発射可否のリクエストです。"Ready for Launch" のあとの 0 はこのミサイルステーションに割り当てられた番号で、ステーション毎に 0-9 までの値が割り当てられています(40 行)。
39| case "Launchable":
40| ant.TransmitMessage("Ready for Launch,0," + (!pj.Enabled && mb.IsConnected).ToString());
41| break;
Main メソッド後半では、ミサイルの自動建造プロセスを変数 status によって制御しています。自動建造プロセスは status が "ProjectorON" になることから始まります。これによりプロジェクターを起動し(46 行)、status を "DownStage" に更新(47 行)、さらにピストンブロックを伸ばして、プロジェクターとマージブロックを上昇させます(48 行)。
45| case "ProjectorON":
46| pj.ApplyAction("OnOff_On");
47| status = "DownStage";
48| PJPiston.Extend();
49| break;
"DownStage" では、ステージを支えているピストンを伸ばして(52-53 行)、ウェルダーを溶接開始位置まで下げます(54-55 行)。ウェルダーが所定の位置まで下がったら、status を "Welding" に更新します(57-58 行)。
50| case "DownStage":
51| bool extended = true;
52| foreach (IMyPistonBase piston in pistons){
53| piston.Velocity = 5f;
54| if (piston.Status != PistonStatus.Extended)
55| extended = false;
56| }
57| if (extended)
58| status = "Welding";
59| break;
"Welding" では、すべてのウェルダーブロックを起動し(61-62 行)、プロジェクターのブループリントに従って溶接を開始します。その後 status を "UpStage" に更新します(63 行)。
60| case "Welding":
61| foreach(var welder in welders)
62| welder.ApplyAction("OnOff_On");
63| status = "UpStage";
64| break;
最後に "UpStage" では、ステージを支えるピストンをゆっくり縮めます(66-67 行)。ピストンが完全に縮んだら(68 行)、Self-update を停止し(69 行)、プロジェクターも停止(70 行)、すべてのウェルダーブロックとピストンブロックを停止した後(71-74 行)、ステーションコントローラーに「発射可能状態である」ことを通知します(75 行)。最後に status を "Ready" に更新して、待機状態に戻ります(76行)。
65| case "UpStage":
66| foreach (IMyPistonBase piston in pistons)
67| piston.Velocity = -2.5f;
68| if ((pistons[0] as IMyPistonBase).Status == PistonStatus.Retracted){
69| Runtime.UpdateFrequency = UpdateFrequency.None;
70| pj.ApplyAction("OnOff_Off");
71| foreach(var welder in welders)
72| welder.ApplyAction("OnOff_Off");
73| foreach (IMyPistonBase piston in pistons)
74| piston.Velocity = 0f;
75| ant.TransmitMessage("Ready for Launch,0,true");
76| status = "Ready";
77| }
78| break;