Checkpoints abfahren

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 Morgen,


    Wie ich immer wieder merke gibt es noch sehr viele Leute die nicht wissen wie man ein Script erstellt bei denen Checkpoints
    abgefahren werden (Die roten Kreise falls jemand nicht genau weiss was das ist ;] ), sei es nun für Jobs oder Rennen.
    Für alle anderen die meinen sie wissen wie man so etwas erstellt,schaut euch das Tutorial trotzdem an.Denn am Beispiel von diesem Post hier des Müllabfuhrscript ist wieder mal deutlich gezeigt wie man es eigentlich nicht machen sollte.
    Es ist unglaublich unübersichtlich mit dem extrem langen Code unter OnPlayerCheckpoint,außerdem sehr schlecht zu
    bearbeiten falls man irgendwo in der Mitte einen neuen Checkpoint hinzufügen möchte oder sonst wo.


    Wer soll sich denn bitte bei diesem Code zurecht finden:



    public OnPlayerEnterCheckpoint(playerid) {
    new trinkgeld = random(85); // Betrag für das Trinkgeld, lässt sich beliebig ändern! ( Zufalls Betrag )
    new string[256];
    if(Checkpoint[playerid] == 1)
    {
    SendClientMessage(playerid, COLOR_RED, "Muell aufgeladen, weiter!");
    GivePlayerMoney(playerid, trinkgeld);
    format(string, sizeof(string), "** Du hast %d$ Trinkgeld bekommen!",trinkgeld);
    SendClientMessage(playerid, COLOR_GREEN, string);
    DisablePlayerCheckpoint(playerid);
    SetPlayerCheckpoint(playerid, -89.2432,-1189.7782,2.3241, 5.0);
    Checkpoint[playerid] = 2;
    }
    else if(Checkpoint[playerid] == 2)
    {
    SendClientMessage(playerid, COLOR_RED, "Muell aufgeladen, weiter!");
    GivePlayerMoney(playerid, trinkgeld);
    format(string, sizeof(string), "** Du hast %d$ Trinkgeld bekommen!",trinkgeld);
    SendClientMessage(playerid, COLOR_GREEN, string);
    DisablePlayerCheckpoint(playerid);
    SetPlayerCheckpoint(playerid, -63.3734,-1588.5732,3.1782, 5.0);
    Checkpoint[playerid] = 3;
    }
    else if(Checkpoint[playerid] == 3)
    {
    SendClientMessage(playerid, COLOR_RED, "Muell aufgeladen, weiter!");
    GivePlayerMoney(playerid, trinkgeld);
    format(string, sizeof(string), "** Du hast %d$ Trinkgeld bekommen!",trinkgeld);
    SendClientMessage(playerid, COLOR_GREEN, string);
    DisablePlayerCheckpoint(playerid);
    SetPlayerCheckpoint(playerid, 220.8943,-1393.5308,52.1264, 5.0);
    Checkpoint[playerid] = 4;
    }
    else if(Checkpoint[playerid] == 4)
    {
    ...
    }



    Ich zeig euch mal wie Ich es besser machen würde.Gibt wahrscheinlich noch andere Varianten,aber so hab ich
    es für mich persöhnlich eingepräkt.
    Als erstes einmal hab ich mir alle Checkpoint Koordinaten aus dem Script rausgeschrieben:


    Wunderbar oder nicht?
    Für sowas erstelle ich immer ein enum,ist mit dem Array vergleichbar nur besser :].
    Man kann verschiedene Typen haben und direkt über einen Namen auf den Index zugreifen (Hoffe ich hab das jetzt nicht völlig falsch erklärt.DMA kann ja sein Wissen hier zur schau stellen :P)
    Nun gut,das enum brauch X,Y,Z und die Größe des Checkpoints als Float Daten,deshalb sieht es bei mir so aus:

    enum e_Muell {
    Float:M_fX,
    Float:M_fY,
    Float:M_fZ,
    Float:M_fRad
    }

    Ich kennzeichnen ein enum immer mit e_ vor dem eigentlichen Namen.
    Float:M_fX,
    M_ = steht bei mir für e_Müll,um zu wissen von welchem enum und um verwechselungen auzuschließen falls ein Variablenname doppelt vergeben wird.
    f = steht bei mir für Float,um zu wissen welcher Typ es ist
    Jetzt müssen wir das enum noch mit Daten füllen,wieso also nicht mit den Checkpoints die wir aufgeschrieben haben.
    Das ganze sieht dann also so aus:

    enum e_Muell {
    Float:M_fX,
    Float:M_fY,
    Float:M_fZ,
    Float:M_fRad
    }


    new
    Muellabfuhr_Stationen[][e_Muell] = {
    {-74.2252, -1128.7936, 1.6359, 5.0},
    {-89.2432, -1189.7782, 2.3241, 5.0},
    {-63.3734, -1588.5732, 3.1782, 5.0},
    {220.8943, -1393.5308, 52.1264, 5.0},
    {169.0361, -1356.8065, 69.8208, 5.0},
    {263.5524, -1341.0842, 53.7643, 5.0},
    {871.9646, -864.5255, 77.2742, 5.0},
    {935.7687, -835.7352, 94.4455, 5.0},
    {1496.5879, -698.0237, 94.5207, 5.0},
    {1001.1724, -935.0218, 41.9509, 5.0},
    {-546.9002, -488.6077, 25.2961, 5.0}
    };

    Jetzt brauchen wir noch Variablen die Speichern, ob der Spieler gerade der Muellfahrer ist und
    bei welchem Checkpoint er sich zur Zeit befindet.



    enum e_PlayerMuellInfo {
    bool:pmi_bAktiv,
    pmi_Checkpoint
    }
    new Muellmann[MAX_PLAYERS][e_PlayerMuellInfo];


    Gut,den Grundstein haben wir jetzt gelegt.Jetzt folgt der eigentliche Code.
    Zuerst brauchen wir einen Start,ich nehme einen Command.



    public OnPlayerCommandText(playerid, cmdtext[]) {
    if (strcmp("/starten", cmdtext, true, 8) == 0) {
    if(!Muellmann[playerid][pmi_bAktiv]) {
    new
    vehicleid = GetPlayerVehicleID(playerid),
    model = GetVehicleModel(vehicleid);
    if(model == 408) { // Text ab hier!
    Muellmann[playerid][pmi_Checkpoint]=0;
    Muellmann[playerid][pmi_bAktiv]=true;
    SendClientMessage(playerid, COLOR_LIGHTGREEN, "Muellabfuhr gestartet, fahre nun zu den einzelnen Haeusern!");
    SetPlayerCheckpoint(playerid,Muellabfuhr_Stationen[0][M_fX],Muellabfuhr_Stationen[0][M_fY],Muellabfuhr_Stationen[0][M_fZ],Muellabfuhr_Stationen[0][M_fRad]);
    }
    else {
    SendClientMessage(playerid, COLOR_RED, "Du bist nicht im Muellwagen!");
    }
    }
    else {
    SendClientMessage(playerid, COLOR_RED, "Es laeuft schon eine Mission!");
    }
    return 1;
    }
    return 0;
    }

    Zuerst müssen wir den aktuellen Checkpoint des Spielers auf 0 setzten,denn man startet ja ganz von vorne und nicht irgendwo
    Anders (pmi_Checkpoint).Danach wird die Variable auf true / 1 gesetzt,die sagt ob ein Spieler gerade Muellmann ist (pmi_bAktiv) .
    Die Nachricht danach ist eher unwichtig.Doch danach wird es wieder interessant.
    Wir setzten den Checkpoint des Spielers.
    Der Checkpoint wird für den Spieler auf die Koordinaten gesetzt des ersten Eintrages (Ist allerdings der Index 0,deshalb [0] im Muellabfuhr_Stationen Enum )
    Muellabfuhr_Stationen[0][M_fX],Muellabfuhr_Stationen[0][M_fY],Muellabfuhr_Stationen[0][M_fZ],Muellabfuhr_Stationen[0][M_fRad]


    Jetzt haben wir den ersten Checkpoint.Doch wie geht es weiter?Bewegen wir uns nun zum OnPlayerEnterCheckpoint() Callback.
    Der bisherige Code sieht übrigens so aus:

    #include <a_samp>


    #define COLOR_LIGHTGREEN 0x86FF59FF
    #define COLOR_RED 0xFF0000FF
    #define COLOR_GREEN 0x00CA00FF


    enum e_PlayerMuellInfo {
    bool:pmi_bAktiv,
    pmi_Checkpoint
    }
    new Muellmann[MAX_PLAYERS][e_PlayerMuellInfo];


    enum e_Muell {
    Float:M_fX,
    Float:M_fY,
    Float:M_fZ,
    Float:M_fRad
    }


    new
    Muellabfuhr_Stationen[][e_Muell] = {
    {-74.2252, -1128.7936, 1.6359, 6.0},
    {-89.2432, -1189.7782, 2.3241, 6.0},
    {-63.3734, -1588.5732, 3.1782, 6.0},
    {220.8943, -1393.5308, 52.1264, 6.0},
    {169.0361, -1356.8065, 69.8208, 6.0},
    {263.5524, -1341.0842, 53.7643, 6.0},
    {871.9646, -864.5255, 77.2742, 6.0},
    {935.7687, -835.7352, 94.4455, 6.0},
    {1496.5879, -698.0237, 94.5207, 6.0},
    {1001.1724, -935.0218, 41.9509, 6.0},
    {-546.9002, -488.6077, 25.2961, 6.0}
    };



    public OnFilterScriptInit()
    {
    print("-] Tutorial - Checkpoints abfahren [-");
    CreateVehicle(408,-535.8450,-502.6665,26.0667,358.0911,1,1,-1);
    return 1;
    }


    public OnPlayerCommandText(playerid, cmdtext[]) {
    if (strcmp("/starten", cmdtext, true, 8) == 0) {
    if(!Muellmann[playerid][pmi_bAktiv]) {
    new
    vehicleid = GetPlayerVehicleID(playerid),
    model = GetVehicleModel(vehicleid);
    if(model == 408) {
    Muellmann[playerid][pmi_Checkpoint]=0;
    Muellmann[playerid][pmi_bAktiv]=true;
    SendClientMessage(playerid, COLOR_LIGHTGREEN, "Muellabfuhr gestartet, fahre nun zu den einzelnen Haeusern!");
    SetPlayerCheckpoint(playerid,Muellabfuhr_Stationen[0][M_fX],Muellabfuhr_Stationen[0][M_fY],Muellabfuhr_Stationen[0][M_fZ],Muellabfuhr_Stationen[0][M_fRad]);
    }
    else {
    SendClientMessage(playerid, COLOR_RED, "Du bist nicht im Muellwagen!");
    }
    }
    else {
    SendClientMessage(playerid, COLOR_RED, "Es laeuft schon eine Mission!");
    }
    return 1;
    }
    return 0;
    }
    public OnPlayerEnterCheckpoint(playerid) {
    // Hier haben wir noch nix eingefügt vom Tutorial,das kommt erst ;)
    return 1;
    }


    Jetzt sollten wir als erstes einen Check einfügen in OnPlayerEnterCheckpoint,der überprüft ob wir einen Muellmann haben
    der durch den Checkpoint gelaufen/gefahren ist.Dafür haben wir ja unsere Variable pmi_bAktiv.

    public OnPlayerEnterCheckpoint(playerid) {
    if(Muellmann[playerid][pmi_bAktiv]) {
    }
    return 1;
    }

    Wunderbar!
    Jetzt kann es direkt weiter gehen.Wir wissen jetzt,dass der Spieler durch einen Checkpoint gelaufen ist und Müllmann ist.
    Er hat also einen Checkpoint betreten,von daher müssen wir seine Variable erhöhen die weiss bei welchem Checkpoint er sich befindet,dafür nehmen wir :
    Muellmann[playerid][pmi_Checkpoint]++;
    Außerdem müssen wir den aktuellen Checkpoint verschwinden lassen,das machen wir mit Hilfe der Funktion DisablePlayerCheckpoint().



    public OnPlayerEnterCheckpoint(playerid) {
    if(Muellmann[playerid][pmi_bAktiv]) {
    Muellmann[playerid][pmi_Checkpoint]++; // ++ ist das gleiche wie +1
    DisablePlayerCheckpoint(playerid);
    }
    return 1;
    }


    Doch jetzt passiert nix beim durchfahren einen Checkpoints außer,dass der Checkpoint verschwindet durch den man gefahren ist.Aber noch wird kein neuer herbei gezaubert.Jetzt brauchen wir den Wert der sich hinter Muellmann[playerid][pmi_Checkpoint] verbirgt und den Vorteil ausmacht hinter dieser Variante des Scripts.
    Um das ganze jetzt leichter für die meisten darzustellen,benutzte ich eine Hilfsvariable,die den Wert enthält des Checkpoints den der Spieler erreicht hat.

    new playercp = Muellmann[playerid][pmi_Checkpoint];

    Jetzt brauchen wir nur noch bei SetPlayerCheckpoint();anstatt wie vorher bei /starten als Index nicht 0 nehmen ,sondern playercp.
    Denn wir brauchen ja den nächsten Eintrag aus den Muellabfuhr_Stationen.



    public OnPlayerEnterCheckpoint(playerid) {
    if(Muellmann[playerid][pmi_bAktiv]) {
    Muellmann[playerid][pmi_Checkpoint]++;
    DisablePlayerCheckpoint(playerid);
    new
    playercp = Muellmann[playerid][pmi_Checkpoint];
    SetPlayerCheckpoint(playerid,Muellabfuhr_Stationen[playercp][M_fX],Muellabfuhr_Stationen[playercp][M_fY],Muellabfuhr_Stationen[playercp][M_fZ],Muellabfuhr_Stationen[playercp][M_fRad]);
    return 1;
    }
    return 1;
    }


    Dieser kleine Code macht schon die meiste Arbeit,die wie im Beispiel oben durch 100 von Zeilen gemacht wird.
    Das einzige was noch fehlt,ist zu prüfen ob der Spieler den letzten Checkpoint erreicht hat.
    Das sollte aber kein Problem sein für jemand den die Grundlagen beherrscht.


    public OnPlayerEnterCheckpoint(playerid) {
    if(Muellmann[playerid][pmi_bAktiv]) {
    Muellmann[playerid][pmi_Checkpoint]++;
    DisablePlayerCheckpoint(playerid);
    new
    playercp = Muellmann[playerid][pmi_Checkpoint];
    if(playercp == sizeof(Muellabfuhr_Stationen)) {
    Muellmann[playerid][pmi_bAktiv]=false;
    }
    else {
    SetPlayerCheckpoint(playerid,Muellabfuhr_Stationen[playercp][M_fX],Muellabfuhr_Stationen[playercp][M_fY],Muellabfuhr_Stationen[playercp][M_fZ],Muellabfuhr_Stationen[playercp][M_fRad]);
    }
    return 1;
    }
    return 1;
    }
    Wenn also der Spieler den Checkpoint erreicht,der gleich dem Wert der Größe bzw der Anzahl von Checkpoints von Muellabfuhr_Stationen ist,wissen wir,dass der
    letzte Checkpoint erreicht ist.Ist der letzte Checkpoint erreicht,können / sollten und brauchen wir keinen neuen Checkpoint setzten.
    Wir müssen nur noch die Variable auf false / 0 setzten,die darüber Info gibt ob der Spieler Muellmann ist.


    Jetzt fehlt nur noch ein feinschliff mit Fahrzeug-Check,Sound,Geld,usw. ,denn die ganze Arbeit ist mit dem winzigem Code bereits getan.
    Natürlich sollte man noch einen Check einfügen der prüft,ob der Spieler sich immernoch in einem Müllwagen befindet.Doch soviel Eigeninziative sollte wohl noch vorhanden sein.
    public OnPlayerEnterCheckpoint(playerid) {
    if(Muellmann[playerid][pmi_bAktiv]) {
    Muellmann[playerid][pmi_Checkpoint]++;
    DisablePlayerCheckpoint(playerid);
    new
    playercp = Muellmann[playerid][pmi_Checkpoint];
    if(playercp == sizeof(Muellabfuhr_Stationen)) {
    Muellmann[playerid][pmi_bAktiv]=false;
    // Extra code
    SendClientMessage(playerid, COLOR_GREEN, "Super Arbeit,du hast die Stadt hervorragend gesäubert");
    GivePlayerMoney(playerid, 2000);
    }
    else {
    new
    String[128];
    PlayerPlaySound(playerid,1056,0.0,0.0,0.0);
    format(String,sizeof(String),"Weiter so,du hast es fasst geschafft ! (%d / %d)",playercp,sizeof(Muellabfuhr_Stationen));
    SendClientMessage(playerid,COLOR_LIGHTGREEN,String);
    SetPlayerCheckpoint(playerid,Muellabfuhr_Stationen[playercp][M_fX],Muellabfuhr_Stationen[playercp][M_fY],Muellabfuhr_Stationen[playercp][M_fZ],Muellabfuhr_Stationen[playercp][M_fRad]);
    }
    return 1;
    }
    return 1;
    }
    Wer trotzdem bei der Anderen Methode bleiben möchte,nur zu.


    Abschließen lässt sich nicht viel sagen,
    Hab das Tutorial jetzt fix herrunter geschrieben ohne großartig auf Wortwahl usw. zu achten.Sollte etwas unverständlich sein oder Fehler enthalten (Was natürlich möglich ist) könnt ihr das gerne posten.


    //Edit 27-03-2015: Download entfernt (Code ist weg :[ )

  • Muss schon sagen,super Tutorial,alles super erklärt ;)

    Sie brauchen Hilfe bei Linux oder Windows Servern? Wissen nicht, wie man am besten ein Forum o. a. installiert? Dann schreiben Sie mir eine PN und ich versuche Ihnen zu helfen!

  • geil gemacht, aber iwie findcih das andere leichter^^ aber hab mir das dcmd und sscanf tut auch paar mal durchgelesen um es zu verstehn^^ und jetzt kann ich immer noch nur sscanf :D aber giel gemacht und immer gut auf farbe im text geachtet, macht das lesen leichter

  • do.de - Domain-Offensive - Domains für alle und zu super Preisen
  • Als ich das Script angeschaut hatte, dachte ich auch, dass es funktioniert, aber nicht schön ist...
    Arrays sind in so einem Fall besonders geschickt ;)


    Ich scripte NICHT mehr, ich möchte mit NIEMANDEM einen Server aufmachen habe auch NICHTS mehr mit LoH zu tun, also lasst es mit den PNs!

  • Besteht die Möglichkeit, dass man in das Enum auch Text einfügt ?
    Ich benutze das System für Busfahrer und möchte die Haltestellen-Namen einfügen.


    enum e_Muell {
    Float:M_fX,
    Float:M_fY,
    Float:M_fZ,
    Float:M_fRad;
    Text:M_tHaltestelle // Irgentwie so was. Soll aber für den ClientMessage sein
    }


    new
    Muellabfuhr_Stationen[][e_Muell] = {
    {-74.2252,-1128.7936,1.6359,5.0 // Hier irgentwo de Namen},
    {-89.2432,-1189.7782,2.3241,5.0},
    {-63.3734,-1588.5732,3.1782,5.0},
    {220.8943,-1393.5308,52.1264,5.0},
    {169.0361,-1356.8065,69.8208, 5.0},
    {263.5524,-1341.0842,53.7643, 5.0},
    {871.9646,-864.5255,77.2742, 5.0},
    {935.7687,-835.7352,94.4455, 5.0},
    {1496.5879,-698.0237,94.5207, 5.0},
    {1001.1724,-935.0218,41.9509, 5.0},
    {-546.9002,-488.6077,25.2961, 5.0}
    };

  • Dürfte schon funktionieren. Probiers mal so:
    enum e_Muell {
    Float:M_fX,
    Float:M_fY,
    Float:M_fZ,
    Float:M_fRad;
    M_Msg[128],
    }


    new
    Muellabfuhr_Stationen[][e_Muell] = {
    {-74.2252,-1128.7936,1.6359,5.0,"Lol1337"},
    {-89.2432,-1189.7782,2.3241,5.0,"I am 1337"},
    {-63.3734,-1588.5732,3.1782,5.0,"I hope this will work"},
    {220.8943,-1393.5308,52.1264,5.0,"this is a funny day"},
    {169.0361,-1356.8065,69.8208, 5.0,"..."},
    {263.5524,-1341.0842,53.7643, 5.0,"..."},
    {871.9646,-864.5255,77.2742, 5.0,"..."},
    {935.7687,-835.7352,94.4455, 5.0,"..."},
    {1496.5879,-698.0237,94.5207, 5.0,"..."},
    {1001.1724,-935.0218,41.9509, 5.0,"..."},
    {-546.9002,-488.6077,25.2961, 5.0,"..."}
    };


    public OnPlayerEnterCheckpoint(playerid) {
    new
    playercp = Muellmann[playerid][pmi_Checkpoint];
    SendClientMessage(playerid, 0xFFAAAAFF, MuellAbfuhr_Stationen[playercp][M_Msg]);
    return 1;
    }


    Dürfte so funktionieren, habs nicht compilet, nicht getestet, probiers einfach mal aus.

  • Erstmal vielen dank für das tolle TUT, GoldKiller ;).


    Jetzt habe ich aber eine Frage: Wie baue ich da ein Random ein? Sodass die CPs im Array per zufall erscheinen?


    Hoffe auf schnelle Antwort ;).


    Mit freundlichen Grüßen
    Spike

  • hallo habe irgendwie ein fehler der zeigt nie den 2 Checkpoint an kann mir jemmand helfen ?


    new
    Muellabfuhr_Stationen[][e_Muell] = {
    {1245.5654, -1716.0409, 12.9469,5.0},//linie 1-1
    {1499.5140, -1734.5255, 12.9541,5.0},//linie 1-2
    {2062.5239, -1755.1163, 12.9630,5.0},//linie 1-3
    {2078.4392, -1916.1873, 12.8876,5.0},//linie 1-4
    {1823.8972, -1884.5686, 12.8971,5.0},//linie 1-5
    {1854.7596, -1390.8596, 12.9502,5.0},//linie 1-6
    {1446.8234, -1031.1287, 23.2122,5.0},//linie 1-7
    {1190.7302, -935.2141, 42.3084,5.0},//linie 1-8
    {536.1373, -1243.3295, 16.1194,5.0},//linie 1-9
    {440.4330, -1525.9337, 29.7305,5.0},//linie 1-10
    {953.4757, -1797.4747, 13.6678,5.0}//linie 1-11


    };
    kann das an 0.3 liegen ?


    Einmal editiert, zuletzt von Unterbilker ()

  • do.de - Domain-Offensive - Domains für alle und zu super Preisen