Jump to content
LSValmont

vAiDriving Multiplayer Script [v13 - updated 05/26/2020]

Recommended Posts

vAiDriving Multiplayer Script by Valmont RELEASED!

 

Improved Ai Driving and Civilian Pedestrian Simulation will now also increase your FPS rather than decrease it!

(Three for the price of one, order NOW!) (promotion ends when Arma 4 releases or we run out of stock!)

EDIT: -SOLD OUT-

 

Inspired by (And adapted from) the work of the Ai Driving master @RCA3  !

 

REQUIRES CBA_A3 !

 

vAiDrive Main Features:


1) Greatly reduces the chances of Ai Driven Vehicles colliding with objects, vehicles and other units.
2) Greatly improved the chances of Ai Driven Vehicles evading other vehicles and units.
3) Since version 13 the script is able to handle the waypoints and movement of both vehicles and pedestrians and therefore it no longer needs manual waypoints setup by the mission maker.

All that is required now is the placement of civilian vehicles and units on the scenario and the script does the rest.
4) By giving vehicles the optimal amount of waypoints, waypoint distance, timeout and position while also giving pedestrians custom routines that mimic real urban movement patterns the immersion of any mission using civilians is greatly increased.
5) Has the option to cache far away units and vehicles being handled by the script.
6) Due to its many optimizations, instead of having a toll on server performance this script actually INCREASES the performance (FPS) on the server!

 

Extra Features:


1) Ai units in the way of vehicles will move away from the streets and into buildings.
2) Option for Handled vehicles to open closed bargates automatically.
3) Option to add random uniforms and gear to civilian pedestrians automatically.
4) Ai vehicle Drivers will occasionally use their horns when a obstacle is in front.
5) Ai Drivers are optimized for driving! And if their vehicle run out of fuel then they exit the vehicle and the script stops (liberating resources).
6) The script uses a combination of scheduled and unscheduled Environments to achieve that virtual CERO impact on performance.

OBS: Since version 13 it is nearly impossible to have fatalities of any kind due to bad Ai Driving with vAiDriving enabled (for the CIVILIAN SIDE).

 


CHANGELOG:

Spoiler

version 13 "Automatic Vehicle Waypoints!" Release Highlights:

 

- vAiDrive now has the option handle the waypoints of vehicles automatically so that players and mission makers do not have to set up each vehicle and each waypoint individually nor have other vehicle movement scripts running enabled.(vAiDriving_handleVehWaypoints=true).
- vAiDrive now has the option to automatically cache vehicles and units to preserve resources when players are far away.  (vAiDriving_handleVehCache=true)
- It is now possible to set the vehicles handled by vAiDrive to never run out of fuel. (vAiDriving_vehUnlimitedFuel=true)
- vAiDrive can now also randomize the look of pedestrians automatically. (vAiDriving_dressPedestrians=true)
- All vAiDrive settings are now set by editing  the "vAiDrivingCONFIG.sqf" instead of the main fnc file.
- Fixed Ai civilians not looking at nearby pedestrians when "talking" to them.
- Fixed Bargates sometimes not being handled correctly.

 

version 12 "Handle Civilians" Release Highlights:

- Added the game changer vAiDriving_handlePedestrians param. If set to true the script will automatically optimize all civilians on the mission, turning them into
performance friendly agents that roam the map smartly,  going into buildings, "talking" to other civies and avoiding walking on the middle of roads for long periods.
- vAiDriving_handlePedestrians increases the server FPS even further than before! WAY WAY MORE!

- Further optimization and tweaking not worth detailing.
- After version 12 update the number of civilian casualties due to bad Ai Driving is virtually CERO.
DISCLOSURE: No pedestrians were harmed during the development of this script version. (FINALLY!)

 

 

How it works:

Spoiler

 

It is a very simple script but sometimes simple is enough for most specially if performance is key on the server.

The script runs on each Ai driver and periodically checking nearObjects (for units and vehicles) and lineIntersectsWith (for objects and structures).

If an "OBSTACLE" is detected then the Ai Driver hits the "brakes" rather harshly but it should in most cases diminish deadly collisions.

What makes this script so efficient is that it only runs if the FPS is above 15 and the speed of the vehicle is greater than 1.

Since the vehicles speeds are many times below 1 due to constant breaking that gives the server room to finish its schedule.

 

 

Limitations:

Spoiler

 

- Due to having performance as a focus the script is rather rough when dealing with immersion. (Vehicles hit the brakes and move a little harshly)

- The vehicles move rather slow but that is a sacrifice I had to make in order to keep those checks from saturating the server and also to avoid having to make the vehicles come to a full stop on every obstacle.

- Was tested on a Hosted server with up to 40 vehicles and 80 civilians without performance degradation but more could have a toll on your system.

 

 

Usage:

Spoiler

 

- Put the vAiDriving.sqf file in your mission directory like so: "missionDirectory\vScripts\vAiDriving\vAiDriving.sqf".

