The command processor that you choose will not affect anything to do with the actual coding structure in particular. This kind of command relies on simple array and looping methods to find the right value for each weapon/vehicle model. As there is a set order in both, you are able to use arrays, because they are in ascending order from 400-611 and 0-46 with small or no breaks.
So basically for the vehicle system, you will want to set up your array to be compatible with both vehicle names and model ids. In order to determine whether the player's input is numerical or not, you can use SSCANF for an easy and understandable structure. SSCANF is technically essential if you're going to use optional parameters in any case.
So for the beginning, you will start with your vehicle names array:
pawn Code:
new VehicleNames[212][] =
{
"Landstalker", "Bravura", "Buffalo", "Linerunner", "Pereniel", "Sentinel", "Dumper", "Firetruck", "Trashmaster", "Stretch", "Manana", "Infernus",
"Voodoo", "Pony", "Mule", "Cheetah", "Ambulance", "Leviathan", "Moonbeam", "Esperanto", "Taxi", "Washington", "Bobcat", "Mr Whoopee", "BF Injection",
"Hunter", "Premier", "Enforcer", "Securicar", "Banshee", "Predator", "Bus", "Rhino", "Barracks", "Hotknife", "Trailer", "Previon", "Coach", "Cabbie",
"Stallion", "Rumpo", "RC Bandit", "Romero", "Packer", "Monster", "Admiral", "Squalo", "Seasparrow", "Pizzaboy", "Tram", "Trailer", "Turismo", "Speeder",
"Reefer", "Tropic", "Flatbed", "Yankee", "Caddy", "Solair", "Berkley's RC Van", "Skimmer", "PCJ-600", "Faggio", "Freeway", "RC Baron", "RC Raider",
"Glendale", "Oceanic", "Sanchez", "Sparrow", "Patriot", "Quad", "Coastguard", "Dinghy", "Hermes", "Sabre", "Rustler", "ZR3 50", "Walton", "Regina",
"Comet", "BMX", "Burrito", "Camper", "Marquis", "Baggage", "Dozer", "Maverick", "News Chopper", "Rancher", "FBI Rancher", "Virgo", "Greenwood",
"Jetmax", "Hotring", "Sandking", "Blista Compact", "Police Maverick", "Boxville", "Benson", "Mesa", "RC Goblin", "Hotring Racer A", "Hotring Racer B",
"Bloodring Banger", "Rancher", "Super GT", "Elegant", "Journey", "Bike", "Mountain Bike", "Beagle", "Cropdust", "Stunt", "Tanker", "RoadTrain",
"Nebula", "Majestic", "Buccaneer", "Shamal", "Hydra", "FCR-900", "NRG-500", "HPV1000", "Cement Truck", "Tow Truck", "Fortune", "Cadrona", "FBI Truck",
"Willard", "Forklift", "Tractor", "Combine", "Feltzer", "Remington", "Slamvan", "Blade", "Freight", "Streak", "Vortex", "Vincent", "Bullet", "Clover",
"Sadler", "Firetruck", "Hustler", "Intruder", "Primo", "Cargobob", "Tampa", "Sunrise", "Merit", "Utility", "Nevada", "Yosemite", "Windsor", "Monster A",
"Monster B", "Uranus", "Jester", "Sultan", "Stratum", "Elegy", "Raindance", "RC Tiger", "Flash", "Tahoma", "Savanna", "Bandito", "Freight", "Trailer",
"Kart", "Mower", "Duneride", "Sweeper", "Broadway", "Tornado", "AT-400", "DFT-30", "Huntley", "Stafford", "BF-400", "Newsvan", "Tug", "Trailer A", "Emperor",
"Wayfarer", "Euros", "Hotdog", "Club", "Trailer B", "Trailer C", "Andromada", "Dodo", "RC Cam", "Launch", "Police Car (LSPD)", "Police Car (SFPD)",
"Police Car (LVPD)", "Police Ranger", "Picador", "S.W.A.T. Van", "Alpha", "Phoenix", "Glendale", "Sadler", "Luggage Trailer A", "Luggage Trailer B",
"Stair Trailer", "Boxville", "Farm Plow", "Utility Trailer"
};
Then you will need a function that retrieves model id from these names. As vehicles start at '400', the first element of your array (element 0) will correspond with 'Vehicle - 400'. (0 = 400 - 400).
pawn Code:
stock GetVehicleModelFromName(vehname[])
{
for(new i = 0; i < sizeof(VehicleNames); i++)
{
if(strfind(VehicleNames[i], vehname, true) != -1) return i + 400;
}
return -1;
}
Then your command will be constructed from the array and function. With a bit of mixing with SSCANF, you are able to create the following:
pawn Code:
CMD:car(playerid, params[])
{
new var, vehname[20], col1, col2;
if(!sscanf(params, "iI(-1)I(-1)", var, col1, col2)) //Player entered a number.
{
if(!(400 <= var <= 611)) return SendClientMessage(playerid, 0xFF0000FF, "ERROR: Invalid Vehicle Model, must be between 400 and 611.");
}
else if(!sscanf(params, "s[20]I(-1)I(-1)", vehname, col1, col2)) //Player entered a string
{
var = GetVehicleModelFromName(vehname);
if(var == -1) return SendClientMessage(playerid, 0xFF0000FF, "ERROR: Invalid vehicle name entered.");
}
else return SendClientMessage(playerid, 0xFF0000FF, "USAGE: /car [vehicle name/id] [Optional: color1] [Optional: color2]");
if(col1 < 0) col1 = random(255);
if(col2 < 0) col2 = random(255);
new Float:X, Float:Y, Float:Z, Float:A, fstr[58];
GetPlayerPos(playerid, X, Y, Z);
GetPlayerFacingAngle(playerid, A);
PutPlayerInVehicle(playerid, CreateVehicle(var, X, Y, Z + 1.0, A, col1, col2, -1), 0);
format(fstr, sizeof(fstr), "You successfully created a %s (ID: %d)", VehicleNames[(var - 400)], var);
SendClientMessage(playerid, 0xFFFF00FF, fstr);
return 1;
}
--
With the weapons, they follow the same principles. An array for weapon names, and a function to retrieve.
pawn Code:
new GunNames[47][] =
{
"Fist", "Brass Knuckles", "Golf Club", "Nightstick", "Knife", "Baseball Bat",
"Shovel", "Pool Cue", "Katana", "Chainsaw", "Purple Dildo", "Dildo", "Vibrator",
"Silver Vibrator", "Flowers", "Cane", "Grenade", "Tear Gas", "Molotov Cocktail",
"null", "null", "null", "9mm", "Silenced 9mm", "Desert Eagle", "Shotgun", "Sawnoff Shotgun",
"Combat Shotgun", "Micro SMG/Uzi", "MP5", "AK-47/AK47", "M4", "Tec-9/Tec9/Tec 9", "Country Rifle",
"Sniper Rifle", "RPG/Rocket Launcher", "Heatseeker/Heat Seeker", "Flamethrower", "Minigun", "Satchel Charges",
"Detonator", "Spraycan", "Fire Extinguisher", "Camera", "Night Vision Goggles", "Thermal Goggles",
"Parachute"
};
stock GetWeaponIDFromName(weapname[])
{
for(new i = 0; i < sizeof(GunNames); i++)
{
if(18 < i < 22) continue;
if(strfind(GunNames[i], weapname, true) != -1) return i;
}
return -1;
}
Remember the input of the player only has to be found within the weapon names, so weapon names don't need to be perfect in this circumstance because we have a 'GetWeaponName' function with SA-MP. With SSCANF again, you can construct this:
pawn Code:
CMD:giveweapon(playerid, params[])
{
new targetid, var, weapname[32], ammo;
if(!sscanf(params, "uiI(500)", targetid, var, ammo)) //Player entered a number.
{
if(!(0 <= var <= 46) || (18 < var < 22)) return SendClientMessage(playerid, 0xFF0000FF, "ERROR: Invalid Weapon ID, must be between 0 and 46.");
}
else if(!sscanf(params, "is[32]I(500)", targetid, weapname, ammo)) //Player entered a string.
{
var = GetWeaponIDFromName(weapname);
if(var == -1) return SendClientMessage(playerid, 0xFF0000FF, "ERROR: Invalid weapon name entered.");
}
else return SendClientMessage(playerid, 0xFF0000FF, "USAGE: /giveweapon [weapon name/id] [Optional: ammo (Default 500)]");
if(!IsPlayerConnected(targetid) || targetid == INVALID_PLAYER_ID) return SendClientMessage(playerid, 0xFF0000FF, "ERROR: Player not connected.");
if(!(0 < ammo < 999999)) return SendClientMessage(playerid, 0xFF0000FF, "ERROR: Invalid Ammo Amount, must be between 1 and 999999.");
GivePlayerWeapon(targetid, var, ammo);
new fstr[105], playername[MAX_PLAYER_NAME];
GetPlayerName(targetid, playername, sizeof(playername));
GetWeaponName(var, weapname, sizeof(weapname));
format(fstr, sizeof(fstr), "You gave %s(%d) a %s (ID: %d) with %d ammo.", playername, targetid, weapname, var, ammo);
SendClientMessage(playerid, 0xFFFF00FF, fstr);
format(fstr, sizeof(fstr), "You were given a %s with %d ammo.", weapname, ammo);
SendClientMessage(targetid, 0xFFFF00FF, fstr);
return 1;
}
--
Your finished code will be:
pawn Code:
new VehicleNames[212][] =
{
"Landstalker", "Bravura", "Buffalo", "Linerunner", "Pereniel", "Sentinel", "Dumper", "Firetruck", "Trashmaster", "Stretch", "Manana", "Infernus",
"Voodoo", "Pony", "Mule", "Cheetah", "Ambulance", "Leviathan", "Moonbeam", "Esperanto", "Taxi", "Washington", "Bobcat", "Mr Whoopee", "BF Injection",
"Hunter", "Premier", "Enforcer", "Securicar", "Banshee", "Predator", "Bus", "Rhino", "Barracks", "Hotknife", "Trailer", "Previon", "Coach", "Cabbie",
"Stallion", "Rumpo", "RC Bandit", "Romero", "Packer", "Monster", "Admiral", "Squalo", "Seasparrow", "Pizzaboy", "Tram", "Trailer", "Turismo", "Speeder",
"Reefer", "Tropic", "Flatbed", "Yankee", "Caddy", "Solair", "Berkley's RC Van", "Skimmer", "PCJ-600", "Faggio", "Freeway", "RC Baron", "RC Raider",
"Glendale", "Oceanic", "Sanchez", "Sparrow", "Patriot", "Quad", "Coastguard", "Dinghy", "Hermes", "Sabre", "Rustler", "ZR3 50", "Walton", "Regina",
"Comet", "BMX", "Burrito", "Camper", "Marquis", "Baggage", "Dozer", "Maverick", "News Chopper", "Rancher", "FBI Rancher", "Virgo", "Greenwood",
"Jetmax", "Hotring", "Sandking", "Blista Compact", "Police Maverick", "Boxville", "Benson", "Mesa", "RC Goblin", "Hotring Racer A", "Hotring Racer B",
"Bloodring Banger", "Rancher", "Super GT", "Elegant", "Journey", "Bike", "Mountain Bike", "Beagle", "Cropdust", "Stunt", "Tanker", "RoadTrain",
"Nebula", "Majestic", "Buccaneer", "Shamal", "Hydra", "FCR-900", "NRG-500", "HPV1000", "Cement Truck", "Tow Truck", "Fortune", "Cadrona", "FBI Truck",
"Willard", "Forklift", "Tractor", "Combine", "Feltzer", "Remington", "Slamvan", "Blade", "Freight", "Streak", "Vortex", "Vincent", "Bullet", "Clover",
"Sadler", "Firetruck", "Hustler", "Intruder", "Primo", "Cargobob", "Tampa", "Sunrise", "Merit", "Utility", "Nevada", "Yosemite", "Windsor", "Monster A",
"Monster B", "Uranus", "Jester", "Sultan", "Stratum", "Elegy", "Raindance", "RC Tiger", "Flash", "Tahoma", "Savanna", "Bandito", "Freight", "Trailer",
"Kart", "Mower", "Duneride", "Sweeper", "Broadway", "Tornado", "AT-400", "DFT-30", "Huntley", "Stafford", "BF-400", "Newsvan", "Tug", "Trailer A", "Emperor",
"Wayfarer", "Euros", "Hotdog", "Club", "Trailer B", "Trailer C", "Andromada", "Dodo", "RC Cam", "Launch", "Police Car (LSPD)", "Police Car (SFPD)",
"Police Car (LVPD)", "Police Ranger", "Picador", "S.W.A.T. Van", "Alpha", "Phoenix", "Glendale", "Sadler", "Luggage Trailer A", "Luggage Trailer B",
"Stair Trailer", "Boxville", "Farm Plow", "Utility Trailer"
};
new GunNames[47][] =
{
"Fist", "Brass Knuckles", "Golf Club", "Nightstick", "Knife", "Baseball Bat",
"Shovel", "Pool Cue", "Katana", "Chainsaw", "Purple Dildo", "Dildo", "Vibrator",
"Silver Vibrator", "Flowers", "Cane", "Grenade", "Tear Gas", "Molotov Cocktail",
"null", "null", "null", "9mm", "Silenced 9mm", "Desert Eagle", "Shotgun", "Sawnoff Shotgun",
"Combat Shotgun", "Micro SMG/Uzi", "MP5", "AK-47/AK47", "M4", "Tec-9/Tec9/Tec 9", "Country Rifle",
"Sniper Rifle", "RPG/Rocket Launcher", "Heatseeker/Heat Seeker", "Flamethrower", "Minigun", "Satchel Charges",
"Detonator", "Spraycan", "Fire Extinguisher", "Camera", "Night Vision Goggles", "Thermal Goggles",
"Parachute"
};
stock GetVehicleModelFromName(vehname[])
{
for(new i = 0; i < sizeof(VehicleNames); i++)
{
if(strfind(VehicleNames[i], vehname, true) != -1) return i + 400;
}
return -1;
}
stock GetWeaponIDFromName(weapname[])
{
for(new i = 0; i < sizeof(GunNames); i++)
{
if(18 < i < 22) continue;
if(strfind(GunNames[i], weapname, true) != -1) return i;
}
return -1;
}
CMD:car(playerid, params[])
{
new var, vehname[20], col1, col2;
if(!sscanf(params, "iI(-1)I(-1)", var, col1, col2)) //Player entered a number.
{
if(!(400 <= var <= 611)) return SendClientMessage(playerid, 0xFF0000FF, "ERROR: Invalid Vehicle Model, must be between 400 and 611.");
}
else if(!sscanf(params, "s[20]I(-1)I(-1)", vehname, col1, col2)) //Player entered a string
{
var = GetVehicleModelFromName(vehname);
if(var == -1) return SendClientMessage(playerid, 0xFF0000FF, "ERROR: Invalid vehicle name entered.");
}
else return SendClientMessage(playerid, 0xFF0000FF, "USAGE: /car [vehicle name/id] [Optional: color1] [Optional: color2]");
if(col1 < 0) col1 = random(255);
if(col2 < 0) col2 = random(255);
new Float:X, Float:Y, Float:Z, Float:A, fstr[58];
GetPlayerPos(playerid, X, Y, Z);
GetPlayerFacingAngle(playerid, A);
PutPlayerInVehicle(playerid, CreateVehicle(var, X, Y, Z + 1.0, A, col1, col2, -1), 0);
format(fstr, sizeof(fstr), "You successfully created a %s (ID: %d)", VehicleNames[(var - 400)], var);
SendClientMessage(playerid, 0xFFFF00FF, fstr);
return 1;
}
CMD:giveweapon(playerid, params[])
{
new targetid, var, weapname[32], ammo;
if(!sscanf(params, "uiI(500)", targetid, var, ammo)) //Player entered a number.
{
if(!(0 <= var <= 46) || (18 < var < 22)) return SendClientMessage(playerid, 0xFF0000FF, "ERROR: Invalid Weapon ID, must be between 0 and 46.");
}
else if(!sscanf(params, "is[32]I(500)", targetid, weapname, ammo)) //Player entered a string.
{
var = GetWeaponIDFromName(weapname);
if(var == -1) return SendClientMessage(playerid, 0xFF0000FF, "ERROR: Invalid weapon name entered.");
}
else return SendClientMessage(playerid, 0xFF0000FF, "USAGE: /giveweapon [weapon name/id] [Optional: ammo (Default 500)]");
if(!IsPlayerConnected(targetid) || targetid == INVALID_PLAYER_ID) return SendClientMessage(playerid, 0xFF0000FF, "ERROR: Player not connected.");
if(!(0 < ammo < 999999)) return SendClientMessage(playerid, 0xFF0000FF, "ERROR: Invalid Ammo Amount, must be between 1 and 999999.");
GivePlayerWeapon(targetid, var, ammo);
new fstr[105], playername[MAX_PLAYER_NAME];
GetPlayerName(targetid, playername, sizeof(playername));
GetWeaponName(var, weapname, sizeof(weapname));
format(fstr, sizeof(fstr), "You gave %s(%d) a %s (ID: %d) with %d ammo.", playername, targetid, weapname, var, ammo);
SendClientMessage(playerid, 0xFFFF00FF, fstr);
format(fstr, sizeof(fstr), "You were given a %s with %d ammo.", weapname, ammo);
SendClientMessage(targetid, 0xFFFF00FF, fstr);
return 1;
}
I scripted this code with 'ZCMD' because that's my personal preference, but the actual commands are not dependent on the processor that you use. You can use ZCMD, YCMD, DCMD etc., but it won't matter in the long run. As long as you are using SSCANF in particular, things will run fairly smoothly.