lima-1.0b5/
lima-1.0b5/driver/
lima-1.0b5/driver/ChangeLog.old/
lima-1.0b5/driver/Win32/
lima-1.0b5/driver/compat/
lima-1.0b5/driver/include/
lima-1.0b5/driver/testsuite/
lima-1.0b5/driver/testsuite/clone/
lima-1.0b5/driver/testsuite/command/
lima-1.0b5/driver/testsuite/data/
lima-1.0b5/driver/testsuite/etc/
lima-1.0b5/driver/testsuite/include/
lima-1.0b5/driver/testsuite/inherit/
lima-1.0b5/driver/testsuite/inherit/master/
lima-1.0b5/driver/testsuite/log/
lima-1.0b5/driver/testsuite/single/
lima-1.0b5/driver/testsuite/single/tests/compiler/
lima-1.0b5/driver/testsuite/single/tests/efuns/
lima-1.0b5/driver/testsuite/single/tests/operators/
lima-1.0b5/driver/testsuite/u/
lima-1.0b5/driver/tmp/
lima-1.0b5/etc/
lima-1.0b5/lib/WWW/help/
lima-1.0b5/lib/cmds/
lima-1.0b5/lib/cmds/create/
lima-1.0b5/lib/cmds/player/attic/
lima-1.0b5/lib/contrib/bboard/
lima-1.0b5/lib/contrib/boards/
lima-1.0b5/lib/contrib/marriage/
lima-1.0b5/lib/contrib/roommaker/
lima-1.0b5/lib/contrib/transient_effect/
lima-1.0b5/lib/daemons/channel/
lima-1.0b5/lib/daemons/imud/
lima-1.0b5/lib/data/
lima-1.0b5/lib/data/config/
lima-1.0b5/lib/data/links/
lima-1.0b5/lib/data/news/
lima-1.0b5/lib/data/players/
lima-1.0b5/lib/data/secure/
lima-1.0b5/lib/domains/
lima-1.0b5/lib/domains/std/2.4.5/maze1/
lima-1.0b5/lib/domains/std/2.4.5/npc/
lima-1.0b5/lib/domains/std/2.4.5/post_dir/
lima-1.0b5/lib/domains/std/2.4.5/sub/
lima-1.0b5/lib/domains/std/camera/
lima-1.0b5/lib/domains/std/config/
lima-1.0b5/lib/domains/std/cult/
lima-1.0b5/lib/domains/std/effects/
lima-1.0b5/lib/domains/std/misc/
lima-1.0b5/lib/domains/std/monsters/
lima-1.0b5/lib/domains/std/recorder/
lima-1.0b5/lib/domains/std/rooms/
lima-1.0b5/lib/domains/std/rooms/beach/
lima-1.0b5/lib/domains/std/rooms/labyrinth/
lima-1.0b5/lib/domains/std/school/
lima-1.0b5/lib/domains/std/school/O/
lima-1.0b5/lib/domains/std/spells/
lima-1.0b5/lib/domains/std/spells/stock-mage/
lima-1.0b5/lib/domains/std/spells/stock-priest/
lima-1.0b5/lib/help/
lima-1.0b5/lib/help/admin/
lima-1.0b5/lib/help/hints/General_Questions/
lima-1.0b5/lib/help/hints/Pirate_Quest/
lima-1.0b5/lib/help/player/
lima-1.0b5/lib/help/player/bin/
lima-1.0b5/lib/help/player/quests/
lima-1.0b5/lib/help/wizard/
lima-1.0b5/lib/help/wizard/coding/guilds/
lima-1.0b5/lib/help/wizard/coding/rooms/
lima-1.0b5/lib/help/wizard/lib/daemons/
lima-1.0b5/lib/help/wizard/lib/lfun/
lima-1.0b5/lib/help/wizard/lib/std/
lima-1.0b5/lib/help/wizard/mudos_doc/
lima-1.0b5/lib/help/wizard/mudos_doc/applies/
lima-1.0b5/lib/help/wizard/mudos_doc/applies/interactive/
lima-1.0b5/lib/help/wizard/mudos_doc/applies/parsing/
lima-1.0b5/lib/help/wizard/mudos_doc/concepts/
lima-1.0b5/lib/help/wizard/mudos_doc/driver/
lima-1.0b5/lib/help/wizard/mudos_doc/efuns/
lima-1.0b5/lib/help/wizard/mudos_doc/efuns/arrays/
lima-1.0b5/lib/help/wizard/mudos_doc/efuns/buffers/
lima-1.0b5/lib/help/wizard/mudos_doc/efuns/compile/
lima-1.0b5/lib/help/wizard/mudos_doc/efuns/filesystem/
lima-1.0b5/lib/help/wizard/mudos_doc/efuns/floats/
lima-1.0b5/lib/help/wizard/mudos_doc/efuns/functions/
lima-1.0b5/lib/help/wizard/mudos_doc/efuns/general/
lima-1.0b5/lib/help/wizard/mudos_doc/efuns/mappings/
lima-1.0b5/lib/help/wizard/mudos_doc/efuns/mixed/
lima-1.0b5/lib/help/wizard/mudos_doc/efuns/numbers/
lima-1.0b5/lib/help/wizard/mudos_doc/efuns/parsing/
lima-1.0b5/lib/help/wizard/mudos_doc/lpc/constructs/
lima-1.0b5/lib/help/wizard/mudos_doc/lpc/types/
lima-1.0b5/lib/include/driver/
lima-1.0b5/lib/log/
lima-1.0b5/lib/obj/admtool/
lima-1.0b5/lib/obj/admtool/internal/
lima-1.0b5/lib/obj/admtool/mudinfo/
lima-1.0b5/lib/obj/admtool/secure/
lima-1.0b5/lib/obj/secure/
lima-1.0b5/lib/obj/secure/cmd/
lima-1.0b5/lib/obj/secure/mailers/
lima-1.0b5/lib/obj/secure/shell/
lima-1.0b5/lib/obj/secure/shell/classes/
lima-1.0b5/lib/obj/tasktool/
lima-1.0b5/lib/obj/tasktool/internal/
lima-1.0b5/lib/open/
lima-1.0b5/lib/secure/
lima-1.0b5/lib/secure/cgi/
lima-1.0b5/lib/secure/modules/
lima-1.0b5/lib/secure/simul_efun/
lima-1.0b5/lib/std/adversary/
lima-1.0b5/lib/std/adversary/advancement/
lima-1.0b5/lib/std/adversary/armor/
lima-1.0b5/lib/std/adversary/blows/
lima-1.0b5/lib/std/adversary/death/
lima-1.0b5/lib/std/adversary/formula/
lima-1.0b5/lib/std/adversary/health/
lima-1.0b5/lib/std/adversary/pulse/
lima-1.0b5/lib/std/adversary/wield/
lima-1.0b5/lib/std/classes/event_info/
lima-1.0b5/lib/std/container/
lima-1.0b5/lib/std/living/
lima-1.0b5/lib/std/modules/contrib/
lima-1.0b5/lib/std/patterns/
lima-1.0b5/lib/std/race/
lima-1.0b5/lib/std/race/restricted/
lima-1.0b5/lib/std/room/
lima-1.0b5/lib/tmp/
lima-1.0b5/lib/trans/
lima-1.0b5/lib/trans/admincmds/
lima-1.0b5/lib/trans/obj/
lima-1.0b5/lib/wiz/
/* Do not remove the headers from this file! see /USAGE for more info. */

