mux/src/look.cpp

Go to the documentation of this file.
00001 // look.cpp -- Commands which look at things.
00002 //
00003 // $Id: look.cpp,v 1.47 2007/04/14 04:57:05 sdennis Exp $
00004 //
00005 // MUX 2.4
00006 // Copyright (C) 1998 through 2004 Solid Vertical Domains, Ltd. All
00007 // rights not explicitly given are reserved.
00008 //
00009 #include "copyright.h"
00010 #include "autoconf.h"
00011 #include "config.h"
00012 #include "externs.h"
00013 
00014 #include "ansi.h"
00015 #include "attrs.h"
00016 #include "command.h"
00017 #include "interface.h"
00018 #include "powers.h"
00019 
00020 #ifdef REALITY_LVLS
00021 #include "levels.h"
00022 #endif /* REALITY_LVLS */
00023 
00024 #if defined(WOD_REALMS) || defined(REALITY_LVLS)
00025 #define NORMAL_REALM  0
00026 #define UMBRA_REALM   1
00027 #define SHROUD_REALM  2
00028 #define MATRIX_REALM  3
00029 #define FAE_REALM     4
00030 #define CHIMERA_REALM 5
00031 #define BLIND_REALM   6
00032 #define STAFF_REALM   7
00033 #define NUMBER_OF_REALMS 8
00034 
00035 static int RealmActions[NUMBER_OF_REALMS] =
00036 {
00037     REALM_DO_NORMALLY_SEEN,
00038     REALM_DO_SHOW_UMBRADESC,
00039     REALM_DO_SHOW_WRAITHDESC,
00040     REALM_DO_SHOW_MATRIXDESC,
00041     REALM_DO_SHOW_FAEDESC,
00042     REALM_DO_SHOW_FAEDESC,
00043     REALM_DO_HIDDEN_FROM_YOU,
00044     REALM_DO_NORMALLY_SEEN
00045 };
00046 
00047 // Umbra and Matrix are realms unto themselves, so if you aren't in the same
00048 // realm as what you're looking at, you can't see it.
00049 //
00050 // Normal things can't see shroud things, but shroud things can see normal things.
00051 //
00052 // Only Fae and Chimera can see Chimera.
00053 //
00054 #define MAP_SEEN     0 // Show this to that.
00055 #define MAP_HIDE     1 // Always hide this from that.
00056 #define MAP_NO_ADESC 2 // Don't trigger DESC actions on that.
00057 #define MAP_MEDIUM   4 // Hide this from that unless that is a medium and this is moving or talking.
00058 
00059 static int RealmHiddenMap[NUMBER_OF_REALMS][NUMBER_OF_REALMS] =
00060 {
00061     /* NORMAL  LOOKER */ {     MAP_SEEN, MAP_HIDE, MAP_MEDIUM, MAP_HIDE,     MAP_SEEN, MAP_HIDE, MAP_NO_ADESC, MAP_SEEN},
00062     /* UMBRA   LOOKER */ {     MAP_HIDE, MAP_SEEN, MAP_MEDIUM, MAP_HIDE,     MAP_HIDE, MAP_HIDE,     MAP_HIDE, MAP_SEEN},
00063     /* SHROUD  LOOKER */ { MAP_NO_ADESC, MAP_HIDE,   MAP_SEEN, MAP_HIDE, MAP_NO_ADESC, MAP_HIDE, MAP_NO_ADESC, MAP_SEEN},
00064     /* MATRIX  LOOKER */ {     MAP_HIDE, MAP_HIDE, MAP_MEDIUM, MAP_SEEN,     MAP_HIDE, MAP_HIDE,     MAP_HIDE, MAP_SEEN},
00065     /* FAE     LOOKER */ {     MAP_SEEN, MAP_HIDE, MAP_MEDIUM, MAP_HIDE,     MAP_SEEN, MAP_SEEN, MAP_NO_ADESC, MAP_SEEN},
00066     /* CHIMERA LOOKER */ { MAP_NO_ADESC, MAP_HIDE, MAP_MEDIUM, MAP_HIDE,     MAP_SEEN, MAP_SEEN, MAP_NO_ADESC, MAP_SEEN},
00067     /* BLIND   LOOKER */ {     MAP_HIDE, MAP_HIDE,   MAP_HIDE, MAP_HIDE,     MAP_HIDE, MAP_HIDE,     MAP_HIDE, MAP_SEEN},
00068     /* STAFF   LOOKER */ {     MAP_SEEN, MAP_SEEN,   MAP_SEEN, MAP_SEEN,     MAP_SEEN, MAP_SEEN,     MAP_SEEN, MAP_SEEN}
00069 };
00070 
00071 static int RealmExitsMap[NUMBER_OF_REALMS][NUMBER_OF_REALMS] =
00072 {
00073     /* NORMAL  LOOKER */ { MAP_SEEN, MAP_HIDE, MAP_HIDE, MAP_HIDE, MAP_HIDE, MAP_HIDE, MAP_HIDE, MAP_HIDE},
00074     /* UMBRA   LOOKER */ { MAP_SEEN, MAP_SEEN, MAP_HIDE, MAP_HIDE, MAP_HIDE, MAP_HIDE, MAP_HIDE, MAP_HIDE},
00075     /* SHROUD  LOOKER */ { MAP_SEEN, MAP_HIDE, MAP_SEEN, MAP_HIDE, MAP_HIDE, MAP_HIDE, MAP_HIDE, MAP_HIDE},
00076     /* MATRIX  LOOKER */ { MAP_SEEN, MAP_HIDE, MAP_HIDE, MAP_SEEN, MAP_HIDE, MAP_HIDE, MAP_HIDE, MAP_HIDE},
00077     /* FAE     LOOKER */ { MAP_SEEN, MAP_HIDE, MAP_HIDE, MAP_HIDE, MAP_SEEN, MAP_SEEN, MAP_HIDE, MAP_HIDE},
00078     /* CHIMERA LOOKER */ { MAP_SEEN, MAP_HIDE, MAP_HIDE, MAP_HIDE, MAP_SEEN, MAP_SEEN, MAP_HIDE, MAP_HIDE},
00079     /* BLIND   LOOKER */ { MAP_HIDE, MAP_HIDE, MAP_HIDE, MAP_HIDE, MAP_HIDE, MAP_HIDE, MAP_HIDE, MAP_HIDE},
00080     /* STAFF   LOOKER */ { MAP_SEEN, MAP_SEEN, MAP_SEEN, MAP_SEEN, MAP_SEEN, MAP_SEEN, MAP_SEEN, MAP_SEEN}
00081 };
00082 
00083 static int WhichRealm(dbref what, bool bPeering)
00084 {
00085     int realm = NORMAL_REALM;
00086     if (isMatrix(what))       realm = MATRIX_REALM;
00087     else if (isUmbra(what))   realm = UMBRA_REALM;
00088     else if (isShroud(what))  realm = SHROUD_REALM;
00089     else if (isChimera(what)) realm = CHIMERA_REALM;
00090     else if (isFae(what))     realm = FAE_REALM;
00091 
00092     if (bPeering)
00093     {
00094         char *buff;
00095         dbref owner;
00096         int flags;
00097         int iPeeringRealm = get_atr("PEERING_REALM");
00098         if (0 < iPeeringRealm)
00099         {
00100             buff = atr_get(what, iPeeringRealm, &owner, &flags);
00101             if (*buff)
00102             {
00103                 if      (mux_stricmp(buff, "FAE") == 0)     realm = FAE_REALM;
00104                 else if (mux_stricmp(buff, "CHIMERA") == 0) realm = CHIMERA_REALM;
00105                 else if (mux_stricmp(buff, "SHROUD") == 0)  realm = SHROUD_REALM;
00106                 else if (mux_stricmp(buff, "UMBRA") == 0)   realm = UMBRA_REALM;
00107                 else if (mux_stricmp(buff, "MATRIX") == 0)  realm = MATRIX_REALM;
00108                 else if (mux_stricmp(buff, "NORMAL") == 0)  realm = NORMAL_REALM;
00109                 else if (mux_stricmp(buff, "BLIND") == 0)   realm = BLIND_REALM;
00110                 else if (mux_stricmp(buff, "STAFF") == 0)   realm = STAFF_REALM;
00111             }
00112             free_lbuf(buff);
00113         }
00114     }
00115     return realm;
00116 }
00117 
00118 static int HandleObfuscation(dbref looker, dbref lookee, int threshhold)
00119 {
00120     int iReturn = REALM_DO_NORMALLY_SEEN;
00121     if (isObfuscate(lookee))
00122     {
00123         char *buff;
00124         int iObfuscateLevel = 0;
00125         dbref owner;
00126         int flags;
00127         buff = atr_get(lookee, get_atr("OBF_LEVEL"), &owner, &flags);
00128         if (*buff)
00129         {
00130             iObfuscateLevel = mux_atol(buff);
00131         }
00132         free_lbuf(buff);
00133 
00134         // For OBF_LEVELS of 0, 1, and 2, we show the regular description.
00135         // 3 and above start showing a different OBFDESC.
00136         //
00137         if (3 <= iObfuscateLevel)
00138         {
00139             iReturn = REALM_DO_SHOW_OBFDESC;
00140         }
00141         if (threshhold < iObfuscateLevel)
00142         {
00143             int iHeightenSensesLevel = 0;
00144             if (isHeightenedSenses(looker))
00145             {
00146                 buff = atr_get(looker, get_atr("HSS_LEVEL"), &owner, &flags);
00147                 if (*buff)
00148                 {
00149                     iHeightenSensesLevel = mux_atol(buff);
00150                 }
00151                 free_lbuf(buff);
00152             }
00153 
00154             if (iHeightenSensesLevel < iObfuscateLevel)
00155             {
00156                 iReturn = REALM_DO_HIDDEN_FROM_YOU;
00157             }
00158             else if (iObfuscateLevel == iHeightenSensesLevel)
00159             {
00160                 if (RandomINT32(0,1))
00161                 {
00162                     iReturn = REALM_DO_HIDDEN_FROM_YOU;
00163                 }
00164             }
00165         }
00166     }
00167     return iReturn;
00168 }
00169 int DoThingToThingVisibility(dbref looker, dbref lookee, int action_state)
00170 {
00171     // If the looker is a room, then there is some contents/recursion stuff
00172     // that happens in the rest of the game code. We'll be called later for
00173     // each item in the room, things that are nearby the room, etc.
00174     //
00175     if (isRoom(looker))
00176     {
00177         return REALM_DO_NORMALLY_SEEN;
00178     }
00179 
00180     if (Staff(looker))
00181     {
00182         if (Connected(looker))
00183         {
00184             // Staff players can see everything
00185             //
00186             return REALM_DO_NORMALLY_SEEN;
00187         }
00188 
00189         if (isThing(looker))
00190         {
00191             // Wizard things in the master room can see everything.
00192             //
00193             if (Location(looker) == mudconf.master_room)
00194             {
00195                 return REALM_DO_NORMALLY_SEEN;
00196             }
00197         }
00198     }
00199     int realmLooker = WhichRealm(looker, isPeering(looker));
00200     int realmLookee = WhichRealm(lookee, false);
00201 
00202     // You can always see yourself.
00203     //
00204     if (looker == lookee)
00205     {
00206         return RealmActions[realmLooker];
00207     }
00208 
00209     bool bDisableADESC = false;
00210     if (isRoom(lookee) || isExit(lookee))
00211     {
00212         // All realms see normal rooms and exits, however, if a realm
00213         // specific description exists, they use that one. If a room or exit
00214         // is flagged with a specific realm, then -only- players and things of
00215         // that realm can see it.
00216         //
00217         // Fae and Chimera are treated as the same realm for this purpose.
00218         //
00219         if (RealmExitsMap[realmLooker][realmLookee] == MAP_HIDE)
00220         {
00221             return REALM_DO_HIDDEN_FROM_YOU;
00222         }
00223     }
00224     else
00225     {
00226         if (Staff(lookee))
00227         {
00228             // Staff players are seen in every realm.
00229             //
00230             if (Connected(lookee))
00231             {
00232                 return REALM_DO_NORMALLY_SEEN;
00233             }
00234 
00235             if (isThing(lookee))
00236             {
00237                 // Everyone can use wizard things in the master room.
00238                 //
00239                 // Wizard things that aren't in the master room follow the same
00240                 // realm-rules as everything else.
00241                 //
00242                 if (Location(lookee) == mudconf.master_room)
00243                 {
00244                     return REALM_DO_NORMALLY_SEEN;
00245                 }
00246             }
00247         }
00248 
00249         int iMap = RealmHiddenMap[realmLooker][realmLookee];
00250         if (iMap & MAP_HIDE)
00251         {
00252             return REALM_DO_HIDDEN_FROM_YOU;
00253         }
00254         if (iMap & MAP_MEDIUM)
00255         {
00256             if (isMedium(looker))
00257             {
00258                 if (action_state == ACTION_IS_STATIONARY)
00259                 {
00260                     // Even Mediums can't hear it if the Wraith is just standing still.
00261                     //
00262                     return REALM_DO_HIDDEN_FROM_YOU;
00263                 }
00264             }
00265             else
00266             {
00267                 return REALM_DO_HIDDEN_FROM_YOU;
00268             }
00269         }
00270         if (iMap & MAP_NO_ADESC)
00271         {
00272             bDisableADESC = true;
00273         }
00274     }
00275 
00276     // Do default see rules.
00277     //
00278     int iReturn = RealmActions[realmLooker];
00279     if (iReturn == REALM_DO_HIDDEN_FROM_YOU)
00280     {
00281         return iReturn;
00282     }
00283 
00284     // Do Obfuscate/Heighten Senses rules.
00285     //
00286     int threshhold = 0;
00287     switch (action_state)
00288     {
00289     case ACTION_IS_STATIONARY:
00290         threshhold = 0;
00291         break;
00292 
00293     case ACTION_IS_MOVING:
00294         threshhold = 1;
00295         break;
00296 
00297     case ACTION_IS_TALKING:
00298         if (bDisableADESC)
00299         {
00300             iReturn |= REALM_DISABLE_ADESC;
00301         }
00302         return iReturn;
00303     }
00304     int iObfReturn = HandleObfuscation(looker, lookee, threshhold);
00305     switch (iObfReturn)
00306     {
00307     case REALM_DO_SHOW_OBFDESC:
00308     case REALM_DO_HIDDEN_FROM_YOU:
00309         iReturn = iObfReturn;
00310         break;
00311     }
00312 
00313     // Decide whether to disable ADESC or not. If we can look at them,
00314     // and ADESC isn't -already- disabled via SHROUD looking at NORMAL (see above).
00315     // then, ADESC may be disabled here if the looker is Obfuscated to the lookee.
00316     //
00317     if (iReturn != REALM_DO_HIDDEN_FROM_YOU && !bDisableADESC)
00318     {
00319         if (REALM_DO_HIDDEN_FROM_YOU == HandleObfuscation(lookee, looker, 0))
00320         {
00321             bDisableADESC = true;
00322         }
00323     }
00324     if (bDisableADESC)
00325     {
00326         iReturn |= REALM_DISABLE_ADESC;
00327     }
00328     return iReturn;
00329 }
00330 
00331 static void LetDescriptionsDefault(dbref thing, int *piDESC, int *piADESC, int RealmDirective)
00332 {
00333     int   iDesc = 0;
00334     dbref owner;
00335     int   flags;
00336 
00337     *piDESC = A_DESC;
00338     *piADESC = A_ADESC;
00339 
00340     if (RealmDirective & REALM_DISABLE_ADESC)
00341     {
00342         *piADESC = 0;
00343     }
00344     switch (RealmDirective & REALM_DO_MASK)
00345     {
00346     case REALM_DO_SHOW_OBFDESC:
00347         iDesc = get_atr("OBFDESC");
00348         break;
00349 
00350     case REALM_DO_SHOW_WRAITHDESC:
00351         iDesc = get_atr("WRAITHDESC");
00352         *piADESC = 0;
00353         break;
00354 
00355     case REALM_DO_SHOW_UMBRADESC:
00356         iDesc = get_atr("UMBRADESC");
00357         break;
00358 
00359     case REALM_DO_SHOW_MATRIXDESC:
00360         iDesc = get_atr("MATRIXDESC");
00361         break;
00362 
00363     case REALM_DO_SHOW_FAEDESC:
00364         iDesc = get_atr("FAEDESC");
00365         break;
00366     }
00367 
00368     if (iDesc > 0)
00369     {
00370         char *buff = atr_pget(thing, iDesc, &owner, &flags);
00371         if (buff)
00372         {
00373             if (*buff)
00374             {
00375                 *piDESC = iDesc;
00376             }
00377             free_lbuf(buff);
00378         }
00379     }
00380 }
00381 #endif
00382 
00383 static void look_exits(dbref player, dbref loc, const char *exit_name)
00384 {
00385     // Make sure location has exits.
00386     //
00387     if (  !Good_obj(loc)
00388        || !Has_exits(loc))
00389     {
00390         return;
00391     }
00392 
00393     dbref thing, parent;
00394     char *buff, *e, *buff1, *e1;
00395     const char *s;
00396 
00397     // make sure there is at least one visible exit.
00398     //
00399     bool bFoundAnyDisplayable = false;
00400     bool bFoundAny = false;
00401     int key = 0;
00402     int lev;
00403 #ifdef REALITY_LVLS
00404     if (Dark(loc) || !IsReal(player, loc))
00405 #else
00406     if (Dark(loc))
00407 #endif /* REALITY_LVLS */
00408     {
00409         key |= VE_BASE_DARK;
00410     }
00411     ITER_PARENTS(loc, parent, lev)
00412     {
00413         key &= ~VE_LOC_DARK;
00414         if (Dark(parent))
00415         {
00416             key |= VE_LOC_DARK;
00417         }
00418         DOLIST(thing, Exits(parent))
00419         {
00420             bFoundAny = true;
00421             if (exit_displayable(thing, player, key))
00422             {
00423                 bFoundAnyDisplayable = true;
00424                 break;
00425             }
00426         }
00427         if (bFoundAnyDisplayable)
00428         {
00429             break;
00430         }
00431     }
00432 
00433     if (!bFoundAny)
00434     {
00435         return;
00436     }
00437 
00438     // Retrieve the ExitFormat attribute from the location, evaluate and display
00439     // the results in lieu of the traditional exits list if it exists.
00440     //
00441     dbref aowner;
00442     int aflags;
00443     char *ExitFormatBuffer = atr_pget(loc, A_EXITFORMAT, &aowner, &aflags);
00444     char *ExitFormat = ExitFormatBuffer;
00445 
00446     bool bDisplayExits = bFoundAnyDisplayable;
00447     if (*ExitFormat)
00448     {
00449         char *VisibleObjectList = alloc_lbuf("look_exits.VOL");
00450         char *tPtr = VisibleObjectList;
00451 
00452         ITL pContext;
00453         ItemToList_Init(&pContext, VisibleObjectList, &tPtr, '#');
00454 
00455         ITER_PARENTS(loc, parent, lev)
00456         {
00457             key &= ~VE_LOC_DARK;
00458             if (Dark(parent))
00459             {
00460                 key |= VE_LOC_DARK;
00461             }
00462 
00463             bool bShortCircuit = false;
00464             DOLIST(thing, Exits(parent))
00465             {
00466                 if (  exit_displayable(thing, player, key)
00467                    && !ItemToList_AddInteger(&pContext, thing))
00468                 {
00469                     bShortCircuit = true;
00470                     break;
00471                 }
00472             }
00473             if (bShortCircuit) break;
00474         }
00475         ItemToList_Final(&pContext);
00476 
00477         char *FormatOutput = alloc_lbuf("look_exits.FO");
00478         tPtr = FormatOutput;
00479 
00480         char *preserve[MAX_GLOBAL_REGS];
00481         int preserve_len[MAX_GLOBAL_REGS];
00482         save_and_clear_global_regs("look_exits_save", preserve, preserve_len);
00483 
00484         mux_exec(FormatOutput, &tPtr, loc, player, player,
00485                 EV_FCHECK | EV_EVAL | EV_TOP,
00486                 &ExitFormat, &VisibleObjectList, 1);
00487         *tPtr = '\0';
00488 
00489         restore_global_regs("look_exits_restore", preserve, preserve_len);
00490         notify(player, FormatOutput);
00491 
00492         free_lbuf(FormatOutput);
00493         free_lbuf(VisibleObjectList);
00494 
00495         bDisplayExits = 0;
00496     }
00497     free_lbuf(ExitFormatBuffer);
00498 
00499     if (!bDisplayExits)
00500     {
00501         return;
00502     }
00503 
00504     // Display the list of exit names
00505     //
00506     notify(player, exit_name);
00507     e = buff = alloc_lbuf("look_exits");
00508     e1 = buff1 = alloc_lbuf("look_exits2");
00509     ITER_PARENTS(loc, parent, lev)
00510     {
00511         key &= ~VE_LOC_DARK;
00512         if (Dark(parent))
00513         {
00514             key |= VE_LOC_DARK;
00515         }
00516         if (Transparent(loc))
00517         {
00518             DOLIST(thing, Exits(parent))
00519             {
00520                 if (exit_displayable(thing, player, key))
00521                 {
00522                     strcpy(buff, Name(thing));
00523                     for (e = buff; *e && *e != ';'; e++)
00524                     {
00525                         ; // Nothing.
00526                     }
00527                     *e = '\0';
00528                     notify(player, tprintf("%s leads to %s.", buff, Name(Location(thing))));
00529                 }
00530             }
00531         }
00532         else
00533         {
00534             DOLIST(thing, Exits(parent))
00535             {
00536                 if (exit_displayable(thing, player, key))
00537                 {
00538                     e1 = buff1;
00539 
00540                     // Put the exit name in buff1.
00541                     //
00542                     // chop off first exit alias to display
00543                     //
00544                     if (buff != e)
00545                     {
00546                         safe_str("  ", buff, &e);
00547                     }
00548 
00549                     for (s = Name(thing); *s && (*s != ';'); s++)
00550                     {
00551                         safe_chr(*s, buff1, &e1);
00552                     }
00553 
00554                     *e1 = 0;
00555                     /* Copy the exit name into 'buff' */
00556                     if (Html(player))
00557                     {
00558                         /* XXX The exit name needs to be HTML escaped. */
00559                         safe_str("<a xch_cmd=\"", buff, &e);
00560                         safe_str(buff1, buff, &e);
00561                         safe_str("\"> ", buff, &e);
00562                         html_escape(buff1, buff, &e);
00563                         safe_str(" </a>", buff, &e);
00564                     }
00565                     else
00566                     {
00567                         /* Append this exit to the list */
00568                         safe_str(buff1, buff, &e);
00569                     }
00570                 }
00571             }
00572         }
00573     }
00574 
00575     if (!Transparent(loc))
00576     {
00577         if (Html(player))
00578         {
00579             safe_str("\r\n", buff, &e);
00580             *e = 0;
00581             notify_html(player, buff);
00582         }
00583         else
00584         {
00585             *e = 0;
00586             notify(player, buff);
00587         }
00588     }
00589     free_lbuf(buff);
00590     free_lbuf(buff1);
00591 }
00592 
00593 #define CONTENTS_LOCAL  0
00594 #define CONTENTS_NESTED 1
00595 #define CONTENTS_REMOTE 2
00596 
00597 static void look_contents(dbref player, dbref loc, const char *contents_name, int style)
00598 {
00599     dbref thing;
00600     char *buff;
00601     char *html_buff, *html_cp;
00602     char remote_num[32];
00603 
00604     // Check to see if he can see the location.
00605     //
00606 #ifdef REALITY_LVLS
00607      bool can_see_loc = ( !Dark(loc) && IsReal(player, loc)
00608 #else
00609      bool can_see_loc = (  !Dark(loc)
00610 #endif /* REALITY_LVLS */
00611                        || (mudconf.see_own_dark && Examinable(player, loc)));
00612 
00613     dbref aowner;
00614     int aflags;
00615     char *ContentsFormatBuffer = atr_pget(loc, A_CONFORMAT, &aowner, &aflags);
00616     char *ContentsFormat = ContentsFormatBuffer;
00617 
00618     bool bDisplayContents = true;
00619     if (*ContentsFormat)
00620     {
00621         char *VisibleObjectList = alloc_lbuf("look_contents.VOL");
00622         char *tPtr = VisibleObjectList;
00623 
00624         ITL pContext;
00625         ItemToList_Init(&pContext, VisibleObjectList, &tPtr, '#');
00626 
00627         DOLIST(thing, Contents(loc))
00628         {
00629 #if defined(WOD_REALMS) || defined(REALITY_LVLS)
00630             if (  can_see(player, thing, can_see_loc)
00631                && (REALM_DO_HIDDEN_FROM_YOU != DoThingToThingVisibility(player,
00632                                                 thing, ACTION_IS_STATIONARY)) )
00633 #else
00634             if (can_see(player, thing, can_see_loc))
00635 #endif
00636             {
00637                 if (!ItemToList_AddInteger(&pContext, thing))
00638                 {
00639                     break;
00640                 }
00641             }
00642         }
00643         ItemToList_Final(&pContext);
00644 
00645         char *ContentsNameScratch = alloc_lbuf("look_contents.CNS");
00646         tPtr = ContentsNameScratch;
00647 
00648         safe_str(contents_name, ContentsNameScratch, &tPtr);
00649         *tPtr = '\0';
00650 
00651         char *FormatOutput = alloc_lbuf("look_contents.FO");
00652         tPtr = FormatOutput;
00653 
00654         char* ParameterList[] =
00655             { VisibleObjectList, ContentsNameScratch };
00656 
00657         char *preserve[MAX_GLOBAL_REGS];
00658         int preserve_len[MAX_GLOBAL_REGS];
00659         save_and_clear_global_regs("look_contents_save", preserve, preserve_len);
00660 
00661         mux_exec(FormatOutput, &tPtr, loc, player, player,
00662                 EV_FCHECK | EV_EVAL | EV_TOP,
00663                 &ContentsFormat, ParameterList, 2);
00664         *tPtr = '\0';
00665 
00666         restore_global_regs("look_contents_restore", preserve, preserve_len);
00667         notify(player, FormatOutput);
00668 
00669         free_lbuf(FormatOutput);
00670         free_lbuf(ContentsNameScratch);
00671         free_lbuf(VisibleObjectList);
00672 
00673         bDisplayContents = false;
00674     }
00675     free_lbuf(ContentsFormatBuffer);
00676 
00677     if (!bDisplayContents)
00678     {
00679         return;
00680     }
00681 
00682     html_buff = html_cp = alloc_lbuf("look_contents");
00683 
00684     // Check to see if there is anything there.
00685     //
00686     DOLIST(thing, Contents(loc))
00687     {
00688 #if defined(WOD_REALMS) || defined(REALITY_LVLS)
00689         if (  can_see(player, thing, can_see_loc)
00690            && (REALM_DO_HIDDEN_FROM_YOU != DoThingToThingVisibility(player, thing, ACTION_IS_STATIONARY)))
00691 #else
00692         if (can_see(player, thing, can_see_loc))
00693 #endif
00694         {
00695             // Something exists! Show him everything.
00696             //
00697             notify(player, contents_name);
00698             DOLIST(thing, Contents(loc))
00699             {
00700 #if defined(WOD_REALMS) || defined(REALITY_LVLS)
00701                 if (  can_see(player, thing, can_see_loc)
00702                    && (REALM_DO_HIDDEN_FROM_YOU != DoThingToThingVisibility(player, thing, ACTION_IS_STATIONARY)))
00703 #else
00704                 if (can_see(player, thing, can_see_loc))
00705 #endif
00706                 {
00707                     buff = unparse_object(player, thing, true);
00708                     html_cp = html_buff;
00709                     if (Html(player))
00710                     {
00711                         safe_str("<a xch_cmd=\"look ", html_buff, &html_cp);
00712                         switch (style)
00713                         {
00714                         case CONTENTS_LOCAL:
00715                             safe_str(Name(thing), html_buff, &html_cp);
00716                             break;
00717                         case CONTENTS_NESTED:
00718                             safe_str(Name(Location(thing)), html_buff, &html_cp);
00719                             safe_str("'s ", html_buff, &html_cp);
00720                             safe_str(Name(thing), html_buff, &html_cp);
00721                             break;
00722 
00723                         case CONTENTS_REMOTE:
00724 
00725                             remote_num[0] = '#';
00726                             mux_ltoa(thing, remote_num+1);
00727                             safe_str(remote_num, html_buff, &html_cp);
00728                             break;
00729 
00730                         default:
00731 
00732                             break;
00733                         }
00734                         safe_str("\">", html_buff, &html_cp);
00735                         html_escape(buff, html_buff, &html_cp);
00736                         safe_str("</a>\r\n", html_buff, &html_cp);
00737                         *html_cp = 0;
00738                         notify_html(player, html_buff);
00739                     }
00740                     else
00741                     {
00742                         notify(player, buff);
00743                     }
00744                     free_lbuf(buff);
00745                 }
00746             }
00747             break;  // we're done.
00748         }
00749     }
00750     free_lbuf(html_buff);
00751 }
00752 
00753 typedef struct
00754 {
00755     int mask;
00756     char letter;
00757 } ATTR_DECODE_ENTRY, *PATTR_DECODE_ENTRY;
00758 
00759 static ATTR_DECODE_ENTRY attr_decode_table[] =
00760 {
00761     { AF_LOCK,    '+' },
00762     { AF_NOPROG,  '$' },
00763     { AF_CASE,    'C' },
00764     { AF_HTML,    'H' },
00765     { AF_PRIVATE, 'I' },
00766     { AF_NOPARSE, 'P' },
00767     { AF_REGEXP,  'R' },
00768     { AF_VISUAL,  'V' },
00769     { AF_MDARK,   'M' },
00770     { AF_WIZARD,  'W' },
00771     { 0, 0 }
00772 };
00773 
00774 size_t decode_attr_flags(int aflags, char *buff)
00775 {
00776     char *p = buff;
00777     PATTR_DECODE_ENTRY pEntry;
00778     for (pEntry = attr_decode_table; pEntry->mask; pEntry++)
00779     {
00780         if (aflags & pEntry->mask)
00781         {
00782             *p++ = pEntry->letter;
00783         }
00784     }
00785     *p = '\0';
00786     return p - buff;
00787 }
00788 
00789 static void view_atr
00790 (
00791     dbref player,
00792     dbref thing,
00793     ATTR *ap,
00794     char *text,
00795     dbref aowner,
00796     int aflags,
00797     bool skip_tag
00798 )
00799 {
00800     char *buf;
00801 
00802     if (ap->flags & AF_IS_LOCK)
00803     {
00804         BOOLEXP *pBoolExp = parse_boolexp(player, text, true);
00805         text = unparse_boolexp(player, pBoolExp);
00806         free_boolexp(pBoolExp);
00807     }
00808 
00809     // If we don't control the object or own the attribute, hide the
00810     // attr owner and flag info.
00811     //
00812     if (  !Controls(player, thing)
00813        && Owner(player) != aowner)
00814     {
00815         if (  skip_tag
00816            && ap->number == A_DESC)
00817         {
00818             buf = text;
00819         }
00820         else
00821         {
00822             buf = tprintf("%s%s:%s %s", ANSI_HILITE, ap->name, ANSI_NORMAL, text);
00823         }
00824         notify(player, buf);
00825         return;
00826     }
00827 
00828     // Generate flags.
00829     //
00830     char xbuf[11];
00831     decode_attr_flags(aflags, xbuf);
00832 
00833     if (  aowner != Owner(thing)
00834        && aowner != NOTHING)
00835     {
00836         buf = tprintf("%s%s [#%d%s]:%s %s", ANSI_HILITE,
00837             ap->name, aowner, xbuf, ANSI_NORMAL, text);
00838     }
00839     else if (*xbuf)
00840     {
00841         buf = tprintf("%s%s [%s]:%s %s", ANSI_HILITE, ap->name,
00842             xbuf, ANSI_NORMAL, text);
00843     }
00844     else if (  !skip_tag
00845             || ap->number != A_DESC)
00846     {
00847         buf = tprintf("%s%s:%s %s", ANSI_HILITE, ap->name, ANSI_NORMAL, text);
00848     }
00849     else
00850     {
00851         buf = text;
00852     }
00853     notify(player, buf);
00854 }
00855 
00856 static void look_atrs1
00857 (
00858     dbref player,
00859     dbref thing,
00860     dbref othing,
00861     bool  check_exclude,
00862     bool  hash_insert
00863 )
00864 {
00865     bool bFoundCommands = false;
00866     bool bFoundListens  = false;
00867 
00868     char *as;
00869     for (int ca = atr_head(thing, &as); ca; ca = atr_next(&as))
00870     {
00871         if (  ca == A_DESC
00872            || ca == A_LOCK)
00873         {
00874             continue;
00875         }
00876 
00877         ATTR *pattr = atr_num(ca);
00878         if (!pattr)
00879         {
00880             continue;
00881         }
00882 
00883         ATTR cattr;
00884         memcpy(&cattr, pattr, sizeof(ATTR));
00885 
00886         // Should we exclude this attr?
00887         //
00888         if (  check_exclude
00889            && (  (pattr->flags & AF_PRIVATE)
00890               || hashfindLEN(&ca, sizeof(ca), &mudstate.parent_htab)))
00891         {
00892             continue;
00893         }
00894 
00895         int   aflags;
00896         dbref aowner;
00897         char *buf = atr_get(thing, ca, &aowner, &aflags);
00898 
00899         if (!(aflags & AF_NOPROG))
00900         {
00901             if (  AMATCH_CMD    == buf[0]
00902                || AMATCH_LISTEN == buf[0])
00903             {
00904                 char *s = strchr(buf+1, ':');
00905                 if (s)
00906                 {
00907                     if (AMATCH_CMD == buf[0])
00908                     {
00909                         bFoundCommands = true;
00910                     }
00911                     else
00912                     {
00913                         bFoundListens = true;
00914                     }
00915                 }
00916             }
00917         }
00918 
00919         if (bCanReadAttr(player, othing, &cattr, false))
00920         {
00921             if (!(check_exclude && (aflags & AF_PRIVATE)))
00922             {
00923                 if (hash_insert)
00924                 {
00925                     hashaddLEN(&ca, sizeof(ca), pattr, &mudstate.parent_htab);
00926                 }
00927                 view_atr(player, thing, &cattr, buf, aowner, aflags, false);
00928             }
00929         }
00930         free_lbuf(buf);
00931     }
00932 
00933     if (bFoundCommands)
00934     {
00935         mudstate.bfNoCommands.Clear(thing);
00936         mudstate.bfCommands.Set(thing);
00937     }
00938     else
00939     {
00940         mudstate.bfCommands.Clear(thing);
00941         mudstate.bfNoCommands.Set(thing);
00942     }
00943 
00944     if (bFoundListens)
00945     {
00946         mudstate.bfNoListens.Clear(thing);
00947         mudstate.bfListens.Set(thing);
00948     }
00949     else
00950     {
00951         mudstate.bfListens.Clear(thing);
00952         mudstate.bfNoListens.Set(thing);
00953     }
00954 }
00955 
00956 static void look_atrs(dbref player, dbref thing, bool check_parents)
00957 {
00958     dbref parent;
00959     int lev;
00960     bool check_exclude, hash_insert;
00961 
00962     if (!check_parents)
00963     {
00964         look_atrs1(player, thing, thing, false, false);
00965     }
00966     else
00967     {
00968         hash_insert = true;
00969         check_exclude = false;
00970         hashflush(&mudstate.parent_htab);
00971         ITER_PARENTS(thing, parent, lev)
00972         {
00973             if (!Good_obj(Parent(parent)))
00974             {
00975                 hash_insert = false;
00976             }
00977             look_atrs1(player, parent, thing, check_exclude, hash_insert);
00978             check_exclude = true;
00979         }
00980     }
00981 }
00982 
00983 static bool show_a_desc(dbref player, dbref loc)
00984 {
00985     int iDescDefault = A_DESC;
00986     int iADescDefault = A_ADESC;
00987 #if defined(WOD_REALMS) || defined(REALITY_LVLS)
00988     int iRealmDirective = DoThingToThingVisibility(player, loc, ACTION_IS_STATIONARY);
00989     if (REALM_DO_HIDDEN_FROM_YOU == iRealmDirective)
00990     {
00991         return true;
00992     }
00993     LetDescriptionsDefault(loc, &iDescDefault, &iADescDefault, iRealmDirective);
00994 #endif
00995 
00996     bool ret = false;
00997 
00998     dbref aowner;
00999     int aflags;
01000     bool indent = (isRoom(loc) && mudconf.indent_desc && atr_get_raw(loc, A_DESC));
01001 
01002     char *DescFormatBuffer = atr_pget(loc, A_DESCFORMAT, &aowner, &aflags);
01003     char *DescFormat = DescFormatBuffer;
01004     if (*DescFormat)
01005     {
01006         char *FormatOutput = alloc_lbuf("look_description.FO");
01007         char *tPtr = FormatOutput;
01008 
01009         ATTR *cattr = atr_num(iDescDefault);
01010 
01011         char *tbuf1 = atr_pget(loc, iDescDefault, &aowner, &aflags);
01012         char *str = tbuf1;
01013         char *temp = alloc_lbuf("look_description.ET");
01014         char *bp = temp;
01015         mux_exec(temp, &bp, loc, player, player,
01016                EV_FCHECK | EV_EVAL | EV_TOP,
01017                &str, (char **)NULL, 0);
01018         *bp = '\0';
01019 
01020         char *attrname = alloc_lbuf("look_description.AN");
01021         char *cp = attrname;
01022 
01023         safe_str(cattr->name, attrname, &cp);
01024         *cp = '\0';
01025         char* ParameterList[] =
01026             { temp, attrname };
01027 
01028         mux_exec(FormatOutput, &tPtr, loc, player, player,
01029                 EV_FCHECK | EV_EVAL | EV_TOP,
01030                 &DescFormat, ParameterList, 2);
01031         *tPtr = '\0';
01032 
01033         notify(player, FormatOutput);
01034 #ifdef REALITY_LVLS
01035         did_it_rlevel(player, loc, 0, NULL, A_ODESC, NULL, iADescDefault, (char **) NULL, 0);
01036 #else
01037         did_it(player, loc, 0, NULL, A_ODESC, NULL, iADescDefault, (char **) NULL, 0);
01038 #endif /* REALITY_LVLS */
01039 
01040         free_lbuf(tbuf1);
01041         free_lbuf(attrname);
01042         free_lbuf(FormatOutput);
01043         free_lbuf(temp);
01044 
01045         ret = true;
01046     }
01047     else
01048     {
01049         char *got;
01050         if (Html(player))
01051         {
01052             got = atr_pget(loc, A_HTDESC, &aowner, &aflags);
01053             if (*got)
01054             {
01055 #ifdef REALITY_LVLS
01056                 did_it_rlevel(player, loc, A_HTDESC, NULL, A_ODESC, NULL, A_ADESC, (char **) NULL, 0);
01057 #else
01058                 did_it(player, loc, A_HTDESC, NULL, A_ODESC, NULL, A_ADESC, (char **) NULL, 0);
01059 #endif /* REALITY_LVLS */
01060                 ret = true;
01061             }
01062             else
01063             {
01064                 free_lbuf(got);
01065                 got = atr_pget(loc, iDescDefault, &aowner, &aflags);
01066                 if (*got)
01067                 {
01068                     if (indent)
01069                     {
01070                         raw_notify_newline(player);
01071                     }
01072 #ifdef REALITY_LVLS
01073                     did_it_rlevel(player, loc, iDescDefault, NULL, A_ODESC, NULL, iADescDefault, (char **) NULL, 0);
01074 #else
01075                     did_it(player, loc, iDescDefault, NULL, A_ODESC, NULL, iADescDefault, (char **) NULL, 0);
01076 #endif /* REALITY_LVLS */
01077                     if (indent)
01078                     {
01079                         raw_notify_newline(player);
01080                     }
01081                     ret = true;
01082                 }
01083             }
01084         }
01085         else if (*(got = atr_pget(loc, iDescDefault, &aowner, &aflags)))
01086         {
01087             if (indent)
01088             {
01089                 raw_notify_newline(player);
01090             }
01091 #ifdef REALITY_LVLS
01092             did_it_rlevel(player, loc, iDescDefault, NULL, A_ODESC, NULL, iADescDefault, (char **) NULL, 0);
01093 #else
01094             did_it(player, loc, iDescDefault, NULL, A_ODESC, NULL, iADescDefault, (char **) NULL, 0);
01095 #endif /* REALITY_LVLS */
01096             if (indent)
01097             {
01098                 raw_notify_newline(player);
01099             }
01100             ret = true;
01101         }
01102         free_lbuf(got);
01103     }
01104     free_lbuf(DescFormatBuffer);
01105     return ret;
01106 }
01107 
01108 static void look_simple(dbref player, dbref thing, bool obey_terse)
01109 {
01110     // Only makes sense for things that can hear.
01111     //
01112     if (!Hearer(player))
01113     {
01114         return;
01115     }
01116 
01117 #if defined(WOD_REALMS) || defined(REALITY_LVLS)
01118     int iRealmDirective = DoThingToThingVisibility(player, thing, ACTION_IS_STATIONARY);
01119     if (REALM_DO_HIDDEN_FROM_YOU == iRealmDirective)
01120     {
01121         notify(player, NOMATCH_MESSAGE);
01122         return;
01123     }
01124 #endif
01125 
01126     // Get the name and db-number if we can examine it.
01127     //
01128     int can_see_thing = Examinable(player, thing);
01129     if (can_see_thing)
01130     {
01131         char *buff = unparse_object(player, thing, true);
01132         notify(player, buff);
01133         free_lbuf(buff);
01134     }
01135     int iDescDefault = A_DESC;
01136     int iADescDefault = A_ADESC;
01137 
01138 #if defined(WOD_REALMS) || defined(REALITY_LVLS)
01139     LetDescriptionsDefault(thing, &iDescDefault, &iADescDefault, iRealmDirective);
01140 #endif
01141 
01142     int pattr = (obey_terse && Terse(player)) ? 0 : iDescDefault;
01143     if (!show_a_desc(player, thing))
01144     {
01145         notify(player, "You see nothing special.");
01146 #ifdef REALITY_LVLS
01147         did_it_rlevel(player, thing, 0, NULL, A_ODESC, NULL, iADescDefault,
01148             (char **)NULL, 0);
01149 #else
01150         did_it(player, thing, pattr, NULL, A_ODESC, NULL, iADescDefault,
01151             (char **)NULL, 0);
01152 #endif /* REALITY_LVLS */
01153     }
01154 
01155     if (  !mudconf.quiet_look
01156        && (  !Terse(player)
01157           || mudconf.terse_look))
01158     {
01159         look_atrs(player, thing, false);
01160     }
01161 }
01162 
01163 static void show_desc(dbref player, dbref loc, int key)
01164 {
01165     char *got;
01166     dbref aowner;
01167     int aflags;
01168 
01169     if (  (key & LK_OBEYTERSE)
01170        && Terse(player))
01171     {
01172 #ifdef REALITY_LVLS
01173         did_it_rlevel(player, loc, 0, NULL, A_ODESC, NULL, A_ADESC, (char **)NULL, 0);
01174 #else
01175         did_it(player, loc, 0, NULL, A_ODESC, NULL, A_ADESC, (char **)NULL, 0);
01176 #endif /* REALITY_LVLS */
01177     }
01178     else if (  !isRoom(loc)
01179             && (key & LK_IDESC))
01180     {
01181         if (*(got = atr_pget(loc, A_IDESC, &aowner, &aflags)))
01182         {
01183 #ifdef REALITY_LVLS
01184            did_it_rlevel(player, loc, A_IDESC, NULL, A_ODESC, NULL, A_ADESC, (char **)NULL, 0);
01185 #else
01186             did_it(player, loc, A_IDESC, NULL, A_ODESC, NULL, A_ADESC, (char **)NULL, 0);
01187 #endif /* REALITY_LVLS */
01188         }
01189         else
01190         {
01191             show_a_desc(player, loc);
01192         }
01193         free_lbuf(got);
01194     }
01195     else
01196     {
01197         show_a_desc(player, loc);
01198     }
01199 }
01200 
01201 void look_in(dbref player, dbref loc, int key)
01202 {
01203     // Only makes sense for things that can hear.
01204     //
01205     if (!Hearer(player))
01206     {
01207         return;
01208     }
01209 
01210     // If he needs the VMRL URL, send it:
01211     //
01212     if (key & LK_SHOWVRML)
01213     {
01214         show_vrml_url(player, loc);
01215     }
01216 
01217     // Use @nameformat (by Marlek) if it's present, otherwise, use the
01218     // name and if the player can link to it, it's dbref as well.
01219     //
01220     dbref aowner;
01221     int aflags;
01222     char *NameFormatBuffer = atr_pget(loc, A_NAMEFORMAT, &aowner, &aflags);
01223     char *NameFormat = NameFormatBuffer;
01224 
01225     if (*NameFormat)
01226     {
01227         char *FormatOutput = alloc_lbuf("look_name.FO");
01228         char *tPtr = FormatOutput;
01229 
01230         char *preserve[MAX_GLOBAL_REGS];
01231         int preserve_len[MAX_GLOBAL_REGS];
01232         save_and_clear_global_regs("look_in_save", preserve, preserve_len);
01233 
01234         mux_exec(FormatOutput, &tPtr, loc, player, player,
01235                 EV_FCHECK | EV_EVAL | EV_TOP,
01236                 &NameFormat, 0, 0);
01237         *tPtr = '\0';
01238 
01239         restore_global_regs("look_in_restore", preserve, preserve_len);
01240         notify(player, FormatOutput);
01241 
01242         free_lbuf(FormatOutput);
01243     }
01244     else
01245     {
01246         // Okay, no @NameFormat.  Show the normal name.
01247         //
01248         char *buff = unparse_object(player, loc, true);
01249         if (Html(player))
01250         {
01251             notify_html(player, "<center><h3>");
01252             notify(player, buff);
01253             notify_html(player, "</h3></center>");
01254         }
01255         else
01256         {
01257             notify(player, buff);
01258         }
01259         free_lbuf(buff);
01260     }
01261     free_lbuf(NameFormatBuffer);
01262 
01263     if (!Good_obj(loc))
01264     {
01265         // If we went to NOTHING et al, then skip the rest.
01266         //
01267         return;
01268     }
01269 
01270     // Tell him the description.
01271     //
01272     int showkey = 0;
01273     if (loc == Location(player))
01274     {
01275         showkey |= LK_IDESC;
01276     }
01277     if (key & LK_OBEYTERSE)
01278     {
01279         showkey |= LK_OBEYTERSE;
01280     }
01281     show_desc(player, loc, showkey);
01282 
01283     bool is_terse = (key & LK_OBEYTERSE) ? Terse(player) : false;
01284 
01285     // Tell him the appropriate messages if he has the key.
01286     //
01287     if (isRoom(loc))
01288     {
01289         int pattr, oattr, aattr;
01290         if (could_doit(player, loc, A_LOCK))
01291         {
01292             pattr = A_SUCC;
01293             oattr = A_OSUCC;
01294             aattr = A_ASUCC;
01295         }
01296         else
01297         {
01298             pattr = A_FAIL;
01299             oattr = A_OFAIL;
01300             aattr = A_AFAIL;
01301         }
01302         if (is_terse)
01303         {
01304             pattr = 0;
01305         }
01306         did_it(player, loc, pattr, NULL, oattr, NULL, aattr, (char **)NULL, 0);
01307     }
01308 
01309     // Tell him the attributes, contents and exits.
01310     //
01311     if (  (key & LK_SHOWATTR)
01312        && !mudconf.quiet_look
01313        && !is_terse)
01314     {
01315         look_atrs(player, loc, false);
01316     }
01317     if (  !is_terse
01318        || mudconf.terse_contents)
01319     {
01320         look_contents(player, loc, "Contents:", CONTENTS_LOCAL);
01321     }
01322     if (  (key & LK_SHOWEXIT)
01323        && (  !is_terse
01324           || mudconf.terse_exits))
01325     {
01326         look_exits(player, loc, "Obvious exits:");
01327     }
01328 }
01329 
01330 void do_look(dbref executor, dbref caller, dbref enactor, int key, char *name)
01331 {
01332     UNUSED_PARAMETER(caller);
01333     UNUSED_PARAMETER(enactor);
01334 
01335     int look_key = LK_SHOWATTR | LK_SHOWEXIT;
01336     if (!mudconf.terse_look)
01337     {
01338         look_key |= LK_OBEYTERSE;
01339     }
01340 
01341     dbref loc = Location(executor);
01342     dbref thing;
01343     if (!name || !*name)
01344     {
01345         thing = loc;
01346         if (Good_obj(thing))
01347         {
01348             if (key & LOOK_OUTSIDE)
01349             {
01350                 if (  isRoom(thing)
01351                    || Opaque(thing))
01352                 {
01353                     notify_quiet(executor, "You can't look outside.");
01354                     return;
01355                 }
01356                 thing = Location(thing);
01357             }
01358             look_in(executor, thing, look_key);
01359         }
01360         return;
01361     }
01362 
01363     // Look for the target locally.
01364     //
01365     thing = (key & LOOK_OUTSIDE) ? loc : executor;
01366     init_match(thing, name, NOTYPE);
01367     match_exit_with_parents();
01368     match_neighbor();
01369     match_possession();
01370     if (Long_Fingers(executor))
01371     {
01372         match_absolute();
01373         match_player();
01374     }
01375     match_here();
01376     match_me();
01377     match_master_exit();
01378     thing = match_result();
01379 
01380     // Not found locally, check possessive.
01381     //
01382     if (!Good_obj(thing))
01383     {
01384         thing = match_status(executor, match_possessed(executor,
01385             ((key & LOOK_OUTSIDE) ? loc : executor), name, thing, false));
01386     }
01387 
01388     // If we found something, go handle it.
01389     //
01390     if (Good_obj(thing))
01391     {
01392 #ifdef REALITY_LVLS
01393         if (!IsReal(executor, thing))
01394             return;
01395 #endif /* REALITY_LVLS */
01396         switch (Typeof(thing))
01397         {
01398         case TYPE_ROOM:
01399 
01400             look_in(executor, thing, look_key);
01401             break;
01402 
01403         case TYPE_THING:
01404         case TYPE_PLAYER:
01405 
01406             look_simple(executor, thing, !mudconf.terse_look);
01407             if (  !Opaque(thing)
01408                && (  mudconf.terse_contents
01409                   || !Terse(executor)))
01410             {
01411                 look_contents(executor, thing, "Carrying:", CONTENTS_NESTED);
01412             }
01413             break;
01414 
01415         case TYPE_EXIT:
01416 
01417             look_simple(executor, thing, !mudconf.terse_look);
01418             if (  Transparent(thing)
01419                && Location(thing) != NOTHING)
01420             {
01421                 look_key &= ~LK_SHOWATTR;
01422                 look_in(executor, Location(thing), look_key);
01423             }
01424             break;
01425 
01426         default:
01427 
01428             look_simple(executor, thing, !mudconf.terse_look);
01429             break;
01430         }
01431     }
01432 }
01433 
01434 static void debug_examine(dbref player, dbref thing)
01435 {
01436     dbref aowner;
01437     char *buf;
01438     int aflags, ca;
01439     BOOLEXP *pBoolExp;
01440     ATTR *pattr;
01441     char *as, *cp;
01442 
01443     notify(player, tprintf("Number  = %d", thing));
01444     if (!Good_obj(thing))
01445     {
01446         return;
01447     }
01448 
01449     notify(player, tprintf("Name    = %s", Name(thing)));
01450     notify(player, tprintf("Location= %d", Location(thing)));
01451     notify(player, tprintf("Contents= %d", Contents(thing)));
01452     notify(player, tprintf("Exits   = %d", Exits(thing)));
01453     notify(player, tprintf("Link    = %d", Link(thing)));
01454     notify(player, tprintf("Next    = %d", Next(thing)));
01455     notify(player, tprintf("Owner   = %d", Owner(thing)));
01456     notify(player, tprintf("Pennies = %d", Pennies(thing)));
01457     notify(player, tprintf("Zone    = %d", Zone(thing)));
01458     buf = flag_description(player, thing);
01459     notify(player, tprintf("Flags   = %s", buf));
01460     free_mbuf(buf);
01461     buf = powers_list(player, thing);
01462     notify(player, tprintf("Powers  = %s", buf));
01463     free_lbuf(buf);
01464 #ifdef REALITY_LVLS
01465     buf = rxlevel_description(player, thing);
01466     notify(player, tprintf("RxLevel = %s", buf));
01467     free_lbuf(buf);
01468     buf = txlevel_description(player, thing);
01469     notify(player, tprintf("TxLevel = %s", buf));
01470     free_lbuf(buf);
01471 #endif /* REALITY_LVLS */
01472     buf = atr_get(thing, A_LOCK, &aowner, &aflags);
01473     pBoolExp = parse_boolexp(player, buf, true);
01474     free_lbuf(buf);
01475     notify(player, tprintf("Lock    = %s", unparse_boolexp(player, pBoolExp)));
01476     free_boolexp(pBoolExp);
01477 
01478     buf = alloc_lbuf("debug_dexamine");
01479     cp = buf;
01480     safe_str("Attr list: ", buf, &cp);
01481 
01482     for (ca = atr_head(thing, &as); ca; ca = atr_next(&as))
01483     {
01484         pattr = atr_num(ca);
01485         if (!pattr)
01486         {
01487             continue;
01488         }
01489 
01490         atr_get_info(thing, ca, &aowner, &aflags);
01491         if (bCanReadAttr(player, thing, pattr, false))
01492         {
01493             if (pattr)
01494             {
01495                 // Valid attr.
01496                 //
01497                 safe_str(pattr->name, buf, &cp);
01498                 safe_chr(' ', buf, &cp);
01499             }
01500             else
01501             {
01502                 safe_str(tprintf("%d ", ca), buf, &cp);
01503             }
01504         }
01505     }
01506     *cp = '\0';
01507     notify(player, buf);
01508     free_lbuf(buf);
01509 
01510     for (ca = atr_head(thing, &as); ca; ca = atr_next(&as))
01511     {
01512         pattr = atr_num(ca);
01513         if (!pattr)
01514         {
01515             continue;
01516         }
01517 
01518         buf = atr_get(thing, ca, &aowner, &aflags);
01519         if (bCanReadAttr(player, thing, pattr, false))
01520         {
01521             view_atr(player, thing, pattr, buf, aowner, aflags, 0);
01522         }
01523         free_lbuf(buf);
01524     }
01525 }
01526 
01527 static void exam_wildattrs
01528 (
01529     dbref player,
01530     dbref thing,
01531     bool do_parent
01532 )
01533 {
01534     int atr;
01535     bool got_any = false;
01536     for (atr = olist_first(); atr != NOTHING; atr = olist_next())
01537     {
01538         ATTR *ap = atr_num(atr);
01539         if (!ap)
01540         {
01541             continue;
01542         }
01543         int   aflags;
01544         dbref aowner;
01545         char *buf;
01546         if (  do_parent
01547            && !(ap->flags & AF_PRIVATE))
01548         {
01549             buf = atr_pget(thing, atr, &aowner, &aflags);
01550         }
01551         else
01552         {
01553             buf = atr_get(thing, atr, &aowner, &aflags);
01554         }
01555 
01556         // Decide if the player should see the attr: If obj is
01557         // Examinable and has rights to see, yes. If a player and has
01558         // rights to see, yes... except if faraway, attr=DESC, and
01559         // remote DESC-reading is not turned on. If I own the attrib
01560         // and have rights to see, yes... except if faraway, attr=DESC,
01561         // and remote DESC-reading is not turned on.
01562         //
01563         if (  Examinable(player, thing)
01564            && bCanReadAttr(player, thing, ap, do_parent))
01565         {
01566             got_any = true;
01567             view_atr(player, thing, ap, buf, aowner, aflags, 0);
01568         }
01569         else if (bCanReadAttr(player, thing, ap, isPlayer(thing) ? do_parent : false))
01570         {
01571             got_any = true;
01572             if (aowner == Owner(player))
01573             {
01574                 view_atr(player, thing, ap, buf, aowner, aflags, 0);
01575             }
01576             else if (  atr == A_DESC
01577                     && (  mudconf.read_rem_desc
01578                        || nearby(player, thing)))
01579             {
01580                 show_desc(player, thing, 0);
01581             }
01582             else if (atr != A_DESC)
01583             {
01584                 view_atr(player, thing, ap, buf, aowner, aflags, 0);
01585             }
01586             else
01587             {
01588                 notify(player, "<Too far away to get a good look>");
01589             }
01590         }
01591         free_lbuf(buf);
01592     }
01593     if (!got_any)
01594     {
01595         notify_quiet(player, "No matching attributes found.");
01596     }
01597 }
01598 
01599 void do_examine(dbref executor, dbref caller, dbref enactor, int key, char *name)
01600 {
01601     UNUSED_PARAMETER(caller);
01602     UNUSED_PARAMETER(enactor);
01603 
01604     // This command is pointless if the player can't hear.
01605     //
01606     if (!Hearer(executor))
01607     {
01608         return;
01609     }
01610 
01611     dbref content, exit, aowner, loc;
01612     char savec;
01613     char *temp, *buf, *buf2;
01614     BOOLEXP *pBoolExp;
01615     int aflags;
01616     bool control;
01617     bool do_parent = ((key & EXAM_PARENT) ? true : false);
01618 
01619     dbref thing = NOTHING;
01620     if (  !name
01621        || !*name)
01622     {
01623         thing = Location(executor);
01624         if (thing == NOTHING)
01625         {
01626             return;
01627         }
01628     }
01629     else
01630     {
01631         // Check for obj/attr first.
01632         //
01633         olist_push();
01634         if (parse_attrib_wild(executor, name, &thing, do_parent, true, false))
01635         {
01636             exam_wildattrs(executor, thing, do_parent);
01637             olist_pop();
01638             return;
01639         }
01640         olist_pop();
01641 
01642         // Look it up.
01643         //
01644         init_match(executor, name, NOTYPE);
01645         match_everything(MAT_EXIT_PARENTS);
01646         thing = noisy_match_result();
01647         if (!Good_obj(thing))
01648         {
01649             return;
01650         }
01651     }
01652 
01653 #if defined(WOD_REALMS) || defined(REALITY_LVLS)
01654     if (REALM_DO_HIDDEN_FROM_YOU == DoThingToThingVisibility(executor, thing, ACTION_IS_STATIONARY))
01655     {
01656         notify(executor, NOMATCH_MESSAGE);
01657         return;
01658     }
01659 #endif
01660 
01661     // Check for the /debug switch.
01662     //
01663     if (key & EXAM_DEBUG)
01664     {
01665         if (!Examinable(executor, thing))
01666         {
01667             notify_quiet(executor, NOPERM_MESSAGE);
01668         }
01669         else
01670         {
01671             debug_examine(executor, thing);
01672         }
01673         return;
01674     }
01675     control = (  Examinable(executor, thing)
01676               || Link_exit(executor, thing));
01677 
01678     if (control)
01679     {
01680         buf2 = unparse_object(executor, thing, false);
01681         notify(executor, buf2);
01682         free_lbuf(buf2);
01683         if (mudconf.ex_flags)
01684         {
01685             buf2 = flag_description(executor, thing);
01686             notify(executor, buf2);
01687             free_mbuf(buf2);
01688         }
01689     }
01690     else
01691     {
01692         if (  key == EXAM_DEFAULT
01693            && !mudconf.exam_public)
01694         {
01695             if (mudconf.read_rem_name)
01696             {
01697                 buf2 = alloc_lbuf("do_examine.pub_name");
01698                 strcpy(buf2, Name(thing));
01699                 notify(executor,
01700                     tprintf("%s is owned by %s",
01701                     buf2, Name(Owner(thing))));
01702                 free_lbuf(buf2);
01703             }
01704             else
01705             {
01706                 notify(executor, tprintf("Owned by %s", Name(Owner(thing))));
01707             }
01708             return;
01709         }
01710     }
01711 
01712     temp = alloc_lbuf("do_examine.info");
01713 
01714     if (  control
01715        || mudconf.read_rem_desc
01716        || nearby(executor, thing))
01717     {
01718         temp = atr_get_str(temp, thing, A_DESC, &aowner, &aflags);
01719         if (*temp)
01720         {
01721             if (  Examinable(executor, thing)
01722                || (aowner == Owner(executor)))
01723             {
01724                 view_atr(executor, thing, atr_num(A_DESC), temp,
01725                     aowner, aflags, true);
01726             }
01727             else
01728             {
01729                 show_desc(executor, thing, 0);
01730             }
01731         }
01732     }
01733     else
01734     {
01735         notify(executor, "<Too far away to get a good look>");
01736     }
01737 
01738     if (control)
01739     {
01740         // Print owner, key, and value.
01741         //
01742         savec = mudconf.many_coins[0];
01743         mudconf.many_coins[0] = mux_toupper(mudconf.many_coins[0]);
01744         buf2 = atr_get(thing, A_LOCK, &aowner, &aflags);
01745         pBoolExp = parse_boolexp(executor, buf2, true);
01746         buf = unparse_boolexp(executor, pBoolExp);
01747         free_boolexp(pBoolExp);
01748         strcpy(buf2, Name(Owner(thing)));
01749         notify(executor, tprintf("Owner: %s  Key: %s %s: %d", buf2, buf, mudconf.many_coins, Pennies(thing)));
01750         free_lbuf(buf2);
01751         mudconf.many_coins[0] = savec;
01752 
01753         // Print the zone
01754         //
01755         if (mudconf.have_zones)
01756         {
01757             buf2 = unparse_object(executor, Zone(thing), false);
01758             notify(executor, tprintf("Zone: %s", buf2));
01759             free_lbuf(buf2);
01760         }
01761 
01762         // Print parent
01763         //
01764         loc = Parent(thing);
01765         if (loc != NOTHING)
01766         {
01767             buf2 = unparse_object(executor, loc, false);
01768             notify(executor, tprintf("Parent: %s", buf2));
01769             free_lbuf(buf2);
01770         }
01771         buf2 = powers_list(executor, thing);
01772         notify(executor, tprintf("Powers: %s", buf2));
01773         free_lbuf(buf2);
01774 #ifdef REALITY_LVLS
01775         /* Show Rx and Tx levels */
01776 
01777         buf2 = rxlevel_description(executor, thing);
01778         notify(executor, tprintf("RxLevel: %s", buf2));
01779         free_mbuf(buf2);
01780         buf2 = txlevel_description(executor, thing);
01781         notify(executor, tprintf("TxLevel: %s", buf2));
01782         free_mbuf(buf2);
01783 #endif /* REALITY_LVLS */
01784     }
01785     if (!(key & EXAM_BRIEF))
01786     {
01787         look_atrs(executor, thing, do_parent);
01788     }
01789 
01790     // Show him interesting stuff
01791     //
01792     if (control)
01793     {
01794         // Contents
01795         //
01796         if (Contents(thing) != NOTHING)
01797         {
01798             notify(executor, "Contents:");
01799             DOLIST(content, Contents(thing))
01800             {
01801                 buf2 = unparse_object(executor, content, false);
01802                 notify(executor, buf2);
01803                 free_lbuf(buf2);
01804             }
01805         }
01806 
01807         // Show stuff that depends on the object type.
01808         //
01809         switch (Typeof(thing))
01810         {
01811         case TYPE_ROOM:
01812             // Tell him about exits
01813             //
01814             if (Exits(thing) != NOTHING)
01815             {
01816                 notify(executor, "Exits:");
01817                 DOLIST(exit, Exits(thing))
01818                 {
01819                     buf2 = unparse_object(executor, exit, false);
01820                     notify(executor, buf2);
01821                     free_lbuf(buf2);
01822                 }
01823             }
01824             else
01825             {
01826                 notify(executor, "No exits.");
01827             }
01828 
01829             // print dropto if present
01830             //
01831             if (Dropto(thing) != NOTHING)
01832             {
01833                 buf2 = unparse_object(executor, Dropto(thing), false);
01834                 notify(executor, tprintf("Dropped objects go to: %s", buf2));
01835                 free_lbuf(buf2);
01836             }
01837             break;
01838 
01839         case TYPE_THING:
01840         case TYPE_PLAYER:
01841 
01842             // Tell him about exits
01843             //
01844             if (Exits(thing) != NOTHING)
01845             {
01846                 notify(executor, "Exits:");
01847                 DOLIST(exit, Exits(thing))
01848                 {
01849                     buf2 = unparse_object(executor, exit, false);
01850                     notify(executor, buf2);
01851                     free_lbuf(buf2);
01852                 }
01853             }
01854             else
01855             {
01856                 notify(executor, "No exits.");
01857             }
01858 
01859             // Print home
01860             //
01861             loc = Home(thing);
01862             buf2 = unparse_object(executor, loc, false);
01863             notify(executor, tprintf("Home: %s", buf2));
01864             free_lbuf(buf2);
01865 
01866             // print location if player can link to it
01867             //
01868             loc = Location(thing);
01869             if (  Location(thing) != NOTHING
01870                && (  Examinable(executor, loc)
01871                   || Examinable(executor, thing)
01872                   || Linkable(executor, loc)))
01873             {
01874                 buf2 = unparse_object(executor, loc, false);
01875                 notify(executor, tprintf("Location: %s", buf2));
01876                 free_lbuf(buf2);
01877             }
01878             break;
01879 
01880         case TYPE_EXIT:
01881             buf2 = unparse_object(executor, Exits(thing), false);
01882             notify(executor, tprintf("Source: %s", buf2));
01883             free_lbuf(buf2);
01884 
01885             // print destination.
01886             //
01887             switch (Location(thing))
01888             {
01889             case NOTHING:
01890                 // Special case. unparse_object() normally returns -1 as '*NOTHING*'.
01891                 //
01892                 notify(executor, "Destination: *UNLINKED*");
01893                 break;
01894 
01895             default:
01896                 buf2 = unparse_object(executor, Location(thing), false);
01897                 notify(executor, tprintf("Destination: %s", buf2));
01898                 free_lbuf(buf2);
01899                 break;
01900             }
01901             break;
01902 
01903         default:
01904             break;
01905         }
01906     }
01907     else if (  !Opaque(thing)
01908             && nearby(executor, thing))
01909     {
01910         if (Has_contents(thing))
01911         {
01912             look_contents(executor, thing, "Contents:", CONTENTS_REMOTE);
01913         }
01914         if (!isExit(thing))
01915         {
01916             look_exits(executor, thing, "Obvious exits:");
01917         }
01918     }
01919     free_lbuf(temp);
01920 
01921     if (!control)
01922     {
01923         if (mudconf.read_rem_name)
01924         {
01925             buf2 = alloc_lbuf("do_examine.pub_name");
01926             strcpy(buf2, Name(thing));
01927             notify(executor, tprintf("%s is owned by %s", buf2, Name(Owner(thing))));
01928             free_lbuf(buf2);
01929         }
01930         else
01931         {
01932             notify(executor, tprintf("Owned by %s", Name(Owner(thing))));
01933         }
01934     }
01935 }
01936 
01937 void do_score(dbref executor, dbref caller, dbref enactor, int key)
01938 {
01939     UNUSED_PARAMETER(caller);
01940     UNUSED_PARAMETER(enactor);
01941     UNUSED_PARAMETER(key);
01942 
01943     int nPennies = Pennies(executor);
01944     notify(executor, tprintf("You have %d %s.", nPennies,
01945         (1 == nPennies) ?  mudconf.one_coin : mudconf.many_coins));
01946 }
01947 
01948 void do_inventory(dbref executor, dbref caller, dbref enactor, int key)
01949 {
01950     UNUSED_PARAMETER(enactor);
01951     UNUSED_PARAMETER(key);
01952 
01953     dbref thing;
01954     char *buff, *e;
01955     const char *s;
01956 
01957     thing = Contents(executor);
01958     if (thing == NOTHING)
01959     {
01960         notify(executor, "You aren't carrying anything.");
01961     }
01962     else
01963     {
01964         notify(executor, "You are carrying:");
01965         DOLIST(thing, thing)
01966         {
01967             buff = unparse_object(executor, thing, true);
01968             notify(executor, buff);
01969             free_lbuf(buff);
01970         }
01971     }
01972 
01973     thing = Exits(executor);
01974     if (thing != NOTHING)
01975     {
01976         notify(executor, "Exits:");
01977         e = buff = alloc_lbuf("look_exits");
01978         DOLIST(thing, thing)
01979         {
01980             // Chop off first exit alias to display.
01981             //
01982             for (s = Name(thing); *s && (*s != ';'); s++)
01983             {
01984                 safe_chr(*s, buff, &e);
01985             }
01986             safe_str("  ", buff, &e);
01987         }
01988         *e = 0;
01989         notify(executor, buff);
01990         free_lbuf(buff);
01991     }
01992     do_score(executor, caller, executor, 0);
01993 }
01994 
01995 void do_entrances(dbref executor, dbref caller, dbref enactor, int key, char *name)
01996 {
01997     UNUSED_PARAMETER(caller);
01998     UNUSED_PARAMETER(enactor);
01999     UNUSED_PARAMETER(key);
02000 
02001     dbref thing, i, j;
02002     char *exit, *message;
02003     int control_thing, count, low_bound, high_bound;
02004     FWDLIST *fp;
02005 
02006     parse_range(&name, &low_bound, &high_bound);
02007     if (  !name
02008        || !*name)
02009     {
02010         if (Has_location(executor))
02011         {
02012             thing = Location(executor);
02013         }
02014         else
02015         {
02016             thing = executor;
02017         }
02018         if (!Good_obj(thing))
02019         {
02020             return;
02021         }
02022     }
02023     else
02024     {
02025         init_match(executor, name, NOTYPE);
02026         match_everything(MAT_EXIT_PARENTS);
02027         thing = noisy_match_result();
02028         if (!Good_obj(thing))
02029         {
02030             return;
02031         }
02032     }
02033 
02034     if (!payfor(executor, mudconf.searchcost))
02035     {
02036         notify(executor, tprintf("You don't have enough %s.",
02037             mudconf.many_coins));
02038         return;
02039     }
02040     message = alloc_lbuf("do_entrances");
02041     control_thing = Examinable(executor, thing);
02042     count = 0;
02043     for (i = low_bound; i <= high_bound; i++)
02044     {
02045         if (control_thing || Examinable(executor, i))
02046         {
02047             switch (Typeof(i))
02048             {
02049             case TYPE_EXIT:
02050                 if (Location(i) == thing)
02051                 {
02052                     exit = unparse_object(executor, Exits(i), false);
02053                     notify(executor, tprintf("%s (%s)", exit, Name(i)));
02054                     free_lbuf(exit);
02055                     count++;
02056                 }
02057                 break;
02058             case TYPE_ROOM:
02059                 if (Dropto(i) == thing)
02060                 {
02061                     exit = unparse_object(executor, i, false);
02062                     notify(executor, tprintf("%s [dropto]", exit));
02063                     free_lbuf(exit);
02064                     count++;
02065                 }
02066                 break;
02067             case TYPE_THING:
02068             case TYPE_PLAYER:
02069                 if (Home(i) == thing)
02070                 {
02071                     exit = unparse_object(executor, i, false);
02072                     notify(executor, tprintf("%s [home]", exit));
02073                     free_lbuf(exit);
02074                     count++;
02075                 }
02076                 break;
02077             }
02078 
02079             // Check for parents.
02080             //
02081             if (Parent(i) == thing)
02082             {
02083                 exit = unparse_object(executor, i, false);
02084                 notify(executor, tprintf("%s [parent]", exit));
02085                 free_lbuf(exit);
02086                 count++;
02087             }
02088 
02089             // Check for forwarding.
02090             //
02091             if (H_Fwdlist(i))
02092             {
02093                 fp = fwdlist_get(i);
02094                 if (!fp)
02095                 {
02096                     continue;
02097                 }
02098                 for (j = 0; j < fp->count; j++)
02099                 {
02100                     if (fp->data[j] != thing)
02101                     {
02102                         continue;
02103                     }
02104                     exit = unparse_object(executor, i, false);
02105                     notify(executor, tprintf("%s [forward]", exit));
02106                     free_lbuf(exit);
02107                     count++;
02108                 }
02109             }
02110         }
02111     }
02112     free_lbuf(message);
02113     notify(executor, tprintf("%d entrance%s found.", count,
02114         (count == 1) ? "" : "s"));
02115 }
02116 
02117 // Check the current location for bugs.
02118 //
02119 static void sweep_check(dbref player, dbref what, int key, bool is_loc)
02120 {
02121     if (  Can_Hide(what)
02122        && Hidden(what)
02123        && !See_Hidden(player))
02124     {
02125         return;
02126     }
02127 
02128     bool canhear    = false;
02129     bool cancom     = false;
02130     bool isplayer   = false;
02131     bool ispuppet   = false;
02132     bool isconnected = false;
02133     bool is_parent  = false;
02134 
02135     if (key & SWEEP_LISTEN)
02136     {
02137         if (  (  (  isExit(what)
02138                  || is_loc)
02139               && Audible(what))
02140            || H_Listen(what)
02141            || mudstate.bfListens.IsSet(what))
02142         {
02143             canhear = true;
02144         }
02145         else if (  !mudstate.bfNoListens.IsSet(what)
02146                 && Monitor(what))
02147         {
02148             bool bFoundCommands = false;
02149 
02150             char *as;
02151             char *buff = alloc_lbuf("sweep_check.Hearer");
02152             for (int atr = atr_head(what, &as); atr; atr = atr_next(&as))
02153             {
02154                 ATTR *ap = atr_num(atr);
02155                 if (  !ap
02156                    || (ap->flags & AF_NOPROG))
02157                 {
02158                     continue;
02159                 }
02160 
02161                 int   aflags;
02162                 dbref aowner;
02163                 atr_get_str(buff, what, atr, &aowner, &aflags);
02164 
02165                 if (aflags & AF_NOPROG)
02166                 {
02167                     continue;
02168                 }
02169 
02170                 char *s = NULL;
02171                 if (  AMATCH_CMD    == buff[0]
02172                    || AMATCH_LISTEN == buff[0])
02173                 {
02174                     s = strchr(buff+1, ':');
02175                     if (s)
02176                     {
02177                         if (AMATCH_CMD == buff[0])
02178                         {
02179                             bFoundCommands = true;
02180                         }
02181                         else
02182                         {
02183                             canhear = true;
02184                             break;
02185                         }
02186                     }
02187                 }
02188             }
02189             free_lbuf(buff);
02190 
02191             if (canhear)
02192             {
02193                 mudstate.bfListens.Set(what);
02194             }
02195             else
02196             {
02197                 mudstate.bfNoListens.Set(what);
02198             }
02199 
02200             if (bFoundCommands)
02201             {
02202                 mudstate.bfNoCommands.Clear(what);
02203                 mudstate.bfCommands.Set(what);
02204             }
02205             else
02206             {
02207                 mudstate.bfCommands.Clear(what);
02208                 mudstate.bfNoCommands.Set(what);
02209             }
02210         }
02211     }
02212 
02213     if (  (key & SWEEP_COMMANDS)
02214        && !isExit(what))
02215     {
02216         // Look for commands on the object and parents too.
02217         //
02218         dbref parent;
02219         int lev;
02220         ITER_PARENTS(what, parent, lev)
02221         {
02222             if (Commer(parent))
02223             {
02224                 cancom = true;
02225                 if (lev)
02226                 {
02227                     is_parent = true;
02228                     break;
02229                 }
02230             }
02231         }
02232     }
02233 
02234     if (key & SWEEP_CONNECT)
02235     {
02236         if (  Connected(what)
02237            || (  Puppet(what)
02238               && Connected(Owner(what)))
02239            || (  mudconf.player_listen
02240               && isPlayer(what)
02241               && canhear
02242               && Connected(Owner(what))))
02243         {
02244             isconnected = true;
02245         }
02246     }
02247 
02248     if (  (key & SWEEP_PLAYER)
02249        || isconnected)
02250     {
02251         if (isPlayer(what))
02252         {
02253             isplayer = true;
02254         }
02255         if (Puppet(what))
02256         {
02257             ispuppet = true;
02258         }
02259     }
02260 
02261     if (  canhear
02262        || cancom
02263        || isplayer
02264        || ispuppet
02265        || isconnected)
02266     {
02267         char *buf = alloc_lbuf("sweep_check.types");
02268         char *bp = buf;
02269 
02270         if (cancom)
02271         {
02272             safe_str("commands ", buf, &bp);
02273         }
02274 
02275         if (canhear)
02276         {
02277             safe_str("messages ", buf, &bp);
02278         }
02279 
02280         if (isplayer)
02281         {
02282             safe_str("player ", buf, &bp);
02283         }
02284 
02285         if (ispuppet)
02286         {
02287             safe_str("puppet(", buf, &bp);
02288             safe_str(Name(Owner(what)), buf, &bp);
02289             safe_str(") ", buf, &bp);
02290         }
02291 
02292         if (isconnected)
02293         {
02294             safe_str("connected ", buf, &bp);
02295         }
02296 
02297         if (is_parent)
02298         {
02299             safe_str("parent ", buf, &bp);
02300         }
02301         bp[-1] = '\0';
02302 
02303         if (!isExit(what))
02304         {
02305             notify(player, tprintf("  %s is listening. [%s]",
02306                 Name(what), buf));
02307         }
02308         else
02309         {
02310             char *buf2 = alloc_lbuf("sweep_check.name");
02311             strcpy(buf2, Name(what));
02312             for (bp = buf2; *bp && (*bp != ';'); bp++)
02313             {
02314                 ; // Nothing.
02315             }
02316             *bp = '\0';
02317             notify(player, tprintf("  %s is listening. [%s]", buf2, buf));
02318             free_lbuf(buf2);
02319         }
02320         free_lbuf(buf);
02321     }
02322 }
02323 
02324 void do_sweep(dbref executor, dbref caller, dbref enactor, int key, char *where)
02325 {
02326     UNUSED_PARAMETER(caller);
02327     UNUSED_PARAMETER(enactor);
02328 
02329     dbref here, sweeploc;
02330     int where_key, what_key;
02331 
02332     where_key = key & (SWEEP_ME | SWEEP_HERE | SWEEP_EXITS);
02333     what_key = key & (SWEEP_COMMANDS | SWEEP_LISTEN | SWEEP_PLAYER | SWEEP_CONNECT);
02334 
02335     if (where && *where)
02336     {
02337         sweeploc = match_controlled(executor, where);
02338         if (!Good_obj(sweeploc))
02339         {
02340             return;
02341         }
02342     }
02343     else
02344     {
02345         sweeploc = executor;
02346     }
02347 
02348     if (!where_key)
02349     {
02350         where_key = -1;
02351     }
02352     if (!what_key)
02353     {
02354         what_key = -1;
02355     }
02356     else if (what_key == SWEEP_VERBOSE)
02357     {
02358         what_key = SWEEP_VERBOSE | SWEEP_COMMANDS;
02359     }
02360 
02361     // Check my location.  If I have none or it is dark, check just me.
02362     //
02363     if (where_key & SWEEP_HERE)
02364     {
02365         notify(executor, "Sweeping location...");
02366         if (Has_location(sweeploc))
02367         {
02368             here = Location(sweeploc);
02369             if (  here == NOTHING
02370                || (  Dark(here)
02371                   && !mudconf.sweep_dark
02372                   && !Examinable(executor, here)))
02373             {
02374                 notify_quiet(executor,
02375                     "Sorry, it is dark here and you can't search for bugs");
02376                 sweep_check(executor, sweeploc, what_key, false);
02377             }
02378             else
02379             {
02380                 sweep_check(executor, here, what_key, true);
02381                 for (here = Contents(here); here != NOTHING; here = Next(here))
02382                 {
02383                     sweep_check(executor, here, what_key, false);
02384                 }
02385             }
02386         }
02387         else
02388         {
02389             sweep_check(executor, sweeploc, what_key, false);
02390         }
02391     }
02392 
02393     // Check exits in my location
02394     //
02395     if (  (where_key & SWEEP_EXITS)
02396        && Has_location(sweeploc))
02397     {
02398         notify(executor, "Sweeping exits...");
02399         for (here = Exits(Location(sweeploc)); here != NOTHING; here = Next(here))
02400         {
02401             sweep_check(executor, here, what_key, false);
02402         }
02403     }
02404 
02405     // Check my inventory
02406     //
02407     if (  (where_key & SWEEP_ME)
02408        && Has_contents(sweeploc))
02409     {
02410         notify(executor, "Sweeping inventory...");
02411         for (here = Contents(sweeploc); here != NOTHING; here = Next(here))
02412         {
02413             sweep_check(executor, here, what_key, false);
02414         }
02415     }
02416 
02417     // Check carried exits
02418     //
02419     if (  (where_key & SWEEP_EXITS)
02420        && Has_exits(sweeploc))
02421     {
02422         notify(executor, "Sweeping carried exits...");
02423         for (here = Exits(sweeploc); here != NOTHING; here = Next(here))
02424         {
02425             sweep_check(executor, here, what_key, false);
02426         }
02427     }
02428     notify(executor, "Sweep complete.");
02429 }
02430 
02431 /* Output the sequence of commands needed to duplicate the specified
02432  * object.  If you're moving things to another system, your mileage
02433  * will almost certainly vary.  (i.e. different flags, etc.)
02434  */
02435 
02436 void do_decomp
02437 (
02438     dbref executor,
02439     dbref caller,
02440     dbref enactor,
02441     int   key,
02442     int   nargs,
02443     char *name,
02444     char *qual
02445 )
02446 {
02447     UNUSED_PARAMETER(caller);
02448     UNUSED_PARAMETER(enactor);
02449     UNUSED_PARAMETER(nargs);
02450 
02451     BOOLEXP *pBoolExp;
02452     char *got, *thingname, *as, *ltext, *buff;
02453     dbref aowner, thing;
02454     int val, aflags, ca;
02455     ATTR *pattr;
02456     NAMETAB *np;
02457     bool wild_decomp;
02458 
02459     // Check for obj/attr first.
02460     //
02461     olist_push();
02462     if (parse_attrib_wild(executor, name, &thing, false, true, false))
02463     {
02464         wild_decomp = true;
02465     }
02466     else
02467     {
02468         wild_decomp = false;
02469         init_match(executor, name, TYPE_THING);
02470         match_everything(MAT_EXIT_PARENTS);
02471         thing = noisy_match_result();
02472     }
02473 
02474     // get result
02475     //
02476     if (thing == NOTHING)
02477     {
02478         olist_pop();
02479         return;
02480     }
02481 
02482     if (!Examinable(executor, thing))
02483     {
02484         notify_quiet(executor,
02485               "You can only decompile things you can examine.");
02486         olist_pop();
02487         return;
02488     }
02489 
02490     thingname = atr_get(thing, A_LOCK, &aowner, &aflags);
02491     pBoolExp = parse_boolexp(executor, thingname, true);
02492 
02493     // Determine the name of the thing to use in reporting and then
02494     // report the command to make the thing.
02495     //
02496     if (qual && *qual)
02497     {
02498         strcpy(thingname, qual);
02499     }
02500     else
02501     {
02502         if (key == DECOMP_DBREF)
02503         {
02504             strcpy(thingname, tprintf("#%d",thing));
02505         }
02506         else
02507         {
02508             switch (Typeof(thing))
02509             {
02510             case TYPE_THING:
02511                 strcpy(thingname, Name(thing));
02512                 val = OBJECT_DEPOSIT(Pennies(thing));
02513                 notify(executor,
02514                     tprintf("@create %s=%d", translate_string(thingname, true),
02515                     val));
02516                 break;
02517 
02518             case TYPE_ROOM:
02519                 strcpy(thingname, "here");
02520                 notify(executor, tprintf("@dig/teleport %s",
02521                     translate_string(Name(thing), true)));
02522                 break;
02523 
02524             case TYPE_EXIT:
02525                 strcpy(thingname, Name(thing));
02526                 notify(executor,
02527                     tprintf("@open %s", translate_string(thingname, true)));
02528                 for (got = thingname; *got; got++)
02529                 {
02530                     if (*got == EXIT_DELIMITER)
02531                     {
02532                         *got = '\0';
02533                         break;
02534                     }
02535                 }
02536                 break;
02537 
02538             case TYPE_PLAYER:
02539                 if (executor == thing)
02540                 {
02541                     strcpy(thingname, "me");
02542                 }
02543                 else
02544                 {
02545                     strcpy(thingname, Name(thing));
02546                 }
02547                 break;
02548             }
02549         }
02550     }
02551 
02552     // Strip out ANSI in one place rather than have it done in
02553     // several places.
02554     //
02555     size_t len;
02556     char *p = strip_ansi(thingname, &len);
02557     memcpy(thingname, p, len+1);
02558 
02559     // Report the lock (if any).
02560     //
02561     if (  !wild_decomp
02562        && pBoolExp != TRUE_BOOLEXP)
02563     {
02564         notify(executor, tprintf("@lock %s=%s", thingname,
02565             unparse_boolexp_decompile(executor, pBoolExp)));
02566     }
02567     free_boolexp(pBoolExp);
02568 
02569     // Report attributes.
02570     //
02571     buff = alloc_mbuf("do_decomp.attr_name");
02572     for (ca = (wild_decomp ? olist_first() : atr_head(thing, &as));
02573         (wild_decomp) ? (ca != NOTHING) : (ca != 0);
02574         ca = (wild_decomp ? olist_next() : atr_next(&as)))
02575     {
02576         if (  ca == A_NAME
02577            || ca == A_LOCK)
02578         {
02579             continue;
02580         }
02581         pattr = atr_num(ca);
02582         if (!pattr)
02583         {
02584             continue;
02585         }
02586         if (  (pattr->flags & AF_NOCMD)
02587            && !(pattr->flags & AF_IS_LOCK))
02588         {
02589             continue;
02590         }
02591 
02592         got = atr_get(thing, ca, &aowner, &aflags);
02593         if (bCanReadAttr(executor, thing, pattr, false))
02594         {
02595             if (pattr->flags & AF_IS_LOCK)
02596             {
02597                 pBoolExp = parse_boolexp(executor, got, true);
02598                 ltext = unparse_boolexp_decompile(executor, pBoolExp);
02599                 free_boolexp(pBoolExp);
02600                 notify(executor, tprintf("@lock/%s %s=%s", pattr->name,
02601                     thingname, ltext));
02602             }
02603             else
02604             {
02605                 strcpy(buff, pattr->name);
02606                 notify(executor, tprintf("%c%s %s=%s", ((ca < A_USER_START) ?
02607                     '@' : '&'), buff, thingname, got));
02608                 for (np = indiv_attraccess_nametab; np->name; np++)
02609                 {
02610                     if (  (aflags & np->flag)
02611                        && check_access(executor, np->perm)
02612                        && (!(np->perm & CA_NO_DECOMP)))
02613                     {
02614                         notify(executor, tprintf("@set %s/%s = %s", thingname,
02615                             buff, np->name));
02616                     }
02617                 }
02618 
02619                 if (aflags & AF_LOCK)
02620                 {
02621                     notify(executor, tprintf("@lock %s/%s", thingname, buff));
02622                 }
02623             }
02624         }
02625         free_lbuf(got);
02626     }
02627     free_mbuf(buff);
02628 
02629     if (!wild_decomp)
02630     {
02631         decompile_flags(executor, thing, thingname);
02632         decompile_powers(executor, thing, thingname);
02633 #ifdef REALITY_LVLS
02634         decompile_rlevels(executor, thing, thingname);
02635 #endif /* REALITY_LVLS */
02636     }
02637 
02638     // If the object has a parent, report it.
02639     //
02640     if (  !wild_decomp
02641        && (Parent(thing) != NOTHING))
02642     {
02643         notify(executor, tprintf("@parent %s=#%d", thingname, Parent(thing)));
02644     }
02645 
02646     // If the object has a zone, report it.
02647     //
02648     int zone;
02649     if (  !wild_decomp
02650        && Good_obj(zone = Zone(thing)))
02651     {
02652         notify(executor, tprintf("@chzone %s=#%d", thingname, zone));
02653     }
02654 
02655     free_lbuf(thingname);
02656     olist_pop();
02657 }
02658 
02659 // show_vrml_url
02660 //
02661 void show_vrml_url(dbref thing, dbref loc)
02662 {
02663     char *vrml_url;
02664     dbref aowner;
02665     int aflags;
02666 
02667     // If they don't care about HTML, just return.
02668     //
02669     if (!Html(thing))
02670     {
02671         return;
02672     }
02673 
02674     vrml_url = atr_pget(loc, A_VRML_URL, &aowner, &aflags);
02675     if (*vrml_url)
02676     {
02677         char *vrml_message, *vrml_cp;
02678 
02679         vrml_message = vrml_cp = alloc_lbuf("show_vrml_url");
02680         safe_str("<img xch_graph=load href=\"", vrml_message, &vrml_cp);
02681         safe_str(vrml_url, vrml_message, &vrml_cp);
02682         safe_str("\">", vrml_message, &vrml_cp);
02683         *vrml_cp = 0;
02684         notify_html(thing, vrml_message);
02685         free_lbuf(vrml_message);
02686     }
02687     else
02688     {
02689         notify_html(thing, "<img xch_graph=hide>");
02690     }
02691     free_lbuf(vrml_url);
02692 }

Generated on Mon May 28 04:40:10 2007 for MUX by  doxygen 1.4.7