"/punish" NO-DM Zone

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
  • Heyho, wie kann man einen "/punish" für eine No DM Zone scripten.
    Zmb. wenn ab, xy in einer No DM Zone tötet , das man den befehl /punish schreiben kann, damit der Spieler für 120 Minuten in den Knast kommt.
    Ich hatte mir da schon was gedacht:


    Unter onplayerdeath, setzt man eine PVar von einem Spieler auf 1, (von killerid), dann schreibt man den Befehl ( ich bevorzuge ocmd ) dieser geht eine for schleife durch und fragt die Spieler ab, die jemanden in einer NO DM Zone getötet haben und wenn true -> Prison und wenn false -> kein Prison.
    Jedenfalls habe ich mir das vorgestellt, das man nur den killerid von sich selbst ins Prison stecken kann.


    Jemand eine Idee, wie man es anders machen könnte?

  • Du hast ja eigentlich alle wichtigen Dinge genannt.


    • Unter OnPlayerDeath, falls in NoDMZone in Variable die killerid ablegen der den Spieler getötet hat
    • Falls Spieler /punish eingibt, dessen Variable prüfen ob die dort abgelegte killerid gültig ist.
    • Spieler in's Gefängnis stecken ( Achtung, die Variable jetzt ungültig setzen ). Eventuell mit SetTimerEx den Spieler nach Zeit X wieder befreien.


    An welchem Punkt scheitert es denn bei dir ?

  • Das Problem ist einfach folgendes:
    Der Spieler der den /punish Befehl schreibt, portet - falls es mehrere Leute gibt, die in einer No DM Zone getötet haben - Alle von den Leuten ins Prison.
    Jedoch soll playerid nur seine killerid ins Prison porten, sonst könnte ja einfach jeder /punish eingeben und alle kommen ins Prison.


    Mellnik
    Diese Methode könnte ich ausprobieren, jedoch weiß ich nicht wie ich anfangen soll.


    Gruß,

    Einmal editiert, zuletzt von roOlling ()

  • Das habe ich doch geschrieben. Es ist doch leichter nur den eigenen Killer zu bestrafen als Alle Spieler,die eventuell Jemanden in einer NoDM-Zone getötet haben.
    Hier mal ein kleiner Denkanstoß:
    new KilledBy[MAX_PLAYERS] = {INVALID_PLAYER_ID,..}; // INVALID_PLAYER_ID für "ungültig"
    // OnPlayerDeath
    KilledBy[playerid] = killerid;
    // /punish
    new jailplayer;
    jailplayer = KilledBy[playerid];

  • Okey, bisher habe ich alles so:
    ( Die Strafe wird später eingeführt, habe zuerst nur eine Message an alle geschickt.)


    new KilledBy[MAX_PLAYERS] = {INVALID_PLAYER_ID};


    public OnPlayerDeath(playerid, killerid, reason)
    {
    for(new nodmsys;nodmsys<sizeof(NoDmSystem);nodmsys++)
    {
    if(IsPlayerInArea(playerid,NoDmSystem[nodmsys][nMinX],NoDmSystem[nodmsys][nMinY],NoDmSystem[nodmsys][nMaxX],NoDmSystem[nodmsys][nMaxY]))
    {
    KilledBy[playerid] = killerid;
    new string[128];
    format(string,sizeof(string),"[NO-DM Zone] %s hat dich in einer NO-DM Zone getötet, tippe /punish um ihn zu bestrafen. Nach 30 Sekunden ist dies nicht mehr möglich.",PlayerName(killerid));
    SendClientMessage(playerid,COLOR_WHITE,string);
    }
    else
    {
    return 0;
    }
    }
    }



    ocmd:punish(playerid,params[])
    {
    #pragma unused params
    new jailplayer;
    jailplayer = KilledBy[playerid];
    new string[128];
    format(string,sizeof(string),"%s wurde von %s ins Prison teleportiert, Grund: Kill in einer NO DM Zone.",PlayerName(jailplayer),PlayerName(playerid));
    SendClientMessageToAll(COLOR_RED,string);
    return 1;
    }


    Jetzt müsste ich es nurnoch hinkriegen, bein /punish ob der Spieler überhaupt getötet wurde von jemanden.
    Nur weiß ich nicht ganz wie ich das hinkriegen soll:


    if(KilledBy[playerid] = jailplayer) oder wie :D?

  • Nicht ganz.
    new KilledBy[MAX_PLAYERS] = {INVALID_PLAYER_ID};
    Ich habe ",.." nicht ohne Grund bei mir im Quellcode gehabt. Damit werden alle Einträge mit INVALID_PLAYER_ID initialisiert. So wie du es jetzt hast,nur der mit dem Index 0.


    Zitat

    if(KilledBy[playerid] = jailplayer)
    oder wie :D?


    Das macht gar keinen Sinn.
    Denn auf der einen Seite wird jailplayer sowieso der Wert hinter KilledBy sein ( Habe extra die Variable genommen damit du es leichter verstehst ) und auf der Anderen Seite vergleicht man mit dem Doppeltem Gleichzeichen ( == ) .


    Zum Beispiel bei OnPlayerConnect solltest du den KilledBy Wert des Spielers auf ungültig festlegen. Dafür würde ich INVALID_PLAYER_ID nehmen.
    Bei dem Befehl abfragen,ob KilledBy INVALID_PLAYER_ID ist oder nicht. Ist es nicht INVALID_PLAYER_ID, so wurde er von einem Spieler getötet. Achtung, wurde der Befehl erfolgreich genutzt müssen wir KilledBy auf ungültig setzen. Sonst könnte man den Befehl beliebig oft wiederholen.
    Übrigens könntest du ein break setzen, wenn die Nachricht versenden wurde bei OnPlayerDeath

  • Ich habe das ",.." entfernt, da bei mir ein Warning kam.
    Habe nun anstatt ",.." ",..." benutzt, also 3 Punkte anstatt 2.
    Jedenfalls sieht der Befehl nun so aus:


    Bei Onplayerconnect, wird KilledBy auf Invalid_Player_id gesetzt.
    KilledBy[playerid] = INVALID_PLAYER_ID;


    Beim Sterben auf killerid.
    KilledBy[playerid] = killerid;


    und hier nun der Befehl.
    ocmd:punish(playerid,params[])
    {
    #pragma unused params
    new jailplayer;
    jailplayer = KilledBy[playerid];
    if(KilledBy[playerid] != INVALID_PLAYER_ID)
    {
    new string[128];
    format(string,sizeof(string),"%s wurde von %s ins Prison teleportiert, Grund: Kill in einer NO DM Zone.",PlayerName(jailplayer),PlayerName(playerid));
    SendClientMessageToAll(COLOR_RED,string);
    }
    else
    {
    SendClientMessage(playerid,COLOR_WHITE,"Du wurdest von niemanden getötet.");
    }
    return 1;
    }


    Tut mir leid, das ich mich ein wenig dumm anstelle, mit soetwas kannte ich mich noch nicht so gut aus :)
    BTW: Finde ich es richtig gut, das du es richtig erklärst und nicht einfach den Code postest und dann einfach Copy & Paste.
    Ich habe es zwar verstanden, aber konnte es Anfangs nicht so gut umsetzen, da ich nicht genau wusste, wie :)
    Jedenfalls geht es nur in einer No DM Zone und zwar in der 1:
    Hier mal die Positionen, ich glaube es liegt daran, das die anderen Zonen zu groß sind (?)


    new NoDmSystem[][nodm]=
    {
    /*MinX, MinY, MaxX, MaxY*/
    {1687.613, -1962.151, 1820.712, -1859.51},// Hier gehts
    {1387.189, -1879.249, 1592.542, -1725.287}, // hier gehts nicht
    {2323.897, -712.3504, 2639.2, -478.7929} // Hier gehts nicht
    };

  • Habe es ebend mit ",.." und ",..." probiert,habe keine Warnungen. Ist aber auch egal,da du sowieso bei OnPlayerConnect auf ungültig setzt.
    Ich poste aus gutem Grund keine fertigen Lösungen mehr ( , schon lange nicht mehr ) . Da habe Ich nichts von und erst recht nicht Derjenige der es benötigt. Verstehe auch nicht wieso es immernoch so viele User gibt,die Anderen die Lösung vorschreiben. So lernt man es nie selber.


    Zum Befehl:
    In der if() Abfrage kannst du jailplayer benutzen. Wozu hast du denn sonst die Variable ;) ?
    Vergiss auch nicht die Variable KilledBy auf ungültig zu setzen,wenn der Spieler in's Gefängnis gesteckt wurde.


    Zum Problem mit den Zonen:
    In der Schleife bei OnPlayerDeath hast du im else-Zweig ein return. Überleg mal ob es dort wirklich hin gehört. Denn zur Zeit wird die Funktion OnPlayerDeath bei dir beendet,wenn der Spieler sich nicht in der ersten NoDM-Zone befindet. Eventuell verpackst es auch in eine eigene Funktion, zB IsPlayerInNoDMZone() .