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/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <signal.h>
#include <ctype.h>
#include <math.h>

#include "global.h"
#include "bug.h"
#include "utils.h"

#include "act_move.h"
#include "comm.h"
#include "constants.h"
#include "db.h"
#include "handler.h"
#include "hash.h"
#include "interpreter.h"
#include "multiclass.h"
#include "opinion.h"
#include "spells.h"
#include "fight.h"
#include "modify.h"

#define _TRACKING_C
#include "tracking.h"

/* predicates for find_path function */

int is_target_room_p(int room, void *tgt_room)
{
    if (DEBUG > 3)
	log_info("called %s with %d, %08zx", __PRETTY_FUNCTION__, room, (size_t) tgt_room);

    // return room == (int)tgt_room;
    return room == (int)(size_t) tgt_room;
}

int named_object_on_ground(int room, void *c_data)
{
    char                                   *name = c_data;

    if (DEBUG > 3)
	log_info("called %s with %d, %08zx", __PRETTY_FUNCTION__, room, (size_t) c_data);

    return NULL != get_obj_in_list(name, real_roomp(room)->contents);
}

int named_mobile_in_room(int room, struct hunting_data *c_data)
{
    struct char_data                       *scan = NULL;

    if (DEBUG > 3)
	log_info("called %s with %d, %08zx", __PRETTY_FUNCTION__, room, (size_t) c_data);

    for (scan = real_roomp(room)->people; scan; scan = scan->next_in_room)
	if (isname(c_data->name, scan->player.name)) {
	    *(c_data->victim) = scan;
	    return 1;
	}
    return 0;
}

/* Perform breadth first search on rooms from start (in_room)
 * until end (tgt_room) is reached. Then return the correct
 * direction to take from start to reach end.
 * thoth@manatee.cis.ufl.edu
 * if dvar<0 then search THROUGH closed but not locked doors,
 * for mobiles that know how to open doors.
 */

static void donothing(void)
{
    if (DEBUG > 3)
	log_info("called %s with no arguments", __PRETTY_FUNCTION__);

    return;
}

int choose_exit(int in_room, int tgt_room, int depth)
{
    if (DEBUG > 3)
	log_info("called %s with %d, %d, %d", __PRETTY_FUNCTION__, in_room, tgt_room, depth);

    // return find_path(in_room, is_target_room_p, (const void *)tgt_room, depth);
    return find_path(in_room, is_target_room_p, (const void *)(size_t) tgt_room, depth);
}

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

    if (ch->specials.fighting)
	return 0;

    if (!IS_SET(EXIT(ch, dir)->exit_info, EX_CLOSED)) {
	return do_move(ch, "", dir + 1);
    } else if (IsHumanoid(ch) && !IS_SET(EXIT(ch, dir)->exit_info, EX_LOCKED)) {
	open_door(ch, dir);
    }
    return 0;
}

