tmi2_fluffos_v2/
tmi2_fluffos_v2/bin/
tmi2_fluffos_v2/etc/
tmi2_fluffos_v2/fluffos-2.7-ds2.018/
tmi2_fluffos_v2/fluffos-2.7-ds2.018/ChangeLog.old/
tmi2_fluffos_v2/fluffos-2.7-ds2.018/Win32/
tmi2_fluffos_v2/fluffos-2.7-ds2.018/compat/
tmi2_fluffos_v2/fluffos-2.7-ds2.018/compat/simuls/
tmi2_fluffos_v2/fluffos-2.7-ds2.018/include/
tmi2_fluffos_v2/fluffos-2.7-ds2.018/testsuite/
tmi2_fluffos_v2/fluffos-2.7-ds2.018/testsuite/clone/
tmi2_fluffos_v2/fluffos-2.7-ds2.018/testsuite/command/
tmi2_fluffos_v2/fluffos-2.7-ds2.018/testsuite/data/
tmi2_fluffos_v2/fluffos-2.7-ds2.018/testsuite/etc/
tmi2_fluffos_v2/fluffos-2.7-ds2.018/testsuite/include/
tmi2_fluffos_v2/fluffos-2.7-ds2.018/testsuite/inherit/
tmi2_fluffos_v2/fluffos-2.7-ds2.018/testsuite/inherit/master/
tmi2_fluffos_v2/fluffos-2.7-ds2.018/testsuite/log/
tmi2_fluffos_v2/fluffos-2.7-ds2.018/testsuite/single/
tmi2_fluffos_v2/fluffos-2.7-ds2.018/testsuite/single/tests/compiler/
tmi2_fluffos_v2/fluffos-2.7-ds2.018/testsuite/single/tests/efuns/
tmi2_fluffos_v2/fluffos-2.7-ds2.018/testsuite/single/tests/operators/
tmi2_fluffos_v2/fluffos-2.7-ds2.018/testsuite/u/
tmi2_fluffos_v2/fluffos-2.7-ds2.018/tmp/
tmi2_fluffos_v2/fluffos-2.7-ds2.018/windows/
tmi2_fluffos_v2/lib/
tmi2_fluffos_v2/lib/adm/
tmi2_fluffos_v2/lib/adm/daemons/languages/
tmi2_fluffos_v2/lib/adm/daemons/network/I3/
tmi2_fluffos_v2/lib/adm/daemons/virtual/
tmi2_fluffos_v2/lib/adm/daemons/virtual/template/
tmi2_fluffos_v2/lib/adm/news/
tmi2_fluffos_v2/lib/adm/obj/
tmi2_fluffos_v2/lib/adm/obj/master/
tmi2_fluffos_v2/lib/adm/priv/
tmi2_fluffos_v2/lib/adm/shell/
tmi2_fluffos_v2/lib/adm/tmp/
tmi2_fluffos_v2/lib/cmds/
tmi2_fluffos_v2/lib/d/
tmi2_fluffos_v2/lib/d/Conf/
tmi2_fluffos_v2/lib/d/Conf/adm/
tmi2_fluffos_v2/lib/d/Conf/boards/
tmi2_fluffos_v2/lib/d/Conf/cmds/
tmi2_fluffos_v2/lib/d/Conf/data/
tmi2_fluffos_v2/lib/d/Conf/logs/
tmi2_fluffos_v2/lib/d/Conf/obj/
tmi2_fluffos_v2/lib/d/Conf/text/help/
tmi2_fluffos_v2/lib/d/Fooland/adm/
tmi2_fluffos_v2/lib/d/Fooland/data/
tmi2_fluffos_v2/lib/d/Fooland/data/attic/
tmi2_fluffos_v2/lib/d/Fooland/items/
tmi2_fluffos_v2/lib/d/TMI/
tmi2_fluffos_v2/lib/d/TMI/adm/
tmi2_fluffos_v2/lib/d/TMI/boards/
tmi2_fluffos_v2/lib/d/TMI/data/
tmi2_fluffos_v2/lib/d/TMI/rooms/
tmi2_fluffos_v2/lib/d/grid/
tmi2_fluffos_v2/lib/d/grid/adm/
tmi2_fluffos_v2/lib/d/grid/data/
tmi2_fluffos_v2/lib/d/std/
tmi2_fluffos_v2/lib/d/std/adm/
tmi2_fluffos_v2/lib/data/adm/
tmi2_fluffos_v2/lib/data/adm/daemons/
tmi2_fluffos_v2/lib/data/adm/daemons/doc_d/
tmi2_fluffos_v2/lib/data/adm/daemons/emoted/
tmi2_fluffos_v2/lib/data/adm/daemons/network/http/
tmi2_fluffos_v2/lib/data/adm/daemons/network/services/mail_q/
tmi2_fluffos_v2/lib/data/adm/daemons/network/smtp/
tmi2_fluffos_v2/lib/data/adm/daemons/news/archives/
tmi2_fluffos_v2/lib/data/attic/connection/
tmi2_fluffos_v2/lib/data/attic/user/
tmi2_fluffos_v2/lib/data/std/connection/b/
tmi2_fluffos_v2/lib/data/std/connection/l/
tmi2_fluffos_v2/lib/data/std/user/a/
tmi2_fluffos_v2/lib/data/std/user/b/
tmi2_fluffos_v2/lib/data/std/user/d/
tmi2_fluffos_v2/lib/data/std/user/f/
tmi2_fluffos_v2/lib/data/std/user/l/
tmi2_fluffos_v2/lib/data/std/user/x/
tmi2_fluffos_v2/lib/data/u/d/dm/working/doc_d/
tmi2_fluffos_v2/lib/data/u/l/leto/doc_d/
tmi2_fluffos_v2/lib/data/u/l/leto/smtp/
tmi2_fluffos_v2/lib/doc/
tmi2_fluffos_v2/lib/doc/driverdoc/applies/
tmi2_fluffos_v2/lib/doc/driverdoc/applies/interactive/
tmi2_fluffos_v2/lib/doc/driverdoc/concepts/
tmi2_fluffos_v2/lib/doc/driverdoc/driver/
tmi2_fluffos_v2/lib/doc/driverdoc/efuns/arrays/
tmi2_fluffos_v2/lib/doc/driverdoc/efuns/buffers/
tmi2_fluffos_v2/lib/doc/driverdoc/efuns/compile/
tmi2_fluffos_v2/lib/doc/driverdoc/efuns/ed/
tmi2_fluffos_v2/lib/doc/driverdoc/efuns/filesystem/
tmi2_fluffos_v2/lib/doc/driverdoc/efuns/floats/
tmi2_fluffos_v2/lib/doc/driverdoc/efuns/functions/
tmi2_fluffos_v2/lib/doc/driverdoc/efuns/general/
tmi2_fluffos_v2/lib/doc/driverdoc/efuns/mappings/
tmi2_fluffos_v2/lib/doc/driverdoc/efuns/numbers/
tmi2_fluffos_v2/lib/doc/driverdoc/efuns/parsing/
tmi2_fluffos_v2/lib/doc/driverdoc/lpc/constructs/
tmi2_fluffos_v2/lib/doc/driverdoc/lpc/preprocessor/
tmi2_fluffos_v2/lib/doc/driverdoc/lpc/types/
tmi2_fluffos_v2/lib/doc/driverdoc/platforms/
tmi2_fluffos_v2/lib/doc/mudlib/
tmi2_fluffos_v2/lib/ftp/
tmi2_fluffos_v2/lib/include/driver/
tmi2_fluffos_v2/lib/log/
tmi2_fluffos_v2/lib/log/driver/
tmi2_fluffos_v2/lib/obj/net/
tmi2_fluffos_v2/lib/obj/shells/
tmi2_fluffos_v2/lib/obj/tools/
tmi2_fluffos_v2/lib/std/adt/
tmi2_fluffos_v2/lib/std/board/
tmi2_fluffos_v2/lib/std/body/
tmi2_fluffos_v2/lib/std/fun/
tmi2_fluffos_v2/lib/std/living/
tmi2_fluffos_v2/lib/std/object/
tmi2_fluffos_v2/lib/std/shop/
tmi2_fluffos_v2/lib/std/socket/
tmi2_fluffos_v2/lib/std/user/
tmi2_fluffos_v2/lib/std/virtual/
tmi2_fluffos_v2/lib/student/
tmi2_fluffos_v2/lib/student/kalypso/
tmi2_fluffos_v2/lib/student/kalypso/armor/
tmi2_fluffos_v2/lib/student/kalypso/rooms/
tmi2_fluffos_v2/lib/student/kalypso/weapons/
tmi2_fluffos_v2/lib/u/l/leto/
tmi2_fluffos_v2/lib/u/l/leto/cmds/
tmi2_fluffos_v2/lib/www/errors/
tmi2_fluffos_v2/lib/www/gateways/
tmi2_fluffos_v2/lib/www/images/
tmi2_fluffos_v2/old/
tmi2_fluffos_v2/win32/
/* File:  /cmds/std/_look.c
   Creator:	Matt. D. Robinson (Yakker/Regret@TMI) 1991
   Updated:	Help added by Brian (1/28/92)
		Rewritten by Adam Beeman (Buddha@TMI) 6/25/92
		Light handling by Steven Schmidt (Mobydick@TMI) 11/9/92
		Contents processing routines, light handling updated,
		   and infravision by Glenn Ferguson (Watcher@TMI) 1/29/93
		Got querying item_desc to work properly if the
		   description was a function by Grendel @ TMI-2,
		   10 August 1993
		Rewritten and door/exit suppression added by Austin H.
		   Ziegler (Fantome@TMI) 11 August 1993

	This code allows a user to "look" in a room, or at a specific
object in the user's inventory or environment.
*/