/*
** Alias module by John Viega (rust@virginia.edu) Jul 2, 1995
**
** NOTE:
** This had to be munged rather badly to get an alias w/ $1 in it to work
** at all.  (I realized after the fact I wanted it to work, since you can
** set an alias to code, and some code uses $1, eg: (: $1 :) )
** use a \\\$1....  It's ugly, nod, but I don't have time at the moment to
** make it nicer. =/
*/

//:PLAYERCOMMAND
//USAGE:
//There are 3 different versions of the alias command:
//
//alias  -- will give you a menu for adding aliases.  some things can only
//	  be done through the alias menu.
//
//alias str -- shows the value of alias 'str'
//
//alias str expansion -- sets the alias 'str' to the expansion.
//
//An alias definition can change each time you use the alias:
//$1  -- Wherever you put this in your alias definition,
//       the $1 will be replaced with the first word after
//       the alias when you use the alias.
//       You can do the same with $2, $3, $4, ad infinitum.
//       If you have $1 in your alias definition, but don't
//       provide a first argument when you use an alias,
//       the default value for $1 is used.
//
//       If you're using the alias menu to add an alias, you can set the
//       default value when you are done with the alias definition.
//
//       Example:  If you alias "you're" to:
//                  say Hey, $2, you're $1!
//       When you type:
//                  you're studly Rust
//       You'll say: "Hey, Rust, you're studly!"
//
//$*  -- It's the same as $1, but it means 'everything else'.
//       Example:  If you alias "you're" to:
//                  say $2, you're $1!  Do you $*?       When you type:
//                 you're studly Rust exercise much
//	You'll say: "Hey, Rust, you're studly!  Do you exercise much?"
//
//Notice $* matches any number of words, whereas $1, $2, etc...
//only match one word.
//
//If you don't put a $* in your expansion, one will be automatically
//added to the end of the alias for you.
//
//If you have an alias, but don't want to use it, you can prepend a \ to
//make the game ignore your alias.  For example, if you have 'grin' aliased
//to 'grin evilly', and you type:
//
//    \grin psychopathically
//
//you'll get:
//    You grin psychopathically.
//
//
//To make an alias where you don't need to type a space after the alias,
//use the menu, and answer 'y' when the game asks: 'Allow space omission?'