int find_path(int in_room, ifuncp predicate, const void *c_data, int depth)
{
    struct room_q                          *tmp_q = NULL;
    struct room_q                          *q_head = NULL;
    struct room_q                          *q_tail = NULL;
    int                                     i = 0;
    int                                     tmp_room = 0;
    int                                     count = 0;
    int                                     thru_doors = 0;
    struct room_data                       *herep = NULL;
    struct room_data                       *therep = NULL;
    struct room_direction_data             *exitp = NULL;
    static struct hash_header               x_room;

    if (DEBUG > 2)
	log_info("called %s with %d, %08zx, %d", __PRETTY_FUNCTION__, in_room, (size_t) c_data,
		 depth);

    /*
     * If start = destination we are done 
     */
    if ((predicate) (in_room, c_data))
	return -1;

    if (depth < 0) {
	thru_doors = TRUE;
	depth = -depth;
    } else {
	thru_doors = FALSE;
    }

    if (x_room.buckets)					       /* junk left over from a previous track */
	destroy_hash_table(&x_room, donothing);
    init_hash_table(&x_room, sizeof(int), 2048);
    hash_enter(&x_room, in_room, (void *)-1);

    /*
     * initialize queue 
     */
    CREATE(q_head, struct room_q, 1);

    q_tail = q_head;
    q_tail->room_nr = in_room;
    q_tail->next_q = 0;

    while (q_head) {
	herep = real_roomp(q_head->room_nr);
	/*
	 * for each room test all directions 
	 */
	for (i = 0; i < MAX_NUM_EXITS; i++) {
	    exitp = herep->dir_option[i];
	    if (exit_ok(exitp, &therep) && (thru_doors ? GO_OK_SMARTER : GO_OK)) {
		/*
		 * next room 
		 */
		tmp_room = herep->dir_option[i]->to_room;
		if (!((predicate) (tmp_room, c_data))) {
		    /*
		     * shall we add room to queue ? 
		     */
		    /*
		     * count determines total breadth and depth 
		     */
		    if (!hash_find(&x_room, tmp_room) && (count < depth)
			&& !IS_SET(RM_FLAGS(tmp_room), DEATH)) {
			count++;
			/*
			 * mark room as visted and put on queue 
			 */
			CREATE(tmp_q, struct room_q, 1);

			tmp_q->room_nr = tmp_room;
			tmp_q->next_q = 0;
			q_tail->next_q = tmp_q;
			q_tail = tmp_q;

			/*
			 * ancestor for first layer is the direction 
			 */
			/*
			 * hash_enter(&x_room, tmp_room, ((int)hash_find(&x_room, q_head->room_nr) == -1) ? (void *)(i
			 * + 1) : hash_find(&x_room, q_head->room_nr)); 
			 */
			hash_enter(&x_room, tmp_room,
				   ((int)(size_t) hash_find(&x_room, q_head->room_nr) == -1) ?
				   (void *)(size_t) (i + 1) : hash_find(&x_room,
									q_head->room_nr));
		    }
		} else {
		    /*
		     * have reached our goal so free queue 
		     */
		    tmp_room = q_head->room_nr;
		    for (; q_head; q_head = tmp_q) {
			tmp_q = q_head->next_q;
			DESTROY(q_head);
		    }
		    /*
		     * return direction if first layer 
		     */
		    // if ((int)hash_find(&x_room, tmp_room) == -1)
		    if ((int)(size_t) hash_find(&x_room, tmp_room) == -1)
			return (i);
		    else				       /* else return the ancestor */
			// return (-1 + (int)hash_find(&x_room, tmp_room));
			return (-1 + (int)(size_t) hash_find(&x_room, tmp_room));
		}
	    }
	}
	/*
	 * free queue head and point to next entry 
	 */
	tmp_q = q_head->next_q;
	DESTROY(q_head);
	q_head = tmp_q;
    }
    /*
     * couldn't find path 
     */
    return (-1);
}

void MobHunt(struct char_data *ch)
{
    int                                     res = 0;
    int                                     k = 0;

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

    if (ch->persist <= 0) {
	res = choose_exit(ch->in_room, ch->old_room, 2000);
	if (res > -1) {
	    go_direction(ch, res);
	} else {
	    if (ch->specials.hunting) {
		if (ch->specials.hunting->in_room == ch->in_room) {
		    if (CanHate(ch, ch->specials.hunting) &&
			(!IS_AFFECTED(ch->specials.hunting, AFF_HIDE))) {
			if (check_peaceful(ch, "You CAN'T fight here!\r\n")) {
			    act("$n fumes at $N", TRUE, ch, 0, ch->specials.hunting, TO_ROOM);
			} else {
			    if (IsHumanoid(ch)) {
				act("$n screams 'Time to die, $N'", TRUE, ch, 0,
				    ch->specials.hunting, TO_ROOM);
			    } else if (IsAnimal(ch)) {
				act("$n growls.", TRUE, ch, 0, 0, TO_ROOM);
			    }
			    hit(ch, ch->specials.hunting, 0);
			    return;
			}
		    }
		}
	    }
	    REMOVE_BIT(ch->specials.act, ACT_HUNTING);
	    ch->specials.hunting = 0;
	    ch->hunt_dist = 0;
	}
    } else if (ch->specials.hunting) {
	if (ch->hunt_dist <= 50)
	    ch->hunt_dist = 50;
	for (k = 1; k <= 2 && ch->specials.hunting; k++) {
	    ch->persist -= 1;
	    res = dir_track(ch, ch->specials.hunting);
	    if (res != -1) {
		go_direction(ch, res);
	    } else {
		ch->persist = 0;
		ch->specials.hunting = 0;
		ch->hunt_dist = 0;
	    }
	}
    } else {
	ch->persist = 0;
    }
}

int dir_track(struct char_data *ch, struct char_data *vict)
{
    int                                     code = 0;

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

    if ((!ch) || (!vict))
	return (-1);

    code = choose_exit(ch->in_room, vict->in_room, ch->hunt_dist);

    if ((!ch) || (!vict))
	return (-1);

    if (code == -1) {
	if (ch->in_room == vict->in_room) {
	    cprintf(ch, "\r\nTrack -> You have found your target!\r\n");
	} else {
	    cprintf(ch, "\r\nTrack -> You have lost the trail.\r\n");
	}
	return (-1);					       /* false to continue the hunt */
    } else {
	cprintf(ch, "\r\nTrack -> You see a faint trail %sward\r\n", dirs[code]);
	return (code);
    }
}

int track(struct char_data *ch, struct char_data *vict)
{
    int                                     code = 0;

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

    if ((!ch) || (!vict))
	return (-1);

    code = choose_exit(ch->in_room, vict->in_room, ch->hunt_dist);

    if ((!ch) || (!vict))
	return (-1);

    if (ch->in_room == vict->in_room) {
	cprintf(ch, "\r\nTrack -> You have found your target!\r\n");
	return (FALSE);					       /* false to continue the hunt */
    }
    if (code == -1) {
	cprintf(ch, "\r\nTrack -> You have lost the trail.\r\n");
	return (FALSE);
    } else {
	cprintf(ch, "\r\nTrack -> You see a faint trail %sward\r\n", dirs[code]);
	return (TRUE);
    }
}

void do_track(struct char_data *ch, const char *argument, int cmd)
{
    int                                     dist = 0;
    int                                     code = 0;
    int                                     cost = 0;
    char                                    name[MAX_INPUT_LENGTH] = "\0";
    struct hunting_data                     huntd;

    if (DEBUG)
	log_info("called %s with %s, %s, %d", __PRETTY_FUNCTION__, SAFE_NAME(ch),
		 VNULL(argument), cmd);

    only_argument(argument, name);

    dist = ch->skills[SKILL_TRACK].learned;

    if (IS_SET(ch->player.class, CLASS_RANGER)) {
	dist *= 2;
	cost = 15 - (GET_LEVEL(ch, RANGER_LEVEL_IND) / 10);
    } else if (IS_SET(ch->player.class, CLASS_THIEF)) {
	cost = 50 - GET_LEVEL(ch, THIEF_LEVEL_IND);
	dist = dist;
    } else {
	dist = dist / 2;
	cost = 50 - (GET_LEVEL(ch, BestThiefClass(ch)) / 2);
    }

    if (!dist) {
	cprintf(ch, "You do not know of this skill yet!\r\n");
	return;
    }
    if (GET_MANA(ch) < cost) {
	cprintf(ch, "You can not seem to concentrate on the trail...\r\n");
	return;
    }
    GET_MANA(ch) -= cost;

    switch (GET_RACE(ch)) {
	case RACE_ELVEN:
	    dist += 10;					       /* even better */
	    break;
	case RACE_DEVIL:
	case RACE_DEMON:
	    dist = MAX_ROOMS;				       /* as good as can be */
	    break;
	default:
	    break;
    }

    if (GetMaxLevel(ch) >= IMMORTAL)
	dist = MAX_ROOMS;

    ch->hunt_dist = dist;

    ch->specials.hunting = 0;
    huntd.name = name;
    huntd.victim = &ch->specials.hunting;
    code = find_path(ch->in_room, (ifuncp)named_mobile_in_room, &huntd, -dist);

    WAIT_STATE(ch, PULSE_VIOLENCE * 1);

    if (code == -1) {
	cprintf(ch, "You are unable to find traces of one.\r\n");
	return;
    } else {
	if (IS_LIGHT(ch->in_room)) {
	    SET_BIT(ch->specials.act, PLR_HUNTING);
	    cprintf(ch, "You see traces of your quarry to the %s\r\n", dirs[code]);
	    if (ch->skills[SKILL_TRACK].learned < 50)
		ch->skills[SKILL_TRACK].learned += 2;
	} else {
	    ch->specials.hunting = 0;
	    cprintf(ch, "It's too dark in here to track...\r\n");
	    return;
	}
    }
}

char                                   *track_distance(struct char_data *ch, char *mob_name)
{
    static char                             buf[MAX_STRING_LENGTH] = "No route";

    if (!ch)
	return buf;
    int                                     this_room = ch->in_room;
    struct char_data                       *target_mob = get_char_vis_world(ch, mob_name, NULL);

    if (!target_mob)
	return buf;
    int                                     dest_room = target_mob->in_room;
    int                                     next_room;
    int                                     dir = -1;
    int                                     dx = 0,
	dy = 0,
	dz = 0;;

    if ((dir = choose_exit(this_room, dest_room, -MAX_ROOMS)) >= 0) {
	while ((dir = choose_exit(this_room, dest_room, -MAX_ROOMS)) > -1) {
	    struct room_data                       *from_here = NULL;
	    struct room_data                       *to_here = NULL;

	    from_here = real_roomp(this_room);
	    next_room = from_here->dir_option[dir]->to_room;
	    to_here = real_roomp(next_room);

	    if (!to_here)
		return buf;
	    switch (dir) {
		case 0:
		    dy++;
		    break;
		case 1:
		    dx++;
		    break;
		case 2:
		    dy--;
		    break;
		case 3:
		    dx--;
		    break;
		case 4:
		    dz++;
		    break;
		case 5:
		    dz--;
		    break;
	    }
	    this_room = next_room;
	}
	sprintf(buf, "(%3d%s, %3d%s, %3d%s)",
		abs(dx), dx < 0 ? "w" : "e",
		abs(dy), dy < 0 ? "s" : "n", abs(dz), dz < 0 ? "d" : "u");
    }
    return buf;
}

double heading(double x, double y)
{
    double                                  val = 0.0;

    if (y == 0.0) {
	if (x > 0.0)
	    return 90.0;
	else if (x == 0.0)
	    return 0.0;
	else
	    return 270.0;
    }

    val = atan2(y, x) * 180.0 / 3.14159;

    if (val > 90.0)
	return 450.0 - val;
    else if (val > 0.0)
	return 90.0 - val;
    else if (val < -90.0)
	return (0.0 - val) + 90.0;
    else
	return 90.0 - val;
}

void do_immtrack(struct char_data *ch, const char *argument, int cmd)
{
    char                                    buf[MAX_INPUT_LENGTH] = "\0\0\0\0\0\0\0";
    int                                     loc_nr = 0;
    int                                     location = 0;
    struct room_data                       *target_room = NULL;
    struct char_data                       *target_mob = NULL;
    struct obj_data                        *target_obj = NULL;
    int                                     type_of_thing = 0;

    if (DEBUG)
	log_info("called %s with %s, %s, %d", __PRETTY_FUNCTION__, SAFE_NAME(ch),
		 VNULL(argument), cmd);

    if (IS_NPC(ch)) {
	cprintf(ch, "You cannot cheat like this.\r\n");
	return;
    }

    only_argument(argument, buf);
    if (!*buf) {
	cprintf(ch, "You must supply a room number or a name.\r\n");
	return;
    }
    if (isdigit(*buf) && NULL == index(buf, '.')) {
	loc_nr = atoi(buf);
	if ((target_room = real_roomp(loc_nr))) {
	    location = loc_nr;
	    type_of_thing = 1;
	} else {
	    cprintf(ch, "No room exists with that number.\r\n");
	    return;
	}
    } else if ((target_mob = get_char_vis_world(ch, buf, NULL))) {
	if (target_mob->in_room != NOWHERE) {
	    location = target_mob->in_room;
	    type_of_thing = 2;
	} else {
	    cprintf(ch, "The mob is not available.\r\n");
	    cprintf(ch, "Try where #.mob to nail its room number.\r\n");
	    return;
	}
    } else if ((target_obj = get_obj_vis_world(ch, buf, NULL))) {
	if (target_obj->in_room != NOWHERE) {
	    location = target_obj->in_room;
	    type_of_thing = 3;
	} else {
	    cprintf(ch, "The object is not available.\r\n");
	    cprintf(ch, "Try where #.object to nail its room number.\r\n");
	    return;
	}
    } else {
	cprintf(ch, "No such creature or object around.\r\n");
	return;
    }

    /*
     * a location has been found. 
     */

    if (!real_roomp(location)) {
	log_error("Massive error in do_goto. Everyone Off NOW.");
	return;
    }

    switch (type_of_thing) {
	case 1:
	    page_printf(ch, "Route to [#%d] %s:\r\n", target_room->number, target_room->name);
	    break;
	case 2:
	    page_printf(ch, "Route to [#%d] %s:\r\n", MobVnum(target_mob),
			SAFE_NAME(target_mob));
	    break;
	case 3:
	    page_printf(ch, "Route to [#%d] %s:\r\n", ObjVnum(target_obj),
			SAFE_ONAME(target_obj));
	    break;
    }

    int                                     this_room = ch->in_room;
    int                                     dest_room = location;
    int                                     next_room;
    int                                     dir = -1;
    int                                     dx = 0,
	dy = 0,
	dz = 0;;
    int                                     i = 0;
    int                                     count = 0;

    if ((dir = choose_exit(this_room, dest_room, -MAX_ROOMS)) < 0) {
	page_printf(ch, "Rats!  Can't find a route!\r\n");
	return;
    } else {
	count = 0;
	page_printf(ch, "Starting in      [#%5d] %s...\r\n", this_room,
		    real_roomp(this_room)->name);
	while ((dir = choose_exit(this_room, dest_room, -MAX_ROOMS)) > -1) {
	    struct room_data                       *from_here = NULL;
	    struct room_data                       *to_here = NULL;

	    from_here = real_roomp(this_room);
	    next_room = from_here->dir_option[dir]->to_room;
	    to_here = real_roomp(next_room);

	    if (!to_here) {
		page_printf(ch, "OOPS!\r\n");
		return;
	    }
	    count++;
	    page_printf(ch, "  %2d %-8s -> [#%5d] %s\r\n", ++i, dirs[dir], next_room,
			to_here->name);
	    switch (dir) {
		case 0:
		    dy++;
		    break;
		case 1:
		    dx++;
		    break;
		case 2:
		    dy--;
		    break;
		case 3:
		    dx--;
		    break;
		case 4:
		    dz++;
		    break;
		case 5:
		    dz--;
		    break;
	    }
	    this_room = next_room;
	}
	page_printf(ch,
		    "Path is %d rooms long, with a distance of (%d%s, %d%s, %d%s),\r\nwhich is roughly %d room lengths away on a heading of %d degrees.\r\n",
		    count, abs(dx), dx < 0 ? "w" : "e", abs(dy), dy < 0 ? "s" : "n", abs(dz),
		    dz < 0 ? "d" : "u",
		    (int)sqrt((double)dx * (double)dx + (double)dy * (double)dy),
		    (int)heading(dx, dy)
	    );
    }
}