Jump to content
ducdragger99

Making a script for multiple objects

Recommended Posts

I am making a mission for a dedicated server andI am wanting to make a script that will add the same actions to certain objects so I don't have to put everything in each individual init.   I'm still new to scripting so please forgive any errors, but I have reached a bit of a speedbump.

 

here's what i've tried so far:

 

 

_Flags = ["USFlag1","NFFlag1","RCFlag1","RangeFlag1","RangeFlag2","RangeFlag3",];


 

USFlag = _Flags select 0;

Nato = _Flags select 1;

RedCross = _Flags select 2;

Range = _Flags select 3,4,5;





 

[

 

forEach _Flag do


 

    ["AmmoboxInit",[_this,true]] call BIS_fnc_arsenal;

    call setFlagAnimationPhase 0.1;};

    addAction["Raise Flag",{[_this, 1.0] remoteExec ["setflaganimationPhase",0,true];}];

    addAction{"Lower Flag",{[_this, 0.1] remoteExec ["setflaganimationPhase",0,true];}];

    addAction["Half Staff",{[_this, 0.5] remoteExec ["setFlagAnimationPhase",0,true];}];

 

 

 

];

 

//NOTE: the only reason I have call outs to specific flags is because I want to add other scroll wheel functions to them in the future.

 

 

Am I on the right track?  What am I missing?  When I try to run it in MP I get a "generic error in expression on my _Flags line

Share this post


Link to post
Share on other sites

There are a lot of errors in your script. Have you read the Introduction to Arma Scripting?

 _Flags = ["USFlag1","NFFlag1","RCFlag1","RangeFlag1","RangeFlag2","RangeFlag3",]; // Error: trailing ","
USFlag = _Flags select 0;
Nato = _Flags select 1;
RedCross = _Flags select 2;
Range = _Flags select 3,4,5; // Error: Invalid use of select and commas
// Range = _flags select [startindex, range];
[ // Error: Trying to create an array
forEach _Flag do // Correct usage of forEach is "{code} forEach [array];", so
/// {...} forEach _Flags;
    ["AmmoboxInit",[_this,true]] call BIS_fnc_arsenal;
    call setFlagAnimationPhase 0.1;}; // call expects {code}, setFlagAnimation expects OBJECT as left argument
    addAction["Raise Flag",{[_this, 1.0] remoteExec ["setflaganimationPhase",0,true];}]; // Error: addAction needs OBJET as left argument "OBJECT addAction ..."
	/// Error: _this is an array, you need the flag object which is first (0) param, so "_this select 0"
    addAction{"Lower Flag",{[_this, 0.1] remoteExec ["setflaganimationPhase",0,true];}]; // Error: Used "{" instead of "["
    addAction["Half Staff",{[_this, 0.5] remoteExec ["setFlagAnimationPhase",0,true];}];
]; 

 

Share this post


Link to post
Share on other sites

ok, i've tried and tried to get this to work with very minimal success.

 

so far, i am able to Raise, Lower, Half Staff, Take and Fly my flag.  

When the selection of TAKE FLAG is selected I would like to put a folded flag in the player that took its' uniform, remove the action to take the flag (since there is only one flag pole) and allow only that player to put it back or "FLY FLAG"

 

i'm putting this into the objects (USFlag1) init because i obviously do not know how to write a script for this.

Any help or input is appreciated.

 

USFlag1 setFlagOwner USFlag1

["AmmoboxInit",[this,true]] call BIS_fnc_arsenal;

call{this setFlagAnimationPhase 1.0;};

this addAction["Raise Flag",{[USFlag1, 1.0] remoteExec ["setflaganimationPhase",0,true];}];

this addAction["Lower Flag",{[USFlag1,0.1] remoteExec ["setflaganimationPhase",0,true];}];

this addAction["Half Staff",{[USFlag1,0.5] remoteExec ["setflaganimationPhase",0,true];}];

this addAction["Take Flag",{[USFlag1,""] remoteExec ["setFlagTexture",0,true];}];

