Jump to content
pognivet

Saving an array of unit variable names, selecting one of those names at random and then using it as a trigger condition

Recommended Posts

I'll try to make this as concise as possible.

 

The objective:

I'm making a mission where armies capture cities in sequence. I've named these cities "sectors".

There is only one active sector at a time, defined by the variable "activeSector".

There is an array containing all of the sectors that are possible to attack.

When the active sector is captured the variable name of that sector (e.g. sector1) is removed from the array of all the sectors and a new sector is selected from that array.

To make sure that people can only capture the active sector (don't accidentally capture other sectors while in transit i.e. stopping in another city for a few minutes while on the way to the active sector etc) the activeSector variable is called in the seized by trigger.

Sector centers are gamelogics named "sector1", "sector2" etc.

 

What works:

- Units going to a sector and fighting/helping each other.

- Units capturing a sector.

 

What doesn't work:

- Setting/changing active sector using a variable.

 

The piece of shit init script I'm using:

sectors = ["sector0", "sector1", "sector2", "sector3", "sector4", "sector5", "sector6", "sector7", "sector8", "sector9", "sector10", "sector11", "sector12", "sector13", "sector14", "sector15"];
importantSectors = ["sector1", "sector8", "sector14"];
baseSectors = ["gMain", "bMain"];
unimportantSectors = sectors;
unimportantSectors deleteRange [importantSectors];

activeSectorPool = ["sector1"];
activeSector = selectRandom [activeSectorPool];
sector1 setVariable ["active", 1, true];
"activeSectorm" setMarkerPos (getPos activeSector);

sectorlayer1 = ["sector2", "sector3", "sector4", "sector5"];
sectorlayer2 = ["sector6", "sector7", "sector8", "sector9", "sector10"];
sectorLayer3 = ["sector11", "sector12", "sector15"];

gCappedSectors = ["sector0"];
bCappedSectors = ["sector1", "sector2", "sector3", "sector4", "sector5", "sector6", "sector7", "sector8", "sector9", "sector10", "sector11", "sector12", "sector13", "sector14", "sector15"];

 

Independent capture trigger for sector0 (capturing this sector leads to sector 1):

 

Trigger condition:

this && !(triggerActivated sector0bt) && (sector0 getVariable "active") == 1

Trigger activation:

activeSector setVariable ["active", 0, true];
activeSectorPool deleteRange [sector0]; 
activeSectorPool append [sector1];
activeSector = selectRandom [activeSectorPool];
activeSector setVariable ["active", 1, true];
gCappedSectors pushBack sector0;
bCappedSectors deleteRange [sector0];
"sector0g" setMarkerAlpha 1;
"sector0b" setMarkerAlpha 0;
"activeSectorm" setMarkerPos (position activeSector);
0 = execVM "update.sqf";

 

Update.sqf simply refreshes the units in the game. It deletes their waypoints and adds new ones around the new active sector.

 

Why do I use selectRandom when theres only one thing in the array? Because in certain areas where there's more breadth there will be multiple sectors in activeSectorPool and one must be chosen at random. In some areas such as near main faction bases there are bottlenecks hence only one sector to choose from.

 

But I digress. The above trigger doesn't work. I don't even know if the active variable even works. I tried also checking to see if "activeSector" == "sector0" but couldn't get that figured out either.

 

This is the script that I use in order to make units go to a sector:

_unit = _this select 0;
_gl = _this select 1;

waitUntil {_unit == _unit};

deleteWaypoint [(group _unit), 0];
deleteWaypoint [(group _unit), 1];

_pos0 = [[[position _gl, 250]],[]] call BIS_fnc_randomPos;

_wp1 = (group _unit) addWaypoint [_pos0, 0, 0];
_wp1 setWaypointBehaviour "AWARE";
_wp1 setWaypointType "SAD";

_h = (leader group _unit) spawn { 
waitUntil {(count units group _this) == 0};
};

(group _unit) setCurrentWaypoint _wp1;

 

I call it as such: 0 = [this, sector1] execVM "sectorattack.sqf". The first option being the unit to be given the orders and the second option being the place to go and execute the orders.

 

With this active sector setup it would look more like this: 0 = [this, activeSector] execVM "sectorattack.sqf".

 

Yes, I know it's all rather confusing, but I think I'm on the verge of a breakthrough here.

 

So can someone help me select a random gamelogic from an array, use that gamelogic's name as a variable and use that as a trigger condition? Thanks.

Share this post


Link to post
Share on other sites
4 hours ago, pognivet said:

activeSector = selectRandom [activeSectorPool];

You are selecting a random element, out of an array containing a single element. This doesn't make sense. The result will always be activeSectorPool.

 

4 hours ago, pognivet said:

"activeSectorm" setMarkerPos (getPos activeSector);

your selectRandom will return an array of strings, getPos on array of strings doesn't work.

 

4 hours ago, pognivet said:

sector1 setVariable ["active", 1, true];

what kind of object is "sector1" ?

Also why are you using 1/0 instead of plain true/false?

If you use bool's you don't need the ==1 check in your trigger condition.

 

4 hours ago, pognivet said:

activeSectorPool deleteRange [sector0];

That is invalid syntax for deleteRange. Check the Wiki.

 

4 hours ago, pognivet said:

activeSectorPool append [sector1];

Just use pushBack, exactly like you do 3 lines below that one.

 

4 hours ago, pognivet said:

_unit = _this select 0; _gl = _this select 1;

you should probably use params.

params ["_unit", "_gl"];

 

4 hours ago, pognivet said:

waitUntil {_unit == _unit};

What's this supposed to do? wait for unit to become non null? If someone passes a null into your function, it won't ever become non-null.

And if someone does happen to pass a null, this script will loop for eternity. I assume what you really wanted is to exit the script? if (...) exitWith {...}

 

4 hours ago, pognivet said:

_h = (leader group _unit) spawn { waitUntil {(count units group _this) == 0}; };

This code, does literally nothing but waste performance.

you spawn a simple waitUntil which does literally nothing. And you store the result in _h which you never use? That doesn't make sense.

 

4 hours ago, pognivet said:

select a random gamelogic from an array

Ah so they are gameLogic's.
Why don't you just store the variables directly in the array? instead of strings?

To get a variable value from a string, you can use getVariable with missionNamespace.

  • Like 1

Share this post


Link to post
Share on other sites

You're right. I noticed my mistake later on. I had brackets around the variable for the array which made selectRandom not work correctly. My bad. I'm kind of new to this.

 

Sector1 is just a gamelogic named Sector1 that acts as the center of a sector's capturable radius.

 

The waitUntil unit == unit thing is something someone told me to do a long time ago to make sure that everything is initialized on the server before doing something. Like checking that 2+2=4. It's just some black magic. I don't know how much it really helps though.

 

I've altered things. They look like this now and seem to work more or less:

 

Spoiler

sectors = [sector1, sector2, sector3, sector4, sector5];
baseSectors = [gMain, bMain];
neutralSectors = sectors;

activeSectorPoolb = [sector5];
activeSectorb = selectRandom activeSectorPoolb;
"activeSectormb" setMarkerPos (getPos activeSectorb);

activeSectorPoolg = [sector1];
activeSectorg = selectRandom activeSectorPoolg;
"activeSectormg" setMarkerPos (getPos activeSectorg);

gCappedSectors = [];
bCappedSectors = [];

 

 

Spoiler

_unit = _this select 0;
_gl = _this select 1;

deleteWaypoint [(group _unit), 0];

_pos0 = [[[position _gl, 50]],[]] call BIS_fnc_randomPos;

_wp1 = (group _unit) addWaypoint [_pos0, 0, 0];
_wp1 setWaypointBehaviour "AWARE";
_wp1 setWaypointType "SAD";

 

 

Run bottom one when I need to like "0 = [this, activesectorb] execVM "gotosector.sqf"" for BLUFOR.

 

This works somewhat for a 5 sector battle with two bases, one for each team.

 

I've altered things slightly so that each team has their own active sector. All sectors start as neutral. As teams capture the neutral sectors they are removed from the neutral sector array and added to the respective teams "owned sectors" array. Once the neutral sector array is empty (meaning that a front-line has now been created between the two teams somewhere in between two sectors) then it switches into another mode where the active sector is selected based on where this front line is.

 

For example: Let us assume there are 5 sectors in a straight line. If Team A owns sectors 1, 2 and 3 and Team B owns sectors 4 and 5 then the active sector for Team A will be 4 and the active sector for Team B will be 3. If Team B captures their active sector before Team A captures theirs then Team A's new active sector will be to re-take Sector 3 while Team B's new active sector will be to push onwards to Sector 2. In this way it creates a sort of back and forth that leaves the detritus of war in its wake, making for an interesting experience.

 

My coding is not the best, but my main concern is simply to have this working at some basic level to provide an interesting and dynamic battleground that can be used with any mod and scaled up or down as one pleases.

  • Like 1

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

×