Jump to content
Sign in to follow this  
mtt_asch

The addAction command, and the script.

Recommended Posts

Once again, I have a problem with the editor (well, it's not the editor's fault, its my lack of understanding, which hopefully will get better as I use it).

So what I am trying to accomplish here is that two players will have to find equipment (Map, Compass, and a Watch), by doing short little quests for an npc (there are 3). So far I have it so the actions are properly added to the npc's lists, but I do not get the correct response. It just gives me the "You have chose map option, from civ1", no matter what npc I go to. It's the same for the other two scripts. My thinking is that each statement will act as an "if, then" statement (In ascending order, due to how the briefing.sqf organizes it's statements, I thought it might be the same), but that clearly does not work. I am very new to ARMA 2 scripting. Thanks for the help in advance!

THE SCRIPT:

//=============Civilian 3 Check=====================//

_actionmap = civ3 select 0;

_caller = _player1 select 1;

_id = _this select 2;

civ3 removeAction _actionmap;

hint "you chose the map option, from civ 3";

//=============Civilian 2 Check=====================//

_actionmap = civ2 select 0;

_caller = _player1 select 1;

_id = _this select 2;

civ2 removeAction _actionmap;

hint "you chose the map option, from civ 2";

//=============Civilian 1 Check=====================//

_actionmap = civ1 select 0;

_caller = _player1 select 1;

_id = _this select 2;

civ1 removeAction _actionmap;

hint "you chose the map option, from civ 1";

END OF SCRIPT

Edited by mtt_asch

Share this post


Link to post
Share on other sites

Scrap that script, basically all of it's wrong. :)

So you have three NPCs. One sends you to get a Watch, one sends you to get a Compass and the third to get a Map? Or each of three NPCs will send you to get all three items, but only one of each? Can you explain in more detail what you're trying to do?

Share this post


Link to post
Share on other sites

Well I kinda figured I was going to have to trash this. But pretty much, All three nps's have all three options but only one will have each item for each player. So it's kind of guess work as to find each item. Basically, I'm trying to get it so one npc will have an 2 different items for the two players, but not the other items. So one will have a compass for player one and a watch for player two, another will have a map for player one, and a compass for player two, and so on... Hence 2+2+2=6 and effectively will equal 2 compasses, 2 maps, and 2 watches, to be split among two players. I hope I explained that well enough? It makes sense to me. Sorry for not explaining this sooner.

Share this post


Link to post
Share on other sites

Ahh ok, I get it. Try this. The init will randomly assign each item to a random civilian, assuming there are three of them named civ1, civ2, civ3. It will assign a variable to the player declaring which civ has each item for him.

Each civ is than given three action choices to ask about a map, watch or compass. If the civilian doesn't have it (the variable isn't correct) he'll say he's got nothing for him. If the variable is correct he'll say he has the item and give it to the player. You'd of course replace that with whatever task you wanted them to complete.

Might not be the most elegant code, (but kinda is!) but works in single player at last and since everything is local should work as is in multiplayer I think. :)

init.sqf + Functions module on map.

waituntil {!isnil "bis_fnc_init"};

_civs = [civ1, civ2, civ3];
_watchHolder = _civs call BIS_fnc_selectRandom;
_civs = _civs - [_watchHolder];
_mapHolder = _civs call BIS_fnc_selectRandom;
_civs = _civs - [_mapHolder];
_compassHolder = _civs select 0;

player setVariable["watchHolder", _watchHolder];
player setVariable["mapHolder", _mapHolder];
player setVariable["compassHolder", _compassHolder];

hint format["Watch = %1\n\nMap = %2\n\nCompass = %3", player getVariable "watchHolder",player getVariable "mapHolder", player getVariable "compassHolder"];

In the init of your civ1, civ2, civ3:

this addAction ["Ask about a watch.","itemCheck.sqf",["watchHolder"]];
this addAction ["Ask about a map.","itemCheck.sqf",["mapHolder"]];
this addAction ["Ask about a compass.","itemCheck.sqf",["compassHolder"]];

itemCheck.sqf:

private ["_item", "_player"];

_npc = _this select 0;
_player = _this select 1;
_action = _this select 2;

_npc removeAction _action;

_itemHeld = _this select 3 select 0;
_item = switch (_itemHeld) do {
case "watchHolder": {"ItemWatch"};
case "mapHolder": {"ItemMap"};
case "compassHolder": {"ItemCompass"};
};


if (_player getVariable _itemHeld == _npc) then {
hint "Found it!";
_player addWeapon _item;
} else {
hint "Sorry, I have nothing for you!";
};

Finally to start your player with absolutely nothing:

removeAllWeapons this; {this removeWeapon _x} forEach items this; removeBackpack this;

Share this post


Link to post
Share on other sites

I'm going to need some time to try this out... But thank you! Looks pretty solid to me. Will post when finished. I don't understand the fundamentals about this code, but I will try to pick it apart. So this code will work in a multiplayer scenario? You get what I was trying to accomplish, even with an added random function, I just wanna make sure that this code accommodates two people (possibly more).

---------- Post added at 04:35 AM ---------- Previous post was at 04:03 AM ----------

It works! Now what is the significance of the code in the init.sqf and the code in the itemCheck.sqf? I think I may have trouble working with this, I don't see the elegance in the code you see :confused:. And while this thread is up, how do I go about setting up re-spawn points like checkpoints after I complete an objective?

