(A fordítás eredetije megtalálható a
http://forum.sa-mp.com/showthread.php?t=91354 oldalon. A módosításokat a fordítás végén közlöm)
LeírásEz egy kis include, ami az
OnPlayerCommandText() callback-et használja a játékosok parancsainak feldolgozására. Minden parancsnak van egy külön funkciója, mint a dcmd-ben, de a
zcmd követlenül hívja meg a CallLocalFunction() segítségével. Ez a módszer sokkal gyorsabb, mintha egymás után hasonlítanád össze a szövegeket a beírt paranccsal minden egyes scriptedben lévõ parancsnál (különösen ha egy nem létezõ parancsot ír be a játékos, az összeset végignézi) valamint a fölénye a régi változattal szemben egyenesen arányos a parancsok számával. Készítettem egy sebesség tesztet amikor még csak gondolkoztam ezen a dolgon, az eredményei megtalálhatóak
itt.
HasználatEgy parancs létrehozásához csupán egy public funkciót kell létrehoznod egy speciális elõredefiniált makró segítségével, így:
COMMAND:parancsom(playerid, params[]) // vagy CMD:parancsom(playerid, params[])
{
// Csinalj valamit
return 1;
}
vagy (régi mód):
command(parancsom, playerid, params[]) // or cmd(parancsom, playerid, params[])
{
// Csinalj valamit
return 1;
}
Itt a
params[] egy string ami a paramétereket tartalmazza, a
playerid az ID-je a játékosnak, aki ezt a parancsot beírta.
Ez minden! Nagyon egyszerû, ugye?
Fontos: A 0.3-as verzió óta az OnPlayerCommandText nem használható többé (a ZCMD_NO_CALLBACK opció is el lett távolítva), de van helyette 2 új callback:
OnPlayerCommandReceived(playerid, cmdtext[])
Ez akkor hívódik meg, mikor a játékos beír egy parancsot. Ha itt return 0 -val térünk vissza, a parancs nem kerül feldolgozásra.
OnPlayerCommandPerformed(playerid, cmdtext[], success)
Ez pedig a parancs lefutása után hívódik meg, ha itt return 0 -val térünk vissza, a játékos a szokásos \"SERVER: Unknown command\" üzenetet fogja megkapni. A \"success\" paraméter az az érték, amivel a parancs funkciója visszatér (ha nincs ilyen funkció, a success értéke 0).
Ezeket a callback-eket nem szükséges beleírni a scriptedbe, ha nem használod õket. Hogy csináljunk két különbözõ parancsot, amik ugyanazt teszikPéldául, van egy
/valami parancs:
COMMAND:valami(playerid, params[])
{
// valami dolog itt
return 1;
}
és szeretnél egy másikat is csinálni, pl. /masik ami azt csinálja, amit a /valami csinál. A legegyszerûbb módja ennek:
COMMAND:masik(playerid, params[])
{
return cmd_valami(playerid, params);
}
Megjegyzés #1: Ha a zcmd-t egy filterscriptben szeretnéd használni, include elé szúrd be ezt a define-t:(a javított kiadásban erre nincs szükség)
#define FILTERSCRIPT
Megjegyzés #2: Ha meg szeretnéd vizsgálni, hogy a \"params\"(paraméterek) string üres-e, ne így tedd:
if (!strlen(params))
{
// nincs parameter
}
vagy:
if (!params[0])
mivel a string hossza sosem nulla (errõl bõvebben:
itt), egyszerûen használd a zcmd-be épített
isnull() függvényt:
if (isnull(params))
Tulajdonképpen, ha az sscanf-et használod, nem kell elvégezned ezt az ellenõrzést, mivel abban van beépített \"isnull\" vizsgálat.Itt egy példa, hogyan készíthetünk egy /givemoney parancsot zcmd és sscanf használatával:
COMMAND:givemoney(playerid, params[])
{
if (IsPlayerAdmin(playerid))
{
new
kinek, // a jatekos, akinek a penzt szeretnenk adni
mennyit;
// a jatekos ID-je es a mennyiseg kinyerese a parameterekbol:
if (!sscanf(params, \"ui\", kinek, mennyit))
{
if (kinek != INVALID_PLAYER_ID)
{
new
uzenet[40];
GivePlayerMoney(kinek, mennyit);
format(uzenet, sizeof(uzenet), \"Kaptál $%d-t az admintól!\", mennyit);
SendClientMessage(kinek, 0x00FF00FF, uzenet);
}
else SendClientMessage(playerid, 0xFF0000FF, \"A játékos nem elérhetõ\");
}
else SendClientMessage(playerid, 0xFFFFFFFF, \"Használat: /givemoney <játékosnév/id> <mennyiség>\");
}
else SendClientMessage(playerid, 0xFF0000FF, \"Csak adminisztrátorok használhatják ezt a parancsot!\");
return 1;
}
Változtatások balintx általA ZCMD_fixed két fõ változtatást foglal magában:
- Mostantól nincs szükség a FILTERSCRIPT makró definiálására, ha filterscriptben kívánjuk használni a zcmd-t.
Nem csak felesleges, de biztosan volt már, hogy elfelejtkeztünk róla és nem értettük miért nem mûködnek parancsaink.
- ZCMD mostantól támogatja a magyar ékezetes parancsokat.
Ennek mûködése:
- a játékos által beírt parancs ékezetes betûinek ékezet nélkülivé alakítása
- az ékezet nélkülivé alakított parancs funkciójának meghívása
Használatához nem kell átírni a már létezõ modokat, csupán újra kell fordítani a zcmd_fixed.inc -el.
Példa a használatra:
CMD:jatekosnev(playerid, params[])
{
szUzenet[MAX_PLAYER_NAME + 12];
strcat(szUzenet, \"* Neved: \");
GetPlayerName(playerid, szUzenet[9], MAX_PLAYER_NAME);
SendClientMessage(playerid, -1, szUzenet);
return 1;
}
a fenti kód le fog futni a /jatekosnev, /játékosnév parancsokra is.
Letöltés /**********************************
* *
* @Author: ZeeX *
* @Version: 0.3.1 *
* @Released: 31/10/2009 *
* *
**********************************/
// Edited by KoczkaHUN
//
// Now it supports Hungarian language
// and you do not have to use the
// FILTERSCRIPT define before
// #include-ing zcmd.
//
// Created 17/05/2012
#if defined _zcmd_included
#endinput
#endif
#define _zcmd_included
#define MAX_FUNC_NAME (32)
#define COMMAND:%1(%2) \\
forward cmd_%1(%2); \\
public cmd_%1(%2)
#define CMD:%1(%2) \\
COMMAND:%1(%2)
#define command(%1,%2,%3) \\
COMMAND:%1(%2, %3)
#define cmd(%1,%2,%3) \\
COMMAND:%1(%2, %3)
#if !defined isnull
#define isnull(%1) \\
((!(%1[0])) || (((%1[0]) == \'\\1\') && (!(%1[1]))))
#endif
forward OnPlayerCommandReceived(playerid, cmdtext[]);
forward OnPlayerCommandPerformed(playerid, cmdtext[], success);
static
bool:zcmd_g_HasOPCS = false,
bool:zcmd_g_HasOPCE = false;
public OnFilterScriptInit()
{
zcmd_g_HasOPCS = funcidx(\"OnPlayerCommandReceived\") != -1;
zcmd_g_HasOPCE = funcidx(\"OnPlayerCommandPerformed\") != -1;
return CallLocalFunction(\"zcmd_OnFilterScriptInit\", \"\");
}
#if defined _ALS_OnFilterScriptInit
#undef OnFilterScriptInit
#else
#define _ALS_OnFilterScriptInit
#endif
#define OnFilterScriptInit zcmd_OnFilterScriptInit
forward zcmd_OnFilterScriptInit();
public OnGameModeInit()
{
zcmd_g_HasOPCS = funcidx(\"OnPlayerCommandReceived\") != -1;
zcmd_g_HasOPCE = funcidx(\"OnPlayerCommandPerformed\") != -1;
if (funcidx(\"zcmd_OnGameModeInit\") != -1)
{
return CallLocalFunction(\"zcmd_OnGameModeInit\", \"\");
}
return 1;
}
#if defined _ALS_OnGameModeInit
#undef OnGameModeInit
#else
#define _ALS_OnGameModeInit
#endif
#define OnGameModeInit zcmd_OnGameModeInit
forward zcmd_OnGameModeInit();
public OnPlayerCommandText(playerid, cmdtext[])
{
if (zcmd_g_HasOPCS && !CallLocalFunction(\"OnPlayerCommandReceived\", \"is\", playerid, cmdtext))
{
return 1;
}
new
pos,
funcname[MAX_FUNC_NAME] = \"cmd_\";
while (cmdtext[++pos] > \' \')
{
switch (cmdtext[pos])
{
case \'á\',\'Á\': funcname[pos+3] = \'a\';
case \'é\',\'É\': funcname[pos+3] = \'e\';
case \'í\',\'Í\': funcname[pos+3] = \'i\';
case \'ó\',\'ö\',\'õ\',\'Ó\',\'Ö\',\'Õ\': funcname[pos+3] = \'o\';
case \'ú\',\'ü\',\'û\',\'Ú\',\'Ü\',\'Û\': funcname[pos+3] = \'u\';
default: funcname[pos+3] = tolower(cmdtext[pos]);
}
}
while (cmdtext[pos] == \' \') pos++;
if (!cmdtext[pos])
{
if (zcmd_g_HasOPCE)
{
return CallLocalFunction(\"OnPlayerCommandPerformed\", \"isi\", playerid, cmdtext, CallLocalFunction(funcname, \"is\", playerid, \"\\1\"));
}
return CallLocalFunction(funcname, \"is\", playerid, \"\\1\");
}
if (zcmd_g_HasOPCE)
{
return CallLocalFunction(\"OnPlayerCommandPerformed\", \"isi\", playerid, cmdtext, CallLocalFunction(funcname, \"is\", playerid, cmdtext[pos]));
}
return CallLocalFunction(funcname, \"is\", playerid, cmdtext[pos]);
}
#if defined _ALS_OnPlayerCommandText
#undef OnPlayerCommandText
#else
#define _ALS_OnPlayerCommandText
#endif
#define OnPlayerCommandText zcmd_OnPlayerCommandText
forward zcmd_OnPlayerCommandText(playerid, cmdtext[]);
LegalAz eredeti include Zeex tulajdona.
Az eredeti publikáció itt megtalálható:
http://forum.sa-mp.com/showthread.php?t=91354A módosítás az utolsó, 0.3.1-es zcmd változathoz készült.