Jump to content
  • 0

setDir Spawning Traders Vehicles


Swikhy

Question

Hi,

 

Can someone help me with this ? I would like to custom the facing direction of a spawned vehicle when we buy it at a trader.

 

I know vehicles are facing North when they spawn but is it possible to make some modifications to choose which direction they are facing ? I need this for Aircraft Dealers. When planes spawn, i want them to face the runway, ready to take off. If it's possible to add an if statement to choose which traders are affected by this script it will be nice.

 

I read this but i'm not really sure what changes i have to do, where i have to do them and what can i custom in it.

 

Thanks :)

Link to comment
Share on other sites

13 answers to this question

Recommended Posts

  • 0

Let me give you a clue. To make matters easier you figure out direction not by trader, but by helipad (all helipad locations can be found server side inside mission.sqf file (not sqm!)). Each trader has a helipad nearby, this object is searched for when you buy a car or aircraft and vehicle spawned right on top of it... 

 

Make an array of locations to compare to. Use switch on 3 or more locations or simple if/else statement if one or two. Create local variable and save direction in it, then simply modify your setDir command ( after createVehicle) by pointing it to this variable.

 

This is more than enough to get you going, welcome to forums.

 

edit: an example switch code to use:

_dir = switch {_location} do {
	case [0,0,0]: {45}; //if matches this location, set direction to 45 
	case [1,1,1]: {90};
	case [2,2,2]: {180};
	default {0};
};

_veh setDir _dir;
Link to comment
Share on other sites

  • 0

Thanks for your help Raymix !

 

So... I opened server_publishVehicle2.sqf and i added your code in it like this :

// Switched to spawn so we can wait a bit for the ID
[_object,_uid,_characterID,_class,_dir,_location,_donotusekey,_activatingPlayer] spawn {
   private ["_object","_uid","_characterID","_done","_retry","_key","_result","_outcome","_oid","_class","_location","_object_para","_donotusekey","_activatingPlayer"];

   _object = _this select 0;
   _uid = _this select 1;
   _characterID = _this select 2;
   _class = _this select 3;
   
   //RAYMIX CODE
   _dir = switch {_location} do {
	case [1053.68,2795.45,0]: {180}; //if matches aircraft dealer south, set direction to 180
	case [2,2,2]: {2}; //empty
	case [3,3,3]: {3}; //empty
	default {0};
};
   _location = _this select 5;
   _donotusekey = _this select 6;
   _activatingPlayer = _this select 7;

In the array, i put the location of where i want the vehicle to spawn, am i right ? or do i have to enter the location of the trader himself ? Or the helipad ?

 

Then you're speaking about creating a local variable and saving direction in it but i don't see where ! The only "createVehicle" i have is this :

// Remove marker
	deleteVehicle _object;

	if(!_done) exitWith { diag_log("CUSTOM: failed to get id for : " + str(_uid)); };

	if(DZE_TRADER_SPAWNMODE) then {
		_object_para = createVehicle ["ParachuteMediumWest", [0,0,0], [], 0, "CAN_COLLIDE"];
		_object_para setPos [_location select 0, _location select 1,(_location select 2) + 65];
		_object = createVehicle [_class, [0,0,0], [], 0, "CAN_COLLIDE"];
	} else {
		_object = createVehicle [_class, _location, [], 0, "CAN_COLLIDE"];
	};

	if(!_donotusekey) then {
		// Lock vehicle
		_object setvehiclelock "locked";
	};

But i'm not sure that's the right place since it says "remover marker". I'm trying to find the code where the vehicle spawn but i can't find it, or i'm not understanding something well.

 

Sorry, i'm really new into scripting and even if i "understand" your clue, i'm a bit lost when i have to implement it in my files :unsure:

Link to comment
Share on other sites

  • 0

Just so we're clear, I won't be giving any actual code solution to this, would break the point of learning now would it? 

 

As I mentioned, vehicles are placed right on top of helipads with exact same coordinates where helipads were created. However what you see there on vehicle creation (sometimes) is [0,0,0]. This is a known practice, basically vehicle is first created in debug zone first then it is teleported on top of helipad using setPosATL.

 

So what you want is... to find variable associated with location of helipad where this vehicle will be teleported to (or created at). Then if one of locations will match one of switch cases, vehicle will be appropriately rotated (if not, then it will be rotated 0 degrees using default {0}; case). It's quite simple concept.

As for the code, feel free to ask any questions, but for sake of learning there won't be any direct solutions.... it's time we start educating our server admins one by one, this forum needs more people capable of answering than asking ;)

