Ein Blick in die Wiki löst einige Fragen:
http://wiki.sa-mp.com/wiki/Limits
Beiträge von Mann im Mond
-
-
Doch hab wieder nicht nachgedacht und einfach nur ein else an deinen Code angehängt. (Beitrag bearbeitet)
@ Luka: Du musst aber nicht für jedes Tor einen einzelnen Timer erstellen, sondern kannst natürlich den für alle verwenden die gleichzeitig aufgehen sollen. Müsstest es halt ein wenig umschreiben, je nachdem wie dus am liebsten willst... -
Oder du benutzt anstatt einen Timer zum Schliessen ein "else". Der Vorteil wäre, dass das Tor sich erst schliesst, wenn man sich davon wegbewegt...
public joa()
{
for(new i=0; i<MAX_PLAYERS; i++)
{
if(IsPlayerConnected(i))
{
if(PlayerToPoint(10.0,playerid,x,y,z)) {//bei x,y,z die Koordinaten vom Tor eintragen (die 10.0 ist der Radius)
{
MoveObject(...); //das Tor im geöffneten Zustand
}
else
{
MoveObject(...); //das Tor im geschlossenen Zustand
}
[...] -
Mein Code oben diente nur als Beispiel. Da ich es wie gesagt nicht gestestet habe, können da Fehler drin sein, die du aber eigentlich selber hättest beheben können. Ein ";" hat gefehlt und newkeys war falsch geschrieben z.B.
-
forward Ramp(playerid);
new Ramp[MAX_PLAYERS];
public OnPlayerConnect(playerid)
{
Ramp[playerid] = 0;
}public OnPlayerKeyStateChange(playerid,newkeys,oldkeys)
{
if(newkeys ... && IsPlayerInAnyVehicle(playerid)) /* Dein Knopf hier rein */
{
if(Ramp[playerid] != 0) return 1; /* Wenn er bereits eine Rampe gespawnt hat */
new
Float:x,
Float:y,
Float:z,
Float:angle;
GetPlayerPos(playerid,x,y,z); /* GetVehiclePos sollte genauso funktionieren */
angle = GetXYInFrontOfPlayer(playerid,x,y,ABSTAND); /* hier dein Abstand zur Rampe */
Ramp[playerid] = CreateObject(OBJECT, x, y, z - 0.4, 0.0, 0.0, angle); /* Objekt hier rein, mit z bin ich mir nicht sicher, wie hoch die spawnt */
SetTimerEx("Ramp",2000,0,"d",playerid); /* Das Löschen hier noch */
}
}public Ramp(playerid)
{
if(Ramp[playerid] != 0)
{
DestoryObject(Ramp[playerid]);
Ramp[playerid] = 0;
}
}GetXYInFrontOfPlayer(playerid, &Float:x, &Float:y, Float:distance)
{
new Float:a;
GetPlayerPos(playerid, x, y, a);
GetPlayerFacingAngle(playerid, a);
if (GetPlayerVehicleID(playerid))
{
GetVehicleZAngle(GetPlayerVehicleID(playerid), a);
}
x += (distance * floatsin(-a, degrees));
y += (distance * floatcos(-a, degrees));
return a; /* Winkel benötigt man , damit die Rampe richtig spawnt */
}Ich habs nicht getestet, bin mir nicht sicher ob die Rampe richtig spawnt (Winkel, Höhe), falls nicht musst du halt noch ein wenig dran arbeiten
-
GetXYInFrontOfPlayer(playerid, &Float:x, &Float:y, Float:distance)
{
new Float:a;
GetPlayerPos(playerid, x, y, a);
GetPlayerFacingAngle(playerid, a);
if (GetPlayerVehicleID(playerid))
{
GetVehicleZAngle(GetPlayerVehicleID(playerid), a);
}
x += (distance * floatsin(-a, degrees));
y += (distance * floatcos(-a, degrees));
}und
CreateObject(modelid, Float:X, Float:Y, Float:Z, Float:rX, Float:rY, Float:rZ);
in
OnPlayerKeyStateChange
und du kannst eine Rampe ganz einfach vor dem Spieler spawnen. Wenn die Rampe allerdings danach wieder verschwinden soll, musst du noch
SetTimerEx(funcname[], interval, repeating, const format[], {Float,_}:...);und
DestroyObject(objectid);verwenden. Um das richtige Object verschwinden zu lassen, kannst du eine Variable benutzen:
new Ramp[MAX_PLAYERS];und dann in OnPlayerKeyStateChange
Ramp[playerid] = CreateObject(...);
und in dem public, der vom Timer aufgerufen wird:
DestroyObject(Ramp[playerid]);
So ich denke das sollte reichen, um so etwas zu erstellen
-
Es gibt im Prinzip 2 verschiedene Möglichkeiten dies umzusetzen. Beide haben ihre Vor- und Nachteile.
Möglichkeit 1 (leichter, effektiver ABER nur "begrenzt" unbesiegbar):
SetPlayerHealth(playerid,9999999); /* Eine möglichst hohe Zahl benutzen als Energie, wenn man den mit einer Mingun abschiesst für eine längere Zeit, dann wäre er früher oder später tot */
Möglichkeit 2 (im Prinzip richtig unbesiegbar ABER schwerer, weniger effektiv)
Man benutzt einen Timer, der z.B. jede Sekunde einen public aufruft. Dieser public setzt dann die Energie dauerhaft hoch.
Ganz oben
new godmode[MAX_PLAYERS];
forward Godmode() /* nicht zwingend, siehe unten */in OnPlayerConnect
godmode[playerid] = 0;in OnGameModeInit
SetTimer("Godmode",1000,1); /* Anstatt eines eigenen Timers, der jede Sekunde aufgrufen wird, rate ich dir den Code des publics "Godmode" in einer anderen public einzubauen, welcher bereits jede Sekunde aufgerufen wird (und möglicherweise bereits eine Schleife ausführt ) */
Der public
public Godmode()
{
for(new i = 0; i < GetMaxPlayers(); i++)
{
if(IsPlayerConnected(i))
{ /* Ab hier kann man es in eine bestende Schleife eingebaut werden, die jede Sekunde aufgrufen wird */
if(godmode[i] == 1)
{
SetPlayerHealth(i,999);
}
}/* Bis hier */
}
}So nun ist jeder Spieler unbesiegbar, bei dem die Variable godmode auf 1 ist, z.B.
in OnPlayerStateChange
if(newstate == PLAYER_STATE_DRIVER)
{
new
carid = GetPlayerVehicleID(playerid);
if(GetVehicleModel(carid) == 522) /* NRG */
{
godmode[playerid] = 1; /* Macht den Spieler unbesiegbar */
}
}Ich empfele dir aber die erstere Variante, bei der 2. lohnt es sich nicht, extra einen eigenen Timer laufen zu lassen nur wegen Godmode. Wenn du allerdings bereits einen Timer benutzt, der jede Sekunde aufgerufen wird und in dem public (welcher vom Timer aufgerufen wird) bereits einen Schleife drin ist, kann du innerhalb dieser Schleife ( for(new ...) ) einfach folgendes hinzufügen:
if(godmode[i] == 1)
{
SetPlayerHealth(i,999);
} -
Ich kenn mich mit dini gar nicht aus, da ich es noch nie benutzt habe. Am Besten fragst du hierfür in dem entsprechenden Thread im Forum, wo du es her hast. Oder du wartest und hoffst, dass dir ein anderer eine Antwort gibt...
-
Fehler mit einem Kommentar versehen
if(strcmp(cmd, "/givecash", true) == 0)
{
new
sendername[MAX_PLAYER_NAME],
erhalter,
summe;
tmp = strtok(cmdtext, idx);
if(tmp[0] == 0) // Keinen Spielernamen angegeben
{
SendClientMessage(playerid, COLOR_GREEN, "BENUTZUNG: /givecash [Spieler] [Summe]");
return 1;
}
erhalter = ReturnUser(tmp); // ReturnUser hat den Vorteil, dass man auch einen Teil des Names eingeben kann anstatt eine ID
tmp = strtok(cmdtext, idx);
if(tmp[0] == 0) // Keine Summe angegeben
{
SendClientMessage(playerid, COLOR_GREEN, "BENUTZUNG: /givecash [Spieler] [Summe]");
return 1;
}
summe = strval(tmp);
GetPlayerName(playerid,sendername,sizeof(sendername));
format(string,sizeof(string),"%s hat dir $%d geschickt.",sendername,summe); // Nur bei strings %s benutzen, bei Zahlen (wie Summe) %d !
SendClientMessage(erhalter, COLOR_GREEN, string);
GivePlayerMoney(playerid, -summe);
GivePlayerMoney(erhalter, summe);
return 1;
} -
Natürlich. Da die Funktion ja heisst:
SetPlayerCheckpoint(playerid,Float:x,Float:y,Float:z,Float:size)Da du bereits eine Schleife benutzt, die an alle ADAC Mitglieder eine Nachricht sendet musst du dise Funktion nur dort noch einfügen:
if(strcmp(cmdtext,"/adac",true)==0)
{
new
sendername[MAX_PLAYER_NAME],
Float:pZ,
Float:pY,
Float:pZ;
GetPlayerPos(playerid,pX,pY,pZ); /* Koordinaten des Spielers in den Variablen speichern */
SendClientMessage(playerid, COLOR_GREEN, "Du hast einen Mechaniker gerufen!");
GetPlayerName(playerid,sendername,sizeof(sendername));
format(string,sizeof(string),"%s braucht einen Mechaniker",sendername);
for(new i = 0; i < GetMaxPlayers(); i++)
{
if(gTeam[i] == TEAM_ADAC)
{
SetPlayerCheckpoint(i, pX, pY, pZ, 5.0); /* Checkpoint für ADAC Leute anzeigen (Koordinaten des Spielers) */
SendClientMessage(i, COLOR_RED, string);
}
}
return 1;
}Allerdings solltest du noch etwas in OnPlayerEnterCheckpoint machen, zum deaktivieren des Checkpoints.
if(gTeam[playerid] == TEAM_ADAC)
{
new
string[64],
sendername[MAX_PLAYER_NAME];
GetPlayerName(playerid, sendername, sizeof(sendername));
for(new i = 0; i < GetMaxPlayers(); i++)
{
if(gTeam[i] == TEAM_ADAC)
{
format(string,sizeof(string),"%s hat das Ziel erreicht", sendername);
SendClientMessage(i, COLOR_RED, string); /* formatierte Nachricht an alle ADAC Mitgleider senden*/
DisablePlayerCheckpoint(i); /* Deaktiviert den Checkpoint */
}
}
}ABER: Dies ist eine vereinfachte Version. Der Nachteil hiervon wäre, dass JEDER Checkpoint nun für alle ADAC Mitglieder deaktiviert wird, sobald ein ADAC Mitglied in einen Checkpoint fährt. Um dies zu verhindern kannst du eine globale Variable erstellen und diese entsprechend verändern:
Ganz oben
new adaccheckpoint;Im /adac Befehl
adaccheckpoint = 1;Im OnPlayerEnterCheckpoint Teil:
/* Zuerst einmal das if verändern */
if(gTeam[playerid] == TEAM_ADAC && adaccheckpoint == 1)
{
adaccheckpoint = 0;
/* Der Rest des Codes */
}Dies behebt den Fehler, allerdings ist dieses System immernoch sehr einfach. Aber ich denke mal es reicht vorerst mal...
-
Wo du die dcmd Befehle hinmachst spielt keine Rolle, solange sie außerhalb eines publics sind. Mach dir keine Sorgen, das Script weis schon wo was steht, da du ja IN OnPlayerCommandText daruf hinweist, wie der Befehl heisst, wie lang er ist usw.
ZitatHabs schonmal ausprobiert...mach die dcmd über OnPlayerCommandText ;D
Wenn es bei dir nur oberhalb ging hattest du an anderer Stelle deines Scipts einen Fehler, bzw. hast im OnPlayerCommandText den Befehl falsch definiert ( dcmd(cmd,3,cmdtext); )
Bei mir funktioniert auf jeden Fall ohn Probleme und meine stehn am Ende des Scripts...ZitatHey also hab jet nur noch einen Error:
C:\Dokumente und Einstellungen\Joker\Desktop\tpp.pwn(2434) : error 017: undefined symbol "dini_Int"
was meinst du mit 2 ??
Wo hab ich was von 2 erwähnt?
Dein Error hat außerdem nicht mit deinem dcmd zu tun. Er liegt wie die Beschreibung schon sagt an "dini". -
Meines Wissens nach nicht.
Vielleicht gibt ja doch einen. Hier sind alle möglichen Funktionen aufgelistet
http://wiki.sa-mp.com/wiki/Category:Scripting_Functions -
Les dir am besten eine Anleitung zu dmcd durch und am besten auch gleich von sscanf (-> wiki).
http://wiki.sa-mp.com/wiki/Fast_Commands
die dcmd_BEFEHL(playerid,params[]) kommen in keinen public sondern einfach so außerhalb eines publics.
Du musst diese dcmd Befehle allerdings unter OnPlayerCommandText definieren:
dcmd(login,5,cmdtext); /* Name des Befehls (gleich wie beim dcmd_login), Länge des Befehls (login hat 5 Buchstaben), cmdtext (Eingabe des Spielers) */
-
if(strcmp(cmdtext,"/adac",true)==0)
{
new
sendername[MAX_PLAYER_NAME];
SetPlayerColor(playerid, COLOR_ADACUSER); /* Sieht aber jeder Spieler, nicht nur der ADAC */
ShowPlayerMarkers(1);
SendClientMessage(playerid, COLOR_GREEN, "Du hast einen Mechaniker gerufen!");
GetPlayerName(playerid,sendername,sizeof(sendername));
format(string,sizeof(string),"%s braucht einen Mechaniker",sendername);
for(new i = 0; i <= GetMaxPlayers(); i++)
{
if(gTeam[i] == TEAM_ADAC)
{
SendClientMessage(i,COLOR_RED,string);
}
}
return 1;
} -
OnPlayerDisconnect wird trotzdem aufgerufen, auch bei einem Kick. Ohne Code kann man dir glaub ich nur schlecht helfen
-
Die Zeilennummer ist unwichtig, es ging nur um die Zeile. Du hast allerdings einen Fehler:
Bei dir steht !== anstatt !=Das ist der Fehler.
Nochmal zum Merken:
== : "gleich"
!= : "ungleich"
: "oder" -
Nein mein Fehler, habe bei Zeile 97 einen kleinen Fehler eigebaut:
Ändere
if(Gate[gateid][Team] == gTeam[playerid]) return 1; /* richtiges Team? */in
if(Gate[gateid][Team] != gTeam[playerid]) return 1; /* richtiges Team? */ -
wenn du eine Variable innerhalb eines publics (z.B. OnGameModeInit) erstellst, kannst du auch diese nur innerhalb dieses publics darauf zugreifen (lokale Variable). Deshalb musst du zuerst eine globale Variable erstellen, dieser dann die PickupID zuweisen und erst dann kannst du überall auf diese Variable zugreifen:
Am Anfang des Scriptes (am Besten dort wo du andere gloable Variablen erstellst):
In OnGameModeInit:
ondutypickup = AddStaticPickup(...) /* Variable eine PickupID zuweisen */So nun kannst du überall im Script auf diese variable zugreifen - auch unter OnPlayerPickupPickup
-
Es wäre um eines einfacher diesen Code zu lesen, wenn du ihn richtig einrücken würdest. Mit deiner "Einrückung" übersieht man schnell,
dass man z.B. einige Klammern falsch gesetzt oder vergessen hat bzw. eine zu viel hat.
1.) siehe oben. Sollte eigentlich funktionieren. Les es dir aber noch einmal durch, nicht grad kopieren und einfügen2.) Damit Admins mit einzelnen Autos fahren können, kannst du z.B. "&& !IsPlayerAdmin(playerid)" (sprich: "... und der Spieler kein Admin ist") hinzufügen.
3.) Dazu müsstest du den Code ein wenig umschreiben. Füge z.B. beim enum eine weitere Variable (z.B. "Team" - natürlich musst du diese dann auch "AddAutoGate(...)" entsprechend anders benutzen) hinzu und überprüfe dann beim public GateEnter unterhalb der Namesüberprüfung, ob das Team übereinstimmt.
Am besten machst dus selber. Konnte meine Veränderung auf die Schnelle nicht testen:
http://pastebin.com/m31bc05174.) Kenn das Autosystem nicht und hab auch keinen Code
5.) Sachen, die du hierfür brauchst sind: (les unter wiki.sa-mp.com die genauen Befehle aus bzw. Pickup ids oder ähnliches)
new pickuponduty = AddStaticPickup(...)
public OnPlayerPickUpPickup(playerid,pickup
{
if(pickupid == pickuponduty)
{
//Was soll passieren?
}
}Wo das hin muss, solltest du selber wissen...