Meinst du nicht das Version 296 etwas alt ist?
Gibt ja schon Version 36X ![]()
Weiß die ganue Version jetzt nicht
Meinst du nicht das Version 296 etwas alt ist?
Gibt ja schon Version 36X ![]()
Weiß die ganue Version jetzt nicht
Und bei Windows 8 bekommt man noch keine Grafikkarten Treiber
Also NVidea ist schon fleißeig dabei, die Treiber zu updaten.
Wie das bei ATI aussieht, ist so eine Sache ![]()
So langsam driften wir hier in den Illegalen Bereich ab.
Darum mach ich mal zu.
In dem Fall wäre "reason" weaponid.
Guck in die Wiki und du weißt warum ![]()
Blunt
Danke - habs ausgebessert ![]()
Das müsstest du dann alles unter OnPlayerDeath regelen,
dabei ist aber zu beachten, das man auch selbst Mord begehen kann.
Sprich killerid hat den Wert von INVALID_PLAYER_ID
Der Wert liegt wiederrum außerhalb, der MAX_PLAYERS angabe
und kann zum absturz des Codes und/oder des Servers führen
und meine wiki bewerbung ist immernoch nicht bearbeitet kam die vielleicht ausversehen in mülleimer oda so ?
Nein, ich vergess das immer nur, da scheinbar die Leute der Meinung sind mir aus meinen 30 ungelesenen 35 - 38 zumachen,
deshalb hab ich auch den Satz in der Signatur ![]()
@Rocky
Das hat nur den Sinn das Includes endlich auch mal Includes sind und nicht zu Codeschnipseln werden.
Beispiel -> B_Stream
Erst war es ja nötig
Beavis_OnPlayerConnect(playerid);
mit einzubinden.
Nachdem ich ihm das erklärt hab und dem Tutorial muss man das ja nicht mehr ![]()
@TheO
Ich glaub auch nicht das ein Anfänger, auf die Idee kommt eine Komplexe Include zu schreiben ![]()
Die Funktion "ClearChat" gibt es standardmäßig nicht ![]()
Würde aber schneller gehen, als jetzt auf antworten zu warten ![]()
Hmm neu Installieren ist so eine Sache da es Steam ist
Naja -gehst in den Steamapps Ordner und löscht da den Ordner vom Landwirtschaftssimulator
Setzen des eigentlichen Hooks
Da muss ich dich kurz verbessern.
Setzen des neuen Hooks.
Ich hab mir mal sein Problem angesehen,
es liegt bzw lag am fehlenden Aufruf der gehookten Funktion
Das Prinzip ist das gleiche wie vorher, nämlich ALS_Hooking,
nur benutzen wir hier keine Forwards bzw Publics sondern müssen hier direkt in das Native System eingreifen.
Desweitern werden wir hier stocks benutzen,
publics sind hier nutzlos, da wir sie nicht per CallLocalFunction oder Timer aufrufen.
Ok, greifen wir ein.
Zu erst müssen wir eine eigene Native erstellen und dem die Funktion zuweisen.
Hier werde ich SendClientMessage als Beispiel nehmen ![]()
Nun haben wir zwar unsere eigene Native,
aber wenn wir den Server nun starten würden, käme "File or Function not found".
Der Grund ist der, die Native ist nirgends registriert.
Sprich der Server kennt diese nicht.
das umgehen wir, einfach, da wir hier ja kein Plugin schreiben, mit einer einfachen zuweisung.
Auch hier gilt, das wir uns dazwischen hängen wollen.
native __SendClientMessage(playerid,color,const string[]) = SendClientMessage; // Wir weisen hier unsere Native zu, das sie wie SendClientMessage funktionern soll. Das ist Später wichtig.
Nun erstellen wir unseren Stock.
Achtung: Er darf nicht wie die Native lauten.
Das ist nun unsere "neue" SendClientMessage Funktion.
Diese hooken wir genauso, wie die Callbacks, siehe oben.
Aber moment, was machen wir nun, wenn wir die alte SendClientMessage verwenden wollen?
Gute Frage - dafür haben wir ja unsere native.
Die Include dürfte nun so aussehen:
native __SendClientMessage(playerid,color,const string[]) = SendClientMessage;
stock _SendClientMessage(playerid,color,const string[])
{
//weiteres
__SendClientMessage(playerid,color,string);
return 1;
}
#if defined _ALS_SendClientMessage
#undef SendClientMessage
#else
#define _ALS_SendClientMessage
#endif
#define SendClientMessage _SendClientMessage
Alles anzeigen
So könnt, ihr auch euren Funktionen neue Parameter zuweisen ![]()
Ich hoffe ihr habt verstanden was ihr gelesen habt,
falls Fragen oder Ergänzungen sind, dafür bin ich immer offen ![]()
Hallo Community,
aufgrund diverser Includes, die mich schon fast kotzen lassen,
zeige ich euch mal, wie ihr jetzt richtig Includes schreibt.
Dafür benötigen wir das sogenannte "hooking".
Was ist Hooking?
Hook ist englisch und bedeutet Haken (siehe z.B. Kapitän Hook).
Im Endeffekt heißt es also nichts anderes als sich irgendwo einzuhaken bzw sich irgendwo dazwischen zu klemmen.
Wozu wird Hooking benötigt?
Hooking wird z.B. in Includes benötigt und zwar aus einem einfachen Grund.
Includes sind theoretisch nichts weiter als Implementierung in die Scripte.
Beispiel:
Script:
#include <BeispielInclude>
forward Tutorial(playerid);
forward SekundenTimer();
main() { }
public Tutorial(playerid)
{
return 1;
}
public SekundenTimer()
{
return 1;
}
Include:
new Variable;
new Float:FloatVariable;
new Array[5];
So würde der Code zusammengefasst aussehen
new Variable;
new Float:FloatVariable;
new Array[5];
forward Tutorial(playerid);
forward SekundenTimer();
main() { }
public Tutorial(playerid)
{
return 1;
}
public SekundenTimer()
{
return 1;
}
Wie man nun sehr gut erkennen kann wurde #include <BeispielInclude>
mit dem Inhalt der BeispielInclude ersetzt.
Wozu ich euch das zeige?
Einfach
Wenn wir nun 2x eine Funktion im Script haben, spuckt der Compiler logischerweise einen Fehler aus,
da er nicht genau weiß, was nun mit der 2. Funktion geschehen soll.
Wie verhindert man dies?
Theoretisch gar nicht.
Oder doch?
Prinzip ist einfach.
Man hakt sich zwischen die Funktionen.
Bitte bedenkt, das sich das zwar auf alle Funktionen ausweiten lässt,
aber nicht immer Sinn macht.
Ab wann was Sinn macht, lest ihr weiter unten.
Hooking von Callbacks/Funktionen
Dazu benutzen wir das ALS-Hooking verfahren.
Das normale Hooking-Verfahren würde bei mehreren Hooks nur zu Problemen führen.
Die ALS Methode ist bisher am verbreitesten.
Es wird immer einen Include und Scriptteil und geben,
das dient nur zu Übersicht ![]()
Wir nehmen mal als Beispiel das Callback OnPlayerConnect
Script:
#include <a_samp>
#include <hooking>
public OnPlayerConnect(playerid)
{
return true;
}
Hier ist das noch ziemlich Standardmäßig
Aber nun zum eigentlichen.
Wir wollen uns ja dazwischen klemmen, deshalb erstellen wir einen weitern
Public, mit dem gleichen Namen.
Aber, dann haben wir doch das gleiche Problem wie vorher...
Ja, aber nur momentan, da kommt noch was dazu, also Geduld ![]()
Kommen wir zum eigentlichen.
Wir müssen dem Compiler nun sagen, das es 2 verschiedene Funkionen/Callbacks sind.
Das machen wir mit einem Macro/Define.
#define OnPlayerConnect _OnPlayerConnect
Vorsicht:
Ihr dürft aber nicht den Fehler machen und es ganz nach oben setzen,
sonst habt ihr eure Problem nicht umgangen.
Es muss direkt unter den public, den ihr hooken wollt.
Include:
public OnPlayerConnect(playerid) // Die Parameter kommen natürlich immer auf die Funktion an ;)
{
return true;
}
#define OnPlayerConnect _OnPlayerConnect
Aber moment.
Nun bekommt ihr den Fehler, das _OnPlayerConnect noch nicht deklariert wurde,
falls ihr versucht es zu compilen.
Das liegt daran, das der Macro/Define erst dann anfängt zu wirken, wenn er erstellt wird.
D.h. würde ich ihn nach oben setzen, würde er den neu erstellten public mit "umbennen".
Um das nicht definiert Problem zu lösen erstellen wir einen forward mit dem Namen der hinter der Funktion steht, die gehookt werden soll.
forward _OnPlayerConnect(playerid); // Die Parameter kommen natürlich immer auf die Funktion an ;)
Aber HALT.
Wenn wir 2 Includes haben die nach diesem Prinzip arbeiten, bekommen wir Fehler.
Dafür ist das oben erwähnte ALS-Hooking erforderlich.
Sofern die 2. Include dies auch verwendet.
Wie gesagt es ist verbreitet, aber nicht jede Include benutzt dies auch ![]()
Dafür müssen wir Macro/Define etwas erweitern.
Folgendes kommt dazu
#if defined _OnPlayerConnect
forward _OnPlayerConnect(playerid);
#endif#
if defined _ALS_OnPlayerConnect
#undef OnPlayerConnect
#else
#define _ALS_OnPlayerConnect
#endif
//hier kommt der Macro hin (#define OnPlayerConnect _OnPlayerConnect)
Kurze Erklärung.
Als erstes wird geprüft, ob die Funktion die wir hooken wollen überhaupt verwendet wird,
wenn ja wird, sie geforwardet um keine Fehler auszulösen.
Danach wird geprüft, ob das ALS Hooking schoneinmal verwendet wurde,
falls Ja, wird der Macro ab der Stelle ungültig gemacht.
Falls Nein, wird ein Macro/Define gesetzt, zu Markierung für weitere Includes,
damit keine Fehler auftreten.
Direkt darunter, wird ein neuer(unser) Macro/Define erstellt.
Fast Fertig.
Bisher sollte es dann so aussehen.
Include:
public OnPlayerConnect(playerid) // Die Parameter kommen natürlich immer auf die Funktion an ;)
{
return 1;
}
#if defined _OnPlayerConnect
forward _OnPlayerConnect(playerid); // Die Parameter kommen natürlich immer auf die Funktion an ;)
#endif
#if defined _ALS_OnPlayerConnect
#undef OnPlayerConnect
#else
#define _ALS_OnPlayerConnect
#endif
#define OnPlayerConnect _OnPlayerConnect
Momentmal, wenn ich es nun teste, wird OnPlayerConnect in meinem Gamemode bzw Script nicht aufgerufen.
Ich sagte doch, wir sind erst fast fertig
Wir haben uns nicht ganz dazwischen gehakt, sondern es eher abgefangen.
Aber wir wollen dazwischen und nicht es abfangen.
Das machen wir wie folgt.
Wie wir es bereits weiter oben gemacht haben nutzen wir wieder die "#if defined" Überprüfung.
Ist es vorhanden rufen wir das Callback auf, wenn nicht, geben wir einfach "true" zurück.
Das verhindert, das wir unnötig Zeit verlieren und das der Aufruf nicht einfach ins Leere läuft.
Am Ende sieht es dann für unser Beispiel wie folgt aus:
public OnPlayerConnect(playerid)
{
#if defined _OnPlayerConnect
return _OnPlayerConnect(playerid);
#else return true;
#endif
}
Dafür hat SA:MP die Funktion CallLocalFunction.
Diese Funktion lässt uns Funktionen direkt aus dem Script, in dem es verwendet wird, laden.
Es gibt aber noch die Möglichkeit des direkten Funktionsaufrufs.
Da gibt es nicht viel zu beachten,
einfach die Funktion mit dem neuen Namen aufrufen,
hier wäre das:
_OnPlayerConnect(playerid);
CallLocalFunktion, funktioniert wie SetTimerEx.
Das brauch ich wohl nicht zu erklären ![]()
Nun sind wir fertig ![]()
Ich finde es aber besser, als wenn man sowas mit zich timern macht
Dagegen hab ich doch gar nichts gesagt.
Ich meine deine PlayAudioStreamForPlayerInRangeEx
da es ja mit dem standart befehl von samp klappt, dass die musik laut und leiser wird, wäre das kein problem. wenn es zu viel arbeit ist lass es.
Naja, was anderes nutzt er ja auch nicht.
Wenn er das richtig machen würde, funktioniert das auch ![]()
Wozu erstellst du eine Neue Funktion, wenn man die Parameter optional machen kann?
Vielleicht wäre es an der Zeit ein kombinations Plugin und ein Hooking Tutorial rauszubringen.
Einiges ist echt schwammig und dumm gehalten.
[ FEHLER ] Erledigt markieren Knopf
Wäre nur interessant ob es auch über mehrer stunden so gut läuft und bei hoher Serverauslastung.
Was hat denn jetzt der Server damit zu tun?
Meinst du wegen dem Timer?
So schlimm wäre das nun nicht.
Interessant ist eher, wenn viele auf den Server connecten, auf dem die Datei liegt, u.a. wegen dem Traffic.
Dann kommt noch die Internet Verbindung dazu, viele haben scheinbar noch eine Holzleitung...
und mehrere lieder hinterander abspielen lassen?? ist das einfacher?
Theoretisch mit einer Playlist.
Da hat aber mehrfach schonmal was nicht geklappt
Du bist echt ein Held.
Versuchst die ModelIDs von Fahrzeugen zu bekommen ohne das sie exestieren.
Setz das bei OnVehicleSpawn oder OnPlayerStateChange rein.
bei OnPlayerStateChange musst du dann halt noch eine Variable setzen, die dir sagt, ob der Tank schon gefüllt wurde