返信先: ARMA3 ミッションエディットスレ
ホーム › フォーラム › TRI Gaming フォーラム › ARMA3 ミッションエディットスレ › 返信先: ARMA3 ミッションエディットスレ
2017年6月24日 11:52 AM
#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を付けなくてもちゃんと識別されますよ。)