// Loads a shockwave in preparation for a mission void shockwave_create_info::load() { int i = -1; // shockwave_load() will return -1 if the filename is "none" or "<none>" // checking for that case lets us handle a situation where a 2D shockwave // of "none" was specified and a valid 3D shockwave was specified if ( strlen(name) ) i = shockwave_load(name, false); if ( (i < 0) && strlen(pof_name) ) shockwave_load(pof_name, true); }
// ------------------------------------------------------------------------------------ // shockwave_init() // // Call once at the start of each level (mission) // void shockwave_level_init() { int i; if ( !Default_shockwave_loaded ) { i = -1; // try and load in a 3d shockwave first // Goober5000 - check for existence of file before trying to load it if ( cf_exists_full("shockwave.pof", CF_TYPE_MODELS) ) { mprintf(("SHOCKWAVE => Loading default shockwave model... \n")); i = shockwave_load( Default_shockwave_3D_filename, true ); if (i >= 0) mprintf(("SHOCKWAVE => Default model load: SUCCEEDED!!\n")); else mprintf(("SHOCKWAVE => Default model load: FAILED!! Falling back to 2D effect...\n")); } // next, try the 2d shockwave effect, unless the 3d effect was loaded if (i < 0) i = shockwave_load( Default_shockwave_2D_filename ); if (i < 0) Error(LOCATION, "ERROR: Unable to open neither 3D nor 2D default shockwaves!!"); Default_shockwave_loaded = 1; } else { // have to make sure that the default 3D model is still valid and usable // the 2D shockwave shouldn't need anything like this if (Shockwave_info[0].model_id >= 0) Shockwave_info[0].model_id = model_load( Default_shockwave_3D_filename, 0, NULL ); } Assert( ((Shockwave_info[0].bitmap_id >= 0) || (Shockwave_info[0].model_id >= 0)) ); list_init(&Shockwave_list); for ( i = 0; i < MAX_SHOCKWAVES; i++ ) { Shockwaves[i].flags = 0; Shockwaves[i].objnum = -1; Shockwaves[i].model_id = -1; } Shockwave_inited = 1; }
// ------------------------------------------------------------------------------------ // shockwave_create() // // Call to create a shockwave // // input: parent_objnum => object number of object spawning the shockwave // pos => vector specifing global position of shockwave center // speed => speed at which shockwave expands (m/s) // inner_radius => radius at which damage applied is at maximum // outer_radius => damage decreases linearly to zero from inner_radius to // outer_radius. Outside outer_radius, damage is 0. // damage => the maximum damage (ie within inner_radius) // blast => the maximux blast (within inner_radius) // sw_flag => indicates whether shockwave is from weapon or ship explosion // delay => delay in ms before the shockwave actually starts // // return: success => object number of shockwave // failure => -1 // // Goober5000 - now parent_objnum can be allowed to be -1 int shockwave_create(int parent_objnum, vec3d *pos, shockwave_create_info *sci, int flag, int delay) { int i, objnum, real_parent; int info_index = -1, model_id = -1; shockwave *sw; // shockwave_info *si; matrix orient; for (i = 0; i < MAX_SHOCKWAVES; i++) { if ( !(Shockwaves[i].flags & SW_USED) ) break; } if (i == MAX_SHOCKWAVES) return -1; // try 2D shockwave first, then fall back to 3D, then fall back to default of either // this should be pretty fool-proof and allow quick change between 2D and 3D effects if ( strlen(sci->name) ) info_index = shockwave_load(sci->name, false); if ( (info_index < 0) && strlen(sci->pof_name) ) info_index = shockwave_load(sci->pof_name, true); if (info_index < 0) { if ( (Shockwave_info[0].bitmap_id >= 0) || (Shockwave_info[0].model_id >= 0) ) { info_index = 0; model_id = Shockwave_info[0].model_id; } else { // crap, just bail return -1; } } else { model_id = Shockwave_info[info_index].model_id; } // real_parent is the guy who caused this shockwave to happen if (parent_objnum == -1) { // Goober5000 real_parent = -1; } else if ( Objects[parent_objnum].type == OBJ_WEAPON ){ real_parent = Objects[parent_objnum].parent; } else { real_parent = parent_objnum; } sw = &Shockwaves[i]; sw->model_id = model_id; sw->flags = (SW_USED | flag); sw->speed = sci->speed; sw->inner_radius = sci->inner_rad; sw->outer_radius = sci->outer_rad; sw->damage = sci->damage; sw->blast = sci->blast; sw->radius = 1.0f; sw->pos = *pos; sw->num_objs_hit = 0; sw->shockwave_info_index = info_index; // only one type for now... type could be passed is as a parameter sw->current_bitmap = -1; sw->time_elapsed=0.0f; sw->delay_stamp = delay; sw->rot_angles = sci->rot_angles; sw->damage_type_idx = sci->damage_type_idx; // si = &Shockwave_info[sw->shockwave_info_index]; // sw->total_time = i2fl(si->num_frames) / si->fps; // in seconds sw->total_time = sw->outer_radius / sw->speed; if ( (parent_objnum != -1) && Objects[parent_objnum].type == OBJ_WEAPON ) { // Goober5000: allow -1 sw->weapon_info_index = Weapons[Objects[parent_objnum].instance].weapon_info_index; } else { sw->weapon_info_index = -1; } orient = vmd_identity_matrix; vm_angles_2_matrix(&orient, &sw->rot_angles); // angles a; // a.p = sw->rot_angle*(PI/180); // a.b = frand_range(0.0f, PI2); // a.h = frand_range(0.0f, PI2); // vm_angles_2_matrix(&orient, &a); objnum = obj_create( OBJ_SHOCKWAVE, real_parent, i, &orient, &sw->pos, sw->outer_radius, OF_RENDERS ); if ( objnum == -1 ){ Int3(); } sw->objnum = objnum; list_append(&Shockwave_list, sw); return objnum; }
/** * Call once at the start of each level (mission) */ void shockwave_level_init() { int i; if ( !Default_shockwave_loaded ) { i = -1; // try and load in a 3d shockwave first if enabled // Goober5000 - check for existence of file before trying to load it // chief1983 - Spicious added this check for the command line option. I've modified the hardcoded "shockwave.pof" that existed in the check // to use the static name instead, and added a check to override the command line if a 2d default filename is not found // Note - The 3d shockwave flag is forced on by TBP's flag as of rev 4983 if ( Cmdline_enable_3d_shockwave && cf_exists_full(Default_shockwave_3D_filename, CF_TYPE_MODELS) ) { mprintf(("SHOCKWAVE => Loading default shockwave model... \n")); i = shockwave_load( Default_shockwave_3D_filename, true ); if (i >= 0) mprintf(("SHOCKWAVE => Default model load: SUCCEEDED!!\n")); else mprintf(("SHOCKWAVE => Default model load: FAILED!! Falling back to 2D effect...\n")); } // next, try the 2d shockwave effect, unless the 3d effect was loaded // chief1983 - added some messages similar to those for the 3d shockwave if (i < 0 || Cmdline_fb_explosions) { mprintf(("SHOCKWAVE => Loading default shockwave animation... \n")); i = shockwave_load( Default_shockwave_2D_filename ); if (i >= 0) mprintf(("SHOCKWAVE => Default animation load: SUCCEEDED!!\n")); else mprintf(("SHOCKWAVE => Default animation load: FAILED!! Checking if 3d effect was already tried...\n")); } // chief1983 - The first patch broke mods that don't provide a 2d shockwave or define a specific shockwave for each model/weapon (shame on them) // The next patch involved a direct copy of the attempt above, with an i < 0 check in place of the command line check. I've taken that and modified it to // spit out a more meaningful message. Might as well not bother trying again if the command line option was checked as it should have tried the first time through if ( i < 0 && !Cmdline_enable_3d_shockwave && cf_exists_full(Default_shockwave_3D_filename, CF_TYPE_MODELS) ) { mprintf(("SHOCKWAVE => Loading default shockwave model as last resort... \n")); i = shockwave_load( Default_shockwave_3D_filename, true ); if (i >= 0) mprintf(("SHOCKWAVE => Default model load: SUCCEEDED!!\n")); else mprintf(("SHOCKWAVE => Default model load: FAILED!! No effect loaded...\n")); } if (i < 0) Error(LOCATION, "ERROR: Unable to open neither 3D nor 2D default shockwaves!!"); Default_shockwave_loaded = 1; } else { // have to make sure that the default 3D model is still valid and usable // the 2D shockwave shouldn't need anything like this if (Shockwave_info[0].model_id >= 0) Shockwave_info[0].model_id = model_load( Default_shockwave_3D_filename, 0, NULL ); } Assert( ((Shockwave_info[0].bitmap_id >= 0) || (Shockwave_info[0].model_id >= 0)) ); list_init(&Shockwave_list); for ( i = 0; i < MAX_SHOCKWAVES; i++ ) { Shockwaves[i].flags = 0; Shockwaves[i].objnum = -1; Shockwaves[i].model_id = -1; } Shockwave_inited = 1; }