Detecting a /v car.
#1

------
Reply
#2

Код:
new bool:VehiclesByVCommand[2000];

// In your /v command use:
VehiclesByVCommand[vehicleid] = true;
After that, you could have a command that destroys all vehicles created by /v.
Just loop through all vehicles (from 1 to 1999) and check if the VehicleByVCommand is set to "true".
If it's "true", destroy the vehicle and set this variable back to "false" (to prevent trying to destroy the vehicle again if the command is used again afterwards).
If it's false, do nothing.
Reply
#3

You could set a variable to the vehicle to make it unique. That will let you detect if it's unique, for example:

This way is probably alot more inefficient than others,

pawn Код:
new bool:HasUniqueVehicle[MAX_PLAYERS];

CMD:v(playerid, params[])
{
    if(HasUniqueVehicle[playerid] == false)
    {
        // codes here
        HasUniqueVehicle[playerid] = true;
    }
    else
    {
        SendClientMessage(playerid, -1, "You already have a unique vehicle!");
    }
}

CMD:doesplayerhavev(playerid, params[])
{
    new target;
    if(sscanf(params, "d", target)) return SendClientMessage(playerid, -1, "Usage: /doesplayerhavev <targetid>");
    {
        if(HasUniqueVehicle[target] == true)
        {
            SendClientMessage(playerid, -1, "He has a unique vehicle");
        }
        else
        {
            SendClientMessage(playerid, -1, "He does not have a unique vehicle");
        }
    }
}
Reply
#4

Quote:

After that, you could have a command that destroys all vehicles created by /v.
Just loop through all vehicles (from 1 to 1999) and check if the VehicleByVCommand is set to "true".
If it's "true", destroy the vehicle and set this variable back to "false" (to prevent trying to destroy the vehicle again if the command is used again afterwards).
If it's false, do nothing.

After what you just said there, I had written a piece of code(untested) but im pretty sure this is going to just destroy every vehicle in the server:
pawn Код:
CMD:delv(playerid, params[])
{
    for(new v = 0; v < MAX_VEHICLES; ++v)
    {
        if(VehiclesByVCommand[v] == true)
        {
            DestroyVehicle(v);
        }
    }
    return 1;
}
I know this isn't my thread, though this could be useful to myself in future updates of my script.
Reply
#5

Quote:
Originally Posted by PowerPC603
Посмотреть сообщение
Код:
new bool:VehiclesByVCommand[2000];

// In your /v command use:
VehiclesByVCommand[vehicleid] = true;
After that, you could have a command that destroys all vehicles created by /v.
Just loop through all vehicles (from 1 to 1999) and check if the VehicleByVCommand is set to "true".
If it's "true", destroy the vehicle and set this variable back to "false" (to prevent trying to destroy the vehicle again if the command is used again afterwards).
If it's false, do nothing.
Why are you using 2000 instead of MAX_VEHICLES? I know MAX_VEHICLES is equals to 2000, but sometimes scripters does not use all of it, so they do is re-define MAX_VEHICLES and change its size, I'm not insulting you in anyway it's just my opinion that using MAX_VEHICLES is much better so if you loop VehiclesByVCommand using (sizeof VehiclesByVCommand) of course, the loop will continue until 2000 instead of the new size you just redefined.
Reply
#6

Quote:
Originally Posted by PowerPC603
Посмотреть сообщение
Код:
new bool:VehiclesByVCommand[2000];

// In your /v command use:
VehiclesByVCommand[vehicleid] = true;
After that, you could have a command that destroys all vehicles created by /v.
Just loop through all vehicles (from 1 to 1999) and check if the VehicleByVCommand is set to "true".
If it's "true", destroy the vehicle and set this variable back to "false" (to prevent trying to destroy the vehicle again if the command is used again afterwards).
If it's false, do nothing.
MAX_VEHICLES is defined as 2000 so why not to use all of them (slots/indexes) but only 1999? I don't see any point of leaving the index 0 unused.

pawn Код:
// In your /v command use:
VehiclesByVCommand[vehicleid - 1] = true;
Reply
#7

Thank you guys for your responses I'll test it and leave a response.
Reply
#8

Quote:
Originally Posted by Konstantinos
Посмотреть сообщение
MAX_VEHICLES is defined as 2000 so why not to use all of them (slots/indexes) but only 1999? I don't see any point of leaving the index 0 unused.

pawn Код:
// In your /v command use:
VehiclesByVCommand[vehicleid - 1] = true;
Samp will only creates vehicleid's from 1 to 1999 anyway.
I just tested it by spawning a little over 2000 vehicles.
The first ID was 1, the last was 1999.
Vehicle 2000 and over that got vehicleid 65535 (Invalid vehicle id).

