|
|
Модератор форума: GUNNER161, Panikaha |
Форум РЕДАКТОР - ArmA 3 Скрипты Боты в здании (Перемещение ботов по зданию) |
Боты в здании |
› Суббота
› 12.09.2015
› 09:20
› Сообщение #
Есть боты в здании,которые при активации триггеры должны подойти например к окнам и начать палить по коллоне!Пробывал маршрутными точками но тогда они сваливаютиз здания!Как можно ещё сделать?
|
› Понедельник
› 14.03.2016
› 21:06
› Сообщение #
Есть скрипт Argato по обороне зданий, для Арма 2. Почему бы не попробовать его портировать в АрмА 3 ?
Код /************************************* Скрипт круговой обороны здания Arigato Defense Building (v1.1) (c) Arigato Software, 2014 *************************************/ #define arg(i) (_this select (i)) #define x(p) ((p) select 0) #define y(p) ((p) select 1) #define z(p) ((p) select 2) #define sqr(x) ((x)*(x)) /* * * PUBLIC * * */ ARGT_DEFBUILD = { private [ "_group", "_building", "_index" ]; _group = if ( typeName arg(0) == "GROUP" ) then {arg(0)} else {group arg(0)}; _building = if ( typeName arg(1) == "OBJECT" ) then {arg(1)} else {nearestBuilding arg(1)}; _index = ARGT_DEFBUILD_INDEX; // индекс здания ARGT_DEFBUILD_INDEX = ARGT_DEFBUILD_INDEX + 1; // наращиваем значение индекса ARGT_DEFBUILD_POINTS set [_index, [_building, [], true]]; // записываем начальное состояние [_index, _building, _group] call ARGT_DEFBUILD_SCAN; // сканирование позиций в здании [_index, _group] spawn ARGT_DEFBUILD_GO; // занять позиции }; /* * * PRIVATE * * */ ARGT_DEFBUILD_POINTS = []; // массив позиций внутри зданий ARGT_DEFBUILD_INDEX = 0; // индекс текущего здания ARGT_DEFBUILD_SCAN = { // Сканирование позиций в здании private [ "_index", "_building", "_group", "_position", "_radius", "_points", "_chicken", "_free", "_pos", "_bpos", "_dir", "_size", "_size0", "_size1", "_a", "_b", "_c", "_angle" ]; _index = arg(0); _building = arg(1); _group = arg(2); _position = getPosATL _building; _radius = (sizeOf typeOf _building) / 2; // радиус дома _points = []; // массив позиций в здании [[x,y,z],dir,chicken,free] // Определяем позиции внутри здания и возле дверей _chicken = true; _free = true; { _pos = _building call compile format ["_this building%1 0", _x]; if ( x(_pos) != 0 ) then { _bpos = 1; while { x(_pos) != 0 } do { _dir = [_position, _pos] call ARGT_DEFBUILD_DIR; _points set [count _points, [_pos, floor _dir, _chicken, true]]; _bpos = _bpos + 1; _pos = _building call compile format ["_this building%1 %2", _x, _bpos]; }; }; if ( count _points >= count units _group ) exitWith {}; // позиций внутри здания достаточно _chicken = false; _free = false; } forEach ["Pos", "Exit"]; if ( count _points < count units _group ) then { // внутри здания не достаточно позиций, добавляем углы здания _size = boundingBox _building; _size0 = _size select 0; _size1 = _size select 1; _a = (x(_size1) - x(_size0)) / 2; _b = (y(_size1) - y(_size0)) / 2; _c = sqrt (sqr(_a) + sqr(_b)); if ( _c != 0 ) then { // позиции в углах дома _angle = asin (_a / _c) + getDir _building; for "_i" from 0 to 1 do { { _pos = [x(_position) + _x * _radius * sin _angle, y(_position) + _x * _radius * cos _angle, 0]; _dir = [_position, _pos] call ARGT_DEFBUILD_DIR; _points set [count _points, [_pos, _dir, false, true]]; } forEach [1, -1]; _angle = 90 + _angle; }; }; }; ARGT_DEFBUILD_POINTS set [_index, [_building, _points, _free]]; // [здание, массив_позиций, флаг_наличия_свободных_позиций] }; ARGT_DEFBUILD_GO = { // Движение к зданию и занятие позиций private [ "_group", "_index", "_building", "_radius", "_position", "_points", "_free", "_radius", "_dir", "_pos", "_handler", "_count", "_idx", "_chicken" ]; _index = arg(0); _group = arg(1); _building = (ARGT_DEFBUILD_POINTS select _index) select 0; // здание _radius = (sizeOf typeOf _building) / 2; // радиус здания _position = getPosATL _building; // координаты здания _points = (ARGT_DEFBUILD_POINTS select _index) select 1; // позиции внутри здания _free = (ARGT_DEFBUILD_POINTS select _index) select 2; // наличие лишних позиций // Движение к зданию _dir = [_position, getPosATL leader _group] call ARGT_DEFBUILD_DIR; _pos = [x(_position) + _radius * sin _dir, y(_position) + _radius * cos _dir]; _group move _pos; _group setSpeedMode "FULL"; _group setBehaviour "AWARE"; _group setCombatMode "YELLOW"; _handler = [leader _group, _position, _radius * 2] spawn ARGT_DEFBUILD_BUSY; waitUntil { scriptDone _handler }; // Движемся к позициям в здании _count = count _points; { if ( alive _x && ! (_x in switchableUnits) ) then { if ( _count > 0 ) then { // еще остались незанятые позиции waitUntil { _idx = floor random count _points; // выбираем случайную позицию в здании (_points select _idx) select 3 // проверяем ее на незанятость }; _count = _count - 1; _pos = (_points select _idx) select 0; _dir = (_points select _idx) select 1; _chicken = (_points select _idx) select 2; _points set [_idx, [_pos, _dir, _chicken, false]]; } else { // все свободные позиции заняты _idx = -1; _angle = random 360; _pos = [x(_position) + _radius * sin _angle, y(_position) + _radius * cos _angle, 0]; _dir = [_position, _pos] call ARGT_DEFBUILD_DIR; _chicken = false; }; [_x, _pos, _dir, _chicken, _free] spawn ARGT_DEFBUILD_POSITION; // движемся на позицию _x setVariable ["ARGT_DEFBUILD_INDEX", _index, true]; // запоминаем индекс здания _x setVariable ["ARGT_DEFBUILD_IDX", _idx, true]; // запоминаем индекс занятой ботом позиции }; } forEach units _group; ARGT_DEFBUILD_POINTS set [_index, [_building, _points, _free]]; // [здание, массив_позиций, флаг_наличия_свободных_позиций] }; ARGT_DEFBUILD_MOVE = { // Движение внутри здания private [ "_index", "_idx", "_points", "_point", "_i" ]; _index = _this getVariable "ARGT_DEFBUILD_INDEX"; // индекс здания _idx = _this getVariable "ARGT_DEFBUILD_IDX"; // индекс занятой позиции в здании _points = (ARGT_DEFBUILD_POINTS select _index) select 1; _point = _points select _idx; _point set [3, true]; waitUntil { _i = floor random count _points; // выбираем случайную позицию в здании (_points select _i) select 3 && _i != _idx// проверяем ее на незанятость }; _point = _points select _i; _point set [3, false]; // отмечаем найденную позицию как занятую _this setVariable ["ARGT_UNIT_AUTO", false, true]; // флаг не менять положение юнита _this setVariable ["ARGT_UNIT_STOP", false, true]; // прекращаем сидение на месте [_this, _point select 0, _point select 1, true, true] spawn ARGT_DEFBUILD_POSITION; // движемся на позицию }; ARGT_DEFBUILD_DIR = { // Расчет угла между двумя точками private [ "_pos1", "_pos2", "_distance", "_dir" ]; _pos1 = arg(0); _pos2 = arg(1); _distance = [x(_pos1), y(_pos1), 0] distance [x(_pos2), y(_pos2), 0]; _dir = if ( _distance != 0 ) then {asin ((x(_pos2) - x(_pos1)) / _distance)} else {random 360}; if ( y(_pos2) < y(_pos1) ) then {_dir = 180 - _dir}; _dir }; ARGT_DEFBUILD_BUSY = { // Ожидание завершения движения private [ "_unit", "_position", "_radius", "_timeout", "_pos", "_ready", "_distance" ]; _unit = arg(0); _position = arg(1); _radius = arg(2); _timeout = time + 30; _pos = [0, 0, 0]; waitUntil { if ( _pos distance _unit > 4 ) then { _pos = getPosATL _unit; _timeout = time + 30; }; _ready = moveToCompleted _unit || moveToFailed _unit || unitReady _unit; _distance = _unit distance _position; _ready || _distance < _radius || time > _timeout || ! alive _unit }; if ( _distance > _radius ) then {_unit setVariable ["ARGT_DEFBUILD_CHANCE", 0.8, true]}; // плохая позиция, повышаем шанс смены }; ARGT_DEFBUILD_POSITION = { // Двигаться и занять указанную позицию private [ "_unit", "_position", "_dir", "_chicken", "_free", "_handler" ]; _unit = arg(0); _position = arg(1); _dir = arg(2); _chicken = arg(3); _free = arg(4); _unit setVariable ["ARGT_DEFBUILD_CHANCE", 0.2, true]; // шанс сменить позицию _unit doMove _position; _handler = [_unit, _position, 1] spawn ARGT_DEFBUILD_BUSY; waitUntil { scriptDone _handler }; _position = getPosATL _unit; _unit doWatch [x(_position) + 10 * sin _dir, y(_position) + 10 * cos _dir, z(_position)]; if ( _chicken ) then { [_unit, _free] spawn ARGT_DEFBUILD_CHICKEN; } else { _unit setUnitPos "MIDDLE"; _unit spawn ARGT_DEFBUILD_STOP; }; }; ARGT_DEFBUILD_CHICKEN = { // Бот в обороне здания private [ "_unit", "_free", "_handler1", "_handler2", "_position" ]; _unit = arg(0); _free = arg(1); _handler1 = _unit addEventHandler ["FiredNear", { if ( side arg(0) getFriend side arg(1) < 0.6 ) then { arg(0) setUnitPos "MIDDLE"; arg(0) doWatch objNull; }; }]; _handler2 = _unit addEventHandler ["Fired", { arg(0) setUnitPos "MIDDLE"; }]; _unit setvariable ["ARGT_UNIT_STOP", true, true]; _unit spawn ARGT_DEFBUILD_STOP; _unit setUnitPos "MIDDLE"; sleep 5; _position = getPosATL _unit; while { alive _unit && _unit getVariable "ARGT_UNIT_STOP" } do { _unit setPosATL _position; // попровляем положение юнита if ( _unit getVariable "ARGT_DEFBUILD_CHANCE" < 0.8 ) then {_unit setUnitPos "UP"}; // если юнит в нормальной позиции sleep (3 + random 10); if ( _unit distance _position > 0.6 ) exitWith { if ( _free ) then {_unit call ARGT_DEFBUILD_MOVE}; }; // юнит сильно сместился со своей позиции if ( alive _unit && _unit getVariable "ARGT_UNIT_STOP" ) then { _unit setUnitPos "MIDDLE"; sleep (5 + random 20); if ( _free && random 1 < _unit getVariable "ARGT_DEFBUILD_CHANCE" ) exitWith { // запускаем процесс смены позиции в здании _unit call ARGT_DEFBUILD_MOVE; }; }; }; _unit setVariable ["ARGT_UNIT_STOP", false, true]; _unit removeEventHandler ["FiredNear", _handler1]; _unit removeEventHandler ["Fired", _handler2]; }; ARGT_DEFBUILD_STOP = { // Остановка юнита (вместо disableai "move") private "_handler"; _this setVariable ["ARGT_UNIT_STOP", true, true]; _this setVariable ["ARGT_UNIT_AUTO", true, true]; // флаг восстановить положение юнита _handler = _this addEventHandler ["HandleDamage", { arg(0) setVariable ["ARGT_UNIT_STOP", false, true]; [arg(0), "RED"] call ARGT_DEFENCE_COMBATMODE; arg(2) }]; waitUntil { _this forceSpeed 0; ! alive _this || ! (_this getVariable "ARGT_UNIT_STOP") }; _this setVariable ["ARGT_UNIT_STOP", false, true]; _this removEeventHandler ["HandleDamage", _handler]; _this forceSpeed -1; _this doWatch objNull; if ( _this getVariable "ARGT_UNIT_AUTO" ) then {_this setUnitPos "AUTO"}; }; ARGT_DEFENCE_COMBATMODE = { // Установить поведение отдельного бота private [ "_unit", "_combatmode", "_group", "_tempgroup" ]; _unit = arg(0); _combatmode = arg(1); _group = group _unit; _tempgroup = createGroup side _unit; [_unit] joinSilent _tempgroup; _unit setCombatMode _combatmode; [_unit] joinSilent _group; deleteGroup _tempgroup; }; Добавлено (14.03.2016, 21:06) |
| |||
| |||
Чат сайта |