Jump to content
thy_

[SOLVED] How to figure out what object Respawn Vehicle Module just spawned?

Recommended Posts

Issue:

When the mission got started, we got one vehicle connected to the Respawn Vehicle Module from Eden Editor. That said, when the vehicle is destroyed, after a while, the vehicle respawns as expected, but it loses the original varName attributed from a script.

P.S.1: I don't want to set a varName through the Eden Editor UI. Script scope reasons.

P.S.2: The vehicle will spawn at an unpredictable position on the map.

 

What I need:

Figure out how to identify this new vehicle that just spawned and set the same varName as the old one. 

 

 

All of this raises these questions:

 

1) Exclusively looking for the example I brought up, is this the advised way to set a varName by script?

_obj setVehicleVarName "MyCar1";

 

2) Exclusively looking for the example I brought up, is this the advised way to bring an object varName? (considering the varName is needed only for the mission timeframe)

_obj = missionNamespace getVariable "MyCar1";

 

Wiki stuff:

 

Share this post


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

Issue:

When the mission got started, we got one vehicle connected to the Respawn Vehicle Module from Eden Editor. That said, when the vehicle is destroyed, after a while, the vehicle respawns as expected, but it loses the original varName attributed to the script.

P.S.1: I don't want to set a varName through the Eden Editor UI. Script scope reasons.

P.S.2: The vehicle will spawn at an unpredictable position on the map.

 

What I need:

Figure out how to identify this new vehicle that just spawned and set the same varName as the old one. 

 

 

All of this raises these questions:

 

1) Exclusively looking for the example I brought up, is this the advised way to set a varName by script?


_obj setVehicleVarName "MyCar1";

 

2) Exclusively looking for the example I brought up, is this the advised way to bring an object varName? (considering the varName is needed only for the mission timeframe)


_obj = missionNamespace getVariable "MyCar1";

 

 

 

Wiki stuff:

 

 

