Beiträge von ucar

    Worum geht es in diesem Tutorial?
    In diesem Tutorial geht es darum, wie man am besten programmieren kann, damit dein Code übersichtlich bleibt und du später keine Probleme mit dem Script hast.


    Wie fange ich an?
    Wenn du wirklich einen großen Projekt haben willst, musst du erst dein Projekt zeichnen, damit du erst alles in Sicht hast.
    Wie es aussehen soll, worum es geht, die Spawnpositionen, den Server Name, die Sprache, usw. musst du dir erst überlegen und dann starten dein Server zu programmieren.


    Tipps für den Server
    Damit dein Server auch mehr Spieler bekommt sollst du aufjedenfall keine Werbungen in anderen Servern machen/spammen. Poste auf breadfish, oder auf SA-MP official forum.
    Dein Server Name muss du dir gut überlegen. Namen wie "[SUCHE ADMIN] TDM", "CnR [http://www.example.com]", usw. sind nicht gut. Er soll kein Tags und Werbungen enthalten z.B. "The Kills of Deaths" etc. Du musst auch Admins haben, die dein Server überwachen. Stats (Score, Kills etc.) musst du auch selbst verdienen. Das heißt auch du musst für Score arbeiten und nicht auf 999999 ändern. Admins müssen wirklich ihren Rank verdienen. Außerdem sollst du auch dir einen Webseite besorgen. Ein Domain brauchst du auch, wie z.B. tkd-cnr.de


    Die Programmierung
    Oft machen viele Fehler beim programmieren. Benutzt immer die SA-MP Wiki und liest euch was ein bestimmtes Funktion macht, was sie zurückgibt und welche Fehler auftreten können.


    Zuerst müsst Ihr die Unterzeilen immer mit TAB einrücken. Hier sind zwei Beispiele, wie der Unterschied aussieht.
    Sowas sollte man aufjedenfall NICHT tuhen.
    if(IsPlayerInAnyVehicle(playerid))

    {
    SendClientMessage( playerid, RED,"HI");
    }
    So soll es sein.
    if (IsPlayerInAnyVehicle(playerid)) {
    SendClientMessage(playerid, COLOR_RED, "Hallo");
    }


    Auch hier benutzen viele Leute bei manchen Befehlen Fehler Meldungen, die oft vorkommt. Die könnte man in einem Array speichern oder sie definieren.


    Mit Array könnte es so aussehen.
    //ID definieren
    #define ERROR_INVEHICLE 0


    // Array erstellen
    new ErrorMsg[][158] = {
    "{0000FF}You cannot use this command in a vehicle."
    };


    // Ausgeben
    SendClientMessage(playerid, -1, ErrorMsg[ERROR_INVEHICLE]);
    ACHTUNG: Hier muss die Reihenfolge mit ID und Text stimmen, ansonsten kommt ihr nicht mehr weiter.


    Aber man sie auch kürzer machen.
    // Definieren
    #define InVehicle_Error(%0, %1) SendClientMessage(%0, %1, "You cannot use this command in a vehicle")


    // Ausgeben
    if(IsPlayerInAnyVehicle(playerid)) return InVehicle_Error(playerid, -1);
    Wenn ihr so macht, dann habt ihr den Vorteil, um den Text einmal zu ändern. Also wenn du später den Text ändern möchtest musst nur einen Satz ändern, dann wird bei allen Befehlen das gleiche.


    Ich habe auch jemanden gesehen, der sein Code voll mit unnötigen Zeilen verschwendet hat. So sah sein Code aus.
    //OnPlayerConnect


    if(IsPlayerNPC(playerid)) {
    new botname[MAX_PLAYER_NAME];
    GetPlayerName(playerid, botname, sizeof(botname));
    if(!strcmp(botname, "Hans", true)) {
    Eingeloggt[playerid] = true;
    }
    }
    if(IsPlayerNPC(playerid)) {
    new botname[MAX_PLAYER_NAME];
    GetPlayerName(playerid, botname, sizeof(botname));
    if(!strcmp(botname, "Mario", true)) {
    Eingeloggt[playerid] = true;
    }
    }
    if(IsPlayerNPC(playerid)) {
    new botname[MAX_PLAYER_NAME];
    GetPlayerName(playerid, botname, sizeof(botname));
    if(!strcmp(botname, "Peter", true)) {
    Eingeloggt[playerid] = true;
    }
    }
    // usw.
    Man kann natürlich noch kürzer machen. Und zwar einen Array erstellen und dort die Namen schreiben. Außerdem braucht man nicht immer prüfen ob der Spieler ein Bot ist, sondern eine reicht schon. Anschließend kann man auch ein Funktion erstellen, die den Name von playerid zurückgibt.
    // Array definieren
    new BotName[][MAX_PLAYER_NAME] = {
    "Hans",
    "Mario",
    "Peter"
    };


    // OnPlayerConnect
    if(IsPlayerNPC(playerid)) {
    for(new i = 0; i < sizeof(BotName); i++) {
    if(!strcmp(GetName(playerid), BotName, true)) {
    Eingeloggt[playerid] = true;
    break;
    }
    }
    }


    // Funktion
    stock GetName(playerid) {
    new userName[MAX_PLAYER_NAME];
    GetPlayerName(playerid, userName, sizeof(userName));
    return userName;
    }


    Nun kommen zur SA-MP wiki. Wir wollen wissen ob ein Spieler gerade ein Fahrzeug betritt. Dafür müssen wir natürlich OnPlayerStateChange benutzen. Aber es gibt auch OnPlayerEnterVehicle. Wofür ist es? Das können wir auf SA-MP wiki schauen.

    Code
    Dieses Callback wird aufgerufen, wenn ein Spieler beginnt ein Fahrzeug zu betreten. Der Spieler ist also noch nicht im Fahrzeug, wenn OnPlayerEnterVehicle aufgerufen wird.



    Das heißt er wird nur aufgerufen wenn der startet ein Fahrzeug zu betreten, aber er ist noch nicht im Fahrzeug. Das heißt der Spieler könnte F-Taste drücken und dann einen Animation ausführen damit er abbricht. Trotzdem wurde OnPlayerEnterVehicle aufgerufen. Das heißt dieser Callback wird uns nicht mehr weiterbringen.
    Wie schon gesagt, hilft SA-MP wiki immer auf solchen Fällen.


    Ende
    Das wars. Wenn ihr die Regeln behält, wird ihr später keine Probleme haben und ihr wird einen berühmten Server haben. Bei Fragen könnt ihr mir PN schicken. Danke, tschüss.

    Dein Geschwindigtkeit wird nur geprüft wenn du ein Checkpoint betrittst.
    Wenn es immer noch nicht funktioniert, dann liegt das Problem bei If-Abfragen. Gib mal die Werte aus durch Printf.
    //OnPlayerEnterCheckpoint
    printf("Pruefung: %d, CP: %d, Model: %d, isRange: %d", Pruefung[playerid], PruefungCP[playerid], GetVehicleModel(GetPlayerVehicleID(playerid)), IsPlayerInRangeOfPoint(playerid,4.0,1634.9910,-1147.7936,23.6333));
    Auch kmh_anzahl
    printf("KMH: %d", kmh_anzahl);

    Hast du maxnpc in server.cfg hochgestellt?


    Außerdem enthält dein Skript viele unnötige Zeilen die du sparen kannst. Du brauchst nicht jedesmal prüfen ob der playerid ein NPC ist.
    OnPlayerConnect kannst du auch so machen.
    if(IsPlayerNPC(playerid))
    {
    new botname[MAX_PLAYER_NAME];
    GetPlayerName(playerid, botname, sizeof(botname));
    if(!strcmp(botname, "BANK1", true) || !strcmp(botname, "BANK2", true) || !strcmp(botname, "BANK3", true) || !strcmp(botname, "BANK4", true) || !strcmp(botname, "BANK5", true) || !strcmp(botname, "bankbody1", true) || !strcmp(botname, "bankbody2", true))
    {
    Eingeloggt[playerid]=1;
    }
    }
    oder die Namen in einem Array speichern und von dort mit for-Schleife auslesen.
    new BotName[][MAX_PLAYER_NAME] = {
    "botname",
    "etc",
    ...
    };


    if(IsPlayerNPC(playerid)) {
    new botname[MAX_PLAYER_NAME];
    GetPlayerName(playerid, botname, sizeof(botname));
    for(new i = 0; i < sizeof(BotName); i++) {
    if(!strcmp(BotName[i], botname, true)) {
    Eingeloggt[playerid] = true;
    }
    }
    }
    Gleiche bei OnPlayerSpawn.

    Eigentlich sollte es ganz normal funktionieren. Du hast dich wahrscheinlich wie Mr.Reese schon gesagt hat verguckt. Wenn nicht probier mal, was GetPlayerState(playerid) ausgibt. Vielleicht warst du nicht wirklich der Fahrer. Einfach vor If-Abfrage die folgende Funktion ausführen.
    printf("PlayerState: %d", GetPlayerState(playerid));
    Also insgesamt sollte es so aussehen.
    printf("PlayerState: %d", GetPlayerState(playerid));
    if (GetPlayerState(playerid) != PLAYER_STATE_DRIVER) //Sollte eigentlich abfragen, ob der Spieler der Fahrer des Fahrzeugs ist
    return SendErrorMessage(playerid, "Du bist nicht der Fahrer dieses Fahrzeugs.");