Only one out of two outcomes would occur
#1

So, I have a command which I can teleport to dealerships by entering their ID.
So the teleporting part works, meaning if you enter a correct ID it'll actually teleport you to the dealership that the ID you've entered is equal to.
But the problem is that when I enter an invalid ID it'd still teleport me-.. But the thing is it'd teleport me to coordinates 0, 0, 0, so bassicly I have attempted to return something else once an invalid ID is entered unfortunatly I couldn't achieve it myself after me trying different methods for quite a while.

This is the first method I've tried and since none worked afterwards I decided to stick to it and just write it here.
Here's the source code:

pawn Код:
YCMD:gotodealership(playerid, params[], help) {

    if(!IsPlayerAdmin(playerid)) return 0;
    else {
        new id;
        if(sscanf(params, "d", id)) return SendClientMessage(playerid, -1, "[ ! ] SYNTAX: /GotoDealerShip [DS-ID]");
        else {
            for(new i = 0 ; i < cache_get_row_count(dbHandle) ; i++) {
                if(id != DS[i][DsID]) {
                    SendClientMessage(playerid, 0xFF0000FF, "[ ! ] Invalid DEALERSHIP ID.");
                }
                else continue;
            }
            SetPlayerPos(playerid, DS[id][DsLocX], DS[id][DsLocY], DS[id][DsLocZ]);
            SendClientMessage(playerid, 0xFF0000FF, "[ ! ] Successfully teleported to a valid DEALERSHIP.");
        }
    }
    return 1;
}
Reply
#2

Add a variable to the dealership enum to show whether it's taken or not. I'm assuming this is because the default X Y Z of a dealership is 0 0 0.
Reply
#3

Quote:
Originally Posted by Divergent
Посмотреть сообщение
Add a variable to the dealership enum to show whether it's taken or not. I'm assuming this is because the default X Y Z of a dealership is 0 0 0.
What?

I didn't quite understand you there? 'Add a variable to the dealership enum'? This is a script where I can create dealerships dynamically in-game, therefore it'd be obvious that some command of teleporting to each one would be useful.

And no, the default X Y Z of the dealership isn't set to 0 0 0 because as I've already explained it above and in my original post, it is created dynamically and I can teleport to bassicly all of them /BUT/ if I enter an invalid ID I'll get teleported to 0 0 0 because that ID doesn't have any teleportation coordinates,
I hope you understood me now?

Thanks for attempting to assist anyways
Reply
#4

Quote:
Originally Posted by Ox1gEN
Посмотреть сообщение
What?

I didn't quite understand you there? 'Add a variable to the dealership enum'? This is a script where I can create dealerships dynamically in-game, therefore it'd be obvious that some command of teleporting to each one would be useful.

And no, the default X Y Z of the dealership isn't set to 0 0 0 because as I've already explained it above and in my original post, it is created dynamically and I can teleport to bassicly all of them /BUT/ if I enter an invalid ID I'll get teleported to 0 0 0 because that ID doesn't have any teleportation coordinates,
I hope you understood me now?

Thanks for attempting to assist anyways
Yeah sorry about that, I misunderstood you a bit but part of my answer is still relevant (I think).

