Фиксер втащил ящик со снаряжением в тесный трюм корабля-перехватчика.
– Мне больше нравится, когда мы всё взрываем и размазываем по стенам геонозианцев. А эти вот размышления рискуют плохо закончиться.
Команда ЭРК "Дельта"
Карен Тревисс, "Истинное Лицо"





Сколько глобус ни крути, там Fess-Style не найти...
Сайт Fess'a
Главная » 2015 » Февраль » 8 » Скрипт «Активная защита»
14:05
Скрипт «Активная защита»

Активная защита - представляет собой расположенные на танке системы отстрела специальных снарядов, совмещённые с радиолокационной системой локального действия. При обнаружении приближающегося к танку боеприпаса (гранаты противотанкового гранатомёта и т.п.) даётся команда на отстрел заряда, который при сближении со снарядом взрывается, формируя облако осколков, уничтожающих, или, по меньшей мере, сильно ослабляющих действие боеприпаса (с) Википедия



Мы напишем две версии скрипта. Первый вариант будет работать быстро, но способен отражать только ракеты с самонаведением. Такие ракеты пускают ПУ «Титан», NLAW и некоторая техника.

Второй вариант будет работать намного медленнее, но зато мы сможем отражать абсолютно любые ракеты, летящие с подходящей стороны. То есть мы сможем блочить РПГ «Аламут» и даже ракеты «Пауни».

Сформулируем наши правила для первого скрипта
- мы будем отражать только ракеты с самонаведением на цель
- ликвидацией снаряда будем считать устранение возможного ущерба транспорту - то есть нам не обязательно уничтожать снаряд, мы можем и просто сбить его с курса
- у транспорта будут четыре стороны, ракеты будут отражаться спереди, сзади и с боков
- каждая сторона имеет свой собственный счетчик патронов активной защиты (назовём их активпатронами)
- будем игнорировать угол приближения ракеты, т.е. отражаем даже удары в крышу и в дно
- после срабатывания активпатрона мы хотим иметь возможность уводить систему на перезарядку (aka кулдаун)

Аргументы

Код
_car = _this select 0; // техника, которую хотим защитить
_rounds = _this select 1; // кол-во активпатронов с каждой стороны
_cooldown = _this select 2; // время перезарядки, может быть 0


Использование

Цитата
Использование 1 :
as = [Object, [LeftSideAmmo, RightSideAmmo, FrontAmmo, BackAmmo], CoolDown_aka_ReloadTime] execVM "FS_ActiveDefence.sqf"
as = [this, [1, 1, 1, 1], 10] execVM "FS_ActiveDefence.sqf"

Использование 2 :
as = [Object, AmmoForEachSide, CoolDown_aka_ReloadTime] execVM "FS_ActiveDefence.sqf"
as = [this, 5, 10] execVM "FS_ActiveDefence.sqf"

Примечание :
[this, 5, 10] эквивалентно [this, [5, 5, 5, 5], 10]


Полная версия скрипта

Код
#ifndef FS_ACTIVE_DEFENCE
#define FS_ACTIVE_DEFENCE

FS_ActiveDefence_Handler = {
  _vehicle = _this select 0;
  _type = _this select 1;
  _shooter = _this select 2;
   
  _side = '';
  _missle = ObjNull;
   
  _m = getPos _shooter nearObjects [_type, 20];
  if (count _m >= 1) then {_missle = _m select 0};  
  if (isNull _missle) exitWith {};
   
  _dir = [_vehicle, _missle] call BIS_fnc_relativeDirTo;
   
  if (_dir >= 0 && _dir < 45 || _dir >= 315) then { _side = 'Front' } else {
  if (_dir >= 45 && _dir < 135) then { _side = 'Right' } else {
  if (_dir >= 135 && _dir < 225) then { _side = 'Back' } else {
  if (_dir >= 225 && _dir < 315) then { _side = 'Left' };  
  };
  };
  };
   
  _ammo = _vehicle getVariable [format ['FS_ActiveDefence_%1', _side], 0];
  _cldwn = _vehicle getVariable [format ['FS_ActiveDefence_%1_CLDWN', _side], 0];
  if (_ammo == 0 || _cldwn > 0) exitWith {};
  _cldwn = _vehicle getVariable ['FS_ActiveDefence_CLDWN', 0];
   
  waitUntil {_vehicle distance _missle < 30 || !alive _missle || !alive _vehicle};
   
  if (alive _vehicle) then {
  //_missle setDamage 1;
  _missle setVelocity [0,0,2000];
   
  _vehicle setVariable [format ['FS_ActiveDefence_%1', _side], _ammo - 1, TRUE];
  _vehicle setVariable [format ['FS_ActiveDefence_%1_CLDWN', _side], _cldwn, TRUE];
   
  _checkFront = _vehicle getVariable ['FS_ActiveDefence_Front', 0];
  _checkBack = _vehicle getVariable ['FS_ActiveDefence_Back', 0];
  _checkRight = _vehicle getVariable ['FS_ActiveDefence_Right', 0];
  _checkLeft = _vehicle getVariable ['FS_ActiveDefence_Left', 0];
   
  if (_checkFront + _checkBack + _checkRight + _checkLeft == 0) then {
  _vehicle setVariable ['FS_ActiveDefence_Protected', false, TRUE];
  };
   
  while {_cldwn > 0} do {
  _cldwn = _cldwn - 1;
  _vehicle setVariable [format ['FS_ActiveDefence_%1_CLDWN', _side], _cldwn, TRUE];
  sleep 1;
  };
  };
};

