Jump to content
cookies2432

Issues calling functions

Recommended Posts

Hi! I've been having some difficulties calling my functions in my script, not sure why. I've read the wiki page and done as it was told there but it still doesn't seem to be working, thankfull for any advices  :)
This is my code:

 

// Finds a mission location from 4 possible ones
[10, 2] call _fn_spawnAiOnMission;
call _fn_missionClock;


_fn_findMissionLocation = {
private ["_convoy1", "_convoy2", "_convoy3", "_convoy4"];
_convoy1 = getMarkerPos "convoy1";
_convoy2 = getMarkerPos "convoy2";
_convoy3 = getMarkerPos "convoy3";
_convoy4 = getMarkerPos "convoy4";
[_convoy1, _convoy2, _convoy3, _convoy4] call BIS_fnc_selectRandom;
};


// Creates a marker at "_location"

_missionMarker = createMarker ["missionMarker", call _fn_findMissionLocation];
_missionMarker setMarkerShape "ELLIPSE";
_missionMarker setMarkerSize [200, 200];
_missionMarker setMarkerBrush "Solid";
_missionMarker setMarkerColor "ColorRed";
_missionMarker setMarkerText "Convoy taking a break";

// A function that spawns the ai and vehicles at the mission, both have a limit.

_fn_spawnAiOnMission = { 
private ["_aiLimit", "_truckLimit"];
_aiLimit = _this select 0; //retrive the first parameter from the function call;
_truckLimit = _this select 1; //retrive the second parameter from the function call;
_aux = 0; //added a aux variable that I use as index for the while loop
_alpha = createGroup west; //create a group that after the execution of this function will be automatically deleted
while {_aux < _aiLimit} do {
"B_Soldier_F" createUnit [getMarkerPos "missionMarker", group _alpha, setBehaviour "SAFE"];
_aux = _aux + 1;
hint format ["There are %1 ai units in the mission area", _aiLimit];
sleep 5;
};
//at this point _aux should be 10
_aux = 0;
//again 0
while {_aux < _truckLimit} do {
   _veh = createVehicle ["B_MRAP_01_F", getMarkerPos "missionMarker"];
   _aux = _aux + 1;
};  
//finish doing the same thing
};
// Creates a timer for the mission, if time <= 1 then it will delete the marker and delete all units after 5 minutes (a hint tells everyone about it)

_fn_missionClock = {
	private ["_time"];
	_time = 1200;
	if (1 + 1 == 2) do {
	while {_time >= 1}
	_time = _time - 1;
	};
	if (_time <= 1) then {
		hint format["The convoy mission has ended. All vehicles and infantry will be deleted in 5 minute"];
		deleteMarker "missionMarker";
		sleep 300;
   };
};
  • Like 1

Share this post


Link to post
Share on other sites

Oh man, in my case I cannot check 54 lines of code right now.

 

Please say what functions are giving trouble, and what you expect from them.

 

BTW I think I've seen a failure in _fn_findMissionLocation, it is probably returning nothing, as there is no variable to return. Change the last line for:

 

_return = [_convoy1, _convoy2, _convoy3, _convoy4] call BIS_fnc_selectRandom;

_return

 

Other: you are assigning local variables to your functions, which is ok... if you are calling them from the same script. If you are calling them from anywhere else, unknown variable man...

 

Other: are you checking .rpt? It is a MUST. And probably is pointing you directly towards what is failing.

Share this post


Link to post
Share on other sites

I know about local and global variables.

_funnyVariable is a local variable

funnyVariable is a global variable.

 

How do i check the .rpt?

 

I thought it was correct since it was working and i didn't need a variable. The Functions i'm in need of calling are: _fn_spawnAiOnMission and _fn_missionClock

 

If there are any other script issues that people can find then please let me know, i'm fairly new to scripting.

Share this post


Link to post
Share on other sites

Pretty sure you need to put the function declarations before you call them. It reads the script top-down and doesn't prototype functions in the script? I could be wrong..

Share this post


Link to post
Share on other sites

As Kingsley pointed out, function is just a variable holding code, if you do not define it before you call it, it doesn't exist.

Share this post


Link to post
Share on other sites
_fn_missionClock = {
    private ["_time"];
    _time = 1200;
    if (1 + 1 == 2) do {
    while {_time >= 1}
    _time = _time - 1;
    };
    if (_time <= 1) then {
        hint format["The convoy mission has ended. All vehicles and infantry will be deleted in 5 minute"];
        deleteMarker "missionMarker";
        sleep 300;
};
};

 

That function has a "sleep" command in it.

You cannot CALL functions with any delay's in them, (sleeps or waituntil commands) you can only spawn them.

 

