[ Problem ] Mit Checkpoints arbeiten(ohne streamer)

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
  • Hey Leute :D


    Hab wieder ein Problemchen :) Folgendes: Ich versuche einen Kurs für eine Fahrprüfung auf nem ReallifeServer zu erstellen.
    Hab alle Checkpoint Coords & kenn auch die drei Befehle, die man verwendet wenn man nicht mit einem Streamer(Wie dann zB SetPlayerDynamicCP)
    arbeitet:



    SetPlayerCheckpoint(playerid,-2044.5792,-126.9101,35.2586,3.0);
    IsPlayerInCheckpoint(playerid)
    DisablePlayerCheckpoint(playerid)

    (RaceCPs ausgeschlossen)


    Hab schon relativ erfolglos versucht diese Befehle richtig in Szene zu setzen & auch tutorials angeschaut in denen die Verwendung dieser Befehle erklärt wird -> Folge, es funktioniert trotzdem nicht so wie ich das will


    Hab mal angefangen und eine Variable gemacht, die mit jedem CP erhöht wird:

    new FS1[MAX_PLAYERS];


    Dann hab ich in dem Befehl den man für den start der Fahrprüfung verwendet diese Variable auf "1" gesetzt & einen CP erstellt:

    SetPlayerCheckpoint(playerid,-2055.2590,-126.5977,35.3067,3.0);
    FS1[playerid] = 1;


    So weit so gut, nun hab ich eif bei
    public OnPlayerEnterCheckpoint(playerid)
    folgendes gemacht(hab ich aus diversen Tutorials):

    //->Fahrschule
    if(FS1[playerid] == 1)
    {
    SetPlayerCheckpoint(playerid,-2090.0313,-142.8927,35.3203,3.0);//p1
    FS1[playerid] = 2;
    }
    if(FS1[playerid] == 2)
    {
    SetPlayerCheckpoint(playerid,-2085.2576,-164.2339,35.3203,3.0);//p2
    FS1[playerid] = 3;
    }
    if(FS1[playerid] == 3)
    {
    SetPlayerCheckpoint(playerid,-2084.8738,-259.3287,35.3203,3.0);//p3
    FS1[playerid] = 4;
    }
    if(FS1[playerid] == 4)
    {
    SetPlayerCheckpoint(playerid,-2088.5686,-278.3327,35.3203,3.0);//p4
    FS1[playerid] = 5;
    }
    if(FS1[playerid] == 5)
    {
    SetPlayerCheckpoint(playerid,-2079.7358,-278.3954,35.3203,3.0);//p5
    FS1[playerid] = 6;
    }
    if(FS1[playerid] == 6)
    {
    SetPlayerCheckpoint(playerid,-2066.9626,-262.5959,35.3274,3.0);//p6
    FS1[playerid] = 7;
    }
    if(FS1[playerid] == 7)
    {
    SetPlayerCheckpoint(playerid,-2054.5481,-278.3344,35.3274,3.0);//p7.1
    SetPlayerCheckpoint(playerid,-2050.3645,-278.4077,35.3274,3.0);//p7.2
    FS1[playerid] = 8;
    }
    if(FS1[playerid] == 8)
    {
    SetPlayerCheckpoint(playerid,-2025.1770,-270.6463,35.3274,3.0);//p8
    FS1[playerid] = 9;
    }
    if(FS1[playerid] == 9)
    {
    SetPlayerCheckpoint(playerid,-2057.9827,-245.1774,35.3203,3.0);//p9
    FS1[playerid] = 10;
    }
    if(FS1[playerid] == 10)
    {
    SetPlayerCheckpoint(playerid,-2057.7407,-165.9292,35.3203,3.0);//p10
    FS1[playerid] = 11;
    }
    if(FS1[playerid] == 11)
    {
    SetPlayerCheckpoint(playerid,-2044.2831,-172.5241,35.3274,3.0);//p11
    FS1[playerid] = 12;
    }
    if(FS1[playerid] == 12)
    {
    SetPlayerCheckpoint(playerid,-2045.1210,-221.3237,35.3274,3.0);//p12
    FS1[playerid] = 13;
    }
    if(FS1[playerid] == 13)
    {
    SetPlayerCheckpoint(playerid,-2034.0541,-209.9391,35.3203,3.0);//p13
    FS1[playerid] = 14;
    }
    if(FS1[playerid] == 14)
    {
    SetPlayerCheckpoint(playerid,-2038.9460,-153.4344,35.3203,3.0);//p14
    FS1[playerid] = 15;
    }
    if(FS1[playerid] == 15)
    {
    SetPlayerCheckpoint(playerid,-2038.9485,-215.7825,35.3203,3.0);//p15
    FS1[playerid] = 16;
    }
    if(FS1[playerid] == 16)
    {
    SetPlayerCheckpoint(playerid,-2044.5792,-126.9101,35.2586,3.0);//p16
    FS1[playerid] = 17;
    }
    if(FS1[playerid] == 17)
    {
    //if Führerschein bestanden
    }
    return 1;


    Problem: Er springt eif durch bis zu letzten CP - hab auch schon einige andere Wege erfolglos getestet, aber da diesen hier wohl die meisten kennen hab ich den für mein Problem genommen.


    Was muss ich anders machen bzw. verbessern?
    Danke für eure Hilfe & fürs Lesen :DD


    Mfg

    THE STORM941


  • Also du machst es in meinen Augen ziemlich umständlich und ressourcenfressend


    #define MAX_DSPOINTS 10


    enum fPoints
    {
    Float:x,
    Float:y,
    Float:z,
    Float:size,
    };
    new DrivingSchoolPoints[MAX_DSPOINTS][fPoints] ={
    {83.2499,-112.4267,0.5920,5.0},
    {76.4198,-93.9598,0.3915,5.0},
    {64.6095,-70.2833,0.3149,5.0},
    {45.9960,-43.9335,0.6408,5.0},
    {23.3448,-20.6985,2.8386,5.0},
    {-14.2797,-17.2095,2.8226,5.0},
    {-25.9122,-37.3183,2.8226,5.0},
    {-36.4352,-66.5518,2.8226,5.0},
    {-44.8992,-96.2774,2.8226,5.0},
    {-53.1776,-126.4076,2.8194,5.0}
    };


    new DSPoint[MAX_PLAYERS char],
    str[35];



    if (strcmp("/start", cmdtext, true, 6) == 0)
    {
    DSPoint[playerid] = 0;
    SetPlayerCheckpoint(playerid,DrivingSchoolPoints[0][x],DrivingSchoolPoints[0][y],DrivingSchoolPoints[0][z],DrivingSchoolPoints[0][size]);
    return 1;
    }


    public OnPlayerEnterCheckpoint(playerid)
    {
    if(IsPlayerInRangeOfPoint(playerid,DrivingSchoolPoints[DSPoint[playerid]][size],DrivingSchoolPoints[DSPoint[playerid]][x],DrivingSchoolPoints[DSPoint[playerid]][y],DrivingSchoolPoints[DSPoint[playerid]][z]) && IsPlayerInAnyVehicle(playerid)){
    if(DSPoint[playerid] == (MAX_DSPOINTS-1)){
    DisablePlayerCheckpoint(playerid);
    return SendClientMessage(playerid,-1,"Du hast es geschaft");
    }else{
    DSPoint[playerid]++;
    SetPlayerCheckpoint(playerid,DrivingSchoolPoints[DSPoint[playerid]][x],DrivingSchoolPoints[DSPoint[playerid]][y],DrivingSchoolPoints[DSPoint[playerid]][z],DrivingSchoolPoints[DSPoint[playerid]][size]);
    strdel(str,0,sizeof(str));
    format(str,35,"Du bist in Checkpoint %d",DSPoint[playerid]);
    return SendClientMessage(playerid,-1,str);
    }
    }
    return 1;
    }


    Ich hab dir mal sowas schnell erstellt zum testen musst du dir nur kurz ein command erstellen um ein auto zu spawnen.
    Den string brauchst du nicht zu beachten ist nur eine kleine spielerei wie die formatierung des textes und sendens bei OnPlayerEnterCheckpoint(playerid).


    Nun gut zur erklärung als aller erstes habe ich ein enum erstellt mit den folgenden werten welche im array als index verwendet werden.
    x , y, z und die größe size daher hat dieses 2 dimensionales array 4 Spalten so kann man sich dies vorstellen es geht natürlich auch nochmal anders mit der verwendung des arrays
    ohne enum da es alles floats sind:



    new Float:DrivingSchoolPoints[MAX_DSPOINTS][4] ={
    ...
    }


    Nun gut das #define definiert die anzahl an einträge in dem array dies kann man auch weg lassen nur meiner meinung nach ist mit sowas lieber als
    immer sizeof(DrivingSchoolPoints) wo er sich den wert her holt das #define hat daher ein konstanten Wert.
    DSPoint[MAX_PLAYERS char];
    hast du auch verwendet in ihr wird der jeweilige punkt bei dem er ist gespeichert das char sorgt dafür das das array nicht so groß ist kann jedoch nicht wie normale integer
    sehr hohe negative bis sehr hohe positive werte speichern sondern nur werte von 0 - 256 daher verbraucht es auch weniger bytes eine Zelle kostet somit 8 Bits einem Byte
    das bedeutet er könnte vom internationalen Zeichen eins wiedergeben.


    Bei dem command /start setze ich das 1D array DSPoint[playerid], welches für den spieler definiert ist auf 0 sollte man dan im gamemode auch machen wenn ein spieler connectet
    um so gesehene Tricks(Bugs) zu vermeiden zu dem wird hier der erste checkpoint erstellt ich man kann dort natürlich wo das 0 steht auch DSPoint[playerid] einfügen es beinhaltet
    den wert 0 jetzt daher macht es zu dem zeitpunkt auch kein unterschied.


    Nun kommen wir zu dem Callback OnPlayerEnterCheckpoint(playerid) welches aufgerufen wird wenn ein spieler ihrgend ein checkpoint betritt.
    Dazu soll der spieler in einem auto sein und an der jeweiligen position sich befinden für den radius würde hier der radius des checkpoints eingestellt macht ja auch sinn
    und das restliche erklärt sich ja von selbst das && gibt die zusätzlich bedingung das er am punkt sein muss und in einem auto.
    Hier wird nun nicht wie vorher 0 eingesetzt man hat ja natürlich mehr checkpoints und will auch durch alle durch kommen sondern der wert der sich dann hinter
    DSPoint[playerid] verbirgt. Das bedeutet sollte dieser 9 Sein so weiß das skript ok hier ist ende daher auch der text. So nun haben wir in der zweiten if abfrage jedoch
    (MAX_DSPOINTS-1) stehen der wert für MAX_DSPOINTS ist ja 10 warum dann nicht einfach auch das system umändert das es mit DSPoint[playerid] übereinstimmt.
    Das in der klammer hat den wert 9 den man letzt endlich hat da die array von 0 an beginnen 0, 1, 2, 3 .. 9 sind jedoch 10 Werte und hier wird vergliechen ob MAX_DSPOINTS
    der dne wert 10 hat -1 dem von DSPoint[playerid] entspricht sollte dies so sein ist die "Prüfung" fertig. Das return hier gibt die naricht zurück welche den wert 1 hat also
    könnte man das auch durch nur ein return 1; ersetzen und bricht den code für dne spieler dort ab . Sollte nun DSPoint[playerid] nicht den wert 9 haben so kommt das else ins spiel was ja auch auf deutsch sonst heißt. Wenn... sonst ... . Dort wird DSPoint[playerid] immer um 1 erhöht durch das ++ += 1 würde auch gehen.
    Und der nächste checkpoint wird danach angezeigt. strdel wird benutzt um den string zu leeren man kan auch nur einen string benutzen für sein gamemode jedoch immer
    wieder leeren sonst wird er nur zu einem teil überschrieben.

  • Danke für die Antwort IPrototypeI !!


    Bin mit den Grundlagen der Programmier-Sprachen(logische Operatoren, Variablen & son zeug) recht gut vertraut als TG schüler mit Profilfach Informationstechnik, aber manche Programmier-Sprachen haben so Ihre Eigenarten die manchmal etwas gewöhnungsbedürftig sind :DD


    Da ich mit dini & nicht mit "enum" arbeite werde ich wohl noch etwas tüfteln müssen, aber ich denk, dass ich das auch irgendwie hinbekomme ;)


    Also Danke nochmal


    Mfg


    //EDIT


    sobald ich einfüge:
    #define MAX_DSPOINTS 10
    stürzt Pawno ab ...

    THE STORM941

    Einmal editiert, zuletzt von TheStorm941 ()


  • Ich geh mal davon aus das du als TG schüler wahrscheinlich im zweiten Jahr bist da man erst ab diesem Jahr die wahl hat Naturwissenschaftlichefächer 4 Stündig oder 2 Stündig zu nehmen jedoch dazu Informatik und du bestimmt nicht wirklich mit der Materie vertraut bist.
    PAWN ist jedoch eine sehr einfach programmiersprache, welche jedoch auch nur eine ableitung von C ist daher gibt es zum beispiel beim reinen C# gewisse ähnlichkeiten.
    Nun gut lange Rede kurzer Sinn. Ich hoffe dir ist bewusst das Dini ein Speichersystem ist beziehungsweise Filesystem und ein enum ist nur ein Schlüsselwort was ein aufzählungstyp ist.
    Daher bestehen dabei keine gemeinsamkeiten außer vllt das es je nach dem als index als array temporär daten speichert.


    Ich weiß ja nicht was du machen möchtest ob du das System hier dynamisch gestalten möchtes,t wo du ingame neue strecken fest legen kannst oder weiß der Geier was du mit DINI einbringen willst.


    Zu dem kann der kompiler nicht durch ein #define abstürzen was so gesehen beim kompielen gar nicht existiert. sonder als normale zahl wieder gegeben wird.