Jump to content
Sign in to follow this  
Tankbuster

Removing a bunch of markers

Recommended Posts

Guys,

My engineers are shown the position of the IEDs in my mission by localmarkers on their maps, but as these change during the course of the game - some are defused/go off/new ones discovered, I've had trouble keeping the map updated. In any case, I don't like the map to be that dynamic.

So, the engineers are allowed to occasionally request an intel update which shows them all known IEDs at that point in time, and that works fine, but what I'd like to do is clear their maps of IED markers before drawing the new ones.

Here's my ied marker removal code;

"centre" is a marker cunningly positioned in the middle of the (takistan) map and the ied localmarkers in use are "mil_warning"

_removeiedmarkerarray = (getMarkerPos "centre") nearObjects ["mil_warning", 6500];
{
deleteVehicle _x;
} forEach _removeiedmarkerarray;

Can nearObjects work with a classname like this? Even a marker classname?

Is doing a big nearObjects like this unwise? It runs on the client, so won't lag the mission, but might desync the player?

Any other comments?

Share this post


Link to post
Share on other sites

Unfortunately you cannot use deleteVehicle to delete markers. You have to use the deleteMarker command. deleteMarker uses the name of the marker in string format.

So, if you wanted to delete specific markers you would have to name them and store them as an array of strings to use forEach.

Example:

_removeiedmarkerarray = ["myMarker1","myMarker2","mtMarker3"];
{
deleteMarker _x;
} forEach _removeiedmarkerarray;

Edited by Loyalguard
Added example

Share this post


Link to post
Share on other sites

I knew that I couldn't use deleteVehicle. Don't know why I wrote that. Too tired!

I do have the markers in an array. I spose illc have to PV it and use that.

Share this post


Link to post
Share on other sites

OK, I need to have a further think about this.

The IEDs are created at random locations around a town on the server and stored in an array which is publicvariabled.

The engineers see IED script runs on the client, in fact, just the engineers and makes markers on their map.

The problem is that when a new town is populated with IEDs, the array gets rewritten, so using that array to remove the markers doesn't work as the markers are at town 1, yet the ied array contains data for town 2. That's why I wanted to have a map wide sweep to remove markers of a certain type.

So, what are my options?

Make a copy of the ied array that will be used just for markers that won't get overwritten when the ied script moves on to town 2? Use the array copy to remove the markers and when they've been removed, empty the copy array?

Could the markers that are made on the engineers map been cleaned off in another way? They can't manually delete them in the normal way - cursor over marker - press delete. Or is there a way to allow this?

Share this post


Link to post
Share on other sites

Is the IED array an array of markers or an array of the IED objects themselves? Assuming it is the former, do you have any reason to keep the markers in town 1 after town 2 is populated? If not, then I would simply suggest removed the markers in the array just before you overwrite the array with the new markers. Otherwise, copying the array before overwriting is probably the best option. You can easily do this using the unary + operator, e.g, myArrayCopy = +myOldArray

Share this post


Link to post
Share on other sites

the IED array is the ieds themselves, but I'm thinking I should make a copy of it to run the markers?

Unless I'm missing something, my problem lies in the fact the IEDs are on the server and the markers are on the client, so only a client action can remove the markers.

Share this post


Link to post
Share on other sites

IMO the problem is how you store the information. Why would you overwrite valid data? Why not just append it at the end?

Are you in control of the ied script, meaning can you get notification when a new one is discovered/defused/exploded? If so then just generate a unique marker name and setVar it on the IED. Whenever the state of an IED changes you save the markername in an array. When the engineer's request an update the server broadcast the "changes array" and resets it locally.

Then clients can read the data and update the markers.

You might need to keep an array of all ied's for JIP players to construct all the markers though.

Edited by Muzzleflash

Share this post


Link to post
Share on other sites
Unless I'm missing something, my problem lies in the fact the IEDs are on the server and the markers are on the client, so only a client action can remove the markers.

Well, deleteMarker is a global command, so you should be able to run it from anywhere and have it apply everywhere. It may require the marker to be local to the system executing the command, though (the Biki is unclear on this)... if that's the case, just globally execute the line (easy to do if you have CBA, will require either setVehicleInit or a publicVariable event handler otherwise).

Share this post


Link to post
Share on other sites
Well, deleteMarker is a global command, so you should be able to run it from anywhere and have it apply everywhere. It may require the marker to be local to the system executing the command, though (the Biki is unclear on this)... if that's the case, just globally execute the line (easy to do if you have CBA, will require either setVehicleInit or a publicVariable event handler otherwise).

Yeah, but the markers are createdMarkerLocal, so they only appear for the engineer. I assume that I'd have to use deletemarkerlocal to remove them.

I'll test this. If a deletemarker command run on the server deletes markers local to a client, then I'm good. I think. :)

---------- Post added at 06:03 PM ---------- Previous post was at 06:00 PM ----------