#include <classes.h>

inherit CLASS_ALIAS;

/*
** Xverb aliases are for aliases where you can omit the space between the verb 
** and the rest of your command.  It's got it's own structure so we can limit 
** our search (That is, the side list is an optimization).
*/
private nosave mapping aliases = ([]);
private nosave string * xaliases = ({});
private nosave mapping alias_save = ([]);
private nosave string* xalias_save = ({});

protected void init_alias_editor()
{
    new(ALIASMENU)->begin_menu(this_object());
}

/*
** Access functions for the alias editor
*/
nomask int query_alias_count()
{
    return sizeof(aliases);
}

nomask int is_xalias(string alias_name)
{
    return member_array(alias_name, xaliases) != -1;
}
nomask void add_xalias(string alias_name)
{
    if ( base_name(previous_object()) != ALIASMENU )
	error("invalid attempt to add an xalias\n");
#ifdef MAX_NUMBER_OF_ALIASES
    if (query_alias_count() >= MAX_NUMBER_OF_ALIASES)
      {
	write("Sorry, you already have too many aliases.\n");
	return;
      }
#endif

    xaliases += ({ alias_name });
}

nomask string * query_alias_names()
{
    return keys(aliases);
}
nomask class alias query_one_alias(string alias_name)
{
    return aliases[alias_name];
}

//:FUNCTION remove_alias
//Add an alias to an alias set.
nomask void add_alias_simple(string alias_name, class alias the_alias)
{
    if ( base_name(previous_object()) != ALIASMENU )
	error("invalid attempt to add an alias\n");

#ifdef MAX_NUMBER_OF_ALIASES
    if (query_alias_count() >= MAX_NUMBER_OF_ALIASES)
      {
	write("Sorry, you already have too many aliases.\n");
	return;
      }
#endif


    aliases[alias_name] = the_alias;

//### really do this? it was in here... leaving it (DB)
    this_object()->save();
}

private nomask void internal_remove_alias(string alias_name)
{
    map_delete(aliases, alias_name);
    xaliases -= ({ alias_name });
}

//:FUNCTION remove_alias
//Remove an alias from an alias set.
nomask void remove_alias(string alias_name)
{
    if ( base_name(previous_object()) != ALIASMENU )
	error("invalid attempt to remove an alias\n");

    internal_remove_alias(alias_name);
}


/*
** Save functions
*/

private string* prep_aliases_for_save(string state)
{
  string a;
  class alias expansion;
  alias_save = ([]);
  xalias_save = ({});
  if(state == "saving")
    foreach(a, expansion in aliases)
      {
	// TMP HACK =(
	if(sizeof(expansion) != 4)
	  {
	    class alias new_expansion;
	    new_expansion = new(class alias);
	    new_expansion->template = expansion->template;
	    new_expansion->defaults = expansion->defaults;
	    new_expansion->num_args = expansion->num_args;
	    new_expansion->global_alias_status = 0;
	    expansion = new_expansion;
	  }
	if(!(expansion->global_alias_status))
	  {
	    alias_save[a] = expansion;
	    if(member_array(a,xaliases) != -1)
	      xalias_save += ({a});
	  }
      }
  return ({ "alias_save", "xalias_save" });
}

//:FUNCTION setup_for_save
//Sets up M_SAVE to save some variables
void setup_for_save()
{
    /*
    ** Use the call_other() interface so that we are not protectedally
    ** bound to require M_SAVE.  This object this modules is applied
    ** to may save natively rather than via M_SAVE.
    */
  this_object()->add_save(({ (: prep_aliases_for_save:) }));
}

