Jump to content
Blitzen88

How to loop a script without re-execing it?

Recommended Posts

Got an AI hunt (ie stalk) script that I made and Im having some trouble re-execing it after a While loop has completed. 
 

Can anyone tell/show me how to make it loop without re-execing it? I feel like re-execing it is bad practice.

 

Here it is (look at the very bottom):

Spoiler

/*==========================================================================================

 

                                                                Arma III - AI Hunt

 

Created by Blitzen

 

===========================================================================================

 

* Script forces AI "hunters" to "hunt" other units by placing a movement waypoint on the location "hunted" group's location

 

* Script can restrict vehicle/infantry groups to only hunt enemy vehicle/infantry groups.  Restrictions can also be turned off (ie vehicle groups can hunt infantry groups)

 

* Script will wait a period of time before re-scanning for enemy groups if no groups are found

 

* Script will ignore aircraft and vanilla artillery units

 

* Parameters:

 

                1. Group Leader - Squad leader of the group which will hunt enemy targets

                

                2. Target Filtering - Whether or not vehicle/infantry groups should only hunt vehicles/infantry. True for restrictions, False for no restrictions

                

                3. Hunt Player - Whether or not the hunter will only target the player.  Friendly units will still hunt enemy groups.

                

                4. Scan Distance - How far the group will look for targets

                

                5. Scan Delay - How long the script will wait to re-scan for targets if no targets are found

                

                6. Waypoint Delay - How quickly the hunter group's waypoint will update

 

* Call with (Unit Init): [This, True, False, 1000, 40, 30] execVM "Scripts\AI\AI_Hunt.sqf"

 

* Call with (Spawn Module): [leader (_This Select 0), True, False, 1000, 40, 30] execVM "Scripts\AI\AI_Hunt.sqf"

 

===========================================================================================*/

 

//Define Input Variables

 

_GroupLeader = _this select 0;

 

_Group = group _GroupLeader;

 

_HuntType = _this select 1;

 

_HuntPlayer = _this select 2;

 

_ScanDistance = _this select 3;

 

_ScanDelay = _this select 4;

 

_WaypointDelay = _this select 5;

 

//Define additional Variables

 

_GroupVehicles = [_Group, true] call BIS_fnc_groupvehicles;

 

_ExcludedUnitTypes = [

 

                "O_MBT_02_arty_F",

 

                "B_MBT_01_arty_F",

 

                "B_MBT_01_mlrs_F",

                

                "I_LT_01_AA_F",

 

                "B_AAA_System_01_F",

 

                "B_SAM_System_03_F",

 

                "B_APC_Tracked_01_AA_F",

 

                "I_Mortar_01_F",

 

                "B_Mortar_01_F",

 

                "O_APC_Tracked_02_AA_F",

 

                "O_SAM_System_04_F",

 

                "O_Mortar_01_F"

 

                ];

 

//Create Variables to avoid scoping issues

 

_nearestMen = [];

 

_nearestVehicles = [];

 

_nearestEnemyInfantry = [];

 

_nearestEnemyVehicles = [];

 

_nearestEnemiesCombined = [];

 

_Hunted = [];

 

//Get an array of enemy infantry groups

 

_nearestMen = nearestObjects [getpos _GroupLeader, ["Man"], _ScanDistance];

 

                {

                                if ( (side _x getFriend (side _GroupLeader)) < 0.6 && {side _x != CIVILIAN} && ( {isNull objectParent _x} foreach units group _x) ) then {

 

                                _nearestEnemyInfantry = _nearestEnemyInfantry + [_x];

                                                               

                                };

                                                               

                } forEach _nearestMen;

                                

//Get an array of enemy vehicle groups

                                

