wileymud-1.187b/
wileymud-1.187b/attic/
wileymud-1.187b/attic/bin/
wileymud-1.187b/attic/lib/
wileymud-1.187b/attic/lib/adm/
wileymud-1.187b/attic/lib/man/
wileymud-1.187b/attic/lib/new-wld/
wileymud-1.187b/attic/lib/new-wld/default/
wileymud-1.187b/attic/lib/old/
wileymud-1.187b/attic/lib/wld/
wileymud-1.187b/attic/public_html/
wileymud-1.187b/attic/public_html/gfx/
wileymud-1.187b/attic/src/bin/
wileymud-1.187b/attic/src/etc/
wileymud-1.187b/attic/src/libauth-4.0-p5/
wileymud-1.187b/attic/src/sedna/
wileymud-1.187b/backups/
wileymud-1.187b/bin/
wileymud-1.187b/docs/
wileymud-1.187b/etc/
wileymud-1.187b/lib/
wileymud-1.187b/lib/adm/
wileymud-1.187b/lib/boards/
wileymud-1.187b/lib/log/
wileymud-1.187b/lib/man/
wileymud-1.187b/lib/ply/
wileymud-1.187b/lib/ply/a/
wileymud-1.187b/lib/ply/b/
wileymud-1.187b/lib/ply/c/
wileymud-1.187b/lib/ply/d/
wileymud-1.187b/lib/ply/g/
wileymud-1.187b/lib/ply/k/
wileymud-1.187b/lib/ply/m/
wileymud-1.187b/lib/ply/s/
wileymud-1.187b/lib/ply/t/
wileymud-1.187b/public_html/gfx/
wileymud-1.187b/src/bin/
wileymud-1.187b/src/convert/attic/
wileymud-1.187b/src/convert/obj/
wileymud-1.187b/src/convert/perl/
wileymud-1.187b/src/convert/perl/MudConvert/
wileymud-1.187b/src/convert/perl/MudConvert/DUMP/
wileymud-1.187b/src/convert/perl/MudConvert/Report/
wileymud-1.187b/src/convert/perl/MudConvert/WileyMUD/
wileymud-1.187b/src/convert/perl/output/
wileymud-1.187b/src/convert/perl/output/DUMP/
wileymud-1.187b/src/convert/perl/output/Report/
wileymud-1.187b/src/convert/perl/output/WileyMUD/
wileymud-1.187b/src/etc/
wileymud-1.187b/src/etc/init.d/
wileymud-1.187b/src/etc/rc.d/
wileymud-1.187b/src/etc/rc.d/init.d/
wileymud-1.187b/src/lib/
wileymud-1.187b/src/lib/adm/
wileymud-1.187b/src/lib/boards/
wileymud-1.187b/src/lib/log/
wileymud-1.187b/src/lib/man/
wileymud-1.187b/src/lib/ply/
wileymud-1.187b/src/lib/ply/a/
wileymud-1.187b/src/lib/ply/b/
wileymud-1.187b/src/lib/ply/c/
wileymud-1.187b/src/lib/ply/d/
wileymud-1.187b/src/lib/ply/e/
wileymud-1.187b/src/lib/ply/f/
wileymud-1.187b/src/lib/ply/g/
wileymud-1.187b/src/lib/ply/h/
wileymud-1.187b/src/lib/ply/i/
wileymud-1.187b/src/lib/ply/j/
wileymud-1.187b/src/lib/ply/k/
wileymud-1.187b/src/lib/ply/l/
wileymud-1.187b/src/lib/ply/m/
wileymud-1.187b/src/lib/ply/n/
wileymud-1.187b/src/lib/ply/o/
wileymud-1.187b/src/lib/ply/p/
wileymud-1.187b/src/lib/ply/q/
wileymud-1.187b/src/lib/ply/r/
wileymud-1.187b/src/lib/ply/s/
wileymud-1.187b/src/lib/ply/t/
wileymud-1.187b/src/lib/ply/u/
wileymud-1.187b/src/lib/ply/v/
wileymud-1.187b/src/lib/ply/w/
wileymud-1.187b/src/lib/ply/x/
wileymud-1.187b/src/lib/ply/y/
wileymud-1.187b/src/lib/ply/z/
wileymud-1.187b/src/obj/
wileymud-1.187b/src/utils/
wileymud-1.187b/src/utils/mobmaker/
/*
 * file: utility.c, Utility module.                       Part of DIKUMUD
 * Usage: Utility procedures
 * Copyright (C) 1990, 1991 - see 'license.doc' for complete information.
 */

#include <stdio.h>
#include <stdlib.h>
/* #include <unistd.h> */
#include <sys/types.h>
/* #include <malloc.h> */
#include <string.h>
#include <assert.h>
#include <time.h>

#include "global.h"
#include "bug.h"
#include "spells.h"
#include "constants.h"
#include "db.h"
#include "opinion.h"
#include "comm.h"
#include "hash.h"
#include "multiclass.h"
#include "handler.h"
#include "fight.h"
#include "act_info.h"
#include "reception.h"
#include "act_off.h"
#include "magic_utils.h"
#include "mudlimits.h"
#include "act_skills.h"
#define _UTILS_C
#include "utils.h"

int MobVnum(struct char_data *c)
{
    if (DEBUG > 3)
	log_info("called %s with %s", __PRETTY_FUNCTION__, SAFE_NAME(c));

    if (!c || IS_PC(c))
	return 0;
    if (IS_MOB(c)) {
	return mob_index[c->nr].virtual;
    } else {
	return -1;
    }
}

