IF-Forum

» IF-Forum - Autorencafé - Schreiben! - I6 Default-Messages ändern?
AntwortenNeues ThemaNeue Umfrage

I6 Default-Messages ändern?

Geschrieben um 20:47 am 02.05.2013 | Zitat | Editieren | Löschen
Mischa
Mitglied
Master Gumby
Beiträge: 107

Für mein Projekt würde ich in I6 gern die Default-Messages ändern.

Ich hab' schonmal herausgefunden, dass diese sich in German.h verstecken. (Sind das alle?)

Die Hauptfrage ist eigentlich:

Gibt's eine elegantere Möglichkeit, als German.h direkt zu modifizieren?

Geschrieben um 22:37 am 02.05.2013 | Zitat | Editieren | Löschen
Martin
Avatar
Mitglied
Prof Gumby
Beiträge: 634

Ja. Man kann ein Objekt LibraryMessages definieren und einzelne Texte austauschen:


  with before [;

           Jump: "Wheee!";

       ];

Man muss dann true zurückgeben, damit die Lib weiß, dass schon etwas geschrieben wurde. Die Variablen lm_n und lm_o enthalten die Id der Meldung und das betreffende Objekt, siehe §25 im DM4. Das bietet sich an, wenn man nur wenige Meldungen austauschen möchte.

Wenn man alle oder zumindest sehr viele Meldungen anfassen muss, zum Beispiel wenn man das Adventure in der ersten Person schreibt, ist es gewiss besser, die gesamte Routine L__M in das eigene Spiel zu kopieren und mit Replace L__M die von der Lib verwendete Implementierung zu unterdrücken:


Replace L__M;

Include "Parser.h";

Include "Verblib.h";

[ L__M;

   ! Angepasste Kopie der L__M aus German.h

];

Auf diese Weise werden die verwendeten Texte nicht doppelt erstellt, was bei der ersten Methode der Fall ist.

Wenn man die Antworten während des Spiels variieren will, kann man sich ein eigenes System überlegen, zum Beispiel Tochterobjekte von LibraryMessages, die man hin- und her verschiebt:


  with before [ o;

            objectloop (o in self) {

                if (o provides before && o.before()) rtrue;

            }

       ];

Object AMessages

  with before [;

           Jump: "Abgehoben, abnorm aufgekommen,

                ausgerutscht. Autsch!";

       ];

Object SMessages

  with before [;

           Jump: "Sachte, sachte! Springen scheint sinnlos,

                seriöseren Sport suchen!";

       ];

Object ARoom

    with after [;

        Go: while (child(LibraryMessages)) {

                remove child(LibraryMessages);

            }

            move AMessages to LibraryMessages;

        ], ...;

So etwas könnte man zum Beispiel auch nutzen, wenn man im Spiel andere Szenen wie zum Beispiel Rückblenden einbaut, die einen anderen Ton haben sollen.

Geschrieben um 07:55 am 03.05.2013 | Zitat | Editieren | Löschen
Hannes
Avatar
Mitglied
Prof Gumby
Beiträge: 558

Also das zweite Beispiel mag bei sehr umfangreichen Aenderungen praktisch sein, aber sonst finde ich folgendes unaufwaendiger:


Object LibraryMessages

  with before [;

           Jump:

               if (real_location == ARoom)

                   "Du stoesst dir den Kopf an der Decke.";

               if (rueckblende == 1)

                   "Du sprangst, die Arme wedelnd, nach oben, und erntest verstaendnislose Blicke der Anwesenden.";

               "Wheee!";

       ];
Geschrieben um 13:03 am 03.05.2013 | Zitat | Editieren | Löschen
Martin
Avatar
Mitglied
Prof Gumby
Beiträge: 634

Hannes:

Also das zweite Beispiel mag bei sehr umfangreichen Aenderungen praktisch sein, aber sonst finde ich folgendes unaufwaendiger: ...

Unaufwändiger stimmt vielleicht, aber wenn's doch mehr wird, wird das ja schnell unübersichtlich. Die If-Abfragen fallen ja in deiner Methode für jeden Text an.

