Jump to content
_Clockwerk

[SOLUTION] Create player markers and update location every 10 seconds

Recommended Posts

So I've been working on my first hand-written script to place markers on the map where players are every 10 seconds, with a line drawn between the squad members and the squad leader.

 

I was having some trouble with undefined variables but just making the variables private within the script got rid of that error. Now I'm stuck with a perpetual missing semi-colon error which tells me that my script is just wrong somewhere.

 

I'm very new to this and I've been scouring the examples on the biki, but just can't seem to get this to work. I can't tell if I'm just doing things out of order or defining variables in the wrong place etc., etc. ... Bottom line: I'm lost.

 

If anyone could just point out where I might be going wrong that would help.

 

And yes I realize that the game already has map markers, just humor my ridiculousness if you will.

 

//////////////Definitions//////////////
private p1 = zCurator;
private p2 = ar;
private p3 = gren;
private p4 = at;
_p1POS = getpos p1;
_p2POS = getpos p2;
_p3POS = getpos p3;
_p4POS = getpos p4;
createMarker ["mkrPos1", _p1POS];
createMarker ["mkrPos2", _p2POS];
createMarker ["mkrPos3", _p3POS];
createMarker ["mkrPos4", _p4POS];
_p1Array = [p1, "mkrPos1", _p1POS];
_p2Array = [p2, "mkrPos2", _p2POS];
_p3Array = [p3, "mkrPos3", _p3POS];
_p4Array = [p4, "mkrPos4", _p4POS];
_delta = [p1,p2,p3,p4];
_deltaUnder = [p2,p3,p4];

//////////////Draw black lines between squad members and squad leader//////////////

{
while {alive p1} do {
(_this select 0) drawLine [_x,p1,[0,0,0,1]];
		sleep 10;
};
} forEach _deltaUnder;

//////////////Create and set approximate locations of players//////////////

_posMarkers = ["mkrPos1","mkrPos2","mkrPos3","mkrPos4"];

{
	_x setMarkerType "mil_dot_noShadow";
	_x setMarkerColor "#(0,0,1,1)";
} forEach _posMarkers;

//////////////Update player location markers every 10 seconds//////////////
{
while {alive _x select 0} do {
	(_x select 1) setMarkerPos (_x select 2);
	sleep 10;
};
} forEach [_p1Array, _p2Array, _p3Array, _p4Array];

 

EDIT: Spent the 6 hours between this post and now trying to diagnose this. I managed to clear all errors after about an hour, but the script still wasn't working. I found drawLine to be a lost cause to I just settled for map icons that update every 10 seconds. Here's the code if anyone is interested. p1-p4 assignments are just the variable names I gave to each of my squad members (Squad Lead, Auto Rifleman, Grenadier, Anti-Tank).

 

_p1 = zCurator;
_p2 = ar;
_p3 = gren;
_p4 = at;
_p1POS = getPos _p1;
_p2POS = getPos _p2;
_p3POS = getPos _p3;
_p4POS = getPos _p4;
_mkr1 = createMarker ["mkrPos1", _p1POS];
_mkr2 = createMarker ["mkrPos2", _p2POS];
_mkr3 = createMarker ["mkrPos3", _p3POS];
_mkr4 = createMarker ["mkrPos4", _p4POS];
_posMarkers = [_mkr1,_mkr2,_mkr3,_mkr4];

	{
	_x setMarkerType "mil_dot_noShadow";
	_x setMarkerShape "ICON";
	_x setMarkerColor "ColorBlue";
	} forEach _posMarkers;

sleep 2;
	
	while {isServer} do {
	_mkr1 setMarkerPos (getPos _p1);
	_mkr2 setMarkerPos (getPos _p2);
	_mkr3 setMarkerPos (getPos _p3);
	_mkr4 setMarkerPos (getPos _p4);
	sleep 10;
	};

 

 

EDIT 2: Noticed that the script was stopping after respawn or death, referencing the players' positions as an array seems to have fixed that.

 

_p1 = zCurator;
_p2 = ar;
_p3 = gren;
_p4 = at;
_p1POS = getPos _p1;
_p2POS = getPos _p2;
_p3POS = getPos _p3;
_p4POS = getPos _p4;
_mkr1 = createMarker ["mkrPos1", _p1POS];
_mkr2 = createMarker ["mkrPos2", _p2POS];
_mkr3 = createMarker ["mkrPos3", _p3POS];
_mkr4 = createMarker ["mkrPos4", _p4POS];
_posMarkers = [_mkr1,_mkr2,_mkr3,_mkr4];

	{
	_x setMarkerType "mil_dot_noShadow";
	_x setMarkerShape "ICON";
	_x setMarkerColor "ColorBlue";
	} forEach _posMarkers;

