/* Copyright (C)1991, Marcus J. Ranum. All rights reserved. */ /* configure all options BEFORE including system stuff. */ #include "config.h" #include "mud.h" #include "sbuf.h" #include "vars.h" #include "look.h" static void say_other (); static void say_name (); static int known (char *att); /* 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 (char *who, char *thing, int flg) { char nxtu[MAXOID]; char *dp; /* 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, sizeof (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, sizeof (nxtu))) != (char *) 0) if (VALID_PLAYER (who, nxtu, flg)) DISPLAY_NAME (who, nxtu, 0); } } #ifdef COMBAT dp = ut_getatt (thing, 0, typ_obj, var_weapon, (char *) 0); if (dp != (char *) 0 && !ISDARK (dp)) say (who, "Wielding: ", ut_name (dp), "\n", (char *) 0); #endif /* 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, sizeof (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, sizeof (nxtu))) != (char *) 0) if (!ISDARK (nxtu)) DISPLAY_NAME (who, nxtu, 0); } } /* wearing */ dp = ut_getatt (thing, 0, typ_list, var_wearing, (char *) 0); if ((flg & LOOK_CARRY) && dp != (char *) 0) { int numdisp = 0; char *savelst = dp; while ((dp = lstnext (dp, nxtu, sizeof (nxtu))) != (char *) 0) if (!ISDARK (nxtu)) numdisp++; if (numdisp > 0) { say (who, "Wearing:\n", (char *) 0); dp = savelst; while ((dp = lstnext (dp, nxtu, sizeof (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, sizeof (nxtu))) != (char *) 0) if (!ISDARK (nxtu)) numdisp++; if (numdisp > 0) { say (who, "Obvious Exits:\n", (char *) 0); dp = savelst; while ((dp = lstnext (dp, nxtu, sizeof (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)) (void) say_attribute (who, thing, var_using, (char *) 0, 0); } static void say_name (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); } /* ob - name or OID of the object att -the attribute to look for title - optional title, overrides default showoid - show object ids? */ int say_attribute (char *who, char *ob, char *att, char *title, int showoid) { 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, sizeof (tbuf)); title = tbuf; } /* here we have to use the stretchy-buffer version of listnext */ if (attistype (atp, typ_list)) { /* a list? */ Sbuf sb; if (atd == (char *) 0 || *atd == '\0') return (1); say (who, title, ":\n", (char *) 0); sbuf_initstatic (&sb); while ((atd = lstnextsbuf (atd, &sb)) != (char *) 0) say_name (who, sbuf_buf (&sb), showoid); sbuf_freestatic (&sb); } 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 (attistype (atp, typ_u)) { /* U-code? */ if (atd == (char *) 0 || *atd == '\0') return (1); say (who, title, "(U-code): ", 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 (char *who, char *ob) { char aname[MAXOID]; Obj *op; /* pointer to the object */ int a; if ((op = cache_get (ob)) == (Obj *) 0) return; for (a = 0; a < (int) op->ocnt; a++) { if (attname (op->oap[a], aname) == 0 && !known (aname)) /* an unknown! */ (void) 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, #ifdef COMBAT var_isdead, var_isweapon, var_isarmor, #endif 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, #ifdef COMBAT var_weapon, #endif var_pass, 0 }; static int known (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); } int do_examine (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)) { (void) say_attribute (who, ob, var_desc, (char *) 0, 0); (void) say_attribute (who, ob, var_owner, (char *) 0, 1); } return (0); } say (who, "Flags: ", (char *) 0); for (ap = flgs; *ap != (char *) 0; ++ap) (void) say_attribute (who, ob, *ap, (char *) 0, 0); say (who, "\n", (char *) 0); for (ap = atts + 1; *ap != (char *) 0; ++ap) (void) say_attribute (who, ob, *ap, (char *) 0, 1); say_other (who, ob); return (0); }