Jump to content
Sign in to follow this  
kOepi

loadout into function conversion

Recommended Posts

hello everyone,

this is another newbie trying to optimize his scripts, read through a lot of stuff and tutorials about functions, so I decided to convert my loadout scripts into function.

It even partly works but I receive a lot of errors, which hopefully have a simple solution to it.

in my init.sqf:

execVM "scripts\RSFspawn.sqf";

nul=[] execVM "scripts\functions\functions.sqf";

in my RSFspawn.sqf:

{
if (typeof  _x == "CUP_O_RUS_Soldier_Marksman") then {
[_x] execVM "scripts\loadouts\MM.sqf"};
} foreach  allunits;  

{
if (typeof  _x == "CUP_O_RUS_SpecOps_Scout") then {
[_x] execVM "scripts\loadouts\0-4RS.sqf"};
} foreach  allunits;  

{
if (typeof  _x == "CUP_O_RUS_SpecOps") then {
[_x] execVM "scripts\loadouts\1-2RO.sqf"};
} foreach  allunits;  

{
if (typeof  _x == "CUP_O_RUS_Commander") then {
[_x] execVM "scripts\loadouts\1iC.sqf"};
} foreach  allunits;  

{
if (typeof  _x == "CUP_O_RUS_Soldier_TL") then {
[_x] execVM "scripts\loadouts\2iC.sqf"};
} foreach  allunits;  

{
if (typeof  _x == "CUP_O_RUS_Soldier_GL") then {
[_x] execVM "scripts\loadouts\1-2WS.sqf"};
} foreach  allunits;  

{
if (typeof  _x == "CUP_O_RUS_SpecOps_SD") then {
[_x] execVM "scripts\loadouts\1-2DS.sqf"};
} foreach  allunits;  

in my functions.sqf:

// spetsnaz loadout function

fnc_RSFgiveUniform = {
removeUniform _this;
_this forceAddUniform "rhs_uniform_mflora_patchless";
};

fnc_RSFgiveMSS = {
for "_i" from 1 to 8 do {_this addItemToUniform "AGM_Bandage";};
for "_i" from 1 to 3 do {_this addItemToUniform "AGM_Morphine";};
for "_i" from 1 to 2 do {_this addItemToUniform "AGM_Epipen";};
_this addItemToUniform "AGM_EarBuds";
};

fnc_RSFgiveWmaks = {
_this addItemtoUniform "CUP_8Rnd_9x18_MakarovSD_M";
_this addWeapon "CUP_hgun_PB6P9";
for "_i" from 1 to 2 do {_this addItemToUniform "CUP_8Rnd_9x18_MakarovSD_M";};
_this addHandgunItem "CUP_muzzle_PB6P9";
};

fnc_removeall = {
removeAllWeapons _this;
removeAllItems _this;
removeAllAssignedItems _this;
removeVest _this;
removeBackpack _this;
removeHeadgear _this;
removeGoggles _this;
_this unlinkItem "tf_microdagr";
};

fnc_RSFgivegren = {
for "_i" from 1 to 2 do {_this addItemToVest "rhs_mag_rgd5";};
for "_i" from 1 to 2 do {_this addItemToVest "rhs_mag_rdg2_white";};
};

fnc_giveitems = {
_this addweapon "binocular";
_this linkItem "ItemMap";
sleep 1;
_this linkItem "Itemwatch";
};

in my MM.sqf:

//	Marksman

_RSF = _this select 0;

_RSF spawn fnc_removeall;
_RSF spawn fnc_RSFgiveUniform;
_RSF spawn fnc_RSFgiveMSS;
_RSF spawn fnc_RSFgiveWmakS;
_RSF spawn fnc_giveitems;

_RSF addVest "rhs_6sh92";
for "_i" from 1 to 7 do {_RSF addItemToVest "CUP_20Rnd_9x39_SP5_VSS_M";};

_RSF addBackpack "CUP_B_ACRScout_m95";

_RSF addHeadgear "rhs_beanie_green";
_RSF addGoggles "G_Bandanna_tan";