So, in your array, you would have index 1999 unused (because you're setting vehicle id 1999 - 1 = 1998 to "true") instead of index 0, so no difference there.
Using index 0 for vehicle id 1 is also adding to your own confusion, because if you forget somewhere you've done that you're messing up all your data or getting the wrong data from your array.
I find it much simpler to use index 1 for vehicle id 1, index 5 for vehicle id 5, and so on.
You can never get confused this way.

And who cares about 4 bytes that aren't used when you have computers with 8GB RAM or more?
Unless you declare your array with [MAX_VEHICLES - 1] as well, to save 4 bytes of memory.

pawn Код:
// This command deletes all vehicles that are spawned using /v
COMMAND:cleanupcars(playerid, params[])
{
    // If the player didn't login properly, fail the command
    if (APlayerData[playerid][LoggedIn] == false) return 0;
    // If the player has an insufficient admin-level (he needs level 3), exit the command
    if (APlayerData[playerid][AdminLevel] < 3) return SendClientMessage(playerid, 0xFFFFFFFF, "{FF0000}Only admins level 3 can use this command");
    // If the player is on the class-selection menu, block the command
    if ((GetPlayerState(playerid) == PLAYER_STATE_WASTED) || (GetPlayerState(playerid) == PLAYER_STATE_NONE)) return SendClientMessage(playerid, 0xFFFFFFFF, "{FF0000}You cannot use this command while using class-selection");

    // Setup local variables
    new CarsDeleted, Msg[128];

    // Loop through all vehicles
    for (new vid; vid < MAX_VEHICLES; vid++)
    {
        // Check if this vehicle was spawned by the /v command
        if (AVehicleData[vid][SpawnedByVCommand] == true)
        {
            // Count the cars that have been deleted
            CarsDeleted++;
            // Destroy the vehicle and clear the data
            DestroyVehicle(vid);
            AVehicleData[vid][SpawnedByVCommand] = false;
        }
    }

    // Let the player know how many vehicles have been cleaned up
    format(Msg, 128, "{00FF00}Total number of vehicles cleaned up: {FFFF00}%i", CarsDeleted);
    SendClientMessage(playerid, 0xFFFFFFFF, Msg);

    // Let the server know that this was a valid command
    return 1;
}
This is my /cleanupcars command are only destroys all vehicles spawned by the /v command.
I've tested this alot and it always does what it's meant to do.



EDIT:
I've tested another thing.
Using (vehicleid - 1) instead of (vehicleid) to access your array also adds extra compiler instructions which makes your amx file larger.

I've added this to my script to check it out.
pawn Код:
new vehicleid;

    if (AVehicleData[vehicleid][SpawnedByVCommand] == true)
    {
    }
Then I used this code:
pawn Код:
new vehicleid;

    if (AVehicleData[vehicleid - 1][SpawnedByVCommand] == true)
    {
    }
Guess what?
The second code actually made my amx file larger by 5 bytes.
So reducing your array size with 1 index (saving 4 bytes) but adding code to access data properly by using index 0 (for vehicles anyway) made it 5 bytes larger.

If you access your array 100 times throughout your script by adding "- 1" to access the proper data, you're actually adding 500 bytes to your amx file, which is loaded into memory as you start your server.

You see 1 index (index 0) in your array wasted memory (only 4 bytes)?
What about the extra code that takes 500 bytes of memory? And it makes your script confusing on top of that, or even buggy if you forgot to add the "- 1" somewhere, or even access the array beyond it's limits, resulting in Array-out-of-bound errors.
Reply
#9

I've never spawned many vehicles and it was something I never knew about valid vehicles 1-1999. I thought it was up to 2000.

But it can still be used as:
pawn Код:
new bool:VehiclesByVCommand[MAX_VEHICLES - 1];

// In your /v command use:
VehiclesByVCommand[vehicleid - 1] = true;
and the worst part of the above is:
pawn Код:
for (new vid; vid < MAX_VEHICLES; vid++)
Your server has 4 vehicles only (an example) and you loop 2000 times. It seems bad, isn't it? The best solution would be an iterator (foreach) for the created vehicles and it will loop through ONLY the valid (those which exist) vehicles.

I'm not saying that the code is bad, this is how it would be used by the most users but optimizations (even small ones) are always good - atleast for me.
Reply
#10

I guess most samp users don't know about this.
The wiki also should be corrected as the amount of vehicles isn't 2000, but 1999.



I'll actually be using almost 2000 vehicles in my script.
500-600 for mission vehicles, 400 for company vehicles and about 800 house vehicles.
This leaves little room for something else, like extra vehicles created during /work for some classes or spawned vehicles using the /v command.

Of course my code could be optimized as well, since the mission vehicles are loaded when the server starts and they are never destroyed so they appear first (before any /v vehicles or house vehicles or company vehicles).
So I could actually start looping through the vehicles starting at the index just after the mission vehicles (it would save 500-600 loops).

I would rather use collections or linked lists but pawn doesn't support it natively.
Reply


Forum Jump:


Users browsing this thread: 1 Guest(s)