Beiträge von Jeffry

    public TextDrawUpdate(wert)
    {
    new string[200];


    format(string,sizeof(string),"Server wird in ~r~%d~w~ restartet",wert);
    TextDrawSetString(Textdraw0,string);
    if(wert>0) SetTimerEx("TextDrawUpdate", 1000, 0, "d", wert-1);
    else {/*Server neu starten.*/ }
    return 1;
    }


    Den Countdown startest du mit
    SetTimerEx("TextDrawUpdate", 1000, 0, "d", 60);


    Du kannst anstatt 1000 auch 875 oder ähnliches nehmen, dann ist es genauer eine Sekunde. Bleibt Dir überlassen.

    Falls du pawno über eine Verknüpfung startest, oder die .pwn Dateien mit einem Doppelklick direkt öffnest, musst du den Pfad zu der pawno.exe aktualisieren. Wenn das nicht hilft, lade dir den ganzen Ordner des RC4 Servers runter, und füg deine Server Files alle in den Ordner ein, danach startest du die pawno.exe des neuen Ordners.
    Nicht vergessen im richtigen Code den bodypart hinzuzufügen.


    Dann sollte es ohne Probleme funktionieren.

    An sich kannst du die Geldwerte nicht ändern. Das Einzige was du machen kannst, ist, abzufragen ob der Spieler in einer Tuning Garage ist, und dadurch zu erkennen, was er ausgegeben hat.


    Du fragst bei OnPlayerUpdate ab, on sich das Geld des Spielers geändert hat. Dazu speicherst du das momentane Geld in einer Spieler Variable und fragst beim nächsten OnPlayerUpdate Aufruf ab, ob es noch gleich ist, wenn es sich um 100 geändert hat fragst du die Position ab, wenn die mit einer der Positionen der Tuning Garagen übereinstimmt, dann hat der Spieler sich etwas gekauft.


    Als weitere Alternative könntest du die Tuning Garagen blockieren und deine eigenen machen.

    enum handp {
    health,
    armour
    }
    new Float:PlayerHPandAP[MAX_PLAYERS][handp];


    stock SavePlayerHPandAP(playerid)
    {
    GetPlayerHealth(playerid, PlayerHPandAP[playerid][health]);
    GetPlayerArmour(playerid, PlayerHPandAP[playerid][armour]);
    return 1;
    }


    stock ReturnPlayerHPandAP(playerid)
    {
    SetPlayerHealth(playerid, PlayerHPandAP[playerid][health]);
    SetPlayerArmour(playerid, PlayerHPandAP[playerid][armour]);
    return 1;
    }


    Mach es mit einem enum. Fertig.

    Danke für deine Mühe, sehr sauberes Tutorial! ;)


    Die ganzen Präfixe, die du bei deiner Variablendeklaration benutzt, verwirren mich etwas, aber das wird schon. Ist doch eher was für Fortgeschrittene einen interaktiven Dialog zu scripten.


    Danke für die Rückmeldung.


    Das kann ich dir gerne erklären:


    g_ - steht für Globale Variablen, das heißt alle Callbacks und Funktionen im Code können darauf zugreifen.
    l_ - steht für Lokale Variablen, das heißt nur die Funktion bzw. das Callback kann auf die Variable zugreifen.
    c_ - steht für einen Counter.


    Natürlich kannst du die auch anders nennen, das bleibt jedem selbst überlassen. :)

    Meiner Meinung nach sollte man die Funktionsweise nicht absichtlich einschränken - auch wenn 2048 Zeichen etwas viel sind.


    Warum nicht? Du kannst mir doch nicht erzählen, dass du bei jedem Dialog einen string mit der Größe 2048 deklarierst. Da wird sich der Compiler aber schnell beschweren, bzw. die RAM, da du jedes mal zig tausende an Bytes verschwendest durch unnötige freie Belegungen.
    Begründung?



    Vielleicht weil diese vorgehensweise in nächsten SA:MP Versionen nicht unbedingt unterstützt werden muss?
    Sowas kann durchaus als Sicherheitslücke eingestuft werden.


    Ich musste mir grade 10 mal ins Gesicht schlagen um sicher zu gehen, dass ich richtig gelesen habe.
    Wie in aller Welt soll denn das bitte eine Sicherheitslücke sein?
    Und "vielleicht wird es nicht mehr unterstützt"? Ernsthaft? Vielleicht wird in SA:MP 1.0 SendClientMessage nicht mehr unterstützt, vielleicht geht die Welt morgen unter, vielleicht regnet es heute Nacht Pizza. :pinch:
    Also bitte, wenn du solche Aussagen machst, dann begründe die doch wenigstens im Ansatz.


    (Übrigens: Pizza-Regen kann durchaus auch als Sicherheitslücke in der Biosphäre der Erde eingestuft werden!)

    Das liegt (mal wieder) an dem sscanf Plugin. Das schießt dir deinen Server ab, wenn du versuchst ein String einem Integer zuzuweißen.
    sscanf ganz einfach nicht benutzen, dann funktioniert vielleicht mal ein Befehl nicht, dann aber auf Windows und Linux, und es zerlegt dir den Server nicht.


    Wie gesagt:


    sscanf :thumbdown:


    strtok :thumbup:

    So, jetzt hatte ich die Möglichkeit das ganze zu kompilieren. Ich ziehe meinen Rückzug zurück (wie auch immer...). Leider kann ich den gelöschten Post nicht wiederherstellen, aber was ich zu Anfang sagte, dass es an der Definition innerhalb des Enumerators liegt ist korrekt! Dies behebt alle Errors.


    Ursprünglich sagte ich:
    Der Fehler liegt daran, dass man keine Vordefinitionen in Enumeratoren machen kann. Mache daher aus:
    bool:waktiv = false
    Das hier:
    bool:waktiv


    Damit wäre der Fehler behoben.



    Hier der korrekte Beweis:
    Mit der Vordefinition:


    Ohne:



    Alle vorherigen "Beweise" müssen fehlerhaft, bzw. nicht korrekt ausgeführt, gewesen sein.



    Cydia: Nein, das ist nicht der Fall, da der Compiler Case-Sensitive ist. Beweis: http://pokit.org/get/img/a4c39…0f2606c35149a3913fbbc.jpg

    TheAmazingFlash:
    Ich kann dir ganz ehrlich sagen: sscanf ist Scheiße. Punkt.
    Grund: Genau deshalb. Es hat unerklärliche Fehler.


    Benutze strtok, damit hast du viel mehr Möglichkeiten.
    dcmd_mute(playerid,params[])
    {
    new pID, time, String[144];
    if (AccountInfo[playerid][AdminLevel] >= 2 || IsPlayerAdmin(playerid))
    {
    new tmp[20], tmp2[20], tmp3[20], idx;
    tmp = strtok(params, idx); tmp2 = strtok(params, idx); tmp3 = strtok(params, idx);
    if(!strlen(tmp3)) return SendClientMessage(playerid,ROT,"USAGE: /Mute [playerid] [Zeit in Minuten] [Grund]");
    pID = strval(tmp);
    if(!IsPlayerConnected(pID)) return SendClientMessage(playerid,ROT,"Spieler nicht verbunden.");
    new zeit = strval(tmp2);
    format(String,sizeof(String), "Administrator %s hat %s für %d Sekunden gemutet! Grund: %s", SpielerName(playerid), SpielerName(pID), zeit, params[strlen(tmp) + strlen(tmp2) + 2]);
    SendClientMessage(playerid, ROT, String);
    mute[pID] = 1;
    SetTimerEx("unmute", zeit*1000, false, "i", pID);
    }
    else SendLanguageMessage(playerid, ROT, "FEHLER: Du bist nicht berechtigt diesen Befehl zu benutzen!","ERROR: You aren't authorized to use this command!");
    return true;
    }


    http://wiki.sa-mp.com/wiki/Strtok



    sscanf :thumbdown:


    strtok :thumbup:

    Simon: Ja, es gibt die Möglichkeit dazu. Die einzige Einschränkung ist, dass die Variable nicht beides mal "Array" heißen darf, das sollte aber klar sein.


    Beispiel:
    new Array1[MAX_PLAYERS][50];
    new Array2[MAX_PLAYERS][25];
    for(new i=0; i<MAX_PLAYERS; i++) for(new j=0; j<25; j++) Array2[i][j] = Array1[i][j];


    Das würde die ersten 25 Werte des Array1 für jeden Spieler in Array2 schreiben. Array2 wäre dann "voll".


    Eine andere Methode ist mir nicht eingefallen, falls es eine bessere Möglichkeit gibt würde die mich auch interessieren.

    Beavis: Ich danke dir für den Test. Da es mit strings nicht geht, bin ich davon ausgegangen, dass es auch für andere Typen nicht geht. Das war falsch. Anscheinend interessiert es den Compiler nicht.
    Es "funktioniert" nicht, weil der Wert dem enum-Wert zugeordnet wird, und nicht der variable an sich. Den Compiler stört es nicht. Gut zu wissen.


    Cydia: Ich nehme meine Aussage zurück, sorry. Trotzdem solltest du darauf achten, Begründungen beizusteuern. ;)


    Sofern bis heute Abend noch keine Lösung vorhanden ist, werde ich mich genauers damit beschäftigen.





    EDIT: Nach eigenem Test stellt sich heraus, dass es NICHT möglich ist, wie Anfangs gesagt. Siehe Posts weiter unten.

    Naja, das erklärt nicht den Error.
    Aber warum sollte es nicht funktionieren, wenn ich es auf True stelle ? etc.


    Wenn du keine Ahnung hast, dann unterlasse doch bitte solche unbegründeten Aussagen.
    Was ich beschrieben habe erklärt sehr wohl den Error, weil vordefinierte Werte in Enumeratoren nicht möglich sind. Das ist eine Tatsache. Falls du anderer Meinung bist, begründe diese bitte, bzw. füge einen Beweis dazu, anstatt falsche Behauptungen auszustellen.
    ...Das scheint zur Zeit zur Mode hier zu werden.

    new farbe;
    switch(zaehler)
    {
    case 0: farbe = 0x00000000;
    //...
    }
    PlayerTextDrawColor(playerid,SchwarzeBox[playerid],farbe);


    farbe ist die Variable die die Farbe speichert und dann dem Textdraw setzt.


    ...

    Du solltest lernen zu kopieren...


    Meins:
    case 0: farbe = 0x00000000;
    Deins:
    case 0: 0x00000000;


    Erkennst du den Fehler?


    farbe = Farbe
    zaehler = Der Zähler, damit der switch weiß, welche Farbe er nehmen soll.


    Beides sind Integer Werte.



    Case 16 war zwei mal vorhanden. Ausgebessert.

    Das 0x000000** ist die Farbe. ** steht für den Alpha Kanal, also von 00 bis FF (Hexadezimal). Du zählst einfach von 00 nach FF hoch, 256 cases (0-255). Das werde ich dir nicht machen.


    Hex: 0123456789ABCDEF
    Genauso zählen wie mit 0-9, nur dass du noch die Buchstaben mit nimmst.

    Dann eben noch höher setzen und die Stream Distance noch kleiner machen. Gleichzeit kannst du auch für die Objekte die Stream Distance größer machen, die sollte größer als die der Autos sein. Dann wird es auch gehen, wenn nicht, machst du was anderes als das was ich gesagt habe, weil so funktioniert es, das mach ich selbst so.