[jTuT] Interaktive Dialoge

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
  • Deine Funktion ist zwar schön und gut, nur bringt die dir hier nichts, da du ShowPlayerDialog_ex verwenden musst.


    Ja, du brauchst zwei unterschiedliche Dialog IDs, da der Code ja sonst nicht weiß welchen Dialog er aktualisieren soll. Die Werte werden ja in den Arrays gespeichert, auf die man mit der dialogid zugreift.


    Beachte, dass du eine möglichst kleine Dialog id nimmst, damit du kein riesen Array benötigst, für zwei Dialoge. Am besten du nimmst 0 und 1.
    Falls du da schon Dialog IDs hast, kannst diese ja ändern.
    Ich werde irgendwann mal das System so ändern, dass eigene Dialog IDs möglich sind.

  • Das ist ne ziemlich verzwickte Sache...


    Also, ich hab es jetzt einmal weitgehendst versucht umzusetzen.


    public OnGameModeInit()
    {
    //Updating Dialogs
    AddItemToDialog(U_DIALOG_DM_DE, "[0] DM1 [Sniper, Desert Eagle, Shotgun]");
    AddItemToDialog(U_DIALOG_DM_DE, "[0] DM2 [Desert Eagle, Combat Shotgun]");
    AddItemToDialog(U_DIALOG_DM_DE, "[0] DM3 [Sawnoff Shotgun, Uzi]");
    AddItemToDialog(U_DIALOG_DM_DE, "[0] DM4 [Katana]");
    AddItemToDialog(U_DIALOG_DM_DE, "[0] DM5 [Minigun]");
    AddItemToDialog(U_DIALOG_DM_DE, "[0] PB [Country Rifle]");
    AddItemToDialog(U_DIALOG_DM_DE, "[0] BF [M4, Uzi, Granaten, Combat Shotgun, Raketenwerfer]");

    AddItemToDialog(U_DIALOG_DM_EN, "[0] DM1 [Sniper, Desert Eagle, Shotgun]");
    AddItemToDialog(U_DIALOG_DM_EN, "[0] DM2 [Desert Eagle, Combat Shotgun]");
    AddItemToDialog(U_DIALOG_DM_EN, "[0] DM3 [Sawnoff Shotgun, Uzi]");
    AddItemToDialog(U_DIALOG_DM_EN, "[0] DM4 [Katana]");
    AddItemToDialog(U_DIALOG_DM_EN, "[0] DM5 [Minigun]");
    AddItemToDialog(U_DIALOG_DM_EN, "[0] PB [Country Rifle]");
    AddItemToDialog(U_DIALOG_DM_EN, "[0] BF [M4, Uzi, Grenades, Combat Shotgun, Rocket Launcher]");
    return 1;
    }


    new DM1_Counter;


    COMMAND:dm1(playerid, params[])
    {
    new Random = random(sizeof(RandomSpawnsDM1)),
    pName[MAX_PLAYER_NAME],
    stringDE[128],
    stringEN[128];
    GetPlayerName(playerid, pName, sizeof(pName));
    format(stringDE, sizeof(stringDE), "»DEATHMATCH« {%06x}%s "#C_DM_E"hat das DM1 betreten! [/DM1]", GetPlayerColor(playerid) >>> 8, pName);
    format(stringEN, sizeof(stringEN), "»DEATHMATCH« {%06x}%s "#C_DM_E"has joined DM1! [/DM1]", GetPlayerColor(playerid) >>> 8, pName);
    AddToDM(playerid, stringDE, stringEN, RandomSpawnsDM1[Random][0], RandomSpawnsDM1[Random][1], RandomSpawnsDM1[Random][2], RandomSpawnsDM1[Random][3], DESERT_EAGLE, 5000, SHOTGUN, 5000, SNIPER_RIFLE, 5000, 0, 0, 1, 0);

    DM1_Counter++;
    format(olditem, 128, GetItemFromDialog(dialogid, U_DIALOG_DM_DE)); //Zeile 498
    format(newitem, 128, "[%d] DM1 [Sniper, Desert Eagle, Combat Shotgun]", DM1_Counter); //Zeile 499
    UpdateItemInDialog(U_DIALOG_DM_DE, olditem, newitem); //Zeile 500


    format(olditem, 128, GetItemFromDialog(dialogid, U_DIALOG_DM_EN)); //Zeile 502
    format(newitem, 128, "[%d] DM1 [Sniper, Desert Eagle, Combat Shotgun]", DM1_Counter); //Zeile 503
    UpdateItemInDialog(U_DIALOG_DM_EN, olditem, newitem); //Zeile 504
    return 1;
    }


    COMMAND:dm(playerid, params[])
    {
    if(pInfo[playerid][Language] == LANGUAGE_DE) ShowUpdateDialog(playerid, U_DIALOG_DM_DE, DIALOG_STYLE_LIST, "Deathmatches", GetDialogInfo(U_DIALOG_DM_DE), "Beitreten", "Schließen");
    if(pInfo[playerid][Language] == LANGUAGE_EN) ShowUpdateDialog(playerid, U_DIALOG_DM_EN, DIALOG_STYLE_LIST, "Deathmatches", GetDialogInfo(U_DIALOG_DM_EN), "Join", "Close");
    return 1;
    }


    D:\Documents\San Andreas Unleashed\pawno\include\Systems\Deathmatches.inc(498) : error 017: undefined symbol "olditem"
    D:\Documents\San Andreas Unleashed\pawno\include\Systems\Deathmatches.inc(499) : error 017: undefined symbol "newitem"
    D:\Documents\San Andreas Unleashed\pawno\include\Systems\Deathmatches.inc(500) : error 017: undefined symbol "olditem"
    D:\Documents\San Andreas Unleashed\pawno\include\Systems\Deathmatches.inc(502) : error 017: undefined symbol "olditem"
    D:\Documents\San Andreas Unleashed\pawno\include\Systems\Deathmatches.inc(503) : error 017: undefined symbol "newitem"
    D:\Documents\San Andreas Unleashed\pawno\include\Systems\Deathmatches.inc(504) : error 017: undefined symbol "olditem"
    ____________________________________________________________________________________________________________________________________________________________________________________________________________________________


    stock ShowUpdateDialog(playerid, dialogid, style, caption[], info[], button1[], button2[])
    {
    DialogOpened[playerid] = dialogid;
    ShowPlayerDialog(playerid, dialogid, style, caption[], info[], button1[], button2[]); //Zeile 1276
    if(dialogid > -1 && dialogid < MAX_DIALOGS)
    {
    format(Caption[dialogid], sizeof(Caption[]), caption);
    format(Info[dialogid], sizeof(Info[]), info);
    format(Button1[dialogid], sizeof(Button1[]), button1);
    format(Button2[dialogid], sizeof(Button2[]), button2);
    }
    return 1;
    }


    stock AddItemToDialog(dialogid, item[])
    {
    new ItemPosition = strfind(Info[dialogid], item);
    if(ItemPosition != -1) strdel(Info[dialogid], ItemPosition, ItemPosition(item) + 1); //Zeile 1299
    format(Info[dialogid], sizeof(Info[]), "%s%s\n", Info[dialogid], item);
    return UpdateDialogForAll(dialogid);
    }


    D:\Documents\San Andreas Unleashed\gamemodes\brawl.pwn(1276) : error 029: invalid expression, assumed zero
    D:\Documents\San Andreas Unleashed\gamemodes\brawl.pwn(1299) : error 012: invalid function call, not a valid address
    D:\Documents\San Andreas Unleashed\gamemodes\brawl.pwn(1299) : warning 215: expression has no effect
    D:\Documents\San Andreas Unleashed\gamemodes\brawl.pwn(1299) : error 001: expected token: ";", but found ")"
    D:\Documents\San Andreas Unleashed\gamemodes\brawl.pwn(1299) : error 029: invalid expression, assumed zero
    D:\Documents\San Andreas Unleashed\gamemodes\brawl.pwn(1299) : fatal error 107: too many error messages on one line

  • Ich finde das dir das Tutorial sehr gut gelungen ist.
    Nun hätte ich da noch die ein oder andere Frage:

    • Es ist doch sicherlich möglich, dies auch mit den anderen Dialog-Arten zu machen, oder ? (MSG,INPUT (auch wenn es nur der Text ist)), oder gibt es einen Grund warum du das nicht mit aufgenannt hast ?
    • Hast du mal nen Speedtest gemacht ? Also mich würde es wirklich interessieren, wenn ca. 200 Spieler drauf sind und 180 von denen wird ein Dialog gezeigt der sich alle X-Sekunden updatet - ob's da zu laggs, gar crashes kommt ?

    Gruß

  • Die ersten Fehler kommen, weil du die zwei Strings nicht deklariert hast.
    new olditem[128], newitem[128];


    Der zweite Fehler kommt, weil du meine AddItemToDialog Funktion geändert hast.
    Der Fehler liegt hier:
    ItemPosition(item) + 1
    Das hast du als Variable deklariert, daher kannst du nicht mit Klammern darauf zugreifen.



    @Paradoxon: Klar, das ist möglich. Ich habe eben nur ein Beispiel gemacht. Mit den anderen Arten geht es auch. Ich kann dir gerne ein Beispiel geben, wenn du willst.
    Wegen dem Speedtest: Werde ich nächste Woche mal machen.

  • Die AddItemToDialog Funktion habe ich nicht verändert, nur den Namen der Variable. Selbst, wenn ich die Funktion aus deinem Tutorial kopiere bleiben die Errors.
    stock AddItemToDialog(dialogid, item[])
    {
    new l_pos = strfind(Info[dialogid], item);
    if(l_pos != -1) strdel(Info[dialogid], l_pos, l_pos+strlen(item)+1);
    format(Info[dialogid], sizeof(Info[]), "%s%s\n", Info[dialogid], item);
    return UpdateDialogForAll(dialogid);
    }

  • Kann ich mir nicht vorstellen, dann hast du noch etwas anderes falsch gemacht.


    Wenn du deine abgeändert Version nimmst, mache die Zeile zu
    if(ItemPosition != -1) strdel(Info[dialogid], ItemPosition, ItemPosition+strlen(item) + 1); //Zeile 1299


    Das strlen hast du nämlich vergessen.

  • if(l_pos != -1) strdel(Info[dialogid], l_pos, l_pos+strlen(item)+1);


    if(ItemPosition != -1) strdel(Info[dialogid], ItemPosition, ItemPosition+strlen(item) + 1);


    Also, ich sehe keinen Unterschied, außer dem Namen der Variable...

  • D:\Documents\San Andreas Unleashed\gamemodes\brawl.pwn(1276) : error 029: invalid expression, assumed zero
    D:\Documents\San Andreas Unleashed\gamemodes\brawl.pwn(1312) : warning 203: symbol is never used: "dialogid"
    D:\Documents\San Andreas Unleashed\gamemodes\brawl.pwn(1328) : error 033: array must be indexed (variable "-unknown-")


    Error Nr.1
    stock ShowUpdateDialog(playerid, dialogid, style, caption[], info[], button1[], button2[])
    {
    DialogOpened[playerid] = dialogid;
    ShowPlayerDialog(playerid, dialogid, style, caption[], info[], button1[], button2[]); //Zeile 1276
    if(dialogid > -1 && dialogid < MAX_DIALOGS)
    {
    format(Caption[dialogid], sizeof(Caption[]), caption);
    format(Info[dialogid], sizeof(Info[]), info);
    format(Button1[dialogid], sizeof(Button1[]), button1);
    format(Button2[dialogid], sizeof(Button2[]), button2);
    }
    return 1;
    }


    Error Nr.2
    stock UpdateDialogForAll(dialogid) //Zeile 1312
    {
    for(new i = 0; i < MAX_PLAYERS; i++)
    {
    {
    ShowPlayerDialog(i, DialogOpened[i], DIALOG_STYLE_LIST, Caption[DialogOpened[i]], Info[DialogOpened[i]], Button1[DialogOpened[i]], Button2[DialogOpened[i]]);
    }
    }
    return 1;
    }


    Error Nr.3
    stock GetItemFromDialog(dialogid, listitem)
    {
    new string[64], count, lastpos = -1, tmp[sizeof(Info[])];
    for(new i = 0; i < strlen(Info[dialogid]); i++)
    {
    if(Info[dialogid][i] == "\n") //Zeile 1328
    {
    if(count == listitem)
    {
    tmp = Info[dialogid];
    strdel(tmp, i, strlen(Info[dialogid]));
    strdel(tmp, 0, lastpos + 1);
    break;
    }
    count++;
    lastpos = i;
    }
    }
    format(string, sizeof(string), tmp);
    return string;
    }

  • Warum hast du denn alle meine Funktionen verbogen? 8|


    ShowPlayerDialog(playerid, dialogid, style, caption[], info[], button1[], button2[]); //Zeile 1276
    Zu
    ShowPlayerDialog(playerid, dialogid, style, caption, info, button1, button2); //Zeile 1276



    stock UpdateDialogForAll(dialogid)
    Zu
    stock UpdateDialogForAll()


    if(Info[dialogid][i] == "\n")
    Zu
    if(Info[dialogid][i] == '\n')


    In den Beispielen von mir ist das aber alles nicht so.

  • Da haben sich ein paar Fehler in meiner Übersetzung im Englischen Forum eingeschlichen, ich werde sie bei Gelegenheit ausbessern, tut mir Leid.^^


    Allerdings ist mir noch nicht klar wohin genau das hin muss.
    format(tmpstr, 128, GetItemFromDialog(dialogid, DM_ID_HIER));
    //dann das neue Item formatieren, also mit switch-case über die DM_ID neu setzen
    switch(DM_ID_VARIABLE)
    {
    case 0: format(newstr, 128, "[%d] DM2 [Desert Eagle, Combat Shotgun]", Spieler_In_dem_DM_0);
    //usw...
    }
    //Dann updaten:
    UpdateItemInDialog(dialogid_von_DE, tmpstr, newstr); //Die Funktion steht In Post #17


    //Dann das gleiche nochmal für Englisch machen.


    Was genau wäre denn z.B. die DM_ID_VARIABLE? Wo müsste ich die vorher benutzt haben?

  • Dieser Teil muss in den Befehl mit dem der Spieler in das DM beitritt. Du hast doch sicher einen Befehl der irgendwie so aussieht:
    /dm [id]


    Die id die du dann eingibst wäre die, die in den switch muss. Ansonsten poste mal den Befehl mit dem du einem DM beitrittst.

  • Ja, so in der Art, allerdings nicht mit der DM ID als Parameter, sondern einen separaten Befehl für jedes DM (/dm1, /dm2, /dm3,...).


    Nehmen wir mal DM1 als Beispiel:
    COMMAND:dm1(playerid, params[])
    {
    new Random = random(sizeof(RandomSpawnsDM1)),
    pName[MAX_PLAYER_NAME],
    stringDE[128],
    stringEN[128];
    GetPlayerName(playerid, pName, sizeof(pName));
    format(stringDE, sizeof(stringDE), "»DEATHMATCH« {%06x}%s "#C_DM_E"hat das DM1 betreten! [/DM1]", GetPlayerColor(playerid) >>> 8, pName);
    format(stringEN, sizeof(stringEN), "»DEATHMATCH« {%06x}%s "#C_DM_E"has joined DM1! [/DM1]", GetPlayerColor(playerid) >>> 8, pName);
    AddToDM(playerid, stringDE, stringEN, RandomSpawnsDM1[Random][0], RandomSpawnsDM1[Random][1], RandomSpawnsDM1[Random][2], RandomSpawnsDM1[Random][3], DESERT_EAGLE, 5000, SHOTGUN, 5000, SNIPER_RIFLE, 5000, 0, 0, 1, 0);
    DM1_Counter++;


    new olditem[128],
    newitem[128];
    format(olditem, sizeof(olditem), GetItemFromDialog(dialogid, U_DIALOG_DM_DE));
    format(newitem, sizeof(newitem), "[%d] DM1 [Sniper, Desert Eagle, Shotgun]", DM1_Counter);
    UpdateItemInDialog(U_DIALOG_DM_DE, olditem, newitem);
    format(olditem, sizeof(olditem), GetItemFromDialog(dialogid, U_DIALOG_DM_EN));
    format(newitem, sizeof(newitem), "[%d] DM1 [Sniper, Desert Eagle, Shotgun]", DM1_Counter);
    UpdateItemInDialog(U_DIALOG_DM_EN, olditem, newitem);
    return 1;
    }


    Hier zeigt er mir error 017: undefined symbol "dialogid" an, da "dialogid" in UpdateUtemInDialog ja nicht definiert ist.

  • Hier zeigt er mir error 017: undefined symbol "dialogid" an, da "dialogid" in UpdateUtemInDialog ja nicht definiert ist.


    COMMAND:dm1(playerid, params[])
    {
    new Random = random(sizeof(RandomSpawnsDM1)),
    pName[MAX_PLAYER_NAME],
    stringDE[128],
    stringEN[128];
    GetPlayerName(playerid, pName, sizeof(pName));
    format(stringDE, sizeof(stringDE), "»DEATHMATCH« {%06x}%s "#C_DM_E"hat das DM1 betreten! [/DM1]", GetPlayerColor(playerid) >>> 8, pName);
    format(stringEN, sizeof(stringEN), "»DEATHMATCH« {%06x}%s "#C_DM_E"has joined DM1! [/DM1]", GetPlayerColor(playerid) >>> 8, pName);
    AddToDM(playerid, stringDE, stringEN, RandomSpawnsDM1[Random][0], RandomSpawnsDM1[Random][1], RandomSpawnsDM1[Random][2], RandomSpawnsDM1[Random][3], DESERT_EAGLE, 5000, SHOTGUN, 5000, SNIPER_RIFLE, 5000, 0, 0, 1, 0);
    DM1_Counter++;


    new olditem[128],
    newitem[128];
    format(olditem, sizeof(olditem), GetItemFromDialog(U_DIALOG_DM_DE, 0)); //DM ID 1 = Listitem 0
    format(newitem, sizeof(newitem), "[%d] DM1 [Sniper, Desert Eagle, Shotgun]", DM1_Counter);
    UpdateItemInDialog(U_DIALOG_DM_DE, olditem, newitem);
    format(olditem, sizeof(olditem), GetItemFromDialog(U_DIALOG_DM_EN, 0));
    format(newitem, sizeof(newitem), "[%d] DM1 [Sniper, Desert Eagle, Shotgun]", DM1_Counter);
    UpdateItemInDialog(U_DIALOG_DM_EN, olditem, newitem);
    return 1;
    }

  • Okay, nun kompiliert es schon einmal.


    Das nächste Problem türmt sich auf.
    Wenn ich nun ein DM betrete bzw. verlasse, wird automatisch der Dialog sofort angezeigt. Das wird wohl an der Funktion UpdateDialogForAll liegen. Wie verändere ich sie, dass der Dialog zwar für alle geändert wird, aber nicht für den SPieler angezeigt wird, der den CMD ausführt?


    Ich habe mir etwas in der Richtung gedacht...
    stock UpdateDialogForAll(playerid, dialogid) //"playerid" hinzugefügt
    {
    for(new i = 0; i < MAX_PLAYERS; i++)
    {
    if(DialogOpened[i] == dialogid)
    {
    if(i != playerid) ShowPlayerDialog(i, DialogOpened[i], DIALOG_STYLE_LIST, Caption[DialogOpened[i]], Info[DialogOpened[i]], Button1[DialogOpened[i]], Button2[DialogOpened[i]]); //if-Abfrage hinzugefügt
    }
    }
    return 1;
    }

  • Du brauchst meine Funktionen nicht zu ändern, die wurden getestet und funktionieren so. Wenn du es änderst, werden nur weitere Fehler auftreten.
    Du kannst es in diesem bestimmten Fall zwar so machen, das wird dir aber in einem anderen Fall wieder Fehler bescheren.


    Hast du vor dem Befehl den Dialog offen gehabt?
    Wenn ja, hast du
    g_PlayerDialog[playerid] = -1;
    als erste Zeile in OnDialogResponse stehen?
    Wenn nein, füge das hinzu.

  • Es klappt alles, danke für deine Hilfe!


    Mich würden Speedtests auch mal interessieren. ;)


    Wenn ichs mir recht überlege, könnte man das Tutorial doch zu einer Include bringen. Ich kann mir vorstellen, dass das sehr viel mehr genutzt werden würde, als sich jemand das Tutorial hier durchliest und es auf eigene Faust versucht.

  • Sehr schön. :)


    Mich würden Speedtests auch mal interessieren. ;)


    Werde ich machen sobald ich Zeit habe. Ich hoffe, dass es mir am Wochenende reicht.
    Ich kann aber auch so sagen, dass es keine Probleme verursacht, solange man es nicht jede Millisekunde aufruft.


    Wenn ichs mir recht überlege, könnte man das Tutorial doch zu einer Include bringen. Ich kann mir vorstellen, dass das sehr viel mehr genutzt werden würde, als sich jemand das Tutorial hier durchliest und es auf eigene Faust versucht.


    Ich merke mir das mal vor. Vielleicht mache ich das über Weihnachten, da findet sich meistens etwas Zeit.



    EDIT:


    Hier der Speedtest @Paradoxon: Manyula:.

    Code
    new t = GetTickCount(), b[16];
    for(new x=0; x<10000; x++)
    {
    for(new i=0; i<10; i++)
    {
    switch(i)
    {
    case 0: b = "Listitem A";
    case 1: b = "Listitem B";
    case 2: b = "Listitem C";
    case 3: b = "Listitem D";
    case 4: b = "Listitem E";
    case 5: b = "Listitem F";
    case 6: b = "Listitem G";
    case 7: b = "Listitem H";
    case 8: b = "Listitem I";
    case 9: b = "Listitem J";
    }
    AddItemToDialog(0, b);
    }
    for(new i=0; i<10; i++)
    {
    switch(i)
    {
    case 0: b = "Listitem A";
    case 1: b = "Listitem B";
    case 2: b = "Listitem C";
    case 3: b = "Listitem D";
    case 4: b = "Listitem E";
    case 5: b = "Listitem F";
    case 6: b = "Listitem G";
    case 7: b = "Listitem H";
    case 8: b = "Listitem I";
    case 9: b = "Listitem J";
    }
    RemoveItemFromDialog(0, b);
    }
    }
    printf("Zeit: %d ms", GetTickCount()-t);

    Zitat

    [18/10/2014 19:31:37] Zeit: 1076 ms


    Das bedeutet, dass es 0,1 Millisekunden (!) dauert, wenn man 10 Items hinzufügt und danach gleich wieder 10 Items entfernt, was eigentlich sowieso keiner macht. Damit kann man entsprechend sagen, dass 1 Item hinzufügen/entfernen 0,005 Millisekunden, also 5 Mikrosekunden dauert.


    => Es ist also zu 100% Lag-Frei und wird keinerlei Fehler verursachen, auch nicht, wenn 200 Spieler den Dialog offen haben, da die Dialoge ja nur per ShowPlayerDialog nach dem aktualisieren angezeigt werden, das hat also keine nennenswerte Auswirkung auf die Laufzeit. Und selbst wenn es die Laufzeit verhundertfachen würde (was völlig absurd ist) würde 1 Item hinzufügen/aktualisieren nur 0,5 Millisekunden dauern, was ebenso keine Lags verursacht, selbst wenn man es 10 mal in der Sekunde macht.


    Fazit: Das System ist selbst bei übermäßig extremen Gebrauch absolut Lag-Frei.

    3HZXdYd.png

    Einmal editiert, zuletzt von Jeffry ()

  • Beitrag von Chans ()

    Dieser Beitrag wurde gelöscht, Informationen über den Löschvorgang sind nicht verfügbar.