And you need to call/spawn the function after you have declared them, not before, so the line "[] spawn _fn_missionClock;"  should be at the end of the script after the _fn_missionClock = {.....................................

Share this post


Link to post
Share on other sites

@terox this is not entirely true:
 

[] spawn {

	//spawned to emulate scheduled environment
	
	_my_fnc = {
		sleep 1; 
		hint "slept 1";
		sleep 1;
		hint "slept another 1";
	};
	
	call _my_fnc;
};

Share this post


Link to post
Share on other sites

 

@terox this is not entirely true:

 

[] spawn {

	//spawned to emulate scheduled environment
	
	_my_fnc = {
		sleep 1; 
		hint "slept 1";
		sleep 1;
		hint "slept another 1";
	};
	
	call _my_fnc;
};

I'm confused, are you stating you can call a function with a sleep command in it, if that function is defined in a spawned script ???

Something I've never attempted.

Share this post


Link to post
Share on other sites

@terox this is not entirely true:

 

[] spawn {

	//spawned to emulate scheduled environment
	
	_my_fnc = {
		sleep 1; 
		hint "slept 1";
		sleep 1;
		hint "slept another 1";
	};
	
	call _my_fnc;
};

Ooo you learn something new every day :)

Share this post


Link to post
Share on other sites

I'm confused, are you stating you can call a function with a sleep command in it, if that function is defined in a spawned script ???

Something I've never attempted.

You can always use sleep in a called function when the enviroment you're calling it from is scheduled. The function doesn't have to be defined within the script.

 

I'd say 95% of the scripts we typically use is ran in a scheduled scope. For example spawn and execvm always create a scheduled thread, so you can sleep as much as you like from that point on.

Share this post


Link to post
Share on other sites

You can call functions with sleep as long as they are in scheduled environment (out of eventhandlers, init.sqf etc..) and they won't drop error, they will just make the script who called it wait until the function is finished to proceed with the next line of code.

 

Its like you were not calling nothing but putting function code in the script itself.

 

And yes, I didnt noticed you were calling the function before defining the function, it's like going home and home has not been constructed yet.

 

And about the .rpt: Ask google: "where is arma 3 .rpt"?

 

A new world of scripting debugging has opened to you right now.

 

You are welcome.

Share this post


Link to post
Share on other sites

Init.sqf, initServer.sqf, initPlayerLocal.sqf and initPlayerServer.sqf are all started in the scheduled environment. So any scripts called from these or their children are scheduled and can be paused no matter if called or spawned. Even CfgFunctions postInit functions and modules are started in the scheduled environment.

The main places where you will find non scheduled code is objectInits, eventHandlers, addAction(condition), triggers, waypoints and similar commands with deferred code parameters.

Share this post


Link to post
Share on other sites
addAction - only condition is non-scheduled, main code is scheduled.
:D Ha knew i would get one wrong somewhere in the list. Updated so as not to sow confusion.

Share this post


Link to post
Share on other sites

I'm still having issues when calling the functions, i have even replaced the functions code to a simple hint command to see if it was something wrong with the function. No luck tho.

// Finds a mission location from 4 possible ones


_fn_findMissionLocation = {
private ["_convoy1", "_convoy2", "_convoy3", "_convoy4"];
_convoy1 = getMarkerPos "convoy1";
_convoy2 = getMarkerPos "convoy2";
_convoy3 = getMarkerPos "convoy3";
_convoy4 = getMarkerPos "convoy4";
[_convoy1, _convoy2, _convoy3, _convoy4] call BIS_fnc_selectRandom;
};


// Creates a marker at "_location"

_missionMarker = createMarker ["missionMarker", call _fn_findMissionLocation];
_missionMarker setMarkerShape "ELLIPSE";
_missionMarker setMarkerSize [200, 200];
_missionMarker setMarkerBrush "Solid";
_missionMarker setMarkerColor "ColorRed";
_missionMarker setMarkerText "Convoy taking a break";

// A function that spawns the ai and vehicles at the mission, both have a limit.

_fn_spawnAiOnMission = { 
private ["_aiLimit", "_truckLimit"];
_aiLimit = _this select 0; //retrive the first parameter from the function call;
_truckLimit = _this select 1; //retrive the second parameter from the function call;
_aux = 0; //added a aux variable that I use as index for the while loop
_alpha = createGroup west; //create a group that after the execution of this function will be automatically deleted
while {_aux < _aiLimit} do {
"B_Soldier_F" createUnit [getMarkerPos "missionMarker", group _alpha, setBehaviour "SAFE"];
_aux = _aux + 1;
hint format ["There are %1 ai units in the mission area", _aiLimit];
sleep 5;
};
//at this point _aux should be 10
_aux = 0;
//again 0
while {_aux < _truckLimit} do {
   _veh = createVehicle ["B_MRAP_01_F", getMarkerPos "missionMarker"];
   _aux = _aux + 1;
};  
//finish doing the same thing
};
// Creates a timer for the mission, if time <= 1 then it will delete the marker and delete all units after 5 minutes (a hint tells everyone about it)
// This is where i changed the code
	[] spawn {
_fn_missionClock = {
	private ["_time"];
	_time = 1200;
	if (1 + 1 == 2) do {
	while {_time >= 1}
	_time = _time - 1;
	};
	if (_time <= 1) then {
		hint format["The convoy mission has ended. All vehicles and infantry will be deleted in 5 minute"];
		deleteMarker "missionMarker";
		sleep 300;
	};
	call _fn_missionClock;
    };
    [10, 2] call _fn_spawnAiOnMission;
   };

Share this post


Link to post
Share on other sites

Okay something is very wrong about the _fn_missionClock function you've written. I've re-written it below, but basically the if (1 + 1 == 2) do { while {} } thing is just plain wrong.

[] spawn {
	_fn_missionClock = {
		private ["_time"];
		_time = 1200;
		
		while {_time >= 1} do {
			_time = _time - 1;
		};
		
		if (_time <= 1) then {
			hint "The convoy mission has ended. All vehicles and infantry will be deleted in 5 minute";
			deleteMarker "missionMarker";
			sleep 300;
			// Delete vehicles and infantry code here
		};
	};
	
	call _fn_missionClock;

	// _fn_spawnAiOnMission won't be defined because this is inside a different scope (spawn)
	// Instead, make _fn_spawnAiOnMission a global function (omit the underscore)
	[10, 2] call fn_spawnAiOnMission;
};

Share this post


Link to post
Share on other sites

I still don't see the units  :mellow: this is my code: 

fn_spawnAiOnMission = { 
private ["_aiLimit", "_truckLimit"];
_aiLimit = _this select 0; //retrive the first parameter from the function call;
_truckLimit = _this select 1; //retrive the second parameter from the function call;
_aux = 0; //added a aux variable that I use as index for the while loop
_alpha = createGroup west; //create a group that after the execution of this function will be automatically deleted
while {_aux < _aiLimit} do {
"B_Soldier_F" createUnit [getMarkerPos "missionMarker", group _alpha, setBehaviour "SAFE"];
_aux = _aux + 1;
hint format ["There are %1 ai units in the mission area", _aiLimit];
sleep 5;
};
//at this point _aux should be 10
_aux = 0;
//again 0
while {_aux < _truckLimit} do {
   _veh = createVehicle ["B_MRAP_01_F", getMarkerPos "missionMarker"];
   _aux = _aux + 1;
};  
//finish doing the same thing
};
// Creates a timer for the mission, if time <= 1 then it will delete the marker and delete all units after 5 minutes (a hint tells everyone about it)
[] spawn {
	_fn_missionClock = {
		private ["_time"];
		_time = 1200;
		
		while {_time >= 1} do {
			_time = _time - 1;
		};
		
		if (_time <= 1) then {
			hint "The convoy mission has ended. All vehicles and infantry will be deleted in 5 minute";
			deleteMarker "missionMarker";
			sleep 300;
			// Delete vehicles and infantry code here
		};
	};
	
	call _fn_missionClock;
	[10, 2] call fn_spawnAiOnMission;
};

Share this post


Link to post
Share on other sites

spawn the units at [0,0,0] then teleport them to the position of the missionMarker...

 

replace the function _fn_spawnAiOnMission with a hint and check if the function is called correctly. the next step would be debugging all needed variables to see if they're really defined

 

just to get it right: the _fn_missionClock is a counter isn't it?

 

 

Edit:

 

so what you want to do is:

spawn units -> start counter ->wait 1200 seconds -> delete units

is that right??

 

as it was stated before, calling a function forces it's parent function to wait until the called function is finished. so you're finishing the loop first and create units afterwards, try it the other way around

_fn_missionClock = {
		private ["_time"];
		_time = 1200;
		
		while {_time >= 1} do {
			_time = _time - 1;
		};
		
		if (_time <= 1) then {
			hint "The convoy mission has ended. All vehicles and infantry will be deleted in 5 minute";
			deleteMarker "missionMarker";
			sleep 300;
			// Delete vehicles and infantry code here
		};
	};
	
!!!     call _fn_missionClock;    !!!
	[10, 2] call fn_spawnAiOnMission;

Share this post


Link to post
Share on other sites

I've rewritten it making it a little more verbose. Each function knows nothing about previous functions making it reusable.

