Jump to content
Vectif

How to make map marker change colour based on enemy presence?

Recommended Posts

Hello. I recently played a mission in Arma 2's Private Military Company DLC which includes a similar feature (or so I believe) to something I want to replicate, and that I believe is possible.

The mission would consist of clearing a route from point A to point B. The idea would be to have map markers of designated blocks or roads / areas that are marked as red when hostile/have enemy presence within, and that they then switch to green once they've been cleared. I would also like this to count/include objects aswell (e.g. barricades that would need to be destroyed, or vehicles needing to be moved off of the road, IEDs). There would need to be multiple of these markers/areas for each block or road that needs to be cleared. This would also need to detect when enemies are not alive, or simply not present, same with objects. Is there a way to do this? Kinda like in the mission I'll link below. Also, is there a way to display trigger areas as marker areas, or do I need to individually make both?

Here is the example of the mission I'm refferencing that inspired me:
https://youtu.be/y0RdVjhsgEk?t=741

Anyone know of a way I could achieve something similar? This way the mission would be non-linear and players could choose their own path to clear. Any guidance, scripts, or code that could help would be greatly appreciated. I don't need the tasks modules for the time being, I just need to do the map markers defining whether an area is clear or not.
Thanks!

Share this post


Link to post
Share on other sites

The easiest way to achieve this would be to use BI's sector modules with triggers defining the zones you want. https://community.bistudio.com/wiki/Arma_3:_Module:_Sector

The game will automatically update the sectors and their markers depending on who effectively controls the area. The system gives you some customizability on how exactly that is determined via weights or costs per unit or vehicle. As for the objects like barricades, you could probably use BIS_fnc_moduleSector to force the area to the enemy side while a list of specific objects are present in the area.

  • Like 1

Share this post


Link to post
Share on other sites

I figured out a way of doing it by using the setMarkerColor command, and using a trigger of the same size as the marker to detect OPFOR presence, changing the colours back and forth in the activation and deactivation fields. The annoying part is when I want to make multiple of them I have to consecutively change their init fields to fit the "_X" numerical suffix scaling names plus altering the sizes on both the trigger and marker area. I will however look into the Sector Module and see if I find that more efficient/intuitive and convenient. Keep in mind I want to do this mostly for roads, without tasks nor names assigned to them nor any other markers aside from the map, which I'm not sure if it's possible via the sector module.

Share this post


Link to post
Share on other sites

I could most likely write a script for you that should take care of all that automatically. All you would need to do is set up triggers with the sizes you want and the script would generate the accompanying marker and handle the color. I'll see what I can come up with and post it back here for you.

  • Like 1

Share this post


Link to post
Share on other sites

All right, so I managed to put something together. The following script will automatically register all triggers you put down with a certain variable name stem (in this case, all triggers that start with "ALP_area" are counted), creating the necessary markers in accordance to the triggers' dimensions and orientation. It then checks every five seconds inside the trigger area for enemies and 'blacklisted' items, turning the marker red if it detects any and green if not. You are able to customize the blacklists however you see fit, so you could have an IED turn the marker red, but a NATO Apers mine leaving it green, for instance.

 

All you have to do to put it into your mission is to create a script file in your mission directory called ALP_areaMarkers.sqf — then put the following code inside.

Spoiler

// PARAMETERS

// Mine blacklist (if any are present the marker will turn red!)

ALP_hostileMines = ["IEDLandBig_Remote_Ammo", "IEDUrbanBig_Remote_Ammo", "IEDLandSmall_Remote_Ammo", "IEDUrbanSmall_Remote_Ammo"];

// Object blacklist (ditto, but with barricades and other such things. This one might be problematic considering some are not destructible)

ALP_hostileObjects = ["Land_Barricade_01_10m_F", "Land_Barricade_01_4m_F", "Land_SandbagBarricade_01_half_F", "Land_SandbagBarricade_01_F", "Land_SandbagBarricade_01_hole_F"];

// Vehicle blacklist (types of cars and whatnot that you would need to move away for the marker to turn green. Should ideally include all enemy vehicle types)

ALP_hostileVehicles = ["I_G_Offroad_01_F", "I_G_Offroad_01_armed_F"];

// BEGIN SCRIPT

// Detect and register all area triggers

ALP_triggerArray = [];
{
	_name = format ["%1", _x];
	if ("ALP_area" in _name) then
	{
		ALP_triggerArray pushBack _x;
	};
} forEach (allMissionObjects "EmptyDetector");