int ObjVnum(struct obj_data *o)
{
    if (DEBUG > 3)
	log_info("called %s with %s", __PRETTY_FUNCTION__, SAFE_ONAME(o));

    if (!o)
	return 0;
    if (o->item_number >= 0)
	return obj_index[o->item_number].virtual;
    else
	return -1;
}

int percent(int value, int total)
{
    if (DEBUG > 3)
	log_info("called %s with %d, %d", __PRETTY_FUNCTION__, value, total);

    if (!total)
	return 0;
    return ((value * 100) / total);
}

const char                             *ordinal(int x)
{
    if (DEBUG > 3)
	log_info("called %s with %d", __PRETTY_FUNCTION__, x);

    if (x < 14 && x > 10)
	x = 4;
    else
	x %= 10;
    switch (x) {
	case 1:
	    return "st";
	case 2:
	    return "nd";
	case 3:
	    return "rd";
	default:
	    return "th";
    }
}

int GetItemClassRestrictions(struct obj_data *obj)
{
    int                                     total = 0;

    if (DEBUG > 3)
	log_info("called %s with %s", __PRETTY_FUNCTION__, SAFE_ONAME(obj));

    if (IS_SET(obj->obj_flags.extra_flags, ITEM_ANTI_MAGE))
	total += CLASS_MAGIC_USER;
    if (IS_SET(obj->obj_flags.extra_flags, ITEM_ANTI_THIEF))
	total += CLASS_THIEF;
    if (IS_SET(obj->obj_flags.extra_flags, ITEM_ANTI_RANGER))
	total += CLASS_RANGER;
    if (IS_SET(obj->obj_flags.extra_flags, ITEM_ANTI_FIGHTER))
	total += CLASS_WARRIOR;
    if (IS_SET(obj->obj_flags.extra_flags, ITEM_ANTI_CLERIC))
	total += CLASS_CLERIC;

    return (total);
}

int CAN_SEE(struct char_data *s, struct char_data *o)
{
    if (DEBUG > 3)
	log_info("called %s with %s, %s", __PRETTY_FUNCTION__, SAFE_NAME(s), SAFE_NAME(o));

    if (!o || !s)
	return (FALSE);

    if ((s->in_room == -1) || (o->in_room == -1))
	return (FALSE);

    if (o->invis_level >= GetMaxLevel(s))
	return FALSE;

    if (IS_IMMORTAL(s))
	return (TRUE);

    if (IS_AFFECTED(s, AFF_TRUE_SIGHT))
	return (TRUE);

    if (IS_AFFECTED(s, AFF_BLIND) && s != o)
	return (FALSE);

    if (IS_AFFECTED(o, AFF_HIDE))
	return (FALSE);

    if (IS_AFFECTED(o, AFF_INVISIBLE)) {
	if (IS_IMMORTAL(o))
	    return (FALSE);
	if (!IS_AFFECTED(s, AFF_DETECT_INVISIBLE))
	    return (FALSE);
    }
    if ((IS_DARK(s->in_room) || IS_DARK(o->in_room)) && (!IS_AFFECTED(s, AFF_INFRAVISION)))
	return (FALSE);

    return (TRUE);

}

int exit_ok(struct room_direction_data *room_exit, struct room_data **rpp)
{
    struct room_data                       *rp = NULL;

    if (DEBUG > 3)
	log_info("called %s with %08zx, %08zx", __PRETTY_FUNCTION__, (size_t) room_exit,
		 (size_t) rpp);

    if (rpp == NULL)
	rpp = &rp;
    if (!room_exit) {
	*rpp = NULL;
	return FALSE;
    }
    *rpp = real_roomp(room_exit->to_room);
    return (*rpp != NULL);
}

int IsImmune(struct char_data *ch, int bit)
{
    if (DEBUG > 3)
	log_info("called %s with %s, %d", __PRETTY_FUNCTION__, SAFE_NAME(ch), bit);

    if (!ch)
	return 0;
    return IS_SET(bit, ch->M_immune);
}

int IsResist(struct char_data *ch, int bit)
{
    if (DEBUG > 3)
	log_info("called %s with %s, %d", __PRETTY_FUNCTION__, SAFE_NAME(ch), bit);

    if (!ch)
	return 0;
    if (GetMaxLevel(ch) >= LOW_IMMORTAL)
	return 1;
    return IS_SET(bit, ch->immune);
}

int IsSusc(struct char_data *ch, int bit)
{
    if (DEBUG > 3)
	log_info("called %s with %s, %d", __PRETTY_FUNCTION__, SAFE_NAME(ch), bit);

    if (!ch)
	return 0;
    return IS_SET(bit, ch->susc);
}

/* creates a random number in interval [from;to] */
int number(int from, int to)
{
    if (DEBUG > 3)
	log_info("called %s with %d, %d", __PRETTY_FUNCTION__, from, to);

    if (to - from + 1)
	return ((random() % (to - from + 1)) + from);
    else
	return from;
}

/* simulates dice roll */
int dice(int rolls, int size)
{
    int                                     r = 0;
    int                                     sum = 0;

    if (DEBUG > 3)
	log_info("called %s with %d, %d", __PRETTY_FUNCTION__, rolls, size);

    if (size < 1 || rolls < 1)
	return 0;
    if (size == 1)
	return rolls;
    for (r = 1; r <= rolls; r++)
	sum += ((random() % size) + 1);
    return sum;
}

int fuzz(int x)
{
    if (DEBUG > 3)
	log_info("called %s with %d", __PRETTY_FUNCTION__, x);

    if (!x)
	return 0;
    if (x < 0)
	x = -x;
    return ((random() % ((2 * x) + 1)) - x);
}

