プログラミング/サンプルプログラム/警告ビーコン

Last-modified: 2017-11-18 (土) 12:33:43

複数のドアを開閉する」がわかった人向け。

ブロック名の取得、ターミナルで設定できる数値の取得、ブロック名の書き込み、ターミナルで設定できる数値の書き込みを含むサンプルです。

update 1.185現在、本サンプルは完成形修正済み・説明は未修正で補足あり。

サンプルプログラム

まずは適当なタレットをいくつか、名前を「NoEntry」にしたBeacon1つ、Programmable Block1つを電源の入ったステーションや大型船に用意してください。

下記のプログラムをProgrammable Blockに貼り付けて実行すると、ビーコンの送信半径が最も射程の長いタレットの射程の2倍になり、名前が「NoEntry:射程m」に変わります。手動で済む初期設定作業ですが。

void Main(string argument){
    List<IMyTerminalBlock> turrets = new List<IMyTerminalBlock> ();
    GridTerminalSystem.GetBlocksOfType<IMyLargeTurretBase>(turrets);
    float MaxRange = 0;
    for (int i = 0; i < turrets.Count; i++){
        float NowRange = turrets[i].GetValueFloat("Range");
        if (NowRange > MaxRange){
            MaxRange = NowRange;
        }
    }
    List<IMyTerminalBlock> beacons = new List<IMyTerminalBlock> ();
    GridTerminalSystem.GetBlocksOfType<IMyBeacon>(beacons);
    for (int i = 0; i < beacons.Count; i++){
        string name = beacons[i].CustomName;
        if (name.StartsWith("NoEntry")){
            beacons[i].SetValueFloat("Radius", MaxRange*2);
            beacons[i].CustomName = "NoEntry!:"+MaxRange+"m";
        }
    }
}

解説

タレットの射程を取得して最も長い数値を残し、名前がNoEntryで始まるビーコンの表示半径を射程距離の2倍にセットし、射程を含む文字列にビーコンの名前を書き換えるプログラムです。

2~3行目:Parentでタレット系列のブロックを全てリストに入れる

リストの作り方は「複数のドアを開閉する」と同様ですが、Interface nameではなくタレット3種を内包するParentであるIMyLargeTurretBase*1を使って3タイプのタレットを全て入れたリストを用意しました。

5~11行目:タレットの射程を取得して最も大きい値を残す

取得以外の部分は割愛します。タレットの射程で最も大きかった数値が変数「maxRange」に残るようにしています。

7行目:設定数値を取得

float 変数名 = 対象.GetValueFloat("プロパティ名");

float nowRange = turrets[i].GetValueFloat("Range");

ターミナルメニューでの設定数値は、float(Single)型の場合GetValueFloat()で取得できます。*2

公式ガイドからMissile TurretのTerminal propertiesを探すとRangeであることがわかるので、数値を比較するためにfloat(Single)型の数値を入れられるようにした変数「nowRange」を作り、今扱っているタレットの射程を一旦そこに書き込むようにしました。

※2015/12/6現在、公式ガイドではGatling Turretの射程のプロパティがRadiusと誤記されています。

13行目以降:対象のビーコンを選んで設定を変更する

13~14行目:Beaconのリストを作る

複数のドアを開閉する」と同様です。

17行目:ブロック名を取得

string 変数名 = 対象.CustomName;

string name = beacons[i].CustomName;

ブロックに付けた名前はCustomNameで取得できます。*3

string(文字列)型の値を入れられるようにした変数「name」を作り、ブロック名を取得してそこに入れました。

18行目:操作対象のブロックかどうかを判定

if (変数名.StartsWith(比較に使う文字列を書き込んだ変数名または""で囲った文字列そのもの)){

if (name.StartsWith("NoEntry")){

18行目は「複数のドアを開閉する」の応用編と同じように名前がら取得した文字列と比較用の文字列を比較していますが、「StartsWith()」でブロック名の最初が指定した文字列であることを条件にしています。

19行目:設定数値の書き込み

対象.SetValue("プロパティ名", 数値);

beacons[i].SetValueFloat("Radius", maxRange*2);

float(Single)型のターミナルプロパティの書き込みはSetValueFloat()で行えます。*4

BeaconのTerminal propertiesを探すと1つしかないので一目瞭然でもありますが、Radiusつまり半径が送信半径だと察しがつきます。

値はタレットの射程から出した「maxRange」の2倍が設定されるようにしました。

20行目:ブロック名の書き込み

対象.SetCustomName(内容);

beacons[i].SetCustomName("NoEntry!:"+ maxRange +"m");

ブロックの名前はSetCustomName()でプログラムから書き込めます。*5

書き込む値は文字列と先ほど出した「maxRange」の値を組み合わせたものにしています。


update 1.185時点において、SetCustonName()は古い書き方として警告が出るようになりましたが、下記のように「直接CustomNameを書き込む」シンプルな書き方が使えるようになりました。

対象.CustomName = 内容;

beacons[i].CustomName = "NoEntry!:"+ maxRange +"m";

*1 公式ガイドを参照
*2 公式ガイドでは「Terminal block and action name list - 1/5」
*3 公式ガイドでは「Programming Guide」の「IMyTerminalBlock」
*4 公式ガイドではGetValueFloatと同じく「Terminal block and action name list - 1/5」
*5 公式ガイドでは先ほどのCustomNameと同じく「Programming Guide」の「IMyTerminalBlock」