FS_ActiveDefence_HUD_func = {
  _color = "#ffffff";
  if (_this select 2 > 0) then {_color = "#ecc200"};
  if (_this select 1 == 0) then {_color = "#ff0000"};
  format ["<t color = '%3'>%1%2</t>", _this select 0, _this select 1, _color]
};

/* HUD */

[] spawn {
  disableSerialization;
  _layer = 'FS_ActiveDefence_HUD' call BIS_fnc_rscLayer;
  _layer cutRsc ['RscDynamicText', 'PLAIN'];
  _ctrl = (uiNamespace getVariable 'BIS_dynamicText') displayCtrl 9999;
  _ctrl ctrlSetPosition [0,0.15];
  while {true} do  
  {
  while {vehicle player getVariable ['FS_ActiveDefence_Protected', false]} do  
  {
  _car = vehicle player;
  _ctrl ctrlSetFade 0;
  _ctrl ctrlCommit 0;
  _text = format
  [
  "<t align = 'center' shadow = '0' size = '0.7'>Active Defence<br/>%1 %2 %3 %4</t>",
  ['L', _car getVariable ['FS_ActiveDefence_Left', 0], _car getVariable ['FS_ActiveDefence_Left_CLDWN', 0]] call FS_ActiveDefence_HUD_func,
  ['R', _car getVariable ['FS_ActiveDefence_Right', 0], _car getVariable ['FS_ActiveDefence_Right_CLDWN', 0]] call FS_ActiveDefence_HUD_func,
  ['F', _car getVariable ['FS_ActiveDefence_Front', 0], _car getVariable ['FS_ActiveDefence_Front_CLDWN', 0]] call FS_ActiveDefence_HUD_func,
  ['B', _car getVariable ['FS_ActiveDefence_Back', 0], _car getVariable ['FS_ActiveDefence_Back_CLDWN', 0]] call FS_ActiveDefence_HUD_func
  ];
  _ctrl ctrlSetStructuredText parseText _text;
  sleep 0.5;
  };
  _ctrl ctrlSetFade 1;
  _ctrl ctrlCommit 0;
  sleep 0.5;
  };
};
#endif

_car = _this select 0;
_rounds = _this select 1;
_cooldown = _this select 2;

_roundsLeft = _rounds;
_roundsRight = _rounds;
_roundsFront = _rounds;
_roundsBack = _rounds;

if (typeName _rounds == "ARRAY") then {
  _roundsLeft = _rounds select 0;
  _roundsRight = _rounds select 1;
  _roundsFront = _rounds select 2;
  _roundsBack = _rounds select 3;
};

_car setVariable ["FS_ActiveDefence_Protected", true, TRUE];
_car setVariable ["FS_ActiveDefence_Left", _roundsLeft, TRUE];
_car setVariable ["FS_ActiveDefence_Right", _roundsRight, TRUE];
_car setVariable ["FS_ActiveDefence_Front", _roundsFront, TRUE];
_car setVariable ["FS_ActiveDefence_Back", _roundsBack, TRUE];

_car setVariable ["FS_ActiveDefence_CLDWN", _cooldown, TRUE];
_car setVariable ["FS_ActiveDefence_Left_CLDWN", 0, TRUE];
_car setVariable ["FS_ActiveDefence_Right_CLDWN", 0, TRUE];
_car setVariable ["FS_ActiveDefence_Front_CLDWN", 0, TRUE];
_car setVariable ["FS_ActiveDefence_Back_CLDWN", 0, TRUE];

