示例#1
0
/**
 * Start the sequence of a piece of debris writhing in unholy agony!!!
 */
static void debris_start_death_roll(object *debris_obj, debris *debris_p)
{
	if (debris_p->is_hull)	{
		// tell everyone else to blow up the piece of debris
		if( MULTIPLAYER_MASTER )
			send_debris_update_packet(debris_obj,DEBRIS_UPDATE_NUKE);

		int fireball_type = fireball_ship_explosion_type(&Ship_info[debris_p->ship_info_index]);
		if(fireball_type < 0) {
			fireball_type = FIREBALL_EXPLOSION_LARGE1 + rand()%FIREBALL_NUM_LARGE_EXPLOSIONS;
		}
		fireball_create( &debris_obj->pos, fireball_type, FIREBALL_LARGE_EXPLOSION, OBJ_INDEX(debris_obj), debris_obj->radius*1.75f);

		// only play debris destroy sound if hull piece and it has been around for at least 2 seconds
		if ( Missiontime > debris_p->time_started + 2*F1_0 ) {
			snd_play_3d( gamesnd_get_game_sound(SND_MISSILE_IMPACT1), &debris_obj->pos, &View_position, debris_obj->radius );
			
		}
	}

    debris_obj->flags.set(Object::Object_Flags::Should_be_dead);
}
示例#2
0
// ----------------------------------------------------------------------------
// afterburners_start() will be called when a ship engages the afterburners.
// This function should only be called once when afterburners first start.  This is
// to start an appropriate sound effect and do any one-time initializations.
//
// parameters:   *objp        ==> pointer to the object starting afterburners
//          
void afterburners_start(object* objp)
{
	ship_info* sip;
	ship* shipp;
	float percent_left;

	Assert(objp != NULL);

	if (objp->type == OBJ_OBSERVER)
		return;

	Assert(objp->type == OBJ_SHIP);
	Assert(objp->instance >= 0 && objp->instance < MAX_SHIPS);

	shipp = &Ships[objp->instance];
	Assert(shipp->ship_info_index >= 0 && shipp->ship_info_index < Num_ship_classes);
	sip = &Ship_info[shipp->ship_info_index];

	// When the ship has no afterburner, leave without doing anything.
	// Caller should have tested ship equipment before deciding to start afterburners.
	if (!(sip->flags & SIF_AFTERBURNER))
	{
		nprintf(("Warning", "Ship type %s does not have afterburner capability\n", sip->name));
		return;
	}

	// bail if afterburners are locked
	if (shipp->flags2 & SF2_AFTERBURNER_LOCKED)
	{
		return;
	}

	if (objp->phys_info.flags & PF_GLIDING)
	{
		return;
	}

	if ((objp->flags & OF_PLAYER_SHIP) && (objp == Player_obj))
	{
		unsigned int now;
		now = timer_get_milliseconds();

		if ((now - Player_afterburner_start_time) < 1300)
		{
			if (Viewer_mode & VM_NOT_COCKPIT)
			{
				snd_play_3d(&Snds[SND_ABURN_FAIL], &objp->pos, &View_position, objp->radius);
			}
			else
			{
				snd_play(&Snds[SND_ABURN_FAIL]);
			}
			return;
		}

		if (objp->phys_info.flags & PF_AFTERBURNER_WAIT)
		{
			return;
		}
	}

	if (objp->phys_info.flags & PF_AFTERBURNER_ON)
	{
		return;		// afterburners are already engaged, nothing to do here
	}

	//boosters take precedence
	if (objp->phys_info.flags & PF_BOOSTER_ON)
		return;

	// Check if there is enough afterburner fuel
	if ((shipp->afterburner_fuel < MIN_AFTERBURNER_FUEL_TO_ENGAGE) && !MULTIPLAYER_CLIENT)
	{
		if (objp == Player_obj)
		{
			if (Viewer_mode & VM_NOT_COCKPIT)
			{
				snd_play_3d(&Snds[SND_ABURN_FAIL], &objp->pos, &View_position, objp->radius);
			}
			else
			{
				snd_play(&Snds[SND_ABURN_FAIL]);
			}
		}
		return;
	}

	objp->phys_info.flags |= PF_AFTERBURNER_ON;

	objp->phys_info.afterburner_decay = timestamp(ABURN_DECAY_TIME);

	percent_left = shipp->afterburner_fuel / sip->afterburner_fuel_capacity;

	//Do anim
	model_anim_start_type(shipp, TRIGGER_TYPE_AFTERBURNER, ANIMATION_SUBTYPE_ALL, 1);

	if (objp == Player_obj)
	{
		Player_afterburner_start_time = timer_get_milliseconds();
		Player_disengage_timer = 1;
		Player_afterburner_vol = Snds[SND_ABURN_LOOP].default_volume;
		snd_set_volume(Player_afterburner_loop_id, Player_afterburner_vol);

		if (percent_left > AFTERBURNER_PERCENT_FOR_LOOP_SND)
		{
			Player_afterburner_loop_delay = timestamp(AFTERBURNER_LOOP_DELAY);
		}
		else
		{
			Player_afterburner_loop_delay = 0;
		}

		if (Viewer_mode & VM_NOT_COCKPIT)
		{
			snd_play_3d(&Snds[SND_ABURN_ENGAGE], &objp->pos, &View_position, objp->radius);
		}
		else
		{
			snd_play(&Snds[SND_ABURN_ENGAGE], 0.0f, 1.0f, SND_PRIORITY_MUST_PLAY);
		}

		joy_ff_afterburn_on();
	}
	else
	{
		snd_play_3d(&Snds[SND_ABURN_ENGAGE], &objp->pos, &View_position, objp->radius);
	}

	objp->phys_info.flags |= PF_AFTERBURNER_WAIT;
}
示例#3
0
/**
 * Do various updates to debris:  check if time to die, start fireballs
 * Maybe delete debris if it's very far away from player.
 *
 * @param obj			pointer to debris object
 * @param frame_time	time elapsed since last debris_move() called
 */
