/* $Header: look.c,v 2.0 90/05/05 12:45:36 lachesis Exp $ * $Log: look.c,v $ * Revision 2.0 90/05/05 12:45:36 lachesis * Incorporated ABODE and HAVEN flags (remembering to convert FireFoot's * usage of those flags to ours). * Added Examine of objects that don't belong to you, added GOD_PRIV. * * Revision 1.3 90/04/21 17:20:46 lachesis * Added property lists. * * Revision 1.2 90/04/20 14:06:44 lachesis * Added @odrop && @drop. * * Revision 1.1 90/04/14 14:56:46 lachesis * Initial revision * */ #include "copyright.h" /* commands which look at things */ #include "db.h" #include "config.h" #include "interface.h" #include "match.h" #include "externs.h" char buf[BUFFER_LEN]; /* prints owner of something */ static void print_owner(dbref player, dbref thing) { char buf[BUFFER_LEN]; switch(Typeof(thing)) { case TYPE_ROOM: sprintf(buf, "Owner: %s", db[db[thing].sp.room.owner].name); break; case TYPE_THING: sprintf(buf, "Owner: %s", db[db[thing].sp.thing.owner].name); break; case TYPE_PLAYER: sprintf(buf, "%s is a player", db[thing].name); break; case TYPE_EXIT: sprintf(buf, "Owner: %s", db[db[thing].sp.exit.owner].name); break; #ifdef RECYCLE case TYPE_GARBAGE: sprintf(buf, "%s is garbage", db[thing].name); break; #endif } notify(player, buf); } static void look_contents(dbref player, dbref loc, const char *contents_name) { dbref thing; dbref can_see_loc; /* check to see if he can see the location */ can_see_loc = (!Dark(loc) || controls(player, loc)); /* check to see if there is anything there */ DOLIST(thing, db[loc].contents) { if(can_see(player, thing, can_see_loc)) { /* something exists! show him everything */ notify(player, contents_name); DOLIST(thing, db[loc].contents) { if(can_see(player, thing, can_see_loc)) { notify(player, unparse_object(player, thing)); } } break; /* we're done */ } } } static void look_simple(dbref player, dbref thing) { if(db[thing].description) { notify(player, db[thing].description); } else { notify(player, "You see nothing special."); } } void look_room(dbref player, dbref loc) { /* tell him the name, and the number if he can link to it */ notify(player, unparse_object(player, loc)); /* tell him the description */ if(db[loc].description) { notify(player, db[loc].description); } /* tell him the appropriate messages if he has the key */ can_doit(player, loc, 0); /* tell him the contents */ look_contents(player, loc, "Contents:"); } void do_look_around(dbref player) { dbref loc; if((loc = getloc(player)) == NOTHING) return; look_room(player, loc); } void do_look_at(dbref player, const char *name) { dbref thing; if(*name == '\0') { if((thing = getloc(player)) != NOTHING) { look_room(player, thing); } } else { /* look at a thing here */ init_match(player, name, NOTYPE); match_all_exits(); match_neighbor(); match_possession(); if(Wizard(player)) { match_absolute(); match_player(); } match_here(); match_me(); if((thing = noisy_match_result()) != NOTHING) { switch(Typeof(thing)) { case TYPE_ROOM: look_room(player, thing); break; case TYPE_PLAYER: look_simple(player, thing); look_contents(player, thing, "Carrying:"); break; default: look_simple(player, thing); break; } } } } #ifdef VERBOSE_EXAMINE static const char *flag_description(dbref thing) { static char buf[BUFFER_LEN]; strcpy(buf, "Type: "); switch(Typeof(thing)) { case TYPE_ROOM: strcat(buf, "ROOM"); break; case TYPE_EXIT: strcat(buf, "EXIT/ACTION"); break; case TYPE_THING: strcat(buf, "THING"); break; case TYPE_PLAYER: strcat(buf, "PLAYER"); break; #ifdef RECYCLE case TYPE_GARBAGE: strcat(buf, "GARBAGE"); break; #endif default: strcat(buf, "***UNKNOWN TYPE***"); break; } if(db[thing].flags & ~TYPE_MASK) { /* print flags */ strcat(buf, " Flags:"); if(db[thing].flags & WIZARD) strcat(buf, " WIZARD"); if(db[thing].flags & STICKY) strcat(buf, " STICKY"); if(db[thing].flags & DARK) strcat(buf, " DARK"); if(db[thing].flags & LINK_OK) strcat(buf, " LINK_OK"); if(db[thing].flags & TEMPLE) strcat(buf, " TEMPLE"); #ifdef RESTRICTED_BUILDING if(db[thing].flags & BUILDER) strcat(buf, " BUILDER"); #endif /* RESTRICTED_BUILDING */ #ifdef PLAYER_CHOWN if(db[thing].flags & CHOWN_OK) strcat(buf, " CHOWN_OK"); #endif /* PLAYER_CHOWN */ if(db[thing].flags & JUMP_OK) strcat(buf, " JUMP_OK"); #ifdef HAVEN if (db[thing].flags & HAVEN) strcat(buf, " HAVEN"); #endif /* HAVEN */ #ifdef ABODE if (db[thing].flags & ABODE) strcat(buf, " ABODE"); #endif /* ABODE */ } return buf; } #endif /* VERBOSE_EXAMINE */ void do_examine(dbref player, const char *name) { dbref thing; char buf[BUFFER_LEN]; dbref content; dbref exit; int i; if(*name == '\0') { if((thing = getloc(player)) == NOTHING) return; } else { /* look it up */ init_match(player, name, NOTYPE); match_all_exits(); match_neighbor(); match_possession(); match_absolute(); /* only Wizards can examine other players */ if(Wizard(player)) match_player(); match_here(); match_me(); /* get result */ if((thing = noisy_match_result()) == NOTHING) return; } if(!can_link(player, thing)) { print_owner(player, thing); do_look_at(player, name); return; } switch(Typeof(thing)) { case TYPE_ROOM: sprintf(buf, "%s Owner: %s", unparse_object(player, thing), db[db[thing].sp.room.owner].name); break; case TYPE_THING: sprintf(buf, "%s Owner: %s Value: %d", unparse_object(player, thing), db[db[thing].sp.thing.owner].name, db[thing].sp.thing.value); break; case TYPE_PLAYER: sprintf(buf, "%s Cookies: %d ", unparse_object(player, thing), db[thing].sp.player.pennies); break; case TYPE_EXIT: sprintf(buf, "%s Owner: %s", unparse_object(player, thing), db[db[thing].sp.exit.owner].name); break; #ifdef RECYCLE case TYPE_GARBAGE: strcpy(buf, unparse_object(player, thing)); break; #endif } notify(player, buf); #ifdef VERBOSE_EXAMINE notify(player, flag_description(thing)); #endif /* VERBOSE_EXAMINE */ if(db[thing].description) notify(player, db[thing].description); sprintf(buf, "Key: %s", unparse_boolexp(player, db[thing].key)); notify(player, buf); if(db[thing].fail_message) { sprintf(buf, "Fail: %s", db[thing].fail_message); notify(player, buf); } if(db[thing].succ_message) { sprintf(buf, "Success: %s", db[thing].succ_message); notify(player, buf); } if (db[thing].drop_message) { sprintf(buf, "Drop: %s", db[thing].drop_message); notify(player, buf); } if(db[thing].ofail) { sprintf(buf, "Ofail: %s", db[thing].ofail); notify(player, buf); } if(db[thing].osuccess) { sprintf(buf, "Osuccess: %s", db[thing].osuccess); notify(player, buf); } if (db[thing].odrop) { sprintf(buf, "Odrop: %s", db[thing].odrop); notify(player, buf); } /* show him the properties */ if (db[thing].properties) { struct plist *p; char buf[BUFFER_LEN]; notify(player, "Properties:"); for (p = db[thing].properties; p; p = p -> next) { strncpy(buf, p -> type, BUFFER_LEN - 1); strncat(buf, ": ", BUFFER_LEN - 1); strncat(buf, p -> class, BUFFER_LEN - 1); notify(player, buf); } } /* show him the contents */ if(db[thing].contents != NOTHING) { if (Typeof(thing) == TYPE_PLAYER) notify(player, "Carrying:"); else notify(player, "Contents:"); DOLIST(content, db[thing].contents) { notify(player, unparse_object(player, content)); } } switch(Typeof(thing)) { case TYPE_ROOM: /* tell him about exits */ if(db[thing].sp.room.exits != NOTHING) { notify(player, "Exits:"); DOLIST(exit, db[thing].sp.room.exits) { notify(player, unparse_object(player, exit)); } } else { notify(player, "No exits."); } /* print dropto if present */ if(db[thing].sp.room.dropto != NOTHING) { sprintf(buf, "Dropped objects go to: %s", unparse_object(player, db[thing].sp.room.dropto)); notify(player, buf); } break; case TYPE_THING: /* print home */ sprintf(buf, "Home: %s", unparse_object(player, db[thing].sp.thing.home)); /* home */ notify(player, buf); /* print location if player can link to it */ if(db[thing].location != NOTHING && (controls(player, db[thing].location) || can_link_to(player, db[thing].location))) { sprintf(buf, "Location: %s", unparse_object(player, db[thing].location)); notify(player, buf); } /* print thing's actions, if any */ if(db[thing].sp.thing.actions != NOTHING) { notify(player, "Actions/exits:"); DOLIST(exit, db[thing].sp.thing.actions) { notify(player, unparse_object(player, exit)); } } else { notify(player, "No actions attached."); } break; case TYPE_PLAYER: /* print home */ sprintf(buf, "Home: %s", unparse_object(player, db[thing].sp.player.home)); /* home */ notify(player, buf); /* print location if player can link to it */ if(db[thing].location != NOTHING && (controls(player, db[thing].location) || can_link_to(player, db[thing].location))) { sprintf(buf, "Location: %s", unparse_object(player, db[thing].location)); notify(player, buf); } /* print player's actions, if any */ if(db[thing].sp.player.actions != NOTHING) { notify(player, "Actions/exits:"); DOLIST(exit, db[thing].sp.player.actions) { notify(player, unparse_object(player, exit)); } } else { notify(player, "No actions attached."); } break; case TYPE_EXIT: if (db[thing].location != NOTHING) { sprintf(buf, "Source: %s", unparse_object(player, db[thing].location)); notify(player, buf); } /* print destinations */ if (db[thing].sp.exit.ndest == 0) break; for (i = 0; i < db[thing].sp.exit.ndest; i++) { switch( (db[thing].sp.exit.dest)[i]) { case NOTHING: break; case HOME: notify(player, "Destination: *HOME*"); break; default: sprintf(buf, "Destination: %s", unparse_object(player, (db[thing].sp.exit.dest)[i])); notify(player, buf); break; } } break; default: /* do nothing */ break; } } void do_score(dbref player) { char buf[BUFFER_LEN]; sprintf(buf, "You have %d %s.", db[player].sp.player.pennies, db[player].sp.player.pennies == 1 ? "cookie" : "cookies"); notify(player, buf); } void do_inventory(dbref player) { dbref thing; if((thing = db[player].contents) == NOTHING) { notify(player, "You aren't carrying anything."); } else { notify(player, "You are carrying:"); DOLIST(thing, thing) { notify(player, unparse_object(player, thing)); } } do_score(player); } void do_find(dbref player, const char *name) { dbref i; if(!payfor(player, LOOKUP_COST)) { notify(player, "You don't have enough cookies."); } else { for(i = 0; i < db_top; i++) { if(Typeof(i) != TYPE_EXIT && controls(player, i) && (!*name || string_match(db[i].name, name))) { notify(player, unparse_object(player, i)); } } notify(player, "***End of List***"); } }