In my script, there are two vehicle types: player; and faction. This is the enum:
Player Vehicles
Player vehicles only spawn when the player is logged in, and they disappear when the player logs out. The player vehicles are created, saved, loaded and unloaded like so --
Created:
Saved:
Loaded:
Unloaded:
Faction Vehicles
Faction vehicles load when the server starts, and remain there permanently. They are created and loaded like so --
Now, BOTH of these work in isolation.
If I create a player car for myself it creates and saves, and then when I logout it disappears, and re-appears on logging back in.
If I create faction cars, they save and load successfully, and re-appear on server restart.
HOWEVER, if I create a faction car AND a player car and then logout, it all goes tits up. It's so random, sometimes both cars will disappear, sometimes the player car will disappear, sometimes the faction car will. Then, when I relog, they will both appear. Sometimes the car will duplicate itself (but not save to the database). If there are two players in-game both with player cars, if ONE of us logs out, BOTH cars will disappear and the random screw ups will start again, with the cars disappearing and respawning at random when someone re-connects or leaves.
I have no idea wtf is causing this, I've tried to fix it and I just can't. Player cars and faction cars save to separate tables in the database. Should I use two separate enums? Are the SQL IDs conflicting? I'm so confused.
PHP Code:
enum carData {
carID, // This is the SQL ID.
carExists,
carModel,
carOwner,
Float:carPos[4],
carColor1,
carColor2,
carPlate[11],
carLocked,
carParked,
carWorld,
carRank,
carFaction,
carVehicle
Player vehicles only spawn when the player is logged in, and they disappear when the player logs out. The player vehicles are created, saved, loaded and unloaded like so --
Created:
PHP Code:
CMD:createpcar(playerid, params[])
{
static
userid,
model[32];
if (PlayerData[playerid][pAdmin] < 4)
return SendErrorMessage(playerid, "You don't have permission to use this command.");
if (sscanf(params, "us[32]", userid, model))
return SendSyntaxMessage(playerid, "/createpcar [playerid/name] [modelid/name]");
if (Car_GetCount(userid) >= MAX_OWNABLE_CARS)
return SendErrorMessage(playerid, "This player already owns the maximum amount of cars.");
if ((model[0] = GetVehicleModelByName(model)) == 0)
return SendErrorMessage(playerid, "Invalid model ID.");
static
Float:x,
Float:y,
Float:z,
Float:angle,
id = -1;
GetPlayerPos(userid, x, y, z);
GetPlayerFacingAngle(userid, angle);
id = PlayerCar_Create(PlayerData[userid][pID], model[0], x, y + 2, z + 1, angle, random(127), random(127));
if (id == -1)
return SendErrorMessage(playerid, "The server has reached the limit for dynamic vehicles.");
SendServerMessage(playerid, "You have created vehicle ID: %d for %s.", CarData[id][carVehicle], ReturnName(userid, 0));
return 1;
}
PlayerCar_Create(ownerid, modelid, Float:x, Float:y, Float:z, Float:angle, color1, color2)
{
for (new i = 0; i != MAX_DYNAMIC_CARS; i ++)
{
if (!CarData[i][carExists])
{
if (color1 == -1)
color1 = random(127);
if (color2 == -1)
color2 = random(127);
CarData[i][carExists] = true;
CarData[i][carModel] = modelid;
CarData[i][carOwner] = ownerid;
CarData[i][carPos][0] = x;
CarData[i][carPos][1] = y;
CarData[i][carPos][2] = z;
CarData[i][carPos][3] = angle;
CarData[i][carColor1] = color1;
CarData[i][carColor2] = color2;
new str[8], query[400];
format(str, sizeof(str), "%s%s%d%d%s%s%s", LetterList[random(sizeof(LetterList))], LetterList[random(sizeof(LetterList))], random(9), random(9), LetterList[random(sizeof(LetterList))], LetterList[random(sizeof(LetterList))], LetterList[random(sizeof(LetterList))]);
SetVehicleNumberPlate(i, str);
format(CarData[i][carPlate], 11, "%s", str);
CarData[i][carPaintjob] = -1;
CarData[i][carLocked] = false;
CarData[i][carParked] = 0;
CarData[i][carWorld] = 0;
CarData[i][carImpounded] = -1;
CarData[i][carImpoundPrice] = 0;
for (new j = 0; j < 14; j ++)
{
if (j < 5)
{
CarData[i][carWeapons][j] = 0;
CarData[i][carAmmo][j] = 0;
}
CarData[i][carMods][j] = 0;
}
CarData[i][carVehicle] = CreateVehicle(modelid, x, y, z, angle, color1, color2, -1);
if (CarData[i][carVehicle] != INVALID_VEHICLE_ID) {
ResetVehicle(CarData[i][carVehicle]);
}
mysql_format(g_iHandle, query, sizeof(query), "INSERT INTO `playercars` (carModel, carOwner, carPosX, carPosY, carPosZ, carPosR, carColor1, carColor2, carPlate, carPaintjob, carParked, carWorld) VALUES(%d, %d, %f, %f, %f, %f, %d, %d, '%s', -1, 0, 0)",
CarData[i][carModel],
CarData[i][carOwner],
CarData[i][carPos][0],
CarData[i][carPos][1],
CarData[i][carPos][2],
CarData[i][carPos][3],
CarData[i][carColor1],
CarData[i][carColor2],
CarData[i][carPlate],
CarData[i][carPaintjob],
CarData[i][carParked],
CarData[i][carWorld]);
mysql_tquery(g_iHandle, query, "OnplayerCarCreated", "i", i);
return 1;
}
}
return -1;
}
forward OnPlayerCarCreated(carid);
public OnPlayerCarCreated(carid)
{
if (carid == -1 || !CarData[carid][carExists])
return 0;
CarData[carid][carID] = mysql_insert_id();
PlayerCar_Save(carid);
return 1;
}
PHP Code:
PlayerCar_Save(carid)
{
static
query[900];
if (CarData[carid][carVehicle] != INVALID_VEHICLE_ID)
{
for (new i = 0; i < 14; i ++) {
CarData[carid][carMods][i] = GetVehicleComponentInSlot(CarData[carid][carVehicle], i);
}
}
format(query, sizeof(query), "UPDATE `playercars` SET `carModel` = '%d', `carOwner` = '%d', `carPosX` = '%.4f', `carPosY` = '%.4f', `carPosZ` = '%.4f', `carPosR` = '%.4f', `carColor1` = '%d', `carColor2` = '%d', `carPlate` = '%s', `carLocked` = '%d', `carParked` = '%d', `carWorld` ='%d'",
CarData[carid][carModel],
CarData[carid][carOwner],
CarData[carid][carPos][0],
CarData[carid][carPos][1],
CarData[carid][carPos][2],
CarData[carid][carPos][3],
CarData[carid][carColor1],
CarData[carid][carColor2],
CarData[carid][carPlate],
CarData[carid][carLocked],
CarData[carid][carParked],
CarData[carid][carWorld]
);
return mysql_function_query(g_iHandle, query, false, "", "");
}
PHP Code:
public OnPlayerSpawn(playerid)
{
new query[300];
mysql_format(g_iHandle, query, sizeof(query), "SELECT * FROM `playercars` WHERE carOwner = %d LIMIT 3", PlayerData[playerid][pID]);
mysql_tquery(g_iHandle, query,"PlayerCar_Load", "i", playerid);
return 1;
}
forward PlayerCar_Load(playerid);
public PlayerCar_Load(playerid)
{
static
rows,
fields,
str[128];
cache_get_data(rows, fields, g_iHandle);
for (new i = 0; i < rows; i ++) if (i < MAX_DYNAMIC_CARS)
{
CarData[i][carExists] = true;
CarData[i][carID] = cache_get_field_int(i, "carID");
CarData[i][carModel] = cache_get_field_int(i, "carModel");
CarData[i][carOwner] = cache_get_field_int(i, "carOwner");
CarData[i][carPos][0] = cache_get_field_float(i, "carPosX");
CarData[i][carPos][1] = cache_get_field_float(i, "carPosY");
CarData[i][carPos][2] = cache_get_field_float(i, "carPosZ");
CarData[i][carPos][3] = cache_get_field_float(i, "carPosR");
CarData[i][carColor1] = cache_get_field_int(i, "carColor1");
CarData[i][carColor2] = cache_get_field_int(i, "carColor2");
cache_get_field_content(i, "carPlate", CarData[i][carPlate], g_iHandle, 12);
CarData[i][carLocked] = cache_get_field_int(i, "carLocked");
CarData[i][carParked] = cache_get_field_int(i, "carParked");
CarData[i][carWorld] = cache_get_field_int(i, "carWorld");
CarData[i][carImpounded] = cache_get_field_int(i, "carImpounded");
CarData[i][carImpoundPrice] = cache_get_field_int(i, "carImpoundPrice");
for (new j = 0; j < 14; j ++)
{
if (j < 5)
{
format(str, sizeof(str), "carWeapon%d", j + 1);
CarData[i][carWeapons][j] = cache_get_field_int(i, str);
format(str, sizeof(str), "carAmmo%d", j + 1);
CarData[i][carAmmo][j] = cache_get_field_int(i, str);
}
format(str, sizeof(str), "carMod%d", j + 1);
CarData[i][carMods][j] = cache_get_field_int(i, str);
}
Car_Spawn(i);
}
for (new i = 0; i < MAX_DYNAMIC_CARS; i ++) if (CarData[i][carExists]) {
format(str, sizeof(str), "SELECT * FROM `carstorage` WHERE `ID` = '%d'", CarData[i][carID]);
mysql_function_query(g_iHandle, str, true, "OnLoadCarStorage", "d", i);
}
return 1;
}
PHP Code:
public OnPlayerDisconnect(playerid, reason)
{
PlayerCar_Unload(playerid);
return 1;
}
stock PlayerCar_Unload(playerid)
{
for(new id; id < MAX_DYNAMIC_CARS; id++)
{
if (IsVehicleSpawned(id))
{
if (PlayerData[playerid][pID] == CarData[id][carOwner])
{
PlayerCar_Save(id);
DestroyVehicle(id);
CarData[id][carExists] = false;
}
}
}
return 1;
}
Faction Vehicles
Faction vehicles load when the server starts, and remain there permanently. They are created and loaded like so --
PHP Code:
CMD:createfcar(playerid, params[])
{
static
model[32],
color1,
color2,
factionid;
if (PlayerData[playerid][pAdmin] < 4)
return SendErrorMessage(playerid, "You don't have permission to use this command.");
if (sscanf(params, "s[32]I(-1)I(-1)I(0)", model, color1, color2, factionid))
return SendSyntaxMessage(playerid, "/createfcar [modelid/name] [color1] [color2] [faction ID]");
if ((model[0] = GetVehicleModelByName(model)) == 0)
return SendErrorMessage(playerid, "Invalid model ID.");
static
Float:x,
Float:y,
Float:z,
Float:angle,
id = -1;
GetPlayerPos(playerid, x, y, z);
GetPlayerFacingAngle(playerid, angle);
id = FactionCar_Create(model[0], x, y, z + 1, angle, color1, color2, factionid, GetPlayerVirtualWorld(playerid));
if (id == -1)
return SendErrorMessage(playerid, "The server has reached the limit for dynamic vehicles.");
return 1;
}
FactionCar_Create(modelid, Float:x, Float:y, Float:z, Float:angle, color1, color2, faction, world)
{
for (new i = 0; i != MAX_DYNAMIC_CARS; i ++)
{
if (!CarData[i][carExists])
{
if (color1 == -1)
color1 = random(127);
if (color2 == -1)
color2 = random(127);
CarData[i][carExists] = true;
CarData[i][carModel] = modelid;
CarData[i][carPos][0] = x;
CarData[i][carPos][1] = y;
CarData[i][carPos][2] = z;
CarData[i][carPos][3] = angle;
CarData[i][carColor1] = color1;
CarData[i][carColor2] = color2;
new str[8], query[400];
format(str, sizeof(str), "%s%s%d%d%s%s%s", LetterList[random(sizeof(LetterList))], LetterList[random(sizeof(LetterList))], random(9), random(9), LetterList[random(sizeof(LetterList))], LetterList[random(sizeof(LetterList))], LetterList[random(sizeof(LetterList))]);
SetVehicleNumberPlate(i, str);
format(CarData[i][carPlate], 11, "%s", str);
CarData[i][carWorld] = world;
CarData[i][carFaction] = faction;
CarData[i][carRank] = 1;
CarData[i][carVehicle] = CreateVehicle(modelid, x, y, z, angle, color1, color2, -1);
if (CarData[i][carVehicle] != INVALID_VEHICLE_ID) {
ResetVehicle(CarData[i][carVehicle]);
}
mysql_format(g_iHandle, query, sizeof(query), "INSERT INTO `factioncars` (carModel, carPosX, carPosY, carPosZ, carPosR, carColor1, carColor2, carPlate, carFaction, carWorld, carRank) VALUES(%d, %f, %f, %f, %f, %d, %d, '%s', %d, %d, %d)",
CarData[i][carModel],
CarData[i][carPos][0],
CarData[i][carPos][1],
CarData[i][carPos][2],
CarData[i][carPos][3],
CarData[i][carColor1],
CarData[i][carColor2],
CarData[i][carPlate],
CarData[i][carFaction],
CarData[i][carWorld],
CarData[i][carRank]
);
mysql_tquery(g_iHandle, query, "OnFactionCarCreated", "i", i);
return 1;
}
}
return -1;
}
forward OnFactionCarCreated(carid);
public OnFactionCarCreated(carid)
{
if (carid == -1 || !CarData[carid][carExists])
return 0;
CarData[carid][carID] = mysql_insert_id();
FactionCar_Save(carid);
return 1;
}
FactionCar_Save(carid)
{
static
query[900];
if (CarData[carid][carVehicle] != INVALID_VEHICLE_ID)
{
for (new i = 0; i < 14; i ++) {
CarData[carid][carMods][i] = GetVehicleComponentInSlot(CarData[carid][carVehicle], i);
}
}
format(query, sizeof(query), "UPDATE `factioncars` SET `carModel` = '%d', `carPosX` = '%.4f', `carPosY` = '%.4f', `carPosZ` = '%.4f', `carPosR` = '%.4f', `carColor1` = '%d', `carColor2` = '%d', `carPlate` = '%s', `carFaction` = '%d', `carWorld` = '%d', `carRank` ='%d' WHERE `carID` = '%d'",
CarData[carid][carModel],
CarData[carid][carPos][0],
CarData[carid][carPos][1],
CarData[carid][carPos][2],
CarData[carid][carPos][3],
CarData[carid][carColor1],
CarData[carid][carColor2],
CarData[carid][carPlate],
CarData[carid][carFaction],
CarData[carid][carWorld],
CarData[carid][carRank],
CarData[carid][carID]
);
return mysql_function_query(g_iHandle, query, false, "", "");
}
forward FactionCar_Load();
public FactionCar_Load()
{
static
rows,
fields;
cache_get_data(rows, fields, g_iHandle);
for (new i = 0; i < rows; i ++) if (i < MAX_DYNAMIC_CARS)
{
CarData[i][carExists] = true;
CarData[i][carID] = cache_get_field_int(i, "carID");
CarData[i][carModel] = cache_get_field_int(i, "carModel");
CarData[i][carPos][0] = cache_get_field_float(i, "carPosX");
CarData[i][carPos][1] = cache_get_field_float(i, "carPosY");
CarData[i][carPos][2] = cache_get_field_float(i, "carPosZ");
CarData[i][carPos][3] = cache_get_field_float(i, "carPosR");
CarData[i][carColor1] = cache_get_field_int(i, "carColor1");
CarData[i][carColor2] = cache_get_field_int(i, "carColor2");
cache_get_field_content(i, "carPlate", CarData[i][carPlate], g_iHandle, 12);
CarData[i][carParked] = cache_get_field_int(i, "carFaction");
CarData[i][carWorld] = cache_get_field_int(i, "carWorld");
CarData[i][carImpounded] = cache_get_field_int(i, "carRank");
if(CarData[i][carModel] > 399 && CarData[i][carModel] < 612)
{
new FCar = CreateVehicle(CarData[i][carModel], CarData[i][carPos][0], CarData[i][carPos][1], CarData[i][carPos][2], CarData[i][carPos][3], CarData[i][carColor1], CarData[i][carColor2], -1);
SetVehicleNumberPlate(FCar, CarData[i][carPlate]);
SetVehicleToRespawn(FCar);
CarData[FCar][carID] = CarData[i][carID];
CarData[FCar][carModel] = CarData[i][carModel];
CarData[FCar][carPos][0] = CarData[i][carPos][0];
CarData[FCar][carPos][1] = CarData[i][carPos][1];
CarData[FCar][carPos][2] = CarData[i][carPos][2];
CarData[FCar][carPos][3] = CarData[i][carPos][3];
CarData[FCar][carColor1] = CarData[i][carColor1];
CarData[FCar][carColor2] = CarData[i][carColor2];
CarData[FCar][carFaction] = CarData[i][carFaction];
CarData[FCar][carWorld] = CarData[i][carWorld];
CarData[FCar][carRank] = CarData[i][carRank];
}
else printf("[MYSQL] ERROR LOADING FACTION VEHICLE SQLID: %d",CarData[i][carID]);
}
return 1;
}
Now, BOTH of these work in isolation.
If I create a player car for myself it creates and saves, and then when I logout it disappears, and re-appears on logging back in.
If I create faction cars, they save and load successfully, and re-appear on server restart.
HOWEVER, if I create a faction car AND a player car and then logout, it all goes tits up. It's so random, sometimes both cars will disappear, sometimes the player car will disappear, sometimes the faction car will. Then, when I relog, they will both appear. Sometimes the car will duplicate itself (but not save to the database). If there are two players in-game both with player cars, if ONE of us logs out, BOTH cars will disappear and the random screw ups will start again, with the cars disappearing and respawning at random when someone re-connects or leaves.
I have no idea wtf is causing this, I've tried to fix it and I just can't. Player cars and faction cars save to separate tables in the database. Should I use two separate enums? Are the SQL IDs conflicting? I'm so confused.