/* * Copyright (C) Volition, Inc. 1999. All rights reserved. * * All source code herein is the property of Volition, Inc. You may not sell * or otherwise commercially exploit the source or things you created based on the * source. * */ #include "mission/missionparse.h" #include "ship/ship.h" #include "ship/shipcontrails.h" // ---------------------------------------------------------------------------------------------- // CONTRAIL DEFINES/VARS // // ---------------------------------------------------------------------------------------------- // CONTRAIL FORWARD DECLARATIONS // // if the object is below the limit for contrails int ct_below_limit(object *objp); // Goober0500 bool ct_display_contrails(); // if an object has active contrails int ct_has_contrails(ship *shipp); // update active contrails - moving existing ones, adding new ones where necessary void ct_update_contrails(ship *shipp); // create new contrails void ct_create_contrails(ship *shipp); // determine if the ship has AB trails int ct_has_ABtrails(ship *shipp); // update active ABtrails - moving existing ones, adding new ones where necessary void ct_update_ABtrails(ship *shipp); // create new ABtrails void ct_create_ABtrails(ship *shipp); void ct_ship_process_ABtrails(ship *shipp); // ---------------------------------------------------------------------------------------------- // CONTRAIL FUNCTIONS // // call during level initialization void ct_level_init() { } // call during level shutdown void ct_level_close() { } // call when a ship is created to initialize its contrail stuff void ct_ship_create(ship *shipp) { int idx; Assert(shipp != NULL); // null out the ct indices for this guy for(idx=0; idxtrail_ptr[idx] = NULL; } for(idx=0; idxABtrail_ptr[idx] = NULL; } } // call when a ship is deleted to free up its contrail stuff void ct_ship_delete(ship *shipp) { int idx; Assert(shipp != NULL); // free up any contrails this guy may have had for(idx=0; idxtrail_ptr[idx] != NULL){ trail_object_died(shipp->trail_ptr[idx]); shipp->trail_ptr[idx] = NULL; } if(shipp->ABtrail_ptr[idx] != NULL){ trail_object_died(shipp->ABtrail_ptr[idx]); shipp->ABtrail_ptr[idx] = NULL; } } } // call each frame for processing a ship's contrails void ct_ship_process(ship *shipp) { // seems like as good a place as any -Bobboau if (shipp->ab_info[0].texture.bitmap_id != -1) ct_ship_process_ABtrails(shipp); Assert(shipp != NULL); Assert(shipp->objnum >= 0); // if trails aren't enabled, return if (!ct_display_contrails()) { return; } int idx; object *objp; objp = &Objects[shipp->objnum]; // if this is not a ship, we don't care if((objp->type != OBJ_SHIP) || (Ship_info[Ships[objp->instance].ship_info_index].ct_count <= 0)){ return; } Assert(objp->instance >= 0); shipp = &Ships[objp->instance]; // if the object is below the critical limit if(ct_below_limit(objp)){ // kill any active trails he has for(idx=0; idxtrail_ptr[idx] != NULL){ trail_object_died(shipp->trail_ptr[idx]); shipp->trail_ptr[idx] = NULL; } } // don't create or update trails if we're not moving fast enough return; } // if the object already has contrails if(ct_has_contrails(shipp)){ ct_update_contrails(shipp); } // otherwise add new ones else { ct_create_contrails(shipp); } } // ---------------------------------------------------------------------------------------------- // CONTRAIL FORWARD DEFINITIONS - test stuff // // if the object is below the limit for contrails int ct_below_limit(object *objp) { if (Contrails_use_absolute_speed) return objp->phys_info.speed < (float) The_mission.contrail_threshold; return objp->phys_info.fspeed < (float) The_mission.contrail_threshold; } // if a ship has active contrails int ct_has_contrails(ship *shipp) { int idx; for(idx=0; idxtrail_ptr[idx] != NULL){ return 1; } } // no contrails return 0; } // update active contrails - moving existing ones, adding new ones where necessary void ct_update_contrails(ship *shipp) { // if trails aren't enabled, return if (!ct_display_contrails()) { return; } vec3d v1; int idx; ship_info *sip; object *objp; // get object and ship info Assert(shipp != NULL); Assert(shipp->objnum >= 0); Assert(shipp->ship_info_index >= 0); objp = &Objects[shipp->objnum]; sip = &Ship_info[shipp->ship_info_index]; // process each contrail for(idx=0; idxtrail_ptr[idx] != NULL){ // get the point for the contrail vm_vec_unrotate(&v1, &sip->ct_info[idx].pt, &objp->orient); vm_vec_add2(&v1, &objp->pos); // if the spew stamp has elapsed if(trail_stamp_elapsed(shipp->trail_ptr[idx])){ trail_add_segment(shipp->trail_ptr[idx], &v1, &objp->orient); trail_set_stamp(shipp->trail_ptr[idx]); } else { trail_set_segment(shipp->trail_ptr[idx], &v1); } } } } // create new contrails void ct_create_contrails(ship *shipp) { #ifdef MULTIPLAYER_BETA_BUILD return; #else // if trails aren't enabled, return if (!ct_display_contrails()) { return; } vec3d v1; int idx; ship_info *sip; object *objp; // get object and ship info Assert(shipp != NULL); Assert(shipp->objnum >= 0); Assert(shipp->ship_info_index >= 0); objp = &Objects[shipp->objnum]; sip = &Ship_info[shipp->ship_info_index]; for(idx=0; idxct_count; idx++) { //if (this is a neb mision and this is a neb trail) or an ABtrail -Bobboau shipp->trail_ptr[idx] = trail_create(&sip->ct_info[idx]); if(shipp->trail_ptr[idx] != NULL) { // add the point vm_vec_unrotate(&v1, &sip->ct_info[idx].pt, &objp->orient); vm_vec_add2(&v1, &objp->pos); trail_add_segment(shipp->trail_ptr[idx], &v1, &objp->orient); trail_add_segment(shipp->trail_ptr[idx], &v1, &objp->orient); } } #endif } // call each frame for processing a ship's ABtrails void ct_ship_process_ABtrails(ship *shipp) { int idx; object *objp; ship_info* sip; Assert(shipp != NULL); Assert(shipp->objnum >= 0); objp = &Objects[shipp->objnum]; sip=&Ship_info[shipp->ship_info_index]; // if this is not a ship, we don't care if((objp->type != OBJ_SHIP) || (Ships[objp->instance].ab_count <= 0)){ return; } // if the ship has no afterburner trail bitmap, don't bother with anything if (sip->afterburner_trail.bitmap_id < 0) return; Assert(objp->instance >= 0); shipp = &Ships[objp->instance]; if(!(objp->phys_info.flags & PF_AFTERBURNER_ON)){ //if the after burners aren't on -Bobboau for(idx=0; idxABtrail_ptr[idx] != NULL) { trail_object_died(shipp->ABtrail_ptr[idx]); shipp->ABtrail_ptr[idx] = NULL; } } //No more abtrails return; } // if the object already has ABtrails if(ct_has_ABtrails(shipp)){ ct_update_ABtrails(shipp); } // otherwise add new ones else { ct_create_ABtrails(shipp); } /* if(shipp->ab_info->stamp > timestamp( (int)(shipp->ab_info->max_life * 1000) ) ){ for(idx=0; idxABtrail_num[idx] >= 0){ trail_object_died(shipp->ABtrail_num[idx]); shipp->ABtrail_num[idx] = (short)-1; } } } */ } // create new ABtrails void ct_create_ABtrails(ship *shipp) { vec3d v1; int idx; ship_info *sip; object *objp; // get object and ship info Assert(shipp != NULL); Assert(shipp->objnum >= 0); Assert(shipp->ship_info_index >= 0); objp = &Objects[shipp->objnum]; sip = &Ship_info[shipp->ship_info_index]; // if the ship has no afterburner trail bitmap, don't bother with anything if (sip->afterburner_trail.bitmap_id < 0) return; if(objp->phys_info.flags & PF_AFTERBURNER_ON){//AB trails-Bobboau for(idx=0; idxab_count; idx++) { shipp->ABtrail_ptr[idx] = trail_create(&shipp->ab_info[idx]); if(shipp->ABtrail_ptr[idx] != NULL) { // get the point for the contrail vm_vec_unrotate(&v1, &shipp->ab_info[idx].pt, &objp->orient); vm_vec_add2(&v1, &objp->pos); // if the spew stamp has elapsed if(trail_stamp_elapsed(shipp->ABtrail_ptr[idx])){ trail_add_segment(shipp->ABtrail_ptr[idx], &v1, &objp->orient); trail_set_stamp(shipp->ABtrail_ptr[idx]); } else { trail_set_segment(shipp->ABtrail_ptr[idx], &v1); } } } /* if( objp == Player_obj){ HUD_printf("trailnum %d", shipp->ABtrail_num[0]); } */ } } // update active ABtrails - moving existing ones, adding new ones where necessary void ct_update_ABtrails(ship *shipp) { vec3d v1; int idx; ship_info *sip; object *objp; // get object and ship info Assert(shipp != NULL); Assert(shipp->objnum >= 0); Assert(shipp->ship_info_index >= 0); objp = &Objects[shipp->objnum]; sip = &Ship_info[shipp->ship_info_index]; // if the ship has no afterburner trail bitmap, don't bother with anything if (sip->afterburner_trail.bitmap_id < 0) return; for(idx=0; idxphys_info.flags & PF_AFTERBURNER_ON){//ABtrails if(shipp->ABtrail_ptr[idx] != NULL){ // get the point for the contrail vm_vec_unrotate(&v1, &shipp->ab_info[idx].pt, &objp->orient); vm_vec_add2(&v1, &objp->pos); // if the spew stamp has elapsed if(trail_stamp_elapsed(shipp->ABtrail_ptr[idx])){ trail_add_segment(shipp->ABtrail_ptr[idx], &v1, &objp->orient); trail_set_stamp(shipp->ABtrail_ptr[idx]); } else { trail_set_segment(shipp->ABtrail_ptr[idx], &v1); } } } } } // if a ship has active ABtrails int ct_has_ABtrails(ship *shipp) { int idx; ship_info* sip=&Ship_info[shipp->ship_info_index]; // if the ship has no afterburner trail bitmap, don't bother with anything if (sip->afterburner_trail.bitmap_id < 0) return 0; for(idx=0; idxABtrail_ptr[idx] != NULL){ return 1; } } // no contrails return 0; } bool ct_display_contrails() { bool display; // normally display trails in a full nebula environment display = (The_mission.flags[Mission::Mission_Flags::Fullneb]) ? true : false; // toggle according to flag if (The_mission.flags[Mission::Mission_Flags::Toggle_ship_trails]) display = !display; return display; }