FENI Patch

#
# J. Ellis 4/19/98
#
# FENI Anonymity
# First Alpha release
#
# This patch attempts to add an aditional layer of realism to the server
# by not revealing character names automatically.  Speech, posing,
# movement, and contents lists, for starters, now provide this feniname
# in preference to the real name.
#
# One of my players told me about this in general terms, but wasn't 
# able to provide a source for a hardcode patch.  I tried implementing
# it in softcode but wasn't able to prevent the server from revealing
# names in several common commands such as SAY and POSE.
#
# The idea behind FENI is that simply walking into a room should not
# instantly provide identity information for every other player or 
# object in the room.  This habit makes playing feature characters 
# more difficult for a number of reasons, which tend to result in
# features limiting their roleplay to private rooms only.
# Larry Homer has a discussion of FENI in general terms in his pages
# "On The Proper Care and Feeding of Mushes.".
#
# Commands added:
#  @admin feni_database=<object number>
#    This command tells the server what object it should use to store
#    attributes containing the names players create with the @remember
#    command.  God is used to access the object, but it may be owned by
#    any player.  The values are not evaluated for display so no
#    security problems should arise.  

#  @admin feni_default=<attribute number>
#    This command tells the server what additional attribute it should
#    use to invent a feniname for a player who has not provided a
#    @feniname attribute on themselves.  For instance, if you use a 
#    &SPECIES attribute for your players and puppets, and provide the
#    attribute's number (from @list user_attributes,) then the server
#    will use @SEX and &SPECIES (if present) for a default feniname.
#    If neither value is present, the server will fall back to the real
#    name of the player or object.
#
#  @feniname <object>=<very short description>
#    This command sets the value of the player or objects feniname 
#    description.  If not set, the server will invent a value (see
#    above.)  Any object in the database could have a feniname, but 
#    it doesn't make much sense for rooms and exits.
#
#  @remember <object>=[<My name for the object>]
#    This command is used by players wishing to remember a specific name
#    for another player or object.  This allows players to recognize
#    other players they've met in the past.  The values provided might
#    be actual names, if the name is now known by the player, or it
#    might simply be a different, memorable nickname.
# 
*** src/attrs.h	1995/03/20 23:59:37	1.7
--- src/attrs.h	1998/04/18 19:40:09
***************
*** 158,163 ****
--- 158,167 ----
  #define A_VRML_URL	220	/* URL of the VRML scene for this object */
  #define A_HTDESC	221	/* HTML @desc */
  
+ #ifdef FENI
+ #define A_FENINAME	222	/* FENI Descriptive Name */
+ #endif /* FENI */
+ 
  #define	A_VLIST		252
  #define	A_LIST		253
  #define	A_STRUCT	254
*** src/command.c	1995/03/20 23:59:47	1.11
--- src/command.c	1998/04/18 19:40:23
***************
*** 501,506 ****
--- 501,510 ----
       0, CS_TWO_ARG | CS_INTERP, do_quota},
      {(char *) "@readcache", NULL, CA_WIZARD,
       0, CS_NO_ARGS, do_readcache},
+ #ifdef FENI
+     {(char *) "@remember", NULL, CA_NO_GUEST | CA_NO_SLAVE,
+      0, CS_TWO_ARG | CS_INTERP, do_remember},
+ #endif /* FENI */
      {(char *) "@robot", NULL,
       CA_NO_SLAVE | CA_GBL_BUILD | CA_NO_GUEST | CA_PLAYER,
       PCRE_ROBOT, CS_TWO_ARG, do_pcreate},
***************
*** 1904,1909 ****
--- 1908,1916 ----
      char *buff;
      time_t now;
      int i;
+ #ifdef FENI
+     ATTR *attr;
+ #endif /* FENI */
  
      now = time(NULL);
  
***************
*** 1961,1967 ****
  #ifdef PUEBLO_SUPPORT
      notify(player, "The Pueblo client HTML extensions are supported.");
  #endif				/* PUEBLO_SUPPORT */
! 
      if (mudconf.fascist_tport)
  	notify(player, "You may only @teleport out of locations that are JUMP_OK or that you control.");
  
--- 1968,1990 ----
  #ifdef PUEBLO_SUPPORT
      notify(player, "The Pueblo client HTML extensions are supported.");
  #endif				/* PUEBLO_SUPPORT */
! #ifdef FENI
!     notify(player, "The FENI anonymity extensions are enabled.");
!     if (mudconf.feni_database >0) {
!       notify(player,"The @remember database is available.");
!     }
!     if (mudconf.feni_default > 0) {
!       attr = atr_num(mudconf.feni_default);
!       if (attr) {
!         notify(
!           player, 
!           tprintf("Default feninames are built from the sex and %s attributes.", attr->name )
!         );
!       }
!     } else {
!       notify(player,"Default feninames are the sex attribute.");
!     }
! #endif /* FENI */
      if (mudconf.fascist_tport)
  	notify(player, "You may only @teleport out of locations that are JUMP_OK or that you control.");
  
***************
*** 2149,2154 ****
--- 2172,2182 ----
  	    mudconf.master_room, mudconf.start_room,
  	    mudconf.start_home, mudconf.default_home);
      notify(player, buff);
+ #ifdef FENI
+     sprintf(buff, "FeniDatabase...#%d FeniDefaultAttr#...%d",
+     	mudconf.feni_database, mudconf.feni_default);
+     notify(player, buff);
+ #endif /* FENI */
    
      sprintf(buff, "New characters:  %s...%d  Quota...%d  Rooms...%d  Exits...%d  Things...%d  Players...%d", 
  	    mudconf.many_coins, mudconf.paystart, mudconf.start_quota, 
*** src/command.h	1995/03/20 23:59:50	1.7
--- src/command.h	1998/04/18 19:40:09
***************
*** 88,93 ****
--- 88,96 ----
  CMD_ONE_ARG(do_queue);		/* Force queue processing */
  CMD_TWO_ARG(do_quota);		/* Set or display quotas */
  CMD_NO_ARG(do_readcache);	/* Reread text file cache */
+ #ifdef FENI
+ CMD_TWO_ARG(do_remember);	/* Setup FeniName Knowledge */
+ #endif /* FENI */
  CMD_NO_ARG(do_rwho);		/* Open or close conn to rem RWHO */
  CMD_ONE_ARG(do_say);		/* Messages to all */
  CMD_NO_ARG(do_score);		/* Display my wealth */
*** src/conf.c	1995/03/20 23:59:54	1.10
--- src/conf.c	1998/04/18 19:40:10
***************
*** 234,239 ****
--- 234,243 ----
      mudconf.cache_width = CACHE_WIDTH;
      mudconf.cache_names = 1;
      mudconf.cache_steal_dirty = 0;
+ #ifdef FENI
+     mudconf.feni_database = -1;
+     mudconf.feni_default = -1;
+ #endif /* FENI */
  
      mudstate.initializing = 0;
      mudstate.panicking = 0;
***************
*** 974,979 ****
--- 978,989 ----
       &mudconf.exit_quota, 0},
      {"fascist_teleport", cf_bool, CA_GOD,
       &mudconf.fascist_tport, 0},
+ #ifdef FENI
+     {"feni_database", cf_int, CA_GOD,
+      &mudconf.feni_database, 0},
+     {"feni_default", cf_int, CA_GOD,
+      &mudconf.feni_default, 0},
+ #endif /* FENI */
      {"find_money_chance", cf_int, CA_GOD,
       &mudconf.payfind, 0},
      {"flag_alias", cf_flagalias, CA_GOD,
*** src/create.c	1995/03/21 23:07:48	1.10
--- src/create.c	1998/04/18 19:40:11
***************
*** 746,751 ****
--- 746,755 ----
  {
      dbref thing;
      int ctl, destok;
+     char *buff;
+ #ifdef FENI
+     char *fbuff;
+ #endif /* FENI */
  
      /* Check for things I control. We do this first, because what we want
       * is probably something we control, and this allows us to check for
***************
*** 796,801 ****
--- 800,818 ----
      }
  
      /* Go do it */
+ #ifdef FENI
+  
+  /* wipe all references to this object from the feni database.  It could be
+  either of F#dbref_#dbref.
+  */
+ 
+     fbuff = alloc_lbuf("do_destroy");
+     fbuff = tprintf("#%d/F#%d_*",mudconf.feni_database, thing);
+     do_wipe(1,cause,WIPE_QUIET,fbuff);
+     fbuff = tprintf("#%d/F#*_#%d",mudconf.feni_database, thing);
+     do_wipe(1,cause,WIPE_QUIET,fbuff);
+     free_lbuf(fbuff);
+ #endif /* FENI */
  
      switch (Typeof(thing)) {
      case TYPE_EXIT:
*** src/db.c	1995/03/21 00:00:04	1.10
--- src/db.c	1998/04/18 19:40:12
***************
*** 377,382 ****
--- 377,385 ----
  #endif /* BETA_QUOTAS */
      {"VRML_URL", A_VRML_URL, AF_ODARK, NULL },
      {"HTDesc", A_HTDESC, AF_NOPROG | AF_HTML, NULL },
+ #ifdef FENI
+     {"FeniName", A_FENINAME, AF_NOPROG | AF_VISUAL | AF_PRIVATE, NULL },
+ #endif /* FENI */
      {"*Password", A_PASS, AF_DARK | AF_NOPROG | AF_NOCMD | AF_INTERNAL,
       NULL},
      {"*Privileges", A_PRIVS, AF_DARK | AF_NOPROG | AF_NOCMD | AF_INTERNAL,
***************
*** 632,637 ****
--- 635,715 ----
      atr_get_str((char *) tbuff, thing, A_NAME, &aowner, &aflags);
      return ((char *) tbuff);
  }
+ 
+ #ifdef FENI
+ 
+ INLINE char *
+ FeniName(player, it)
+     dbref player, it;
+ {
+     dbref aowner;
+     int aflags;
+     char *buff;
+     static char tbuffer[LBUF_SIZE];
+     static char *tbuff=tbuffer;
+     static char sbuffer[LBUF_SIZE];
+     static char *sbuff=sbuffer;
+     ATTR *attr;
+     char *bp;
+ /* 
+    See if player has tagged it with a personal feniname yet.  if so, pull
+    that string from the feni_database object and display it. 
+ */
+ 
+    if (Good_obj(mudconf.feni_database)) {
+      sprintf(sbuff, "f#%d_#%d",player,it);
+      attr = atr_str(sbuff);
+      if (attr) {
+        atr_get_str(tbuff, mudconf.feni_database, attr->number, &aowner, &aflags);
+        if (*tbuff) {
+ 	 return (tbuff);
+        }
+      }
+    }
+ 
+ /* 
+    Okay, no feni_database name for this combination of player/it, so
+    get the default one from it, instead.  If _that_ is blank, then combine
+    sex and species.  If THOSE are blank, use the dummy's real Name(). 
+ */
+ 
+ 
+    atr_get_str(tbuff,it, A_FENINAME, &aowner, &aflags);
+    if (*tbuff) {  
+      return (tbuff);
+    }
+ 
+ 
+ /* 
+    Okay, nothing on the feni_database, and no feniname on it, so let's
+    invent one.   use "sex species" if both are present, otherwise use the
+    real name of it.
+ */
+    bp = tbuff;
+    *tbuff = '\0';
+    *sbuff = '\0';
+ 
+    atr_get_str(sbuff, it, A_SEX, &aowner, &aflags);
+    if (*sbuff) {
+      safe_str(sbuff, tbuff, &bp);
+      *sbuff = '\0';
+    }
+    if (mudconf.feni_default > 0) {
+      atr_get_str(sbuff, it, mudconf.feni_default, &aowner, &aflags);
+      if (*sbuff) {
+        if (*tbuff) {
+          safe_chr(' ', tbuff, &bp);
+        }
+        safe_str(sbuff, tbuff, &bp);
+      }
+    } 
+    if (! *tbuff) {
+     atr_get_str(tbuff, it, A_NAME, &aowner, &aflags);
+     return (tbuff);
+    }
+    return (tbuff);
+ }
+ #endif /* FENI */
  
  INLINE void 
  s_Name(thing, s)
*** src/eval.c	1995/03/21 00:00:09	1.7
--- src/eval.c	1998/04/18 19:40:12
***************
*** 542,548 ****
--- 542,552 ----
  		if (gender < 0)
  		    gender = get_gender(cause);
  		if (!gender)
+ #ifdef FENI
+ 		    tbuf = FeniName(player, cause);
+ #else /* FENI */
  		    tbuf = Name(cause);
+ #endif
  		else
  		    tbuf = (char *) obj[gender];
  		safe_str(tbuf, buff, &bufc);
***************
*** 552,558 ****
--- 556,566 ----
  		if (gender < 0)
  		    gender = get_gender(cause);
  		if (!gender) {
+ #ifdef FENI
+ 		    safe_str(FeniName(player, cause), buff, &bufc);
+ #else /* FENI */
  		    safe_str(Name(cause), buff, &bufc);
+ #endif /* FENI */
  		    safe_chr('s', buff, &bufc);
  		} else {
  		    safe_str((char *) poss[gender],
***************
*** 574,580 ****
--- 582,592 ----
  		if (gender < 0)
  		    gender = get_gender(cause);
  		if (!gender) {
+ #ifdef FENI
+ 		    safe_str(FeniName(player,cause), buff, &bufc);
+ #else /* FENI */
  		    safe_str(Name(cause), buff, &bufc);
+ #endif /* FENI */
  		    safe_chr('s', buff, &bufc);
  		} else {
  		    safe_str((char *) absp[gender],
***************
*** 597,603 ****
--- 609,619 ----
  		break;
  	    case 'N':		/* Invoker name */
  	    case 'n':
+ #ifdef FENI
+ 		safe_str(FeniName(player,cause), buff, &bufc);
+ #else /* FENI */
  		safe_str(Name(cause), buff, &bufc);
+ #endif /* FENI */
  		break;
  	    case 'L':		/* Invoker location db# */
  	    case 'l':
*** src/externs.h	1995/03/21 00:00:11	1.9
--- src/externs.h	1998/04/18 19:40:13
***************
*** 98,103 ****
--- 98,109 ----
  				  const char *));
  extern void FDECL(notify_except2, (dbref, dbref, dbref, dbref,
  				   const char *));
+ #ifdef FENI
+ extern void FDECL(notify_except2_feni, (dbref, dbref, dbref, dbref,
+ 				   const char *, dbref));
+ extern void FDECL(notify_all_from_inside_feni, (dbref, dbref, 
+ 				   const char *, dbref));
+ #endif /* FENI */
  extern int FDECL(check_filter, (dbref, dbref, int,
  				const char *));
  extern void FDECL(notify_check, (dbref, dbref, const char *, int));
***************
*** 277,282 ****
--- 283,291 ----
  extern void FDECL(s_Pass, (dbref, const char *));
  extern void FDECL(s_Name, (dbref, const char *));
  extern char *FDECL(Name, (dbref));
+ #ifdef FENI
+ extern char *FDECL(FeniName, (dbref, dbref));
+ #endif /* FENI */
  extern int FDECL(fwdlist_load, (FWDLIST *, dbref, char *));
  extern void FDECL(fwdlist_set, (dbref, FWDLIST *));
  extern void FDECL(fwdlist_clr, (dbref));
***************
*** 524,529 ****
--- 533,541 ----
  #define	TWARP_CLEAN	4	/* Warp the cleaning interval */
  #define	TWARP_IDLE	8	/* Warp the idle check interval */
  #define	TWARP_RWHO	16	/* Warp the RWHO dump interval */
+ #ifdef FENI
+ #define WIPE_QUIET	1	/* shuts up wipe */
+ #endif /* FENI */
  
  /* Hush codes for movement messages */
  
*** src/flags.c	1995/03/21 00:00:19	1.8
--- src/flags.c	1998/04/18 19:40:14
***************
*** 560,565 ****
--- 560,607 ----
      return buf;
  }
  
+ #ifdef FENI
+ /* ---------------------------------------------------------------------------
+  * Return an lbuf containing the anonymous feniname of an object
+  */
+ 
+ char *
+ unparse_object_feni(player, target, obey_myopic)
+     dbref target, player;
+     int obey_myopic;
+ {
+     char *buf, *fp;
+     int exam;
+ 
+     buf = alloc_lbuf("unparse_object_feni");
+     if (target == NOTHING) {
+ 	strcpy(buf, "*NOTHING*");
+     } else if (target == HOME) {
+ 	strcpy(buf, "*HOME*");
+     } else if (!Good_obj(target)) {
+ 	sprintf(buf, "*ILLEGAL*(#%d)", target);
+     } else {
+ 	if (obey_myopic)
+ 	    exam = MyopicExam(player, target);
+ 	else
+ 	    exam = Examinable(player, target);
+ 	if (exam ||
+ 	    (Flags(target) & (CHOWN_OK | JUMP_OK | LINK_OK | DESTROY_OK)) ||
+ 	    (Flags2(target) & ABODE)) {
+ 
+ 	    /* show everything */
+ 	    fp = unparse_flags(player, target);
+ 	    sprintf(buf, "%s(#%d%s)", FeniName(player, target), target, fp);
+ 	    free_sbuf(fp);
+ 	} else {
+ 	    /* show only the name. */
+ 	    strcpy(buf, FeniName(player, target));
+ 	}
+     }
+     return buf;
+ }
+ #endif /* FENI */
+ 
  /* ---------------------------------------------------------------------------
   * Return an lbuf pointing to the object name and possibly the db# and flags
   */
*** src/flags.h	1995/03/21 00:00:21	1.6
--- src/flags.h	1998/04/18 19:40:14
***************
*** 173,178 ****
--- 173,181 ----
  extern char *FDECL(decode_flags, (dbref, FLAG, int));
  extern int FDECL(has_flag, (dbref, dbref, char *));
  extern char *FDECL(unparse_object, (dbref, dbref, int));
+ #ifdef FENI
+ extern char *FDECL(unparse_object_feni, (dbref, dbref, int));
+ #endif /* FENI */
  extern char *FDECL(unparse_object_numonly, (dbref));
  extern int FDECL(convert_flags, (dbref, char *, FLAGSET *, FLAG *));
  extern void FDECL(decompile_flags, (dbref, dbref, char *));
*** src/functions.c	1995/03/29 02:55:13	1.12
--- src/functions.c	1998/04/18 19:40:16
***************
*** 1818,1823 ****
--- 1819,1913 ----
      }
  }
  
+ #ifdef FENI
+ FUNCTION(fun_feniname)
+ {
+     dbref it, aowner;
+     int aflags;
+     char *s;
+     char *tbuff;
+     char *sbuff;
+     ATTR *attr;
+     char *bp;
+ 
+     it = match_thing(player, fargs[0]);
+     if (it == NOTHING) {
+ 	buff[0] = '\0';
+ 	return;
+     }
+     if (!mudconf.read_rem_name) {
+ 	if (!nearby_or_control(player, it) && !isPlayer(it)) {
+ 	    strcpy(buff, "#-1 TOO FAR AWAY TO SEE");
+ 	    return;
+ 	}
+     }
+ /* See if player has tagged it with a personal feniname yet.  if so, pull
+    that string from the feni_database object and display it. */
+ 
+ /*
+    if (Good_obj(mudconf.feni_database)) {
+      sbuff = alloc_lbuf("fun_feniname.lookup");
+      sprintf(sbuff, "f#%d_#%d",player,it);
+      attr = atr_str(sbuff);
+      if (attr) {
+        tbuff = atr_get(mudconf.feni_database, attr->number, &aowner, &aflags);
+        if (*tbuff) {
+          strcpy(buff,tbuff);
+ 	 free_lbuf(tbuff);
+ 	 free_lbuf(sbuff);
+ 	 return;
+        }
+        free_lbuf(tbuff);
+      }
+      free_lbuf(sbuff);
+    }
+ */
+ 
+ /* 
+    Okay, no feni_database name for this combination of player/it, so
+    get the default one from it, instead.  If _that_ is blank, then combine
+    sex and species.  If THOSE are blank, use the dummy's real Name(). 
+ */
+ 
+ /*
+    tbuff = atr_get(it, A_FENINAME, &aowner, &aflags);
+    if (*tbuff) {  
+      strcpy(buff, tbuff);
+      free_lbuf(tbuff);
+      return;
+    }
+    free_lbuf(tbuff);
+ */
+ 
+ /* 
+    Okay, nothing on the feni_database, and no feniname on it, so let's
+    invent one.   use "sex species" if both are present, otherwise use the
+    real name of it.
+ */
+ /*
+    bp = buff;
+    sbuff = atr_get(it, A_SEX, &aowner, &aflags);
+    if (mudconf.feni_default > 0) {
+      tbuff = atr_get(it, mudconf.feni_default, &aowner, &aflags);
+    }
+    if (*sbuff && *tbuff) {
+      safe_str(sbuff,buff,&bp);
+      safe_chr(' ',buff,&bp);
+      safe_str(tbuff,buff,&bp);
+    } else if (*tbuff) {
+      strcpy(buff, tbuff);
+    } else {
+      strcpy(buff,Name(it));
+    }
+    free_lbuf(sbuff);
+    free_lbuf(tbuff);
+ */
+ 
+   strcpy(buff,FeniName(player,it));
+   return;
+ }
+ #endif /* FENI */
+ 
  /* ---------------------------------------------------------------------------
   * fun_match, fun_matchall, fun_strmatch: Match arg2 against each word of
   * arg1 returning index of first match (or index of all matches), or against
***************
*** 5699,5704 ****
--- 5789,5797 ----
      {"EXP", fun_exp, 1, 0, CA_PUBLIC},
      {"EXTRACT", fun_extract, 0, FN_VARARGS, CA_PUBLIC},
      {"FDIV", fun_fdiv, 2, 0, CA_PUBLIC},
+ #ifdef FENI
+     {"FENINAME", fun_feniname, 1, 0, CA_PUBLIC},
+ #endif /* FENI */
      {"FILTER", fun_filter, 0, FN_VARARGS, CA_PUBLIC},
      {"FIRST", fun_first, 0, FN_VARARGS, CA_PUBLIC},
      {"FLAGS", fun_flags, 1, 0, CA_PUBLIC},
*** src/game.c	1995/03/21 00:00:27	1.9
--- src/game.c	1998/04/18 19:40:17
***************
*** 703,708 ****
--- 703,732 ----
      }
  }
  
