Jump to content
Robustcolor

Spawn units when player near markers

Recommended Posts

On ‎10‎/‎19‎/‎2019 at 2:44 AM, LSValmont said:

 

Do you have a direct download link perhaps? 

 

Thanks!

 

Sure: https://github.com/XEngima/Arma3-Scripts-PatrolledAreas

Full documentation is included in Engima\PatrolledAreas\Documentation.txt.

 

For Windows users interested in keeping up to date with future updates of these scripts the TypeSqf editor is recomended.

  • Like 1
  • Thanks 1

Share this post


Link to post
Share on other sites
16 hours ago, engima said:

 

Sure: https://github.com/XEngima/Arma3-Missions-PatrolledAreas

Full documentation is included in Engima\PatrolledAreas\Documentation.txt.

 

For Windows users interested in keeping up to date with future updates of these scripts the TypeSqf editor is recomended.

 

Wow Enigma your Patrolled areas script is amazing and exactly what I was looking for!

 

Any chance of small updates to it in the future?

 

1) I noticed that you use triggers for spawning/despawning of the groups. As of Arma 3 version 1.97 there will be a new trigger param that let you change/define the intervals (setTriggerInterval),  (https://community.bistudio.com/wiki/triggerInterval) at which the triggers check their conditions. Adding that to your script settings would greatly increase the performance, specially if instead of the triggers' standard 0.5 second check you could set for example (2 + (random 2)); then a high number of triggers would all check their conditions at different intervals greatly improving the performance in a mission.

 

2) I couldn't find any reference to your script deleting the trigger and marker after the group was completely killed. I checked PATAREAS_DepopulateArea but couldn't find it. Perhaps you do delete the trigger elsewhere whenever the patrol group is empty but if you don't you could add that to the next version so you squeeze a little more optimization out of it.

 

3) If I wanted markers 1,2,3,4,5 to spawn opfor units while markers 6,7,8,9 and 10 to spawn resistance units is that possible? Because I only see ["SIDE", east], on the example.

 

4) Finally, there is a probability option for the patrol group to spawn ["GROUP_PROBABILITY_OF_PRESENCE", 0.5],.

If the group does in fact not spawn, are the marker and trigger checking the conditions deleted also or it remains in the mission checking its conditions in vane? 

 

Other than that it is probably the best patrol spawn system I've seen for A3!

 

Well done!

 

 

Share this post


Link to post
Share on other sites

Thanks. Glad you like it.

 

1. setTriggerInterval sounds nice. That should be an easy fix. But I give no promises for  when you got it.

 

2. Script does not ”remember” if units are killed or not, and therefore I do not delete the trigger. If you leave and come back there will be new units patrolling. I understand that people may want both, and actually I’m in need of that feature myself, so I might add that parameter too.

 

3. Yes, that is possible. You do it by configuring and starting two instances of the script, each with its own parameter set. Look for ”instance” in the documentation.

 

4. Again, see 2 above. Probability of presence is checked each time you enter inside the marker.

Share this post


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

Thanks. Glad you like it.

 

1. setTriggerInterval sounds nice. That should be an easy fix. But I give no promises for  when you got it.

 

2. Script does not ”remember” if units are killed or not, and therefore I do not delete the trigger. If you leave and come back there will be new units patrolling. I understand that people may want both, and actually I’m in need of that feature myself, so I might add that parameter too.

 

3. Yes, that is possible. You do it by configuring and starting two instances of the script, each with its own parameter set. Look for ”instance” in the documentation.

 

4. Again, see 2 above. Probability of presence is checked each time you enter inside the marker.

 

Thank you! 

 

Perhaps going as far as to "remember" how many units survived etc you could take a far easier path:

Only "check" if the patrolling team was COMPLETELY WIPED OUT.

If it was then perhaps with setTriggerInterval you could just increase the interval so it takes a lot longer for a trigger to recheck and repopulate (saving precious resources in the process).

 