#include <config.h>
#include <mudlib.h>
#include <daemons.h>

inherit DAEMON;


/* Contents display format flag:
	0 == standard look
	1 == line by line processed
	2 == processed linked together
*/
#define FLAG 1

// prototypes...
string look_in_room (object room, int flag);
varargs string look_at_item (string item, object user, string In);
string look_in_item (string item, object user);
string convert_number (int num);
string process_contents (mixed *inv, int flag);
string content_match (object what);

mixed *number;
object viewingOb, env, it;
#ifndef BLOCK_ATTACK
int Attacking;
#endif

/* cmd_look (string)
  this function 'look's in a room and handles the case of
whether it's just the room or a separate object */
int cmd_look (string str) {
  int oldStatus;   
  string tmp, tmp2;
  mapping exits, doors;
  mixed *hidden_exits, *hidden_doors;
   
  it = 0;
  viewingOb = this_player();
  env = environment (viewingOb);
   
/* standard TMI-2 look blocks for 2 seconds, but I don't like that,
   so we've got another option available on compile-time */
#ifndef BLOCK_ATTACK
  Attacking = ((viewingOb->query_attackers()) ? 1 : 0);
#endif

/* Check to see if we have an argument list.  If we do, see if
we're trying to look at a particular object.  If so, get the
object's description.  Otherwise, ask the room for its description.
*/

  
// are we looking at our immediate environment?
  if (!str || !stringp (str)) {
    // do we have an environment?  If not, write the default message
    if (!env) {
      write ("There is nothing to see here.\n");
#ifdef BLOCK_ATTACK
      viewingOb->block_attack (2);
#endif
      return 1;
    }
/*
This garbles the room description. It's useful for simulating acid
flashbacks among your players. We recommend you not do that too often. :)
write (LANGUAGE_D->garble_string(look_in_room (env, (int)viewingOb->query_temp ("force_to_look")),"orcish")+"\n") ;
*/
    write (look_in_room (env, (int)viewingOb->query_temp ("force_to_look")));
#ifdef BLOCK_ATTACK
    viewingOb->block_attack (2);
#endif
    return 1;
  }

// are we looking at something in a container?
  if (sscanf(str, "at %s in %s", tmp, tmp2) == 2) {
    // we're looking inside a container
    // blocking a look in a locked/opaque container doesn't work yet. -- Fantome
    // hopefully will work soon
#ifndef BLOCK_ATTACK
    if (Attacking) {
      write ("You are too busy to get a detailed look at that!\n");
      return 1;
    }
#endif
    write (sprintf ("%-=75s", look_at_item (tmp, viewingOb, tmp2)));
    return 1;
  }

// are we looking at an object?
  if (sscanf(str, "at %s", tmp)) {
    write (sprintf ("%-=75s", look_at_item (tmp, viewingOb)));
    return 1;
  }
// are we looking in an object?
  if (sscanf(str, "in %s", tmp)) {
#ifndef BLOCK_ATTACK
    if (Attacking) {
      write ("You are too busy to get a detailed look at that!\n");
      return 1;
    }
#endif
    write (sprintf ("%-=75s", look_in_item (tmp, viewingOb)));
    return 1;
  }
// are we looking in the room?
  if (env) {
    exits = env->query ("exits");
    doors = env->query ("doors");
    hidden_exits = env->query ("exit_suppress");
    hidden_doors = env->query ("door_suppress");
    if (mapp (exits) && member_array (str, keys (exits)) != -1) {
      if (doors && doors[str]) {
	if (((!pointerp (hidden_doors) || (int)hidden_doors[0] != 1 ||
		member_array (str, hidden_doors) == -1))
	    && doors[str]["status"] != "open") {
	  write ("The door is closed.\n");
#ifdef BLOCK_ATTACK
	  viewingOb->block_attack(2);
#endif
	  return 1;
	}
      }
      if ((!pointerp (hidden_exits) ||
		member_array (str, hidden_exits) == -1) ||
		(!intp (hidden_exits) || (int)hidden_exits[0] != 1)) {
	env = find_object_or_load (exits[str]);
	write (look_in_room (env, (int)this_player()->query_temp("force_to_look")));
#ifdef BLOCK_ATTACK
	viewingOb->block_attack(2);
#endif
	return 1;
      }
    }
  }
   
  cmd_look (sprintf ("at %s", str));
  return 1;
}