this addAction["Fly Flag",{[USFlag1,"Flag_US_F"] remoteExec ["setFlagTexture",0,ture];}]

 

if

("Take Flag" == true)

then {

    this RemoveAction["Take Flag",this,true];

    USFlag1 setFlagOwner _Player;

    _Player addItemtoUniform "FoldedFlag_US_01_F";

 

};

 

if ("Fly Flag" == true)

 then {

     USFlag1 setFlagOwner USFlag1;

     _Player removeitemfromUniform "FoldedFlag_US_01_F";

    this addAction["Take Flag",this,true];

};

 

 

Share this post


Link to post
Share on other sites
2 hours ago, ducdragger99 said:

("Take Flag" == true)

This is logically wrong and invalid in sqf. Logically, because this code will only get executed once and invalid because you can't compare different data types with "==".

 

2 hours ago, ducdragger99 said:

    this RemoveAction["Take Flag",this,true];

Wrong syntax, check the BIKI. correct one would be "this removeAction id" where id is the return value of the addAction command.

 

2 hours ago, ducdragger99 said:

    USFlag1 setFlagOwner _Player;

_Player is undefined

 

2 hours ago, ducdragger99 said:

    this addAction["Take Flag",this,true];

Wrong syntax for addAction, second param is code not an object (this refers to the flag pole), third param is also wrong it has to be an array.

Share this post


Link to post
Share on other sites

As @7erra said you have many syntax errors. The sqf engine expects commands in a specific format and when it doesn't get them like it expects then it starts saying error error. Here are the pages for select, forEach, call, and addAction. I think it would be a good idea for you to take a look at those pages to match the syntax used on the wiki and to get familiar with looking at the wiki, in general. Many of us from this forum also spend a lot of time making edits and tweaks to it, making it the best it can be

 

The reason you got the generic error in expression is because you have an extra comma at the end of your list right before the closing square bracket

Share this post


Link to post
Share on other sites

I have looked at those pages for hours, I have watched countless videos on scripting.  Perhaps I just don't grasp the concept of this foreign language.  I've been trying to make my missions more stream lined and less Zeus dependent.  I give up, I just don't understand.

Share this post


Link to post
Share on other sites

Start simple. Make a flagpole with an addaction that creates some hint text. Then one that adds an item to your inventory. Then one that only works when you have a certain item in your inventory. You will make progress if you move forward in steps. You are trying to scale a mountain with one leap, and that always leads to frustration.

 

We all started at the beginning, and there are plenty here who are happy to help you start there as well.

  • Like 1

Share this post


Link to post
Share on other sites
4 minutes ago, Harzach said:

Start simple

This is the way. After 2-3 solid years of arma scripting, hundreds of posts in this forum helping people, and numerous edits to the wiki, I still haven't even tackled MP scripting 😀

  • Like 1

Share this post


Link to post
Share on other sites

ok, so I'm trying to start from the most basic point I can.

 

I put down a flagpole and a player in VR.

I named the flag pole "USFlag1"

I put in USFlag1 init: this execVM "savetheflag.sqf"

I made a file called savetheflag.sqf

 

in the sqf i put the following:

 

[

_USFlag = ["USFlag1"];

 

_USFlag setFlagTexture "\A3\Data_F\Flags\flag_us_CO.paa";

_USFlag setFlagAnimationPhase 1.0;

];

 

 

 

Nothing happens and I get an error missing ]           

 

What's wrong with what I wrote?

Share this post


Link to post
Share on other sites
53 minutes ago, ducdragger99 said:

I put down a flagpole and a player in VR.

I named the flag pole "USFlag1"

I put in USFlag1 init: this execVM "savetheflag.sqf"


Just a couple of things to point out here. Calling 'this execVM "savetheflag.sqf"' does two things of note: it provides "this" as the left side argument to "execVM", and it returns a script handle back to the context in which it was called.

In the flagpole's "init" context, "this" refers to the flagpole itself.  Thus you are providing the flagpole object directly to the script - there's no need to give it a name at all.

 

