! NPCs in Raumbeschreibungen - Beispiel 1 ! ! Der Schmnied bekommt eine eigene Zeile in der Raumbeschreibung. Das ! wird ganz einfach mit 'initial' gemacht. Diese Beschreibung kommt ! immer, da der Schmied ja nie aufgehoben wird. Alle anderen ! Gegenstände im Raum werden gesondert aufgeführt. ! ! Der Schmied führt eine dämonengesteuerte Handlung durch, er ! schmiedet ein Hufeisen. Wenn die Aktion ##Look ist, wird diese ! Aktion direkt in 'initial' erwähnt, ansonsten nach dem Zug in ! 'each_turn'. Das vermeidet holperige Beschreibungen wie: ! ! Der Schmied ist hier. ! ! Der Schmied härtet das Hufeisen in einem Bottich mit Öl. Es ! gibt ein zischendes Geräusch. ! ! Wenn die Aktion 'life' des Schmieds aufgerufen wird, führt der ! Schmied keine Aktion durch, er hält einen Zug lang inne. ! !----------------------------------------------------------------------- Constant Story "Jeder ist seines Glückes Schmied"; Constant Headline "^Ein Beispiel für NPCs in Raumbeschreibungen^^"; Constant NO_SCORE; Include "Parser"; Include "Verblib"; Object Vor_der_Schmiede "Vor der Schmiede" with name 'schmiede', description "Du stehst vor einer kleinen Schmiede, deren Eingang im Norden liegt. Ein Weg führt nach Westen auf einen Lagerplatz und nach Osten aus dem Spiel.", n_to Schmiede, w_to Lagerplatz, in_to Schmiede, e_to [; <>; ], out_to [; return self.e_to(); ], each_turn [; switch (Schmied.action_stage) { 0: "^In der Schmiede hörst du ein Fauchen."; 2: "^Aus der Schmiede hörst du schwere metallische Schläge."; 3: "^Die Schläge in der Schmiede werden schneller, federnder."; 5: "^Aus der Schmiede dringen regelmäßige Schläge."; 6: "^Die Schläge sind jetzt kurz und in schneller Abfolge."; 7: "^Jetzt sind die Schläge nur noch vereinzelt zu hören."; 8: "^Aus der Schmiede kommt ein Zischen."; 9: "^Ein federnd metallisches Geräusch kommt aus der Schmiede."; } ], has light; Object Lagerplatz "Lagerplatz" with name 'schrott' 'schutt' 'lager' 'gras' 'sammlung' 'ansammlung', description "Dieser Lagerplatz ist eigentlich eher eine trostlose, teilweise mit Gras bewachsene Ansammlung von Schrott und Schutt. Ein Weg führt nach Osten.", e_to Vor_der_Schmiede, out_to Vor_der_Schmiede, has light; Object -> Flasche "Plastikflasche" with name 'flasche' 'plastik' 'gruen' 'blass' 'blassgruen' 'blind' 'plastikflasche', description "Eine weggeworfene blassgrüne Plastikflasche, ohne Verschluss und schon etwas blind.", initial "Am Rande des Schutthaufens, noch nicht vom Gras bedeckt, siehst du eine grüne Plastikflasche.", has female; Object Schmiede "Schmiede" with name 'haufen' 'blasebalg' 'balg' 'fenster', description "Die Schmiede ist ein kleiner, dunkler Raum, der weniger vom Tageslicht, das durch die verschmierten Fenster fällt, als vom rötlichen Licht der Glut im Ofen erhellt wird. Der Mittelpunkt der Schmiede ist der schwere Amboss. Eine Tür führt im Süden nach draußen.", s_to Vor_der_Schmiede, out_to Vor_der_Schmiede, has light; !----------------------------------------------------------------------- ! ! Der Schmied, das Kernstück dieses Beispiels. Er hat, wie ! versprochen, ein eigenes 'initial'. Er ist das erste Objekt in der ! Schmiede, das getrennt gelistet wird. Der Hammer, der ebenfalls ein ! 'initial' hat, ist ein jüngeres Kind der Schmiede (s. $3 DM4). Wenn ! er aufehoben und wieder abgelegt wird, ist er älter als der Schmied, ! aber dann wurde er bereits bewegt, und 'initial' greift nicht. ! ! Das eigentlich Interessante ist, dass die Beschreibung der Tätigkeit ! des Schmieds in zwei Fällen aus 'ech_turn' ausgelagert wird, um einen ! (hoffentloich) schöneren Textfluss zu haben. Dioes passiert für ! , wo die Tätigkeit in 'initial', und für , wo ! sie in 'descriptionb' ausgelagert wird. Mit der Flagge 'silent_each_ ! turn' wird dann die Ausgabe in 'each_turn' unterdrückt. Der Text wird ! ausgelagert in eine neu definierte individuelle Eigenschaft ! 'action_desc', in der 'silent_each_turn' als Indikator dafür verwendet ! wird, ob eine neue Zeile angefangen wird und der Schmied mit seinem ! vollen Namen genannt wird (weil der Kontext bei 'each_turn' unklar ! ist) oder ob ein Pronomen verwendet wird, um unschöne Doppelnennungen ! zu vermeiden. Das Hochzählen der Arbeitsschritte 'actuion_stage' wird ! in 'TimePasses' vorgenommen, da es immer nach 'each_turn' erfolgt, ! siehe dazu weiter unten. ! ! Ein weiteres Gimmick ist, dass der Schmied seine Arbeit unterbricht, ! wenn er etwas gefragt wird oder eine andere 'life'-Aktion ausführen ! soll. ! !----------------------------------------------------------------------- Object -> Schmied "Schmied" with name 'schmied' 'hufschmied' 'herr' 'schmidt' 'mann', silent_each_turn false, pause_action false, action_stage 0, action_desc [g; if (self.pause_action) return; if (self.silent_each_turn) { g = random ("gerade ", "im Moment ", "im Augenblick"); if (self.action_stage ~= 6) print "Er "; } else { g = ""; new_line; if (self.action_stage ~= 6) print (GDer) self, " "; } switch (self.action_stage) { 0: "facht ", (string) g, "das Feuer mit dem Blasebalg an und die Glut im Ofen glüht hell."; 1: "holt ", (string) g, "mit einer Zange einen der glühenden Rohlinge aus dem Ofen."; 2: "hämmert mit schweren Schlägen auf dem Rohling herum und biegt ihn so um einen Dorn auf dem Amboss in die Form eines Hufeisens."; 3: "flacht ", (string) g, "das Hufeisen ab, indem er den gebogenen Rohling mit schweren Schlägen treibt."; 4: "hält das Hufeisen noch einmal kurz in die Glut."; 5: "schlägt ", (string) g, "mit einem Dorn die Löcher für die Hufnägel ein."; 6: print "Mit schnellen, federnden Schlägen richtet "; if (self.silent_each_turn) print "er jetzt"; else print "der Hufschmied"; " das Hufeisen auf dem Amboss."; 7: "bearbeitet ", (string) g, "die letzten Details des Hufeisens. Dabei benutzt er einen spezielle Form auf dem Amboss."; 8: "betrachtet ", (string) g, "das fertige Hufeisen. Dann schreckt er es in einem Bottich mit Öl ab. Es zischt."; 9: "wirft ", (string) g, "das fertige Hufeisen auf einen Haufen neben dem Amboss."; } ], description [; self.silent_each_turn = true; print "Der Schmied ist ein kräftiger, ruhiger Mann. "; self.action_desc(); ], initial [; self.silent_each_turn = true; print "Der Schmied ist hier. "; self.action_desc(); ], life [; self.pause_action = true; Ask, Tell: "Der Schmied hält inne und überlegt. ~", (string) random("Ja, so etwas gibt's", "Nein, davon habe ich noch nichts gehört", "Darüber kann ich Ihnen leider nichts sagen"), "~, sagt er schließlich."; Give, Show: "Der Schmied hält inne und schaut sich ", (den) noun, " an. ~Das ist ", (ein) noun, "~, sagt er nachdenklich."; default: "Verwundert blickt der Schmied von seiner Arbeit auf und schaut dich ruhig an."; ], each_turn [; if (~~self.silent_each_turn) self.action_desc(); self.silent_each_turn = false; ], time_passes [; if (self.pause_action) { self.pause_action = false; return; } self.action_stage++; if (self.action_stage > 9) self.action_stage = 0; ], has male animate transparent; Object -> -> Hufeisen "Hufeisen" with name 'hufeisen' 'eisen', description "Ein glühendes Stück Eisen, das sich nach und nach der Form eises Hufeisens annähert.", before [; Examine: default: "Glühende Hufeisen anzufassen bringt gewiss kein Glück."; ], has neuter concealed; Object -> Amboss "Amboss" with name 'amboss' 'dorn' 'block' 'form', description "Der Amboss ist ein massiver Block mit einer großen Arbeitsfläche, einem konischen Dorn auf der einen und einer Hufeisenform auf der anderen Seite.", before [; Examine: ; default: "Besser nicht. Der Schmiede braucht den Amboss zum Arbeiten. Du machst nur seinen Akkord kaputt."; ], has male static concealed; Object -> Ofen "Ofen" with name 'ofen' 'glut' 'feuer' 'rohling', description "Ein bulliger Ofen, in dem einige gerade Rohlinge in der Glut darauf warten, zu Hufeisen umgearbeitet zu werden.", before [; Examine: ; default: "Der Ofen ist zu heiß, um sich ihm zu nähern. Außerdem störst du so gewiss den Arbeitsrhythmus des Schmieds."; ], has male static concealed; Object -> Vorschlaghammer "Vorschlaghammer" with name 'hammer' 'vorschlaghammer' 'bello' 'mottek', description "Ein schwerer Hammer, der zum Schmieden von Hufeisen sicher nicht benötigt wird.", initial "In einer Ecke der Schmiede lehnt ein Vorschlaghammer an der Wand.", has male; Object Stock "Stock" with name 'stock' 'stab' 'stecken' 'wanderstock' 'wanderstab', description "Dein Stock, ein treuer Gefährte auf deinen Wanderungen.", has male; !----------------------------------------------------------------------- ! ! Einhänger (Entry Point Routines) ! ! Hier wird 'TimePasses' anstelle eines Dämons beim Schmied benutzt, ! da dieser Einhänger immer nach der Ausgabe im Spielzug (##Look, ! ##Examine Schmied) und nach allen 'each_turn's erfolgt. Dämonen ! werden nach dem Zug, aber vor 'each_turn' abgearbeitet, und daher ! sind die Aktionen des Schmieds nicht konsistent: 'each_turn' wäre ! schon einen Schritt weiter. (Vgl. §20 im DM4) ! ! 'TimePasses' ist hier so implementiert, dass jedes beliebige Objekt ! eine Eigenschaft 'time_passes' haben kann, die in jedem Zug ausge- ! führt wird. Dies ist eine einfache Implementierung von Dämonen, die ! nicht aktiviert werden müssen und fügt dem System der Dämonen eine ! weitere Stufe hinzu. (Vermutlich wird es bei großen Spielen aber ! sehr langsam. Wenn viele Objekte 'time_passes' haben, sollte man ! diese Eigenschaft vielleicht als "common property" deklarieren, ! siehe dazu $3.13 im DM4. ! !----------------------------------------------------------------------- [ Initialise; move Stock to player; location = Vor_der_Schmiede; "^^^^^"; ]; [ TimePasses o; objectloop (o provides time_passes) o.time_passes(); ]; Include "GermanG";