int can_see (object who, object what) {
  int invis;

  if (!(what->query ("short")))
    return 0;
  invis = what->query ("invisible");
  if (!invis)
    return 1; 
  if (invis == 1 && wizardp (who))
    return 1;
  if (invis == 2 && adminp(who->query ("name")))
    return 1;
  return 0;
}

int can_see2 (object what, object who) {
  return can_see (who, what);
}

string living_description (object ob) {
  object *inv;
  int i;
  string a1, a2, tmp, reg, race, raceat, short, gender, genat;
   
  reg = (string)ob->query ("long");
  if (!reg)
    reg = "";
   
  race = (string)ob->query ("race");
  raceat = article (race) + " " + race;
  gender = (string)ob->query ("gender");
  genat = ((viewingOb == ob) ? "You are"
			      : capitalize (subjective (gender)) + " is");
  
  i = sizeof (inv = all_inventory(ob));
  while (i--)
    if (tmp = inv[i]->query ("extra_look")) {
      while (sscanf(tmp, "%s$N%s", a1, a2) > 1)
        tmp = sprintf ("%s%s%s", a1, ob->query ("cap_name"), a2);
      reg += tmp;
    }

  if (stringp (race) && race != "")
    reg = sprintf ("%s%s %s.\n", reg, genat, raceat);
   
#ifndef BLOCK_ATTACK
  if (!Attacking) {
#endif
  inv = filter_array (inv, "can_see2", this_object(), viewingOb);
  i = sizeof (inv);
  if (i) {
    reg = sprintf ("%s %s carrying:\n", reg, genat);
    while (i--) {
      short = (string)inv[i]->query ("short");
      if (short)
	reg = sprintf ("%s  %s%s%s.\n", reg, short,
		(inv[i]->query ("equipped") ? " (equipped)" : ""),
		(inv[i]->query ("wielded") ? " (wielded)" : ""));
    }
  } else
    reg = sprintf ("%s%s empty handed.\n", reg, genat);
#ifndef BLOCK_ATTACK
  }
#endif
  return reg;
}

