Tutorial: dyn. Navigationssystem
NICHT FÜR COPY & PASTE GEEIGNET
Hier zeige ich euch, wie man am besten ein dynamisches Navigationssystem erstellt. Das heißt: Ihr müsst nicht für jeden Ort ein Menüpunkt sowie Dialog bei OnDialogResponse reinfummeln. Leichter gehts so!:
[1] Wir erstellen alle benötigten Variablen (am besten "oben" im Skript)
Zuerst definieren wir 2 Werte, ncount (Anzahl der wählbaren Orte) und diaNavi als Dialogid für den später genutzten Dialog.
Es wird eine Spielervariable erstellt (SpielerHatNavigationsCP), das MAX_PLAYERS steht für die Anzahl der Spielerslots da die selbe Variable für verschiedene Spieler existieren soll, diese Variable wird später zum Erkennen eines Navi-Checkpunktes sein.
Dann erstellen wir ein enum, in dem wir festlegen: Name des Ortes, X, Y, Z Positionen. Anschließend definieren wir die Orte. Das wird mit <new const> gemacht. Ich hab mal 2 Beispielorte eingetragen.
#define ncount 2 //2 für 2 Beispielorte
#define diaNavi 1 //Dialogid
new SpielerHatNavigationsCP[MAX_PLAYERS]; //Für jeden Spieler wird eine Variable erstellt, muss nach Logout auf 0 null gesetzt werden!
enum NaviInfo //Variableln Enum erstellen mit den Namen und den Positionen (mehr braucht man auch nicht)
{
oName[64],
Float:npX,
Float:npY,
Float:npZ
};
new const Navigation[][NaviInfo] = {
// Hier tragen wir ein: Ortsname sowie X Y und Z position (was oben definiert wurde)
{"Los Santos Police Departement", 1529.4445,-1673.9855,12.9552},
{"Mapmittelpunkt", 0.0, 0.0, 0.0}
};
So weit so gut. Wir haben jetzt schonmal 2 Orte festgelegt, also das war nun wirklich net schwer. Weiter gehts.
ZitatSo fügt man einen Ort hinzu:
1. bei < #define ncount > um eine Steller erhöhen
2. Name und Position (enum) einfügen. Name in "Anführungszeichen".
[2] Der Befehl zum Aufrufen des Navis (OnPlayerCommandText und strcmp).
Der Command zum Aufrufen des Dialogs. Hier erstellen wir eine Variable (bei uns eine Zeichenkette) <shownav>. Das wird später in der Dialogfunktion verwendet. Wir erstellen eine Schleife, die dia Anzahl der Navigationspunkte durchläuft. Das geschieht 2 mal da wir als ncount 2 festgelegt haben. Solltet ihr einen Punkt hinzufügen wird das 3 oder mehrmals durchlaufen. Mit der format-Funktion wird der angezeigte Text "generiert" indem er die Ortsnamen (Navigation[0 und 1][oName]) in eine Zeichenkette einträgt.
Wenn alle Punkte durchlaufen sind, wird dem Spieler der Dialog angezeigt.
if(strcmp(cmd, "/navi", true) == 0) //Befehl
{
new shownav[2048]; //Variable für die Navigationspunkte
for(new nav = 0; nav < ncount; nav++) //Schleife damit alle Punkte durchlaufen werden.
{
if(nav == 0) //Wenn es der erste Menüpunkt ist
{
format(shownav, 256, "%s", Navigation[nav][oName]); // Beispiel: in unserem Falle ist es das LSPD ("Los Santos Police Departement")
}
else //Andernfalls wird der shownav vor den neuen shownav gesetzt.
{
format(shownav, 256, "%s\r\n%s", shownav, Navigation[nav][oName]); // Beispiel wie das abläuft:("Los Santos Police Departement\r\nMapmittelpunkt") usw.
}
}
//letztendlich wird die erstellt Zeichenkette in den Dialog eingefügt. Der Dialog wird dem Spieler angezeigt.
ShowPlayerDialog(playerid, diaNavi, DIALOG_STYLE_LIST, "Navigation", shownav, "Suchen", "Beenden");
return 1;
}
Das funktioniert so schonmal halbwegs. Jetzt muss noch abgefragt werden welcher Menüpunkt gewählt wurde.
[3] Anzeigen des Punktes. Auch ganz einfach, gut aufgepasst.
Bei dem public OnDialogResponse wird die dialogid abgefragt. In unserem Fall ist das <diaNavi> (oben definiert). <if(response)> fragt ab ob er die Linke Taste oder Enter drückt.
Wieder nehmen wir uns eine Schleife her, mit dieser wird das angeklickte listitem abgefragt. In unserem enum hat zB Los Santos Police Departement die stelle 0, da es zuerst definiert wurde, Mapmittelpunkt hat die 1. Wenn listitem dann 0 ist, wird der Checkpunkt für das LSPD angezeigt, wenn listitem 1 ist, der für den Mapmittelpunkt. Die 0 oder 1 im Beispiel wär unten im Skript die Variable nav.
Der Checkpoint wird gesetzt mit den Koordinaten des enums (von nav) und dem Spieler wird eine Nachricht geschrieben. Nun muss nurnoch die Spielervariable für <playerid> der den Dialog aufgerufen hat auf 1 gesetzt werden (siehe Punkt 4).
// Bei OnDialogResponse(...)
if(dialogid == diaNavi)
{
if(response) //Wenn linker Button gedrückt wird. (In unserem Falle "Suchen")
{
for(new nav = 0; nav < ncount; nav++) //Wieder eine Schleife wo alle Navigationspunkte durchlaufen werden (die oben festgelegt sind).
{
if(listitem == nav) //Wenn Auswahl. Beispiel: LSPD ist bei uns 0. Daher auch Listitem 0. Das ergänzt sich selber.
{
SetPlayerCheckpoint(playerid, Navigation[nav][npX], Navigation[nav][npY], Navigation[nav][npZ], 5); //CP wird gesetztm mit den oben definierten Koordinaten
SpielerHatNavigationsCP[playerid] = 1; //Der Gamemode weis: der CP des Spielers gilt dem Navi.
format(str, 256, "Navigation: Neues Ziel <%s>.", Navigation[nav][oName]);
SendClientMessage(playerid, white, str); //Nachricht an den Spieler (kann auch mit GameTextForPlayer etc. gemacht werden)
return 1;
}
}
}
}
Es funktioniert jetzt voll und ganz. Als Sahnehäubchen noch der Berühmte Satz: "Sie haben ihr Ziel erreicht."
[4] Bestätigung des Reiseziels.
Das Callback wird aufgerufen wenn ein Spieler eine Markierung/ einen Checkpoint betritt. Da wird dann abgefragt ob der letzt gesetzte Checkpoint ein Navi-Checkpoint ist <if(SpielerHatNavigationsCP[playerid] == 1)> bzw wenn ja. Dann wird der Checkpoint entfernt, dem Spieler eine Nachricht gesendet und Die Spielervariable wird wieder auf 0 gesetzt, da der nächste Checkpoint kein Navi-Checkpoint sein kann.
public OnPlayerEnterCheckpoint(playerid)
{
if(SpielerHatNavigationsCP[playerid] == 1) //Abfrage ob der letzte CP ein Navi-CP ist.
{
DisablePlayerCheckpoint(playerid); //Mapmarkierung verschwindet
SpielerHatNavigationsCP[playerid] = 0; //kein Navigations-CP mehr.
SendClientMessage(playerid, white, "Navigation: Sie haben ihr Ziel erreicht.");
return 1;
}
}
Das wars schon, so schwer war es nicht oder?
Noch Fragen oder Unklarheiten?
Wenn nicht, viel Spaß mit eurem neuen bequemen Navigationssystem
Gruß.