nebulazerz 18 Posted July 25, 2016 I have easter eggs hidden in my game mode im working on, one is a power suit. Right now I have it checking to see if the player picked it up with an inventory closed event handler but I dont always give it to the player by having them pick it up off the ground, any suggestions for a better method to check than this? player addEventHandler ["InventoryClosed", { player removeAllEventHandlers "InventoryClosed"; _powerSuit = "U_B_Soldier_VR"; if (uniform player isequalto _powerSuit) then { [ [], "fnc_bluSuitPowers", player ] call BIS_fnc_MP; }; }]; 1 Share this post Link to post Share on other sites
jshock 513 Posted July 25, 2016 initPlayerLocal.sqf: [ "checkEquippedUniform", "onEachFrame", { if (uniform (_this select 0) isEqualTo "U_B_Soldier_VR") then { [ [], "fnc_bluSuitPowers", player ] call BIS_fnc_MP; }; }, [player] ] call BIS_fnc_addStackedEventHandler; 1 Share this post Link to post Share on other sites
nebulazerz 18 Posted July 26, 2016 initPlayerLocal.sqf: [ "checkEquippedUniform", "onEachFrame", { if (uniform (_this select 0) isEqualTo "U_B_Soldier_VR") then { [ [], "fnc_bluSuitPowers", player ] call BIS_fnc_MP; }; }, [player] ] call BIS_fnc_addStackedEventHandler; oh, thats pretty cool. a stacked event handler. This does work all though, im using this to start up holdaction "skils" and this is repeatedly adding them over and over. is there any way to stop that from happening but still have it check all of the time? remove the event handlers every time? Could this hurt performance because its checking so often or is it easy enough for the game to do that it does not effect it? Edit: like this its hurting performance pretty bad too. Share this post Link to post Share on other sites
theend3r 83 Posted July 26, 2016 You could add a variable to the unit that would be true if it has powers and prevent the handler from adding them again by _unit setVariable ["powers", true, true]; // the last true is to broadcast it in MP I think your original solution is better player addEventHandler ["InventoryClosed", { _powerSuit = "U_B_Soldier_VR"; if (uniform player isequalto _powerSuit) then { if ( !(player getVariable ["powers", false]) ) then { [ [], "fnc_bluSuitPowers", player ] call BIS_fnc_MP; }; player setVariable ["powers", true, true]; } else { player setVariable ["powers", false, true]; }; }]; 1 Share this post Link to post Share on other sites
jshock 513 Posted July 26, 2016 I think your original solution is better That solution only works if the player picks it up and equips it, but the OP stated that is not always the case (implies that the uniform could be applied directly to the player via script). onEachFrame in this case shouldn't cause too much of a performance impact, unless you are adding a whole bunch of onEachFrame stacked event handlers, which is probably the issue here, so try the following, hopefully it works better, if it doesn't I'll need to see where you are actually using and putting the code. if !(player getVariable ["bluSuitPowers_eh",false]) then { [ "checkEquippedUniform", "onEachFrame", { params ["_unit"]; if (uniform _unit isEqualTo "U_B_Soldier_VR") then { [ [], "fnc_bluSuitPowers", _unit ] call BIS_fnc_MP; } else { //remove suit powers }; }, [player] ] call BIS_fnc_addStackedEventHandler; player setVariable ["bluSuitPowers_eh",true]; }; 1 Share this post Link to post Share on other sites
theend3r 83 Posted July 26, 2016 I see we've had the same idea, jshock, although I forgot to remove the powers. Anyway, if the suit is added with a script then the powers can be activated with a script, too. No need to check each frame unless it wouldn't work with virtual arsenal and the OP intends to use it. Still, your solution is more powerful and universal. 1 Share this post Link to post Share on other sites
nebulazerz 18 Posted July 26, 2016 You could add a variable to the unit that would be true if it has powers and prevent the handler from adding them again by _unit setVariable ["powers", true, true]; // the last true is to broadcast it in MP I think your original solution is better player addEventHandler ["InventoryClosed", { _powerSuit = "U_B_Soldier_VR"; if (uniform player isequalto _powerSuit) then { if ( !(player getVariable ["powers", false]) ) then { [ [], "fnc_bluSuitPowers", player ] call BIS_fnc_MP; }; player setVariable ["powers", true, true]; } else { player setVariable ["powers", false, true]; }; }]; Yes, this is working pretty nicely, Its just not removing the powers when I take the suit off for some reason, isnt that what the powers set variable should be doing in the first place. Am I doing this wrong, this is how its set up. when player is given uniform if forceadded player forceAddUniform "U_B_Soldier_VR"; [ [], "fnc_bluSuitPowers", player ] call BIS_fnc_MP; player setVariable ["powers", true, true]; player addEventHandler ["InventoryClosed", { _powerSuit = "U_B_Soldier_VR"; if (uniform player isequalto _powerSuit) then { if ( !(player getVariable ["powers", false]) ) then { [ [], "fnc_bluSuitPowers", player ] call BIS_fnc_MP; }; player setVariable ["powers", true, true]; } else { player setVariable ["powers", false, true]; }; }]; 1 Share this post Link to post Share on other sites
nebulazerz 18 Posted July 26, 2016 That solution only works if the player picks it up and equips it, but the OP stated that is not always the case (implies that the uniform could be applied directly to the player via script). onEachFrame in this case shouldn't cause too much of a performance impact, unless you are adding a whole bunch of onEachFrame stacked event handlers, which is probably the issue here, so try the following, hopefully it works better, if it doesn't I'll need to see where you are actually using and putting the code. if !(player getVariable ["bluSuitPowers_eh",false]) then { [ "checkEquippedUniform", "onEachFrame", { params ["_unit"]; if (uniform _unit isEqualTo "U_B_Soldier_VR") then { [ [], "fnc_bluSuitPowers", _unit ] call BIS_fnc_MP; } else { //remove suit powers }; }, [player] ] call BIS_fnc_addStackedEventHandler; player setVariable ["bluSuitPowers_eh",true]; }; This, strangely is still spawning the abilities an infinite amount of times, heres the suit powers function so you can see what its calling fnc_bluSuitPowers = { [ /* 0 object */ player, /* 1 action title */ "Blink", /* 2 idle icon */ "images\blinkicon.paa", /* 3 progress icon */ "images\blinkicon.paa", /* 4 condition to show */ "true", /* 5 condition for action */ "true", /* 6 code executed on start */ {["Suit", "Preparing Blink"] call BIS_fnc_showSubtitle}, /* 7 code executed per tick */ {hint "Blink Charging"}, /* 8 code executed on completion */ {execVM "blinkJump.sqf"}, /* 9 code executed on interruption */ {hint ""}, /* 10 arguments */ ["Blink"], /* 11 action duration */ 3, /* 12 priority */ 0, /* 13 remove on completion */ false, /* 14 show unconscious */ false ] call bis_fnc_holdActionAdd; [ /* 0 object */ player, /* 1 action title */ "Sprint 1", /* 2 idle icon */ "images\sprinticonA.paa", /* 3 progress icon */ "images\sprinticonA.paa", /* 4 condition to show */ "true", /* 5 condition for action */ "true", /* 6 code executed on start */ {player setAnimSpeedCoef 1.50}, /* 7 code executed per tick */ {player setAnimSpeedCoef 2}, /* 8 code executed on completion */ {player setAnimSpeedCoef 1}, /* 9 code executed on interruption */ {player setAnimSpeedCoef 1}, /* 10 arguments */ ["Sprint"], /* 11 action duration */ 6, /* 12 priority */ 0, /* 13 remove on completion */ false, /* 14 show unconscious */ false ] call bis_fnc_holdActionAdd; [ /* 0 object */ player, /* 1 action title */ "Sprint 2", /* 2 idle icon */ "images\sprinticonB.paa", /* 3 progress icon */ "images\sprinticonB.paa", /* 4 condition to show */ "true", /* 5 condition for action */ "true", /* 6 code executed on start */ {player setAnimSpeedCoef 1.50}, /* 7 code executed per tick */ {player setAnimSpeedCoef 4}, /* 8 code executed on completion */ {player setAnimSpeedCoef 1}, /* 9 code executed on interruption */ {player setAnimSpeedCoef 1}, /* 10 arguments */ ["Sprint"], /* 11 action duration */ 6, /* 12 priority */ 0, /* 13 remove on completion */ false, /* 14 show unconscious */ false ] call bis_fnc_holdActionAdd; [ /* 0 object */ player, /* 1 action title */ "Lightning", /* 2 idle icon */ "images\blinkicon.paa", /* 3 progress icon */ "images\blinkicon.paa", /* 4 condition to show */ "true", /* 5 condition for action */ "true", /* 6 code executed on start */ {["Suit", "Preparing Lightning"] call BIS_fnc_showSubtitle}, /* 7 code executed per tick */ {hint "Lightning Charging"}, /* 8 code executed on completion */ {execVM "strikeLight.sqf"}, /* 9 code executed on interruption */ {hint ""}, /* 10 arguments */ ["Lightning"], /* 11 action duration */ 3, /* 12 priority */ 0, /* 13 remove on completion */ false, /* 14 show unconscious */ false ] call bis_fnc_holdActionAdd; }; 1 Share this post Link to post Share on other sites
jshock 513 Posted July 26, 2016 Realized my stupid mistake (tired as hell atm), try this: if !(player getVariable ["bluSuitPowers_eh",false]) then { [ "checkEquippedUniform", "onEachFrame", { params ["_unit"]; if (uniform _unit isEqualTo "U_B_Soldier_VR") then { if ( !(_unit getVariable ["powers", false]) ) then { [ [], "fnc_bluSuitPowers", _unit ] call BIS_fnc_MP; }; _unit setVariable ["powers", true]; } else { _unit setVariable ["powers", false]; }; }, [player] ] call BIS_fnc_addStackedEventHandler; player setVariable ["bluSuitPowers_eh",true]; }; 1 Share this post Link to post Share on other sites
nebulazerz 18 Posted July 26, 2016 Realized my stupid mistake (tired as hell atm), try this: if !(player getVariable ["bluSuitPowers_eh",false]) then { [ "checkEquippedUniform", "onEachFrame", { params ["_unit"]; if (uniform _unit isEqualTo "U_B_Soldier_VR") then { if ( !(_unit getVariable ["powers", false]) ) then { [ [], "fnc_bluSuitPowers", _unit ] call BIS_fnc_MP; }; _unit setVariable ["powers", true]; } else { _unit setVariable ["powers", false]; }; }, [player] ] call BIS_fnc_addStackedEventHandler; player setVariable ["bluSuitPowers_eh",true]; }; that works much better now, no performance hit and its giving the right amount of abilities. The powers are still there when I take the suit off though. Do I need to add a removeAction to the eventhandler in the else portion to have it work like that? Also, just figured out how to make lightning strike wherever you are looking figured I would share so you guys can have some fun with it because its funny haha :) private ["_strikeTarget","_dummy"]; _strikeTarget = cursorObject; _strikeLoc = (getPos _strikeTarget); if (_strikeLoc isequalto [0,0,0]) then { hint "NO TARGET"; }else{ [_strikeTarget,nil,true] call BIS_fnc_moduleLightning; hint ""; }; 1 Share this post Link to post Share on other sites
jshock 513 Posted July 26, 2016 You need to remove all the actions that your fnc_bluSuitPowers adds add put a call to that above the _unit setVariable ["powers", false]; line. Share this post Link to post Share on other sites
nebulazerz 18 Posted July 26, 2016 You need to remove all the actions that your fnc_bluSuitPowers adds add put a call to that above the _unit setVariable ["powers", false]; line. Is there a way to setVariable an action and use that to remove it? Sequentially removing actions is not going to work in this case. if I start the player with 2 actions then this will work the first time without removing the actions and only removing the powers, but if I take off the suit a second time after picking it up, the powers are still there (probably because they are not the same sequential actions.) removeAllActions Player; would work but it removes the 2 actions that are added at mission load and I might have people start with a few default skills that can be leveled up. Nevermind, ill put the actions that I want loaded all of the time in a function and call it both times, that will fix it. if !(player getVariable ["bluSuitPowers_eh",false]) then { [ "checkEquippedUniform", "onEachFrame", { params ["_unit"]; if (uniform _unit isEqualTo "U_B_Soldier_VR") then { if ( !(_unit getVariable ["powers", false]) ) then { [ [], "fnc_bluSuitPowers", _unit ] call BIS_fnc_MP; }; _unit setVariable ["powers", true]; } else { player removeAction 2; player removeAction 3; player removeAction 4; player removeAction 5; _unit setVariable ["powers", false]; }; }, [player] ] call BIS_fnc_addStackedEventHandler; player setVariable ["bluSuitPowers_eh",true]; }; Share this post Link to post Share on other sites
nebulazerz 18 Posted July 26, 2016 hmm, I have been messing with it quite a bit and I cant seem to get it to remove the powers properly when the suit is off, I have tried a few things like this. It will remove the default abilities if the suit goes on but it will not remove the suit abilities if it goes to 'else' and checks for default actions. Do I have the order of lines wrong? if !(player getVariable ["bluSuitPowers_eh",false]) then { [ "checkEquippedUniform", "onEachFrame", { params ["_unit"]; if (uniform _unit isEqualTo "U_B_Soldier_VR") then { if ( !(_unit getVariable ["powers", false]) ) then { removeAllactions player; [ [], "fnc_bluSuitPowers", _unit ] call BIS_fnc_MP; }; _unit setVariable ["powers", true]; } else { if ( !(_unit getVariable ["defaultActions", false]) ) then { removeAllactions player; [ [], "fn_defaultActions", _unit ] call BIS_fnc_MP; _unit setVariable ["defaultActions", true]; }; _unit setVariable ["powers", false]; }; }, [player] ] call BIS_fnc_addStackedEventHandler; player setVariable ["bluSuitPowers_eh",true]; }; Edit: Also, why does nothing show up after respawning even if I put this in my onPlayerRespawn.sqf and how can I fix that? Share this post Link to post Share on other sites
nebulazerz 18 Posted July 27, 2016 I figured it out! Turns out you can save actions to a variable and removeAction the variable... would be nice if this page even mentions that a tiny bit, i tried it out of curiosity and it works Edit: Well, seems they do mention it here at the bottom, but i was looking to remove actions not add them so it kinda slipped my mind to check the addaction page especially since im using holdaction Edit: I have a new issue, it seems that this eventhandler is not reactivating on respawn. I tried putting it in a function and in onPlayerRespawn.sqf I added [player] call fn_suitPowerEH; but that doesnt work either. Heres what it looks like if !(player getVariable ["bluSuitPowers_eh",false]) then { [ "checkEquippedUniform", "onEachFrame", { params ["_unit"]; if (uniform _unit isEqualTo "U_B_Soldier_VR") then { if ( !(_unit getVariable ["powers", false]) ) then { [ [], "fnc_bluSuitPowers", _unit ] call BIS_fnc_MP; }; _unit setVariable ["powers", true]; } else { _skillA = player getVariable ["skillA",-1]; _skillB = player getVariable ["skillB",-1]; _skillC = player getVariable ["skillC",-1]; _skillD = player getVariable ["skillD",-1]; player removeAction _skillA; player removeAction _skillB; player removeAction _skillC; player removeAction _skillD; _unit setVariable ["powers", false]; }; }, [player] ] call BIS_fnc_addStackedEventHandler; player setVariable ["bluSuitPowers_eh",true]; }; fnc_bluSuitPowers = { _skillA = [ /* 0 object */ player, /* 1 action title */ "Blink", /* 2 idle icon */ "images\blinkicon.paa", /* 3 progress icon */ "images\blinkicon.paa", /* 4 condition to show */ "true", /* 5 condition for action */ "true", /* 6 code executed on start */ {["Suit", "Preparing Blink"] call BIS_fnc_showSubtitle}, /* 7 code executed per tick */ {hint "Blink Charging"}, /* 8 code executed on completion */ {execVM "blinkJump.sqf"}, /* 9 code executed on interruption */ {hint ""}, /* 10 arguments */ ["Blink"], /* 11 action duration */ 3, /* 12 priority */ 0, /* 13 remove on completion */ false, /* 14 show unconscious */ false ] call bis_fnc_holdActionAdd; _skillB = [ /* 0 object */ player, /* 1 action title */ "Sprint 1", /* 2 idle icon */ "images\sprinticonA.paa", /* 3 progress icon */ "images\sprinticonA.paa", /* 4 condition to show */ "true", /* 5 condition for action */ "true", /* 6 code executed on start */ {player setAnimSpeedCoef 1.50}, /* 7 code executed per tick */ {player setAnimSpeedCoef 2}, /* 8 code executed on completion */ {player setAnimSpeedCoef 1}, /* 9 code executed on interruption */ {player setAnimSpeedCoef 1}, /* 10 arguments */ ["Sprint"], /* 11 action duration */ 6, /* 12 priority */ 0, /* 13 remove on completion */ false, /* 14 show unconscious */ false ] call bis_fnc_holdActionAdd; _skillC = [ /* 0 object */ player, /* 1 action title */ "Sprint 2", /* 2 idle icon */ "images\sprinticonB.paa", /* 3 progress icon */ "images\sprinticonB.paa", /* 4 condition to show */ "true", /* 5 condition for action */ "true", /* 6 code executed on start */ {player setAnimSpeedCoef 1.50}, /* 7 code executed per tick */ {player setAnimSpeedCoef 4}, /* 8 code executed on completion */ {player setAnimSpeedCoef 1}, /* 9 code executed on interruption */ {player setAnimSpeedCoef 1}, /* 10 arguments */ ["Sprint"], /* 11 action duration */ 6, /* 12 priority */ 0, /* 13 remove on completion */ false, /* 14 show unconscious */ false ] call bis_fnc_holdActionAdd; _skillD = [ /* 0 object */ player, /* 1 action title */ "Lightning", /* 2 idle icon */ "images\blinkicon.paa", /* 3 progress icon */ "images\blinkicon.paa", /* 4 condition to show */ "true", /* 5 condition for action */ "true", /* 6 code executed on start */ {["Suit", "Preparing Lightning"] call BIS_fnc_showSubtitle}, /* 7 code executed per tick */ {hint "Lightning Charging"}, /* 8 code executed on completion */ {execVM "strikeLight.sqf"}, /* 9 code executed on interruption */ {hint ""}, /* 10 arguments */ ["Lightning"], /* 11 action duration */ 3, /* 12 priority */ 0, /* 13 remove on completion */ false, /* 14 show unconscious */ false ] call bis_fnc_holdActionAdd; player setVariable ["skillA", _skillA]; player setVariable ["skillB", _skillB]; player setVariable ["skillC", _skillC]; player setVariable ["skillD", _skillD]; }; Share this post Link to post Share on other sites