Jump to content

Recommended Posts

I wrote this neat (and pretty straightforward tbh :P) function to simplify testing scripts written for triggers and inits, but it can just as well be used to add simple actions like "Show health". It work by taking the "arguments" parameter in addAction (see Biki) and interpret that as code to be run.

The function handles both String and Code types, on invalid type default behavior is to print "Error in gen_action.sqf: Invalid type passed to function." in the arma2.rpt

Parameters passed to the code being executed are: [target, caller, ActionID]

Examples:

Lets say we want to show how much health the player has with an action... instead of creating a .sqf file "getHealthAndShowItToPlayer.sqf" and calling addAction with that in the parameter we do this.

//in soldiers init
this addAction [
    "Show health",
    "gen_action.sqf", 
    {hint format ["Health: %1", damage player];}
];

(Note the {} around the code we want to execute)

Of course we can add the other parameters like priority, showWindow, hideOnUse, etc...

String instead of Code works too:

this addAction [
   "Express power",
   "gen_action.sqf",
   "player sideChat 'Muha, I got the powa!';",
   10,
   false,
   true,
   "",
   "isServer"
];

We can also run caller/target dependent code using the parameters passed to the script:

this addAction [
   "Touch inappropriately",
   "gen_action.sqf",
   {
        (_this select 1) sideChat format [
               "You have touched %1 inappropriately.", 
               name (_this select 0)
        ];
   }
];

Any questions, thoughts or bugs? Please feel free to post them.

DISCLAIMER: This is not a recommended way to launch complicated scripts... if that is the case for you stick to a separate .sqf file.

Download link

Edited by mrCurry

Share this post


Link to post
Share on other sites

That's pretty cool. Thanks.

I have one more.

To change the color of the Action Entry use this:

this addAction [
("<t color=""[color="SeaGreen"]#ffffff[/color]"">" + ("[color="SeaGreen"]Colored text here[/color]") + "</t>"),
"script.sqf"
];

To get the color code you can use this Hex Color Generator! :)

You should always use very bright colors to make sure it's pretty visible. Just try it on your own!

Edited by sxp2high

Share this post


Link to post
Share on other sites

Sorry for gravedigging but I just stumbled upon this little script and I´m really loving it :)

I got a quick question though. As you mentioned, it is not recommended to execute complex code and apparently one cannot use code that contains single quotation marks (').

I was thinking coulnd´t one just compile any kind of code and call it within the added Action? Would this method still be limited to 'simple' and short code?

Cheers,

bbq

Share this post


Link to post
Share on other sites

Why do you have a function named the same as a built-in command? Way bad form there... :blush:

Edited by kylania

Share this post


Link to post
Share on other sites

Great idea! The event handler way of doing things... :)

@kylania: You should read Curry's post again. ;)

Share this post


Link to post
Share on other sites
@kylania: You should read Curry's post again. ;)

Oh, now I see what he's doing. Oops. :)

Share this post


Link to post
Share on other sites

This is the exact thing I proposed (and implemented) for CBA. And being in CBA, if you know your user is using CBA you can use it for remote execution of code via actions. In otherwords, you can execute code from a script that the client doesn't need to have the source file for when they use the action.

Totally unrelated development though, I didn't even know someone had already proposed the idea. :cool:

Share this post


Link to post
Share on other sites

Heh, finally =L2D=Curry gets some credit for his work^^

And as I see it, Big Dawg already used it in combination with compiled functions.

So, is there any reason, to use 'addAction' the way it was intended? ;)

Share this post


Link to post
Share on other sites

Well, you don´t. That´s what this helper script is about ;)

Btw, while pimping my debug mode with the new syntax I made this little script..

