/* 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; }
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; } } } }