_RSF addWeapon "CUP_srifle_VSSVintorez";
_RSF addPrimaryWeaponItem "CUP_optic_PSO_1";

the error is : undefined variable expression in line 5 of MM.sqf "fnc_removeall".

it execute all the functions as expected, but not the rest of the MM.sqf.

I am sitting for hours on this now, someone please help me on this.

greetz

kOepi

Share this post


Link to post
Share on other sites

I am maybe completely off here but don't you also need to add [] infront of the spawn? Like:

[_RSF] spawn fnc_removeall;

Edited by R3vo

Share this post


Link to post
Share on other sites

The way I was taught was

create your functions folder 'KO_functions'

Inside that folder create a file called 'functions.h' and add the following code

class KO_functions
{
tag = "KO";

class Main_Directory
{
	file = "KO_functions";
	class  RSFgiveUniform{};

};

};

no create the following file in the KO_functions folder

fn_RSFgiveUniform.sqf

 
   removeUniform _this; 
   _this forceAddUniform "rhs_uniform_mflora_patchless"; 

to call on the function use, note you may have to pass your object variable to it


[] spawn KO_fnc_RSFgiveUniform; 

You can keep adding scripts the folder and add them to your functions.h

Share this post


Link to post
Share on other sites

Offtopic: in your rsfspawn.sqf, you are iterating through all units for each of your unit types. That is inefficient; I suggest that you instead use a switch to check the unit type and assign loadouts, in only one loop.

Share this post


Link to post
Share on other sites

@ Fight 9:

in the RSFspawn.sqf - Line 3

@ R3vo

maybe, but I tried that and then it did not execute the functions.

@ Cpt Hammerbeard

I dont see the difference, but I will try it. Thanks.

@ zooloo75

yes I got advised to do that with the "switch" command, but I havent figured out yet how to implement it, the nature of that command is totally unclear to me.

Share this post


Link to post
Share on other sites

To be honest I'm not sure if there's a difference, just thought I'd throw my 2 cents in. Your switch would look something like below, I think, I'm no expert.

switch (typeOf) do{

case "CUP_O_RUS_Soldier_Marksman":
{

   [_x] execVM "scripts\loadouts\MM.sqf"; 
   foreach  allunits;   
};

case "CUP_O_RUS_SpecOps_Scout":
{

   [_x] execVM "scripts\loadouts\0-4RS.sqf"; 
   foreach  allunits;   
};

};

Share this post


Link to post
Share on other sites
To be honest I'm not sure if there's a difference, just thought I'd throw my 2 cents in. Your switch would look something like below, I think, I'm no expert.

switch (typeOf) do{

case "CUP_O_RUS_Soldier_Marksman":
{

   [_x] execVM "scripts\loadouts\MM.sqf"; 
   foreach  allunits;   
};

case "CUP_O_RUS_SpecOps_Scout":
{

   [_x] execVM "scripts\loadouts\0-4RS.sqf"; 
   foreach  allunits;   
};

};

That shouldn't work, and the code is still looping through the set of AllUnits multiple times when it can only loop once and have the same effect.

Here's what it should look like. Note: I haven't tested this ingame.

_loadoutScript = "";

{
switch(typeOf _x) do
{
	case "CUP_O_RUS_Soldier_Marksman":
	{
		_loadoutScript = "scripts\loadouts\MM.sqf";
	};

	case "CUP_O_RUS_SpecOps_Scout":
	{
		_loadoutScript = "scripts\loadouts\0-4RS.sqf";
	};

	case "CUP_O_RUS_SpecOps":
	{
		_loadoutScript = "scripts\loadouts\1-2RO.sqf";
	};

	case "CUP_O_RUS_Commander":
	{
		_loadoutScript = "scripts\loadouts\1iC.sqf";
	};

	case "CUP_O_RUS_Soldier_TL":
	{
		_loadoutScript = "scripts\loadouts\2iC.sqf";
	};

	case "CUP_O_RUS_Soldier_GL":
	{
		_loadoutScript = "scripts\loadouts\1-2WS.sqf";
	};

	case "CUP_O_RUS_SpecOps_SD":
	{
		_loadoutScript = "scripts\loadouts\1-2DS.sqf";
	};

	default
	{
		_loadoutScript = "";
	};
};

if(_loadoutScript != "") then 
{
	[_x] execVM _loadoutScript;
};
} foreach allUnits;
Edited by zooloo75