int scan_number(const char *text, int *rval)
{
    int                                     length = 0;

    if (DEBUG > 3)
	log_info("called %s with %s, %08zx", __PRETTY_FUNCTION__, VNULL(text), (size_t) rval);

    if (!text || !*text)
	return 0;
    if (1 != sscanf(text, " %i %n", rval, &length))
	return 0;
    if (text[length] != 0)
	return 0;
    return 1;
}

int str_cmp(const char *arg1, const char *arg2)
{
    if (DEBUG > 3)
	log_info("called %s with %s, %s", __PRETTY_FUNCTION__, VNULL(arg1), VNULL(arg2));

    if (!arg1 || !arg2)
	return 1;
    return strcasecmp(arg1, arg2);
}

int strn_cmp(const char *arg1, const char *arg2, const int n)
{
    if (DEBUG > 3)
	log_info("called %s with %s, %s, %d", __PRETTY_FUNCTION__, VNULL(arg1), VNULL(arg2), n);

    if (!arg1 || !arg2)
	return 1;
    return strncasecmp(arg1, arg2, n);
}

void sprintbit(unsigned long vektor, const char *names[], char *result)
{
    long                                    nr = 0L;

    if (DEBUG > 3)
	log_info("called %s with %lu, %08zx, %08zx", __PRETTY_FUNCTION__, vektor,
		 (size_t) names, (size_t) result);

    *result = '\0';
    for (nr = 0; vektor; vektor >>= 1) {
	if (IS_SET(1, vektor)) {
	    if (*names[nr] != '\n') {
		strcat(result, names[nr]);
		strcat(result, " ");
	    } else {
		strcat(result, "UNDEFINED");
		strcat(result, " ");
	    }
	}
	if (*names[nr] != '\n')
	    nr++;
    }
    if (!*result)
	strcat(result, "NOBITS");
}

void sprinttype(int type, const char *names[], char *result)
{
    int                                     nr = 0;

    if (DEBUG > 3)
	log_info("called %s with %d, %08zx, %08zx", __PRETTY_FUNCTION__, type, (size_t) names,
		 (size_t) result);

    for (nr = 0; (*names[nr] != '\n'); nr++);
    if (type < nr)
	strcpy(result, names[type]);
    else
	strcpy(result, "UNDEFINED");
}

/* Calculate the REAL time passed over the last t2-t1 centuries (secs) */
struct time_info_data real_time_passed(time_t t2, time_t t1)
{
    long                                    secs = 0L;
    struct time_info_data                   now;

    if (DEBUG > 3)
	log_info("called %s with %ld, %ld", __PRETTY_FUNCTION__, t2, t1);

    secs = (long)(t2 - t1);
    now.hours = (secs / SECS_PER_REAL_HOUR) % 24;	       /* 0..23 hours */
    secs -= SECS_PER_REAL_HOUR * now.hours;
    now.day = (secs / SECS_PER_REAL_DAY);		       /* 0..34 days */
    secs -= SECS_PER_REAL_DAY * now.day;
    now.month = -1;
    now.year = -1;
    return now;
}

/* Calculate the MUD time passed over the last t2-t1 centuries (secs) */
struct time_info_data mud_time_passed(time_t t2, time_t t1)
{
    long                                    secs = 0L;
    struct time_info_data                   now;

    if (DEBUG > 3)
	log_info("called %s with %ld, %ld", __PRETTY_FUNCTION__, t2, t1);

    secs = (long)(t2 - t1);
    now.hours = (secs / SECS_PER_MUD_HOUR) % 24;	       /* 0..23 hours */
    secs -= SECS_PER_MUD_HOUR * now.hours;
    now.day = (secs / SECS_PER_MUD_DAY) % 35;		       /* 0..34 days */
    secs -= SECS_PER_MUD_DAY * now.day;
    now.month = (secs / SECS_PER_MUD_MONTH) % 17;	       /* 0..16 months */
    secs -= SECS_PER_MUD_MONTH * now.month;
    now.year = (secs / SECS_PER_MUD_YEAR);		       /* 0..XX? years */
    return now;
}

struct time_info_data age(struct char_data *ch)
{
    struct time_info_data                   player_age;

    if (DEBUG > 3)
	log_info("called %s with %s", __PRETTY_FUNCTION__, SAFE_NAME(ch));

    player_age = mud_time_passed(time(0), ch->player.time.birth);
    player_age.year += 17;				       /* All players start at 17 */
    return player_age;
}

int in_group(struct char_data *ch1, struct char_data *ch2)
{
    if (DEBUG > 3)
	log_info("called %s with %s, %s", __PRETTY_FUNCTION__, SAFE_NAME(ch1), SAFE_NAME(ch2));

    /*
     * three possibilities ->
     * 1.  char is char2's master
     * 2.  char2 is char's master
     * 3.  char and char2 follow same.
     * 
     * otherwise not true.
     */

    if ((!ch1) || (!ch2))
	return (0);
    if (ch1 == ch2)
	return (TRUE);
    if ((!ch1->master) && (!ch2->master))
	return (0);
    if (ch2->master)
	if (!strcmp(GET_NAME(ch1), GET_NAME(ch2->master))) {
	    return (1);
	}
    if (ch1->master)
	if (!strcmp(GET_NAME(ch1->master), GET_NAME(ch2))) {
	    return (1);
	}
    if ((ch2->master) && (ch1->master))
	if (!strcmp(GET_NAME(ch1->master), GET_NAME(ch2->master))) {
	    return (1);
	}
    return (0);
}

/*
 * more new procedures 
 */

/*
 * these two procedures give the player the ability to buy 2*bread
 * or put all.bread in bag, or put 2*bread in bag...
 */

int getall(char *name, char *newname)
{
    char                                    arg[40] = "\0\0\0\0\0\0\0";
    char                                    tmpname[80] = "\0\0\0\0\0\0\0";
    char                                    otname[80] = "\0\0\0\0\0\0\0";
    char                                    prd = '\0';

    if (DEBUG > 3)
	log_info("called %s with %s, %s", __PRETTY_FUNCTION__, VNULL(name), VNULL(newname));

    sscanf(name, "%s ", otname);			       /* reads up to first space */

    if (strlen(otname) < 5)
	return (FALSE);

    sscanf(otname, "%3s%c%s", arg, &prd, tmpname);

    if (prd != '.')
	return (FALSE);
    if (tmpname == NULL)
	return (FALSE);
    if (strcmp(arg, "all"))
	return (FALSE);

    while (*name != '.')
	name++;

    name++;

    for (; (*newname = *name); name++, newname++);
    return (TRUE);
}

int getabunch(char *name, char *newname)
{
    int                                     num = 0;
    char                                    tmpname[80] = "\0\0\0\0\0\0\0";

    if (DEBUG > 3)
	log_info("called %s with %s, %s", __PRETTY_FUNCTION__, VNULL(name), VNULL(newname));

    sscanf(name, "%d*%s", &num, tmpname);
    if (tmpname[0] == '\0')
	return (FALSE);
    if (num < 1)
	return (FALSE);
    if (num > 9)
	num = 9;

    while (*name != '*')
	name++;

    name++;

    for (; (*newname = *name); name++, newname++);

    return (num);

}

int DetermineExp(struct char_data *mob, int exp_flags)
{
    int                                     base = 0;
    int                                     phit = 0;
    int                                     sab = 0;

    /*
     * reads in the monster, and adds the flags together 
     * for simplicity, 1 exceptional ability is 2 special abilities 
     */

    if (DEBUG > 3)
	log_info("called %s with %s, %d", __PRETTY_FUNCTION__, SAFE_NAME(mob), exp_flags);

    if (GetMaxLevel(mob) < 0)
	return (1);

    switch (GetMaxLevel(mob)) {

	case 0:
	    base = 5;
	    phit = 1;
	    sab = 10;
	    break;

	case 1:
	    base = 10;
	    phit = 1;
	    sab = 15;
	    break;

	case 2:
	    base = 20;
	    phit = 2;
	    sab = 20;
	    break;

	case 3:
	    base = 35;
	    phit = 3;
	    sab = 25;
	    break;

	case 4:
	    base = 60;
	    phit = 4;
	    sab = 30;
	    break;

	case 5:
	    base = 90;
	    phit = 5;
	    sab = 40;
	    break;

	case 6:
	    base = 150;
	    phit = 6;
	    sab = 75;
	    break;

	case 7:
	    base = 225;
	    phit = 8;
	    sab = 125;
	    break;

	case 8:
	    base = 600;
	    phit = 12;
	    sab = 175;
	    break;

	case 9:
	    base = 900;
	    phit = 14;
	    sab = 300;
	    break;

	case 10:
	    base = 1100;
	    phit = 15;
	    sab = 450;
	    break;

	case 11:
	    base = 1300;
	    phit = 16;
	    sab = 700;
	    break;

	case 12:
	    base = 1550;
	    phit = 17;
	    sab = 700;
	    break;

	case 13:
	    base = 1800;
	    phit = 18;
	    sab = 950;
	    break;

	case 14:
	    base = 2100;
	    phit = 19;
	    sab = 950;
	    break;

	case 15:
	    base = 2400;
	    phit = 20;
	    sab = 1250;
	    break;

	case 16:
	    base = 2700;
	    phit = 23;
	    sab = 1250;
	    break;

	case 17:
	    base = 3000;
	    phit = 25;
	    sab = 1550;
	    break;

	case 18:
	    base = 3500;
	    phit = 28;
	    sab = 1550;
	    break;

	case 19:
	    base = 4000;
	    phit = 30;
	    sab = 2100;
	    break;

	case 20:
	    base = 4500;
	    phit = 33;
	    sab = 2100;
	    break;

	case 21:
	    base = 5000;
	    phit = 35;
	    sab = 2600;
	    break;

	case 22:
	    base = 6000;
	    phit = 40;
	    sab = 3000;
	    break;

	case 23:
	    base = 7000;
	    phit = 45;
	    sab = 3500;
	    break;

	case 24:
	    base = 8000;
	    phit = 50;
	    sab = 4000;
	    break;

	case 25:
	    base = 9000;
	    phit = 55;
	    sab = 4500;
	    break;

	case 26:
	    base = 10000;
	    phit = 60;
	    sab = 5000;
	    break;

	case 27:
	    base = 12000;
	    phit = 70;
	    sab = 6000;
	    break;

	case 28:
	    base = 14000;
	    phit = 80;
	    sab = 7000;
	    break;

	case 29:
	    base = 16000;
	    phit = 90;
	    sab = 8000;
	    break;

	case 30:
	    base = 20000;
	    phit = 100;
	    sab = 10000;
	    break;

	default:
	    base = 25000;
	    phit = 150;
	    sab = 20000;
	    break;
    }

    return (base + (phit * GET_HIT(mob)) + (sab * exp_flags));

}