- On your initServer.sqf add the following lines:


call compile preprocessFileLineNumbers "vScripts\vAiDriving\vAiDriving.sqf";
waitUntil {sleep 1; time > 1};
[] call vAiDriving_init;

In your mission add the vehicles with Ai Drivers using EDEN and hopefully give them move waypoints on roads. (This Script does not deal with vehicle movement so you will need waypoints or another script for that!)

 

 

Script Optional Configs:

Spoiler

 

Open "vAiDriving.sqf" with a text editor and change these lines to your liking:


vAiDriving_useLinesIntersectWith = true; // Helps vehicles reduce speed when facing obstacles other than other vehicles and men.
vAiDriving_show3DLine = true; // Set to true to draw a visual line for the LINES INTERSECT.
vAiDriving_handleBargates = true; // Should the vehicles open BarGates automatically?
vAiDriving_debug = true; // If you want to see why a car hit the breakes etc.
vAiDriving_handlePedestrians = true; // Set to true to optimize Ai Civilian units and give them waypoints to look "realistic". // New since v12

 

 

The script (Updated to version 12):

Spoiler

// on initServer.sqf add: [] call vAiDriving_init;

vAiDriving_init = {
	if !(isServer) exitWith {}; // Run on Server Only
	
	if !(isNil "vAiDrinvingScriptRunning") exitWith {}; //Script already running
	if (isNil "vAiDrinvingScriptRunning") then {vAiDrinvingScriptRunning = 1;}; // Prevent the loop from running several times.
	
	vAiDriving_useLinesIntersectWith = true; // Helps vehicles reduce speed when facing obstacles other than other vehicles and men.
	vAiDriving_show3DLine = true; // Set to true to draw a visual line for the LINES INTERSECT.
	vAiDriving_handleBargates = true; // Should the vehicles open BarGates automatically?
	vAiDriving_debug = true; // If true will show when Ai Drivers hit the brakes and/or their nearObjects.
	vAiDriving_handlePedestrians = true; // Set to true to optimize Ai Civilian units and give them waypoints to look "realistic".
	
	[{
		[] call vAiDriving_postInit;
	},[],5] call CBA_fnc_waitAndExecute; // Delay execution until all objects and vehicles are placed.
};

vAiDriving_postInit = {
	if !(isServer) exitWith {}; // Run on Server Only
	
	if (vAiDriving_handleBargates) then {
		[] spawn vAiDriving_handleBargatesFnc;
	};
	
	if (vAiDriving_handlePedestrians) then {
		[] spawn vAiDriving_handlePedestrianFnc;
	};
	
	private _aiDrivenVeh = [];
	_aiDrivenVeh = vehicles select {(alive driver _x && !(isPlayer driver _x) && (local driver _x) && (_x isKindOf "Car" || _x isKindOf "Motorcycle" || _x isKindOf "Tank"))}; //Select all vehicles being driven by Ai.
	if (_aiDrivenVeh isEqualTo []) exitWith {[vAiDriving_postInit,[],300] call CBA_fnc_waitAndExecute;}; //If no candidate found recheck 300 seconds later!
	
	{
		if (isNil {_x getVariable "vAiDrivingSet"}) then {
			_x setVariable ["vAiDrivingSet",0];
			_x setConvoySeparation 20;
			//_x forceFollowRoad true;
			_x setSpeedMode "LIMITED";
			//Add Event Handler
			_x addEventHandler ["GetIn", {_this spawn vAiDriving_loop;}];
			_x addEventHandler ["HandleDamage", {params ["","","","","_p","","",""]; if (_p isEqualTo "") exitWith {false};}];
			if (isNil {driver _x getVariable "vAiDrivingSet"}) then {
				driver _x setVariable ["vAiDrivingSet",0];
				driver _x addEventHandler ["GetOutMan", {_this spawn vAiDriving_restoreDriver;}];
				[driver _x] spawn vAiDriving_setDriver;
				//Start function if driver inside
				if !(isNull (driver _x)) then{null=[_x,"driver",(driver _x)] spawn vAiDriving_loop;};					
			};
		};
	} forEach _aiDrivenVeh;
	
	[vAiDriving_postInit,[],300] call CBA_fnc_waitAndExecute; // Check again Later if new veh or barGates were placed!
};

