Jump to content
ColonelKernel

Script for revealing empty playerside vehicles

Recommended Posts

I'm trying to write a script for revealing all empty playerside vehicles to the player (MP & SP). This is how I've done it:

0 = [] spawn {
  while {true} do {
     _allEmptyVehs = vehicles select {{alive _x} count crew _x == 0 && (side==playerside)}; //vehicle should be empty (not counting the dead units) and on the player's side
     {
       player reveal _x;
     } foreach _allEmptyVehs;
  sleep 2;
  };
};

The problem is that the unit positions do not update on the map. Can someone please tell me what I'm doing wrong?

Share this post


Link to post
Share on other sites

Empty vehicles are side civilian I believe (which is why the ai don't shoot at empty vehicles).

 

You can check in their config entry for the default side there:

 

getNumber (configfile >> "cfgvehicles" >> (typeOf _x) >> "side")

 

and it will give you 0 for opfor, 1 for blufor, 2 for independents and 3 for civ.

Share this post


Link to post
Share on other sites
12 minutes ago, das attorney said:

Empty vehicles are side civilian I believe (which is why the ai don't shoot at empty vehicles).

 

You can check in their config entry for the default side there:

 

getNumber (configfile >> "cfgvehicles" >> (typeOf _x) >> "side")

 

and it will give you 0 for opfor, 1 for blufor, 2 for independents and 3 for civ.

Then, e.g, why are BLUEFOR vehicles shown as blue on the map? (civilians are purple, right?)

Also can you please check if I've made any errors in the script?

Share this post


Link to post
Share on other sites

Ok, after checking I've found a few problems:

1. Revealed vehicles disappear (from map) after a unit embarks and then disembarks them, and don't appear again.

2. Empty vehicle markers do not update on the map.

 

How can I keep the position of revealed vehicles updated on the map?

Share this post


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

Then, e.g, why are BLUEFOR vehicles shown as blue on the map? (civilians are purple, right?)

 

If you get in an empty vehicle, it changes to your side.

 

If you leave and walk off over 100m it reverts to side CIVILIAN.

 

So you can't reliably expect empty vehicles belonging to your faction to be on your side.

 

Check it yourself if you like:

 

onEachFrame{hintSilent format ["%1  %2",side car1,player distance car1]}

 

Share this post


Link to post
Share on other sites
9 minutes ago, das attorney said:

 

If you get in an empty vehicle, it changes to your side.

 

If you leave and walk off over 100m it reverts to side CIVILIAN.

 

So you can't reliably expect empty vehicles belonging to your faction to be on your side.

 

Check it yourself if you like:

 


onEachFrame{hintSilent format ["%1  %2",side car1,player distance car1]}

 

Can you please help me with the part I mentioned i.e making units update on the map ? I'm kind of stuck!

Share this post


Link to post
Share on other sites

I already gave you a way in my first post....

 

Quote

 

getNumber (configfile >> "cfgvehicles" >> (typeOf _x) >> "side")

 

and it will give you 0 for opfor, 1 for blufor, 2 for independents and 3 for civ.

 

 

Change this:

 

_allEmptyVehs = vehicles select {{alive _x} count crew _x == 0 && (side player)};

 

To one of these:

 

_allEmptyVehs = vehicles select {{alive _x} count crew _x == 0 && {getNumber (configfile >> "cfgvehicles" >> (typeOf _x) >> "side") == 1}}; // if you are blufor
_allEmptyVehs = vehicles select {{alive _x} count crew _x == 0 && {getNumber (configfile >> "cfgvehicles" >> (typeOf _x) >> "side") == 0}}; // if you  are opfor
_allEmptyVehs = vehicles select {{alive _x} count crew _x == 0 && {getNumber (configfile >> "cfgvehicles" >> (typeOf _x) >> "side") == 2}}; // if you  independent

 

btw: iterating through all the "vehicles" will probably bog down the scheduler if you have a busy mission.

 

 

Share this post


Link to post
Share on other sites
I already gave you a way in my first post....
 
 

getNumber (configfile >> "cfgvehicles" >> (typeOf _x) >> "side")

 

and it will give you 0 for opfor, 1 for blufor, 2 for independents and 3 for civ.

 
 
Change this:
 
_allEmptyVehs = vehicles select {{alive _x} count crew _x == 0 && (side player)};

 
To one of these:
 

_allEmptyVehs = vehicles select {{alive _x} count crew _x == 0 && {getNumber (configfile >> "cfgvehicles" >> (typeOf _x) >> "side") == 1}}; // if you are blufor_allEmptyVehs = vehicles select {{alive _x} count crew _x == 0 && {getNumber (configfile >> "cfgvehicles" >> (typeOf _x) >> "side") == 0}}; // if you  are opfor_allEmptyVehs = vehicles select {{alive _x} count crew _x == 0 && {getNumber (configfile >> "cfgvehicles" >> (typeOf _x) >> "side") == 2}}; // if you  independent

 
 
 
 
Maybe addVehicle could be used to hold an empty vehicle on a specific side. But I did not test it

sent from mobile using Tapatalk

Share this post


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

Maybe addVehicle could be used to hold an empty vehicle on a specific side. But I did not test it

 

 

Maybe...   I don't fancy checking it either though  ;)

Share this post


Link to post
Share on other sites
17 minutes ago, das attorney said:

btw: iterating through all the "vehicles" will probably bog down the scheduler if you have a busy mission.

You're right. But I don't have any idea how to do it in a different way. Do you have any suggestions?

Share this post


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

Not offhand

What if I limit the distance? Does it improve the performance?

Share this post


Link to post
Share on other sites

My advice is to run this on clients. This also means it will work for all sides. Second, we know that empty vehicles don't move on their own, so we don't need to constantly update. I believe it is practical to go through all vehicles regularly on the client. There are more advanced ways with event handlers, but just wanted to quickly make something. The only possible problem with doing it client side, is that vehicles that are far away might not get transmitted to clients. Anywhere I made this script, and tested it and it seems to work (not sure how well the _visual commands work, maybe just use ordinary):

if (!hasInterface) exitWith {};

EM_Vehicles = [];

EM_MapDrawCallback = {
    params ["_mapCtrl"];
    // This just draws the data from EM_Vehicles on the map.
    {
        _x params ["_obj", "_pos", "_dir", "_icon", "_color"];
        _mapCtrl drawIcon [
            _icon,
            _color,
            _pos,
            22,
            22,
            _dir,
            '',
            0,
            0.03,
            'TahomaB',
            'center'
        ];
    } forEach EM_Vehicles;
};


[] spawn {
    disableSerialization;
    while {true} do {
        // Wait for player object to determine side
        waitUntil {sleep (5 + random 3);
            !isNull player
        };

        // This array links colors, side indexes, with actual side values
        private _sideArray = [east, west, resistance, civilian];
        // We pick the group side, because you can mix members in a group
        private _playerSide = _sideArray find (side group player); 
        private _alpha = 0.5;
        // We only need to select the color once per loop, since we only care for one side
        private _color = [ [1,0,0,_alpha], [0,0,1,_alpha], [0,1,0,_alpha], [1,1,0,_alpha] ] select _playerSide;

        private _cfgVehicles = configFile >> "CfgVehicles";
        private _newVehicles = vehicles select {
            (_x isKindOf "AllVehicles") and //Just avoid possible weird objects
            (count units _x == 0) and //Empty
            (getNumber (_cfgVehicles >> typeOf _x >> "side") == _playerSide) //On the player's side
        };

        // From the vehicle gather the data
        EM_Vehicles = _newVehicles apply {
            private _cfg = _cfgVehicles >> typeOf _x;
            private _icon = getText (_cfg >> "icon");
            private _side = getNumber (_cfg >> "side");
            [
                _x,
                getPosASLVisual _x,
                getDirVisual _x,
                _icon,
                _color
            ]
        };
    };
};

// We must wait for the player and display to be active before we can add the event handler.
[] spawn {
    disableSerialization;
    waitUntil {sleep 0.25; !isNull player};
    private _display = objNull;
    while {isNull _display} do {
        sleep 0.25;
        _display = findDisplay 12;
    };
    private _ctrl = _display displayCtrl 51;
    _ctrl ctrlAddEventHandler ["Draw", EM_MapDrawCallback];
};

 

  • Like 1

Share this post


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

My advice is to run this on clients. This also means it will work for all sides. Second, we know that empty vehicles don't move on their own, so we don't need to constantly update. I believe it is practical to go through all vehicles regularly on the client. There are more advanced ways with event handlers, but just wanted to quickly make something. The only possible problem with doing it client side, is that vehicles that are far away might not get transmitted to clients. Anywhere I made this script, and tested it and it seems to work (not sure how well the _visual commands work, maybe just use ordinary):


if (!hasInterface) exitWith {};

EM_Vehicles = [];

EM_MapDrawCallback = {
    params ["_mapCtrl"];
    // This just draws the data from EM_Vehicles on the map.
    {
        _x params ["_obj", "_pos", "_dir", "_icon", "_color"];
        _mapCtrl drawIcon [
            _icon,
            _color,
            _pos,
            22,
            22,
            _dir,
            '',
            0,
            0.03,
            'TahomaB',
            'center'
        ];
    } forEach EM_Vehicles;
};


[] spawn {
    disableSerialization;
    while {true} do {
        // Wait for player object to determine side
        waitUntil {sleep (5 + random 3);
            !isNull player
        };

        // This array links colors, side indexes, with actual side values
        private _sideArray = [east, west, resistance, civilian];
        // We pick the group side, because you can mix members in a group
        private _playerSide = _sideArray find (side group player); 
        private _alpha = 0.5;
        // We only need to select the color once per loop, since we only care for one side
        private _color = [ [1,0,0,_alpha], [0,0,1,_alpha], [0,1,0,_alpha], [1,1,0,_alpha] ] select _playerSide;

        private _cfgVehicles = configFile >> "CfgVehicles";
        private _newVehicles = vehicles select {
            (_x isKindOf "AllVehicles") and //Just avoid possible weird objects
            (count units _x == 0) and //Empty
            (getNumber (_cfgVehicles >> typeOf _x >> "side") == _playerSide) //On the player's side
        };

        // From the vehicle gather the data
        EM_Vehicles = _newVehicles apply {
            private _cfg = _cfgVehicles >> typeOf _x;
            private _icon = getText (_cfg >> "icon");
            private _side = getNumber (_cfg >> "side");
            [
                _x,
                getPosASLVisual _x,
                getDirVisual _x,
                _icon,
                _color
            ]
        };
    };
};

// We must wait for the player and display to be active before we can add the event handler.
[] spawn {
    disableSerialization;
    waitUntil {sleep 0.25; !isNull player};
    private _display = objNull;
    while {isNull _display} do {
        sleep 0.25;
        _display = findDisplay 12;
    };
    private _ctrl = _display displayCtrl 51;
    _ctrl ctrlAddEventHandler ["Draw", EM_MapDrawCallback];
};

 

Thank you for your reply.

The reason I use the reveal command is because that way I can order my units to get in a vehicle. I did find a way (which is kind of silly!) that solves the update problem. If you have the time to test it, here it is:

0 = [] spawn {
	While {true} do {
    {
    waitUntil {visibleMap};
     _allVehs = _x nearobjects ["allvehicles", 800];
     _allEmptyVehs = _allVehs select {{alive _x} count crew _x == 0};
     {
	 player forgettarget _x;
	 player reveal _x;
     } foreach _allEmptyVehs;
     } foreach units group player;
    sleep 2;
    waitUntil {shownMap};
	};
};

If you could help me iron out the unit position shifting on map (because of using forgettarget) I would greatly appreciate it.

Share this post


Link to post
Share on other sites

2 hours ago, Muzzleflash said:

My advice is to run this on clients. This also means it will work for all sides. Second, we know that empty vehicles don't move on their own, so we don't need to constantly update. I believe it is practical to go through all vehicles regularly on the client. There are more advanced ways with event handlers, but just wanted to quickly make something. The only possible problem with doing it client side, is that vehicles that are far away might not get transmitted to clients. Anywhere I made this script, and tested it and it seems to work (not sure how well the _visual commands work, maybe just use ordinary):


if (!hasInterface) exitWith {};

EM_Vehicles = [];

EM_MapDrawCallback = {
    params ["_mapCtrl"];
    // This just draws the data from EM_Vehicles on the map.
    {
        _x params ["_obj", "_pos", "_dir", "_icon", "_color"];
        _mapCtrl drawIcon [
            _icon,
            _color,
            _pos,
            22,
            22,
            _dir,
            '',
            0,
            0.03,
            'TahomaB',
            'center'
        ];
    } forEach EM_Vehicles;
};


[] spawn {
    disableSerialization;
    while {true} do {
        // Wait for player object to determine side
        waitUntil {sleep (5 + random 3);
            !isNull player
        };

        // This array links colors, side indexes, with actual side values
        private _sideArray = [east, west, resistance, civilian];
        // We pick the group side, because you can mix members in a group
        private _playerSide = _sideArray find (side group player); 
        private _alpha = 0.5;
        // We only need to select the color once per loop, since we only care for one side
        private _color = [ [1,0,0,_alpha], [0,0,1,_alpha], [0,1,0,_alpha], [1,1,0,_alpha] ] select _playerSide;

        private _cfgVehicles = configFile >> "CfgVehicles";
        private _newVehicles = vehicles select {
            (_x isKindOf "AllVehicles") and //Just avoid possible weird objects
            (count units _x == 0) and //Empty
            (getNumber (_cfgVehicles >> typeOf _x >> "side") == _playerSide) //On the player's side
        };

        // From the vehicle gather the data
        EM_Vehicles = _newVehicles apply {
            private _cfg = _cfgVehicles >> typeOf _x;
            private _icon = getText (_cfg >> "icon");
            private _side = getNumber (_cfg >> "side");
            [
                _x,
                getPosASLVisual _x,
                getDirVisual _x,
                _icon,
                _color
            ]
        };
    };
};

// We must wait for the player and display to be active before we can add the event handler.
[] spawn {
    disableSerialization;
    waitUntil {sleep 0.25; !isNull player};
    private _display = objNull;
    while {isNull _display} do {
        sleep 0.25;
        _display = findDisplay 12;
    };
    private _ctrl = _display displayCtrl 51;
    _ctrl ctrlAddEventHandler ["Draw", EM_MapDrawCallback];
};

 

I just did something cool! If I use your script in conjunction with mine and disable friendly icons on the map (in difficulty settings) it actually does what I want!

Share this post


Link to post
Share on other sites

I see now I misunderstand, and you literally meant reveal. I don't have time to test atm. That script is rather intensive if you have a larger group, since the nearunits check runs for each member of the group. Maybe just increase the radius a tiny bit and just do the search once from the player's position? But I am a bit confused about the use case. You only do this once the player open his map, but he does not have to enter the map to order his units around. If the server is running with higher difficulty, or disabled map icons, I am not even sure it is possible to giver 'getin' orders on the map. Finally, I am not sure what the last line where you waituntil shownMap is for, you already waited for the map to be visible?

Share this post


Link to post
Share on other sites
2 minutes ago, ColonelKernel said:

 

 

I just did something cool! If I use your script in conjunction with mine and disable friendly icons on the map (in difficulty settings) it actually does what I want!

Sure go ahead, do what you want with it :)   (yeah my version always draws the vehicles on the map regardless of difficulty settings).

  • Like 1

Share this post


Link to post
Share on other sites
18 minutes ago, Muzzleflash said:

I see now I misunderstand, and you literally meant reveal. I don't have time to test atm. That script is rather intensive if you have a larger group, since the nearunits check runs for each member of the group. Maybe just increase the radius a tiny bit and just do the search once from the player's position? But I am a bit confused about the use case. You only do this once the player open his map, but he does not have to enter the map to order his units around. If the server is running with higher difficulty, or disabled map icons, I am not even sure it is possible to giver 'getin' orders on the map. Finally, I am not sure what the last line where you waituntil shownMap is for, you already waited for the map to be visible?

-Actually, I created a ten unit group with 200 vehicles around me and I didn't notice much difference. (except for an initial slowdown because of those 200 vehicles of course!)

-I need it to do the search for all my units because I sometimes I stage my units somewhere far from my position.

-I added the line for it to work once the map is opened because I figured it would improve performance (why should it keep revealing vehicles to me when I still haven't opened the map?)

-To be honest, I don't know why I used that line either ;) I just tried it with plain

waitUntil {visibleMap};

at the start but the script ran only once (i,e the while loop would get stuck at the beginning). Then I tried the waituntil shownMap and it worked! Weird, right?!

Anyway, thanks for your help! I was going crazy with this!

Share this post


Link to post
Share on other sites

This also fixes the flickering!

0 = [] spawn {
    While {true} do {
    {
     waitUntil {visibleMap};
     _allVehs = _x nearobjects ["allvehicles", 800];
     _allEmptyVehs = _allVehs select {{alive _x} count crew _x == 0};
     {
	 if (player knowsabout _x != 1) then {player forgettarget _x};
     player reveal [_x, 1];
     } foreach _allEmptyVehs;
     } foreach units group player;
    sleep 2;
    waitUntil {shownMap};
    };
}; 

 

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

×