void down_river(int current_pulse)
{
    struct char_data                       *ch = NULL;
    struct char_data                       *tmp = NULL;
    struct obj_data                        *obj_object = NULL;
    struct obj_data                        *next_obj = NULL;
    int                                     rd = 0;
    int                                     or = 0;
    struct room_data                       *rp = NULL;

    if (DEBUG > 3)
	log_info("called %s with %d", __PRETTY_FUNCTION__, current_pulse);

    if (current_pulse < 0)
	return;

    for (ch = character_list; ch; ch = tmp) {
	tmp = ch->next;
	if (!IS_NPC(ch)) {
	    if (ch->in_room != NOWHERE) {
		if (real_roomp(ch->in_room)->sector_type == SECT_WATER_NOSWIM)
		    if ((real_roomp(ch->in_room))->river_speed > 0) {
			if ((current_pulse % (real_roomp(ch->in_room))->river_speed) == 0) {
			    if (((real_roomp(ch->in_room))->river_dir < MAX_NUM_EXITS) &&
				((real_roomp(ch->in_room))->river_dir >= 0)) {
				rd = (real_roomp(ch->in_room))->river_dir;
				for (obj_object = (real_roomp(ch->in_room))->contents;
				     obj_object; obj_object = next_obj) {
				    next_obj = obj_object->next_content;
				    if ((real_roomp(ch->in_room))->dir_option[rd]) {
					obj_from_room(obj_object);
					obj_to_room(obj_object,
						    (real_roomp(ch->in_room))->
						    dir_option[rd]->to_room);
				    }
				}
/*
 * flyers don't get moved
 */
				if (!IS_AFFECTED(ch, AFF_FLYING)) {
				    rp = real_roomp(ch->in_room);
				    if (rp && rp->dir_option[rd] && rp->dir_option[rd]->to_room
					&& (EXIT(ch, rd)->to_room != NOWHERE)) {
					if (ch->specials.fighting) {
					    stop_fighting(ch);
					}
					cprintf(ch, "You drift %s...\r\n", dirs[rd]);
					if (MOUNTED(ch)) {
					    or = ch->in_room;
					    char_from_room(ch);
					    char_from_room(MOUNTED(ch));
					    char_to_room(ch,
							 (real_roomp(or))->
							 dir_option[rd]->to_room);
					    char_to_room(MOUNTED(ch),
							 (real_roomp(or))->
							 dir_option[rd]->to_room);
					    do_look(ch, "", 15);
					} else if (RIDDEN(ch)) {
					    or = ch->in_room;
					    char_from_room(ch);
					    char_from_room(RIDDEN(ch));
					    char_to_room(ch,
							 (real_roomp(or))->
							 dir_option[rd]->to_room);
					    char_to_room(RIDDEN(ch),
							 (real_roomp(or))->
							 dir_option[rd]->to_room);
					    do_look(ch, "", 15);
					} else {
					    or = ch->in_room;
					    char_from_room(ch);
					    char_to_room(ch,
							 (real_roomp(or))->
							 dir_option[rd]->to_room);
					    do_look(ch, "", 15);
					}

					if (IS_SET(RM_FLAGS(ch->in_room), DEATH)
					    && GetMaxLevel(ch) < LOW_IMMORTAL) {
					    death_cry(ch);
					    zero_rent(ch);
					    extract_char(ch);
					}
				    }
				}
			    }
			}
		    }
	    }
	}
    }
}

/* these are all very arbitrary */
int IsHumanoid(struct char_data *ch)
{
    if (DEBUG > 3)
	log_info("called %s with %s", __PRETTY_FUNCTION__, SAFE_NAME(ch));

    switch (GET_RACE(ch)) {
	case RACE_HALFBREED:
	case RACE_HUMAN:
	case RACE_GNOME:
	case RACE_ELVEN:
	case RACE_DWARF:
	case RACE_HALFLING:
	case RACE_ORC:
	case RACE_LYCANTH:
	case RACE_UNDEAD:
	case RACE_GIANT:
	case RACE_GOBLIN:
	case RACE_DEVIL:
	case RACE_TROLL:
	case RACE_VEGMAN:
	case RACE_MFLAYER:
	case RACE_DEMON:
	case RACE_GHOST:
	case RACE_PRIMATE:
	    return TRUE;
	default:
	    return FALSE;
    }
}

int IsAnimal(struct char_data *ch)
{
    if (DEBUG > 3)
	log_info("called %s with %s", __PRETTY_FUNCTION__, SAFE_NAME(ch));

    switch (GET_RACE(ch)) {
	case RACE_PREDATOR:
	case RACE_FISH:
	case RACE_BIRD:
	case RACE_HERBIV:
	case RACE_ANIMAL:
	case RACE_LYCANTH:
	    return TRUE;
	default:
	    return FALSE;
    }
}

int IsUndead(struct char_data *ch)
{
    if (DEBUG > 3)
	log_info("called %s with %s", __PRETTY_FUNCTION__, SAFE_NAME(ch));

    switch (GET_RACE(ch)) {
	case RACE_UNDEAD:
	case RACE_GHOST:
	    return TRUE;
	default:
	    return FALSE;
    }
}

int IsLycanthrope(struct char_data *ch)
{
    if (DEBUG > 3)
	log_info("called %s with %s", __PRETTY_FUNCTION__, SAFE_NAME(ch));

    switch (GET_RACE(ch)) {
	case RACE_LYCANTH:
	    return TRUE;
	default:
	    return FALSE;
    }
}

int IsDiabolic(struct char_data *ch)
{
    if (DEBUG > 3)
	log_info("called %s with %s", __PRETTY_FUNCTION__, SAFE_NAME(ch));

    switch (GET_RACE(ch)) {
	case RACE_DEMON:
	case RACE_DEVIL:
	    return TRUE;
	default:
	    return FALSE;
    }
}

int IsReptile(struct char_data *ch)
{
    if (DEBUG > 3)
	log_info("called %s with %s", __PRETTY_FUNCTION__, SAFE_NAME(ch));

    switch (GET_RACE(ch)) {
	case RACE_REPTILE:
	case RACE_DRAGON:
	case RACE_DINOSAUR:
	case RACE_SNAKE:
	    return TRUE;
	default:
	    return FALSE;
    }
}

