Beiträge von KornChief

    Hallo,
    ich habe hier eine kleine Alternative zu strtok bzw. strget gescriptet.


    ( Dies ist die BETA-Version und wurde nur auf meinem HomeServer getestet. Falls Bugs vorhanden sind, melden, ich setzte mich dann gleich ran um sie zu beheben. )



    // ====> Code <====
    // Irgendwo einfügen
    retstr(const sstr[], desstr[][],args, del = ' ')
    {
    new
    s,Num,start,argnum;
    do
    {
    if((sstr== del && sstr[s+1] != del) || s == strlen(sstr))
    {
    if(args == 0 && argnum == 0)
    {
    strmid(desstr[0],sstr,start,s,128);
    break;
    }
    strmid(desstr[Num],sstr,start,s,128);
    start = s+1;
    Num++;
    argnum++;
    if(argnum == args && sstr != EOS )
    {
    strmid(desstr[Num],sstr,start,strlen(sstr),128);
    break;
    }
    }
    s++;
    }
    while(s < strlen(sstr));
    return 1;
    }



    Nun erkläre ich euch kurz wie es funktioniert und gebe 2 Beispiele dazu:
    Zuerst fügt ihr unter "OnPlayerCommandText(...)" folgendes ein:

    new tmp[5][35];

    Die "5" könnt ihr mit jeder Zahl tauschen (sie gibt die Anzahl der maximal möglichen Parameter an - ohne 0, dazu kommen wir aber noch).
    Natürlich könnt ihr "tmp" mit allem erdenklichen austauschen (wie z.B.: "new param[5][128];"). Die 35 lasst ihr am besten so.


    Dann vergleicht ihr - wie immer - den CMDTEXT und den CMD (= "/kick","/givecash", usw. )

    if(strcmp("/givecash",cmdtext,false,9) == 0) { // die 9 nicht vergessen - gibt an, wie lange der CMD (einschließlich des "/") ist.


    Jetzt müsst ihr nur folgendes einfügen:

    retstr(cmdtext,tmp,2);

    Ihr müsst nur die "2" mit der Anzahl der Parameter tauschen (z.B.: "/kick ID GRUND" = 2 | "/adminchat TEXT" = 1 | "/givecash ID MENGE" = 2 | ... ).
    Dann könnt ihr auch schon loslegen. Ihr verwendet einfach (statt wie bei strtok tmp = strtok(cmdtext, idx)) tmp[1] und tmp[2] (bzw. tmp[1], tmp[2],tmp[3], ... bzw. param[1], ... )
    ( WICHTIG: Diese beiden sind strings, d.h. müssen um Zahlen (wie ID's) zu werden umgeformt werden (strval(tmp[1]). Zudem ist tmp[0] immer der CMD-Anfang, sprich "/giveceash","/kick", usw. )


    Prinzip:


    retstr trennt den eingegebenen string (cmdtext), wenn ein " " (Space / Leertaste) gefunden worden ist, jedoch kein " " darauf folgt ! Die "Stücken" überträgt es in das Arry solange, bis alle Argumente übertragen worden sind. Das letzte Parameter wird vollkommen übertragen,d.h. nicht abgeschnitten, geeignet für Strings. Es (bei "/upm ID TEXT" gibt er den gesamten Text zurück am Ende).



    Beispiele:



    public OnPlayerCommandText(playerid, cmdtext[])
    {
    new tmp[3][128];
    if(strcmp("/givecash",cmdtext,false,9) == 0)
    {
    retstr(cmdtext,tmp,2);
    if(!strlen(tmp[1]) || !strlen(tmp[2])) return SendClientMessage(playerid,0xAAAAAAAA,"*** Verwende: /givecash ID MENGE ***");
    if(!IsPlayerConnected(strval(tmp[1]))) return SendClientMessage(playerid,0xAAAAAAAA,"*** Angegebener User nicht online ***");
    if(strval(tmp[2]) <= 0 || strval(tmp[2]) >= 1001) return SendClientMessage(playerid,0xFF66FFAA,"*** Menge muss zwischen 1 und 1000 liegen ***");
    GivePlayerMoney(strval(tmp[1]),strval(tmp[2]));
    GivePlayerMoney(playerid,-strval(tmp[2]));
    SendClientMessage(playerid,0xAAAAAAAA,"*** Geld abgegeben ***");
    SendClientMessage(strval(tmp[1]),0xAAAAAAAA,"*** Geld erhalten ***");
    return 1;
    }
    if(strcmp("/upm",cmdtext,false,4) == 0)
    {
    retstr(cmdtext,tmp,2);
    if(!strlen(tmp[1]) || !strlen(tmp[2])) return SendClientMessage(playerid,0xAAAAAAAA,"*** Verwende: /upm ID NACHRICHT ***");
    if(!IsPlayerConnected(strval(tmp[1]))) return SendClientMessage(playerid,0xAAAAAAAA,"*** Angegebener User nicht online ***");
    new string1[100],string2[100],name1[MAX_PLAYER_NAME],name2[MAX_PLAYER_NAME];
    GetPlayerName(playerid,name1,sizeof name1);
    GetPlayerName(strval(tmp[1]),name2,sizeof name2);
    format(string1, sizeof string1,"*** User PM to %s: %s ***",name2,tmp[2]);
    format(string2, sizeof string2,"*** User PM from %s: %s ***",name1,tmp[2]);
    SendClientMessage(playerid,0xAAAAAAAA,string1);
    SendClientMessage(strval(tmp[1]),0xAAAAAAAA,string2);
    return 1;
    }
    return 0;
    }



    Hier noch ein ReturnUser Code von mir wieder:

    stock ReturnUser(string[])
    {
    new i = 0;
    new count = 0;
    new len = strlen(string);
    if(len > 3)
    {
    for(; i < MAX_PLAYERS;i++)
    {
    new name[MAX_PLAYER_NAME];
    GetPlayerName(i,name,sizeof(name));
    if(strcmp(name,string,false) == 0)
    {
    return i;
    }
    else
    {
    if(len == 3)
    {
    count = 2;
    }
    else
    {
    count = 1;
    }
    }
    }
    }
    else
    {
    return strval(string);
    }
    return (count == 1) ? (INVALID_PLAYER_ID) : (strval(string));
    }


    Anwendung mit retstr wäre:

    Kick(ReturnUser(tmp[1]));


    Der User hat die Möglichkeit, statt nur einer ID oder nur einen Namen, beides anzugeben. Bei der Selection (falls es genau 3 Zeichen seien sollten) hat der String (bzw. als Name) eine höhere priorität.



    Hoffe alles klappt, sonst behebe ich es selbstverständlich.


    MfG KornChief.


    // Edit: Ich vergaß zu erwähnen, dass natürlich alles von mir ist und nichts kopiert worden ist.

    Du musst ja folgendes beachten:
    Important note: GetPlayerColor will return nothing unless SetPlayerColor has been used!


    Nun setzt du (iwo im Script) die Farbe...

    // Je nach dem welche Farbe du setzt...
    dini_Set(datei,"COLOR","RED");
    // Und nun bei SetPlayerColor:
    SetPlayerColor(playerid, (!strcmp(dini_Get(datei,"COLOR"),"RED",true)) ? (0xAA3333AA) : (0x21DD00FF));


    Keine Ahnung ob es funktioniert, einfach testen....
    So würde ich es machen, denn man kann soweit ich weiß (und ich weiß es nicht) keinen String in einen hexa code umformen - wenn ja ist es ja einfach :)


    Kannst auch statt den Farben Integerwert verwenden, nur musst halt wissen welche Farbe das war :S

    Entweder oder möchte ich.... eine Funktion, die bei der einen Bedingung den Arry (String) zurück gibt und beim anderen die Zahl, den Integerwert.


    // Edit: Genau... nur statt return 0 einen String und statt dem 2. return einen bestimmten Wert... geht das? Bei mir nicht ;X . Also nicht nur true und false, sondern genaue Werte :S ... Bei mir siehts nur so aus: Es soll einmal string[] = "..."; und einmal stringX[Y][]; , wobei Y für x-beliebige Werte steht...

    Hallo,
    ich habe (wiedereinmal :D ) ein Problem:
    Ich möchte in meiner Funktion verschiedene Sachen zurückgeben lassen, doch wird mir folgender Fehler angezeigt:

    Code
    error 079: inconsistent return types (array & non-array)


    Ein kleines Beispiel:


    // ====> Irgendwo im Script (zB unter main) rufen wir folgende Funktion auf:
    new val = 3;
    myfunk(val);


    // ====> Nun zur Funktion selbst:
    myfunk(val)
    {
    if(val > 5) { // Wenn der Integerwert "val" über 5 ist, was er definitiv nicht ist, geben wir den String "s" zurück.
    new s[100];
    s = " Dies ist ein Tes! ";
    return s; // -"-
    }
    else {
    return val+5; // Wenn er eben 5 oder kleiner ist, addieren wir 5 dazu.*
    }
    return 1; // *
    }


    Alle mit dem * gekennzeichneten Zeilen geben an, wo der "Fehler" ist.


    Nun ist meine Frage, ist das unumgänglich?



    Ich freue mich über jede konstruktive Antwort,


    MfG,
    KornChief.

    Dass wir dir helfen ist schon etwas besonderes. Natürliche tuen wir das gerne (zumindest in meinem Fall) solange du auch lernfähig bist...


    In dem Tutorial wird von Bright sehr gut die Bedeutung und Behebung von Warnings und Errors,welche du hast, beschrieben. (LINK : [ SCRIPTING ] Warning (& Error) Erklärungen + Behebungen ) Vorteil Davon: Du lernst es für die Zukunft und kannst es dann selbst beheben...Learning by Doing. ;)

    Wenn du meins hernimmst gar nicht, nur bei seinem

    for(new i = 0; i < MAX_PLAYERS; i++)
    {
    if(Team[i] == TEAM_USA && Team[playerid] == TEAM_USA)
    {
    SendClientMessage(i, COLOR_BLUE, str);
    }
    else if(Team[i] == TEAM_OTHER && Team[playerid] == TEAM_OTHER)
    {
    SendClientMessage(i, COLOR_BLUE, str);
    }
    }

    wäre es dadurch kürzer


    if(Team[i] == Team[playerid])
    {
    SendClientMessage(i, COLOR_BLUE, str);
    }
    // Kürzer


    Das ist kein GF, aber du brauchst den dcmd und sscanf Code. ( Tutorial dazu : [ SCRIPTING ] Commands mit Parametern - by GoldKiller)


    Kommt drau an, was du verwendest....

    // Irgendwo im Script:
    stock strtok(const string[], &index)
    {
    new length = strlen(string);
    while ((index < length) && (string[index] <= ' '))
    {
    index++;
    }


    new offset = index;
    new result[20];
    while ((index < length) && (string[index] > ' ') && ((index - offset) < (sizeof(result) - 1)))
    {
    result[index - offset] = string[index];
    index++;
    }
    result[index - offset] = EOS;
    return result;
    }


    // Unter das CallBack (wenn du bereits Commands hast, brauchst das public ... und return 0; } natürlich nicht ;)
    public OnPlayerCommandText(playerid, cmdtext[])
    {
    new idx;
    new cmd[256];


    cmd = strtok(cmdtext, idx);


    if(strcmp(cmd, "/f", false) == 0)
    {
    new tmp[130];
    tmp = strtok(cmdtext, idx);
    if(!strlen(tmp)) return SendClientMessage(playerid,0x33AA33AA," Verwende /f [TEXT]");
    new i = 0;
    new name[MAX_PLAYER_NAME];
    GetPlayerName(playerid,name,sizeof name);
    for(;i < MAX_PLAYERS;i++)
    {
    if(IsPlayerConnected(i) && gTeam[i] == gTeam[playerid])
    {
    new s[100];
    format(s,sizeof s," *** %s : %s *** ",name,tmp);
    SendClientMessage(i,0xAA3333AA,s);
    }
    }
    return 1;
    }


    return 0;
    }



    public OnPlayerDeath(playerid, killerid, reason) // playerid = Die ID,die getötet worden ist - killerid = Die ID,die getötet hat
    {
    GivePlayerMoney(playerid, -100);
    SendClientMessage(killerid,0x1229FAFF,"SERVER: Du hast jemanden getötet ;) ");
    return 1;
    }