I have also messed around and added a side parameter to the spawnAI function so it is reusable for spawning different side units and MRAPs if needed.

Your main problem was the use of createUnit, you were using group _alpha when _alpha is already a group, and the init needed to be a STRING using this as a reference to the spawned unit. See the comment in the code below.

 

//Define some functions

//Create mission marker
fn_missionMarker = {
	private[ "_missionPos", "_missionMarker" ];
	params[
		"_possibleMarkers" //retrive the first parameter from the function call
	];

	// Finds a mission location from the possible ones
	_missionPos = _possibleMarkers call BIS_fnc_selectRandom;

	// Creates a marker at "_missionPos"
	_missionMarker = createMarker ["missionMarker", getMarkerPos _missionPos ];
	_missionMarker setMarkerShape "ELLIPSE";
	_missionMarker setMarkerSize [200, 200];
	_missionMarker setMarkerBrush "Solid";
	_missionMarker setMarkerColor "ColorRed";
	//_missionMarker setMarkerText "Convoy taking a break"; //This does nothing for area markers

	//Pass back the missions marker
	_missionMarker
};

//Create mission objects
fn_spawnAiOnMission = {
	private [ "_missionPos", "_group", "_unitClass", "_vehClass", "_count", "_vehicles", "_veh", "_nul" ];
	params[
		"_side", //retrive the first parameter from the function call
		"_missionMarker", //retrive the second parameter from the function call
		[ "_aiLimit", 0 ], //retrive the third parameter from the function call, default 0 if not passed
		[ "_truckLimit", 0 ] //retrive the fourth parameter from the function call, default 0 if not passed
	];

	//Get mission marker position
	_missionPos = getMarkerPos _missionMarker;
	
	//Create a center for the side just incase one does not exist
	_nul = createCenter _side;

	//create a group
	_group = createGroup _side;

	//Get default soldier class for side
	_unitClass = [ "O_Soldier_F", "B_Soldier_F", "I_Soldier_F" ] select ( _side call BIS_fnc_sideID );

	//Get default MRAP for side
	_vehClass = [ "O_MRAP_02_F", "B_MRAP_01_F", "I_MRAP_03_F" ] select ( _side call BIS_fnc_sideID );

	//Create _aiLimit number of units
	for "_count" from 1 to _aiLimit do {
		//NOTE : _group not group _group AND Init as string using THIS to reference spawned unit
		_unitClass createUnit [_missionPos, _group, 'this setBehaviour "SAFE"'];
		sleep 0.5;
	};

	//Array to store a list of spawned vehicles
	_vehicles = [];

	//Create _truckLimit number of vehicles
	for "_count" from 1 to _truckLimit do {
		_veh = createVehicle [_vehClass, _missionPos, [], 0, "NONE"];
		//Give the unit use of the vehicle
		_group addVehicle _veh;
		//Add vehicle to Array
		_nul = _vehicles pushBack _veh;
	};

	//Pass back the created group and the list of vehicles
	[ _group, _vehicles ]
};

// Creates a timer for the mission
fn_missionClock = {
	private ["_time"];
	params[
		"_missionObjects",	//retrive the first parameter from the function call
		"_missionMarker",	//retrive the second parameter from the function call
		"_missionTime"		//retrive the third parameter from the function call
	];

	_missionObjects params[
		"_group",	//retrive the first parameter from _missionObjects
		"_vehicles"	//retrive the second parameter from _missionObjects
	];

	//Work out mission end time
	_time = time + _missionTime;

	//Wait until time period has finished
	waitUntil { time > _time };

	//Clean up mission objects
	hint "The convoy mission has ended. All vehicles and infantry will be deleted in 5 minute";
	deleteMarker _missionMarker;
	sleep 300;

	//Delete vehicles and infantry code here
	{
		deleteVehicle _x;
	}forEach ( units _group + _vehicles );
	deleteGroup _group;
};



//Setup the mission

private [ "_possibleMissionPositions", "_mrk", "_missionObjects", "_nul" ];

//An array of markers for possible mission position
_possibleMissionPositions = ["convoy1", "convoy2", "convoy3", "convoy4"];

//Create mission marker from possible positions
_mrk =  [_possibleMissionPositions] call fn_missionMarker;

//Create AI and vehicles at mission marker [ SIDE, marker, num AI, num MRAPs ]
_missionObjects = [ west, _mrk, 8, 2 ] call fn_spawnAiOnMission;

//Start mission timer
_nul = [ _missionObjects, _mrk, 1200 ] spawn fn_missionClock;
I hope this helps and makes the code flow a little more readable..

Share this post


Link to post
Share on other sites

:blink: I totally understand that whole code.  :huh: Will have a look at it and try to understand it. Thanks!

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

×