sleep 2;
	
	while {isServer} do {
	_mkr1 setMarkerPos (getPos (units group player select 0));
	_mkr2 setMarkerPos (getPos (units group player select 1));
	_mkr3 setMarkerPos (getPos (units group player select 2));
	_mkr4 setMarkerPos (getPos (units group player select 3));
	sleep 5;
	};

 

  • Like 1

Share this post


Link to post
Share on other sites

The code could be optimized. Could you send the "ideal" picture of what you want to update every 10 seconds? i.e. multiplayer? all played sides? For each sides? with different colors? with texts? ....

Share this post


Link to post
Share on other sites
On 11/15/2024 at 11:42 AM, pierremgi said:

The code could be optimized. Could you send the "ideal" picture of what you want to update every 10 seconds? i.e. multiplayer? all played sides? For each sides? with different colors? with texts? ....

 

I would definitely like to optimize the code and potentially add some more information to the markers, but I was struggling just with creating them and updating their position so I didn't bother.

 

As of right now the only information being updated every 10 seconds (I ended up setting it for 5, but that's not really relevant) is the location of the markers created within the script. My mission is 4 player coop (all slots on NATO) with no civs. I considered adding text to the markers via:

 

{

_x setMarkerText str _x;

}

 

But the text crowded the screen and become unreadable when players were close to each other. Which segues into a related problem: I was also really struggling to find a way to "consolidate" the markers when all players are close to each other. As in, when the players are spaced out, they'll each have their own individual marker, but when they get close to each other their individual markers will be deleted in place of one group marker.

 

Maybe you could give some advice?

 

EDIT: I worked a little bit more on it and got it into a state that I'm happy with. The script now occludes individual markers when the players are grouped up near the squad leader and shows when a player is incapacitated. Probably still far from optimized, but it works.

 

private _nOfPlayers = count units group player;
_p1POS = getPos zCurator;
_p2POS = getPos ar;
_p3POS = getPos gren;
_p4POS = getPos at;
_mkr1 = createMarker ["mkrPos1", _p1POS];
_mkr2 = createMarker ["mkrPos2", _p2POS];
_mkr3 = createMarker ["mkrPos3", _p3POS];
_mkr4 = createMarker ["mkrPos4", _p4POS];
_mkr2Array = [ar, _mkr2];
_mkr3Array = [gren, _mkr3];
_mkr4Array = [at, _mkr4];
_mkrArrays = [_mkr2Array, _mkr3Array, _mkr4Array];
_posMarkers = [_mkr1,_mkr2,_mkr3,_mkr4];

	{
	_x setMarkerType "mil_dot_noShadow";
	_x setMarkerShape "ICON";
	_x setMarkerColor "ColorWEST";
	} forEach _posMarkers;

sleep 2;
	
	while {isServer && _nOfPlayers == 4} do {
	{
		if ((getMarkerPos _mkr1) distance2D (getMarkerPos _x) < 30) then {
			_x setMarkerAlpha 0.25;
		} else {
			_x setMarkerAlpha 1;
		};
	} forEach [_mkr2, _mkr3, _mkr4];

	if (markerAlpha _mkr2 == 0.25 || markerAlpha _mkr3 == 0.25 || markerAlpha _mkr4 == 0.25) then {
		_mkr1 setMarkerText "Delta Squad";
		_mkr1 setMarkerType "b_inf";
	} else {
		_mkr1 setMarkerText "";
		_mkr1 setMarkerType "mil_dot_noShadow";
	};

	if ([zCurator] call ace_common_fnc_isAwake == false) then {
		_mkr1 setMarkerColor "ColorRed";
		_mkr1 setMarkerType "mil_dot_noShadow";
		_mkr1 setMarkerText "Man Down!";
		{
			_x setMarkerAlpha 1;
		} forEach [_mkr2, _mkr3, _mkr4];
	} else {
		_mkr1 setMarkerColor "ColorWEST";
	};

	{
		if ([_x select 0] call ace_common_fnc_isAwake == false) then {
			_x select 1 setMarkerColor "ColorRed";
			_x select 1 setMarkerType "mil_dot_noShadow";
			_x select 1 setMarkerAlpha 1;
			_x select 1 setMarkerText "Man Down!";
		} else {
			_x select 1 setMarkerColor "ColorWEST";
		};
	} forEach _mkrArrays;

	_mkr1 setMarkerPos zCurator;
	_mkr2 setMarkerPos ar;
	_mkr3 setMarkerPos gren;
	_mkr4 setMarkerPos at;
	
	sleep 0.01;
	};

 

Share this post


Link to post
Share on other sites

Run this code on all clients:

 

// creating markers locally. Replace playableUnits (MP) by allPlayers or even [p1,p2,p3,p4] or else  (switchableUnits is for SP (then preview) as far as playableUnits doesn't work in SP)
// creating markers locally is resource saving
{
  private _mk = createMarkerLocal [str _x, getPos _x];
  _mk setMarkerTypeLocal "mil_dot_noShadow";
  _mk setMarkerColorLocal "colorWest";
  _x setVariable ["mk",_mk];
} forEach playableUnits + switchableUnits;

// as any line on map must be drawn on each frame, you need to use the draw event handler. So use it also for refreshing the positions of the markers (marker is paired to player by a variable).

(findDisplay 12 displayCtrl 51) ctrlAddEventHandler ["Draw", {
    {
        (_this select 0) drawLine [leader _x,_x,[0,0,0,1]];
        _x getVariable ["mk",""] setMarkerPosLocal getPos _x;
    } forEach playableUnits + switchableUnits;
}];

 

 

 

Share this post


Link to post
Share on other sites
On 11/23/2024 at 1:33 AM, pierremgi said:

Run this code on all clients:

 


// creating markers locally. Replace playableUnits (MP) by allPlayers or even [p1,p2,p3,p4] or else  (switchableUnits is for SP (then preview) as far as playableUnits doesn't work in SP)
// creating markers locally is resource saving
{
  private _mk = createMarkerLocal [str _x, getPos _x];
  _mk setMarkerTypeLocal "mil_dot_noShadow";
  _mk setMarkerColorLocal "colorWest";
  _x setVariable ["mk",_mk];
} forEach playableUnits + switchableUnits;

// as any line on map must be drawn on each frame, you need to use the draw event handler. So use it also for refreshing the positions of the markers (marker is paired to player by a variable).

(findDisplay 12 displayCtrl 51) ctrlAddEventHandler ["Draw", {
    {
        (_this select 0) drawLine [leader _x,_x,[0,0,0,1]];
        _x getVariable ["mk",""] setMarkerPosLocal getPos _x;
    } forEach playableUnits + switchableUnits;
}];

 

 

 

 

Thanks! I made some small tweaks to it (and tried to get fancy with it, to no avail) and it's working great. This is the code I ended up going with: it doesn't group the players under a single marker when nearby anymore, but I think the line drawn between units serves the same purpose. I managed to work in functionality for displaying incapacitated players as well. Definitely learned a lot from this.

 

	{
		private _mk = createMarkerLocal [str _x, getpos _x];
		_mk setMarkerTypeLocal "mil_dot_noShadow";
		_mk setMarkerShapeLocal "ICON";
		_mk setMarkerColorLocal "ColorWEST";
		_mk setMarkerTextLocal roleDescription _x;
		_x setVariable ["mk",_mk];
	} forEach playableUnits + switchableUnits;

	sleep 2;

	while {isServer} do {

	{
		if ([_x] call ace_common_fnc_isAwake) then {
			str _x setMarkerColorLocal "ColorWEST";
			str _x setMarkerTextLocal roleDescription _x;
		} else {
			str _x setMarkerColorLocal "ColorRed";
			str _x setMarkerTextLocal "Man Down!";
		};
	} forEach playableUnits + switchableUnits;

	};

 

Share this post


Link to post
Share on other sites

In one of my modules (Terrain & Map interactive), I added the possibility for showing on map, traits of player's units (medic, engineer, explosive specialist) + the squad number of the units (not in code below).

This feature appears only when you scroll in, reducing bad effect of superimposed icon traits (simplified here for clarity  and no interference with my addon).

Roughly, something like that:


 

findDisplay 12 displayCtrl 51 ctrlAddEventHandler ["Draw", {
  _map = _this select 0;
  if (ctrlMapScale _map <0.03) then {
	{
      if (isNull objectParent _x) then {
        _map drawIcon [
          ["","\a3\ui_f\data\IGUI\Cfg\simpleTasks\types\heal_ca.paa"] select (_x getUnitTrait "medic"),
          [1,1,1,1],
          getPosVisual _x vectorAdd [850*ctrlMapScale _map,300 *ctrlMapScale _map,0],
          12,12,0,"",0,0,"TahomaB","right"
        ];
        _map drawIcon [
          ["","\a3\ui_f\data\IGUI\Cfg\Cursors\iconRepairVehicle_ca.paa"] select (_x getUnitTrait "engineer"),
          [0,1,0,1],
          getPosVisual _x vectorAdd [850*ctrlMapScale _map,0,0],
          12,12,0,"",2,0,"TahomaB","right"
        ];
        _map drawIcon [
          ["","\a3\ui_f\data\IGUI\Cfg\simpleTasks\types\destroy_ca.paa"] select (_x getUnitTrait "explosiveSpecialist"),
          [1,0,0,1],
          getPosVisual _x vectorAdd [850*ctrlMapScale _map,-300 *ctrlMapScale _map,0],
          12,12,0,"",0,0,"TahomaB","right"
        ];
      };
    } forEach (units player select {_x == effectiveCommander vehicle _x});
  };
}];

 

In addon (see picture):

Zoomed out (units are too close):

ArmA-3-Screenshot-2024.11.24-10.05.20.84

 

 

Zoomed in (traits and numbers displayed):

 

ArmA-3-Screenshot-2024.11.24-10.05.45.65

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

×