int IsDraconic(struct char_data *ch)
{
    if (DEBUG > 3)
	log_info("called %s with %s", __PRETTY_FUNCTION__, SAFE_NAME(ch));

    switch (GET_RACE(ch)) {
	case RACE_DRAGON:
	    return TRUE;
	default:
	    return FALSE;
    }
}

int IsAvian(struct char_data *ch)
{
    if (DEBUG > 3)
	log_info("called %s with %s", __PRETTY_FUNCTION__, SAFE_NAME(ch));

    switch (GET_RACE(ch)) {
	case RACE_BIRD:
	case RACE_DRAGON:
	case RACE_GHOST:				       /* insubstantial? */
	    return TRUE;
	default:
	    return FALSE;
    }
}

int IsExtraPlanar(struct char_data *ch)
{
    if (DEBUG > 3)
	log_info("called %s with %s", __PRETTY_FUNCTION__, SAFE_NAME(ch));

    switch (GET_RACE(ch)) {
	case RACE_DEMON:
	case RACE_DEVIL:
	case RACE_PLANAR:
	case RACE_ELEMENT:
	    return TRUE;
	default:
	    return FALSE;
    }
}

int HasHands(struct char_data *ch)
{
    if (DEBUG > 3)
	log_info("called %s with %s", __PRETTY_FUNCTION__, SAFE_NAME(ch));

    if (IsHumanoid(ch) || IsDiabolic(ch) || IsDraconic(ch))
	return TRUE;
    else
	return FALSE;
}

int IsPerson(struct char_data *ch)
{
    if (DEBUG > 3)
	log_info("called %s with %s", __PRETTY_FUNCTION__, SAFE_NAME(ch));

    switch (GET_RACE(ch)) {
	case RACE_HUMAN:
	case RACE_ELVEN:
	case RACE_DWARF:
	case RACE_HALFLING:
	case RACE_GNOME:
	    return TRUE;
	default:
	    return FALSE;
    }
}

void SetHunting(struct char_data *ch, struct char_data *tch)
{
    int                                     persist = 0;
    int                                     dist = 0;

    if (DEBUG > 3)
	log_info("called %s with %s, %s", __PRETTY_FUNCTION__, SAFE_NAME(ch), SAFE_NAME(tch));

    persist = GetMaxLevel(ch);
    /*
     * persist *= (int) GET_ALIGNMENT(ch) / 100; 
     */
    persist *= (int)GET_ALIGNMENT(ch) / 200;

    if (persist < 0)
	persist = -persist;

    dist = GET_INT(ch) + GetMaxLevel(ch);

    /*
     * dist = GET_ALIGNMENT(tch) - GET_ALIGNMENT(ch); 
     */

    dist = (dist > 0) ? dist : -dist;
    if (DoesHate(ch, tch))
	dist *= 2;

    SET_BIT(ch->specials.act, ACT_HUNTING);
    ch->specials.hunting = tch;
    ch->hunt_dist = dist;
    ch->persist = persist;
    ch->old_room = ch->in_room;

    if (GetMaxLevel(tch) >= IMMORTAL) {
	cprintf(tch, ">>%s is hunting you from %s\r\n",
		ch->player.short_descr, (real_roomp(ch->in_room))->name);
    }
}

void CallForGuard(struct char_data *ch, struct char_data *vict, int lev)
{
    struct char_data                       *i = NULL;

    if (DEBUG > 3)
	log_info("called %s with %s, %s, %d", __PRETTY_FUNCTION__, SAFE_NAME(ch),
		 SAFE_NAME(vict), lev);

    if (lev == 0)
	lev = 3;

    for (i = character_list; i && lev > 0; i = i->next) {
	if (IS_NPC(i) && (i != ch)) {
	    if (!i->specials.fighting) {
		if ((mob_index[i->nr].virtual == GUARD_VNUM)
		    || (mob_index[i->nr].virtual == GUARD2_VNUM)) {
		    if (number(1, 6) >= 3) {
			if (!IS_SET(i->specials.act, ACT_HUNTING)) {
			    if (vict) {
				SetHunting(i, vict);
				lev--;
			    }
			}
		    }
		}
	    }
	}
    }
}

void CallForAGuard(struct char_data *ch, struct char_data *vict, int lev)
{
    struct char_data                       *point = NULL;

    if (DEBUG > 3)
	log_info("called %s with %s, %s, %d", __PRETTY_FUNCTION__, SAFE_NAME(ch),
		 SAFE_NAME(vict), lev);

    if (lev == 0)
	lev = 3;

    for (point = character_list; point && (lev > 0); point = point->next) {
	if (IS_NPC(point) &&
	    (ch != point) &&
	    (!point->specials.fighting) &&
	    (real_roomp(ch->in_room)->zone == real_roomp(point->in_room)->zone) &&
	    (IS_SET(point->specials.act, ACT_PROTECTOR))) {
	    if (number(0, 1)) {
		if (!IS_SET(point->specials.act, ACT_HUNTING)) {
		    if (vict) {
			SetHunting(point, vict);
			lev--;
		    }
		}
	    }
	}
    }
}

void StandUp(struct char_data *ch)
{
    if (DEBUG > 3)
	log_info("called %s with %s", __PRETTY_FUNCTION__, SAFE_NAME(ch));

    if ((GET_POS(ch) < POSITION_STANDING) && (GET_POS(ch) > POSITION_STUNNED)) {
	if (ch->points.hit > (ch->points.max_hit / 2))
	    act("$n quickly stands up.", 1, ch, 0, 0, TO_ROOM);
	else if (ch->points.hit > (ch->points.max_hit / 6))
	    act("$n slowly stands up.", 1, ch, 0, 0, TO_ROOM);
	else
	    act("$n gets to $s feet very slowly.", 1, ch, 0, 0, TO_ROOM);
	GET_POS(ch) = POSITION_STANDING;
    }
}