_nearestVehicles = nearestObjects [getpos _GroupLeader, ["LandVehicle"], _ScanDistance];

 

                {

                                if ( (side _x getFriend (side _GroupLeader)) < 0.6 && {side _x != CIVILIAN} && !( _x isKindOf "staticWeapon") && !(typeof _x in _ExcludedUnitTypes) ) then {

 

                                _nearestEnemyVehicles = _nearestEnemyVehicles + [_x];

                                                               

                                };

                                                               

                } forEach _nearestVehicles;

 

//Combine enemy Infantry and Vehicle arrays

 

{_nearestEnemiesCombined append _x} foreach [

                

                _nearestEnemyInfantry,

                

                _nearestEnemyVehicles

                

                ];

 

//"Filter" targets based upon input

 

if (_HuntType) then {

 

//Group has a vehicle - Hunt enemy vehicles

                

                if (count _GroupVehicles > 0) then {

                

                                _Hunted = _nearestEnemyVehicles select 0;

                                

                };

 

//Group does NOT have a vehicle - Hunt enemy infantry

 

                if (count _GroupVehicles == 0) then {

                

                                _Hunted = _nearestEnemyInfantry select 0;

                                

                };

 

} else {

 

                _Hunted = _nearestEnemiesCombined select 0;

 

};

 

//Whether or not enemy groups should hunt the player's group

 

if ( (_HuntPlayer) && !(side _Group == playerSide) ) then {

 

                _Hunted = player;

 

};

 

//Start Movement Cycle

_Go = True;

 

while {_Go} do {

 

                if ( isNil "_Hunted" ) exitwith {_Go = False};

 

                if (({alive _x} count units _Group) == 0) exitwith {_Go = False};

 

                if (({alive _x} count units group _Hunted) == 0) exitwith {_Go = False};

 

                if ( _Hunted distance _GroupLeader >= _ScanDistance ) exitwith {_Go = False};

                

                for "_i" from count waypoints _Group -1 to 0 step -1 do {

                

                                deleteWaypoint [_group, _i]

                                

                                };

                

    _GroupWp = _Group addWaypoint [leader group _Hunted, 20];

    

                _GroupWp setWaypointType "MOVE";

    

                _GroupWp setWaypointBehaviour "AWARE";

    

                _GroupWp setWaypointCombatMode "GREEN";

    

                _GroupWp setWaypointSpeed "NORMAL";

                

                Sleep _WaypointDelay;

};

//End Movement Cylce - Hunted or Hunter group is dead

 

 

//Re-Exec the script if Hunters still exist

if ( ( {alive _x}count units _Group ) > 0 ) then {

 

                sleep _ScanDelay;

 

                [leader _Group, _HuntType, _HuntPlayer, _ScanDistance, _ScanDelay, _WaypointDelay] execVM "Scripts\AI\AI_Hunt.sqf";

 

};

 

Share this post


Link to post
Share on other sites

Write it as a function instead.

Share this post


Link to post
Share on other sites
18 minutes ago, Harzach said:

Write it as a function instead.

Isnt that the same as re-execing it if you just re-call it?

Share this post


Link to post
Share on other sites
2 minutes ago, Blitzen88 said:

Isnt that the same as re-execing it if you just re-call it?

 

No. execVM compiles the script and passes it to the scheduler. Best used for scripts you only need to run once.

 

A function is precompiled. Ideal for scripts you need to run often.

 

https://community.bistudio.com/wiki/Function

Share this post


Link to post
Share on other sites

Why? SQS is obsolete. Write a function.

 

You can easily convert it to an inline function by wrapping it in curly brackets and assigning a handle. Run it in init.sqf or wherever it makes sense.

 

Basically:

 

Spoiler


/*==========================================================================================

* Call with (Unit Init): [This, True, False, 1000, 40, 30] call BLTZ_fnc_stalk;

* Call with (Spawn Module): [leader (_This Select 0), True, False, 1000, 40, 30] call BLTZ_fnc_stalk;

===========================================================================================*/