varargs
string item_description (string str, object user, int infra, string In) {
  object inob;
  mapping items, doors;
  string tmp, ret, dir, foo;
     
  if (str == "me")
    str = (string)viewingOb->query ("name");
   
  if (str == "door" || (str && sscanf(str, "%s door", dir))) {
#ifndef BLOCK_ATTACK
    if (Attacking)
      return "You are too busy to get a detailed look at that!\n";
#endif
    if (user && environment (user))
      doors = environment (user)->query ("doors");
    if(!doors || !sizeof(doors))
      return "You don't see any doors here.\n";
      
    if (!dir) {
      if (sizeof (doors) > 1)
	return "Which door do you wish to look at?\n";
      dir = keys (doors)[0];
    }
      
    if (infra)
      return "That door gives off no heat pattern.\n";
      
    if (!doors[dir])
      return sprintf ("There is no door in the %s direction.\n", dir);

    if (!doors[dir]["desc"])
      tmp = "";
    else
      tmp = sprintf ("%s.\n", capitalize(doors[dir]["desc"]));
      
    if (doors[dir]["status"])
      tmp = sprintf ("%sThe %s door is %s.\n", tmp, dir, doors[dir]["status"]);
      
#ifdef BLOCK_ATTACK
    viewingOb->block_attack (2);
#endif
    if (!tmp || tmp == "")
      return sprintf ("There is nothing special about the %s door.\n", dir);
    else
      return tmp;
  }
   
#ifndef BLOCK_ATTACK
  if (!Attacking) {
#endif
  if (In) {
    inob = present (In, user);
    if (!inob && env)
      inob = present (In, env);
    if (inob) {
      it = present (str, inob);
      if ((int)inob->query_is_closed() && (int)inob->query ("opaque"))
	return "Just how do you propose looking in a closed container?\n";
    }
  }
#ifndef BLOCK_ATTACK
  }
#endif
  if (!it)
    it = present (str, user);
#ifndef BLOCK_ATTACK
  if (!Attacking) {
#endif
  if (!it && env)
    it = present(str, env);
#ifndef BLOCK_ATTACK
  }
#endif
   
  if (it && !can_see (viewingOb, it))
    return "I don't see that here.\n";
   
  if (infra && it && objectp(it))
    if (living (it) || it->query ("hot"))
      return "Your infravision shows a bright heat pattern.\n";
    else
      return "Your infravision shows no heat pattern.\n";
   
  if (it) {
    if (living (it))
      ret = living_description (it);
    else
      ret = (string)it->query ("long");
  } else {
#ifndef BLOCK_ATTACK
    if (Attacking)
      return "You are too busy to get a detailed look at that!\n";
#endif
    if (env) {
/* okay, this is the way to get things built into the room.
   assuming that we _can_ look at objects, check for room-defined
   dummy items.  Fix to item_desc of @@fun by Grendel.*/
      tmp = env->query ("item_desc/" + str);
      if (tmp)
	ret = tmp;
      if (!ret) {
        tmp = env->query ("item_func/" + str);
	if (tmp) {
	  (string)call_other (env, tmp);
#ifdef BLOCK_ATTACK
	  viewingOb->block_attack (2);
#endif
	  return "";
	}
      }
    } else
      return "There is nothing to see here.\n";
  }

  if (!ret || ret == "")
    return "I don't see that here.\n";

  if (it) {
    if (it != viewingOb) {
      if (living (it))
	message ("tell_object",
		sprintf ("%s looks at you.\n", user->query ("cap_name")),
		it);
      foo = it->query("cap_name");
      if (!foo)
	foo = it->query("short") ;
      if (!foo)
	foo = "something";
    } else
      foo = sprintf ("%sself", objective ((string)viewingOb->query ("gender")));
      
    message ("say", sprintf ("%s looks at %s.\n", user->query ("cap_name"),
		(living (it) ? foo : lower_case (foo))), environment (user),
		({ user, it }));
  } else
    message ("say", sprintf ("%s looks at %s.\n", user->query ("cap_name"),
		str), environment (user), user);
#ifdef BLOCK_ATTACK
  viewingOb->block_attack (2);
#endif
  return ret;
}

