Beiträge von M4rciii

    Ich habe das so ausführlich gemacht, sodass es jemand verstehen kann, der es verstehen will.


    Ich meine, wenn man nicht bereit ist, dieses kleine Stück Zeit aufzubringen, dann sollte mans mit dem Scripten echt sein lassen.

    Guten Tag alle miteinander!


    Ich möchte euch heute zeigen, wie man ein Tutortial anschaulich und sauber gestaltet, da das immer weniger in dieser Tutorial-Kategeorie vorzufinden ist.
    Das kann ich am besten, in dem ich selber eines über ein einfaches Anfänger-Thema schreibe, nämlich über Teleports von Spielern.



    Bei Teleports wird man immer zu einer Position teleportiert, die eindeutig durch 3 Koordinaten bestimmbar ist. Man erhält diese Koordinaten ganz einfach, indem man sich auf einem Server an eine Stelle stellt und dort den Command /save [Kommentar] eingibt. Nun müsst ihr in euer Rockstar Games/GTA San Andreas-Verzeichnis schauen, dort sollte eine Datei namens savedpositions.txt sein. In dieser Datei werden alle eure gespeicherten Positionen aufbewahrt. Ihr könnt dort beispielsweise so etwas vorfinden:

    Zitat

    AddPlayerClass(212,-1061.8599,1562.4587,33.2313,32.5994,0,0,0,0,0,0); // Kommentar

    -1061.8599,1562.4587,33.2313 sind die X, Y und Z Koordinaten. Direkt dahinter könnt ihr die Drehung sehen, in der ihr in dem Moment gestanden seid, hier 32.5994. Die restlichen Variablen in dieser Zeile interessieren uns nicht.
    Wärt ihr zu dem Zeitpunkt des Speicherns in einem Fahrzeug gewesen, könnte das ungefähr so aussehen:

    Zitat

    AddStaticVehicle(519,-1061.8599,1562.4587,33.2313,32.5994,1,1); //Kommentar

    Auch hier gelten dieselben Koordinaten wie oben.




    Um einen Teleport selbst zu erstellen, solltet ihr den Grundaufbau kennen:


    SetPlayerPos(playerid,Float:X,Float:Y,Float:Z);
    Hierbei wird der Spieler playerid zu den Koordinaten X, Y und Z teleportiert. Wenn man einen Spieler so teleportiert, behält er seine Drehung bei. Guckt er in diesem Moment nach Süden, schaut er auch bei seiner neuen Position nach Süden. Sollte der Spieler beim Teleport in einem Fahrzeug sein, wird er herausgerissen. Wie man das Fahrzeug mitteleportiert, seht ihr weiter unten.


    SetPlayerFacingAngle(playerid,Float:A);
    Diese Funktion dreht den Spieler playerid auf den Winkel A(0°-360°). Sollte A = 0.0 sein, dann schaut er nach Norden, bei A = 180.0 schaut er nach Süden.


    SetPlayerInterior(playerid,int);
    Diese Funktion steckt den Spieler playerid in das Interior int. Diese Funktion wird vorallem gebraucht, wenn man beispielsweise jemand in ein Haus teleportiert (Interior != 0). Jedoch sollte man bei den meisten Teleports in den freien Raum den Spieler in das Interior 0 stecken, da der Spieler den Teleport auch aus einem Haus heraus betätigen könnte.


    SetPlayerVirtualWorld(playerid,virtualw);
    Diese Funktion weist dem Spieler playerid die VirtualWorld virtualw zu. Dies ist beispielsweise nötig, um Spieler zwar zur gleichen Position zu bringen, jedoch so, sodass sie sich nicht gegenseitig sehen. Bsp: mehrere Verwendung von Häusern.



    Mit diesen Kenntnissen können wir schon einen solchen Teleport erstellen:
    SetPlayerPos(playerid,1864.5662,-1383.5651,13.4896);
    SetPlayerFacingAngle(playerid,233.7254);
    SetPlayerInterior(playerid,0);
    SetPlayerVirtualWorld(playerid,0);



    Nun stellen wir fest: Wenn wir den Teleport so nutzen, wird das Auto nicht mitteleportiert.



    Wenn das Auto mitteleportiert werden soll, müsst ihr diese Funktionen benutzen:


    SetVehiclePos(vehicleid,Float:X,Float:Y,Float:Z);
    Hier wird das Fahrzeug vehicleid ganz einfach zu den Koordinaten X, Y und Z gebracht. (Ist wie SetPlayerPos, nur für Autos).


    SetVehicleZAngle(vehicleid,Float:A);
    Das Fahrzeug vehicleid wird auf den Winkel A gedreht. (Ist wie SetPlayerFacingAngle, nur für Autos).


    LinkVehicleToInterior(vehicleid,int);
    Das Fahrzeug vehicleid wird in das Interior int gesteckt. Dies wird aber selten benutzt, eventuell bei einer Stuntarena. (Ist wie SetPlayerInterior, nur für Autos).


    SetVehicleVirtualWorld(vehicleid,virtualw);
    Das Fahrzeug vehicleid wird in die VirtualWorld virtualw gesteckt.



    Mit diesen Kenntnissen können wir nun einen solchen Teleport erstellen, bei dem Autos mit teleportiert werden:
    new veh = GetPlayerVehicleID(playerid); // Abspeichern der FahrzeugID des Spielers => Unten dann weniger Schreibarbeit, da man nur "veh" schreiben muss
    if(GetPlayerState(playerid) == PLAYER_STATE_DRIVER) // Ist der Spieler der Fahrer eines Fahrzeugs?
    {
    SetVehiclePos(veh,1864.5662,-1383.5651,13.4896);
    SetVehicleZAngle(veh,233.7254);
    LinkVehicleToInterior(veh,0);
    SetVehicleVirtualWorld(veh,0);
    }
    else
    {
    SetPlayerPos(playerid,1864.5662,-1383.5651,13.4896);
    SetPlayerFacingAngle(playerid,233.7254);
    }
    SetPlayerInterior(playerid,0); // Auch wenn man mit dem Auto teleportiert wird, muss der Spieler selbst auch das Interior des Autos annehmen
    SetPlayerVirtualWorld(playerid,0); // Auch wenn man mit dem Auto teleportiert wird, muss der Spieler selbst auch die VirtualWorld des Autos annehmen



    Jetzt kann man einen Teleport-CMD ganz einfach von der Hand schreiben:
    if(strcmp("/teleport",cmdtext,true) == 0)
    {
    if(GetPlayerState(playerid) == PLAYER_STATE_DRIVER)
    {
    SetVehiclePos(GetPlayerVehicleID(playerid),1864.5662,-1383.5651,13.4896);
    SetVehicleZAngle(GetPlayerVehicleID(playerid),233.7254);
    }
    else
    {
    SetPlayerPos(playerid,1864.5662,-1383.5651,13.4896);
    SetPlayerFacingAngle(playerid,233.7254);
    }
    // Interior und Virtualworld werden nicht berücksichtigt
    return 1;
    }


    Wer seine Command auf DCMD basierend schreibt, kann es so machen:
    // In OnPlayerCommandText:
    dcmd(teleport,8,cmdtext); // teleport=Name des Commands 8=Länge des Commands cmdtext=String, in dem der Command steht


    // Unten ins Script
    dcmd_teleport(playerid,params[])
    {
    #pragma unused params // Die Parameter hinter /teleport sind uns wayne ;)
    if(GetPlayerState(playerid) == PLAYER_STATE_DRIVER)
    {
    SetVehiclePos(GetPlayerVehicleID(playerid),1864.5662,-1383.5651,13.4896);
    SetVehicleZAngle(GetPlayerVehicleID(playerid),233.7254);
    }
    else
    {
    SetPlayerPos(playerid,1864.5662,-1383.5651,13.4896);
    SetPlayerFacingAngle(playerid,233.7254);
    }
    // Interior und Virtualworld werden nicht berücksichtigt
    return 1;
    }


    Sollte euch diese DCMD-Methode nicht so ganz vertraut sein, könnt ihr gerne dieses Tutorial anschauen.



    Natürlich muss es nicht immer ein Command sein, wieso kein Pickup?
    public OnPlayerPickUpPickup(playerid,pickupid)
    {
    if(pickupid == teleportpickup)
    {
    SetPlayerPos(playerid,1864.5662,-1383.5651,13.4896);
    SetPlayerFacingAngle(playerid,233.7254);
    }
    return 1;
    }


    Wenn ihr mit Pickups nicht vertraut seid, könnt ihr dieses Tutorial anschauen.



    Nun denkt sicher der ein oder andere: GEHT DAS DENN NICHT EINFACHER???

    Dazu habe ich einmal diese Funktion geschrieben, die einem die 10 Zeilen Schreibarbeit abnimmt. Sie befindet sich im Dateianhang. Ihr könnt sie zum Beispiel wiefolgt nutzen:
    CreateTeleport(playerid,2494.0205,-1670.3756,13.3359,90.0,true,0,0,200) // Teleport mit Fahrzeug, Sicht nach Osten, Interior sowie Virtualworld auf 0 und 200 Dollar Kosten



    Puhh, das war jetzt eine Menge Schreibarbeit. Ein Tutorial muss nicht immer wie Kraut und Rüben aussehen, sondern kann einem auch anschaulich und ausführlich erklären, wie etwas funktioniert.
    Darum ging es mir hierbei.


    Grüßle, M4rciii :)


    Last Update: 22.12.2009 - 15:38

    Also ich würde dem Tutorial 0,5/10 geben, da:

    • Nicht im Ansatz erklärt, wie DCMD geht
    • was ist bitte strcmd?
    • Das IsPlayerConnected ist nicht nötig, wie sollte denn jemand der nicht auf dem Server ist, den CMD eingeben?
    • Nicht erklärt, wie man an dieses Koordinaten kommt
    • Die Drehung/Angle außen vor gelassen
    • Auch nicht den DCMD-Code gepostet (#define dcmd(...)

    Und ein kleiner Tipp zur Erweiterung: Was passiert wenn man in einem Auto sitzt? / Wie geht das, dass das Auto mitteleportiert wird?

    Bau es einfach in deinen Gamemode ein!


    Diese ganzen new's tust du nach oben zu den anderen.


    Das pickup1 = ... kommt in OnGameModeInit().


    Der Inhalt von OnPlayerPickUpPickup tust du ohne das return 1; in dein OnPlayerPickUpPickup rein.


    Aber bitte neu downloaden, da ich das ganze Tut auf 0.3 umgeschrieben habe (auch das Scriptbeispiel).

    Das mit der while-Schleife ist glaube ich nicht sonderlich ressourcenschonend. Versuchs mal so:
    SendClientMessage(playerid, COLOR_RED, "HALLO");
    SendClientMessageDelay(playerid, COLOR_RED, "GEHE ZUM CHECKPOINT", 2000);


    Oben ins Script:
    #define SendClientMessageDelay(%1,%2,%3,%4) SetTimerEx("SCMD",%4,0,"dxs",%1,%2,%3);
    public SCMD(playerid,color,message[]) return SendClientMessage(playerid,color,message);



    Nun kannst du immer dieses Funktion benutzen:
    SendClientMessageDelay(playerid,color,message,delay); // delay = Zeitabstand in Millisekunden

    FAIL!
    Das ist mal wieder super... Jeder sagt "Ach wie toll!! 10/10 Punkten", wobei das Tutorial komplett falsch ist...


    Bei random(4) können 0,1,2 und 3 ausgegeben werden.
    Das heißt mit diesem Code ist es unmöglich die 500$ zu gewinnen.


    Wenn ein Neuling jetzt die SuFu benutzt, dieses Thema findet, wird es ihm von Anfang an falsch beigebracht! :thumbdown:


    Wenn man ein Tut schreibt, sollte man es wenigstens selbst können!!


    PS: Ich weis, das Thema ist alt, aber wenn hier so ne Scheisse verzapft wird, muss man mal was sagen.

    Nunja, ist ok. 7,5/10
    Du solltest noch ne Version machen, wo die News in ne Datei gespeichert werden und dann beim Restart automatisch wieder geladen werden.

    Ahh...kleiner Leichtsinnsfehler von mir. Ändere die Funktion von
    stock SetVehiclePosEx(vehicleid,x,y,z,a)
    in
    stock SetVehiclePosEx(vehicleid,Float:x,Float:y,Float:z,Float:a)


    Bei Zeile 792 ist RaceNamen wahrscheinliche ein String/Zeichenkette. Das muss aber ein Integer/Ganzzahl sein. Die Variable muss irgendwie anders heißen.

    Ich bin mir gar nicht sicher, ob man überhaupt mit was anderem außer Abschleppwagen und Traktor abschleppen kann.
    Das bin ich mal schnell testen...


    EDIT:
    Ja, es geht. Man kann einen Infernus an einen Infernus dranhängen, jedoch is dazwischen kein Abstand und kein Seil, sondern die sind wie aneinandergeklebt.

    Denk bitte mal nach, bevor du was postest. Wenn ich das jetzt les, schließe ich daraus: In den Zeilen 792-800 sind Fehler... Kann ich nun telepathisch in deinen Script schauen?
    Also wenn schon, dann bitte mit den dazugehörigen Zeilen 790-805.


    PS: Sorry, soll jetzt nicht beleidigend klingen, ich will eig nur helfen.

    Ach weist du was, mach es einfach so:
    new vehicleid = GetPlayerVehicleID(playerid);
    switch(race) // anstatt race deine variable eintragen, mit der die "Rennennummer" gespeichert wird
    {
    case 0: SetVehiclePosEx(vehicleid,x,y,z,a); // Koordinaten für Spawn von Rennen 0 eintragen
    case 1: SetVehiclePosEx(vehicleid,x,y,z,a); // Koordinaten für Spawn von Rennen 1 eintragen
    case 2: SetVehiclePosEx(vehicleid,x,y,z,a); // Koordinaten für Spawn von Rennen 2 eintragen
    // usw.
    }


    // Irgendwo ins script:
    stock SetVehiclePosEx(vehicleid,x,y,z,a)
    {
    SetVehiclePos(vehicleid,x,y,z);
    SetVehicleZAngle(vehicleid,a);
    return 1;
    }


    Dann musst du zwar für jedes Rennen den Spawn /saven, aber es ist einfach einfach.

    Also, wenn du das Machen willst, dann müsstest du den FacingAngle, also die Drehung des Checkpoints wissen.
    // Diese Funktion irgendwo ins Script rein. Ich bin mir nicht sicher ob sie funktioniert, da ich sie soeben von GetXYInFrontOfPlayer abgeleitet hab
    Float:GetXYInFrontOfPosition(Float:positionX, Float:positionY, &Float:X, &Float:Y, Float:distance, Float:angle)
    {
    X = positionX + (distance * floatsin(-angle, degrees));
    Y = positionY + (distance * floatcos(-angle, degrees));
    return 1;
    }


    // Beim Teleport:
    new Float:racex, Float:racey;
    GetXYInFrontofPosition(RaceCheckpoints[0][0],RaceCheckpoints[0][1],racex,racey,-10.0,/*ANGLE*/); // Drehung des Checkpoints eintragen
    SetVehiclePos(GetPlayerVehicleID(playerid),racex,racey,RaceCheckpoints[0][2]);
    SetVehicleZAngle(GetPlayerVehicleID(playerid),/*ANGLE*/); // Drehung des Checkpoints eintragen


    Die Drehung steht übrigens nirgends geschrieben, wenn dann müsstest du dich in den Start des Checkpoint in die richtige Richtung reinstellen, Position speichern und davon dann die Angle-Kommazahl nehmen.

    Versuch es nach diesem Schema:
    public OnDialogResponse(playerid, dialogid, response, listitem, inputtext[])
    {
    if(dialogid == 1) // Deine Dialogid
    {
    switch(listitem)
    {
    case 0: //Wenn das erste Listenelement gewählt wurde
    {
    // Hier der Code mit dem Fightstyle
    }
    case 1: //Wenn das zweite Listenelement gewählt wurde
    {
    // Hier der Code mit dem Fightstyle
    }
    // usw.
    }
    }
    return 1;
    }

    Im Anhang ist ein Beispiel, wie dieses Bombenscript aussehen könnte (von mir grade geschrieben).


    Im Prinzip geht das so:
    new Float:X, Float:Y, Float:Z;
    GetPlayerPos(playerid,X,Y,Z);
    Jetzt ist die Spielerposition von playerid in X,Y und Z gespeichert.
    Dann kann man damit den Spieler beispielsweise ein Stückchen nach oben teleportieren:
    SetPlayerPos(playerid,X,Y,Z+3); //Z-Achse ist jetzt 3 Einheiten höher