BLTZ_fnc_stalk = {

params ["_GroupLeader","_HuntType","_HuntPlayer","_ScanDistance","_ScanDelay","_WaypointDelay"];

_Group = group _GroupLeader;
_GroupVehicles = [_Group, true] call BIS_fnc_groupvehicles;

_ExcludedUnitTypes = [
	"O_MBT_02_arty_F",
	"B_MBT_01_arty_F",
	"B_MBT_01_mlrs_F",
	"I_LT_01_AA_F",
	"B_AAA_System_01_F",
	"B_SAM_System_03_F",
	"B_APC_Tracked_01_AA_F",
	"I_Mortar_01_F",
	"B_Mortar_01_F",
	"O_APC_Tracked_02_AA_F",
	"O_SAM_System_04_F",
	"O_Mortar_01_F"
];

//Create Variables to avoid scoping issues

_nearestMen = [];
_nearestVehicles = [];
_nearestEnemyInfantry = [];
_nearestEnemyVehicles = [];
_nearestEnemiesCombined = [];
_Hunted = [];

//Get an array of enemy infantry groups

_nearestMen = nearestObjects [getpos _GroupLeader, ["Man"], _ScanDistance];

{
	if ( (side _x getFriend (side _GroupLeader)) < 0.6 && {side _x != CIVILIAN} && ( {isNull objectParent _x} foreach units group _x) ) then {
		_nearestEnemyInfantry = _nearestEnemyInfantry + [_x];
	};
} forEach _nearestMen;

//Get an array of enemy vehicle groups

_nearestVehicles = nearestObjects [getpos _GroupLeader, ["LandVehicle"], _ScanDistance];

{
	if ( (side _x getFriend (side _GroupLeader)) < 0.6 && {side _x != CIVILIAN} && !( _x isKindOf "staticWeapon") && !(typeof _x in _ExcludedUnitTypes) ) then {
		_nearestEnemyVehicles = _nearestEnemyVehicles + [_x];
	};
} forEach _nearestVehicles;

//Combine enemy Infantry and Vehicle arrays

{_nearestEnemiesCombined append _x} foreach [
	_nearestEnemyInfantry,
	_nearestEnemyVehicles
];

//"Filter" targets based upon input

if (_HuntType) then {

//Group has a vehicle - Hunt enemy vehicles

	if (count _GroupVehicles > 0) then {
		_Hunted = _nearestEnemyVehicles select 0;
	};

//Group does NOT have a vehicle - Hunt enemy infantry

	if (count _GroupVehicles == 0) then {
		_Hunted = _nearestEnemyInfantry select 0;
	};

} else {
	_Hunted = _nearestEnemiesCombined select 0;
};

//Whether or not enemy groups should hunt the player's group

if ( (_HuntPlayer) && !(side _Group == playerSide) ) then {
	_Hunted = player;
};

//Start Movement Cycle

_Go = True;
while {_Go} do {
	if ( isNil "_Hunted" ) exitwith {_Go = False};
	if (({alive _x} count units _Group) == 0) exitwith {_Go = False};
	if (({alive _x} count units group _Hunted) == 0) exitwith {_Go = False};
	if ( _Hunted distance _GroupLeader >= _ScanDistance ) exitwith {_Go = False};
	
	for "_i" from count waypoints _Group -1 to 0 step -1 do {
		deleteWaypoint [_group, _i]
	};

	_GroupWp = _Group addWaypoint [leader group _Hunted, 20];
	_GroupWp setWaypointType "MOVE";
	_GroupWp setWaypointBehaviour "AWARE";
	_GroupWp setWaypointCombatMode "GREEN";
	_GroupWp setWaypointSpeed "NORMAL";
	Sleep _WaypointDelay;
};

//End Movement Cylce - Hunted or Hunter group is dead

//Recall function if Hunters still exist

if ( ( {alive _x}count units _Group ) > 0 ) then {
	sleep _ScanDelay;
	[leader _Group, _HuntType, _HuntPlayer, _ScanDistance, _ScanDelay, _WaypointDelay] call BLTZ_fnc_stalk;
};

};

 

 

Not tested.

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

×