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);
    }

    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.


    Zitat

    Habs 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...


    Zitat

    Hey 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".

    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;
    }

    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):

    SQL
    new ondutypickup; /* globale Variable "ondutypickup" erstellen */


    In OnGameModeInit:
    ondutypickup = AddStaticPickup(...) /* Variable eine PickupID zuweisen */


    So nun kannst du überall im Script auf diese variable zugreifen - auch unter OnPlayerPickupPickup

    http://pastebin.com/m5915c242


    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ügen


    2.) 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/m31bc0517


    4.) 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...