Look at it from bright side - when done you will be able to release your very own creation at some point.

Link to comment
Share on other sites

  • 0

 

Just so we're clear, I won't be giving any actual code solution to this, would break the point of learning now would it?

 

I'm ok with this ! ^_^

 

I'm trying to get the position of the nearest Helipad to use it in the switch :

// Switched to spawn so we can wait a bit for the ID
[_object,_uid,_characterID,_class,_dir,_location,_donotusekey,_activatingPlayer] spawn {
   private ["_object","_uid","_characterID","_done","_retry","_key","_result","_outcome","_oid","_class","_location","_object_para","_donotusekey","_activatingPlayer"];

   _object = _this select 0;
   _uid = _this select 1;
   _characterID = _this select 2;
   _class = _this select 3;
   //Spawned vehicle location
   _location = getPos _activatingPlayer nearestObject "HeliHEmpty";
   //Spawned vehicle direction
   _dir = switch {_location} do {
    case [1053.68,2795.45,0]: {146.893}; //if matches aircraft dealer south, set direction to 146.893
    case [2,2,2]: {2}; //empty
    case [3,3,3]: {3}; //empty
    default {0};
    };

And i added _object setDir _dir; after this :

_object setVariable ["ObjectID", _oid, true];
	
_object setVariable ["lastUpdate",time];
	
_object setVariable ["CharacterID", _characterID, true];

Now, vehicles are not spawning anymore because my _location is wrong. I think i'm not using the good syntax, do i have to be more accurate when i ask for "HeliHEmpty" ?

Link to comment
Share on other sites

  • 0

lol, I gave you broken syntax.. change switch {} to switch ()..i meant parenthesis not squiggly brackets. My bad...been up over 24h can't think straight.. here's wiki on syntax if lost.

 

Once that's fixed, it should work just fine. Make sure you rotate _object after it's teleported (if teleported) because moving it might reset rotation.

 

edit: you can find full list of helipad locations in mission.sqf (here's the file on Mudzereli's github, nice chap), contains coords for all helipads. Ofc you can just use the one from your server, I am linking since I don't have A2 or any epoch related files locally

Link to comment
Share on other sites

  • 0

Ok, i changed the syntax of switch {} to switch ().

 

I still have an error in my .RPT :

 9:55:12 "EPOCH SERVERTRADE: Player: Swikhy (76561197978161570) bought a GNT_C185 in/at Unknown Trader for 40000x Coins"

 9:55:12 "PUBLISH: Attempt 37ed3900# 1056814: arrow_down_large_ep1.p3d REMOTE"

 9:55:12 "HIVE: WRITE: "CHILD:308:11:GNT_C185:0:4334:[327,[12072.7,12667.3,0]]:[]:[]:1:12072712667301331:""

 9:55:12 Error in expression <s = _this select 3;

 

_location = getPos _activatingPlayer nearestObject "HeliHEm>

 9:55:12   Error position: <_activatingPlayer nearestObject "HeliHEm>

 9:55:12   Error Undefined variable in expression: _activatingplayer

 9:55:12 File z\addons\dayz_server\compile\server_publishVehicle2.sqf, line 47

 9:55:13 "HIVE: WRITE: "CHILD:388:12072712667301331:""

 9:55:13 "CUSTOM: Selected "373""

 9:55:13 Error in expression <else {

_object = createVehicle [_class, _location, [], 0, "CAN_COLLIDE"];

};

Apparently, _activatingPlayer isn't defined. I don't know why since i'm seeing it multiple times in the code. Here is the entire .sqf if you want to check :

private ["_activatingPlayer","_isOK","_object","_worldspace","_location","_dir","_class","_uid","_key","_keySelected","_characterID","_donotusekey"];


//PVDZE_veh_Publish2 = [_veh,[_dir,_location],_part_out,false,_keySelected,_activatingPlayer];
_object =         _this select 0;
_worldspace =     _this select 1;
_class =         _this select 2;
_donotusekey =    _this select 3;
_keySelected =  _this select 4;
_activatingPlayer =  _this select 5;

if(_donotusekey) then {
    _isOK = true;
} else {
    _isOK = isClass(configFile >> "CfgWeapons" >> _keySelected);
};

if(!_isOK) exitWith { diag_log ("HIVE: CARKEY DOES NOT EXIST: "+ str(_keySelected));  };

if(_donotusekey) then {
    _characterID = _keySelected;
} else {
    _characterID = str(getNumber(configFile >> "CfgWeapons" >> _keySelected >> "keyid"));
};

diag_log ("PUBLISH: Attempt " + str(_object));
_dir =         _worldspace select 0;
_location = _worldspace select 1;

//Generate UID test using time
_uid = _worldspace call dayz_objectUID3;

// TODO: check if uid already exists && if so increment by 1 && check again as soon as we find nothing continue.

//Send request
_key = format["CHILD:308:%1:%2:%3:%4:%5:%6:%7:%8:%9:",dayZ_instance, _class, 0 , _characterID, _worldspace, [], [], 1,_uid];
diag_log ("HIVE: WRITE: "+ str(_key));
_key call server_hiveWrite;

// Switched to spawn so we can wait a bit for the ID
[_object,_uid,_characterID,_class,_dir,_location,_donotusekey,_activatingPlayer] spawn {
   private ["_object","_uid","_characterID","_done","_retry","_key","_result","_outcome","_oid","_class","_location","_object_para","_donotusekey","_activatingPlayer"];

   _object = _this select 0;
   _uid = _this select 1;
   _characterID = _this select 2;
   _class = _this select 3;
   //Spawned vehicle location
   _location = getPos _activatingPlayer nearestObject "HeliHEmpty";
   //Spawned vehicle direction
   _dir = switch (_location) do {
    case [1053.68,2795.45,0]: {146.893}; //if matches aircraft dealer south, set direction to 146.893
    case [2,2,2]: {2}; //empty
    case [3,3,3]: {3}; //empty
    default {0};
    };
   _donotusekey = _this select 6;
   _activatingPlayer = _this select 7;

   _done = false;
    _retry = 0;
    // TODO: Needs major overhaul for 1.1
    while {_retry < 10} do {
        
        sleep 1;
        // GET DB ID
        _key = format["CHILD:388:%1:",_uid];
        diag_log ("HIVE: WRITE: "+ str(_key));
        _result = _key call server_hiveReadWrite;
        _outcome = _result select 0;
        if (_outcome == "PASS") then {
            _oid = _result select 1;
            //_object setVariable ["ObjectID", _oid, true];
            diag_log("CUSTOM: Selected " + str(_oid));
            _done = true;
            _retry = 100;

        } else {
            diag_log("CUSTOM: trying again to get id for: " + str(_uid));
            _done = false;
            _retry = _retry + 1;
        };
    };

    // Remove marker
    deleteVehicle _object;
    
    if(!_done) exitWith { diag_log("CUSTOM: failed to get id for : " + str(_uid)); };

    if(DZE_TRADER_SPAWNMODE) then {
        _object_para = createVehicle ["ParachuteMediumWest", [0,0,0], [], 0, "CAN_COLLIDE"];
        _object_para setPos [_location select 0, _location select 1,(_location select 2) + 65];
        _object = createVehicle [_class, [0,0,0], [], 0, "CAN_COLLIDE"];
    } else {
        _object = createVehicle [_class, _location, [], 0, "CAN_COLLIDE"];
    };

    if(!_donotusekey) then {
        // Lock vehicle
        _object setvehiclelock "locked";
    };

    clearWeaponCargoGlobal  _object;
    clearMagazineCargoGlobal  _object;
    // _object setVehicleAmmo DZE_vehicleAmmo;

    _object setVariable ["ObjectID", _oid, true];
    
    _object setVariable ["lastUpdate",time];
    
    _object setVariable ["CharacterID", _characterID, true];
    _object setDir _dir;

    if(DZE_TRADER_SPAWNMODE) then {
        _object attachTo [_object_para, [0,0,-1.6]];
        sleep 1.0;
        WaitUntil{(([_object] call FNC_GetPos) select 2) < 0.1};
        detach _object;
        deleteVehicle _object_para;
    };

    PVDZE_serverObjectMonitor set [count PVDZE_serverObjectMonitor,_object];

    _object call fnc_veh_ResetEH;
    
    // for non JIP users this should make sure everyone has eventhandlers for vehicles.
    PVDZE_veh_Init = _object;
    publicVariable "PVDZE_veh_Init";
    
    diag_log ("PUBLISH: " + str(_activatingPlayer) + " Bought " + (_class) + " with ID " + str(_uid));
};

 

As you said, i set the _dir after the object is spawned.

Btw, i'm using custom positions for helipads since they are for new traders. So in order to get the nearest helipad from the player buying the vehicle, i need to define that _activatingPlayer variable. But i don't know how and why since it's already in the file :mellow:

 

PS : Sorry if i'm not explaining correctly, english isn't my native langage.

Link to comment
Share on other sites

  • 0

_activatingPlayer is defined few lines below, it is taken from _this as 8th element when spawn was initiated (8th because element count starts from 0 where 0 is first element)

 

Basically this whole function is being called elsewhere from scheduled environment.. this means you cannot hold script using waituntil or sleep commands.

So, as a workaround scripters are putting their code on a new thread using spawn command. Think of it as a new function (new script file, its not, but still..) without name that is created on a new scheduled thread. Scheduled means that this thread will wait for confirmation from unscheduled environment when it's its turn to run (known as 0.3 sec delay). But before you can spawn new thread and local variables were used, you need to pass these variables to a new thread.

 

In line #39 you see exactly that. A new array is created on left from spawn command with 8 variables passed to a new thread.

When allowed, this thread will be executed, but you need means of taking passed variables, right? Well, that's actually very easy to do.

 

Passed variables (the array we gave to spawn) can be accessed using _this magic variable. Because we don't want whole array as a variable, we can select specific elements instead using select #.

So in this example first element is _object. Because arrays start count from 0, to access object we can do:

_this select 0;

The variables we cared for your script were _location and _activatingPlayer, right? 

_location = _this select 5;
_activatingPlayer = _this select 7;

I see you changed location to use nearestObject. It will not work this way, so you need to figure out a different way of doing things.
Either way, your undefined error in RPT indicates that you were checking variable BEFORE it was defined. In your script Line #47 checks, but Line #56 defines.

Keep in mind, variables are read from top to bottom, load order is very important.

 

My suggestion to make your script to work is - keep the original location define taken from _this array. Find out where helipad is... Dayz epoch automatically searches for nearest helipad for you. This means you can simply compare _location to your own custom arrays (thats why I gave you switch!)

 

By the way, make use of hint, systemchat and diag_log commands. While developing scripts, it is important (especially when starting) to find out bugs, these commands can output variables to screen or RPT so you can find out if something is wrong.

For example:

diag_log _dir;

hint str _location;

systemchat str _object;

str command takes variable and converts to string. Hint and systemchat only works with strings.

Getting the idea?

The reason I explain this is because you are trying to edit quite complex script, so this requires understanding things from slightly wider perspective. So sit down, try to figure out what I meant, hopefully things will make more sense when you edit it again.

Also hint: make use of notepad++ syntax highlighter (google it), it will apply colors to commands, easier to work with.

Link to comment
Share on other sites

  • 0

Hey,

 

I'm coming back with some news !

This is my actual server_publishVehicle2.sqf :

private ["_activatingPlayer","_isOK","_object","_worldspace","_location","_dir","_class","_uid","_key","_keySelected","_characterID","_donotusekey"];
//PVDZE_veh_Publish2 = [_veh,[_dir,_location],_part_out,false,_keySelected,_activatingPlayer];
_object =         _this select 0;
_worldspace =     _this select 1;
_class =         _this select 2;
_donotusekey =    _this select 3;
_keySelected =  _this select 4;
_activatingPlayer =  _this select 5;

if(_donotusekey) then {
    _isOK = true;
} else {
    _isOK = isClass(configFile >> "CfgWeapons" >> _keySelected);
};

if(!_isOK) exitWith { diag_log ("HIVE: CARKEY DOES NOT EXIST: "+ str(_keySelected));  };

if(_donotusekey) then {
    _characterID = _keySelected;
} else {
    _characterID = str(getNumber(configFile >> "CfgWeapons" >> _keySelected >> "keyid"));
};

diag_log ("PUBLISH: Attempt " + str(_object));
_dir =         _worldspace select 0;
_location = _worldspace select 1;

//Generate UID test using time
_uid = _worldspace call dayz_objectUID3;

// TODO: check if uid already exists && if so increment by 1 && check again as soon as we find nothing continue.

//Send request
_key = format["CHILD:308:%1:%2:%3:%4:%5:%6:%7:%8:%9:",dayZ_instance, _class, 0 , _characterID, _worldspace, [], [], 1,_uid];
diag_log ("HIVE: WRITE: "+ str(_key));
_key call server_hiveWrite;

// Switched to spawn so we can wait a bit for the ID
[_object,_uid,_characterID,_class,_dir,_location,_donotusekey,_activatingPlayer] spawn {
   private ["_object","_uid","_characterID","_done","_retry","_key","_result","_outcome","_oid","_class","_location","_object_para","_donotusekey","_activatingPlayer"];

   _object = _this select 0;
   _uid = _this select 1;
   _characterID = _this select 2;
   _class = _this select 3;
   //Spawned vehicle location
   _location = _this select 5;
   //Spawned vehicle direction
   _dir = switch (_location) do {
    case [1053.73,2795.45,0.00303841]: {146.893}; //if matches aircraft dealer south, set direction to 146.893
    case [2,2,2]: {2}; //empty
    case [3,3,3]: {3}; //empty
    default {0};
    };
    
    diag_log _dir;
    diag_log _location;
    
   _donotusekey = _this select 6;
   _activatingPlayer = _this select 7;

   _done = false;
    _retry = 0;
    // TODO: Needs major overhaul for 1.1
    while {_retry < 10} do {
        
        sleep 1;
        // GET DB ID
        _key = format["CHILD:388:%1:",_uid];
        diag_log ("HIVE: WRITE: "+ str(_key));
        _result = _key call server_hiveReadWrite;
        _outcome = _result select 0;
        if (_outcome == "PASS") then {
            _oid = _result select 1;
            //_object setVariable ["ObjectID", _oid, true];
            diag_log("CUSTOM: Selected " + str(_oid));
            _done = true;
            _retry = 100;

        } else {
            diag_log("CUSTOM: trying again to get id for: " + str(_uid));
            _done = false;
            _retry = _retry + 1;
        };
    };

    // Remove marker
    deleteVehicle _object;
    
    if(!_done) exitWith { diag_log("CUSTOM: failed to get id for : " + str(_uid)); };

    if(DZE_TRADER_SPAWNMODE) then {
        _object_para = createVehicle ["ParachuteMediumWest", [0,0,0], [], 0, "CAN_COLLIDE"];
        _object_para setPos [_location select 0, _location select 1,(_location select 2) + 65];
        _object = createVehicle [_class, [0,0,0], [], 0, "CAN_COLLIDE"];
    } else {
        _object = createVehicle [_class, _location, [], 0, "CAN_COLLIDE"];
    };

    if(!_donotusekey) then {
        // Lock vehicle
        _object setvehiclelock "locked";
    };

    clearWeaponCargoGlobal  _object;
    clearMagazineCargoGlobal  _object;
    // _object setVehicleAmmo DZE_vehicleAmmo;

    _object setVariable ["ObjectID", _oid, true];
    
    _object setVariable ["lastUpdate",time];
    
    _object setVariable ["CharacterID", _characterID, true];
    
    _object setDir _dir;

    if(DZE_TRADER_SPAWNMODE) then {
        _object attachTo [_object_para, [0,0,-1.6]];
        sleep 1.0;
        WaitUntil{(([_object] call FNC_GetPos) select 2) < 0.1};
        detach _object;
        deleteVehicle _object_para;
    };

    PVDZE_serverObjectMonitor set [count PVDZE_serverObjectMonitor,_object];

    _object call fnc_veh_ResetEH;
    
    // for non JIP users this should make sure everyone has eventhandlers for vehicles.
    PVDZE_veh_Init = _object;
    publicVariable "PVDZE_veh_Init";
    
    diag_log ("PUBLISH: " + str(_activatingPlayer) + " Bought " + (_class) + " with ID " + str(_uid));
};

 

I kept the original _location = _this select 5; so now i have this :

_object = _this select 0;
   _uid = _this select 1;
   _characterID = _this select 2;
   _class = _this select 3;
   _location = _this select 5;
   _dir = switch (_location) do {
    case [1053.73,2795.45,0.00303841]: {146.893}; //if matches aircraft dealer south, set direction to 146.893
    case [2,2,2]: {2}; //empty
    case [3,3,3]: {3}; //empty
    default {0};
    };

I added some diag_log for _dir and _location after this code and when i buy a vehicle in game at this specific trader, these are the results :

 

_location = 1053.73,2795.45,0.00303841 (these are the exact location where my vehicle spawn)

_dir = 0

 

So the switch thing isn't changing my _dir variable apparently, even if the coords are good. Is there a mistake into the syntax ?

 

Btw, i kept this too :

_object setVariable ["ObjectID", _oid, true];
    
_object setVariable ["lastUpdate",time];
    
_object setVariable ["CharacterID", _characterID, true];
	
_object setDir _dir;

But i don't know if this part is working since the result of _dir is still 0.

So my vehicle spawn but the direction it's facing is still north (0).

Link to comment
Share on other sites

  • 0

Very odd indeed...i've never checked arrays on switch personally, but this command is a bit peace of work if you ask me... hmm

I guess, replace switch with a simple IF statement for now, get your script running, then go back to fixing the less essential stuff.

dir = if (_location == [1053.73,2795.45,0.00303841]) then {146.893} else [0];
Link to comment
Share on other sites

  • 0

Error in RPT when i try with a simple IF statement :

18:40:08 Error in expression <= _this select 5;

 

_dir = if (_location == [1053.73,2795.45,0.00303841]) then {1>

18:40:08   Error position: <== [1053.73,2795.45,0.00303841]) then {1>

18:40:09   Error ==: Type Array, expected Number,String,Object,Side,Group,Text,Config entry,Display (dialog),Control,Team member,Task,Location

18:40:09 File z\addons\dayz_server\compile\server_publishVehicle2.sqf, line 49

I think something is wrong with the locations array inside the if statement, no ?

Link to comment
Share on other sites

  • 0

God damn peasant arma 2, slipped my mind that you can't compare 2 arrays that easily, in A3 isEqualTo usually does it for me.

Sorry for misleading info... had to google solution for this one:

dir = if ([_location, [1053.73,2795.45,0.00303841]] call BIS_fnc_areEqual) then {146.893} else [0];

There is, however, a dirty trick to get switch or == to work with this. For something as simple as this, it shouldn't be a sin (lol). Normally arrays can't be compared due to amount of elements that engine requires you to go trough (function above), but for such simple position arrays that only holds 3 elements there's an easy fix that gets the job done and is visually friendlier when adding more locations - namely stringify everything! Crazy, but should work just fine:

_locString = str _location; //convert array to string so switch works
_dir = switch (_locString) do {
	case "[1053.73,2795.45,0.00303841]": {146.893}; //if matches aircraft dealer south, set direction to 146.893
	case "[2,2,2]": {2}; //empty
	case "[3,3,3]": {3}; //empty
	default {0};
};

So what happens now is - we end up checking simple strings instead of complex arrays. In theory this should be faster than using bis function (for the simple stuff like this).
I am using this method when checking UI Controls inside switch, works just fine.

 

edit: derp

Edited by raymix
Link to comment
Share on other sites

  • 0

Mmmh... Still not working :(

 

No error, but the vehicle spawn facing north, the direction isn't modified (still 0).

 

Edit : Oh you did the same error on switch. You put the {} ! I'll try with () :lol:

 

Edit 2 : Finally ! It's working !

 

I have to try with other locations in the switch and i will come back to tell you if everything is fine !

Thanks so much for your help :)

Link to comment
Share on other sites

Please sign in to comment

You will be able to leave a comment after signing in



Sign In Now
  • Advertisement
  • Discord

×
×
  • Create New...