vAiDriving_loop = {

	if !(isServer) exitWith {}; // Run on Server Only
	
	if (diag_fps < 15) exitWith {[{[] spawn vAiDriving_loop;},[],60] call CBA_fnc_waitAndExecute;}; // Server FPS too low, save resources and restart the loop until FPS gets better

	params ["_car", "_role", "_driver"];
	
	if (!(_car isKindOf "Car" || _car isKindOf "Motorcycle" || _car isKindOf "Tank") || {!(_role isEqualTo "driver")} || {isPlayer _driver} || {!(local _driver)}) exitWith{};

	while {alive _driver && !(isNull (objectParent _driver))} do {
		// If FPS too low let the Drivers be stupid again to save performance.
		if (diag_fps > 15) then {
			private _fuel = fuel _car;
			if (_fuel isEqualTo 0) exitWith {private _crew = crew _car; {unassignVehicle _x} forEach _crew; _crew allowGetIn false;}; //Basically exit the while loop if out of fuel!
			_speed = speed _car;
			// Static Vehicles do not need brakes applied!
			if (_speed > 1) then {		
				_objectsIntersected = [];
				// Extra measure to reduce speed if a object is in the way, quite performance friendly!
				if (vAiDriving_useLinesIntersectWith) then {			
					private _carFrontPos = ATLToASL (_car modelToWorld [0, 2, -0.2]);
					private _distanceToCheck = 10;
					_distanceToCheck = ((_speed)*1.1);
					if (_distanceToCheck < 10) then {_distanceToCheck = 10;};
					private _carFrontDistanceToCheck = ATLToASL (_car modelToWorld [0, _distanceToCheck, 0.5]); //position far in front of vehicle
					_objectsIntersected = lineIntersectsWith [_carFrontPos, _carFrontDistanceToCheck, _car, _driver, true];
					if (vAiDriving_show3DLine) then {drawLine3D [ASLToATL _carFrontPos, ASLToATL _carFrontDistanceToCheck, [1,0,0,1]];};
				};
				// If vehicle already slowing down because of linesIntersect no point in searching for other Entities (Reduces resources usage!)
				if !(_objectsIntersected isEqualTo []) then {	
					_car setSpeedMode "LIMITED";
					_car forceSpeed 1;
					_car limitSpeed 5;
					_car enableSimulationGlobal false;
					_car setVelocityModelSpace [0, 0, 0];
					if (vAiDriving_debug) then { systemChat format ["Car hit the BRAKE due to: LINESINTERSECT",""]; };
					sleep 1; // Do not overwhelm the server.			
				} else {
					_nearestObjects = [];
					private _radius = 6;
					_radius = _speed * 0.3;
					if (_radius < 6) then {_radius = 6;};
					if (_radius > 20) then {_radius = 20;};
					if (vAiDriving_handleBargates) then {
						_nearestObjects = ((nearestObjects[_car getRelPos [5,0],["CAManBase","Car","Wall_F"],_radius]) select {alive _x && !(_car isEqualTo _x)});
					} else {
						_nearestObjects = ((nearestObjects[_car getRelPos [5,0],["CAManBase","Car"],_radius]) select {alive _x && !(_car isEqualTo _x)});
					};
					sleep 0.5;
					if !(_nearestObjects isEqualTo []) then {
					if (vAiDriving_debug) then { systemChat format ["NEARESTOBJ COUNT: %1",count _nearestObjects]; };
						_car setSpeedMode "LIMITED";
						_car forceSpeed 1;
						_car limitSpeed 5;
						_car enableSimulationGlobal false;
						_car setVelocityModelSpace [0, 0, 0];
						if (vAiDriving_debug) then { systemChat format ["Car hit the BRAKE due to: NEAROBJECT",""]; };
						if (random 5 > 4) then {driver _car forceWeaponFire [currentWeapon _car ,currentWeapon _car ];}; // Blow the horn for those pesky pedestrians!
						{
							switch (true) do {
								case (_x isKindOf "CAManBase" && {isNull (objectParent _x)}): {				// Pedestrian, try to save him!
									//if ((side _x isEqualTo "CIVILIAN" && (currentWeapon _x isEqualTo ""))) then {_x allowDamage false;};
									[_x, _car] spawn vAiPedestrian_runToNearestBuilding;
									if (vAiDriving_debug) then { systemChat format ["NEAROBJECTS: MEN",""]; };
								};
								case (_x isKindOf "Car" && !(isPlayer driver _x)): {											// Helps cars avoid other cars.
									if (speed _car < 5 && speed _x < 5) then {
										//_car setDir ((getposatl _car) getDir ((_x modelToWorld [-3, 0, 0])));			// This causes more troubles than it solves! Need a better way to unstuck vehicles.
										if (vAiDriving_debug) then { systemChat format ["NEAROBJECTS: CAR",""]; };
									};
								};
								case (vAiDriving_handleBargates && _x in vAiDriving_barGates): {_x animateSource ["Door_1_source", 1];};	// If it is a BarGate, open it!
							};
						sleep 0.3;
						} forEach _nearestObjects;
					} else {
						_car enableSimulationGlobal true;
						_car forceSpeed -1;
						_car limitSpeed 30;						// Now restore speed
						_car setSpeedMode "NORMAL";
						if (((getPos _car) getEnvSoundController "houses") >= 0.7) then {
							_car limitSpeed 20;					// In cities reduce speed limit a little bit.
						};		
					};
				};
			};	
		};
	sleep 1; // Do not overwhelm the server.	
	};
};

