[SAMMELTHREAD] Kleine Scripting Fragen

Dein Problem konnte durch einen User gelöst werden? Bedank dich bei ihm indem du seinen Beitrag als Hilfreich markierst sowie einen Daumen oben dalässt
Wichtiger Hinweis: Bitte ändert nicht manuell die Schriftfarbe auf schwarz sondern belasst es bei der Standardeinstellung. Somit tragt ihr dazu bei dass euer Text auch bei Verwendung unseren dunklen Forenstils noch lesbar ist!

Tipp: Ihr wollt längere Codeausschnitte oder Logfiles bereitstellen? Benutzt unseren eigenen PasteBin-Dienst Link
  • @Mausibiba:


    new player;
    repeat:
    player =random(MAX_PLAYERS);
    if(!IsPlayerConnected(player))goto repeat;


    Das ist sogenannter Spaghetti Code und eine sehr schlechte Möglichkeit dieses Problem zu lösen.


    benutz GetMaxPlayers();


    Dann würde das alles noch länger dauern, denn angenommen MAX_PLAYERS und GetMaxPlayers() würden den selben Wert haben, dann muss trotzdem immer wieder eine Funktion aufgerufen werden.


    Besser zu lösen, wäre es mit einem Array:


    /*
    Oben im Skript am besten:
    #undef MAX_PLAYERS
    #define MAX_PLAYERS (ANZAHL_DER_MAXIMALEN_SPIELER)
    */


    new bool:e_Player[MAX_PLAYERS char];


    public OnPlayerConnect(playerid)
    {
    if(!IsPlayerNPC(playerid)) e_Player{playerid} = true; //für jeffry
    return 1;
    }
    public OnPlayerDisconnect(playerid)
    {
    e_Player{playerid} = false;
    return 1;
    }


    //Dann der Command
    new tmp[MAX_PLAYERS],c,Float:p[3];
    for(new i; i<MAX_PLAYERS; i++) if(e_Player{i} && i != playerid) tmp[code=c] = i,c++;
    if(!c) return SendClientMessage(playerid,-1,"Es ist kein Spieler online, den du porten kannst!");
    new p_random = tmp[random(c)];


    GetPlayerPos(playerid,p[0],p[1],p[2]); //<< du fragst deine Position ab:
    SetPlayerPos(p_random,p[0],p[1]+1.5,p[2]); //<<hier setzt du den random Spieler zu dir


    mfg. :thumbup:


    //Edit: Code

    ast2ufdyxkb1.png


    Leute, lernt scripten und versucht mal lieber etwas selber zu schreiben, als es aus einem GF zu kopieren. :S

    2 Mal editiert, zuletzt von Kaliber ()

  • Das so zu machen ( Nemesus Jr: Fabi.StaR:) ist keine gute Idee. In einem Befehl mag es zwar funktionieren, da ja dann mindestens ein Spieler online ist, aber setzt man es in einen Timer und kein Spieler ist online, dann hat man eine Endlosschleife, was zur Folge hat, dass auch niemand mehr den Server betreten kann.
    Außerdem kann es theoretisch sein, dass es sehr sehr viele Wiederholungen bei der Methode gibt, denn wenn nur ein Spieler online ist, man aber 500 Slots hat, besteht jedes mal nur eine Chance von 1 zu 499 Chance, dass der Wert getroffen wird. Bei 2000 Wiederholungen ist immer noch eine 2%'ige Chance, dass noch kein Spieler gefunden wurde (2000 ist zwar nicht viel, trotzdem sollte man keine theoretischen Lücken lassen).


    Kaliber: Deine Methode wird auch nicht, bzw. nicht richtig, funktionieren, wenn nur ein/kein Spieler online ist, da ein random aus 0 keinen Sinn gibt.


    Für @Mausibiba: ist es sicher am einfachsten und am leichtesten zu verstehen, eine Funktion zu verwenden, die einfach eine random ID ausgibt, ohne viel Code drum herum (fehleranfällig!).



    stock GetRandomPlayer(playerid)
    {
    new onlinecount = 0, oID[MAX_PLAYERS];
    for(new i=0; i<MAX_PLAYERS; i++)
    {
    if(IsPlayerConnected(i) && !IsPlayerNPC(i) && i != playerid)
    {
    oID[onlinecount] = i;
    onlinecount++;
    }
    }
    if(onlinecount > 0) return oID[random(onlinecount)];
    else return INVALID_PLAYER_ID;
    }


    Wäre dann ganz einfach zu verwenden:
    new player1 = GetRandomPlayer(playerid);
    if(player1 == INVALID_PLAYER_ID) return SendClientMessage(playerid, 0xFF0000FF, "Es ist kein Spieler außer dir online!");
    SetPlayerPos(player1, x, y, z);

  • Kaliber: Deine Methode wird auch nicht, bzw. nicht richtig, funktionieren, wenn nur ein/kein Spieler online ist, da ein random aus 0 keinen Sinn gibt.


    Doch...da wird nämlich kein Spieler geportet, da der Wert invalid ist :)


    Wenn ihm das nicht passt kann man im übrigen ganz leicht abfragen ob c > 0 ist oder eben nicht :rolleyes:


    ...oder man macht eine Funktion daraus, die nach dem selben Algorithmus funktioniert wie mein Beispiel..im Endeffekt egal, außer das mein Code schneller ist xD

    ast2ufdyxkb1.png


    Leute, lernt scripten und versucht mal lieber etwas selber zu schreiben, als es aus einem GF zu kopieren. :S

  • Auf ein Array mit einem invaliden Index zuzugreifen ist dennoch keine gute Idee und ein schlechtes Beispiel, weil im schlechtesten Fall bricht der Code einfach ab und es kommt "Unknown Command.", was nicht wirklich schön ist. Mir ist klar, dass die Abfrage auf 0 fehlt, aber einem Anfänger ist das meistens nicht auf den ersten Blick klar.
    Außerdem fehlt noch die Abfrage, ob der Spieler ein NPC ist, den kann man ja schlecht teleportieren.


    Schneller ist der Code zwar, aber dafür fehleranfälliger. Wird beispielsweise OnPlayerDisconnect durch einen Fehler in einem Filterscript mal nicht ausgeführt (verursacht zum Beispiel durch ein zugreifen auf einen Array-Index mit einem invaliden Wert...), dann bleibt der Wert des Arrays für online Spieler auf true, was zur Folge haben kann, dass ein Spieler ausgewählt wird, der gar nicht online ist. Das ist zwar weit hergeholt, passiert aber dennoch Anfängern häufig. Da die Geschwindigkeit hier irrelevant ist (Nanosekunden) ist es wichtiger einen sicheren, unabhängigen Code zu haben.

  • Beitrag von Kriegerbeere ()

    Dieser Beitrag wurde vom Autor gelöscht ().
  • C:\Users\tobialvarez\Desktop\samp03z_svr_R1_win32 (2)\gamemodes\GTA.pwn(1275) : warning 208: function with tag result used before definition, forcing reparse



    stock SendSayChat(string[],playerid) //fehlerzeile
    {
    for(new i = 0;i < MAX_PLAYERS; i++)
    {
    if(GetDistanceBetweenPlayers(i,playerid) <= 15)
    {
    SendClientMessage(i,-1,string);
    }
    }
    return 1;
    }

  • do.de - Domain-Offensive - Domains für alle und zu super Preisen
  • Hab da ne Frage zu meinem Unban befehl.


    Wenn ich jemanden unbanne funktioniert das aber ich bekomme auch die Message, dass der Befehl nicht existiert.


    ocmd:unban(playerid,params[])
    {
    new name, grund[128], n1[128],query[1024];
    if(sInfo[playerid][pEingeloggt] == 0) return SendClientMessage(playerid, GRAU, LOGINERROR);
    if(sInfo[playerid][pAdmin] < 2) return SendClientMessage(playerid, GRAU, ADMERROR);
    if(sscanf(params, "s[128]s[128]", name, grund)) return SendClientMessage(playerid, GRAU, "Verwende: /unban {FF9E00}<Spieler-Name> <Grund>");
    format(query,sizeof(query), "UPDATE accounts SET Gebannt='0' WHERE Name='%s'", name);
    mysql_function_query(mysql,query,false,"","");
    format(n1,sizeof(n1), "%s hat %s den Zugang zum Server wieder gewehrt. Grund: %s", SpielerName(playerid), name, grund);
    SendClientMessageToAll(ADMIN, n1);
    return 1;
    }


    Der Chat:


    Code
    [19:29:52] Jonny_Ramirez hat Maik den Zugang zum Server wieder gewehrt. Grund: Test
    
    
    [19:29:52] Der Befehl {FF9E00}/unban Maik Test {908B8E}existiert nicht! Um eine Liste mit Befehlen zu bekommen nutze {FF9E00}/help{908B8E}.

    Mit freundlichen Grüßen,
    Derakar


  • Ich habe das jetzt so gemacht und es funktioniert. Danke dafür schon mal,
    aber noch eine frage, wie mach ich es das der Randomplayer zu Position A geportet wird und alle anderen User zu Position B?
    ich dachte zuerst daran eine if abfrage zu machen:


    CMD:random(playerid)
    {
    new player1 = GetRandomPlayer(playerid);
    if(player1 == INVALID_PLAYER_ID) return SendClientMessage(playerid, 0xFF0000FF, "Es ist kein Spieler außer dir online!");
    //SetPlayerPos(player1, 195.7658,-1436.2083,12.9808);
    if(player1)
    {
    SetPlayerPos(player1, 195.7658,-1436.2083,12.9808);
    }
    else
    {
    SetPlayerPos(?, 195.7658,-1436.2083,12.9808);
    }
    return 1;
    }


    aber ich weiß nicht was ich dann bei "?" hin machen soll, und wäre es nicht einfacher dem Player eine variabel zu setzen und diese dann abzufragen?
    Wie würdet ihr es machen und warum?
    Danke im Voraus Mausibiba

    Einmal editiert, zuletzt von Mausibiba () aus folgendem Grund: //zitat versteckt für Jeffry

  • @K3Ksii:
    new name, grund[128], n1[128],query[1024];
    zu:
    new name[MAX_PLAYER_NAME], grund[64], n1[145],query[128];


    @Mausibiba:
    Das kannst, bzw. musst, du mit einer Schleife machen.
    CMD:random(playerid)
    {
    new player1 = GetRandomPlayer(playerid);
    if(player1 == INVALID_PLAYER_ID) return SendClientMessage(playerid, 0xFF0000FF, "Es ist kein Spieler außer dir online!");
    //SetPlayerPos(player1, 195.7658,-1436.2083,12.9808);
    for(new i=0; i<MAX_PLAYERS; i++)
    {
    if(IsPlayerConnected(i) && !IsPlayerNPC(i))
    {
    if(i == player1)
    {
    SetPlayerPos(player1, 195.7658,-1436.2083,12.9808);
    }
    else
    {
    SetPlayerPos(i, 195.7658,-1436.2083,12.9808);
    }
    }
    }
    return 1;
    }
    PS: Gewöhne dir bitte ab, Vollzitate zu verwenden, das stört. Danke :)

  • Ich habe eine if Bedingung, wenn diese erfüllt ist, soll wenn:
    1 Spieler in Team Test ist ein car spawnen mit ihm als Fahrer
    2 Spieler in Team Test sind 2 cars (beide fahrer)
    3 Spieler in Team Test sind 3 cars (alle fahrer)
    usw.
    sollten bereits alle Fahrzeuge einen Fahrer haben, sollen die Beifahrerplätze gefüllt werden, der reihe nach.
    da ich das öfter brauche, wollte ich fragen ob man da eine Art array machen kann, sprich ich hab eine Liste in der 5 Autos sind,
    und mit diesen Autos wird gearbeitet, also erst 5 Fahrer dann Beifahrer und falls dann noch Player in Team Test sind, sollen diese zu einer stelle geportet werden.
    da ich bisher noch nicht mit arrays gearbeitet habe, habe ich keinen plan wie ich das angehen soll.


    Ich habe es bereits geschafft den Spieler ein Auto zu spawnen und ihn auf den Fahrersitz zu setzen, jedoch weiß ich nicht wie ich das mache wenn mehr autos/player im team sind,
    wegen der Reihenfolge und so

    if(gTeam[playerid] == Test)
    {
    new vehicleid;
    vehicleid = CreateVehicle(413,2038.8768,1415.6444,10.6058,180.7780,-1,-1,-1);
    PutPlayerInVehicle(playerid, vehicleid, 0);
    }
    else...
    PS: und ist es möglich das array dynamisch zu machen, sprich wenn 6 cars drinnen sind macht er es mit 6 und wenn 7 dann eben 7 cars

  • Wie kann ich ein Integer zu einem String machen?


    Ungefair so? (ist aber falsch)


    if(sInfo[playerid][pGeschlecht] == 1){
    sInfo[playerid][pGeschlecht] = "Männlich";
    } else if(sInfo[playerid][pGeschlecht] == 2){
    sInfo[playerid][pGeschlecht] = "Weiblich";
    }

    Mit freundlichen Grüßen,
    Derakar

  • Okay wie kann ich das dann mit einem Dialog machen?


    Hier wird das Geschlecht gemacht:


    if(dialogid == DIALOG_GESCHLECHT){
    if(response){
    sInfo[playerid][pGeschlecht] = 1;
    ShowPlayerDialog(playerid,DIALOG_ALTER,1,"{FF9E00}Wähle dein Alter","Gebe nun dein Alter hier ein, mit welchem du auf dem Server spielen willst.\nDu kannst auch dein richtiges Alter angeben.","OK","");
    } else {
    sInfo[playerid][pGeschlecht] = 2;
    ShowPlayerDialog(playerid,DIALOG_ALTER,1,"{FF9E00}Wähle dein Alter","Gebe nun dein Alter hier ein, mit welchem du auf dem Server spielen willst.\nDu kannst auch dein richtiges Alter angeben.","OK","");
    }
    return 1;
    }

    Mit freundlichen Grüßen,
    Derakar

  • do.de - Domain-Offensive - Domains für alle und zu super Preisen