Autor |
Nachricht |
< Schreibtisch mit Laden |
|
Verfasst am:
Di, 16 Feb 2010 - 16:42
|
|
|
Abenteurer

Anmeldungsdatum: 05.03.2008
Beiträge: 285
Wohnort: Wien
|
|
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:
Code: |
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; |
|
|
|
|
 |
|
Verfasst am:
Di, 16 Feb 2010 - 18:27
|
|
|
Experte

Anmeldungsdatum: 05.05.2004
Beiträge: 633
Wohnort: Hamburg
|
|
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):
Code: | Class Lade
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 |
|
|
|
 |
|
Verfasst am:
Mi, 17 Feb 2010 - 13:20
|
|
|
Abenteurer

Anmeldungsdatum: 05.03.2008
Beiträge: 285
Wohnort: Wien
|
|
Danke Christian!
Funktioniert perfekt!
Jetzt wäre nur noch der Grund für das komische Verhalten interessant... |
|
|
|
 |
|
Verfasst am:
Mi, 17 Feb 2010 - 23:33
|
|
|
Experte

Anmeldungsdatum: 05.05.2004
Beiträge: 633
Wohnort: Hamburg
|
|
Mischa hat folgendes geschrieben: | 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:
Code: | 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 |
|
|
|
 |
|
Verfasst am:
Do, 18 Feb 2010 - 10:25
|
|
|
Experte

Anmeldungsdatum: 25.08.2002
Beiträge: 677
Wohnort: München
|
|
Mischa hat folgendes geschrieben: | 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:
Code: |
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 hat folgendes geschrieben: | 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 hat folgendes geschrieben: |
>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.) _________________ Every silver lining has a cloud. |
|
|
|
 |
|
|
Alle Zeiten sind GMT + 1 Stunde (MEZ) |
|
Du kannst keine Beiträge in dieses Forum schreiben. Du kannst auf Beiträge in diesem Forum nicht antworten. Du kannst deine Beiträge in diesem Forum nicht bearbeiten. Du kannst deine Beiträge in diesem Forum nicht löschen. Du kannst an Umfragen in diesem Forum nicht mitmachen.
|
|