Beiträge von Kaliber

    Hier, schreibs so:


    if(newkeys & KEY_SECONDARY_ATTACK)
    {
    for(new i = 0; i < MAX_TRASH_CANS; i++)
    {
    if(!IsPlayerInRangeOfPoint(playerid, 2.0, TrashCans[i][0], TrashCans[i][1], TrashCans[i][2])) continue;
    if(!AlreadySearching[playerid])
    {
    if(gettime() < TrashCans_ID[i])
    {
    new stringDE[128],stringEN[128];
    format(stringDE, sizeof(stringDE), "»WARNUNG« Diese Mülltonne wurde schon geplündert. Versuche es in %imin noch einmal.", (TrashCans_ID[i] - gettime())/60);
    format(stringEN, sizeof(stringEN), "»WARNING« This trash can has already been emptied. Try again in %imin.", (TrashCans_ID[i] - gettime())/60);
    return SendLanguageMessage(playerid, C_RED, stringDE, stringEN);
    }
    TrashCanLootTimer[playerid] = SetTimerEx("TrashCanLoot", 4000, false, "ii", playerid, i);
    ApplyAnimation(playerid, "BD_FIRE", "BD_Panic_Loop", 4.1, 0, 0, 0, 0, 4000, 1);
    SendLanguageMessage(playerid, C_PINK, "»SPIELER« Du stöberst in der Mülltonne rum...", "»PLAYER« You rummage through the trash...");
    AlreadySearching[playerid] = true;
    }
    else
    {
    TrashCans_ID[i] = 0;
    SendLanguageMessage(playerid, C_RED, "»WARNUNG« Du hast aufgehört im Müll zu wühlen.", "»WARNING« You stopped rummaging through the trash.");
    ClearAnimations(playerid);
    KillTimer(TrashCanLootTimer[playerid]);
    AlreadySearching[playerid] = false;
    }
    }
    }


    //Und dann hier:
    public TrashCanLoot(playerid,i)
    {
    TrashCans_ID[i] = gettime() + 30*60;
    //Du hast die Mülltonne erfolgreich durchsucht
    }


    mfg. :thumbup:

    Mit diesen Angaben, kann man dir schlecht helfen...


    Poste nochmal genau den Teil, wo du dem Spieler Geld gibst...


    Und printe dir Stellenweise doch dein Geld, wahrscheinlich gibst du ihm irgendwo halt nochmal geld oder irgendwas wird doppelt aufgerufen ;)

    Guten Mittag liebe Brotfische :)


    Heute zeige ich euch mal ein kleines, aber sehr nützliches System.


    Funktionen:
    //Normale Array-Funktionen:
    GetArray(string[])<string2[]> //returnt die Daten als String
    GetArrayInt(string[])<string2[]> //returnt die Daten als Int
    GetArrayFloat(string[])<string2[]> //returnt die Daten als Float


    //Index Arrays:
    CountIndexArray(array[]) //Gibt die Anzahl der Elemente im index-Array wieder
    SortIndexArray(array[]) //Sortiert die Elemente
    GetIndexArray(array[])<idx> //Gibt das Element an dem Index wieder (als Integer)


    //Zum Laden:
    LoadArray(Pfad[]);
    LoadArrayEx(Pfad[]+Name[]+Endung[]);
    //returnt den Array als string


    //Zum Speichern:
    SaveArray(Pfad[], Array[]);
    SaveArrayEx(Pfad[]+Name[]+Endung[], Array[]);


    //Zusätzliche Funktion:
    Push(variable, array[]); //schreibt das array in die variable
    //Zusätzliche "Features", siehe unten


    Das sieht etwas wirr aus, also ich versuche euch nun mal zu erklären, was ihr damit alles machen könnt.


    Ein zusätzliches Feature ist, ihr könnt ein Array direkt returnen:


    stock func() return->Array("day: 6;month: 10;year: 2014;");


    Das Array muss immer so aufgebaut sein:


    "xxx: Value;"
    //xxx = Hiernach wird immer gesucht
    //Value = Der Wert, wenn xxx gefunden wurde
    //; = Das Semikolon beendet die eine Spalte des Arrays


    Wie in dem Beispiel gezeigt, kann man dann ganz viele Spalten hintereinander hängen.


    Um uns das Datum korrekt ausgeben zu lassen, können wir einfach das machen:


    //Also fangen wir langsam an:
    new d = GetArrayInt(func())<"day">; //GetArrayInt brauchen wir, da day ja ein Integer (eine Zahl) ist.
    new m = GetArrayInt(func())<"month">; //GetArrayInt brauchen wir, da month ja ein Integer (eine Zahl) ist.
    new y = GetArrayInt(func())<"year">; //GetArrayInt brauchen wir, da year ja ein Integer (eine Zahl) ist.


    printf("Datum: %02d.%d.%d",d,m,y);
    //Output: Datum: 06.10.2014


    Normale Arrays Speichern & Laden:
    Wollen wir ein schlichtes Array speichern, können wir das z.B. so machen:


    new array[] = "day: 6;month: 10;year: 2014;"; //Das ist unser Array
    SaveArray("array.txt",array); //Jetzt speichern wir in der array.txt das array


    //Um das Array wieder zu laden, einfach folgendes machen:
    new array[_b_Data];
    Push(array,LoadArray("array.txt"));
    //Jetzt kann man damit weiter arbeiten, einfach dann so:
    printf("Heute ist Tag: %02d",GetArrayInt(array)<"day">);


    z.B. Spieler Arrays Speichern & Laden:
    Mal ein kleines Beispiel, wie man entweder einen komplexen Pfad oder Spieler ohne format speichern&laden kann:


    new array[] = "geld: 1000;level: 5;"; //Das ist wollen wir jetzt speichern
    new name[] = "Gustav";
    SaveArrayEx("/"+name+".txt",array); //Jetzt speichern wir das direkt in den scriptfiles unter Gustav.txt
    //anderes Beispiel:
    SaveArrayEx("/Accounts/"+name+".ini",array); //Jetzt speichern wir das z.B. unter /Accounts/Gustav.ini
    //Natürlich kann man auch Funktionen anwenden:
    SaveArrayEx("/Accounts/"+GetName(playerid)+".ini",array); //Jetzt speichern wir das z.B. unter /Accounts/Gustav.ini


    //Das Alles was für SaveArrayEx gilt, gilt auch für LoadArrayEx


    //Um das Array wieder zu laden, einfach folgendes machen:
    new array[_b_Data];
    Push(array,LoadArrayEx("/"+name+".txt"));
    //Jetzt kann man damit weiter arbeiten, einfach dann so:
    printf("Du hast %d$",GetArrayInt(array)<"geld">);
    //Output: Du hast 1000$


    Index-Arrays:
    Also, dann zeige ich euch mal, was ihr hiermit alles machen könnt:


    stock func() return->Array("idx: 9, 3, 12,9, 139, 1293, 12");
    So zum Beispiel sähe ein Index-Array aus.
    Ihr müsst es nur mit dem idx: an 1. Stelle kennzeichnen und dann könnt ihr die Variablen zurückgeben.
    Ihr müsst nicht auf Leerzeichen achten, nur das Kommas die Elemente trennen.


    Wichtig: Ein Index-Array darf nur aus Zahlen bestehen und dem idx: an 1. Stelle, sonst funktioniert es nicht.


    Wenn wir jetzt das 1. Element oder 2. Element abfragen wollen, sähe das so aus:


    new first = GetIndexArray(func())<0>;
    new sec = GetIndexArray(func())<1>;
    printf("First: %d | Second: %d",first,sec);
    //Gibt aus: First: 9 | Second: 3


    So, wenn wir das ganze Array mal sortieren wollen, sähe das so aus:


    new tmp[_r_Data];
    Push(tmp, SortIndexArray(func())); //Hier sortieren wir das IndexArray und speichern es in tmp


    //Und jetzt können wir mal alle Elemente Sortiert ausgeben:
    /*
    Kleine Information:
    CountArrayIndex(tmp) gibt 7 wieder, da es 7 Elemente gibt (0-6)
    */
    for(new i,l=CountArrayIndex(tmp); i<l; i++)
    {
    printf("Element: %d | Wert: %d",i,GetIndexArray(tmp)<i>);
    }
    /*
    Das sieht dann so aus:


    Element: 0 | Wert: 3
    Element: 1 | Wert: 9
    Element: 2 | Wert: 9
    Element: 3 | Wert: 12
    Element: 4 | Wert: 12
    Element: 5 | Wert: 139
    Element: 6 | Wert: 1293
    */


    PS: Das Array Index könnt ihr auch ganz einfach so speichern & laden, wie das normale Array.


    Speedtest:
    Also,10.000 Abfragen mit GetArray()<> dauern nur: 15ms
    Und 10.000 Abfragen für das IndexArray sind: 18ms
    Und das speichern und laden, basiert (wenn man sich den Source anschaut) unmittelbar auf den f-Functions, somit kann man das nicht direkt schneller lösen.


    Mal als kleine Information:
    100x das Index Array (Beispiel von oben) zu sortieren, dauert: 2ms (und ich greife auf die Funktion mit dem array zu...)


    Download:
    Source-Code: Pastebin
    Direkter-Download: MediaFire


    Schlusswort:
    Ich würde mich über ein kleines Feedback freuen :)
    Falls Fragen bestehen oder ihr Vorschläge habt, einfach schreiben :)


    mfg. :thumbup:


    //Edit: Link
    //Edit²: ->Array Funktion
    //Edit³: Neue Array-Index Funktionen
    //Edit4: Push Funktion verbessert
    //Edit5/6: Links

    GivePlayerMoney(playerid, mysql_GetInt("accounts", "Geld", "Name", SpielerInfo[playerid][pName]));


    Das solltest du vielleicht so schreiben:


    SpielerInfo[playerid][pGeld] = mysql_GetInt("accounts", "Geld", "Name", SpielerInfo[playerid][pName]);
    GivePlayerMoney(playerid, SpielerInfo[playerid][pGeld]);


    und printe dir das mal, dann weißt du ja, was er macht.


    Wenn pGeld = 0 ist, dann steht in deiner Datenbank auch 0.
    Dann solltest du überprüfen ob PVarInt(playerid,"Eingeloggt") auch wirklich 1 ist und das gespeichert wird.


    mfg. :thumbup:

    Das kannst du so machen:


    new r_Spieler[2][3] = {
    {-1, ...}, {-1, ...}
    };


    for(new i,idx[2]; i<MAX_PLAYERS; i++) {
    if(!IsPlayerConnected(i)) continue;
    if(gTeam[i] == TEAM_BLUE && idx[0] < sizeof r_Spieler[]) r_Spieler[0][idx[0]] = i,idx[0]++;
    if(gTeam[i] == TEAM_GREEN && idx[1] < sizeof r_Spieler[]) r_Spieler[1][idx[1]] = i,idx[1]++;
    }
    //Und dann so:
    if(r_Spieler[0][2] != -1)
    {
    //Nur wenn alle IDs vergeben sind:
    new random_Spieler1 = r_Spieler[0][random(3)];
    }
    if(r_Spieler[1][2] != -1)
    {
    //Nur wenn alle IDs vergeben sind:
    new random_Spieler2 = r_Spieler[1][random(3)];
    }


    mfg. :thumbup:

    Also würde es mich auch freuen, wenn das zufällig mal einer herausgefunden hat.


    Lies doch den Text von Jeffry...


    oder ihr verwendet mal google und findet auf Wikipedia folgendes:


    Zitat von Wikipedia

    Unmittelbar vor dem Übersetzen eines Programms in Maschinensprache fügt der Präprozessor Kopien der benötigten Includes an diejenigen Stellen des Programms ein, die vom Programmierer mit einer Include-Anweisung und dem Namen des jeweiligen Includes gekennzeichnet wurden.


    mfg. :rolleyes:

    //Edit:
    Ich habe mal einen Fix geschrieben für den normalen Chat.


    Ihr kennt das Problem alle, ihr wollt ein % Zeichen schreiben und es kommt nur ein #...


    Das behebt ihr nun so:


    stock _Fix(const string[],bool:chat=false) {
    new tmp[145],pos = strfind(string,"#");
    strcat(tmp,string);
    if(pos == -1) return tmp;
    for(;;) {
    if(tmp[((pos-1) < 0)?0:(pos-1)] != '\\') {
    strdel(tmp,pos,pos+1),strins(tmp,(!chat)?("%%"):("%%%%"),pos,sizeof tmp);
    pos = strfind(tmp,"#",false,pos+((!chat)?(2):(4)));
    }
    else {
    strdel(tmp,pos-1,pos);
    pos = strfind(tmp,"#",false,pos);
    }
    if(pos == -1) break;
    }
    return tmp;
    }


    //Und unter OnPlayerText:
    public OnPlayerText(playerid,text[]) {
    format(text,146,_Fix(text)); //Das muss die 1. Zeile hier sein:
    return 1;
    }


    //Wenn ihr allerdings mit einer eigenen Message arbeitet, dann so:
    public OnPlayerText(playerid,text[]) {
    format(text,146,_Fix(text,true)); //Das muss die 1. Zeile hier sein:
    //Halt unten der Rest
    SendClientMessage(playerid,-1,text);
    return 0;
    }


    Dadurch wird aus dem # ein %...wenn ihr jetzt aber ein normales # inGame schreiben wollt, müsst ihr \# eingeben ;)


    //Fakultät:
    Also, mir ist keine Funktion bekannt und habe auch noch keine gesehen (nicht mal im Englischen Forum), dass man die Fakultät berechnen kann.


    Also, hier eine Funktion, mit der das möglich ist:


    stock fac(x) {
    if(x < 0) return 0;
    if(0 <= x <= 1) return 1;
    if(x==2) return x;
    new y=1,i=x;
    for(; i!=0; i--) y *= i;
    return y;
    }


    //Anwendung:
    new x = 5;
    printf("Die Fakultät von %d ist: %d",x,fac(x));
    //->: Die Fakultät von 5 ist: 120


    Keywords: Fakultät, Factorial


    mfg. :thumbup:


    //Edit: Umbenannt wegen Pille...wobei das völlig egal ist, da man das eh selber kann <(^.^)>
    //Edit²: Prozent-Fix

    Nene


    Achso, dann so:


    ocmd:setmoney(playerid,params[])
    {
    new pID, money;
    if(sscanf(params,"ui",pID,money))return SendClientMessage(playerid,COLOR_RED,"Benutze: /setmoney [PlayerID] [Summe]");
    if(!IsPlayerConnected(pID)) return SendClientMessage(playerid,COLOR_RED,"Ein Spieler mit dieser ID ist nicht online!");
    sSpieler[pID][Geld] += money;
    GivePlayerMoney(pID, sSpieler[pID][Geld]);
    return 1;
    }


    mfg. :thumbup:

    SetMoney, soll also das Geld setzen.


    Sprich wenn du /setmoney 0 5000 eingibst, soll dieser Spieler egal, wie viel Geld er vorher hatte 5000$ haben?


    Wenn ja, dann muss das so aussehen:


    ocmd:setmoney(playerid,params[])
    {
    new pID, money;
    if(sscanf(params,"ui",pID,money))return SendClientMessage(playerid,COLOR_RED,"Benutze: /setmoney [PlayerID] [Summe]");
    if(!IsPlayerConnected(pID)) return SendClientMessage(playerid,COLOR_RED,"Ein Spieler mit dieser ID ist nicht online!");
    ResetPlayerMoney(pID),sSpieler[pID][Geld]= money;
    GivePlayerMoney(pID, money);
    return 1;
    }


    mfg. :thumbup:

    und was bedeuten diese ganzen nummern hier ?


    Ich hab doch extra das Wiki verlinkt...das gibt es auch in Deutsch:


    ApplyAnimation(playerid, animlib[], animname[], Float:fDelta, loop, lockx, locky, freeze, time, forcesync);
    playerid Die ID des Spielers, der die Animation ausführen soll.
    animlib[] Der Name der Bibliothek der Animation.
    animname[] Der Name der Animation.
    fDelta Die Geschwindigkeit der Animation.
    loop 1, um die Animation wiederholen zu lassen, 0, um sie nur ein Mal abzuspielen.
    lockx 0, um den Spieler auf die ursprüngliche X-Position zurückzubringen, nachdem die Animation fertig ist. 1 bewirkt das Gegenteil.
    locky 0, um den Spieler auf die ursprüngliche Y-Position zurückzubringen, nachdem die Animation fertig ist. 1 bewirkt das Gegenteil.
    freeze 0, um den Spieler nach der Animation wieder frei beweglich zu machen, 1, um ihn am Ende der Bewegung "einzufrieren".
    time Länge der Animation in Millisekunden. Wird 0 angegeben, hört die Animation nicht von selbst auf.
    forcesync 1, um die Animation mit allen Spielern zu synchronisieren (in allen Instanzen) (optional).


    mfg. :rolleyes: