IF-Forum

» IF-Forum - Autorencafé - Schreiben! - Schreibtisch mit Laden
AntwortenNeues ThemaNeue Umfrage

Schreibtisch mit Laden

Geschrieben um 17:42 am 16.02.2010 | Zitat | Editieren | Löschen
Mischa
Mitglied
Master Gumby
Beiträge: 107

Diesmal brauche ich auch Hilfe, allerdings mit Inform6 bzw. Deform.

Ich versuche einen Schreibtisch mit Laden zu programmieren.

Der Schreibtisch selbst ist transparent (damit man die Laden sieht, die als Subobjekte ausgeführt sind) aber kein Container (sollte wahrscheinlich in der finalen Version ein Supporter werden).

Als Subobjekte gibt's lade1 und lade2 als Container (beide sind Container und openable, eine davon lockable und locked).

Mein Problem:

Wenn ich Objekte in die Laden lege (entweder direkt im Objekt-Baum oder durch Move testobjekt to lade1), funtionieren die Laden zwar prinzipiell, aber ich kann das reingelegte Objekt nicht rausnehmen.

(Fehlermeldung lautet ungefähr: Testobjekt scheint ein Teil des Schreibtischs zu sein.)

1) Hat jemand eine Ahnung warum das so ist und kann es mir erklären? (Bei allen anderen Objekten hatte ich keine Probleme, sie zu verschachteln (allerdings bis dahin nicht zweimal)) (Ich denke ja, dass das Attribut transparent transitiv ist (also für den gesamten Unterzweig gilt), aber dann könnte man ja prinzipiell keine aufhebbaren Objekte in transparenten Containern lagern!)

2) Weiß jemand eine Lösung für mein Problem und kann sie mir beschreiben? :-)

Eine Idee hätte ich ja (kann sie aber im Moment leider noch nicht ausprobieren): Statt transparent könnte ich die Laden mit add_to_scope hinzufügen.

Hier noch kurz der Teil-Objekt-Baum zur Veranschaulichung des aktuellen Status:



Object wohnzimmer

(...)

has light neuter;

Object -> schreibtisch

(...)

has scenery transparent male;

Object ->-> lade1

(...)

has static container openable female;

Object ->->-> testobjekt

(...)

has neuter;

Object ->-> lade2

(...)

has static container lockable locked female;```
Geschrieben um 19:27 am 16.02.2010 | Zitat | Editieren | Löschen
ChristianB
Mitglied
Retired Gumby
Beiträge: 1062

Hi Mischa!

Warum die Kinder von Teilen des Schreibtischs auch dazu verdonnert werden, auf ewig beim Schreibtisch zu bleiben, weiß ich nicht. Aber man kann die Sippenhaft ganz einfach auflösen, so zum Beispiel (muss nicht mit einer Klasse sein, ich hatte es so nur für alle Laden ausprobiert):



  with  name 'lade' 'schublade' 'schieblade' 'fach' 'n.',

        react_before [;

            Take, Remove:

                if (parent(noun) == self) {

                    move noun to player;

                    ! ohne Rücksicht auf ein mögliches Limit

                    ! des Spieler-Inventars

                    "Du nimmst ", (den) noun, " aus ", (dem) self, ".";

                }

     ],

   has  female container;

[...]

Lade ->-> lade1 "ober@00 Schublade"

  with  name 'ober'

has openable;

Object ->->-> testobjekt "Testobjekt"

  with   name 'testobjekt',

    has  neuter;```

Viele Grüße,

Christian
Geschrieben um 14:20 am 17.02.2010 | Zitat | Editieren | Löschen
Mischa
Mitglied
Master Gumby
Beiträge: 107

Danke Christian!

Funktioniert perfekt!

Jetzt wäre nur noch der Grund für das komische Verhalten interessant...

Geschrieben um 00:33 am 18.02.2010 | Zitat | Editieren | Löschen
ChristianB
Mitglied
Retired Gumby
Beiträge: 1062

Mischa:

Jetzt wäre nur noch der Grund für das komische Verhalten interessant...

Ich habe den Grund gefunden: In unseren Test-Beispielen war der Schreibtisch (wie Du ja auch schon angemerkt hattest) nicht als supporter definiert. Und da gibt es in der Routine ObjectIsUntouchable() in verblibm.h (Zeile 1532) [deform 2010-01-31] eine klare Beschränkung:

if (flag2 && i hasnt container && i hasnt supporter) ...

Alle Kinder von Objekten, die keine Behälter oder Ablagen sind, können nicht so einfach berührt werden. Macht auch Sinn.

Also, wenn Du den Schreibtisch doch noch zu einer Ablage machst, wird eine react_before-Eigenschaft überflüssig.

Grüße,

Christian

Geschrieben um 11:25 am 18.02.2010 | Zitat | Editieren | Löschen
Martin
Avatar
Mitglied
Prof Gumby
Beiträge: 634

Mischa:

Statt transparent könnte ich die Laden mit add_to_scope hinzufügen.

Das ist, denke ich, die saubere Lösung. Es gibt da die Übung 104 im Designers' Manual, in der eine Sterilisiermaschine mit angehängtem Knopf und mit Ablage implementiert wird. Diese Lösung hat allerdings auch einige Nachteile:

Zunächst gibt es noch einen Bug, der sowohl in deform als auch in der englischen 6/11 zu finden ist: Ein Unterobjekt, das mit add_to_scope an andere Objekte angehängt wird, sollte nicht im Objektbaum auftauchen und hat daher keine Mutter. Dann kommt es aber zu einem "Programming Error", wenn man nun den Knopf nimmt. Die Ablage auf der Maschine hat kein Vokabular und existiert nur für die umgelenkten Aktionen. Das ist ein Bug in der Lib, aber man kann ihn umgehen, indem man das Nehmen explizit abfängt.