vAiDriving_handleBargatesFnc = {
	if (diag_fps < 15) exitWith {};
	private _bargatetypes = ["Land_BarGate_01_open_F", "Land_BarGate_F", "Land_RoadBarrier_01_F"];
	vAiDriving_barGates = (allMissionObjects "Wall_F") select {private _object = _x; !(_bargatetypes findIf {_object isKindOf _x} isEqualTo -1)};
	//Add Event Handler
	{
		_driver addEventHandler ["HandleDamage", {params ["","","","","_projectile","","",""]; if (_projectile isEqualTo "") then {_d=0; _d};}];
	sleep 1;	
	} forEach vAiDriving_barGates;
};

vAiDriving_setDriver = {
	params ["_driver"];
	if !(local _driver) exitWith {};
	if (isPlayer _driver) exitWith {};
	if !(isNil {_driver getVariable "vDriverSet"}) exitWith {};
	_driver setVariable ["vDriverSet", 0];
	_driver disableAi "ALL";
	{_driver enableAI _x} forEach ["MOVE","PATH","TEAMSWITCH"];
	[_driver] spawn {params ["_driver"]; sleep 5; _driver doMove (getPos _driver);};
	_driver setCombatMode "BLUE";
	_driver setBehaviour "CARELESS";
	_driver allowFleeing 0;
	_driver setSkill 0.0;
	(group _driver) enableDynamicSimulation true;
	(group _driver) deleteGroupWhenEmpty true;
	_driver setVariable ["BIS_noCoreConversations", true];
	_driver disableConversation true;
	_driver setSpeaker "NoVoice";
	_driver removeAllEventHandlers "HandleDamage";
	_driver addEventHandler ["HandleDamage", {params ["","","","","_projectile","","",""]; if (_projectile isEqualTo "") then {_d=0; _d};}];
};

vAiDriving_restoreDriver = {
	params ["_unit", "_role", "_vehicle", ""];
	if !(local _unit) exitWith {};
	if (isPlayer _unit) exitWith {};
	if (isNil {_unit getVariable "vDriverSet"}) exitWith {};
	_unit setVariable ["vDriverSet", nil];
	{_unit enableAI _x} forEach ["MOVE","PATH","ANIM","TEAMSWITCH"];
	_unit setCombatMode "YELLOW";
	_unit setBehaviour "SAFE";
	_unit allowFleeing 0;
	if (side group _unit isEqualTo CIVILIAN) then {
		[group _unit, getPos _unit, 100] call BIS_fnc_taskPatrol;
	} else {
		{_unit enableAi _x} forEach ["WEAPONAIM","FSM","AIMINGERROR","SUPPRESSION","AUTOCOMBAT","CHECKVISIBLE","TARGET","AUTOTARGET"];
	};
};

vAiDriving_handlePedestrianFnc = {
	private _aiPedestrians = [];
	_aiPedestrians = allUnits select {(alive _x && (_x isKindOf "CAManBase") && !(isAgent teamMember _x) && !(isPlayer _x) && (local _x) && (isNull (objectParent _x)) && !(_x in playableUnits) && (currentWeapon _x isEqualTo "") && (side group _x isEqualTo CIVILIAN))}; //Select all Ai Civs.
	if !(_aiPedestrians isEqualTo []) then {
		{
			if (isNil {_x getVariable "vAiPedestrianSet"}) then {
				_x setVariable ["vAiPedestrianSet",0];
				[_x] call vAiDriving_setPedestrian;
			};
		sleep (1 + (random 1));	
		} forEach _aiPedestrians;
	};
};

