/*
Copyright (C)1991, Marcus J. Ranum. All rights reserved.
*/
#ifndef lint
static char RCSid[] = "$Header: /home/mjr/hacks/umud/RCS/do_look.c,v 1.6 91/10/22 11:29:24 mjr Exp $";
#endif
#include <ctype.h>
/* configure all options BEFORE including system stuff. */
#include "config.h"
#include "mud.h"
#include "vars.h"
#include "look.h"
static void say_other();
static void say_name();
/*
this is to enable/disable TinyMUD-style object IDs after looked at stuff
which means you do a lock evaluation every time you look at something. UGH!
*/
#ifdef LOOK_OBJECT_IDS
#define DISPLAY_NAME(who,ob,showoid) say_name(who,ob,showoid)
#else
#define DISPLAY_NAME(who,ob,junk) say(who,ut_name(ob),"\n",(char *)0)
#endif
#define ISDARK(obj) (ut_flagged((obj),var_isdark))
/*
* Setup macro for whether a player is a valid
* player or not, given who is calling and the
* look flags. If ignoring unconnected players,
* the check ensures that the player isn't the
* current player, that the player isn't DARK,
* and that either unconnected players are
* to be shown or the player is connected.
* Note that the DARK check uses the macro defined
* above.
*
* If ignoring unconnected players, the check
* just ensures that the player isn't DARK, using
* the ISDARK macro.
*/
#ifdef CONNONLY
#define VALID_PLAYER(who,ply,flg) \
(strcmp((who),(ply)) && \
(!ISDARK((ply))) && \
(((flg) & LOOK_UNCONN) || playerconn((ply))))
#else
#define VALID_PLAYER(who,ply,flg) \
(strcmp((who),(ply)) && \
(!ISDARK((ply))))
#endif
/* look at something */
void
lookat(who,thing,flg)
char *who;
char *thing;
int flg;
{
char nxtu[MAXOID];
char *dp;
char *linkok;
/* flagged to print the thing's name */
if(flg & LOOK_NAME) {
DISPLAY_NAME(who,thing,
(ut_flagged(who,var_wiz)
|| ut_isobjown(who,thing)
|| !bool_locked(who,thing,(char *)0,var_link,1)));
}
dp = ut_getatt(thing,0,typ_str,var_desc,(char *)0);
if(dp == (char *)0) {
say(who,"You see nothing special.\n",(char *)0);
} else {
say(who,dp,"\n",(char *)0);
}
#ifdef TINYHACK
/* This revolting little bit of cat vomit is for compatibility with */
/* converted Tiny* style databases. The code that is commented out */
/* would be the "right thing" to do if you were really going to do */
/* this. The working stuff is the minimum that needs to be done. */
if(ut_flagged(thing,var_isroom)) {
int ac = 0;
char *av[2];
av[0] = av[1] = (char *)0;
if(bool_locked(who,thing,thing,var_lock,0)) {
(void)activate(ACTIV_PONLY,who,thing,thing,var_fail,ac,av);
(void)activate(ACTIV_ECAST,who,thing,thing,var_ofail,ac,av);
} else {
(void)activate(ACTIV_PONLY,who,thing,thing,var_succ,ac,av);
(void)activate(ACTIV_ECAST,who,thing,thing,var_osucc,ac,av);
}
}
#endif
/* Don't show any lists if this thing is dark */
if(ISDARK(thing))
return;
/* players? */
dp = ut_getatt(thing,0,typ_list,var_ply,(char *)0);
if((flg & LOOK_PLAY) && dp != (char *)0) {
int numdisp = 0;
char *savelst = dp;
while((dp = lstnext(dp,nxtu)) != (char *)0)
if(VALID_PLAYER(who,nxtu,flg))
numdisp++;
if(numdisp > 0) {
say(who,"Players:\n",(char *)0);
dp = savelst;
while((dp = lstnext(dp,nxtu)) != (char *)0)
if(VALID_PLAYER(who,nxtu,flg))
DISPLAY_NAME(who,nxtu,0);
}
}
/* carrying or contents? */
dp = ut_getatt(thing,0,typ_list,var_cont,(char *)0);
if((flg & (LOOK_CARRY|LOOK_CONT)) && dp != (char *)0) {
int numdisp = 0;
char *savelst = dp;
while((dp = lstnext(dp,nxtu)) != (char *)0)
if(!ISDARK(nxtu))
numdisp++;
if(numdisp > 0) {
if(flg & LOOK_CARRY)
say(who,"Carrying:\n",(char *)0);
else
say(who,"Contents:\n",(char *)0);
dp = savelst;
while((dp = lstnext(dp,nxtu)) != (char *)0)
if(!ISDARK(nxtu))
DISPLAY_NAME(who,nxtu,0);
}
}
#ifdef LIST_EXITS
/* Listing of non dark exits added by Ed Hand 6/27/91 */
dp = ut_getatt(thing,0,typ_list,var_xit,(char *)0);
if((flg & LOOK_NAME) && dp != (char *)0) {
int numdisp = 0;
char *savelst = dp;
while((dp = lstnext(dp,nxtu)) != (char *)0)
if(!ISDARK(nxtu))
numdisp++;
if(numdisp > 0) {
say(who,"Obvious Exits:\n",(char *)0);
dp = savelst;
while((dp = lstnext(dp,nxtu)) != (char *)0)
if(!ISDARK(nxtu))
DISPLAY_NAME(who,nxtu,0);
}
}
#endif /* LIST_EXITS */
/* using? */
dp = ut_getatt(thing,0,typ_obj,var_using,(char *)0);
if((flg & LOOK_USING) && dp != (char *)0 && !ISDARK(dp))
say_attribute(who,thing,var_using,(char *)0,0);
}
static void
say_name(who,ob,showoid)
char *who;
char *ob;
int showoid;
{
if(showoid)
say(who,ut_name(ob),"(",ob,")\n",(char *)0);
else
say(who,ut_name(ob),"\n",(char *)0);
}
say_attribute(who,ob,att,title,showoid)
char *who;
char *ob; /* name or OID of the object */
char *att; /* the attribute to look for */
char *title; /* optional title, overrides default */
int showoid; /* show object ids? */
{
char tbuf[MAXOID]; /* buffer for the title */
Obj *op; /* pointer to the object */
char *atp; /* pointer to the attribute */
char *atd;
if((op = cache_get(ob)) == (Obj *)0)
return(1);
if((atp = objattr(op,att,(int *)0)) == (char *)0)
return(1);
atd = attdata(atp);
/* possibly generate a title */
if(title == (char *)0) {
fndvnam(att,tbuf);
title = tbuf;
}
if(attistype(atp,typ_list)) { /* a list? */
char nxtu[MAXOID];
if(atd == (char *)0 || *atd == '\0')
return(1);
say(who,title,":\n",(char *)0);
while((atd = lstnext(atd,nxtu)) != (char *)0) {
say_name(who,nxtu,showoid);
}
}
else if(attistype(atp,typ_obj)) { /* an object? */
if(atd == (char *)0 || *atd == '\0')
return(1);
say(who,title,": ",(char *)0);
say_name(who,atd,showoid);
}
else if(attistype(atp,typ_flag)) { /* a flag? */
say(who,title," ",(char *)0);
}
else if(attistype(atp,typ_cmd)) { /* a command? */
if(atd == (char *)0 || *atd == '\0')
return(1);
say(who,title,"(macro): ",atd,"\n",(char *)0);
}
else {
if(atd == (char *)0 || *atd == '\0')
return(1);
say(who,title,": ",atd,"\n",(char *)0);
}
return(0);
}
static void
say_other(who,ob)
char *who;
char *ob;
{
char aname[MAXOID];
Obj *op; /* pointer to the object */
int a;
static int known();
if((op = cache_get(ob)) == (Obj *)0)
return;
for(a = 0; a < op->ocnt; a++) {
if(attname(op->oap[a],aname) == 0
&& !known(aname)) /* an unknown! */
say_attribute(who,ob,aname,aname,1);
}
}
/* attributes in the order you want to to see them */
static char *flgs[] = {
var_isroom, var_isplay, var_wiz, var_isdark,
var_islocal,
0
};
static char *atts[] = {
var_nam, var_desc, var_text, var_owner,
var_ply, var_cont, var_using, var_xit,
var_lock, var_link, var_succ, var_osucc,
var_fail, var_ofail, var_drop, var_odrop,
var_loc, var_dest, var_home, var_dropto,
var_newsart, var_subive, var_objive, var_posive,
var_pass, 0
};
static int
known(att)
char *att;
{
char **ap;
for(ap = flgs; *ap != (char *)0; ++ap)
if(strcmp(att,*ap) == 0)
return(2);
for(ap = atts; *ap != (char *)0; ++ap)
if(strcmp(att,*ap) == 0)
return(1);
return(0);
}
do_examine(who,aswho,ob)
char *who;
char *aswho;
char *ob;
{
char **ap;
if(ut_flagged(ob,var_isplay)) {
say(who, "A player", (char *)0);
} else
if(ut_flagged(ob,var_isroom)) {
say(who, "A room", (char *)0);
} else
if(lstlook(ut_getatt(ob,0,typ_list,var_loc,var_xit,(char *)0),ob)) {
say(who, "An exit", (char *)0);
} else
{
say(who, "An object", (char *)0);
}
say(who," named: ",(char *)0);
say_name(who,ob,1);
if(!ut_flagged(aswho,var_wiz) && !ut_isobjown(aswho,ob)) {
char *here,*there;
here = ut_loc(aswho);
there = ut_loc(ob);
if(!strcmp(here,there) || !strcmp(here,ob) || !strcmp(there,aswho)){
say_attribute(who,ob,var_desc,(char *)0,0);
say_attribute(who,ob,var_owner,(char *)0,1);
}
return(0);
}
say(who,"Flags: ",(char *)0);
for (ap = flgs; *ap != (char *)0; ++ap)
say_attribute(who,ob,*ap,(char *)0,0);
say(who,"\n",(char *)0);
for (ap = atts + 1; *ap != (char *)0; ++ap)
say_attribute(who,ob,*ap,(char *)0,1);
say_other(who,ob);
return(0);
}