Hey Leute
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
Alles anzeigen
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.