vAiDriving_setPedestrian = {
	params ["_aiPedestrian"];
	if !(local _aiPedestrian) exitWith {};
	if (isPlayer _aiPedestrian) exitWith {};
	if (_aiPedestrian in playableUnits) exitWith {};
	if !(side group _aiPedestrian isEqualTo CIVILIAN) exitWith {};
	
	[group _aiPedestrian, getPos _aiPedestrian, 100] call BIS_fnc_taskPatrol; // Set the Pedestrian WayPoints
	private _unitType = typeOf _aiPedestrian;
	private _aiPedestrianPos = getPos _aiPedestrian;
	private _aiPedestrianDir = getDir _aiPedestrian;
	
	// just in case
	private _attachMents = attachedObjects _aiPedestrian;
	if (count _attachMents > 0) then {
		{detach _x;} forEach _attachMents;
		{deleteVehicle _x;} forEach _attachMents;
	};
	
	private _agentPedestrian = objNull;
	_agentPedestrian = createAgent [_unitType, [0,0,0], [], 0, "CAN_COLLIDE"];
	_agentPedestrian disableAi "ALL";
	{_agentPedestrian enableAI _x} forEach ["MOVE","PATH","ANIM","TEAMSWITCH"];
	[_agentPedestrian] spawn {params ["_unit"]; sleep 3; _unit moveTo (getPos _unit);};
	removeAllWeapons _agentPedestrian;
	removeAllItems _agentPedestrian;
	removeAllAssignedItems _agentPedestrian;
	removeVest _agentPedestrian;
	removeBackpack _agentPedestrian;
	removeHeadgear _agentPedestrian;
	removeGoggles _agentPedestrian;
	_agentPedestrian disablecollisionwith _aiPedestrian;
	_aiPedestrian disablecollisionwith _agentPedestrian;
	[_agentPedestrian] joinSilent _aiPedestrian; // to get its waypoints!
	_agentPedestrian switchMove "";
	_agentPedestrian enableStamina false;
	_agentPedestrian setanimspeedcoef 0.7;
	_agentPedestrian setCombatMode "BLUE";
	_agentPedestrian setBehaviour "CARELESS";
	_agentPedestrian setSpeedMode "LIMITED";
	_agentPedestrian forcespeed -1;
	_agentPedestrian allowFleeing 0;
	_agentPedestrian setSkill 0.0;
	(group _agentPedestrian) enableDynamicSimulation true;
	(group _agentPedestrian) deleteGroupWhenEmpty true;
	_agentPedestrian setVariable ["BIS_noCoreConversations", true];
	_agentPedestrian disableConversation true;
	_agentPedestrian setSpeaker "NoVoice";
	_agentPedestrian removeAllEventHandlers "HandleDamage";
	_agentPedestrian addEventHandler ["HandleDamage", {params ["","","","","_projectile","","",""]; if (_projectile isEqualTo "") then {_d=0; _d};}];
	deleteVehicle _aiPedestrian;
	_agentPedestrian setpos _aiPedestrianPos;
	_agentPedestrian setdir _aiPedestrianDir;
	_agentPedestrian setVariable ["vAiPedestrianSet",0];
	[_agentPedestrian,50,8,8] spawn vPedestrianPatrol;
};

vPedestrianPatrol = {
	params ["_agent","_radius","_waypoints","_timeOut"];
	if !(isAgent teamMember _agent) exitWith {};
	private _agentMoveCount = _waypoints;
	private _origAgentPos = getPos _agent;
	while {alive _agent} do {
		if (simulationEnabled _agent && diag_fps > 15 && speed _agent < 2) then {
			if (random 10>1) then {
				private _nOa = [];
				_nOa = nearestObjects [_agent, ["house"], _radius];
				if !(_nOa isEqualTo []) then {
					private _rdmO = selectRandom _nOa; 
					private _aDest = getPos _rdmO;
					if !(surfaceIsWater _aDest) then {
						_agent setDestination [_aDest, "LEADER PLANNED", true]; if (random 3 > 1) then {_agent forceWalk false;} else {_agent forceWalk true;};
						private _forcedTimeOut = time + 60;
						waitUntil {sleep (2 + (random 4)); (_agent distance2d _aDest < 10 OR time > _forcedTimeOut)};
						if (isOnRoad (ASLToAGL getPosASL _agent)) then {sleep 0.1;} else {sleep _timeOut;};
					};
				};
			} else {
				_goTalkTo = objNull;
				_goTalkTo = nearestObject [_agent, "CAManBase"];
				if (!(isNull _goTalkTo) && (_goTalkTo distance2d _agent < _radius) && (side _goTalkTo isEqualTo side _agent)) then {
					if (vAiDriving_debug) then { systemChat format ["GOTALKTO: %1",name _goTalkTo]; };
					private _goTalkToPos = getPos _goTalkTo;
					_agent setDestination [_goTalkToPos, "LEADER PLANNED", true]; if (random 3 > 1) then {_agent forceWalk false;} else {_agent forceWalk true;};
					private _forcedTimeOutB = time + 60;
					waitUntil {sleep (2 + (random 4)); (_agent distance2d _goTalkToPos < 10 OR time > _forcedTimeOutB)};
					waitUntil {sleep (2 + (random 2)); (speed _agent < 2 OR time > _forcedTimeOutB)};
					if (_agent distance2d _goTalkTo < 5) then {_agent setDir (getDir _goTalkTo); _goTalkTo setDir (getDir _agent);};
					if (isOnRoad (ASLToAGL getPosASL _agent)) then {sleep 0.1;} else {sleep _timeOut;};
				};
			};
			_agentMoveCount = _agentMoveCount - 1;
			if (vAiDriving_debug) then { systemChat format ["AGENT MOVE COUNT: %1",_agentMoveCount]; };
			if (_agentMoveCount < 1) then {_agent setDestination [_origAgentPos, "LEADER PLANNED", true]; _agentMoveCount = _waypoints; sleep (10 + (random 10));};
			sleep (2 + (random 2));
		} else {sleep (5 + (random 5));};
	 sleep (1 + (random 1));
	};
};