It could work like this: 

When running PATAREAS_DepopulateArea the trigger already passes _markerName and _group. All it needs to pass additionally is its own name.

 

Then at the beginning of PATAREAS_DepopulateArea it checks if (count units _group < 1). //if the patrolling group has less than 1 member.

 

If true then it the fnc changes the interval of the trigger to a _repopulateDelay value. So it would:

 

if (count units _group < 1) then {

_TriggerName setTriggerInterval _repopulateDelay;

};

 

Then mission makers who do not want infinite enemies on their missions could just set _repopulateDelay = 9999999; and so once emptied locations are never repopulated or could set _repopulateDelay = 120; for a two minutes repopulation etc.

 

Most of my missions are meant to last 2 hours or so and in those instances instant repopulation makes no sense mostly and having an option to delay that would be a game changer.

 

The bad thing is that setTriggerInterval will come with version 1.96 so currently it is only working on the Dev Branch.

The good thing is that that gives you plenty of time to further refine your script 😉

 

 

  • Like 1

Share this post


Link to post
Share on other sites

I looked into it a little, and the script actually do remember state of despawned area. Wrote it a long time ago, so I forgot.

 

That said, the triggers should be removed when a town is empty, but that is not the case now.

 

Plan now will be to update script at some time after setTriggerInterval comes to Arma.

  • Like 1
  • Thanks 1

Share this post


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

I looked into it a little, and the script actually do remember state of despawned area. Wrote it a long time ago, so I forgot.

 

That said, the triggers should be removed when a town is empty, but that is not the case now.

 

Plan now will be to update script at some time after setTriggerInterval comes to Arma.

 

Its great to hear that!

 

May I also suggest you use this system for the Enigma Civilian Population script.

 

Instead of just considering the houses like it currently does (creating an unlimited supplies of civilians per town) it could do:


1) Check the town/cities locations of the mission map. Example script:

Spoiler



private ["_locTypeArr", "_islandNamesArr"];

_locTypeArr =
[
"CityCenter",
"NameCity",
"NameCityCapital",
"NameLocal",
"NameMarine",
"NameVillage"
];

_islandNamesArr = [];
_locPosArr = [];
_locNamePosArr = [];

[_locTypeArr,[],true] call bis_fnc_locations;
_nearbyLocations = nearestLocations [getPos player, _locTypeArr, 100000];

for "_i" from 0 to (count _nearbyLocations)-1 do {
_location = _nearbyLocations select _i;
_locationName = text _location;
_locationPos = locationPosition _location;

_locPosArr set [count _locPosArr, _locationPos];
_islandNamesArr set [count _islandNamesArr, _locationName];

_locNamePosArr set [count _locNamePosArr, _locationName];
_locNamePosArr set [count _locNamePosArr, _locationPos];

};

copyToClipboard (str (_locNamePosArr));
//copyToClipboard (str (_locPosArr));
//copyToClipboard (str (_IslandNamesArr));


 

2) Count the amount of open houses/buildings (with interiors) around each location to determine its size.

3) Create a Population/Depopulation trigger with its size based on the size of the location.

4) On the trigger set a max/min civilian population amount based on the size of each location.

5) On depopulation, remember how many civilians remained like the Patrolled Areas script already does.

6) On re population of the town add the amount of civilians the trigger remembers it had.

7) If cero civilians remain then the trigger deletes itself or sets an increased interval for re population.

 

Additionally, when creating the civilian groups I suggest adding:

_group deleteGroupWhenEmpty true;

 

I know that you delete the group on depopulation but just in case 😉

  • Like 1
  • Thanks 1

Share this post


Link to post
Share on other sites

@Dedmen

I'm trying to get my fnc to work with apply, not 100% sure what's going on.

It works when i use this code

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

_markerdist = 400;