The fact that execVM returns a script handle is a problem - an object's init field CANNOT return a value.  So, your call to execVM ends up return a script handle where NOTHING should be returned.

 

This is fixed easily, just change it to:

_handle = this execVM "savetheflag.sqf";

now _handle is asisgned the return value, and the init field code as a whole returns nothing.
 

 

53 minutes ago, ducdragger99 said:

in the sqf i put the following:

 

[

_USFlag = ["USFlag1"];

 

_USFlag setFlagTexture "\A3\Data_F\Flags\flag_us_CO.paa";

_USFlag setFlagAnimationPhase 1.0;

];

 

Well, for one thing, the [ ]; around the outside are unneccessary and incorrect.  [ <stuff>, <stuff>, <...>] is an array declaration, not an SQF statement.  So get rid of those.  The other point to note here is that since we passed the flagpole object directly to the script (with "this" in our execVM call), we don't need to use its name.

 

Your line:

_USFlag = ["USFlag1"];

Is assigning _USFlag with an array, the first element of which is a string.  What we want to do is assign _USFlag with a single object. If you wanted to continue (redundantly) using the flagpole's name, then you would just write that as:

_USFlag = USFlag1;

No quotes are used because it's the proper global name of an object.

 

However, since we passed the flagpole to the script, you can instead do:

_USFlag = _this;

In a script call, _this always refers to the entire left-side argument that was used in the original invocation.  Thus, "_this" in the SQF corresponds directly to "this" in our execVM call.

  • Like 1
  • Thanks 1

Share this post


Link to post
Share on other sites

dwringer,

thank you for the explanation.  It is most helpful.  That really sheds some light on things.

Share this post


Link to post
Share on other sites

@dwringer

 

ok, couldn't get that to work at all, so I started from scratch.

 

I put an execVM into my init file in my mission folder. (seems to work, it's referencing my script file)

 

I placed an empty flag pole in the VR editor and named it Pole_1

 

In my script.sqf I put the following:

 

_Flag = Pole_1;

Pole_1 = _this;

_Flag setFlagTexture "\A3\Data_F\Flags\flag_us_CO.paa";  //set initial flag texture

[_Flag,1.0,true] call BIS_fnc_animateFlag;  //set initial flag height

 

^^^^^^^^ the above worked great, I spawned in and saw an American Flag high atop the flag pole.^^^^^^^^^^^^^

 

the next step was to put the actions on the flag,  this is where i'm having extreme difficulties.  I've read the wikis and watched some vids, and still even after copying the wiki line for line, am getting errors.
 

[

    //flag positions

        //Raise flag

       

        _Flag addAction [

            "Raise Flag", //Action Name

            {_this,1.0}, //Script to send to fnc  

            nil, //Argument

            1, //Priority

            true, //showWindow

            true, //hideonuse

            "", //shortcut

            "",  //condition

            10, //Radius

            false, //unconscious

            "", //selection

            "" //memoryPoints

                        ]

                            call BIS_fnc_animateFlag];

 

        //Half Staff flag

 

        _Flag addAction [

            "Half Staff", //Action Name

            {_this,0.5}, //Script to send to fnc

            nil, //Argument

            2, //Priority

            true, //showWindow

            true, //hideonuse

            "", //shortcut

            "",  //condition

            10, //Radius

            false, //unconscious

            "", //selection

            "" //memoryPoints

                        ]

                            call BIS_fnc_animateFlag];      

        //Lower flag

 

        _Flag addAction [

            "Lower Flag", //Action Name

            {_this,0.1}, //Script to send to fnc  

            nil, //Argument

            3, //Priority

            true, //showWindow

            true, //hideonuse

            "", //shortcut

            "",  //condition

            10, //Radius

            false, //unconscious

            "", //selection

            "" //memoryPoints

                        ]

                            call BIS_fnc_animateFlag];


 

];

 

Once again i'm lost.  Any help would be appreciated.

 

 

 

 

Share this post


Link to post
Share on other sites
_Flag = Pole_1; // unnecessary
Pole_1 = _this; // WRONG! Whatever "_this" is, now your flagpole's variable name points to it instead

