【GAME】ARMA3 EXILE MODサーバの旅その48
追記:備忘録ウェイポイント
追記:また思いついた機能追加
追記:アドオン大改変のデバッグ作業
追記:日本ならではの恐怖エラー
追記:Arma3配信者さん
追記:自動給油ってどうよ
変なところが凝り性なんです。悪い癖なのは承知の上。
先日公開したLOOTBOXアドオンの書き直しを行ってます。
諸先輩方のスクリプトを見よう見まねで書いてはいたのですが、ちゃんと理解してたかというと、そうでも無い訳で。。
(;^ω^)
せっかくリリースするので、書けるうちに綺麗に書いておこうと。全体的に見て怪しいコードを一斉に書き直してます。
そのついでに、新しい機能を追加しました。このアドオンでは、EXILEの町に完全にスポットして、機能提供するつもりです。
車両湧きです。
(;´Д`)手を出してもうた。欲しかった機能はこれで最後です。。
Server側の車両湧きと違う点は、以下になります。
(特定部位、タイヤだけ破損といった事もできる)
(最小値・最大値でランダム)
実際の車両をスポーンさせる部分は、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];
追記:自動給油ってどうよ
ずっと以前から気になっていました。
感じ的に、Client側の処理に思えるので、コードを追ってみた。
Land_fs_feed_Fオブジェクトに対して、常に最大のFuelを持たせてるようです。
ExileClient_util_fuel_getRealFuel.sqf
これは被せないと処理は外せそうにない。
給油時の1サイクル分の処理で、ここが呼び出されてるようですが、どないして、呼び出されてるかは分からない。。
(;^ω^)
ヘリの給油の事考えると、この給油止めると厳しいっぽいんけんども。
追記:Arma3配信者さん
(;^ω^)
数少ない日本のArma3動画配信者さんのご紹介。
毎日動画をアップロードしてます。DAYZかArma3がほとんどという、まだマイナーな配信者さん。
追記:日本ならではの恐怖エラー
LB_VFuelLow = 0.1;
この、どこに文法エラーがあるんだッ!!!文末の”;”が無いって言ってるんです。あるやん・・
昨夜からずーと、睨め続けてます。
Arma3特有なのか?
サーバ起動タイミングが悪い?
今になって、小数点は扱えない!?”f”とか付けろと。
何か、オカルト的な??
気になって眠れず、睡眠不足気味です。
(;´Д`)
次の日。
あれ?
何かズレてる・・。
も・・もしや・・、全角スペース様が降臨されてるのでは!!
(´;ω;`)
ま、まさかの超初歩的ミスをここで。。
「エディタのフォント設定、これ大事」m9( ゚д゚)
追記:アドオン大改変のデバッグ作業
もう、作業は終わっていてデバッグ作業をしてます。
すんげー疲れた。
(;´Д`)
Arma3スクリプトの癖も大体に理解してきました。エラーが出ても、何となく分かるようになりましたw
(;´∀`)
機能改変や追加も結構あったので、Readme・取説にも更新しなきゃなりません。こっちも終わった。400行
Config設定ファイルにも、丁寧なコメントを置かなきゃいけません。地味作業ですが、これも終わった。
これなら、どこに何が置かれたのか、一目です。
他のアドオンと動作が並行してるので、ワケワカメなんですよね。
一応、念の為、遅れて動作するように設定もできます。
Readmeからの抜粋ですが、今回の改変分です。
2018/03/24 V1.1
AIリーダー忘れ、スナイパー設定追加、ロケーション位置自動調整、ログ出力周り改変、config見やすく改変、起動待機の追加
コンテナ許容量エラーチェック、コンテナへアイテム追加時コード書き直し、奇妙オブジェクトシミュレーションフラグ追加
ポップタブ計算方法変更、セーフエリアの除外追加(トレーダー/スポーン/各拠点)、アイテム50%集計の改変
車両湧きの追加、負荷が掛かりそうな処理後にウェイト挿入
追記:また思いついた機能追加
また新しい機能を思いついてしまった。
車両湧きを、ロケーション毎に設定できるようにしました。
スポーンゾーンでは、自転車や低レベル車両で、空港には、ヘリや軍事車両とか。
大きな町では、バスやSUVとかの高級車など・・ね。
(;^ω^)リアリティ・・が欲しいのよ
特に、空港での安全な場所での、ヘリやエアープレーン湧きは、良いかもです。
”必ず”タイヤがパンク状態で湧く車両湧き。
しっかり湧いてます。
しかも、いかにも駐車してるっぽい場所に湧いてます。
しっかり、全ホイールにダメージが入ってます。
(;^ω^)
これで、Server側の車両湧きと、差別化が出来たんではないかと思います。
マップ上に、ボーナス的に置かれてるのがサーバ側の車両湧きで、このアドオンでは、町漁りの一貫でのボーナス的な。
追記:備忘録ウェイポイント
AIグループに指定できるウェイポイントタイプ。
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 {“・・・”}とかの書き方もあるが、こうだと意味が変わってくる。
無意識にコピペすると、こういう罠に掛かる。
偶然見つけた、使える?なコマンド。0-1で、太陽と月の状態を知ることができる(多分)
こんなのもあったんだが。月欠けの事か?
(;´∀`)
良く使ってたgetPos(オブジェクト位置取得)ですが、今になって新しい使い方があるのを知りました。これは何かに使えそうです。
プレーヤー位置を基準に、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{}で回すと、ちゃんとオブジェクトで入ってくるんです。
(´・ω・`)まさか・・と思い、これに気づくのに数時間・・