Undetectable bug? (Vehicle system - Car ID's - Won't despawn correctly)
#1

Car bugs, freeroam


Hello!
Okay, now after checking my code at least 40-50 times, re-coding the entire vehicle system and replacing PVars with arrays, I still can't find the bug, which is causing vehicles to be messed up. By messed up, I mean that vehicle ID's, specifically car ID 255 (which is server-sided on restart), is causing players to steal vehicles from eachother, and causing additional vehicle features to bug, such as a Private vehicle system I've made. First, I thought CreateVehicle returned 255 in some cases, because instead of creating a new vehicle, it just stole a vehicle from someone else. -_-

I have also been in-touch with several people on the #sa-mp.scripting IRC channel, in order to get details about different functions and callbacks, and how they act in different situations.


What the system is supposed to do?
- Mainly, I want it to handle the cars in such a way, that it doesn't end up being vehicles spawned everywhere on the server. So I am currently allowing one spawned car per playerid. When a new car is spawned, I use a check to see if there is any past-spawned cars, and if so (and if valid) I destroy it before i create the new one.
The Race system I made also uses the "per-playerid" spawned cars Array, so the Race vehicle also can get destroyed when the player is either leaving or spawning a new car after the race.


What can I see that bugs up?
- Firstly, after I changed the code to check for "IsValidVehicle", I started experiencing alot more car-spam around the map than before.
Also, I've kept a close eye on Car ID 255 when Im online. And it has always something to do with players after a while. I did never actually see how it bugs up. All I know is that it is spawned on OnGamemodeInit() (look at the attachment)

Please be aware, that I did not create a global function to call each time, as I wasn't aware of that method back then when i started out with it.




The code I use
OnPlayerDeath(playerid):
PHP код:
if(AccInfo[playerid][SpawnedCarID] != INVALID_VEHICLE_ID)
    {
        
DestroyVehicle(AccInfo[playerid][SpawnedCarID]);
        
AccInfo[playerid][SpawnedCarID] = INVALID_VEHICLE_ID;
    } 
OnPlayerDisconnect(playerid)
PHP код:
if(AccInfo[playerid][SpawnedCarID] != INVALID_VEHICLE_ID)
    {
        
DestroyVehicle(AccInfo[playerid][SpawnedCarID]);
        
AccInfo[playerid][SpawnedCarID] = INVALID_VEHICLE_ID;
    }
    if(
PlayerInfo[playerid][CarID] != -1)
    {
        if(
IsValidVehicle(PlayerInfo[playerid][CarID]))
            
DestroyVehicle(PlayerInfo[playerid][CarID]);
        
DestroyDynamic3DTextLabel(PlayerInfo[playerid][textie]);
        
PlayerInfo[playerid][CarID] = -1;
    } 
CMD:car
PHP код:
if(AccInfo[playerid][SpawnedCarID] != INVALID_VEHICLE_ID)
    {
        
printf("CMD:CAR = Old spawned car ID = %d  BY Payerid = %d",AccInfo[playerid][SpawnedCarID],playerid);
        
DestroyVehicle(AccInfo[playerid][SpawnedCarID]);
        
AccInfo[playerid][SpawnedCarID] = INVALID_VEHICLE_ID;
    }
        
LVehicleID CreateVehicle(carX,Y,ZAngle123colour1colour2, -1);
    
AccInfo[playerid][SpawnedCarID] = LVehicleID
Tuned cars:
PHP код:
if(AccInfo[playerid][SpawnedCarID] != INVALID_VEHICLE_ID)
        {
            
DestroyVehicle(AccInfo[playerid][SpawnedCarID]);
            
AccInfo[playerid][SpawnedCarID] = INVALID_VEHICLE_ID;
        }
        
LVehicleIDt CreateVehicle(560,X,Y,Z,Angle123,1,-1,-1);
        
AccInfo[playerid][SpawnedCarID] = LVehicleIDt
And so the method goes for all player spawned vehicles..


Race system:
PHP код:
//Joining the race:
if(GetPlayerState(playerid) == PLAYER_STATE_DRIVER)
        
