Beiträge von Kaliber

    Lass doch lieber die Größe des Arrays bzw die Enum Größe übergeben.


    //Edit:
    Aber...dann müsste man immer einen parameter noch mitgeben nämlich p_DATA


    oder hast du eine Idee...wie man auf den Namen vom Enumerator schließen kann oder anders die Größe abfragen kann? :huh:

    Ist ja cool, aber gibt es auch die Möglichkeit dann die Werte offline mit einem Befehl zu editieren?


    Oh stimmt, daran habe ich noch gar nicht gedacht :D


    Ich editiere mal den Thread, habe gerade eine Funktion dafür geschrieben ;)


    Danke für die Information :)


    Wenn das Ding funktioniert, ist es sehr nützlich


    Tut es..habe es ja schließlich getestet :rolleyes:


    mfg. :thumbup:

    Guten Nachmittag Liebe Brotfische :)


    Ich stelle euch nun mal ein System vor, mit dem es extrem einfach ist Daten zu speichern und zu laden.


    Also, das alles basiert einfach auf einem Enumerator:


    C
    enum p_DATA
    {
    	pMoney,
    	pLevel,
    	Float:pX,
    	Float:pY,
    	Float:pZ,
    	pName[MAX_PLAYER_NAME]
    };
    new SpielerInfo[MAX_PLAYERS][p_DATA];

    Also in diesen Enumerator, packen wir alle SpielerDaten die wir für den Spieler speichern wollen :)


    So und sagen wir, wir geben dem jetzt mal paar Werte, wenn der Spieler connected:


    C
    SpielerInfo[playerid][pMoney] = 5000;
    SpielerInfo[playerid][pLevel] = 5;
    SpielerInfo[playerid][pX] = 300.5;
    SpielerInfo[playerid][pY] = 6000.3;
    SpielerInfo[playerid][pZ] = 1002.94;
    format(SpielerInfo[playerid][pName],MAX_PLAYER_NAME,"Kaliber");


    Und wenn wir diese unter OnPlayerDisconnect speichern wollen, einfach folgende Zeile:


    C
    Save(playerid,p_DATA,SpielerInfo[playerid]);

    Das wars, diese eine Zeile, speichert alles was in diesem Enumerator ist :)


    Ich hoffe es wird klar, wieso das Easy Save heißt ^^


    Und zum Laden einfach folgende Zeile:


    C
    Load(playerid,p_DATA,SpielerInfo[playerid]);


    Also, damit sollte es nun wirklich jeder hinbekommen Variablen zu sichern :D


    Editierung:
    Angenommen, ein Spieler ist nicht gerade online und man will einen Wert editieren, nehmen wir jetzt mal im oberen Beispiel das Geld, dann macht man folgendes:


    C
    Edit("Kaliber.txt",1,10000);
    /*
        Kaliber.txt = Der Pfad von der Spielerdatei
        1 = Die erste Variable im Enum, also das Geld
        10000 = Der neue Geldwert, den der Spieler haben soll
    */


    Um Offline Daten von einem Spieler Abzufragen, das geht leider nur mit Floats und Integern.
    Strings kann man wegen dieser Methode leider nicht auslesen:


    C
    new kaliber_geld = strval(Get("Kaliber.txt",1)); //Hat jetzt einen Wert von 5000 (wegen oben)


    Zusatz-Informationen:
    Angenommen wir Speichern die Werte, die ich oben angegeben habe, dann sieht unsere Datei so aus:

    Code
    5000|5|300.5000|6000.2998|1002.9400|75|97|108|105|98|101|114|


    Nicht wundern, dass ist alles richtig so :D


    Wenn ihr das printet, kommt schon am Ende Kaliber wieder beim Namen raus, nur ich zerlege die chars in zahlen von der Ascii-Tabelle :)
    Aber das setzt sich alles wieder richtig zusammen :)


    Speedtest:
    Also, leider kann man hier keinen guten Speedtest zum speichern machen, aber zum Laden, ich denke die Werte sind ziemlich ähnlich:

    Code
    10.000x Loaded in 60ms
    100.000x Loaded in 300ms


    Pfad Speicherung:
    Also, das hier ist ein Spieler-Daten Speicherungssystem :)


    Ihr könnt den Pfad selbst festlegen und auch welche Endung die Datei haben soll:


    #define PATH "/Accounts/%s.ini"
    #include <k_save>
    Jetzt würde das zum Beispiel im Ordner Accounts als .ini Datei gespeichert werden.
    Wenn ihr aber dieses define nicht setzt, wird einfach der Name.txt in den scriptfiles gespeichert :)


    Download:
    Pastebin: http://pastebin.com/nnLN10Z2
    Mediafire: https://www.mediafire.com/?tory1a375eeqsr0


    Viel Spaß damit, ich würde mich über ein kleines Feedback freuen :)


    mfg. :thumbup:


    //Edit: Editierung
    //Edit²: Fehler im in der Editierung gewesen
    //Edit³: Informationen zu MAX_VARS
    //Edit4: Get Methode
    //Edit5: MAX_VARS verbessert einfach enum namen eingeben oder sizeof(SpielerInfo[])
    //Edit6: Neue Downloadlinks & Anpassung der Path Größe vom Array
    //Edit7: fclose bei der Load Methode vergessen
    //Edit8: Kleiner Fehler mit dem NUL Terminator

    [19:14:39] *** Streamer Plugin: Warning: Include file version (0x26104) does not match plugin version (0x26105) (script might need to be recompiled with the latest include file)


    Aktualisiere mal deine Include, damit das mit der Plugin Version übereinstimmt ;)


    mfg. :thumbup:

    Hey, ich habe hier auch mal einen interessanten Codeschnipsel :)


    Damit könnt ihr bestimmen, welchen Typ eine Variable hat:


    #define INVALID -1
    stock GetVarType({Float,_}:...) {
    if(numargs() != 1) return INVALID;
    static buffer[16],tmp[16];
    format(tmp,sizeof tmp,"%.02f",getarg(0,0));
    if(strcmp(tmp,"0.00") != 0 && strfind(tmp,".") != -1) return 1;
    for(new i; i<sizeof buffer; i++) buffer[i] = getarg(0,i);
    return (strlen(buffer) >= 2) ? 0 : 2;
    }
    #undef INVALID


    //Nutzen kann man es so:
    new x=500,buffer[32];
    switch(GetVarType(x)) {
    case 0: strcat(buffer,"String.");
    case 1: strcat(buffer,"Float.");
    case 2: strcat(buffer,"normaler Integer.");
    case -1: strcat(buffer,"Invalide Variable!");
    }
    printf("Variable x ist ein %s",buffer);
    //->Output: Variable x ist ein normaler Integer.


    mfg. :thumbup:

    Was gut und was schlecht ist, ist doch immer Geschmackssache, ich denke, dass musst du dir schon selber anschauen und entscheiden.


    Gehe die einzelnen Threads doch in Ruhe durch und teste evtl die einzelnen Skripts kurz:


    click


    mfg. :thumbup:

    Ich hoffe du weißt das die ausgabe sich nicht auf einen dialog bezieht und SendClientMessage ein ausgaben limit von 168 oder mehr zeichen hat.


    Daher versetze die erste ausgabe des strings vor die schleife
    entferne den zeilenbruch in format und verschiebe SendClientMessage an diese Position, welches den formatierten String enthält.


    (Mit dem Handy online)


    Gutes Argument, gar nicht darauf geachtet...dann sollte er es so schreiben:


    COMMAND:admins(playerid)
    {
    new string[12 + MAX_PLAYER_NAME];
    for(new i,l=GetMaxPlayers();i<l;i++) {
    if(!IsPlayerConnected(i) || !User[i][Admin])continue;
    if(!string[0]) SendClientMessage(playerid,GRAU,"Admins online:");
    format(string,sizeof string,"%s: %s",Adminrang[User[i][Admin]],PlayerName(i));
    SendClientMessage(playerid,GRAU,string);
    }
    return (!string[0]) ? SendClientMessage(playerid,GRAU,"Es sind keine Admins Online!") : 1;
    }


    mfg. :thumbup:

    symbol is assigned a value that is never used: "neulingsinfo"


    Hat aber nichts mit meinem Code zu tun :rolleyes:


    Nur du brauchst die PickupID nicht in einer Variable speichern, also lösche folgendes:


    new neulingsinfo; //<< brauchst du nicht! also löschen
    neulingsinfo = CreatePickup //neulingsinfo = auch löschen..nur CreatePickup stehen lassen


    Sonst bringt das Pickup ja nichts.


    Es soll doch auch nur zur Information da sein...denke ich, weil er doch zeigen will, dass man nur da den Befehl nutzen will?


    mfg. :thumbup:

    Kannst du einfach so machen:


    ocmd:neuling(playerid) {
    if(!IsPlayerInRangeOfPoint(playerid,3.0,369.7458,-2049.3774,7.8359)) return SendClientMessage(playerid,-1,"Du befindest dich nicht in der Nähe vom Neulings-Pickup!");
    return ShowPlayerDialog(playerid,DIALOG_NEULINGSHILFE, DIALOG_STYLE_MSGBOX,"Neulingshilfe","Hallo und Herzlichen willkommen auf RGR!\n\nHier schon mal einige wichtige Befehle für den Anfang:\n/roller -->Neulingsroller (nur für Level1)\n/navi --> Navigationsmenü\n/sup -->Supportticket an Admins/Supporter\n\nweiter Befehle findest du unter /help!\nBitte beachte unsere Serverregeln im Forum!","Alles Klar","");
    }


    mfg. :thumbup:

    Probier das mal so.


    Das ist aber nicht sehr schön :S


    Schau mal:


    for(new i=0;i<GetMaxPlayers();i++)


    Ganz schlechte Zeile. Hier fragt er immer wieder den Wert von GetMaxPlayers() ab...besser und schneller wäre deshalb:


    for(new i,l=GetMaxPlayers();i<l;i++)


    Desweiteren, wäre es so besser:


    COMMAND:admins(playerid)
    {
    new string[(12+MAX_PLAYER_NAME) * 5]; //5 = Anzahl der Admins, wenn es mehr gibt, erhöhen
    for(new i,l=GetMaxPlayers();i<l;i++) {
    if(!IsPlayerConnected(i) || !User[i][Admin])continue;
    format(string,sizeof string,"%s\n%s: %s",string,Adminrang[User[i][Admin]],PlayerName(i));
    }
    if(!string[0]) return SendClientMessage(playerid,GRAU,"Es sind keine Admins Online!");
    SendClientMessage(playerid,GRAU,"Admins online:");
    SendClientMessage(playerid,GRAU,string);
    return 1;
    }


    mfg. :thumbup:

    Niemand kann den Command nutzen ;/


    Probiere es mal so:


    CMD:pay(playerid, params[])
    {
    new pID, mon, string[128];
    if(sscanf(params, "ud",pID, mon)) return SyntaxMessage(playerid, "/pay [playerid/name] [amount]");
    if(mon > 1000 && PlayerInfo[playerid][pLevel] < 3) return SendClientMessage(playerid, GREY, " You must be level 3 to pay more than $1,000 at a time.");
    if(mon < 1 || mon > 50000 && PlayerInfo[playerid][pAdmin] < 1337) return SendClientMessage(playerid, GREY, " You cannot pay under $1 or more than $50,000 at a time.");
    if(!IsPlayerConnected(pID)) return SendClientMessage(playerid, WHITE, " Not an active player!");
    if(pID == playerid) return SendClientMessage(playerid, GREY, " You cannot pay money to yourself.");
    if(!ProxDetectorS(5.0, playerid, pID)) return SendClientMessage(playerid, GREY, " You are too far away.");
    new playermoney = PlayerInfo[playerid][pCash];
    if(mon <= 0 || playermoney < mon) return SendClientMessage(playerid, GREY1, "Invalid transaction amount.");
    PlayerInfo[playerid][pCash] -= mon;
    GivePlayerMoney(playerid, -mon);
    PlayerInfo[pID][pCash] += mon;
    GivePlayerMoney(pID, mon);
    format(string, sizeof(string), " You have sent %s(player: %d), $%d.", pName(pID), pID, mon);
    SendClientMessage(playerid, GREY1, string);
    format(string, sizeof(string), " You have recieved $%d from %s(player: %d).", mon, pName(playerid), playerid);
    SendClientMessage(pID, GREY1, string);
    if(PlayerInfo[playerid][pMask] == 1) format(string, sizeof(string), "* Stranger takes out some Cash, and hands it to %s.",pName(pID));
    else format(string, sizeof(string), "* %s takes out some Cash, and hands it to %s.", pName(playerid),pName(pID));
    ProxDetector(30.0, playerid, string, PURPLE,PURPLE,PURPLE,PURPLE,PURPLE);
    PlayerPlaySound(playerid, 1052, 0.0, 0.0, 0.0);
    PlayerPlaySound(pID, 1052, 0.0, 0.0, 0.0);
    new plrIP[16],giveplrIP[16];
    GetPlayerIp(playerid, plrIP, sizeof(plrIP)),GetPlayerIp(pID, giveplrIP, sizeof(giveplrIP));
    format(string, sizeof(string), "%s (IP:%s) (Key:%d) (ConTime:%d) has paid $%d to %s (IP:%s) (Key:%d)", pName(playerid),plrIP,PlayerInfo[playerid][pKey], PlayerInfo[playerid][pConnectTime],mon,pName(pID),giveplrIP,PlayerInfo[pID][pKey]);
    PayLog(string);
    return 1;
    }


    mfg. :thumbup:

    Hahahaa :D


    Das ist mal ein lustiger Thread :D


    Oh ja, am Anfang, Pawn war auch meine erste Sprache und das alles ist ewig lang her...ich glaub so um die 7-8 Jahre :D


    Ich hatte das nie mit diesem return; gerafft und nie verstanden wo an was das jetzt zurück gibt und was das genau bewirkt :D


    Hatte dann meistens immer so einen Code:


    new x = 0;
    SendClientMessage(playerid,-1,"hi");
    return 1;
    x++;
    SendClientMessage(playerid,-1,"hi");
    return;


    und ich hatte das mit den ID's nie verstanden xD Was jetzt pID...oder playerid ist, was da vom Parameter kommt, nein ich hatte keine Ahnung, habe das immer schön gemixxt und mich dann gewundert, warum das nicht ging :D


    Oder sowas hier:


    if(!strcmp(cmd,"/test")) {
    new pID;
    SCM(pID,-1,"hi");
    }


    Dachte man kann das dann direkt nutzen ohne Wertzuweisung :D


    Viel Spaß beim lachen ^^

    Schreib es so:


    if(sSpieler[killerid][pWanted] == 5 && sSpieler[killerid][pPremium] == 0)
    {
    new string[64];
    SetPlayerWantedLevel(killerid,0);
    sSpieler[killerid][pWanted] = 0;
    format(string,sizeof(string),"~>~ ~g~Neues Level: ~w~%d ~<~",GetPlayerScore(killerid)+ 1);
    GameTextForPlayer(killerid, string, 5000, 2)
    SetPlayerScore(killerid,GetPlayerScore(killerid)+1);
    return 1;
    }


    mfg. :thumbup: