Dialoge strukturieren - leicht gemacht | Script strukturieren

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
  • Einige werden sich sicherlich fragen, was es mit dem Titel so auf sich hat.


    Prinzipiell ist das ganz einfach.
    Wenn man programmiert/scriptet gibt es fast nichts schlimmeres, wenn man unstrukturiert arbeitet.
    Besonders unvorteilhaft ist das, wenn viele an einem Script gearbeitet haben.


    Man hat bei Dialogen meistens auch überhaupt keinen Überblick, welche DialogIDs man schon genutzt hat
    und welche nicht.


    Das sieht denn meistens in den Scripten so aus:
    (grobes Beispiel :P)
    #define Dialog1 5
    #define Dialog2 6
    #define Dialog3 7


    // weitere defines z.B. Farben


    #define Dialog8 20
    #define Dialog9 21


    // usw - meistens hängen dann noch new und forwards dazwischen
    defakto hat man keinen Überblick mehr.
    Hier haben wir freie DialogIDs von 8 bis 19.


    Das ist zwar nicht weiterschlimm, aber unvorteilhaft, da man nicht mehr weiß welche bereits belegt sind.


    Dafür hab ich nun die Perfekte Lösung gefunden, die Lösung exestiert schon etwas länger, nur habe ich vermutet, dass man damit Speicher belegt.
    Dies passiert aber nicht.


    Es ist mehr eine andere Art Konstanten bzw Macros zu erstellen.


    Wichtig: Nicht zu verwechseln mit dem const Keyword, es ist diesem nur sehr ähnlich.


    Soviel zur Theorie.
    Kommen wir zu Praxis:


    Der Schlüssel heißt enum.
    Was machen wir jetzt damit?


    Üblicherweise erstellt man damit eine kleine Struktur, von Variablen.
    Enum kann aber viel mehr als nur eine Struktur erstellen.


    Eine Technik wenden wir hier an.


    Hier ein Beispiel, welches noch einmal behandelt wird.


    enum // DialogIDs - hier brauchen wir keinen Namen, da wir im nachinein nicht auf einen Array verweisen, bzw auf einen Arrays hinauswollen
    {
    DIALOG_LOGIN,
    DIALOG_REGISTER
    };


    DIALOG_LOGIN bekommt vom Enum die ID 0 - nicht den Wert - zugewiesen.
    DIALOG_REGISTER bekommt vom Enum die ID 1 - nicht den Wert - zugewiesen.


    Warum ist das nun so?
    Wie möglicherweise aus der üblichen Arbeitsweise bekannt ist,
    simmuliert der Enum Arraywerte.


    Beispiel:
    enum Spieler
    {
    Kills, // hat die ID 0
    Tode, // hat die ID 1
    xBeligigerArray[10] // hat die Werte 2-12
    // Der Enum nummeriert also durch
    };
    new SpielerInfo[50][Spieler];


    // Wir können statt SpielerInfo[5][Kills] die Variable auch direkt ansprechen
    // dies funktioniert in dem wir dem compiler ersteinmal erklären welchen Enum er nun ansprechen soll, es gibt ja schlißlich nicht nur einen
    // Wir nehmen den Enum Namen und benutzen ihn als Tag im Array, den wir bearbeiten wollen


    Spieler:Kills[playerid] = 8; // wäre somit falsch
    //richtig wäre
    SpielerInfo[playerid][Spieler:0] = 8; // 0 - weil Kills vom Enum die ID 0 bekommen hat.


    Um das noch einmal zu verdeutliche - ich weiß, ihr wollt endlich wissen wie das nun angewendet werden kann.
    Die Theorie zur Praxis ist nunnmal nicht ganz unwichtig ;)


    Weiter im Text,
    um das nochmal zu verdeutlichen:


    Dieser Code:
    const Array1 = 0; // oder #define Array1 0
    const Array2 = 1; // oder #define Array2 2
    const Array3 = 2; // oder #define Array3 2


    new Array[3];
    //Anwendung:
    Array[Array1] = 2;
    Array[Array2] = 5;
    Array[Array3] = 8;
    Ist hoffentlich selbst erklärend.
    Man könnte dies natürlich auch wieder per Enum machen ;)


    Aber nungut, ihr wollt ja schließlich was über die Anwendung lernen.
    Machen wir also weiter :P


    Den Enum von Oben:
    enum
    {
    DIALOG_LOGIN,
    DIALOG_REGISTER
    };
    Benutzen wir einfach in einem Dialog für die DialogID
    ShowPlayerDialog(playerid,DIALOG_LOGIN,DIALOG_STYLE_PASSWORD,"Login","Willkommen auf XYZ.\nBitte logge dich ein","Login","Ich gehe");
    Eigentlich sollte das nun selbst erklärend sein, sofern man die Theorie von oben verstanden hat.
    Falls nicht, nochmal lesen.


    Falls beim 2. Mal es immer noch nicht verstanden wurde, im Thread fragen - dafür ist er schließlich da ;)


    Einige werden sich bestimmt fragen, ob man damit nun speicher belegt.
    Seid beruhigt.
    Ich würde dieses Tutorial nicht machen, wenn man dies tuen würde.


    Beiweis:
    //Defines


    #include <a_samp>


    #define Test1 0
    #define Test2 1
    main() { }
    public OnGameModeInit()
    {
    print("loaded");
    return true;
    }


    //Enum
    #include <a_samp>


    enum
    {
    Test1,
    Test2
    };
    main() { }
    public OnGameModeInit()
    {
    print("loaded");
    return true;
    }
    enum
    {
    Test1,
    Test2
    };
    wenn wir nun uns die Anforderungen ansehen:


    Vom ersten Test:
    Header size: 136 bytes
    Code size: 84 bytes
    Data size: 28 bytes
    Stack/heap size: 16384 bytes; estimated max. usage=9 cells (36 bytes)
    Total requirements: 16632 bytes


    Vom 2. Test:
    Header size: 136 bytes
    Code size: 84 bytes
    Data size: 28 bytes
    Stack/heap size: 16384 bytes; estimated max. usage=9 cells (36 bytes)
    Total requirements: 16632 bytes


    Stellt man sicherlich fest, das es vollkommen identisch ist.
    Dies trifft auch auf mit dem Keyword const erstellen zu, diese sind aber wie defines ziehmlich unübersichtlich ;(,
    deswegen nicht zu empfehlen.


    Die "Anforderungen" bekommt ihr einfach, wenn ihr mit -d3 compiliert ;)


    Vorteile:
    - Übersicht
    - kein Speicherverbrauch
    - Klare Struktur
    - Keine unnötigen freien DialogIDs
    - Kein überlegen mehr, welche DialogID noch frei ist (Zeit ersparnis)


    Nachteil:


    Leider gibt es auch einen Nachteil, und zwar der, dass man in Filterscripten/Includes so nicht arbeiten sollte,
    es wird zu einer Überschneidung kommen
    Dies kann man aber umgehen, in dem man die IDs im Enum ändert.


    Dies geht folgendermaßen:enum
    {
    DIALOG_LOGIN = 500,
    DIALOG_REGISTER
    };
    Dies braucht man überlicherweise nur beim ersten machen, da Enum dann weiterzählt.
    DIALOG_REGISTER hat somit die ID 501.


    Natürlich könnte man die IDs auch häufiger ändern, man sollte aber aufpassen, nicht das man durcheinander kommt.


    Ich hoffe, ich konnte euch die PAWN Welt ein bisschen aufhellen.
    Fehler und Verbesserungen sind natürlich erwünscht ;)

    "Bevor ich mir Informationen aus der "Bild" hole,
    werde ich anfangen, Wahlergebnisse danach vorauszusagen,
    neben welchen Busch unsere Katze gepinkelt hat."

    Margarete Stokowski

  • BlackAce warum stellst du die verwendung von arrays die mit const deklariert wurden so umständlich da ? ^^


    Ganz einfach, damit das klarer wird, warum es möglich ist.
    Deine Art das dazustellen, wäre schon wieder zukomplex und stellt es nicht so da wie es wirklich ist und warum es funktioniert ;)


    new const Array[20] = {0,1,...};


    Wozu jetzt new?
    Was willst du mit dem Speicher?

    "Bevor ich mir Informationen aus der "Bild" hole,
    werde ich anfangen, Wahlergebnisse danach vorauszusagen,
    neben welchen Busch unsere Katze gepinkelt hat."

    Margarete Stokowski


  • Ganz einfach, damit das klarer wird, warum es möglich ist.
    Deine Art das dazustellen, wäre schon wieder zukomplex und stellt es nicht so da wie es wirklich ist und warum es funktioniert ;)



    Wozu jetzt new?
    Was willst du mit dem Speicher?


    nix ist ja auch nur angelegt an deinem beispiel. Da du mit const ein konstante werte erstellst die der kompiler auch nicht verändert
    man kann auch


    stock const Array[20] = {0,1,...};


    draus machen sogar die kombination mit static ist möglich auch , wenn das ja hier abweicht


    static const Array[20] = {0,1,...};

  • sogar die kombination mit static ist möglich auch , wenn das ja hier abweicht


    static und stock sind wieder was anderes.


    static besagt nur, dass man es nur in dem verwendeten Script benutzen kann.
    stock besagt nur, dass der compiler es ignorieren soll, wenn es nicht benutzt wird.


    Daher ist keins der beiden ein vergleich mit new.


    Aber wenn new, dort keinen Speicher will, OK

    "Bevor ich mir Informationen aus der "Bild" hole,
    werde ich anfangen, Wahlergebnisse danach vorauszusagen,
    neben welchen Busch unsere Katze gepinkelt hat."

    Margarete Stokowski

  • Das Enum bekommt keinen Namen ?


    Das ist nicht nötig, da die Konstaten im Enum sonst einen Tag bekommen würden,
    was Kontraproduktiv wäre


    Du kannst dem enum natürlich einen Namen geben


    bspw Dialog ->
    enum dialog
    {
    LOGIN,
    REGISTER
    };
    Verwendung wäre dann
    dialog:LOGIN


    // mal wiederhergestellt, denn so blöd ist die Frage nicht :D

    "Bevor ich mir Informationen aus der "Bild" hole,
    werde ich anfangen, Wahlergebnisse danach vorauszusagen,
    neben welchen Busch unsere Katze gepinkelt hat."

    Margarete Stokowski

    Einmal editiert, zuletzt von Akino Kiritani ()

  • do.de - Domain-Offensive - Domains für alle und zu super Preisen
  • Danke für den Hinweis, hatte das mit dem "enum" für die Dialoge auch mal in der wiki gelesen, doch jetzt habe ich es auch auf
    diese Weiße mit den Dialogen umgebaut, da es einfach übersichtlicher ist.


    LG

    Main: CPU: Intel Core i5-4440 @ 3,10 GHz | CPU-Cooling: Matterhorn -PURE- | RAM: 16GB Crucial Ballistix Sport DDR3-1600 DIMM CL9-9-9-24 |
    Motherboard: ASRock B85M Pro4 | GPU: Sapphire Radeon R9 390X Nitro 8GB GDDR5 |

    SSD: Samsung SSD 840 Evo 500GB | Power Supply: 550 Watt Corsair CS Series Modular 80+ Gold | Case: beQuiet! Silent Base 800


    As I walk through the valley of the shadow of death
    I take a look at my life and realize there's nothin' left.