Godis_1 63 Posted October 5, 2017 Hi, I'm facing a little problem. I added a killcounter to my mission. It's working well, and I simply want to reset it when it reaches a specific amount. But I'm not sure what's the most efficient method. Spawn a while {true} do loop? Use a WaitUntil condition loop? I just don't know what's the most performance efficient method. When i.e. spawning a thread including a sleep command it shouldn't run too often, right? On the other hand, when running a while do loop in a non-sheduled environment it's limited to 10000 - well, I have no idea what that actually means! :) Might not be necessary. And a WaitUntil loop will exit when the condition is met, so it would have to be restarted. What's the best way? Thx Oh, and could someone explain me this. I wrote this - and no matter if it works or not, I need to understand it better: // Example while {true} do { if (_eosKills >= 75) then { HINTC "You've killed %1",_eosKills,". Counter reset"; // Update the amount of killed civillians to "0" - make them happy again! _gdskills= 0; server setvariable ["GDSKillcounter",_gdskills,true]; // Reset the amount of killed Al-Nusra Fighters _eosKills= 0; server setvariable ["EOSkillCounter",_eosKills,true]; }; sleep 0.5; // Now I need to jump back to script start - does that work? }; WOuld this work? I don't fully understand the While do loop. What actually defines the "true" condition? And would it be right to spawn the script via init.sqf? Or call it? EDIT: Ok, that does not work! :D I tried something else which could be better for overall performance. I included a check into the eventhandler which fires the counter. But for a unknown reason it just caused the counter to act very weird! The following is the code from the script executed by the eventhandler: if (isnil "_eosKills") then {_eosKills=0;}else{ _eosKills=server getvariable "EOSkillCounter"; }; _eosKills=_eosKills + 1; server setvariable ["EOSkillCounter",_eosKills,true]; // Add 0.5 CP for each killed Nusra Fighter! commandpointsblu1 = commandpointsblu1 + 0.5; publicVariable "commandpointsblu1"; if (_eoskills >= 75) then { HINTC ["Counter reset!"]; _eoskills = 0; server setvariable ["EOSkillCounter",_eosKills,true]; }; But then I noticed after this condition is met (_eoskills >= 75) I suddenly get a amount of, i.e. "_eoskills = 516" or sth like that. I really don't know how it could reach that number! Thx anyone Share this post Link to post Share on other sites
7erra 629 Posted October 5, 2017 (edited) Well if you are using an eventhandler (which one exactly? How do you apply it?) you don't need a while-true-loop since EH are way more performance friendly. // use the alternate syntax for getVariable instead: _eosKills = server getVariable ["EOSkillCounter",0]; // if the variable doesn't exist then 0 will be taken _eosKills = _eosKills + 1; server setvariable ["EOSkillCounter",_eosKills,true]; // Add 0.5 CP for each killed Nusra Fighter! commandpointsblu1 = commandpointsblu1 + 0.5; publicVariable "commandpointsblu1"; if (_eosKills >= 75) then { HINTC ["Counter reset!"]; // HintC is local. Depending on where and how you assigned the EH this will only fire on the local pc server setvariable ["EOSkillCounter",0,true]; }; Personally I had some locality issues with setting a variable before so I don't use them. If you are running this script on the server only then global variables will be sufficient and you can instead use remoteExec to execute commands that should fire on other PCs. With this method you might actually save a bit of bandwith since publicVariable broadcasts the variable over the network everytime. The whole locality thing is one huge topic that needs some getting used to. About understanding your code better: while {true} do { // The condition is defined in the brackets. Expression has to return true or false. True means that the code will run the entire mission unless an exitWith statement is placed inside of the code. if (_eosKills >= 75) then { HINTC ["You've killed %1",_eosKills,". Counter reset"]; // Wrong syntax: Missing brackets, see hintC on the BIKI // Update the amount of killed civillians to "0" - make them happy again! _gdskills= 0; // Not wrong but a bit redundant. server setvariable ["GDSKillcounter",_gdskills,true]; // Every new variable takes a bit of performance // Reset the amount of killed Al-Nusra Fighters _eosKills= 0; // See above server setvariable ["EOSkillCounter",_eosKills,true]; // " " }; sleep 0.5; // Now I need to jump back to script start - does that work? // Yes this will check the if statement every .5 seconds. The condition of the while loop will also be checked right here }; Edited October 5, 2017 by 7erra Code explanation added 1 Share this post Link to post Share on other sites
Godis_1 63 Posted October 5, 2017 Ok, thx. The alternate getVariable syntax helps me with another issue. The eventhandler is attached on each soawned unit, like this: .... if (EOS_KILLCOUNTER) then {_unit addEventHandler ["killed", "null=[] execVM ""eos\functions\EOS_KillCounter.sqf"""]}; } forEach (units _grp); And yes, the HINTC is supposed to be local - but actually it's better to inform all players because it affects the whole mission when it happens. But besides the HINT my check seems not working for a reason. The EH fires the EOS_KillCounter.sqf script on each killed enemy unit, right? So it should run through the whole check each time it's executed, and when the condition is met (_eoskills >= 75) it should set the counter back to 0. Right? But it doesn't seem to work. I saw I forgot something: Again, the whole killcounter script with your changes: private ["_eosKills"]; // usef the alternate syntax for getVariable _eosKills = server getVariable ["EOSkillCounter",0]; _eosKills = _eosKills + 1; server setvariable ["EOSkillCounter",_eosKills,true]; // Add 0.5 CP for each killed Nusra Fighter! commandpointsblu1 = commandpointsblu1 + 0.5; publicVariable "commandpointsblu1"; if (_eosKills >= 75) then { HINT ["Counter reset!"]; // _eosKills = 0; // Is this redundant now because of: "...,0, TRUE ];" ? server setvariable ["EOSkillCounter",0,true]; }; I guess with this kind of declaration I can leave out "private [_"eosKills"]; " ? well, I didn't think about the declaration of a private variable here! I guess that might be the culprit. Share this post Link to post Share on other sites
Godis_1 63 Posted October 5, 2017 Never mind. I got it! I confused it with another variable and there I know hwo to fix it! :D Share this post Link to post Share on other sites
7erra 629 Posted October 5, 2017 14 minutes ago, Godis_1 said: The eventhandler is attached on each soawned unit, like this: I guess that the script is executed on the server therefore you can run all other commands on the server only too. 16 minutes ago, Godis_1 said: HINTC is supposed to be local - but actually it's better to inform all players Use this: ["You've killed %1",_eosKills,". Counter reset"] remoteExec ["hintC", [0,-2] select isDedicated]; Look at the syntax for remoteExec. select can also take true and false as parameter, so if it is a dedicated server then the hint will only be shown to people with interface. 19 minutes ago, Godis_1 said: The EH fires the EOS_KillCounter.sqf script on each killed enemy unit, right? So it should run through the whole check each time it's executed, and when the condition is met (_eoskills >= 75) it should set the counter back to 0. Right? That's right. The script will be executed where unit is local (server, I guess). There's no need for a public variable then. What exactly is server in your script? _eosKills = _eosKills + 1; server setvariable ["EOSkillCounter",_eosKills,true]; Remove the true from the array since it is unnecessary network traffic. As far as this script goes the variable is only needed on the server. Correct me if i'm wrong. 24 minutes ago, Godis_1 said: I guess with this kind of declaration I can leave out "private [_"eosKills"]; " ? That's right. I never use private I just define the variables beforehand. Another smooth trick is to do this: _myVar = if (_condition) then {_valueTrue} else {_valueFalse}; Same goes for switch-do: _myVar = switch _value do { case _value1: {_result1}; case _value2: {_result2}; case _value3: {_result3}; default {_defaultResult}; }; 30 minutes ago, Godis_1 said: // _eosKills = 0; // Is this redundant now because of: "...,0, TRUE ];" ? Yes. Declaring a variable to only use it once or if it is short (one digit) is not wrong but not good practice. But that's your taste. Keep in mind that longer script will also take up more performance which is the case here. 1 Share this post Link to post Share on other sites
Godis_1 63 Posted October 5, 2017 Very nice explanation! Thank you very much! Right before your post I figured that I confused something - so many variables..lol - but your post really helps me out with overall SQF stuff! Thx :) Share this post Link to post Share on other sites