IMO the problem is how you store the information. Why would you overwrite valid data? Why not just append it at the end?

Are you in control of the ied script, meaning can you get notification when a new one is discovered/defused/exploded? If so then just generate a unique marker name and setVar it on the IED. Whenever the state of an IED changes you save the markername in an array. When the engineer's request an update the server broadcast the "changes array" and resets it locally.

Then clients can read the data and update the markers.

You might need to keep an array of all ied's for JIP players to construct all the markers though.

This script started as a small bolt on and has since grown to a huge great project so it's not had a planned growth. :)

I am in control of the IED generation script and could get notification when one is defused or exploded (they are done by triggers), though at the moment, I don't. I have to admit I've never done setVar so am going to have to have a serious look at it.

Share this post


Link to post
Share on other sites

Maybe you can use something like this:




/********* Server side script *********/

// [ TO_REMOVE, TO_ADD ]
PV_IedMrk_Changes = [ [], [] ];

//Handles deletion and addition of markers.
Ied_UpdateMarker = {
   private ["_array"];
   //Select correct array
   _array = PV_IedMrk_Changes select (_this select 1);
   //Add the markername
   _array set [count _array, _this select 0];
   //Handle JIP too
   _this call Ied_JipDataUpdate;
};

//Used for function below
if (isNil "Ied_UnigCounter") then {
   Ied_UnigCounter = 0;
};

//Gets an unique markername
Ied_UnigMrkName = {
   Ied_UnigCounter = Ied_UnigCounter + 1;
   format ["ied_mrk_%1", Ied_UnigCounter]
};

//Call this with [ied] when it is destroyed/removed
Ied_DeadHandler = {
   private ["_ied","_mrkName"];
   _ied = _this select 0;
   _mrkName = _ied getVariable "mrk";
   [_mkrName, 0] call Ied_UpdateMarker;
};

//Call this with [ied] when you create one.
Ied_CreatedHandler = {
   private ["_ied","_mrkName"];
   _ied = _this select 0;
   _mrkName = [] call Ied_UnigMrkName;
   _ied setVariable ["mrk", _mrkName, true];
   [_mrkName, 1] call Ied_UpdateMarker;
};

//You call this when you want folks to receive an update
Ied_HandleBroadcast = {
   //Send changes
   publicVariable "PV_IedMrk_Changes";
   //Local call in case of hosted server
   if (!isDedicated) then { //Could use an "isEngineer" code in this if.
       PV_IedMrk_Changes call PV_IedMrk_ClientChange;
   };
   //Reset what's changed
   PV_IedMrk_Changes = [ [], [] ];
};


//Jip updating - you publicVariable this sometimes so for JIP's preferably when they connect for minimum traffic
Ied_JipDate = [];

Ied_JipDataUpdate = {
   private ["_mrkName", "_action","_idx","_count"];
   _mrkName = _this select 0;
   _action = _this select 1;
   _count = count Ied_JipDate;
   if (_action == 0) then {
       //Remove from Jip Data
       _idx = Ied_JipDate find _mrkName;
       if (_idx != -1) then {
           //Swap with last and shrink array
           Ied_JipDate set [_idx, Ied_JipDate select (_count - 1)];
           Ied_JipDate resize (_count - 1);
       };
   } else {
       //Add to Jip Data
       Ied_JipDate set [_count, _mrkName];
   };
};

/********* Client (engineer) script *********/

//Handle change
"PV_IedMrk_Changes" addPublicVariableEventHandler {
   (_this select 1) call PV_IedMrk_ClientChange;
};

//This calls your functions that remove and create markers locally.
PV_IedMrk_ClientChange = {
   (_this select 0) call MyFunctionThatRemovesMarkers;
   (_this select 1) call MyFunctionThatCreatesMarkers;
};

//Jip creation
if (!isServer && !isNil Ied_JipDate) then {
   Ied_JipDate call MyFunctionThatCreatesMarkers;
};

Not tested!!. Function and variable containing *JipDate* should have been *JipData*.

EDIT:

Not sure if removal will work correctly since the object is destroyed and thus might be removed before getVariable is used.

EDIT2:

If you create the ied's in chunks then another method would be to publicVariable an array containing all IEDs. Engineers players listen for this. They delete any previous ied markers and create a new on for each non-null ied and stores the markername so the cycle can be done again. This would be simpler to make.

Edited by Muzzleflash

Share this post


Link to post
Share on other sites

OK, thanks everyone. I'm very grateful. :)

I need to go away and have a good think about this. Originally, I planned to have the pressure plate IED not removed from the town as the AO moves on, but it seems that I am removing them for performance reasons and because there'd be a problem with unique trigger names.

In short, I ought to be removing these markers, but given the pressure I'm under to complete other parts of this module, I think I might take a clunky, less satisfactory but simpler approach to this. Or just leave the markers. :)

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  

×