Problem mit dynamischen TexDraw (Spielerinfos)

Wichtiger Hinweis: Bitte ändert nicht manuell die Schriftfarbe auf schwarz sondern belasst es bei der Standardeinstellung. Somit tragt ihr dazu bei dass euer Text auch bei Verwendung unseren dunklen Forenstils noch lesbar ist!

Tipp: Ihr wollt längere Codeausschnitte oder Logfiles bereitstellen? Benutzt unseren eigenen PasteBin-Dienst Link
  • Hey,


    ich habe ein Problem mit meinem Textdraw, der Informationen von Spielern während des Spectaten übergibt (HP, FPS, Ping, Waffen etc.).
    Um genau zu sein betrifft das die Waffeninformationen, denn diese werden zwar dargestellt, aber nur die Waffendaten im ersten (nullten?) Waffenslot werden übergeben
    bzw. als Textdraw dargestellt.
    Das bedeutet alle anderen Waffendaten in anderen Slots werden ignoriert und nicht dargestellt.
    Ich habs zwar noch nicht getestet aber wäre es richtig, einfach noch ein Textdraw im gleichen Format zu erstellen?


    grobe Skizze vom TextDraw (ASCII Art Level: -1):


    Code
    Beobachtungsinformationen von Name(ID) <- Text[7]
    ----------------------------------------------------
    HP: , Ping:, FPS:                                   | <- Text[6]
                                              BOX       |
    Waffen:                                             | <-Text[8]
    WaffeX(Munition)                                    | <-Text[9]
    ----------------------------------------------------


    Code:


    ocmd:spec(playerid, params[]){
    TextDrawShowForPlayer(playerid,Text[6]); //Wesentliche
    TextDrawShowForPlayer(playerid,Text[7]);
    TextDrawShowForPlayer(playerid,Text[8]);
    TextDrawShowForPlayer(playerid,Text[9]);
    gSpecTimer[playerid] = SetTimerEx("SpecInfo",1000,1,"d",pID);
    }


    public SpecInfo(pID)
    {
    new info[128],info1[128],info2[128],Float:health,wp[2];
    GetPlayerHealth(pID,health);
    format(info,sizeof(info),"Beobachtungsinformationen von: %s (%d)",SpielerName(pID),pID);
    format(info1,sizeof(info1),"HP: %.2f, Ping: %d, FPS: %d~n~~n~~n~",health,GetPlayerPing(pID),pFPS[pID]);
    for(new x=0;x<6;x++){
    GetPlayerWeaponData(pID,x,wp[0],wp[1]);
    if(wp[0] != 0){
    format(info2,sizeof(info2),"%d: %s(%d)",x,WaffenName[wp[0]],wp[1]);
    TextDrawSetString(Text[9],info2);
    }
    }
    TextDrawSetString(Text[6],info1);
    TextDrawSetString(Text[7],info);
    }


    (Ist zwar nich die Effizienteste - vielleicht auch garnicht geignete Methode, (Timer wird für jeden, der den Befehl eingibt erstellt ) aber für den Anfang erstmal ist es so, da ich noch etwas unerfahren mit dynamischen TextDraws bin)

  • Du solltest auch noch PlayerTextDraws verwenden, weil sich sonst die TextDraws bei jedem Spieler überschreiben, anstatt immer für einem Spieler geupdatet wird.
    Außerdem solltest du TextDrawSetString(Text[9],info2); nach der Schleife einfügen.


    Jeffry:
    Da muss noch ein Zeilenumbruch hin:
    format(info2,sizeof(info2),"%s%d: %s(%d)~n~",info2,x,WaffenName[wp[0]],wp[1]);

    Einmal editiert, zuletzt von AirM4X ()

  • Stimmt, danke!


    Er kann ja mehrere Waffen besitzen daher würde das Sinn machen einen Zeilenumbruch hinzusetzen. ;)

  • Ja, du kannst den Timer global bei OnGameModeInit einmal starten und im public dann eine Schleife durch alle Spieler machen.
    Dann im Befehl:
    gSpecPlayer[playerid] = pID;


    Und im Timer in der Schleife:
    if(gSpecPlayer[i] != -1)
    {
    //...
    }


    Zwecks Umbruch: Dann passt es ja, wie es im Code ist. :)

  • Jetzt kommt das Problem:


    So wie ich es gemacht habe, benötige ich playerid, da ich aber den Timer bei OnGameModeInit(); ersstellt habe, ist SetTimerEx(); nicht möglich, da
    Das Callback kein Wert wie playerid zurückgibt bzw. garnichts zurückgibt.


    Neuer Code (nun mit PlayerTextDraw):


    for(new i=0;i<MAX_PLAYERS; i++){
    if(!IsPlayerConnected(i))continue;
    if(gSpectateID[i] == playerid){
    new info[128],info1[128],info2[128],Float:health,wp[2];
    GetPlayerHealth(playerid,health);
    format(info,sizeof(info),"Beobachtungsinformationen von: %s (%d)",SpielerName(playerid),playerid);
    format(info1,sizeof(info1),"HP: %.2f, Ping: %d, FPS: %d~n~~n~~n~",health,GetPlayerPing(playerid),pFPS[playerid]);
    for(new x=0;x<6;x++){
    GetPlayerWeaponData(playerid,x,wp[0],wp[1]);
    if(wp[0] != 0){
    format(info2,sizeof(info2),"%s%d: %s(%d)",info2,x,WaffenName[wp[0]],wp[1]);
    }
    }
    }
    }
    PlayerTextDrawSetString(playerid,t_Name[playerid],info);
    PlayerTextDrawSetString(playerid,t_Stats[playerid],info1);
    PlayerTextDrawSetString(playerid,t_WaffenInfo[playerid],info2);


    Also, ich muss da irgendwie playerid reinbringen aber dabei nicht wieder die ineffiziente Methode verwenden.
    Oder kann man das einfacher machen?

  • Bei OnGameModeInit:
    SetTimer("SpecInfo",1000,true);


    Das Callback:
    forward SpecInfo();
    public SpecInfo()
    {
    new info[128], Float:health, wp[2], pID;
    for(new i=0;i<MAX_PLAYERS; i++)
    {
    if(!IsPlayerConnected(i))continue;
    if(gSpectateID[i] != -1)
    {
    pID = gSpectateID[i];
    GetPlayerHealth(pID,health);
    format(info,sizeof(info),"Beobachtungsinformationen von: %s (%d)",SpielerName(pID),pID);
    PlayerTextDrawSetString(i,t_Name[i],info);
    format(info,sizeof(info),"HP: %.2f, Ping: %d, FPS: %d~n~~n~~n~",health,GetPlayerPing(pID),pFPS[pID]);
    PlayerTextDrawSetString(i,t_Stats[i],info);
    info = "Waffen: ";
    for(new x=0;x<6;x++)
    {
    GetPlayerWeaponData(pID,x,wp[0],wp[1]);
    if(wp[0] != 0)
    {
    format(info,sizeof(info),"%s%d: %s(%d) ",info,x,WaffenName[wp[0]],wp[1]);
    }
    }
    PlayerTextDrawSetString(i,t_WaffenInfo[i],info);
    }
    }
    return 1;
    }


    Und bei OnPlayerConnect und beim beenden des Spectator-Modus:
    gSpectateID[playerid] = -1;