Jump to content
Sign in to follow this  
voiper

ACE Custom Interactions

Recommended Posts

So, you want to add custom interactions to players and objects? There's still a few growing pains, but adding custom actions is easy.

 

Pertinent functions from ace_interact_menu:

ace_interact_menu_fnc_createAction
ace_interact_menu_fnc_addActionToClass
ace_interact_menu_fnc_addActionToObject
ace_interact_menu_fnc_removeActionFromClass
ace_interact_menu_fnc_removeActionFromObject
For now, only a few work properly. addActionToObject/removeActionFromObject work only at top action level, so I'd avoid them for now. removeActionFromClass works, but throws an error every time (some harmless leftover code).

 

 

The Mechanics:

 

EVERYTHING IS LOCAL. Remember this. Plan accordingly.

 

It appears the entire action system is oriented around global variables assigned based on an object's class (derived from inherits on init). After inheriting, each class can have additional actions added to them, and/or individual objects can have actions added with setVariable (but we'll ignore individual objects for now since they're bugged).

 

On init, a gvar will be assigned based on a class's "ACE_Actions" and "ACE_SelfActions" classes. Most vehicles have "ACE_Actions", all units have "ACE_Actions" and "ACE_SelfActions", and some objects (mostly static, non-vehicle ones) have none. The gvar takes the format of: ace_interact_menu_act_* or ace_interact_menu_selfact_*, with the full classname following. So, in a mission with a default NATO soldier, on init, gvars called ace_interact_menu_act_b_soldier_f and ace_interact_menu_selfact_b_soldier_f will be created. Then, each of these vars will be filled with nests of actions inherited from their class defines.

 

An actions children (sub-actions) are nested in their array. For instance, for a crate, the first array is the blank action named "ACE_MainActions" (the main "Interactions" node), and its two child actions, "Carry" and "Drag", are the second and third elements in the array.

 

"But voiper, why do I need to know all this?" Because as a mission maker you can modify these gvars as you see fit (with or without ACE's functions) to add, remove, and manage actions.

 

 

Example 1:

 

I want an action where an the player can brofist a specific AI, bob.

 

Since addActionToObject doesn't work yet, we'll have to use it for bob's class. In case I have other units who have the same class as bob, I will need to make the action's condition check if I'm interacting with him (if I want the action added to everyone of the same class, I can just leave the condition block as {true}).

 

First, I need to format the new action properly. createAction does this no problem. Its parameters are:

0: Action name <STRING>
1: Name of the action shown in the menu <STRING>
2: Icon <STRING>
3: Statement <CODE>
4: Condition <CODE>
5: Insert children code <CODE> (Optional)
6: Action parameters <ANY> (Optional)
7: Position (Position or Selection Name) <POSITION> or <STRING> (Optional)
8: Distance <NUMBER> (Optional)
9: Other parameters <ARRAY> (Optional)
In the statement and condition blocks, (_this select 0) is the object. If I really want to get fancy, I can mess around with the icon (look in ui_f_data.pbo for paths). More fanciness comes from position and max distance, but those will only work on top-level actions.

_action = ["vip_brofist", "Brofist", "", {hint format["%1 does not wish to brofist.", name (_this select 0)]}, {(_this select 0) == bob}] call ace_interact_menu_fnc_createAction;
Returns me an appropriately formatted array, ready to be added to a class.

 

addActionToClass uses these parameters:

0: TypeOf of the class <STRING>
1: Type of action, 0 for actions, 1 for self-actions <NUMBER>
2: Parent path of the new action <ARRAY>
3: Action <ARRAY>
Pretty easy. I'm adding it to his main actions, so I'll use the main node path of "ACE_MainActions" (whoa crazy). Remember, I'm adding to bob's class, so I'll need his classname.

[typeOf bob, 0, ["ACE_MainActions"], _action] call ace_interact_menu_fnc_addActionToClass;
lsKHaEg.png

Bob refused. Not cool.

 

Example 2:

 

I want to give the player the option of taking a cyanide pill.

 

This time we're working with self actions, so the parent array is "ACE_SelfActions" (again, crazy). We're going to get a little fancier, and place the action as a child of the "Equipment" node.

 

_action = ["vip_cyanide", "Take Cyanide Capsule", "", {player setDamage 1}, {true}] call ace_interact_menu_fnc_createAction;
[typeOf player, 1, ["ACE_SelfActions", "ACE_Equipment"], _action] call ace_interact_menu_fnc_addActionToClass;
lASoxsK.png

Don't do it.

 

Since player is always local, it doesn't matter that I'm applying this to the player's class, which other units might also have: it will only ever show up in the player's self menu. If I don't want all players who have this class receive this, then I'll have to add a condition (side, variable, what have you) to call the function on the appropriate clients.

 

 

Example 3:

 

I want to remove the "drag" and "carry" options from a crate. (There are the functions ace_dragging_fnc_setCarryable and ace_dragging_fnc_setDraggable, but I'm using this as an example.)

 

I'll make all crates of a certain class not carryable. Now, recall, removeActionFromClass works, but atm throws a harmless error. I don't want the MMO officers burning my house down, so I'm going to work around that.

 

Remember all that stuff about act_interact_menu_act_*? Since it's just a gvar, it can be directly modified like any other gvar. Without giving you the full dump, act_interact_menu_act_Box_NATO_wps_f has only a handful of entries: ["Ace_MainActions", "ace_dragging_drag", "ace_dragging_carry"], and a few others. I'm focusing on the first array, since that's the main action tree. For my mission, I'm never planning to have crate moving, so I can safely remove the two children of the array:

 

 

(act_interact_menu_act_Box_NATO_wps_f select 0) deleteAt 2;
(act_interact_menu_act_Box_NATO_wps_f select 0) deleteAt 1;
Hey presto, no more grand theft crate.

 

And there you have it. As the bugs get fixed, I'll update this, but for now, this is how I've gotten it functioning.

Edited by voiper

Share this post


Link to post

 

 

"But voiper, why do I need to know all this?" Because as a mission maker you can modify these gvars as you see fit (with or without ACE's functions) to add, remove, and manage actions.

 

Please  keep in mind, because you are using an unsupported method of modifying things (Not using the functions) - anything you do using this method WILL BREAK IN THE FUTURE, as those arrays WILL change.

Edited by jaynus

Share this post


Link to post

Any ETA on when we are going to have the required functions to do all this correctly?

Share this post


Link to post

Any ETA on when we are going to have the required functions to do all this correctly?

 

next release.

Share this post


Link to post

Either from idiocy on my part, or because something was fixed, you can add to objects now.

[bob, 0, ["ACE_MainActions"], _action] call ace_interact_menu_fnc_addActionToObject;

One thing to watch out for is blank execute code blocks: if you're making just a parent node (like "ACE_Equipment", let's say), then use {true} for execute. If you use {} the node will not appear.

 

ace_interact_menu_fnc_removeActionFromClass also works without error, however it does not work in vehicle init fields (actions are added postInit, presumably?), so you'll have to call it after time > 0.

Edited by voiper

Share this post


Link to post

Is there any news on the proper functions for this?

I can't find any other documentation for this...

Share this post


Link to post

As of 3.2.0, ace_interact_menu_fnc_removeActionFromClass is still broken (thought it was fixed, turns out it wasn't). Will be fixed in 3.3.0. For the time being, you'll need to remove actions from the class's global variable.

 

There was a bug where actions added by ace_interact_menu_fnc_addActionToObject would only render on screen for 1s before disappearing, but that's been fixed in 3.2.0.

 

I can field questions here, if you'd like.

Edited by voiper

Share this post


Link to post

[...]

There was a bug where actions added by ace_interact_menu_fnc_addActionToObject would only render on screen for 1s before disappearing, but that's been fixed in 3.2.0.

[...]

 

Just to double check, are "ace_interact_menu_fnc_addActionToObject" and "ace_interact_menu_fnc_removeActionFromObject" working and will this method be supported in the future? I would like to try and implement this method, but only if it will not break with the next update.

 

Is it possible to use those two to replace "addAction" commands and would one gain a performance advantage by using this method rather than the addAction method from BI? Basically I try to implement a few options for players to interact with objects. So far I used addAction which is just fine but might impact performance as I understand it (and as you told me in another thread).

But if I can add options with this method to objects and have them appear/ disappear based on the condition set (which is based on a public variable) and then execute another script, then this might be an alternative to look into.

 

Will the condition block be checked every time the player uses the interact key on the object and will the option be dynamically be shown/ not shown based on the value? Or is it only used to initialize at mission start and later stay on the object unless ace_interact_menu_fnc_removeActionFromObject is used?

Share this post


Link to post

Just to double check, are "ace_interact_menu_fnc_addActionToObject" and "ace_interact_menu_fnc_removeActionFromObject" working and will this method be supported in the future? I would like to try and implement this method, but only if it will not break with the next update.

 

Yes, they work. I see no reason they won't be supported in the future. The only issue I know of is that if the object you're adding the actions to doesn't already have the "ACE_MainActions" class (many static objects don't have it), it won't work. This particular issue is scheduled to be fixed.

 

Is it possible to use those two to replace "addAction" commands and would one gain a performance advantage by using this method rather than the addAction method from BI? Basically I try to implement a few options for players to interact with objects. So far I used addAction which is just fine but might impact performance as I understand it (and as you told me in another thread).

But if I can add options with this method to objects and have them appear/ disappear based on the condition set (which is based on a public variable) and then execute another script, then this might be an alternative to look into.

 

Of course! That's the whole point of ace_interact_menu. It would be a performance increase overall, yes. In addition, it will be much easier for players to use your options, since you can organise them into menus.

 

Will the condition block be checked every time the player uses the interact key on the object and will the option be dynamically be shown/ not shown based on the value? Or is it only used to initialize at mission start and later stay on the object unless ace_interact_menu_fnc_removeActionFromObject is used?

 

The condition code runs when:

 

1) The player is within the minimum distance to interact (varies with object type/size), and

2) The object is within the player's field of view, and

