Mud20/accounts/
Mud20/accounts/c/
Mud20/accounts/f/
Mud20/accounts/k/
Mud20/accounts/s/
Mud20/accounts/t/
Mud20/area_current/
Mud20/area_current/newareas/
Mud20/bin/
Mud20/clans/
Mud20/gods/
Mud20/old-sources/
Mud20/player/
Mud20/player/a/del/
Mud20/player/b/
Mud20/player/b/bak/
Mud20/player/b/del/
Mud20/player/f/
Mud20/player/f/bak/
Mud20/player/f/del/
Mud20/player/k/
Mud20/player/k/bak/
Mud20/player/k/del/
Mud20/player/k/dmp/
Mud20/player/m/
Mud20/player/m/bak/
Mud20/player/o/
Mud20/player/o/bak/
Mud20/player/p/
Mud20/player/s/
Mud20/player/s/bak/
Mud20/player/s/del/
Mud20/player/t/
Mud20/player/t/del/
Mud20/player/v/
Mud20/public_html/
Mud20/races/
Mud20/skilltables/
__MACOSX/Mud20/accounts/
__MACOSX/Mud20/accounts/c/
__MACOSX/Mud20/accounts/f/
__MACOSX/Mud20/accounts/k/
__MACOSX/Mud20/accounts/s/
__MACOSX/Mud20/area_current/
__MACOSX/Mud20/area_current/core_areas/
__MACOSX/Mud20/area_current/helps/
__MACOSX/Mud20/area_current/newareas/
__MACOSX/Mud20/backups/
__MACOSX/Mud20/bin/
__MACOSX/Mud20/clans/
__MACOSX/Mud20/gods/
__MACOSX/Mud20/log/
__MACOSX/Mud20/old-sources/
__MACOSX/Mud20/player/
__MACOSX/Mud20/player/a/del/
__MACOSX/Mud20/player/b/
__MACOSX/Mud20/player/b/bak/
__MACOSX/Mud20/player/f/
__MACOSX/Mud20/player/f/bak/
__MACOSX/Mud20/player/f/del/
__MACOSX/Mud20/player/k/
__MACOSX/Mud20/player/k/bak/
__MACOSX/Mud20/player/k/del/
__MACOSX/Mud20/player/k/dmp/
__MACOSX/Mud20/player/m/
__MACOSX/Mud20/player/m/bak/
__MACOSX/Mud20/player/o/
__MACOSX/Mud20/player/o/bak/
__MACOSX/Mud20/player/p/
__MACOSX/Mud20/player/s/
__MACOSX/Mud20/player/s/bak/
__MACOSX/Mud20/player/t/del/
__MACOSX/Mud20/player/v/
__MACOSX/Mud20/public_html/
__MACOSX/Mud20/races/
__MACOSX/Mud20/skilltables/
/***************************************************************************
 * Mud20 1.0 by Todd H. Johnson (Kregor) a derivative of the Open Gaming   *
 * License by Wizards of the Coast. All comments referring to D20, OGL,    *
 * and SRD refer to the System Reference Document for the Open Gaming      *
 * system. Any inclusion of these derivatives must include credit to the   *
 * Mud20 system, the full and complete Open Gaming LIcense, and credit to  *
 * the respective authors. See ../doc/srd.txt for more information.        *
 *                                                                         *
 * Emud  2.2 by Igor van den Hoven, Michiel Lange, and Martin Bethlehem.   *
 *                                                                         *
 * MrMud 1.4 by David Bills, Dug Michael and Martin Gallwey                *
 *                                                                         *
 * Merc  2.1 Diku Mud improvments copyright (C) 1992, 1993 by Michael      *
 * Chastain, Michael Quan, and Mitchell Tse.                               *
 *                                                                         *
 * Original Diku Mud copyright (C) 1990 1991 by Sebastian Hammer,          *
 * Michael Seifert, Hans Henrik St{rfeld, Tom Madsen, and Katje Nyboe.     *
 ***************************************************************************/

/***************************************************************************
 * pathfind.c: Pathfinding functions 																		   *
 ***************************************************************************/

#include "mud.h"

bool			world_index[2000];

ROOM_INDEX_DATA	*	pfind_dest;
CHAR_DATA			*	pfind_char;
CHAR_DATA 		*	pfind_mob;
AREA_DATA			*	pfind_area;
char				*	pfind_name;

bool					pfind_cnt;
sh_int				valid_exit;
sh_int				pfind_dir;

bool valid_pfind_exit( EXIT_DATA *pExit )
{
	if (room_index[pExit->to_room] == NULL)
	{
		return FALSE;
	}

	if (room_index[pExit->to_room]->area != pfind_area)
	{
		return FALSE;
	}

	return TRUE;
}


/*
	Fast short distance node weighted algorithm, can be used to backtrack the
	entire shortest path - Scandum
*/

void findpath_dest(ROOM_INDEX_DATA *room, bool cnt)
{
	bool door;

	world_index[room->vnum - room->area->low_r_vnum] = cnt;

	if (room == pfind_dest)
	{
		pfind_cnt  = cnt;
		valid_exit = pfind_dir;
	}
	else if (cnt < pfind_cnt)
	{
		cnt++;

		for (door = 0 ; door < 6 ; door++)
		{
			if (room->exit[door] && valid_pfind_exit(room->exit[door]))
			{
				if (world_index[room->exit[door]->to_room - room->area->low_r_vnum] > cnt)
				{
					findpath_dest(room_index[room->exit[door]->to_room], cnt);
				}
			}
		}
	}
}

void findpath_name(ROOM_INDEX_DATA *room, bool cnt)
{
	CHAR_DATA *rch;
	bool door;

	world_index[room->vnum - room->area->low_r_vnum] = cnt;

	if (pfind_cnt > cnt)
	{
		for (rch = room->first_person ; rch ; rch = rch->next_in_room)
		{
			if (is_name_short(pfind_name, rch->name) && can_see(pfind_char, rch) && can_hear(pfind_char, rch))
			{
				pfind_cnt = cnt;
				pfind_mob = rch;
				return;
			}
		}

		cnt++;

		for (door = 0 ; door < 6 ; door++)
		{
			if (room->exit[door] && valid_pfind_exit(room->exit[door]))
			{
				if (world_index[room->exit[door]->to_room - room->area->low_r_vnum] > cnt)
				{
					findpath_name(room_index[room->exit[door]->to_room], cnt);
				}
			}
		}
	}
}

int findpath_search_victim( CHAR_DATA *ch, CHAR_DATA *victim, int range )
{
	int area_size;

	push_call("findpath_search_victim(%p,%p,%p)",ch,victim,range);

	if (ch->in_room == victim->in_room)
	{
		pop_call();
		return -2;
	}

	if (ch->in_room->area != victim->in_room->area)
	{
		pop_call();
		return -1;
	}

	if ((area_size = ch->in_room->area->hi_r_vnum - ch->in_room->area->low_r_vnum) >= 2000)
	{
		log_build_printf(ch->in_room->vnum, "findpath_search_victim: Area too big");
		pop_call();
		return -1;
	}

	pfind_area = ch->in_room->area;
	pfind_mob  = victim;
	pfind_dest = victim->in_room;
	pfind_cnt  = range;
	valid_exit = -1;

	memset(world_index, 128, area_size);
	world_index[ch->in_room->vnum - ch->in_room->area->low_r_vnum] = 0;

	for (pfind_dir = 0 ; pfind_dir < 6 ; pfind_dir++)
	{
		if (ch->in_room->exit[pfind_dir] && valid_pfind_exit(ch->in_room->exit[pfind_dir]))
		{
			findpath_dest(room_index[ch->in_room->exit[pfind_dir]->to_room], 1);
		}
	}
	pop_call();
	return valid_exit;
}


int findpath_room( CHAR_DATA *ch, int vnum, int range )
{
	int area_size;
	ROOM_INDEX_DATA *room;

	push_call("findpath_room(%p,%p,%p)",ch,vnum,range);

	if ((room = get_room_index(vnum)) == NULL)
	{
		log_build_printf(ch->in_room->vnum, "findpath_room: invalid room vnum");
		pop_call();
		return -1;
	}

	if (ch->in_room == room)
	{
		pop_call();
		return -2;
	}

	if (ch->in_room->area != room->area)
	{
		pop_call();
		return -1;
	}

	if ((area_size = ch->in_room->area->hi_r_vnum - ch->in_room->area->low_r_vnum) >= 2000)
	{
		log_build_printf(ch->in_room->vnum, "findpath_room: Area too big");
		pop_call();
		return -1;
	}

	pfind_area = ch->in_room->area;
	pfind_dest = room;
	pfind_cnt  = range;
	valid_exit = -1;

	memset(world_index, 128, area_size);
	world_index[ch->in_room->vnum - ch->in_room->area->low_r_vnum] = 0;

	for (pfind_dir = 0 ; pfind_dir < 6 ; pfind_dir++)
	{
		if (ch->in_room->exit[pfind_dir] && valid_pfind_exit(ch->in_room->exit[pfind_dir]))
		{
			findpath_dest(room_index[ch->in_room->exit[pfind_dir]->to_room], 1);
		}
	}
	pop_call();
	return valid_exit;
}


CHAR_DATA *findpath_search_name( CHAR_DATA *ch, char *name, int range )
{
	CHAR_DATA *victim;
	int area_size;

	push_call("findpath_search_name(%p,%p,%p)",ch,name,range);

	if ((victim = get_char_room(ch, name)) != NULL)
	{
		pop_call();
		return victim;
	}

	if ((area_size = ch->in_room->area->hi_r_vnum - ch->in_room->area->low_r_vnum) >= 2000)
	{
		log_build_printf(ch->in_room->vnum, "findpath_search_name: Area too big");
		pop_call();
		return NULL;
	}

	pfind_area = ch->in_room->area;
	pfind_name = name;
	pfind_mob  = NULL;
	pfind_char = ch;
	pfind_cnt  = range;

	memset(world_index, 128, area_size);
	world_index[ch->in_room->vnum - ch->in_room->area->low_r_vnum] = 0;

	for (pfind_dir = 0 ; pfind_dir < 6 ; pfind_dir++)
	{
		if (ch->in_room->exit[pfind_dir] && valid_pfind_exit(ch->in_room->exit[pfind_dir]))
		{
			findpath_name(room_index[ch->in_room->exit[pfind_dir]->to_room], 1);
		}
	}
	pop_call();
	return pfind_mob;
}