Beiträge von Stas

    Vorwort:
    Dies ist ein HeadShot - Script zu einem meiner Tutorials (klick ), welches den Gebrauch der Vektor- und Kamera Funktion des neuen SAMP 0.3 R5 (R7) releases verdeutlicht. Das Script funktioniert ganz einfach. Es werden in einem Zylinder sogesagt ein paar Kugeln erstellt, welche die Position des Kopfes darstellen sollen.
    Wenn der Schütze eines dieser trifft, dann ist es ein Headshot. Die Entfernung beträgt 100 Einheinten und sollte nicht erhöhrt werden, da die Rechnung sonnst zu auslastend wäre. Wollte dafür keine 3D-Verktor-Rechnung erstellen, da das mir noch zu kompliziert ist.
    Lange Rede - kurzer Sinn - kommen wir zu der Installation.


    Installation:
    Die Installation ist ganz simple, da es ein einfaches FilterScript ist.
    Um dieses Filterscript zu installieren, müsst ihr es einfach zuerst in den FilterScripts - Ordner einfügen und danach "headshot_script" in die "filterscripts" - Zeile in der server.cfg eintragen.


    Vorschau:
    Die Vorschau hab ich mir mal gespart, da es eigentlich verständlich ist, was das Script macht. Es wurde aber gut getestet, mit Winkeln bis zu ca. 70°.


    Updates:
    - v 1.1: SendDeathMessage bei Tod, #define SENDE_NACHRICHT ausklammern, falls unerwünscht
    - v 1.2: HeadShot nun mit mehreren Waffen möglich; bestimmen der Waffen in der Funktion: ValideWaffe(waffe) (Zeile 51)


    Download:
    - PasteBin (macht aber meine schöne Einrückung kaputt :cursing: )
    - breadfish.de/wcf/attachment/1983/


    Danksagung:
    Wie immer Danke an meinen Lehrer Ping ;)

    Noch eine Idee: Wenn Polizist aus einem SWAT-Van auf einen Spieler schießt, kann der so verletzt werden, durch zB heißen Wasser. Oder gefreezed, weil der Druck zus tart war.
    Für die Feuerwehr: Einmal in einer 10 Minuten spawnt ein brennendes Objekt. der Feuerwehrmann muss hinfahren und dieses 5 Sekundenlang anvisieren und dabei Schießen halten. Dann wirds wieder gelöscht und Mission erfolgreich beendet.


    Solche Sachen sind dmait möglich.

    :D Danke Danke :D


    Soll ich mich da mal durcharbeiten? ^^


    PS: Da gibt es auch keine Möglichkeit für pVars, ist schon richtig so. Hast ne PN :D

    Wie wärs mit einem neuem Krankenhaus Interior. Das ist schwerer, sowas realistisch zusammen zu bauen. Mit allem drum und dran. Kantine, Empfang, Wartezimmer, Krankzimmern, OP Zimmern etc.

    Beschreibung:
    Mit Hilfe der Kamera Vektor - Funktionen ist es nun möglich zu überprüfen, welchen Punkt der Spieler nun ungefähr anguckt.
    Dieses kann nur abgefragt werden, wenn der Spieler zu Fuß oder in einem Fahrzeug mit möglicher Zielvorrichtung ist.
    Dies ist seit der 0.3a R5 Version von SAMP möglich.
    Auf diese Weise ist es nun möglich, schöne RolePlay Funktionen wie zB Feuerwehr (anvisieren brennender Objekte) zu erstellen.


    Funktionen:
    Folgende Funktionen werden wir für unser Script brauchen, mit dem wir das Anvisieren eines Punktes ermitteln wollen:


    GetPlayerCameraPos(playerid, &Float:x, &Float:y, &Float:z);
    Diese Funktion ermittelt die Positon der Kamera des Spielers und speichert diese in vorher erstellte Floats.
    Zum Beispiel:


    new Float:x, Float:y, Float:z;
    GetPlayerCameraPos(playerid, x, y, z);
    printf("Die Kamera des Spielers befindet sich auf den Koordinaten X: %f, Y: %f, Z: %f.", x, y, z);


    GetPlayerCameraFrontVector(playerid, &Float:x, &Float:y, &Float:z);
    Diese Funktion ist einfach die Längeneinheiten als Vektor, in welche Richtung der Spieler aus der Kamera-Position anstrebt.


    Vorarbeit:
    Als erstes erstellen wir eine Funktion, welche die Distanz der Kamera zu einem Punkt berechnet ...
    stock Float:ErmittleDistanzZumPunkt(Float:CamX, Float:CamY, Float:CamZ, Float:PunktX, Float:PunktY, Float:PunktZ, Float:FrontX, Float:FrontY, Float:FrontZ) {
    new Float:Distanz;
    Distanz= floatsqroot((CamX - PunktX) * (CamX - PunktX) + (CamY - PunktY) * (CamY - PunktY) + (CamZ - PunktZ) * (CamZ - PunktZ));
    new Float:tmpX, Float:tmpY, Float:tmpZ;
    tmpX = FrontX * Distanz+ CamX;
    tmpY = FrontY * Distanz+ CamY;
    tmpZ = FrontZ * Distanz+ CamZ;
    return floatsqroot((tmpX - PunktX) * (tmpX - PunktX) + (tmpY - PunktY) * (tmpY - PunktY) + (tmpZ - PunktZ) * (tmpZ - PunktZ));
    }


    ... und eine die überprüft, ob ein Spieler einen bestimmten Punkt anzielt:
    stock ZieltSpielerAufPunkt(playerid, Float:x, Float:y, Float:z, Float:radius)
    {
    new Float:cx,Float:cy,Float:cz,Float:fx,Float:fy,Float:fz;
    GetPlayerCameraPos(playerid, cx, cy, cz);
    GetPlayerCameraFrontVector(playerid, fx, fy, fz);
    return (radius >= ErmittleDistanzZumPunkt(cx, cy, cz, x, y, z, fx, fy, fz));
    }


    Gebrauch:
    Nun könnt ihr mit einer kleinen Abfrage ermitteln, ob der Spieler einen Punkt anvisiert.
    Dazu musst ihr bloss überprüfen, ob der die Funktion ZieltSpielerAufPunkt eintrifft.
    Um das zu testen habe ich ein Auto erstellt und dessen Koordinaten in einem enum gespeichert.
    Das gleiche könnt ihr aber auch mit Objekten machen. Dies könnt ihr zB dann abfragen, wenn der Spieler die schießen-Taste drückt.
    So siehts aus:

    if(ZieltSpielerAufPunkt(playerid, Autos[1][Position][X], Autos[1][Position][Y], Autos[1][Position][Z], 2.0)) {
    SendClientMessage(playerid, 0x00ff00ff, "Erfolg!");
    }
    Den Radius könnt ihr bei 1.0 oder 2.0 lassen, je nach dem wie genau der Schuss sein soll.


    Schlusswort:
    Ich habe in diesem Tutorial extra keine fertige Funktion erstellt, damit ihr selber noch dran denken könnt. Daher ist es nicht für Anfänger, sondern für Leute mit etwas Ahnung von PAWN gedacht. Ich hoffe, ich konnte euch einen kleinen Schritt weiter bringen ;)


    Credits:
    RedShirt - Distanzermittlungs- Funktion

    Ebenfalls ganz einfach. Man muss nur immer halt den richtigen Gedanken finden.
    Du speicherst die Koordinaten, Model und Tuningteile etc. in einer .ini (im zB Odner "autos"), welche den Spielernamen hat.
    Bei OnPlayerConnect überprüfst du, ob zu dem Spielernamen die Auto - Ini existiert. Wenn ja, dann lädst du die Inhalte und erstellst das Auto.
    Wenn er /parken macht, dann werden die Inhalte der .ini aktualisiert. Wenn er den Server verlässt, kann man das auch. (dort halt nur die Tuning Teile)

    Das ein ein Tutorial kein Script, CCCP. Wie meinst du das denn? 8|


    Update:
    Include selber erstellen:
    Eine Include selber erstellen, ist nicht sehr schwer. Genau genommen sind es einfach die Funktionen, die genauso im GameMode geschrieben werden können.
    Damit ihr aber nicht immer den kompletten GameMode compilen musst, um zu gucken, ob in der Include keine Fehler sind, kann man in diese Include ebenfalls andere Includes (a_samp) includen. So könnte eine eigene Include aussehen: PasteBin

    Das brauchst du eig. nur einmal.


    Und den Rest machst du wie bfx es gesagt hat. Du setzt den Spieler einfach eine pVar Fraktion auf die FraktionsID, siehe Godfather.
    Die Fraktionsachen wie Spawn, Name etc. kannst du in MySQL oder ini speichern lassen.

    Da hast du Recht.


    Ich bin mir nicht mehr genau sicher, wie die Begründung dafür war.
    Aber ich habe es auch immer so gemacht und da meinte Y_Less (bin mir nicht mehr ganz sicher), dass es so unschön wäre, obwohl es ja kürzer sei.





    Edit:
    Eine weitere wichtige Funktion für das Optimieren des Codes ist die neue pVar Funktion des R5 - Releases (Zitat):
    _____________________________________________________________________________________


    Per-player variable system: (PVars)


    Originally SA-MP was only designed for 100 maximum players. This meant defining arrays in pawn of MAX_PLAYERS size such as: PlayerInfo[MAX_PLAYERS] was generally okay. Now that MAX_PLAYERS is defined as 500, script writers are finding themselves creating arrays with 500 elements just to store a single flag. This can turn out to be very wasteful in terms of memory use. These variables also need to be manually reset when the player using them leaves the server.


    Advantages of using PVars over arrays of MAX_PLAYERS:
    1) PVars can be shared/accessed across gamemode scripts and filterscripts, making it easier to modularise your code.
    2) PVars are automatically deleted when a player leaves the server, meaning you don't have to manually reset variables for the next player who joins.
    3) No real need for complex enums/player info structures.
    4) Saves memory by not allocating pawn array elements for playerids which will probably never be used.
    5) You can easily enumerate and print/store the PVar list. This makes both debugging and player info storage easier.
    6) Even if a PVar hasn't been created, it still will return a default value of 0.
    7) PVars can hold very large strings using dynamically allocated memory.



    // Per-player variable system (PVars)
    native SetPVarInt(playerid, varname[], int_value);
    native GetPVarInt(playerid, varname[]);
    native SetPVarString(playerid, varname[], string_value[]);
    native GetPVarString(playerid, varname[], string_return[], len);
    native SetPVarFloat(playerid, varname[], Float:float_value);
    native Float:GetPVarFloat(playerid, varname[]);
    native DeletePVar(playerid, varname[]);


    // PVar enumeration
    #define PLAYER_VARTYPE_NONE 0
    #define PLAYER_VARTYPE_INT 1
    #define PLAYER_VARTYPE_STRING 2
    #define PLAYER_VARTYPE_FLOAT 3


    native GetPVarsUpperIndex(playerid);
    native GetPVarNameAtIndex(playerid, index, ret_varname[], ret_len);
    native GetPVarType(playerid, varname[]);

    _____________________________________________________________________________________

    Per-player variable system: (PVars).


    Originally SA-MP was only designed for 100 maximum players. This meant defining arrays in pawn of MAX_PLAYERS size such as: PlayerInfo[MAX_PLAYERS] was generally okay. Now that MAX_PLAYERS is defined as 500, script writers are finding themselves creating arrays with 500 elements just to store a single flag. This can turn out to be very wasteful in terms of memory use. These variables also need to be manually reset when the player using them leaves the server.


    Advantages of using PVars over arrays of MAX_PLAYERS:
    1) PVars can be shared/accessed across gamemode scripts and filterscripts, making it easier to modularise your code.
    2) PVars are automatically deleted when a player leaves the server, meaning you don't have to manually reset variables for the next player who joins.
    3) No real need for complex enums/player info structures.
    4) Saves memory by not allocating pawn array elements for playerids which will probably never be used.
    5) You can easily enumerate and print/store the PVar list. This makes both debugging and player info storage easier.
    6) Even if a PVar hasn't been created, it still will return a default value of 0.
    7) PVars can hold very large strings using dynamically allocated memory.



    // Per-player variable system (PVars)
    native SetPVarInt(playerid, varname[], int_value);
    native GetPVarInt(playerid, varname[]);
    native SetPVarString(playerid, varname[], string_value[]);
    native GetPVarString(playerid, varname[], string_return[], len);
    native SetPVarFloat(playerid, varname[], Float:float_value);
    native Float:GetPVarFloat(playerid, varname[]);
    native DeletePVar(playerid, varname[]);


    // PVar enumeration
    #define PLAYER_VARTYPE_NONE 0
    #define PLAYER_VARTYPE_INT 1
    #define PLAYER_VARTYPE_STRING 2
    #define PLAYER_VARTYPE_FLOAT 3


    native GetPVarsUpperIndex(playerid);
    native GetPVarNameAtIndex(playerid, index, ret_varname[], ret_len);
    native GetPVarType(playerid, varname[]);