Hey!
Ich erkläre euch heute, was eigentlich #define ist und was man daraus alles machen kann.
z.B. schreibt man Werte oder Prozesse rein, weil man einfach zu faul ist, diese immer wieder zu schreiben.
Was sagt uns dieses Define?
#define COLOR_RED 0xFF0000AA
Es sagt uns, dass wenn wo im Script COLOR_RED steht, der Wert 0xFF0000AA ausgegeben wird.
Manchmal machen Leute einen Fehler und schreiben "COLOR_RED". Das ist natürlich falsch, weil alles was in "" geschrieben wird, der Compiler als Textstring wertet.
Es lassen sich andere Sachen damit auch schnell und gut erzeugen.
Das, was definiert wird ist beim Compilieren mit dem Anfangswert gleichgestellt. #define ist nur für den Scripter eine Hilfe!
Wenn man zum Beispiel Konstante Werte braucht, die immer gleich bleiben sollen, verwendet man #define.
Zum Beispiel die Menge von Racecheckpoints. Wenn es angenommen 30 gibt, müsste man, wenn man damit scriptet immer 30 nehmen. Doch hier kann man ganz bequem MAX_CHECKPOINTS schreiben.
#define MAX_CHECKPOINTS 30
Wenn man einmal die Zahl ändern will ändert man einfach den Wert oben im Define, statt immer die Zahl auszutauschen.
In Roleplaye/Reallife ist es nicht schlecht, wenn Errors einheitlich angezeigt werden.
Man könnte da wieder ein Define machen.
#define FehlerAdmin SendClientMessage(playerid,Color,"Du darfst diesen Befehl nicht benutzen");
überall ihr jetzt SendClientMessage(p..... schreiben müsstet könnt ihr ganz einfach FehlerAdmin ohne irgendetwas anderes schreiben.
Das ist die einfache Variante, doch man kann es noch einfacher und dynamischer machen.
Zum Beispiel beim Abfragen, ob jemand Admin ist.
Wie in den Mr.Monat Tutorials gezeigt wird, und auch deshalb die Anfänger auch gerne damit arbeiten sind PVars. Darüber lässt sich jetzt streiten, ob man mit PVars, Enums oder anderen Dingen arbeitet.
Hier aber jetzt ein konkretes Beispiel:
#define AL(%1) if(GetPVarInt(playerid,"Adminlevel") == %1)
Wenn jetzt bei einem Command zum Beispiel steht:
AL(2){ return 1;}
dann fragt das ab, ob das Adminlevel 2 ist. Das ist ziemlich hilfreich, wenn man vermeiden will, dass man Fingerkrämpfe bekommt, wenn man immer das gleiche schreibt.
Die zwei %1 sind sind gleiche Werte. Der Wert ist hierbei nicht fix bestimmt, und ist dynamisch. Wenn wir einen neuen brauchen wo dann ist der nächste %2. Es ist schwer zu erklären.
Probiert einfach einmal selber mal herum.
Es lassen sich auch unzählige Dinge mit Defines machen.
dcmd wurde zum Beispiel so gemacht, und besteht aus nichts anderem als aus einer Scriptzeile.
#define dcmd(%1,%2,%3) if ((strcmp((%3)[1], #%1, true, (%2)) == 0) && ((((%3)[(%2) + 1] == 0) && (dcmd_%1(playerid, "")))||(((%3)[(%2) + 1] == 32) && (dcmd_%1(playerid, (%3)[(%2) + 2]))))) return 1
Defines lassen sich auch mehrzeilig schreiben, um mehr Übersicht zu schaffen. (Hier in den Beispielen sieht man es leider nicht, da der PWN Code in einer Zeile fortgesetzt wird!)
z.B. hier:
#define PRESSED(%0) \(((newkeys & (%0)) == (%0)) && ((oldkeys & (%0)) != (%0)))
in der ersten Zeile das Define und zum Schluss das \ sagt dem Compiler, dass das, was in der nächste Zeile steht auch noch weiter zum define gehört.
man könnte es auch so schreiben:
#define PRES\SED(%0) (((newkeys & (%0)) == (%0)) && ((oldkeys & (%0)) != (%0)))
aber ob das sinnvoll wäre, darüber könnte man streiten..
mit #define definierte Werte können während der Server online ist nicht geändert werden. Sie sind Konstante eigentlich.
man kann normale ge-newte werte immer ändern..
new test = 4815162342 test = 35;
doch bei defines geht das nicht.
Warum (müssen) defines ganz oben im Script geschrieben werden?
Natürlich weil der Gültigkeitsbereich nur unterhalb gilt.
OnPlayerConnect(playerid)
{
defineTest
return 1
}
#define defineTest print("This is a #define Test");
geht nicht, weil ein define, muss über der Funktion stehen, die einen definierten Wert beeinhaltet!
vielleicht bekommt ihr mal diesen Error:
#define pattern must start with an alphabetic character
jeder der etwas Englisch kann, versteht es. Der Name des definierten Wertes muss mit einem Buchstaben anfangen.
#define -test new test[32]; das würde genau diesen error ausgeben!
#undef
Es gibt noch die Möglichkeit, ein definiertes "Etwas" wieder unzudefinieren, das geht mit #define und Variablen (über new ...;)
z.B.
#define Copyright "Copyright by ULLLIIK 2011"
#undef Copyright
SendClientMessage(playerid,Color,Copyright);
so gäbe es dann einen undefined Symbol - Error
#if - #else - #elseif
nicht viel anders als die normalen if, else und else if - Statements
hmm.. hier ein Beispiel:
#define HierBinIch 20
#if
HierBinIch > 10
printf("Mein Inhalt ist größer als 10");#if HierBinIch > 11 printf("Mein Inhalt ist sogar größer als 11");
#else
printf("Mein Inhalt ist größer oder gleich 11");
#endif
nicht so schwer, oder?
#pragma
Es gibt immer wieder Fragen wie z.B., dass man Warnings bekommt, weil man unsauber eingerückt hat.
#pragma unterdrückt sozusagen sachen.
#pragma tabsize 0
unterdrückt dieses lästige Warning.
#pragma unused VariablenName
das unused sagt dem Compiler, dass zwar eine Variable mit dem Namen ( hier VariablenName ) existiert, er aber deshalb kein Warning geben soll.
das sind eigentlich die 2 gängisten #pragma Verwendungen
#error
Dieses Directive finde ich eigentlich sehr nett. Ein forcierter Error im Script.
leicht zu bilden:
#error Errorname
Ich finde dieses hier oft, um mich an Sachen zu erinnen, die ich unbedingt noch machen muss. Manchmal vergesse ich auf Sachen, aber mein #error erinnert mich daran.^^
Ich werde in nächster Zeit nochmal zu ein paar Directives Stellung Nehmen. Kritik ist immer noch gerne erwünscht.
/edit: Namesänderung
/edit2: Ergänzung
/edit3: Mehrzeilige defines eingefügt edit 4: etwas ausgebessert
/edit5: Zusatz & Graphik
/edit6, 7, 8, 9: #undef neu & etwas verbessert
/edit10: Überarbeitung