/
lib/banish/
lib/d/coronos/
lib/d/coronos/w/alena/
lib/d/coronos/w/angel/
lib/d/coronos/w/angel/caves/
lib/d/coronos/w/angel/caves/monst/
lib/d/coronos/w/angel/city/chambers/
lib/d/coronos/w/angel/city/monst/
lib/d/coronos/w/angel/city/obj/
lib/d/coronos/w/angel/city/streets/
lib/d/coronos/w/angel/farms/plains/
lib/d/coronos/w/angel/monst/
lib/d/tempus/
lib/d/tempus/w/angel/
lib/d/tempus/w/kingbill/
lib/d/tempus/w/mirak/
lib/d/tempus/w/mirak/monst/
lib/d/tempus/w/mirak/obj/
lib/d/tempus/w/relgar/planes/baat/
lib/d/tempus/w/sarak/
lib/d/tempus/w/serepion/mon/
lib/d/tempus/w/valrejn/
lib/doc/
lib/doc/domains/
lib/doc/efun/
lib/include/fn_specs/
lib/info/
lib/inherit/base/
lib/log/
lib/log/mailbox/
lib/log/main/
lib/news/
lib/obj/party/
lib/objects/componen/
lib/open/
lib/open/party/
lib/open/paste/
lib/open/spells/
lib/open/valrejn/
lib/players/
lib/players/alena/
lib/players/alena/obj/
lib/players/alena/open/
lib/players/alena/private/
lib/players/angel/
lib/players/angel/obj/
lib/players/ash/
lib/players/biggs/
lib/players/biggs/food/
lib/players/biggs/gobkeep/
lib/players/biggs/mnstr/
lib/players/biggs/town/caves/
lib/players/biggs/town/tower/
lib/players/biggs/wpns/
lib/players/calris/
lib/players/deathurg/
lib/players/deathurg/open/
lib/players/deathurg/private/thief/
lib/players/dogberry/
lib/players/dogberry/library/
lib/players/dogberry/open/
lib/players/epsilon/
lib/players/epsilon/private/
lib/players/farewell/
lib/players/hippo/
lib/players/hippo/open/
lib/players/hippo/tools/
lib/players/jimpa/
lib/players/josh/
lib/players/josh/room/
lib/players/josh/room/mage/dungeon/
lib/players/josh/room/mage/dungeon/obj/
lib/players/josh/wep/
lib/players/kingbill/
lib/players/metatron/
lib/players/miette/
lib/players/mirak/
lib/players/mirak/open/
lib/players/parsilan/
lib/players/relgar/
lib/players/relgar/private/
lib/players/sarak/
lib/players/sarak/bugs/
lib/players/sarak/feelings/
lib/players/sarak/magical/
lib/players/sarak/minotaur/island/
lib/players/sarak/open/
lib/players/sarak/private/
lib/players/serepion/
lib/players/serepion/open/
lib/players/serepion/private/
lib/players/spike/
lib/players/spike/open/
lib/players/spike/private/
lib/players/spike/seaworld/
lib/players/valrejn/
lib/players/valrejn/open/
lib/players/valrejn/private/
lib/players/virus/
lib/players/wrath/
lib/players/wrath/arm/
lib/players/wrath/mon/
lib/players/wrath/room/
lib/players/wrath/room/entry/
lib/players/wrath/room/zolgath/
lib/players/wrath/weap/
lib/players/zil/
lib/room/
lib/room/city/arena/
lib/room/city/creator/
lib/room/city/garden/monst/
lib/room/city/library/
lib/room/city/library/open/books/
lib/room/city/shop/
lib/room/death/
lib/room/death/open/
lib/room/island/
lib/room/keeps/
lib/room/registry/
lib/room/ships/crew/
lib/room/ships/open/
lib/room/ships/open/types/bounty/
lib/room/ships/open/types/nebula/
lib/room/ships/open/types/phoenix/
lib/secure/udp_cmd_/
lib/skills/
lib/skills/fighter/
lib/skills/psionici/
lib/skills/thief/
lib/usr/
lib/usr/creators/
lib/usr/no_banis/
lib/usr/players/
/*
 * This is a mudlib file. Copy it to /obj/simul_efun.c, or
 * wherever the get_simul_efun() in master.c says.
 * The functions defined in this file should only be replacements of efuns
 * no longer supported. Don't use these functions any longer, use the
 * replacement instead.
 */

