Guten Tag.
Heute werden ich euch ein Mietsystem vorstellen, das folgendes kann:
•Man kann nur 1 Auto mieten
•Nur der Besitzer kann in das Auto einsteigen
•Wenn es 10 Minuten nicht benutzt wurde, wird es respawnt!
•Das Mieten kostet 500$, wenn man es entmietet hat, kriegt man sein Geld wieder.
Was wir dafür brauchen:
• Ganz klar, Pawno
• Aufjedenfall Grundkenntnisse, da ich auch bestimmte Dinge nichtmehr genauer eingehen werde.
• Zeit
Anfang
Als erstes erstellen wir eine Player Variable und definieren unserer Maximale Anzahl der Mietfahrzeuge.
Dies machen wir mit einem 1 Dimensionalen Array und mit #define
Die Erklärung zum Array und #define findet ihr hier:
•Array: http://wiki.sa-mp.com/wiki/Scripting_Basics_DE#Array
•#define (Von Kaliber): [ SCRIPTING ] Directives / Makros (pre-processor)
Dies kommt oben ins Script:
#define MAX_MIETAUTOS 3
Jetzt hat MAX_MIETAUTOS immer die Zahl 3, außer ihr erhöht die Zahl, und gleichzeitig die Anzahl der Mietautos (Wenn ihr das macht, muss der Array auch erweitert werden (Folgt später))
new bool: HatGemietet[MAX_PLAYERS];
Erklärung was eine Boolean ist: http://wiki.sa-mp.com/wiki/Scripting_Basics_DE#Boolean
Damit man nicht alle Autos für sich alleine "wegmieten" kann, erstellen wir ein 1 Dimensionales Array in verbindung mit einem Boolean. Wenn der Index auf 0 ist, sprich false, sagen wir damit dem script, das wir kein Auto gemietet haben. Wenn es auf true ist haben wir eins.
Als nächstes erstellen wir ein 2 Dimensionales Array in verbindung mit einem Enum.
Die Erklärung was ein Enum ist, findet ihr hier:
•Enum: http://wiki.sa-mp.com/wiki/Keywords:Initialisers#enum
enum Mietinfo
{
ModelID,
Float:X,
Float:Y,
Float:Z,
Float:A,
Farbe1,
Farbe2,
Respawn,
bool: gemietet,
BesitzerID
}
ModelID = Die Fahrzeug ID Hier die Liste, aller IDs: http://wiki.sa-mp.com/wiki/Vehicle_Model_ID_List
Mit der ModelID, X, Y, Z, A, Farbe1 und Farbe2 lassen wir, wenn der Server gestartet wird, die Autos erstellen.
Da wir wollen, dass das Auto, wenn es unbenutzt ist, nach 10 Minuten Respawnt, erstellen wir noch eine Variable die "Respawn" heißt.
Mit der Bollean "gemietet" und "BesitzerID" weisen wir dem Fahrzeug zu, ob es bereits gemietet wurde, und wenn ja, wer hat es gemietet?
Im nächsten Schritt folgt der dazugehörige Array:
Am Anfang sieht er noch so aus:
new rInfo[MAX_MIETAUTOS][Mietinfo] = {
};
wir erstellen also eine Variable die "rInfo" die 3 Zeilen enthält und die in verbindung mit einem Enum gebracht wurde.
So füllen wir die Lücken: Bsp:
{ModelID, X, Y, Z, A, Farbe1, Farbe2, Respawn, gemietet, BesitzerID},
//... Die anderen 2 Autos
Um die ModelID, X, Y, Z, A, Farbe1 und Farbe2 rauszubekommen, können wir in unserem SAMP Debug gehen, in ein Auto einsteigen und /save machen
ModelID = Blau,
X = Rot,
Y = Orange
Z = Grün
A(FacingAngle des Autos) = Lila
Farbe1 = Grau
Farbe2 = Gelb
AddStaticVehicle(522,2038.4113,1343.0154,10.2438,181.2589,161,1);
Ein fertig ausgefüllter 2 Dimensionaler Array schaut dann so aus:
new rInfo[MAX_MIETAUTOS][Mietinfo] = {
{522,2038.4113,1343.0154,10.2438,181.2589,161,1,600,false,-1},
{522,2038.7362,1337.0945,10.2291,181.7973,167,1,600,false,-1},
{522,2038.6490,1330.8617,10.2300,185.5121,166,1,600,false,-1}
};
Um später, herrauszufinden, ob unser Auto in das wir evtl einsteigen, ein Mietauto ist, müssen wir uns noch eine Variable erstellen, in der wir die Fahrzeuge "reinpacken"
new Mietauto[MAX_MIETAUTOS];
Nun gehen wir zu dem Public OnGameModeInit:
public OnGameModeInit()
{
//Hier dürfte bereits schon folgendes drinne stehen:
SetGameModeText("Blank Script");
AddPlayerClass(0, 1958.3783, 1343.1572, 15.3746, 269.1425, 0, 0, 0, 0, 0, 0);
}
Um die Mietfahrzeuge mit dem Array zu erstellen, was wir gerade eben erstellt haben, brauchen wir eine for schleife, die durch 3 geht. Da wir 3 mit MAX_MIETAUTOS definiert haben, geht unsere schleife durch MAX_MIETAUTOS
•for-schleife: http://wiki.sa-mp.com/wiki/Loop
Nur mit der for schleife, würde es so aussehen, und es würde nichts passieren
public OnGameModeInit()
{
//Hier dürfte bereits schon folgendes drinne stehen:
SetGameModeText("Blank Script");
AddPlayerClass(0, 1958.3783, 1343.1572, 15.3746, 269.1425, 0, 0, 0, 0, 0, 0);
for(new i = 0; i < MAX_MIETAUTOS;i++)
{
}
}
Da wir aber die Autos erstellen wollen, brauchen wir AddStaticVehicle. Außerdem kommt nun unsere Variable "Mietauto" ins Spiel.
In dieser Variable packen wir nun die 3 Mietautos rein und lassen Sie gleichzeitig erstellen.
Um Fehlern aus dem Weg zugehen, lassen wir noch von jedem Fahrzeug den Besitzer auf -1 setzen und sagen dem Script das es nicht gemietet wurde, in dem fall einfach die Variable "gemietet" auf false setzen.
public OnGameModeInit()
{
// Don't use these lines if it's a filterscript
SetGameModeText("Blank Script");
AddPlayerClass(0, 1958.3783, 1343.1572, 15.3746, 269.1425, 0, 0, 0, 0, 0, 0);
for(new i = 0; i < MAX_MIETAUTOS;i++){
Mietauto[i] = AddStaticVehicleEx(rInfo[i][ModelID],rInfo[i][X],rInfo[i][Y],rInfo[i][Z],rInfo[i][A],rInfo[i][Farbe1],rInfo[i][Farbe2],rInfo[i][Respawn]);
rInfo[i][BesitzerID] = -1;
rInfo[i][gemietet] = false;
}
return 1;
}
Nun sind wir soweit, das wir, wenn wir Ingame gehen würden die Fahrzeuge erstellt werden. Jedoch könnte ich damit wild durch die Gegend fahren, ohne es zu mieten. Dazu kommen wir im nächsten Schritt.
Ich werde es auch an strcmp zeigen, da nicht jeder OCMD oder DCMD benutzt. Jedoch werde ich noch den Befehl wie er in dcmd und wie er in ocmd aussieht, dazupacken.
Wir wir einen Befehl mit strcmp erstellen, müsste eig. jeder Anfänger wissen. Als erstes wollen wir den miet Befehl haben.
Dies kommt unter den public "OnPlayerCommandText"
f(strcmp("/mieten", cmdtext, true, 10) == 0)
{
return 1;
}
Da wir ja das Fahrzeug mieten wollen, müssen wir natürlich noch mehr machen.
Dazu fragen wir erstmal ab, ob der Spieler in einem Fahrzeug ist, ob er 500$ dabei hat und ob das Fahrzeug ein Mietfahrzeug ist.
Mit den Funktionen GetPlayerMoney, IsPlayerInAnyVehicle und IsPlayerInVehicle , können wir das Problem schnell lösen. Dies würde so ausschauen:
Wenn er also in keinem Fahrzeug ist und den Befehl /mieten eingibt, geben wir Ihm eine Nachricht zurück. Der Rest wird so gesagt "übersprungen" D.h dies wird nicht aufgerufen. Hat er nicht genug Geld dabei, ist aber in einem Mietfahrzeug, dann wird ihm nur eine Nachricht gesendet, und nichts weiter geschieht
Um außerdem zu verhindern, das man sich nicht alle Fahrzeuge wegschnappen kann, wird zusätzlich noch abgefragt, ob er schon ein Fahrzeug gemietet hat. Ist dies auf true (Also auf 1) wird Ihm auch hier eine Nachricht gesendet.
Mit der Boolean "no" werden wir dem Spieler später eine Nachricht senden, falls es kein Mietauto ist, was er mieten will
if(strcmp("/mieten", cmdtext, true, 10) == 0)
{
new bool:no;
if(HatGemietet[playerid] == true)return SendClientMessage(playerid,0xFFFFFFFF,"Du hast bereits ein Fahrzeug gemietet!");
if(!IsPlayerInAnyVehicle(playerid))return SendClientMessage(playerid,0xFFFFFFFF,"Du bist in keinem Fahrzeug!");
if(GetPlayerMoney(playerid) < 500)return SendClientMessage(playerid,0xFFFFFFF,"Du hast nicht genug Geld!");
return 1;
}
Da wir nun endlich Taten folgen lassen wollen. Überprüfen wir mit einer for - schleife, ob es ein Mietfahrzeug ist, und ob es schon gemietet wurde, wenn dies nicht zutrifft, wird dem Spieler eine Message gesendet.
for(new i = 0; i < MAX_MIETAUTOS;i++)
{
if(IsPlayerInVehicle(playerid,Mietauto[i]) && rInfo[i][gemietet] == false)
{
no = true;
}
}
if(no) return SendClientMessage(playerid,0xFFFFFFFFF,"Du kannst dieses Auto nicht mieten!");
So. Als nächstes wollen wir dem Script sagen, das wir, der jenige der den Befehl eingeben hat, jetzt ein Auto gemietet hat. Dazu setzen wir die Variable "HatGemietet" auf true.
Außerdem sagen wir dem Script, welches Auto wir gemietet haben. Dazu wird die BesitzerID des Autos auf unsere SpielerID gesetzt und die Variable gemietet wird auf true gesetzt, damit nicht 2 Leute ein und das selbe Auto mieten können. Der fertige Befehl schaut dann so aus:
public OnPlayerCommandText(playerid, cmdtext[])
{
if(strcmp("/mieten", cmdtext, true, 10) == 0){
new bool:no;
if(HatGemietet[playerid] == true)return SendClientMessage(playerid,0xFFFFFFFF,"Du hast bereits ein Fahrzeug gemietet!");
if(!IsPlayerInAnyVehicle(playerid))return SendClientMessage(playerid,0xFFFFFFFF,"Du bist in keinem Fahrzeug!");
if(GetPlayerMoney(playerid) < 500)return SendClientMessage(playerid,0xFFFFFFF,"Du hast nicht genug Geld!");
for(new i = 0; i < MAX_MIETAUTOS;i++){
if(IsPlayerInVehicle(playerid,Mietauto[i]) && rInfo[i][gemietet] == false){
rInfo[i][gemietet] = true;
rInfo[i][BesitzerID] = playerid;
GivePlayerMoney(playerid,-500);
SendClientMessage(playerid,0xFFFFFFFF,"Du hast das Auto gemietet! Tippe /entmieten um das Auto abzugeben!");
TogglePlayerControllable(playerid,1);
HatGemietet[playerid] = true;
no = true;
break;
}
else no = true;
}
if(no) return SendClientMessage(playerid,0xFFFFFFFF,"Du kannst dieses Auto nicht mieten!");
return 1;
}
return 1;
}
ocmd:mieten(playerid){
new bool:no;
if(HatGemietet[playerid] == true)return SendClientMessage(playerid,0xFFFFFFFF,"Du hast bereits ein Fahrzeug gemietet!");
if(!IsPlayerInAnyVehicle(playerid))return SendClientMessage(playerid,0xFFFFFFFF,"Du bist in keinem Fahrzeug!");
if(GetPlayerMoney(playerid) >= 500)return SendClientMessage(playerid,0xFFFFFFFF,"Du hast nicht genug Geld!");
for(new i = 0; i < MAX_MIETAUTOS;i++){
if(IsPlayerInVehicle(playerid,Mietauto[i]) && rInfo[i][gemietet] == false){
rInfo[i][gemietet] = true;
rInfo[i][BesitzerID] = playerid;
GivePlayerMoney(playerid,-500);
SendClientMessage(playerid,0xFFFFFFFF,"Du hast das Auto gemietet! Tippe /entmieten um das Auto abzugeben!");
TogglePlayerControllable(playerid,1);
HatGemietet[playerid] = true;
no = true;
break;
}
}
if(no) return SendClientMessage(playerid,0xFFFFFFFF,"Du kannst dieses Auto nicht mieten!");
return 1;
}
//Unter OnPlayerCommandText:
dcmd(mieten,6,cmdtext);
//Außerhalb eines publics
dcmd_mieten(playerid,params[]){
#pragma unused params
new bool:no;
if(HatGemietet[playerid] == true)return SendClientMessage(playerid,0xFFFFFFFF,"Du hast bereits ein Fahrzeug gemietet!");
if(!IsPlayerInAnyVehicle(playerid))return SendClientMessage(playerid,0xFFFFFFFF,"Du bist in keinem Fahrzeug!");
if(GetPlayerMoney(playerid) >= 500)return SendClientMessage(playerid,0xFFFFFFFF,"Du hast nicht genug Geld!");
for(new i = 0; i < MAX_MIETAUTOS;i++){
if(IsPlayerInVehicle(playerid,Mietauto[i]) && rInfo[i][gemietet] == false){
rInfo[i][gemietet] = true;
rInfo[i][BesitzerID] = playerid;
GivePlayerMoney(playerid,-500);
SendClientMessage(playerid,0xFFFFFFFF,"Du hast das Auto gemietet! Tippe /entmieten um das Auto abzugeben!");
TogglePlayerControllable(playerid,1);
HatGemietet[playerid] = true;
no = true;
break;
}
}
if(no) return SendClientMessage(playerid,0xFFFFFFFF,"Du kannst dieses Auto nicht mieten!");
return 1;
}
Erklärung von Break:
•break:http://wiki.sa-mp.com/wiki/Control_Structures#break
Wir wollen ja auch, das nur wir, als Besitzer in das Fahrzeug einsteigen dafür Drücken wir strg + f und suchen nach OnPlayerStateChange
nun dürftet ihr folgenden public sehen:
public OnPlayerStateChange(playerid, newstate, oldstate)
{
return 1;
}
Hier stellen wir uns eine Variable, die ich vID genannt habe und setzen in die variable GetPlayerVehicleID(playerid);
Damit überprüfen wir später, ob wir in ein Mietfahrzeug einsteigen.
Aber als erstes müssen wir Abfragen, ob wir überhaupt in ein Auto als Fahrer einsteigen. Dies geht mit PLAYER_STATE_DRIVER
Es würde dann so aussehen, wenn ihr alles richtig gemacht habt:
public OnPlayerStateChange(playerid, newstate, oldstate)
{
new vID = GetPlayerVehicleID(playerid);
if(oldstate == PLAYER_STATE_ONFOOT && newstate == PLAYER_STATE_DRIVER)
{
}
return 1;
}
Nun kommt wieder die for - schleife ins Spiel, den ohne sie können wir nicht überprüfen, ob der Spieler jetzt wirklich in ein Mietfahrzeug einsteigt und ob das in das er einsteigt, bereits gemietet wurde oder nicht.
for(new i = 0; i < MAX_MIETAUTOS;i++)
{
if(vID == Mietauto[i])
{
if(rInfo[i][BesitzerID] == -1 && rInfo[i][gemietet] == false)
{
}
}
}
Wenn dies Zutrifft, lassen wir den Spieler freezen, damit er nicht wegfahren kann
Wenn das Auto schon gemietet wurde, lassen wir ihn aus dem Auto werfen.
public OnPlayerStateChange(playerid, newstate, oldstate)
{
new vID = GetPlayerVehicleID(playerid);
if(oldstate == PLAYER_STATE_ONFOOT && newstate == PLAYER_STATE_DRIVER){
for(new i = 0; i < MAX_MIETAUTOS;i++){
if(vID == Mietauto[i]){
if(rInfo[i][BesitzerID] == -1 && rInfo[i][gemietet] == false){
TogglePlayerControllable(playerid,0);
SendClientMessage(playerid,0xFFFFFFFF,"Benutze /exit um das Auto zu verlassen, oder /mieten um das AUto zu mieten!");
}
else if(vID == Mietauto[i] && playerid != rInfo[i][BesitzerID]){
new string[128];
format(string,sizeof(string),"Dieses Auto wird bereits von (%d)%s gemietete!",rInfo[i][BesitzerID],SpielerName(rInfo[i][BesitzerID]));
SendClientMessage(playerid,0xFFFFFFFF,string);
TogglePlayerControllable(playerid,1);
RemovePlayerFromVehicle(playerid);
}
}
}
}
return 1;
}
Jetzt würde bei euch ein warning kommen, das ihr "SpielerName" nicht in eurem Script habt, dafür fügt ihr außerhalb eines public folgendes ein:
stock SpielerName(playerid){
new pname[MAX_PLAYER_NAME];
GetPlayerName(playerid,pname,sizeof(pname));
return pname;
}
Wenn wir 500$ haben, können wir nun das Auto mieten!
Wenn wir das Auto nicht mehr haben wollen, erstellen wir uns noch einen /entmieten Befehl.
Wenn Ihr das Konzept verstanden habt, dürfte das für euch kein Problem sein.
Hierzu gehen wir wieder zu "OnPlayerCommandText" und erstellen und einen neuen Befehl
if(strcmp("/entmieten",cmdtext,true,10) == 0)
{
}
Damit wir nur das Geld wiederbekommen, wenn wir wirklich ein Auto gemietet haben. müssen wir dies vorher abfragen.
if(HatGemietet[playerid] == false)return SendClientMessage(playerid,0xFFFFFFFF,"Sie haben kein Auto gemietet!");
Nur wenn wir ein Fahrzeug gemietet haben, wollen wir das unser Geld zurück bekommen, dass das Fahrzeug respawnt wird, und sogesagt "entmietet" wird. D.H wird resetten einfach die Variablen, auf den Alten Stand. Überprüfen wir aber mit Hilfe einer For schleife, welches Auto wir genau gemietet haben
for(new i = 0; i < MAX_MIETAUTOS;i++)
{
if(rInfo[i][BesitzerID] == playerid){
}
if(strcmp("/entmieten",cmdtext,true,10) == 0){
if(HatGemietet[playerid] == false)return SendClientMessage(playerid,0xFFFFFFFF,"Sie haben kein Auto gemietet!");
for(new i = 0; i < MAX_MIETAUTOS;i++){
if(rInfo[i][BesitzerID] == playerid){
SendClientMessage(playerid,0xFFFFFFF,"Auto entmietet! Hier sind Ihre 500$");
rInfo[i][BesitzerID] = -1;
rInfo[i][gemietet] = false;
HatGemietet[playerid] = false;
RemovePlayerFromVehicle(playerid);
SetVehicleToRespawn(Mietauto[i]);
GivePlayerMoney(playerid,500);
break;
}
}
}
Wenn wir uns entschieden haben, das Auto doch nicht zumieten. Fügt ihr das einfach unter OnPlayerCommandText ein:
(Darauf werde ich jetzt nicht weiter eingehen)
if(strcmp("/exit",cmdtext,true,10) == 0){
if(!IsPlayerInAnyVehicle(playerid))return 0;
for(new i = 0; i < MAX_MIETAUTOS;i++){
if(IsPlayerInVehicle(playerid,Mietauto[i])){
RemovePlayerFromVehicle(playerid);
TogglePlayerControllable(playerid,1);
}
}
}
Theoretisch sind wir nun fertig. Da wir aber auch wollen, das unser Auto entmietet wird, wenn wir uns ausloggen, oder das Fahrzeug kaputt geht, müssen wir zu
zuerst zu "OnPlayerDisconnect" gehen.
public OnPlayerDisconnect(playerid,reason)
{
return 1;
}
Da eine For schleife auch sehr Resurcenfressend sein kann, überprüfen wir zur Sicherheit noch, ob wir ein Auto gemietet haben.
public OnPlayerDisconnect(playerid, reason)
{
if(HatGemietet[playerid] == true){
}
return 1;
}
Wenn dies zutrifft, lassen wir die Schleife starten.
In der Schleife, überprüfen wir, welches Auto wir genau gemietet haben. Wenn die Schleife das Auto gefunden hat, lassen wir es respawnen und stoppen die Schleife
for(new i = 0; i < MAX_MIETAUTOS;i++){
if(rInfo[i][BesitzerID] == playerid){
rInfo[i][BesitzerID] = -1;
rInfo[i][gemietet] = false;
SetVehicleToRespawn(Mietauto[i]);
HatGemietet[playerid] = false;
break;
}
}
Fertig sieht es dann so aus:
public OnPlayerDisconnect(playerid, reason)
{
if(HatGemietet[playerid] == true){
for(new i = 0; i < MAX_MIETAUTOS;i++){
if(rInfo[i][BesitzerID] == playerid){
rInfo[i][BesitzerID] = -1;
rInfo[i][gemietet] = false;
SetVehicleToRespawn(Mietauto[i]);
HatGemietet[playerid] = false;
break;
}
}
}
return 1;
}
Fast das selbe machen wir auch Unter OnVehicleDeath
Darauf werde ich jetzt auch nicht weiter drauf eingehen. Ich werde nur sagen, das hier geprüft wird, ob das Auto was zerstört wurde ein Mietfahrzeug ist, und ob es gemietet wurde. Wenn es gemietet wurde, werden die Variablen resettet, und der Spieler, der das Fahrzeug gemietet hat, wird benachrichtigt
public OnVehicleDeath(vehicleid, killerid)
{
for(new i = 0; i < MAX_MIETAUTOS;i++){
if(vehicleid == Mietauto[i]){
if(rInfo[i][gemietet] == true){
SendClientMessage(rInfo[i][BesitzerID],0xFFFFFFFFF,"Ihr Mietfahrzeug wurde zerstört!");
HatGemietet[rInfo[i][BesitzerID]] = false;
rInfo[i][BesitzerID] = -1;
rInfo[i][gemietet] = false;
break;
}
}
}
return 1;
}
Nun sind wir auch am ende. Die Maximalen Zeichen sind fast aufgebraucht. aber bis hierhin habe ich noch 653 Zeichen frei.
Um Evtl Bugs aus dem wegzugehen, könnt ihr folgendes noch einfügen:
public OnPlayerConnect(playerid)
{
HatGemietet[playerid] = false;
return 1;
}
{
for(new i = 0; i < MAX_MIETAUTOS;i++){
SetVehicleToRespawn(Mietauto[i]);
rInfo[i][BesitzerID] = -1;
rInfo[i][gemietet] = false;
}
return 1;
}
•Pastebin: http://pastebin.de/31145
Viel Spaß damit.
Ich bitte um Bewertung:)
Mfg
-Sebastian