Edited by mtt_asch

Share this post


Link to post
Share on other sites

Here's how it works line by line.

init.sqf:

waituntil {!isnil "bis_fnc_init"};

Functions Module Init: This line waits until the Functions Module we put on the map is ready. Any time you use the Functions module (like for using BIS_fnc_selectRandom as we're about to) you should include this line at the top of your init.sqf.

_civs = [civ1, civ2, civ3];

List of possible civilians: Here we create an array named _civs which hold the object names for our three possible item holders. We've placed three units on the map called civ1, civ2 and civ3 in the editor. An array is just a list and we'll be selecting from and changing that list next.

_watchHolder = _civs call BIS_fnc_selectRandom;
_civs = _civs - [_watchHolder];

Select a random watch holder: The first line there uses a build in function to select a random value from the _civs array and saves it as the variable _watchHolder. If it had selected civ1 for example _watchHolder would now be equal to civ1. The second line removes the selected value from the list so we can't have one unit giving out two items. So after selecting civ1 we're left with _civs being equal to [civ2, civ3].

_mapHolder = _civs call BIS_fnc_selectRandom;
_civs = _civs - [_mapHolder];
_compassHolder = _civs select 0;

Select the rest of the item holders: The first two lines are identical to the above watchHolder code - we pick someone to hold the map and remove it from the _civs array. Since we only have 3 civilians and only 3 items the last line simply assigns the remaining _civs value as the _compassHolder.

player setVariable["watchHolder", _watchHolder];
player setVariable["mapHolder", _mapHolder];
player setVariable["compassHolder", _compassHolder];

Assign the holders are variables to the player: Now that we know which unit will give which item we save that information as a variable on the player. We use the names "mapHolder" and the like to keep track of which item is on which civilian. We'll reference that during itemCheck.sqf. Now if we checked what the value of the "watchHolder" variable on the player is, in our example we'd get civ1.

hint format["Watch = %1\n\nMap = %2\n\nCompass = %3", player getVariable "watchHolder",player getVariable "mapHolder", player getVariable "compassHolder"];

Debug test: This last line is simply for testing and probably should be removed! :) But it's a quick and easy glance to see which value is assigned while previewing the mission.

itemCheck.sqf:

private ["_item", "_player"];

Privatize the variables _item and _player: This is just to ensure that the values of these variables are available throughout this script since they are local but referenced within code blocks later. Not entirely sure this is needed, but eariler I'd been declaring them in a switch block so would have needed this. :)

_npc = _this select 0;
_player = _this select 1;
_action = _this select 2;

Capture input variables: The _this array for addAction includes 4 pieces of information. The first value is the object the action was on, in this case that would be the civilian NPC. The second value is the object that used the addAction, in this case the player. The third value is the ID of the action that was used. The fourth bit of information is the arguments which we'll get to in a second. Here we just assign each of those to variables to use them easily in this script.

_npc removeAction _action;

Remove the action: Here we remove the action ID (variable _action) from the civilian (variable _npc) so it's no longer available. We can only ask about each item once.

_itemHeld = _this select 3 select 0;

Get arguments: This is the 4th bit of information, the arguments. This is the array after the script name in the addAction code. In this case it's an array with a single string in it declaring which item we're asking about. So "watchHolder", "mapHolder" or "compassHolder". We assign this to the _itemHeld variable. _this select 3 is the arguments array itself ["watchHolder"] from the addAction call. While the select 0 would be the first value in that array (only element in this case).

_item = switch (_itemHeld) do {
case "watchHolder": {"ItemWatch"};
case "mapHolder": {"ItemMap"};
case "compassHolder": {"ItemCompass"};
};

Assign the item to give based on what we're looking for: Here we take the _itemHeld variable and match that with a physical item to possible give if we have it. At this point we don't know if we're the proper holder of the item, but we want to be ready in case we are! If we were looking for the "compassHolder" we'll have an "ItemCompass" ready to hand out.

if (_player getVariable _itemHeld == _npc) then {
hint "Found it!";
_player addWeapon _item;
} else {
hint "Sorry, I have nothing for you!";
};

Check if we have the item or not: Here's the elegance of the script. We have basically one script with basically one if/then check that covers all three civs and all three items for any player. The if statement checks the requested variable of the player and matches it with the civilian that was selected. If we'd checked "watchHolder" from civ1 in our example that statement would look like: player getVariable "watchHolder" == civ1 which it does!

If the variables we set in the init.sqf match with this code then we give the _item that we choose before or possibly change that to start a task or something else. If however the variables don't match we simply say "Sorry, I have nothing for you!" and exit the script doing nothing but removing the action from the NPC.

Does that help explain how it works better?

For the respawn thing at each checkpoint, we'll say that would be a trigger on the map we could use this onAct code to move the player's respawn point:

"respawn_west" setMarkerPosLocal getPos thisTrigger;

That way if a BLUFOR unit set off that trigger their respawn point would be moved to that trigger's location. We're doing it locally so other BLUFOR units would still respawn where the "respawn_west" marker was located for them.

Share this post


Link to post
Share on other sites

THANK YOU SO MUCH! Yes that explains everything quite well indeed. This is very refreshing just how helpful people are on the forums. Thank you for your time and effort in this matter :).

Share this post


Link to post
Share on other sites

Please sign in to comment

You will be able to leave a comment after signing in



Sign In Now
Sign in to follow this  

×