Pole_1 setFlagTexture "\A3\Data_F\Flags\flag_us_CO.paa";  // just use the variable name

[Pole_1, 1.0,true] call BIS_fnc_animateFlag;  //set initial flag height

 

^^^^^^^^^^^^^^^^^^^^^^^^

FORGET ALL OF THAT

 

Now, you don't really need to name the flagpoles, which is great if you want to run this script on many flagpoles. First, we'll call the script from each flagpole's init field like this:

nul = this execVM "script.sqf";

"This" is a magic variable that we are now passing to the script. It refers to the flagpole since it is in the flagpole's init field. The script receives "this" as a local variable "_this," which we could use in the script, but using params makes everything nice and tidy and private:

params ["_flag"];

_flag setFlagTexture "\A3\Data_F\Flags\flag_us_CO.paa";
[_flag, 1.0, true] call BIS_fnc_animateFlag;

For clarity:

params ["_flag"];

//  is the same as 

private _flag = _this;

When passing more robust parameters to scripts, they go into an array:

nul = [this, true] execVM "script.sqf";

where

params ["_flag", "_boolean"];

//  is the same as 

private _flag = _this select 0;
privat _boolean = _this select 1;

 

 

 

~~~INTERMISSION~~~

 

 

 

So, going back a few steps to the idea of running this on multiple flagpoles that represent different sides, you could pass each flagpole's side to the script then apply the correct texture according to that variable:

//nul = [this, <side>] execVM "script.sqf";
//example, for a US flag:

nul = [this, west] execVM "script.sqf";
params ["_flag", "_side"];

if (_side == west) then 
{
	_flag setFlagTexture "\A3\Data_F\Flags\flag_us_CO.paa";
	[_flag, 1.0, true] call BIS_fnc_animateFlag;
};

But we'll stop there for now, as sorting all sides for different textures will be a new concept.

  • Like 1

Share this post


Link to post
Share on other sites

ok, so if I am understanding this correctly, let's say the faction the flag belongs to does not matter.

If i were wanting flag height to dictate which action was displayed, I could use something along the lines of:

Flagpoles' init: 

 

nul = [this, true] execVM "script.sqf";

 

 

in script.sqf:

 

params ["_Flag","_CurrentFlagHeight"];

 

but I need to define "_CurrentFlagHeight"?

 

so would I write

 

_CurrentFlagHeight = _Flag getVariable flagAnimationPhase;

Share this post


Link to post
Share on other sites
4 minutes ago, ducdragger99 said:

nul = [this, true] execVM "script.sqf";

 

Well, you just copied my example. The second param is a boolean, which nothing in your script is looking for:

params ["_Flag","_CurrentFlagHeight"];

_currentFlagHeight is now a boolean variable set to true, which is not useful to you in any meaningful way.

 

Simply:

nul = this execVM "script.sqf";

is fine for the moment.

 

https://community.bistudio.com/wiki/flagAnimationPhase

 

GetVariable is not necessary. Read the Biki entry.

params ["_flag"];

_CurrentFlagHeight = flagAnimationPhase _flag;

 

Share this post


Link to post
Share on other sites

Got it.

well, kinda.

I am able to execute my "HalfStaff" and "lower" functions, but I cannot get the "Raise or Take" to even appear?  (It did before I added the remoteExec to it though).  

 

On a side note, is it an issue to run the script from the missions' init?

 

//Define Player "operator"

 

_operator = Player;

 

 

 

//Define parameters for flag

 

 

_USFlag1 = USFlag1;

params ["_USFlag1","_CurrentFlagHeight","_FlagCarrier"];

 

 

 

//Define starting flag

 

_USFlag1 setFlagTexture "\A3\Data_F\Flags\flag_us_CO.paa";

[_USFlag1, 1.0, true] call BIS_fnc_animateFlag;

_USFlag1 setflagOwner objNull;

_CurrentFlagHeight = flagAnimationPhase _USFlag1;