coordMode = player addAction [("<t color="#1F67CC"">" + ("Coordinates") + "</t>"),"gen_action.sqf","

player removeAction coordMode;

titleText ['Click on map to copy target coordinates to clipboard', 'PLAIN DOWN];

onMapSingleClick 'copyToClipboard (str (_pos)); hintSilent format [''%1'',_pos]';

",10,false,true,"",""];

It copies map positions to clipboard, nothing spectacular but it saved me some time already so I thought I´ll put it out there.

Cheers,

CptBBQ

Share this post


Link to post
Share on other sites
How do you actually add the sqf tho??

1. Copy the gen_action.sqf to your mission folder.

2. Add the addAction command where you need it (see info and examples in OP). Note that the path to the file is relative to mission folder

If I didn't get your question right simply ignore above.

Share this post


Link to post
Share on other sites

Ty Curry.

Id forgot to edit the last post saying i'd figured it out lol.

But ty

Edit:However I am looking to make a simple 'Recurit unit' addaction if you (or anyone else) might know. Sofar ive found no threads tht'v been that helpful. Possibly a dismiss action too.

I've played with triggers etc, think addaction would be best.

Edited by Whiteraven

Share this post


Link to post
Share on other sites

Something along these lines should work (not tested it):

Init

this addAction ["Recruit","recruit_unit.sqf"];
this addAction ["Dismiss","dismiss_unit.sqf"];

recruit_unit.sqf

Change the class names in _unitSet to the types you want to be able to spawn.

_unitSet 	 = ["ClassName","ClassName"];
_placementRadius = 5;

_caller 	= _this select 1;
_t 		= _unitSet select floor (random (count _unitSet));
_g 		= group _caller;
_p 		= getPos _caller;
_g createUnit [_t,_p,[],_placementRadius,"NONE"];

dismiss_units.sqf

Select units to dismiss using f1-f10 and then use action.

_caller		= _this select 1;
_u		=  groupSelectedUnits _caller;

_u joinSilent grpNull;
sleep 0.5;
{ deleteVehicle _x; } forEach _u;

Edited by mrCurry

Share this post


Link to post
Share on other sites

Can I have a trigger execute via an addAction with this? If so could someone please give me an example?

Share this post


Link to post
Share on other sites

It's quite possible, though I'm not sure why you'd want to since the action code can do anything the trigger can.

in condition field of trigger put a variable:

bActiveTrigger

The name of the variable doesn't matter as long as it's the same as below.

Use addAction to set the variable to true.

this addAction [
    "Activate trigger",
    "gen_action.sqf", 
    {bActiveTrigger = true; publicVariable "bActiveTrigger";}
];

Bam!

Edited by mrCurry

Share this post


Link to post
Share on other sites

This is amazing! Thank you so much!

When using this, with this addaction;

_AnswerStrikePositive = Johnrayner addAction ["Yeah, sounds good. Where do we start?", "ObjectiveHandling\Gen_action.sqf", {ConfirmedStrikeBack = 1; Johnrayner removeaction _AnswerStrikePositive}];

The action remains in the list of options for the player, but the variable sets to 1 as expected (debug shows this). Any idea why the 2nd part won't work?

Thanks again,

- HateDread.

EDIT: It's because I can't treat the action as local to the addaction, right? That'd explain why it works when I make it non-local...

This would be interesting for MP :/ Any work-arounds?

Edited by HateDread

Share this post


Link to post
Share on other sites

is it possible to specify at wich range from the object an action can be taken?

Ive been toying with directing civs in missions, but no luck since i cant get the if mouse cursor is on target, and using knowsabout 4, doesnt work as it lasts awhile after i dont look at target.

Say a civilian at 20 m from player then when player points mouse cursor at target, player gets action(action is on civ unit not player) on civ to shout STOP!!

Is this at all possible in any way?

Share this post


Link to post
Share on other sites

@HateDread

Problem is that you save the ID to a variable local to the scope where the addAction is called, while the addAction spawns another script in which's scope the variable you try to utilize is not initialized or it contains complete jibberish, causing removeAction to fail in its task.

One simple workaround would be to save the ID in the variable space of the object the action is attached to.

_actionID = someGuy addAction [
"Do whatever", 
"gen_action.sqf", 
{
	_id = (_this select 0) getVariable "Strikeanswer_positive";
	(_this select 0) removeAction _id;
	//Do whatever...
}
];
_someGuy setVariable ["Strikeanswer_positive",_actionID];

A MP note on the command... AFAIK the action will only be added to the object on the machine that calls the addAction and the action ID may differ between seperate machines.

In other words, addAction's effect is local to the calling machine.

(Can someone please confirm/disconfirm? Without access to my computer I cannot atm)

@Demonized

I suspect using the extended syntax of the command (see addAction) is what you need. More specifically combining the condition parameter with distance and/or possibly cursorTarget

Share this post


Link to post
Share on other sites

Hi all,

with =L2D=Curry´s permission I made a few changes to the script, so it can handle additional arguments passed to the code.

Like this..

this addAction ["Say Hello World!","gen_action.sqf",["player sideChat format ['Hello %1', _this select 3];", "World"]];

It´s still compatible to actions made for the original version of the script and, of course, you can use the extended syntax, too.

For some reason I cannot attach a file to this post... :confused: so here´s the code.

/*	---Generic Action Script---
Author: [EVO] Curry
Slightly edited by: CptBBQ
Function: Enables you to run any code directly from the addAction command
Installation: Copy into your missions folder and call this file through addAction
Example usage:  
	In init of something
	this addAction ["Say Hello World!","gen_action.sqf","player sideChat 'Hello World!';"];

	Alternative Syntax with additional arugment passed
	this addAction ["Say Hello World!","gen_action.sqf",["player sideChat format ['Hello %1', _this select 3];", "World"]];
	Multiple arguments can be passed in an array and accessed with e.g. (_this select 3) select 1

Notes: Recommended only for simple code or for testing scripts/functions designed for inits and triggers
*/

//Parameter one: String or Code - Whatever commands you want to issue, remember to check the syntax ;)

private ["_target","_caller","_ID","_code","_arguments"];
_target = _this select 0;
_caller = _this select 1;
_ID = _this select 2;

if (typeName (_this select 3) == "ARRAY") then
{	
_code = (_this select 3) select 0;	
_arguments 	= (_this select 3) select 1;
} else 
{
_code = _this select 3;
_arguments = "";
};

switch (typeName _code) do {
case "STRING": 	
{
	nul = [_target,_caller,_ID,_arguments] spawn (compile _code);
};
case "CODE":	
{
	nul = [_target,_caller,_ID,_arguments] spawn _code;
};
default			
{
	diag_log text "Error in gen_action.sqf: Invalid type passed to function.";
};
};

Have fun!

Cheers,

bbq.

Share this post


Link to post
Share on other sites

wrong post.

Edited by F2k Sel

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

×