kOepi 10 Posted March 8, 2015 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
fight9 14 Posted March 8, 2015 Where are you calling MM.sqf? Share this post Link to post Share on other sites
R3vo 2654 Posted March 8, 2015 (edited) I am maybe completely off here but don't you also need to add [] infront of the spawn? Like: [_RSF] spawn fnc_removeall; Edited March 8, 2015 by R3vo Share this post Link to post Share on other sites
cpthammerbeard 10 Posted March 8, 2015 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
zooloo75 834 Posted March 8, 2015 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
kOepi 10 Posted March 8, 2015 @ 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
cpthammerbeard 10 Posted March 8, 2015 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
zooloo75 834 Posted March 8, 2015 (edited) 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 March 8, 2015 by zooloo75 Share this post Link to post Share on other sites
cpthammerbeard 10 Posted March 8, 2015 Ah yes, I see Zooloo75. You don't the forEach nice fix. Share this post Link to post Share on other sites
R3vo 2654 Posted March 8, 2015 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
fight9 14 Posted March 8, 2015 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
jshock 513 Posted March 8, 2015 (edited) 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 March 8, 2015 by JShock Share this post Link to post Share on other sites
zooloo75 834 Posted March 8, 2015 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
jshock 513 Posted March 8, 2015 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
zooloo75 834 Posted March 8, 2015 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
dreadedentity 278 Posted March 9, 2015 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
fight9 14 Posted March 9, 2015 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
kOepi 10 Posted March 9, 2015 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
viper2511 28 Posted March 9, 2015 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
kOepi 10 Posted March 9, 2015 @ 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
fight9 14 Posted March 9, 2015 (edited) 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 March 10, 2015 by Fight9 Share this post Link to post Share on other sites
kOepi 10 Posted March 10, 2015 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
jshock 513 Posted March 10, 2015 (edited) 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 March 10, 2015 by JShock Share this post Link to post Share on other sites
fight9 14 Posted March 10, 2015 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
kOepi 10 Posted March 10, 2015 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