void FighterMove(struct char_data *ch)
{
    int                                     num = 0;

    if (DEBUG > 3)
	log_info("called %s with %s", __PRETTY_FUNCTION__, SAFE_NAME(ch));

    num = number(1, 4);

    switch (num) {
	case 1:
	    if (!ch->skills[SKILL_BASH].learned)
		ch->skills[SKILL_BASH].learned = 10 + GetMaxLevel(ch) * 4;
	    do_bash(ch, GET_NAME(ch->specials.fighting), 0);
	    break;
	case 2:
	    if (ch->equipment[WIELD] || ch->equipment[WIELD_TWOH]) {
		if (!ch->skills[SKILL_DISARM].learned)
		    ch->skills[SKILL_DISARM].learned = 10 + GetMaxLevel(ch) * 4;
		do_disarm(ch, GET_NAME(ch->specials.fighting), 0);
	    } else {
		if (!ch->skills[SKILL_DISARM].learned)
		    ch->skills[SKILL_DISARM].learned = 60 + GetMaxLevel(ch) * 4;
		do_disarm(ch, GET_NAME(ch->specials.fighting), 0);
	    }
	    break;
	case 3:
	case 4:
	    if (!ch->skills[SKILL_KICK].learned)
		ch->skills[SKILL_KICK].learned = 10 + GetMaxLevel(ch) * 4;
	    do_kick(ch, GET_NAME(ch->specials.fighting), 0);
	    break;
    }
}

void DevelopHatred(struct char_data *ch, struct char_data *v)
{
    if (DEBUG > 3)
	log_info("called %s with %s, %s", __PRETTY_FUNCTION__, SAFE_NAME(ch), SAFE_NAME(v));

    if (DoesHate(ch, v))
	return;

    if (ch == v)
	return;

/*
 * diff = GET_ALIGNMENT(ch) - GET_ALIGNMENT(v);
 * (diff > 0) ? diff : diff = -diff;
 * 
 * diff /= 20;
 * 
 * patience = (int) 100 * (float) (GET_HIT(ch) / GET_MAX_HIT(ch));
 * 
 * var = number(1,40) - 20;
 * 
 * if (patience+var < diff)
 * AddHated(ch, v);
 */

    AddHated(ch, v);

}

void Teleport(int current_pulse)
{
    struct char_data                       *ch = NULL;
    struct char_data                       *tmp = NULL;
    struct char_data                       *pers = NULL;
    struct obj_data                        *obj_object = NULL;
    struct obj_data                        *temp_obj = NULL;
    struct room_data                       *rp = NULL;
    struct room_data                       *dest = NULL;

    if (DEBUG > 3)
	log_info("called %s with %d", __PRETTY_FUNCTION__, current_pulse);

    if (current_pulse < 0)
	return;

    for (ch = character_list; ch; ch = ch->next) {
	if (IS_NPC(ch))
	    continue;
	rp = real_roomp(ch->in_room);
	if (rp &&
	    (rp)->tele_targ > 0 &&
	    rp->tele_targ != rp->number &&
	    (rp)->tele_time > 0 && (current_pulse % (rp)->tele_time) == 0) {

	    dest = real_roomp(rp->tele_targ);
	    if (!dest) {
		log_error("invalid tele_target:ROOM %s", rp->name);
		continue;
	    }
	    obj_object = (rp)->contents;
	    while (obj_object) {
		temp_obj = obj_object->next_content;
		obj_from_room(obj_object);
		obj_to_room(obj_object, (rp)->tele_targ);
		obj_object = temp_obj;
	    }

	    while (rp->people /* should never fail */ ) {

		/*
		 * find an NPC in the room 
		 */
		for (tmp = rp->people; tmp; tmp = tmp->next_in_room) {
		    if (IS_NPC(tmp))
			break;
		}

		if (tmp == NULL)
		    break;				       /* we've run out of NPCs */

		char_from_room(tmp);			       /* the list of people in the room has changed */
		char_to_room(tmp, rp->tele_targ);
		if (IS_SET(dest->room_flags, DEATH)) {
		    death_cry(tmp);
		    if (IS_NPC(tmp) && (IS_SET(tmp->specials.act, ACT_POLYSELF))) {
			/*
			 *   take char from storage, to room     
			 */
			pers = tmp->desc->original;
			char_from_room(pers);
			char_to_room(pers, tmp->in_room);
			SwitchStuff(tmp, pers);
			zero_rent(pers);
			extract_char(tmp);
			tmp = pers;
		    }
		    zero_rent(tmp);
		    extract_char(tmp);
		}
	    }
	    char_from_room(ch);
	    char_to_room(ch, rp->tele_targ);
	    if (rp->tele_look) {
		do_look(ch, "", 15);
	    }
	    if (IS_SET(dest->room_flags, DEATH) && GetMaxLevel(ch) < LOW_IMMORTAL) {
		death_cry(ch);

		if (IS_NPC(ch) && (IS_SET(ch->specials.act, ACT_POLYSELF))) {
		    /*
		     *   take char from storage, to room     
		     */
		    pers = ch->desc->original;
		    char_from_room(pers);
		    char_to_room(pers, ch->in_room);
		    SwitchStuff(ch, pers);
		    zero_rent(ch);
		    extract_char(ch);
		    ch = pers;
		}
		zero_rent(ch);
		extract_char(ch);
	    }
	}
    }
}

