示例#1
0
static void m2_swipe_nearby_items(short player_index)
{
	object_data *object;
	object_data *player_object;
	player_data *player= get_player_data(player_index);
	short next_object;
	polygon_data *polygon;
	short *neighbor_indexes;
	short i;

	player_object= get_object_data(get_monster_data(player->monster_index)->object_index);

	polygon= get_polygon_data(player_object->polygon);
	neighbor_indexes= get_map_indexes(polygon->first_neighbor_index, polygon->neighbor_count);
	
	// Skip this step if neighbor indexes were not found
	if (!neighbor_indexes) return;

	for (i=0;i<polygon->neighbor_count;++i)
	{	
		
		polygon_data *neighboring_polygon= get_polygon_data(*neighbor_indexes++);
	
		if (POLYGON_IS_DETACHED(neighboring_polygon))
			continue;
	
		next_object= neighboring_polygon->first_object;

		while(next_object != NONE)
		{
			object= get_object_data(next_object);
			if (GET_OBJECT_OWNER(object)==_object_is_item && !OBJECT_IS_INVISIBLE(object)) 
			{
				if (guess_distance2d((world_point2d *) &player->location, (world_point2d *) &object->location)<=MAXIMUM_ARM_REACH)
				{
					world_distance radius, height;
					
					get_monster_dimensions(player->monster_index, &radius, &height);
	
					if (object->location.z >= player->location.z - MAXIMUM_ARM_REACH && object->location.z <= player->location.z + height &&
						test_item_retrieval(player_object->polygon, &player_object->location, &object->location))
					{
						if(get_item(player_index, next_object))
						{
							/* Start the search again.. */
							next_object= neighboring_polygon->first_object;
							continue;
						}
					}
				}
			}
			
			next_object= object->next_object;
		}
	
	}
}
示例#2
0
// Main routine
void RenderVisTreeClass::build_render_tree()
{
	assert(view);	// Idiot-proofing

	/* initialize the queue where we remember polygons we need to fire at */
	initialize_polygon_queue();

	/* initialize our node list to contain the root, etc. */
	initialize_render_tree();
	
	/* reset clipping buffers */
	initialize_clip_data();
	
	// LP change:
	// Adjusted for long-vector handling
	// Using start index of list of nodes: 0
	long_vector2d view_edge;
	
	short_to_long_2d( view->left_edge, view_edge );
	cast_render_ray( &view_edge, NONE, &Nodes.front(), _counterclockwise_bias );
	
	short_to_long_2d( view->right_edge, view_edge );
	cast_render_ray( &view_edge, NONE, &Nodes.front(), _clockwise_bias );
	
	/* 
		pull polygons off the queue, fire at all their new endpoints, building the tree as we go 
	*/
	while (polygon_queue_size)
	{
		auto polygon_index 	= PolygonQueue[ --polygon_queue_size ];
		polygon_data *polygon 	= get_polygon_data(polygon_index);
		
		assert( !POLYGON_IS_DETACHED(polygon) );
		
		const ix vertex_count = polygon->vertex_count;
		for( ix vertex_index = 0; vertex_index < vertex_count; ++vertex_index )
		{
			const auto endpoint_index	= polygon->endpoint_indexes[vertex_index];
			endpoint_data *endpoint		= get_endpoint_data(endpoint_index);
			
			if (TEST_RENDER_FLAG(endpoint_index, _endpoint_has_been_visited))
				continue;
			// LP change: move toward correct handling of long distances
			long_vector2d _vector;
			
			/* transform all visited endpoints */
			endpoint->transformed = endpoint->vertex;
			transform_overflow_point2d( &endpoint->transformed, 
						(world_point2d *) &view->origin, 
						view->yaw, 
						&endpoint->flags );
						
			/* calculate an outbound vector to this endpoint */
			// LP: changed to do long distance correctly.	
			_vector.i 	= int32( endpoint->vertex.x ) - int32( view->origin.x );
			_vector.j	= int32( endpoint->vertex.y ) - int32( view->origin.y );
			
			// LP change: compose a true transformed point to replace endpoint->transformed,
			// and use it in the upcoming code
			long_vector2d transformed_endpoint;
			overflow_short_to_long_2d( 	endpoint->transformed, 
							endpoint->flags, 
							transformed_endpoint );
			if (transformed_endpoint.i > 0)
			{
				const int32 x = view->half_screen_width + 
				( transformed_endpoint.j * view->world_to_screen_x ) / transformed_endpoint.i;
				
				endpoint_x_coordinates[ endpoint_index ] = 
					static_cast< int16 >( PIN(x, INT16_MIN, INT16_MAX) );
					
				SET_RENDER_FLAG(endpoint_index, _endpoint_has_been_transformed);
			}
			
			/* 
				do two cross products to determine whether this endpoint is in our view cone or not
				(we don't have to cast at points outside the cone) 
			*/
			const auto ri = view->right_edge.i;
			const auto rj = view->right_edge.j;
			const int32 crossprod_right = ( ri * _vector.j ) - ( rj * _vector.i );
			
			const auto li = view->left_edge.i;
			const auto lj = view->left_edge.j;
			const int32 crossprod_left = ( li * _vector.j ) - ( lj * _vector.i );
			
			if( crossprod_right <= 0 && crossprod_left >= 0 )
			{
				//it's in our view, cast at it
				int16 endpoint_;
				
				if( ENDPOINT_IS_TRANSPARENT(endpoint) )
					endpoint_ = NONE;
				else
					endpoint_ = endpoint_index;
					
				cast_render_ray(&_vector, endpoint_, &Nodes.front(), _no_bias);
			}
			SET_RENDER_FLAG(endpoint_index, _endpoint_has_been_visited);
		
		}
	}
}
示例#3
0
static void a1_swipe_nearby_items(short player_index)
{
	object_data *object;
	object_data *player_object;
	player_data *player = get_player_data(player_index);
	short next_object;
	polygon_data *polygon;
	short *neighbor_indexes;
	short i;

	player_object = get_object_data(get_monster_data(player->monster_index)->object_index);

	polygon= get_polygon_data(player_object->polygon);
	neighbor_indexes= get_map_indexes(polygon->first_neighbor_index, polygon->neighbor_count);
	
	// Skip this step if neighbor indexes were not found
	if (!neighbor_indexes) return;

	for (i=0;i<polygon->neighbor_count;++i)
	{	
		
		struct polygon_data *neighboring_polygon= get_polygon_data(*neighbor_indexes++);
		
		/*
			LP change: since precalculate_map_indexes() and its associated routine
			intersecting_flood_proc() appear to have some bugs in them, I will
			instead search the neighbors of each indexed polygon.
			
			Starting the search from -1 is a kludge designed to include a search
			for the current polygon.
		*/
		polygon_data *source_polygon = neighboring_polygon;
		for (int ngbr_indx = -1; ngbr_indx<source_polygon->vertex_count; ngbr_indx++)
		{
		if (ngbr_indx >= 0)
		{
			// Be sure to check on whether there is a valid polygon on the other side
			auto adjacent_index = source_polygon->adjacent_polygon_indexes[ngbr_indx];
			if (adjacent_index == NONE) continue;
			neighboring_polygon = get_polygon_data(adjacent_index);
		}
		else
			neighboring_polygon = source_polygon;
		
		if (!POLYGON_IS_DETACHED(neighboring_polygon))
		{
			next_object= neighboring_polygon->first_object;

			while(next_object != NONE)
			{
				object= get_object_data(next_object);
				if (GET_OBJECT_OWNER(object)==_object_is_item && !OBJECT_IS_INVISIBLE(object)) 
				{
					if (guess_distance2d((world_point2d *) &player->location, (world_point2d *) &object->location)<=MAXIMUM_ARM_REACH)
					{
						world_distance radius, height;
						
						get_monster_dimensions(player->monster_index, &radius, &height);
		
						if (object->location.z >= player->location.z - MAXIMUM_ARM_REACH && object->location.z <= player->location.z + height &&
							test_item_retrieval(player_object->polygon, &player_object->location, &object->location))
						{
							if(get_item(player_index, next_object))
							{
								/* Start the search again.. */
								next_object= neighboring_polygon->first_object;
								continue;
							}
						}
					}
				}
				
				next_object= object->next_object;
			}
		}
		// LP addition: end of that kludgy search loop
		}
	}
}
示例#4
0
文件: flood_map.c 项目: DrItanium/moo
/* returns next polygon index or NONE if there are no more polygons left cheaper than maximum_cost */
short flood_map(
	short first_polygon_index,
	long maximum_cost,
	cost_proc_ptr cost_proc,
	short flood_mode,
	void *caller_data)
{
	short lowest_cost_node_index, node_index;
	struct node_data *node;
	short polygon_index;
	long lowest_cost;

	/* initialize ourselves if first_polygon_index!=NONE */
	if (first_polygon_index!=NONE)
	{
		/* clear the visited polygon array */
		memset(visited_polygons, NONE, sizeof(short)*MAXIMUM_POLYGONS_PER_MAP);
		
		node_count= 0;
		last_node_index_expanded= NONE;
		add_node(NONE, first_polygon_index, 0, 0, (flood_mode==_flagged_breadth_first) ? *((long*)caller_data) : 0);
	}
	
	switch (flood_mode)
	{
		case _best_first:
			/* find the unexpanded node with the lowest cost */
			lowest_cost= maximum_cost, lowest_cost_node_index= NONE;
			for (node= nodes, node_index= 0; node_index<node_count; ++node_index, ++node)
			{
				if (NODE_IS_UNEXPANDED(node)&&node->cost<lowest_cost)
				{
					lowest_cost_node_index= node_index;
					lowest_cost= node->cost;
				}
			}
			break;
		
		case _breadth_first:
		case _flagged_breadth_first:
			/* find the next unexpanded node in the list under maximum_cost */
			node_index= (last_node_index_expanded==NONE) ? 0 : (last_node_index_expanded+1);
			for (node= nodes+node_index; node_index<node_count; ++node_index, ++node)
			{
				if (node->cost<maximum_cost) break;
			}
			if (node_index==node_count)
			{
				lowest_cost_node_index= NONE;
				lowest_cost= maximum_cost;
			}
			else
			{
				lowest_cost_node_index= node_index;
				lowest_cost= node->cost;
			}
			break;
		
		case _depth_first:
			/* implementation left to the caller (c.f., zen() in fareast.c) */
			halt();
			
		default:
			halt();
	}

	/* if we found a node, mark it as expanded and add itÕs adjacent non-solid polygons to the search tree */
	if (lowest_cost_node_index!=NONE)
	{
		struct polygon_data *polygon;
		short i;
		
		/* for flood_depth() and reverse_flood_map(), remember which node we successfully expanded last */
		last_node_index_expanded= lowest_cost_node_index;

		/* get pointer to lowest cost node */
		assert(lowest_cost_node_index>=0&&lowest_cost_node_index<node_count);
		node= nodes+lowest_cost_node_index;

		polygon= get_polygon_data(node->polygon_index);
		assert(!POLYGON_IS_DETACHED(polygon));

		/* mark node as expanded */
		MARK_NODE_AS_EXPANDED(node);

		for (i= 0; i<polygon->vertex_count; ++i)		
		{
			short destination_polygon_index= polygon->adjacent_polygon_indexes[i];
			
			if (destination_polygon_index!=NONE &&
				(maximum_cost!=LONG_MAX || visited_polygons[destination_polygon_index]==UNVISITED))
			{
				long new_user_flags= node->user_flags;
				long cost= cost_proc ? cost_proc(node->polygon_index, polygon->line_indexes[i], destination_polygon_index, (flood_mode==_flagged_breadth_first) ? &new_user_flags : caller_data) : polygon->area;
				
				/* polygons with zero or negative costs are not added to the node list */
				if (cost>0) add_node(lowest_cost_node_index, destination_polygon_index, node->depth+1, lowest_cost+cost, new_user_flags);
			}
		}
		
		polygon_index= node->polygon_index;
		if (flood_mode==_flagged_breadth_first) *((long*)caller_data)= node->user_flags;
	}
	else
	{
		polygon_index= NONE;
	}
	
	return polygon_index;
}