Share this post


Link to post
Share on other sites
Ah yes, I see Zooloo75. You don't the forEach nice fix.

He still uses forEach and he still goes through all units. The main difference is that he only checks every unit once.

Just wanted to make that clear, that's a pretty good example of code optimisation.

Share this post


Link to post
Share on other sites

Switch the two lines in your INIT.sqf. You are calling the function before defining it.

Share this post


Link to post
Share on other sites
To be honest I'm not sure if there's a difference, just thought I'd throw my 2 cents in

He is using inline functions and your using file functions, same basic usage, just compiled at different times/in different ways.(reference Zooloo's post below)

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

I prefer file functions myself.

Edited by JShock

Share this post


Link to post
Share on other sites
He is using inline functions and your using file functions, same basic usage, just compiled at different times/in different ways.

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

I prefer file functions myself.

With file functions there is additional file IO to retrieve and read. This can be costly if used frequently and would be better if the functions were precompiled/interpreted as it then would already be in memory and would circumvent file operations.

Share this post


Link to post
Share on other sites
With file functions there is additional file IO to retrieve and read. This can be costly if used frequently and would be better if the functions were precompiled/interpreted as it then would already be in memory and would circumvent file operations.

Fine point, I guess I just like the look and structure of file functions, inline is just messy in my eyes, but in light of performance inline is the way to go.

Share this post


Link to post
Share on other sites
Fine point, I guess I just like the look and structure of file functions, inline is just messy in my eyes, but in light of performance inline is the way to go.

It is possible to move each function to its own file and #include the multiple files into a single "master" file.

ex: function0.sqf, function1.sqf, function2.sqf

each file has its own function, and then there's a "master" file/script:

#include "function0.sqf"

#include "function1.sqf"

#include "function2.sqf"

These preprocessor directives work the same as in C/++, simply concatenating the content of the files into the current file.

This method provides clean separation and better performance.

Share this post


Link to post
Share on other sites
It is possible to move each function to its own file and #include the multiple files into a single "master" file.

ex: function0.sqf, function1.sqf, function2.sqf

each file has its own function, and then there's a "master" file/script:

#include "function0.sqf"

#include "function1.sqf"

#include "function2.sqf"

These preprocessor directives work the same as in C/++, simply concatenating the content of the files into the current file.

This method provides clean separation and better performance.

If you're going to go through all the trouble to do this, you may as well use the functions library and define your scripts in CfgFunctions in description.ext. This comes with the added bonus of preventing function overwriting or rewriting (a security matter). Also, this is a pretty dirty work-around when you consider that there is already an official solution for this

Share this post


Link to post
Share on other sites

Using CfgFunctions also allows you to use that function in a units INIT field without having schedule it with a sleep.

Share this post


Link to post
Share on other sites

First of all, thanks for the great response !

Switch the two lines in your INIT.sqf. You are calling the function before defining it.

I switched it, but there is no change to the better.

------------------

my init.sqf looks like this now:

nul=[] execVM "scripts\functions\functions.sqf";

execVM "scripts\RSFspawn.sqf";

my RSVspawn.sqf looks like this now:

_loadoutScript = "scripts\RSFspawn.sqf";

{
   switch(typeOf _x) do
   {
       case "CUP_O_RUS_Soldier_Marksman":
       {
           _loadoutScript = "scripts\loadouts\MM.sqf";
       };

       case "CUP_O_RUS_SpecOps_Scout":
       {
           _loadoutScript = "scripts\loadouts\0-4RS.sqf";
       };

       case "CUP_O_RUS_SpecOps":
       {
           _loadoutScript = "scripts\loadouts\1-2RO.sqf";
       };

       case "CUP_O_RUS_Commander":
       {
           _loadoutScript = "scripts\loadouts\1iC.sqf";
       };

       case "CUP_O_RUS_Soldier_TL":
       {
           _loadoutScript = "scripts\loadouts\2iC.sqf";
       };

       case "CUP_O_RUS_Soldier_GL":
       {
           _loadoutScript = "scripts\loadouts\1-2WS.sqf";
       };

       case "CUP_O_RUS_SpecOps_SD":
       {
           _loadoutScript = "scripts\loadouts\1-2DS.sqf";
       };

       default
       {
           _loadoutScript = "";
       };
   };

   if(_loadoutScript != "scripts\RSFspawn.sqf") then 
   {
       [_x] execVM _loadoutScript;
   };
} foreach allUnits;  

and my MM.sqf:

//	Marksman

_RSF = _this select 0;

_RSF spawn fnc_removeall;                                              -works
_RSF spawn fnc_RSFgiveUniform;                                      -works
_RSF spawn fnc_RSFgiveMSS;                                          -works
_RSF spawn fnc_RSFgiveWmakS;                                      -works
_RSF spawn fnc_giveitems;                                             -works

_RSF addVest "rhs_6sh92";                                             -does not work
for "_i" from 1 to 7 do {_RSF addItemToVest "CUP_20Rnd_9x39_SP5_VSS_M";};               -does not work

_RSF addBackpack "CUP_B_ACRScout_m95";                     -does not work

_RSF addHeadgear "rhs_beanie_green";                           -does not work
_RSF addGoggles "G_Bandanna_tan";                              -does not work

_RSF addWeapon "CUP_srifle_VSSVintorez";                     -does not work
_RSF addPrimaryWeaponItem "CUP_optic_PSO_1";             -does not work

so the basic outcome in the MM.sqf has not changed yet, is that normal, that only the functions in the script are being executed?

cheers !

Share this post


Link to post
Share on other sites

in my functions.sqf:

// spetsnaz loadout function

fnc_RSFgiveUniform = {
removeUniform _this;
_this forceAddUniform "rhs_uniform_mflora_patchless";
};

fnc_RSFgiveMSS = {
for "_i" from 1 to 8 do {_this addItemToUniform "AGM_Bandage";};
for "_i" from 1 to 3 do {_this addItemToUniform "AGM_Morphine";};
for "_i" from 1 to 2 do {_this addItemToUniform "AGM_Epipen";};
_this addItemToUniform "AGM_EarBuds";
};

fnc_RSFgiveWmaks = {
_this addItemtoUniform "CUP_8Rnd_9x18_MakarovSD_M";
_this addWeapon "CUP_hgun_PB6P9";
for "_i" from 1 to 2 do {_this addItemToUniform "CUP_8Rnd_9x18_MakarovSD_M";};
_this addHandgunItem "CUP_muzzle_PB6P9";
};

fnc_removeall = {
removeAllWeapons _this;
removeAllItems _this;
removeAllAssignedItems _this;
removeVest _this;
removeBackpack _this;
removeHeadgear _this;
removeGoggles _this;
_this unlinkItem "tf_microdagr";
};

fnc_RSFgivegren = {
for "_i" from 1 to 2 do {_this addItemToVest "rhs_mag_rgd5";};
for "_i" from 1 to 2 do {_this addItemToVest "rhs_mag_rdg2_white";};
};

fnc_giveitems = {
_this addweapon "binocular";
_this linkItem "ItemMap";
sleep 1;
_this linkItem "Itemwatch";
};

in my MM.sqf:

//	Marksman

_RSF = _this select 0;

_RSF spawn fnc_removeall;
_RSF spawn fnc_RSFgiveUniform;
_RSF spawn fnc_RSFgiveMSS;
_RSF spawn fnc_RSFgiveWmakS;
_RSF spawn fnc_giveitems;

_RSF addVest "rhs_6sh92";
for "_i" from 1 to 7 do {_RSF addItemToVest "CUP_20Rnd_9x39_SP5_VSS_M";};

_RSF addBackpack "CUP_B_ACRScout_m95";

_RSF addHeadgear "rhs_beanie_green";
_RSF addGoggles "G_Bandanna_tan";

_RSF addWeapon "CUP_srifle_VSSVintorez";
_RSF addPrimaryWeaponItem "CUP_optic_PSO_1";

the error is : undefined variable expression in line 5 of MM.sqf "fnc_removeall".

it execute all the functions as expected, but not the rest of the MM.sqf.

I am sitting for hours on this now, someone please help me on this.

greetz

kOepi

I am not 100% sure but I think it may purely the order in which you add items within the function. I would suggest trying adding the vest and backpack to the unit before you add all the medical supplies, weapons/mags, grenades and items etc. I am not sure as to the amount of items the uniform can carry on its own.

Share this post


Link to post
Share on other sites

@ viper2511

Tried that. doesnt change anything.

----------------------------------------

Somehow I managed to get rid of these errors when I replaced all of the code in the MM.sqf with a function. ( I think it was again some syntax error that came through my notepadd ++ )

looks like script and functions in one file dont work together simultanously.

So now I only want to summarize and simplify the functions.sqf, as you can see in my Test - Test part of functions.sqf.

I bet its just a simple syntax error which I confuse.

my current functions.sqf:

// spetsnaz loadout function

fnc_removeall =
{
removeAllWeapons _this;
removeAllItems _this;
removeAllAssignedItems _this;
removeVest _this;
removeBackpack _this;
removeHeadgear _this;
removeGoggles _this;
_this unlinkItem "tf_microdagr";
};

// Items, Radios

fnc_giveMSRSF =
{
for "_i" from 1 to 8 do {_this addItemToUniform "AGM_Bandage";};
for "_i" from 1 to 3 do {_this addItemToUniform "AGM_Morphine";};
for "_i" from 1 to 2 do {_this addItemToUniform "AGM_Epipen";};
_this addItemToUniform "AGM_EarBuds";
};

fnc_giveitems =
{
_this addweapon "binocular";
_this linkItem "ItemMap";
sleep 1;
_this linkItem "Itemwatch";
};

// Clothing 

fnc_giveUniformRSF =
{
removeUniform _this;
_this forceAddUniform "rhs_uniform_mflora_patchless";
};

fnc_giveVestRSF1 =
{
_this addVest "rhs_6sh92";
// flora, no Armor
};

fnc_giveVestRSF2 =
{
_this addVest "rhs_6sh92_digi_headset";
// EMR-Summer, headset, no Armor
};

fnc_giveVestRSF3 =
{
_this addVest "rhs_6sh92_digi";
// EMR-Summer, no Armor
};

fnc_giveVestRSF4 =
{
_this addVest "rhs_6sh92_headset";
// flora, no Armor
};

//-------------------------------------- TEST -------------------------

fnc_giveVestRSF =
private ["_one","_two","_three","_four"];
{
_one = _this select 0;
_two = _this select 1;
_three = _this select 2;
_four = _this select 3;
	_one = _this addVest "rhs_6sh92";					// flora, no Armor;
	_two =_this addVest "rhs_6sh92_digi_headset";		// EMR-Summer, headset, no Armor;
	_three = _this addVest "rhs_6sh92_digi";			// EMR-Summer, no Armor;
	_four = _this addVest "rhs_6sh92_headset";			// flora, no Armor;
};

//---------------------------------------TEST -------------------------

fnc_giveBPACR =
{
_this addBackpack "CUP_B_ACRScout_m95";
};

fnc_giveCapR1 =
{
_this addheadgear "rhs_fieldcap";
// flora field cap
};

fnc_giveCapR2 =
{
_this addheadgear "rhs_fieldcap";
// EMR-Summer field cap
};

fnc_giveBeanieR =
{
_this addheadgear "rhs_beanie_green";
// EMR-summer Beanie
};

// CLothing - Facewear

fnc_giveBda1 =
{
_this addGoggles "G_Bandanna_tan";
// facemask tan
};

// weapons

fnc_giveWMaks =
{
_this addItemtoUniform "CUP_8Rnd_9x18_MakarovSD_M";
_this addWeapon "CUP_hgun_PB6P9";
for "_i" from 1 to 2 do {_this addItemToUniform "CUP_8Rnd_9x18_MakarovSD_M";};
_this addHandgunItem "CUP_muzzle_PB6P9";
};

fnc_giveWVSS =
{
for "_i" from 1 to 7 do {_this addItemToVest "CUP_20Rnd_9x39_SP5_VSS_M";};
_this addWeapon "CUP_srifle_VSSVintorez";
_this addPrimaryWeaponItem "CUP_optic_PSO_1";
};

fnc_givegrensVR =
{
for "_i" from 1 to 2 do {_this addItemToVest "rhs_mag_rgd5";};
for "_i" from 1 to 2 do {_this addItemToVest "rhs_mag_rdg2_white";};
};

fnc_givegrensBPR =
{
for "_i" from 1 to 2 do {_this addItemToBackpack "rhs_mag_rdg2_white";};
for "_i" from 1 to 2 do {_this addItemToBackpack "rhs_mag_rgd5";};
};

and my 0-4.sqf, which cant call the function and the parameter for the vest correctly:

//	0-4 Recon Specialist Spetsnaz

_RSF = _this select 0;

_RSF spawn fnc_removeall;
_RSF spawn fnc_giveUniformRSF;
_RSF spawn fnc_giveMSRSF;
_RSF spawn fnc_giveitems;

//_RSF spawn fnc_giveBPACR;
//_RSF spawn fnc_giveVestRSF3;
_RSF = [_three] spawn fnc_giveVestRSF;

//_RSF spawn fnc_giveWVSS;
//_RSF spawn fnc_giveWMakS;

...

Share this post


Link to post
Share on other sites

The setup on your vest function is a little off. Use this instead.

// [_RSF,1] spawn fnc_giveVestRSF; -- adds "rhs_6sh92"
// [_unit,3] spawn fnc_giveVestRSF; -- adds "rhs_6sh92_digi"
// 1-4 for different vests - returns true if vest was selected correctly

fnc_giveVestRSF = {
private "_vest";
_vest = switch (_this select 1) do {
	case 1:{"rhs_6sh92"};
	case 2:{"rhs_6sh92_digi_headset"};
	case 3:{"rhs_6sh92_digi"};
	case 4:{"rhs_6sh92_headset"};
	default {""};
};
if (_vest == "") exitWith {false};
(_this select 0) addVest _vest;
true;
};

looks like script and functions in one file dont work together simultanously.

They work great together... its something else.

EDIT: make sure those classnames are right for the vests. The word "headset" in them makes me doubt...

EDIT 2: Changed exitWith to opposite usage... cleaner that way.

Edited by Fight9

Share this post


Link to post
Share on other sites

thank you fight 9 !

I got it running and exactly how I thought it should be.

Another question:

to get rid of the tf_microdagr I use a "sleep 1;" to replace it with a wristwatch. Does that work negative on the performance? should I avoid sleep commands in functions entirely?

Share this post


Link to post
Share on other sites
to get rid of the tf_microdagr I use a "sleep 1;" to replace it with a wristwatch. Does that work negative on the performance? should I avoid sleep commands in functions entirely?

Should be fine, and it depends on context whether a sleep is good or not, but here I don't think it will be an issue. In most cases sleeps can help performance because it slows the code down, but then the issue comes when your trying to do something in a certain timeframe, then sleeps as well as other code performance factors could greatly affect what your trying to accomplish.

Edited by JShock

Share this post


Link to post
Share on other sites

Yeah, there is probably a fancier way to detected when the unit has the DAGR, but the sleep method works well enough...

Also, I changed the vest function above a bit. I didn't like my usage of the exitWith so I changed it to the opposite. It now exits if a vest was not selected correctly instead of exiting with the vest addition. Its just cleaner and easier to read...

Share this post


Link to post
Share on other sites

I got it all running and put out every sleep command.

unfortunately in the editor and on dedicated, like 50 % of the units are not completely executed/equipped.

Do I really have to use sleep ( values between 0.001 s and 0.01 s are taking effect ) to get that working?

well these values are quite high in comparison to one code lenght ( mm.sqf ) with 0.0037 ms.

tweaking with these values in the functions and the loadoutscript itself ...

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
Sign in to follow this  

×