3) The player is holding the interact key

 

You can give the action any condition code you want, public vars included.

Share this post


Link to post

 

Yes, they work. I see no reason they won't be supported in the future. The only issue I know of is that if the object you're adding the actions to doesn't already have the "ACE_MainActions" class (many static objects don't have it), it won't work. This particular issue is scheduled to be fixed.

 

As far as I can tell I can add a single action to objects (not classes) if I leave the parent path empty.

[_object, 0, [],_actionPickup] call ace_interact_menu_fnc_addActionToObject;

Adding more then one however places the actions on top of each other. But as you said, this will be fixed.

 

 

Is there an eta on the fix? And in the meanwhile can I add the "ACE_MainActions" in a simple way? I've tried adding an empty action but that doesn't seem to work.

Share this post


Link to post

Can anyone already confirm if this is working now with ACE 3.3.0? Specifically the part of adding custom interactions to objects with no MainAction already in place.

 

Also, is there any other documentation already available except what is shown in this thread? Looking forward to try this out and replace the BIS AddAction with it.

Share this post


Link to post

I have been using this in a mission in the past week to add a custom radio end trigger, so it seems to still work.  I've only been adding self interact options, so I cant say whether the object interaction works.

Share this post


Link to post

Alright, so I played around with these functions and it seems like the ace_interact_menu_fnc_addActionToObject function is working now. I was able to add the base Interaction option to a static object that previously had no ACE interaction option (laptop object).

 

However, I stumbled over more questions. Hope it is alright to post this here. I will try to structure this as good as possible to make it easy to follow along.

 

 

Introduction to the problem:

 

I made a mission with quite a few addAction options that I now plan to replace with the ACE interaction to increase performance, to keep things more clean looking in-game and to avoid having 3 different systems in place.

To get used to how the ACE interaction functions work I tried to replace one simple addAction currently in use in my mission with the new functions.

 

Following the script activated by the addAction command that later should be activated with the ACE interaction. Take a close look on all the parameters I need. I will also require them for the ACE interaction.

// file switch_floodlights_base.sqf
 
// Initialization
if (isDedicated) exitWith {};
 
// Defining variables
_switch = _this select 0;       // the object used as the switch
_caller = _this select 1;       // the person using the addAction command
_floodlights = [fl1,fl2,fl3,fl4,fl5,fl6,fl7,fl8,pl19];       // array with all the lights (name objects in editor appropriately)
 
// Defines variables by grabbing the addAction arguments
_status = (_this select 3) select 0;        // 1st argument, defines status of the lights (returns true or false)
_damage = (_this select 3) select 1;        // 2nd argument, defines damage to be set to the lights (returns 0.97 for off or 0 for on)
_variable = (_this select 3) select 2;      // 3rd argument, defines the variable "lightsOn"
 
// Turning lights on or off
{
    _x setHit ["light_1_hitpoint", _damage];        // sets all lights that are part of the array _floodlights either on or off by changing the damage value
    _x setHit ["light_2_hitpoint", _damage];
    _x setHit ["light_3_hitpoint", _damage];
    _x setHit ["light_4_hitpoint", _damage];
}
 
forEach _floodlights;       // runs the above command on each light part of the array _floodlights
 
// Return variables to switch object
_switch setVariable [_variable, _status, true];         // changes the variables and returns them to the switch. Needed to remove the addAction option OFF and add the addAction option ON
 

 

The "old" addAction command:

 

The addAction (see below) allows players to turn the base lights on or off. This is done by looking at the laptop and using the addAction command.

 

This is the initialization of my addAction commands. This file is run for all clients at mission start.

// file addaction_init.sqf
 
