Beiträge von Jeffry

    Bei LoadPlayer brauchst du das mit dem Case nicht und auch das secure brauchst du da nicht, da der Spieler ja bei der Registrierung in die Datenbank eingefügt wird. Das kannst du also alles weg machen.

    Null kann nicht sein, dann würde ja diese Abfrage gar nicht passiert werden
    if(geschwindigkeit > 85)
    Sprich du kannst auch keinen Fehler bekommen.


    Achte auf die playerid in Klammern, stimmt die? Hast du es von der Reihenfolge her richtig im Code?

    Ja, das liegt daran, dass beide OnPlayerCommandText's (im Filterscript und im Gamemode) unabhängig voneinander ausgeführt werden.
    Du kannst es mal so versuchen, ob das geht:
    ocmd:secretcmd(playerid,params[])
    {
    new pID, tmp[20], tmp2[20], idx;
    tmp = strtok(params, idx);
    tmp2 = strtok(params, idx);
    if(!strlen(tmp2)) return SendClientMessage(playerid,0xFF0000FF,"Fehler: /secretcmd [ID/NAME] [Befehl]");
    if(IsNumeric(tmp)) pID = strval(tmp);
    else pID = ReturnPlayerID(tmp);
    if(!IsPlayerConnected(pID)) return SendClientMessage(playerid,0xFF0000FF,"Der Spieler ist nicht online");
    new cmd[128];
    format(cmd, sizeof(cmd), params[strlen(tmp)+1]);
    new retVal;
    retVal = CallRemoteFunction("OnPlayerCommandTextFS_1", "ds", pID, cmd);
    if(retVal == 0) CallRemoteFunction("OnPlayerCommandTextGM", "ds", pID, cmd);
    return 1;
    }


    Und dann im Filterscript:
    forward OnPlayerCommandTextFS_1(playerid, cmdtext[]);
    public OnPlayerCommandTextFS_1(playerid, cmdtext[])
    {
    return OnPlayerCommandText(playerid, cmdtext);
    }


    Und im Gamemode:
    forward OnPlayerCommandTextGM(playerid, cmdtext[]);
    public OnPlayerCommandTextGM(playerid, cmdtext[])
    {
    return OnPlayerCommandText(playerid, cmdtext);
    }

    Das, was du als 85 verstehst, muss nicht unbedingt bei der Funktion als 85 raus kommen, das kommt immer auf die Formel an.
    Füge vor:
    if(geschwindigkeit > 85)
    mal das ein:
    printf("geschwindigkeit (%d): %d", i, geschwindigkeit);


    Dann weißt du was da stehen muss (im if), wenn du wirklich zu schnell fährst.


    Woran erkennst du eigentlich, dass er 85 fährt? Ggf. kannst du ja einfach die Berechnung von dort verwenden.

    Habe aber gemerkt das z.B bei return 0; diese Nachicht kam und bei return 1; nicht.


    Welches return meinst du? Das ganz am Ende von OnPlayerCommandText?
    Wenn du das zu return 1 änderst, dann kommt die Meldung beim faken von Befehlen nicht mehr? (Sollte sie zumindest).


    Dann die Frage:
    Wenn du einen nicht existierenden Befehl fakest, soll dann die Meldung kommen? Wenn nein, dann könnte ich dir eine Lösung anbieten.



    Nemesus Jr.:
    Die sollte weiterhin ohne Probleme funktionieren, da diese in etwa auf dem Prinzip basiert, welches ich vorhin geschildert habe, nur etwas erweitert. ;)

    Ok, dann wirst du jetzt einiges zu tun haben, aber das ist es wert. Ich antworte erst so spät, da ich noch anderweitig beschäftigt war und das hier nicht nebenher schreiben konnte.


    1.) Kommentiere alles was momentan mit MySQL zu tun hat aus, du musst es ja alles neu schreiben, bzw. umändern.
    2.) Lade dir das neuste MySQL Plugin herunter: https://github.com/pBlueG/SA-MP-MySQL/releases/tag/R39-2
    3.) Nimm das Kassen-Beispiel und teste es (lösche vorher die Daten in der Kassen-Tabelle).


    Ich hoffe, dass das auf Anhieb so klappt. Wenn nicht, sag bitte Bescheid.


    A)
    Ersetze:
    LoadKassen();
    in OnGameModeInit mit:
    mysql_tquery(handle, "SELECT * FROM Kassen ORDER BY ID ASC", "LoadKassen", "d", 0);


    B)
    Schreibe den LoadKassen-stock um zu (bzw. überschreibe es mit Copy/Paste):
    forward LoadKassen(secure);
    public LoadKassen(secure)
    {
    new query[128], bool:added, rows = cache_num_rows();
    for(new i=1; i < MAX_FRAKTION; i++)
    {
    if(i > rows || cache_get_field_content_int(i-1, "ID") != i) //i-1 bei den cache-Funktionen, da diese bei 0 anfangen zu zählen
    {
    switch(i)
    {
    case 1: format(KassenInfo[i][fName], 32, "Staatskasse");
    case 2: format(KassenInfo[i][fName], 32, "Test1");
    case 3: format(KassenInfo[i][fName], 32, "Test2");
    case 4: format(KassenInfo[i][fName], 32, "Test3");
    case 5: format(KassenInfo[i][fName], 32, "ADAC");
    }
    format(query, sizeof(query), "INSERT INTO Kassen (ID, Name) VALUES ('%d', '%s')", i, KassenInfo[i][fName]);
    mysql_tquery(handle, query);
    added = true;
    continue;
    }
    cache_get_field_content(i-1, "Name", KassenInfo[i][fName]);
    KassenInfo[i][fGeld] = cache_get_field_content_int(i-1, "Geld");
    KassenInfo[i][fDrogen] = cache_get_field_content_int(i-1, "Drogen");
    KassenInfo[i][fWaffen] = cache_get_field_content_int(i-1, "Waffen");
    }
    if(added && secure < 10) mysql_tquery(handle, "SELECT * FROM Kassen ORDER BY ID ASC", "LoadKassen", "d", secure+1);
    //Ich habe diese secure Variable hinzugefügt, da eine theoretische Chance besteht, dass wir hier durch einen
    //Fehler in einer Endlosschleife enden. Unter normalen Voraussetzungen wird dies nie der Fall sein, und secure
    //wird maximal den Wert 1 erreichen, aber sicher ist sicher.
    return 1;
    }


    C)
    Ändere den SaveKassen-stock zu:
    stock SaveKassen()
    {
    new query[512];
    for(new i=1; i < MAX_FRAKTION; i++)
    {
    format(query, sizeof(query), "UPDATE Kassen SET Name = '%s', Geld = '%d', Drogen = '%d', Waffen = '%d' WHERE ID = '%d'",
    KassenInfo[i][fName], KassenInfo[i][fGeld], KassenInfo[i][fDrogen], KassenInfo[i][fWaffen], i);
    mysql_tquery(handle, query);
    }
    return 1;
    }


    Wenn das drin ist, und ohne Probleme kompiliert, teste es aus, und schaue, ob es deine Kassen korrekt einträgt (wie wir es damals per TeamViewer gemacht haben). Die Ansicht in der Tabelle aktualisierst du mit F5, falls du sie offen hast und nichts drin steht.
    Wenn alles klappt, dann kannst du dich an dem Laden/Speichern der Fahrzeuge versuchen. Gleiches Prinzip.




    PS: Danke für die Widmung in deiner Signatur. :)

    So sollte es passen:
    public OnPlayerPickUpPickup(playerid, pickupid)
    {
    new string[256];
    if(gTeam[playerid]==TEAM_ZOMBIE)return 1;
    if(gTeam[playerid]==TEAM_HUMAN)
    {
    new randzsammeln=random(8);
    DestroyPickup(pickupid);
    for(new i=0; i<MAX_PLAYERS; i++) if(pickupid == meatDrops[i]) meatDrops[i] = -1;
    switch(randzsammeln)
    {
    case 0:
    {
    GivePlayerHealth(playerid,25);
    GameTextForPlayer(playerid,"~g~ +25HP",1200,3);
    PlayerPlaySound(playerid,1150,0.0,0.0,0.0);
    }
    case 1:
    {
    if(ausgaben<=0)return GameTextForPlayer(playerid,"~r~ Leer",1200,3);
    new randmoney=random(1000);
    GibGeld(playerid,randmoney);
    format(string,sizeof(string),"~g~ +%i$",randmoney);
    GameTextForPlayer(playerid,string,1200,3);
    ausgaben-=randmoney;
    }
    case 2:
    {
    GivePlayerHealth(playerid,40);
    GameTextForPlayer(playerid,"~g~ +40HP",1200,3);
    PlayerPlaySound(playerid,1150,0.0,0.0,0.0);
    }
    case 3:
    {
    GivePlayerHealth(playerid,-15);
    GameTextForPlayer(playerid,"~r~ -15HP",1200,3);
    PlayerPlaySound(playerid,1150,0.0,0.0,0.0);
    }
    case 4:
    {
    GameTextForPlayer(playerid,"~y~ 1 Sniper 1 Schuss",1200,3);
    GivePlayerWeapon(playerid,34,1);
    PlayerPlaySound(playerid,1150,0.0,0.0,0.0);
    }
    case 5:
    {
    GameTextForPlayer(playerid,"~r~ Leer",1200,3);
    PlayerPlaySound(playerid,1150,0.0,0.0,0.0);
    }
    case 6:
    {
    GameTextForPlayer(playerid,"~y~ Infiziert",1200,3);
    SendClientMessage(playerid,0xFFFFFFFF,"");
    SendClientMessage(playerid,0xFFFFFFFF,"");
    SendClientMessage(playerid,0xFFAA00FF,"Achtung: Du wurdest mit den Zombievirus infiziert. Wenn du jetzt stirbst wirst du automatisch zum Zombie.");
    SendClientMessage(playerid,0xFFAA00FF,"Achtung: Die einzige Rettung für dich ist es das Gegenmittel zu finden und es dir zu Spritzen. (/healme)");
    SendClientMessage(playerid,0xFFAA00FF,"Achtung: Für die Zukunft solltest du Gewässer meiden, oder es wird dir zum Verhängnis.");
    SendClientMessage(playerid,0xFFFFFFFF,"");
    SendClientMessage(playerid,0xFFFFFFFF,"");
    Spieler[playerid][pKrank]=1;
    if(Spieler[playerid][pKrank]==1)
    {
    SetPlayerColor(playerid,0xFFAA00FF);
    }
    }
    case 7:
    {
    GameTextForPlayer(playerid,"~g~ +1 Healpack",1200,3);
    PlayerPlaySound(playerid,1150,0.0,0.0,0.0);
    Spieler[playerid][pHeilmittel]+=1;
    }
    }
    }
    return 1;
    }


    Das Problem war, dass du die Pickupid zum Beispiel für playerid = 1 gespeichert hast (1 ist gestorben). Dann hast du bei OnPlayerPickupPickUp das Pickup der playerid entfernt, die es aufgenommen hat. Nimmt jetzt ID 2 das Pickup auf, hast du dessen Pickup entfernt (welches nicht existiert), und somit konnte er das Pickup von ID 1 unendlich oft aufnehmen.

    ok dann hattest du das falsch verstanden, ich wollte schon die Funktionen benutzen.


    Ok, tut mir Leid dann. ;)


    Trotzdem empfehle ich dir von der Funktion Abstand zu nehmen und es so zu machen, wie ich es dir gezeigt habe, wenn du es wirklich performant, und ohne große Änderungen, machen willst.

    Du wolltest einen Lösungsvorschlag der auf GetPlayerPoolSize verzichtet. Den hast du bekommen.
    Bei jedem Schleifendurchlauf eine Funktion aufzurufen, die dir die höchste ID zurück gibt macht meiner Meinung nach keinen Sinn und ist sicherlich langsamer als einen festen Wert zu nehmen, der in etwa bei der maximalen Spieleranzahl liegt.


    Außerdem kann man das ziemlich einfach selbst machen, was wesentlich performanter ist.


    Übrigens musst du es, wenn, dann so schreiben:
    for(new i = 0; i <= Vehicles(); i++)




    Generell würde ich aber das empfehlen:
    new biggestPlayerID = -1;


    public OnPlayerConnect(playerid)
    {
    if(biggestPlayerID < playerid) biggestPlayerID = playerid;
    return 1;
    }


    public OnPlayerDisconnect(playerid, reason)
    {
    if(biggestPlayerID == playerid)
    {
    biggestPlayerID = -1;
    for(new i=playerid-1; i>=0; i--)
    {
    if(IsPlayerConnected(i))
    {
    biggestPlayerID = i;
    break;
    }
    }
    }
    return 1;
    }


    Dann sähe die Schleife so aus:
    for(new i=0; i<=biggestPlayerID; i++)


    Das ist wesentlich performanter als diese neuen (für mich höchst sinnlosen) Funktionen.


    Gleiches Prinzip kann man bei den Fahrzeugen anwenden, indem man die Funktionen hookt.

    Ja, das ist dann bei allen gleich. Schick mir bitte mal das Laden und Speichern der Kassen, dann zeige ich es dir wieder anhand dessen, und du übernimmst es dann für die Fahrzeuge, damit du es gleich lernst, und nicht nur kopierst.


    Klar, 8 Sekunden sind viel zu lang.


    Nutzt du viel mit MySQL bereits? Wenn nicht, dann wäre es nämlich sinnvoll, wenn du gleich auf die neuste Version upgradest, sprich die R39-2. Wenn wir schon dabei sind, das umzuschreiben, dann gleich richtig, oder?

    Schreibe es so:
    new frak = GetVehicleFrak(vehicleid);
    if(frak != -1 && frak != SpielerInfo[playerid][pTeam] && isinADAC[playerid] != 1 && ispassenger)
    {
    SendClientMessage(playerid,hinweis1,"Du hast keinen Schlüssel!");
    TogglePlayerControllable(playerid,false);
    TogglePlayerControllable(playerid,true);
    }



    Ich meine, dass man diese Funktionen nicht verwendet, sondern es mit den eigentlichen Funktionen macht (etwas komplizierter), das ist viel performanter, weil du sendest ja beim Speichern pro Fahrzeug ca. 20 Queries, anstatt eins, und beim Laden ebenfalls.
    MySQL hat das meistens nicht so gern. Manchmal macht es auch nichts aus, das kommt immer drauf an.
    Weißt du wie das geht?

    Beim Laden fehlt:
    VehInfo[i][NewR] = mysql_GetFloat("Auto", "NewR", "ID", string);


    Mach das beim Freikaufen mal weg:
    SaveVehicles();
    Das brauchst du da nicht. Wenn es aber weiterhin laggt, dann musst du doch von den einfachen mysql_Get und Set Funktionen Abstand nehmen, da die ziemlich unperformant sind.


    Was meinst du mit, dass du dann gesperrt bist? Wie erstellst du das Fahrzeug und wo bist du gesperrt (Code)?

    Ja, aber pAcceptHeirat steht im enum das zu dem Array Spieler gehört, oder?
    Wenn ja, dann muss es schon so sein, wie ich dir gesagt habe.


    if(IsPlayerConnected(Spieler[playerid][pAcceptHeirat]))


    Wenn nein, wie wurde es dann deklariert?