「server」タグアーカイブ

【GAME】ARMA3 EXILE MODサーバの旅その50

20180402194331_1はぁ・・長かった。

( ´Д`)=3・・

うっかり、素人がArma3スクリプトに手を出したばかりに、メチャメチャしんどかったよ。

でも、Arma3スクリプト書きに抵抗が無くなったし、無事公開する事ができました。

つい先程、全面改良版を公開致しましたッ!!

こちらからダウンロードできます(70KBと前回から2倍のサイズ)

【公開】ARMA3EXILEアドオン「LOOTBOX」公開

詳しくは、Readmeを見て下さい(日本語のみ)

めっちゃ丁寧に書きましたので、サーバ初心者でも多分大丈夫でしょう。

20180402195416_1随分苦労したのが、車両湧きに関してです。

微調整の繰り返しでした。

どうしても、建物近くに湧かせたかったのですが、どうにも、接触してしまい爆発してしまうか、どこかに飛んでいってしまう。

それっぽく見せるための絶妙な位置調整を、延々としておりました。

自転車が一番難しかった。

(;´Д`)

もう既に公開に踏み切っちゃいましたが、マップはTakistanでしか試してません。

多分、そのままサーバディレクトリにコピペするだけで、無設定で他マップで動作してくれるはず・・です。

簡単便利も、特徴のひとつでもあります。

。゚(゚´Д`゚)゚。

だって、もう、ライフが残り僅かなのよ。デバッグはもうしたくないお。。。

明日から作業する、Exile1.0.4サーバ構築で、ついでにAltisとかTanoaとかで試す予定です。

(追記予定)

【GAME】ARMA3 EXILE MODサーバの旅その49

sc20180331121721追記:アドオン改修完了と公開

追記:今度こそマジで最終デバッグ

追記:{}地獄から這い出た

追記:動作確認の旅

まだ、Arma3スクリプトの闇に紛れ込んでおります。。

(;´Д`)

ただ、体感的に分かってきました。

公開するので、汚いコードは見せたくありません。出来るだけ綺麗に書き上げたい。もうちょいだけ頑張る。

されど配列、めっさ使いまくる配列について備忘録。公式(Array)

参照するッ

_array select 0; 0番(最初)を参照

_array select [1,2]; 1番から2個までの配列

_array select {_x isEqualTo 2}; trueを返した要素だけの配列

要素数を得る!

count _array

ループするッ

{ }forEach _array; _xに入ります

削除するッ

_array deleteAt 0; 0番を削除

_array deleteRange [0,2]; 0番から2個削除

_array1 = _array1 – _array2; 構造が合ったものを削除できちゃうが、これは怖いね。

_array resize 5; 先頭から5要素だけ残し削除

要素に入れてまう

_array set [0,”test”]; 0番に”test”を入れてまう

_array = _array apply {_x = _x * 2;}; 各要素に対して計算結果を格納してまう

_array pushBack 1; 最後に追加する

_array pushbackUnique 1; 配列内に1が無かったら追加される。有ったらエラーとして-1になる(戻り値は追加場所)

合体する!!

_array1 append _array2 (怪しい?)

_array1 = _array1 + _array2; 同じ:これなら安心

_array1 = +_array2; ヘルプにはこれでも良いようだが、動作が怪しい。

_array1 = _array1 arrayIntersect _array2; 両方の配列双方に、同じ値が入ってるものだけを抽出(論理式のANDみたいな感じ)

検索したい

_array find x; 要素番号が戻る。-1は見つからない

ソートする?(比較用コードは書けない)

sort _array trueかfalse; 単純な昇順降順ソートだけ

これはあくまで1次元配列のためのモノ。インデックスが2番目だったり、複雑な構造体のソートはゼロからこさえないといけない。

要素を反転しちゃう?

reverse _array; 全ての要素を反転する

シャッフルいてまう

有りそうで無かったので、こさえました。厳密には綺麗にシャッフルされませんけども、改造してください(reverseを見て察して)

private [“_vl”,”_cnt”,”_rst”];
for “_j” from 1 to floor((count _array) / 2) do
{
    _vl = floor(random (count _array)) + 1;
    _cnt = floor(random ((count _array) – _vl)) + 1;
    _rst = _array select [_vl,_cnt];
    _array deleteRange [_vl,_cnt];
    _array = _rst + array;
    if(random 1 >= 0.5)then{
        reverse _array;
    };
};

※見ての通り、配列の先頭と後ろが確率的に低い

余:重複しないランダム数字配列(0-9)

_cnt = 10;
_rst = [];
for “_j” from 1 to _cnt do
{
    _val = floor(random (_cnt));
    while{(_rst pushBackUnique _val) isEqualTo -1}do
    {
        _val = (_val + 1) mod (_cnt);
    };
};

追記:動作確認の旅

20180328205920_1うむ。

大丈夫だ。動いてる。

(;´∀`)

自転車も、このアドオンで出せば、街中に、それっぽく置かれてるので雰囲気壊さずに良いかもです。

ちなみに、設定で、車両をエンジンオン状態ライトon状態で湧かせられるかなぁ・・と思っていた時期もありましたが。

Arma3の仕様でダメなようです。

こういった類は、ローカル側でしか制御できないようでした。Exileサーバ側で用意されてるかも?と思ったけど、これ以上の深追いはやめよう。。

修正:

コードが間違ってた。サーバ側からも出来ます。とても簡単。

_vehicle engineOn true;

_vehicle setPilotLight true;

(;´∀`)

20180331153822_1AIも湧いてます。

突如撃たれるので、アイテム漁りにも緊張感が出ます。

「居るかも・・?」

と思わせれば良いので、設定で町に0~1体だけでも十分な印象です。

追記:{}地獄から這い出た

sc20180401174437いままでスクリプトを書いていて、どーしても理解できない不思議な挙動がありました。

・・が、分からないので、適当にゴリ押しで書いてたんですが。

や・・や、やっと。。

カラクリが分かった。。。

。゚(゚´Д`゚)゚。

まぁ・・どこぞに、こんな単純な比較文があったとしましょう。

_OK変数にフラグを入れて、いくつかの条件をチェックするような感じです。よくあるシチュエーションです。

if (_val isEqualTo 2)then
{
 _OK = true;
};

んで、最後にこのフラグを見て、色々やりましょうと意気込む訳です。

if(_OK) then
{
 いろいろ
};

ね?凄い単純なコードです。だがしかし、これはエラーで弾かれるんです。エラーで弾かれるんです。。弾かれるんです。。ヒロシです。

でもね。一番最初のif文に、これを追加すると。。

_OK = false; < これ
if (_val isEqualTo 2)then
{
 _OK = true;
};

ちゃんと動作するんですよね。もう、これが謎過ぎて、今まで分からなかった。。

sc20180401175719前の記事で書いてた言葉がありました。

旅48/追記:スコープの不思議と戯言

例外なく{}の中はスコープ

これは、if文も例外じゃねぇぞ、と。

(;´Д`)

もう、なんでしょう、心が晴れ晴れしております。モヤモヤが無くなりました。

まるで、1週間ぶりにお風呂に入ったような気分です。

(;^ω^)

sc20180401180143今後、Arma3のスクリプトを書く機会があるかどうか分かりませんが、流用できるようにコードを分けてます。

getBuildingPosなんて、自分的には傑作です。

建物オブジェクトを渡すと、建物内の様々な場所を返してくれます。

入口/入口に近い場所/入口から遠い場所/低い場所/高い場所/道路に近い場所

これを使って、アイテムボックスやAIを配置してます。

追記:今度こそマジで最終デバッグ

sc20180402154414趣味とはいえ、いつまでもやってられないので、そろそろ見切りを付け、最終的かつ完全な最終デバッグをしております。

自分なりには、欲しい機能は全て入れ込んだつもりです。

やるだけやった。

町に特化してるので、他アドオンに影響も与えないでしょう。どうぞ、使ってくださいまし。

今日夜か、明日には、Version1.1として公開致します。

Version1.0から、かなりの量(ほぼ全部)、改変しました。

デバッグ作業ですが、ランダムだらけで動作してるので、時と場所によってエラーが出たりするんですよ。

だから、何度も実行しては、確認してます。。

つ・・疲れた。。(;´Д`)

追記:アドオン改修完了と公開

たった今、Version1.1を公開しました。

【GAME】ARMA3 EXILE MODサーバの旅その48

sc20180326134316追記:スコープの不思議と戯言

追記:備忘録ウェイポイント

追記:また思いついた機能追加

追記:アドオン大改変のデバッグ作業

追記:日本ならではの恐怖エラー

追記:Arma3配信者さん

追記:自動給油ってどうよ

変なところが凝り性なんです。悪い癖なのは承知の上。

先日公開したLOOTBOXアドオンの書き直しを行ってます。

諸先輩方のスクリプトを見よう見まねで書いてはいたのですが、ちゃんと理解してたかというと、そうでも無い訳で。。

(;^ω^)

せっかくリリースするので、書けるうちに綺麗に書いておこうと。全体的に見て怪しいコードを一斉に書き直してます。

そのついでに、新しい機能を追加しました。このアドオンでは、EXILEの町に完全にスポットして、機能提供するつもりです。

車両湧きです。

(;´Д`)手を出してもうた。欲しかった機能はこれで最後です。。

Server側の車両湧きと違う点は、以下になります。

  • 町中や周囲に湧く
  • アイテムを格納できる(LOOTBOXエンジン)
  • ダメージをより細かく設定
    (特定部位、タイヤだけ破損といった事もできる)
  • 燃料をより細かく設定
    (最小値・最大値でランダム)

    実際の車両をスポーンさせる部分は、EXILE MODを呼び出してますので、今後のアップデートでおかしくなる事は、多分、無いでしょう。

    また、湧き位置判断での、AIスナイパー設定を入れ込みました。

    以下、参考資料(スクリプト書きの方向け)

    車両ダメージ

    _vehicle setHitPointDamage [破損箇所, 0-1];

    なのだが、破損箇所はモデル毎に自由に決められてる。これは人間オブジェクトでも利用できる。人間だと以下の部位になるようです。

    [“HitFace”,”HitNeck”,”HitHead”,”HitPelvis”,”HitAbdomen”,”HitDiaphragm”,”HitChest”,”HitBody”,”HitArms”,”HitHands”,”HitLegs”], // [“”,”neck”,”head”,”pelvis”,”spine1″,”spine2″,”spine3″,”body”,””,”hands”,”legs”],

    では、車両ではどうするか?ですが。

    getAllHitPointsDamageでエントリーされる全ての部位から調べる必要があります。

    EXILE MODとか多くの車両を扱う場合、以下な感じで対応するとええかもしれない。”wheel”の文字を含んでいたら?のような。それっぽい単語でいくのが手っ取り早いかなと。

    if((toLower(_x) find “wheel” > 0))then

    ※ただ、キャタピラー(TANK)とかの特殊車両だと、違う名前っぽいですが、調べてません

    資料:車両には以下部位があるようですが、深くは調べてません。ホイールが無いので、基本的な?

    HitEngine (engine #1)/HitEngine2 (engine #2)/HitEngine3 (engine #3)/HitHRotor (main rotor)/HitVRotor (tail rotor)/HitBatteries (electrical systems)/HitLight (landing light)/HitHydraulics (entire hydraulics system)/HitTransmission (engine transmission)/HitGear (landing gear)/HitFuel (all fuel tanks)/HitHStabilizerL1 (first left horizontal stabilizer)/HitHStabilizerR1 (first right horizontal stabilizer)/HitVStabilizer1 (first vertical stabilizer)/HitTail (tail boom)/HitPitotTube (all pitot tubes)/HitStaticPort (all static ports)/HitStarter1 (starter for engine #1)/HitStarter2 (starter for engine #2)/HitStarter3 (starter for engine #3)/HitAvionics/HitHull/HitMissiles/HitRGlass/HitLGlass/HitGlass1/HitGlass2/HitGlass3/HitGlass4/HitGlass5/HitGlass6/

    コンテナへのアイテム格納

    アイテムによって格納仕方が違うようなので、ちゃんと書くと以下になるようです。ちゃんと公式調べ上げました。

    _cargoオブジェクトに、_itemsのアイテムリストを順に入れ込むスクリプトです。最後の一行はEXILE特有のモノですけどもw

    clearMagazineCargoGlobal _cargo;
    clearWeaponCargoGlobal _cargo;
    clearItemCargoGlobal _cargo;
    _content = “”;
    {
    if !(_cargo canAdd _x)exitWith{};
    _itemType = _x call BIS_fnc_itemType;
    switch(_itemType select 0)do{
      case “Weapon”:{_cargo addWeaponCargoGlobal [_x, 1]};
      case “Magazine”:{_cargo addMagazineCargoGlobal [_x, 1]};
      case “Backpack”:{_cargo addBackpackCargoGlobal [_x, 1]};
      case “Item”;
      case “Equipment”;
      default {_cargo addItemCargoGlobal [_x, 1]};
    };
    } foreach _items;

    _cargo setVariable [“ExileMoney”, _poptabs, true];

    追記:自動給油ってどうよ

    sc20180326180926ガソリンスタンドに行くと自動で給油が始まりますが、これを止める事ができるのか?

    ずっと以前から気になっていました。

    感じ的に、Client側の処理に思えるので、コードを追ってみた。

    Land_fs_feed_Fオブジェクトに対して、常に最大のFuelを持たせてるようです。

    ExileClient_util_fuel_getRealFuel.sqf

    これは被せないと処理は外せそうにない。

    給油時の1サイクル分の処理で、ここが呼び出されてるようですが、どないして、呼び出されてるかは分からない。。

    (;^ω^)

    ヘリの給油の事考えると、この給油止めると厳しいっぽいんけんども。

    追記:Arma3配信者さん

    sc20180326194334記事とは関係ありませんけんども。。

    (;^ω^)

    数少ない日本のArma3動画配信者さんのご紹介。

    norapoさん

    毎日動画をアップロードしてます。DAYZかArma3がほとんどという、まだマイナーな配信者さん。

    追記:日本ならではの恐怖エラー

    sc20180327121610この何でも無い、どシンプルなコードに、文法エラーがあると言って、どーしてもプログラムが走らない。

    LB_VFuelLow = 0.1;

    この、どこに文法エラーがあるんだッ!!!文末の”;”が無いって言ってるんです。あるやん・・

    昨夜からずーと、睨め続けてます。

    Arma3特有なのか?

    サーバ起動タイミングが悪い?

    今になって、小数点は扱えない!?”f”とか付けろと。

    何か、オカルト的な??

    気になって眠れず、睡眠不足気味です。

    (;´Д`)

    次の日。

    sc20180327122049何気に、違うエディタ(Emeditor)で開いたら・・

    あれ?

    何かズレてる・・。

    も・・もしや・・、全角スペース様が降臨されてるのでは!!

    (´;ω;`)

    ま、まさかの超初歩的ミスをここで。。

    エディタのフォント設定、これ大事」m9( ゚д゚)

    追記:アドオン大改変のデバッグ作業

    sc20180327192738LOOTBOXアドオンのスクリプト全域に渡って、大改変をしております。

    もう、作業は終わっていてデバッグ作業をしてます。

    すんげー疲れた。

    (;´Д`)

    Arma3スクリプトの癖も大体に理解してきました。エラーが出ても、何となく分かるようになりましたw

    (;´∀`)

    機能改変や追加も結構あったので、Readme・取説にも更新しなきゃなりません。こっちも終わった。400行

    Config設定ファイルにも、丁寧なコメントを置かなきゃいけません。地味作業ですが、これも終わった。

    sc20180327193221ログも見やすくしました。無駄な情報をカットした。

    これなら、どこに何が置かれたのか、一目です。

    他のアドオンと動作が並行してるので、ワケワカメなんですよね。

    一応、念の為、遅れて動作するように設定もできます。

    Readmeからの抜粋ですが、今回の改変分です。

    2018/03/24 V1.1
    AIリーダー忘れ、スナイパー設定追加、ロケーション位置自動調整、ログ出力周り改変、config見やすく改変、起動待機の追加
    コンテナ許容量エラーチェック、コンテナへアイテム追加時コード書き直し、奇妙オブジェクトシミュレーションフラグ追加
    ポップタブ計算方法変更、セーフエリアの除外追加(トレーダー/スポーン/各拠点)、アイテム50%集計の改変
    車両湧きの追加、負荷が掛かりそうな処理後にウェイト挿入

    追記:また思いついた機能追加

    sc20180328164717キリが無いぞ。

    また新しい機能を思いついてしまった。

    車両湧きを、ロケーション毎に設定できるようにしました。

    スポーンゾーンでは、自転車や低レベル車両で、空港には、ヘリや軍事車両とか。

    大きな町では、バスやSUVとかの高級車など・・ね。

    (;^ω^)リアリティ・・が欲しいのよ

    特に、空港での安全な場所での、ヘリやエアープレーン湧きは、良いかもです。

    20180327195725_1昨夜のデバックシーンからのショット。

    ”必ず”タイヤがパンク状態で湧く車両湧き。

    しっかり湧いてます。

    しかも、いかにも駐車してるっぽい場所に湧いてます。

    20180327195800_1うむ。

    しっかり、全ホイールにダメージが入ってます。

    (;^ω^)

    これで、Server側の車両湧きと、差別化が出来たんではないかと思います。

    マップ上に、ボーナス的に置かれてるのがサーバ側の車両湧きで、このアドオンでは、町漁りの一貫でのボーナス的な。

    追記:備忘録ウェイポイント

    sc20180329110045念の為、備忘録。

    AIグループに指定できるウェイポイントタイプ。

    Waypoint types

    OccupationのPlace AIは、「SAD」で動作してる(Seek&Destroyの略)

    建物に入れる設定の場合は、「Cycle」のようです。これは単純に、ループする。

    沢山種類がありますね。図解で説明してくれるととても助かるんだけどもなぁ。。

    詳しく見たい場合は、EDENエディタで動作チェックした方がいいんでしょうね。

    Occupationからの丸写しですが、コードはこんな感じ。

    _wp = _group addWaypoint [_pos, 0];
         _wp setWaypointBehaviour “AWARE”;
         _wp setWaypointCombatMode “RED”;
         _wp setWaypointCompletionRadius 1;
         _wp waypointAttachObject _building;
         _wp setwaypointHousePosition _buildingPos find _bpos;
         //_wp setWaypointType “SAD”;
         _wp setWaypointType “CYCLE”;

    建物内にウェイポイントを指定する場合は、waypointAttachObject /setwaypointHousePosition これで別途指定しないといけない。

    追記:スコープの不思議と戯言

    変数や名前空間のスコープは、公式をちゃんと読んで理解してる訳ではありませんが、普通のプログラム言語と同じやろ・・と見てるんですが。

    どうにも、なんだか変な挙動をする。騙し騙し書いてたんですが、どうにも、エラーが取れない。。

    (;´Д`)

    これ、Privateんところのコピペですが、まぁ、こんなもんですよね。{}内は例外なくスコープとして機能するので、外でも使いたい場合は初期化とかしておく必要があるのは知ってましたが。。(for文でも例外無く)

    _localVar = “bla”;
    if (true) then {
     //new scope
     private _localVar = “some string”;
     if (true) then {
      //new scope
      private _localVar = “some other string”;
      systemChat _localVar; // = “some other string”
     };
     systemChat _localVar; // = “some string”
    }; systemChat _localVar; // = “bla”

    未定義の時は、ログに出すと、”any”となるようですね。

    う~ん・・・わかんねぇ。。

    (;´Д`)

    本気で綺麗に書くつもりなら、コード頭で、Private宣言して変数を利用すべきのようです。

    private [“_ok”,”_building”,”_positionReal”];

    うむむ。

    その後、なんとか正常に動くようになったんだけども。

    やっぱ、Arma3スクリプトの変態さ加減を甘くみちゃいけんです(良い意味でも悪い意味でも、尊敬の念はあります。あくまでゲームソフトだもん、凄いよ)

    引数を頭にもケツにも書けたりする訳で、その戻り値を直接、引数で渡すとかだと、コードがわけワカメになります。

    保守性を上げる意味でも、強引にでも括弧を付けたり、一度変数に置いたりした方が絶対にいい。

    ちなみに、他言語でよく使う、for{}やforeach{}ループ内の「continue」が存在しないようです。。

    (;´Д`) GOTO使えってか?

    私は仕方無く、でっかいif{}で切り抜けてます(ブツブツ言いながらですが)

    ちなみに、ループを抜ける時は、(上で言った事を忘れず)ループ内はスコープなので、exitWith{}が正解です。コードを終了する時も、exitWith{}です。

    良く使うであろう、NULLチェックはこう書かなきゃいけない。

    _building = nil;

    if(_ok and not isNil “_building”)then

    ヘルプには、isNil {“・・・”}とかの書き方もあるが、こうだと意味が変わってくる。

    無意識にコピペすると、こういう罠に掛かる。

    sunOrMoon

    偶然見つけた、使える?なコマンド。0-1で、太陽と月の状態を知ることができる(多分)

    moonPhase

    こんなのもあったんだが。月欠けの事か?

    (;´∀`)

    良く使ってたgetPos(オブジェクト位置取得)ですが、今になって新しい使い方があるのを知りました。これは何かに使えそうです。

    player getPos [100,45];

    プレーヤー位置を基準に、45度100m先の場所を指すことになります。

    player getPos [100,getDir player];

    こうすれば、プレーヤーの向いてる方向、100m先ってなります。(getDir player + 180) mod 360って書きゃ、プレーヤーの背後ってなります。

    追記:やっぱ一度変数に・・

    _house = [_c_pos select 0,_c_pos select 1] nearObjects [“house”,_c_radius];

    これは周囲の建物を検索するコードなのですが、公式ヘルプを見ても確実に、オブジェクトのリストが帰ってくるんです。

    なら、直接、foreachで回せそうじゃないですか?

    (;^ω^)ね?

    {・・・・

    }foreach [_c_pos select 0,_c_pos select 1] nearObjects [“house”,_c_radius];

    ですが、なぜか、数字が入ってきます。座標っぽい。

    なぜぇ??(;´Д`)

    一度、変数に入れて・・foreach{}で回すと、ちゃんとオブジェクトで入ってくるんです。

    (´・ω・`)まさか・・と思い、これに気づくのに数時間・・