/*
  simul_efun.c
*/
#define MAX_LOG_SIZE 50000

#include "/sys/wizlist.h"
#if 0
#include "/secure/std.h"
#endif

#pragma strong_types
#pragma save_types
#ifdef COMPAT_FLAG
#define MASTER "obj/master"
#else
#define MASTER "secure/master"
#endif

/*
 * The ls() function is no longer needed, as get_dir() can do the same
 * work.
 */
void ls(string path) {
    int max, i, len, tmp;
    status trunc_flag;
    mixed *dir;
    set_this_object(previous_object());
    dir = get_dir (path,3);
#if defined(COMPAT_FLAG) && 0
    if (path[0] == '/')
	path = extract(path, 1);
    if (path != "")
	path += "/";
#else
    if (path != "/")
	path += "/";
#endif
    if (!dir) {
        write("No such directory.\n");
        return;
    }
    if (sizeof(dir) > 999)
    {
        dir = dir[0..998];
        trunc_flag = 1;
    }
    for(i = sizeof(dir); i--; ) {
        if(dir[i--] == -2)
            dir[i]+="/";
        len = strlen(dir[i]);
        if (len > max)
            max = len;
    }
    ++max;
    if (max > 79)
        max = 79;
    for (i=0; i < sizeof(dir); i+=2) {
	string name;
            name = dir[i];
	tmp = strlen(name);
	if (len + tmp > 79) {
	    len = 0;
	    write("\n");
	}
	write(name);
        if (len + max > 79) {
            write("\n");
            len = 0;
        } else {
            write(extract(
"                                                                                ",
                80-max+tmp));
            len += max;
        }
    }
    write("\n");
    if (trunc_flag) write("***TRUNCATED***\n");
}

int file_time(string path)
{
    mixed *v;

    set_this_object(previous_object());
    if (sizeof(v=get_dir(path,4))) return v[0];
}

string create_wizard(string owner, string domain)
{
    mixed result;

    set_this_object(previous_object());
    result =
      (mixed)MASTER->master_create_wizard(owner, domain, previous_object());
    if (stringp(result)) return result;
    return 0;
}

void log_file(string file,string str)
{
    string file_name;
    int *st;

    file_name = "/log/" + file;
#ifdef COMPAT_FLAG
    if (sizeof(regexp(({file}), "/")) || file[0] == '.' || strlen(file) > 30 )
    {
        write("Illegal file name to log_file("+file+")\n");
        return;
    }
#endif
    if ( sizeof(st = get_dir(file_name,2) ) && st[0] > MAX_LOG_SIZE) {
	catch(rename(file_name, file_name + ".old")); /* No panic if failure */
    }
    set_this_object(previous_object());
    write_file(file_name, str);
}

void localcmd() {
    string *verbs;
    int i,j;

    verbs = query_actions(this_player());
    for (i=0, j = sizeof(verbs); --j >= 0; i++) {
	write(verbs[i]+" ");
    }
    write("\n");
}

mixed *unique_array(mixed *arr,string func,mixed skipnum) {
    mixed *al, last;
    int i, j, k, *ordinals;

    if (sizeof(arr) < 32) return efun::unique_array(arr, func, skipnum);
    for (ordinals = allocate(i = sizeof(arr)); i--; )
	ordinals[i] = i;
    al = order_alist(map_objects(arr, func), ordinals, (ordinals=0,arr));
    arr = al[2];
    ordinals = al[1];
    al = al[0];
    if (k = i = sizeof(al)) {
	for (last = al[j = --i]; i--; ) {
	    if (al[i] != last) {
		if (last != skipnum) {
		    arr[--k] = arr[i+1..j];
		    ordinals[k] = ordinals[j];
		}
		last = al[j = i];
	    }
	}
	if (last != skipnum) {
	    arr[--k] = arr[0..j];
	    ordinals[k] = ordinals[j];
	}
    }
    return order_alist(ordinals[k..], arr[k..])[1];
}

#ifdef COMPAT_FLAG
mixed snoop(mixed snoopee) {
    int result;

    if (snoopee && query_snoop(snoopee)) {
        write("Busy.\n");
        return 0;
    }
    result = snoopee ? efun::snoop(this_player(), snoopee)
                     : efun::snoop(this_player());
    switch (result) {
	case -1:
	    write("Busy.\n");
	case  0:
	    write("Failed.\n");
	case  1:
	    write("Ok.\n");
    }
    if (result > 0) return snoopee;
}
#endif

string version() {
    return __VERSION__;
}

#ifndef NO_MAPPINGS
mapping m_delete(mapping m, mixed key) {
    return efun::m_delete(copy_mapping(m), key);
}
#endif

void add_worth(int value, object ob) {
    mixed old;
#ifdef COMPAT_FLAG
    switch (explode(file_name(previous_object()), "/")[0]) {
#else
    switch (explode(file_name(previous_object()), "/")[1]) {
#endif
      default:
	raise_error("Illegal call of add_worth.\n");
      case "obj":
      case "std":
      case "room":
    }
    if (!ob) {
	if ( !(ob = previous_object(1)) )
	    return;
    }
    if (intp(old = get_extra_wizinfo(ob)))
        set_extra_wizinfo(ob, old + value);
}

void wizlist(string name) {
    int i, pos, total_cmd;
    int *cmds;
    mixed *a;
    mixed *b;

    if (!name) {
        name = this_player()->query_real_name();
        if (!name)
            return;
    }
    a = transpose_array(wizlist_info());
    cmds = a[WL_COMMANDS];
    a[WL_COMMANDS] = a[0];
    a[0] = cmds;
    a = order_alist(a);
    cmds = a[0];
    a[0] = a[WL_COMMANDS];
    a[WL_COMMANDS] = cmds;
    if ((pos = member(a[WL_NAME], name)) < 0 && name != "ALL")
        return;
    b = allocate(sizeof(cmds));
    for (i = sizeof(cmds); i;) {
        b[<i] = i;
        total_cmd += cmds[--i];
    }
    a = transpose_array(a + ({b}) );
    if (name != "ALL") {
        if (pos + 18 < sizeof(cmds)) {
            a = a[pos-2..pos+2]+a[<15..];
        } else if (pos < sizeof(cmds) - 13) {
            a = a[pos-2..];
        } else {
            a = a[<15..];
        }
    }
    write("\nWizard top score list\n\n");
    if (total_cmd == 0)
        total_cmd = 1;
    for (i = sizeof(a); i; ) {
        b = a[<i--];
        printf("%-15s %5d %2d%% (%d)\t[%4dk,%5d] %6d %d\n",
          b[WL_NAME], b[WL_COMMANDS], b[WL_COMMANDS] * 100 / total_cmd, b[<1],
          b[WL_EVAL_COST] / 1000,
          b[WL_HEART_BEATS], b[WL_EXTRA], b[WL_ARRAY_TOTAL]
        );
    }
    printf("\nTotal         %7d     (%d)\n\n", total_cmd, sizeof(cmds));
}

/*
 * Function name: exclude_array
 * Description:   Deletes a section of an array
 * Arguments:     arr: The array
 *		  from: Index from which to delete elements
 *		  to: Last index to be deleted.
 * Returns:       
 */
public mixed *
exclude_array(mixed *arr, int from, int to)
{
    return arr[0..from-1] + arr[to+1..sizeof(arr)];
}

/*
 * Function name: exclude_element
 * Description:   deletes an element from an array
 * Arguments:     arr: the array
 *                from: index of the element to remove from the array
 * Returns:       first element of the array, or -1 if failed.
 * Warning:       elements in the array will have been reshuffled somewhat.
 */
public mixed * exclude_element (mixed *arr, int index) {
        arr[index] = arr[0];
        return slice_array (arr, 1, sizeof (arr));
}


/*************************************************************************/

/* Efun: all_environment() */

/*
 * Function name: all_environment
 * Description:   Gives an array of all containers which an object is in, i.e.
 *		  match in matchbox in bigbox in chest in room, would for the
 *		  match give: matchbox, bigbox, chest, room 
 * Arguments:     ob: The object
 * Returns:       The array of containers.
 */
public object *
all_environment(object ob)
{
  object *r;
  
  if (!ob || !environment(ob)) return 0;
  if (!environment(environment(ob)))
      return ({ environment(ob) });
  r = ({ ob = environment(ob) });
  while (environment(ob))
      r = r + ({ ob = environment(ob) });
  return r;
}

/*************************************************************************/

/* Efuns: break_string() and update_actions()
*/

static int gCol;

/*
 * Function name: break_string
 * Description:   Breaks a continous string without newlines into a string
 *		  with newlines inserted at regular intervalls replacing spaces
 *		  Each newline separeted string can be indented with a given
 *		  number of spaces.
 * Arguments:     str: Original message
 *		  width: The total maximum width of each line.
 *		  indent: (optional) How many spaces to indent with.
 * Returns:       A string with newline separated strings
 */
public varargs string
break_string(string str, int width, int indent)
{
    mixed *brkarg;
    string indstr;

    if (indent)
	indstr = extract("                                                                                ", 0, indent-1);
    else
	indstr = "";
    gCol = indent;
    brkarg = ({ width, indstr });
  
    return indstr + 
	implode(map_array(explode(str+" "," "),"brk",this_object(),brkarg)," ");
}

static string brk(string word, mixed *width_indstr)
{
    int width;
    string indstr;

    width = width_indstr[0];
    indstr = width_indstr[1];
    if ((strlen(word)+gCol) > width) {
	gCol = strlen(indstr) + strlen(word) + 1;
	return "\n" + indstr + word;
    }
    else {
	gCol += strlen(word) + 1;
	return word;
    }
}    

/*
 * Function name:   update_actions
 * Description:     Updates this_objects actions in all living objects
 */
public void
update_actions()
{
  int objs;

  if (environment(previous_object()))
    previous_object()->move(environment(previous_object()),1);
  filter_array(all_inventory(previous_object()),"move_inv",previous_object());
}

static void move_inv(object ob) { if (living(ob)) ob->move(previous_object(),1); }

/*************************************************************************/


/* Functions below are useful but should probably not be made into efuns
*/

#if 0
string creator(object ob) { return (string)SECURITY->creator_object(ob); }
#endif
#if 0
string domain(object ob) { return (string)SECURITY->domain_object(ob); }
#endif


static void dump_elem(mixed sak, string tab);

/*
 * Function name: dump_array
 * Description:   Dumps a variable with write() for debugging purposes.
 * Arguments:     a: Anything including an array
 */
public varargs void 
dump_array(mixed *a, string tab)
{
  int n,m;

  if (!tab) tab = "";
  if (!pointerp(a)) {
    write(a); return;
  }
  else write("\n");
  m=sizeof(a);
  n=0;
  while (n<m) {
    write(tab+"["+n+"] = "); dump_elem(a[n],tab); n+=1;
  }
}

status is_clone(mixed ob) {
    return objectp(ob) && member(file_name(ob), '#') >= 0;
}

static void dump_elem(mixed sak, string tab)
{
  if (pointerp(sak)) {
    write("Array: \n"); dump_array(sak,tab+"   ");
  }
  else write(sak);
  write("\n");
}

#if 0
/*
 * The old 'slice_array' is no longer needed. Use range argument inside
 * a pair of brackets instead.
 */
mixed *slice_array(mixed *arr, int from, int to) {
    return arr[from..to];
}

/*
 * filter_objects() has been renamed to filter_array().
 */
mixed *filter_objects(mixed *list, string str, object ob, mixed extra) {
    return filter_array(list, str, ob, extra);
}

#endif