[SOLVED \o/]sscanf and multiple optional parameters
#1

Hi, I'm trying to convert my whole gamemode (235 commands -_-) to sscanf and ZCMD .. it's going great, but I have come up against a problem.

The command below is to spawn a vehicle with optional colour params.. basically, if they don't enter a colour .. or two colours then the vehicle colour is set to a random colour. Could someone please explain to me how I would do this? I can't see any way to use !strlen and it doesn't even work with ZCMD anyways.

pawn Код:
CMD:v(playerid, params[])
{
    if(PlayerInfo[playerid][Level] >= 3 || IsPlayerAdmin(playerid))
    {
        new car, colour1, colour2, vehicle, Int, Float: Angle, Float: X,Float: Y,Float: Z, world;
        GetPlayerPos(playerid, X, Y, Z); Int = GetPlayerInterior(playerid); world = GetPlayerVirtualWorld(playerid); GetPlayerFacingAngle(playerid,Angle);
        if(sscanf(params, "dzz", car, colour1, colour2)) return SendClientMessage(playerid, Red,"USAGE: /v [model ID] [colour 1] [colour 2]");
        if(!strlen(colour1)) colour1st = random(126); else colour1st = strval(tmp2);
        if(!strlen(colour2)) colour2nd = random(126); else colour2nd = strval(tmp3);

        if(!strlen(params)) return SendClientMessage(playerid, Red,"USAGE: /v [model ID] [colour 1] [colour 2]");
        if(car < 400 || car > 611) return SendClientMessage(playerid, Red, "Invalid Vehicle Model");
      vehicle = CreateVehicle(car, X+3, Y, Z, Angle, colour1, colour2, -1);
      vName = GetVehicleName(vehicle);
      if(world > 0) return SetVehicleVirtualWorld(vehicle,world);
      LinkVehicleToInterior(vehicle,Int);
      format(string, sizeof(string), "%s successfully spawned. To destroy it, use /dv", vName);
      return SendClientMessage(playerid,White,string);
    } else return 0;
}
Any help appreciated, thanks.
Reply
#2

new car;
new colour1 = random(number here);
new colour2 = random(number here);

if(sscanf(params, "d", car)) return SendClientMessage(playerid, Red,"USAGE: /v [model ID] [colour 1] [colour 2]");
if(!sscanf(params, "ddd", car,colour1,colour2))
{
rest of code here


}
Reply
#3

Is there not any way to make the colour params optional with "z" but also check if they have entered an optional param... so like, if they don't enter a colour it will be a random one and if they do it will be that..? I'm new to sscanf so forgive my ignorance.
Reply
#4

Define "color" as a string, then it will be possible. and use strval
Reply
#5

Not being funny, but the whole point in using sscanf (for me) was to get rid of strval and strtok.. plus if the colours were defined as a string, would they not have to be entered as a string? It wouldn't process it if it was a numeric entry would it?
Reply
#6

Hi.
Reply
#7

pawn Код:
else colour1st = strval(colour1);
else colour2nd = strval(colour2);
I wonder why it didn't output a compiling error with tmp2,tmp3.
Reply
#8

Quote:
Originally Posted by //exora
pawn Код:
else colour1st = strval(colour1);
else colour2nd = strval(colour2);
I wonder why it didn't output a compiling error with tmp2,tmp3.
Meh, those are some bits of code that I was trying out .. I still can't understand how to do this with sscanf
Reply
#9

I can answer the random colour part, just use CreateVehicle(modelid, x, y, z, -1, -1, 60);

Then -1s mean random colour.