Inform unterscheidet zwar zwischen ##Insert und ##PutOn (das über die Variable receive_action auch an ##Receive weitergegeben wird), aber nicht zwischen dem Herunter- und Herausnehmen, das beides zu ##Remove wird. Das ist meistens in Ordnung, da Inform es nicht erlaubt, dass ein Objekt supporter und container gleichzeitig ist, aber es verhindert hier, dass ich etwas von der Maschine herunternehmen kann. Wenn ein Bericht auf der Maschine liegt, geht "take report", aber "take report from machine" geht nicht, es erzeugt sogar den etwas blöden Fehler "You can't see any such thing." Natürlich wird jeder faule Tipper nur "take report" sagen, aber "take all from machine" geht eben auch nicht.

Also:


 Object -> Schreibtisch "Schreibtisch"

   with name 'tisch' 'schreibtisch' 'solide' 'abgewetzt',

        open_drawer nothing,

        description [;

            print "Ein etwas abgewetzter, aber solider Schreibtisch

                steht in der Mitte des Raums. An der rechten Seite

                sind drei Schubladen.^";

            self.describe();

        ],

        describe [ d;

            d = self.open_drawer;

            if (children(self)) {

                new_line;

                <Search self>;

            }

            if (d && children(d)) {

                new_line;

                <Search d>;

            }

            rtrue;

        ],

        before [ d;

            Receive:

                if (receive_action == ##Insert) {

                    d = self.open_drawer;

                    if (d == nothing) {

                        "Sage bitte, ob du ", (den) noun, " in

                        die obere, die mittlere oder die

                        untere Schublade  legen willst.";

                    }

                    print "(in ", (den) d, "^)";

                    <<Insert noun d>>;

                }

        ],

        add_to_scope

            Obere_Schublade Mittlere_Schublade Untere_Schublade,

    has static supporter enterable male;

 Object -> -> Telefon "Telefon" ...

   

  Class Schublade

   with name 'schublade' 'lade'

           'schubfach' 'n.' 'fach' 'n.',

        short_name [;

            print (address) self.&name-->0, "@00 Schublade";

            if (action == ##Search) {

                print " des Schreibtischs";

            }

            rtrue;

        ],

        before [ d;

            Take:

                L__M(##Take, 11, noun);

                rtrue;

            Open:

                d = Schreibtisch.open_drawer;

                if (d && d ~= self) {

                    print "(Du machst zuerst ",

                        (den) d, " zu.)^";

                    keep_silent = true;

                    <Close d>;

                    keep_silent = false;

                    if (d has open) rtrue;

                }

            Receive:

                if (self hasnt open) {

                    print "(Du machst zuerst ",

                        (den) self, " auf.)^";

                    keep_silent = true;

                    <Open self>;

                    keep_silent = false;

                    if (self hasnt open) rtrue;

                }

        ],

        after [;

            Open:

                Schreibtisch.open_drawer = self;

            Close:

                Schreibtisch.open_drawer = nothing;

        ],

        disambig [;

            Open: rfalse;

            default:

                if (self has open) return 3;

                return 1;

        ],

    has static container openable female;

 Schublade Obere_Schublade

   with name 'ober' 'erst';

 Object -> Luger "Luger" ...

 Schublade Mittlere_Schublade

   with name 'mittler' 'zweite';

   

 Object -> Flasche "Flasche" ...

    has female;

 Schublade Untere_Schublade

   with name 'unter' 'dritt' 'letzt';

Es gibt in Deinem Fall übrigens noch eine ganz einfache Lösung: Die Schubladen liegen einfach so im Raum, werden mit scenery in Raumbeschreibungen unterdrückt und können nicht aufgehoben werden. Dass sie eigentlich zum Schreibtisch gehören, bekommt der Spieler nur in den Texten mit. Die Lösung mit add_to_scope benötigt man nur dann, wenn ein Objekt den Raum wechseln kann und entweder supporter oder container sein soll.

ChristianB:

Also, wenn Du den Schreibtisch doch noch zu einer Ablage machst, wird eine react_before-Eigenschaft überflüssig.

Das geht auch und funktioniert so wie mit add_to_scope, wenn man die Schubladen concealed macht. Dass die Raumbeschreibung und die Beschreibung des Tischs korrekt ausgegeben werden muss man dann aber auch von Hand machen.

Mir ist beim Testen der Schreibtischgeschichte aber auch etwas anderes aufgefallen: Irgendwie geht das Nehmen und Ablegen mit "alles" nicht so richtig. Das ist wohl ein Fehler bei den [multi*]-Tokens, der zu eigenartigen Dialogen führt:

frotz:

lege alles in die untere lade

Dort ist aber nichts, das du einfach so nehmen kannst.

nimm alles vom tisch

Ich habe nur Folgendes verstanden: nehmen.

Zu Beginn funktioniert alles, aber wenn es einmal schiefgegangen ist, ist der Wurm drin. Das passiert auch in anderen Beispielen, die nur einfache Behälter ohne add_to_scope haben und ist offenbar schon seit den ersten Versionen von deform drin.

(Und zu guter Letzt muss ich mich wohl von meiner immer wieder gern verbreiteten Aussage trennen, dass deform nie Objekte im Genitiv ausgibt: Die Meldung ##Take 7 - "Die Schublade ist offenbar ein Teil des Tischs" - widerlegt das. Die Ausgaberegeln (des) und (eines) kommen sonst aber nur beim Deklinieren im Debug-Modus vor.)

AntwortenNeues ThemaNeue Umfrage
Powered by Spam Board SVN © 2007 - 2021
Impressum / Datenschutz