while {true} do {
_distanceMarkers = _markers apply {[player distance getmarkerpos _x, _x]};
_marker = (_distanceMarkers select 0) select 1;
_closestMarkerDistance = (_distanceMarkers select 0) select 0;

if (_closestMarkerDistance < _markerdist) then {
[getmarkerpos _marker] call Robust_fnc_Ambushai;   
waitUntil {sleep 5; allPlayers findIf {(_x distance2d _marker) < 500} ==-1};
};
};

But i still need to use getmarkerpos in my first fnc when sending the call to my second fnc. Not working as you wrote with just sending _marker call.

 

The first code that checks if a player is near a marker, can i make it sleep between searches? Before it's actually finding a player and then making IF THEN.

Share this post


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

But i still need to use getmarkerpos in my first fnc when sending the call to my second fnc. Not working as you wrote with just sending _marker call.

You mean this:

2 hours ago, Robustcolor said:

[getmarkerpos _marker] call Robust_fnc_Ambushai;

?

Yeah seems I missinterpreted that. Your variable _marker had the marker position, not the marker name. I would've named that _markerPosition.

 

2 hours ago, Robustcolor said:

The first code that checks if a player is near a marker, can i make it sleep between searches?

Sure you can sleep wherever you want.


Btw your script doesn't get the closest marker, you removed the sorting when you copied my code. In your code _marker is always "A1"

Share this post


Link to post
Share on other sites

@Dedmen

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

_markerdist = 400;

while {true} do {

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

_distanceMarkers sort false;

_marker = (_distanceMarkers select 0) select 1;

_markerPosition = (_distanceMarkers select 0) select 0;

if (_markerPosition < _markerdist) then {

[_marker] call Robust_fnc_Ambushai;   

waitUntil {sleep 5; allPlayers findIf {(_x distance2d _marker) < 500} ==-1};

};

sleep 5;

};

I have no clue what i'm doing wrong but it does not work at all when using sort. Tried using [getmarkerpos _marker] call Robust_fnc_Ambushai but not working either.

Share this post


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

I have no clue what i'm doing wrong but it does not work at all when using sort.

Can you explain what "at all" means?

I see you are passing _marker to fnc_Ambushai again, but in your last post you wrote that it needs the marker position as argument?

Share this post


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

Can you explain what "at all" means?

I see you are passing _marker to fnc_Ambushai again, but in your last post you wrote that it needs the marker position as argument?

The script does not give any error, i think it's not activating fnc in the IF THEN. My guess is, is that it does not notice if a player is near one of the markers from the array.

Share this post


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

The script does not give any error, i think it's not activating fnc in the IF THEN. My guess is, is that it does not notice if a player is near one of the markers from the array.

You can use hint/systemChat/diag_log to debug your script and check exactly what's running and what values the variables have while its running

Share this post


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

_distanceMarkers sort true;

I don't know why but switching this to true from false makes the script work as intended.

 

Looks like this now.

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

_markerdist = 400;

while {true} do {

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

_distanceMarkers sort true;

_marker = (_distanceMarkers select 0) select 1;

_markerPosition = (_distanceMarkers select 0) select 0;

if (_markerPosition < _markerdist) then {

[getmarkerpos _marker] call Wise_fnc_Ambushai;   

waitUntil {sleep 5; allPlayers findIf {(_x distance2d getmarkerpos _marker) < 500} ==-1};

};

sleep 5;

};

 

Share this post


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

I don't know why but switching this to true from false makes the script work as intended.

Argh.. Must've had a total brainlag.

true sorts in ascending order, false in descending order.

Meaning false gets the biggest number, I thought biggest is good. But actually you wanted smallest 😄

Share this post


Link to post
Share on other sites

I believe this only works in Single Player right:

 

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

 

How could we do the same but with any player in MP?

Share this post


Link to post
Share on other sites
3 minutes ago, LSValmont said:

I believe this only works in Single Player right

Player is only valid when the script runs on a players machine. You can also run scripts on the players machine in MP.

 

