Exemplo n.º 1
0
/**
 * Simulate a single shockwave.  If the shockwave radius exceeds outer_radius, then
 * delete the shockwave.
 *
 * @param shockwave_objp	object pointer that points to shockwave object
 * @param frametime			time to simulate shockwave
 */
void shockwave_move(object *shockwave_objp, float frametime)
{
	shockwave	*sw;
	object		*objp;
	float			blast,damage;
	int			i;

	Assert(shockwave_objp->type == OBJ_SHOCKWAVE);
	Assert(shockwave_objp->instance  >= 0 && shockwave_objp->instance < MAX_SHOCKWAVES);
	sw = &Shockwaves[shockwave_objp->instance];

	// if the shockwave has a delay on it
	if(sw->delay_stamp != -1){
		if(timestamp_elapsed(sw->delay_stamp)){
			sw->delay_stamp = -1;
		} else {
			return;
		}
	}

	sw->time_elapsed += frametime;

	shockwave_set_framenum(shockwave_objp->instance);
		
	sw->radius += (frametime * sw->speed);
	if ( sw->radius > sw->outer_radius ) {
		sw->radius = sw->outer_radius;
		shockwave_objp->flags |= OF_SHOULD_BE_DEAD;
		return;
	}

	// blast ships and asteroids
	// And (some) weapons
	for ( objp = GET_FIRST(&obj_used_list); objp !=END_OF_LIST(&obj_used_list); objp = GET_NEXT(objp) ) {
		if ( (objp->type != OBJ_SHIP) && (objp->type != OBJ_ASTEROID) && (objp->type != OBJ_WEAPON)) {
			continue;
		}

		if ( objp->type == OBJ_WEAPON ) {
			// only apply to missiles with hitpoints
			weapon_info* wip = &Weapon_info[Weapons[objp->instance].weapon_info_index];
			if (wip->weapon_hitpoints <= 0 || !(wip->wi_flags2 & WIF2_TAKES_SHOCKWAVE_DAMAGE))
				continue;
			if (sw->weapon_info_index >= 0) {
				if (Weapon_info[sw->weapon_info_index].wi_flags2 & WIF2_CIWS) {
					continue;
				}
			}
		}

	
		if ( objp->type == OBJ_SHIP ) {
			// don't blast navbuoys
			if ( ship_get_SIF(objp->instance) & SIF_NAVBUOY ) {
				continue;
			}
		}

		// only apply damage to a ship once from a shockwave
		for ( i = 0; i < sw->num_objs_hit; i++ ) {
			if ( objp->signature == sw->obj_sig_hitlist[i] ){
				break;
			}
		}

		if ( i < sw->num_objs_hit ){
			continue;
		}

		if ( weapon_area_calc_damage(objp, &sw->pos, sw->inner_radius, sw->outer_radius, sw->blast, sw->damage, &blast, &damage, sw->radius) == -1 ){
			continue;
		}

		// okay, we have damage applied, record the object signature so we don't repeatedly apply damage
		Assert(sw->num_objs_hit < SW_MAX_OBJS_HIT);
		if ( sw->num_objs_hit >= SW_MAX_OBJS_HIT) {
			sw->num_objs_hit--;
		}

		weapon_info* wip = NULL;

		switch(objp->type) {
		case OBJ_SHIP:
			sw->obj_sig_hitlist[sw->num_objs_hit++] = objp->signature;
			// If we're doing an AoE Electronics shockwave, do the electronics stuff. -MageKing17
			if ( (sw->weapon_info_index >= 0) && (Weapon_info[sw->weapon_info_index].wi_flags3 & WIF3_AOE_ELECTRONICS) && !(objp->flags & OF_INVULNERABLE) ) {
				weapon_do_electronics_effect(objp, &sw->pos, sw->weapon_info_index);
			}
			ship_apply_global_damage(objp, shockwave_objp, &sw->pos, damage );
			weapon_area_apply_blast(NULL, objp, &sw->pos, blast, 1);
			break;
		case OBJ_ASTEROID:
			asteroid_hit(objp, NULL, NULL, damage);
			break;
		case OBJ_WEAPON:
			wip = &Weapon_info[Weapons[objp->instance].weapon_info_index];
			if (wip->armor_type_idx >= 0)
				damage = Armor_types[wip->armor_type_idx].GetDamage(damage, shockwave_get_damage_type_idx(shockwave_objp->instance),1.0f);

			objp->hull_strength -= damage;
			if (objp->hull_strength < 0.0f) {
				Weapons[objp->instance].lifeleft = 0.01f;
				Weapons[objp->instance].weapon_flags |= WF_DESTROYED_BY_WEAPON;
			}
			break;
		default:
			Int3();
			break;
		}

		// If this shockwave hit the player, play shockwave impact sound
		if ( objp == Player_obj ) {
			float full_damage, vol_scale;
			if (sw->weapon_info_index >= 0) {
				full_damage = Weapon_info[sw->weapon_info_index].damage;
			} else {
				full_damage = sw->damage;
			}
			if (full_damage != 0.0f) {
				vol_scale = MAX(0.4f, damage/full_damage);
			} else {
				vol_scale = 1.0f;
			}
			snd_play( &Snds[SND_SHOCKWAVE_IMPACT], 0.0f, vol_scale );
		}

	}	// end for
}
Exemplo n.º 2
0
// ------------------------------------------------------------------------------------
// shockwave_move()
//
//	Simulate a single shockwave.  If the shockwave radius exceeds outer_radius, then
// delete the shockwave.
//
//	input:		ojbp			=>		object pointer that points to shockwave object
//					frametime	=>		time to simulate shockwave
//
void shockwave_move(object *shockwave_objp, float frametime)
{
	shockwave	*sw;
	object		*objp;
	float			blast,damage;
	int			i;

	Assert(shockwave_objp->type == OBJ_SHOCKWAVE);
	Assert(shockwave_objp->instance  >= 0 && shockwave_objp->instance < MAX_SHOCKWAVES);
	sw = &Shockwaves[shockwave_objp->instance];

	// if the shockwave has a delay on it
	if(sw->delay_stamp != -1){
		if(timestamp_elapsed(sw->delay_stamp)){
			sw->delay_stamp = -1;
		} else {
			return;
		}
	}

	sw->time_elapsed += frametime;
/*
	if ( sw->time_elapsed > sw->total_time ) {
		shockwave_objp->flags |= OF_SHOULD_BE_DEAD;
	}
*/

	shockwave_set_framenum(shockwave_objp->instance);
		
	sw->radius += (frametime * sw->speed);
	if ( sw->radius > sw->outer_radius ) {
		sw->radius = sw->outer_radius;
		shockwave_objp->flags |= OF_SHOULD_BE_DEAD;
		return;
	}

	// blast ships and asteroids
	for ( objp = GET_FIRST(&obj_used_list); objp !=END_OF_LIST(&obj_used_list); objp = GET_NEXT(objp) ) {
		if ( (objp->type != OBJ_SHIP) && (objp->type != OBJ_ASTEROID) ) {
			continue;
		}
	
		if ( objp->type == OBJ_SHIP ) {
			// don't blast navbuoys
			if ( ship_get_SIF(objp->instance) & SIF_NAVBUOY ) {
				continue;
			}
		}

		// only apply damage to a ship once from a shockwave
		for ( i = 0; i < sw->num_objs_hit; i++ ) {
			if ( objp->signature == sw->obj_sig_hitlist[i] ){
				break;
			}
		}

		if ( i < sw->num_objs_hit ){
			continue;
		}

		if ( weapon_area_calc_damage(objp, &sw->pos, sw->inner_radius, sw->outer_radius, sw->blast, sw->damage, &blast, &damage, sw->radius) == -1 ){
			continue;
		}

		// okay, we have damage applied, record the object signature so we don't repeatedly apply damage
		Assert(sw->num_objs_hit < SW_MAX_OBJS_HIT);
		if ( sw->num_objs_hit >= SW_MAX_OBJS_HIT) {
			sw->num_objs_hit--;
		}

		switch(objp->type) {
		case OBJ_SHIP:
			sw->obj_sig_hitlist[sw->num_objs_hit++] = objp->signature;
			ship_apply_global_damage(objp, shockwave_objp, &sw->pos, damage );
			weapon_area_apply_blast(NULL, objp, &sw->pos, blast, 1);
			break;
		case OBJ_ASTEROID:
			asteroid_hit(objp, NULL, NULL, damage);
			break;
		default:
			Int3();
			break;
		}


		// If this shockwave hit the player, play shockwave impact sound
		if ( objp == Player_obj ) {
			snd_play( &Snds[SND_SHOCKWAVE_IMPACT], 0.0f, MAX(0.4f, damage/Weapon_info[sw->weapon_info_index].damage) );
		}

	}	// end for
}
Exemplo n.º 3
0
BOOL WeaponEditorDlg::OnInitDialog() 
{
	int i, z, big = 1, end1, end2, inst, flag = 0;
	object *ptr;
	model_subsystem *psub;
	ship_subsys *ssl, *pss;
	CComboBox *box;
	CListBox *list;

	CDialog::OnInitDialog();
	m_ship = cur_ship;
	if (m_ship == -1)
		m_ship = Objects[cur_object_index].instance;

	end1 = First_secondary_index;
	end2 = Num_weapon_types;

	list = (CListBox *) GetDlgItem(IDC_LIST);

	z = list->AddString("Pilot");
	if (m_multi_edit) {
		list->SetItemDataPtr(z, &pilot);
		ptr = GET_FIRST(&obj_used_list);
		while (ptr != END_OF_LIST(&obj_used_list)) {
			if (((ptr->type == OBJ_SHIP) || (ptr->type == OBJ_START)) && (ptr->flags & OF_MARKED)) {
				inst = ptr->instance;
				if (!(ship_get_SIF(inst) & (SIF_BIG_SHIP | SIF_HUGE_SHIP)))
					big = 0;

				if (!flag) {
					pilot = Ships[inst].weapons;
					m_ship_class = Ships[inst].ship_info_index;
					flag = 1;

				} else {
					Assert(Ships[inst].ship_info_index == m_ship_class);
					if (pilot.ai_class != Ships[inst].weapons.ai_class)
						pilot.ai_class = BLANK_FIELD;

					for (i=0; i<MAX_SHIP_PRIMARY_BANKS; i++)
						if (pilot.primary_bank_weapons[i] != Ships[inst].weapons.primary_bank_weapons[i])
							pilot.primary_bank_weapons[i] = BLANK_FIELD;

					for (i=0; i<MAX_SHIP_SECONDARY_BANKS; i++) {
						if (pilot.secondary_bank_weapons[i] != Ships[inst].weapons.secondary_bank_weapons[i])
							pilot.secondary_bank_weapons[i] = BLANK_FIELD;
						if (pilot.secondary_bank_ammo[i] != Ships[inst].weapons.secondary_bank_ammo[i])
							pilot.secondary_bank_ammo[i] = BLANK_FIELD;
					}
				}
			}

			ptr = GET_NEXT(ptr);
		}

	} else {
		if (!(ship_get_SIF(m_ship) & (SIF_BIG_SHIP | SIF_HUGE_SHIP)))
			big = 0;

		m_ship_class = Ships[m_ship].ship_info_index;
		list->SetItemDataPtr(z, &Ships[m_ship].weapons);
		ssl = &Ships[m_ship].subsys_list;
		for (pss = GET_FIRST(ssl); pss != END_OF_LIST(ssl); pss = GET_NEXT(pss)) {
			psub = pss->system_info;
			if (psub->type == SUBSYSTEM_TURRET) {
				z = list->AddString(psub->subobj_name);
				list->SetItemDataPtr(z, &pss->weapons);
			}
		}
	}

	box = (CComboBox *) GetDlgItem(IDC_AI_CLASS);
	for (i=0; i<Num_ai_classes; i++){
		box->AddString(Ai_class_names[i]);
	}

	for (i=0; i<end1; i++){
		if ((Weapon_info[i].wi_flags & WIF_CHILD) || (!big && (Weapon_info[i].wi_flags & WIF_BIG_ONLY))){
			end1 = i;
		}
	}

	box = (CComboBox *) GetDlgItem(IDC_GUN1);
	box->AddString("None");
	for (i=0; i<end1; i++){
		box->AddString(Weapon_info[i].name);
	}

	box = (CComboBox *) GetDlgItem(IDC_GUN2);
	box->AddString("None");
	for (i=0; i<end1; i++){
		box->AddString(Weapon_info[i].name);
	}

	box = (CComboBox *) GetDlgItem(IDC_GUN3);
	box->AddString("None");
	for (i=0; i<end1; i++){
		box->AddString(Weapon_info[i].name);
	}

	for (i=First_secondary_index; i<end2; i++){
		if ((Weapon_info[i].wi_flags & WIF_CHILD) || (!big && (Weapon_info[i].wi_flags & WIF_BIG_ONLY))){
			end2 = i;
		}
	}

	box = (CComboBox *) GetDlgItem(IDC_MISSILE1);
	box->AddString("None");
	for (i=First_secondary_index; i<end2; i++){
		box->AddString(Weapon_info[i].name);
	}

	box = (CComboBox *) GetDlgItem(IDC_MISSILE2);
	box->AddString("None");
	for (i=First_secondary_index; i<end2; i++){
		box->AddString(Weapon_info[i].name);
	}

	box = (CComboBox *) GetDlgItem(IDC_MISSILE3);
	box->AddString("None");
	for (i=First_secondary_index; i<end2; i++){
		box->AddString(Weapon_info[i].name);
	}

	box = (CComboBox *) GetDlgItem(IDC_MISSILE4);
	box->AddString("None");
	for (i=First_secondary_index; i<end2; i++){
		box->AddString(Weapon_info[i].name);
	}
 
	box = (CComboBox *) GetDlgItem(IDC_MISSILE5);
	box->AddString("None");
	for (i=First_secondary_index; i<end2; i++){
		box->AddString(Weapon_info[i].name);
	}

	box = (CComboBox *) GetDlgItem(IDC_MISSILE6);
	box->AddString("None");
	for (i=First_secondary_index; i<end2; i++){
		box->AddString(Weapon_info[i].name);
	}

	m_cur_item = 0;
	UpdateData(FALSE);
	change_selection();
	UpdateData(TRUE);
	return TRUE;
}