Ejemplo n.º 1
0
/* false means donÕt fire this (itÕs in a floor or ceiling or outside of the map), otherwise
	the monster that was intersected first (or NONE) is returned in target_index */
bool preflight_projectile(
	world_point3d *origin,
	short origin_polygon_index,
	world_point3d *destination,
	angle delta_theta,
	short type,
	short owner,
	short owner_type,
	short *obstruction_index)
{
	bool legal_projectile= false;
	struct projectile_definition *definition= get_projectile_definition(type);
	
	(void) (delta_theta);
	
	/* will be used when we truly preflight projectiles */
	(void) (owner_type);
	
	if (origin_polygon_index!=NONE)
	{
		world_distance dx= destination->x-origin->x, dy= destination->y-origin->y;
		angle elevation= arctangent(isqrt(dx*dx + dy*dy), destination->z-origin->z);
		
		if (elevation<MAXIMUM_PROJECTILE_ELEVATION || elevation>FULL_CIRCLE-MAXIMUM_PROJECTILE_ELEVATION)
		{
			struct polygon_data *origin_polygon= get_polygon_data(origin_polygon_index);
			
			// LP note: "penetrates media boundary" means "hit media surface and continue";
			// it will act like "penetrates_media" here
			// Added idiot-proofing to media data
			media_data *media = get_media_data(origin_polygon->media_index);
			if (origin->z>origin_polygon->floor_height && origin->z<origin_polygon->ceiling_height &&
				(origin_polygon->media_index==NONE || definition->flags&(_penetrates_media) || (media ? origin->z>media->height : true)))
			{
				/* make sure it hits something */
				uint16 flags= translate_projectile(type, origin, origin_polygon_index, destination, (short *) NULL, owner, obstruction_index, 0, true, NONE);
				
				*obstruction_index= (flags&_projectile_hit_monster) ? get_object_data(*obstruction_index)->permutation : NONE;
				legal_projectile= true;
			}
		}
	}
	
	return legal_projectile;
}
Ejemplo n.º 2
0
static void update_view_data(
	struct view_data *view)
{
	angle theta;

	// LP change: doing all the FOV changes here:
	View_AdjustFOV(view->field_of_view,view->target_field_of_view);
	
	if (view->effect==NONE)
	{
		view->world_to_screen_x= view->real_world_to_screen_x;
		view->world_to_screen_y= view->real_world_to_screen_y;
	}
	else
	{
		update_render_effect(view);
	}
	
	view->untransformed_left_edge.i= view->world_to_screen_x;
	view->untransformed_right_edge.i= - view->world_to_screen_x;
	
	/* calculate world_to_screen_y*tan(pitch) */
	view->dtanpitch= (view->world_to_screen_y*sine_table[view->pitch])/cosine_table[view->pitch];

	/* calculate left cone vector */
	theta= NORMALIZE_ANGLE(view->yaw-view->half_cone);
	view->left_edge.i= cosine_table[theta], view->left_edge.j= sine_table[theta];
	
	/* calculate right cone vector */
	theta= NORMALIZE_ANGLE(view->yaw+view->half_cone);
	view->right_edge.i= cosine_table[theta], view->right_edge.j= sine_table[theta];
	
	/* calculate top cone vector (negative to clip the right direction) */
	view->top_edge.i= - view->world_to_screen_y;
	view->top_edge.j= - (view->half_screen_height + view->dtanpitch); /* ==k */

	/* calculate bottom cone vector */
	view->bottom_edge.i= view->world_to_screen_y;
	view->bottom_edge.j= - view->half_screen_height + view->dtanpitch; /* ==k */

	/* if weÕre sitting on one of the endpoints in our origin polygon, move us back slightly (±1) into
		that polygon.  when we split rays weÕre assuming that weÕll never pass through a given
		vertex in different directions (because if we do the tree becomes a graph) but when
		we start on a vertex this can happen.  this is a destructive modification of the origin. */
	{
		short i;
		struct polygon_data *polygon= get_polygon_data(view->origin_polygon_index);
		
		for (i= 0;i<polygon->vertex_count;++i)
		{
			struct world_point2d *vertex= &get_endpoint_data(polygon->endpoint_indexes[i])->vertex;
			
			if (vertex->x==view->origin.x && vertex->y==view->origin.y)
			{
				world_point2d *ccw_vertex= &get_endpoint_data(polygon->endpoint_indexes[WRAP_LOW(i, polygon->vertex_count-1)])->vertex;
				world_point2d *cw_vertex= &get_endpoint_data(polygon->endpoint_indexes[WRAP_HIGH(i, polygon->vertex_count-1)])->vertex;
				world_vector2d inset_vector;
				
				inset_vector.i= (ccw_vertex->x-vertex->x) + (cw_vertex->x-vertex->x);
				inset_vector.j= (ccw_vertex->y-vertex->y) + (cw_vertex->y-vertex->y);
				view->origin.x+= SGN(inset_vector.i);
				view->origin.y+= SGN(inset_vector.j);
				
				break;
			}
		}
		
		/* determine whether we are under or over the media boundary of our polygon; we will see all
			other media boundaries from this orientation (above or below) or fail to draw them. */
		if (polygon->media_index==NONE)
		{
			view->under_media_boundary= false;
		}
		else
		{
			struct media_data *media= get_media_data(polygon->media_index);
			
			// LP change: idiot-proofing
			if (media)
			{
				view->under_media_boundary= UNDER_MEDIA(media, view->origin.z);
				view->under_media_index= polygon->media_index;
			} else {
				view->under_media_boundary= false;
			}
		}
	}
}