/** * 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 }
// ------------------------------------------------------------------------------------ // 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 }
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; }