//:FUNCTION add_alias
//Add an alias to an alias set.
varargs void
add_alias(string name, string template, string* defaults, int xverb)
{
  class alias new_alias;
  int i;

#ifdef MAX_NUMBER_OF_ALIASES
    if (query_alias_count() >= MAX_NUMBER_OF_ALIASES)
      {
	write("Sorry, you already have too many aliases.\n");
	return;
      }
#endif

  if(strsrch(template,"$*") == -1)
    template += " $*";

  new_alias = new(class alias);
  new_alias->template = template;
  new_alias->defaults = defaults;
  new_alias->num_args = 
    max(map(explode(template[strsrch(template,"$")..],"$"), 
		   function(string s){
		     int d;
		     sscanf(s, "%d%s",d,s);
		     return d;}));

// Pad the default array with empty strings if there aren't enough
// defaults provided to us.
  if(!arrayp(new_alias->defaults))
    new_alias->defaults = ({});
  i = new_alias->num_args - (sizeof(defaults) - 1);
  while(i--)
    new_alias->defaults += ({""});

  if(xverb)
    {
      xaliases += ({name});
    }
  aliases[name] = new_alias;

  this_object()->save();
}


//:FUNCTION expand_alias
//Expand an argv with any aliases if applicable.
mixed expand_alias(string input)
{
  string * argv = explode(input, " ");
  class alias this_alias;
  string* xverb_matches;
  string expanded_input;
  int numargs = sizeof(argv) - 1;
  int i, j;

  xverb_matches = filter_array(xaliases, (: strsrch($2, $1) == 0 :), argv[0]);
  switch(sizeof(xverb_matches))
    {
    case 0:
      break;
    case 1:
      sscanf(argv[0],xverb_matches[0]+"%s",argv[0]);
      if(argv[0]=="")
	argv[0] = xverb_matches[0];
      else
	{
	  numargs++;
	  argv = xverb_matches + argv;
	}
      break;
    default:
      printf("ERROR: Alias conflict: can't destinguish between: %s.\n", 
	     implode(xverb_matches,", "));
      return "";
    }
  if(!(this_alias = aliases[argv[0]]))
    return trim_spaces(implode(argv, " "));

  expanded_input = replace_string(this_alias->template,"\\\\$",sprintf("%c",255));
  j = numargs;


  for(i=1;i<=this_alias->num_args;i++, j--)
    {
      if(j<1)
	expanded_input = replace_string(expanded_input, sprintf("$%d",i), 
					this_alias->defaults[i]);
      else
	expanded_input = replace_string(expanded_input, 
					sprintf("$%d",i), argv[i]);
    }
  if(j>0)
    expanded_input = replace_string(expanded_input, "$*", 
				    implode(argv[i..]," "));
  else
    expanded_input = replace_string(expanded_input, "$*", 
				    this_alias->defaults[0]);

  return trim_spaces(replace_string(expanded_input,sprintf("%c",255), "$"));
}


private void initialize_aliases()
{
  mixed info;
  info = call_other(ALIAS_D,"query_default_aliases");

  if(wizardp(this_user()))
    {
      aliases = info[0] + info[2] + alias_save;
      xaliases = clean_array(info[1] + info[3] +  xalias_save);
    }
  else
    {
      aliases = info[0] + alias_save;
      xaliases = clean_array(info[1] + xalias_save);
    }
}

void create()
{
    if ( clonep(this_object()) && base_name(this_object()) != M_ALIAS )
    {
#if 1
        initialize_aliases();
#else
	call_out((: initialize_aliases :), 0);
#endif
    }
}

varargs protected void cmd_alias(mixed argv, string array implode_info)
{
    switch(sizeof(argv))
    {
    case 1:
	init_alias_editor();
	return;
    case 2:
	ALIASMENU->display_one_alias(argv[1], this_object());
	return;
    default:
	if(strlen(argv[1]) > 1 && argv[1][0] == '$')
	{
	  if(implode_info)
	    add_alias(argv[1][1..], implode_by_arr(argv[2..],
		      implode_info[2..])[1..],0,1);
	  else
	    add_alias(argv[1][1..], implode(argv[2..]," "),0,1);
	    printf("Xverb alias '%s' set to: %s.\n", argv[1][1..], 
		   ((class alias)aliases[argv[1][1..]])->template);
	    return;
	}
	if(implode_info)
	  add_alias(argv[1], implode_by_arr(argv[2..],implode_info[2..])[1..]);
	else
	  add_alias(argv[1], implode(argv[2..]," "));
	printf("Alias '%s' set to: %s.\n", argv[1],
	       ((class alias)aliases[argv[1]])->template);
    }
}

varargs protected void cmd_remove_alias(mixed argv)
{
    if ( sizeof(argv) != 2 )
    {
	printf("Usage: unalias <aliasname>\n");
	return;
    }

    if ( !aliases[argv[1]] )
    {
	printf("You don't have '%s' as an alias.\n", argv[1]);
    }
    else
    {
	internal_remove_alias(argv[1]);
	printf("Alias '%s' removed.\n", argv[1]);
    }
}