Exemplo n.º 1
0
void batch_reset()
{
	geometry_map.clear();
	distortion_map.clear();
}
Exemplo n.º 2
0
// ********************************************************************************************
// Engages autopilot
// This does:
//        * Control switched from player to AI
//        * Time compression to 32x
//        * Lock time compression -WMC
//        * Tell AI to fly to targeted Nav Point (for all nav-status wings/ships)
//		  * Sets max waypoint speed to the best-speed of the slowest ship tagged
bool StartAutopilot()
{
	// Check for support ship and dismiss it if it is not doing anything.
	// If the support ship is doing something then tell the user such.
	for ( object *objp = GET_FIRST(&obj_used_list); objp !=END_OF_LIST(&obj_used_list); objp = GET_NEXT(objp) )
	{
		if ((objp->type == OBJ_SHIP) && !(objp->flags & OF_SHOULD_BE_DEAD))
		{
			Assertion((objp->instance >= 0) && (objp->instance < MAX_SHIPS),
				"objp does not have a valid pointer to a ship. Pointer is %d, which is smaller than 0 or bigger than %d",
				objp->instance, MAX_SHIPS);
			ship *shipp = &Ships[objp->instance];

			if (shipp->team != Player_ship->team)
				continue;

			Assertion((shipp->ship_info_index >= 0) && (shipp->ship_info_index < MAX_SHIP_CLASSES),
				"Ship '%s' does not have a valid pointer to a ship class. Pointer is %d, which is smaller than 0 or bigger than %d",
				shipp->ship_name, shipp->ship_info_index, MAX_SHIP_CLASSES);
			ship_info *sip = &Ship_info[shipp->ship_info_index];

			if ( !(sip->flags & SIF_SUPPORT) )
				continue;

			// don't deal with dying or departing support ships
			if ( shipp->flags & (SF_DYING | SF_DEPARTING) )
				continue;

			Assert(shipp->ai_index != -1);
			ai_info* support_ship_aip = &(Ai_info[Ships[objp->instance].ai_index]);

			// is support ship trying to rearm-repair
			if ( ai_find_goal_index( support_ship_aip->goals, AI_GOAL_REARM_REPAIR ) == -1 ) {
				// no, so tell it to depart
				ai_add_ship_goal_player( AIG_TYPE_PLAYER_SHIP, AI_GOAL_WARP, -1, NULL, support_ship_aip );
			} else {
				// yes
				send_autopilot_msgID(NP_MSG_FAIL_SUPPORT_WORKING);
				return false;
			}
		}
	}
	if (!CanAutopilot())
		return false;

	AutoPilotEngaged = true;

	// find the ship that is "leading" all of the ships when the player starts
	// autopilot
	// by default the ship that is leading the autopilot session the player's
	// wing leader (if the player is the wing leader then it will be the
	// player).
	// TODO:implement a way to allow a FREDer to say a different ship is leader
	Autopilot_flight_leader = get_wing_leader(Player_ship->wingnum);
	if ( Autopilot_flight_leader == NULL ) {
		// force player to be the leader if he doesn't have a wing
		Autopilot_flight_leader = Player_obj;
	}

	if (The_mission.flags & MISSION_FLAG_USE_AP_CINEMATICS)
		LockAPConv = timestamp(); // lock convergence instantly
	else
		LockAPConv = timestamp(3000); // 3 seconds before we lock convergence
	Player_use_ai = 1;
	set_time_compression(1);
	lock_time_compression(true);

	// determine speed cap
	int i,j, wcount=1, tc_factor=1;
	float speed_cap = 1000000.0; // 1m is a safe starting point
	float radius = Player_obj->radius, distance = 0.0f, ftemp;
	bool capshipPresent = false;
	int capship_counts[3]; // three size classes
	capship_counts[0] = 0;
	capship_counts[1] = 0;
	capship_counts[2] = 0;

	int capship_placed[3]; // three size classes
	capship_placed[0] = 0;
	capship_placed[1] = 0;
	capship_placed[2] = 0;

	float capship_spreads[3];
	capship_spreads[0] = 0.0f;
	capship_spreads[1] = 0.0f;
	capship_spreads[2] = 0.0f;

	SCP_vector<int> capIndexes;

	// empty the autopilot wings map
	autopilot_wings.clear();

	// vars for usage w/ cinematic
	vec3d pos, norm1, perp, tpos, rpos = Player_obj->pos, zero;
	memset(&zero, 0, sizeof(vec3d));


	// instantly turn player toward tpos
	if (The_mission.flags & MISSION_FLAG_USE_AP_CINEMATICS)
	{
		vm_vec_sub(&norm1, Navs[CurrentNav].GetPosition(), &Player_obj->pos);
		vm_vector_2_matrix(&Player_obj->orient, &norm1, NULL, NULL);
	}

	for (i = 0; i < MAX_SHIPS; i++)
	{
		if (Ships[i].objnum != -1 && 
				(Ships[i].flags2 & SF2_NAVPOINT_CARRY || 
					(Ships[i].wingnum != -1 && Wings[Ships[i].wingnum].flags & WF_NAV_CARRY)
				)
			)
		{
			if (speed_cap > vm_vec_mag(&Ship_info[Ships[i].ship_info_index].max_vel))
				speed_cap = vm_vec_mag(&Ship_info[Ships[i].ship_info_index].max_vel);
		}
	}

	// damp speed_cap to 90% of actual -- to make sure ships stay in formation
	if (The_mission.flags & MISSION_FLAG_USE_AP_CINEMATICS)
		speed_cap = 0.90f * speed_cap;

	if ( speed_cap < 1.0f ) {
		/* We need to deal with this so that incorrectly flagged ships will not
		cause the engine to fail to limit all the ships speeds correctly. */
		Warning(LOCATION, "Ship speed cap is way too small (%f)!\n"
			"This is normally caused by a ship that has nav-carry-status set, but cannot move itself (like a Cargo container).\n"
			"Speed cap has been set to 1.0 m/s.",
			speed_cap);
		speed_cap = 1.0f;
	}

	ramp_bias = speed_cap/50.0f;

	// assign ship goals
	// when assigning goals to individual ships only do so if Ships[shipnum].wingnum != -1 
	// we will assign wing goals below

	for (i = 0; i < MAX_SHIPS; i++)
	{
		if (Ships[i].objnum != -1 && 
				(Ships[i].flags2 & SF2_NAVPOINT_CARRY || 
					(Ships[i].wingnum != -1 && Wings[Ships[i].wingnum].flags & WF_NAV_CARRY)
				)
			)
		{
			// do we have capital ships in the area?
			if (Ship_info[Ships[i].ship_info_index].flags 
				& ( SIF_CRUISER | SIF_CAPITAL | SIF_SUPERCAP | SIF_CORVETTE | SIF_AWACS | SIF_GAS_MINER | SIF_FREIGHTER | SIF_TRANSPORT))
			{
				capshipPresent = true;

				capIndexes.push_back(i);
				// ok.. what size class

				if (Ship_info[Ships[i].ship_info_index].flags & (SIF_CAPITAL | SIF_SUPERCAP))
				{
					capship_counts[0]++;
					if (capship_spreads[0] < Objects[Ships[i].objnum].radius)
						capship_spreads[0] = Objects[Ships[i].objnum].radius;
				}
				else if (Ship_info[Ships[i].ship_info_index].flags & (SIF_CORVETTE))
				{
					capship_counts[1]++;
					if (capship_spreads[1] < Objects[Ships[i].objnum].radius)
						capship_spreads[1] = Objects[Ships[i].objnum].radius;
				}
				else
				{
					capship_counts[2]++;
					if (capship_spreads[2] < Objects[Ships[i].objnum].radius)
						capship_spreads[2] = Objects[Ships[i].objnum].radius;
				}
			}



			// check for bigger radius for usage later
			/*if (!vm_vec_cmp(&rpos, &Player_obj->pos)) 
				// want to make sure rpos isn't player pos - we can worry about it being largest object's later
			{
				rpos = Objects[Ships[i].objnum].pos;
			}*/

			if (Objects[Ships[i].objnum].radius > radius)
			{
				rpos = Objects[Ships[i].objnum].pos;
				radius = Objects[Ships[i].objnum].radius;
			}

			if (The_mission.flags & MISSION_FLAG_USE_AP_CINEMATICS)
			{// instantly turn the ship to match the direction player is looking
				//vm_vec_sub(&norm1, Navs[CurrentNav].GetPosition(), &Player_obj->pos);
				vm_vector_2_matrix(&Objects[Ships[i].objnum].orient, &norm1, NULL, NULL);
			}

			// snap wings into formation
			if (The_mission.flags & MISSION_FLAG_USE_AP_CINEMATICS &&  // only if using cinematics 
				(Ships[i].wingnum != -1 && Wings[Ships[i].wingnum].flags & WF_NAV_CARRY) // only if in a wing
				&& Autopilot_flight_leader != &Objects[Ships[i].objnum]) //only if not flight leader's object
			{	
				ai_info	*aip = &Ai_info[Ships[i].ai_index];
				int wingnum = aip->wing, wing_index = get_wing_index(&Objects[Ships[i].objnum], wingnum);
				vec3d goal_point;
				object *leader_objp = get_wing_leader(wingnum);
				
				if (leader_objp != &Objects[Ships[i].objnum])
				{
					// not leader.. get our position relative to leader
					get_absolute_wing_pos_autopilot(&goal_point, leader_objp, wing_index, aip->ai_flags & AIF_FORMATION_OBJECT);
				}
				else
				{
					ai_clear_wing_goals(wingnum);
					j = 1+int( (float)floor(double(wcount-1)/2.0) );
					switch (wcount % 2)
					{
						case 1: // back-left
							vm_vec_add(&perp, &zero, &Autopilot_flight_leader->orient.vec.rvec);
							//vm_vec_sub(&perp, &perp, &Player_obj->orient.vec.fvec);
							vm_vec_normalize(&perp);
							vm_vec_scale(&perp, -166.0f*j); // 166m is supposedly the optimal range according to tolwyn
							vm_vec_add(&goal_point, &Autopilot_flight_leader->pos, &perp);
							break;

						default: //back-right
						case 0:
							vm_vec_add(&perp, &zero, &Autopilot_flight_leader->orient.vec.rvec);
							//vm_vec_sub(&perp, &perp, &Player_obj->orient.vec.fvec);
							vm_vec_normalize(&perp);
							vm_vec_scale(&perp, 166.0f*j);
							vm_vec_add(&goal_point, &Autopilot_flight_leader->pos, &perp);
							break;
					}
					autopilot_wings[wingnum] = wcount;
					wcount++;
				}
				Objects[Ships[i].objnum].pos = goal_point;			
				if (vm_vec_dist_quick(&Autopilot_flight_leader->pos, &Objects[Ships[i].objnum].pos) > distance)
				{
					distance = vm_vec_dist_quick(&Autopilot_flight_leader->pos, &Objects[Ships[i].objnum].pos);
				}
			}
			// lock primary and secondary weapons
			if ( LockWeaponsDuringAutopilot )
				Ships[i].flags2 |= (SF2_PRIMARIES_LOCKED | SF2_SECONDARIES_LOCKED);

			// clear the ship goals and cap the waypoint speed
			ai_clear_ship_goals(&Ai_info[Ships[i].ai_index]);
			Ai_info[Ships[i].ai_index].waypoint_speed_cap = (int)speed_cap;

			
			// if they're not part of a wing set their goal
			if (Ships[i].wingnum == -1 || The_mission.flags & MISSION_FLAG_USE_AP_CINEMATICS)
			{ 
				if (Navs[CurrentNav].flags & NP_WAYPOINT)
				{
					ai_add_ship_goal_player( AIG_TYPE_PLAYER_SHIP, AI_GOAL_WAYPOINTS_ONCE, 0, ((waypoint_list*)Navs[CurrentNav].target_obj)->get_name(), &Ai_info[Ships[i].ai_index] );
					//fixup has to wait until after wing goals
				}
				else
				{
					ai_add_ship_goal_player( AIG_TYPE_PLAYER_SHIP, AI_GOAL_FLY_TO_SHIP, 0, ((ship*)Navs[CurrentNav].target_obj)->ship_name, &Ai_info[Ships[i].ai_index] );
				}

			}
		}
	}

	// assign wing goals
	if (!(The_mission.flags & MISSION_FLAG_USE_AP_CINEMATICS))
	{
		for (i = 0; i < MAX_WINGS; i++)
		{
			if (Wings[i].flags & WF_NAV_CARRY )
			{	
				//ai_add_ship_goal_player( int type, int mode, int submode, char *shipname, ai_info *aip );

				//ai_add_wing_goal_player( AIG_TYPE_PLAYER_WING, AI_GOAL_STAY_NEAR_SHIP, 0, target_shipname, wingnum );
				//ai_add_wing_goal_player( AIG_TYPE_PLAYER_WING, AI_GOAL_WAYPOINTS_ONCE, 0, target_shipname, wingnum );
				//ai_clear_ship_goals( &(Ai_info[Ships[num].ai_index]) );
				
				ai_clear_wing_goals( i );
				if (Navs[CurrentNav].flags & NP_WAYPOINT)
				{
					
					ai_add_wing_goal_player( AIG_TYPE_PLAYER_WING, AI_GOAL_WAYPOINTS_ONCE, 0, ((waypoint_list*)Navs[CurrentNav].target_obj)->get_name(), i );

					// "fix up" the goal
					for (j = 0; j < MAX_AI_GOALS; j++)
					{
						if (Wings[i].ai_goals[j].ai_mode == AI_GOAL_WAYPOINTS_ONCE ||
							Wings[i].ai_goals[j].ai_mode == AIM_WAYPOINTS )
						{
							autopilot_ai_waypoint_goal_fixup(&(Wings[i].ai_goals[j]));
						}
					}
				}
				else
				{
					ai_add_wing_goal_player( AIG_TYPE_PLAYER_WING, AI_GOAL_FLY_TO_SHIP, 0, ((ship*)Navs[CurrentNav].target_obj)->ship_name, i );

				}
			}
		}
	}

	// fixup has to go down here because ships are assigned goals during wing goals as well
	for (i = 0; i < MAX_SHIPS; i++)
	{
		if (Ships[i].objnum != -1)
		{
			if (Ships[i].flags2 & SF2_NAVPOINT_CARRY || 
				(Ships[i].wingnum != -1 && Wings[Ships[i].wingnum].flags & WF_NAV_CARRY))
				for (j = 0; j < MAX_AI_GOALS; j++)
				{
					if (Ai_info[Ships[i].ai_index].goals[j].ai_mode == AI_GOAL_WAYPOINTS_ONCE ||
						Ai_info[Ships[i].ai_index].goals[j].ai_mode == AIM_WAYPOINTS)
					{
						autopilot_ai_waypoint_goal_fixup( &(Ai_info[Ships[i].ai_index].goals[j]) );

						
						// formation fixup
						//ai_form_on_wing(&Objects[Ships[i].objnum], &Objects[Player_ship->objnum]);
					}
				}
		}
	}
	start_dist = DistanceTo(CurrentNav);

	// ----------------------------- setup cinematic -----------------------------
	if (The_mission.flags & MISSION_FLAG_USE_AP_CINEMATICS)
	{	
		if (capshipPresent)
		{
			// position capships

			vec3d right, front, up, offset;
			for (SCP_vector<int>::iterator idx = capIndexes.begin(); idx != capIndexes.end(); ++idx)
			{
				vm_vec_add(&right, &Autopilot_flight_leader->orient.vec.rvec, &zero);
				vm_vec_add(&front, &Autopilot_flight_leader->orient.vec.fvec, &zero);
				vm_vec_add(&up, &Autopilot_flight_leader->orient.vec.uvec, &zero);
				vm_vec_add(&offset, &zero, &zero);
				if (Ship_info[Ships[*idx].ship_info_index].flags & (SIF_CAPITAL | SIF_SUPERCAP))
				{
					//0 - below - three lines of position

					// front/back to zero
					vm_vec_add(&front, &zero, &zero);

					// position below
					vm_vec_scale(&up, capship_spreads[0]); // scale the up vector by the radius of the largest ship in this formation part


					switch (capship_placed[0] % 3)
					{
						case 1: // right
							vm_vec_scale(&right, capship_spreads[0]);
							break;
							
						case 2: // left
							vm_vec_scale(&right, -capship_spreads[0]);
							break;

						default: // straight
						case 0:
							vm_vec_add(&right, &zero, &zero);
							vm_vec_scale(&up, 1.5); // add an extra half-radius
							break;
					}
		
					// scale by  row
					vm_vec_scale(&right, (1+((float)floor((float)capship_placed[0]/3)))); 
					vm_vec_scale(&up, -(1+((float)floor((float)capship_placed[0]/3))));

					capship_placed[0]++;
				}
				else if (Ship_info[Ships[*idx].ship_info_index].flags & SIF_CORVETTE)
				{
					//1 above - 3 lines of position
					// front/back to zero
					vm_vec_add(&front, &zero, &zero);

					// position below
					vm_vec_scale(&up, capship_spreads[1]); // scale the up vector by the radius of the largest ship in this formation part


					switch (capship_placed[1] % 3)
					{
						case 1: // right
							vm_vec_scale(&right, capship_spreads[1]); 
							break;
							
						case 2: // left
							vm_vec_scale(&right, -capship_spreads[1]); 
							break;

						default: // straight
						case 0:
							vm_vec_add(&right, &zero, &zero);
							vm_vec_scale(&up, 1.5); // add an extra half-radius
							break;
					}
		
					// scale by  row
					vm_vec_scale(&right, (1+((float)floor((float)capship_placed[1]/3)))); 
					vm_vec_scale(&up, (1+((float)floor((float)capship_placed[1]/3))));

					// move ourselves up and out of the way of the smaller ships
					vm_vec_add(&perp, &Autopilot_flight_leader->orient.vec.uvec, &zero);
					vm_vec_scale(&perp, capship_spreads[2]);
					vm_vec_add(&up, &up, &perp);

					capship_placed[1]++;
				}
				else
				{
					//2 either side - 6 lines of position (right (dir, front, back), left (dir, front, back) )
					// placing pattern: right, left, front right, front left, rear right, rear left

					// up/down to zero
					vm_vec_add(&up, &zero, &zero);


					switch (capship_placed[2] % 6)
					{
						case 5:  // rear left
							vm_vec_scale(&right, -capship_spreads[2]);
							vm_vec_scale(&front, -capship_spreads[2]); 
							break;

						case 4:  // rear right
							vm_vec_scale(&right, capship_spreads[2]); 
							vm_vec_scale(&front, -capship_spreads[2]); 
							break;

						case 3:  // front left
							vm_vec_scale(&right, -capship_spreads[2]); 
							vm_vec_scale(&front, capship_spreads[2]); 
							break;

						case 2:  // front right
							vm_vec_scale(&right, capship_spreads[2]); 
							vm_vec_scale(&front, capship_spreads[2]);
							break;

						case 1:  // straight left
							vm_vec_scale(&right, 1.5);
							vm_vec_scale(&right, -capship_spreads[2]);
							vm_vec_add(&front, &zero, &zero);
							break;

						default: // straight right
						case 0:
							vm_vec_scale(&right, 1.5);
							vm_vec_scale(&right, capship_spreads[2]);
							vm_vec_add(&front, &zero, &zero);
							break;
					}
					// these ships seem to pack a little too tightly
					vm_vec_scale(&right, 2*(1+((float)floor((float)capship_placed[2]/3)))); 
					vm_vec_scale(&front, 2*(1+((float)floor((float)capship_placed[2]/3))));

					// move "out" by 166*(wcount-1) so we don't bump into fighters
					vm_vec_add(&perp, &Autopilot_flight_leader->orient.vec.rvec, &zero);
					vm_vec_scale(&perp, 166.0f*float(wcount-1));
					if ( (capship_placed[2] % 2) == 0)
						vm_vec_add(&right, &right, &perp);
					else
						vm_vec_sub(&right, &right, &perp);

					capship_placed[2]++;
				}

				// integrate the up/down componant
				vm_vec_add(&offset, &offset, &up);

				//integrate the left/right componant
				vm_vec_add(&offset, &offset, &right);

				//integrate the left/right componant
				vm_vec_add(&offset, &offset, &front);

				// global scale the position by 50%
				//vm_vec_scale(&offset, 1.5);

				vm_vec_add(&Objects[Ships[*idx].objnum].pos, &Autopilot_flight_leader->pos, &offset);

				if (vm_vec_dist_quick(&Autopilot_flight_leader->pos, &Objects[Ships[*idx].objnum].pos) > distance)
				{
					distance = vm_vec_dist_quick(&Autopilot_flight_leader->pos, &Objects[Ships[*idx].objnum].pos);
				}
			}
		}

		ftemp = floor(Autopilot_flight_leader->phys_info.max_vel.xyz.z/speed_cap);
		if (ftemp >= 2.0f && ftemp < 4.0f)
			tc_factor = 2;
		else if (ftemp >= 4.0f && ftemp < 8.0f)
			tc_factor = 4;
		else if (ftemp >= 8.0f)
			tc_factor = 8;



		tpos = *Navs[CurrentNav].GetPosition();
		// determine distance toward nav at which camera will be
		vm_vec_sub(&pos, &tpos, &Autopilot_flight_leader->pos);
		vm_vec_normalize(&pos); // pos is now a unit vector in the direction we will be moving the camera
		//norm1 = pos;
		vm_vec_scale(&pos, 5*speed_cap*tc_factor); // pos is now scaled by 5 times the speed (5 seconds ahead)
		vm_vec_add(&pos, &pos, &Autopilot_flight_leader->pos); // pos is now 5*speed cap in front of player ship

		switch (myrand()%24) 
		// 8 different ways of getting perp points
		// 4 of which will not be used when capships are present (anything below, or straight above)
		{

			case 1: // down
			case 9:
			case 16:
				if (capship_placed[0] == 0)
					vm_vec_sub(&perp, &zero, &Autopilot_flight_leader->orient.vec.uvec);
				else
				{	// become up-left
					vm_vec_add(&perp, &zero, &Autopilot_flight_leader->orient.vec.uvec);
					vm_vec_sub(&perp, &perp, &Autopilot_flight_leader->orient.vec.rvec);
				}
				break;

			case 2: // up
			case 10:
			case 23:
				vm_vec_add(&perp, &perp, &Autopilot_flight_leader->orient.vec.uvec);
				if (capshipPresent) // become up-right
					vm_vec_add(&perp, &perp, &Autopilot_flight_leader->orient.vec.rvec);
				break;

			case 3: // left
			case 11:
			case 22:
				vm_vec_sub(&perp, &zero, &Autopilot_flight_leader->orient.vec.rvec);
				break;

			case 4: // up-left
			case 12:
			case 21:
				vm_vec_sub(&perp, &zero, &Autopilot_flight_leader->orient.vec.rvec);
				vm_vec_add(&perp, &perp, &Autopilot_flight_leader->orient.vec.uvec);
				break;

			case 5: // up-right
			case 13:
			case 20:
				vm_vec_add(&perp, &zero, &Autopilot_flight_leader->orient.vec.rvec);
				vm_vec_add(&perp, &perp, &Autopilot_flight_leader->orient.vec.uvec);
				break;

			case 6: // down-left
			case 14:
			case 19:
				vm_vec_sub(&perp, &zero, &Autopilot_flight_leader->orient.vec.rvec);
				if (capship_placed[0] < 2)
					vm_vec_sub(&perp, &perp, &Autopilot_flight_leader->orient.vec.uvec);
				else
					vm_vec_add(&perp, &perp, &Autopilot_flight_leader->orient.vec.uvec);
				break;

			case 7: // down-right
			case 15:
			case 18:
				vm_vec_add(&perp, &zero, &Autopilot_flight_leader->orient.vec.rvec);
				if (capship_placed[0] < 1)
					vm_vec_sub(&perp, &perp, &Autopilot_flight_leader->orient.vec.uvec);
				else
					vm_vec_add(&perp, &perp, &Autopilot_flight_leader->orient.vec.uvec);
				break;

			default:
			case 0: // right
			case 8:
			case 17:
				perp = Autopilot_flight_leader->orient.vec.rvec;
				break;

		}
		vm_vec_normalize(&perp);
		//vm_vec_scale(&perp, 2*radius+distance);

		vm_vec_scale(&perp,  Autopilot_flight_leader->radius+radius);

		// randomly scale up/down by up to 20%
		j = 20-myrand()%40; // [-20,20]

		vm_vec_scale(&perp, 1.0f+(float(j)/100.0f));
		vm_vec_add(&cameraPos, &pos, &perp);

		if (capshipPresent)
		{
			vm_vec_normalize(&perp);

			// place it behind
			//vm_vec_copy_scale(&norm1, &Player_obj->orient.vec.fvec, -2*(Player_obj->radius+radius*(1.0f+(float(j)/100.0f))));
			//vm_vec_add(&cameraTarget, &cameraTarget, &norm1);

			vm_vec_copy_scale(&cameraTarget,&perp, radius/5.0f);

			//vm_vec_scale(&cameraTarget, Player_obj->radius+radius*(1.0f+(float(j)/100.0f)));

			//vm_vec_add(&cameraTarget, &pos, &cameraTarget);
			//CameraSpeed = (radius+distance)/25;

			//vm_vec_add(&cameraTarget, &zero, &perp);
			//vm_vec_scale(&CameraVelocity, (radius+distance/100.f));
			//vm_vec_scale(&CameraVelocity, 1.0f/float(NPS_TICKRATE*tc_factor));
		}
		else
		{
			vm_vec_add(&cameraTarget, &zero, &zero);
			//CameraSpeed = 0;
		}
		//CameraMoving = false;


		EndAPCinematic = timestamp((10000*tc_factor)+NPS_TICKRATE); // 10 objective seconds before end of cinematic 
		MoveCamera = timestamp((5500*tc_factor)+NPS_TICKRATE);
		camMovingTime = int(4.5*float(tc_factor));
		set_time_compression((float)tc_factor);
	}

	return true;
}