Jump to content
Sign in to follow this  
Kolmain

Insurgency Style Markers & BIS Respawn Points

Recommended Posts

Hi again BIS fans,

I've got two scripting questions:

1) Does anyone have any idea how to turn the map grid your are in a certain color with a marker, like in the the ARMA2 insurgency and EOS scripts? I can create the marker but I'm not sure how to align it to the grid. I'd like to color each map grid the color of the units in it.

2) How do you name a respawn point using BIS' respawn system via script? I've used the functions to add my vehicle as a respawn point, but it's name is AI: AI Name. Any idea how I can change that to a string of my choice?

Thanks! :)

Share this post


Link to post
Share on other sites

For your #1, I'm unsure of any exact way to place a marker in the exact center of a grid, but you could get it close with just the normal editor. Then for the changing of colors you would have to write a script that creates triggers based on the marker size and then have a switch case structure for those triggers based on who is present.

And then obviously put that into a while loop that checks every few seconds.

Edited by JShock

Share this post


Link to post
Share on other sites

For your #2, you could just use setName, but if that doesn't work setIdentity should do it.

EDIT: Actually my method will probably make it something like AI: Your Name. Don't know how to change the whole string.

Edited by 654wak654

Share this post


Link to post
Share on other sites

Pretty simple actually.

- The setpos coordinates are in meters.

- The map uses gridsquares with 100m sidelength.

Now there are two ways in which you could do this.

1. create triggers for every gridsquare (that is probably quite performance hungry)

2. loop through all units, get the gridsquare they're in and generate markers accordingly (that should be more effective)

Something like this should work (untested):

if (!isServer) exitWith {};
private ["_pos","_px","_py","_nam","_col"];
gridmarkers = [];
while { true } do {
   {deleteMarker _x;} count gridmarkers;
   gridmarkers = [];
   {
       if ( !((side _x) isEqualTo civilian) ) then {
           _pos = getPosATL _x;
           _px = floor ( (_pos select 0) / 100);
           _py = floor ( (_pos select 1) / 100);
           _nam = format["grid_%1_%2",_px,_py];
           _col = format["Color%1",side _x];

           if ( (markerShape _nam) isEqualTo "RECTANGLE" ) then {
               if ( !((markerColor _nam) isEqualTo _col) ) then {
                   _nam setMarkerColor "ColorOrange";
               };
           } else {
               createMarker[_nam,[(_px*100)+50,(_py*100)+50,0]];
               _nam setMarkerShape "RECTANGLE";
               _nam setMarkerSize [50,50];
               _nam setMarkerColor _col;
               gridmarkers pushBack _nam;
           };
       };
       true
   } count allUnits;
   sleep 10;
};

//

Put it in a scriptfile and execVM it from your init.sqf

Civilians are ignored.

If units from differend sides are present, the color is set to orange to indicate a contested gridsquare.

If you're concerned about network load, you could also change the commands to their local counterparts and let the script run on every client.

Edited by Tajin
fixed
  • Like 1

Share this post


Link to post
Share on other sites
Pretty simple actually.

- The setpos coordinates are in meters.

- The map uses gridsquares with 100m sidelength.

Now there are two ways in which you could do this.

1. create triggers for every gridsquare (that is probably quite performance hungry)

2. loop through all units, get the gridsquare they're in and generate markers accordingly (that should be more effective)

Something like this should work (untested):

if (!isServer) exitWith {};
private ["_gridmarkers","_pos","_px","_py","_nam","_col"];
_gridmarkers = [];
while { true } do {
   {deleteMarker _x;} count _gridmarkers;
   _gridmarkers = [];
   {
       if ( !((side _x) isEqualTo civilian) ) then {
           _pos = getPosATL _x;
           _px = floor ( (_pos select 0) / 100);
           _py = floor ( (_pos select 1) / 100);
           _nam = format["grid_%1_%2",_px,_py];
           _col = format["Color%1",side _x];

           if ( (_nam markerShape) isEqualTo "RECTANGLE" ) then {
               if ( (markerColor _nam) isEqualTo _col ) then {
                   // nothing
               } else {
                   _nam setMarkerColor "ColorOrange"; // contested
               };
           } else {
               createMarker[_nam,[_px+50,_py+50,0]];
               _nam setMarkerShape "RECTANGLE";
               _nam setMarkerSize [100,100];
               _nam setMarkerColor _col;
               _gridmarkers pushBack _nam;
           };
       };
   } count allUnits;
   sleep 10;
};

//

Put it in a scriptfile and execVM it from your init.sqf

Civilians are ignored.

If units from differend sides are present, the color is set to orange to indicate a contested gridsquare.

If you're concerned about network load, you could also change the commands to their local counterparts and let the script run on every client.

Thanks for the help Tajin, but why are you using count instead of ForEach?

---------- Post added at 14:12 ---------- Previous post was at 14:01 ----------

Actually, that's going to spazz out when there are different units from different sides in the same grid right?

Share this post


Link to post
Share on other sites
Actually, that's going to spazz out when there are different units from different sides in the same grid right?

