Dj Rolnik 29 Posted March 9, 2019 Hey guys, I would like to add for my players the ability to use an action which would only appear to them if they met a specific criteria. The criteria is to have a specific backpack and inside it, a specific item. I got the script responsible for the condition working, but only once I put it in the init.sqf. If I did it that way, the action would appear and remain available even after the condition was no longer fulfilled (the object being dropped for example). Naturally, I'd like to remove the action if the condition was no longer met. I basically do not know how to check for the condition so that it always pops up for the player once he meets that criteria. This is the script that I don't know how to call: if ((unitBackpack Player isKindof "tfw_ilbe_a_gr") && ("tfw_rf3080Item" in (items player + assignedItems player))) then {Player addAction ["Test Action", "test_action.sqf"];} Thanks! Share this post Link to post Share on other sites
cb65 86 Posted March 9, 2019 6 hours ago, Dj Rolnik said: I would like to add for my players the ability to use an action which would only appear to them if they met a specific criteria. The criteria is to have a specific backpack and inside it, a specific item. I got the script responsible for the condition working, but only once I put it in the init.sqf. If I did it that way, the action would appear and remain available even after the condition was no longer fulfilled (the object being dropped for example). Naturally, I'd like to remove the action if the condition was no longer met. Hello Dj Rolnik, This should do the trick. Just add it to your missions init.sqf. player addAction ["Test Action","test_action.sqf",[],-1,false,true,"","((unitBackpack _this isKindof 'tfw_ilbe_a_gr') && ('tfw_rf3080Item' in (items _this + assignedItems _this)))"]; The action will appear for the player each time the condition is met and disappear when its not. Cheers. 2 Share this post Link to post Share on other sites
NumbNutsJunior 67 Posted March 9, 2019 https://community.bistudio.com/wiki/addAction Share this post Link to post Share on other sites
Dj Rolnik 29 Posted March 9, 2019 Yep, it did work just as expected. Dropping an object removes the action and adding it back in brings the action back. Thank a lot @cb65! Share this post Link to post Share on other sites
killzone_kid 1333 Posted March 9, 2019 You should add check with Take and Put EHs and hide/reveal or add/remove action. What you have now is a waste of CPU going through backpack inventory every frame, makes me cringe 2 Share this post Link to post Share on other sites
Maff 251 Posted March 9, 2019 (edited) Would this be a better method? Do not use - It will add the action every time you put or take from for an inventory! 🤪 Spoiler /* Do initial check for specific kit - After kit assignment. Put/Take will only fire if you put or take from container, right? */ if ((backpack player isKindof 'tfw_ilbe_a_gr') && ('tfw_rf3080Item' in (items player + assignedItems player))) then { player addAction [ "Test Action", "test_action.sqf", [], 1.5, true, true, "", "true", 50, false, "", "" ]; }; /* Is if then else necessary in the Event Handlers? if ( hasSpecificKit ) then { AddTheAction } else {}; */ player addEventHandler ["Put", { params ["_unit", "_container", "_item"]; if ((backpack _unit isKindof "tfw_ilbe_a_gr") && {"tfw_rf3080Item" in (items _unit + assignedItems _unit)}) then { player addAction [ "Test Action", "test_action.sqf", [], 1.5, true, true, "", "true", 50, false, "", "" ]; }; } ]; player addEventHandler ["Take", { params ["_unit", "_container", "_item"]; if ((backpack _unit isKindof "tfw_ilbe_a_gr") && {"tfw_rf3080Item" in (items _unit + assignedItems _unit)}) then { player addAction [ "Test Action", "test_action.sqf", [], 1.5, true, true, "", "true", 50, false, "", "" ]; }; } ]; Edited March 10, 2019 by Maff Warning: Crap script! 1 Share this post Link to post Share on other sites
cb65 86 Posted March 10, 2019 17 hours ago, Dj Rolnik said: Yep, it did work just as expected. Dropping an object removes the action and adding it back in brings the action back. Thank a lot @cb65! Sorry for wasting your time with my solution Dj Rolnik. Even though it works, killzone_kid and Maff solution is the way to do it mate. Cheers. Share this post Link to post Share on other sites
Maff 251 Posted March 10, 2019 2 minutes ago, cb65 said: Sorry for wasting your time with my solution Dj Rolnik. Even though it works killzone_kid and Maff solution is the way to do it mate. Cheers. @cb65, I looked at my attempt a few hours later and "instantly" saw that it would not work. Serves me right for not testing! Share this post Link to post Share on other sites
Maff 251 Posted March 10, 2019 Another approach... Better than my last attempt anyway. Spoiler /* Create the action. Surely checking a variable is better than checking backpack and items? */ player addAction [ "Test Action", "test_action.sqf", [], 1.5, true, true, "", "player getVariable 'ABC_hasSpecificKit'", 50, false, "", "" ]; /* Quick check after kit assignment as Put/Take EH will only fire if you put or take from container. */ if ((backpack player isKindof "tfw_ilbe_a_gr") && ("tfw_rf3080Item" in (items player + assignedItems player))) then { player setVariable ['ABC_hasSpecificKit', true]; }; /* Create the Event Handlers Put and Take. Detects if player has the specific backpack and item when adding or removing kit from inventories. Would it be worth adding a condition that (player getVariable 'ABC_hasSpecificKit' != false)? */ player addEventHandler ["Put", { params ["_unit", "_container", "_item"]; if ((backpack _unit isKindof "tfw_ilbe_a_gr") && {"tfw_rf3080Item" in (items _unit + assignedItems _unit)}) then { player setVariable ['ABC_hasSpecificKit', true]; } else { player setVariable ['ABC_hasSpecificKit', false]; }; } ]; player addEventHandler ["Take", { params ["_unit", "_container", "_item"]; if ((backpack _unit isKindof "tfw_ilbe_a_gr") && {"tfw_rf3080Item" in (items _unit + assignedItems _unit)}) then { player setVariable ['ABC_hasSpecificKit', true]; } else { player setVariable ['ABC_hasSpecificKit', false]; }; } ]; Share this post Link to post Share on other sites
Grumpy Old Man 3549 Posted March 10, 2019 7 hours ago, Maff said: Another approach... Better than my last attempt anyway. Hide contents /* Create the action. Surely checking a variable is better than checking backpack and items? */ player addAction [ "Test Action", "test_action.sqf", [], 1.5, true, true, "", "player getVariable 'ABC_hasSpecificKit'", 50, false, "", "" ]; /* Quick check after kit assignment as Put/Take EH will only fire if you put or take from container. */ if ((backpack player isKindof "tfw_ilbe_a_gr") && ("tfw_rf3080Item" in (items player + assignedItems player))) then { player setVariable ['ABC_hasSpecificKit', true]; }; /* Create the Event Handlers Put and Take. Detects if player has the specific backpack and item when adding or removing kit from inventories. Would it be worth adding a condition that (player getVariable 'ABC_hasSpecificKit' != false)? */ player addEventHandler ["Put", { params ["_unit", "_container", "_item"]; if ((backpack _unit isKindof "tfw_ilbe_a_gr") && {"tfw_rf3080Item" in (items _unit + assignedItems _unit)}) then { player setVariable ['ABC_hasSpecificKit', true]; } else { player setVariable ['ABC_hasSpecificKit', false]; }; } ]; player addEventHandler ["Take", { params ["_unit", "_container", "_item"]; if ((backpack _unit isKindof "tfw_ilbe_a_gr") && {"tfw_rf3080Item" in (items _unit + assignedItems _unit)}) then { player setVariable ['ABC_hasSpecificKit', true]; } else { player setVariable ['ABC_hasSpecificKit', false]; }; } ]; Those if then else statements are redundant, since you already check the (binary) outcome in the if condition, you can simply use it as the setVariable value. You can condense it down to this: player addEventHandler ["Put", { params ["_unit", "_container", "_item"]; _unit setVariable ['ABC_hasSpecificKit', (backpack _unit isKindof "tfw_ilbe_a_gr") && {"tfw_rf3080Item" in (items _unit + assignedItems _unit)}]; } ]; player addEventHandler ["Take", { params ["_unit", "_container", "_item"]; _unit setVariable ['ABC_hasSpecificKit', (backpack _unit isKindof "tfw_ilbe_a_gr") && {"tfw_rf3080Item" in (items _unit + assignedItems _unit)}]; } ]; Cheers 2 Share this post Link to post Share on other sites
Dedmen 2721 Posted March 12, 2019 I see tfw_ilbe radios in there. From that I assume you have CBA. Meaning you also have CBA's inventory changed eventhandlers. You can just set a global variable "HasRequiredItems" and update it everytime the inventory changed eventhandler fires. That would turn the Put/Take eventhandlers into one single EH. Share this post Link to post Share on other sites
Dj Rolnik 29 Posted March 12, 2019 Thanks a lot for your suggestions guys! I actually did not think about the performance aspect of the script, you're right. I will try to digest your suggestions and come back with the results probably in the next few days. Unfortunately I lack some thorough scripting knowledge so I do struggle with event handlers and most importantly where to call all those scripts from, but I will try to solve it. I really appreciate the feedback. Thanks! Share this post Link to post Share on other sites