//Laptop Floodlights Base
fobE_toc_laptop_1 setVariable ["lightsOnBase", true, true]; // define variable in laptop for use in the addAction conditions
fobE_toc_laptop_1 addAction ["Switch Base Lights OFF", "switch_floodlights_base.sqf", [false, 0.97, "lightsOnBase"], 6, false, true, "", "(_target getVariable 'lightsOnBase')"];
fobE_toc_laptop_1 addAction ["Switch Base Lights ON"), "switch_floodlights_base.sqf", [true, 0, "lightsOnBase"], 6, false, true, "", "!(_target getVariable 'lightsOnBase')"];
 
This worked flawlessly so far.
 
 
What I tried to do:
 
So, I tried to follow this thread closely but soon stumbled over some obstacles. The main problem is, that I not only need to first add the "ACE_MainActions" to my object, but I also want to add other layers to it. What I wanted to accomplish is to have "Interactions" >> "Base Lights" >> "Turn ON" (and "Turn OFF"). The option "Turn ON" and "Turn OFF" should only appear one at a time depending on the condition (the variable set in the laptop object that is altered when activating the script).
 
Now, I figured I would need at least 3 separate actions to realize just the bare minimum:
// file addaction_init.sqf (new version)
 

fobE_toc_laptop_1 setVariable ["lightsOnBase", true, true]; // define variable in laptop for use in the addAction conditions
_action_1 = ["ace_MainActions", "Interactions", "", {true}, {true}, {}, [], [0,0,-0.15], 1.5] call ace_interact_menu_fnc_createAction; // add the main interaction node
_action_2 = ["lights", "Base Lights", "", {true}, {true}] call ace_interact_menu_fnc_createAction; // add another custom node
_action_3 = ["lights_on", "Turn ON", "", {execVM "scripts\client_side\switch_floodlights_base.sqf"}, {(fobE_toc_laptop_1 getVariable 'lightsOnBase') == true}] call ace_interact_menu_fnc_createAction; // add the option to turn lights on and execute script (see above; spoiler)
_action_4 = ["lights_on", "Turn OFF", "", {execVM "scripts\client_side\switch_floodlights_base.sqf"}, {(fobE_toc_laptop_1 getVariable 'lightsOnBase') == false}] call ace_interact_menu_fnc_createAction; // add the option to turn lights on and execute script (see above; spoiler)
[fobE_toc_laptop_1, 0, [], _action_1] call ace_interact_menu_fnc_addActionToObject;
[fobE_toc_laptop_1, 0, ["ACE_MainActions"], _action_2] call ace_interact_menu_fnc_addActionToClass;
[fobE_toc_laptop_1, 0, ["ACE_MainActions", "Base Lights"], _action_3] call ace_interact_menu_fnc_addActionToClass;
[fobE_toc_laptop_1, 0, ["ACE_MainActions", "Base Lights"], _action_4] call ace_interact_menu_fnc_addActionToClass;
 
Well, what this did is it added the simple "Interactions" option to my laptop. This is already great as it works to "attach" interactions to the static object. But nothing else showed up.
 
So, my questions are:

 

  1. What do I have to do to have the interaction options show up as I planned it? Do I need several action commands? Given my current number of addAction commands, I will probably end up with over 100 actions I need to define if I need 3-4 for each addAction command.
  2. How can I pass custom parameters to the script I execute and how can I refer to them inside the script? (See the current addAction command above.)

Thanks for reading this far! I will try to keep playing around with this to get it to work and suit my needs. But I am sure that I will have little chance of success without some help here. So anyone who can help me out here is very much welcome to do so.

I also apologize if this exploits this thread, but I figured it is the best place to post and makes more sense than starting a new thread again. Maybe it helps other people reading through here in the future.

Edited by Whiplash

Share this post


Link to post

Hi,

 

just a small question:

 

 

How can i create a class like "ACE_Equipment" ?

 

I added already successful 4 new actions to the equipment class, but i would like to create a own class.

 

Greetings Ganglf

Share this post


Link to post

3rd parameter for ace_interact_menu_fnc_addActionToClass is a path for a new node. In following example it is ["ACE_SelfActions", "menu_name"]. You create new node that doesn't do nothing when selected, then you use it as a parent for a new node.

_action = ["menu_name", "Your new menu", "", {}, {true}] call ace_interact_menu_fnc_createAction;
[player, 1, ["ACE_SelfActions"], _action] call ace_interact_menu_fnc_addActionToObject;

_action = ["option_name", "Option", "", {hint "stuff"}, {true}] call ace_interact_menu_fnc_createAction;
[player, 1, ["ACE_SelfActions", "menu_name"], _action] call ace_interact_menu_fnc_addActionToObject;

Share this post


Link to post

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Sign in to follow this  

×
×
  • Create New...