Außerdem hat die Methode der Unterobjekte den Vorteil, dass die angepassten Texte dort sind, wo auch die passende Räume und Objekte zu finden sind. Beim ARoom stünde das Messages-Unterobjekt direkt beim Raum, bei der Rückblende würde ich alles, also Objekte und Messages-Objekt, in eine eigene Datei packen.

Die Platypus-Lib von Anson Turner hat ein zentrales Gizmo-Objekt, in das man Objekte verschieben kann, deren Methoden die Einhänger (entry points) in der Inform-Lib ersetzen. Diese können ja nur einmalig definiert werden. (Man könnte sich natürlich auch hier ein Gerüst bauen, so dass dann zum Beispiel PrintVerb für alle Töchter o von Gizmo o.print_verb() aufruft. Dann wäre es sogar für Erweiterungen möglich, in PrintVerb einzugreifen, ohnd die Lib selbst oder das Spiel zu ändern.)

Geschrieben um 14:13 am 03.05.2013 | Zitat | Editieren | Löschen
Hannes
Avatar
Mitglied
Prof Gumby
Beiträge: 558

Alles korrekt, nur: Wenn man die Texte nicht monolitisch szenenweise, sondern unter unterschiedlichen Bedingungen einzeln austauschen möchte, dann ist man ganz schnell bei dem Stil, den ich skizziert habe. Letztlich kommt es also darauf an, was man erreichen will.

Geschrieben um 15:08 am 03.05.2013 | Zitat | Editieren | Löschen
Martin
Avatar
Mitglied
Prof Gumby
Beiträge: 634

Hannes:

Letztlich kommt es also darauf an, was man erreichen will.

Ja, genau. Aber das bestreite ich ja gar nicht. Ich habe lediglich drei verschiedene Möglichkeiten, die Standardtexte zu ändern, gezeigt.

Vielleicht habe ich mich nur nicht klar genug ausgedrückt. Die dritte, komplexe Variante ist natürlich nicht die einzige Möglichkeit, dynamische Texte umzusetzen. Bedingungen in LibraryMessages.before() funktionieren genauso gut und sind, wenn man nur einzelne Texte gezielt austauschen will, gewiss am besten.

Ich kenne aber Mischas Projekt und vermute, dass er nicht nur einzelne Antworten austauschen will. Deshalb habe ich die beiden anderen Möglichkeiten erwähnt.

Vielleicht ist L__M(##Jump, 1) eh kein gutes Beispiel, denn das würde ich für einen einzelnen Raum eher in real_location.before() abfangen.

Geschrieben um 15:28 am 03.05.2013 | Zitat | Editieren | Löschen
Mischa
Mitglied
Master Gumby
Beiträge: 107

Jump hatte ich eigentlich vor im player_object mit react_before abzufangen, aber das hat andere Gründe (nämlich, dass ich das player_object während des Spiels austauschen will).

Ansonsten gefällt mir die Methode, die gesamten restlichen Messages auszutauschen ganz gut!

Ist aber ein sehr interessanter Thread geworden!

Hätte nie gedacht, dass es so viele unterschiedliche Möglichkeiten gibt.

(Vorallem da mir Dr. Google nicht wirklich weiterhelfen konnte... ;-)

Geschrieben um 22:15 am 07.05.2013 | Zitat | Editieren | Löschen
Mischa
Mitglied
Master Gumby
Beiträge: 107

Martin:


Replace L__M;

Include "Parser.h";

Include "Verblib.h";

[ L__M;

   ! Angepasste Kopie der L__M aus German.h

];

Erster Test erfolgreich! :-)

Nur dass die zu ersetzende Routine bei mir LanguageLM heißt.

Oder ersetze ich damit etwas anderes?

Geschrieben um 22:22 am 07.05.2013 | Zitat | Editieren | Löschen
ChristianB
Mitglied
Retired Gumby
Beiträge: 1062