As for the optional parameters, I think if you do something like this:
pawn Код:
CMD:v(playerid, params[]
{
    new car, colour1, colour2;
    if(!sscanf(params, "ddd", car, colour1, colour2))
    {
         //code here
    }
    else if(!sscanf(params, "d", car))
    {
        //same code here with random colours
    }
    else return SendClientMessage(playerid, Red, "USAGE: /v [modelid] [colour1 optional] [colour2 optional]");
    return 1;
}
would work.
Reply
#10

strval() isn't necessarily slow, strtook is slow. There's no point in not using it at all, because there's definitely going to be instances where you need to use it.
Reply
#11

Here's a snippet I made some time ago for a script
pawn Код:
new
        car[20],
        col1 = -1,
        col2 = -1,
        spaces = 0;
    if (sscanf(params, "sz", car, msg4))
    {
        SendClientMessage(playerid, COLOR_SYSTEM, "*** USAGE: /gangcar [carname] [custom name] [color1] [color2]");
    SendClientMessage(playerid, COLOR_SYSTEM, "*** You need to be in a turf you own to use this command.");
    SendClientMessage(playerid, COLOR_SYSTEM, "*** Color1 and Color2 are optional.");
    return 1;
    }
  new lenght, idx;
    for(lenght = strlen(msg4), idx = 0; idx < lenght; idx++) //checks for spaces (name_SPACE_color1_SPACE_color2)
    {
      if(msg4[idx] == ' ')
      {
        spaces++;
      }
    }

    if(spaces > 2) //more then just 3 words, cancel the process
    {
        SendClientMessage(playerid, COLOR_SYSTEM, "*** USAGE: /gangcar [carname] [custom name] [color1] [color2]");
        SendClientMessage(playerid, COLOR_SYSTEM, "*** You need to be in a turf you own to use this command.");
        SendClientMessage(playerid, COLOR_SYSTEM, "*** Color1 and Color2 are optional.");
        return 1;
    }
    else if(spaces == 0) //just the car name, store in the global variable
    {
      format(CarName[ turf ], MAX_PLAYER_NAME, "%s", msg4);
    }
    else if (spaces == 1) //one parameter to much, the last one will be ignored
    {
        if (sscanf(msg4, "sz", CarName[ turf ], msg1))
        {
            SendClientMessage(playerid, COLOR_SYSTEM, "*** USAGE: /gangcar [carname] [custom name] [color1] [color2]");
            SendClientMessage(playerid, COLOR_SYSTEM, "*** You need to be in a turf you own to use this command.");
            SendClientMessage(playerid, COLOR_SYSTEM, "*** Color1 and Color2 are optional.");
            return 1;
        }
    }
    else if (spaces == 2)//car name, col1, col2 = perfect
    {
        if (sscanf(msg4, "sdd", CarName[ turf ], col1, col2))
        {
            SendClientMessage(playerid, COLOR_SYSTEM, "*** USAGE: /gangcar [carname] [custom name] [color1] [color2]");
            SendClientMessage(playerid, COLOR_SYSTEM, "*** You need to be in a turf you own to use this command.");
            SendClientMessage(playerid, COLOR_SYSTEM, "*** Color1 and Color2 are optional.");
            return 1;
        }
    }
It can be vastly improved, but you'll get the idea. Or you could try
pawn Код:
new id, col1, col2, string[128];
sscanf(cmdtext, "dz", id, string);

if(sscanf(string, "dd", col1, col2))
{
    //use random colors
}
Reply
#12

Thanks for the help, dudes. Those last few posts explained it better.
Reply
#13

Ok, cannot believe I'm still stuck on this crap. Basically, I've written the command .. but now I have no idea how to let the user enter either a partial or full name of the car (Infernus, Inf, etc.) or the model ID, I mean, it was EASY with strtok, but now I'm stuck ..

pawn Код:
CMD:v(playerid, params[])
{
    if(PlayerInfo[playerid][Level] >= 3 || IsPlayerAdmin(playerid))
    {
        new car, vIsName, colour1, colour2, vehicle, Int, Float: Angle, Float: X,Float: Y,Float: Z, world;
        if(sscanf(params, "ddd", car, colour1, colour2)) return SendClientMessage(playerid, Red, "USAGE: /v [ModelID/Name] [Colour 1] [Colour 2] (Colours optional)");
        {
            GetPlayerPos(playerid, X, Y, Z); Int = GetPlayerInterior(playerid); world = GetPlayerVirtualWorld(playerid); GetPlayerFacingAngle(playerid,Angle);
            if(car < 400 || car > 611) return SendClientMessage(playerid, Red, "Invalid Vehicle Model");
      if(!IsNumeric(car)) vIsName = GetVehicleModelIDFromName(car); else vIsName = strval(car); // This bit I'm stuck at :|
            vehicle = CreateVehicle(vIsName, X+3, Y, Z, Angle, colour1, colour2, -1);
        vName = GetVehicleName(vehicle);
        if(world > 0) return SetVehicleVirtualWorld(vehicle,world);
        LinkVehicleToInterior(vehicle,Int);
        DynamicV[vehicle] = 1;
        format(string, sizeof(string), "%s successfully spawned. To destroy it, use /dc", vName);
        return SendClientMessage(playerid,White,string);
        }
        else if(sscanf(params, "d", car))
        {
      GetPlayerPos(playerid, X, Y, Z); Int = GetPlayerInterior(playerid); world = GetPlayerVirtualWorld(playerid); GetPlayerFacingAngle(playerid,Angle);
            if(car < 400 || car > 611) return SendClientMessage(playerid, Red, "Invalid Vehicle Model");
      if(!IsNumeric(car)) vIsName = GetVehicleModelIDFromName(car); else vIsName = strval(car);
            vehicle = CreateVehicle(vIsName, X+3, Y, Z, Angle, -1, -1, -1);
        vName = GetVehicleName(vehicle);
        if(world > 0) return SetVehicleVirtualWorld(vehicle,world);
        LinkVehicleToInterior(vehicle,Int);
        DynamicV[vehicle] = 1;
        format(string, sizeof(string), "%s successfully spawned. To destroy it, use /dc", vName);
        return SendClientMessage(playerid,White,string);
        }
    } else return 0;
    return 1;
}
Any help is appreciated, as usual.
Reply
#14

pawn Код:
CMD:v(playerid, params[])
{
    if(PlayerInfo[playerid][Level] >= 3 || IsPlayerAdmin(playerid))
    {
        new car[ 64 ], vIsName, colour1, colour2, vehicle, Int, Float: Angle, Float: X,Float: Y,Float: Z, world;
        if(sscanf(params, "sdd", car, colour1, colour2)) return SendClientMessage(playerid, Red, "USAGE: /v [ModelID/Name] [Colour 1] [Colour 2] (Colours optional)");
        {
            GetPlayerPos(playerid, X, Y, Z); Int = GetPlayerInterior(playerid); world = GetPlayerVirtualWorld(playerid); GetPlayerFacingAngle(playerid,Angle);
            if(!IsNumeric(car)) vIsName = GetVehicleModelIDFromName(car); else vIsName = strval(car); // This bit I'm stuck at :|
            if(car < 400 || car > 611) return SendClientMessage(playerid, Red, "Invalid Vehicle Model");
            vehicle = CreateVehicle(vIsName, X+3, Y, Z, Angle, colour1, colour2, -1);
            if(world > 0) return SetVehicleVirtualWorld(vehicle,world);
            LinkVehicleToInterior(vehicle,Int);
            DynamicV[vehicle] = 1;
            format(string, sizeof(string), "%s successfully spawned. To destroy it, use /dc", GetVehicleName(vehicle));
            return SendClientMessage(playerid,White,string);
        }
        else if(sscanf(params, "s", car))
        {
            GetPlayerPos(playerid, X, Y, Z); Int = GetPlayerInterior(playerid); world = GetPlayerVirtualWorld(playerid); GetPlayerFacingAngle(playerid,Angle);
            if(!IsNumeric(car)) vIsName = GetVehicleModelIDFromName(car); else vIsName = strval(car);
            if(car < 400 || car > 611) return SendClientMessage(playerid, Red, "Invalid Vehicle Model");
            vehicle = CreateVehicle(vIsName, X+3, Y, Z, Angle, -1, -1, -1);
            if(world > 0) return SetVehicleVirtualWorld(vehicle,world);
            LinkVehicleToInterior(vehicle,Int);
            DynamicV[vehicle] = 1;
            format(string, sizeof(string), "%s successfully spawned. To destroy it, use /dc", GetVehicleName(vehicle));
            return SendClientMessage(playerid,White,string);
        }
    } else return 0;
    return 1;
}
Reply
#15

Here are the compile errors for your edit .. the one's I've commented out are the one's that have nothing to do with it or I know what the problem is.


pawn Код:
(4147) : error 033: array must be indexed (variable "car")
//(4152) : error 017: undefined symbol "GetVehicleName"
(4155) : warning 225: unreachable code
(4155) : error 029: invalid expression, assumed zero
(4155) : warning 215: expression has no effect
(4155) : error 001: expected token: ";", but found "if"
(4159) : error 033: array must be indexed (variable "car")
//(4164) : error 017: undefined symbol "GetVehicleName"
Here is the code again:

pawn Код:
CMD:v(playerid, params[])
{
    if(PlayerInfo[playerid][Level] >= 3 || IsPlayerAdmin(playerid))
    {
        new car[ 64 ], string[128], vIsName, colour1, colour2, vehicle, Int, Float: Angle, Float: X,Float: Y,Float: Z, world;
        if(sscanf(params, "sdd", car, colour1, colour2)) return SendClientMessage(playerid, Red, "USAGE: /v [ModelID/Name] [Colour 1] [Colour 2] (Colours optional)");
        {
            GetPlayerPos(playerid, X, Y, Z); Int = GetPlayerInterior(playerid); world = GetPlayerVirtualWorld(playerid); GetPlayerFacingAngle(playerid,Angle);
            if(!IsNumeric(car)) vIsName = GetVehicleModelIDFromName(car); else vIsName = strval(car); // This bit I'm stuck at :|
            if(car < 400 || car > 611) return SendClientMessage(playerid, Red, "Invalid Vehicle Model");
            vehicle = CreateVehicle(vIsName, X+3, Y, Z, Angle, colour1, colour2, -1);
            if(world > 0) return SetVehicleVirtualWorld(vehicle,world);
            LinkVehicleToInterior(vehicle,Int);
        DynamicV[vehicle] = 1;
        format(string, sizeof(string), "%s successfully spawned. To destroy it, use /dc", GetVehicleName(vehicle));
        return SendClientMessage(playerid,White,string);
        }
        else if(sscanf(params, "s", car)) // Line 4155 here
        {
      GetPlayerPos(playerid, X, Y, Z); Int = GetPlayerInterior(playerid); world = GetPlayerVirtualWorld(playerid); GetPlayerFacingAngle(playerid,Angle);
      if(!IsNumeric(car)) vIsName = GetVehicleModelIDFromName(car); else vIsName = strval(car);
      if(car < 400 || car > 611) return SendClientMessage(playerid, Red, "Invalid Vehicle Model");
            vehicle = CreateVehicle(vIsName, X+3, Y, Z, Angle, -1, -1, -1);
        if(world > 0) return SetVehicleVirtualWorld(vehicle,world);
        LinkVehicleToInterior(vehicle,Int);
        DynamicV[vehicle] = 1;
        format(string, sizeof(string), "%s successfully spawned. To destroy it, use /dc", GetVehicleName(vehicle));
        return SendClientMessage(playerid,White,string);
        }
    } else return 0;
    return 1;
}
Reply
#16

Do you use the old sscanf or sscanf 2.0 (plugin) ?
Reply
#17

The old one, I thought I'd start off with the original one, thought it might be easier to learn/implement?
Reply
#18

I believe sscanf returns 0 if it's conditions are met or something. At line 4155, it should be:
pawn Код:
if(sscanf(params, "s", car)) return SendClientMessage(/*error message*/
else
{
  //code...
}
Reply
#19

All I really need is a way to check if they entered a colour param and then I wouldn't need to rewrite a perfectly fine command, I thought ssacanf is meant to makes things easier lol. If only there was some way to check like using if(!strlen(params) does with strtok .. but if I use !strlen it doesn't work at all .. don't know whether that's ZCMD's fault or sscanf
Reply
#20

So... you want to check if a string is empty? Use isnull. I'm sure sscanf must have inbuilt isnull checking.

Edit: check at this, might help you:
pawn Код:
CMD:car(playerid,params[]) {
    if(AccountInfo[playerid][aAdminLevel] >= 1) {
      new tmp[128], tmp2[128], tmp3[128], Index; tmp = strtok(params,Index), tmp2 = strtok(params,Index); tmp3 = strtok(params,Index);
      if(isnull(tmp)) return SendClientMessage(playerid, red, "USAGE: /car [Modelid/Name] [colour1] [colour2]");
        new car, colour1, colour2, sendername[MAX_PLAYER_NAME];
        if(!IsNumeric(tmp)) car = GetVehicleModelIDFromName(tmp); else car = strval(tmp);
        if(car < 400 || car > 611) return SendClientMessage(playerid, red, "ERROR: Invalid Vehicle Model");
        if(isnull(tmp2)) colour1 = random(126); else colour1 = strval(tmp2);
        if(isnull(tmp3)) colour2 = random(126); else colour2 = strval(tmp3);
        new LVehicleID,Float:X,Float:Y,Float:Z, Float:Angle,int1; GetPlayerPos(playerid, X,Y,Z); GetPlayerFacingAngle(playerid,Angle); int1 = GetPlayerInterior(playerid);
        LVehicleID = CreateVehicle(car, X+3,Y,Z, Angle, colour1, colour2, -1); LinkVehicleToInterior(LVehicleID,int1);
        CreatedCars[CreatedCar] = LVehicleID;
        CreatedCar ++;
        GetPlayerName(playerid, sendername, sizeof(sendername));
        //format(string, sizeof(string), "%s spawned a \"%s\" (Model:%d) colour (%d, %d), at %0.2f, %0.2f, %0.2f", sendername, VehNames[car-400], car, colour1, colour2, X, Y, Z);
        format(string, sizeof(string), "You have spawned a \"%s\" (Model:%d) colour (%d, %d)", VehNames[car-400], car, colour1, colour2);
        PutPlayerInVehicle(playerid, LVehicleID, 0);
        return SendClientMessageToAdmins(ADMIN_RED, string, 1);
    }
    return 1;
}
Edit2: I'm off, good night all, @_❼_ : hope it helped you.
Reply


Forum Jump:


Users browsing this thread: 2 Guest(s)