+ #ifdef FENI
+ void 
+ notify_except_feni(loc, player, exception, msg, it)
+     dbref loc, player, exception, it;
+     const char *msg;
+ {
+     dbref first;
+     char tbuffer[LBUF_SIZE];
+     char *tbuff=tbuffer;
+ 
+     if (loc != exception)
+ 	sprintf(tbuff,msg,FeniName(loc,it));
+ 	notify_check(loc, player, tbuff,
+ 		  (MSG_ME_ALL | MSG_F_UP | MSG_S_INSIDE | MSG_NBR_EXITS_A));
+     DOLIST(first, Contents(loc)) {
+ 	if (first != exception) {
+ 	    sprintf(tbuff,msg,FeniName(first,it));
+ 	    notify_check(first, player, tbuff,
+ 			 (MSG_ME | MSG_F_DOWN | MSG_S_OUTSIDE));
+ 	}
+     }
+ }
+ #endif /* FENI */
+ 
  void 
  notify_except2(loc, player, exc1, exc2, msg)
      dbref loc, player, exc1, exc2;
***************
*** 720,725 ****
--- 744,821 ----
  	}
      }
  }
+ 
+ #ifdef FENI
+ void 
+ notify_except2_feni(loc, player, exc1, exc2, msg, it)
+     dbref loc, player, exc1, exc2, it;
+     const char *msg; 
+ /*    char *msg; */
+ {
+     dbref first;
+     char tbuffer[LBUF_SIZE];
+     char *tbuff=tbuffer;
+ 
+ /* notify the location the object it has left. */
+     if ((loc != exc1) && (loc != exc2)) {
+ 	sprintf(tbuff,msg,FeniName(loc,it));
+ 	notify_check(loc, player, tbuff,
+ 		  (MSG_ME_ALL | MSG_F_UP | MSG_S_INSIDE | MSG_NBR_EXITS_A));
+     }
+ /* notify each object in loc's contents that the object has left. */
+     DOLIST(first, Contents(loc)) {
+ 	if (first != exc1 && first != exc2) {
+ 	    sprintf(tbuff,msg,FeniName(first,it));
+ 	    notify_check(first, player, tbuff,
+ 			 (MSG_ME | MSG_F_DOWN | MSG_S_OUTSIDE));
+ 	}
+     }
+ }
+ void 
+ notify_except2_feni2(loc, player, exc1, exc2, msg, it,it2)
+     dbref loc, player, exc1, exc2, it,it2;
+     const char *msg; 
+ /*    char *msg; */
+ {
+     dbref first;
+     char tbuffer[LBUF_SIZE];
+     char *tbuff=tbuffer;
+     char sbuffer[LBUF_SIZE];
+     char *sbuff=tbuffer;
+ 
+     if ((loc != exc1) && (loc != exc2)) {
+ 	sprintf(tbuff,msg,FeniName(loc,it),FeniName(loc,it2));
+ 	notify_check(loc, player, tbuff,
+ 		  (MSG_ME_ALL | MSG_F_UP | MSG_S_INSIDE | MSG_NBR_EXITS_A));
+     }
+     DOLIST(first, Contents(loc)) {
+ 	if (first != exc1 && first != exc2) {
+ 	    sprintf(sbuff,FeniName(first,it));
+ 	    sprintf(tbuff,msg,sbuff,FeniName(first,it2));
+ 	    notify_check(first, player, tbuff,
+ 			 (MSG_ME | MSG_F_DOWN | MSG_S_OUTSIDE));
+ 	}
+     }
+ }
+ void 
+ notify_all_from_inside_feni(loc, player, msg, it)
+     dbref loc, player, it;
+     const char *msg;
+ {
+     dbref first;
+     char tbuffer[LBUF_SIZE];
+     char *tbuff=tbuffer;
+ 
+     sprintf(tbuff,msg,FeniName(loc,it));
+     notify_check(loc, player, tbuff,
+ 	(MSG_ME_ALL | MSG_F_UP | MSG_S_INSIDE | MSG_NBR_EXITS_A));
+     DOLIST(first, Contents(loc)) {
+       sprintf(tbuff,msg,FeniName(first,it));
+       notify_check(first, player, tbuff,
+ 		   (MSG_ME | MSG_F_DOWN | MSG_S_OUTSIDE));
+     }
+ }
+ #endif /* FENI */
  
  void 
  do_shutdown(player, cause, key, message)