RemovePlayerFromVehicle(playerid);
    if(
AccInfo[playerid][SpawnedCarID] != INVALID_VEHICLE_ID)
    {
        
DestroyVehicle(AccInfo[playerid][SpawnedCarID]);
        
AccInfo[playerid][SpawnedCarID] = INVALID_VEHICLE_ID;
    }
//////////////
//then this function is called:
forward PutRacerInVehicle(i); //called from the function timer, so the maps can load.
public PutRacerInVehicle(i)
{
            new 
Float:xFloat:yFloat:z;
            
GetPlayerPos(ix,yz);
            new 
car CreateVehicle(Data[RaceCar], xyData[StartZ]+1,Data[Angle], -1, -1, -1);
            
SetVehicleVirtualWorld(carraceworld);
            
PutPlayerInVehicle(icar0);
            
AccInfo[i][SpawnedCarID] = car;
            return 
1;

(Im sorry about the identation, it gets kinda fked when i paste it into the forums )


At least you can see system
Am I doing anything wrong, and can i get some nice help on how to solve this?
Is a vehicle returned as "valid" when it just exploded? Or, what about the CreateVehicle(........, SPAWN_TIME); ?

Am I missing something?

I hate issues with the cars, as they are really important in that kind of gamemodes.


EDIT

Restarted server today again.
Quote:

[09:01:42] CMD:CAR = Old spawned car ID = 489 BY Payerid = 11
[09:01:42] CMD:CAR = LvehicleID = 255
[09:01:42] CMD:CAR = new spawned car ID (VAR) = 255 BY Payerid = 11

I was standing by Vehicle 255 and just watching, until i got this one ^
It didn't reuse the slot of the old car, instead just taking Vehicle ID 255. for no reason.


Help is hugely appreciated!
denNorske
Reply
#2

Do you have any code at OnVehicleDeath?

If not, the following could happen:

Player A spawns a vehicle with ID 1.
This vehicle explodes and despawns.
Player B spawns a vehicle, this vehicle will have ID 1.
Player A spawns a new vehicle, causing vehicle ID 1 to be deleted because his variable was not reset.

I hope it helps.
Reply
#3

The thing is, no one used Vehicle ID 255, when the bug occurred.

And therefore, this wouldn't explain this.

EDIT: Also, the vehicle is valid until you literally used DestroyCar on it, which would count in your explanation.
Reply
#4

I have rescripted the vehicle system;

SpawnPlayerVehicle is a function I call in all places where there is a player-vehicle spawned (to avoid car spam)

PHP код:
stock SpawnPlayerVehicle(playeridvehicleidFloat:x,Float:y,Float:z,Float:anglecolor1313,color2323respawn = -1,putinvehicle)
{
    
#pragma unused respawn
    
if(IsValidVehicle(AccInfo[playerid][SpawnedCarID]))
    {
 
        
printf("SpawnPlayerVehicle: Old spawned car ID = %d  BY Playerid = %d (Destroyed)",AccInfo[playerid][SpawnedCarID],playerid);
        
DestroyVehicle(AccInfo[playerid][SpawnedCarID]);
        
AccInfo[playerid][SpawnedCarID] = -1;
    }
 
    
AccInfo[playerid][SpawnedCarID] = CreateVehicle(vehicleidx,y,zanglecolor1313color2323240);
    
printf("SpawnPlayerVehicle: New spawned car ID = %d  BY Playerid = %d (Created)",AccInfo[playerid][SpawnedCarID],playerid);
    if(
AccInfo[playerid][SpawnedCarID] == 255)
    {
        print(
"IT WAS Vehicle ID 255, was sent to hell (World 255)");
        
SetVehicleVirtualWorld(255255);
        
AccInfo[playerid][SpawnedCarID] = CreateVehicle(vehicleidx,y,zanglecolor1313color2323240);
        
printf("SpawnPlayerVehicle: New spawned car ID = %d  BY Playerid = %d (Created)",AccInfo[playerid][SpawnedCarID],playerid);
        if(!
IsPlayerInRace[playerid])
            
putinvehicle 0;
    }
    if(
AccInfo[playerid][SpawnedCarID] == 255)
    {
        print(
"IT WAS Vehicle ID 255, was sent to hell AGAIN (World 255)\nFATAL ERROR VEHICLE 255 !!!!");
        
SetVehicleVirtualWorld(255255);
        return 
scm(playeridred"An Error Occured. Please contact one of the scripters! (Vehicle 255)");
    }
    
SetVehicleVirtualWorld(AccInfo[playerid][SpawnedCarID], GetPlayerVirtualWorld(playerid));
    
LinkVehicleToInterior(AccInfo[playerid][SpawnedCarID], GetPlayerInterior(playerid));
    if(
putinvehicle == 1)
    {
        
PutPlayerInVehicle(playeridAccInfo[playerid][SpawnedCarID], 0);
    }
    return 
1;

However, it did also end up with:

Код:
//here is the paste from my log, first occurrence in the i could find, appears randomly from /carmenu
 
[15:07:36] SpawnPlayerVehicle: Old spawned car ID = 470  BY Playerid = 6 (Destroyed)
[15:07:36] SpawnPlayerVehicle: New spawned car ID = 255  BY Playerid = 6 (Created)
[15:07:36] IT WAS Vehicle ID 255, was sent to hell (World 255) //I set the Virtual world of the vehicle, and tries to spawn a new one, as a temporary "patch".
[15:07:36] SpawnPlayerVehicle: New spawned car ID = 456  BY Playerid = 6 (Created)
But, i got help on the scripting channel, where they told me to redifine the destroyvehicle and createvehicle functions, so i did (in order to log)

PHP код:
#undef CreateVehicle
#undef DestroyVehicle
stock Log_CreateVehicle(vehicletype,Float:x,Float:y,Float:z,Float:rotation,color1,color2,respawn_delay) {
        new 
vehicleid CreateVehicle(vehicletype,x,y,z,rotation,color1,color2,respawn_delay);
        
printf("CreateVehicle(%d,%f,%f,%f,%f,%d,%d,%d) = %d",vehicletype,x,y,z,rotation,color1,color2,respawn_delay,vehicleid);
        return 
vehicleid;
}
#define CreateVehicle Log_CreateVehicle
stock Log_DestroyVehicle(vehicleid)
{
    if(!
IsValidVehicle(vehicleid))
        return 
0;
    else
    {
        
printf("><>><><><<<<<>><  DestroyVehicle(%d) >><<<<>><<><<<<<><>>"vehicleid);
        
DestroyVehicle(vehicleid);
        return 
1;
    }
}
#define DestroyVehicle Log_DestroyVehicle 
But, still i end up with this:

Код:
[18:47:49] SpawnPlayerVehicle: Old spawned car ID = 458  BY Playerid = 1 (Destroyed)
[18:47:49] ><>><><><<<<<>><  DestroyVehicle(458) >><<<<>><<><<<<<><>>
[18:47:49] CreateVehicle(444,1807.247070,-1297.331298,132.105606,0.000000,-1,-1,240) = 255
[18:47:49] SpawnPlayerVehicle: New spawned car ID = 255  BY Playerid = 1 (Created)
[18:47:49] IT WAS Vehicle ID 255, was sent to hell (World 255)
[18:47:49] CreateVehicle(444,1807.247070,-1297.331298,132.105606,0.000000,-1,-1,240) = 458
[18:47:49] SpawnPlayerVehicle: New spawned car ID = 458  BY Playerid = 1 (Created)
As you can see, there nothing wrong happening, besides that 255...
Why is the vehicle id returned as to be 255, and mess up the entire vehicle system?

Any suggestions what to do further?
Thanks
Reply
#5

[Update]

The first bug i had is resolved (above), and it's not a problem anymore.
Now i just have that two players might end up having the same car id in their SpawnedCarID variable, and therefore they "steal" cars.
I'll figure that out, and suggestions are appreciated.
Reply
#6

CreateVehicle can re-use vehicle ids.If you destroy a vehicle, that vehicle id becomes free so the next time you use CreateVehicle it will return the first unused vehicle id.

Therefore do not rely on vehicle ids(I mean using the same vehicle ids after respawn).Vehicle IDs can change.

Probably vehicle id 255 was destroyed at some point because of which CreateVehicle used 255.
Reply


Forum Jump:


Users browsing this thread: 1 Guest(s)