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

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

#222806

Exile Modなんかでセーフゾーンの弾消えるやつどうやってるのかなーって思ってたらイベントハンドラからやっていたんですね。

セーフゾーンに出入り&車両乗車時にも対応できるようにしてみました。
safeZone.sqf

/*
	2017/06/22
	
	Author: Line
	
	File: safeZone.sqf
	
	Parameters:
		1: String: マーカーもしくはトリガー(inAreaで指定できるパラメータ) セーフゾーンのエリアを表す
			トリガーの場合は、範囲のみ指定して、それ以外は初期値にする。
			どうしてもセーフゾーンの監視を止めたいときはトリガーにする。(deleteVehicleでトリガーを消せば監視が終わる)
		2: Array: 適用しないユニット、ビークルのタイプ(isKindOfで指定するパラメータ)
		
	Return: None
	
	Example: ["marker_0"] execVM "safeZone.sqf";
	
	// グループ: sixGrp に規制区域内で発砲された場合通知する(すべてのクライアントで実行)
	[true, "TRI_safeZone_fired", {
		params ["_shooter", "_weapon"];
		
		private "_hintStr";
		_hintStr = format ["<<発砲規制区域内での発砲>>\n発砲者: %1\n使用武器: %2\n使用車両: %3",
			name _shooter,
			gettext (configfile >> "CfgWeapons" >> _weapon >> "displayName"),
			if (vehicle _shooter isEqualTo _shooter) then {"無し"} else {
				gettext (configfile >> "CfgVehicles" >> typeOf (vehicle _shooter) >> "displayName")}
		]; 
		
		_hintStr remoteExec ["hint", sixGrp];
	}] call BIS_fnc_addScriptedEventHandler;
*/
#define FIRED_EH_INDEX "TRI_safeZoneEHIndex"
#define EVENT_FIRED "TRI_safeZone_fired"

if (isDedicated || !hasInterface) exitWith {};
params [["_target", objNull], ["_exceptType", [], [[]]]];

waitUntil {sleep 1; !isNull player};
/* ローカル関数 */
private _local_fnc_isAnyType = {
	params ["_obj", "_typeList"];
	
	private _result = false;
	{
		if (_obj isKindOf _x) exitWith {_result = true};
	} forEach _typeList;
	
	_result
};

private _local_fnc_disableFiring = {
	params ["_unit"];
	
	if (isNil {_unit getVariable FIRED_EH_INDEX}) then {
		private _command_fire = {
			private _projectile = param [6, objNull, [objNull]];
			if (isNull _projectile) exitWith {};
			
			deleteVehicle _projectile;
			hint "<<発砲規制区域>>\n武器、兵器の使用ができません。";
			
			[missionNamespace, EVENT_FIRED, _this] call BIS_fnc_callScriptedEventHandler;
		};
	
		systemChat "発砲規制 - 開始";
		player setVariable [
			FIRED_EH_INDEX,
			player addEventHandler ["FiredMan", _command_fire]
		];
	};
};

private _local_fnc_enableFiring = {
	params ["_unit"];
	
	private _ehIndex = player getVariable FIRED_EH_INDEX;
	if !(isNil "_ehIndex") then {
		systemChat "発砲規制 - 停止";
		player removeEventHandler ["FiredMan", _ehIndex];
		player setVariable [FIRED_EH_INDEX, nil];
	};
};

/* メイン処理 */
if (!local player) exitWith {}; // おまじない

while {if (_target isEqualType objNull) then {alive _target} else {true}} do {
	if (player inArea _target) then {
		systemChat "発砲規制区域に入りました。";
		player allowDamage false;
		while {player inArea _target} do {
			if ([vehicle player, _exceptType] call _local_fnc_isAnyType) then {
				// 発砲規制 - 除外タイプ
				[player] call _local_fnc_enableFiring;
			} else {
				// 発砲規制 - 対象
				[player] call _local_fnc_disableFiring;
			};
			sleep 2;
		};
		systemChat "発砲規制区域を抜けました。";		
		[player] call _local_fnc_enableFiring;
		player allowDamage true;
	};
	sleep 2;
};

セーフゾーン複数ある時に効率悪いかなーと思ったけど、1つのファイルで終わらせようとすると見にくくなるし、そんなに沢山セーフゾーンあるわけでもないしなーと思って「セーフゾーン1個につき、1つの監視タスクを実行する仕様」にしました。

(ちなみに、paramsで指定したローカル変数は、privateを付けなくてもちゃんと識別されますよ。)