vAiPedestrian_runToNearestBuilding = {
	params ["_aiPedestrian", "_car"];
	if !(isNil {_aiPedestrian getVariable "vIsAvoidingVeh"}) exitWith {};
	if (lifeState _aiPedestrian isEqualTo "INCAPACITATED" OR !(canStand _aiPedestrian)) exitWith {};
	private _onFoot = isNull (objectParent _aiPedestrian); // check for vehicle
	if (!_onFoot) exitWith {}; 	// no further action if unit in vehicle
	if (isPlayer _aiPedestrian) exitWith {};
	
	_aiPedestrian setVariable ["vIsAvoidingVeh", 0];
	if (vAiDriving_debug) then { systemChat format ["PEDESTRIAN RUNNING!",""]; };
	
	private _fleeDir = 180 + (_aiPedestrian getDir _car); //direction opposite to car
	private _fleePos = _aiPedestrian getrelPos [30,_fleeDir]; //finds location at 30 mtrs in established direction.
	
	// nearBuildings
	_NearestBuilding = [];
	_NearestBuilding = _fleePos call CBA_fnc_getNearestBuilding;
	sleep 1;
	if (_NearestBuilding isEqualTo []) exitWith {};
	private _Building = _NearestBuilding select 0;
	if (_aiPedestrian distance2D _Building > 30) exitWith {};
	private _BuildingPositions = [];
	_BuildingPositionsCount = _NearestBuilding select 1;
	
	// pick a random building spot and move!
	_BuildingPosition = getPos _aiPedestrian;
	if (_BuildingPositionsCount > 1) then {_BuildingPosition = (selectRandom (_Building buildingPos -1));} else {_BuildingPosition = getPos _Building;};
	private _previousGroup = group _aiPedestrian;
	
	// Just in case...
	if (count attachedObjects _aiPedestrian > 0) then {
		{detach _x;} forEach attachedObjects _aiPedestrian;
	};	
	// Prepare the Civie so he is able to run!
	_previousGroup deleteGroupWhenEmpty false;
	[_aiPedestrian] join grpNull;
	{_aiPedestrian enableAI _x} forEach ["MOVE","PATH","ANIM","AUTOTARGET","TARGET"];
	_aiPedestrian forceWalk false;
	_aiPedestrian switchMove "";
	_aiPedestrian setUnitPos "UP";
	_aiPedestrian setBehaviour "CARELESS";
	_aiPedestrian forceSpeed -1;
	_aiPedestrian forcespeed 30;
	_aiPedestrian setSpeedMode "FULL";
	if (isAgent teamMember _aiPedestrian) then {
		_aiPedestrian moveTo _BuildingPosition; // agents only move with moveTo.
	} else {
		_aiPedestrian doMove _BuildingPosition;
	};
	[_aiPedestrian, _previousGroup] spawn {
		params ["_aiPedestrian", "_previousGroup"];
		sleep 20;
		_aiPedestrian switchMove "";
		_aiPedestrian allowDamage true;
		_aiPedestrian setVariable ["vIsAvoidingVeh", nil];
		_aiPedestrian setBehaviour "AWARE";
		[_aiPedestrian] join _previousGroup;
		_previousGroup deleteGroupWhenEmpty true;
		_aiPedestrian setUnitPos "AUTO";
		_aiPedestrian forceSpeed -1;
		[group _aiPedestrian, getPos _aiPedestrian, 100] call BIS_fnc_taskPatrol;
	};
};

 

 

PS: This script aims towards making the Ai Driven vehicles brake better. If you actually want to make the Ai drive better then you should use @RCA3's amazing AI Driving Control. (Link in spoiler Below)

 

Spoiler

 

 

Enjoy and I am looking forward for suggestions and testing input!

 

Special thanks to @RCA3 again for his work and sharing his amazing scripts and mods with us!

 

vAiDriving version 13 Demo Mission (Malden) DOWNLOAD LINK: https://drive.google.com/open?id=133RUlQmcrzXFxV9RLC27sdIQYOLkFyR5

 

PS2: I haven't tested this script as a CONVOY but I believe it should also help with convoy missions probably. (Please report your results)

  • Like 12
  • Thanks 2

Share this post


Link to post
Share on other sites

version 12 "Handle Civilians" of the vAiDriving script RELEASED:

 

Release Highlights:

 

- Added the game changer vAiDriving_handlePedestrians param. If set to true the script will automatically optimize all civilians on the mission, turning them into
performance friendly agents that roam the map smartly,  going into buildings, "talking" to other civies and avoiding walking on the middle of roads for long periods.


- vAiDriving_handlePedestrians increases the server FPS even further than before! WAY WAY MORE!

 

- Further optimization and tweaking not worth detailing.


- After this update the number of civilian casualties due to bad Ai Driving is: CERO.


DISCLOSURE: No pedestrians were harmed during the development of this script version. (FINALLY!)

 

PS: Since Ai Drivers are no longer the top predators of Arma 3, players can now be the main danger on the streets again...

 

version 12 DEMO mission DOWNLOAD LINK: https://drive.google.com/open?id=1caZLcakfdH9UyHf7PuAL5-FgKz0MKiZg

