Biesmen
15/04/2011, 08:52 AM
Inleiding
Mijn eerste tutorial op SA-MP.com. Ik heb er wel wat vaker geplaatst over SAMP, maar dan op andere forums.
Ik zie dat er vraag is naar het opslaan van score, kills en deaths. Nou, ik heb besloten om hier even een tutorial van te maken.
We gebruiken hiervoor de makkelijke manier om dingen op te slaan: Dini. Normaal raad ik je af om dit te gebruiken, maar voor een kleine script kun je dat wel doen.
Omdat ik momenteel geen PAWN editor heb, kan ik niet zeggen of het werkt omdat ik dit ter plekke type.
Wat is Dini?
Dini is gemaakt door DracoBlue (http://forum.sa-mp.com/member.php?u=389). Je kent de standaard functie van C/C++ wel, om bestanden te lezen en te maken. PAWN gebruikt deze dus ook. De 'standaard' functie heeft deze onderdelen:
fwrite (http://wiki.sa-mp.com/wiki/Fwrite): Om naar een bestand te schrijven
fopen: (http://wiki.sa-mp.com/wiki/Fopen) Een bestand openen
fclose: (http://wiki.sa-mp.com/wiki/Fclose) Een bestand sluiten
fremove: (http://wiki.sa-mp.com/wiki/Fremove) Een bestand verwijderen
fread (http://wiki.sa-mp.com/wiki/Fread): Om een bestand te lezen
De dini functies:
Als het goed is mis ik geen functie, ik heb dit uit m'n hoofd getypt, als ik er wel één mis, zeg het dan a.u.b
dini_Exists(bestandsnaam): (http://forum.sa-mp.com/showthread.php?p=1165314) Controleren of "bestandsnaam" bestaat.
dini_Remove(bestaandsnaam): (http://forum.sa-mp.com/showthread.php?p=1165314) Het verwijderen van "bestandsnaam".
dini_Create(bestandsnaam): (http://forum.sa-mp.com/showthread.php?p=1165314) Het maken van "bestandsnaam".
dini_Set(bestandsnaam, key, string): (http://forum.sa-mp.com/showthread.php?p=1165314) In een bestand een bepaald iets schrijven. Bijvoorbeeld: dini_Set("Hallo.txt", "Test", "hoi");, dit zal in Hallo.txt het volgende plaatsen: "Test=hoi".
dini_IntSet(bestandsnaam, key, cijfer): (http://forum.sa-mp.com/showthread.php?p=1165314) Hetzelfde als hierboven, alleen hier zet je geen string maar een 'value', een getal. Bijvoorbeeld: dini_IntSet("Hallo.txt", "Test", 1);, dit zal in Hallo.txt het volgende plaatsen: "Test=1".
dini_FloatSet(bestandsnaam, key, floatcijfer): (http://forum.sa-mp.com/showthread.php?p=1165314) Dit doet bijna precies hetzelfde als IntSet, alleen dit is niet voor een integer maar een float integer. Dus met cijfers achter de komma. In het Engels is het cijfers achter de punt. Bijvoorbeeld voor coordinaten.
dini_BoolSet(bestandsnaam, key, cijfer): (http://forum.sa-mp.com/showthread.php?p=1165314) Ik heb nooit begrepen waar dit op slaat, want voor zover ik het nog weet kun je hier niks doen met het cijfer, het kiest zelf een cijfer: 1 of 0. Dus dit is nergens voor nodig.
dini_Int(bestandsnaam, key): (http://forum.sa-mp.com/showthread.php?p=1165314) Dit zal aangeven wat de key als getal heeft. Bijvoorbeeld, we hebben dini_IntSet gebruikt bij "Hallo.txt" en "Hoi" met het getal 501. dini_Int("Hallo.txt", "Test"); zal jou dan het getal "501" geven.
dini_Float(bestandsnaam, key): (http://forum.sa-mp.com/showthread.php?p=1165314) Dit doet precies hetzelfde als dini_Int, alleen dit returnt een float integer.
dini_Get(bestandsnaam, key): (http://forum.sa-mp.com/showthread.php?p=1165314) Dit doet precies hetzelfde als dini_Int en dini_Float, alleen dit zal een string lezen.
dini_Unset(.....): (http://forum.sa-mp.com/showthread.php?p=1165314) Hier zal later informatie van komen, ik weet niet wat dit inhoud, nog nooit gebruikt. Maar ik weet wel dat het bestaat.
Nou, wat dini eigenlijk is, het opent een bestand en sluit het bij elke 'functie'(stock) die je gebruikt.
Daarom raden mensen af om dini te gebruiken. Als iemand, bijvoorbeeld, bij een RP Server inlogt, dan moet je heel veel data laden. Misschien wel 100 dingen. Als je dini gebruikt, zal het gebruikersbestand 100 keer worden geopend en 100 keer worden gesloten.
Terwijl als je geen dini gebruikt, hij maar 1 keer een bestand hoeft te openen, en 1 keer sluiten.
De tutorial
Ik ben een grote voorstander van inloggen en registreren met dialogs, alleen andere mensen niet. Dus ik doe het maar gewoon via een command.
We gebruiken nu strtok om een wachtwoord in te vullen. Ik zal over een paar dagen of misschien later op deze dag, dezelfde tutorial maken alleen dan voor sscanf2.
Ik, en vele andere scripters, raden je af om strtok te gebruiken. Ik wil dat deze tutorial voor iedereen te volgen en te lezen is, daarom gebruik ik de makkelijkere manieren om dit te maken.
We kunnen ook gewoon 'cmdtext' gebruiken, maar de meeste mensen weten niet hoe dat werkt. Daar zal ik ook, net zoals sscanf2 een tutorial over maken, in deze topic.
Zet dit helemaal bovenaan je script, onder #include <a_samp>:
#include <dini>
Stap 1.
Als we strtok gaan gebruiken, moet je het ook definen.
Dus hier is de code om strtok te definen:
strtok(const string[], &index)
{
new length = strlen(string);
while ((index < length) && (string[index] <= ' '))
{
index++;
}
new offset = index;
new result[20];
while ((index < length) && (string[index] > ' ') && ((index - offset) < (sizeof(result) - 1)))
{
result[index - offset] = string[index];
index++;
}
result[index - offset] = EOS;
return result;
}
Stap 2.
We gaan een aantal variabelen maken.
Zet dit bovenaan je script, onder de #includes.
new logged[MAX_PLAYERS]; // Een variabel zodat we kunnen zien of de speler is ingelogt of niet. MAX_PLAYERS betekent het maximaal aantal spelers dat in een server kan, en dat is 500.
new Kills[MAX_PLAYERS];
new Deaths[MAX_PLAYERS];
new Score[MAX_PLAYERS];
Stap 3.
Nu we strtok hebben, kunnen we beginnen met het echte werk.
We gaan beginnen met een command genaamd "/register [wachtwoord]".
Als eerst moeten we naar de callback genaamd "OnPlayerCommandText".
Dus, zoek die maar even op. Tip: CTRL + F.
Als je die hebt gevonden, moet je dit meteen bovenaan zetten:
new cmd[128]; // Het definen, herkennen van CMD.
new idx; // Afkorting van index
new tmp[128];
cmd = strtok(cmdtext, idx); //Hier gebruiken we CMD. CMD wordt nu herkend als strtok.
new playername[MAX_PLAYER_NAME]; // Om de speler's naam te ontvangen
new file[40];
tmp = strtok(cmdtext, idx); // tmp wordt nu ook herkend als strtok
GetPlayerName(playerid, playername, sizeof(playername)); // De speler's naam ontvangen, die een command typt.
De command zelf:
if(strcmp(cmd, "/register", true) == 0)
{
return 1;
}
Dat 'haakje' "{", ookwel "brace" in het Engels, gebruiken we om de 'commando' te openen. En dat andere haakje om hem weer te sluiten.
Als we geen "return" gebruiken, zal hij de volgende command ook meteen pakken, terwijl je het niet typt. (als je meerdere commands hebt)
Dan nu de inhoud van de command.
if(strcmp(cmd, "/register", true) == 0)
{
new playername[MAX_PLAYER_NAME]; // Om de speler's naam te ontvangen
new file[40];
tmp = strtok(cmdtext, idx); // tmp wordt nu ook herkend als strtok
GetPlayerName(playerid, playername, sizeof(playername)); // De speler's naam ontvangen, die /register typt
if(!strlen(tmp)) // Dus, als TMP niet wordt gebruikt:
{ // openen
SendClientMessage(playerid, -1, "GEBRUIK: /register [wachtwoord]"); // Stuur een bericht
return 1; // Wel 'return' doen, anders kan ie toch registreren
} // sluiten
return 1;
}
Wat we nu hebben, is dat als TMP, ookwel het wachtwoord(string), niet wordt getypt, je niet kan registreren.
Nu gaan we de registratie maken.
if(strcmp(cmd, "/register", true) == 0)
{
if(!strlen(tmp)) // Dus, als TMP niet wordt gebruikt:
{ // openen
SendClientMessage(playerid, -1, "GEBRUIK: /register [wachtwoord]"); // Stuur een bericht
return 1; // Wel 'return' doen, anders kan ie toch registreren
} // sluiten
format(file, sizeof(file), "%s.ini", playername); // %s betekent dat hij een string vervangt met %s. Playername is een string.
if(!dini_Exists(file)) // Kijken of naam.ini NIET bestaat.
{ // openen
dini_Create(file); // Het bestand maken, naam.ini
dini_Set(file, "Wachtwoord", tmp); // Zet in naam.ini het wachtwoord dat je hebt gekozen/
//Nu gaan we met de score, death en kills aan de gang.
dini_IntSet(file, "Score", 0); // Als ze registreren moet hun score 0 zijn.
dini_IntSet(file, "Deaths", 0); // Hetzelfde geld voor het aantal keer dat je dood bent gegaan
dini_IntSet(file, "Kills", 0); // en ook voor het aantal kills
//Dan sturen we nu een bericht dat zijn account gemaakt is, en dat hij kan inloggen.
SendClientMessage(playerid, -1, "Je account is gemaakt. Log nu in door /login te typen, met je wachtwoord die je zelf gekozen hebt.");
// Prachtig, nu is het account gemaakt.
} // Sluiten
else // MAARR!! Als naam.ini WEL bestaat, kan hij natuurlijk niet registreren!
{ // Dus, openen die else
SendClientMessage(playerid, -1, "Dit account bestaat al! Je kan niet registreren"); // Bericht sturen
} // Sluiten die handel.
return 1; // Dan weer return zodat de command wordt afgesloten/
}
Stap 4.
Dan gaan we nu het login systeem maken.
Hier gaan we controlleren of het account bestaat, als ze inloggen, en het laden van hun score, deaths en kills.
if(strcmp(cmd, "/login", true) == 0) // Als ze /login typen:"
{ // Openen
if(logged[playerid] == 1) // Als de speler al is ingelogt, mag hij dat natuurlijk niet nog een keer doen.
{ // openen
SendClientMessage(playerid, -1, "Je bent al ingelogt!"); // Bericht sturen
return 1; // Return, zodat hij niet verder kan
} // Sluiten
if(!strlen(tmp)) // Deze ken je al.
{ // openen
SendClientMessage(playerid, -1, "Gebruik: /login [wachtwoord]");
return 1; // Ken je ookal
} // sluiten
format(file, sizeof(file), "%s.ini", playername); // Ken je ook wel
if(dini_Exists(file)) // Als het account bestaat
{ // openen
if(strcmp(tmp, !dini_Get(file, "Wachtwoord"), true) == 0) // Als het wachtwoord NIET overeenkomt
{ // openen
SendClientMessage(playerid, -1, "Het wachtwoord klopt niet!");
return 1;
} // sluiten
//Als het wel klopt, zal hij alles laden.
logged[playerid] = 1; // Als eerst aangeven dat hij is ingelogt.
Score[playerid] = dini_Int(file, "Score"); //De gegevens laden en in een variabel zetten van Score.
Deaths[playerid] = dini_Int(file, "Deaths"); //De gegevens laden en in een variabel zetten van Deaths.
Kills[playerid] = dini_Int(file, "Kills"); // De gegevens laden en in een variabel zetten van Kills.
SendClientMessage(playerid, -1, "Je bent nu ingelogd."); // Bericht geven dat hij is ingelogt
} // Sluiten
else // MAAR... Als het account niet bestaat:
{
SendClientMessage(playerid, -1, "Je account bestaat niet. Registreer eerst door /register te typen!");
return 1;
} // sluiten
return 1;
} // De commando sluiten
Mooi, nu hebben we het registreer en login systeem gemaakt. Dan gaan we later drie commando's maken om je score, kills en deaths te achterhalen.
Stap 5.
Nu ga ik een aantal 'stocks' maken, zodat je kunt achterhalen hoeveel kills/deaths en score je hebt.
Plaats deze stocks ergens in je script waar je ook maar wilt.
stock GetPlayerDeaths(playerid) // Dit kunnen we gebruiken om te achterhalen hoeveel deaths iemand heeft.
{
return Deaths[playerid]; // Als GetPlayerDeaths wordt getypt, zal hij nu aangeven hoeveel deaths iemand heeft.
}
stock NewGetPlayerScore(playerid) // GetPlayerScore bestaat al, maar we willen ook de opgeslagen playerscore zien.
{
Score[playerid] = Score[playerid] + GetPlayerScore(playerid); // Hier worden de scores bij elkaar opgeteld.
return Score[playerid]; // Zelfde als bij GetPlayerDeaths.
}
stock GetPlayerKills(playerid)
{
return Kills[playerid]; // Zelfde als bij GetPlayerDeaths
}
Eerlijk gezegd is niet allemaal niet heel erg nodig, maar soms wel handig.
Stap 6.
Nu moeten we zorgen dat als iemand dood gaat, hij een 'death' erbij krijgt. En de killer een score + kill erbij.
Ga naar de callback: "OnPlayerDeath".
Tip: CTRL + F
Als je de callback hebt gevonden, ga je de callback verwijderen, en vervangen met dit:
public OnPlayerDeath(playerid, killerid, reason) // Default
{ // Openen
Score[killerid]++; // ++ betekent gewoon, simpel weg: +1. Killerid = de moordenaar
Kills[killerid]++;
Deaths[playerid]++; // Nu geven we de gene die is vermoord +1 deaths.
return 1; // Return.
} // callback sluiten
Stap 7.
Nu moeten we zorgen dat de informatie wordt opgeslagen als de speler uit de server gaat.
Daarom gaan we naar de callback: "OnPlayerDisconnect".
Tip: CTRL + F
Verwijder die callback maar, vervang het met dit:
public OnPlayerDisconnect(playerid, reason)
{ // openen
// Als eerst weer de naam van de speler ontvangen en file definen.
new playername[MAX_PLAYER_NAME];
GetPlayerName(playerid, playername, sizeof(playername));
new file[40];
format(file, sizeof(file), "%s.ini", playername);
if(logged[playerid] == 1) // Als hij is ingelogt
{
dini_IntSet(file, "Score", NewGetPlayerScore(playerid)); // De score
dini_IntSet(file, "Deaths", GetPlayerDeaths(playerid)); // De deaths. Eigenlijk kon je ook gewoon ipv de stocks het heel anders doen, door "Deaths[playerid]" te gebruiken.
dini_IntSet(file, "Kills", GetPlayerKills(playerid)); // De kills. Eigenlijk kon je ook gewoon ipv de stocks het heel anders doen, door "Kills[playerid]" te gebruiken.
logged[playerid] = 0; // Uitloggen
}
return 1; // Return.
} // Sluiten
Uitleiding
We hebben nu een 'save' systeempje gemaakt, registreer en login, met het opslaan van de score, deaths en kills.
Nu zijn we weer blij vandaag.
Maar, ik heb wel, ook expres gedaan, onnodige stocks gemaakt. Ik vond het op die manier misschien wat beter voor de beginners om dat zo te doen.
Binnenkort zal er ook een SSCANF2 en CMDTEXT versie komen.
Bedankt voor het lezen en veel plezier ermee.
Einde
Mijn eerste tutorial op SA-MP.com. Ik heb er wel wat vaker geplaatst over SAMP, maar dan op andere forums.
Ik zie dat er vraag is naar het opslaan van score, kills en deaths. Nou, ik heb besloten om hier even een tutorial van te maken.
We gebruiken hiervoor de makkelijke manier om dingen op te slaan: Dini. Normaal raad ik je af om dit te gebruiken, maar voor een kleine script kun je dat wel doen.
Omdat ik momenteel geen PAWN editor heb, kan ik niet zeggen of het werkt omdat ik dit ter plekke type.
Wat is Dini?
Dini is gemaakt door DracoBlue (http://forum.sa-mp.com/member.php?u=389). Je kent de standaard functie van C/C++ wel, om bestanden te lezen en te maken. PAWN gebruikt deze dus ook. De 'standaard' functie heeft deze onderdelen:
fwrite (http://wiki.sa-mp.com/wiki/Fwrite): Om naar een bestand te schrijven
fopen: (http://wiki.sa-mp.com/wiki/Fopen) Een bestand openen
fclose: (http://wiki.sa-mp.com/wiki/Fclose) Een bestand sluiten
fremove: (http://wiki.sa-mp.com/wiki/Fremove) Een bestand verwijderen
fread (http://wiki.sa-mp.com/wiki/Fread): Om een bestand te lezen
De dini functies:
Als het goed is mis ik geen functie, ik heb dit uit m'n hoofd getypt, als ik er wel één mis, zeg het dan a.u.b
dini_Exists(bestandsnaam): (http://forum.sa-mp.com/showthread.php?p=1165314) Controleren of "bestandsnaam" bestaat.
dini_Remove(bestaandsnaam): (http://forum.sa-mp.com/showthread.php?p=1165314) Het verwijderen van "bestandsnaam".
dini_Create(bestandsnaam): (http://forum.sa-mp.com/showthread.php?p=1165314) Het maken van "bestandsnaam".
dini_Set(bestandsnaam, key, string): (http://forum.sa-mp.com/showthread.php?p=1165314) In een bestand een bepaald iets schrijven. Bijvoorbeeld: dini_Set("Hallo.txt", "Test", "hoi");, dit zal in Hallo.txt het volgende plaatsen: "Test=hoi".
dini_IntSet(bestandsnaam, key, cijfer): (http://forum.sa-mp.com/showthread.php?p=1165314) Hetzelfde als hierboven, alleen hier zet je geen string maar een 'value', een getal. Bijvoorbeeld: dini_IntSet("Hallo.txt", "Test", 1);, dit zal in Hallo.txt het volgende plaatsen: "Test=1".
dini_FloatSet(bestandsnaam, key, floatcijfer): (http://forum.sa-mp.com/showthread.php?p=1165314) Dit doet bijna precies hetzelfde als IntSet, alleen dit is niet voor een integer maar een float integer. Dus met cijfers achter de komma. In het Engels is het cijfers achter de punt. Bijvoorbeeld voor coordinaten.
dini_BoolSet(bestandsnaam, key, cijfer): (http://forum.sa-mp.com/showthread.php?p=1165314) Ik heb nooit begrepen waar dit op slaat, want voor zover ik het nog weet kun je hier niks doen met het cijfer, het kiest zelf een cijfer: 1 of 0. Dus dit is nergens voor nodig.
dini_Int(bestandsnaam, key): (http://forum.sa-mp.com/showthread.php?p=1165314) Dit zal aangeven wat de key als getal heeft. Bijvoorbeeld, we hebben dini_IntSet gebruikt bij "Hallo.txt" en "Hoi" met het getal 501. dini_Int("Hallo.txt", "Test"); zal jou dan het getal "501" geven.
dini_Float(bestandsnaam, key): (http://forum.sa-mp.com/showthread.php?p=1165314) Dit doet precies hetzelfde als dini_Int, alleen dit returnt een float integer.
dini_Get(bestandsnaam, key): (http://forum.sa-mp.com/showthread.php?p=1165314) Dit doet precies hetzelfde als dini_Int en dini_Float, alleen dit zal een string lezen.
dini_Unset(.....): (http://forum.sa-mp.com/showthread.php?p=1165314) Hier zal later informatie van komen, ik weet niet wat dit inhoud, nog nooit gebruikt. Maar ik weet wel dat het bestaat.
Nou, wat dini eigenlijk is, het opent een bestand en sluit het bij elke 'functie'(stock) die je gebruikt.
Daarom raden mensen af om dini te gebruiken. Als iemand, bijvoorbeeld, bij een RP Server inlogt, dan moet je heel veel data laden. Misschien wel 100 dingen. Als je dini gebruikt, zal het gebruikersbestand 100 keer worden geopend en 100 keer worden gesloten.
Terwijl als je geen dini gebruikt, hij maar 1 keer een bestand hoeft te openen, en 1 keer sluiten.
De tutorial
Ik ben een grote voorstander van inloggen en registreren met dialogs, alleen andere mensen niet. Dus ik doe het maar gewoon via een command.
We gebruiken nu strtok om een wachtwoord in te vullen. Ik zal over een paar dagen of misschien later op deze dag, dezelfde tutorial maken alleen dan voor sscanf2.
Ik, en vele andere scripters, raden je af om strtok te gebruiken. Ik wil dat deze tutorial voor iedereen te volgen en te lezen is, daarom gebruik ik de makkelijkere manieren om dit te maken.
We kunnen ook gewoon 'cmdtext' gebruiken, maar de meeste mensen weten niet hoe dat werkt. Daar zal ik ook, net zoals sscanf2 een tutorial over maken, in deze topic.
Zet dit helemaal bovenaan je script, onder #include <a_samp>:
#include <dini>
Stap 1.
Als we strtok gaan gebruiken, moet je het ook definen.
Dus hier is de code om strtok te definen:
strtok(const string[], &index)
{
new length = strlen(string);
while ((index < length) && (string[index] <= ' '))
{
index++;
}
new offset = index;
new result[20];
while ((index < length) && (string[index] > ' ') && ((index - offset) < (sizeof(result) - 1)))
{
result[index - offset] = string[index];
index++;
}
result[index - offset] = EOS;
return result;
}
Stap 2.
We gaan een aantal variabelen maken.
Zet dit bovenaan je script, onder de #includes.
new logged[MAX_PLAYERS]; // Een variabel zodat we kunnen zien of de speler is ingelogt of niet. MAX_PLAYERS betekent het maximaal aantal spelers dat in een server kan, en dat is 500.
new Kills[MAX_PLAYERS];
new Deaths[MAX_PLAYERS];
new Score[MAX_PLAYERS];
Stap 3.
Nu we strtok hebben, kunnen we beginnen met het echte werk.
We gaan beginnen met een command genaamd "/register [wachtwoord]".
Als eerst moeten we naar de callback genaamd "OnPlayerCommandText".
Dus, zoek die maar even op. Tip: CTRL + F.
Als je die hebt gevonden, moet je dit meteen bovenaan zetten:
new cmd[128]; // Het definen, herkennen van CMD.
new idx; // Afkorting van index
new tmp[128];
cmd = strtok(cmdtext, idx); //Hier gebruiken we CMD. CMD wordt nu herkend als strtok.
new playername[MAX_PLAYER_NAME]; // Om de speler's naam te ontvangen
new file[40];
tmp = strtok(cmdtext, idx); // tmp wordt nu ook herkend als strtok
GetPlayerName(playerid, playername, sizeof(playername)); // De speler's naam ontvangen, die een command typt.
De command zelf:
if(strcmp(cmd, "/register", true) == 0)
{
return 1;
}
Dat 'haakje' "{", ookwel "brace" in het Engels, gebruiken we om de 'commando' te openen. En dat andere haakje om hem weer te sluiten.
Als we geen "return" gebruiken, zal hij de volgende command ook meteen pakken, terwijl je het niet typt. (als je meerdere commands hebt)
Dan nu de inhoud van de command.
if(strcmp(cmd, "/register", true) == 0)
{
new playername[MAX_PLAYER_NAME]; // Om de speler's naam te ontvangen
new file[40];
tmp = strtok(cmdtext, idx); // tmp wordt nu ook herkend als strtok
GetPlayerName(playerid, playername, sizeof(playername)); // De speler's naam ontvangen, die /register typt
if(!strlen(tmp)) // Dus, als TMP niet wordt gebruikt:
{ // openen
SendClientMessage(playerid, -1, "GEBRUIK: /register [wachtwoord]"); // Stuur een bericht
return 1; // Wel 'return' doen, anders kan ie toch registreren
} // sluiten
return 1;
}
Wat we nu hebben, is dat als TMP, ookwel het wachtwoord(string), niet wordt getypt, je niet kan registreren.
Nu gaan we de registratie maken.
if(strcmp(cmd, "/register", true) == 0)
{
if(!strlen(tmp)) // Dus, als TMP niet wordt gebruikt:
{ // openen
SendClientMessage(playerid, -1, "GEBRUIK: /register [wachtwoord]"); // Stuur een bericht
return 1; // Wel 'return' doen, anders kan ie toch registreren
} // sluiten
format(file, sizeof(file), "%s.ini", playername); // %s betekent dat hij een string vervangt met %s. Playername is een string.
if(!dini_Exists(file)) // Kijken of naam.ini NIET bestaat.
{ // openen
dini_Create(file); // Het bestand maken, naam.ini
dini_Set(file, "Wachtwoord", tmp); // Zet in naam.ini het wachtwoord dat je hebt gekozen/
//Nu gaan we met de score, death en kills aan de gang.
dini_IntSet(file, "Score", 0); // Als ze registreren moet hun score 0 zijn.
dini_IntSet(file, "Deaths", 0); // Hetzelfde geld voor het aantal keer dat je dood bent gegaan
dini_IntSet(file, "Kills", 0); // en ook voor het aantal kills
//Dan sturen we nu een bericht dat zijn account gemaakt is, en dat hij kan inloggen.
SendClientMessage(playerid, -1, "Je account is gemaakt. Log nu in door /login te typen, met je wachtwoord die je zelf gekozen hebt.");
// Prachtig, nu is het account gemaakt.
} // Sluiten
else // MAARR!! Als naam.ini WEL bestaat, kan hij natuurlijk niet registreren!
{ // Dus, openen die else
SendClientMessage(playerid, -1, "Dit account bestaat al! Je kan niet registreren"); // Bericht sturen
} // Sluiten die handel.
return 1; // Dan weer return zodat de command wordt afgesloten/
}
Stap 4.
Dan gaan we nu het login systeem maken.
Hier gaan we controlleren of het account bestaat, als ze inloggen, en het laden van hun score, deaths en kills.
if(strcmp(cmd, "/login", true) == 0) // Als ze /login typen:"
{ // Openen
if(logged[playerid] == 1) // Als de speler al is ingelogt, mag hij dat natuurlijk niet nog een keer doen.
{ // openen
SendClientMessage(playerid, -1, "Je bent al ingelogt!"); // Bericht sturen
return 1; // Return, zodat hij niet verder kan
} // Sluiten
if(!strlen(tmp)) // Deze ken je al.
{ // openen
SendClientMessage(playerid, -1, "Gebruik: /login [wachtwoord]");
return 1; // Ken je ookal
} // sluiten
format(file, sizeof(file), "%s.ini", playername); // Ken je ook wel
if(dini_Exists(file)) // Als het account bestaat
{ // openen
if(strcmp(tmp, !dini_Get(file, "Wachtwoord"), true) == 0) // Als het wachtwoord NIET overeenkomt
{ // openen
SendClientMessage(playerid, -1, "Het wachtwoord klopt niet!");
return 1;
} // sluiten
//Als het wel klopt, zal hij alles laden.
logged[playerid] = 1; // Als eerst aangeven dat hij is ingelogt.
Score[playerid] = dini_Int(file, "Score"); //De gegevens laden en in een variabel zetten van Score.
Deaths[playerid] = dini_Int(file, "Deaths"); //De gegevens laden en in een variabel zetten van Deaths.
Kills[playerid] = dini_Int(file, "Kills"); // De gegevens laden en in een variabel zetten van Kills.
SendClientMessage(playerid, -1, "Je bent nu ingelogd."); // Bericht geven dat hij is ingelogt
} // Sluiten
else // MAAR... Als het account niet bestaat:
{
SendClientMessage(playerid, -1, "Je account bestaat niet. Registreer eerst door /register te typen!");
return 1;
} // sluiten
return 1;
} // De commando sluiten
Mooi, nu hebben we het registreer en login systeem gemaakt. Dan gaan we later drie commando's maken om je score, kills en deaths te achterhalen.
Stap 5.
Nu ga ik een aantal 'stocks' maken, zodat je kunt achterhalen hoeveel kills/deaths en score je hebt.
Plaats deze stocks ergens in je script waar je ook maar wilt.
stock GetPlayerDeaths(playerid) // Dit kunnen we gebruiken om te achterhalen hoeveel deaths iemand heeft.
{
return Deaths[playerid]; // Als GetPlayerDeaths wordt getypt, zal hij nu aangeven hoeveel deaths iemand heeft.
}
stock NewGetPlayerScore(playerid) // GetPlayerScore bestaat al, maar we willen ook de opgeslagen playerscore zien.
{
Score[playerid] = Score[playerid] + GetPlayerScore(playerid); // Hier worden de scores bij elkaar opgeteld.
return Score[playerid]; // Zelfde als bij GetPlayerDeaths.
}
stock GetPlayerKills(playerid)
{
return Kills[playerid]; // Zelfde als bij GetPlayerDeaths
}
Eerlijk gezegd is niet allemaal niet heel erg nodig, maar soms wel handig.
Stap 6.
Nu moeten we zorgen dat als iemand dood gaat, hij een 'death' erbij krijgt. En de killer een score + kill erbij.
Ga naar de callback: "OnPlayerDeath".
Tip: CTRL + F
Als je de callback hebt gevonden, ga je de callback verwijderen, en vervangen met dit:
public OnPlayerDeath(playerid, killerid, reason) // Default
{ // Openen
Score[killerid]++; // ++ betekent gewoon, simpel weg: +1. Killerid = de moordenaar
Kills[killerid]++;
Deaths[playerid]++; // Nu geven we de gene die is vermoord +1 deaths.
return 1; // Return.
} // callback sluiten
Stap 7.
Nu moeten we zorgen dat de informatie wordt opgeslagen als de speler uit de server gaat.
Daarom gaan we naar de callback: "OnPlayerDisconnect".
Tip: CTRL + F
Verwijder die callback maar, vervang het met dit:
public OnPlayerDisconnect(playerid, reason)
{ // openen
// Als eerst weer de naam van de speler ontvangen en file definen.
new playername[MAX_PLAYER_NAME];
GetPlayerName(playerid, playername, sizeof(playername));
new file[40];
format(file, sizeof(file), "%s.ini", playername);
if(logged[playerid] == 1) // Als hij is ingelogt
{
dini_IntSet(file, "Score", NewGetPlayerScore(playerid)); // De score
dini_IntSet(file, "Deaths", GetPlayerDeaths(playerid)); // De deaths. Eigenlijk kon je ook gewoon ipv de stocks het heel anders doen, door "Deaths[playerid]" te gebruiken.
dini_IntSet(file, "Kills", GetPlayerKills(playerid)); // De kills. Eigenlijk kon je ook gewoon ipv de stocks het heel anders doen, door "Kills[playerid]" te gebruiken.
logged[playerid] = 0; // Uitloggen
}
return 1; // Return.
} // Sluiten
Uitleiding
We hebben nu een 'save' systeempje gemaakt, registreer en login, met het opslaan van de score, deaths en kills.
Nu zijn we weer blij vandaag.
Maar, ik heb wel, ook expres gedaan, onnodige stocks gemaakt. Ik vond het op die manier misschien wat beter voor de beginners om dat zo te doen.
Binnenkort zal er ook een SSCANF2 en CMDTEXT versie komen.
Bedankt voor het lezen en veel plezier ermee.
Einde