Jump to content
Robustcolor

Spawn units when player near markers

Recommended Posts

Hi, is there a better way to do this kind of script? It seems like each marker will have my fnc active with a waituntil all the time correct?

My goal is to have the fnc to spawn and despawn enemies with a 50% chance of activating fnc when player is near.

_marker =  ["A1","A2","A3","A4","A5","A6","A7","A8","A9"];
{ [_x] spawn Robust_fnc_Ambush
} 
foreach _marker;

And my fnc looks like this.

private ["_marker","_pos","_grp01"];

_marker = _this; 

while {true} do {
sleep 5;

Call {
if ({(_x distance2d getMarkerpos _marker < 350)} count allPlayers > 0) exitWith {

_ambush = (1 + round (random 1));

for "_x" from 1 to _ambush do {

_pos = [getMarkerpos _marker, 0, 50, 5, 0, 0.4, 0] call BIS_fnc_findSafePos;

_grp01 = [_pos, east, ["uns_men_NVA_65_MGS","uns_men_NVA_65_LMG","uns_men_NVA_65_MED","uns_men_NVA_65_AT","uns_men_NVA_65_AS5","uns_men_NVA_65_AA","uns_men_NVA_65_AT","uns_men_NVA_65_HMG"],[],[],[1,1],[1,1]] call BIS_fnc_spawnGroup;

{_x setBehaviour "Safe"; _x setSpeedMode "Limited"; _x setFormation "Column"; _x setCombatMode "Red"} forEach [_grp01];

{_x setSkill ["AimingAccuracy",0.01]} forEach (units _grp01);

_grp01 enableDynamicSimulation true;
_grp01 allowFleeing 0;
_grp01 deleteGroupWhenEmpty true;

[_grp01, getMarkerpos _marker, 50] call bis_fnc_taskPatrol;

{_x addCuratorEditableObjects [units _grp01, true];} foreach allCurators;

waitUntil {sleep 5; ({(_x distance2d getMarkerpos _marker) < 500} count allPlayers < 1)};

{deleteVehicle _x;}forEach units _grp01;
deleteGroup _grp01;
{deleteVehicle _x;} count allDead;

};

waitUntil {sleep 5; ({(_x distance2d getMarkerpos _marker) < 500} count allPlayers < 1)};

};};};

 

  • Like 3

Share this post


Link to post
Share on other sites
34 minutes ago, Robustcolor said:

private ["_marker","_pos","_grp01"];

use private keyword  instead of private array

34 minutes ago, Robustcolor said:

_marker = _this;

use params

34 minutes ago, Robustcolor said:

Call {

useless call? Seems like you can just replace the "exitWith" with a "then"?

 

 

Better variant would be. To iterate through all markers in the waitUntil (every 5 seconds) and if one marker has nearby players, then act on it.
And repeat that.

 

I'd recommend moving the actual spawning logic outside into a seperate function, and pass parameters to it.
That way you have much less code to shuffle around and that should make the checking all markers at once variant easier to implement.

Sorry I dont have time to chew out some code for you.

  • Like 1

Share this post


Link to post
Share on other sites
6 hours ago, Robustcolor said:

Hi, is there a better way to do this kind of script?

 

Hello there Robustcolor !

 

Take a look here if you like :

 

  • Like 1

Share this post


Link to post
Share on other sites

Thank you @Dedmen and @GEORGE FLOROS GR

I tried two different approaches but can't get it to work.

 

I'm spawning my function from initserver

[] spawn Robust_fnc_Start;

First is this

_distance = 20;

_A1 = getMarkerPos "A1"; 
_A2 = getMarkerPos "A2";

while{true}do{
_area = selectrandom [_A1,_A2];
if (((player distance2d _area) < _distance))
then
{
_ambush = [] call Robust_fnc_Ambush;

};
sleep 1;
};

Second i tried was this

_markers = ["A1","A2"];
_markerdist = 20;
_marker = _markers select 0;
	while {true} do {
{
			if (player distance getmarkerpos _x < player distance getmarkerpos _marker) then
			{
				_marker = _x;
			};
			sleep 0.01;
		}foreach _markers;

		if (player distance getmarkerpos _marker < _markerdist) then
		{

[] call Robust_fnc_Ambush;

				sleep 2;

		}
		else {sleep 5;};
};

Both of these scripts work if player is near one of these markers, but continues to activate my fnc everytime its looping, i want it to pause until player is 500m away then continue checking. And i have no clue how to make my units spawn at that specific marker that's activated.

private ["_marker","_pos","_grp01"];

Tried both these
_marker = getmarkerpos _marker; 
_marker = _markers select 0;

_ambush = (1 + round (random 1));

for "_x" from 1 to _ambush do {

_pos1 = [getMarkerpos _marker, 0, 10, 5, 0, 0.4, 0] call BIS_fnc_findSafePos;

_grp01 = [_pos1, east, ["B_Soldier_TL_F"],[],[],[1,1],[1,1]] call BIS_fnc_spawnGroup;

{_x setBehaviour "Safe"; _x setSpeedMode "Limited"; _x setFormation "Column"; _x setCombatMode "Red"} forEach [_grp01];

{_x setSkill ["AimingAccuracy",0.01]} forEach (units _grp01);

_grp01 enableDynamicSimulation true;
_grp01 allowFleeing 0;
_grp01 deleteGroupWhenEmpty true;

[_grp01, getMarkerpos _marker, 50] call bis_fnc_taskPatrol;

{_x addCuratorEditableObjects [units _grp01, true];} foreach allCurators;

waitUntil {sleep 5; ({(_x distance2d getMarkerpos _marker) < 500} count allPlayers < 1)};

{deleteVehicle _x;}forEach units _grp01;
deleteGroup _grp01;
{deleteVehicle _x;} count allDead;

};

 

Share this post


Link to post
Share on other sites

if !(isserver) exitWith {};

 

_markers = [“A1“,“A2“,“An“];
_markerdist = 20;

 

while {count _markers > 0} do
{

  {
    if (player distance (getmarkerpos _x) <= _markerdist) then
     {
        _markers = _markers - [_x]; //!!!
        ...
     };
  } foreach _markers;

};

 

 

Share this post


Link to post
Share on other sites
1 hour ago, Smart Games said:

if !(isserver) exitWith {};

 

_markers = [“A1“,“A2“,“An“];
_markerdist = 20;

 

while {count _markers > 0} do
{

  {
    if (player distance (getmarkerpos _x) <= _markerdist) then
     {
        _markers = _markers - [_x]; //!!!
        ...
     };
  } foreach _markers;

};

 

 

It worked, but not as intended, it just spawned the unit on one of the markers, not the one that the player is near. Where should i put the call for fnc?

Share this post


Link to post
Share on other sites
1 hour ago, Robustcolor said:

{ if (player distance getmarkerpos _x < player distance getmarkerpos _marker) then { _marker = _x; }; sleep 0.01; }foreach _markers;

use apply and sort to find the closest marker.
 

_distanceMarkers = _markers apply {[player distance getmarkerpos _x, _x]};

_distanceMarkers sort false;

_closestMarker = (_distanceMarkers select 0) select 1;
_closestMarkerDistance = (_distanceMarkers select 0) select 0;

Build array of all markers and their distances, then sort by distance in descending order thus having the biggest distance at the start, and then just take the first element which will be the closest.

 

Alternatively, you could find the first marker in your list that is close enough, using this:

private _firstMarkerIndex = _markers findIf {player distance getMarkerPos _x < _markerDist};
private _firstMarker = _markers param [_firstMarkerIndex, ""]; 
//_firstMarker might be set to "" if there is no marker thats close enough. You need to check that before continuing.

 

 

After you have your marker you can do

if (_closestMarkerDistance < _markerdist) then Robust_fnc_Ambush;

 

1 hour ago, Robustcolor said:

i want it to pause until player is 500m away then continue checking.

 

Turn the "then Robust_fnc_Ambush" into a

if (_closestMarkerDistance < _markerdist) then {
    call Robust_fnc_Ambush;
    waitUntil {sleep 5; player distance getMarkerPos _closestMarker > 500};
}

Then just slap a while loop around the whole thing.
End result: The closest marker to the player, if closer than _markerdist will activate a ambush, and it will wait before checking the next marker, till player is >500m away from the last active one.

 

 

 

 

 

1 hour ago, Robustcolor said:

And i have no clue how to make my units spawn at that specific marker that's activated.

Pass it to the function as a parameter. As I wrote above, use params and private keyword. Read up on the wiki about them

 

call Robust_fnc_Ambush;

turns into

_closestMarker call Robust_fnc_Ambush;

 

and inside fnc_ambush the

1 hour ago, Robustcolor said:

private ["_marker","_pos","_grp01"]; Tried both these _marker = getmarkerpos _marker; _marker = _markers select 0;

 

turns into

params ["_marker"];

 

  • Like 1

Share this post


Link to post
Share on other sites

Have you looked at eos?  You could easily configure the markers using that script.  Check it out.  

  • Like 1

Share this post


Link to post
Share on other sites

I got it to work as intended by doing this

_markers =  ["A1","A2","A3","A4","A5","A6","A7","A8","A9"];
_markerdist = 350;

_marker = _markers select 0;

	while {true} do {
{
			if (player distance getmarkerpos _x < player distance getmarkerpos _marker) then
			{
				_marker = _x;
			};
			sleep 0.01;
		}foreach _markers;

		if (player distance getmarkerpos _marker < _markerdist) then
		{

_marker call Robust_fnc_Ambushai;

}
else {sleep 5;};
};

And my fnc looks like this

params ["_marker"];

_ambush = (0 + round (random 1));

for "_x" from 1 to _ambush do {

_pos = [getMarkerpos _marker, 0, 50, 5, 0, 0.4, 0] call BIS_fnc_findSafePos;

_grp01 = [_pos, east, ["uns_men_NVA_65_MGS","uns_men_NVA_65_LMG","uns_men_NVA_65_MED","uns_men_NVA_recon_65_AT2","uns_men_NVA_65_AS5","uns_men_NVA_65_AA","uns_men_NVA_65_AT","uns_men_NVA_65_HMG"],[],[],[1,1],[1,1]] call BIS_fnc_spawnGroup;

{_x setBehaviour "Aware"; _x setSpeedMode "FULL"; _x setFormation "LINE"; _x setCombatMode "Red"} forEach [_grp01];

{_x setSkill ["AimingAccuracy",0.01]} forEach (units _grp01);

_grp01 enableDynamicSimulation true;
_grp01 allowFleeing 0;
_grp01 deleteGroupWhenEmpty true;

_wp = _grp01 addWaypoint [_pos,10];
_wp setWaypointType "GUARD";

{_x addCuratorEditableObjects [units _grp01, true];} foreach allCurators;

waitUntil {sleep 5; ({(_x distance2d getMarkerpos _marker) < 400} count allPlayers < 1)};

{deleteVehicle _x;}forEach units _grp01;
deleteGroup _grp01;
{deleteVehicle _x;} count allDead;

};

What i don't understand with param is, if i call the script by

[_marker] call Robust_fnc_Ambushai;

i don't need the params in my fnc to find the position.

params ["_marker"];

 

But if i call it like this

_marker call Robust_fnc_Ambushai;

then i need the params otherwise it wont find my position in my fnc.

params ["_marker"];

Why is this?

Share this post


Link to post
Share on other sites
1 hour ago, Robustcolor said:

What i don't understand with param is, if i call the script by


[_marker] call Robust_fnc_Ambushai;

i don't need the params in my fnc to find the position.


params ["_marker"];

That is because as you already know, local variable carry over to lower scopes.

If you don't pass _marker and don't grab it with params, then the fnc_Ambushai will see all variables from the place from where it was called from, including the local _marker variable that you have there.

That's also why its important to use private, else you might overwrite variables that were set in the code which called your function.

 

1 hour ago, Robustcolor said:

then i need the params otherwise it wont find my position in my fnc.

No you don't. Same thing as above. You must be doing something else wrong.

Share this post


Link to post
Share on other sites

Thanks @Dedmen

 

If i want to catch more variables with params like

params ["_marker","_radiussize";]

 

How would i call the fnc then?

 

Is it possible to spawn the fnc and catch the variables if i want the first script to end?

 

Share this post


Link to post
Share on other sites

[ _marker,_radiussize] call function;

 

function:

params ["_marker","_radiussize"];

Share this post


Link to post
Share on other sites
1 hour ago, Robustcolor said:

If i want to catch more variables with params like

params ["_marker","_radiussize";]

 

How would i call the fnc then?

your ; is missplaced there.

 

you'd just call the func with an array of all your parameters so

[_marker, 50] call my_fnc_function;

 

for a _radiussize of 50.

 

1 hour ago, Robustcolor said:

Is it possible to spawn the fnc and catch the variables

Sure. Same thing

 

[_marker, 50] spawn my_fnc_function;

 

1 hour ago, Robustcolor said:

if i want the first script to end? 

What do you mean with that?

Share this post


Link to post
Share on other sites

Thanks @Dedmen. What i meant with ending my script is that call seems to wait for a return of something right? Spawning the fnc would let my first script continue till the end if i got it right.

 

So if my first script look like this

_marker = getMarkerpos "Marker1";

_aosize = getMarkerSize "Marker1";

_axisA = _aosize select 0;

_radius = _axisA;

And i want to call these variables _marker and _radius to my next fnc, is it [_marker, 50] spawn my_fnc_function; or do i need to use [_marker, _radius] spawn my_fnc_function;

Because in my next fnc i will be using

_pos1 = [_marker, 0, _radius, 5, 0, 0.4, 0, [], _ao] call BIS_fnc_findSafePos;

To make random spawn positions.

Share this post


Link to post
Share on other sites
26 minutes ago, Robustcolor said:

And i want to call these variables _marker and _radius to my next fnc, is it [_marker, 50] spawn my_fnc_function; or do i need to use [_marker, _radius] spawn my_fnc_function;

What names you use left of spawn/call doesn't matter.

You pass the content of the variables, what the variable name was doesn't matter.


You might aswell just do

 

[getMarkerPos "Marker1", getMarkerSize "Marker1" select 0] spawn
or
[_marker, _aosize select 0] spawn

or

[_marker, _axisA] spawn

 

27 minutes ago, Robustcolor said:

Spawning the fnc would let my first script continue till the end if i got it right.

correct.

Share this post


Link to post
Share on other sites

Is it possible to exclude player if in air in this code 

if ({(_x distance2d getMarkerpos _marker < 350)} count allPlayers > 0) exitWith {

Share this post


Link to post
Share on other sites
3 hours ago, Robustcolor said:

Is it possible to exclude player if in air in this code 

if ({(_x distance2d getMarkerpos _marker < 350)} count allPlayers > 0) exitWith {

This is horrendously inefficient code. Does marker position change? If not, you should store it and use that instead of querying it each time with getMarkerPos. Also use findIf instead of count.

Share this post


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

This is horrendously inefficient code. Does marker position change? If not, you should store it and use that instead of querying it each time with getMarkerPos. Also use findIf instead of count.

Could i get an example how the findif should be done in this?

if ({(_x distance2d getMarkerpos _marker < 350)} count allPlayers > 0) exitWith {

Share this post


Link to post
Share on other sites
Spoiler
38 minutes ago, killzone_kid said:

if (allPlayers findIf {_x distance2D _markerPos < 350} > -1) exitWith { 

 

Thanks @killzone_kid

 

Should i be using findif in the waituntil too?

waitUntil {sleep 5; ({(_x distance2d _markerpos) < 1000} count allPlayers > 0)};

 

I tried make something like this

waitUntil {sleep 10; (allPlayers findif {_x distance2D _markerpos <350}>-1)}; but did not work.

 

Share this post


Link to post
Share on other sites

Thanks, waituntil count allPlayers works pretty good in my mission, but if waituntil allPlayers findif is better then i need help putting the code together to use it since mine did not start working.

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

×