if (!isNil {_car getVariable "FS_ActiveDefence_EV"}) then {
  _id = _car getVariable "FS_ActiveDefence_EV";
  _car removeEventHandler ["IncomingMissile", _id];
};  

_id = _car addEventHandler ["IncomingMissile", {_this spawn FS_ActiveDefence_Handler}];
_car setVariable ["FS_ActiveDefence_EV", _id, TRUE];


Скачать скрипт файлом

Вторая версия скрипта будет намного сложнее, но зато мы сможем отражать любые ракеты, в том числе неуправляемые.

В целом, наш код сильно усложнился, и из-за команды nearObjects работает теперь намного медленнее. Дело в том, что nearObjects вместе с подлетающими ракетами вываливает абсолютно все объекты рядом, включая бабочек, камни и стоящие рядом кусты, и нам каждый раз приходится фильтровать весь этот мусор, вытаскивая из него только ракеты.

Код


#ifndef FS_ACTIVE_DEFENCE
#define FS_ACTIVE_DEFENCE

FS_ActiveDefence_HUD_func = {
    _color = "#ffffff";
    if (_this select 2 > 0) then {_color = "#ecc200"};
    if (_this select 1 == 0) then {_color = "#ff0000"};
    format ["<t color = '%3'>%1%2</t>", _this select 0, _this select 1, _color]
};

/* HUD */

[] spawn {
    disableSerialization;
    _layer = 'FS_ActiveDefence_HUD' call BIS_fnc_rscLayer;
    _layer cutRsc ['RscDynamicText', 'PLAIN'];
    _ctrl = (uiNamespace getVariable 'BIS_dynamicText') displayCtrl 9999;
    _ctrl ctrlSetPosition [0,0.15];
    while {true} do
    {
        
        while {vehicle player getVariable ['FS_ActiveDefence_Protected', false]} do
        {
            _car = vehicle player;
            _ctrl ctrlSetFade 0;
            _ctrl ctrlCommit 0;
            _text = format
            [
                "<t align = 'center' shadow = '0' size = '0.7'>Active Defence<br/>%1 %2 %3 %4</t>",
                ['L', _car getVariable ['FS_ActiveDefence_Left', 0], _car getVariable ['FS_ActiveDefence_Left_CLDWN', 0]] call FS_ActiveDefence_HUD_func,
                ['R', _car getVariable ['FS_ActiveDefence_Right', 0], _car getVariable ['FS_ActiveDefence_Right_CLDWN', 0]] call FS_ActiveDefence_HUD_func,
                ['F', _car getVariable ['FS_ActiveDefence_Front', 0], _car getVariable ['FS_ActiveDefence_Front_CLDWN', 0]] call FS_ActiveDefence_HUD_func,
                ['B', _car getVariable ['FS_ActiveDefence_Back', 0], _car getVariable ['FS_ActiveDefence_Back_CLDWN', 0]] call FS_ActiveDefence_HUD_func
            ];
            _ctrl ctrlSetStructuredText parseText _text;
            sleep 0.5;
        };
        _ctrl ctrlSetFade 1;
        _ctrl ctrlCommit 0;
        sleep 0.5;
    };
};
#endif

_car = _this select 0;
_rounds = _this select 1;
_cooldown = _this select 2;

_roundsLeft = _rounds;
_roundsRight = _rounds;
_roundsFront = _rounds;
_roundsBack = _rounds;

if (typeName _rounds == "ARRAY") then {
    _roundsLeft = _rounds select 0;
    _roundsRight = _rounds select 1;
    _roundsFront = _rounds select 2;
    _roundsBack = _rounds select 3;
};

/* Checks */

if (isNull _car) exitWith {};

if (_roundsLeft + _roundsRight + _roundsFront + _roundsBack == 0) exitWith {
    _car setVariable ["FS_ActiveDefence_Protected", false, TRUE];
};

/* ------ */

_car setVariable ["FS_ActiveDefence_KnownRockets", [], TRUE];
_car setVariable ["FS_ActiveDefence_Protected", true, TRUE];
    
_car setVariable ["FS_ActiveDefence_Left", _roundsLeft, TRUE];
_car setVariable ["FS_ActiveDefence_Right", _roundsRight, TRUE];
_car setVariable ["FS_ActiveDefence_Front", _roundsFront, TRUE];
_car setVariable ["FS_ActiveDefence_Back", _roundsBack, TRUE];