1. A vehicle's varname being "xyz" doesn't mean that the variable xyz automatically points to that object (xyz won't even be defined). vehicleVarName has no functional connection to actual variables. That they are similar when entered in the editor is just by convention or for 'ease of use'.

 

If you want to replicate the way variable names from the editor work you need to both execute setVehicleVarName and assign the reference to the variable:

 

_obj setVehicleVarName "MyCar1";

MyCar1 = _obj;

 

Or if you want to be extra explicit (these are both equivalent):

 

_obj setVehicleVarName "MyCar1";

missionNamespace setVariable ["MyCar1", _obj];

 

2. That is one appropriate way to get the mission-global variable called MyCar1.

For the same reason as above you

 

_obj = missionNamespace getVariable "MyCar1";

is equally equivalent to

_obj = MyCar1;

unless the latter is explicitly executed in another namespace for example using 'with'.

If you want the vehicleVarName you use the command by the same name.
 

 

As for identifying the vehicle the respawn module passes the old and new vehicle to code in the statement executed on each respawn so using that you can easily get the correct reference without resorting to global variables if that's what you wish.

  • Like 2

Share this post


Link to post
Share on other sites

First, thanks @mrcurry! Now setVariable/getVariable are almost clarified on my end.

 

5 hours ago, mrcurry said:

As for identifying the vehicle the respawn module passes the old and new vehicle to code in the statement executed on each respawn so using that you can easily get the correct reference without resorting to global variables if that's what you wish.

 

Not sure if I really got it. So what you saying is for me to take already existent parameters provided for the Arma Respawn Vehicle function that will bring the new and old vehicle references.

Can I ask you to bring an example of how to call them from a .sqf?

 

 

How I'm searching for vehicles that should be available for respawning too:

I am scanning vehicles inside a range and then setting a varName dynamically to - in theory - the Respawn Vehicle Module to get to know what vehicle should be targeting with further codes...

private [..., ..., ...];

_counter = 0;
{
    _counter = _counter + 1;
    _var = "veh" + (str _counter);
    _x setVehicleVarName _var;
    missionNamespace setVariable [_var, _x];
    _allVehicles pushBack _x;
  
} forEach (nearestObjects [_zonePos, ["Car", "Tank"], _zoneRange]);

 

 

How I'm checking each vehicle (all of them using Respawn):

I have no clue how to say to my script that it shouldn't stop the while-loop if the vehicle is destroyed 'cause it would respawn in a while...

params ["_veh"];

while { !isNull _veh } do {
    // Message:
    systemChat format [">> %1 still available!", vehicleVarName _veh];
    // Breath:
    sleep 30;
};

 

 

Testing through Module UI on Eden:

Just for testing purposes (I wouldn't like to work with this hard code), I've tried the snippet below and it doesn't work...

D6nuW7E.png

params ["_newVehicle","_oldVehicle"]; _newVehicle setVehicleVarName (vehicleVarName _oldVehicle); missionNamespace setVariable [vehicleVarName _oldVehicle, _newVehicle];

 


 

 

Share this post


Link to post
Share on other sites
17 hours ago, thy_ said:

What I need:

Figure out how to identify this new vehicle that just spawned and set the same varName as the old one. 

No need to do this, the respawn module handles this for you already (both giving the vehicle a varName at mission start AND renaming the newly spawned vehicle to the old name).

 

Your problem comes from you renaming the vehicle and not wanting to set a default name using the editor.

17 hours ago, thy_ said:

P.S.1: I don't want to set a varName through the Eden Editor UI. Script scope reasons. 

Not sure what script scope has to do with this.

 

Either name the vehicle in the editor. OR modify the way you are changing its name...

private [..., ..., ...];

_counter = 0;
{
	//Only if it doesnt already have a varName
	if ( vehicleVarName _x == "" ) then {
		_counter = _counter + 1;
		_var = "veh" + (str _counter);
		_x setVehicleVarName _var;
		_x call BIS_fnc_objectVar;
	};
	_allVehicles pushBack _x;

} forEach (nearestObjects [_zonePos, ["Car", "Tank"], _zoneRange]);

This will leave vehicles synced to the respawn module named as per the editor(which you say you are not doing) or by the default varName given to them by the respawn module. If they have neither then they will be named "veh#" where # is your counter.

 

If you must rename all the vehicles then instead...

private [..., ..., ...];

_counter = 0;
{
	//Only if it doesnt already have a varName starting with "veh"
	if ( vehicleVarName _x select[ 0, 3 ] != "veh" ) then {
		_counter = _counter + 1;
		_var = "veh" + (str _counter);
		_x setVariable[ "#var", nil ]; //Remove BIS_fnc_objectVar reference to name set by respawn module
		_x setVehicleVarName _var;
		_x call BIS_fnc_objectVar;
	};
	_allVehicles pushBack _x;

} forEach (nearestObjects [_zonePos, ["Car", "Tank"], _zoneRange]);

As the vehicles are not named in the editor, any that start synced to the respawn module will be automatically named at the mission start by the module.

The module uses BIS_fnc_objectVar to name them, when named by BIS_fnc_objectVar a variable or "#var" is placed on the vehicle of its given name. Any changes to its varName and using BIS_fnc_objectVar (of which the module uses both on mission start and when repsawning and transferring the name) to update its reference will...

 

  1. If it has no varName
    1. Has it been set before (has "#var" variable) then use contents of #var to rename it and set reference
    2. Give it a name based off of BI's internal counter "bis_o#" where # is the counter value and set its reference
  2. if it has a varName
    1. Has it been set before (has "#var" variable) then use contents of #var to set reference
    2. Give it reference based off of its current varName
  • Like 1
  • Thanks 1

Share this post


Link to post
Share on other sites
24 minutes ago, Larrow said:

Your problem comes from you renaming the vehicle and not wanting to set a default name using the editor.

 

😮😅

 

24 minutes ago, Larrow said:

Not sure what script scope has to do with this.

 

It's a script that protects zones on the map, zones defined by marker positions. This "protection" is against any nature of damage in vehicles. Vehicles protected are defined when the mission get started. All vehicles (from a type) inside the zone range will be protected by an "invisible dome". Out of this zone, there's no protection anymore. In all my scripts I try all "mission editor" interferences in Eden Editor, so I'm always looking for ways to avoid, e.g., making the mission editor input varNames in Eden objects, etc. 

 

That's why the vehicles aren't receiving "hard" varNames via Eden.

 

Awesome, @Larrow

 

 All hands on deck and in a few hours I'm back with something to share...

Share this post


Link to post
Share on other sites
14 hours ago, thy_ said:

How I'm checking each vehicle (all of them using Respawn):

I have no clue how to say to my script that it shouldn't stop the while-loop if the vehicle is destroyed 'cause it would respawn in a while...


params ["_veh"];

while { !isNull _veh } do {
    // Message:
    systemChat format [">> %1 still available!", vehicleVarName _veh];
    // Breath:
    sleep 30;
};

 

But how could I call the new _veh on it?

 

 

Edited: works fine here...

params ["_veh"];
private ["_var"];

// Declaration:
_var = vehicleVarName _veh;

while { true } do {
    // Updating:
    _veh = missionNamespace getVariable _var;
    // If the vehicle exist:
    if ( !isNull _veh ) then {
        // Message:
        systemChat format [">> %1 still available!", vehicleVarName _veh];
    };
    // Breath:
    sleep 30;
};

 

Share this post


Link to post
Share on other sites

All day long working on it, I realized something.

 

A question actually: via code only, how do we know if a vehicle/object is SYNCED with Respawn Vehicle Module?

 

fSCDzrQ.png

Share this post


Link to post
Share on other sites
5 hours ago, thy_ said:

A question actually: via code only, how do we know if a vehicle/object is SYNCED with Respawn Vehicle Module?

 

Assuming _car and _module are defined elsewhere this will definitely work:

_car in synchronizedObjects _module;

 

This might not work:

_module in synchronizedObjects _car;

If I remember correctly this is because only "smart" objects (logics, units and triggers) retain a list of synchronizedObjects. I recommend testing to be sure 🙂

Share this post


Link to post
Share on other sites

Here's some goes:

synchronizedObjects MyModuleDroppedOnEden;
// Returned: [car1, car2];

synchronizedObjects car1;
// returned: []

 

But this is curious:

private _synced = synchronizedObjects MyModuleDroppedOnEden;

systemChat str _synced;
// Returned: [car1, car2]


// Two ways, first is faster than the second one:

if ( _synced findIf { car1 isEqualTo _x } != -1 ) then { systemChat "TRUE" } else { systemChat "FALSE" };
// Returned: FALSE;

if ( car1 in _synced ) then { systemChat "TRUE" } else { systemChat "FALSE" };
// Returned: FALSE;

🤨

 

Commands used on wiki:

Edited by thy_
Included "findIf" example.

Share this post


Link to post
Share on other sites

Hmm weird... car1 in _synced should work.

Is this after a respawn of the vehicle? 

Have you tried the same in a clean mission?

Share this post


Link to post
Share on other sites
44 minutes ago, mrcurry said:

Is this after a respawn of the vehicle? 

Have you tried the same in a clean mission?

 

1) Yes.
2) Yes. In addition, I'm running no mods, nothing! Only vanilla Arma 3.

 