_FlagCarrier = flagOwner _USFlag1;





 

 

 

    //flag positions

 

        //Raise flag

 

    if(_CurrentFlagHeight < 0.9)

 

    then {_USFlag addAction ["Raise Flag",{[USFlag1,1.0,false] remoteExec ["BIS_fnc_animateFlag",0,true];}];};

 

        //Half Staff flag

 

    if(_CurrentFlagHeight > 0.0)

 

    then {_USFlag1 addAction ["Half Staff",{[USFlag1,0.5,false] remoteExec ["BIS_fnc_animateFlag",0,true];}];};

 

 

 

        //Lower flag

 

    if(_CurrentFlagHeight > 0.2)

 

    then {_USFlag1 addAction ["Lower Flag",{[USFlag1,0.1,false] remoteExec ["BIS_fnc_animateFlag",0,true];}];};

 

 

 

        //Take flag

 

    if(_CurrentFlagHeight < 0.3)

 

    then {_USFlag1 addAction ["Take Flag",{[USFlag1,""] remoteExec ["setFlagTexture",0,true];}];};  

 

 

 

        //Return flag

 

    if(_CurrentFlagHeight == 0.0)  

 

    then    {_USFlag1 addAction ["Return Flag",{[USFlag,"\A3\Data_F\Flags\flag_us_CO.paa"] remoteExec ["setFlagTexture",0,true];}];};

   

   

   

 

Also, If a player didn't take the flag down, I do not want him to be able to "Return" it.

 

I was thinking I could do this:

//Return flag

 

    if(_CurrentFlagHeight == 0.0)  

    then{

        if (_Operator == _flagCarrier)

   

        then {_USFlag1 addAction ["Return Flag","Functions\dUc_fnc_ReturnFlag.sqf"]}

 

        else {hint "YOU DON'T HAVE THE FLAG";}

 

    else {hint "The Flag is still flying";};

};

Share this post


Link to post
Share on other sites

I'm guessing i'm missing something that will change the value of the current animation phase when it is changed.  So by setting the initial flag height to 1.0 

On 3/24/2022 at 1:09 PM, ducdragger99 said:

/Define starting flag

 

_USFlag1 setFlagTexture "\A3\Data_F\Flags\flag_us_CO.paa";

[_USFlag1, 1.0, true] call BIS_fnc_animateFlag;

_USFlag1 setflagOwner objNull;

_CurrentFlagHeight = flagAnimationPhase _USFlag1;

_FlagCarrier = flagOwner _USFlag1;

 

It is always thinking of the flag that way, hence i'm only seeing the actions performed when the height is less than 1.

 

How do you get the variable to update the current position?

 

Share this post


Link to post
Share on other sites

Alright, I have all my addActions figured out and working well.  

How would I put in a if/then/else for the "take" and "Fly" options?

 

i.e.

Take Flag=

If (the flag has already been taken)

Then hint "THE FLAG IS ALREADY TAKEN"

Else Perform the action

 

 

Fly Flag =

If (you didn't take the flag, set by assignment of flagOwner)

then hint "you don't have the flag"

Else Perform Action

 

 

this is my addActions currently

 

 

//Take Flag

USFlag

    addAction

        [

            "Take Flag",

            {

                [USFlag,0.0,false] remoteExec ["BIS_fnc_animateFlag",0,true];

                sleep 10;

                [USFlag,""] remoteExec ["SetFlagTexture",0,true];

                player action ["TakeFlag",USFlag];

                USFlag setFlagOwner player;

            }

                       

        ];

       

 

//Replace Flag

USFlag

    addAction

        [

            "Fly Flag",

            {  

                            USFlag setFlagOwner objNull;

                            [USFlag,0.0] remoteExec ["setFlagAnimationPhase",0,true];

                            sleep 1.0;

                            [USFlag,"\A3\Data_F\Flags\flag_us_CO.paa"] remoteExec ["SetFlagTexture",0,true];

                            [USFlag,1.0,false] remoteExec ["BIS_fnc_animateFlag",0,true];

            }  

        ];

 

 

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

×