1


Благодарности/Неодобрения |
Получено: 62/4 Отправлено: 30/0 |
tym32167 commented 7 days ago
Алгоритм установки отряда.
- Открываем карту
- Наводим курсор чуть выше и правее целевого перекрестия на карте, видим на мышке координаты
- На рисунке координаты отмеченной точки - 035, 131
- В коде эти координаты превратятся в [3500,13100,0]
- Открываем скрипт. заполняем поля
Код:_radius = 100; _bots = 30; _side = EAST; _startPos = [3500,13100,0];
- В итоге получаем
Код:_radius = 100; _bots = 30; _side = EAST; _startPos = [3500,13100,0]; _units = ["O_Soldier_F","O_Soldier_GL_F","O_Soldier_AR_F","O_Soldier_SL_F","O_Soldier_TL_F","O_soldier_M_F","O_Soldier_LAT_F","O_medic_F","O_soldier_repair_F","O_soldier_exp_F","O_Soldier_AT_F","O_Soldier_AA_F","O_engineer_F","O_soldier_PG_F","O_recon_F","O_recon_M_F","O_recon_LAT_F","O_recon_medic_F","O_recon_TL_F","O_Soldier_AAT_F","O_soldierU_M_F","O_SoldierU_GL_F"]; if (!isServer) exitWith {}; _grp = createGroup _side; _goodPos = []; TB_fnc_relativePos = { private [_p1, _dir, _dst, _r,_alt]; _p1 = _this select 0; _dir = _this select 1; _dst = _this select 2; _alt = 0; if (count _this == 3) then { _alt = _this select 3; }; _r = [(_p1 select 0) + sin _dir * _dst, (_p1 select 1) + cos _dir * _dst, _alt]; _r }; _houseList = nearestObjects [_startPos, ["building"], _radius]; { _c = 0; while { format ["%1", _x buildingPos _c] != "[0,0,0]" } do { _goodPos set [(count _goodPos), [_x, _x buildingPos _c]]; _c = _c + 1; }; } forEach _houseList; _goodPos = _goodPos call BIS_fnc_arrayShuffle; if ((count _goodPos) < _bots) then { _bots = count _goodPos; }; for "_i" from 1 to _bots do { _point = (_goodPos select (_i - 1)); _house = _point select 0; _pos = _point select 1; _unit = _grp createUnit [(_units call BIS_fnc_selectRandom), [0, 0, 0], [], 0, "CAN_COLLIDE"]; _unit setPosATL _pos; _watchDir = (([_unit, _house] call BIS_fnc_dirTo) + 180); _unit setDir _watchDir; _unit setUnitPos (["UP", "MIDDLE"] call BIS_fnc_selectRandom) ; doStop _unit; _watchPos = [getPos _unit, _watchDir, ((round (random 30) + 30)), 1] call TB_fnc_relativePos; _unit doWatch _watchPos; }; { _x addCuratorEditableObjects [(units _grp), true]; } forEach allCurators;
- Запускаем скрипт НА СЕРВЕРЕ
- Профит.
Если нужно прямо точно знать координаты.
- Ставим своего персонажа в целевую точку
- Запускам ЛОКАЛЬНО
Код:_pos = getPos player; copyToClipboard format ["%1", getPos player]; player sideChat format ["%1", _pos];
Благодарности/Неодобрения |
Получено: 64/0 Отправлено: 12/0 |
Вот новый вариант:
[startPos, radius, bots, side, (bool) zeus curator (optional), (array) black list of buildings (optional)] call QS_fnc_FillBots;
startPos - координаты центра зоны ([x,y] или [x,y,z])
radius - радиус зоны в метрах
bots - количество ботов
side - сторона (EAST, WEST, RESISTANCE)
zeus curator - добавлять ли ботам управление для Зевса (true/false). По-умолчанию false
black list of buildings - черный список зданий куда боты не будут заселены (массив объектов). По-умолчанию пустой массив.
Примeры:
заселит 80 красных ботов а зданиях которые есть в радиусе 150м от координат [3500,13100] и добавит им управление через Zeus.Код:[[3500,13100], 150, 80, EAST, true] call QS_fnc_FillBots;
заселит 8 синих ботов в пределах 10м (примерно 1-2 здания) около точки [3500,13100] без управления через Zeus.Код:[[3500,13100], 10, 8, WEST] call QS_fnc_FillBots;
Не все получилось что хотелось - ждем исправления БИСами ошибки с float number positions.
Благодарности/Неодобрения |
Получено: 14/1 Отправлено: 15/0 |
Благодарности/Неодобрения |
Получено: 64/0 Отправлено: 12/0 |
Посмотри https://github.com/ToxaBes/ADR-Spec-...n_FillBots.sqf (внутри используется еще пара функций/скриптов которые расположены там же в репозитарии)
В этом варианте есть возможность указать точность и боты на позициях без окон не стоят а патрулируют здания внутри. Если не разберешься то помогу написать нужный вариант когда вернусь.
Благодарности/Неодобрения |
Получено: 64/0 Отправлено: 12/0 |
Я так понял тебе нужен скрипт чтобы зевсовать на офф. серверах Армы. Вот вариант с патрулями, указанием ранга и скила ботов:
Пример для Алтиса (заваруха в Кавале):Код:TB_fnc_fillBots = { if (!isServer) exitWith {}; _startPos = _this select 0; if (count _startPos > 2) then { _startPos resize 2; }; _radius = _this select 1; _bots = _this select 2; _side = _this select 3; _defaultRank = selectRandom ["CAPTAIN","MAJOR","COLONEL"]; _rank = _this param [4, _defaultRank]; _skill = _this param [5, 0.5]; _zeusCurator = _this param [6, false]; _blackList = _this param [7, []]; _bridges = ["Land_Bridge_HighWay_PathLod_F","Land_Bridge_Concrete_PathLod_F","Land_Bridge_Asphalt_PathLod_F","Land_Bridge_01_PathLod_F"]; _towers = ["Land_Cargo_Tower_V1_F","Land_Cargo_Tower_V1_No1_F","Land_Cargo_Tower_V1_No2_F","Land_Cargo_Tower_V1_No3_F","Land_Cargo_Tower_V1_No4_F", "Land_Cargo_Tower_V1_No5_F","Land_Cargo_Tower_V1_No6_F","Land_Cargo_Tower_V1_No7_F","Land_Cargo_Tower_V2_F","Land_Cargo_Tower_V3_F"]; _groups = []; _units = []; switch (_side) do { case WEST : { _units = ["B_GEN_Soldier_F","B_GEN_Commander_F","B_helicrew_F","B_Soldier_GL_F","B_Soldier_GL_F","B_engineer_F","B_Soldier_TL_F","B_Soldier_SL_F", "B_medic_F","B_Sharpshooter_F","B_soldier_repair_F","B_soldier_UAV_F","B_soldier_UAV_06_F","B_soldier_UAV_06_medical_F","B_officer_F", "B_Soldier_A_F","B_soldier_AAR_F","B_soldier_AAA_F","B_soldier_AAT_F","B_support_AMG_F","B_support_AMG_F","B_support_AMort_F","B_soldier_AR_F", "B_HeavyGunner_F","B_soldier_AA_F","B_soldier_AT_F","B_soldier_exp_F","B_soldier_M_F","B_soldier_mine_F","B_Soldier_F","B_soldier_M_F", "B_soldier_mine_F","B_Soldier_F","B_support_MG_F","B_support_Mort_F","B_soldier_LAT_F","B_support_GMG_F","B_Soldier_lite_F","B_recon_TL_F", "B_spotter_F","B_recon_F","B_recon_LAT_F","B_recon_JTAC_F","B_recon_exp_F","B_recon_medic_F","B_recon_M_F","B_Recon_Sharpshooter_F","B_sniper_F", "B_ghillie_ard_F","B_ghillie_lsh_F","B_ghillie_sard_F","B_Patrol_Engineer_F","B_Patrol_Soldier_TL_F","B_Patrol_Medic_F","B_Patrol_Soldier_UAV_F", "B_Patrol_Soldier_A_F","B_Patrol_HeavyGunner_F","B_Patrol_Soldier_AR_F","B_Patrol_Soldier_MG_F","B_Patrol_Soldier_AT_F","B_Patrol_Soldier_M_F", "B_CTRG_Soldier_TL_tna_F","B_CTRG_Soldier_Exp_tna_F","B_CTRG_Soldier_AR_tna_F","B_CTRG_Soldier_tna_F","B_CTRG_Soldier_LAT_tna_F", "B_CTRG_Soldier_Medic_tna_F","B_CTRG_Soldier_M_tna_F","B_CTRG_Soldier_JTAC_tna_F","B_G_Soldier_GL_F","B_G_engineer_F","B_G_Soldier_TL_F", "B_G_Soldier_SL_F","B_G_medic_F","B_G_Sharpshooter_F","B_G_officer_F","B_G_Soldier_A_F","B_G_Soldier_AR_F","B_G_Soldier_exp_F","B_G_Soldier_M_F", "B_G_Soldier_F","B_G_Soldier_LAT_F","B_G_Soldier_unarmed_F","B_G_Soldier_lite_F"]; }; case RESISTANCE : { _units = ["I_Soldier_GL_F","I_engineer_F","I_Soldier_TL_F","I_Soldier_SL_F","I_soldier_UAV_06_F","I_Soldier_A_F","I_Soldier_AAR_F","I_Soldier_AAA_F", "I_Soldier_AAT_F","I_support_AMG_F","I_support_AMort_F","I_Soldier_AR_F","I_Soldier_AA_F","I_Soldier_AT_F","I_Soldier_exp_F","I_Soldier_M_F", "I_soldier_mine_F","I_soldier_F","I_support_MG_F","I_support_Mort_F","I_Soldier_LAT_F","I_support_GMG_F","I_Soldier_lite_F","I_Sniper_F", "I_G_Sharpshooter_F","I_G_officer_F","I_G_Soldier_A_F","I_G_Soldier_AR_F","I_G_Soldier_exp_F","I_G_Soldier_M_F","I_G_Soldier_F","I_G_Soldier_LAT_F", "I_G_Soldier_lite_F","I_C_Soldier_Bandit_8_F","I_C_Soldier_Bandit_7_F","I_C_Soldier_Bandit_6_F","I_C_Soldier_Bandit_4_F","I_C_Soldier_Bandit_2_F", "I_C_Soldier_Bandit_3_F","I_C_Soldier_Bandit_1_F","I_C_Pilot_F","I_C_Soldier_Bandit_5_F","I_C_Soldier_Para_2_F","I_C_Soldier_Para_7_F", "I_C_Soldier_Para_8_F","I_C_Soldier_Para_3_F","I_C_Helipilot_F","I_C_Soldier_Para_6_F","I_C_Soldier_Para_1_F","I_C_Soldier_Para_5_F", "I_C_Soldier_Para_4_F","I_medic_F","I_Soldier_repair_F","I_soldier_UAV_F","I_soldier_UAV_06_medical_F","I_officer_F","I_Spotter_F", "I_ghillie_ard_F","I_ghillie_lsh_F","I_ghillie_sard_F","I_G_Soldier_GL_F","I_G_engineer_F","I_G_Soldier_TL_F","I_G_Soldier_SL_F","I_G_medic_F"]; }; case EAST : { _units = ["O_Soldier_GL_F","O_Soldier_TL_F","O_medic_F","O_soldier_repair_F","O_soldier_UAV_06_F","O_soldier_UAV_06_medical_F","O_recon_TL_F", "O_spotter_F","O_recon_F","O_recon_LAT_F","O_Pathfinder_F","O_SoldierU_GL_F","O_soldierU_TL_F","O_SoldierU_SL_F","O_soldierU_medic_F", "O_Urban_Sharpshooter_F","O_V_Soldier_TL_hex_F","O_V_Soldier_hex_F","O_V_Soldier_JTAC_hex_F","O_V_Soldier_Exp_hex_F","O_V_Soldier_Medic_hex_F", "O_engineer_F","O_Soldier_SL_F","O_Soldier_SL_F","O_Sharpshooter_F","O_soldier_UAV_F","O_engineer_U_F","O_officer_F","O_Pilot_F","O_helipilot_F", "O_Soldier_A_F","O_Soldier_AAR_F","O_Soldier_AAA_F","O_Soldier_AAT_F","O_support_AMG_F","O_support_AMort_F","O_Soldier_AR_F","O_Soldier_AA_F", "O_Soldier_AT_F","O_soldier_exp_F","O_soldier_M_F","O_soldier_mine_F","O_Soldier_F","O_support_MG_F","O_support_Mort_F","O_Soldier_LAT_F", "O_support_GMG_F","O_Soldier_unarmed_F","O_Soldier_lite_F","O_HeavyGunner_F","O_recon_JTAC_F","O_recon_exp_F","O_recon_medic_F","O_recon_M_F", "O_sniper_F","O_ghillie_ard_F","O_ghillie_lsh_F","O_ghillie_sard_F","O_soldierU_repair_F","O_soldierU_A_F","O_soldierU_AAR_F","O_soldierU_AAA_F", "O_soldierU_AAT_F","O_soldierU_AR_F","O_soldierU_AA_F","O_soldierU_AT_F","O_soldierU_exp_F","O_soldierU_exp_F","O_soldierU_M_F","O_soldierU_F", "O_soldierU_LAT_F","O_Urban_HeavyGunner_F","O_V_Soldier_M_hex_F","O_V_Soldier_LAT_hex_F","O_V_Soldier_TL_ghex_F","O_V_Soldier_ghex_F", "O_V_Soldier_JTAC_ghex_F","O_V_Soldier_Exp_ghex_F","O_V_Soldier_Medic_ghex_F","O_V_Soldier_M_ghex_F","O_V_Soldier_LAT_ghex_F","O_G_Soldier_GL_F", "O_G_engineer_F","O_G_Soldier_TL_F","O_G_Soldier_SL_F","O_G_medic_F","O_G_Sharpshooter_F","O_G_officer_F","O_G_Soldier_A_F","O_G_Soldier_AR_F", "O_G_Soldier_exp_F","O_G_Soldier_M_F","O_G_Soldier_F","O_G_Soldier_LAT_F","O_G_Soldier_unarmed_F","O_G_Soldier_lite_F"]; }; }; _goodPos = []; _houseList = _startPos nearObjects ["House", _radius]; { if (_x in _blackList || typeOf _x in _bridges) then { } else { _c = 0; while { format ["%1", _x buildingPos _c] != "[0,0,0]" } do { _buildingPos = _x buildingPos _c; _nearMan = nearestObject [_buildingPos, "Man"]; _skip = false; if (_nearMan != objNull) then { if (_nearMan distance _buildingPos > 2) then { _goodPos set [(count _goodPos), [_x, _x buildingPos _c]]; }; }; _c = _c + 1; }; }; } forEach _houseList; KK_fnc_arrayShuffle = { private "_cnt"; _cnt = count _this; for "_i" from 1 to _cnt do { _this pushBack (_this deleteAt floor random _cnt); }; _this }; _goodPos = _goodPos call KK_fnc_arrayShuffle; if ((count _goodPos) < _bots) then { _bots = count _goodPos; } else { _goodPos resize _bots; }; _grp = createGroup _side; for "_i" from 1 to _bots do { if (count units _grp >= 5) then { _groups pushBack _grp; _grp = createGroup _side; }; _point = (_goodPos select (_i - 1)); _house = _point select 0; _pos = _point select 1; _dir = getDir _house; _samplePosASL = ATLtoASL[_pos select 0, _pos select 1, (_pos select 2) + 1.5]; _windowsCnt = 0; _windowsDir = []; _wallsDir = []; for "_d" from _dir to (_dir + 270) step 90 do { _dst = 5; _counterPosASL = [(_samplePosASL select 0) + sin _d * _dst, (_samplePosASL select 1) + cos _d * _dst,_samplePosASL select 2]; _counterPosHASL = [_counterPosASL select 0, _counterPosASL select 1, (_counterPosASL select 2) + 20]; _window = true; _liw = lineIntersectsWith [_counterPosHASL, _counterPosASL]; if (count _liw > 0 && {(_liw select 0) isKindOf "House"}) then { _window = false; }; if(_window) then { _liw = lineIntersectsWith [_samplePosASL, _counterPosASL]; if (count _liw > 0 && {(_liw select 0) isKindOf "House"}) then { _window = false; }; }; _watchDir = ([_samplePosASL,_counterPosASL] call BIS_fnc_dirTo); if (_window) then { _windowsCnt = _windowsCnt + 1; _windowsDir = _windowsDir + [_watchDir]; } else { _wallsDir = _wallsDir + [_watchDir]; }; }; _unit = selectRandom _units; _unit createUnit [_pos, _grp, "currentGuard = this;", 0, _rank]; currentGuard allowDamage false; currentGuard setVariable ["BIS_enableRandomization", false]; if (typeOf _house in _towers) then { currentGuard setPosATL _pos; } else { currentGuard setPos _pos; }; doStop currentGuard; currentGuard setBehaviour "SAFE"; currentGuard allowDamage true; if (_windowsCnt == 0) then { _watchDir = selectRandom _wallsDir; currentGuard setDir (_watchDir + 180); currentGuard setUnitPos "UP"; [currentGuard, _house, 30] spawn { _unit = _this select 0; _house = _this select 1; _time = _this select 2; _c = 0; _goodPos = []; while { format ["%1", _house buildingPos _c] != "[0,0,0]" } do {_c = _c + 1}; _c = _c - 1; if (_c < 3) then { doStop _unit; [_unit,(selectRandom ["WATCH","WATCH1","WATCH2"]),"FULL", {!isNull (_unit findNearestEnemy (getPos _unit)) || lifestate _unit == "INJURED"}, "COMBAT"] call BIS_fnc_ambientAnimCombat; } else { while {alive _unit} do { _destination = _house buildingPos (floor (random _c)); _unit doMove _destination; _unit moveTo _destination; sleep 0.5; _timeout = time + _time; waitUntil {moveToCompleted _unit || moveToFailed _unit || !alive _unit || _timeout < time}; sleep (random (_time)); }; }; }; } else { if (_windowsCnt == 1) then { currentGuard setUnitPos "UP"; [currentGuard, _windowsDir, 0] spawn { TB_fnc_relativePos = { private ["_p1", "_dir", "_dst", "_r", "_alt"]; _p1 = _this select 0; _dir = _this select 1; _dst = _this select 2; _alt = 0; if (count _this == 3) then { _alt = _this select 3; }; _r = [(_p1 select 0) + sin _dir * _dst, (_p1 select 1) + cos _dir * _dst, _alt]; _r }; _unit = _this select 0; _directions = _this select 1; _time = _this select 2; _watchDir = selectRandom _directions; _unit setDir _watchDir; if (_time == 0) then { _watchPos = [getPos _unit, _watchDir, ((round (random 50) + 30)), 1] call TB_fnc_relativePos; _unit doWatch _watchPos; } else { while {alive _unit && isNull (_unit findNearestEnemy (getPos _unit))} do { _watchDir = selectRandom _directions; _unit setDir _watchDir; _watchPos = [getPos _unit, _watchDir, ((round (random 30) + 30)), 1] call TB_fnc_relativePos; _unit doWatch _watchPos; sleep _time; }; }; }; } else { _unitPos = selectRandom ["UP","MIDDLE"]; currentGuard setUnitPos _unitPos; [currentGuard,(selectRandom ["WATCH1","WATCH2"]),"FULL", {!isNull (_unit findNearestEnemy (getPos _unit)) || lifestate currentGuard == "INJURED"}, "COMBAT"] call BIS_fnc_ambientAnimCombat; }; }; }; { _grp = _x; if (_zeusCurator) then { { _x addCuratorEditableObjects [(units _grp), true]; } forEach allCurators; }; _grp setBehaviour "SAFE"; _grp setCombatMode "RED"; { _x setSkill _skill; } forEach (units _grp); _grp deleteGroupWhenEmpty true; } forEach _groups; };
[[3497,13186], 50, 50, EAST, "CAPTAIN", 0.6, true] call TB_fnc_fillBots;
Благодарности/Неодобрения |
Получено: 14/1 Отправлено: 15/0 |
Благодарности/Неодобрения |
Получено: 64/0 Отправлено: 12/0 |
Ты все вместе запусти, одним вызовом - вверху скрипт, внизу строка вызова. Запускай кнопкой "На сервере". Я тестировал его перед публикацией.
Благодарности/Неодобрения |
Получено: 14/1 Отправлено: 15/0 |
Благодарности/Неодобрения |
Получено: 14/1 Отправлено: 15/0 |
А вот если if (!isServer) exitWith {}; убрать, то срабатывает!
Благодарности/Неодобрения |
Получено: 64/0 Отправлено: 12/0 |
Странно, я специально добавил эту строку чтобы при случайном нажатии кнопки "Выполнить глобально" ты не положил сервер.
Кстати, можно использовать этот скрипт для сценариев типа помощи союзникам попавшим в окружение. Для этого просто вызывай функцию два раза для разных сторон, например:
Код:[[3497,13186], 50, 30, EAST, "CAPTAIN", 0.6, true] call TB_fnc_fillBots; [[3497,13186], 30, 10, WEST, "MAJOR", 0.7, true] call TB_fnc_fillBots;
Благодарности/Неодобрения |
Получено: 0/0 Отправлено: 0/0 |
Полезная информация.