Author Topic: Getting a list of vehicles on the server  (Read 1469 times)

Dumb question...
How would I loop through the vehicle menu to see if a vehicle is on the list?

Code: [Select]
for ??

Don't know if it's also stored somewhere else.
Just do something like this.
Code: [Select]
%count = getDataBlockGroupSize();

for(%i = 0; %i < %count; %i++)
{
%data = getDataBlock(%i);

if(%data.getClassName() $= "something" || %data.getClassName() $= "somethingElse" || (%data.getClassName() $= "PlayerData" && %data.rideable))
{
//It's a vehicle
}
}

Don't know if it's also stored somewhere else.
Just do something like this.
Code: [Select]
getDataBlockGroupSize();

Thank you sir this is what I was looking for, a way to count current datablocks
« Last Edit: January 23, 2016, 07:35:27 AM by Goth77 »

Alright so...using this command lags the hell outta me for about 30 seconds while the console sifts through all the datablock groups. To make matters worse, it doesn't seem like I am able to get the datablock from the group object?

Code: [Select]
function serverCMDCheckVehicleType(%client, %vehicle)
{
%count = getDataBlockGroupSize();
for(%i=0; %i < %count; %i++)
{
%data = %i.getDataBlock();
%type = %data.getClassName();

if(%type $= "WheeledVehicle" || %type $= "FlyingVehicle")
{
echo("" @ %data.uiName @ "");
}
}
}

That's not correct.

%i is an iteration counter. It's 0, 1, 2, 3, 4, ... datablock count.
Find the simset for all the datablocks and use .getObject(%i) on that.

something like this
Code: [Select]
function indexVehicles()
{
$VehicleListCount = -1;
%size = getDataBlockGroupSize();

for(%i=0;%i<%size;%i++)
{
%d= getDataBlock(%i);
if(%d.getClassName() $= "Vehicle" || (%d.getClassName() $= "Player" && %d.rideable))
$VehicleList[$VehicleListCount++] = %d;
}
}
function checkVehicleType(%vehicle)
{
for(%i=0;%i<$VehicleListCount;%i++)
{
%d = $VehicleList[%i];
if(%d.uiName $= %vehicle)
return %d;
}
return -1;
}
indexVehicles();
You want to store all the vehicles in a small array so that you just go through that array instead of iterating every single datablock every time


Another way of storing the array, this will allow you to access the elements in the array without having to check more than one element but it locks you into only being able to access them with the uiName
Code: [Select]
function indexVehiclesUi()
{
%size = getDataBlockGroupSize();

for(%i=0;%i<%size;%i++)
{
%d= getDataBlock(%i);
if(%d.getClassName() $= "Vehicle" || (%d.getClassName() $= "Player" && %d.rideable))
$VehicleListUi[%d.uiName] = %d;
}
}
function checkVehicleType(%vehicle)
{
if(isObject($VehicleListUi[%vehicle]))
return $VehicleListUi[%vehicle];
return -1;
}
indexVehiclesUi();


Find the simset for all the datablocks and use .getObject(%i) on that.
default blockland functions use getDatablock(%i); and getDataBlockGroupSize();
iterating through the simSet is absolute last resort and should not be done unless you are doing this completely client-sidedly
« Last Edit: January 24, 2016, 02:21:04 AM by Swollow »

Thanks for the help all

For some reason I cannot get the class name during the loop? But I can get the datablock name?

Code: [Select]
function indexVehicles()
{
%size = getDataBlockGroupSize();

for(%i=0;%i<%size;%i++)
{
%d = getDataBlock(%i);
%c = getClassName(%d);
echo("" @ %c @ "");
}
}
indexVehicles();
« Last Edit: January 24, 2016, 05:46:45 AM by Goth77 »

Thanks for the help all

For some reason I cannot get the class name during the loop? But I can get the datablock name?

Code: [Select]
function indexVehicles()
{
%size = getDataBlockGroupSize();

for(%i=0;%i<%size;%i++)
{
%d = getDataBlock(%i);
%c = getClassName(%d);
echo("" @ %c @ "");
}
}
indexVehicles();
getClassName is an object function
replace line 8 with
Code: [Select]
%c = %d.getClassName();

Thanks again Swollow. After messing around with code for a bit I have figured out a few things.
First off, it's not a good idea to call the indexing function before player datablocks are loaded (or any datablocks, for that matter). This makes calling the index function during code execution a bad idea because it only shows datablocks that have been loaded before the function. I decided to leave out player type objects/armor class because it also returns all playertypes that are parented to the standard player armor (rideable). I'm fine with only wheeled/flying vehicles in this case. It wouldnt be hard to make an exception for the horse uiName

For some reason I cannot call the getClassName() function on a datablock directly because %datablock.className is already a variable? Well that makes sense...

Code: [Select]
function serverCMDsetNextVehicle(%client,%vehicle)
{
//Cycle through datablocks
%size = datablockGroup.getCount();
for(%i=0;%i<%size;%i++)
{
%d = getDataBlock(%i);

if(%d.rideable $= true && %d.className $= "FlyingVehicleData" || %d.className $= "WheeledVehicleData")
{
                       echo("" @ %d.uiName@ "");

if(%d.uiName $= %vehicle)
{
echo("" @ %vehicle @ "");
%client.selectedVehicle = %d.getName();
bottomPrint(%client,"Next vehicle set to " @ %vehicle @ " ",2,true);
break;
}
}
}
}

When i echo the ui name it works, but if(%d.uiName $= %vehicle) always returns false unless left empty...but echoing %vehicle right after echoing the ui name returns input....wtf??
« Last Edit: January 24, 2016, 08:27:39 PM by Goth77 »

do
schedule(0,0,indexVehicles);
this will make the function called after all of the addons have been loaded

I still can't figure out why %d.uiName will not check if $= %vehicle even though
/setNextVehicle Jeep echos "Jeep" before the if statement. I even tried making another variable
outside the loop %ride = %vehicle and then checking if %d.uiName $= %ride, but that didn't work either.
« Last Edit: January 24, 2016, 09:26:38 PM by Goth77 »

On second thought, I wouldn't cycle through all datablocks. Instead keep track of all vehicles added to the server.
Code: [Select]
if(!isObject(vehicleGroup))
    new simset(vehicleGroup);
package vehicles
{
    function Vehicle::onAdd(%vehicle)
    {
        parent::onAdd(%vehicle);
        vehicleGroup.add(%vehicle);
    }
};
activatePackage(vehicles);
Wrote this on my phone so sorry for any typos.

Then just cycle through that group to get any vehicle on the server currently.

On second thought, I wouldn't cycle through all datablocks. Instead keep track of all vehicles added to the server.
Code: [Select]
if(!isObject(vehicleGroup))
    new simset(vehicleGroup);
package vehicles
{
    function Vehicle::onAdd(%vehicle)
    {
        parent::onAdd(%vehicle);
        vehicleGroup.add(%vehicle);
    }
};
activatePackage(vehicles);
Wrote this on my phone so sorry for any typos.

Then just cycle through that group to get any vehicle on the server currently.
but thats not what hes trying to accomplish

but thats not what hes trying to accomplish
I'm just offering an alternative even though it requires monitoring from the start.

I'm just offering an alternative even though it requires monitoring from the start.
no that is storing vehicle objects, goth77 is looking for vehicle datablocks