void debris_process_post(object * obj, float frame_time)
{
	int i, num;
	num = obj->instance;

	int objnum = OBJ_INDEX(obj);
	Assert( Debris[num].objnum == objnum );
	debris *db = &Debris[num];

	if ( db->is_hull ) {
		MONITOR_INC(NumHullDebris,1);
		radar_plot_object( obj );

		if ( timestamp_elapsed(db->sound_delay) ) {
			obj_snd_assign(objnum, SND_DEBRIS, &vmd_zero_vector, 0);
			db->sound_delay = 0;
		}
	} else {
		MONITOR_INC(NumSmallDebris,1);
	}

	if ( db->lifeleft >= 0.0f) {
		db->lifeleft -= frame_time;
		if ( db->lifeleft < 0.0f )	{
			debris_start_death_roll(obj, db);
		}
	}

	maybe_delete_debris(db);	//	Make this debris go away if it's very far away.

	// ================== DO THE ELECTRIC ARCING STUFF =====================
	if ( db->arc_frequency <= 0 )	{
		return;			// If arc_frequency <= 0, this piece has no arcs on it
	}

	if ( !timestamp_elapsed(db->fire_timeout) && timestamp_elapsed(db->next_fireball))	{		

		db->next_fireball = timestamp_rand(db->arc_frequency,db->arc_frequency*2 );
		db->arc_frequency += 100;	

		if (db->is_hull)	{

			int n, n_arcs = ((rand()>>5) % 3)+1;		// Create 1-3 sparks

			vec3d v1, v2, v3, v4;

			if ( Cmdline_old_collision_sys ) {
				submodel_get_two_random_points( db->model_num, db->submodel_num, &v1, &v2 );
				submodel_get_two_random_points( db->model_num, db->submodel_num, &v3, &v4 );
			} else {
				submodel_get_two_random_points_better( db->model_num, db->submodel_num, &v1, &v2 );
				submodel_get_two_random_points_better( db->model_num, db->submodel_num, &v3, &v4 );
			}

			n = 0;

			int a = 100, b = 1000;
			int lifetime = (myrand()%((b)-(a)+1))+(a);

			// Create the spark effects
			for (i=0; i<MAX_DEBRIS_ARCS; i++ )	{
				if ( !timestamp_valid( db->arc_timestamp[i] ) )	{

					db->arc_timestamp[i] = timestamp(lifetime);	// live up to a second

					switch( n )	{
					case 0:
						db->arc_pts[i][0] = v1;
						db->arc_pts[i][1] = v2;
						break;
					case 1:
						db->arc_pts[i][0] = v2;
						db->arc_pts[i][1] = v3;
						break;

					case 2:
						db->arc_pts[i][0] = v2;
						db->arc_pts[i][1] = v4;
						break;

					default:
						Int3();
					}
						
					n++;
					if ( n == n_arcs )
						break;	// Don't need to create anymore
				}
			}

	
			// rotate v2 out of local coordinates into world.
			// Use v2 since it is used in every bolt.  See above switch().
			vec3d snd_pos;
			vm_vec_unrotate(&snd_pos, &v2, &obj->orient);
			vm_vec_add2(&snd_pos, &obj->pos );

			//Play a sound effect
			if ( lifetime > 750 )	{
				// 1.00 second effect
				snd_play_3d( gamesnd_get_game_sound(SND_DEBRIS_ARC_05), &snd_pos, &View_position, obj->radius );
			} else if ( lifetime >  500 )	{
				// 0.75 second effect
				snd_play_3d( gamesnd_get_game_sound(SND_DEBRIS_ARC_04), &snd_pos, &View_position, obj->radius );
			} else if ( lifetime >  250 )	{
				// 0.50 second effect
				snd_play_3d( gamesnd_get_game_sound(SND_DEBRIS_ARC_03), &snd_pos, &View_position, obj->radius );
			} else if ( lifetime >  100 )	{
				// 0.25 second effect
				snd_play_3d( gamesnd_get_game_sound(SND_DEBRIS_ARC_02), &snd_pos, &View_position, obj->radius );
			} else {
				// 0.10 second effect
				snd_play_3d( gamesnd_get_game_sound(SND_DEBRIS_ARC_01), &snd_pos, &View_position, obj->radius );
			}
		}
/**
 * Called when a ship engages the afterburners.
 * This function should only be called once when afterburners first start.  This is
 * to start an appropriate sound effect and do any one-time initializations.
 *
 * @param *objp pointer to the object starting afterburners
 */          
void afterburners_start(object *objp)
{
	ship_info	*sip;
	ship			*shipp;
	float			percent_left;

	Assert( objp != NULL );

	if(objp->type == OBJ_OBSERVER)
		return;

	Assert( objp->type == OBJ_SHIP);
	Assert( objp->instance >= 0 && objp->instance < MAX_SHIPS );

	shipp = &Ships[objp->instance];
	Assert( shipp->ship_info_index >= 0 && shipp->ship_info_index < static_cast<int>(Ship_info.size()) );
	sip = &Ship_info[shipp->ship_info_index];
	
	// bail if afterburners are locked
	if (shipp->flags[Ship::Ship_Flags::Afterburner_locked])	{
		return;
	}

	if ( (objp->flags[Object::Object_Flags::Player_ship]) && (objp == Player_obj) ) {
		unsigned int now;
		now = timer_get_milliseconds();

		if ( (now - Player_afterburner_start_time) < 1300 ) {
			snd_play( gamesnd_get_game_sound(ship_get_sound(objp, GameSounds::ABURN_FAIL)) );
			return;
		}

		if ( objp->phys_info.flags & PF_AFTERBURNER_WAIT ){
			return;
		}
	}

	if ( objp->phys_info.flags & PF_AFTERBURNER_ON )	{
		return;		// afterburners are already engaged, nothing to do here
	}

	//boosters take precedence
	if (objp->phys_info.flags & PF_BOOSTER_ON)
		return;	
	    
	if ( !(sip->flags[Ship::Info_Flags::Afterburner]) )	{
		return;
	}

	// Check if there is enough afterburner fuel
	if ( (shipp->afterburner_fuel < MIN_AFTERBURNER_FUEL_TO_ENGAGE) && !MULTIPLAYER_CLIENT ) {
		if ( objp == Player_obj ) {
			snd_play( gamesnd_get_game_sound(ship_get_sound(objp, GameSounds::ABURN_FAIL)) );
		}
		return;
	}

	objp->phys_info.flags |= PF_AFTERBURNER_ON;

	objp->phys_info.afterburner_decay = timestamp(ABURN_DECAY_TIME);

	percent_left = shipp->afterburner_fuel / sip->afterburner_fuel_capacity;

	//Do anim
	model_anim_start_type(shipp, TRIGGER_TYPE_AFTERBURNER, ANIMATION_SUBTYPE_ALL, 1);

	if ( objp == Player_obj ) {
		Player_afterburner_start_time = timer_get_milliseconds();
		Player_disengage_timer = 1;
		Player_afterburner_vol = AFTERBURNER_DEFAULT_VOL;

		if ( percent_left > AFTERBURNER_PERCENT_FOR_LOOP_SND ) {
			Player_afterburner_loop_delay = timestamp(AFTERBURNER_LOOP_DELAY);
		}
		else {
			Player_afterburner_loop_delay = 0;
		}

		snd_play( gamesnd_get_game_sound(ship_get_sound(objp, GameSounds::ABURN_ENGAGE)), 0.0f, 1.0f, SND_PRIORITY_MUST_PLAY );
		joy_ff_afterburn_on();
	} else {
		snd_play_3d( gamesnd_get_game_sound(ship_get_sound(objp, GameSounds::ABURN_ENGAGE)), &objp->pos, &View_position, objp->radius );
	}

	Script_system.SetHookObjects(1, "Ship", objp);
	Script_system.RunCondition(CHA_AFTERBURNSTART, 0, NULL, objp);
	Script_system.RemHookVars(1, "Ship");
	
	objp->phys_info.flags |= PF_AFTERBURNER_WAIT;
}