varargs string look_at_item (string str, object user, string In) {
//Check if the user is blind.
  if ((int)user->query ("blind"))      
    return "You are blind and cannot see.\n";
   
//Check to see if the user can see.
  if ((int)user->query ("vision"))
    if (!undefinedp (In))
      return item_description (str, user, 0, In);
    else
      return item_description (str, user, 0);
   
//Check to see if user has infravision capabilities
  if ((int)user->query("infravision"))
    if (!undefinedp (In))
      return item_description (str, user, 1, In);
    else
      return item_description (str, user, 1);
   
//Guess there is no light here, then.
  return "It is dark and you can't see a thing.\n";
}

string lit_room_description(object room, int infra, int flag);

varargs string look_in_room (object room, int flag) {
//Check to see if the user is blind
  if (viewingOb->query("blind"))
    return "You are blind and cannot see.\n";

//Check to see if the room can be seen.
  if (room->query("no_vision"))
    return (string)room->query("no_vision") ;
   
//Check to see if the user can see within the room.
  if (viewingOb->query ("vision"))
    return lit_room_description (room, 0, flag);
   
//Check to see if the user has infravision
  if (viewingOb->query("infravision"))
    return lit_room_description (room, 1, flag);
   
//Looks like there isn't any light here.
  return "It is dark and you can't see a thing.\n";
}