{
  
  	// Set up markers in accordance to trigger dimensions

	_ALP_areaMarkerName = format ["%1_marker", _x];
	_ALP_areaMarkerSize = triggerArea _x;
	_ALP_areaMarker = createMarker [_ALP_areaMarkerName, _x];
	_ALP_areaMarker setMarkerShapeLocal (if (_ALP_areaMarkerSize select 3) then {"RECTANGLE"} else {"ELLIPSE"});
	_ALP_areaMarker setMarkerColorLocal "ColorRed";
	_ALP_areaMarker setMarkerSizeLocal  [(_ALP_areaMarkerSize select 0), (_ALP_areaMarkerSize select 1)];
	_ALP_areaMarker setMarkerDirLocal (_ALP_areaMarkerSize select 2);
	_ALP_areaMarker setMarkerAlphaLocal 0.75;
	_ALP_areaMarker setMarkerBrush "Grid"; // Several looks are available, feel free to change
	
	_x setVariable ["marker",_ALP_areaMarkerName]; // Store marker into trigger variable set for convenience
	
  	// Spawn monitoring script per trigger
  
	_ALP_manageArea = [_x] spawn
	{
		params ["_trigger"];			 // Define trigger
		_marker = _trigger getVariable "marker"; // Define respective marker
		
		while {true} do // Infinite loop (this way areas can be recaptured by hostiles)
		{
			_enemyCount = count ((entities "CAManBase" inAreaArray _trigger) select {side _x == east});	// Count all enemy infantry
			_IEDCount = count ((allMines inAreaArray _trigger) select {typeOf _x in ALP_hostileMines}); // Count all blacklisted IEDs
			_vehicleCount = count ((vehicles inAreaArray _trigger) select {typeOf _x in ALP_hostileVehicles}); // Count all blacklisted vehicles
			
			_areaSize = selectMax [(triggerArea _trigger) select 0, (triggerArea _trigger) select 1];	// Get max trigger dimensions
			_buildings = _trigger nearObjects ["Building", _areaSize];					// Get all buildings in area
			_validBuildings = _buildings select {((getPos _x) inArea (_trigger)) AND (typeOf _x in ALP_hostileObjects)}; // Filter buildings in trigger
			
			_objectCount = count _validBuildings;	// Count all blacklisted buildings
			
			if ((_enemyCount > 0) OR (_IEDCount > 0) OR (_objectCount > 0) OR (_vehicleCount > 0)) then
			{
				_marker setMarkerColor "ColorRed";	// Set marker red if any of the above are present
			}
			else
			{
				_marker setMarkerColor "ColorGreen"; // Set marker green if clear
			};
			
			sleep 5; // wait five seconds before updating (Feel free to adjust)
		};
	};
	
} forEach ALP_triggerArray; // Repeat process for each individual trigger

 

 

Afterwards, create an init.sqf file if you haven't already and place the following inside:

if (isServer) then
{
	nul = [] execVM "ALP_areaMarkers.sqf";
};

