/* KiloSwiss */ private["_group","_endPos","_missionID","_mainVehicle","_convoyVehicles","_enterableVehicles","_convoyGrps","_ranks","_side","_vehiclePos","_vehFrontPos","_veh1","_veh2","_veh3","_start"]; _group = _this select 0; _endPos = _this select 1; _missionID = _this select 2; _mainVehicle = _this select 3; _convoyVehicles = _this select 4; _enterableVehicles = _this select 5; /* Marker position update */ _this spawn { private["_endPos","_missionID","_mainVehicle","_oldPos","_newPos"]; _endPos = _this select 1; _missionID = _this select 2; _mainVehicle = _this select 3; _oldPos = position _mainVehicle; while{alive _mainVehicle && _mainVehicle distance _endPos > 50}do{ UIsleep 10; _newPos = position _mainVehicle; if(_oldPos distance _newPos > 10)then{ _oldPos = _newPos; SEM_updateMissionMarkerPos = [_missionID, _newPos]; SEM_updateMissionMarkerPos call SEM_client_updateMissionMarkerPos; }; }; }; _units = (units _group); _side = side (_units select 0); _startPos = getPos _mainVehicle; _vehFront = (if(count _convoyVehicles == 1)then[{_mainVehicle},{{if(_x != _mainVehicle)exitWith{_x}; (_convoyVehicles select 0)}count _convoyVehicles}]); {_x setVariable ["AIskill",(skill _x)]}count _units; _ranks = ["COLONEL","MAJOR","CAPTAIN","LIEUTENANT","SERGEANT","CORPORAL","PRIVATE"]; { _x setFuel 1; _x setDamage 0; _group addVehicle _x; if(_x in _enterableVehicles)then[{_x lock 0},{_x lock 3}]; _x setVariable ["AIrank", (_ranks select (_forEachIndex min (count _ranks -1)))]; _x addEventHandler ["getIn",{ (_this select 2) setUnitRank ((_this select 0) getVariable ["AIrank","PRIVATE"]); if((_this select 1) == "driver")then{ (_this select 2) setSkill 1; }; }]; _x addEventHandler ["getOut",{ (_this select 2) setSkill ((_this select 2) getVariable ["AIskill",0.7]); }]; _x addeventHandler ["handleDamage",{ if(isNull (_this select 3))then{false}; }]; // Fill driver seats first (_units select _forEachIndex) assignAsDriver _x; //(_units select _forEachIndex) moveInDriver _x; //(_units select _forEachIndex) setSkill 1; //(_units select _forEachIndex) setUnitRank (_x getVariable ["AIrank","PRIVATE"]); if(_x emptyPositions "GUNNER" > 0)then{ // Assign a gunner _x allowCrewInImmobile true; //allow gunner to stay in immobilized vehicle (_units select (_forEachIndex + (count _convoyVehicles))) assignAsGunner _x; //(_units select (_forEachIndex + (count _convoyVehicles))) moveInGunner _x; //(_units select (_forEachIndex + (count _convoyVehicles))) setUnitRank (_x getVariable ["AIrank","PRIVATE"]); }; }forEach _convoyVehicles; //Order all Units to get in _units allowGetIn true; _units orderGetIn true; //Wait until every unit has boarded a vehicle _start = time; waitUntil{sleep 1;{(alive _x && vehicle _x == _x)}count _units == 0 || time - _start >= 30}; if({alive _x && vehicle _x == _x}count _units > 0)then{ { /* Move stuck AI into vehicles */ if(vehicle _x == _x)then{ _y = _x; { /* Fill driver/gunner seats first */ if(_x emptyPositions "DRIVER" > 0)exitWith{_y moveInDriver _x; _y setSkill 1}; if(_x emptyPositions "GUNNER" > 0)exitWith{_y moveInGunner _x}; }forEach _convoyVehicles; { /* Fill cargo seats */ if(_x emptyPositions "CARGO" > 0)exitWith{_y moveInCargo _x}; }forEach (_convoyVehicles - [_mainVehicle]); }; _x setUnitRank ((vehicle _x) getVariable ["AIrank","PRIVATE"]); }forEach _units; }; //-- Get lowest TopSpeed from all vehicles _topSpeeds = []; { _maxSpd = getNumber (configFile >> "cfgVehicles" >> typeOf _x >> "maxSpeed"); if(!isNil "_maxSpd")then{_topSpeeds pushBack _maxSpd}; }forEach _convoyVehicles; _select = 0; _maxSpd = _topSpeeds select _select; while{{_maxSpd > _x}count _topSpeeds != 0}do{ _select = _select + 1; _maxSpd = _topSpeeds select _select; }; {_x forceSpeed (_maxSpd*0.8)*0.2777778}forEach _convoyVehicles; // m/s //DEBUG if(SEM_debug in ["log","full"])then{diag_log format["SEM DEBUG: Convoy Vehicles TopSpeeds: %1 - Selected lowest: %2", _topSpeeds, _maxSpd]}; hint "start"; _group move _endPos; //{driver _x move _endPos}count _convoyVehicles; _group setSpeedMode "FULL";//"FULL"; _group setBehaviour "SAFE"; //"CARELESS"; _group setCombatMode "GREEN"; _group setFormation "COLUMN"; /* temporary definition of 3 vehicles */ _veh1 = _convoyVehicles select 0; _veh2 = _convoyVehicles select 1; _veh3 = _convoyVehicles select 2; _lastMoveCheck = time; _oldPos = getPos _mainVehicle; /* Convoy loop */ _stayToDefend = true; while{{_x distance _endPos < 20}count _convoyVehicles < 1}do{ //CONVOY LOOP _vehiclePos = getPos _mainVehicle; _vehFrontPos = getPos _vehFront; if({!canMove _x}count _convoyVehicles > 0 && _stayToDefend)then{ {if(canMove _x)then{(driver _x) doMove _vehiclePos}}forEach _convoyVehicles; sleep 5; { if(_x distance _vehiclePos < 50)then[{ if(_x != gunner (vehicle _x))then{ _x action ["GetOut", (vehicle _x)]; sleep 0.5; [_x] orderGetIn false; [_x] allowGetIn false; _x doMove _vehiclePos; }; },{ _x doMove _vehiclePos; }]; }forEach units _group; _group move _vehiclePos; _group setSpeedMode "FULL"; if({_x distance _veh2 < 50}count units _group == count units _group)then{ _endPos = _vehiclePos; }; }else{ //-- Work In Progress! if({alive _x && !(vehicle _x in _convoyVehicles)}count units _group > 0)then{ //AI has left the vehicle hint "AI has left the vehicle"; _group setBehaviour "CARELESS"; _group setCombatMode "GREEN"; { if(!(vehicle _x in _convoyVehicles))then{ [_x] allowGetIn true; [_x] orderGetIn true; }; }forEach units _group; sleep 10; //Brake the loop for 10 seconds _group move _endPos; //_group setSpeedMode "NORMAL"; }else{ //Do vehicle speed management and continue travel to destination //_group move _endPos; //{driver _x move _endPos}count _convoyVehicles; _group setBehaviour "SAFE"; _group setCombatMode "GREEN"; //_group setFormation "COLUMN";//"FILE"; _group setSpeedMode "FULL"; if(time - _lastMoveCheck > 60)then{ _group move _endPos; _lastMoveCheck = time; if(_vehiclePos distance _oldPos < 30)then[{ hint "Convoy is stuck"; //FAILSAFE IF CONVOY IS STUCK {driver _x doMove _endPos}count _convoyVehicles; //_group setSpeedMode "FULL"; sleep 10; //Brake the loop for 20 seconds //_group move _endPos; //_group setSpeedMode "NORMAL"; },{_group move _endPos}]; _oldPos = getPos _mainVehicle; _group move _endPos; }; //-- Distance Checks // forceSpeed = m/s // limitSpeed = km/h // 1 km/h == ~0.2777778 m/s /* //Check Formation _distanceA = _veh1 distance _veh2; _distanceB = _veh1 distance _veh3; if(_distanceA > _distanceB)then{ _3inFrontOf2 = [_veh2, _veh3, 0] call BIS_fnc_isInFrontOf; if(_3inFrontOf2 || abs(_distanceA - _distanceB) > 10)then{//Swap Vehicles position in convoy (2 <-> 3) //diag_log format["A: Distance 1-2: %1 - Distance 1-3: %2", round (_veh1 distance _veh2), round (_veh1 distance _veh3)]; _vehinMiddle = _veh3; _veh3 = _veh2; _veh2 = _vehinMiddle; //diag_log format["B: Distance 1-2: %1 - Distance 1-3: %2", round (_veh1 distance _veh2), round (_veh1 distance _veh3)]; }; }; */ //Speed Management for Vehicle 1 if(_veh1 distance _veh2 > 80 || _veh1 distance _veh3 > 120)then{ if(_veh1 distance _veh2 > 100 || _veh1 distance _veh3 > 150)then{ //_veh1 forceSpeed (_maxSpd*0.1)*0.2777778; _veh1 limitSpeed 0; }else{ if(speed _veh3 < 10)then{ //_veh1 forceSpeed (1 max (speed _veh3)*0.2777778); _veh1 limitSpeed (1 max (speed _veh3)); }else{ //_veh1 forceSpeed (_maxSpd*0.4)*0.2777778; _veh1 limitSpeed (_maxSpd*0.5); }; }; }else{ if(speed _veh3 < 10)then{ //_veh1 forceSpeed (_maxSpd*0.1)*0.2777778; _veh1 limitSpeed (_maxSpd*0.1); }else{ //_veh1 forceSpeed (_maxSpd*0.8)*0.2777778; //-- m/s _veh1 limitSpeed (_maxSpd*0.8); }; }; //Speed Management for Vehicle 2 if(_veh2 distance _veh1 > 80)then{ if(_veh2 distance _veh3 < _veh2 distance _veh1)then{ //_veh2 forceSpeed (_maxSpd*0.8)*0.2777778; _veh2 limitSpeed (_maxSpd*0.8); }else{ //Move faster to catch up with Vehicle1 //_veh2 forceSpeed _maxSpd*0.2777778; _veh2 limitSpeed _maxSpd; }; }else{ if(_veh2 distance _veh1 < 40)then{ //_veh2 forceSpeed (1 max (speed _veh1)*0.2777778); _veh2 limitSpeed (1 max (speed _veh1)); }else{ if(_veh2 distance _veh3 > _veh2 distance _veh1)then{ //let Vehicle3 catch up //_veh2 forceSpeed (_maxSpd*0.5)*0.2777778; _veh2 limitSpeed (_maxSpd*0.5); }else{ //_veh2 forceSpeed (_maxSpd*0.8)*0.2777778; _veh2 limitSpeed (_maxSpd*0.8); }; }; }; //Speed Management for Vehicle 3 if(_veh3 distance _veh2 > 80 || _veh3 distance _veh1 > 120)then{ //catch up //_veh3 forceSpeed _maxSpd*0.2777778; _veh3 limitSpeed _maxSpd; }else{ if(_veh3 distance _veh2 < 40)then{ //_veh3 forceSpeed (1 max (speed _veh2)*0.2777778); _veh3 limitSpeed (1 max (speed _veh2)); }else{ //if(speed _veh1 < 10)then{ //FAILSAFE IF CONVOY IS STUCK // (driver _veh3) doMove (getPos _veh1); //_veh3 forceSpeed (_maxSpd*0.8)*0.2777778; // _veh3 limitSpeed (_maxSpd*0.8); //}else{ //_veh3 forceSpeed (_maxSpd*0.8)*0.2777778; _veh3 limitSpeed (_maxSpd*0.8); //}; }; }; }; }; //code to end the while _unitsAlive = ({alive _x}count units _group); if(_unitsAlive < 1) then { _endPos = _vehiclePos; }; if (damage _mainVehicle == 1) then { _endPos = _vehiclePos; }; if({isPlayer _x && alive _x}count crew _mainVehicle > 0)then{ doStop (units _group); { _x spawn{ _this action ["engineOff", (vehicle _this)]; sleep 0.5; deleteVehicle _this; }; }foreach units _group; _endPos = _vehiclePos; }; UIsleep 1; }; //END OF LOOP hint "Dynamic Mission Status: Convoy Ended"; if({alive _x}count units _group > 0 && damage _mainVehicle < 1)then{ _group move _vehiclePos; sleep 10; { if(_x != gunner (vehicle _x))then{ [_x,_vehiclePos] spawn{ private "_unit"; _unit = _this select 0; doStop _unit; sleep 1; _unit action ["engineOff", (vehicle _unit)]; _unit action ["GetOut", (vehicle _unit)]; unassignVehicle _unit; sleep 0.1; [_unit] orderGetIn false; [_unit] allowGetIn false; }; }; }forEach (units _group); _group move _vehiclePos; _group setBehaviour "AWARE"; _group setFormation "FILE"; _group setCombatMode "YELLOW"; [_group, _vehiclePos] call SEM_fnc_AImove; };