Nützliche Codeschnipsel

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
  • Beitrag von Akino Kiritani ()

    Dieser Beitrag wurde gelöscht, Informationen über den Löschvorgang sind nicht verfügbar.
  • Ich hätte da auch noch paar interessante Tricks.


    Eine Alternative für != -1
    So kann man das ganze statt so zu schreiben
    if(strfind("Hallo wie gehts", "wie") != -1) print("Gefunden");


    auch einen Bitoperator nehmen


    if(~strfind("Hallo wie gehts", "wie"))print("Gefunden");


    Ebenfalls ist es möglich auf einen Index eines zurückgegebenen Arrays zuzugreifen.


    enum tData {
    a[10],
    b[10],
    c[10],
    }


    stock test() {
    new str[2][tData] ={{"Hallo","wie","gehts"},{"Hallo","wie","gehts"}};
    return str;
    }

    print((test())[0][a]);


    Ausgabe "Hallo"


    natürlich geht das auch mit einfachen strings


    stock test() {
    new str[40] ="Hallo wie gehts";
    return str;
    }


    print((test())[5]);

  • Da ich hier auch immer wieder falsche oder komplizierte Funktionen dazu sehe, hier eine funktionierende und einfache Variante:


    new stock g_days_m[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
    stock GetPlayerAge(input[]) //©Jeffry
    {
    new date[12];
    strcat(date, input);
    if(date[1] == '.') strins(date, "0", 0, 12);
    if(date[4] == '.') strins(date, "0", 3, 12);
    if(!date[9] || date[10]) return -1;
    new day = 10*(date[0]-48)+(date[1]-48);
    new month = 10*(date[3]-48)+(date[4]-48);
    new year = 1000*(date[6]-48)+100*(date[7]-48)+10*(date[8]-48)+(date[9]-48);
    if(year < 1000 || year > 9999 || month < 1 || month > 12 || day < 1) return -1;
    if(month == 2)
    {
    if(day > 28 && (year % 4 != 0 || (year % 100 == 0 && year % 400 != 0))) return -1;
    }
    else if(day > g_days_m[month-1]) return -1;
    new d, m, y;
    getdate(y, m, d);
    new age = y - year;
    if(m < month) age--;
    else if(m == month && d < day) age--;
    return (age < 0) ? (-1) : (age);
    }


    Beispiel zur Nutzung:

    Spoiler anzeigen
    public OnDialogResponse(playerid, dialogid, response, lisitem, inputtext[])
    {
    if(dialogid == DIALOG_AGE)
    {
    if(!response) return 1;
    new age = GetPlayerAge(inputtext);
    if(age == -1) return ShowPlayerDialog(playerid, DIALOG_AGE, DIALOG_STYLE_INPUT, "Geburtsdatum", "Bitte gebe Dein Geburtsdatum hier ein: (Format: TT.MM.JJJJ)", "Ok", "Abbrechen");
    PlayerInfo[playerid][pAge] = age;
    new str[145];
    format(str, sizeof(str), "Du hast am %s Geburtstag, damit bist Du %d Jahre alt! Sehr schön :)", inputtext, PlayerInfo[playerid][pAge]);
    SendClientMessage(playerid, 0xFF0000FF, str);
    return 1;
    }
    return 0;
    }

    Spoiler anzeigen
    Ausgabe:

    Zitat
    Spoiler anzeigen

    [12/03/2015 19:34:56] Du hast am 24.01.1993 Geburtstag, damit bist Du 22 Jahre alt! Sehr schön :)


    Keywords: GetPlayerAge, GetSpielerAlter, SpielerJahre, Alter eines Spielers, CalculateAge, BerechneAlter, YearsSince, JahreSeit.

  • native __SetPlayerCameraLookAt(playerid, Float:x, Float:y, Float:z) = SetPlayerCameraLookAt;
    native __InterpolateCameraLookAt(playerid, Float:FromX, Float:FromY, Float:FromZ, Float:ToX, Float:ToY, Float:ToZ, time, cut = CAMERA_CUT) = InterpolateCameraLookAt;


    enum CAMERA_LOOKAT_INFO{
    Float:_posX,
    Float:_posY,
    Float:_posZ
    };
    new cameraLookAt[MAX_PLAYERS][CAMERA_LOOKAT_INFO];


    #define SetPlayerCameraLookAt _SetPlayerCameraLookAt
    #define InterpolateCameraLookAt _InterpolateCameraLookAt


    stock _InterpolateCameraLookAt(playerid, Float:FromX, Float:FromY, Float:FromZ, Float:ToX, Float:ToY, Float:ToZ, time, cut = CAMERA_CUT){
    cameraLookAt[playerid][_posX] = ToX;
    cameraLookAt[playerid][_posY] = ToY;
    cameraLookAt[playerid][_posZ] = ToZ;


    __InterpolateCameraLookAt(playerid, FromX, FromY, FromZ, ToX, ToY, ToZ, time, cut);
    }


    stock _SetPlayerCameraLookAt(playerid, Float:x, Float:y, Float:z){
    cameraLookAt[playerid][_posX] = x;
    cameraLookAt[playerid][_posY] = y;
    cameraLookAt[playerid][_posZ] = z;


    __SetPlayerCameraLookAt(playerid, x, y, z);
    }


    stock GetPlayerCameraLookAt(playerid, &Float:x, &Float:y, &Float:z){
    x = cameraLookAt[playerid][_posX];
    y = cameraLookAt[playerid][_posY];
    z = cameraLookAt[playerid][_posZ];
    return 1;
    }

  • @Jack_Bauer:
    Da bekommt man doch nur die Koordinaten wieder zurück, die man zuvor in SetPlayerCameraLookAt bzw. InterpolateCameraLookAt eingegeben hat, was macht das für einen praktikablen Sinn? Warum sollte man etwas abfragen, was man zuvor selbst gesetzt hat?
    Wenn man die Kamera selbst bewegt dann funktioniert die Funktion nicht, man bekommt immer nur die Koordinaten zurück, die man irgendwann mal mit SetPlayerCameraLookAt bzw. InterpolateCameraLookAt gesetzt hat.


    Macht man dann aber SetCameraBehindPlayer dann bekommt man trotzdem die Koordinaten, die man zuvor mit einer der beiden Funktionen gesetzt hat, zurück, und das sind dann falsche Koordinaten.

  • @Jack_Bauer:
    Klar, ich kann mir schon vorstellen was du damit angestellt hast, nur ist es vielleicht etwas verwirrend für Leute die es sich einfach raus-kopieren. Das wäre in etwa so, wie wenn man SendClientMessage hookt und dann eine Funktion GetLastSCMColor macht. Prinzipiell könnte man das mit jedem Funktionsparameter jeder Funktion machen. :D


    Hier ein Beispiel wie die Funktion aussehen würde, wie ich davon ausgegangen bin:
    stock GetPlayerCameraLookAt(playerid, Float:dist, &Float:x, &Float:y, &Float:z) {
    new Float:cmrX, Float:cmrY, Float:cmrZ;
    new Float:vctX, Float:vctY, Float:vctZ;
    GetPlayerCameraPos(playerid, cmrX, cmrY, cmrZ);
    GetPlayerCameraFrontVector(playerid, vctX, vctY, vctZ);
    x = cmrX + dist * vctX;
    y = cmrY + dist * vctY;
    z = cmrZ + dist * vctZ;
    return 1;
    }


    Quelle: https://github.com/MacMailler/…aster/include/r_utils.inc


    In der Quelle finden sich auch noch sehr viele weitere nützliche Funktionen.

  • Natürlich ;)
    Die Länge der Vektoren. Also praktisch der Abstand zwischen Spieler und dem Punkt auf dem man schaut. Man kann ja nicht zwangsläufig einen Punkt fest machen, auf den die Kamera schaut, letztendlich ist es ja eine Gerade im Raum auf die man schaut, und darauf muss man den Punkt bestimmen. Dazu braucht man die Distanz.


    Stell dir vor du bist in einem Würfel im unteren Eck und schaust auf das Eck diagonal oben auf der anderen Seite (gegenüberliegend). Die Gerade zwischen diesen beiden Punkten ist diese Gerade auf die du schaust, keiner kann sagen, wo genau auf der Gerade du hinschaust, da alle Punkte auf der Gerade die gleiche, nennen wir es Richtung, haben. Nur mit der Distanz kann man einen Punkt bestimmen.

  • Wenn du zum Beispiel abfragen willst ob der Spieler einen bestimmten Punkt anschaut, dann mit einer Schleife über die Distanz. So fragst du zum Beispiel 100 Punkte ab, und schaust ob einer der Punkte mit dem Punkt den du suchst übereinstimmt (in etwa natürlich, genau ist ja nicht möglich).

  • Was heißt ein vollkommen unbekannter Punkt? Wie soll man einen Punkt finden den man nicht kennt?
    Es ist nicht möglich einen Punkt zu bestimmen, sondern man bestimmt eine Gerade. Auf dieser Gerade befindet sich dann der Punkt auf den man schaut (man schaut auf alle Punkte der Gerade).

  • Natürlich, in deinem Fall bringt dir die Funktion nicht direkt etwas, das ist klar. Da ist es effizienter so wie du es machst.
    Ja, man kann einen Punkt auf einer Gerade berechnen, das geht schon, nur dazu muss man den Punkt ja kennen, um zu schauen ob er auf der Geraden liegt.



    EDIT:
    @Jack_Bauer:
    Das dürfte das sein, was du benötigst bzw. meinst:



    stock IsPlayerLookingAtPos(playerid, Float:x, Float:y, Float:z, Float:radius = 3.0, Float:maxdist = 100.0)
    {
    new Float:cx, Float:cy, Float:cz, Float:vx, Float:vy, Float:vz, Float:dist;
    GetPlayerCameraPos(playerid, cx, cy, cz);
    GetPlayerCameraFrontVector(playerid, vx, vy, vz);
    dist = floatsqroot((cx-x)*(cx-x) + (cy-y)*(cy-y) + (cz-z)*(cz-z));
    if(dist > maxdist) return 0;
    vx = vx * dist + cx;
    vy = vy * dist + cy;
    vz = vz * dist + cz;
    dist = floatsqroot((vx-x)*(vx-x) + (vy-y)*(vy-y) + (vz-z)*(vz-z));
    if(dist > radius) return 0;
    return 1;
    }


    Bei x, y, z gibst du die Position ein, die du abfragen willst, ob der Spieler diese anschaut, bei radius gibst du die erlaubte Abweichung ein (man schaut ja nie direkt auf genau einen Punkt, es kann ja auch ein paar Zentimeter daneben sein) und bei maxdist gibst du die maximale Distanz zu dem Punkt ein (rein theoretisch kann man von jedem Punkt aus jeden Punkt anschauen, aber das macht ja keinen Sinn, wenn man in LV irgendwo steht, dass man dann einen Punkt in LS anschaut, theoretisch schaut man ihn zwar an, praktisch sieht man ihn aber gar nicht, das ist eben weil Geraden ja in beide Richtungen unendlich lang sind).


    Somit könnte man auch abfragen, ob man ein Fahrzeug oder ein Objekt anschaut, oder gegebenenfalls sogar einen anderen Spieler.


    Beispiele zur Nutzung:

    Spoiler anzeigen
    1.)
    if(IsPlayerLookingAtPos(playerid, 1234.5, 987.6, 12.34)) printf("Spieler %d schaut Position an.", playerid);

    Spoiler anzeigen
    2.)
    new Float:x, Float:y, Float:z;
    GetVehiclePos(myVeh, x, y, z);
    if(IsPlayerLookingAtPos(playerid, x, y, z, 5.0, 20.0)) printf("Spieler %d schaut myVeh an und ist in der Nähe (20m)", playerid);

    Spoiler anzeigen
    3.)
    new Float:x, Float:y, Float:z;
    GetPlayerPos(pID, x, y, z);
    if(IsPlayerLookingAtPos(playerid, x, y, z, 1.0, 5.0)) printf("Spieler %d schaut Spieler %d an.", playerid, pID);



    Keywords: IsPlayerLookingAtPos, IsPlayerLookingAtObject, IsPlayerLookingAtVehicle, IsPlayerLookingAtPlayer, LookAtPos, PlayerFacePlayer, PlayerLookAtObject, SpielerSchautAufPos, SpielerSchautAufSpieler, SpielerSchautAufObjekt, SpielerSchautAufFahrzeug

    3HZXdYd.png

    Einmal editiert, zuletzt von Jeffry ()

  • Jeffry:


    Mit der Funktion VectorSize kannst du das schneller berechnen, quasi anstatt:


    dist = floatsqroot((cx-x)*(cx-x) + (cy-y)*(cy-y) + (cz-z)*(cz-z));


    Kannst du einfach folgendes schreiben:


    dist = VectorSize(cx-x, cy-y, cz-z);


    if(dist > radius) return 0;
    return 1;


    Ein


    return (dist <= radius);


    reicht ^^


    Nette Funktion, gab es aber glaube ich schonmal hier :3

    ast2ufdyxkb1.png


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

  • Mit der Funktion VectorSize kannst du das schneller berechnen



    Quelle: https://wiki.sa-mp.com/wiki/VectorSize
    Ich habe die Funktion absichtlich nicht verwendet, da sie nicht mit den früheren Versionen kompatibel ist, in denen die Camera-Funktionen schon existieren.


    Zwecks dem return sagte ich ja bereits, dass ich meine Codes lieber übersichtlich und verständlich halte, sofern es nur ein paar Nanosekunden ausmacht, aber wenn du es so willst, an mir soll es nicht liegen.

    Spoiler anzeigen
    stock IsPlayerLookingAtPos(playerid, Float:x, Float:y, Float:z, Float:radius = 3.0, Float:maxdist = 100.0)
    {
    new Float:cx, Float:cy, Float:cz, Float:vx, Float:vy, Float:vz, Float:dist;
    GetPlayerCameraPos(playerid, cx, cy, cz);
    GetPlayerCameraFrontVector(playerid, vx, vy, vz);
    if((dist = floatsqroot(floatpower((cx = cx - x), 2) + floatpower((cy = cy - y), 2) + floatpower((cz = cz - z), 2))) > maxdist) return 0;
    return (radius >= floatsqroot(floatpower((vx * dist + cx), 2) + floatpower((vy * dist + cy), 2) + floatpower((vz * dist + cz), 2)));
    }

    7 Millisekunden auf 100.000 Durchläufe schneller (~5%).


    Bzw, wer will, mit VectorSize:

    Spoiler anzeigen
    stock IsPlayerLookingAtPos(playerid, Float:x, Float:y, Float:z, Float:radius = 3.0, Float:maxdist = 100.0)
    {
    new Float:cx, Float:cy, Float:cz, Float:vx, Float:vy, Float:vz, Float:dist;
    GetPlayerCameraPos(playerid, cx, cy, cz);
    GetPlayerCameraFrontVector(playerid, vx, vy, vz);
    if((dist = VectorSize((cx = cx - x), (cy = cy - y), (cz = cz - z))) > maxdist) return 0;
    return (radius >= VectorSize((vx * dist + cx), (vy * dist + cy), (vz * dist + cz)));
    }


    Nur versteht den Code wohl kaum einer noch.


    Das hier ist nicht der Code-Optimierungs Thread

    :rolleyes:

  • Ich habe die Funktion absichtlich nicht verwendet, da sie nicht mit den früheren Versionen kompatibel ist


    Wieso entwirfst du denn Funktionen für alte SA:MP Versionen. Macht irgendwie keinen Sinn...da bald eh alle 0.3.7 nutzen werden...oder ~95% aller Server eh 0.3z momentan nutzen.



    Zitat von »Kaliber«
    Das hier ist nicht der Code-Optimierungs Thread


    Das war ja auch weniger Optimiert, eher hätte es die schreibweise vereinfacht bzw den Code übersichtlicher und kürzer gemacht :P (Das schneller wäre nur ein positiver Nebeneffekt.)


    Wenn wir schon dabei sind:


    Spoiler anzeigen
    stock IsPlayerLookingAtPos(playerid, Float:x, Float:y, Float:z, Float:radius = 3.0, Float:maxdist = 100.0)
    {
    new Float:cx, Float:cy, Float:cz, Float:vx, Float:vy, Float:vz, Float:dist;
    GetPlayerCameraPos(playerid, cx, cy, cz),GetPlayerCameraFrontVector(playerid, vx, vy, vz);
    cx-=x,cy-=y,cz-=z,dist = VectorSize(cx, cy, cz);
    return (dist > maxdist) ? 0 : _:(radius >= VectorSize(vx * dist + cx, vy * dist + cy, vz * dist + cz));
    }


    mfg. :thumbup:


    //Edit: Da war n TAG Mismatch drinnen..

    ast2ufdyxkb1.png


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

    Einmal editiert, zuletzt von Kaliber ()

  • den Code übersichtlicher


    Also übersichtlicher ist das so ganz sicher nicht.
    Übersichtlicher wäre es wenn untereinander und nicht alles hintereinander gequescht.

    "Bevor ich mir Informationen aus der "Bild" hole,
    werde ich anfangen, Wahlergebnisse danach vorauszusagen,
    neben welchen Busch unsere Katze gepinkelt hat."

    Margarete Stokowski

  • Übersichtlicher wäre es wenn untereinander und nicht alles hintereinander gequescht.


    Ich habe von meinem Beitrag davor gesprochen und natürlich ist dist = VectorSize(cx-x, cy-y, cz-z); übersichtlicher als dist = floatsqroot((cx-x)*(cx-x) + (cy-y)*(cy-y) + (cz-z)*(cz-z));

    ast2ufdyxkb1.png


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