Beiträge von Kaliber

    Gibts eine einfache Möglichkeit wenn ich bspw pGeld = 20000 habe, dass ich es bei einer Übersicht für den Spieler mit einen Punkt anzeigen lassen (also ab den 1000er) also: 20.000 ohne das Geld System ändern zu müssen?

    Hatte dafür mal eine Funktion geschrieben gehabt:



    C
    stock sMoney(geld)
    {
        new str[24],i;
        valstr(str,geld),i=(geld > 0) ? strlen(str)-3 : strlen(str)-4;
        for(; i>0; i-=3) strins(str,".",(geld > 0) ? i : i+1,24);
        return str;
    }

    Nutzung einfach so:


    format(string,sizeof(string),"Habe soviel Geld: %s$",sMoney(pGeld)); //Output: Habe soviel Geld: 20.000$

    Hallo Brotfische,


    oft sehe ich hier ein großes Missverständnis von Includes und Code-Trennungen.
    Deshalb möchte ich hier noch einmal versuchen ein wenig mit diesen Fehlern aufzuräumen.


    Was ist eigentlich ein Include?
    Viele wissen dies nicht. Viele denken, das ist etwas ganz anderes als eine .pwn Datei, schließlich steht da ja .inc.
    Allerdings ist das ein großes Missverständnis, denn im Endeffekt ist es identisch.
    Die Endung soll nur symbolisieren, dass es sich um ein Include handelt und kein eigenständiges Skript.


    Was ist der Unterschied?
    Ein eigenständiges Skript wird kompiliert. Ein Include wird nicht kompiliert.


    Wieso muss ein Include nicht kompiliert werden?
    Ganz einfach, stellen wir uns mal folgende Situation vor:



    Kompilieren wir jetzt den Gamemode, sieht das nach dem pre-compile Prozess so aus:


    C
    //Hier würde alles stehen, was in a_samp steht.
    stock GetMyFunction()
    {
    	return 1;
    }
    main() {
    	print("%d",GetMyFunction());
    }


    Wir sehen also, es wird "einfach nur" (soo leicht ist das auch nicht, aber dazu später mehr) in die Datei kopiert.


    Deshalb müssen wir Includes nicht kompilieren, da sie vom Gamemode kompiliert werden.


    Und deshalb müssen wir in den Includes z.B. auch nicht mehr #include <a_samp> schreiben, da ja das schon im Gamemode steht und das somit auch für das Include gilt.


    Was bringt das jetzt?
    Das wurde ja schon oft gesagt, man kann nun viele Sachen auslagern.
    Okay, aber was genau bedeutet das?


    Logikfehler
    Viele machen hier einen großen Logikfehler.
    Da viele sich die Struktur ihres Gamemodes bei einem Godfather abschauen, verstehen sie oft nicht, wieso diese so schlecht ist.
    Auf den Ersten Blick sieht das ja auch gut aus, ich meine, alle defines Oben, alle Variablen oben, alle Commands und publics in der Mitte und ganz unten alle "stock - Funktionen".
    Ja cool, jetzt wo wir also Includes nutzen können, packen wir alle Variablen in ein Include, alle Commands, alle publics und alle "stock - Funktionen" und voila. Skript aufgeräumt xD


    (No Joke, das machen sehr viele und sind fest von dieser Struktur überzeugt).


    Wieso ist das aber schlecht?
    Genau das versuche ich jetzt hiermit zu vermitteln, das ist NICHT der Sinn oder Vorteil eines Includes.
    Da könnte man sich diesen ganzen Prozess gleich schenken.


    Denn denken wir das weiter und es entsteht jetzt ein Fehler beim Haussystem.
    Wie finden wir in so einem System den Fehler?


    Ja Herzlichen Glückwunsch, jetzt sogar noch schlechter, da wir in 4 Dateien Suchen, alle Variablen dafür finden müssen, alle Funktionen, alle Befehle und überall in jedem public steht mal ein fitzelchen Code von dem System xD
    Kein Wunder also, dass soviele Skripte verbuggt sind, wie will man da auch irgendwas finden.


    Deshalb posten hier auch so viele Menschen 500 Zeilen Code und sagen, ja wo ist denn da der Fehler, bla bla funktioniert nicht.


    Was wäre ein besserer Ansatz?
    So, hier kommt jetzt das Wichtige.
    Man packt ein einzelnes System in ein Include.


    Und damit meine ich nicht nur den Hauptteil des Systems, sondern ALLES.


    Und um noch einen drauf zu setzen, macht sowas:



    Hier sehen wir sehr viel static.
    Das hat mehrere Gründe:


    • static ist nur im Include verfügbar. Das heißt es ist sichergestellt, dass diese Variable NUR dort verändert wird.
      Sprich, gibt es ein Fehler mit dem System, MUSS er dort zu finden sein.
    • Ein weiterer Vorteil ist, dass man einfache Namen verwenden kann und sich nicht darum kümmern muss, dass diese in anderen Include auch nochmal verwendet werden.
      Da die Variablen ja immer für jedes Include abgegrenzt sind. Selbiges gilt für Funktionen, die man als static deklariert.
      PS: Nur globale Variablen im Include static machen, nicht Lokale!! Das wäre etwas völlig Anderes.
    • Es sollte nur mit Callbacks und Hooks gearbeitet werden, die alle in dem Include landen und dort ALLES gesteuert wird, jede Logik.


    Denn wenn man dann einen Fehler hat, weiß man genau, wo man suchen muss.


    Zusammenfassung
    Weg von der Trennung von Bezeichnungen, wie new, public, stock...
    Diese Trennung bringt rein gar nichts, man muss die LOGIK in einem Gamemode trennen.


    Dafür eigenen sich Includes ideal.


    Es sind im Endeffekt auch nur .pwn Dateien, die ihr mit Pawno schreiben könnt.
    Und kompiliert, wird nur das Gamemode.


    Zusätzliche Informationen:
    Schneller & strukturierter skripten


    Es ist auch nicht notwendig, dass ihr ein Selfmade anfangt und das dann konsequent macht (obwohl das ser sinnig wäre).
    Ihr könnt auch anfangen neue Systeme, die ihr in ein GF implementiert, versucht so umzusetzen.


    In diesem Sinne, ich hoffe ich sehe bald mehr Leute die das nutzen und schönere Fragen in der Scripting Base.
    Mit freundlichen Grüßen
    Euer Kalle

    Ich hoffe mir kann jemand sagen wo das Problem ist, danke

    Du erwartest jetzt, dass wir 525 Zeilen schlechten Code durcharbeiten, um dein Problem zu finden.


    Wir wissen nicht, was für Werte die einzelnen Variablen haben, inwiefern OnPlayerDeath da eine entscheidende Rolle spielt etc pp.


    Du solltest dir noch mal die Basics anschauen, wie du selbst print-Debugs machen kannst um eigenständig Fehler zu finden und eventuell crashdetect nutzen.


    Zumal solltest du dir Tutorials anschauen, wie man Modular Skriptet bzw genrell mal schauen, wie man das in anderen Sprachen macht.


    Den Code straight runter zu schreiben...sieht 1. Scheiße aus, 2. ist ineffizient und 3. Man findet nix mehr, genau deshalb stehst du jetzt vor deinem Problem.

    Da sein?

    Ja da hast du vollkommen recht, gar nicht auf den Code geachtet haha xD


    Sinnvoller wäre eh sowas:


    C
    ocmd:sb(playerid,params[])
    {
    	new str[6*sizeof(Saveboxs)];
    	for(new i; i<sizeof(Saveboxs); i++)
    	{
    	    format(str,sizeof(str),"%sBox%d\n",string,(i+1));
    	}
    	ShowPlayerDialog(playerid,SBLISTE,DIALOG_STYLE_LIST,"Savebox - Liste",str,"Wählen","");
    	return 1;
    }

    Wenn sie mit dem Thema zu tuen haben, einfach drunter.


    Falls es sich um neue Themen handelt, eröffne einen neuen Thread.


    Bitte nicht privat mit Problemen kommen, das ist nicht der Sinn eines Forums ^^

    Das unten schreib mal so:



    Und das andere schreib so:



    Der Code ist ein richtig gutes Paradebeispiel dafür, wie man es nicht machen sollte haha xD


    Das Problem ist, dass du alle 40 Safeboxen in eine Zeile schreibst und deswegen der crasht.

    Nein, dann würde nur der Compiler crashen, er redet vom Server.


    Crashdetect könnte hier definitiv helfen.


    Deine Abfrage, ob er sich in einem Checkpoint befindet ist auch falsch, weil du nur prüfst ob er sich in einem zufälligen befindet.


    Die Chance, dass der Befehl klappt steht damit bei 1/40 xD

    Mit 2 einfachen Funktionen kannst du das realisieren:



    Und dann kannst du ja einfach abfragen:



    C
    new buchstaben = CountCharsInString(string);
    new zahlen = CountNumbersInString(string);
    if(buchstaben == 2 && zahlen == 3 || buchstaben == 1 && zahlen == 4)
    {
        //Valid
    }

    Ich möchte gerne ein Filterscript erstellen, dass z.B. jeden Tag um 5 Uhr ein restart vom Server kommt

    Also möglich ist das auch wirklich einfach durch ein Filterskript.


    Falls du also noch irgendwas machen magst, bevor der Server Restartet, so könntest du das realisieren:



    Die variance Variable sorgt nur dafür, dass eine Timer Varianz miteinkalkuliert wird und so nicht 2x restartet.

    Kommt darauf an, wie groß dein Skript ist und wie effizient du mit dem Speicher umgehst, aber so wie ich deinen Code sehe, tust du das eben nicht.


    Du kannst Variablen mehrfach verwenden:


    Dadurch kannst du dir also die ganzen anderen Variablen schenken.