Die Meldungen stehen in LanguageLM; das ist also OK so, wie Du es gemacht hast. Mit L__M() gibt man zwar eine Meldung aus, dort werden aber nur ein paar Parameter gesetzt und dann L___M aufgerufen, von wo aus dann am Ende LibraryMessages und/oder LanguageLM dran sind.

Geschrieben um 07:29 am 08.05.2013 | Zitat | Editieren | Löschen
Mischa
Mitglied
Master Gumby
Beiträge: 107

Eine Folgefrage hätte ich da noch:

Wenn ich

grabe

eingebe, erhalte ich als Antwort

Worein willst du graben?

Ich kann diese Phrase aber nirgends finden.

Ich vermute, das hängt damit zusammen, dass graben (Dig) ein noun verlangt und das schon irgendwo vorher abgefangen wird, doch hat auch das Umdefinieren von


Extend 'grab' *  -> Dig;

nicht geholfen, um auch ohne noun graben zu dürfen.

Weiß jemand

a) wo ich die Phrase bearbeiten kann oder

b) wie ich die Verbdefinition richtig ergänzen muss!? (Oder muss ich sie gar ersetzen?)

Geschrieben um 08:13 am 08.05.2013 | Zitat | Editieren | Löschen
Martin
Avatar
Mitglied
Prof Gumby
Beiträge: 634

ChristianB:

Die Meldungen stehen in LanguageLM; das ist also OK so, wie Du es gemacht hast.

Ja, das habe ich oben nicht richtig erklärt, Entschuldigung.

LanguageLM enthält die Basis-Texte. Es wird aber immer nur der Wrapper L__M aufgerufen, der zum Beispiel (in einem weiteren Wrapper, L___M) auch prüft, ob der Text vom Objekt LibraryMessages kommt.

Deform:

Worein willst du graben?

Das ist ein Fehler in deform. Damit die Nachfrage richtig gestellt wird, muss man dem [noun]-Token ein [dative] voranstellen. Ab Zeile 1186 in GermanG.h müste es also eigentlich heißen:


Verb 'grab' 'buddel' 'buddl'

    * 'in' dative noun                          -> Dig

    * noun                                      -> Dig

    * 'in' dative noun 'mit' dative held        -> Dig

    * 'mit' dative held 'in' dative noun        -> Dig reverse

    * noun 'mit' dative held                    -> Dig

    ;
Geschrieben um 20:21 am 09.05.2013 | Zitat | Editieren | Löschen
Mischa
Mitglied
Master Gumby
Beiträge: 107

Ok... Jetzt bekomme ich als Antwort

Worin willst du graben?

Das war aber nicht mein gewünschtes Resultat! ;-)

Eigentlich wollte ich diese Meldung gar nicht bekommen bzw. auf die Standard-Antwort von grab in noun umgeleitet werden.

(Diese von mir umgeschriebene Antwort wird kein noun enthalten, sollte also auch auf grabe eine passende Antwort geben.)

Geschrieben um 23:19 am 09.05.2013 | Zitat | Editieren | Löschen
Hannes
Avatar
Mitglied
Prof Gumby
Beiträge: 558

Das Standard-DigSub setzt nun mal die Existenz eines Nomens voraus. Entweder kannst du das also komplett ersetzen oder aber (das würde ich machen) du definierst eine neue Aktion, bspw. so:



   * -> DigHere;

[ DigHereSub;

   "Der Untergrund ist hier zu hart.";

];```

Und dann eben dort, wo du es erlauben möchtest, kannst du die DigHere-Aktion spezifisch definieren, umleiten oder was immer du vorhast.
Geschrieben um 22:14 am 10.05.2013 | Zitat | Editieren | Löschen
Mischa
Mitglied
Master Gumby
Beiträge: 107

Hannes:



   * -> DigHere;

[ DigHereSub;

   "Der Untergrund ist hier zu hart.";

];```

Ersetzt man das **last** in dem Beispiel durch **first**, funktioniert das wunderbar! Danke für den Tipp!
AntwortenNeues ThemaNeue Umfrage
Powered by Spam Board SVN © 2007 - 2021
Impressum / Datenschutz