/* * look.c -- commands which look at things */ #include "copyright.h" #include "config.h" #include "mudconf.h" #include "config.h" #include "db.h" #include "interface.h" #include "match.h" #include "externs.h" #include "flags.h" #include "powers.h" #include "attrs.h" #include "command.h" #include "alloc.h" #include "ansi.h" extern void ufun(char *, char *, int, int, int, dbref, dbref); static void look_exits(dbref player, dbref loc, const char *exit_name) { dbref thing, parent; char *buff, *e, *s, *buff1, *e1; int foundany, lev, key; /* * make sure location has exits */ if(!Good_obj(loc) || !Has_exits(loc)) return; /* * make sure there is at least one visible exit */ foundany = 0; key = 0; if(Dark(loc)) key |= VE_BASE_DARK; ITER_PARENTS(loc, parent, lev) { key &= ~VE_LOC_DARK; if(Dark(parent)) key |= VE_LOC_DARK; DOLIST(thing, Exits(parent)) { if(exit_displayable(thing, player, key)) { foundany = 1; break; } } if(foundany) break; } if(!foundany) return; /* * Display the list of exit names */ notify(player, exit_name); e = buff = alloc_lbuf("look_exits"); e1 = buff1 = alloc_lbuf("look_exits2"); ITER_PARENTS(loc, parent, lev) { key &= ~VE_LOC_DARK; if(Dark(parent)) key |= VE_LOC_DARK; if(Transparent(loc)) { DOLIST(thing, Exits(parent)) { if(exit_displayable(thing, player, key)) { StringCopy(buff, Name(thing)); for(e = buff; *e && (*e != ';'); e++); *e = '\0'; notify_printf(player, "%s leads to %s.", buff, Name(Location(thing))); } } } else { DOLIST(thing, Exits(parent)) { if(exit_displayable(thing, player, key)) { e1 = buff1; /* Put the exit name in buff1 */ /* * chop off first * * * * * exit alias to * * * * display */ if(buff != e) safe_str((char *) " ", buff, &e); for(s = Name(thing); *s && (*s != ';'); s++) safe_chr(*s, buff1, &e1); *e1 = 0; /* Copy the exit name into 'buff' */ /* Append this exit to the list */ safe_str(buff1, buff, &e); } } } } if(!(Transparent(loc))) { safe_str((char *) "\r\n", buff, &e); *e = 0; notify(player, buff); } free_lbuf(buff); free_lbuf(buff1); } #define CONTENTS_LOCAL 0 #define CONTENTS_NESTED 1 #define CONTENTS_REMOTE 2 static void look_contents(dbref player, dbref loc, const char *contents_name, int style) { dbref thing; dbref can_see_loc; char *buff; char remote_num[32]; /* * check to see if he can see the location */ can_see_loc = (!Dark(loc) || (mudconf.see_own_dark && Examinable(player, loc))); /* * check to see if there is anything there */ DOLIST(thing, Contents(loc)) { if(can_see(player, thing, can_see_loc)) { /* * something exists! show him everything */ notify(player, contents_name); DOLIST(thing, Contents(loc)) { if(can_see(player, thing, can_see_loc)) { buff = unparse_object(player, thing, 1); notify(player, buff); free_lbuf(buff); } } break; /* * we're done */ } } } static void view_atr(dbref player, dbref thing, ATTR * ap, char *text, dbref aowner, int aflags, int skip_tag) { char *buf; char xbuf[6]; char *xbufp; BOOLEXP *bool; if(ap->flags & AF_IS_LOCK) { bool = parse_boolexp(player, text, 1); text = unparse_boolexp(player, bool); free_boolexp(bool); } /* * If we don't control the object or own the attribute, hide the * * * * * attr owner and flag info. */ if(!Controls(player, thing) && (Owner(player) != aowner)) { if(skip_tag && (ap->number == A_DESC)) buf = text; else buf = tprintf("\033[1m%s:\033[0m %s", ap->name, text); notify(player, buf); return; } /* * Generate flags */ xbufp = xbuf; if(aflags & AF_LOCK) *xbufp++ = '+'; if(aflags & AF_NOPROG) *xbufp++ = '$'; if(aflags & AF_PRIVATE) *xbufp++ = 'I'; if(aflags & AF_REGEXP) *xbufp++ = 'R'; if(aflags & AF_VISUAL) *xbufp++ = 'V'; if(aflags & AF_MDARK) *xbufp++ = 'M'; if(aflags & AF_WIZARD) *xbufp++ = 'W'; *xbufp = '\0'; if((aowner != Owner(thing)) && (aowner != NOTHING)) { buf = tprintf("\033[1m%s [#%d%s]:\033[0m %s", ap->name, aowner, xbuf, text); } else if(*xbuf) { buf = tprintf("\033[1m%s [%s]:\033[0m %s", ap->name, xbuf, text); } else if(!skip_tag || (ap->number != A_DESC)) { buf = tprintf("\033[1m%s:\033[0m %s", ap->name, text); } else { buf = text; } notify(player, buf); } static void look_atrs1(dbref player, dbref thing, dbref othing, int check_exclude, int hash_insert) { dbref aowner; int ca, aflags; ATTR *attr, *cattr; char *as, *buf; cattr = (ATTR *) malloc(sizeof(ATTR)); for(ca = atr_head(thing, &as); ca; ca = atr_next(&as)) { if((ca == A_DESC) || (ca == A_LOCK)) continue; attr = atr_num(ca); if(!attr) continue; bcopy((char *) attr, (char *) cattr, sizeof(ATTR)); /* * Should we exclude this attr? */ if(check_exclude && ((attr->flags & AF_PRIVATE) || nhashfind(ca, &mudstate.parent_htab))) continue; buf = atr_get(thing, ca, &aowner, &aflags); if(Read_attr(player, othing, attr, aowner, aflags)) { /* check_zone/atr_num overwrites attr!! */ if(attr->number != cattr->number) bcopy((char *) cattr, (char *) attr, sizeof(ATTR)); if(!(check_exclude && (aflags & AF_PRIVATE))) { if(hash_insert) nhashadd(ca, (int *) attr, &mudstate.parent_htab); view_atr(player, thing, attr, buf, aowner, aflags, 0); } } free_lbuf(buf); } free(cattr); } static void look_atrs(dbref player, dbref thing, int check_parents) { dbref parent; int lev, check_exclude, hash_insert; if(!check_parents) { look_atrs1(player, thing, thing, 0, 0); } else { hash_insert = 1; check_exclude = 0; nhashflush(&mudstate.parent_htab, 0); ITER_PARENTS(thing, parent, lev) { if(!Good_obj(Parent(parent))) hash_insert = 0; look_atrs1(player, parent, thing, check_exclude, hash_insert); check_exclude = 1; } } } static void look_simple(dbref player, dbref thing, int obey_terse) { int pattr; char *buff; /* * Only makes sense for things that can hear */ if(!Hearer(player)) return; /* * Get the name and db-number if we can examine it. */ if(Examinable(player, thing)) { buff = unparse_object(player, thing, 1); notify(player, buff); free_lbuf(buff); } pattr = (obey_terse && Terse(player)) ? 0 : A_DESC; did_it(player, thing, pattr, "You see nothing special.", A_ODESC, NULL, A_ADESC, (char **) NULL, 0); if(!mudconf.quiet_look && (!Terse(player) || mudconf.terse_look)) { look_atrs(player, thing, 0); } } static void show_a_desc(dbref player, dbref loc) { char *got2; dbref aowner; int aflags, indent = 0; indent = (isRoom(loc) && mudconf.indent_desc && atr_get_raw(loc, A_DESC)); if(indent) raw_notify_newline(player); did_it(player, loc, A_DESC, NULL, A_ODESC, NULL, A_ADESC, (char **) NULL, 0); if(indent) raw_notify_newline(player); } static void show_desc(dbref player, dbref loc, int key) { char *got; dbref aowner; int aflags; if((key & LK_OBEYTERSE) && Terse(player)) did_it(player, loc, 0, NULL, A_ODESC, NULL, A_ADESC, (char **) NULL, 0); else if((Typeof(loc) != TYPE_ROOM) && (key & LK_IDESC)) { if(*(got = atr_pget(loc, A_IDESC, &aowner, &aflags))) did_it(player, loc, A_IDESC, NULL, A_ODESC, NULL, A_ADESC, (char **) NULL, 0); else show_a_desc(player, loc); free_lbuf(got); } else { show_a_desc(player, loc); } } void look_in(dbref player, dbref loc, int key) { int pattr, oattr, aattr, is_terse, showkey; char *buff; is_terse = (key & LK_OBEYTERSE) ? Terse(player) : 0; /* * Only makes sense for things that can hear */ if(!Hearer(player)) return; /* * tell him the name, and the number if he can link to it */ buff = unparse_object(player, loc, 1); notify(player, buff); free_lbuf(buff); if(!Good_obj(loc)) return; /* * If we went to NOTHING et al, skip the * * * * * rest */ /* * tell him the description */ showkey = 0; if(loc == Location(player)) showkey |= LK_IDESC; if(key & LK_OBEYTERSE) showkey |= LK_OBEYTERSE; show_desc(player, loc, showkey); /* * tell him the appropriate messages if he has the key */ if(Typeof(loc) == TYPE_ROOM) { if(could_doit(player, loc, A_LOCK)) { pattr = A_SUCC; oattr = A_OSUCC; aattr = A_ASUCC; } else { pattr = A_FAIL; oattr = A_OFAIL; aattr = A_AFAIL; } if(is_terse) pattr = 0; did_it(player, loc, pattr, NULL, oattr, NULL, aattr, (char **) NULL, 0); } /* * tell him the attributes, contents and exits */ if((key & LK_SHOWATTR) && !mudconf.quiet_look && !is_terse) look_atrs(player, loc, 0); if(!is_terse || mudconf.terse_contents) look_contents(player, loc, "Contents:", CONTENTS_LOCAL); if((key & LK_SHOWEXIT) && (!is_terse || mudconf.terse_exits)) look_exits(player, loc, "Obvious exits:"); } void do_look(dbref player, dbref cause, int key, char *name) { dbref thing, loc, look_key; look_key = LK_SHOWATTR | LK_SHOWEXIT; if(!mudconf.terse_look) look_key |= LK_OBEYTERSE; loc = Location(player); if(!name || !*name) { thing = loc; if(Good_obj(thing)) { if(key & LOOK_OUTSIDE) { if((Typeof(thing) == TYPE_ROOM) || Opaque(thing)) { notify_quiet(player, "You can't look outside."); return; } thing = Location(thing); } look_in(player, thing, look_key); } return; } /* * Look for the target locally */ thing = (key & LOOK_OUTSIDE) ? loc : player; init_match(thing, name, NOTYPE); match_exit_with_parents(); match_neighbor(); match_possession(); if(Long_Fingers(player)) { match_absolute(); match_player(); } match_here(); match_me(); match_master_exit(); thing = match_result(); /* * Not found locally, check possessive */ if(!Good_obj(thing)) { thing = match_status(player, match_possessed(player, ((key & LOOK_OUTSIDE) ? loc : player), (char *) name, thing, 0)); } /* * If we found something, go handle it */ if(Good_obj(thing)) { switch (Typeof(thing)) { case TYPE_ROOM: look_in(player, thing, look_key); break; case TYPE_THING: case TYPE_PLAYER: look_simple(player, thing, !mudconf.terse_look); if(!Opaque(thing) && (!Terse(player) || mudconf.terse_contents)) { look_contents(player, thing, "Carrying:", CONTENTS_NESTED); } break; case TYPE_EXIT: look_simple(player, thing, !mudconf.terse_look); if(Transparent(thing) && (Location(thing) != NOTHING)) { look_key &= ~LK_SHOWATTR; look_in(player, Location(thing), look_key); } break; default: look_simple(player, thing, !mudconf.terse_look); } } } static void debug_examine(dbref player, dbref thing) { dbref aowner; char *buf; int aflags, ca; BOOLEXP *bool; ATTR *attr; char *as, *cp; notify_printf(player, "Number = %d", thing); if(!Good_obj(thing)) return; notify_printf(player, "Name = %s", Name(thing)); notify_printf(player, "Location= %d", Location(thing)); notify_printf(player, "Contents= %d", Contents(thing)); notify_printf(player, "Exits = %d", Exits(thing)); notify_printf(player, "Link = %d", Link(thing)); notify_printf(player, "Next = %d", Next(thing)); notify_printf(player, "Owner = %d", Owner(thing)); notify_printf(player, "Pennies = %d", Pennies(thing)); notify_printf(player, "Zone = %d", Zone(thing)); buf = flag_description(player, thing); notify_printf(player, "Flags = %s", buf); free_mbuf(buf); buf = power_description(player, thing); notify_printf(player, "Powers = %s", buf); free_mbuf(buf); buf = atr_get(thing, A_LOCK, &aowner, &aflags); bool = parse_boolexp(player, buf, 1); free_lbuf(buf); notify_printf(player, "Lock = %s", unparse_boolexp(player, bool)); free_boolexp(bool); buf = alloc_lbuf("debug_dexamine"); cp = buf; safe_str((char *) "Attr list: ", buf, &cp); for(ca = atr_head(thing, &as); ca; ca = atr_next(&as)) { attr = atr_num(ca); if(!attr) continue; atr_get_info(thing, ca, &aowner, &aflags); if(Read_attr(player, thing, attr, aowner, aflags)) { if(attr) { /* * Valid attr. */ safe_str((char *) attr->name, buf, &cp); safe_chr(' ', buf, &cp); } else { safe_str(tprintf("%d ", ca), buf, &cp); } } } *cp = '\0'; notify(player, buf); free_lbuf(buf); for(ca = atr_head(thing, &as); ca; ca = atr_next(&as)) { attr = atr_num(ca); if(!attr) continue; buf = atr_get(thing, ca, &aowner, &aflags); if(Read_attr(player, thing, attr, aowner, aflags)) view_atr(player, thing, attr, buf, aowner, aflags, 0); free_lbuf(buf); } } static void exam_wildattrs(dbref player, dbref thing, int do_parent) { int atr, aflags, got_any; char *buf; dbref aowner; ATTR *ap; got_any = 0; for(atr = olist_first(); atr != NOTHING; atr = olist_next()) { ap = atr_num(atr); if(!ap) continue; if(do_parent && !(ap->flags & AF_PRIVATE)) buf = atr_pget(thing, atr, &aowner, &aflags); else buf = atr_get(thing, atr, &aowner, &aflags); /* * Decide if the player should see the attr: * If obj is * * * * Examinable and has rights to see, yes. * If a player and * * * * * has rights to see, yes... * except if faraway, * * * * attr=DESC, and * remote DESC-reading is not turned * on. * * * * * * If I own the attrib and have rights to * see, yes... * * * * except if faraway, attr=DESC, and * * remote * DESC-reading * * is not turned on. */ if(Examinable(player, thing) && Read_attr(player, thing, ap, aowner, aflags)) { got_any = 1; view_atr(player, thing, ap, buf, aowner, aflags, 0); } else if((Typeof(thing) == TYPE_PLAYER) && Read_attr(player, thing, ap, aowner, aflags)) { got_any = 1; if(aowner == Owner(player)) { view_atr(player, thing, ap, buf, aowner, aflags, 0); } else if((atr == A_DESC) && (mudconf.read_rem_desc || nearby(player, thing))) { show_desc(player, thing, 0); } else if(atr != A_DESC) { view_atr(player, thing, ap, buf, aowner, aflags, 0); } else { notify(player, "<Too far away to get a good look>"); } } else if(Read_attr(player, thing, ap, aowner, aflags)) { got_any = 1; if(aowner == Owner(player)) { view_atr(player, thing, ap, buf, aowner, aflags, 0); } else if((atr == A_DESC) && (mudconf.read_rem_desc || nearby(player, thing))) { show_desc(player, thing, 0); } else if(nearby(player, thing)) { view_atr(player, thing, ap, buf, aowner, aflags, 0); } else { notify(player, "<Too far away to get a good look>"); } } free_lbuf(buf); } if(!got_any) notify_quiet(player, "No matching attributes found."); } void do_examine(dbref player, dbref cause, int key, char *name) { dbref thing, content, exit, aowner, loc; char savec; char *temp, *buf, *buf2; BOOLEXP *bool; int control, aflags, do_parent; /* * This command is pointless if the player can't hear. */ if(!Hearer(player)) return; do_parent = key & EXAM_PARENT; thing = NOTHING; if(!name || !*name) { if((thing = Location(player)) == NOTHING) return; } else { /* Check for obj/attr first */ olist_push(); if(parse_attrib_wild(player, name, &thing, do_parent, 1, 0)) { exam_wildattrs(player, thing, do_parent); olist_pop(); return; } olist_pop(); /* Look it up */ init_match(player, name, NOTYPE); match_everything(MAT_EXIT_PARENTS); thing = noisy_match_result(); if(!Good_obj(thing)) return; } /* * Check for the /debug switch */ if(key == EXAM_DEBUG) { if(!Examinable(player, thing)) { notify_quiet(player, "Permission denied."); } else { debug_examine(player, thing); } return; } control = (Examinable(player, thing) || Link_exit(player, thing)); if(control) { buf2 = unparse_object(player, thing, 0); notify(player, buf2); free_lbuf(buf2); if(mudconf.ex_flags) { buf2 = flag_description(player, thing); notify(player, buf2); free_mbuf(buf2); } } else { if((key == EXAM_DEFAULT) && !mudconf.exam_public) { if(mudconf.read_rem_name) { buf2 = alloc_lbuf("do_examine.pub_name"); StringCopy(buf2, Name(thing)); notify_printf(player, "%s is owned by %s", buf2, Name(Owner(thing))); free_lbuf(buf2); } else { notify_printf(player, "Owned by %s", Name(Owner(thing))); } return; } } temp = alloc_lbuf("do_examine.info"); if(control || mudconf.read_rem_desc || nearby(player, thing)) { temp = atr_get_str(temp, thing, A_DESC, &aowner, &aflags); if(*temp) { if(Examinable(player, thing) || (aowner == Owner(player))) { view_atr(player, thing, atr_num(A_DESC), temp, aowner, aflags, 1); } else { show_desc(player, thing, 0); } } } else { notify(player, "<Too far away to get a good look>"); } if(control) { /* * print owner, key, and value */ savec = mudconf.many_coins[0]; mudconf.many_coins[0] = (islower(savec) ? toupper(savec) : savec); buf2 = atr_get(thing, A_LOCK, &aowner, &aflags); bool = parse_boolexp(player, buf2, 1); buf = unparse_boolexp(player, bool); free_boolexp(bool); StringCopy(buf2, Name(Owner(thing))); notify_printf(player, "Owner: %s Key: %s %s: %d", buf2, buf, mudconf.many_coins, Pennies(thing)); free_lbuf(buf2); mudconf.many_coins[0] = savec; if(mudconf.have_zones) { buf2 = unparse_object(player, Zone(thing), 0); notify_printf(player, "Zone: %s", buf2); free_lbuf(buf2); } /* * print parent */ loc = Parent(thing); if(loc != NOTHING) { buf2 = unparse_object(player, loc, 0); notify_printf(player, "Parent: %s", buf2); free_lbuf(buf2); } buf2 = power_description(player, thing); notify(player, buf2); free_mbuf(buf2); } if(key != EXAM_BRIEF) look_atrs(player, thing, do_parent); /* * show him interesting stuff */ if(control) { /* * Contents */ if(Contents(thing) != NOTHING) { notify(player, "Contents:"); DOLIST(content, Contents(thing)) { buf2 = unparse_object(player, content, 0); notify(player, buf2); free_lbuf(buf2); } } /* * Show stuff that depends on the object type */ switch (Typeof(thing)) { case TYPE_ROOM: /* * tell him about exits */ if(Exits(thing) != NOTHING) { notify(player, "Exits:"); DOLIST(exit, Exits(thing)) { buf2 = unparse_object(player, exit, 0); notify(player, buf2); free_lbuf(buf2); } } else { notify(player, "No exits."); } /* * print dropto if present */ if(Dropto(thing) != NOTHING) { buf2 = unparse_object(player, Dropto(thing), 0); notify_printf(player, "Dropped objects go to: %s", buf2); free_lbuf(buf2); } break; case TYPE_THING: case TYPE_PLAYER: /* * tell him about exits */ if(Exits(thing) != NOTHING) { notify(player, "Exits:"); DOLIST(exit, Exits(thing)) { buf2 = unparse_object(player, exit, 0); notify(player, buf2); free_lbuf(buf2); } } else { notify(player, "No exits."); } /* * print home */ loc = Home(thing); buf2 = unparse_object(player, loc, 0); notify_printf(player, "Home: %s", buf2); free_lbuf(buf2); /* * print location if player can link to it */ loc = Location(thing); if((Location(thing) != NOTHING) && (Examinable(player, loc) || Examinable(player, thing) || Linkable(player, loc))) { buf2 = unparse_object(player, loc, 0); notify_printf(player, "Location: %s", buf2); free_lbuf(buf2); } break; case TYPE_EXIT: buf2 = unparse_object(player, Exits(thing), 0); notify_printf(player, "Source: %s", buf2); free_lbuf(buf2); /* * print destination */ switch (Location(thing)) { case NOTHING: break; case HOME: notify(player, "Destination: *HOME*"); break; default: buf2 = unparse_object(player, Location(thing), 0); notify_printf(player, "Destination: %s", buf2); free_lbuf(buf2); break; } break; default: break; } } else if(!Opaque(thing) && nearby(player, thing)) { if(Has_contents(thing)) look_contents(player, thing, "Contents:", CONTENTS_REMOTE); if(Typeof(thing) != TYPE_EXIT) look_exits(player, thing, "Obvious exits:"); } free_lbuf(temp); if(!control) { if(mudconf.read_rem_name) { buf2 = alloc_lbuf("do_examine.pub_name"); StringCopy(buf2, Name(thing)); notify_printf(player, "%s is owned by %s", buf2, Name(Owner(thing))); free_lbuf(buf2); } else { notify_printf(player, "Owned by %s", Name(Owner(thing))); } } } void do_score(dbref player, dbref cause, int key) { notify_printf(player, "You have %d %s.", Pennies(player), (Pennies(player) == 1) ? mudconf.one_coin : mudconf.many_coins); } void do_inventory(dbref player, dbref cause, int key) { dbref thing; char *buff, *s, *e; thing = Contents(player); if(thing == NOTHING) { notify(player, "You aren't carrying anything."); } else { notify(player, "You are carrying:"); DOLIST(thing, thing) { buff = unparse_object(player, thing, 1); notify(player, buff); free_lbuf(buff); } } thing = Exits(player); if(thing != NOTHING) { notify(player, "Exits:"); e = buff = alloc_lbuf("look_exits"); DOLIST(thing, thing) { /* * chop off first exit alias to display */ for(s = Name(thing); *s && (*s != ';'); s++) safe_chr(*s, buff, &e); safe_str((char *) " ", buff, &e); } *e = 0; notify(player, buff); free_lbuf(buff); } do_score(player, player, 0); } void do_entrances(dbref player, dbref cause, int key, char *name) { dbref thing, i, j; char *exit, *message; int control_thing, count, low_bound, high_bound; FWDLIST *fp; parse_range(&name, &low_bound, &high_bound); if(!name || !*name) { if(Has_location(player)) thing = Location(player); else thing = player; if(!Good_obj(thing)) return; } else { init_match(player, name, NOTYPE); match_everything(MAT_EXIT_PARENTS); thing = noisy_match_result(); if(!Good_obj(thing)) return; } if(!payfor(player, mudconf.searchcost)) { notify_printf(player, "You don't have enough %s.", mudconf.many_coins); return; } message = alloc_lbuf("do_entrances"); control_thing = Examinable(player, thing); count = 0; for(i = low_bound; i <= high_bound; i++) { if(control_thing || Examinable(player, i)) { switch (Typeof(i)) { case TYPE_EXIT: if(Location(i) == thing) { exit = unparse_object(player, Exits(i), 0); notify_printf(player, "%s (%s)", exit, Name(i)); free_lbuf(exit); count++; } break; case TYPE_ROOM: if(Dropto(i) == thing) { exit = unparse_object(player, i, 0); notify_printf(player, "%s [dropto]", exit); free_lbuf(exit); count++; } break; case TYPE_THING: case TYPE_PLAYER: if(Home(i) == thing) { exit = unparse_object(player, i, 0); notify_printf(player, "%s [home]", exit); free_lbuf(exit); count++; } break; } /* * Check for parents */ if(Parent(i) == thing) { exit = unparse_object(player, i, 0); notify_printf(player, "%s [parent]", exit); free_lbuf(exit); count++; } /* * Check for forwarding */ if(H_Fwdlist(i)) { fp = fwdlist_get(i); if(!fp) continue; for(j = 0; j < fp->count; j++) { if(fp->data[j] != thing) continue; exit = unparse_object(player, i, 0); notify_printf(player, "%s [forward]", exit); free_lbuf(exit); count++; } } } } free_lbuf(message); notify_printf(player, "%d entrance%s found.", count, (count == 1) ? "" : "s"); } /* * check the current location for bugs */ static void sweep_check(dbref player, dbref what, int key, int is_loc) { dbref aowner, parent; int canhear, cancom, isplayer, ispuppet, isconnected, attr, aflags; int is_parent, lev; char *buf, *buf2, *bp, *as, *buff, *s; ATTR *ap; if(Dark(what) && !WizRoy(player) && !mudconf.sweep_dark) return; canhear = 0; cancom = 0; isplayer = 0; ispuppet = 0; isconnected = 0; is_parent = 0; if((key & SWEEP_LISTEN) && (((Typeof(what) == TYPE_EXIT) || is_loc) && Audible(what))) { canhear = 1; } else if(key & SWEEP_LISTEN) { if(Monitor(what)) buff = alloc_lbuf("Hearer"); else buff = NULL; for(attr = atr_head(what, &as); attr; attr = atr_next(&as)) { if(attr == A_LISTEN) { canhear = 1; break; } if(Monitor(what)) { ap = atr_num(attr); if(!ap || (ap->flags & AF_NOPROG)) continue; atr_get_str(buff, what, attr, &aowner, &aflags); /* * Make sure we can execute it */ if((buff[0] != AMATCH_LISTEN) || (aflags & AF_NOPROG)) continue; /* * Make sure there's a : in it */ for(s = buff + 1; *s && (*s != ':'); s++); if(s) { canhear = 1; break; } } } if(buff) free_lbuf(buff); } if((key & SWEEP_COMMANDS) && (Typeof(what) != TYPE_EXIT)) { /* * Look for commands on the object and parents too */ ITER_PARENTS(what, parent, lev) { if(Commer(parent)) { cancom = 1; if(lev) { is_parent = 1; break; } } } } if(key & SWEEP_CONNECT) { if(Connected(what) || (Puppet(what) && Connected(Owner(what))) || (mudconf.player_listen && (Typeof(what) == TYPE_PLAYER) && canhear && Connected(Owner(what)))) isconnected = 1; } if(key & SWEEP_PLAYER || isconnected) { if(Typeof(what) == TYPE_PLAYER) isplayer = 1; if(Puppet(what)) ispuppet = 1; } if(canhear || cancom || isplayer || ispuppet || isconnected) { buf = alloc_lbuf("sweep_check.types"); bp = buf; if(cancom) safe_str((char *) "commands ", buf, &bp); if(canhear) safe_str((char *) "messages ", buf, &bp); if(isplayer) safe_str((char *) "player ", buf, &bp); if(ispuppet) { safe_str((char *) "puppet(", buf, &bp); safe_str(Name(Owner(what)), buf, &bp); safe_str((char *) ") ", buf, &bp); } if(isconnected) safe_str((char *) "connected ", buf, &bp); if(is_parent) safe_str((char *) "parent ", buf, &bp); bp[-1] = '\0'; if(Typeof(what) != TYPE_EXIT) { notify_printf(player, " %s is listening. [%s]", Name(what), buf); } else { buf2 = alloc_lbuf("sweep_check.name"); StringCopy(buf2, Name(what)); for(bp = buf2; *bp && (*bp != ';'); bp++); *bp = '\0'; notify_printf(player, " %s is listening. [%s]", buf2, buf); free_lbuf(buf2); } free_lbuf(buf); } } void do_sweep(dbref player, dbref cause, int key, char *where) { dbref here, sweeploc; int where_key, what_key; where_key = key & (SWEEP_ME | SWEEP_HERE | SWEEP_EXITS); what_key = key & (SWEEP_COMMANDS | SWEEP_LISTEN | SWEEP_PLAYER | SWEEP_CONNECT); if(where && *where) { sweeploc = match_controlled(player, where); if(!Good_obj(sweeploc)) return; } else { sweeploc = player; } if(!where_key) where_key = -1; if(!what_key) what_key = -1; else if(what_key == SWEEP_VERBOSE) what_key = SWEEP_VERBOSE | SWEEP_COMMANDS; /* * Check my location. If I have none or it is dark, check just me. */ if(where_key & SWEEP_HERE) { notify(player, "Sweeping location..."); if(Has_location(sweeploc)) { here = Location(sweeploc); if((here == NOTHING) || (Dark(here) && !mudconf.sweep_dark && !Examinable(player, here))) { notify_quiet(player, "Sorry, it is dark here and you can't search for bugs"); sweep_check(player, sweeploc, what_key, 0); } else { sweep_check(player, here, what_key, 1); for(here = Contents(here); here != NOTHING; here = Next(here)) sweep_check(player, here, what_key, 0); } } else { sweep_check(player, sweeploc, what_key, 0); } } /* * Check exits in my location */ if((where_key & SWEEP_EXITS) && Has_location(sweeploc)) { notify(player, "Sweeping exits..."); for(here = Exits(Location(sweeploc)); here != NOTHING; here = Next(here)) sweep_check(player, here, what_key, 0); } /* * Check my inventory */ if((where_key & SWEEP_ME) && Has_contents(sweeploc)) { notify(player, "Sweeping inventory..."); for(here = Contents(sweeploc); here != NOTHING; here = Next(here)) sweep_check(player, here, what_key, 0); } /* * Check carried exits */ if((where_key & SWEEP_EXITS) && Has_exits(sweeploc)) { notify(player, "Sweeping carried exits..."); for(here = Exits(sweeploc); here != NOTHING; here = Next(here)) sweep_check(player, here, what_key, 0); } notify(player, "Sweep complete."); } /* * Output the sequence of commands needed to duplicate the specified * * object. If you're moving things to another system, your milage * * will almost certainly vary. (i.e. different flags, etc.) */ extern NAMETAB indiv_attraccess_nametab[]; void do_decomp(dbref player, dbref cause, int key, char *name, char *qual) { BOOLEXP *bool; char *got, *thingname, *as, *ltext, *buff, *s; dbref aowner, thing; int val, aflags, ca, atr; ATTR *attr; NAMETAB *np; /* Check for obj/attr first */ olist_push(); if(parse_attrib_wild(player, name, &thing, 0, 1, 0)) { buff = alloc_mbuf("do_decomp.attr_name"); thingname = alloc_lbuf("do_decomp"); if(key & DECOMP_DBREF) { sprintf(thingname, "%d", (int) thing); } else { StringCopy(thingname, Name(thing)); } for(atr = olist_first(); atr != NOTHING; atr = olist_next()) { if((atr == A_NAME || atr == A_LOCK)) continue; attr = atr_num(atr); if(!attr) continue; got = atr_get(thing, atr, &aowner, &aflags); if(Read_attr(player, thing, attr, aowner, aflags)) { if(attr->flags & AF_IS_LOCK) { bool = parse_boolexp(player, got, 1); ltext = unparse_boolexp_decompile(player, bool); free_boolexp(bool); notify_printf(player, "@lock/%s %s=%s", attr->name, strip_ansi(thingname), ltext); } else { StringCopy(buff, attr->name); for(s = thingname; *s; s++) { if(*s == EXIT_DELIMITER) { *s = '\0'; break; } } notify_printf(player, "%c%s %s=%s", ((atr < A_USER_START) ? '@' : '&'), buff, strip_ansi(thingname), got); if(aflags & AF_LOCK) { notify_printf(player, "@lock %s/%s", strip_ansi(thingname), buff); } for(np = indiv_attraccess_nametab; np->name; np++) { if((aflags & np->flag) && check_access(player, np->perm) && (!(np->perm & CA_NO_DECOMP))) { notify_printf(player, "@set %s/%s = %s", strip_ansi(thingname), buff, np->name); } } } } free_lbuf(got); } free_mbuf(buff); free_lbuf(thingname); olist_pop(); return; } olist_pop(); init_match(player, name, TYPE_THING); match_everything(MAT_EXIT_PARENTS); thing = noisy_match_result(); /* * get result */ if(thing == NOTHING) return; if(!Examinable(player, thing)) { notify_quiet(player, "You can only decompile things you can examine."); return; } thingname = atr_get(thing, A_LOCK, &aowner, &aflags); bool = parse_boolexp(player, thingname, 1); /* * Determine the name of the thing to use in reporting and then * report the command to make the thing. */ if(qual && *qual) { StringCopy(thingname, qual); } else { switch (Typeof(thing)) { case TYPE_THING: StringCopy(thingname, Name(thing)); val = OBJECT_DEPOSIT(Pennies(thing)); notify_printf(player, "@create %s=%d", translate_string(thingname, 1), val); break; case TYPE_ROOM: StringCopy(thingname, "here"); notify_printf(player, "@dig/teleport %s", translate_string(Name(thing), 1)); break; case TYPE_EXIT: StringCopy(thingname, Name(thing)); notify_printf(player, "@open %s", translate_string(Name(thing), 1)); for(got = thingname; *got; got++) { if(*got == EXIT_DELIMITER) { *got = '\0'; break; } } break; case TYPE_PLAYER: StringCopy(thingname, "me"); break; } } /* * Report the lock (if any) */ if(bool != TRUE_BOOLEXP) { notify_printf(player, "@lock %s=%s", strip_ansi(thingname), unparse_boolexp_decompile(player, bool)); } free_boolexp(bool); /* * Report attributes */ buff = alloc_mbuf("do_decomp.attr_name"); for(ca = atr_head(thing, &as); ca; ca = atr_next(&as)) { if((ca == A_NAME) || (ca == A_LOCK)) continue; attr = atr_num(ca); if(!attr) continue; if((attr->flags & AF_NOCMD) && !(attr->flags & AF_IS_LOCK)) continue; got = atr_get(thing, ca, &aowner, &aflags); if(Read_attr(player, thing, attr, aowner, aflags)) { if(attr->flags & AF_IS_LOCK) { bool = parse_boolexp(player, got, 1); ltext = unparse_boolexp_decompile(player, bool); free_boolexp(bool); notify_printf(player, "@lock/%s %s=%s", attr->name, thingname, ltext); } else { StringCopy(buff, attr->name); notify_printf(player, "%c%s %s=%s", ((ca < A_USER_START) ? '@' : '&'), buff, strip_ansi(thingname), got); if(aflags & AF_LOCK) { notify_printf(player, "@lock %s/%s", strip_ansi(thingname), buff); } for(np = indiv_attraccess_nametab; np->name; np++) { if((aflags & np->flag) && check_access(player, np->perm) && (!(np->perm & CA_NO_DECOMP))) { notify_printf(player, "@set %s/%s = %s", strip_ansi(thingname), buff, np->name); } } } } free_lbuf(got); } free_mbuf(buff); decompile_flags(player, thing, thingname); decompile_powers(player, thing, thingname); /* * If the object has a parent, report it */ if(Parent(thing) != NOTHING) notify_printf(player, "@parent %s=#%d", strip_ansi(thingname), Parent(thing)); /* * If the object has a zone, report it */ if(Zone(thing) != NOTHING) notify_printf(player, "@chzone %s=#%d", strip_ansi(thingname), Zone(thing)); free_lbuf(thingname); }