Handy System

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
  • Hallo erstmal,




    Ich will euch nun zeigen wie man ein Handy System erstellt dazu fangen wir erstmal mit einem enum an diesen schreiben wir am besten Unter die Includes, aber zuvor noch die Benötigen Includes:

    #include <a_samp>
    #include <ocmd>

    Jetzt zum Enum:

    // Handy System //
    enum AHandy
    {
    AnruferID
    }
    new Anrufer[MAX_PLAYERS][AHandy];
    new Telefoniert[MAX_PLAYERS];
    new HandyKlingelt[MAX_PLAYERS];

    // Handy System Ende //


    Erklärung(en):
    Der Enum sorgt dafür das ihr es nicht jedesmal neu Definieren müsst und es ist MMn Übersichtlicher.
    Anrufer = Der Spieler der uns Anruft
    Telefoniert = Falls man Gerade Telefoniert soll man nicht nochmal Angerufen werden können.
    HandyKlingelt = Bedeutet soviel das man jetzt /abheben tippen kann.


    Jetzt gehen wir unter:

    public OnPlayerText(playerid, text[])


    Und dann tippen wir erstmal diesen Befehl ein:

    public OnPlayerText(playerid, text[])
    {
    if(Telefoniert[playerid] == 1)
    {
    for(new i=0; i<GetMaxPlayers(); i++)
    {
    if(Anrufer[i][AnruferID] == playerid)
    {
    new str[128], GetName[MAX_PLAYER_NAME];
    GetPlayerName(playerid,GetName,sizeof(GetName));
    format(str,128,"Handy %s: %s",GetName,text);
    SendClientMessage(playerid,GRUEN,str);
    SendClientMessage(i,GRUEN,str);
    return 0;
    }
    }
    }

    if(strlen(text) > 128) return 0;

    new Float:x, Float:y, Float:z;
    GetPlayerPos(playerid,x,y,z);
    new string[280];
    format(string,sizeof string,"%s sagt: %s",SpielerName(playerid),text);
    for(new i=0; i<MAX_PLAYERS; i++)
    {
    if(IsPlayerConnected(i))
    {
    if(IsPlayerInRangeOfPoint(i,20,x,y,z))
    {
    SendClientMessage(i,GRAU,string);
    }
    }
    }
    return 0;
    }


    Erklärung(en):
    if(Telefoniert) == 1) = if Bedeutet soviel wie "Falls" oder "Wenn" das heisst wenn unser Spieler gerade Telefoniert dann ist die Bedingung erfüllt und es kann weitergehen ansonsten passiert garnichts.
    format = Formartiert den zuvor Definierten String
    SendClientMessage(i,BLAU,string) = Sendet den String zum Anrufer
    SendClientMessage(playerid,BLAU,string) = Man liest was man selber geschrieben hat
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    if(strlen(text) < 128) return 0; = Wenn der Spieler zuviel geschrieben hat passiert nichts.
    GetPlayerPos = Findet die Aktuelle Position des Absenders heraus mit den zuvor Definierten Floats
    format = Formatiert den String2
    if(IsPlayerConnected(i)) = Prüft ob ein Connnecter Spieler Online ist
    if(IsPlayerInRangeOfPoint(playerid)) = Wenn ein Spieler Online ist(Also die obrige Bedingung erfüllt wird) prüft diese if Abfrage ob jemand in der Nähe des Angerufenen ist.
    SendClientMessage(i,BLAU,string2) = Wenn beide Bedingungen erfüllt sind wird eine Nachricht an alle Spieler in einer Entfernung von 20 Metern gesendet.


    So jetzt brauchen wir noch ein paar Befehle fangen wir doch mit dem Anrufen Befehl an:

    ocmd:anrufen(playerid, params[])
    {
    new pID, string[128], string2[128];
    if(sscanf(params,"u",pID))return SendClientMessage(playerid,ROT,"/anrufen [ID]");
    if(IsPlayerConnected(pID))
    {
    if(Telefoniert[pID] == 1)
    {
    return SendClientMessage(playerid,GRAU,"Besetzt...");
    }
    else
    {
    format(string,sizeof(string),"Du wirst von %s angerufen. Benutze /p um abzunehmen.",SpielerName(playerid));
    SendClientMessage(pID,GELB,string);
    format(string2,sizeof(string2),"Du rufst %s an, warte einen Moment.",SpielerName(pID));
    SendClientMessage(playerid,GELB,string2);
    format(string,sizeof(string),"Das Handy von %s klingelt...",SpielerName(pID));
    ProxDetector(40.0, pID, string, GELB,GELB,GELB,GELB,GELB);
    HandyKlingelt[pID] = 1;
    Telefoniert[playerid] = 1;
    Anrufer[pID][AnruferID]= playerid;
    Anrufer[playerid][AnruferID]= pID;
    return 1;
    }
    }
    return 1;
    }


    Erklärung(en):
    pID = Der andere Spieler.
    Der Sscanf Teil = Sorgt dafür das wenn man einen Befehl falsch eintippt eine Nachricht ausgegeben wird wie man es Richtig macht.
    IsPlayerConnected = Fragt ab ob der Spieler überhaupt Connected ist
    Telefoniert & Die Mailbox = Sollte der Spieler schon Telefonieren kommt diese Nachricht
    else = Falls es anders ist
    format = Formatiert den String
    SendClientMessage = Sendet die Nachricht
    (2.) format = Formatiert den String für den Anrufer
    (2.) SendClientMessage = Sendet die Message für den Anrufer
    (3.) Format = Formatiert den String nochmals
    ProxDector Teil(Der Stock dazu ist ganz unten) = Alle Spieler in der Umgebung des Angerufenen kriegen die Nachricht das sein Handy klingelt
    BereitZumAbheben & TelefoniertGerade = Setzt beides auf Eins um Bugs zu vermeiden und damit die anderen Befehle möglich sind.



    So was währe ein Anruf Befehl ohne Befehl zum Abheben?

    ocmd:abheben(playerid, params[])
    {
    if(HandyKlingelt[playerid] == 1)
    {
    for(new i=0; i<GetMaxPlayers(); i++)
    {
    if(Anrufer[i][AnruferID] == playerid)
    {
    new string[128],string2[128], xname[MAX_PLAYER_NAME], xname2[MAX_PLAYER_NAME];
    GetPlayerName(i,xname,sizeof(xname));
    GetPlayerName(playerid,xname2,sizeof(xname2));
    format(string,sizeof(string),"Du hast den Anruf von %s angenommen. Tippe /auflegen um aufzulegen.",xname2);
    format(string2,sizeof(string2),"%s hat abgehoben. Tippe /auflegen um aufzulegen.",xname);
    SendClientMessage(playerid,GRAU,string);
    SendClientMessage(i,GRAU,string2);
    SetPlayerSpecialAction(i,SPECIAL_ACTION_USECELLPHONE);
    SetPlayerSpecialAction(playerid,SPECIAL_ACTION_USECELLPHONE);
    Telefoniert[i] = 1;
    Telefoniert[playerid] = 1;
    HandyKlingelt[i] = 0;
    return 1;
    }
    }
    }
    return 1;
    }


    Erklärungen:
    if(HandyKlingelt == 1) = Fragt ab ob der Spieler überhaupt einen Anruf hat.
    for Schleife = Erstellt das "i"
    die Formats = Formatieren die Strings
    Die SendClientMessages = Senden Die Nachrichten Ab
    SetPlayerSpecialAction = Solang der Spieler zu Fuß ist wird die Aktion ausgeführt das er das Handy aus der Tasche holt und Abnimmt.
    Telefoniert = Wird auf 1 Gesetzt.
    BereitZumAbheben = Sorgt dafür das man nicht zweimal Abheben kann(Bzw Das keine Bugs da sind).


    Doch plötzlich wird euer GesprächsPartner zur Nervensäge ihr wollt ihn Abwimmeln ... wozu gibts den /auflegen Befehl?

    ocmd:auflegen(playerid, params[])
    {
    if(Telefoniert[playerid] == 1)
    {
    for(new i=0; i<GetMaxPlayers(); i++)
    {
    if(Anrufer[i][AnruferID] == playerid)
    {
    new string[128],string2[128],xname[MAX_PLAYER_NAME];
    GetPlayerName(i,xname,sizeof(xname));
    format(string,sizeof(string),"Der Anruf mit %s ist beendet.",xname);
    format(string2,sizeof(string2),"Es wurde aufgelegt...");
    SendClientMessage(playerid,GRAU,string);
    SendClientMessage(i,GRAU,string2);
    SendClientMessage(playerid,ROT,"Das Gespräch hat 50$ Gekostet!");
    SetPlayerSpecialAction(i,SPECIAL_ACTION_STOPUSECELLPHONE);
    SetPlayerSpecialAction(playerid,SPECIAL_ACTION_STOPUSECELLPHONE);
    Telefoniert[i]= 0, Telefoniert[playerid]= 0;
    HandyKlingelt[playerid]= 0, HandyKlingelt[i]= 0;
    GivePlayerMoney(playerid,-50);
    GivePlayerMoney(playerid,-50);
    return 1;
    }
    }
    }
    return 1;
    }


    Erklärung(en):
    Ich glaube den if Teil habt ihr jetzt verstanden ...
    Den SendClientMessage&Format Teil auch ...
    SetPlayerSpecialAction = Stoppt die Animation wieder.
    Das mit dem Telefoniert usw. denke ich mal auch.



    Als kleinen Bonus noch einen SMS Befehl, den ihr euch selber machen dürft ;)
    Für die die es Ernsthaft Versuchen und nicht schaffen:

    Spoiler anzeigen

    ocmd:sms(playerid,params[])
    {
    new text[128], string[128], string2[128], pID, xname[MAX_PLAYER_NAME];
    if(sscanf(params,"us",pID,text))
    {
    return SendClientMessage(playerid,ROT,"/sms [ID] [Text]");
    }
    if(IsPlayerConnected(playerid))
    {
    if(IsPlayerConnected(pID))
    {
    format(string,sizeof(string),"SMS von %s: %s",xname,text);
    SendClientMessage(pID,GELB,string);
    format(string2,sizeof(string2),"Deine SMS: %s: %s",xname,text);
    SendClientMessage(playerid,GELB,string2);
    GivePlayerMoney(playerid,-25);
    SendClientMessage(playerid,ROT,"Die SMS kostet 25$");
    return 1;
    }
    }
    return 1;
    }

    Erklärungen braucht ihr glaube ich nicht dazu steht eigentlich alles oben...



    Der ProxDector Stock:

    // Prox Detector //
    stock ProxDetector(Float:radi, playerid, string[],col1,col2,col3,col4,col5)
    {
    if(IsPlayerConnected(playerid))
    {
    new Float:posx, Float:posy, Float:posz;
    new Float:oldposx, Float:oldposy, Float:oldposz;
    new Float:tempposx, Float:tempposy, Float:tempposz;
    GetPlayerPos(playerid, oldposx, oldposy, oldposz);
    for(new i = 0; i < MAX_PLAYERS; i++)
    {
    if(!IsPlayerConnected(i))continue;
    GetPlayerPos(i, posx, posy, posz);
    tempposx = (oldposx -posx);
    tempposy = (oldposy -posy);
    tempposz = (oldposz -posz);
    if (((tempposx < radi/16) && (tempposx > -radi/16)) && ((tempposy < radi/16) && (tempposy > -radi/16)) && ((tempposz < radi/16) && (tempposz > -radi/16)))SendClientMessage(i, col1, string);
    else if (((tempposx < radi/8) && (tempposx > -radi/8)) && ((tempposy < radi/8) && (tempposy > -radi/8)) && ((tempposz < radi/8) && (tempposz > -radi/8)))SendClientMessage(i, col2, string);
    else if (((tempposx < radi/4) && (tempposx > -radi/4)) && ((tempposy < radi/4) && (tempposy > -radi/4)) && ((tempposz < radi/4) && (tempposz > -radi/4)))SendClientMessage(i, col3, string);
    else if (((tempposx < radi/2) && (tempposx > -radi/2)) && ((tempposy < radi/2) && (tempposy > -radi/2)) && ((tempposz < radi/2) && (tempposz > -radi/2)))SendClientMessage(i, col4, string);
    else if (((tempposx < radi) && (tempposx > -radi)) && ((tempposy < radi) && (tempposy > -radi)) && ((tempposz < radi) && (tempposz > -radi)))SendClientMessage(i, col5, string);
    }
    }
    return 1;
    }
    // Prox Detector Ende //

    Am besten gaaaanz unten ins Script.


    Die Farben:

    #define BLAU 0x0087FFFF
    #define ROT 0xE10000FF
    #define GELB 0xFFE600FF




    Schlusswort:
    Ich habe es auch als FilterScript rausgebracht aber hier ist es auch in Erklärter Form :>
    Ich hoffe es hat euch sehr Geholfen!


    Mit Freundlichen Grüßen HellYeah


    // Edits:
    // Edit 1:
    Bug Gefixxt

    Einmal editiert, zuletzt von HellYeah ()

  • Dein Ernst? :huh:


    Du hast Teile aus deinem Filterscript kopiert und hier eingefügt.


    Und meine Vorschläge für das Filterscript wieder nicht beachtet.


    Nun...ahja...okay :rolleyes:

    ast2ufdyxkb1.png


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

  • Was ich nicht ganz verstehe wieso packst du diese variablen
    new TelefoniertGerade[MAX_PLAYERS];
    new BereitZumAbheben[MAX_PLAYERS];
    nicht ins enum?
    und wieso erstellst du sie nicht so
    new TelefoniertGerade[MAX_PLAYERS],BereitZumAbheben[MAX_PLAYERS];


    Ich finde es schlecht erklärt Youtube Tutorial Niveau.

  • do.de - Domain-Offensive - Domains für alle und zu super Preisen
  • Abgesehen, das es für mich eher kein Tutorial ist sondern wie ein Einfacher C&P Code aussieht ist nicht wirklich viel Erklärt...


    Hier ist wieder der Fall, das die Meisten Sachen Vorgemacht sind und ausführliche Erklärungen übersprungen wurden...


    Und da wäre noch eine Frage, warum verwendest du GetMaxPlayers(); diese Funktion macht den Code nur noch langsamer...


    Und, warum machst du ein MIX von einer Makro (MAX_PLAYERS) & GetMaxPlayers(); ?


    Sowie kann die Variable Telefoniert eine boolean sein (true, false) werte da du sowieso nichts anderes außer 0/1 verwendet und das das gleiche ist, bloß mehr Speicher spart.

  • Hab es mir nun mal Durchgelesen, und muss sagen, dass das meiste schon gesagt wurde
    obwohl es mir so vorkommt als ob ich einer der einzigen bin, der es tatsächlich genau durchgelesen hat.
    Oder warum fällt niemand auf, dass er zwar ocmd includiert, jedoch sscanf nicht?
    also würde man es einfach so kopieren, und würde sich nur ocmd hollen, hätte man ein Problem ;)


    Zur Geschwindigkeit kann ich nix sagen, da ich mich damit nicht Auskenne :`(


    Von daher, durch ein paar Logik Fehler und ähnliches 7/10 Punkten

    Zurzeit bin ich an einem Script schreiben, dass sich so gut es machbar ist an GTA Online orientiert ;)


    Falls jemand Frage hat, bzw mir helfen will soll mir einfach hier oder bei PSN schreiben ^^