ENJOY your newly found Military Simulator first, Destruction Derby simulator second! 😉 

  • Like 2

Share this post


Link to post
Share on other sites

Nice work, I always joke about how drivers intentionally drive off the road specifically to kill pedestrians lol. Good job finding a fix.

  • Thanks 1

Share this post


Link to post
Share on other sites
2 hours ago, phronk said:

Nice work, I always joke about how drivers intentionally drive off the road specifically to kill pedestrians lol. Good job finding a fix.

 

Thank you @phronk!

 

Yeah it was always funny and sometimes nerve-wrecking watching the Ai Drive over pedestrians. On most missions the civilian population was reduced to half during the first 10 min of a session. 

 

Rather than a fix this is a work-around that sacrifices some stuff in favor of a more grounded and FPS friendly experience. I am sure it will serve many servers and coop missions well.

Share this post


Link to post
Share on other sites

Nice work man.  Thanks for the contribution. 

 

If you want to improve on the "hits the brakes harshly" bit, you could use setVelocityModelSpace in a tight loop or onEachFrame to slow the vehicle down smoothly in whatever increment you choose.  I can dig up some sample similar code (but not exactly this use case) if you are interested. 

 

In my second Last Tango mission I had a chase sequence where player driving an offroad was chasing a fleeing AI truck.  I used setVelocityModelSpace in two ways:  1) Increase speed incrementally  of chased AI truck so it went much faster in straight sections of road, and 2) slowed player's vehicle incrementally when player too close to fleeing AI vehicle (as it was important to mission that player was not able to crash into the fleeing AI vehicle).

  • Thanks 1

Share this post


Link to post
Share on other sites

Thank you @johnnyboy , the appreciation is mutual and I still have a long road to travel if I want contribute 10% of what you have around here!

 

I am actually already using  setVelocityModelSpace on the script and it works quite well.

 

The problem is that since this script is meant for multiplayer I had to space checks over 1 sec or more so onEachFrame or tight loops are my mortal enemies. I only every use such loops on my draw3D scripts but nothing else.

 

You would be impressed by the amount of "damage" that a single and even the simplest tight loop can do to a server over two hours of gameplay.

 

In fact CBA, a mod I always found top notch performance wise, has serious issues with its current PATROL/SEARCH fncs just to let you know delicate server performance can be, that even the veterans coders and scripts sometimes fail at optimization some times.

  • Like 1

Share this post


Link to post
Share on other sites

Makes sense.  But...

11 minutes ago, LSValmont said:

The problem is that since this script is meant for multiplayer I had to space checks over 1 sec or more so onEachFrame or tight loops are my mortal enemies. I only every use such loops on my draw3D scripts but nothing else.

... I was only thinking of using onEachFrame or tight loops just for the braking event.  So you would sense when to brake however you do it now, then use setVelocityModelSpace in a tight loop momentarily for the braking.  It would not be a constantly running loop or onEachFrame.

 

But its obvious you have thought this through in detail and understand performance impacts far greater than I (especially MP stuff which I am quite weak on).  I'm sure its better how you have it now (just throwing ideas out...not all of them stick!).   Carry on dude! 

 

I need to get back into scripting, but for some reason I haven't been motivated, eventhough I technically have more time for it due to the annoying lockdowns.

  • Like 1

Share this post


Link to post
Share on other sites
3 hours ago, johnnyboy said:

I need to get back into scripting, but for some reason I haven't been motivated, eventhough I technically have more time for it due to the annoying lockdowns.

 

Your input is always welcome my friend, specially if I ever get into Single Player mission making. Ever since I started playing arma a couple years ago I never got into Single Player, it is all about the player interactions for me.

 

Anyways about the motivation part... it comes and goes at unexpected moments. Covid is a big let down so even if we have more time now it is also harder to have the will for stuff since we are all kinda depressed.

 

My current motivation is that all these scripts are really for my HUGE Script suite that I plan on using on my next super Multiplayer Mission 😉

 

If you ever wanna combine forces I believe we could do cool things faster than on our own. Additionally I am terrible at the marketing material specially since my english sucks!

 

I could give you a private snippet of what I am working on if you are interested and perhaps could be a motivation to do something BIG.

  • Like 3

Share this post


Link to post
Share on other sites

This is great! Anything that improves the shit driving code (that has vehicles swerving INTO foot mobiles) is very welcome indeed. 

 

Would it be possible to package it up in a mod to work everywhere? 

  • Like 1

Share this post


Link to post
Share on other sites
13 hours ago, kremator said:

This is great! Anything that improves the shit driving code (that has vehicles swerving INTO foot mobiles) is very welcome indeed. 

 

Would it be possible to package it up in a mod to work everywhere? 

 

Perhaps... I am in the process of gathering a team so I can get help and help others do things faster and perhaps a mod version too.

  • Like 1

Share this post


Link to post
Share on other sites
8 hours ago, headstone said:

Is it compatible with ai driving mod, can i run them together?

 

You mean the Ai Drive Control mod? Can you link the mod?

Share this post


Link to post
Share on other sites
1 hour ago, headstone said:

 

Then no.

 

This script is compatible with mods that ONLY deal with the movement of the vehicles a nothing else.

 

Ai Driving Control does what this script does (Makes the vehicles brake in time) but also handles the way vehicles interact with other nearby vehicles.

 

So if you have Ai Drive Control you don't need vAiDriving.

 

If you are not having performance problems with Ai Drive Control then there is no point in switching to vAiDriving.

Share this post


Link to post
Share on other sites

version 13 "Automatic Vehicle Waypoints!" of the vAiDriving script RELEASED:

 

Release Highlights:

 

- vAiDrive now has the option handle the waypoints of vehicles automatically so that players and mission makers do not have to set up each vehicle and each waypoint individually nor have other vehicle movement scripts running.(vAiDriving_handleVehWaypoints=true).


- vAiDrive now has the option to automatically cache vehicles and units to preserve resources when players are far away.  (vAiDriving_handleVehCache=true)


- It is now possible to set the vehicles handled by vAiDrive to never run out of fuel. (vAiDriving_vehUnlimitedFuel=true)


- vAiDrive can now also randomize the look of pedestrians automatically. (vAiDriving_dressPedestrians=true)


- All vAiDrive settings are now set by editing  the "vAiDrivingCONFIG.sqf" instead of the main fnc file.


- Fixed Ai civilians not looking at nearby pedestrians when "talking" to them.


- Fixed Bargates sometimes not being handled correctly.

 

While it started as a simple script to help Arma 3 vehicles brake better, AS OF VERSION 13, vAiDriving has expanded to become a fully fledged CIVILIAN vehicle and pedestrian handling script that does not require any input/extra work from the mission makers to work as intended and to have all its features enabled.

It provides mission makers whose missions involve Ai vehicular driving and/or Ai civilian pedestrians with ALL the tools they need in order to have a more immersive, performance friendly and overall better Arma 3 experience.

 

Version 13 DOWNLOAD LINKhttps://drive.google.com/open?id=133RUlQmcrzXFxV9RLC27sdIQYOLkFyR5

  • Like 1

Share this post


Link to post
Share on other sites

Hi, Valmont,

Finally did a little test on your script running your demo mission.

I compared to my script, disabled your waypoints (added manual ones), cache and pedestrians to be fair with mine, and the FPS were not that different. They both variate ~5 FPS while running the mission. The good part is (on my potato PC) I could definitely notice my pointer/mouse to be more responsive while running vAiDriving 🙂. That's probably due to the CBA function(s) keeping everything together while my script is probably flooding the scheduler.

Driving wise they also behaved pretty good 👍.

A quick test with pedestrians only, loved the performance when turning them into agents 👌.

One question: the script does update on spawned vehicles and pedestrians along the mission, right, not just editor placed?

Well done.

Cheers!

  • Like 2

Share this post


Link to post
Share on other sites
13 hours ago, RCA3 said:

Hi, Valmont,

Finally did a little test on your script running your demo mission.

I compared to my script, disabled your waypoints (added manual ones), cache and pedestrians to be fair with mine, and the FPS were not that different. They both variate ~5 FPS while running the mission. The good part is (on my potato PC) I could definitely notice my pointer/mouse to be more responsive while running vAiDriving 🙂. That's probably due to the CBA function(s) keeping everything together while my script is probably flooding the scheduler.

Driving wise they also behaved pretty good 👍.

A quick test with pedestrians only, loved the performance when turning them into agents 👌.

One question: the script does update on spawned vehicles and pedestrians along the mission, right, not just editor placed?

Well done.

Cheers!

 

I am glad you liked it @RCA3!

 

One key aspect is that I also disable most Ai features on Ai drivers so they are also consuming less scheduler time.

 

The script updates for new drivers/vehicles/pedestrians/BarGates every 300 seconds (5 minutes), It could be set to less and still won't affect performance.

 

Agents are amazing for these kind of scenarios.

 

I am turning @maxjoiner's aliens into agents now and they will be deadly! (While also performing 3 times faster).

  • Thanks 1

Share this post


Link to post
Share on other sites

With handleVehWaypoints and handleVehCache both set to false, distant vehicles are stopped until a player comes near enough. Is this intentional?

This is quite an exciting script, but the above mentioned behaviour breaks any mission design that expects certain vehicles to be able to move regardless of where the players are.

 

Additionally, the script seems to mess with drivers that are being handled by Silola's DAC. When a player moves near, it may take a while for the driver to start heading towards its waypoint. Upon reaching the waypoint, the driver won't get out and patrol as it's supposed to, which effectively prevents it from following any more waypoints.

Share this post


Link to post
Share on other sites

Please sign in to comment

You will be able to leave a comment after signing in



Sign In Now

×