Add a "Created" variable to the enumerator (or however you're organizing the data for the dealerships) so that only dealerships which have been created (valid IDs) are able to be teleported to. So for example in the TP command you would add

Код:
if(DealershipInfo[id][Created] == true)
This would only allow the dealerships that you have created to be teleported to.
Reply
#5

The code is all fine except for the part in red, oh, and you don't need a second level if-else statement!
Код:
YCMD:gotodealership(playerid, params[], help)
{
	if (!IsPlayerAdmin(playerid)) return 0;

	new id;
	if (sscanf(params, "d", id)) return SendClientMessage(playerid, -1, "[ ! ] SYNTAX: /GotoDealerShip [DS-ID]");

	for (new i = 0 ; i < cache_get_row_count(dbHandle) ; i++)
	{
		if (id != DS[i][DsID]) 
		{
			SendClientMessage(playerid, 0xFF0000FF, "[ ! ] Invalid DEALERSHIP ID.");
		}
		else continue;
	}

	SetPlayerPos(playerid, DS[id][DsLocX], DS[id][DsLocY], DS[id][DsLocZ]);
	SendClientMessage(playerid, 0xFF0000FF, "[ ! ] Successfully teleported to a valid DEALERSHIP.");
	return 1;
}
What exactly are you trying to achieve with that loop? When and where is the query (assuming it's a MySQL query) formed and result fetched??
That part of code makes absolutely zero sense. You're checking if the number you entered (the "id" variable) doesn't equal one of those (I assume, again) dealership IDs in "DS" enum, how is it then supposed to be invalid?

Just do it like: You enter an ID, you loop through the "DS" enum and check if it's found. If it's not then it's invalid.
Reply
#6

Quote:
Originally Posted by Divergent
Посмотреть сообщение
Yeah sorry about that, I misunderstood you a bit but part of my answer is still relevant (I think).

Add a "Created" variable to the enumerator (or however you're organizing the data for the dealerships) so that only dealerships which have been created (valid IDs) are able to be teleported to. So for example in the TP command you would add

Код:
if(DealershipInfo[id][Created] == true)
This would only allow the dealerships that you have created to be teleported to.
Oh, I understand thanks, but that is not quite what I was trying to do.
I was just checking if the ID is valid or not, not created or not created.
Thanks anyways






Quote:
Originally Posted by Virtual1ty
Посмотреть сообщение
The code is all fine except for the part in red, oh, and you don't need a second level if-else statement!
Код:
YCMD:gotodealership(playerid, params[], help)
{
	if (!IsPlayerAdmin(playerid)) return 0;

	new id;
	if (sscanf(params, "d", id)) return SendClientMessage(playerid, -1, "[ ! ] SYNTAX: /GotoDealerShip [DS-ID]");

	for (new i = 0 ; i < cache_get_row_count(dbHandle) ; i++)
	{
		if (id != DS[i][DsID]) 
		{
			SendClientMessage(playerid, 0xFF0000FF, "[ ! ] Invalid DEALERSHIP ID.");
		}
		else continue;
	}

	SetPlayerPos(playerid, DS[id][DsLocX], DS[id][DsLocY], DS[id][DsLocZ]);
	SendClientMessage(playerid, 0xFF0000FF, "[ ! ] Successfully teleported to a valid DEALERSHIP.");
	return 1;
}
What exactly are you trying to achieve with that loop? When and where is the query (assuming it's a MySQL query) formed and result fetched??
That part of code makes absolutely zero sense. You're checking if the number you entered (the "id" variable) doesn't equal one of those (I assume, again) dealership IDs in "DS" enum, how is it then supposed to be invalid?

Just do it like: You enter an ID, you loop through the "DS" enum and check if it's found. If it's not then it's invalid.
This was what I was looking for I believe, so I forgot to make a mysql query.
Thanks for notifying me about that.
If it works I'll reply.

Reputation++ for both.
Reply
#7

You should load all of your dealership values OnGameModeinit then you don't need to run a query every time you want to teleport to a dealership. Thanks for the rep as well.
Reply
#8

Quote:
Originally Posted by Divergent
Посмотреть сообщение
You should load all of your dealership values OnGameModeinit then you don't need to run a query every time you want to teleport to a dealership. Thanks for the rep as well.
I already have that, and everything is set to variables already.
I only have a problem with this specifiec code, everything else works great, loading and saving.

Here's what you mean if you'd like to look at it:


pawn Код:
public OnFilterScriptInit()
{
    mysql_log(LOG_ALL);
    print("\n--------------------------------------");
    print(" ************************************");
    print("--------------------------------------\n");
    dbconnect(SQL_DB);
    return 1;
}

forward dbconnect(db);
public dbconnect(db) {

    if(db == SQL_DB) {
       
        dbHandle = mysql_connect(MySQL_HOST, MySQL_USER, MySQL_DATABASE, MySQL_PASSWORD);
        if(mysql_errno() != 0) {
            print("Failed connection to database -- Shutting down.");
            SendRconCommand("exit");
        }
        else
        {
            print("Successful connection to database -- Continue ~~~");
        }
        LoadDSquery();
    }
}


stock LoadDSquery() {
    mysql_tquery(dbHandle, "SELECT * FROM `dealerships`", "loadDEALERSHIPS");
    return 1;
}

forward loadDEALERSHIPS();
public loadDEALERSHIPS() {

    for(new i = 0 ; i < cache_num_rows(dbHandle) ; i++) {

        DS[i][DsID] = cache_get_field_content_int(i, "DsID", dbHandle);
        DS[i][DsLocX] = cache_get_field_content_float(i, "DsLocX", dbHandle);
        DS[i][DsLocY] = cache_get_field_content_float(i, "DsLocY", dbHandle);
        DS[i][DsLocZ] = cache_get_field_content_float(i, "DsLocZ", dbHandle);
        DS[i][DsIcon] = cache_get_field_content_int(i, "DsIcon", dbHandle);
        DS[i][DsSpawned] = cache_get_field_content_int(i, "DsSpawned", dbHandle);


        DsPickups = CreatePickup(1239, 23, DS[i][DsLocX], DS[i][DsLocY], DS[i][DsLocZ], -1);


        DS[i][DsSpawned] = 1;
    }
    printf("[ ! ] Loaded %d DEALERSHIPS", cache_num_rows(dbHandle));
    return 1;
}
Reply
#9

One thing that comes into mind as well when looking at your enum structure.

For the ID of the dealership, you can simply use the index of the array for that.
So the index is actually the dealership ID.

So you could load your data the same way as you do now, but use the ID field from your database as the index of your array to store all the data.
Then you're also sure you won't get duplicate ID's in your database, because arrays don't have duplicate ID's (or indices).

When creating a new dealership in-game, you could simply loop through your array and check for each index if the DsSpawned (or DsIcon) variables hold 0.
Then you know that ID isn't taken and you can use it to store your new dealership.

Also, when you create the new dealership and want to save the data, you can use that empty index of your array, where you stored the new data, as the ID of your new dealership.

I'm also in the process of creating everything in-game and I'm doing the same thing.
Some sample code, taken directly from my gamemode PPC Trucking V2:
pawn Код:
// OnFilterScriptInit:

    // Send a query to load all gas-stations from MySQL
    format(Query, sizeof(Query), "SELECT * FROM %s", table_gasstations);
    result = mysql_query(SQL_db, Query, true);
    // Print some debug info to the server console
    printf("*** Loading gas-stations from MySQL using \"%s\"", Query);
    GasStationsLoad();
    cache_delete(result, SQL_db);


// This function is called to load the gas-stations
GasStationsLoad()
{
    // Setup local variables
    new Rows, GasID, Name[50], Float:x, Float:y, Float:z, CountSuccess, CountFailed;

    // Get the amount of rows (gas-stations)
    Rows = cache_get_row_count(SQL_db);

    // If there are any rows (gas-stations) loaded, load data and create them
    if (Rows >= 1)
    {
        // Loop through all rows
        for (new Row; Row < Rows; Row++)
        {
            // Load the data
            GasID = cache_get_field_content_int(Row, "ID", SQL_db);
            cache_get_field_content(Row, "Name", Name, SQL_db, sizeof(Name));
            x = cache_get_field_content_float(Row, "X", SQL_db);
            y = cache_get_field_content_float(Row, "Y", SQL_db);
            z = cache_get_field_content_float(Row, "Z", SQL_db);

            // Check if the GasID is invalid (out of range)
            if ((GasID < 0) || (GasID >= MAX_GASSTATIONS))
            {
                // Count the amount of failed gas-stations (invalid GasID's)
                CountFailed++;
                printf("*** ERROR: Invalid GasID found in table %s: %i", table_gasstations, GasID);
                // Continue with the next gas-station from the MySQL query
                continue;
            }

            // Create the gas-station at the given GasID (there should be no duplicate gas-stations with the same ID as the table-structure doesn't allow it, ID = primary key)
            SetupGasStation(x, y, z, Name, GasID);
            // Count the succesfully created gas-stations
            CountSuccess++;
        }
    }

    // Print the amount of gas-stations loaded for debugging
    printf("*** Gas-stations loaded: %i (successful: %i, failed: %i)", Rows, CountSuccess, CountFailed);

    return 1;
}

// This function creates a gas-station (store data and create pickup/map-icon)
SetupGasStation(Float:x, Float:y, Float:z, Name[], ID = -1)
{
    // Setup local variables
    new GasID, bool:SlotFound = false;

    // Check if an ID has been given
    if (ID == -1)
    {
        // No ID has been given, search for a free slot to create a new gas-station
        // Loop through all gas-station slots
        for (GasID = 0; GasID < MAX_GASSTATIONS; GasID++)
        {
            // If an empty slot is found (no valid pickup)
            if (!IsValidDynamicPickup(AGasStations[GasID][PickupID]))
            {
                // An empty slot has been found
                SlotFound = true;
                // Exit the loop
                break;
            }
        }
    }
    else // An ID has been specified
    {
        // Check if this slot is available
        if (!IsValidDynamicPickup(AGasStations[ID][PickupID]))
        {
            // An empty slot has been found
            SlotFound = true;
            // Store the given ID as GasID
            GasID = ID;
        }
    }

    // Check if an empty slot was found
    if (SlotFound == true)
    {
        // Store the pickup-id in this empty slot
        AGasStations[GasID][PickupID] = CreateDynamicPickup(1244, 1, x, y, z, 0); // Type 1, cannot be pickup up, exists all the time
        AGasStations[GasID][GasX] = x;
        AGasStations[GasID][GasY] = y;
        AGasStations[GasID][GasZ] = z;
        format(AGasStations[GasID][GasName], 50, Name);
        // Add a 3DText message above the pickup icon
        AGasStations[GasID][PickupText] = CreateDynamic3DTextLabel("Press and hold Y-key\nto refuel your vehicle", 0x008080FF, x, y, z + 0.8, 30.0);
        // Add an icon to the map for this gas-station
        AGasStations[GasID][PickupIcon] = CreateDynamicMapIcon(x, y, z, 56, 0, 0, 0, -1, 300.0);

        return GasID;
    }

    // If no gas-station could be added (no free slots), return -1 to indicate adding a gas-station has failed
    return -1;
}
You'll see that the ID from my database is used as the index of my array.

You'll also see the I'm using mysql_query to load my data, you don't need to do that.
I did it this way because I want to be sure my data is loaded before the server is running.
Otherwise, with ALOT of data, it might take a few seconds to load it all and players might be able to connect already when the script didn't finish loading all the data yet.
Using mysql_query, the script halts execution of OnFilterScriptInit until all data has been loaded.
After the data is loaded, the rest of the code is executed and the server is open to the public.


Another issue in your code:
You seem to have one global variable "DsPickups" to which you assign the handle (or ID) of the pickup.
But this will only point to the last pickup you created, since the variable can only hold one value.
You should consider putting that variable inside your enum as well.

Then it's easier to delete the pickup when you delete the dealership in-game.


PS: sorry for the long post.
Reply
#10

Quote:
Originally Posted by PowerPC603
Посмотреть сообщение
One thing that comes into mind as well when looking at your enum structure.

For the ID of the dealership, you can simply use the index of the array for that.
So the index is actually the dealership ID.

So you could load your data the same way as you do now, but use the ID field from your database as the index of your array to store all the data.
Then you're also sure you won't get duplicate ID's in your database, because arrays don't have duplicate ID's (or indices).

When creating a new dealership in-game, you could simply loop through your array and check for each index if the DsSpawned (or DsIcon) variables hold 0.
Then you know that ID isn't taken and you can use it to store your new dealership.

Also, when you create the new dealership and want to save the data, you can use that empty index of your array, where you stored the new data, as the ID of your new dealership.

I'm also in the process of creating everything in-game and I'm doing the same thing.
Some sample code, taken directly from my gamemode PPC Trucking V2:
pawn Код:
// OnFilterScriptInit:

    // Send a query to load all gas-stations from MySQL
    format(Query, sizeof(Query), "SELECT * FROM %s", table_gasstations);
    result = mysql_query(SQL_db, Query, true);
    // Print some debug info to the server console
    printf("*** Loading gas-stations from MySQL using \"%s\"", Query);
    GasStationsLoad();
    cache_delete(result, SQL_db);


// This function is called to load the gas-stations
GasStationsLoad()
{
    // Setup local variables
    new Rows, GasID, Name[50], Float:x, Float:y, Float:z, CountSuccess, CountFailed;

    // Get the amount of rows (gas-stations)
    Rows = cache_get_row_count(SQL_db);

    // If there are any rows (gas-stations) loaded, load data and create them
    if (Rows >= 1)
    {
        // Loop through all rows
        for (new Row; Row < Rows; Row++)
        {
            // Load the data
            GasID = cache_get_field_content_int(Row, "ID", SQL_db);
            cache_get_field_content(Row, "Name", Name, SQL_db, sizeof(Name));
            x = cache_get_field_content_float(Row, "X", SQL_db);
            y = cache_get_field_content_float(Row, "Y", SQL_db);
            z = cache_get_field_content_float(Row, "Z", SQL_db);

            // Check if the GasID is invalid (out of range)
            if ((GasID < 0) || (GasID >= MAX_GASSTATIONS))
            {
                // Count the amount of failed gas-stations (invalid GasID's)
                CountFailed++;
                printf("*** ERROR: Invalid GasID found in table %s: %i", table_gasstations, GasID);
                // Continue with the next gas-station from the MySQL query
                continue;
            }

            // Create the gas-station at the given GasID (there should be no duplicate gas-stations with the same ID as the table-structure doesn't allow it, ID = primary key)
            SetupGasStation(x, y, z, Name, GasID);
            // Count the succesfully created gas-stations
            CountSuccess++;
        }
    }

    // Print the amount of gas-stations loaded for debugging
    printf("*** Gas-stations loaded: %i (successful: %i, failed: %i)", Rows, CountSuccess, CountFailed);

    return 1;
}

// This function creates a gas-station (store data and create pickup/map-icon)
SetupGasStation(Float:x, Float:y, Float:z, Name[], ID = -1)
{
    // Setup local variables
    new GasID, bool:SlotFound = false;

    // Check if an ID has been given
    if (ID == -1)
    {
        // No ID has been given, search for a free slot to create a new gas-station
        // Loop through all gas-station slots
        for (GasID = 0; GasID < MAX_GASSTATIONS; GasID++)
        {
            // If an empty slot is found (no valid pickup)
            if (!IsValidDynamicPickup(AGasStations[GasID][PickupID]))
            {
                // An empty slot has been found
                SlotFound = true;
                // Exit the loop
                break;
            }
        }
    }
    else // An ID has been specified
    {
        // Check if this slot is available
        if (!IsValidDynamicPickup(AGasStations[ID][PickupID]))
        {
            // An empty slot has been found
            SlotFound = true;
            // Store the given ID as GasID
            GasID = ID;
        }
    }

    // Check if an empty slot was found
    if (SlotFound == true)
    {
        // Store the pickup-id in this empty slot
        AGasStations[GasID][PickupID] = CreateDynamicPickup(1244, 1, x, y, z, 0); // Type 1, cannot be pickup up, exists all the time
        AGasStations[GasID][GasX] = x;
        AGasStations[GasID][GasY] = y;
        AGasStations[GasID][GasZ] = z;
        format(AGasStations[GasID][GasName], 50, Name);
        // Add a 3DText message above the pickup icon
        AGasStations[GasID][PickupText] = CreateDynamic3DTextLabel("Press and hold Y-key\nto refuel your vehicle", 0x008080FF, x, y, z + 0.8, 30.0);
        // Add an icon to the map for this gas-station
        AGasStations[GasID][PickupIcon] = CreateDynamicMapIcon(x, y, z, 56, 0, 0, 0, -1, 300.0);

        return GasID;
    }

    // If no gas-station could be added (no free slots), return -1 to indicate adding a gas-station has failed
    return -1;
}
You'll see that the ID from my database is used as the index of my array.

You'll also see the I'm using mysql_query to load my data, you don't need to do that.
I did it this way because I want to be sure my data is loaded before the server is running.
Otherwise, with ALOT of data, it might take a few seconds to load it all and players might be able to connect already when the script didn't finish loading all the data yet.
Using mysql_query, the script halts execution of OnFilterScriptInit until all data has been loaded.
After the data is loaded, the rest of the code is executed and the server is open to the public.


Another issue in your code:
You seem to have one global variable "DsPickups" to which you assign the handle (or ID) of the pickup.
But this will only point to the last pickup you created, since the variable can only hold one value.
You should consider putting that variable inside your enum as well.

Then it's easier to delete the pickup when you delete the dealership in-game.


PS: sorry for the long post.
Thanks for that, I now understand the flaws in my code.

Edit: Oh and by the way, I have fixed my code, for this specifiec command, and also changed that DsPickups thing you've told me about.
Everything in this command works now, thanks for everyone
Reply


Forum Jump:


Users browsing this thread: 1 Guest(s)