*** src/look.c	1995/03/21 00:00:37	1.8
--- src/look.c	1998/04/18 19:40:17
***************
*** 137,144 ****
--- 137,148 ----
  	    notify(player, contents_name);
  	    DOLIST(thing, Contents(loc)) {
  		if (can_see(player, thing, can_see_loc)) {
+ #ifdef FENI
+                     buff = unparse_object_feni(player, thing, 1);
+ #else
  		    buff = unparse_object(player,
  					  thing, 1);
+ #endif /* FENI */
  		    notify(player, buff);
  		    free_lbuf(buff);
  		}
***************
*** 179,197 ****
--- 183,217 ----
  	    notify(player, contents_name);
  	    DOLIST(thing, Contents(loc)) {
  		if (can_see(player, thing, can_see_loc)) {
+ #ifdef FENI
+                     buff = unparse_object_feni(player, thing, 1);
+ #else
  		    buff = unparse_object(player,
  					  thing, 1);
+ #endif /* FENI */
  		    html_cp = html_buff;
  		    if (Html(player)) {
  			safe_str("<a xch_cmd=\"look ", html_buff, &html_cp);
  			switch (style) {
  			    case CONTENTS_LOCAL:
+ #ifdef FENI
+ 				safe_str(FeniName(player, thing), html_buff, &html_cp);
+ #else /* FENI */
  				safe_str(Name(thing), html_buff, &html_cp);
+ #endif /* FENI */
  				break;
  			    case CONTENTS_NESTED:
+ #ifdef FENI
+ 				safe_str(FeniName(player, Location(thing)), html_buff, &html_cp);
+ #else /* FENI */
  				safe_str(Name(Location(thing)), html_buff, &html_cp);
+ #endif /* FENI */
  				safe_str("'s ", html_buff, &html_cp);
+ #ifdef FENI
+ 				safe_str(FeniName(player, thing), html_buff, &html_cp);
+ #else /* FENI */
  				safe_str(Name(thing), html_buff, &html_cp);
+ #endif /* FENI */
  				break;
  			    case CONTENTS_REMOTE:
  				sprintf(remote_num, "#%d", thing);
***************
*** 359,365 ****
--- 379,389 ----
      /* Get the name and db-number if we can examine it. */
  
      if (Examinable(player, thing)) {
+ #ifdef FENI
+ 	buff = unparse_object_feni(player, thing, 1);
+ #else /* FENI */
  	buff = unparse_object(player, thing, 1);
+ #endif /* FENI */
  	notify(player, buff);
  	free_lbuf(buff);
      }
***************
*** 462,468 ****
--- 486,496 ----
  
      /* tell him the name, and the number if he can link to it */
  
+ #ifdef FENI
+     s = unparse_object_feni(player, loc, 1);
+ #else /* FENI */
      s = unparse_object(player, loc, 1);
+ #endif
  #ifdef PUEBLO_SUPPORT
      if (Html(player)) {
  	notify_html(player, "<center><h3>");
***************
*** 792,798 ****
--- 820,830 ----
      control = (Examinable(player, thing) || Link_exit(player, thing));
  
      if (control && (key != EXAM_BRIEF)) {
+ #ifdef FENI
+ 	buf2 = unparse_object_feni(player, thing, 0);
+ #else /* FENI */
  	buf2 = unparse_object(player, thing, 0);
+ #endif /* FENI */
  	notify(player, buf2);
  	free_lbuf(buf2);
  	if (mudconf.ex_flags) {
***************
*** 805,819 ****
--- 837,864 ----
  	    ((key == EXAM_DEFAULT) && !mudconf.exam_public)) {
  	    if (mudconf.read_rem_name) {
  		buf2 = alloc_lbuf("do_examine.pub_name");
+ #ifdef FENI
+ 		strcpy(buf2, FeniName(player, thing));
+ 		notify(player,
+ 		       tprintf("%s is owned by %s",
+ 			       buf2, FeniName(player, Owner(thing))));
+ #else /* FENI */
  		strcpy(buf2, Name(thing));
  		notify(player,
  		       tprintf("%s is owned by %s",
  			       buf2, Name(Owner(thing))));
+ #endif /* FENI */
  		free_lbuf(buf2);
  	    } else {
+ #ifdef FENI
+ 		notify(player,
+ 		       tprintf("Owned by %s",
+ 			       FeniName(player, Owner(thing))));
+ #else /* FENI */
  		notify(player,
  		       tprintf("Owned by %s",
  			       Name(Owner(thing))));
+ #endif /* FENI */
  	    }
  	    return;
  	}
***************
*** 883,889 ****
--- 928,938 ----
  	if (Contents(thing) != NOTHING) {
  	    notify(player, "Contents:");
  	    DOLIST(content, Contents(thing)) {
+ #ifdef FENI
+ 		buf2 = unparse_object_feni(player, content, 0);
+ #else /* FENI */
  		buf2 = unparse_object(player, content, 0);
+ #endif /* FENI */
  		notify(player, buf2);
  		free_lbuf(buf2);
  	    }
***************
*** 987,993 ****
--- 1036,1046 ----
      if (!control)
  	if (mudconf.read_rem_name) {
  	    buf2 = alloc_lbuf("do_examine.pub_name");
+ #ifdef FENI
+ 	    strcpy(buf2, FeniName(player, thing));
+ #else /* FENI */
  	    strcpy(buf2, Name(thing));
+ #endif /* FENI */
  	    notify(player,
  		   tprintf("%s is owned by %s",
  			   buf2, Name(Owner(thing))));
***************
*** 1024,1030 ****
--- 1077,1087 ----
      } else {
  	notify(player, "You are carrying:");
  	DOLIST(thing, thing) {
+ #ifdef FENI
+ 	    buff = unparse_object_feni(player, thing, 1);
+ #else /* FENI */
  	    buff = unparse_object(player, thing, 1);
+ #endif /* FENI */
  	    notify(player, buff);
  	    free_lbuf(buff);
  	}
***************
*** 1255,1261 ****
--- 1312,1322 ----
  	    safe_str((char *) "player ", buf, &bp);
  	if (ispuppet) {
  	    safe_str((char *) "puppet(", buf, &bp);
+ #ifdef FENI
+ 	    safe_str(FeniName(player, Owner(what)), buf, &bp);
+ #else /* FENI */
  	    safe_str(Name(Owner(what)), buf, &bp);
+ #endif /* FENI */
  	    safe_str((char *) ") ", buf, &bp);
  	}
  	if (isconnected)
***************
*** 1264,1274 ****
--- 1325,1344 ----
  	    safe_str((char *) "parent ", buf, &bp);
  	*--bp = '\0';		/* nuke the space at the end */
  	if (!isExit(what)) {
+ #ifdef FENI
+ 	    notify(player, tprintf("  %s is listening. [%s]",
+ 				   FeniName(player,what), buf));
+ #else /* FENI */
  	    notify(player, tprintf("  %s is listening. [%s]",
  				   Name(what), buf));
+ #endif /* FENI */
  	} else {
  	    buf2 = alloc_lbuf("sweep_check.name");
+ #ifdef FENI
+ 	    strcpy(buf2, FeniName(player, what));
+ #else /* FENI */
  	    strcpy(buf2, Name(what));
+ #endif /* FENI */
  	    for (bp = buf2; *bp && (*bp != ';'); bp++);
  	    *bp = '\0';
  	    notify(player,
*** src/match.c	1995/03/21 00:00:39	1.7
--- src/match.c	1998/04/18 19:40:18
***************
*** 304,309 ****
--- 304,323 ----
  	    match_count++;
  	    local_match = 1;
  	}
+ #ifdef FENI
+ 	else {
+ 	  namebuf = FeniName(match_who, first);
+ 	  if (!string_compare(namebuf, match_name)) {
+ 	      /* if multiple exact matches, randomly choose one */
+ 	      exact_match = choose_thing(exact_match, first);
+ 	      local_match = 1;
+ 	  } else if (string_match(namebuf, match_name)) {
+ 	      last_match = first;
+ 	      match_count++;
+ 	      local_match = 1;
+ 	  }
+ 	}
+ #endif /* FENI */
      }
  }
  
*** src/move.c	1995/03/21 00:00:45	1.8
--- src/move.c	1998/04/18 19:40:19
***************
*** 69,76 ****
--- 69,81 ----
  
      if ((!Dark(thing) && !Dark(loc)) ||
  	(canhear && !(Wizard(thing) && Dark(thing)))) {
+ #ifdef FENI
+ 	notify_except2_feni(loc, thing, thing, cause,
+ 		       "%s has left.", thing);
+ #else
  	notify_except2(loc, thing, thing, cause,
  		       tprintf("%s has left.", Name(thing)));
+ #endif /* FENI */
      }
  }
  
***************
*** 126,133 ****
--- 131,143 ----
       */
  
      if (canhear && !(Dark(thing) && Wizard(thing))) {
+ #ifdef FENI
+ 	notify_except2_feni(loc, thing, thing, cause,
+ 		       "%s has arrived.", thing);
+ #else
  	notify_except2(loc, thing, thing, cause,
  		       tprintf("%s has arrived.", Name(thing)));
+ #endif /* FENI */
      }
  }
  
*** src/mudconf.h	1995/03/29 23:42:53	1.10
--- src/mudconf.h	1998/04/18 19:40:19
***************
*** 186,191 ****
--- 186,195 ----
        int ntfy_nest_lim;	/* Max nesting of notifys */
        int lock_nest_lim;	/* Max nesting of lock evals */
        int parent_nest_lim;	/* Max levels of parents */
+ #ifdef FENI
+       int feni_database;	/* dbref of database object for FENI relationships */
+       int feni_default;		/* number of attrib to look for if no @feniname */
+ #endif /* FENI */
  #else
        int paylimit;		/* getting money gets hard over this much */
        int digcost;		/* cost of @dig command */
***************
*** 208,213 ****
--- 212,221 ----
        int log_info;		/* Info that goes into log entries */
        Uchar markdata[8];	/* Masks for marking/unmarking */
        int ntfy_nest_lim;	/* Max nesting of notifys */
+ #ifdef FENI
+       int feni_database;	/* dbref of database object for FENI relationships */
+       int feni_default;		/* number of attrib to look for if no @feniname */
+ #endif /* FENI */
  #endif /* STANDALONE */
    };
  
*** src/predicates.c	1995/03/21 00:01:03	1.8
--- src/predicates.c	1998/04/18 19:40:20
***************
*** 534,540 ****
--- 534,544 ----
  
      if (!could_hear && can_hear) {
  	buff = alloc_lbuf("handle_ears.grow");
+ #ifdef FENI
+ 	strcpy(buff, FeniName(thing, thing));
+ #else /* FENI */
  	strcpy(buff, Name(thing));
+ #endif /* FENI */
  	if (isExit(thing)) {
  	    for (bp = buff; *bp && (*bp != ';'); bp++);
  	    *bp = '\0';
***************
*** 547,553 ****
--- 551,561 ----
  	free_lbuf(buff);
      } else if (could_hear && !can_hear) {
  	buff = alloc_lbuf("handle_ears.lose");
+ #ifdef FENI
+ 	strcpy(buff, FeniName(thing,thing));
+ #else /* FENI */
  	strcpy(buff, Name(thing));
+ #endif /* FENI */
  	if (isExit(thing)) {
  	    for (bp = buff; *bp && (*bp != ';'); bp++);
  	    *bp = '\0';
***************
*** 1073,1091 ****
--- 1081,1114 ----
  	    }
  	    buff = exec(thing, player, EV_EVAL | EV_FIGNORE | EV_TOP,
  			d, args, nargs);
+ #ifdef FENI
+ 	    notify_except2_feni(loc, player, player, thing,
+ 			   tprintf("%s %s", "%s", buff),player);
+ #else
  	    notify_except2(loc, player, player, thing,
  			   tprintf("%s %s", Name(player), buff));
+ #endif /* FENI */
  	    free_lbuf(buff);
  	} else if (odef) {
+ #ifdef FENI
+ 	    notify_except2_feni(loc, player, player, thing,
+ 			   tprintf("%s %s", "%s", odef),player);
+ #else
  	    notify_except2(loc, player, player, thing,
  			   tprintf("%s %s", Name(player), odef));
+ #endif /* FENI */
  	}
  	free_lbuf(d);
      } else if ((owhat < 0) && def && Has_location(player) &&
  	       Good_obj(loc = Location(player))) {
  	if (odef) {
+ #ifdef FENI
+ 	    notify_except2_feni(loc, player, player, thing,
+ 			   tprintf("%s %s", "%s", odef),player);
+ #else
  	    notify_except2(loc, player, player, thing,
  			   tprintf("%s %s", Name(player), odef));
+ #endif /* FENI */
  	}
      }
  
*** src/set.c	1995/03/21 00:01:09	1.8
--- src/set.c	1998/04/18 19:40:21
***************
*** 1123,1129 ****
      char *atext;
  
      if (!it || !*it || !parse_attrib_wild(player, it, &thing, 0, 0, 1)) {
! 	notify_quiet(player, "No match.");
  	return;
      }
      /* Iterate through matching attributes, zapping the writable ones */
--- 1123,1132 ----
      char *atext;
  
      if (!it || !*it || !parse_attrib_wild(player, it, &thing, 0, 0, 1)) {
! #ifdef FENI
! 	if (!(key & WIPE_QUIET))
! #endif /* FENI */
! 	  notify_quiet(player, "No match.");
  	return;
      }
      /* Iterate through matching attributes, zapping the writable ones */
***************
*** 1150,1158 ****
--- 1153,1168 ----
      olist_init();
  
      if (!got_one) {
+ #ifdef FENI
+       if (!(key & WIPE_QUIET))
+ #endif /* FENI */
  	notify_quiet(player, "No matching attributes.");
      } else {
+ #ifdef FENI
+ 	if (!Quiet(player) && !(key & WIPE_QUIET))
+ #else /* FENI */
  	if (!Quiet(player))
+ #endif /* FENI */
  	    notify_quiet(player, "Wiped.");
      }
  }
***************
*** 1262,1264 ****
--- 1272,1325 ----
      }
      do_setattr(player, cause, anum, s, arg2);
  }
+ 
+ #ifdef FENI
+ 
+ void 
+ do_remember(player, cause, key, feniname, remembername)
+     dbref player, cause;
+     int key;
+     char *feniname, *remembername;
+ {
+     dbref thing;
+     char *buff;
+     char tbuffer[LBUF_SIZE];
+     char *tbuff=tbuffer;
+     int anum;
+ 
+     if (*feniname == '\0') {
+ 	notify_quiet(player, "Give what a new feniname?");
+ 	return;
+     }
+ 
+     init_match(player, feniname, NOTYPE);
+     match_everything(MAT_EXIT_PARENTS);
+     thing = match_result();
+ 
+     /* get the original feniname of the target */
+     switch (thing) {
+       case NOTHING:
+         notify_quiet(player, "I don't see that here.");
+ 	return;
+       case AMBIGUOUS:
+ 	notify_quiet(player,
+ 		     "I don't know which one you want to feniname!");
+ 	return;
+       default:
+ 	buff = FeniName(player,thing);
+         if (*remembername == '\0') {
+ 	  notify(player, tprintf("You will no longer remember %s.",buff));
+ 	} else {
+ 	  notify(player,
+ 	       tprintf("You will now remember %s as %s.", buff, remembername));
+         }
+ 	buff = tprintf("f#%d_#%d", player, thing);
+ 	anum = mkattr(buff);
+ 	if (anum <= 0) {
+ 	  notify_quiet(player,"Unable to store feniname.");
+ 	  return;
+ 	}
+         set_attr_internal(1, mudconf.feni_database, anum, remembername, SET_QUIET); 
+      }
+ }
+ #endif /* FENI */
*** src/speech.c	1995/03/21 00:01:11	1.9
--- src/speech.c	1998/04/18 19:55:00
***************
*** 50,55 ****
--- 50,59 ----
      dbref loc;
      char *buf2, *bp;
      int say_flags, depth;
+ #ifdef FENI
+     char tbuffer[LBUF_SIZE];
+     char *tbuff=tbuffer;
+ #endif /* FENI */
  
      /* Convert prefix-coded messages into the normal type */
  
***************
*** 104,124 ****
--- 108,150 ----
      case SAY_SAY:
  #ifdef COMMA_IN_SAY
  	notify(player, tprintf("You say, \"%s\"", message));
+ #ifdef FENI
+         sprintf(tbuff,"%s says, \"%s\"", "%s", message);
+ 	notify_except_feni(loc, player, player,
+ 		      tbuff, player);
+ #else /* FENI */
  	notify_except(loc, player, player,
  		      tprintf("%s says, \"%s\"", Name(player), message));
+ #endif /* FENI */
  #else
  	notify(player, tprintf("You say \"%s\"", message));
+ #ifdef FENI
+         sprintf(tbuff,"%s says \"%s\"", "%s", message);
+ 	notify_except_feni(loc, player, player,
+ 		      tbuff, player);
+ #else /* FENI */
  	notify_except(loc, player, player,
  		      tprintf("%s says \"%s\"", Name(player), message));
+ #endif /* FENI */
  #endif /* COMMA_IN_SAY */
  	break;
      case SAY_POSE:
+ #ifdef FENI
+ 	notify_all_from_inside_feni(loc, player,
+ 			       tprintf("%s %s", "%s", message),player);
+ #else /* FENI */
  	notify_all_from_inside(loc, player,
  			       tprintf("%s %s", Name(player), message));
+ #endif /* FENI */
  	break;
      case SAY_POSE_NOSPC:
+ #ifdef FENI
+ 	notify_all_from_inside_feni(loc, player,
+ 			       tprintf("%s%s", "%s", message),player);
+ #else /* FENI */
  	notify_all_from_inside(loc, player,
  			       tprintf("%s%s", Name(player), message));
+ #endif /* FENI */
  	break;
      case SAY_EMIT:
  #ifdef PARANOID_EMIT
***************
*** 434,444 ****
--- 460,483 ----
      char *message;
  {
      char *buff;
+ #ifdef FENI
+     char tbuffer[LBUF_SIZE];
+     char *tbuff=tbuffer;
+ #endif /* FENI */
  
      buff = alloc_lbuf("do_pemit.whisper.pose");
+ #ifdef FENI
+     strcpy(buff, FeniName(target,player));
+ #else /* FENI */
      strcpy(buff, Name(player));
+ #endif /* FENI */
+ #ifdef FENI
+     notify(player,
+ 	   tprintf("%s senses \"%s%s\"", FeniName(player, target), buff, message));
+ #else /* FENI */
      notify(player,
  	   tprintf("%s senses \"%s%s\"", Name(target), buff, message));
+ #endif /* FENI */
      notify_with_cause(target, player,
  		      tprintf("You sense %s%s", buff, message));
      free_lbuf(buff);
***************
*** 497,502 ****
--- 536,545 ----
      dbref target, loc;
      char *buf2, *bp;
      int do_contents, ok_to_do, depth, pemit_flags;
+ #ifdef FENI
+     char tbuffer[LBUF_SIZE];
+     char *tbuff=tbuffer;
+ #endif /* FENI */
  
      if (key & PEMIT_CONTENTS) {
  	do_contents = 1;
***************
*** 624,639 ****
--- 667,696 ----
  	    case '"':
  		message++;
  	    default:
+ #ifdef FENI
+ 		notify(player,
+ 		       tprintf("You whisper \"%s\" to %s.",
+ 			       message, FeniName(player, target)));
+ 		notify_with_cause(target, player,
+ 				  tprintf("%s whispers \"%s\"",
+ 					  FeniName(target, player), message));
+ #else /* FENI */
  		notify(player,
  		       tprintf("You whisper \"%s\" to %s.",
  			       message, Name(target)));
  		notify_with_cause(target, player,
  				  tprintf("%s whispers \"%s\"",
  					  Name(player), message));
+ #endif /* FENI */
  	    }
  	    if ((!mudconf.quiet_whisper) && !Wizard(player)) {
  		loc = where_is(player);
  		if (loc != NOTHING) {
+ #ifdef FENI
+ 		    notify_except2_feni2(loc, player, player,
+ 				   target, "%s whispers something to %s", 
+ 				   player, target);
+ #else /* FENI */
  		    buf2 = alloc_lbuf("do_pemit.whisper.buzz");
  		    bp = buf2;
  		    safe_str(Name(player), buf2, &bp);
***************
*** 643,648 ****
--- 700,706 ----
  		    notify_except2(loc, player, player,
  				   target, buf2);
  		    free_lbuf(buf2);
+ #endif /* FENI */
  		}
  	    }
  	    break;
***************
*** 650,664 ****
  #ifdef COMMA_IN_SAY
  	    notify(target, tprintf("You say, \"%s\"", message));
  	    if (loc != NOTHING) {
  		notify_except(loc, player, target,
  			      tprintf("%s says, \"%s\"", Name(target),
  #else
  	    notify(target, tprintf("You say \"%s\"", message));
  	    if (loc != NOTHING) {
  		notify_except(loc, player, target,
  			      tprintf("%s says \"%s\"", Name(target),
- #endif /* COMMA_IN_SAY */
  				      message));
  	    }
  	    break;
  	case PEMIT_FPOSE:
--- 708,735 ----
  #ifdef COMMA_IN_SAY
  	    notify(target, tprintf("You say, \"%s\"", message));
  	    if (loc != NOTHING) {
+ #ifdef FENI
+                 sprintf(tbuff,"%s says, \"%s\"", "%s", message);
+ 		notify_except_feni(loc, player, target,
+ 			      tbuff, target);
+ #else /* FENI */
  		notify_except(loc, player, target,
  			      tprintf("%s says, \"%s\"", Name(target),
+ 				      message));
+ #endif /* FENI */
  #else
  	    notify(target, tprintf("You say \"%s\"", message));
  	    if (loc != NOTHING) {
+ #ifdef FENI
+                 sprintf(tbuff,"%s says \"%s\"", "%s", message);
+ 		notify_except_feni(loc, player, target,
+ 			      tbuff, target);
+ #else /* FENI */
  		notify_except(loc, player, target,
  			      tprintf("%s says \"%s\"", Name(target),
  				      message));
+ #endif /* FENI */
+ #endif /* COMMA_IN_SAY */
  	    }
  	    break;
  	case PEMIT_FPOSE:
*** text/help.txt	1998/04/18 20:11:16	1.1
--- text/help.txt	1998/04/18 20:16:50
***************
*** 75,88 ****
    ARBITRARY COMMANDS  ATTRIBUTE OWNERSHIP BEING KILLED        BOGUS COMMANDS
    BOOLEAN VALUES      COMMAND EVALUATION  CONTROL             COSTS
    CREDITS             DROP-TO             ENACTOR             EXITS
!   FAILURE             FLAG LIST           FLAGS               FUNCTION LIST
!   FUNCTIONS           GENDER              GOALS               HERE
!   HOMES               LINKING             LISTENING           LISTS
!   LOOPING             ME                  MONEY               MOVING
!   OBJECT TYPES        PARENT OBJECTS      PATCHLEVEL	      PUPPETS
!   ROBBERY             SEARCH CLASSES      SEMAPHORES          SPOOFING
!   STACK		      SUBSTITUTIONS       SUCCESS             SWITCHES
!   VERBS		      WIZARDS
  
  & drop 
    Command: drop[/<switch>] <object>
--- 75,87 ----
    ARBITRARY COMMANDS  ATTRIBUTE OWNERSHIP BEING KILLED        BOGUS COMMANDS
    BOOLEAN VALUES      COMMAND EVALUATION  CONTROL             COSTS
    CREDITS             DROP-TO             ENACTOR             EXITS
!   FAILURE             FENI                FLAG LIST           FLAGS               
!   FUNCTION LIST       HOMES               LINKING             LISTENING           
!   LISTS               LOOPING             ME                  MONEY               
!   MOVING              OBJECT TYPES        PARENT OBJECTS      PATCHLEVEL	      
!   PUPPETS             ROBBERY             SEARCH CLASSES      SEMAPHORES          
!   SPOOFING            STACK		  SUBSTITUTIONS       SUCCESS             
!   SWITCHES            VERBS               WIZARDS
  
  & drop 
    Command: drop[/<switch>] <object>
***************
*** 780,785 ****
--- 779,800 ----
    Some MUSHes may restrict the use of this command.
    See also: @emit, @fpose, @fsay, INHERIT, SPOOFING.
  
+ & @feniname
+   Command: @feniname <object>=<name>
+   Attribute: Feniname
+    
+   Sets the feniname by which other players will see you.  If you do not 
+   specify a feniname for yourself, others will see a combination of your sex
+   and another attribute as defined for your server (ie species), or your
+   true name if neither of those are defined.
+    
+   The feniname should be a very short description of your character or 
+   object, not an entire desc.  IE, "A tall human in a blue jacket".  The
+   feniname appears in every Say, Pose, Move, or other in-character use where
+   your name would otherwise appear. 
+   
+   See also: feniname(), @remember.
+ 
  & @find
    Command: @find <name>[,<low>[,<high>]]
   
***************
*** 2694,2699 ****
--- 2709,2726 ----
    Example: @reject me = I _told_ you not to page me anymore...
    See also: @away, @idle, page.
  
+ & @remember
+   Command: @remember <object>=<name>
+    
+   This command allows you to assign names of your own chosing to objects 
+   and players you meet.  Once a name is assigned, you will see that name
+   automatically whenever you encounter the object or player.  No one but you
+   can see the names you have assigned to others.  Once you have assigned a
+   name of your own to a player or object, you will no longer see that player's
+   @feniname attribute.
+   
+   See also: feniname(), @feniname.
+ 
  & @rfail
    Command: @rfail <object> = <message>
    Attribute: Rfail
***************
*** 3415,3421 ****
    performed in an action list to return information about the enactor:
   
      %# or [v(#)]           - Database number of the enactor
!     %N/%n or [v(N)]/[v(n)] - Name of the enactor.
      %O/%o ...              - Objective pronoun for the enactor
                               (him her it them)
      %P/%p ...              - Possessive pronoun (his her its their)
--- 3442,3448 ----
    performed in an action list to return information about the enactor:
   
      %# or [v(#)]           - Database number of the enactor
!     %N/%n or [v(N)]/[v(n)] - FeniName of the enactor.
      %O/%o ...              - Objective pronoun for the enactor
                               (him her it them)
      %P/%p ...              - Possessive pronoun (his her its their)
***************
*** 3509,3514 ****
--- 3536,3570 ----
    to look around (because it's locked).
    See also: get, look, @afail, @fail, @lock, @ofail, STRINGS.
  
+ & FENI
+   Topic: FENI
+ 
+   The FENI system provides automatic anonymity to players moving about in
+   the environment.  Rather than revealing your name to everyone who joins 
+   you in a room, they see a short description of you, as provided in your
+   @feniname attribute.  If you do not provide a @feniname yourself, the 
+   server will invent one based on your sex and a secondary attribute as 
+   shown in @list options, for instance, &SPECIES.  The @feniname value 
+   should be short and generic, what someone would unconsciously notice 
+   when scanning a room.  For example, Han Solo's @feniname might contain
+   "Scruffy human in a blue jacket."  If left blank, he might show up as
+   "Male human" depending upon the server's configuration.
+   
+   Continued in: FENI2
+   See also: @feniname, feniname(), @remember
+ 
+ & FENI2
+   Most areas of the server code that automatically reveal names, including
+   speech, posing, movement, @sweep, and %N have been changed to provide 
+   only the FENI name, where possible.  However, some commands like examine
+   have been left unaltered, to allow victims to identify their harrassers.
+   
+   There may be softcoded additions to the FENI environment, so be sure to
+   check NEWS, +help, +info, or whatever help commands your server provides
+   for additional information.
+    
+   See also: @feniname, feniname(), @remember
+ 
  & FLAGS
    Topic: FLAGS
   
***************
*** 3922,3928 ****
      %o, %O  = Name, him, her, it, them.       (objective)
      %p, %P  = Name's, his, her, its, their.   (possessive)
      %a, %A  = Name's, his, hers, its, theirs. (absolute possessive)
!     %n, %N  = the player's name.
      %r      = carriage return
      %t      = tab character
      %b      = space character
--- 3978,3984 ----
      %o, %O  = Name, him, her, it, them.       (objective)
      %p, %P  = Name's, his, her, its, their.   (possessive)
      %a, %A  = Name's, his, hers, its, theirs. (absolute possessive)
!     %n, %N  = the player's FeniName.
      %r      = carriage return
      %t      = tab character
      %b      = space character
***************
*** 4799,4804 ****
--- 4855,4880 ----
   
    See also: LISTS, match().
   
+ & FENINAME()
+   feniname(<dbref>)
+    
+   This function returns the feniname of the specified object, as known
+   by the object calling the function.  This value is found by:
+     1) searching the feni_database object for values stored with the
+        @remember command by looker,
+     2) examining the object for a feniname attribute,
+     3) computing a value based on the object's sex and optional feni
+        attribute (as defined for this server,)
+     4) the object's true name.
+    
+   Name    Sex   Species   Feniname        Value returned
+   Foo      -       -      -               Foo
+   Foo      ?       ?      Walking Carpet  Walking Carpet
+   Foo     Male     -      -               Male
+   Foo     Male  Wookiee   -               Male Wookiee
+   
+   See also: name(), fullname(), @remember.
+ 
  & FLAGS()
    flags(<object>)
   
***************
*** 4883,4893 ****
  
  & NAME()
    name(<dbref>)
!  
    This function returns the name of the indicated object.  When called with
    an exit it returns the only the first alias.
! 
!   See also: fullname().
  
  & FULLNAME()
    Function: fullname(<dbref>)
--- 4959,4969 ----
  
  & NAME()
    name(<dbref>)
!    
    This function returns the name of the indicated object.  When called with
    an exit it returns the only the first alias.
!   
!   See also: feniname(), fullname().
  
  & FULLNAME()
    Function: fullname(<dbref>)
***************
*** 4896,4902 ****
    same as name() in all cases except when <dbref> is an exit, then all the
    aliases are returned as well.
   
!   See also: name().
  
  & NEXT()
    next(<thing>)
--- 4972,4978 ----
    same as name() in all cases except when <dbref> is an exit, then all the
    aliases are returned as well.
   
!   See also: feniname(), name().
  
  & NEXT()
    next(<thing>)
*** text/wizhelp.txt	1998/04/18 20:13:26	1.1
--- text/wizhelp.txt	1998/04/18 20:16:51
***************
*** 37,45 ****
  & topics
    Help available on the following Topics:
   
!   CAUTIONS         CONFIG PARAMETERS  DEBUG FEATURES     FILES
!   FLAGS            INHERITANCE        LOGGING            MASTER ROOM
!   PERMISSIONS      SEARCH CRITERIA    SITE LISTS
  
  & flags
    Information is available on the following flags:
--- 37,45 ----
  & topics
    Help available on the following Topics:
   
!   CAUTIONS         CONFIG PARAMETERS  DEBUG FEATURES     FENI
!   FILES            FLAGS              INHERITANCE        LOGGING            
!   MASTER ROOM      PERMISSIONS        SEARCH CRITERIA    SITE LISTS
  
  & flags
    Information is available on the following flags:
***************
*** 1298,1303 ****
--- 1298,1337 ----
    teleport out of locations that they do not control or which are not set
    JUMP_OK.  If the teleporting player is inside an object, the room that
    ultimately contains the object is checked.  Going home is unaffected.
+ 
+ & FENI
+   Topic: FENI
+ 
+   The FENI system provides in-character anonymity to characters who are 
+   wandering about the environment.  Many areas where the server routinely
+   delivers a character's real name have been replaced with a new call that
+   delivers an anonymous feniname, a very short physical description of the
+   player.  
+   
+   See also: feni_database, feni_default, player @feniname, feniname(),
+     @remember
+ 
+ & feni_database
+   Config parameter: feni_database <objectnum>.  Default: (none)
+   Specifies the number of the object that contains feniname relationships 
+   created with the @remember command.  This object need not be owned by God
+   or any particular wizard, and may contain other attributes as required by
+   any softcoded additions to the FENI system.  For further information, see 
+   the README.FENI file included with the FENI patch sources.
+   
+   See also: feni_default, @list options.
+ 
+ & feni_default
+   Config parameter: feni_default <attrnum>.  Default: (none)
+   Specifies the number of the attribute which will be used, along with the @sex
+   attribute, when generating a default feniname for a player who has not
+   specified one for himself via the @feniname attribute.  For example, 
+   if you specify a user attribute called &species, with number 258, the 
+   server will combine sex and species, if both are provided.  If sex is 
+   provided and species is not, then only the sex is displayed.  If neither
+   are provided, the player's true name is used instead.  
+   
+   See also: feni_default, @list options.
  
  & find_money_chance
    Config parameter: find_money_chance .  Default: 0

Frames Homepage Non-Frames Homepage

Say no to monopolies, BOYCOTT MICROSOFT!
KMFMS, one of the Angry Penguins.
[U.S. Flag] In memory of those who died Sept. 11, 2001 at the World Trade Center, the Pentagon, and on American Airlines Flight 11, United Airlines Flight 175, American Airlines Flight 77, and United Airlines Flight 93
Honoring Marsh & McLennan professionals I've worked with, including:
Jack Aron, Valerie Hanna, Joe Sisolak, Greg Reda, and Cathy Fagan.
Shattered Photoessay by James Nachtewy

Comments may be sent to gyles19@nospam.visi.com

This page last updated Monday, 15-Jun-1998 17:57:44 CDT.