_car setVariable ["FS_ActiveDefence_CLDWN", _cooldown, TRUE];
_car setVariable ["FS_ActiveDefence_Left_CLDWN", 0, TRUE];
_car setVariable ["FS_ActiveDefence_Right_CLDWN", 0, TRUE];
_car setVariable ["FS_ActiveDefence_Front_CLDWN", 0, TRUE];
_car setVariable ["FS_ActiveDefence_Back_CLDWN", 0, TRUE];

while {_car getVariable ["FS_ActiveDefence_Protected", FALSE]} do {

    // Регистрация ракет
    _objects = getPos _car nearObjects 30;
    _rockets = [];
    
    {
        if (typeOf _x isKindOf "MissileBase") then { _rockets = _rockets + [_x] };
    }
    forEach _objects;
    _objects = nil;
    
    {
        // Установка слежки за ракетой
        if (!(_x in (_car getVariable "FS_ActiveDefence_KnownRockets"))) then {
            [_car, _x] spawn {
                _vehicle = _this select 0;
                _missle = _this select 1;
                
                // Убираем взорвавшиеся ракеты из спика слежки
                _realRockets = [];
                _knownRockets = _vehicle getVariable "FS_ActiveDefence_KnownRockets";
                {
                    if (!isNull _x) then {_realRockets = _realRockets + [_x] };
                } forEach _knownRockets;
                _knownRockets = _realRockets + [_missle];
                _vehicle setVariable ["FS_ActiveDefence_KnownRockets", _knownRockets, TRUE];
                
                _side = '';
                _dir = [_vehicle, _missle] call BIS_fnc_relativeDirTo;
                
                if (_dir >= 0 && _dir < 45 || _dir >= 315) then { _side = 'Front' } else {
                    if (_dir >= 45 && _dir < 135) then { _side = 'Right' } else {
                        if (_dir >= 135 && _dir < 225) then { _side = 'Back' } else {
                            if (_dir >= 225 && _dir < 315) then { _side = 'Left' };            
                        };
                    };
                };
                
                _ammo = _vehicle getVariable [format ['FS_ActiveDefence_%1', _side], 0];
                _cldwn = _vehicle getVariable [format ['FS_ActiveDefence_%1_CLDWN', _side], 0];
                if (_ammo == 0 || _cldwn > 0) exitWith {};
                _cldwn = _vehicle getVariable ['FS_ActiveDefence_CLDWN', 0];
                
                waitUntil {_vehicle distance _missle < 30 || !alive _missle || !alive _vehicle};
                
                if (alive _missle && alive _vehicle) then {
                    
                    _missle setDamage 1;
                    _missle setVelocity [0,0,2000];
                    
                    _vehicle setVariable [format ['FS_ActiveDefence_%1', _side], _ammo - 1, TRUE];
                    _vehicle setVariable [format ['FS_ActiveDefence_%1_CLDWN', _side], _cldwn, TRUE];
                    
                    _checkFront = _vehicle getVariable ['FS_ActiveDefence_Front', 0];
                    _checkBack = _vehicle getVariable ['FS_ActiveDefence_Back', 0];
                    _checkRight = _vehicle getVariable ['FS_ActiveDefence_Right', 0];
                    _checkLeft = _vehicle getVariable ['FS_ActiveDefence_Left', 0];
                    
                    if (_checkFront + _checkBack + _checkRight + _checkLeft == 0) then {
                        _vehicle setVariable ['FS_ActiveDefence_Protected', false, TRUE];
                    };
                    
                    while {_cldwn > 0} do {
                        _cldwn = _cldwn - 1;
                        _vehicle setVariable [format ['FS_ActiveDefence_%1_CLDWN', _side], _cldwn, TRUE];
                        sleep 1;
                    };
                    
                };
            };
        };
    } forEach _rockets;
    sleep 0.05;
};

 


Скачать скрипт файлом

 

Категория: Arma 3 | Просмотров: 2302 | Добавил: Fess
Всего комментариев: 1
Комментарий № 1 написал: Fess
0  
05.09.2016 | Понедельник | 04:06

По просьбам трудящихся вот миссия для редактора https://yadi.sk/d/-QpBB3bZumX8z . Скачивайте скрипты файлом, так как там я добавил одно условие, которое включает активную защиту только если включён двигатель.

Добавлять комментарии могут только зарегистрированные пользователи.
[ Регистрация | Вход ]

Форма входа

Категории раздела

Arma 3 [11]
Сайт [2]
Мысли и обзоры [5]
Minecraft [1]

Поиск

Наш опрос

Редкий выход видеороликов?

Архив | Результаты

Мини-чат

200



Статистика


Онлайн всего: 1
Те, кому лень регаться: 1
Пользователей: 0