Added public files
Roughly added all public files. Probably missed some, though.
diff --git a/doc/beispiele/Praxis-Kurs/README b/doc/beispiele/Praxis-Kurs/README
new file mode 100644
index 0000000..99a8dd0
--- /dev/null
+++ b/doc/beispiele/Praxis-Kurs/README
@@ -0,0 +1,16 @@
+In diesem Verzeichnis befindet sich ein kleiner "Praxis LPC-Kurs".
+Im Prinzip sind es verschiedene gut dokumentierte LPC-Objekte die
+aufeinander aufbauen und in denen alles notwendige erklaert wird.
+Wer also schon mal irgendwo programmiert hat und sich nur an die
+LPC-Umgebung gewoehnen muss, fuer den ist dieser Mini-Kurs sicher
+genau das richtige. Fuer jemand der noch nie programmiert hat ist
+dieser Kurs alleine aber sicher nicht geeignet um programmieren zu
+lernen. Die Files sollten in der Alphabetischer Reihenfolge und da
+die Files aufeinander aufbauen, auch vollstaendig durchgegangen
+werden.
+Bei dem Verzeichnis zauberwald handelt es sich um ein kleines und
+dadurch ueberschaubares Gebiet von mir, das nicht eine Ansammlung
+von AddDetails darstellt, sondern auch komplexere Funktionen wie
+Virtual Compiler oder Heilstellen enthaelt.
+
+ Padreic
diff --git a/doc/beispiele/Praxis-Kurs/hello_world.c b/doc/beispiele/Praxis-Kurs/hello_world.c
new file mode 100644
index 0000000..8109e06
--- /dev/null
+++ b/doc/beispiele/Praxis-Kurs/hello_world.c
@@ -0,0 +1,37 @@
+// (c) by Padreic (Padreic@mg.mud.de)
+
+// Auch wenn dieses Objekt noch keinerlei tieferen Sinn hat, so ist es doch
+// bereits ein vollstaendiges Objekt (bereits eine einzige Funktion reicht
+// fuer ein LPC-Object aus).
+
+// Die 3 Funktionen in diesem Objekt haben darueber hinaus noch eine
+// ganz besondere Bedeutung. Jede dieser 3 Funktionen wird vom Game-Driver
+// im laufenden Betrieb bei besonderen Anlaessen aufgerufen.
+
+protected void create()
+// Diese Funktion wird aufgerufen sobald dieses Objekt geclont wird.
+{
+ // gibt an den Spieler der dieses Objekt clont eine Meldung aus.
+ tell_object(this_player(), "Hello World!\n");
+}
+
+void init()
+// Diese Funktion wird aufgerufen, sobald ein Spieler oder ein NPC in
+// Reichweite dieses Objektes kommt: Also entweder wenn ein Lebewesen in
+// das Objekt bewegt wird oder umgekehrt oder wenn ein Lebewesen in die
+// Umgebung eines Objektes kommt oder umgekehrt.
+{
+ // gibt wieder eine Meldung an den Spieler aus...
+ tell_object(this_player(), ("Hello again :).\n");
+}
+
+void reset()
+// Diese Funktion wird im beruemten Reset aufgerufen, den Du ja sicher auch
+// schon als Spieler kennengelernt hast (Also alle 30-60 Minuten).
+// Ausnahme: Wenn das Objekt laengere Zeit mit keinem anderen Objekt
+// kommuniziert hat, wird diese Funktion vorlaeufig nicht mehr aufgerufen!
+{
+ // Hier kann man nun auch irgendetwas machen. Ein write("..") haette
+ // hier jedoch keinen Effekt, da kein Spieler diese Funktion ausgeloest
+ // hat und daher nicht bekannt ist, an wen die Meldung denn gehen soll...
+}
diff --git a/doc/beispiele/Praxis-Kurs/juwelen.c b/doc/beispiele/Praxis-Kurs/juwelen.c
new file mode 100644
index 0000000..c1070a6
--- /dev/null
+++ b/doc/beispiele/Praxis-Kurs/juwelen.c
@@ -0,0 +1,66 @@
+// (c) by Padreic (Padreic@mg.mud.de)
+
+// Dieses ist ein erstes Objekt das so oder aehnlich tatsaechlich im
+// MorgenGrauen vorkommen koennte.
+
+// Jedes Objekt im MorgenGrauen braucht bereits eine solche Vielzahl von
+// Standardfunktionen, dass es ziemlich unmoeglich ist, diese alle in jedem
+// Objekt zu definieren. Daher "erbt" man diese Funktionen von einem
+// Standardobjekt.
+// "Erben" bedeutet hierbei, das man auf alle Funktionen, die bereits im
+// Standardobjekt definiert sind, zugreifen kann.
+//
+// Die folgende Zeile erklaert, dass man das Objekt an der Position
+// /std/thing.c "erben" moechte.
+inherit "/std/thing";
+
+
+// Die Funktion folgender Zeile kann man sich recht einfach wie folgt
+// vorstellen: Wenn der Game-Driver dieses Objekt hier compiliert, dann
+// tut er so, als wuerde die Datei /sys/properties.h genau an dieser Stelle
+// hier im Code stehen.
+//
+// Die Datei properties.h beinhaltet einfach nur haufenweise Defines fuer
+// die haufenweise Properties.
+//
+// Anmerkung: Alle Defines in dieser Datei starten uebrigens mit einem 'P_'.
+// Am Besten solltest Du einfach mal kurz in /doc/properties.h reinsehn
+// und ein bisschen rumlesen
+// (keine Angst, die muss man nicht alle kennen :).
+#include <properties.h>
+
+protected void create()
+{
+ // Die Funktion create() wurde naemlich bereits in /std/thing.c
+ // beschrieben, kann aber nicht mehr ueber create() aufgerufen werden, da
+ // dann ja wieder diese Funktion hier aufgerufen wuerde
+ // (wodurch wir dann eine Endlos-Rekursion haetten).
+ // Kurzschreibweise waere ::create(); wenn man nur von einem Objekt erbt.
+ thing::create(); // oder auch einfach ::create();
+
+ // Auch diese Funktion wurde aus /std/thing geerbt.
+ // SetProp() ist eine der wichtigsten Funktionen ueberhaupt, wenn es darum
+ // geht, ein Objekt zu beschreiben. Mit dieser Funktion kannst Du naemlich
+ // zahlreiche Eigenschaften (engl. properties) des Objektes festlegen.
+ SetProp(P_SHORT, "Einige wertvolle Juwelen"); // die Kurzbeschreibung
+ SetProp(P_LONG, "Die Juwelen glitzern verlockend.\n"); // Langbeschreibung
+ SetProp(P_NAME, "Juwelen"); // der eigentliche Name
+ SetProp(P_NAME_ADJ, "wertvoll"); // das Adjektiv vor dem Namen
+ SetProp(P_GENDER, FEMALE); // Geschlecht (kann auch MALE oder NEUTER sein)
+ SetProp(P_WEIGHT, 5000); // dieses Objekt wiegt 5kg
+ SetProp(P_VALUE, 10000); // das Objekt ist insgesamt 10000 Muenzen Wert
+
+ // Mit dieser Funktion kann man eine id angeben, ueber die das Objekt
+ // ansprechbar ist.
+ // Anmerkung: Auch diese Funktion ist wieder von std/thing geerbt, im
+ // folgenden werde ich dies aber nicht mehr bei jeder Funktion extra
+ // angeben. Wenn nicht anders angegeben, handelt es sich ab jetzt
+ // naemlich _immer_ um ererbte Funktionen.
+ AddId("juwelen");
+
+ // In diesem Fall benoetigt man noch ein weiteres Adjektiv, da man das
+ // Objekt ja auch mit wertvolle Juwelen ansprechen koennen moechte.
+ // z.B.: unt wertvolle juwelen
+ // gib wertvolle juwelen an padreic
+ AddAdjective("wertvolle");
+}
diff --git a/doc/beispiele/Praxis-Kurs/los.c b/doc/beispiele/Praxis-Kurs/los.c
new file mode 100644
index 0000000..f3b41e8
--- /dev/null
+++ b/doc/beispiele/Praxis-Kurs/los.c
@@ -0,0 +1,118 @@
+// (c) by Padreic (Padreic@mg.mud.de)
+
+#include <properties.h> // wieder unsere allgemeinen Propertys
+#include <moving.h> // einige Defines zum Bewegen von Objekten (s.u.)
+
+inherit "/std/thing";
+
+protected void create()
+{
+ ::create();
+ // Objekt ueber seine Properties beschreiben...
+ SetProp(P_SHORT, "Ein Rubbellos");
+ SetProp(P_LONG,
+ "Du kannst dieses Los aufrubbeln um zu sehen, ob Du einen grossen "
+ "Schatz\ngewonnen hast.\n");
+ SetProp(P_NAME, "Rubbellos");
+ SetProp(P_ARTICLE, 1); // ist eigentlich bereits Defaultwert
+ SetProp(P_GENDER, NEUTER);
+ SetProp(P_VALUE, 1000);
+ SetProp(P_WEIGHT, 500);
+ SetProp(P_INFO, "Deine Gewinnchancen bei diesen Losen sind nicht "
+ "sonderlich gut.\n");
+ SetProp(P_MAGIC, 0); // (einfach nur, um mal alle Properties zu benutzen)
+ AddId("los"); // noch eine id angeben...
+
+ // Mit Hilfe dieser neuen wichtigen Funktion ist es moeglich, Befehle zu
+ // definieren, ueber die man irgendetwas ausloesen koennen soll:
+ // Und zwar wird sobald ein Spieler den Befehl rubble oder rubbel
+ // benutzt, die Funktion _rubbeln() hier im Objekt aufgerufen. Da diese
+ // Funktion bisher ja noch nicht definiert ist, muss diese natuerlich
+ // auch noch programmiert werden.
+ AddCmd(({"rubble", "rubbel"}), "_rubbeln");
+}
+
+// Diese Funktion sieht gleich um einiges komplexer aus als die Funktionen
+// create(), init() und reset(), die bisher benutzt wurden.
+// Das static am Anfang erklaert nur, dass diese Funktion nicht von aussen,
+// sondern nur von innerhalb des Objektes aufgerufen werden kann.
+// Das "int" anstelle des "void" bedeutet, dass die Funktionen ein Ergebnis
+// zurueckliefert. Da diese Funktion in Verbindung mit AddCmd() benutzt
+// wird, hat dieser Rueckgabewert auch eine besondere Bedeutung:
+// Eine 1 bedeutet, dass der Befehl fertig abgearbeitet wurde.
+// Eine 0 bedeutet, das Objekt konnte mit dem Befehl nichts anfangen, der
+// Gamedriver muss also noch in weiteren Objekten anfragen, die der
+// Spieler bei sich traegt.
+// Der String 'str', den die Funktion als Parameter uebergeben bekommt,
+// enthaelt das, was der Spieler ausser dem eigentlichen Verb eingegeben
+// hat (Woerter wie 'und', 'ein', 'der', 'die', 'das' ... werden hierbei
+// zuvor herausgefiltert)
+// Bsp.: rubbel los -> _rubbeln("los")
+// rubbel katze -> _rubbeln("katze")
+// rubbel los auf -> _rubbeln("los auf")
+public int _rubbeln(string str)
+{
+ // Die Funktion notify_fail() ist wieder eine Funktion des Gamedrivers:
+ // Und zwar ist es moeglich hier eine Meldung anzugeben, die anstelle
+ // eines "Wie bitte?" kommt, falls kein Objekt den Befehl richtig
+ // abgearbeitet hat.
+ notify_fail("Syntax: rubbel los auf\n"); // eigentlich efun::notify_fail()
+
+ // Wenn der uebergebene String ungleich "los auf" ist, dann fuehlt sich
+ // das Objekt nicht angesprochen, kann das Verb also nicht komplett
+ // abarbeiten und gibt deshalb eine 0 zurueck.
+ if (str!="los auf") return 0;
+
+ // Auch die Funktion random() ist wieder eine Funktion des Gamedriver:
+ // Und zwar liefert sie eine ganzzahlige Zufallszahl zwischen 0 und n-1
+ // (wobei n die uebergebene Zahl ist). In diesem Fall also zwischen
+ // 0 und 99.
+ if (random(100)<92) { // sollte diese Zahl < 92 sein, dann tue Folgendes:
+ write("Du rubbelst das Los auf. Leider war es jedoch nur eine Niete.\n"
+ +"Veraergert laesst Du das Los deshalb fallen.\n");
+ }
+ else { // sollte die Zahl nicht < 92 gewesen sein, dann tue Folgendes:
+ object ob; // bereitstellen einer Hilfsvariablen
+
+ write("Du rubbelst das Los auf und strahlst vor Freude. Es war der "
+ +"absolute Hauptgewinn.\nSofort kommt ein Bote herein und "
+ +"ueberreicht Dir Deinen Gewinn.\n");
+
+ // Mit clone_object() kann man ein beliebiges Objekt Clonen, indem man
+ // einfach den entsprechenden Filenamen als Parameter uebergibt.
+ ob=clone_object("/doc/beispiele/Praxis-Kurs/juwelen");
+
+ // Nun kommen gleich 3 neue Dinge auf einmal...
+ // Mit -> wird eine Funktion in einem anderen Objekt aufgerufen
+ // (alternativ auch: call_other(ob,move,this_player(), M_GET); )
+ // Die Funktion, die hierbei aufgerufen werden soll, heisst move().
+ // Diese Funktion ist in allen Objekten definiert, die /std/thing erben.
+ // Somit koennen wir also fest davon ausgehen, dass sie auch in unseren
+ // Juwelen vorhanden ist.
+ // this_player() ist eine sehr wichtige Gamedriver-Funktion, da sie
+ // uns das Lebewesen zurueckliefert, das gerade aktiv durch einen Befehl
+ // den aktuellen Funktionsaufruf gestartet hat.
+ // M_GET ist lediglich ein Define, das in moving.h definiert ist.
+ // Naeheres hierzu findet man auch in <man move>.
+ ob->move(this_player(), M_GET);
+ // ACHTUNG: um dieses Beispiel simpel zu halten, wird hier darauf
+ // verzichtet, zu pruefen, ob diese Bewegung ueberhaupt funktioniert
+ // hat. Normalerweise muss man in diesem Fall (misslungene Bewegung)
+ // eine Fehlerbehandlung durchfuehren (z.B. ob wieder entfernen,
+ // Meldung an den Spieler ausgeben).
+ }
+
+ // Die Funktion say() gibt an alle Spieler im Raum des aktiven Spielers
+ // eine Nachricht aus, aber nicht an den betroffenen Spieler selbst!
+ // Die Funktion Name(), die hier im Spieler aufgerufen wird, wertet
+ // dessen Propertie P_NAME aus und dekliniert den Namen im angegebenen
+ // Fall.
+ say(this_player()->Name(WER)+" rubbelt ein Los auf.\n");
+
+ // Und nun soll sich das Objekt selbst entfernen (zerstoeren).
+ remove();
+
+ // Da der Befehl ja komplett abgearbeitet wurde, geben wir eine 1
+ // zurueck.
+ return 1;
+}
diff --git a/doc/beispiele/Praxis-Kurs/milch.c b/doc/beispiele/Praxis-Kurs/milch.c
new file mode 100644
index 0000000..66b6173
--- /dev/null
+++ b/doc/beispiele/Praxis-Kurs/milch.c
@@ -0,0 +1,91 @@
+// (c) by Padreic (Padreic@mg.mud.de)
+
+// Anmerkung: Heutzutage gibt es fuer Lebensmittel (bzw. alle Dinge, die
+// man essen oder trinken kann) ein Standardobjekt namens /std/food,
+// welches viele Funktionalitaet mitbringt, die man ansonsten selber
+// muehsam basteln muss. Die Verwendung ist dringend empfohlen.
+
+#include <properties.h> // wieder unsere allgemeinen Properties
+
+inherit "/std/thing";
+
+// globale Variable, die angibt, wie voll die Flasche ist. Es sind 5
+// Portionen enthalten.
+int menge = 5;
+
+protected void create()
+{
+ ::create();
+ // Objekt ueber seine Properties beschreiben...
+ // P_SHORT und P_LONG werden direkt als Funktion implementiert (s.u.)
+ SetProp(P_NAME, "Milchflasche");
+ SetProp(P_GENDER, FEMALE);
+ SetProp(P_VALUE, 80);
+ SetProp(P_WEIGHT, 1000);
+ AddId(({"flasche", "milchflasche"}));
+ AddCmd(({"trink", "trinke"}), "_trinken");
+}
+
+// Anstelle von P_SHORT Kurzbeschreibung ueber Funktion short().
+// Dies ist nicht immer moeglich, da nicht zwangslaeufig zu jeder Propertie
+// eine gleichnamige Funktion existiert.
+// Es ist allerdings noch sog. Querymethoden (siehe dazu <man QueryProp> und
+// <man Query> bei Bedarf).
+public string short()
+{
+ string str;
+ switch(menge) {
+ case 1: str="Eine fast leere Milchflasche.\n"; break;
+ case 2: str="Eine bald leere Milchflasche.\n"; break;
+ case 3: str="Eine halbvolle Milchflasche.\n"; break;
+ case 4: str="Eine fast volle Milchflasche.\n"; break;
+ case 5: str="Eine volle Milchflasche.\n"; break;
+ default: str="Eine leere Milchflasche.\n";
+ }
+ return str;
+}
+
+public string long()
+{
+ if (menge>1)
+ return "Eine Flasche mit leckerer Vollmilch.\n";
+ else
+ return "Die Milchflasche ist bald leider schon alle, Du solltest "
+ "Dich vielleicht mal\nnach Nachschub umsehn.\n";
+}
+
+public int _trinken(string str)
+{
+ notify_fail("Syntax: trinke aus milchflasche\n");
+
+ // Falls die ersten vier Zeichen in dem uebergebenen String ungleich
+ // "aus " sind, dann fuehlt sich das Objekt nicht angesprochen, kann das
+ // Verb also nicht komplett abarbeiten und gibt deshalb eine 0 zurueck.
+ if (str[0..3]!="aus ") return 0;
+
+ // Ich benutze nun alles ab dem vierten Zeichen und pruefe, ob sich das
+ // Objekt davon angesprochen fuehlt. Hierzu dient die Funktion id().
+ // Grosser Vorteil: Uebersichtlich und spaeteres Ergaenzen von Ids bzw.
+ // Adjektiven geht sehr einfach und erspart lange if()-Abfragen.
+ if ( !id(str[4..]) ) return 0;
+
+ if (menge<=0) {
+ write("Die Milchflasche ist leider schon leer :(.\n");
+ }
+ else {
+ // drink_soft() ist eine Funktion, die in allen Lebewesen im
+ // Morgengrauen definiert ist und ueber die man sowohl Abfragen als
+ // auch hochsetzen von P_DRINK vornehmen sollte.
+ if (this_player()->drink_soft(10)) {
+
+ // heal_self() ist auch in allen Lebewesen definiert und heilt bei
+ // dem Lebewesen Lebens- und Konzentrationspunkte.
+ this_player()->heal_self(10);
+ write("Genuesslich trinkst Du einen Schluck Milch.\n");
+ say(this_player()->Name(WER)+" trinkt einen Schluck Vollmilch,\n");
+ menge--;
+ }
+ else write("Soviel kannst Du leider nicht mehr trinken.\n");
+ }
+ return 1;
+}
diff --git a/doc/beispiele/Praxis-Kurs/npc.c b/doc/beispiele/Praxis-Kurs/npc.c
new file mode 100644
index 0000000..39a54fd
--- /dev/null
+++ b/doc/beispiele/Praxis-Kurs/npc.c
@@ -0,0 +1,115 @@
+// (c) by Padreic (Padreic@mg.mud.de)
+
+#include <properties.h>
+#include <attributes.h>
+#include <combat.h>
+#include <guard.h>
+#include <moving.h>
+#include <new_skills.h>
+
+// Ein NPC wird nicht von /std/thing direkt geerbt, sondern von /std/npc.
+// Da /std/npc aber seinerseits wieder von /std/thing erbt, sind im NPC auch
+// saemtliche Funktionen definiert, die bereits in /std/thing enthalten sind.
+inherit "/std/npc";
+
+void create()
+{
+ ::create();
+ // create_default_npc() setzt schon mal einige wichtige Properties wie
+ // P_ATTRIBUTES automatisch...
+ create_default_npc(20, 300);
+
+ // Keine Angst: Es muessen keineswegs immer alle diese Properties benutzt
+ // werden, auch wenn ich sie jetzt einmal alle angebe, um eine Uebersicht
+ // zu geben, was man alles ueber Properties steuern kann...
+ SetProp(P_SHORT, "Ein fieser Ork");
+ SetProp(P_LONG, "Der Ork schaut Dich grimmig an.\n");
+ SetProp(P_NAME, "Ork");
+ SetProp(P_NAME_ADJ, "fies");
+ SetProp(P_GENDER, MALE);
+ SetProp(P_MAGIC, 0);
+ SetProp(P_MATERIAL, MAT_MISC_LIVING);
+
+ // nun komen einige wirklich neue Properties
+ SetProp(P_INFO, "Der Ork ist ein ganz gemeiner... :)\n");
+ SetProp(P_ALIGN, -500); // Alignment des Gegners
+ SetProp(P_RACE, "Ork"); // Rasse des NPCs
+ SetProp(P_AGGRESSIVE, 1); // greift aggressiv jeden an
+ SetProp(P_ATTRIBUTES, ([A_INT:5, A_DEX:10, A_STR:25, A_CON:10]));
+ SetProp(P_SIZE, 134); // Groesse in cm
+ SetProp(P_MAX_HP, 300); // max. Lebenspunkte
+ SetProp(P_HP, 300); // Lebenspunkte
+ SetProp(P_MAX_SP, 200); // max. Magiepunkte
+ SetProp(P_SP, 200); // Magiepunkte
+ SetProp(P_BODY, 80); // Grundruestungsschutz des Koerpers
+ SetProp(P_MAX_HANDS, 2); // kaempft mit zwei Haenden...
+ SetProp(P_HANDS, ({" mit blossen Haenden", 150}));
+ SetProp(P_NOMAGIC, 20); // 20% Resistenz gegen Spells
+ SetProp(P_GUARD, 20); // Der NPC laesst sich ggf. weglocken
+ SetProp(P_NO_GLOBAL_ATTACK, 0); // wird von 'toete alles' erfasst
+ SetProp(P_NO_ATTACK, 0); // kann man den NPC ueberhaupt angreifen?
+ SetProp(P_FRIEND, 0); // soll der NPC in Spells als Freund erfasst
+ // werden?
+ SetProp(P_RESISTANCE, DT_FIRE); // Resistenzen
+ SetProp(P_VULNERABILITY, DT_HOLY); // Empfindlichkeiten
+ SetProp(P_FOOD, 0);
+ SetProp(P_MAX_FOOD, 100);
+ SetProp(P_DRINK, 0);
+ SetProp(P_MAX_DRINK, 100);
+ SetProp(P_ALCOHOL, 0);
+ SetProp(P_MAX_ALCOHOL, 100);
+ SetProp(P_XP, QueryProp(P_MAX_HP)*QueryProp(P_HANDS)[0]*5); // Erfahrung
+ SetProp(P_MURDER_MSG, "Ich komme doch eh wieder!\n"); // Moerdermeldung
+ SetProp(P_KILL_NAME, "Ein fieser Testork"); // noetig falls != P_NAME
+ SetProp(P_KILL_MSG, "Das kommt davon wenn man sich mit mir anlegt.\n");
+ SetProp(P_DIE_MSG, "Der Ork schreit ein letztes mal laut auf.\n");
+ SetProp(P_NOCORPSE, 0); // soll der NPC eine Leiche hinterlassen?
+ SetProp(P_HEAL, -10); // wieviel LP bekommt man beim Leichen essen...
+
+ // der Ork ist Mitglied der Abenteurergilde...
+ SetProp(P_GUILD, "abenteurer"); // in die Abenteuergilde mit ihm...
+ SetProp(P_GUILD_LEVEL, 20);
+ ModifySkill("feuerball",([SI_SKILLABILITY:10000]),1,"abenteurer");
+
+ // nun noch eine andere Art zu zaubern...
+ SetProp(P_SPELLRATE, 10);
+ AddSpell(100, 400,
+ "Der Ork tritt Dich einmal feste zwischen die Beine.\n",
+ "Der Ork tritt @WEN einmal feste zwischen die Beine.\n", DT_BLUDGEON);
+
+ // was soll der NPC mit ihm gegebenen Gegenstaenden machen...
+ SetProp(P_REJECT, ({REJECT_DROP, "Damit kann ich nichts anfangen.\n"}));
+
+ // und natuerlich auch noch eine id fuer den ork
+ AddId("ork");
+
+ // Der NPC hat immer einige Juwelen bei sich.
+ AddItem("/doc/beispiele/Praxis-Kurs/juwelen");
+}
+
+// Diese Funktion wird aufgerufen, wenn man einen Gegenstand bekommt...
+public void give_notify(object ob)
+{
+ if (ob->id("milchflasche")) // Milch annehmen und einen Spruch aufsagen
+ write("Der Ork sagt: Ohh.... Danke fuer die leckere Milch.\n");
+ else ::give_notify(ob); // Gegenstand fallen lassen
+}
+
+// Diese Funktion wird aufgerufen, wenn uns jemand im Kampf Schaden zufuegen
+// moechte...
+public varargs int Defend(int dam, mixed dam_type, mixed spell, object enemy)
+{
+ if (!random(4))
+ write("Der Ork weicht Deinem Angriff geschickt aus.\n");
+ else
+ return ::Defend(dam, dam_type, spell, enemy);
+}
+
+public void Attack(object enemy)
+{
+ // das Kommando 'Feuerball' eingeben. Da der NPC Mitglied der
+ // Abenteurergilde ist (s.o.), spricht er also den Spell, falls er genug
+ // Magiepunkt dafuer hat.
+ if (!random(3)) command_me("feuerball");
+ ::Attack(enemy);
+}