int suppress_filt (string exit, string *suppress) {
  if (member_array (exit, suppress) == -1)
    return 1;
  return 0;
}

string lit_room_description (object room, int infra, int flag) {
  string long, str, tmp, *dirs;
  object *contents, *live;
  int i;
  mixed *suppress;
  mapping exits, doors ;
   
/*  Check the player's "brief" property and get either the long or short
description as is appropriate.  If infravision is being used, minimal
details of the surroundings are given. */
   
  if (infra)
    long = "";
  else
    if (flag && viewingOb->query ("brief")) {
      long = sprintf ("%s\n", room->query ("short"));
    } else {
#ifdef LONG_WITH_SHORT
      long = sprintf ("%s\n%s", room->query ("short"), room->query ("long"));
#else
      long = room->query ("long");
#endif
      if (!flag && room->query ("outside"))
        long += WEATHER_D->query_weather_msg();
    }

  if (!long)
    long = "";

/* Query a room's "door_suppress" property to see what, if any, doors
and their statuses will be displayed in the room. */

  suppress = room->query ("door_suppress");
  if (!suppress || pointerp (suppress)) {
    doors = room->query ("doors");
    if (doors && !infra) {
      dirs = keys (doors);
      if (pointerp (suppress))
	dirs = filter_array (dirs, "suppress_filt", this_object(), suppress);
      i = sizeof (dirs);
      while (i--)
	long = sprintf ("%s The %s door is %s.\n", long, dirs[i],
		doors[dirs[i]]["status"]);
    }
  }
 
/* Query a room's "exit_suppress" property to see what, if any, obvious
exits will be displayed or not. */

  suppress = room->query ("exit_suppress");
  if (!suppress || pointerp (suppress)) {
    exits = room->query ("exits");
    if (exits)
      dirs = keys (exits);
    if (pointerp (suppress))
      dirs = filter_array (dirs, "suppress_filt", this_object(), suppress);
    i = sizeof (dirs);
    switch (i) {
      case 0: {
	long += ((infra) ? "\tYou cannot detect any obvious exits.\n"
			 : "\tThere are no obvious exits.\n");
	break;
      }
      case 1: {
	long = sprintf ("%s\tThe only obvious exit%s is %s.\n", long,
		((infra) ? " you can detect" : ""), dirs[0]);
	break;
      }
      case 2: {
	long = sprintf ("%s\t%sbvious exits %sare %s and %s.\n", long,
		((infra) ? "The only o" : "O"),
		((infra) ? "you can detect " : ""), dirs[0], dirs[1]);
	break;
	}
      default: {
	long = sprintf ("%s\t%sbvious exits %sare %s, and %s.\n", long,
		((infra) ? "The only o" : "O"),
		((infra) ? "you can detect " : ""),
		implode (dirs[0..(i-2)], ", "), dirs[i-1]);
	}
      }
  }
 
// Process inventory of the room/object being examined
  contents = all_inventory (room);
   
//  Check for infravision flag and living heat patterns
  if (infra) {
    i = sizeof (live = filter_array (contents, "filter_living", this_object()));
    switch (i) {
      case 0: {
	long += "Your infravision shows no other heat patterns.\n";
	break;
      }
      case 1: {
	long += "Your infravision shows only one heat pattern.\n";
	break;
      }
      default: {
	long = sprintf ("%sYour infravision shows %s heat patterns.\n",
		long, convert_number (i));
	break;
      }
    }
    return long;
  }
   
  if (!FLAG) {
    i = sizeof (contents);
    while (i--) {
      tmp = (string)contents[i]->query ("short");
      if (contents[i] != viewingOb && tmp && tmp != "")
	if (can_see(viewingOb,contents[i]))
	  long = sprintf ("%s %s\n", long, capitalize (tmp));
    }
  } else
    long += process_contents (contents, FLAG);
   
  return long;
}

