Einfacher Enum-Waffendialog (Anfänger)

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

  • Guten Tag,


    im folgendem Thema möchte ich euch zeigen,
    wie ihr einen einfachen Waffendialog erstellen könnt.



    Der fertige Dialog wird ungefähr so aussehen:


    -------------------------------------------------------------


    Der erste Schritt ist ein Enum (Aufzählung) zu erstellen.
    Für unseren Dialog wird es so aufgebaut sein:



    enum WaffenladenInfo //Name des Enums
    {
    Name[32], //Name der Waffe
    Preis, //Preis der Waffe
    WaffenID, //WaffenID (Weaponid - http://wiki.sa-mp.com/wiki/Weapons)
    Munition //Munition, die man bei einem Kauf bekommen soll
    };


    Im zweiten Schritt erstellen wir die "Liste" der Waffen,
    die der Dialog später beinhalten soll. Dafür benötigen
    wir noch eine festgelegte Anzahl (MAX_WEAPONS) an "Elementen" (Waffen),
    die das Enum beinhaltet. In unserem Beispiel sind das 6 Waffen.
    Also haben wir 6 Elemente, die wir so definieren:



    #define MAX_WEAPONS 6


    Jetzt kommen wir zur eigentlichen Waffenauswahl.
    Wir erstellen eine Array (new Waffenladen) mit 6 Einträgen (MAX_WEAPONS)
    und der Struktur von "WaffenladenInfo". Somit bekommt jedes Element einen
    Namen, Preis, WaffenID und Munition.



    new Waffenladen[MAX_WEAPONS][WaffenladenInfo]=
    {
    {"Vibrator (Silber)",99999,13,1},
    {"Desert Eagle",500,24,50},
    {"Shotgun",700,24,50},
    {"MP5",1500,29,200},
    {"M4",4000,31,300},
    {"Minigun",8000,38,500} //Das Komma in der letzten Zeile fällt bei einem Enum immer weg
    };


    Für eine bessere Übersicht im Script definieren wir den Ausdruck "DIALOG_WAFFENLADEN"
    als die Zahl, die der Dialog später erhalten wird. In unserem Beispiel bekommt
    er die Zahl 1. Das ist generell ratsam, da man bei 20+ Dialogen, die alle nur nummeriert
    sind, leicht vergisst für welchen Dialog die einzelnen Nummer stehen.
    "DIALOG_WAFFENLADEN" ist da schon hilfreicher.



    #define DIALOG_WAFFENLADEN 1


    Um den Dialog einem Spieler zu zeigen verwenden wir eine "Stock"-Funktion. !Hinweis 1!
    In diesem Beispiel nennen wir ihn "ShowWaffenladen(playerid)".



    stock ShowWaffenladen(playerid) //playerid ist die Spielerid, die ihn angezeigt bekommen soll
    {
    new string[512]; //Der String, in dem alle Informationen gespeichert werden, um dann dargestellt zu werden
    for(new i; i < MAX_WEAPONS; i++) //Eine For-Schleife, die in unserem Fall 6x aufgerufen wird (0 bis 5). Das i steht hier für die momentane Zahl. !Hinweis 2!
    {
    format(string,sizeof(string),"%s%s (%d Schuss/$%d)\n",string,Waffenladen[i][Name],Waffenladen[i][Munition],Waffenladen[i][Preis]);
    //!Hinweis 3!
    }
    ShowPlayerDialog(playerid,DIALOG_WAFFENLADEN,DIALOG_STYLE_LIST,"Waffenladen",string,"Kaufen","Abbrechen");
    //Der Dialog DIALOG_WAFFENLADEN (1) wird als Liste angezeigt mit dem Inhalt von "string" und den 2 Buttons "Kaufen" & "Abbrechen"
    return 1;
    }


    Diese Funktion kann z.B. dann aufgerufen werden, wenn der Spieler einen
    bestimmten Befehl eingibt oder in einem bestimmten Radius einer Positonen
    eine festgelegte Taste drückt.



    if(strcmp("/mycommand", cmdtext, true, 10) == 0)
    {
    ShowWaffenladen(playerid);
    return 1;
    }



    public OnPlayerKeyStateChange(playerid, newkeys, oldkeys)
    {
    if(newkeys == KEY_FIRE)
    {
    if(IsPlayerInRangeOfPoint(playerid, ...))
    {
    ShowWaffenladen(playerid);
    }
    }
    return 1;
    }


    Damit auch etwas passiert bzw. der Spieler seine Waffe bekommt, die er
    kaufen möchte, müssen wir im Public "OnDialogResponse" unseren Dialog
    noch hinzufügen.



    if(dialogid == DIALOG_WAFFENLADEN)
    {
    if(response) //Wenn auf "Kaufen" gelickt wurde (Button 1)
    {
    new string[128]; //Ein String wird erstellt, um eine formatierte Nachricht an den Spieler zu senden
    new Money = GetPlayerMoney(playerid); //Die Variabele Money wird verwendet, um nicht jedes mal GetPlayerMoney(playerid) schreiben zu müssen
    if(Money >= Waffenladen[listitem][Preis]) //Wenn er genug Geld dabei hat !Hinweis 4!
    {
    format(string,sizeof(string),"Du hast erfolgreich einen/eine %s mit %d Schuss fuer $%d gekauft!",Waffenladen[listitem][Name],Waffenladen[listitem][Munition],Waffenladen[listitem][Preis]);
    //Der string wird formatiert, um eine passende Nachricht an den Spieler zu senden, was er gerade gekauft hat
    SendClientMessage(playerid,FARBE,string);
    GivePlayerWeapon(playerid,Waffenladen[listitem][WaffenID],Waffenladen[listitem][Munition]); //Die Waffe mit der entsprechender Munition wird vergeben
    GivePlayerMoney(playerid,-Waffenladen[listitem][Preis]); //Das benötigte Geld wird dem Spieler abgezogen
    }
    else //Wenn er nicht genug Geld dabei hat
    {
    new RMoney = Waffenladen[listitem][Preis]-Money;
    format(string,sizeof(string),"Du hast nicht genug Geld dabei, um einen/eine %s zu kaufen! ($%d zu wenig)",Waffenladen[listitem][Name],RMoney);
    //Der Spieler wird eine Nachricht bekommen, wie viel Geld ihm fehlt, um seine ausgewählte Waffe zu kaufen
    SendClientMessage(playerid,FARBE,string);
    // Die FARBE könnt ihr durch euere ersetzen
    }
    }
    }


    -------------------------------------------------------------


    Hinweis 1:
    Stock-Funktionen werden verwendet, um einen Codeabschnitt nur 1x schreiben zu müssen,
    anstatt an jeder Stelle im Script, an dem er gebraucht wird, wieder von neu zu schreiben.
    ShowWaffenladen(playerid) benötigt maximal 1 Zeile im Script, wobei eine For-Schleife
    mit anschließendem Zeigen eines Dialoges viel mehr benötigt => spart viel Platz & man
    hat eine bessere Übersicht.


    Hinweis 2:
    Ein Enum (und Standart-For-Schleife) beginnt mit 0 an zu zählen. Also 0,1,2,3,...
    Die Elemente, um sie in MAX_WEAPONS zu definieren, jedoch mit 1,2,3,4,...
    Deswegen zählt unsere Schleife von 0-5. Dabei wird die Information, die in
    Waffenladen[i][Name], etc, vorher festgelegt wurde, vom Element i=0 abgerufen.
    => Waffenladen[0][Name] = Vibrator (Silber) bzw. Waffenladen[3][Name] = MP5.


    Hinweis 3:
    Wir formatieren den String mit format, um Informationen zu speichern. Das erste %s (Text) nimmt den bisherigen Inhalt des Strings
    und hängt die weiteren Informationen an. Das zweite %s steht für den Namen der Waffe, das erste %d (Zahl) steht für die Munition,
    die man bekommen soll und das zweite %d steht für den Preis, den man für die Waffen bezahlen muss. Am Ende jeder Zeile befindet
    sich noch ein \n, welches dafür da ist, dass nach jedem Durchlauf eines i's eine neue Zeile im String angehängt wird.


    Hinweis 4:
    Dialoge, die den Style "DIALOG_STYLE_LIST" (Liste) haben, beginnen auch mit 0 an zu zählen.
    Daher ist die ID der ersten Zeile im Dialog 0 (listitem = 0). Logischerweise hat dann
    die zweite Zeile den listitem-"Wert" 1 usw. Deswegen kann man "listitem" als die Zahl einsetzen,
    die das Element des Enums eigentlich hätte.
    => zweite Zeile im Dialog ist die Desert Eagle (Enum-Element 1) => zweite Zeile im Dialog hat das
    listitem 1 => Waffenladen[listitem] = Waffenladen[1], was die Desert Eagle wäre.


    -------------------------------------------------------------


    Ich hoffe, ich konnte einigen helfen und da das meine erste Tutorial ist, ist
    Kritik natürlich willkommen.



    NeRoTeX

    Berlin - Tel Aviv - Moskau

  • Das könnte man weglassen, da sizeof genauso funktioniert und da man kein wert bei der anzahl brauch ;)


    Aber sonst ist es recht gut


    (ja es ist etwas älter aber mal ein Tut was nicht so grausam ist)


    ich hoffe du weisst das sizeof einen wert ermittelt , daher brauchen solche vorgänge länger als wenn du mit konstanten werten.
    Arbeitest. beispiel mit einem #define nach dem kompilen steht an der stelle die definierte Zahl.


    Was mich stört ist das unnötige formatieren. Es reicht einmal formatieren man darf jedoch den string nichtmehr verändern :D.
    dennoch ist das ganze schön gemacht die jeweilige id per lisitem aufzurufen.

    Einmal editiert, zuletzt von IPrototypeI ()