Jump to content

Recommended Posts

I have got a script that works by calling it like this:

 

guard = [op1] execVM "HousePatrol.sqf";

is there a way to call this script for multiple units at the same time so as not to write:
 

guard = [op2] execVM "HousePatrol.sqf";

guard = [op3] execVM "HousePatrol.sqf";

...

 

Share this post


Link to post
Share on other sites
7 minutes ago, JohnKalo said:

I have got a script that works by calling it like this:

 


guard = [op1] execVM "HousePatrol.sqf";

is there a way to call this script for multiple units at the same time so as not to write:
 


guard = [op2] execVM "HousePatrol.sqf";

guard = [op3] execVM "HousePatrol.sqf";

...

 

 

I think in your example the "guard" variable will not point to any guard but the script handle returned by execVM

 

But to call the script multiple times you can do this:

 

HousePat = Compile preprocessFileLineNumbers "HousePatrol.sqf";



guard = [op2] call HousePat;

guard = [op3] call HousePat;

 

You have to use the "call" if you want something returned from the script/function

 

 

  • Like 1

Share this post


Link to post
Share on other sites

Yep that is no actual guard. Oh okay. Thanks for the prompt reply 👍

Share this post


Link to post
Share on other sites

Use forEach to repeat the same code for the units in an array.

You still want to compile the function as gc8 suggests, as using execVM would repetitively compile the script in each cycle of the forEach.  By defining the function beforehand, it compiles once.

HousePat = Compile preprocessFileLineNumbers "HousePatrol.sqf";

{guard = [_x] call HousePat;} forEach [op1,op2,op3];

 

  • Like 2
  • Thanks 1

Share this post


Link to post
Share on other sites

but "guard=" really is useless here.

Also you should probably use a local viarable for the function.

  • Thanks 1

Share this post


Link to post
Share on other sites

Well planning on using a trigger to call the script. That way it will work for all. So as far as I understand:

HousePat = Compile preprocessFileLineNumbers "HousePatrol.sqf"; 


{[_x] call HousePat;} forEach [op1,op2,op3];

is the right way to go   :thumbsup:

Share this post


Link to post
Share on other sites

Has been some time since I asked. Mission 09 took a lot more work than expected. Anyways, all of the above do not work. There is no error or anything but the AI just does not go anywhere for some reason. Here is the script:

 

if (!isServer) exitWith {};
sleep random 1;

// Set variables
_unit 				= _this select 0;
_maxWaitTime 		= if (count _this > 2) then {_this select 2} else {30};
_excludedPositions 	= if (count _this > 3) then {_this select 3} else {[]};
_startingPos 		= if (count _this > 4) then {_this select 4} else {-1};
_debug 				= if (count _this > 6) then {_this select 6} else {false};


_position = getPos _unit;
_house = nearestBuilding _unit;
_numOfBuildingPos = 0;
_currentBuildingPos = 0;
_lastBuildingPos = 0;
_waitTime = 0;
_timeout = 0;


_name = vehicleVarName _unit;


if (isNil _name) then 
{
	_name = format["Guard x%1y%2", floor (_position select 0), floor (_position select 1)]
};


_unit setBehaviour "SAFE";
_unit setBehaviour "UP";
	


// Find number of positions in building
while {!((_house buildingPos _numOfBuildingPos) isEqualTo [0,0,0])} do {
	_numOfBuildingPos = _numOfBuildingPos + 1;
};

// DEBUGGING - Mark house on map, mark building positions ingame, broadcast information
if (_debug) then {
	for [{_i = 0}, {_i <= _numOfBuildingPos}, {_i = _i + 1}] do	{
		if (!(_i in _excludedPositions)) then {	
			_arrow = "Sign_Arrow_F" createVehicle (_house buildingPos _i);
			_arrow setPos (_house buildingpos _i);
		};
	};
	player globalChat format["%1 - Number of available positions: %2", _name, _numOfBuildingPos]; 
	if (count _excludedPositions > 0) then
	{
		player globalChat format["%1 - Excluded positions: %2", _name, _excludedPositions]; 
	};
	
	_marker = createMarker [_name, position _unit];
	_marker setMarkerType "mil_dot";
	_marker setMarkerText _name;
	_marker setMarkerColor "ColorGreen";
};

// Put unit at random starting pos.
while {_startingPos in _excludedPositions || _startingPos < 0} do {
	_startingPos = floor(random _numOfBuildingPos);
};

if (_startingPos > _numOfBuildingPos - 1) then {
	_startingPos = _numOfBuildingPos - 1
};

if (_numOfBuildingPos > 0) then {
	_unit setPos (_house buildingPos _startingPos); 
	_unit setPos (getPos _unit);
};

// DEBUGGING - broadcast starting position
if (_debug) then {
	player globalChat format["%1 - starting at building pos %2", _name, _startingPos]
};