// Filter out all objects without a possible heat pattern
int filter_living (object what) {
  if (what == viewingOb || (userp (what) && !interactive (what)))
    return 0;
  return (living (what) && !what->query ("cold") || what->query ("hot"));
}

string look_in_item (string tmp, object user) {
  string tmp2;
  object *contents;
   
  it = present (tmp, user);
  if (!it && env)
    it = present (tmp, env);

// THIS CLEARS UP THE look in foo PROBLEM   --  Moby
   if (!it) {
	return "I don't see that here.\n" ;
   }

// THAT'S ALL


  if (living (it))
    return "You must be kidding me!  Look INSIDE a living being?\n";


  if ((int)it->query_is_closed() && (int)it->query ("opaque"))
    return "Just how do you propose looking in a closed container?\n";

  if (it) {
// in our hands or in our environment.
    contents = all_inventory (it);
    if (!contents) {
      return "You don't see anything inside.\n";
    } else {
      tmp2 = process_contents (contents, FLAG);
      if (tmp2 == "")
	return "You don't see anything inside.\n";
      return sprintf ("%s contains:\n%s\n", capitalize (tmp), tmp2);
    }
  }
// this is where we could look for things in the room's properties.
  return "Look in what?\n";
}

string process_contents (mixed *contents, int flag) {
  mapping match;
  mixed *inv, *ninv;
  string tmp, ret;
  int loop, i; 
   
  ret = "";
  inv = contents;
   
// Remove all objects with no short desc or command initiator
  inv = filter_array (inv, "clean_objects", this_object());
   
// Compile list of objects with matching short descriptions
  match = unique_mapping (inv, "query", "short");
  ninv = keys (match);
   
//Loop through object contents and place them into a display string
   
  loop = sizeof (ninv);  
  while (loop--) {
/* older code handled living cases separately.  taken out by Mobydick @ TMI-2
on 10 April 1993, kept out by Fantome 24 July 1993 */
    i = sizeof (match[ninv[loop]]);
    if (i > 1)
      tmp = sprintf ("%s %s", convert_number (i), pluralize (ninv[loop]));
    else tmp = ninv[loop];
      
    if (flag == 1)
	if(stringp(tmp)) ret = sprintf("%s  %s\n", ret,capitalize(tmp));
       else ret = sprintf("%s  A person with a number for a short\n",ret);
    else
      ret = sprintf ("%s%s%s", ret, tmp,
		((loop > 1) ? ", " : ((!loop) ? "." : ", and ")));
  }
   
  if (flag == 2 && ret != "")
    ret = wrap (sprintf ("You see %s", ret));
   
  return ret;
}

// Remove all invisible objects from the room's content's list
int clean_objects (object what) {
  if (!can_see (viewingOb, what))
    return 0;
  return (((string)what->query ("short") && what != viewingOb) ? 1 : 0);
}

// Compare each object's short desc with processing short desc
string content_match (object what) {
  return (string)what->query("short");
}

// Convert numeric value to word format if below 21
string convert_number(int num) {
  if (!number)
    number = ({
"one", "two", "three", "four", "five", "six", "seven", "eight",
"nine", "ten", "eleven", "twelve", "thirteen", "fourteen",
"fifteen", "sixteen", "seventeen", "eighteen", "nineteen",
"twenty" });
   
  return ((num > 20) ? "many" : number[num - 1]);
}

string help() {
  return (@Help
Syntax: look [at object]

If no object is specified this command makes you look
around the room.  If an object is specified it lets you
examine the object more closely.

See also: brief, glance
Help
);
}