No, it should just turn orange when multiple sides are within the same grid square?

Share this post


Link to post
Share on other sites
No, it should just turn orange when multiple sides are within the same grid square?

Derp. Completely missed the orange line. So if I'm reading this correctly then it would never switch back to a side color once contested?

EDIT: I see. You're deleting the marker and recreating it, tracking the unit individually. Okay.

Edited by Kolmain

Share this post


Link to post
Share on other sites

Oh it should – the markers get cleaned up and then re-generated in each cycle.

ps.: Tested it now, fixed a few typos – works great. :)

pps.: Additionally, here is the local version I was talking off. Probably better to use this, as it significantly reduces the network load.

		private ["_pos","_px","_py","_nam","_col"];
	gridmarkers = [];
	startAlpha = 0.2;
	changeAlpha = 0.2;
	while { true } do {
		{deleteMarkerLocal _x;} count gridmarkers;
		gridmarkers = [];
		{
			if ( !((side _x) isEqualTo civilian) ) then {
				_pos = getPosATL _x;
				_px = floor ( (_pos select 0) / 100);
				_py = floor ( (_pos select 1) / 100);
				_nam = format["grid_%1_%2",_px,_py];
				_col = format["Color%1",side _x];

				if ( (markerShape _nam) isEqualTo "RECTANGLE" ) then {
					if ( ((markerColor _nam) isEqualTo _col) ) then {
						_nam setMarkerAlphaLocal ( (markerAlpha _nam) + changeAlpha);
					} else {
						_nam setMarkerColorLocal "ColorOrange";
						_nam setMarkerAlphaLocal ( (markerAlpha _nam) + changeAlpha);
					};
				} else {
					createMarkerLocal[_nam,[(_px*100)+50,(_py*100)+50,0]];
					_nam setMarkerShapeLocal "RECTANGLE";
					_nam setMarkerSizeLocal [50,50];
					_nam setMarkerColorLocal _col;
					_nam setMarkerAlpha startAlpha;
					gridmarkers pushBack _nam;
				};
			};
			true
		} count allUnits;
		sleep 10;
	};

In this version, the opacity of the marker depends on the number of units in it. With 1 unit it will be barely visible. At 5 or more units, the marker is shown in full strength. Just modify the "startAlpha" and "changeAlpha" variable to your liking.

http://img.rising.at/107410_screenshots_2014-11-20_00002.jpg (247 kB)

Edited by Tajin
smile

Share this post


Link to post
Share on other sites

Any particular reason why you took out the count loop for all units? Because the count loop, at least how I understood it, went through all units making sure to update every unit's position as they moved around, changing/creating markers as it loops, so I'm not sure just checking one unit will work the way your wanting it too?

Edited by JShock

Share this post


Link to post
Share on other sites

The code I originally posted wasn't tested and contained a few minor bugs.

I've updated that post already, so copy it again or use the clientside version from my other post.

Both are tested and work fine. (the smilie proves it ^^)

ps.: As Dreaded already stated, don't remove the count. Trust the code :)

Unless (and your function looks that way) you want to run it for specific units/groups only. In which case you'll have to change more than that.

If you want it to check only a certain selection of units, the easiest way is to replace "allUnits" with a global array. Then simply add the units that should be checked to that array.

Edited by Tajin

Share this post


Link to post
Share on other sites
The code I originally posted wasn't tested and contained a few minor bugs.

I've updated that post already, so copy it again or use the clientside version from my other post.

Both are tested and work fine. (the smilie proves it ^^)

ps.: As Dreaded already stated, don't remove the count. Trust the code :)

Unless (and your function looks that way) you want to run it for specific units/groups only. In which case you'll have to change more than that.

If you want it to check only a certain selection of units, the easiest way is to replace "allUnits" with a global array. Then simply add the units that should be checked to that array.

Thanks for the clarification Tajin. I'm trying to run it for the leader of every group I spawn. So whenever I spawn a group I spawn [(leader group)] spawn KOL_fnc_gridMarkers;

Share this post


Link to post
Share on other sites

I see what you're trying to do.

I just don't know why you'd want to do that and what you want to achieve with it.

Just keep the script running in one loop. Then...

a) replace "allUnits" with a custom array

If you want it to check only a certain selection of units, the easiest way is to replace "allUnits" with a global array. Then simply add the units that should be checked to that array.

or

b) add a condition inside the count, so it ignores for example everyone on opfor or whatever you want.

If you want it for all blufor units, then theres no point in spawning it separately for each group.

You could even set it up so it only considers units that have a specific object-variable set and ignores everything else.

Share this post


Link to post
Share on other sites
I see what you're trying to do.

I just don't know why you'd want to do that and what you want to achieve with it.

Just keep the script running in one loop. Then...

a) replace "allUnits" with a custom array

or

b) add a condition inside the count, so it ignores for example everyone on opfor or whatever you want.

If you want it for all blufor units, then theres no point in spawning it separately for each group.

You could even set it up so it only considers units that have a specific object-variable set and ignores everything else.

