Der Verkaeufer ~~~~~~~~~~~~~~ Dateinamen: zum inheriten: /i/money/verkaeufer.c zum clonen: /obj/verkaeufer.c lfuns: void set_roman (int i) roemische Ziffern void set_valuta (string s) Waehrung string query_valuta () string query_valutas () void set_accept_tip (mixed t) Trinkgeld void set_dont_serve_murderers (mixed msg) werden Moerder bedient? void set_lagerraum (string dateiname) string query_lagerraum () void set_standard_conversation (mapping C) mapping query_standard_conversation () void change_standard_conversation (mapping changes) void add_to_filter (mixed s) was wird aus Spielereingabe void delete_from_filter (mixed s) herausgefiltert string *query_filter () void set_filter (string *s) void add_react_on (mixed add) void delete_react_on (mixed del)) void set_react_on (string* react) string* query_react_on () lfuns zum Ueberladen: mapping want (string was, object wer) mapping given (object was, object wer) int want_while_serving (string was, object wer) Vorbemerkung: ~~~~~~~~~~~~ Der Verkaeufer ist mittlerweile unheimlich umfangreich geworden, man kann mit ihm so ziemlich alles machen, angefangen vom Gildenein- und Austritt bis hin zum Einsatz als Raetselmonster. Diese ganzen Funktionalitaeten machen zwangsweise diese Dokumentation auch irre gross, sodass sie fuer jemanden, der dies hier zum ersten mal liest, abschreckend wirken muss. Keine Angst, es ist alles halb so wild; fuer einen normalen Verkaeufer braucht man zunaechst nur einen kleinen Teil all dieser Funktionalitaeten, wie man an dem ersten Beispiel etwas tiefer sehr schoen sieht. Erst im Lauf der Zeit, wenn auch immer mehr Sonderwuensche und ungewoehnliche, neue Ideen kommen, kann man dann immer mehr der Moeglichkeiten des Verkaeufers ausnutzen, und wird dabei selten an Grenzen stossen. Also, nicht abschrecken lassen! Allgemeines: ~~~~~~~~~~~ Der Verkaeufer kann entweder geclont und in den Verkaufsraum hineingestellt werden oder er kann inheritet werden. Inheriten ist nur fuer einen herumlaufenden Verkaeufer sinnvoll. Wird der Verkaeufer geclont, so programmiert man die benoetigten der folgenden Funktionen in den Raum hinein, andernfalls in das Objekt, welches den Verkaeufer inherittet: mapping want (string was, object wer) mapping given (object was, object wer) int want_while_serving (string was, object wer) Zu want, want_while_serving und given weiter unten mehr. Beim inheriten ist zu Beachten, dass im create ein ::create(); ganz am Anfang von create steht, wird sogar ein eigenes init programmiert, so darf auch hier am Anfang von init ein ::init(); nicht fehlen. ------------------------------------------------------------------------------ ------------------------------------------------------------------------------ Einfuehrendes Beispiel: Ein einfacher Fackelverkaeufer ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Mit "sage will fackel" bringt man den Fackelverkaeufer dazu, einem eine Fackel zu verkaufen. Ein richtig schoener Verkaeufer sollte natuerlich noch auf Begruessung und Seelebefehle reagieren etc. pp. inherit "/i/money/verkaeufer"; void create() { ::create(); set_name("karl"); add_id("karl"); set_valuta("gulden"); } mapping want(string str, object wer) { if(strstr(str, "fackel")!=-1) { return ([ "good": clone_object("/obj/fackel"), ]); } } Weitere Beispiele ~~~~~~~~~~~~~~~~~ /d/Vaniorh/Tadmor/Laeden/room/schmied /d/Vaniorh/Tadmor/Laeden/room/pub (er zeigt auch die Verwendung von set_accept_tip) Connor: /d/Vaniorh/Tadmor/Laeden/room/connor /d/Vaniorh/Terqa/Laeden/room/vegi zeigt vor allem "messages" /d/Vaniorh/Tadmor/Troedlermarkt/room/pfand zeigt den Lagerraum ---------------------------------------------------------------------------- ---------------------------------------------------------------------------- Bei den Meldungen besteht nun die Moeglichkeit, generell ein ! voran zu stellen. Beginnt der Text mit einem ! (Ausrufezeichen), so wird er dabei nicht ausgegeben sondern via do_command ausgefuehrt. Eine Sonderstellung nimmt dabei der Befehl !GEBEN ein (in Grossbuchstaben, damit Konflikte zu existierenden Befehlen ausgeschlossen sind). Trifft der Verkaeufer auf diesen Befehl, so geschieht folgendes: - falls der Spieler gerade eine Ware bezaht hat, gibt der Verkaeufer ihm an dieser Stelle diese Ware, - falls der Spieler dem Verkaeufer irgendeinen Gegenstand gegeben hat, gibt der Verkaeufer ihn an dieser Stelle wieder zurueck. Siehe Beispiele. ---------------------------------------------------------------------------- ---------------------------------------------------------------------------- Die Standardmeldungen des Verkaeufers koennen mit set_standard_conversation und change_standard_conversation beeinflusst werden. Waehrend die erstere alle Meldungen neu setzt, kann mit der zweiten eine einzelne Meldung geaendert werden. In dem uebergebenen Mapping sollten natuerlich nur die Eintraege drinstehen, die veraendert werden sollen. An der Stelle, an welcher im Text ein Parameter rein muss, fuegt man ein $ - Zeichen ein. Im Folgenden nun alle setzbaren Einstellungen an einem Beispiel (das mehr sagt als tausend Worte): Beispiel: verkaeufer->set_standard_conversation (([ "unsichtbarer_sagt": "Hans sagt: Nanu, jetzt hoer ich schon Gespenster.\n" "Hans kratzt sich reichlich ratlos hinterm Ohr.\n", "unsichtbarer_gibt": "Hans sagt: Nanu, wo kommt denn $ her?\n", "unsichtbarer_gibt_verschwinden": "Hans wirft $ in den Brunnen.", "al_kann_nicht_mehr_tragen": "Hans sagt: Du kannst $ nicht mehr tragen, Du hast zuviel bei Dir.", // Der Verkaeufer verkauft einen AutoLoader, den der Spieler nicht // mehr tragen kann. "bedient_bereits_diesen_spieler": "Hans sagt: Moment, eines nach dem anderen.", // Wenn der Spieler, der gerade bedient wird, noch etwas will, // bevor er bezahlt hat "bedient_bereits_anderen_spieler": "Hans sagt: Moment, ich bediene gerade $.", // Wenn bereits ein anderer Spieler bedient wird. "kunde_verschwunden": "Hans sagt: Nanu, wo ist denn $ hin?", // ein Kunde ist davongelaufen, hat sich ausgeloggt, ... "was_willst_du_haben": "Hans sagt: Bitte? Was moechtest Du gerne haben?", // Wird benutzt, falls ein Spieler nur "will" oder "moechte" // eingibt, nicht jedoch, was er will. "hab_ich_nicht": "Hans sagt: Tut mir leid, sowas hab ich nicht.", // Wird benutzt, falls "want" nix zurueckgibt "das_kostet": "Hans sagt: Das kostet $, wenn ich bitten darf...", // wird verwendet, wnn keine procemessage angegeben ist "zu_wenig_geld": "Hans sagt: Das ist zu wenig, das kostet $.", // Der Spieler hat dem Verkaeufer zu wenig Geld gegeben. "zu_viel_geld": "Hans sagt: Das ist zu viel, das kostet $.", // Der Spieler hat dem Verkaeufefr zu viel Geld gegeben, der // Verkaeufer akzeptiert kein Trinkgeld (-> set_accept_tip) "bittesehr": "Hans sagt: Da hast Du $, viel Spass damit!", "dann_halt_nicht": "Hans sagt: Dann eben nicht.\n" "Hans seufzt tief.\n", "nanu": "Hans sagt: Nanu, was ist denn das und was soll ich damit?", // Dem Verkaeufer wurde was einfach so gegeben, // given hat nicht reagiert, oder der Spieler hat bei einem // Tauschgeschaeft das Falsche gegeben. "illusion": ({"!betrachte meine illusion", "!lache", "!GEBEN", "!sage Bin ich blind oder was?"})); // Reaktion auf Illusionen "moment": "Hans sagt: Moment, moment.", // Der Verkaeufer tut grad was (beispielsweise reparieren) "falsche_waehrung": "Hans sagt: Das ist jetzt aber die falsche Waehrung, " "$ nehm ich nicht an.", "fehler": "Hans sagt: Tut mir leid, das ist mir ausgegangen", // Programmierer hat nen Fehler gemacht, // erhaelt mit do_error eine Nachricht, // aber der Spieler soll auch was kriegen. ])); ---------------------------------------------------------------------------- ---------------------------------------------------------------------------- want, want_while_serving und given ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Die Funktion "want" wird aufgerufen, wenn ein Spieler sagt, dass er was moechte, will, oder sonstwie gerne haette, der uebergebene String ist der Text, den der Spieler haben will, aus dem einige, aber nicht alle Fuellwoerter bereits entwernt wurden. Es bietet sich an, ihn mit strstr zu bearbeiten. Alle Grossbuchstaben wurden bereits in Kleinbuchstaben umgewandelt. Mit den Methoden add_react_on, delete_react_on und set_react_on kann beeinflusst werden, worauf der Verkaeufer reagiert; mit query_react_on kann dies abgefragt werden. Dies wird nur in Ausnahmefaellen benoetigt. Welche Fuellwoerter herausgefiltert werden, kann mit den Funktionen add_to_filter, delete_from_filter und set_filter beeinflusst werden, mit query_filter kann der aktive Filter abgefragt werden. Dies kann beispielsweise dazu verwendet werden, das Wort "bitte" nicht herausfiltern zu lassen, mit delete_from_filter ("bitte"), um testen zu koennen, ob ein Spieler "bitte" verwendet hat. "want_while_serving" deckt einen Spezialfall ab: der Verkaeufer kann keine zwei Kunden gleichzeitig bedienen, es gibt jedoch Aktionen wie das Zeigen der Karte bei einem Wirt, die ein Wirt auch schnell dazwischenschieben kann, waehrend er bedient. Fuer diese Aktionen gibt es want_while_serving; gibt die Funktion 0 zurueck, so macht der Verkaeufer normal weiter, in der Regel bedeutet dies "Moment, ich bediene gerade", liefert die Funktion etwas von 0 verschiedenes zurueck, so geht der Verkaeufer davon aus, dass want_while_serving die Arbeit abgeschlossen hat und macht nichts weiteres. "given" wird aufgerufen, wenn der Spieler dem Verkaeufer etwas gibt, vondem der Verkaeufer nicht weiss, was er damit anfangen soll, sprich, wenn der Verkaeufer, ohne dabei zu sein, etwas zu verkaufen, Geld gekriegt hat oder einen Gegenstand bekommen hat. Gibt given 0 zurueck und das Objekt existiert weiterhin, so geht der Verkaeufer davon aus, dass given mit dem Objekt nichts anfangen konnte und sagt "nanu, was soll ich denn damit?" und gibt das Objekt zurueck. Liefert given ([]) und der Gegenstand existiert noch, so gibt der Verkaeufer den Gegenstand zurueck, ohne die Meldung "Nanu? Was soll ich denn damit?" zu erzeugen. Liefert given ein Mapping, so wird dieses wie bei "want" benutzt; enthaelt dieses Mapping den Eintrag "keep_given" (s.u.), so behaelt der Verkaeufer den ihm gegebenen Gegenstand. Zerstoert given das uebergebene Objekt und liefert 0 zurueck, so geht der Verkaeufer davon aus, dass "given" alles noetige getan hat und tut nix mehr. Das zweite Argument fuer given und want ist der Spieler. Das Mapping, das given und want zurueckliefern, kann die folgenden Eintraege beinhalten: "message": Text, den alle Spieler im Raum erhalten. Der Text kann aus einem String oder aus eimem Stringarray bestehen. Der Text wird sofort ausgegeben. Beginnt der Text mit einem ! (Ausrufezeichen), so wird er nicht ausgegeben sondern via do_command ausgefuehrt. Ausnahme: Der Befehl !GEBEN bewirkt die Uebergabe eines Gegenstandes an den Spieler; im Falle einer Kostenlosen Ware die Ware, im Falle eines unmotiviert an den Verkaeufer uebergebenen Gegenstandes dieser Gegenstand Beispiel fuer die Stringarrays: "message":({"Der Baecker nimmt eine Brezel aus einem Korb.", "Der Baecker riecht an der Brezel."}), ist das Selbe wie: "message":"Der Baecker nimmt eine Brezel aus einem Korb.\n" "Der Baecker riecht an der Brezel.\n", "messages": Ein Feld aus Texten, die dann alle nacheinander ausgegeben werden. Feldelemente, die mit ! (Ausrufezeichen) beginnen, werden nicht ausgegeben, sondern via do_command ausgefuehrt. Beispiel fuer mehrere "messages": return ([ "messages": ({ "Surgi nimmt eine Karaffe mit dunkelrotem Saft vom Tisch.", "Surgi giesst Saft aus der Karaffe in ein Glas.", "Surgi stellt die Karaffe wieder auf den Tisch zurueck."}), "good":ob ]); "messages_speed": Ein int-Wert mit der Geschwindigkeit in Sekunden, in der die messages nacheinander ausgegeben werden sollen; dieser muss >= 2 sein, Vorgabewert ist 2. "soldmessage": Diesen Text erhalten alle Spieler im Raum, wenn der Spieler bezahlt hat. Ist er nicht angegeben, so sagt der Verkaeufer: "Bitteschoen, , ein .". Durch "soldmessage":"" kann diese Standardmeldung unterdrueckt werden, ohne eine eigene Meldung zu definieren. Ist der Preis 0 (s.u.), so ist es "natuerlich" sinnlos, diesen Text anzugeben. "soldmessages": Ein Feld von Texten, die alle nacheinander im Abstand von "messages_speed" ausgegeben werden. Der Befehl !GEBEN bewirkt als einzelnes Element dieses Feldes die Uebergabe des gekauften Gegenstandes an den Spieler. Siehe Beispiel. "pricemessage": Um die "Das macht dann x Taler, wenn ich bitten darf" - Meldung zu ersetzen, kann die pricemessage gesetzt sein, dies ist ein ganz einfacher String. "price": Dieser Eintrag muss gesetzt sein, wenn eine closure oder ein Funktionsaufrufspaar als Ware uebergeben werden (s.u.), in den anderen Faellen kann er, muss aber nicht, gesetzt sein. Wird kein Preis gesetzt, so wird er aus 2 * ware->query_value() berechnet und in die mit set_valuta gesetzte Waehrung umgerechnet (was natuerlich bei closures oder Funktionsaufrufsparen nicht geht). Falls "price" gesetzt wird, so kann es eine Zahl, ein Array aus IDs oder eine Closure sein: - Integer: Der geforderte Preis in Taler - Array aus Strings: Ein Objekt, welches eines dieser Strings als ID hat, wird als Tauschgegenstand akzeptiert. - Closure: Diese Funktion aufgerufen, um zu pruefen, ob ein erhaltener Gegenstand als Tauschobjekt akzeptabel ist. Die Closure erhaelt folgende Parameter: 1. der will-string, den der Spieler eingegeben hat, 2. das Objekt, das der given-Funktion uebergeben wurde, 3. das Objekt, mit dem der Spieler bezahlen will (Tausch), 4. der Container, aus dem das Objekt kam (sollte der Kunde sein), 5. Das von will oder given zurueckgelieferte Mapping (mit eben diesen Eintraegen), 6. der Kunde selber. Beispiel: Der Verkaeufer tauscht Seile und Schaufeln gegen Fackeln ein (ja, ein schlechtes Geschafft fuer einen Spieler), dann setzt man "price":({"seil","schaufel"}), "pricemessage":"Wenn Du mir ein Seil gibst, geb ich Dir " "eine Fackel.", "good":"/obj/fackel" Ist der Preis 0 (also, als 0 gesetzt und nicht etwa weggelassen, ([..., "preis":0, ...]) ist was anderes als wenn kein "preis" - Eintrag da waere), so wird die mit "good" gesetzte ware sofort dem Spieler gegeben. "good": Die zu verkaufende Ware. Dies kann ein Objekt, ein String, ein Funktionsaufrufspaar oder eine Closure sein. - objekt: Die zu verkaufende Ware als Objekt - string: Ein String wird als ein Dateiname eines zu clonenden Objektes interpretiert. Statt "good": clone_object ("/obj/fackel") kann "good": "/obj/fackel" geschrieben werden. Ist der Preis gesetzt, so hat letzteres den Vorteil, dass das Objekt nur dann geclont wird, wenn der Spieler tatsaechlich dafuer bezahlt. Es hat aber den Nachteil, dass das Objekt in einer eigenen Datei stehen muss. - Ein Funktionsaufrufspaar ist eine besonders primitive Alternativ zu einer closure in Form eines zweielementigen Arrays vom Typ ({object ob, string fun}). Bezahlt der Spieler das, was im Preis-Eintrag gesetzt ist, so wird im Objekt ob die Funktion fun aufgerufen. (ob->fun (...)). Das ist uebrigens dasselbe, wie wenn man die closure symbol_function (fun, ob) uebergeben haette. Der Preis muss gesetzt und ungleich 0 sein. - eine closure. Bezahlt der Spieler den Preis, so wird diese closure aufgerufen. Der Preis muss gesetzt und ungleich 0 sein. Die Argumente fuer die Closure sowie fuer die mit dem Funktionsaufrufspaar gegebene Funktion sind folgende: 1. der will-string, den der Spieler eingegeben hat, 2. das Objekt, das der given-Funktion uebergeben wurde, 3. das Objekt, mit dem der Spieler bezahlt hat (->Tausch). 4. ein Zeiger auf den Spieler selber. Diese Parameter werden nur deshalb zur Verfuegung gestellt, um hoechstmoegliche Flexibilitaet zu erreichen. Gibt die Closure bzw. das Funktionsaufrufspaar ein Objekt zurueck, so wird dieses dem Spieler gegeben; ist der Preis ("price") 0, so muessen Closure und Funktionsaufrufspaar ein Objekt liefern. Ist das Objekt, das der Spieler dem Verkaeufer gegeben hat, (nicht das Zahlungsmittel, sondern der zweite Parameter) nachher immernoch im Besitz des Verkaeufers, so gibt der Verkaeufer dies an den Spieler zurueck. Die Standardreparatur - Prozedur waere somit ein Funktionsaufrufspaar, welches das Objekt repariert und nichts zurueckgibt. Soll das Objekt nicht an den Spieler zurueckgegeben werden (->Tausch), so muss die Closure / das Funktionsaufrufspaar das Objekt removen. Fuer einen Tausch bietet sich allerdings an, als Preis die ids zu setzen, die man tauschen will. "timeout": Dauer in Sekunden, bis wann dem Verkaeufer die Geduld ausgeht und er eben "Dann halt nicht" - oder die timeoutmessage - sagt: "timeoutmessage": Die Meldung wird ausgegeben, wenn der Spieler nicht in einer gewissen Zeit bezahlt. Dies kann ein String oder ein Stringarray sein. Also beispielsweise (als Stringarray): ({"Der Baecker sagt: Dann halt nicht.", "Der Baecker legt die Brezel wieder in den Korb zurueck."}) Das folgende waere dasselbe (als String): "Der Baecker sagt: Dann halt nicht.\n" "Der Baecker legt die Brezel wieder in den Korb zurueck.\n" Wirt timeoutmessage nicht angegeben, so seufzt der Verkaeufer und sagt "Dann halt nicht.". "keep_given": Wurde dem Verkaeufer etwas gegeben, mit dem er nichts anfangen konnte so ruft er die Funktion "given" auf. Zerstoert diese das uebergebene Objekt nicht, so wird es nach dem Aufruf von given durch den Verkaeufer zurueckgegeben. Manchmal ist dies jedoch nicht erwuenscht, der Verkaeufer soll die uebergebene Sache behalten. Dies kann durch "keep_given":1 als Mappingeintrag im Ergebnis von given verhindert werden, der Verkaeufer behaelt dann das Gegebene. Beispiel: /d/Maerchenland/Koboldingen/Schmied/rooms/schmied ------------------------------------------------------------------------------ Beispiel: Ganz normaler Brezelverkauf: mapping want (string s) { if (strstr (s,"brezel") != -1) return ([ "message":"Der Baecker nimmt eine Brezel aus einem Korb.", "soldmessage":"Der Baecker tut die Brezel in eine Tuete.", "timeoutmessage":"Der Baecker legt die Brezel in den Korb zurueck.", "price":12, "good":({this_object(),"mach_brezel_in_tuete"}) ]); Dann passiert das folgende: Ein Spieler sagt: will brezel. Der Baecker nimmt eine Brezel aus einem Korb. Der Baecker sagt: Das macht 12 Taler, wenn ich bitten darf. Ein Spieler gibt dem Baecker 12 Taler. Der Baecker tut die Brezel in eine Tuete rein. Der Baecker gibt dem Spieler eine Tuete. ------------------------------------------------------------------------------ Beispiel fuer "!GEBEN", Beispiel fuer Funktion given: return ([ "messages":({ "sage Was soll ich denn mit sowas?", "!GEBEN", "sage Das will ich nicht haben, behalt Du es."}) ]); ------------------------------------------------------------------------------ Beispiel fuer "!GEBEN" in soldmessages, Funktion want: return ([ ... "soldmessages": ({ "!ich nimmt die Schokolade aus dem Regal.", "!sage Da, nimm das suesse Ding!", "!GEBEN", "!sage Lass Dir die Schokolade schmecken." }), ... fuehrt zu: Hugo nimmt die Schokolade aus dem Regal. Hugo sagt: Da, nimm das suesse Ding! Hugo gibt Dir eine Fackel. Hugo sagt: Lass Dir die Schokolade schmecken. ------------------------------------------------------------------------------ ------------------------------------------------------------------------------ Trinkgeld: ~~~~~~~~~ Die lfun set_accept_tip hat einen mixed Parameter. Wird der Wert 0 uebergeben, so wird kein Trinkgeld genommen; dies ist die Standardeinstellung. Ist t vom Typ integer, so bedeutet jeder Wert ausser 0 natuerlich, dass der Verkaeufer Trinkgeld nimmt. Eine Danke-schoen-Meldung wird ausgegeben. Ist t ein String, so akzeptiert der Verkaeufer Trinkgeld und gibt dann den String als Meldung aus. Der String duerfte in den meisten Faellen soetwas wie "Hugo sagt: Dankeschoen fuer das Trinkgeld." sein. Ist der Parameter ein Funktionsaufrufspaar ({string/object wo, string funktionsname}) oder eine Closure, so wird die Funktion / die Closure aufgerufen mit einem int-Parameter als Argument, der die Hoehe des Trinkgeldes anzeigt. Beispiel: Tadmorer Schaenke /d/Vaniorh/Tadmor/Laeden/room/pub ------------------------------------------------------------------------------ ------------------------------------------------------------------------------ Roemische Zahlen: ~~~~~~~~~~~~~~~~ Mit der lfun set_roman kann der Verkaeufer in den Roemisch - Modus (fuer Gallien) und auch wieder zurueck gesetzt werden. ------------------------------------------------------------------------------ ------------------------------------------------------------------------------ Waehrung: ~~~~~~~~ Mit der lfun set_valuta MUSS die Waehrung des Verkaeufers gesetzt werden (es sei denn, es ist ein Tauschgeschaeft-Verkaeufer). Diese Waehrung kann mit query_valuta (Einzahl) und query_valutas (Mehrzahl) auch wieder abgefragt werden. ------------------------------------------------------------------------------ ------------------------------------------------------------------------------ Moerder: ~~~~~~~ Der Verkaeufer kann mit set_dont_serve_murderers so eingestellt werden, dass er keine Moerder bedient. Als Argument wird der Text uebergeben, den ein Moerder erhaelt, eine 0, wenn Moerder bedient werden sollen (Standardeinstellung) oder eine 1 zum Nicht-Bedienen von Moerder mit einer Standardmeldung. ------------------------------------------------------------------------------ ------------------------------------------------------------------------------ Lagerraum: ~~~~~~~~~ Man kann dem Verkaeufer auch einen Lagerraum geben, dann muss man die Gegenstaende nicht zu ihm hinmoven, es genuegt, dem Verkaeufer einen Pointer zu uebergeben. Beispiel, wo das sinnvoll ist: der Pfandleiher in Tadmor: /d/Vaniorh/Tadmor/Troedlermarkt/room/pfand. ------------------------------------------------------------------------------ ------------------------------------------------------------------------------ Noch ein paar Beispiele, die die prinzipielle Vorgehensweise erlaeutern sollen: ~~~~~~~~~~~~~~~~~~~~~~~ Normaler Laden: Spieler sagt: will fackel want wird aufgerufen, want liefert eine Fackel Spieler bezahlt, fertig. Reparatur: Spieler sagt: repariere mir bitte mein Schwert want liefert: Wenn ich Dir Dein Schwert reparieren soll, dann gibs mir einfach. Spieler gibt Schwert an Verkaeufer given wird aufgerufen, setzt den Preis fuer die Reparatur, liefert ein Funktionsaufrufspaar fuer die Repariere-Funktion. Spieler bezahlt. Repariere-Funktion wird aufgerufen, Waffe an Spieler zurueckgegeben. Maler: Maler malt einen auf Wunsch fuer Geld, vergisst aber seine Signatur. Wenn man ihm nun das Bild zurueckgibt, unterschreibt er es und gibt es zurueck. Spieler sagt: male mich want liefert: "message":"Der Maler malt ein ganz tolles Bild." "pricemessage":"Fuer 100 Taler is das Bild Deines." "soldmessage":"Der Maler sagt: Pass auf, die Farbe ist noch " "nicht ganz trocken.", "timeoutmessage":({"Der Maler zerreist das Bild wieder. "Der Maler seufz tief." "Der Maler sagt: Dann halt nicht."}) "price":100, "good":Bildobjekt Spieler gibt dem Maler 100 Taler, kriegt das Bild. Spieler sieht: Signatur fehlt. Spieler sagt: will auch eine signatur haben Maler sagt: Na, dann gib halt nochmal her. Spieler gibt Bild an Maler zurueck given wird mit (Bildobjekt, Spieler) aufgerufen und liefert lediglich die "message":"Der Maler bringt seine Signatur auf dem Bild an." der Maler gibt dem Spieler das Bild zurueck. Tausch: Alterative 1: Seil gegen Fackel Spieler sagt: will fackel want liefert: Wenn Du mir ein Seil gibst, geb ich Dir eine Fackel. want setzt ({"seil"}) als Preis, "/obj/fackel" als Ware. Spieler gibt Seil an Verkaeufer. Verkaeufer gibt Fackel an Spieler. Tausch: Alternative 2: Seil gegen Fackel Spieler sagt: will fackel want liefert nur: Wenn Du mir ein Seil gibst, geb ich Dir eine Fackel. want setzt keinen Preis. Spieler gibt Seil an Verkaeufer. given wird aufgerufen mit mit dem Sail und dem Spieler; given removt das Seil und liefert als Ware eine Fackel zum Preis 0. Tausch: Alternative 3: Irgendwas gegen Fackel Spieler sagt: will fackel want liefert nur: Wenn Du mir was schoenes gibst, geb ich Dir eine Fackel. want setzt keinen Preis. Spieler gibt Streichholz an Verkaeufer given wird aufgerufen mit dem Streichholz und dem Spieler; given ueberprueft, ob Nudelholz->query_value() > streichholz->query_value() (duerfte nicht der Fall sein). given liefert (lediglich) die Meldung, dass das Streichholz nicht "schoen genug" ist, um dafuer eine Fackel zu erhalten. Der Verkaeufer gibt dem Spieler das Streichholz zurueck. Spieler gibt Nudelholz an Verkaeufer. given wird aufgerufen mit dem Nudelholz und dem Spieler; given ueberprueft, ob Nudelholz->query_value() > fackel->query_value(). given removt das Nudelholz und liefert als Ware eine Fackel zum Preis 0. Verkaeufer gibt dem Spieler die Fackel. Geldwechsler: want liefert: Wenn ich Dir Geld in Dukaten umwechseln soll, dann gib es mir einfach. Spieler gibt Geld an Geldwechsler. given rechnet den Wert des Geldes in der neuen Waehrung um und setzt das Geld auf die neue Waehrung, liefert die Meldungen und als Preis den Wert 0 Der Verkaeufer gibt dem Spieler das gewechselte Geld. ------------------------------------------------------------------------------ ------------------------------------------------------------------------------ Closures: ~~~~~~~~ Bei allen Meldungen der standard_conversation und in den Meldungen in den von want oder given zurueckgelieferten Mappings kann man auch eine Closure angeben. Diese werden erst ausgewertet und dann ausgegeben oder, wenn der zurueckgelieferte String mit ! beginnt, als Befehl ausgefuehrt. Die Standardmeldungen erhalten folgende Parameter in der angegebenen Reihenfolge: "al_kann_nicht_mehr_tragen": object verkaeufer - Wer jemanden was geben will. object wer - Wer nix mehr tragen kann. object was - Was er nicht mehr tragen kann. "bedient_bereits_anderen_spieler": object verkaeufer - Wer bedient bereits einen anderen Spieler. object wer - Wer hat was gesagt. object kunde - Wer wird gerade bedient. "bedient_bereits_diesen_spieler": object verkaeufer - Wer bedient bereits diesen Spieler. object wer - Wer wird gerade bedient. "bittesehr": object verkaeufer - Wer gibt ihm es gerade. object kunde - Wer bekommt es gerade. object good - Was bekommt er gerade. "dann_halt_nicht": object verkaeufer - Wer gibt es ihm nun nicht mehr. object kunde - Wer bekommt es nun nicht mehr. mixed good - Was bekommt er nun nicht mehr. "das_kostet": object verkaeufer - Wer will etwas verkaufen. object kunde - Wer will etwas kaufen. mixed good - Was will jemand kaufen. int price - Und wie teuer ist das in Talern. "falsche_waehrung": object verkaeufer - Wer wurde gerade bezahlt. object kunde - Wer bezahlt gerade. object geld - Womit hat er bezahlt. "fehler": object verkaeufer - Wer will gerade was loswerden. object kunde - Wer will gerade was. mixed good - Das wurde beim Mapping uebergeben und ist falsch. "hab_ich_nicht": object verkaeufer - Wer hat was nicht. object wer - Wer will was. string str - Was hat er gesagt. "kunde_verschwunden": object verkaeufer - Vor wem ist er verschwunden. object kunde - Wer ist verschwunden. (Kann sehr wohl 0 sein!) "nanu": object verkaeufer - Wem hat er etwas gegeben. object wer - Wer hat dem Verkaeufer etwas gegeben. object was - Was hat er dem Verkaeufer gegeben. "unsichtbarer_gibt": object verkaeufer - Wem hat er etwas gegeben. object wer - Wer hat dem Verkaeufer etwas gegeben. object was - Was hat er gegeben. "unsichtbarer_gibt_verschwinden": object verkaeufer - Wem hat er etwas gegeben. object wer - Wer hat dem Verkaeufer etwas gegeben. object was - Was hat er gegeben. "unsichtbarer_sagt": object verkaeufer - Wer hat etwas gehoert. object wer - Wer hat etwas gesagt. "was_willst_du_haben": object verkaeufer - Wer hat nix gehoert. object wer - Wer hat nix gesagt. "zu_viel_geld": object verkaeufer - Wer ist jetzt reich. object kunde - Wer hat zuviel bezahlt. mixed good - Wofuer hat er zuviel bezahlt. int price - Was haette er bezahlen sollen. int bezahlt - Was hat er bezahlt. "zu_wenig_geld": object verkaeufer - Wer ist jetzt sauer. object kunde - Wer hat zuwenig bezahlt. mixed good - Wofuer hat er zuwenig bezahlt. int price - Was haette er bezahlen sollen. int bezahlt - Was hat er bezahlt. Und die Closures im Mapping von want oder given erhalten folgende Parameter: "message": object verkaeufer - Der bedienende Verkaeufer object kunde - Der bediente Kunde mixed good - Der Gegenstand, um den es geht. "messages": object verkaeufer - Der bedienende Verkaeufer object kunde - Der bediente Kunde mixed good - Der Gegenstand, um den es geht. "pricemessage": object verkaeufer - Der bedienende Verkaeufer object kunde - Der bediente Kunde mixed good - Der Gegenstand, um den es geht. int price - Der Preis. "soldmessage": object verkaeufer - Der bedienende Verkaeufer object kunde - Der bediente Kunde object good - Der Gegenstand, um den es geht. "soldmessages": object verkaeufer - Der bedienende Verkaeufer object kunde - Der bediente Kunde object good - Der Gegenstand, um den es geht. "timeoutmessage": object verkaeufer - Der bedienende Verkaeufer object kunde - Der bediente Kunde mixed good - Der Gegenstand, um den es geht. ------------------------------------------------------------------------------ ------------------------------------------------------------------------------