int HasObject(struct char_data *ch, int ob_num)
{
    int                                     j = 0;
    int                                     found = FALSE;
    struct obj_data                        *i = NULL;

    if (DEBUG > 3)
	log_info("called %s with %s, %d", __PRETTY_FUNCTION__, SAFE_NAME(ch), ob_num);

    /*
     * equipment too
     */

    for (j = 0; j < MAX_WEAR; j++)
	if (ch->equipment[j])
	    found += RecCompObjNum(ch->equipment[j], ob_num);

    if (found > 0)
	return (TRUE);

    /*
     * carrying 
     */
    for (i = ch->carrying; i; i = i->next_content)
	found += RecCompObjNum(i, ob_num);

    if (found > 0)
	return (TRUE);
    else
	return (FALSE);
}

int room_of_object(struct obj_data *obj)
{
    if (DEBUG > 3)
	log_info("called %s with %s", __PRETTY_FUNCTION__, SAFE_ONAME(obj));

    if (obj->in_room != NOWHERE)
	return obj->in_room;
    else if (obj->carried_by)
	return obj->carried_by->in_room;
    else if (obj->equipped_by)
	return obj->equipped_by->in_room;
    else if (obj->in_obj)
	return room_of_object(obj->in_obj);
    else
	return NOWHERE;
}

struct char_data                       *char_holding(struct obj_data *obj)
{
    if (DEBUG > 3)
	log_info("called %s with %s", __PRETTY_FUNCTION__, SAFE_ONAME(obj));

    if (obj->in_room != NOWHERE)
	return NULL;
    else if (obj->carried_by)
	return obj->carried_by;
    else if (obj->equipped_by)
	return obj->equipped_by;
    else if (obj->in_obj)
	return char_holding(obj->in_obj);
    else
	return NULL;
}

int RecCompObjNum(struct obj_data *o, int obj_num)
{
    int                                     total = 0;
    struct obj_data                        *i = NULL;

    if (DEBUG > 3)
	log_info("called %s with %s, %d", __PRETTY_FUNCTION__, SAFE_ONAME(o), obj_num);

    if (obj_index[o->item_number].virtual == obj_num)
	total = 1;

    if (ITEM_TYPE(o) == ITEM_CONTAINER) {
	for (i = o->contains; i; i = i->next_content)
	    total += RecCompObjNum(i, obj_num);
    }
    return (total);

}

void RestoreChar(struct char_data *ch)
{
    if (DEBUG > 3)
	log_info("called %s with %s", __PRETTY_FUNCTION__, SAFE_NAME(ch));

    GET_MANA(ch) = GET_MAX_MANA(ch);
    GET_HIT(ch) = GET_MAX_HIT(ch);
    GET_MOVE(ch) = GET_MAX_MOVE(ch);

    if (GetMaxLevel(ch) < LOW_IMMORTAL) {
	GET_COND(ch, THIRST) = 24;
	GET_COND(ch, FULL) = 24;
    } else {
	GET_COND(ch, THIRST) = -1;
	GET_COND(ch, FULL) = -1;
    }
}

void RemAllAffects(struct char_data *ch)
{
    if (DEBUG > 3)
	log_info("called %s with %s", __PRETTY_FUNCTION__, SAFE_NAME(ch));

    spell_dispel_magic(IMPLEMENTOR, ch, ch, 0);
}

const char                             *pain_level(struct char_data *ch)
{
    int                                     health_percent = 0;

    if (DEBUG > 3)
	log_info("called %s with %s", __PRETTY_FUNCTION__, SAFE_NAME(ch));

    if (GET_MAX_HIT(ch) > 0)
	health_percent = (100 * GET_HIT(ch)) / GET_MAX_HIT(ch);
    else
	health_percent = -1;				       /* How could MAX_HIT be < 1?? */
    if (health_percent >= 100)
	return ("is in an excellent condition");
    else if (health_percent >= 90)
	return ("has a few scratches");
    else if (health_percent >= 75)
	return ("has some small wounds and bruises");
    else if (health_percent >= 50)
	return ("has quite a few wounds");
    else if (health_percent >= 30)
	return ("has some big nasty wounds and scratches");
    else if (health_percent >= 15)
	return ("looks pretty hurt");
    else if (health_percent >= 0)
	return ("is in an awful condition");
    else
	return ("is bleeding awfully from big wounds");
}

int IsWizard(struct char_data *ch)
{
    if (DEBUG > 3)
	log_info("called %s with %s", __PRETTY_FUNCTION__, SAFE_NAME(ch));

    if (!ch)
	return 0;
    return ch->player.class & CLASS_WIZARD;
}

int IsPriest(struct char_data *ch)
{
    if (DEBUG > 3)
	log_info("called %s with %s", __PRETTY_FUNCTION__, SAFE_NAME(ch));

    if (!ch)
	return 0;
    return ch->player.class & CLASS_PRIEST;
}

int IsMagical(struct char_data *ch)
{
    if (DEBUG > 3)
	log_info("called %s with %s", __PRETTY_FUNCTION__, SAFE_NAME(ch));

    if (!ch)
	return 0;
    return ch->player.class & CLASS_MAGICAL;
}

int IsFighter(struct char_data *ch)
{
    if (DEBUG > 3)
	log_info("called %s with %s", __PRETTY_FUNCTION__, SAFE_NAME(ch));

    if (!ch)
	return 0;
    return ch->player.class & CLASS_FIGHTER;
}

int IsSneak(struct char_data *ch)
{
    if (DEBUG > 3)
	log_info("called %s with %s", __PRETTY_FUNCTION__, SAFE_NAME(ch));

    if (!ch)
	return 0;
    return ch->player.class & CLASS_SNEAK;
}