4 minutes ago, LSValmont said:

How could we do the same but with any player in MP? 

You could let each player run their own loop. Or you do that for every player in allPlayers, but what do you wanna select then? the marker with the closest player, the marker with the most close players?

Share this post


Link to post
Share on other sites
7 hours ago, Dedmen said:

Player is only valid when the script runs on a players machine. You can also run scripts on the players machine in MP.

 

You could let each player run their own loop. Or you do that for every player in allPlayers, but what do you wanna select then? the marker with the closest player, the marker with the most close players?

 

@Dedmen Well, I want to select any markers with players inside their radius and if true they (the markers positions) are used to spawn an enemy patrol on those "activated" marker/s and then the marker/s must be deleted and also taken out of the main markers array so the main loop stops checking for that/those markers that had already been activated by nearby players....

 

By the way I am following the ACE 3 guidelines for most of my scripts so: https://ace3mod.com/wiki/development/coding-guidelines.html#72-scheduled-vs-unscheduled and https://ace3mod.com/wiki/development/coding-guidelines.html#84-unscheduled-vs-scheduled

Share this post


Link to post
Share on other sites

@Dedmen Only tested my script local and alone and player command works there, but as LSValmont said, does 

_distanceMarkers = _markers apply {[player distance getmarkerpos _x, _x]}; work in MP if script is spawned from initserver? 

 

@LSValmont The main loop stops when a player is near one the markers from the array because of the waituntil in the if then. It starts the loop again when player is outside of the radius.

Share this post


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

The main loop stops when a player is near one the markers from the array because of the waituntil in my if then. It starts the loop when player is outside of the radius.

 

Yeah and that is good for optimization but in my scenario there are several groups of players all over the map so I cannot have just a bunch of them spawn enemy patrols while the rest of players elsewhere waits for them to step out of their markers so other markers can spawn enemies.

 

Your loop is great when you are forcing players to stay together rather than the open world scenario I am doing.

 

Also I've set up a very strong cache/dynamic simulation for ai units so as soon as players get far from a spawned enemy patrol that AI just goes offline until the players return, so I still get a quite good performance even with lots of makers activated.

 

Also I don't want to go the trigger way... that some other scripters use... I find that kinda unnecessary given how optimal some new commands and loops can be... controlling all the markers from one single loop instead of 120 triggers + markers is so much easier and clean.

Share this post


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

work in MP if script is spawned from initserver? 

I already answered that.

 

17 hours ago, Dedmen said:

Player is only valid when the script runs on a players machine.

 

initServer is.. server, not player. So no. It doesn't.

 

17 hours ago, LSValmont said:

I want to select any markers with players inside their radius

 


Get all markers with players in <_markerdist distance to it.

private _activeMarkers = _markers select {
    private _markerPos = getmarkerpos _x;

    //Get all players inside circle of _markerdist radius around _markerPos
    //_markerdist might need to be halfed here, didn't use inAreaArray before
    private _playersInArea = allPlayers inAreaArray [_markerPos, _markerdist, _markerdist];
    count _playersInArea > 0
};

 

  • Like 2

Share this post


Link to post
Share on other sites

@Dedmen

So this work on a dedicated server correct?

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

Share this post


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

So this work on a dedicated server correct?

How often do you want me to repeat the same answer to the same question.

 

19 hours ago, Dedmen said:

Player is only valid when the script runs on a players machine.

A dedicated server is not a players machine. And the script there contains "player" thus, player is not valid, thus no it doesn't work.

Share this post


Link to post
Share on other sites
19 minutes ago, Dedmen said:

How often do you want me to repeat the same answer to the same question.

 

A dedicated server is not a players machine. And the script there contains "player" thus, player is not valid, thus no it doesn't work.

So how would the code look like for it to work on a dedicated server?

Share this post


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

So how would the code look like for it to work on a dedicated server?

Is this a joke?

 

 

 

  • Haha 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

×