// Have unit patrol inside house
while {alive _unit && (_numOfBuildingPos - count _excludedPositions) > 0} do {

	if (_numOfBuildingPos < 2) exitWith {};
	
	while {_lastBuildingPos == _currentBuildingPos || _currentBuildingPos in _excludedPositions} do	{
		_currentBuildingPos = floor(random _numOfBuildingPos);
	};
	
	_waitTime = floor(random _maxWaitTime);
	_unit doMove (_house buildingPos _currentBuildingPos);
	_unit moveTo (_house buildingPos _currentBuildingPos);
	sleep 0.5;
	_timeout = time + 50;
	waitUntil {moveToCompleted _unit || {moveToFailed _unit || {!alive _unit || _timeout < time}}};
	if (_timeout < time) then {_unit setPos (_house buildingPos _currentBuildingPos)};
	
	// DEBUGGING - move marker to new position
	if (_debug) then {
		_name setMarkerPos position _unit; 
		_text = format["%1: moving to pos %2", _name, _currentBuildingPos]; 
		_name setMarkerText _text;
	};
	
	sleep _waitTime;
	_lastBuildingPos = _currentBuildingPos;
};

// DEBUGGING - Change marker color if script ends
if (_debug) then {
	player globalChat format["%1 - ended house patrol loop", _name];
	_name setMarkerColor "ColorRed";
};

I should again mention that the script is not mine but by Tophe of Östgöta Ops [OOPS] . In usual circumstances the above would not be needed since for realism all units load at the start but with Mission 10 it will be needed. Oh and the directions of the author:

 

Quote

HOW TO USE:
Place unit close to a house and put this in the init field:  
guard = [this] execVM "HousePatrol.sqf"

 

The above script has been changed a bit. There were many other optional settings for the patrol but they had optimization issues while not offering anything so with my spectacular scripting skills I just erased all parts that were not needed 😂

Share this post


Link to post
Share on other sites

Truly so many things to fix. You should start with your own script.

 

First of all, not sure you wrote the right housePatrol.sqf

[this] execVM "housePatrol.sqf" is supposed to pass [this] as argument (I don't know the added value of an array for a single argument). this, as variable, only works in init field of an edited object (so an AI here).

 

_unit = _this select 0;  // bah, consistent so far!

 

_maxWaitTime = if (count _this > 2) then {_this select 2} else {30}; // never in that case. I guess this is an old script before params command.

_excludedPositions = if (count _this > 3) then {_this select 3} else {[]};   //nope

_startingPos = if (count _this > 4) then {_this select 4} else {-1}; //  ??? should be a position but wait and see

_debug = if (count _this > 6) then {_this select 6} else {false}; // that means as 7th parameter

 

So, where are all parameters? You can save the deal, starting the script with:

params [ _this, nil, ["_maxWaitTime",30], ["_excludedPositions",[]], ["_startingPos",[0,0,0]], nil, ["_debug",FALSE] ];

but, to say the truth, make your own script with your own params.

then:

private _position = getPos _unit;

_house = nearestBuilding _unit; // I dislike this command!  you can't imagine what can/can't be returned by this ugly command

private _house = (nearestObjects [getpos _unit, ["House", "Building","tourism"], 50] select 0);   // "house" is rather fine, "building" is a mess grabbing even lamps but needed for some classes of houses, "tourism" is for hotel in Tanoa (plenty of building positions but not a house...) You can spend time adjusting this mess all over the maps.

 

_numOfBuildingPos = 0;

_currentBuildingPos = 0;

_lastBuildingPos = 0;

_waitTime = 0;

_timeout = 0;

 

_name = vehicleVarName _unit; if (isNil _name) then { _name = format["Guard x%1y%2", floor (_position select 0), floor (_position select 1)] }; // pffff what for? you can name your unit in editor, assorted with a specific loadout to follow the test. Useless in game, probably

 

// Find number of positions in building

while {!((_house buildingPos _numOfBuildingPos) isEqualTo [0,0,0])} do { _numOfBuildingPos = _numOfBuildingPos + 1; };

 

private _allPositions = _house buildingPos -1;  // if _allPositions isEqualTo []   ... no position. Or all returned positions! You can count them if you want.

At this stage, think about several houses to be checked it's not much more difficult:

_houses = (nearestObjects [getpos _unit, ["House", "Building","tourism"], 50]); // array

_allPositions = [];

{_allPositions (pushBack _x buildingPos _1)} forEach _houses;

 

then shuffle them , selectRandom them...  what you want...

the couple doMove / moveTo  ????  I'd rather use a simple  move  or  addWaypoint

 

the waitTime and timeOut are supposed to check if a unit is stuck.... Well, as I'm working on an advanced waypoint  similar to this purpose, I can say some ladder/corner/door/balcony are horrible. I check for timer, unit readiness (unitReady) and even animation of the unit.

Just saying stay motivated!

 

  • Thanks 1

Share this post


Link to post
Share on other sites

Thank you very much for the detailed description. Still complicating since the only code training I have is a Python class. The rest is via simple experience with already existing scripts. This will need some time to be developed. I will see what I can do because time is short and I would really like the mission to be ready till the first days of August. In the worst case scenario I will use the initial setting with a sleep inbetween so as not to cause a lag freeze. Yes [this] is when directly added to the init of the unit. So many things to do and so hot these days 😓

Share this post


Link to post
Share on other sites
10 hours ago, pierremgi said:

So, where are all parameters?

 

The script takes arguments with default values:

It was originally written for A2, ported in 2014, so it could indeed use an update pass.

  • Like 1

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

×