Beiträge von MustangReallife

    Da geht warscheinlich kein Weg an einem Timer vorbei :o Ich benutze bei so etwas gerne die funktion "wait".

    stock wait(seconds)
    {
    new _newTime[4], _oldTime[4];
    gettime(_oldTime[0], _oldTime[1], _oldTime[2]);
    _oldTime[3] = _oldTime[2] + (_oldTime[1] * 60) + (_oldTime[0] * 600);
    while(_newTime[3] != (_oldTime[3] + seconds))
    {
    gettime(_newTime[0], _newTime[1], _newTime[2]);
    _newTime[3] = _newTime[2] + (_newTime[1] * 60) + (_newTime[0] * 600);
    }
    }
    Während dem Tutorial:
    tutcar[playerid] = GetPlayerVehicleID(playerid);
    Nach dem Tutorial :

    wait(30);
    SetVehicleToRespawn(tutcar[playerid]);

    Habs nicht getestet :D


    Ob ich "return SendClientMessage..." oder return 1; stehen habe ist ja egal, da diese ja erscheinen soll, WENN dieses parameter fehlt..


    return 1; beendet die funktion, gibt im prinzip der funktion CMD: true aus! ich weiß nicht was du gedacht hast was das macht. Setzte einfach mal ganz oben in deine abfrage return 1; und er wird dir gar nichts machen!

    @Music4You: dies habe ich auch überlegt, aber da ja die User faul sind, wollte ich diese 4 Aktionen in einen Befehl packen und da mna bei "/waren Taschen" keine Anuahl benötigt, würde er ja ein weiteren Parameter von mir verlangen, obwohl ich diesen dann nicht benötige....


    -.- ich versteh nicht wieso du dieses return 1; nicht einfach mal wegnimmst und merkst, dass es dann funktioniert ?(

    und alles andere( Der Audiostream hört auf,..) geht? Was ich immer mache ist: Ich schreib mir dann vor SetSpawnInfo(playerid, 0, 26, 2866.9541,-2036.3248,11.1012, 0, 0, 0, 0, 0, 0, 0); eine Nachricht, um sicher zu sein, dass der Code bis hier hin arbeitet. Das kann man noch hinter das SpawnPlayer(playerid); machen. Wird die funktion TextDrawtut noch irgendwo aufgerufen? Du gibst ja den wert "True" zurück, sofern der code bis dort hin arbeitet, was er normalerweise macht :D

    Da ich mich mal umgeschaut habe und feststellen musste, dass es ja noch gar kein Tutorial ueber Sortierungen gibt, moechte ich euch den Bubblesort heute mal naeher erklaeren und mit Pawno verbinden.
    Mit dem Bubblesort lassen sich einfache Arrays sortieren. Damit koennt ihr auf eurem Server beispielsweise eine Liste der reichsten Spieler oder aehnlichem erstellen :)


    Über ein Feedback würde ich mich sehr freuen ! :D


    Bubblesort - Ein Sortieralgorithmus
    Der Bubblesort ist weit verbreitet. Er durchlaeuft Schritt fuer Schritt die Arrays und vergleicht dabei den rechten mit dem linken Nachbarn, der jeweiligen Spalte. Das kann man sich gut wie eine Blase vorstellen, die immer zwei Variablen gleichzeitig Überprüft. Stimmen den vorher definierten Sortierregeln nicht ueberein, wird einfach links mit rechts vertauscht. Die Schleife wird so lange durchlaufen, bis alles sortiert ist.


    Bubblesort - Umsetzung in Pawno fuer eine "Reichenliste"
    Um uns die Spieler auflisten zu lassen, brauchen wir zunaechst ein Array. Da ich in dem Fall der Reichenliste den Geldbetrag des Spielers benötige, benutze ich ein Enum:
    Das Array zum Sortieren nenne ich "sortrich".

    enum e_Rich
    {
    Spielername,
    Spielergeld
    }
    new sortrich[MAX_PLAYERS][e_Rich];

    Jetzt kann man auch schon gleich zum Befehl selbst springen. Hierfür benutze ich ocmd.
    Außerdem erstelle ich zwei strings, um dem Spieler später die Liste anzeigen zu können.
    Das Array rich[e_Rich] erstelle ich für später, da dies unsere Zwischenvariable zum tauschen des eigentlichen Arrays sortrich ist.

    ocmd:rich (playerid,params[])
    {
    new string[32];
    new rich[e_Rich];
    new richlist[218];
    return 1;
    }

    Nun weißen wir erst mal jedem Spieler seinen Geldbetrag und seine ID zu. Am besten funktioniert das mit einer Schleife. Die ID ist sehr wichtig, da sie zu einer Autentifizierung des Spielers sorgt und wir mithilfe dieser ID den Namen rausfinden können.

    for(new i = 0; i < MAX_PLAYERS; i++)
    {
    if(!IsPlayerConnected(i))continue; //Überprüfung, ob der Spieler online ist.
    sortrich[i][Spielername] = i; //ID wird dem Spieler zugewiesen
    sortrich[i][Spielergeld] = GetPVarInt(i,"Geld"); //Geldbetrag wird dem Spieler zugewiesen
    }

    Nachdem das erfolgt ist, hat unser Array sortrich alle Geldbeträge jedem Spieler der online ist erfasst und gespeichert. Jetzt müssen wir nur noch sortieren :)
    Wir erstellen eine erste Schleife, die wieder jeden Spieler durchläuft. Direkt in dieser Schleife erstellen wir eine weitere, die jedoch ihren Betrag +1 der ersten Schleife definiert. Klingt ganz schön kompliziert, ist aber ganz simpel :)

    for(new a = 0; a < MAX_PLAYERS; a ++)
    {
    for(new b = a+1; b < MAX_PLAYERS; b++)
    {

    }
    }

    Jetzt können wir mit dem sortiernen und tauschen anfangen. Wir fragen ab, ob die sortrich von a kleiner als sortrich von b ist. Wenn ja soll das ganze vertauscht werden. Wenn nicht, wird die Abfrage übersprungen.

    for(new a = 0; a < MAX_PLAYERS; a ++)
    {
    for(new b = a+1; b < MAX_PLAYERS; b++)
    {
    if(sortrich[a][Spielergeld] < sortrich[b][Spielergeld])
    {


    }
    }
    }

    Wenn die Bedingung wahr ist, also sortrich von a kleiner als sortrich von b, sollen die beiden Werte vertauscht werden. Dazu verwenden wir die schon vorher definierte variable rich.

    rich[Spielername] = sortrich[a][Spielername]; //Ablegen des Spielername und Geldes von der ID a in die Zwischenvariable
    rich[Spielergeld] = sortrich[a][Spielergeld]; //Ablegen des Spielername und Geldes von der ID a in die Zwischenvariable
    sortrich[a][Spielername] = sortrich[b][Spielername]; //-"-
    sortrich[a][Spielergeld] = sortrich[b][Spielergeld]; //-"-
    sortrich[b][Spielername] = rich[Spielername]; //-"-
    sortrich[b][Spielergeld] = rich[Spielergeld]; // -"-

    Da ich den Code in einem Dialog haben möchte, baue ich noch eine letzte Funktion ein, damit auch jeder Name in einer anderen Zeile steht.

    for(new p = 0; p < MAX_PLAYERS; p++)
    {
    if(!IsPlayerConnected(p))continue; //Wir gucken wieder, ob der Spieler online ist. Wenn nicht, wird die Nummer einfach übersprungen
    new param[3] = "\n"; // \n trennt eine Zeichenkette in zwei Spalten - also ein Umbruch
    format(string,sizeof(string)," %s: %i %s",SpielerName(sortrich[p][Spielername]),sortrich[p][Spielergeld],param);
    strcat(richlist,string); //Hier wird der string, der richlist hinzugefügt, da der string sonst zu groß werden würde bei vielen Spielern
    }

    Und zuletzt zeigen wir dem Spieler natürlich noch den Dialog. Dafür müssen wir den Dialog noch definieren. Das passiert ganz oben im Script, unter den #include 's :)

    #define DIALOG_RICHLIST 90


    ocmd:rich
    {
    .
    .
    .
    ShowPlayerDialog(playerid,DIALOG_RICHLIST,DIALOG_STYLE_MSGBOX,"Reichenliste",richlist,"Ok","");
    return 1;
    }

    Jetzt noch der ganze Code :)

    #define DIALOG_RICHLIST 90


    enum e_Rich
    {
    Spielername,
    Spielergeld
    }
    new sortrich[MAX_PLAYERS][e_Rich];


    ocmd:rich (playerid,params[])
    {
    new string[32];
    new rich[e_Rich];
    new richlist[218];
    for(new i = 0; i < MAX_PLAYERS; i++)
    {
    if(!IsPlayerConnected(i))continue;
    sortrich[i][Spielername] = i;
    sortrich[i][Spielergeld] = GetPVarInt(i,"Geld");
    }
    for(new a = 0; a < MAX_PLAYERS; a ++)
    {
    for(new b = b+1; b < MAX_PLAYERS; b++)
    {
    if(sortrich[a][Spielergeld] < sortrich[b][Spielergeld])
    {
    rich[Spielername] = sortrich[a][Spielername];
    rich[Spielergeld] = sortrich[a][Spielergeld];
    sortrich[a][Spielername] = sortrich[b][Spielername];
    sortrich[a][Spielergeld] = sortrich[b][Spielergeld];
    sortrich[b][Spielername] = rich[Spielername];
    sortrich[b][Spielergeld] = rich[Spielergeld];
    }
    }
    }
    for(new p = 0; p < MAX_PLAYERS; p++)
    {
    if(!IsPlayerConnected(p))continue;
    new param[3] = "\n";
    format(string,sizeof(string)," %s: %i %s",SpielerName(sortrich[p][Spielername]),sortrich[p][Spielergeld],param);
    strcat(richlist,string);
    }
    ShowPlayerDialog(playerid,DIALOG_RICHLIST,DIALOG_STYLE_MSGBOX,"Reichenliste",richlist,"Ok","");
    return 1;
    }

    Ich hoffe ich konnte euch weiterhelfen oder einfach nur den Bubblesort vorstellen :D Über Kommentare und Bewertungen würde ich mich freuen, da dies mein erstes Tutorial war.

    aber SetTimer kan nich ja nicht playerid verwenden


    Klar kann ein Timer "playerid" verwenden! :)

    public OnGameModeInit()
    {
    SetTimer("timer",10000,true);
    return 1;
    }
    forward timer(playerid);//hier schreibst du playerid in die Klammer. Du kannst natürlich auch andere Parameter benutzen!
    public timer(playerid)
    {
    return 1;
    }

    PS: Auch wenn das Thema erledigt ist, finde ich diese Nachricht hilfreich. :D

    Es gibt viele Möglichkeiten, wo der Fehler sein könnte... :D das dürften aber nicht alle Infos zum Bluescreen sein. Normalerweise ist immer ein Code, vor dem viele Sterne sind. Das ist die Ursache. Vielleicht schreibst du dir den mal auf und googelst danach. Dann dürftest du wissen, woran das Problem liegt :)

    So wie ihr der Überschrift entnehmen könnt, wird bei mir der Callback OnPlayerSelectedMenuRow einfach nicht aufgerufen :/ Ich hab mir das ganze mehr mals ausgeben lassen und OnPlayerExitedMenu mit einer Nachricht versehen(das selbe bei OnPlayerSelectedMenuRow) . Diese Nachricht vom OnPlayerExitedMenu wird jedes mal angezeigt, jedoch passiert beim OnPlayerSelectedMenuRow nichts. Mein Code habe ich mehrmals neu geschrieben, verglichen und angepasst aber habe keinen Fehler gefunden. Warnings, bzw Errors gibts keine :D



    //Global
    new Menu:menu1;


    public OnGameModeInit()
    {
    menu1 = CreateMenu("Klassen", 1, 200.0, 100.0, 150.0, 150.0);
    SetMenuColumnHeader(menu1, 0, "Klassen");
    AddMenuItem(menu1, 0, "Klasse 1");
    AddMenuItem(menu1, 0, "Klasse 2");
    AddMenuItem(menu1, 0, "Klasse 3");
    AddMenuItem(menu1, 0, "Klasse 4");
    AddMenuItem(menu1, 0, "Klasse 5");
    return 1;
    }
    ocmd:menu (playerid,params[])
    {
    ShowMenuForPlayer(menu1,playerid);
    return 1;
    }
    public OnPlayerSelectedMenuRow(playerid, row)
    {
    new Menu:CurrentMenu = GetPlayerMenu(playerid);
    SendClientMessage(playerid,BLAU,"Geht in OnPlayerSelectedMenuRow rein");
    if(CurrentMenu == menu1)
    {
    switch(row)
    {
    case 0:
    {
    print("Klasse 1");
    GivePlayerWeapon(playerid,20,50);
    TogglePlayerControllable(playerid,true);
    SendClientMessage(playerid,BLAU,"geht in 1");
    }
    case 1:
    {
    print("Klasse 2");
    GivePlayerWeapon(playerid,20,50);
    TogglePlayerControllable(playerid,true);
    }
    case 2:
    {
    print("Klasse 3");
    GivePlayerWeapon(playerid,20,50);
    TogglePlayerControllable(playerid,true);
    }
    case 3:
    {
    print("Klasse 4");
    GivePlayerWeapon(playerid,20,50);
    TogglePlayerControllable(playerid,true);
    }
    case 4:
    {
    print("Klasse 5");
    GivePlayerWeapon(playerid,20,50);
    TogglePlayerControllable(playerid,true);
    }
    }
    }
    return 1;
    }


    public OnPlayerExitedMenu(playerid)
    {
    TogglePlayerControllable(playerid,1);
    SendClientMessage(playerid,BLAU,"exit menu");
    return 1;
    }


    Ich hoffe mir kann jemand helfen :)

    Das ist klar das die Maschine in den 2ten Code sofort reingeht, da ein Code immer von oben nach unten abgearbeitet wird und du ja eine Klammer davor eine Variable höher gesetzt hast und somit die zweite Bedingung erfüllt ist. Was du brauchst ist, dass die Funktion nach der ersten Bedienung rausgeht also return true; (oder return 1;)

    forward TutorialTimer(playerid);public TutorialTimer(playerid)
    {
    if(Tutorial[playerid] == 1) //Wenn ich diese überprüfung mache, zeigt bei mir auch Tutorial[playerid] 2 auch sofort an, also die Nachricht von Tutorial[playerid] 2. Tutorial[playerid] habe ich ganz oben im Script definiert als new Tutorial[MAX_PLAYERS];
    {
    //Beim Register-Public setze ich das Tutorial auf eins, da sonst ich eh diesen Tutorial nicht sehe :D
    ClearChat(playerid, 500);
    SendClientMessage(playerid,Gelb,"*** Tutorial: Stadthalle ***");
    SendClientMessage(playerid,Weiß,"Dies hier ist die Stadthalle. Hier kannst du dir einen Personalausweis beantragen.");
    SendClientMessage(playerid,Weiß,"Ebenso kannst du hier einen Job suchen und deinen Arbeitslosengeld beantragen.");
    SendClientMessage(playerid,Weiß,"Durch die Stadthalle kannst du auch in den Bundestag kommen!");
    Tutorial[playerid] = 2;
    SetTimerEx("TutorialTimer",20000,true,"i",playerid);
    return 1;
    }
    if(Tutorial[playerid] == 2)
    {
    ClearChat(playerid, 500);
    SendClientMessage(playerid,Weiß,"");
    }
    return 1;
    }