返信先: ARMA3 ミッションエディットスレ

ホーム フォーラム TRI Gaming フォーラム ARMA3 ミッションエディットスレ 返信先: ARMA3 ミッションエディットスレ

#233770

一応できる方法を考えてみましたがアーセナルの仕様上ブラックリストでの管理は難しいように感じられました。

おそらく一番簡単な方法ですが…

["AmmoboxInit", [arsenalBox, true]] call BIS_fnc_arsenal; 
[arsenalBox, "ACE_Banana"] call BIS_fnc_removeVirtualItemCargo;

コレはできません!
原因はアーセナルの処理の仕様上です。(詳しくは最後)

ならばConfigから全アイテムを取得して…と思いましたがBIのアーセナルスクリプトでやっていることをまたやるのは面倒なので…
若干不満は残りますが以下のようにして実現してみました。
※内容を設定するだけなのでアーセナルのアクション項目の追加は別途行ってください。
setArsenalContensByBlackList.sqf

/*
	v1.0.000
	
	Script: setArsenalContensByBlackList.sqf
	
	Description:
		アーセナルの中身をブラックリストを用いて設定する。
		ブラックリストとは: 
			使用、許可するものを指定するホワイトリストに対して、
			禁止するものや除くものを指定する方法がブラックリストという。
	
	Parameters:
		1: Object: アーセナルを設定するオブジェクト(ブラックリストを用いて)
		2: Any: 指定されたタグで結びつけたクラスのリスト
		
			NestedArray: [["weapon", []], ["magazine", []], ["backpack", []], ["item", []]]
				*"weapon"等のタグは大文字小文字を区別するので変更しないように。
			
			String: 上記配列を最後の行に記述したSQFファイル(例: "script\blacklist.sqf")
	
	Returns: true
*/
private ["_obj", "_blacklist"];
_obj = param [0, objNull, [objNull]];
_blacklist = param [1, [], [[], ""]];

// ローカル関数
private _local_fnc_getClass = {
	private ["_removeClasses"];
	params ["_classes", "_blacklist", "_key"];
	
	_removeClasses = ([_blacklist, _key] call BIS_fnc_getFromPairs);
	if (!isNil "_removeClasses") then {_classes = _classes - _removeClasses};
	
	_classes
};

if (_blacklist isEqualType "") then {
	_blacklist = call (compile preprocessFileLineNumbers _blacklist);
};

/* メイン処理 */
private ["_data"];

// アーセナルで取扱うアイテムクラスを取得できるようにする
_data = missionNamespace getVariable "bis_fnc_arsenal_data";
if (isNil "_data") then {
	["Preload"] call BIS_fnc_arsenal;
	_data = missionNamespace getVariable ["bis_fnc_arsenal_data", []];
};

// アーセナルの内容設定
for [{private _i = 0}, {_i < count _data}, {_i = _i + 1}] do {
	private _classes = _data select _i;
	switch (true) do {
		case (_i in [0, 1, 2]): {
			_classes = [_classes, _blacklist, "weapon"] call _local_fnc_getClass;
			[_obj, _classes, false, false] call BIS_fnc_addVirtualWeaponCargo;
		};
		case (_i in [22, 23, 26]): {
			_classes = [_classes, _blacklist, "magazine"] call _local_fnc_getClass;
			[_obj, _classes, false, false] call BIS_fnc_addVirtualMagazineCargo;
		};
		case (_i == 5): {
			_classes = [_classes, _blacklist, "backpack"] call _local_fnc_getClass;
			[_obj, _classes, false, false] call BIS_fnc_addVirtualBackpackCargo;
		};
		case (_i > 2): {
			_classes = [_classes, _blacklist, "item"] call _local_fnc_getClass;
			[_obj, _classes, false, false] call BIS_fnc_addVirtualItemCargo;
		};
	};
};

true

blacklist.sqf

private ["_wpn", "_mag", "_bpack", "_item"];

_wpn = ["arifle_MX_Black_F"];
_mag = [];
_bpack = ["B_AssaultPack_blk", "B_FieldPack_ocamo"];
_item = ["Binocular"];

[["weapon", _wpn], ["magazine", _mag], ["backpack", _bpack], ["item", _item]]

最後に ; が無いのは仕様です。

これをそのまま使うとロード画面が変なタイミングで入る上にスクリプトエラーを吐く(精神衛生上悪いだけ)のでアーセナルの設定時に以下のようなコードをInit欄に書くことをおすすめします。
(それでも予めアーセナルを開いてないのでスクリプトエラー吐くのは内緒)

this addAction ["Initialize Arsenal", {  
	private ["_obj", "_script"]; 
	_obj = _this select 0;  
	_script = [_obj, "blacklist.sqf"] execVM "setArsenalContensByBlackList.sqf"; 
	waitUntil {sleep 0.1; scriptDone _script}; 
	["AmmoboxInit", [_obj, false]] call BIS_fnc_arsenal; 
	(_this select 0) removeAction (_this select 2);  
}, nil, 6, false];

今回、たいしてデバッグしてないのでアイテムが足りないとかあるかも。
ぁ…アーセナル対象のオブジェクトを一旦初期化(クリア)する処理してないや…別にいいよね|д゚)チラッ

BIのArsenalスクリプトの仕様(予想)
Preloadの処理の時にConfigから扱えるアイテム類を全て列挙し、そこから各種値(名前とか性能)を取得し、GUIのデータを保持する領域に保存。
プレイヤーがアーセナルのアクションメニューを開いた時もしくは項目タブの切替時に、エディッターが設定したアイテムと比較して、それと合致するやつだけ表示するようにしている…はず。
その処理の際、簡略化のために全てのアイテムを取扱うときにのみ”%ALL”という特殊データを用いるので、全アイテムを使う処理→いらないやつを削除ができない。
なので、BIS_fnc_getVirtual…系で現在アーセナルで取り扱っているアイテム類を取得しようとしても、全てのアイテムを使う設定にしていると”%ALL”が返ってしまう。