7 hours ago, mrcurry said:

Assuming _car and _module are defined elsewhere this will definitely work

 

For me in the future: find all Respawn Vehicle Modules on the mission with no set varnames:

private _modulesFound = [];
private _searchForModules = entities "Logic";  // probably there's a way to filter better and make it even faster.

{
    if (typeOf _x isEqualTo "ModuleRespawnVehicle_F") then {
        // Adding to the module list:
        GLOBAL_moduleList pushBack _x;
    };
} forEach _searchForModules;

systemChat str GLOBAL_moduleList;
// Returned: [MyModuleDroppedOnEden1, MyModuleDroppedOnEden2]

 

Share this post


Link to post
Share on other sites

The vehicle once respawned is never resynched with the module, it works via recursion of the function handled by the events placed on the vehicle.

 

This should tell you whether a vehicle is set to respawn or not...

if (
	//By recursion from events
	( !( _veh getVariable[ "BIS_fnc_moduleRespawnVehicle_first", false ] ) && {
		!isNil{ _veh getVariable "BIS_fnc_moduleRespawnVehicle_mpKilled" }
	} ) || 
	//By initial sync
	{ _veh in synchronizedObjects MyModuleDroppedOnEden }
) then {
	true
}else{
	false
};

Could likely just check whether BIS_fnc_moduleRespawn_mpKilled is not nil, just being verbose to allude to what is happening.

  • Thanks 1

Share this post


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

But this is curious:


private _synced = synchronizedObjects MyModuleDroppedOnEden;

systemChat str _synced;
// Returned: [car1, car2]

if ( car1 in _synced ) then { systemChat "TRUE" } else { systemChat "FALSE" };
// Returned: FALSE;

 

This again I would guess at being a discrepancy between reference and varName. The initial [ car1, car2 ] would relate to the vehicles varName, where as car1 in would rely on the reference being set up correctly.

Share this post


Link to post
Share on other sites

This...

1 hour ago, thy_ said:

private _modulesFound = [];
private _searchForModules = entities "Logic";  // probably there's a way to filter better and make it even faster.

{
    if (typeOf _x isEqualTo "ModuleRespawnVehicle_F") then {
        // Adding to the module list:
        GLOBAL_moduleList pushBack _x;
    };
} forEach _searchForModules;

systemChat str GLOBAL_moduleList;

 

...is just...

GLOBAL_moduleList = entities "ModuleRespawnVehicle_F";
systemchat str GLOBAL_moduleList;

...entities already does the filter by type, no need to do it manually.

  • Like 1
  • Thanks 1

Share this post


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

 


GLOBAL_moduleList = entities "ModuleRespawnVehicle_F";
systemchat str GLOBAL_moduleList;

...entities already does the filter by type, no need to do it manually.

 

I'm performing some tests here and only this below already returned positively 100% of tests here:

// By recursion from events:
if ( !( _veh getVariable["BIS_fnc_moduleRespawnVehicle_first", false]) && !isNil {_veh getVariable "BIS_fnc_moduleRespawnVehicle_mpKilled"} ) then { true } else { false };

... so, I do not see the need to check this below (originally inside the IF above):

//By initial sync:
{ _veh in synchronizedObjects MyModuleDroppedOnEden }

 

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

×