Beiträge von Jeffry

    new Float:randomfloat = (random(10)/100);


    Das gibt einfach nur 0 aus, in jedem Fall, da Integers immer auf das drunter liegende Integer abgerundet werden. Da du maximal 9/100 haben kannst => 0,09 => folgt 0.


    So ist es richtig:
    new Float:randomfloat = (float(random(10))/100.0);


    Beachte aber, dass Floats nicht sooo toll sind, meistens kommt da z.B. "0.05999" raus, für 6.0/100.0 .
    Davon abgesehen, wären hier folgende Werte möglich:
    0.00
    0.01
    0.02
    0.03
    0.04
    0.05
    0.06
    0.07
    0.08
    0.09


    Ist das, was du willst?

    Naja, was du machst ist Folgendes (Beispiel Kills):


    • Kills als -1 aus der Datenbank laden.

      Zitat

      [16:38:42] CMySQLHandler::Query(SELECT `Kills` FROM `accounts` WHERE `Name` = 'Fachkraftx3') - Successfully executed.
      [16:38:42] CMySQLHandler::FetchRow() - Return: -1


    • Kills als -1 in die Datenbank speichern.

      Zitat

      [16:39:06] CMySQLHandler::Query(UPDATE `accounts` SET `Kills` = '-1' WHERE `Name` = 'Fachkraftx3') - Successfully executed.



    Also an sich stimmt das. Du hast den Wert (SpielerInfo[playerid][pKills]) einfach nirgends geändert, zwischen Laden und Speichern.

    Hast du dem Spieler auch Werte gegeben, zum Beispiel 10 Kills oder so, bei
    SpielerInfo[playerid][pKills]
    ?


    Wenn ja, dann schalte mal den mysql_debug oder mysql_log mit 1 oder LOG_ALL (je nach Plugin) ein und poste was im Log ausgegeben wird, wenn du den Spieler speicherst.

    Jeffry: Heißt also, dass ein Timer, der ein Loop hat (foreach :)), wesentlich besser ist als ein Timer mit MAX_PLAYERS, danke dir werde ich mir merken :)


    Korrekt, wenn du mit "Timer mit MAX_PLAYERS" sagen willst, dass es für jeden Spieler einen extra Timer gibt.


    Andere Frage, ist es Möglich, einen Spieler an ein Fahrzeug zu attachen?


    Nein.
    Du könntest es nur so machen: http://forum.sa-mp.com/showpost.php?p=1290737&postcount=2232
    Aber ob das so schön aussieht bezweifle ich.

    Eine Frage und zwar, wie ist das mit dem attachen hab sowas nie gemacht und naja will bevor erstmal nachfragen ...
    Sprich ich will an einem Spieler ObjektID: 1550 attachen lassen das diese Money Bag am rücken von dem Spieler hängt .. wie kann ich sowas raus finden ...


    Mit einem Editor:
    http://forum.sa-mp.com/showthread.php?p=2385649
    http://forum.sa-mp.com/showthread.php?t=209234
    http://forum.sa-mp.com/showthread.php?t=196342

    Was ist eigentlich schneller und besser, ein globaler Timer, der alle Spieler durchgeht und abfragt ob Var X = 4 ist oder aber Timer für jeden Spieler (new Timer[MAX_PLAYERS];)? (Knastsystem)
    @Jeffy: was meinst du dazu?


    Ich würde sagen ein Timer mit einem Loop ist besser, wenn nicht sogar wesentlich besser. Ich kann dir auch sagen warum.


    • Ein Timer der alle X Sekunden einen Loop durchführt belastet die CPU nur wenig innerhalb der X Sekunden bis zum Aufruf (ist ja nur 1 Timer), dann kurzzeitig etwas mehr, da er ja MAX_PLAYERS Durchläufe macht.
    • Hat man aber MAX_PLAYERS Timer, die alle X Sekunden aufgerufen werden, dann laufen MAX_PLAYERS Timer gleichzeitig, was bedeutet die CPU muss während der Zwit zwischen dem Aufruf (MAX_PLAYERS-1)-mal mehr Arbeit leisten. Wenn dann einer der ganzen Timer aufgerufen wird, dann wird zwar nur 1/MAX_PLAYERS -stel der Arbeit verrichtet als beim Timer mit Loop, aber (!) es wird ja jeder Timer aufgerufen, somit summiert sich hier die Arbeit wieder auf die selbe auf, nur, dass wir zwischen den Aufrufen eben eine MAX_PLAYERS-Fache CPU-Leistung brauchen.


    => Ein Timer mit Loop ist ressourcentechnisch gesehen besser.

    Freut mich zu sehen, dass es immer wieder Leute gibt die ihr Gesagtes auch darlegen können, Templer gehört da auf jeden Fall dazu! :thumbup:


    Also es muss ein Compilerfehler selbst sein, da er wahrscheinlich vergisst die 2. Variable (Anschaulich an "WaffenLink") nicht umwandelt und an die if-Strukturen (oder andere wie "switch") anpasst. (An der Funktion schon, sonst würde man nicht in einer anderen Funktion es erneut definieren können)


    Genau. Deine Testläufe mit dem crashdetect-Plugin untermauern meine vorherige Aussage noch, dass es ein Fehler im Compiler ist. Ich habe diese Testläufe selbst auch nochmal gemacht und kann das bestätigen. Wie genau der Compiler das macht, da geht es mir wie dir, weiß ich nicht, aber das könnte eine Möglichkeit sein. Letztendlich ist es ja auch egal wie er es macht, er macht es falsch und zwar komplett falsch.
    Der Fehler bleibt auch innerhalb einer Funktion bzw. eines Callbacks, da man das Multi-dimensionale Array in einer anderen Funktion wieder definieren kann.


    Mit 3-dimensionalen Arrays ist es übrigens genau gleich.


    Finde die Tatsache mit der Variable "Waffe" lustig, weil wenn man die Deklaration "Waffen" und die Verwendung weglöscht, erkennt der PAWN Compiler es nicht als "already defined" für Waffe.
    Nebenbei das "already defined" für die Variable "Waffe" erscheint nur, wenn sie oberhalb vom Array initialisiert wird.


    Habe das eben auch nochmal ausprobiert. Es ist tatsächlich so, dass egal was man über einem Multi-dimensionalen Array auf gleicher Ebene (!) definiert hat, der Compiler erkennt es als Error (bereits definiert). Wirklich interessant, denn wenn man es drunter definiert macht es gar nichts aus.


    Noch interessanter wird es hier: (ich habe mir mal eben dein Beispiel geborgt)
    public OnGameModeInit()
    {
    // Don't use these lines if it's a filterscript
    SetGameModeText("Blank Script");
    AddPlayerClass(0, 1958.3783, 1343.1572, 15.3746, 269.1425, 0, 0, 0, 0, 0, 0);


    new test = 5;

    if(test == 5)
    {
    if(test == 5)
    {
    new Waffe;
    new Waffen[10][2];
    Waffen[0][1] = 999;
    printf("DEBUG %d", Waffen[0][1]);


    Waffe = 5;
    printf("DEBUG %d", Waffe);
    }
    }


    if(test == 5)
    {
    new Waffe;
    Waffe = 6;


    printf("DEBUG %d", Waffe);
    }


    return 1;
    }


    => warning 219: local variable "Waffe" shadows a variable at a preceding level


    Es ist jetzt nicht mehr die gleiche Ebene, von der Syntax her passt es immer noch, da es nicht in der gleichen if-Klammer ist, dennoch meint der Compiler es sei schon vorhanden, in diesem Fall aber die Warnung, die normal kommt wenn es in einer tieferen Ebene erneut definiert wird, z.B. so:
    new tmp;
    if(tmp)
    {
    new tmp;
    }

    Hier bekommen wir die Warnung 219.


    Im Beispiel oben mit "Waffe" ist es aber anschaulich dargestellt so:
    new xy;
    if(xy)
    {
    new tmp;
    }
    new tmp;

    Hier findet der Compiler keinen Fehler (ist ja auch korrekt!), abgesehen von den "is never used", die ich hier mal vernachlässige. Durch die nachfolgende Definition eines multi-dimensionalen Arrays wird es plötzlich als falsch erkannt.
    new xy;
    if(xy)
    {
    new tmp;
    new array[10][10];
    }
    new tmp; //219

    => Warnung 219 für tmp.



    Irgendwas bringt den Compiler also mächtig durcheinander, wenn man Multi-dimensionale Arrays innerhalb von Funktionen/Callbacks definiert, auch wenn es von der Syntax her kein Problem sein darf.




    Durch diese Tests und die Tests von Templer sehe ich es als bewiesen an, dass hier ein Fehler im Compiler ist.
    ...und zwar kein kleiner!

    public OnPlayerConnect(playerid)
    {
    new Spielerdatei[164], name[MAX_PLAYER_NAME];
    GetPlayerName(playerid,name,sizeof(name));
    format(Spielerdatei,sizeof(Spielerdatei),"Accounts/%s.txt",name);
    if(dini_Exists(Spielerdatei))
    {
    ShowPlayerDialog(playerid,DIALOG_LOGIN,DIALOG_STYLE_PASSWORD,"Login Vorgang..,","Willkommen auf dem Script Server\nDein Account wurde in der Datenbank Gefunden!\nBitte logge dich mit deinem Passwort ein.","Login","Abbrechen");
    }
    else
    {
    ShowPlayerDialog(playerid,DIALOG_REGISTER,DIALOG_STYLE_PASSWORD,"Registrierungs Vorgang..,","Willkommen auf dem Script Server.\nEs wurde noch kein Account Gefunden!\nBitte gib für die Registrierung ein Passwort ein.","Registrieren","Abbrechen");
    }


    return 1;
    }



    public OnDialogResponse(playerid, dialogid, response, listitem, inputtext[])
    {
    if(dialogid==DIALOG_REGISTER)
    {
    if(response==0)
    {
    SendClientMessage(playerid,0xFF0000FF, "Du hast den Registrierungs Vorgang Abbgebrochen!");
    Kick(playerid);
    }
    if(response==1)
    {
    Register(playerid,inputtext);
    }
    }
    if(dialogid==DIALOG_LOGIN)
    {
    if(response==0)
    {
    SendClientMessage(playerid,0xFF0000FF, "Du hast den Login Vorgang Abbgebrochen!");
    Kick(playerid);
    }
    if(response==1)
    {
    Login(playerid,inputtext);
    }
    return 1;
    }
    return 0;
    }


    stock Login(playerid,key[])
    {
    new Spielerdatei[164], name[MAX_PLAYER_NAME];
    GetPlayerName(playerid,name,sizeof(name));
    format(Spielerdatei,sizeof(Spielerdatei),"Accounts/%s.txt",name);
    if(!strcmp(key,dini_Get(Spielerdatei,"Passwort"),false))
    {
    SendClientMessage(playerid,0xFF0000FF, "Du hast dich Erfolgreich Eingeloggt!");
    }
    else
    {
    ShowPlayerDialog(playerid,DIALOG_LOGIN,DIALOG_STYLE_PASSWORD,"Login VOrgang..,","Willkommen auf dem Script Server\nDein Account wurde in der Datenbank Gefunden!\nBitte logge dich mit deinem Passwort ein.","Login","Abbrechen");
    }
    return 1;
    }
    stock Register(playerid,key[])
    {
    new Spielerdatei[164], name[MAX_PLAYER_NAME];
    GetPlayerName(playerid,name,sizeof(name));
    format(Spielerdatei,sizeof(Spielerdatei),"Accounts/%s.txt",name);
    dini_Create(Spielerdatei);
    dini_Set(Spielerdatei,"Passwort",key);
    return 1;
    }


    2 Klammerfehler
    Passwort benötigt dini_Get, nicht dini_Int
    1 Semikolon zu viel
    1 runde Klammer zu wenig
    stock schreibt man klein
    Einrückung war völlig daneben

    new Float:cPos[7][10][3]; //7 Dateien mit max. 10 CPs
    new vehID[7];
    new Float:vehPos[7][3];
    new picID[7];
    new Float:picPos[7][3];
    new string[128], fstr[16], File:rFile;
    for(new f=0; f<10; f++) //0.txt bis 9.txt
    {
    format(fstr, sizeof(fstr), "%d.txt", f);
    if(fexist(fstr))
    {
    rFile = fopen(fstr, io_read);
    if(rFile)
    {
    new line, i;
    while(fread(rFile, string))
    {
    new idx;
    switch(line)
    {
    case 0: {}
    case 1: vehID[f] = strval(strtok(string, idx));
    case 2:
    {
    vehPos[f][0] = floatstr(strtok(string, idx));
    vehPos[f][1] = floatstr(strtok(string, idx));
    vehPos[f][2] = floatstr(strtok(string, idx));
    }
    case 3: picID[f] = strval(strtok(string, idx));
    case 4:
    {
    picPos[f][0] = floatstr(strtok(string, idx));
    picPos[f][1] = floatstr(strtok(string, idx));
    picPos[f][2] = floatstr(strtok(string, idx));
    }
    case 5: {}
    case 6..15: //max. 10 CPs, ansonsten hier auch erhöhen.
    {
    cPos[f][i][0] = floatstr(strtok(string, idx));
    cPos[f][i][1] = floatstr(strtok(string, idx));
    cPos[f][i][2] = floatstr(strtok(string, idx));
    i++;
    }
    }
    line++;
    }
    }
    fclose(rFile);
    }
    }


    Du kannst den ganzen Kram auch in ein Enum packen, bleibt dir überlassen.

    new Float:cPos[10][3]; //10 CPs
    new i, string[128], fstr[16], File:rFile;
    for(new f=0; f<10; f++) //0.txt bis 9.txt
    {
    format(fstr, sizeof(fstr), "%d.txt", f);
    if(fexist(fstr))
    {
    rFile = fopen(fstr, io_read);
    if(rFile)
    {
    while(fread(rFile, string))
    {
    new idx;
    cPos[i][0] = floatstr(strtok(string, idx));
    cPos[i][1] = floatstr(strtok(string, idx));
    cPos[i][2] = floatstr(strtok(string, idx));
    i++;
    }
    }
    fclose(rFile);
    }
    }

    Hat er sich also doch verschieben. Ich nutze NaviCat nicht, daher keine Ahnung was für was steht, normalerweise weiß das der Ersteller der Datenbank, er hat es ja auch eingegeben. :D
    In phpMyAdmin steht an gleicher Stelle nämlich der Name der Datenbank.


    Danke dir für den Hinweis! :)



    EDIT:
    Post unten: Das Lob gebe ich gerne an @.x22 Zieglein weiter, er hat den entscheidenden Hinweis gegeben. :thumbup:

    Nimm den "root" Benutzer ohne Passwort. Localhost solltest du nehmen, wenn die Datenbank auf dem gleichen Server liegt:


    #define MYSQL_HOST "localhost"
    #define MYSQL_USER "root"
    #define MYSQL_PASS ""
    #define MYSQL_DATA "DATENBANKNAME"


    Das ist in 99% aller Fälle standardmäßig so eingestellt.
    Dein user "samp" wird nicht die richtigen Berechtigungen haben, das ist auf localhost (dein Rechner) so eingestellt, standardmäßig zumindest.
    Deshalb benutze, wie ich oben geschrieben habe, den root - User ohne Passwort, der hat ALLE Berechtigungen. Dem kannst du später auch, je nach Client, ein Passwort geben.