void prevent_spawning_collision(object *new_obj)
{
	int collided;
	ship_obj *moveup;
	object *hit_check;
	ship *s_check;

	do {
		collided = 0;

		for (moveup = GET_FIRST(&Ship_obj_list); moveup != END_OF_LIST(&Ship_obj_list); moveup = GET_NEXT(moveup))
		{
			// don't check the new object itself!!
			if (moveup->objnum == OBJ_INDEX(new_obj))
				continue;

			hit_check = &Objects[moveup->objnum];

			Assert(hit_check->type == OBJ_SHIP);
			Assert(hit_check->instance >= 0);
			if ((hit_check->type != OBJ_SHIP) || (hit_check->instance < 0))
				continue;

			s_check = &Ships[hit_check->instance];
							
			// just to make sure we don't get any strange magnitude errors
			if (vm_vec_same(&hit_check->pos, &new_obj->pos))
				new_obj->pos.xyz.x += 1.0f;
							
			polymodel *pm = model_get(Ship_info[s_check->ship_info_index].model_num);
			WITHIN_BBOX();				
			if (collided)
			{
				MOVE_AWAY_BBOX();
				break;
			}
		}
	} while (collided);
}
Example #2
0
void multi_respawn_place(object *new_obj, int team)
{
	ship_obj *moveup;
	ship *s_check;
	ship *pri = NULL;
	object *pri_obj = NULL;
	object *hit_check;
	int collided, idx, lookup;

	// first determine if there are any appropriate priority ships to use
	pri = NULL;
	pri_obj = NULL;
	for(idx=0; idx<Multi_respawn_priority_count; idx++){
		// all relevant ships
		if((Multi_respawn_priority_ships[idx].team == team) || !(Netgame.type_flags & NG_TYPE_TEAM)){

			lookup = ship_name_lookup(Multi_respawn_priority_ships[idx].ship_name);
			if( (lookup >= 0) && ((pri == NULL) || (Ships[lookup].respawn_priority > pri->respawn_priority)) && (Ships[lookup].objnum >= 0) && (Ships[lookup].objnum < MAX_OBJECTS)){
				pri = &Ships[lookup];
				pri_obj = &Objects[Ships[lookup].objnum];
			}
		}
	}
	
	// if we have a relevant respawn ship
	if((pri != NULL) && (pri_obj != NULL)){
		// pick a point just outside his bounding box
		polymodel *pm = model_get(pri->modelnum); 

		// hmm, ugly. Pick a point 2000 meters to the y direction
		if(pm == NULL){			
			vm_vec_scale_add(&new_obj->pos, &pri_obj->pos, &pri_obj->orient.v.rvec, 2000.0f);
		} else {
			// pick a random direction
			int d = (int)frand_range(0.0f, 5.9f);
			switch(d){
			case 0:
				vm_vec_scale_add(&new_obj->pos, &pri_obj->pos, &pri_obj->orient.v.rvec, (pm->maxs.xyz.x - pm->mins.xyz.x)); 
				break;

			case 1:
				vm_vec_scale_add(&new_obj->pos, &pri_obj->pos, &pri_obj->orient.v.rvec, -(pm->maxs.xyz.x - pm->mins.xyz.x));
				break;

			case 2:
				vm_vec_scale_add(&new_obj->pos, &pri_obj->pos, &pri_obj->orient.v.uvec, (pm->maxs.xyz.y - pm->mins.xyz.y)); 
				break;

			case 3:
				vm_vec_scale_add(&new_obj->pos, &pri_obj->pos, &pri_obj->orient.v.uvec, -(pm->maxs.xyz.y - pm->mins.xyz.y)); 
				break;

			case 4:
				vm_vec_scale_add(&new_obj->pos, &pri_obj->pos, &pri_obj->orient.v.fvec, (pm->maxs.xyz.z - pm->mins.xyz.z)); 
				break;

			case 5:
				vm_vec_scale_add(&new_obj->pos, &pri_obj->pos, &pri_obj->orient.v.fvec, -(pm->maxs.xyz.z - pm->mins.xyz.z)); 
				break;

			default:
				vm_vec_scale_add(&new_obj->pos, &pri_obj->pos, &pri_obj->orient.v.uvec, -(pm->maxs.xyz.y - pm->mins.xyz.y)); 
				break;
			}
		}
	}
	// otherwise, resort to plain respawn points
	else {
		Assert(Multi_respawn_point_count > 0);
		
		// get the next appropriate respawn point by team
		lookup = 0;		
		int count = 0;
		while(!lookup && (count < 13)){
			if((team == TEAM_TRAITOR) || (team == Multi_respawn_points[Multi_next_respawn_point].team)){
				lookup = 1;
			}			

			// next item
			if(!lookup){
				if(Multi_next_respawn_point >= (Multi_respawn_point_count-1)){
					Multi_next_respawn_point = 0;
				} else {
					Multi_next_respawn_point++;
				}				
			}

			count++;
		}

		// set respawn info
		new_obj->pos = Multi_respawn_points[Multi_next_respawn_point].pos;		
	}

	// now make sure we're not colliding with anyone		
	do {
		collided = 0;
		moveup = GET_FIRST(&Ship_obj_list);
		while(moveup!=END_OF_LIST(&Ship_obj_list)){
			// don't check the new_obj itself!!
			if(Objects[moveup->objnum].net_signature != new_obj->net_signature){
				hit_check = &Objects[moveup->objnum];
				Assert(hit_check->type == OBJ_SHIP);
				Assert(hit_check->instance >= 0);
				if((hit_check->type != OBJ_SHIP) || (hit_check->instance < 0)){
					continue;
				}
				s_check = &Ships[hit_check->instance];
				
				// just to make sure we don't get any strange magnitude errors
				if(vm_vec_same(&hit_check->pos, &new_obj->pos)){
					new_obj->pos.xyz.x += 1.0f;
				}
				
				WITHIN_BBOX();				
				if(collided){						
					MOVE_AWAY_BBOX();
					break;
				} 
				collided = 0;
			}
			moveup = GET_NEXT(moveup);
		}
	} while(collided);   		
}