MAX_PLAYERS - Dialog

  • Ich release heute mal ein kleines System welches ich letzte Nacht kurz geschrieben habe. Es ist dazu da, einem Spieler einen Dialog anzuzeigen, zb. Mit allen connected Spielern oder mit allen Admins etc. Man kann dann ganz leicht unter OnPlayerDialogResponse das Listitem benutzen.


    Als erstes erstellen wir ein Makro für den Dialog.
    #define DIALOG_PLAYERS 1525 //1525 = Eindeutige DialogID.
    Dann brauchen wir noch eine Variable in der das Listitem zwischengespeichert wird.
    new item[MAX_PLAYERS][MAX_PLAYERS]; //Das 1. MAX_PLAYERS ist dafür da das das Array für jeden Spieler einzeln erstellt wird. Das 2. ist für die einzelnen Listitems da.
    Dann der Befehl:
    if(strcmp("/players", cmdtext, true) == 0)//Standart-Befehl halt
    {
    new iItem;//Variable damit das listitem richtig gesetzt wird
    new string[MAX_PLAYER_NAME*MAX_PLAYERS];//String
    new dName[MAX_PLAYER_NAME];//String für den Namen
    for(new i; i<MAX_PLAYERS; i++)//Schleife die alle Spieler durchgeht
    {
    if(!IsPlayerConnected(i))continue;//Wenn Spieler nicht Connected -> Continue
    //if(!IsPlayerAdmin(i))continue; <- Würde alle RCON-Admins anzeigen.
    GetPlayerName(i, dName, sizeof dName);//String mit Namen setzen
    format(string, sizeof string, "%s\n%s", string, dName);//String für den Dialog erweitern + nächsten Namen reinsetzen
    item[playerid][iItem] = i;//Listitem auf Playerid setzen
    iItem ++;//Listitem hochsetzen damit es das nächste ist
    }
    ShowPlayerDialog(playerid, DIALOG_PLAYERS, DIALOG_STYLE_LIST, "Spieler:", string, "Weiter","Abbrechen");//Dialog anzeigen
    return 1;
    }
    Dann noch ganz simpel bei OnPlayerDialogResponse:
    if(dialogid == DIALOG_PLAYERS)//Dialogid abfragen
    {
    if(!response)return 1;//Wenn er auf Abbrechen drückt -> Abbrechen
    //Hier kannst du nun item[playerid][listitem] für den gewählten Spieler verwenden.
    SendClientMessage(item[playerid][listitem], -1, "Dein Name wurde angeklickt!");
    }


    Wenn ihr noch Fragen habt, schreibt sie einfach hier im Thema!
    Bei Bugs natürlich auch ;)


    MfG.

    Einmal editiert, zuletzt von SynonymousZ ()

  • for(new i; i != GetMaxPlayers(); i++)//Schleife die alle Spieler durchgeht


    Dann nutz da bitte MAX_PLAYERS das ist etwas schneller als die Variante
    new string[MAX_PLAYER_NAME*MAX_PLAYERS];//String
    Kommt mir bekannt vor :D
    Aber dennoch ist die Variante besser als eine Feste größe

    All in all it's just another brick in the wall

  • Finde es soweit ganz gut, jedoch habe ich einwas zu beanstanden.


    Zitat

    new dName[MAX_PLAYER_NAME];//String für den Namen


    Ändere dies bitte zu:


    new dName[MAX_PLAYER_NAME+1];//String für den Namen


    Da es den abschliesenden Null Character noch gibt.


    Quelle: SA:MP Wiki GetPlayerName


    Zitat

    Note: A player's name can be up to 24 characters long (as of 0.3d R2).


    This is defined in a_samp as MAX_PLAYER_NAME.
    Strings to store names in should be made this size, plus one extra cell for the null terminating character.
    i.e. new pName[MAX_PLAYER_NAME+1];

  • @ulbi1990:
    Unnötig.


    Das gilt zwar für den Namens-String den du setzen kannst, jedoch kannst du eh nur mit einem String von 20 Charactern auf einen Server connecten. Sprich eigentlich würde in diesem Fall ein Array von 21 Cells völlig reichen ;)


  • Wenn ich InGame /wanted einegebe kommt Unknowed Command. 8|
    Warum?


    ocmd:wanted(playerid,params[])
    {
    new count=0,iItem;
    new string[MAX_PLAYER_NAME*MAX_PLAYERS];
    for(new i; i != GetMaxPlayers(); i++)
    {
    if (IsPlayerConnected(i))
    {
    if(SpielerInfo[i][pWanted] > 0)
    {
    new dName[MAX_PLAYER_NAME];
    GetPlayerName(i, dName, sizeof dName);
    format(string,sizeof(string),"%s %d\n%s %d",SpielerName(i),GetPlayerWantedLevel(i));
    item[playerid][iItem] = i;
    iItem ++;
    ShowPlayerDialog(i,DialogSubjects,DIALOG_STYLE_LIST,"Verbrecher Akte",string,"Ok","Abbrechen"); //OK Clearen beim anderen Dialog danach
    count++;
    return 1;
    }
    }
    }
    if (count == 0)
    {
    SendClientMessage(playerid, hellblau, "Niemand hat Wanteds!");
    return 1;
    }
    return 1;
    }


    - Tom



    Einmal editiert, zuletzt von Tomsen ()

  • Änder doch nicht meinen Code so drastisch ab, dann kommen solche Fehler auch nicht. Soweit ichs jetzt sehe ist einmal der ShowPlayerDialog zu früh und das hier musst du ändern:
    format(string,sizeof(string),"%s %d\n%s %d",SpielerName(i),GetPlayerWantedLevel(i));
    zu
    format(string,sizeof(string),"%s\n%s %d",string,SpielerName(i),GetPlayerWantedLevel(i));
    Und das return 1; unter count++; hat auch keinen Sinn.

  • @ulbi1990:
    Unnötig.


    Das gilt zwar für den Namens-String den du setzen kannst, jedoch kannst du eh nur mit einem String von 20 Charactern auf einen Server connecten. Sprich eigentlich würde in diesem Fall ein Array von 21 Cells völlig reichen ;)


    Sorry das ich erst jetzt nen Reply schreibe, aber ich wollte dich nur einmal daran erinnern das es noch eine Funktion gibt welche sich SetPlayerName nennt und diese ist NICHT auf die 20 Character gebunden und es gibt hierbei genug Leute die bestimmt wenn jemand /afk geht oder was auch immer noch nen Tag ran geben, so sollte er nun schon 20 Character als Namen haben kommen diese hinzu und dein Code wird nicht mehr ohne Bugs laufen.

  • Schonmal dran gedacht wie lang solch ein Name ist?
    "Heinzelmaennchen1234"
    Mal abgesehen davon, das daraus dann lediglich "[AFK]Heinzelmaennchen123" wird und es nur diesen kleinen Anzeigefehler gibt, ändert es rein gar Nichts. Und mal ehrlich, niemand hat solch einen langen Namen.

  • for(new i; i != GetMaxPlayers(); i++)


    Anstatt MAX_PLAYERS kannst du auch folgendes machen:


    for(new i, l=GetMaxPlayers(); i<l; i++)


    Und, wenn es sich vermeiden lässt, deklariert man keine Variablen in Schleifen.


    Aber, du kannst sie einfach in den "Header" der Schleife packen und dann sieht das so aus:


    for(new i, l=GetMaxPlayers(),dName[MAX_PLAYER_NAME]; i<l; i++)//Schleife die alle Spieler durchgeht
    {
    if(!IsPlayerConnected(i))continue;//Wenn Spieler nicht Connected -> Continue
    //if(!IsPlayerAdmin(i))continue; <- Würde alle RCON-Admins anzeigen.
    GetPlayerName(i, dName, sizeof dName);//String mit Namen setzen
    format(string, sizeof string, "%s\n%s", string, dName);//String für den Dialog erweitern + nächsten Namen reinsetzen
    item[playerid][iItem] = i;//Listitem auf Playerid setzen
    iItem ++;//Listitem hochsetzen damit es das nächste ist
    }


    mfg. :thumbup:

    ast2ufdyxkb1.png


    Leute, lernt scripten und versucht mal lieber etwas selber zu schreiben, als es aus einem GF zu kopieren. :S

  • Anstatt MAX_PLAYERS kannst du auch folgendes machen:


    Hab es jetzt aber als MAX_PLAYERS, wenn man sein MAX_PLAYERS nicht selbstständig runtersetzt ist es halt so, brauch ich mich ja nicht drum kümmern die Schleife kürzer zu machen :D


    Zitat

    Und, wenn es sich vermeiden lässt, deklariert man keine Variablen in Schleifen.


    Hab es nun außerhalb der Schleife.


  • Hab es jetzt aber als MAX_PLAYERS, wenn man sein MAX_PLAYERS nicht selbstständig runtersetzt ist es halt so, brauch ich mich ja nicht drum kümmern die Schleife kürzer zu machen :D



    Hab es nun außerhalb der Schleife.


    Hallo SynonymousZ ich möchte dir mal etwas zum Thema Dialoge erläutern , wenn du ein listitem anklickst wird der inhalt an den Funktionparameter inputtext übergeben,
    daher wird kein extra array benötigt für die listitemid.


    Ich setze immer eine ID bei sowas vor dem listitem, ein beispiel hier die Spielerid.


    [0] Hans
    [1] Dieter
    [2] Peter
    ...


    wenn du den Dialog so formatierst kannst du mit paar Stringfunktionen diese Zahl extrahieren


    Beispielcode mit dem du das kurz testen kannst:
    new inputtext[20] = "[12] Peter";
    strdel(inputtext,0,1);
    strdel(inputtext,strfind(inputtext,"]",0),strlen(inputtext));
    new pID = strval(inputtext);
    printf("%d",pID);