L.Trale 10 Posted September 11, 2016 Hello, I'm trying to make a script that uses multiple if then else statements, but for some reason it won't change a variable. (Messy code, sorry, still using notepad :D ) //Inventory Slot 1. _Item = nearestObject [player, "Thing"]; if ((HandInUse) && (BeltSlot1 == "isEmpty") && (_Item isKindOf "Land_Hammer_F")) then { //HandInUse is a bool variable on the player, BeltSlot1 is a string on the player _Item setVariable ["_isInCargo", true]; //_isInCargo is a bool variable on the object, same with below. _Item setVariable ["_InHand", false]; BeltSlot1 = typeOf ItemInHand; //Setting the value of BeltSlot1 to the detected item in players hand. ItemInHand is on the player player playMove "AmovPercMstpSrasWpstDnon_AmovPercMstpSnonWnonDnon"; sleep 0.9; Tool = 0; //Located on player HandInUse = false; sleep 0.1; _Item attachTo [player, [0.2,0,0], "Pelvis"]; exit; } else { if ((HandInUse) && (BeltSlot1 == "isEmpty") && (_Item isKindOf "Land_Axe_F")) then { //If its not hammer time, check if its a saw _Item setVariable ["_isInCargo", true]; _Item setVariable ["_InHand", false]; BeltSlot1 = typeOf ItemInHand; player playMove "AmovPercMstpSrasWpstDnon_AmovPercMstpSnonWnonDnon"; sleep 0.9; Tool = 0; HandInUse = false; sleep 0.1; _Item attachTo [player, [0.2,0,0], "Pelvis"]; exit; } else { if ((!HandInUse) && (BeltSlot1 == "Land_Hammer_F") && (_Item isKindOf "Land_Hammer_F")) then { //If you've got an item on your belt, take it into your hands _Item setVariable ["_isInCargo", false]; _Item setVariable ["_InHand", true]; BeltSlot1 = "isEmpty"; HandInUse = true; //Where it goes south. Won't change this to true for some reason? player playMove "AmovPercMstpSrasWpstDnon_AmovPercMstpSnonWnonDnon"; sleep 0.9; Tool = 1; sleep 0.1; _Item attachTo [player, [0,0,0], "righthandmiddle1"]; exit; } else { if ((!HandInUse) && (BeltSlot1 == "Land_Saw_F") && (_Item isKindOf "Land_Saw_F")) then { //same as above, except for Saw _Item setVariable ["_isInCargo", false]; _Item setVariable ["_InHand", true]; BeltSlot1 = "isEmpty"; HandInUse = true; player playMove "AmovPercMstpSrasWpstDnon_AmovPercMstpSnonWnonDnon"; sleep 0.9; Tool = 3; sleep 0.1; _Item attachTo [player, [0,0,0], "righthandmiddle1"]; exit; }; }; }; }; I know the code isn't very efficient, I'm just experimenting for the most part. The problem is that everything else works except for changing the "HandInUse" variable. Any ideas on whats going on? Update: I've neatened up the code a little bit to make it a little bit less of an eye sore and changed some things around, but still have the same result. I'm calling this from the init, when the player presses the 1 key (shown below). waituntil {!isnull (finddisplay 46)}; (findDisplay 46) displayAddEventHandler ["KeyDown","_this select 1 call MY_KEYDOWN_FNC;false;"]; MY_KEYDOWN_FNC = { switch (_this) do { //Key 1 case 2: { nul = [] execVM "Mechanics\Inventory\Belt_Slot1.sqf"; }; }; }; Updated Code: //File: Belt_Slot1.sqf //Desc: Action for putting item on tool belt. _Item = nearestObject [player, "Thing"]; if ((HandInUse) && (BeltSlot1 == "isEmpty")) then { if (_Item isKindOf "Land_Hammer_F") then { _Item setVariable ["_isInCargo", true]; _Item setVariable ["_InHand", false]; BeltSlot1 = typeOf ItemInHand; player playMove "AmovPercMstpSrasWpstDnon_AmovPercMstpSnonWnonDnon"; sleep 0.9; Tool = 0; HandInUse = false; sleep 0.1; _Item attachTo [player, [0.2,0,0], "Pelvis"]; } else { if (_Item isKindOf "Land_Axe_F") then { _Item setVariable ["_isInCargo", true]; _Item setVariable ["_InHand", false]; BeltSlot1 = typeOf ItemInHand; player playMove "AmovPercMstpSrasWpstDnon_AmovPercMstpSnonWnonDnon"; sleep 0.9; Tool = 0; HandInUse = false; sleep 0.1; _Item attachTo [player, [0.2,0,0], "Pelvis"]; }; }; } else { if ((!HandInUse) && (BeltSlot1 == "Land_Hammer_F")) then { _Item setVariable ["_isInCargo", false]; _Item setVariable ["_InHand", true]; BeltSlot1 = "isEmpty"; HandInUse = true; player playMove "AmovPercMstpSrasWpstDnon_AmovPercMstpSnonWnonDnon"; sleep 0.9; Tool = 1; sleep 0.1; _Item attachTo [player, [0,0,0], "righthandmiddle1"]; } else { if ((!HandInUse) && (BeltSlot1 == "Land_Saw_F") && (_Item isKindOf "Land_Saw_F")) then { _Item setVariable ["_isInCargo", false]; _Item setVariable ["_InHand", true]; BeltSlot1 = "isEmpty"; HandInUse = true; player playMove "AmovPercMstpSrasWpstDnon_AmovPercMstpSnonWnonDnon"; sleep 0.9; Tool = 3; sleep 0.1; _Item attachTo [player, [0,0,0], "righthandmiddle1"]; }; }; }; Share this post Link to post Share on other sites
f2k sel 164 Posted September 12, 2016 I would take a serious look at switch case commads as it's easier to read for this sort of stuff. I did try it but couldn't get very far as I can't seem to set it up correctly and a bit short of time. Are the type of objects correct, "Land_Saw_F" seems to appear right at the end. Share this post Link to post Share on other sites
L.Trale 10 Posted September 12, 2016 I would take a serious look at switch case commads as it's easier to read for this sort of stuff. I did try it but couldn't get very far as I can't seem to set it up correctly and a bit short of time. Are the type of objects correct, "Land_Saw_F" seems to appear right at the end. I did look into switch case, but It gives the same results. The objects are correct, the saw part is to check if the item the player has in their hands is a saw. I'm trying to get it to check in this order: 1. Does the player have an item in their hands and the belt slot is empty? Yes (go to 1a), No (go to 2) 1a. Does the player have a Hammer in their hands? Yes (Put item in belt), No (go to 1b) 1b. Does the player have a Saw in their hands? Yes (Put item in belt) 2. Does the player have no item in their hand and a Hammer in their belt? Yes (Take the item out of belt and into hand), No (go to 2a) 2a. Does the player have no item in their hand and a Saw in their belt? Yes (Take the item out of belt and into hand) Share this post Link to post Share on other sites
HazJ 1289 Posted September 12, 2016 I'd recommend using exitWith instead of the old OFP exit command as I think it was for SQS but might still work with SQF. https://community.bistudio.com/wiki/exitWith To simply just exit, just do: if (true) exitWith {}; Edit: Ah, just noticed the updated code part. My bad. Edit 2: Going through your code now, will update this shortly. Share this post Link to post Share on other sites
HazJ 1289 Posted September 12, 2016 Not tested it, hope it's okay and does what you need. I've tried to comment some parts for you. Also, add this in your init.sqf or somewhere... I usually use CfgFunctions but for now, this will do: /* File: fn_Belt_Slot.sqf Author: L.Trale Description: Action for putting item on tool belt Parameter(s): OBJECT - Unit that you want to check Return(s): 0: BOOL - TRUE if the unit has something in it's hand, and FALSE if not 1: ARRAY - Retruns an array of items in the unit's slot belt, or [] if it's empty */ private ["_Unit", "_In_Hand", "_Slot_Items", "_Item"]; params [ ["_Unit", player] ]; if (isNil {player getVariable "Item_In_Hand"}) then { _Unit setVariable ["Item_In_Hand", [false, ""], true]; }; if (isNil {player getVariable "Belt_Slot_Items"}) then { _Unit setVariable ["Belt_Slot_Items", [], true]; }; _In_Hand = _Unit getVariable "Item_In_Hand"; // Returns the value of the variable on the unit _Slot_Items = _Unit getVariable "Belt_Slot_Items"; _Item = nearestObject [_Unit, "Thing"]; // Returns the nearest object with the classname passed from parameter 1 if (isNil {_Item getVariable "Item_In_Use"}) then { _Item setVariable ["Item_In_Use", false, true]; }; _In_Use = _Item getVariable "Item_In_Use"; // Added incase you ever need to check in the item is in use if ((_In_Hand select 0)) exitWith {}; if (typeOf _Item == "") exitWith {}; // Just incase nearestObject if fails :P if (count _Slot_Items > 5) exitWith {}; // You can make less exitWith by merging them and using the || (OR) command but I just wanted to show you what's what, etc... // Feel free to comment out or remove the above line, added it just incase you ever needed to check item count switch (typeOf _Item) do { case "Land_Hammer_F" : { _Unit playMoveNow "AmovPercMstpSrasWpstDnon_AmovPercMstpSnonWnonDnon"; // Replaced playMove with playMoveNow - https://community.bistudio.com/wiki/playMoveNow _Unit setVariable ["Item_In_Hand", false, true]; // Sets the variable to the given value, on the unit - I'm not sure if public parameter is needed in this case, I know it's not needed but I added it so you can check if for returned BOOL on another unit's machine, however I'm not sure you need this for that... Maybe something can let me know xD _Item setVariable ["Item_In_Use", true, true]; _Item attachTo [_Unit, [0.2, 0, 0], "Pelvis"]; }; case "Item" : { // Code }; case "Item" : { // Code }; case "Item" : { // Code }; case "Item" : { // Code }; case "Item" : { // Code }; case "Item" : { // Code }; }; [_In_Hand, _Slot_Items] LT_fnc_Belt_Slot = compile preprocessFileLineNumbers "fn_Belt_Slot.sqf"; To use it, just do: [player] call LT_fnc_Belt_Slot; Read the header section in the file too! You can check what it returns by: _Return = [player] call LT_fnc_Belt_Slot; if (!(_Return select 0)) then { // If there is NO item in hand then do code... // Blah... }; if ((_Slot_Items select 1) == "Land_Hammer_F") then { // If second belt slot item is hammer then do code... // Blah... }; Share this post Link to post Share on other sites
Tajin 349 Posted September 12, 2016 I would rethink your variables. You have "handInUse" as a boolean and you store the item on your belt in a variable, yet for some reason you don't store the item in hand in a variable. That would make things easier, especially since you don't have to rely on nearestObject. Personally I would just use these: "HandItem" "BeltSlot1" Way I see it you wouldn't even have to differentiate between the tooltypes in that code. Just make a universal function for putting items from belt to hand and the other way around. Furthermore, don't use global variables for playerspecific information. Objectspace is more useful and gives you better options for server/client interaction. Here is what I would do: beltSlots = [ ["BeltSlot1",[0.2,0,0],"Pelvis"], ["BeltSlot2",[-0.2,0,0],"Pelvis"] ]; fnc_useBelt = { param ["_unit","_slotnum"]; private ["_slot","_slotname","_slotpos","_slotpoint","_beltItem","_handItem","_beltitem","_InHand","_isInCargo"]; _slot = beltSlots select _slotnum; _slotname = _slot select 0; _slotpos = _slot select 1; _slotpoint = _slot select 2; _beltItem = _unit getVariable [_slotname,objNull]; _handItem = _unit getVariable ["handItem",objNull]; if (isNull _handItem) then { // empty hand -> try to grab item from belt if (isNull _beltItem) then { _unit setVariable ["tool", "", true]; "no Item in that slot." } else { _unit setVariable ["handItem", _beltItem, true]; _unit setVariable [_slotname, objNull, true]; _unit setVariable ["tool", typeOf _beltitem, true]; _beltitem setVariable ["_InHand", true, true]; _beltitem setVariable ["_isInCargo", false, true]; [_unit,"AmovPercMstpSrasWpstDnon_AmovPercMstpSnonWnonDnon"] remoteExec ["playMove", 0, false]; sleep 1; _beltItem attachTo [_unit, [0,0,0], "righthandmiddle1"]; "took item from " + _slotname }; } else { // item in hand -> check belt if (isNull _beltItem) then { _unit setVariable ["handItem", objNull, true]; _unit setVariable [_slotname, _handItem, true]; _unit setVariable ["tool", "", true]; _handItem setVariable ["_InHand", false, true]; _handItem setVariable ["_isInCargo", true, true]; [_unit,"AmovPercMstpSrasWpstDnon_AmovPercMstpSnonWnonDnon"] remoteExec ["playMove", 0, false]; sleep 1; _handItem attachTo [_unit, _slotpos, _slotpoint]; "item stored in " + _slotname } else { "this slot is full." }; }; }; This easily allows for multiple beltslots and doesn't care what Items you put on them. Use like this: _callback = [player,0] call fnc_useBelt; _callback will give you a response of the function. Note that beltslot1 has id 0. - - - - - @HazJ Why would you use this? if (isNil {player getVariable "Item_In_Hand"}) then { _Unit setVariable ["Item_In_Hand", [false, ""], true]; }; When this is enough: _Unit getVariable ["Item_In_Hand", [false, ""]]; There is no need to check for "isNil" with getVariable. Just put the default value as second parameter. Share this post Link to post Share on other sites
HazJ 1289 Posted September 12, 2016 Yeah, I orignally did that but it gave a very weird error saying it was undefined when I tried to check the variable. Odd. Probably just me. :) Share this post Link to post Share on other sites
L.Trale 10 Posted September 13, 2016 I would rethink your variables. You have "handInUse" as a boolean and you store the item on your belt in a variable, yet for some reason you don't store the item in hand in a variable. That would make things easier, especially since you don't have to rely on nearestObject. Personally I would just use these: "HandItem" "BeltSlot1" Way I see it you wouldn't even have to differentiate between the tooltypes in that code. Just make a universal function for putting items from belt to hand and the other way around. Furthermore, don't use global variables for playerspecific information. Objectspace is more useful and gives you better options for server/client interaction. Here is what I would do: beltSlots = [ ["BeltSlot1",[0.2,0,0],"Pelvis"], ["BeltSlot2",[-0.2,0,0],"Pelvis"] ]; fnc_useBelt = { param ["_unit","_slotnum"]; private ["_slot","_slotname","_slotpos","_slotpoint","_beltItem","_handItem","_beltitem","_InHand","_isInCargo"]; _slot = beltSlots select _slotnum; _slotname = _slot select 0; _slotpos = _slot select 1; _slotpoint = _slot select 2; _beltItem = _unit getVariable [_slotname,objNull]; _handItem = _unit getVariable ["handItem",objNull]; if (isNull _handItem) then { // empty hand -> try to grab item from belt if (isNull _beltItem) then { _unit setVariable ["tool", "", true]; "no Item in that slot." } else { _unit setVariable ["handItem", _beltItem, true]; _unit setVariable [_slotname, objNull, true]; _unit setVariable ["tool", typeOf _beltitem, true]; _beltitem setVariable ["_InHand", true, true]; _beltitem setVariable ["_isInCargo", false, true]; [_unit,"AmovPercMstpSrasWpstDnon_AmovPercMstpSnonWnonDnon"] remoteExec ["playMove", 0, false]; sleep 1; _beltItem attachTo [_unit, [0,0,0], "righthandmiddle1"]; "took item from " + _slotname }; } else { // item in hand -> check belt if (isNull _beltItem) then { _unit setVariable ["handItem", objNull, true]; _unit setVariable [_slotname, _handItem, true]; _unit setVariable ["tool", "", true]; _handItem setVariable ["_InHand", false, true]; _handItem setVariable ["_isInCargo", true, true]; [_unit,"AmovPercMstpSrasWpstDnon_AmovPercMstpSnonWnonDnon"] remoteExec ["playMove", 0, false]; sleep 1; _handItem attachTo [_unit, _slotpos, _slotpoint]; "item stored in " + _slotname } else { "this slot is full." }; }; }; This easily allows for multiple beltslots and doesn't care what Items you put on them. Use like this: _callback = [player,0] call fnc_useBelt; _callback will give you a response of the function. Note that beltslot1 has id 0. - - - - - @HazJ Why would you use this? if (isNil {player getVariable "Item_In_Hand"}) then { _Unit setVariable ["Item_In_Hand", [false, ""], true]; }; When this is enough: _Unit getVariable ["Item_In_Hand", [false, ""]]; There is no need to check for "isNil" with getVariable. Just put the default value as second parameter. Ah, thank you very much for your help guys :) Share this post Link to post Share on other sites
Tajin 349 Posted September 14, 2016 You're welcome. But please avoid fullquotes, they turn the forum into a real mess. Use names to reply to someone or just quote the specific part you're replying to. Share this post Link to post Share on other sites