Ein mobiler Händler
![]()
// mobiler Händler, // ----------------- // der herumläuft und u.a. Weintrauben verkauft // // Dieser Händler ist schon ein etwas komplexerer NPC. Bitte zuerst // die beiden Bsp.-Hasen und den Hund anschauen für das Verständnis von // netten und herumlaufenden NPCs. Außerdem bitte die Beispiele der Rubrik // Lcontainer anschauen für das Verständnis des Flaschenfüllens. // Original by Sunrise@Wunderland 2000 // // Bemerkung: Von allem überflüssigen entschlackt für die Beispielsammlung // (d.h. kaum noch Infos/Details - es geht um die Funktionalität) // // 10.10.2005 Holger: angepasst fuer einheitlichen Coinmaster #pragma strong_types inherit "npc"; inherit "trade"; // erbt Hilfsfunktionen fuer Händler #include <properties.h> // für die allgemeinen Properties #include <defines.h> // ein paar praktische Defines wg. der Schreibarbeit ;-) #include <npc/react.h> // es ist ein netter NPC #include <moving.h> // es ist ein moving NPC #include <npc/walking.h> #include <lcontainer.h> // für das Auffüllen der Flaschen #include <bank.h> // für die Zentralbank int kaufe(string str); // die Verkaufsabwicklung string auffuellen(); // der Händler füllt Flaschen (Lcontainer) // mit Wasser string preise(); // für die Preisinformationen void create() { if (!clonep()) return; ::create(); SetStandardReactions(); // Nettireaktionen SetProp(P_NAME_ADJ, "gerissen"); SetProp(P_NAME, "Haendler"); SetProp(P_PLURAL, "Haendler"); SetProp(P_MNPC_HOME, "/doc/beispiele/raum1"); SetProp(P_MNPC_AREA, ({ "/doc/beispiele/" })); SetProp(P_MNPC_DELAY, 40); SetProp(P_MMSGOUT, "zieht sein Maultier hinter sich her und verschwindet"); SetProp(P_MSGOUT, "zieht sein Maultier hinter sich her und verschwindet"); SetProp(P_MMSGIN, "kommt mit seinem Maultier herein"); SetProp(P_MSGIN, "kommt mit seinem Maultier herein"); SetProp(P_MNPC_FLAGS, MNPC_WALK); SetProp(P_GENDER, MALE); SetProp(P_ALIGN, -200); SetProp(P_LOG_INFO, "/doc/beispiele/haendler.rep"); // Im Wunderland gibt es verschiedene Währungen. // Dieser Händler will unbedingt die Außenweltwährung. SetProp(P_CURRENCY, CT_AUSSENWELT); // Wenn der Händler stirbt, erzählen wir, daß auch sein Maultier wegrennt. SetProp(P_DIE_MSG, " faellt tot zu Boden.\n" "Das Maultier rennt voller Panik davon und ward nie mehr gesehen.\n"); AddId(({"haendler", "mann"}), ({"haendler", "maenner"})); SetProp(P_ADJECTIVES, ({"gerissen", "gerissener", "gerissenen", "gerissenem", "gerissene"})); // Für die Werte für P_BODY etc. machen wirs uns leicht create_default_npc(25); ////// DETAILS /////////////////////////////////////////////////////////// SetProp(P_LONG, "Dieser Haendler ist staendig unterwegs, immer " "auf der Suche nach einem guten Geschaeft. Er fuehrt ein vollbepacktes " "Maultier an der Leine hinter sich her.\n" "Seine gierigen Augen schauen Dich abschaetzend an."); AddDetail(({"schild", "preise"}), #'preise); AddReadDetail(({"schild", "preise"}), #'preise); ////// FUNKTIONEN //////////////////////////////////////////////////////// AddCmd("kauf|kaufe", #'kaufe); ////// INFOS ///////////////////////////////////////////////////////////// AddInfo("fuellst|fuellen|auffuellen&flasche|flaschen", #'auffuellen); ////// REAKTIONEN //////////////////////////////////////////////////////// // Durch SetStandardReactions() werden ein paar Reaktionen angelegt, die // nicht so recht zu diesem Händler passen. Wir entfernen sie und deklarieren // dann neue. RemoveReaction("danke", R_ME); RemoveReaction("grinse", R_ME); RemoveReaction("strecke", R_ME); RemoveReaction("liebe", R_OTHER); RemoveReaction("druecke", R_ME); RemoveReaction("nicke", R_ME); RemoveReaction("weine", R_ME|R_NOONE); AddReaction("danke", R_ME, ({ 1, "sage Solange Du immer bezahlst, brauchst Du Dich nicht zu bedanken."})); AddReaction("grinse", R_ME, ({ 1, "grins &name gerissen" })); AddReaction("strecke", R_ME, ({ 1, "emote ist empoert", 1, "sage Diese Jugend von Heute!!" })); AddReaction("liebe", R_OTHER, ({ 2, "denke Wer bezahlt hier wen?" })); AddReaction("druecke", R_ME, ({ 1, "sage Lass mich in Ruh."})); AddReaction("nicke", R_ME, ({ 1, "nicke &name wichtigtuerisch"})); AddReaction("weine", R_ME|R_NOONE, ({ 2, "sage Heul nicht rum, &Name."})); // Ein paar Chats für bißchen mehr "Leben" SetChats(3, ({ "Der Haendler beschimpft das Maultier.", "Das Maultier schaut deprimiert in die Gegend.", "Der Haendler zerrt an der Leine.", "Das Maultier bockt und will nicht weitergehen." })); } string preise() { // MakePriceList wurde geerbt aus std/trade.c und erstellt automagisch // ein Preisschild mit dem Angebot und der aktuellen Waehrung PL->More(MakePriceList("Preisliste", "", 2, ({ ({"Weintraube", 250}), ({"Tuch", 30}), ({"Fuellung Wasser", 200}), ({"Glasflasche", 450}), 55)); return "\n"; } int kaufe(string str) { int preis; string mess, was; mixed *kauf; object ob; // Wenn der Spieler grad unser Feind ist, verkaufen wir ihm natürlich nix. if (IsEnemy(PL)) { command_me("sage Dir soll ich noch etwas verkaufen, nachdem Du mich " "feige angegriffen hast? Das soll wohl ein Witz sein?!?!?"); return 1; } notify_fail("WAS willst Du kaufen?\n"); // Wir brauchen ein Argument, das uns angibt, was der Spieler kaufen will. // Ist keins angegeben, geben wir die Fehlermeldung aus, die wir mit notify_fail // festgelegt haben if (!str || !stringp(str) || !strlen(str)) return 0; // Wir wandeln alle Großbuchstaben in dem Argument in Kleinbuchstaben. // Das erleichtert uns die Arbeit und der Spieler kann auch "kaufe Tuch" // statt "kaufe tuch" schreiben, ohne, daß es wen stört :-)) str = lower_case(str); // Nun schaun wir, was der Spieler denn konkret will. Je nach Fall legen wir // den Preis und das zu clonende Objekt (was) fest. mess ist der Text, den // der Spieler bei der Uebergabe bekommt. switch(str) { case "weintraube": case "weintrauben": case "wein": case "traube": case "trauben": mess = "Der Haendler reicht Dir aus einem seiner Koerbe " "eine frische Traube Weinbeeren.\n"; was = "/doc/beispiele/weintraube"; preis = 500; break; case "wasser": // Das Wasser hat eine Sonderrolle tell_object(PL, "Der Haendler sagt: Frag mich doch einfach, " "ob ich Dir Deine Flasche auffuelle.\n"); return 1; break; case "flasche": case "glasflasche": case "flaschen": case "glasflaschen": mess = "Der Haendler reicht Dir aus einem seiner Koerbe eine " "leere Glasflasche.\n"; was = "/doc/beispiele/lcontainer/flasche"; preis = 900; break; case "tuch": mess = "Der Haendler reicht Dir aus einem seiner Koerbe ein " "weiches Tuch.\n"; was = "/doc/beispiele/tuch"; preis = 60; break; default: tell_object(PL, "Sowas kannst Du hier nicht kaufen.\n"); return 1; } // Mit QueryMoney schaun wir, was der Spieler an Geld in der von uns // gewünschten Währung hat. Ist es zu wenig, verkaufen wir natürlich // nicht. if (PL->QueryMoney(QueryProp(P_CURRENCY)) < preis) { tell_object(PL, break_string( "Der Haendler schaut Dich geringschaetzig an und meint: " "Du hast nicht genug Geld bei Dir.\n")); return 1; } // Mit AddMoney kann man das Barvermögen beeinflussen. Wir reduzieren das // des Spielers um den zu zahlenden Preis. PL->AddMoney(QueryProp(P_CURRENCY), -preis); // Für die Statistik: // Wir teilen der Zentralbank mit, wieviel Geld wir eingenommen haben ZENTRALBANK->PutMoney(ME, preis); // Das Clonen der verkauften Güter ob = clone_object(was); // Ausgabe der Meldung an den Spieler tell_object(PL, mess); // Und die Uebergabe des Objektes an den Spieler // Hat die Uebergabe nicht geklappt, legen wir den bezahlten Gegenstand im // Raum ab. if (ob->move(PL) < MOVE_OK) { tell_object(PL, break_string( "Der Haendler sagt: Du kannst " + ob->name(WEN, NAME_AUTO) + " nicht mehr tragen. Ich lege " + ob->QueryPronoun(WEN) + " hier hin.")); return ob->move(environment(ME), M_PUT); } // Und nun noch eine Meldung an die Umgebung. tell_room(environment(ME), PL->name(WER, NAME_AUTO|NAME_CAP) + " kauft " + ob->name(WEN, NAME_INDEF) + ".\n", ({PL}) ); return 1; } // Dies Funktion wird durch AddInfo aufgerufen. Sie soll uns einen Antwort-String // zurückgeben über Erfolg oder Mißerfolg des Auffüllens string auffuellen() { int am, preis; object *flaschen, *leer; // Der Preis für das Auffüllen des Gefäßes in Grundeinheiten preis = 200; // Lcontainer erkennt man an der Aufnahmefähigkeit von Flüssigkeiten // -> LCNT_MAXCAPA // Wir suchen alle, auf die das zutrifft aus dem Inventar des Spielers flaschen = filter_objects(all_inventory(PL), "QueryProp", P_LCNT_MAXCAPA); if (!sizeof(flaschen)) return "sagt: Du hast kein geeignetes Gefaess bei Dir."; // IsEmpty ist eine interne Funktion der Lcontainer. Sie gibt 1 zurück, wenn // der Behälter leer ist. leer = filter_objects(flaschen, "IsEmpty"); // In Lcontainern können sich Flüssigkeiten vermischen. Das wollen wir // hier nicht. Schließlich geh ich auch nicht mit ner halben Flasche Bier // an den Brunnen und füll sie mit Wasser auf ;-)) if (!sizeof(leer)) return "sagt: Du hast keine leeres Gefaess bei Dir."; // Wieviel paßt rein in das Gefäß? Wir wollen es ganz füllen. am = leer[0]->QueryProp(P_LCNT_MAXCAPA); // Hat der Spieler genug Geld? if (!PL->AddMoney(QueryProp(P_CURRENCY), -preis)) return "Der Haendler schaut Dich geringschaetzig an und meint: " "Du hast nicht genug Geld bei Dir.\n"; // Auffüllen des Gefäßes und Ausgabe des Antwortstrings if (leer[0]->AddLiquid(am, "wasser", "Wasser", am/10, 0, 0, am/2)) return "oeffnet einen seiner Wasserschlaeuche und fuellt Dir Deine Flasche mit " "frischem Wasser."; return "sagt: Etwas geht nicht."; } |
| Start » Magierhandbuch » Dokumentation » Programmierbeispiele » Mobiler Händler | |
|
| |