Okay, does count work or do I need to use forEach?

Also, do I need to spawn this in BIS_fnc_mp or can it just be run on the server?

Share this post


Link to post
Share on other sites

Do you think I would've used "count" if it didn't work? ;)

Count does pretty much the same thing as forEach, only faster.

Also, do I need to spawn this in BIS_fnc_mp or can it just be run on the server?

The first version I posted only has to run on the server but that isn't really optimal.

You can simply put the local-version in the init.sqf to have it run on every client.

Share this post


Link to post
Share on other sites
Do you think I would've used "count" if it didn't work? ;)

Count does pretty much the same thing as forEach, only faster.

The first version I posted only has to run on the server but that isn't really optimal.

You can simply put the local-version in the init.sqf to have it run on every client.

I never knew that! I thought count return integers :confused:

Thanks for the help, I'll try the clientside version tonight.

Share this post


Link to post
Share on other sites

It still does return integers, but who said you need to use that return value :p. But yea both count and forEach still filter through code exactly the same way otherwise :D.

Share this post


Link to post
Share on other sites

Pretty simple actually.

- The setpos coordinates are in meters.

- The map uses gridsquares with 100m sidelength.

Now there are two ways in which you could do this.

1. create triggers for every gridsquare (that is probably quite performance hungry)

2. loop through all units, get the gridsquare they're in and generate markers accordingly (that should be more effective)

Something like this should work (untested):

if (!isServer) exitWith {};
private ["_pos","_px","_py","_nam","_col"];
gridmarkers = [];
while { true } do {
{deleteMarker _x;} count gridmarkers;
gridmarkers = [];
{
if ( !((side _x) isEqualTo civilian) ) then {
_pos = getPosATL _x;
_px = floor ( (_pos select 0) / 100);
_py = floor ( (_pos select 1) / 100);
_nam = format["grid_%1_%2",_px,_py];
_col = format["Color%1",side _x];

if ( (markerShape _nam) isEqualTo "RECTANGLE" ) then {
if ( !((markerColor _nam) isEqualTo _col) ) then {
_nam setMarkerColor "ColorOrange";
};
} else {
createMarker[_nam,[(_px*100)+50,(_py*100)+50,0]];
_nam setMarkerShape "RECTANGLE";
_nam setMarkerSize [50,50];
_nam setMarkerColor _col;
gridmarkers pushBack _nam;
};
};
true
} count allUnits;
sleep 10;
};

//

Put it in a scriptfile and execVM it from your init.sqf

Civilians are ignored.

If units from differend sides are present, the color is set to orange to indicate a contested gridsquare.

If you're concerned about network load, you could also change the commands to their local counterparts and let the script run on every client.

 

Dear Tajin,

 

I would sooooooo love to include it in an addaction in a way tht it highlights these positions only for 10 seconds and then completely stop the find marker loop to save performance :)

I am waiting man.

 

Thank you.

Share this post


Link to post
Share on other sites

 

On 11/20/2014 at 9:27 PM, Tajin said:

Oh it should – the markers get cleaned up and then re-generated in each cycle.

ps.: Tested it now, fixed a few typos – works great. :)

pps.: Additionally, here is the local version I was talking off. Probably better to use this, as it significantly reduces the network load.

 


		private ["_pos","_px","_py","_nam","_col"];
	gridmarkers = [];
	startAlpha = 0.2;
	changeAlpha = 0.2;
	while { true } do {
		{deleteMarkerLocal _x;} count gridmarkers;
		gridmarkers = [];
		{
			if ( !((side _x) isEqualTo civilian) ) then {
				_pos = getPosATL _x;
				_px = floor ( (_pos select 0) / 100);
				_py = floor ( (_pos select 1) / 100);
				_nam = format["grid_%1_%2",_px,_py];
				_col = format["Color%1",side _x];

				if ( (markerShape _nam) isEqualTo "RECTANGLE" ) then {
					if ( ((markerColor _nam) isEqualTo _col) ) then {
						_nam setMarkerAlphaLocal ( (markerAlpha _nam) + changeAlpha);
					} else {
						_nam setMarkerColorLocal "ColorOrange";
						_nam setMarkerAlphaLocal ( (markerAlpha _nam) + changeAlpha);
					};
				} else {
					createMarkerLocal[_nam,[(_px*100)+50,(_py*100)+50,0]];
					_nam setMarkerShapeLocal "RECTANGLE";
					_nam setMarkerSizeLocal [50,50];
					_nam setMarkerColorLocal _col;
					_nam setMarkerAlpha startAlpha;
					gridmarkers pushBack _nam;
				};
			};
			true
		} count allUnits;
		sleep 10;
	};
 

 

In this version, the opacity of the marker depends on the number of units in it. With 1 unit it will be barely visible. At 5 or more units, the marker is shown in full strength. Just modify the "startAlpha" and "changeAlpha" variable to your liking.

http://img.rising.at/107410_screenshots_2014-11-20_00002.jpg (247 kB)

 

 

Great script. Do you mind if I edit and use it for some missions?

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
Sign in to follow this  

×