View Single Post
  #8  
Old 08-18-2004, 01:30 AM
Wiz
Dragon
 
Join Date: Feb 2002
Posts: 583
Default

I wrote a fairly well-functioning LOS the other day - also have combat pathing code using it.

I'll paste it here for reference. It essentially draws an angle to the target and checks for blockers.

Code:
bool Mob::CheckCoordLos(float cur_x, float cur_y, float cur_z, float trg_x, float trg_y, float trg_z, float perwalk_x, float perwalk_y, float perwalk_z) {
	if (zone->map == 0)
	{
		return true;
	}
	float dist_x = cur_x - trg_x;
	if (dist_x < 0)
		dist_x *= -1;
	float dist_y = cur_y - trg_y;
	if (dist_y < 0)
		dist_y *= -1;
	float dist_z = cur_z - trg_z;
	if (dist_z < 0)
		dist_z *= -1;
	if (dist_x  <= dist_y && dist_z <= dist_y)
	{
		perwalk_x /= (dist_y/dist_x);
		perwalk_z /= (dist_y/dist_z);
	}
	else if (dist_y <= dist_x && dist_z <= dist_x)
	{
		perwalk_y /= (dist_x/dist_y);
		perwalk_z /= (dist_x/dist_z);
	}
	else if (dist_y <= dist_z && dist_x <= dist_z)
	{
		perwalk_y /= (dist_z/dist_y);
		perwalk_x /= (dist_z/dist_x);
	}
	int steps = 300000; //Just a safety check to prevent endless loops.
	while (steps > 0) {
		steps--;
		//X traj
		if (cur_x < trg_x)
		{
			if (cur_x + perwalk_x < trg_x)
				cur_x += perwalk_x;
			else
				cur_x = trg_x;
		}
		if (cur_x > trg_x)
		{
			if (cur_x - perwalk_x > trg_x)
				cur_x -= perwalk_x;
			else
				cur_x = trg_x;
		}
		//Y traj
		if (cur_y < trg_y)
		{
			if (cur_y + perwalk_y < trg_y)
				cur_y += perwalk_y;
			else
				cur_y = trg_y;
		}
		if (cur_y > trg_y)
		{
			if (cur_y - perwalk_y > trg_y)
				cur_y -= perwalk_y;
			else
				cur_y = trg_y;
		}
		//Z traj
		if (cur_z < trg_z)
		{
			if (cur_z + perwalk_z < trg_z)
				cur_z += perwalk_z;
			else
				cur_z = trg_z;
		}
		if (cur_z > trg_z)
		{
			if (cur_z - perwalk_z > trg_z)
				cur_z -= perwalk_z;
			else
				cur_z = trg_z;
		}
		PNODE pnode = zone->map->SeekNode( zone->map->GetRoot(), cur_x, cur_y );
		if (pnode != 0)
		{
			int *iface = zone->map->SeekFace( pnode, cur_x, cur_y );
			if (*iface == -1) {
				return false;
			}
			float tmp_z = 0;
			float best_z = -999999;

			while(*iface != -1)
			{
				tmp_z = zone->map->GetFaceHeight( *iface, cur_x, cur_y );
				if (tmp_z-1 <= cur_z  && tmp_z > best_z)
				{
					best_z = tmp_z;
				}
				iface++;
			}
			if (best_z == -999999)
			{
				return false;
			}

			int diff = (best_z) - (cur_z);
			if (diff <= 1 && diff >= -1)
			{
				return false;
			}

		}
		if (cur_y == trg_y && cur_x == trg_x && cur_z == trg_z)
		{
			return true;
		}
	}
	return true;
}
Rogean should be putting this into the source, but he's lazy.
Reply With Quote