Vereinigung von examine und sense_exa
Die unterschiedlichen Funktionen fuer Untersuchen per Sicht
und der anderen Sinne wurden vereinigt.
Ausserdem:
Code aufgeraeumt, viele neue und bessere Kommentare,
Code vereinfacht, einige Bugs entfernt (z.B. doppelte
Meldungen, wenn man nix sehen kann), Code in
ueberschaubarere Funktionen gesplittet.
look_into ("schau in") benutzt find_objects aus
put_and_get zum Finden von Objekten.
Change-Id: I1d2863ac3b347eba93a976293d6a04de82b8e0d5
diff --git a/std/player/viewcmd.c b/std/player/viewcmd.c
index 5d7e618..4dce807 100644
--- a/std/player/viewcmd.c
+++ b/std/player/viewcmd.c
@@ -10,13 +10,7 @@
#pragma no_clone
#pragma pedantic
-#define NEED_PROTOTYPES
-#include "/sys/thing/properties.h"
-#include "/sys/living/put_and_get.h"
-#include "/sys/living/description.h"
-
-#include <container.h>
-#include <player.h>
+//#include <player.h>
#include <properties.h>
#include <rooms.h>
#include <wizlevels.h>
@@ -24,9 +18,17 @@
#include <moving.h>
#include <new_skills.h>
#include <ansi.h>
-
+#include <notify_fail.h>
#include <sys_debug.h>
+#define NEED_PROTOTYPES
+#include <container.h>
+#include <thing/properties.h>
+#include <living/put_and_get.h>
+#include <living/description.h>
+#include <living/put_and_get.h>
+#include <player/command.h>
+
varargs mixed More(string str, int fflag, string returnto);
void create()
@@ -230,195 +232,9 @@
return 1;
}
-private nosave int exa_cnt;
-private nosave int exa_time;
-private nosave string *exa;
-
-varargs int _examine(string str, int mode)
+private int select_sense(string str)
{
- object base, *objs, env;
- string what, detail, parent, out, error;
- int i, size, done;
-
- if(CannotSee()) return 1;
-
- _notify_fail("Was willst Du denn untersuchen?\n");
- if (!str) return 0;
-
- if (member(({"boden","decke","wand","waende"}),old_explode(str," ")[0]) == -1) {
- exa_cnt -= (time() - exa_time)/2;
- exa_time = time();
- exa_cnt++;
- if (!exa)
- exa = ({ str });
- else
- exa += ({ str });
- if (exa_cnt > 10) {
- log_file("ARCH/LOOK",
- sprintf("%s: %s in %s\n%@O\n",dtime(time()),getuid(this_object()),
- environment() ? object_name(environment()) : "???",exa), 150000);
- exa_cnt = 0;
- exa = ({});
- }
- else if (exa_cnt < 0) {
- exa_cnt = 0;
- exa = ({});
- }
- }
- // do we look at an object in our environment ?
- if (sscanf(str,"%s in raum", what) || sscanf(str,"%s im raum", what))
- base = environment();
- // is the object inside of me (inventory)
- else if (sscanf(str,"%s in mir", what) || sscanf(str,"%s in dir", what))
- base = this_object();
- else {
- what = str;
- // get the last object we looked at
- base = QueryProp(P_REFERENCE_OBJECT);
-
- // if a reference object exists, test for its existance in the room
- // or in our inventory
- if (objectp(base))
- {
- if (base == environment() || base==this_object())
- {
- // Umgebung oder Spieler selber sind als Bezugsobjekt immer in
- // Ordnung, nichts machen.
- }
- // Das Referenzobjekt darf nicht unsichtbar sein.
- else if (!base->short())
- base = 0;
- else if(member(deep_inventory(environment()), base) != -1)
- {
- foreach(env : all_environment(base)) {
- // Ist eine Umgebung Living oder intransparenter Container oder
- // unsichtbar?
- if (living(env) || !env->QueryProp(P_TRANSPARENT)
- || !env->short())
- {
- // in dem Fall ist ende, aber wenn das gefundene Env nicht
- // dieses Living selber oder sein Env ist, wird das
- // Referenzobjekt zusaetzlich genullt.
- if (env != this_object() && env != environment())
- base = 0;
- break;
- }
- }
- }
- else
- base = 0; // nicht im Raum oder Inventory
- }
- }
-
- // scan input if we want a specific object to look at
- if(sscanf(what, "%s an %s", detail, parent) == 2 ||
- sscanf(what, "%s am %s", detail, parent) == 2 ||
- sscanf(what, "%s in %s", detail, parent) == 2 ||
- sscanf(what, "%s im %s", detail, parent) == 2)
- {
- // if an ref object exists get its inventory. (Oben wurde sichergestellt,
- // dass das Referenzobjekt einsehbar ist)
- if(base)
- objs = base->locate_objects(parent, 1) || ({});
- else {
- // else get our inv and env
- objs = environment()->locate_objects(parent, 1)
- + locate_objects(parent, 1);
- }
- objs = filter_objects(objs, "short"); // nur sichtbare...
- if(sizeof(objs) > 1)
- return (notify_fail("Es gibt mehr als eine(n) "+capitalize(parent)+".\n"), 0);
- else
- {
- if (sizeof(objs))
- base = objs[0];
- else
- return (notify_fail("Hier ist kein(e) "+capitalize(parent)+".\n"), 0);
- }
- objs = 0;
- }
- else detail = what;
-
- int base_was_env = 1;
- do {
- // if a base exists get its inventory, else get our inv and env
- if (base)
- {
- if (base == this_object() || base == environment() ||
- (base->QueryProp(P_TRANSPARENT) && !living(base)))
- {
- // ich kann in base reingucken...
- objs = base->locate_objects(detail, 1) || ({});
- }
- else
- {
- // Referenzobjekt da, aber nicht reinguckbar. base aber nicht nullen,
- // denn es ist ja noch gueltig fuer Detailsuchen an base...
- objs = ({});
- }
- }
- else
- {
- objs = environment()->locate_objects(detail, 1)
- + locate_objects(detail, 1);
- base = environment();
- }
- objs = filter_objects(objs, "short"); // nur sichtbare...
-
- if(!sizeof(objs))
- {
- // wenn keine Objekte gefunden wurden, wird nach Details gesucht...
- if((out = base->GetDetail(detail, QueryProp(P_REAL_RACE),SENSE_VIEW)) ||
- (out = base->GetDoorDesc(detail)))
- {
- SetProp(P_REFERENCE_OBJECT, base);
- return (write(out), 1);
- }
- else
- {
- // wenn auch keine Details gefunden, dann schauen, ob Ende ist
- // (base==env) oder wir evtl. noch im env suchen koennen.
- if (base == environment())
- {
- if (base_was_env) {
- // in diesem Fall war das Env das Bezugsobjekt - daher wegwerfen.
- SetProp(P_REFERENCE_OBJECT, 0);
- _notify_fail("Sowas siehst Du da nicht!\n");
- }
- else {
- _notify_fail("Sowas siehst Du auch da nicht!\n");
- // in diesem Fall war nicht das Env das Bezugsobjekt - es soll
- // behalten und nicht geloescht werden.
- }
- return 0;
- }
- else {
- base_was_env=0;
- write(break_string("Du findest an "+base->name(WEM)
- +" kein \"" + capitalize(detail) + "\"."
- " Dein Blick wendet sich der Umgebung zu.",78));
- base = 0;
- }
- }
- }
- else // Objekte gefunden!
- done = 1;
- } while(!done);
-
- // Es muss min. ein (sichtbares) Objekt geben, sonst waere man hier nicht
- // hingekommen.
- object ob = objs[0];
- SetProp(P_REFERENCE_OBJECT, ob);
- tell_object(ME, ob->long(mode));
- return 1;
-}
-
-varargs int _sense_exa(string str)
-{
- object base, *objs, env;
- string what, detail, parent, out, error;
- int sense;
-
+ int sense = -1;
if(member(({"riech","rieche","schnupper","schnuppere"}),query_verb())!=-1)
{
_notify_fail("Du kannst nichts Besonderes riechen.\n");
@@ -427,8 +243,10 @@
else if(member(({"lausche","lausch","hoer","hoere"}),query_verb())!=-1)
{
if(QueryProp(P_DEAF))
- return notify_fail("Du bist taub!\n"), 0;
-
+ {
+ notify_fail("Du bist taub!\n");
+ return -1;
+ }
_notify_fail("Du kannst nichts Besonderes hoeren.\n");
sense = SENSE_SOUND;
}
@@ -450,50 +268,69 @@
{
_notify_fail("Was willst Du lesen?\n");
if ( !str ) // Kein SENSE_DEFAULT zulassen.
- return 0;
- if (this_object()->CannotSee()) {
- notify_fail("Du kannst nichts sehen!\n");
- return 0;
+ return -1;
+ if (CannotSee(1)) {
+ notify_fail("Du kannst nichts sehen!\n", NF_NL_MAX);
+ return -1;
}
sense = SENSE_READ;
}
-
- if (!str) {
- if(!detail =
- environment()->GetDetail(SENSE_DEFAULT,QueryProp(P_REAL_RACE),sense))
- return 0;
- write(detail);
- return 1;
+ // else ist normales Sehen/untersuchen
+ else
+ {
+ if (CannotSee(1)) {
+ notify_fail("Du kannst nichts sehen!\n", NF_NL_MAX);
+ return -1;
+ }
+ _notify_fail("Was willst Du denn untersuchen?\n");
+ if (!str) return -1;
+ sense = SENSE_VIEW;
}
- else if(sscanf(str,"an %s",what)==1)
- str=what;
+ // "rieche an ..." etc.: das an rausschneiden, wird nicht gebraucht.
+ if (sizeof(str))
+ {
+ if (sense!=SENSE_VIEW)
+ {
+ string what;
+ if (sscanf(str,"an %s",what)==1) str=what;
+ }
+ }
+ return sense;
+}
+
+private object get_ref_object(string str, string what)
+{
+ object ref_object;
// do we look at an object in our environment ?
if (sscanf(str,"%s in raum", what) || sscanf(str,"%s im raum", what))
- base = environment();
+ ref_object = environment();
// is the object inside of me (inventory)
else if (sscanf(str,"%s in mir", what) || sscanf(str,"%s in dir", what))
- base = this_object();
- else {
+ ref_object = this_object();
+ else
+ {
+ // ansonsten ist das argument komplett der suchstring und wir nehmen das
+ // Referenzobjekt (so existent).
what = str;
// get the last object we looked at
- base = QueryProp(P_REFERENCE_OBJECT);
-
+ ref_object = QueryProp(P_REFERENCE_OBJECT);
// if a reference object exists, test for its existance in the room
// or in our inventory
- if (objectp(base))
+ if (objectp(ref_object))
{
- if (base == environment() || base==this_object())
+ if (ref_object == environment() || ref_object==this_object())
{
// Umgebung oder Spieler selber sind als Bezugsobjekt immer in
// Ordnung, nichts machen.
}
// Das Referenzobjekt darf nicht unsichtbar sein.
- else if (!base->short())
- base = 0;
- else if(member(deep_inventory(environment()), base) != -1)
+ else if (!ref_object->short())
+ ref_object = 0;
+ // Nur wenn unser environment()
+ else if(member(deep_inventory(environment()), ref_object) != -1)
{
- foreach(env : all_environment(base)) {
+ foreach(object env : all_environment(ref_object)) {
// Ist eine Umgebung Living oder intransparenter Container oder
// unsichtbar?
if (living(env) || !env->QueryProp(P_TRANSPARENT)
@@ -503,54 +340,139 @@
// dieses Living selber oder sein Env ist, wird das
// Referenzobjekt zusaetzlich genullt.
if (env != this_object() && env != environment())
- base = 0;
+ ref_object = 0;
break;
}
}
}
else
- base = 0; // nicht im Raum oder Inventory
+ ref_object = 0; // nicht im Raum oder Inventory
}
}
+ return ref_object;
+}
- // scan input if we want a specific object to look at
+private object find_base(object ref_object, string what, string detail,
+ string parent)
+{
+ object base;
+ // Suchen wir an/im/in/etc. einem bestimmten Objekt?
if(sscanf(what, "%s an %s", detail, parent) == 2 ||
sscanf(what, "%s am %s", detail, parent) == 2 ||
sscanf(what, "%s in %s", detail, parent) == 2 ||
sscanf(what, "%s im %s", detail, parent) == 2)
{
- // if an ref object exists get its inventory. (Oben wurde sichergestellt,
- // dass das Referenzobjekt einsehbar ist)
-
- if(base)
- objs = base->locate_objects(parent, 1) || ({});
- else
- {
- // else get our inv and env
+ object *objs;
+ // Wenn es ein Referenzobjekt gibt, wird das parent-Objekt in diesem
+ // gesucht. (Oben wurde sichergestellt, dass das Referenzobjekt einsehbar
+ // ist)
+ if(ref_object)
+ objs = ref_object->locate_objects(parent, 1) || ({});
+ // sonst im Environment oder in uns.
+ else {
objs = environment()->locate_objects(parent, 1)
+ locate_objects(parent, 1);
}
objs = filter_objects(objs, "short"); // nur sichtbare...
- if(sizeof(objs) > 1)
- return (notify_fail("Es gibt mehr als eine(n) "+capitalize(parent)+".\n"), 0);
- else
+ switch(sizeof(objs))
{
- if(sizeof(objs))
- base = objs[0];
- else
- return (notify_fail("Hier ist kein(e) "+capitalize(parent)+".\n"), 0);
+ case 0:
+ notify_fail("Hier ist kein(e) "+capitalize(parent)+".\n");
+ return 0;
+ case 1:
+ // Basisobjekt gefunden.
+ base = objs[0];
+ break;
+ default:
+ notify_fail("Es gibt mehr als eine(n) "+capitalize(parent)+".\n");
+ return 0;
}
- objs = 0;
}
- else detail = what;
+ // im anderen fall ist das komplette what das gesuchte detail, was wir am
+ // Referenzobjekt suchen (sofern vorhanden).
+ else
+ {
+ base = ref_object;
+ detail = what;
+ }
+ return base;
+}
- // wie auch immer haben wir jetzt ein Bezugsobjekt.
- int maxtries=3;
+private nosave int exa_cnt;
+private nosave int exa_time;
+private nosave string *exa;
+private void unt_script_dings(string str)
+{
+ // unt-script-sucher
+ if (!sizeof(str)) return;
+ if (member(({"boden","decke","wand","waende"}),old_explode(str," ")[0]) == -1) {
+ exa_cnt -= (time() - exa_time)/2;
+ exa_time = time();
+ exa_cnt++;
+ if (!exa)
+ exa = ({ str });
+ else
+ exa += ({ str });
+ if (exa_cnt > 10) {
+ log_file("ARCH/LOOK",
+ sprintf("%s: %s in %s\n%@O\n",dtime(time()),getuid(this_object()),
+ environment() ? object_name(environment()) : "???",exa), 150000);
+ exa_cnt = 0;
+ exa = ({});
+ }
+ else if (exa_cnt < 0) {
+ exa_cnt = 0;
+ exa = ({});
+ }
+ }
+}
+
+varargs int _examine(string str, int mode)
+{
+ // Sinn auswaehlen, der benutzt wird. Wenn -1, abbrechen (kein Sinn bzw.
+ // Sinn erlaubt ggf. kein leeren <str> fuer Defaulmeldung). Je nach Sinn
+ // wird auch <str>modifiziert.
+ int sense=select_sense(&str);
+ if (sense<0) return 0;
+
+ unt_script_dings(str);
+
+ // Wenn kein str, dann SENSE_DEFAULT vom Environment ausgeben. Bei
+ // SENSE_VIEW wurde das bereits bei den Aufrufern dieser Funktion gemacht.
+ if (sense!=SENSE_VIEW)
+ {
+ if (!str)
+ {
+ string detail = environment()->GetDetail(SENSE_DEFAULT,
+ QueryProp(P_REAL_RACE),sense);
+ if(!detail)
+ return 0;
+ write(detail);
+ return 1;
+ }
+ }
+
+ // Das Ref-Objekt finden, das kann dann auch in <what> angeben sein. In dem
+ // Fall wird <what> um die Angabe des Ref-Objekts gekuerzt.
+ string what;
+ object ref_object = get_ref_object(str, &what);
+
+ // Sodann ein Basisobjekt finden. Das Basisobjekt ist das, was bei einem
+ // "detail an parent" durch parent gekennzeichnet wird oder notfalls das
+ // Ref-Objekt von oben.
+ string detail, parent; // detail an parent
+ object base; // das fuer parent gefundene objekt
+ base = find_base(ref_object, what, &detail, &parent);
+
+ // Jetzt wird versucht, ein Objekt mit der ID "detail" in base (parent) oder
+ // ein Detail an base zu finden. Die Schleife laeuft ggf. zweimal. Wenn im
+ // ersten Durchlauf nichts gefunden wird, wird ggf. noch die Umgebung in
+ // einem zweiten Durchlauf anguckt.
+ int first_base_was_env = (!base || base==environment() ? 1 : 0);
do {
- int base_was_env=1;
- // als ersten werden in Frage kommende Objekte gesucht. Wenn base
- // existiert (idR nur im ersten Durchlauf), wird dort gesucht, sonst in
- // Env und Inv.
+ object *objs;
+ // Wenn base existiert und wir reingucken koennen, ermitteln wir alle zu
+ // detail in Frage kommenanden Objekte in seinem Inventar
if (base)
{
if (base == this_object() || base == environment() ||
@@ -561,19 +483,25 @@
}
else
{
- // Referenzobjekt da, aber nicht reinguckbar. base aber nicht nullen,
- // denn es ist ja noch gueltig fuer Detailsuchen an base...
+ // Basisobjekt da, aber nicht reinguckbar, also keine Objekte
+ // gefunden. base aber nicht nullen, denn es ist ja noch gueltig fuer
+ // Detailsuchen an base...
objs = ({});
}
}
+ // Wenn nicht, werden alle fuer detail in Frage kommenden Objekt in
+ // unserer Umgebung und in uns selber ermittelt.
else
{
+ base = environment();
objs = environment()->locate_objects(detail, 1)
+ locate_objects(detail, 1);
- base = environment();
}
+ // Und in jedem Fall werden alle Objekt raussortiert, die unsichtbar sind.
+ // ;-)
objs = filter_objects(objs, "short"); // nur sichtbare...
+ // Wenn es sichtbare gibt, werden die ggf. angeguckt.
if (sizeof(objs))
{
// Objekte gefunden, mal schauen, ob die taugen (d.h. fuer den jew. Sinn
@@ -581,7 +509,12 @@
// Aber erstmal die Objekte durchlaufen.
foreach(object ob: objs)
{
- if (sense == SENSE_READ)
+ string out;
+ if (sense == SENSE_VIEW)
+ {
+ out = ob->long(mode);
+ }
+ else if (sense == SENSE_READ)
{
// Extrawurst: P_READ_MSG auch noch abfragen.
out = ob->QueryProp(P_READ_MSG);
@@ -590,6 +523,7 @@
}
else
out=ob->GetDetail(SENSE_DEFAULT,QueryProp(P_REAL_RACE),sense);
+ // Wenn was gefunden wurde, sind wir fertig.
if (stringp(out))
{
SetProp(P_REFERENCE_OBJECT, ob);
@@ -598,47 +532,70 @@
}
}
}
-
- // Keine Objekte gefunden, die in Frage kommen. Nach Details suchen.
- if(out = base->GetDetail(detail, QueryProp(P_REAL_RACE),sense))
+ // offenbar keine Objekte gefunden oder die hatten nix fuer unseren Sinn
+ // dabei. Also nach ordinaeren Details an base/parent suchen.
+ string out = base->GetDetail(detail, QueryProp(P_REAL_RACE), sense);
+ if (!out && sense==SENSE_VIEW)
+ out = base->GetDoorDesc(detail);
+ if (out)
{
+ // Detail gefunden, base darf neues Referenzobjekt werden und nach
+ // Ausgabe sind wir fertig.
SetProp(P_REFERENCE_OBJECT, base);
- return (write(out), 1);
+ write(out);
+ return 1;
}
else
{
- // Auch keine Details gefunden... Wenn wir uns noch das Env angucken
- // koennen (weil base != env), dann machen wir das, ansonsten ist
- // jetzt hier leider Ende...
- if(base == environment())
+ // wenn auch keine Details gefunden, dann schauen, unser Env evtl.
+ // noch nen passendes Detail oder Objekt hat. Das ist aber natuerlich
+ // nur der Fall, wenn base nicht eh schon das Environment ist.
+ if (base != environment())
{
- if (base_was_env)
- SetProp(P_REFERENCE_OBJECT, 0);
- return 0;
+ // Wir schauen uns das Env noch an. Bei den anderen Sinnen kein neues
+ // notify_fail, weil sonst staendig Meldungen kommen, dass x nicht da
+ // ist, nur weil es keine Beschreibung fuer den Sinn hat.
+ if (sense==SENSE_VIEW)
+ write(break_string("Du findest an "+base->name(WEM)
+ +" kein \"" + capitalize(detail) + "\"."
+ " Dein Blick wendet sich der Umgebung zu.",78));
+ // in diesem Fall nullen wir base und lassen die Schleife noch
+ // einmal durchlaufen.
+ base = 0;
+ continue;
}
+ // Leider ist nix mehr uebrig zum angucken und in jedem Fall Ende.
else
{
- // nochmal im naechsten Schleifendurchlauf ohne base probieren.
- base = 0;
- base_was_env = 0;
+ // Wenn schon das erste angeguckte base das Environment war (dann
+ // ist diese Schleife uebrigens nur einmal gelaufen), gibt es eine
+ // leicht andere Meldung und das Bezugsobjekt muss weg.
+ // neue notify_fail gibt es nur fuer SENSE_VIEW (s.o.)
+ if (first_base_was_env) {
+ SetProp(P_REFERENCE_OBJECT, 0);
+ if (sense==SENSE_VIEW)
+ _notify_fail("Sowas siehst Du da nicht!\n");
+ }
+ else if (sense==SENSE_VIEW) {
+ _notify_fail("Sowas siehst Du auch da nicht!\n");
+ }
+ return 0;
}
}
- } while(--maxtries);
-
- // nach dieser Schleife sollte man nie ankommen...
- raise_error(sprintf("_sense_exa(): zuviele Versuche, etwas zu finden."));
-
+ } while(1);
+ // Nie erreicht.
return 0;
}
+// Funktion fuer "schau in ..."
varargs int look_into(string str,int mode)
{
object *found_obs;
if( CannotSee() ) return 1;
- _notify_fail("Wo willst Du denn reinschauen ?\n");
- found_obs=find_obs(str,PUT_GET_NONE);
- if (!found_obs)
+ _notify_fail("Wo willst Du denn reinschauen?\n");
+ found_obs=find_objects(str, 0, 0);
+ if (!sizeof(found_obs))
{
if (environment() &&
(environment()->GetDetail(str,QueryProp(P_REAL_RACE))||
@@ -646,6 +603,7 @@
_notify_fail("Da kannst Du so nicht reinsehen.\n");
return 0;
}
+
return _examine(str, mode);
}
@@ -671,6 +629,8 @@
return env->int_short(ME,ME);
}
+// Kommandofunktion fuer schau.
+// Verzweigt ggf. in _examine() fuers normale Untersuchen.
int _look(string str)
{
string s;
@@ -678,6 +638,8 @@
if(CannotSee()) return 1;
+ // nur schau mit ggf. Flags entsorgt das Ref-Objekt und schaut die
+ // Raumbeschreibung an.
if(!str)
{
SetProp(P_REFERENCE_OBJECT, 0);
@@ -696,6 +658,9 @@
write( env_descr(1,2,1) );
return 1;
}
+ // Ansonsten wird in _examine() weitergemacht, wobei Flags vorher
+ // rausgeschnitten werden. _examine() benutzt die Flags, falls es eine
+ // Langbeschreibung eines Objektes ausgeben wird.
if(str[0..2]=="-f "){
flag=2;
str=str[3..];
@@ -705,9 +670,12 @@
str=str[6..];
}
else flag = 0;
+
if (sscanf(str,"%s an",s)) str=s;
+ // "in mir", "in dir" soll in _examine rein, aber "in ..." in look_into().
if (sscanf(str,"%s in mir",s)||sscanf(str,"%s in dir",s)) return _examine(str,flag);
if (sscanf(str,"in %s",s)) return look_into(s,flag);
+ // Alles andere weiter an _examine().
return _examine(str,flag);
}
@@ -733,20 +701,20 @@
({"untersuche","_examine",0,0}),
({"betrachte","_examine",0,0}),
({"betr","_examine",0,0}),
- ({"lausche","_sense_exa",0,0}),
- ({"lausch","_sense_exa",0,0}),
- ({"hoer","_sense_exa",0,0}),
- ({"hoere","_sense_exa",0,0}),
- ({"lies","_sense_exa",0,0}),
- ({"lese","_sense_exa",0,0}),
- ({"les","_sense_exa",0,0}),
- ({"schnupper","_sense_exa",0,0}),
- ({"schnuppere","_sense_exa",0,0}),
- ({"riech","_sense_exa",0,0}),
- ({"rieche","_sense_exa",0,0}),
- ({"taste","_sense_exa",0,0}),
- ({"beruehre","_sense_exa",0,0}),
- ({"beruehr","_sense_exa",0,0}),
+ ({"lausche","_examine",0,0}),
+ ({"lausch","_examine",0,0}),
+ ({"hoer","_examine",0,0}),
+ ({"hoere","_examine",0,0}),
+ ({"lies","_examine",0,0}),
+ ({"lese","_examine",0,0}),
+ ({"les","_examine",0,0}),
+ ({"schnupper","_examine",0,0}),
+ ({"schnuppere","_examine",0,0}),
+ ({"riech","_examine",0,0}),
+ ({"rieche","_examine",0,0}),
+ ({"taste","_examine",0,0}),
+ ({"beruehre","_examine",0,0}),
+ ({"beruehr","_examine",0,0}),
({"kurz","_toggle_brief",0,0}),
({"lang","_toggle_brief",0,0}),
({"ultrakurz","_toggle_brief",0,0})
diff --git a/sys/living/put_and_get.h b/sys/living/put_and_get.h
index 802ad23..8d00300 100644
--- a/sys/living/put_and_get.h
+++ b/sys/living/put_and_get.h
@@ -27,6 +27,7 @@
#ifndef __LIVING_PUT_AND_GET_H_PROTO__
#define __LIVING_PUT_AND_GET_H_PROTO__
+object *find_objects(string what, object env, int is_source);
object *find_obs(string str, int meth);
void add_put_and_get_commands();