In terms of mission set-up, all you need to do is place down triggers (You don't need to put down any markers!) and name them ALP_area_1, ALP_area_2, ALP_area_3, and so on. The script takes care of the rest. (You could even call them ALP_area_foo, ALP_area_bar, or anything else. The important part is just the stem)

 

This is how it should look in the editor:

UCfXn5h.jpg?1

 

And this is the result in-game with some areas hostile and some cleared:

 

aoqrbzL.jpg?1

 

Hope this helps! If you have any questions or run into any issues please don't hesitate to let me know!

  • Thanks 1

Share this post


Link to post
Share on other sites

Oh I forgot to mention that the script allows for the areas to be of any size and any shape, so you can have elliptical areas as well!

Share this post


Link to post
Share on other sites
On 4/1/2021 at 10:34 AM, Rhaonoa said:

Hello. I recently played a

 

Place 2 markers on the map.  Set one as red and size 3.  Set the other as blue and size 0.  (When it is size 0 is is invisible and cannot be seen).

 

Start the mission.  Note you can see one red marker and no blue marker.

 

Create a trigger. When the trigger is fired, change the size of the red marker to zero and the size of the blue marker to 3. Now you can see one blue marker and no red markers.

 

Summary,

instead of adding new markers with a trigger, change the size of existing markers with a trigger.

 

 

Share this post


Link to post
Share on other sites
25 minutes ago, Joe98 said:

 

Place 2 markers on the map.  Set one as red and size 3.  Set the other as blue and size 0.  (When it is size 0 is is invisible and cannot be seen).

 

 

It would be so much easier just to change the marker colour though: https://community.bistudio.com/wiki/setMarkerColor

Otherwise you're dealing with twice as many markers as you need?

  • Like 1

Share this post


Link to post
Share on other sites

Well yes the marker colour can be changed with a trigger 

 

But the only way to make a marker invisible is to make the size zero.

.

 

Share this post


Link to post
Share on other sites

@Joe98 you can set the markers alpha to 0, retaining its size, and is perhaps the best way to hide a marker (especially if it's needed for any inArea checks). But there's no need to hide any markers in this case anyway. 

Share this post


Link to post
Share on other sites
12 hours ago, alpha993 said:

All right, so I managed to put something together. The following script will automatically register all triggers you put down with a certain variable name stem (in this case, all triggers that start with "ALP_area" are counted), creating the necessary markers in accordance to the triggers' dimensions and orientation. It then checks every five seconds inside the trigger area for enemies and 'blacklisted' items, turning the marker red if it detects any and green if not. You are able to customize the blacklists however you see fit, so you could have an IED turn the marker red, but a NATO Apers mine leaving it green, for instance.

 

All you have to do to put it into your mission is to create a script file in your mission directory called ALP_areaMarkers.sqf — then put the following code inside.

  Reveal hidden contents


// PARAMETERS

// Mine blacklist (if any are present the marker will turn red!)

ALP_hostileMines = ["IEDLandBig_Remote_Ammo", "IEDUrbanBig_Remote_Ammo", "IEDLandSmall_Remote_Ammo", "IEDUrbanSmall_Remote_Ammo"];

// Object blacklist (ditto, but with barricades and other such things. This one might be problematic considering some are not destructible)

ALP_hostileObjects = ["Land_Barricade_01_10m_F", "Land_Barricade_01_4m_F", "Land_SandbagBarricade_01_half_F", "Land_SandbagBarricade_01_F", "Land_SandbagBarricade_01_hole_F"];

// Vehicle blacklist (types of cars and whatnot that you would need to move away for the marker to turn green. Should ideally include all enemy vehicle types)

ALP_hostileVehicles = ["I_G_Offroad_01_F", "I_G_Offroad_01_armed_F"];

// BEGIN SCRIPT

// Detect and register all area triggers

ALP_triggerArray = [];
{
	_name = format ["%1", _x];
	if ("ALP_area" in _name) then
	{
		ALP_triggerArray pushBack _x;
	};
} forEach (allMissionObjects "EmptyDetector");

{
  
  	// Set up markers in accordance to trigger dimensions

	_ALP_areaMarkerName = format ["%1_marker", _x];
	_ALP_areaMarkerSize = triggerArea _x;
	_ALP_areaMarker = createMarker [_ALP_areaMarkerName, _x];
	_ALP_areaMarker setMarkerShapeLocal (if (_ALP_areaMarkerSize select 3) then {"RECTANGLE"} else {"ELLIPSE"});
	_ALP_areaMarker setMarkerColorLocal "ColorRed";
	_ALP_areaMarker setMarkerSizeLocal  [(_ALP_areaMarkerSize select 0), (_ALP_areaMarkerSize select 1)];
	_ALP_areaMarker setMarkerDirLocal (_ALP_areaMarkerSize select 2);
	_ALP_areaMarker setMarkerAlphaLocal 0.75;
	_ALP_areaMarker setMarkerBrush "Grid"; // Several looks are available, feel free to change
	
	_x setVariable ["marker",_ALP_areaMarkerName]; // Store marker into trigger variable set for convenience
	
  	// Spawn monitoring script per trigger
  
	_ALP_manageArea = [_x] spawn
	{
		params ["_trigger"];			 // Define trigger
		_marker = _trigger getVariable "marker"; // Define respective marker
		
		while {true} do // Infinite loop (this way areas can be recaptured by hostiles)
		{
			_enemyCount = count ((entities "CAManBase" inAreaArray _trigger) select {side _x == east});	// Count all enemy infantry
			_IEDCount = count ((allMines inAreaArray _trigger) select {typeOf _x in ALP_hostileMines}); // Count all blacklisted IEDs
			_vehicleCount = count ((vehicles inAreaArray _trigger) select {typeOf _x in ALP_hostileVehicles}); // Count all blacklisted vehicles
			
			_areaSize = selectMax [(triggerArea _trigger) select 0, (triggerArea _trigger) select 1];	// Get max trigger dimensions
			_buildings = _trigger nearObjects ["Building", _areaSize];					// Get all buildings in area
			_validBuildings = _buildings select {((getPos _x) inArea (_trigger)) AND (typeOf _x in ALP_hostileObjects)}; // Filter buildings in trigger
			
			_objectCount = count _validBuildings;	// Count all blacklisted buildings
			
			if ((_enemyCount > 0) OR (_IEDCount > 0) OR (_objectCount > 0) OR (_vehicleCount > 0)) then
			{
				_marker setMarkerColor "ColorRed";	// Set marker red if any of the above are present
			}
			else
			{
				_marker setMarkerColor "ColorGreen"; // Set marker green if clear
			};
			
			sleep 5; // wait five seconds before updating (Feel free to adjust)
		};
	};
	
} forEach ALP_triggerArray; // Repeat process for each individual trigger

 

 

Afterwards, create an init.sqf file if you haven't already and place the following inside:


if (isServer) then
{
	nul = [] execVM "ALP_areaMarkers.sqf";
};

In terms of mission set-up, all you need to do is place down triggers (You don't need to put down any markers!) and name them ALP_area_1, ALP_area_2, ALP_area_3, and so on. The script takes care of the rest. (You could even call them ALP_area_foo, ALP_area_bar, or anything else. The important part is just the stem)

 

This is how it should look in the editor:

UCfXn5h.jpg?1

 

And this is the result in-game with some areas hostile and some cleared:

 

aoqrbzL.jpg?1

 

Hope this helps! If you have any questions or run into any issues please don't hesitate to let me know!


Thank you very much for taking the time to do this! This is very interesting! I will be playing around with it, very nice of you! Once again, thank you!

  • Like 1

Share this post


Link to post
Share on other sites

My pleasure!

 

Just a note based on the other comments: my script uses triggers because they are visible both in the 2D and 3D views of the editor, which in my experience makes it a little easier to work with the areas. However, if you don't need the 3D view you can just place the markers in the editor and edit the script to use them directly instead of spawning them.

Share this post


Link to post
Share on other sites
On 4/2/2021 at 2:17 PM, alpha993 said:

 

I am trying to adopt this to make a colored area objective. I can't seem to grasp it:

 

Spoiler

// BEGIN SCRIPT

// Detect and register all area triggers

ALP_triggerArray = [];
{
    _name = format ["%1", _x];
    if ("ALP_area" in _name) then
    {
        ALP_triggerArray pushBack _x;
    };
} forEach (allMissionObjects "EmptyDetector");

{
      _ALP_areaMarkerName = format ["%1_marker", _x];
    _ALP_areaMarkerSize = triggerArea _x;
    _ALP_areaMarker = createMarker [_ALP_areaMarkerName, _x];
    _ALP_areaMarker setMarkerShapeLocal (if (_ALP_areaMarkerSize select 3) then {"RECTANGLE"} else {"ELLIPSE"});
    _ALP_areaMarker setMarkerColorLocal "ColorBlack";
    _ALP_areaMarker setMarkerSizeLocal  [(_ALP_areaMarkerSize select 0), (_ALP_areaMarkerSize select 1)];
    _ALP_areaMarker setMarkerDirLocal (_ALP_areaMarkerSize select 2);
    _ALP_areaMarker setMarkerAlphaLocal 0.75;
    _ALP_areaMarker setMarkerBrush "Solid"; // Several looks are available, feel free to change
    _x setVariable ["marker",_ALP_areaMarkerName]; // Store marker into trigger variable set for convenience
    
      
  
    _ALP_manageArea = [_x] spawn
    {
        params ["_trigger"];             // Define trigger
        _marker = _trigger getVariable "marker"; // Define respective marker
        
        while {true} do // Infinite loop (this way areas can be recaptured by hostiles)
        {
            _opforCount = count ((entities "CAManBase" inAreaArray _trigger) select {side _x == east});    // Count all opfor
            _bluforCount = count ((entities "CAManBase" inAreaArray _trigger) select {side _x == west});    // Count all blufor
            _areaSize = selectMax [(triggerArea _trigger) select 0, (triggerArea _trigger) select 1];    // Get max trigger dimensions
            
            
            if (_opforCount > _bluforCount) then
            {
                _marker setMarkerColor "ColorRed";    // Set marker red 
            }
            else
            {
                if (_opforCount < _bluforCount) then
                {
                    _marker setMarkerColor "Colorblue";    // Set marker blue
                }
                else
                {
                    if (_opforCount == _bluforCount) then
                    {
                    _marker setMarkerColor "ColorCIV";    // Set marker purple
                    }
                    else _marker setMarkerColor "ColorBlack";    // Set marker blue
                };
            }
        };        
            
            sleep 5; // wait five seconds before updating (Feel free to adjust)
            
        
    }
    
} forEach ALP_triggerArray; 

    };
    
} forEach ALP_triggerArray; // Repeat process for each individual trigger

 

 

 

Share this post


Link to post
Share on other sites

Could you provide some more details on what exactly you want to accomplish? I'd be happy to help!

Share this post


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

Could you provide some more details on what exactly you want to accomplish? I'd be happy to help!

I DMed you

  • 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

×