// randomly say yes or no to a gauge, if emp is not active, always say yes int emp_should_blit_gauge() { // if the EMP effect is not active, always blit if(!emp_active_local()){ return 1; } // otherwise, randomly say no return frand_range(0.0f, 1.0f) > Emp_intensity; }
// throw some jitter into HUD x and y coords void emp_hud_jitter(int *x, int *y) { // if the emp effect is not active, don't jitter anything if(!emp_active_local()){ return; } // some movement *x += (int)frand_range(-8.0f * Emp_intensity, 8.0f * Emp_intensity); *y += (int)frand_range(-8.0f * Emp_intensity, 8.0f * Emp_intensity); }
// radar is damaged, so make blips dance around void radar_blip_draw_distorted(blip *b) { int xdiff, ydiff; float scale; xdiff = -10 + rand()%20; ydiff = -10 + rand()%20; // maybe scale the effect if EMP is active if(emp_active_local()){ scale = emp_current_intensity(); xdiff = (int)((float)xdiff * scale); ydiff = (int)((float)ydiff * scale); } radar_draw_circle( b->x+xdiff, b->y+ydiff, b->rad ); }
void HudGaugeRadarStd::blipDrawDistorted(blip *b, int x, int y) { int xdiff, ydiff; float scale; xdiff = -10 + rand()%20; ydiff = -10 + rand()%20; // maybe scale the effect if EMP is active if(emp_active_local()){ scale = emp_current_intensity(); xdiff = (int)((float)xdiff * scale); ydiff = (int)((float)ydiff * scale); } drawContactCircle(x + xdiff, y + ydiff, b->rad); }
// process some stuff every frame (before frame is rendered) void emp_process_local() { if(!emp_active_local()){ return; } // decrement the intensity a bit Emp_intensity -= (flFrametime * Emp_decr); // see if we should choose a random target if((Emp_wacky_target_timestamp == -1) || timestamp_elapsed(Emp_wacky_target_timestamp)){ // choose a target (if not the "first" time) if(Emp_wacky_target_timestamp != -1){ hud_target_random_ship(); } // reset the timestamp Emp_wacky_target_timestamp = timestamp((int)frand_range(100.0f, 750.0f * (1.0f - Emp_intensity))); } }
// emp hud printf void emp_hud_printf(int x, int y, int gauge_id, const char *format, ...) { char tmp[256] = ""; va_list args; // format the text va_start(args, format); vsprintf(tmp, format, args); va_end(args); // if the emp effect is not active, don't even bother messing with the text if(emp_active_local()){ emp_maybe_reformat_text(tmp, 256, gauge_id); // jitter the coords emp_hud_jitter(&x, &y); } // print the string out gr_string(x, y, tmp); }
// emp hud string void emp_hud_string(int x, int y, int gauge_id, const char *str, int resize_mode) { char tmp[256] = ""; // maybe bail if (!*str) return; // copy the string strcpy_s(tmp, str); // if the emp effect is not active, don't even bother messing with the text if(emp_active_local()){ emp_maybe_reformat_text(tmp, 256, gauge_id); // jitter the coords emp_hud_jitter(&x, &y); } // print the string out gr_string(x, y, tmp, resize_mode); }
// radar is damaged, so make blips dance around void HudGaugeRadarOrb::blipDrawDistorted(blip *b, vec3d *pos) { float scale; float dist=vm_vec_normalize(pos); vec3d out; float distortion_angle=20; // maybe alter the effect if EMP is active if(emp_active_local()) { scale = emp_current_intensity(); distortion_angle *= frand_range(-3.0f,3.0f)*frand_range(0.0f, scale); dist *= frand_range(MAX(0.75f, 0.75f*scale), MIN(1.25f, 1.25f*scale)); if (dist > 1.25f) dist = 1.25f; if (dist < 0.75f) dist = 0.75f; } vm_vec_random_cone(&out,pos,distortion_angle); vm_vec_scale(&out,dist); drawContactHtl(&out,b->rad); }
// radar is damaged, so make blips dance around void HudGaugeRadarDradis::blipDrawDistorted(blip *b, vec3d *pos, float alpha) { float temp_scale; float dist = vm_vec_normalize(pos); vec3d out; float distortion_angle=20; // maybe alter the effect if EMP is active if (emp_active_local()) { temp_scale = emp_current_intensity(); dist *= frand_range(MAX(0.75f, 0.75f*temp_scale), MIN(1.25f, 1.25f*temp_scale)); distortion_angle *= frand_range(-3.0f,3.0f)*frand_range(0.0f, temp_scale); if (dist > 1.0f) dist = 1.0f; if (dist < 0.1f) dist = 0.1f; } vm_vec_random_cone(&out, pos, distortion_angle); vm_vec_scale(&out, dist); drawContact(&out, -1, unknown_contact_icon, b->dist, alpha, 1.0f); }
// maybe reformat a string void emp_maybe_reformat_text(char *text, int max_len, int gauge_id) { wacky_text *wt; // if the EMP effect is not active, never reformat it if(!emp_active_local()){ return; } // randomly _don't_ apply text craziness if(frand_range(0.0f, 1.0f) > Emp_intensity){ return; } // if the gauge is EG_NULL, empty the string if(gauge_id == EG_NULL){ strcpy(text, ""); return; } // if this gauge has not been wacked out, or if the timestamp has expired, we // neeed to wack it out again Assert((gauge_id >= EG_NULL) && (gauge_id < NUM_TEXT_STAMPS)); wt = &Emp_wacky_text[gauge_id]; if((wt->stamp == -1) || timestamp_elapsed(wt->stamp)){ // reformat specific gauges differently switch(gauge_id){ // weapons case EG_WEAPON_TITLE: case EG_WEAPON_P1: case EG_WEAPON_P2: case EG_WEAPON_P3: case EG_WEAPON_S1: case EG_WEAPON_S2: int wep_index; wep_index = (int)frand_range(0.0f, (float)(MAX_WEAPON_TYPES - 1)); strcpy_s(wt->str, Weapon_info[ wep_index >= MAX_WEAPON_TYPES ? 0 : wep_index ].name); break; // escort list case EG_ESCORT1: case EG_ESCORT2: case EG_ESCORT3: // choose a random ship int shipnum; shipnum = ship_get_random_targetable_ship(); if(shipnum >= 0){ strcpy_s(wt->str, Ships[shipnum].ship_name); } break; // directives title case EG_OBJ_TITLE: strcpy_s(wt->str, ""); break; // directives themselves case EG_OBJ1: case EG_OBJ2: case EG_OBJ3: case EG_OBJ4: case EG_OBJ5: strcpy_s(wt->str, text); emp_randomize_chars(wt->str); break; // target box info case EG_TBOX_EXTRA1: case EG_TBOX_EXTRA2: case EG_TBOX_EXTRA3: case EG_TBOX_CLASS: case EG_TBOX_DIST: case EG_TBOX_CARGO: case EG_TBOX_HULL: case EG_TBOX_NAME: case EG_TBOX_INTEG: strcpy_s(wt->str, text); emp_randomize_chars(wt->str); break; // squadmsg menu case EG_SQ1: case EG_SQ2: case EG_SQ3: case EG_SQ4: case EG_SQ5: case EG_SQ6: case EG_SQ7: case EG_SQ8: case EG_SQ9: case EG_SQ10: strcpy_s(wt->str, text); emp_randomize_chars(wt->str); break; // default default : return; } // recalculate the timestamp wt->stamp = timestamp((int)frand_range(100.0f, 750.0f * (1.0f - Emp_intensity))); // copy the text strcpy(text, wt->str); } // otherwise, use what we calculated last time else { strcpy(text, wt->str); } // watch out for '#' - Goober5000 end_string_at_first_hash_symbol(text); }
// hud_update_lock_indicator() will manage the non-rendering dependant part of // missle locking void hud_update_lock_indicator(float frametime) { ship_weapon *swp; weapon_info *wip; vector lock_world_pos; #ifndef NO_NETWORK // if i'm a multiplayer observer, bail here if((Game_mode & GM_MULTIPLAYER) && ((Net_player->flags & NETINFO_FLAG_OBSERVER) || (Player_obj->type == OBJ_OBSERVER)) ){ return; } #endif Assert(Player_ai->target_objnum != -1); // be sure to unset this flag, then possibly set later in this function so that // threat indicators work properly. Player_ai->ai_flags &= ~AIF_SEEK_LOCK; if ( hud_abort_lock() ) { hud_lock_reset(); return; } // if there is an EMP effect active, never update lock if(emp_active_local()){ hud_lock_reset(); return; } swp = &Player_ship->weapons; wip = &Weapon_info[swp->secondary_bank_weapons[swp->current_secondary_bank]]; Lock_start_dist = wip->min_lock_time * wip->lock_pixels_per_sec; // if secondary weapons change, reset the lock if ( hud_lock_secondary_weapon_changed(swp) ) { hud_lock_reset(); } Player_ai->last_secondary_index = swp->current_secondary_bank; if ( !(wip->wi_flags & WIF_HOMING_ASPECT) ) { hud_lock_reset(); return; } // Allow locking on ships and bombs (only targeted weapon allowed is a bomb, so don't bother checking flags) if ( (Objects[Player_ai->target_objnum].type != OBJ_SHIP) && (Objects[Player_ai->target_objnum].type != OBJ_WEAPON) ) { hud_lock_reset(); return; } hud_lock_determine_lock_point(&lock_world_pos); if ( !hud_lock_has_homing_point() ) { Player->target_in_lock_cone=0; } hud_lock_check_if_target_in_lock_cone(&lock_world_pos); // check if the target is within range of the current secondary weapon. If it is not, // a lock will not be detected if ( !hud_lock_target_in_range() ) { Player->target_in_lock_cone = 0; } // If locking on a subsystem, and not in sight... can't lock // Changed by MK on 4/3/98. It was confusing me that my hornets would not lock on my target. // It will now be confusing that they lock, but don't home on your subsystem, but I think that's preferable. // Often you really care about destroying the target, not just the subsystem. /*if ( Player_ai->targeted_subsys ) { if ( !hud_lock_on_subsys_ok() ) { Player->target_in_lock_cone=0; } }*/ if ( !Player->target_in_lock_cone ) { Player->locking_on_center=0; Player->locking_subsys_parent=-1; Player->locking_subsys=NULL; } hud_calculate_lock_position(frametime); if (!Players[Player_num].lock_indicator_visible) return; if (Player_ai->current_target_is_locked) { if ( Missile_track_loop > -1 ) { snd_chg_loop_status(Missile_track_loop, 0); Missile_track_loop = -1; Missile_lock_loop = snd_play(&Snds[SND_MISSILE_LOCK]); } } else { Player_ai->ai_flags |= AIF_SEEK_LOCK; // set this flag so multiplayer's properly track lock on other ships if ( Missile_lock_loop != -1 && snd_is_playing(Missile_lock_loop) ) { snd_stop(Missile_lock_loop); Missile_lock_loop = -1; } } }
void radar_frame_render(float frametime) { float sensors_str; int ok_to_blit_radar; ok_to_blit_radar = 1; sensors_str = ship_get_subsystem_strength( Player_ship, SUBSYSTEM_SENSORS ); if ( ship_subsys_disrupted(Player_ship, SUBSYSTEM_SENSORS) ) { sensors_str = MIN_SENSOR_STR_TO_RADAR-1; } // note that on lowest skill level, there is no radar effects due to sensors damage if ( (Game_skill_level == 0) || (sensors_str > SENSOR_STR_RADAR_NO_EFFECTS) ) { Radar_static_playing = 0; Radar_static_next = 0; Radar_death_timer = 0; Radar_avail_prev_frame = 1; } else if ( sensors_str < MIN_SENSOR_STR_TO_RADAR ) { if ( Radar_avail_prev_frame ) { Radar_death_timer = timestamp(2000); Radar_static_next = 1; } Radar_avail_prev_frame = 0; } else { Radar_death_timer = 0; if ( Radar_static_next == 0 ) Radar_static_next = 1; } if ( timestamp_elapsed(Radar_death_timer) ) { ok_to_blit_radar = 0; } hud_set_gauge_color(HUD_RADAR); radar_blit_gauge(); radar_draw_range(); if ( timestamp_elapsed(Radar_static_next) ) { Radar_static_playing ^= 1; Radar_static_next = timestamp_rand(50, 750); } // if the emp effect is active, always draw the radar wackily if(emp_active_local()){ Radar_static_playing = 1; } if ( ok_to_blit_radar ) { if ( Radar_static_playing ) { radar_draw_blips_sorted(1); // passing 1 means to draw distorted if ( Radar_static_looping == -1 ) { Radar_static_looping = snd_play_looping(&Snds[SND_STATIC]); } } else { radar_draw_blips_sorted(); if ( Radar_static_looping != -1 ) { snd_stop(Radar_static_looping); Radar_static_looping = -1; } } } else { if ( Radar_static_looping != -1 ) { snd_stop(Radar_static_looping); Radar_static_looping = -1; } } }
void HudGaugeRadarDradis::render(float frametime) { float sensors_str; int ok_to_blit_radar; ok_to_blit_radar = 1; sensors_str = ship_get_subsystem_strength(Player_ship, SUBSYSTEM_SENSORS); if (ship_subsys_disrupted(Player_ship, SUBSYSTEM_SENSORS)) sensors_str = MIN_SENSOR_STR_TO_RADAR - 1; // note that on lowest skill level, there is no radar effects due to sensors damage if ((Game_skill_level == 0) || (sensors_str > SENSOR_STR_RADAR_NO_EFFECTS)) { Radar_static_playing = 0; Radar_static_next = 0; Radar_death_timer = 0; Radar_avail_prev_frame = 1; } else if (sensors_str < MIN_SENSOR_STR_TO_RADAR) { if (Radar_avail_prev_frame) { Radar_death_timer = timestamp(2000); Radar_static_next = 1; } Radar_avail_prev_frame = 0; } else { Radar_death_timer = 0; if (Radar_static_next == 0) Radar_static_next = 1; } if (timestamp_elapsed(Radar_death_timer)) ok_to_blit_radar = 0; setupViewHtl(); //WMC - This strikes me as a bit hackish bool g3_yourself = !g3_in_frame(); if(g3_yourself) g3_start_frame(1); drawSweeps(); if (timestamp_elapsed(Radar_static_next)) { Radar_static_playing ^= 1; Radar_static_next = timestamp_rand(50, 750); } // if the emp effect is active, always draw the radar wackily if (emp_active_local()) Radar_static_playing = 1; if (ok_to_blit_radar) { if (Radar_static_playing) { drawBlipsSorted(1); // passing 1 means to draw distorted if (Radar_static_looping == -1) Radar_static_looping = snd_play_looping(&Snds[SND_STATIC]); } else { drawBlipsSorted(0); if (Radar_static_looping != -1) { snd_stop(Radar_static_looping); Radar_static_looping = -1; } } } else { if (Radar_static_looping != -1) { snd_stop(Radar_static_looping); Radar_static_looping = -1; } } if(g3_yourself) g3_end_frame(); doneDrawingHtl(); }
// hud_do_lock_indicator() manages missle locking, both the non-rendering calculations and the 2D HUD rendering void hud_do_lock_indicator(float frametime) { ship_weapon *swp; weapon_info *wip; // if i'm a multiplayer observer, bail here if((Game_mode & GM_MULTIPLAYER) && ((Net_player->flags & NETINFO_FLAG_OBSERVER) || (Player_obj->type == OBJ_OBSERVER)) ){ return; } Assert(Player_ai->target_objnum >= 0); // be sure to unset this flag, then possibly set later in this function so that // threat indicators work properly. Player_ai->ai_flags.remove(AI::AI_Flags::Seek_lock); if ( hud_abort_lock() ) { hud_lock_reset(); return; } // if there is an EMP effect active, never update lock if(emp_active_local()){ hud_lock_reset(); return; } swp = &Player_ship->weapons; wip = &Weapon_info[swp->secondary_bank_weapons[swp->current_secondary_bank]]; Lock_start_dist = wip->min_lock_time * wip->lock_pixels_per_sec; // if secondary weapons change, reset the lock if ( hud_lock_secondary_weapon_changed(swp) ) { hud_lock_reset(); } Player_ai->last_secondary_index = swp->current_secondary_bank; object *tobjp = &Objects[Player_ai->target_objnum]; vec3d dir_to_target; vm_vec_normalized_dir(&dir_to_target, &tobjp->pos, &Player_obj->pos); if ( !(wip->is_locked_homing()) ) { hud_lock_reset(); return; } // Allow locking on ships and bombs (only targeted weapon allowed is a bomb, so don't bother checking flags) if ( (Objects[Player_ai->target_objnum].type != OBJ_SHIP) && (Objects[Player_ai->target_objnum].type != OBJ_WEAPON) ) { hud_lock_reset(); return; } // Javelins must lock on engines if locking on a ship and those must be in sight if (wip->wi_flags[Weapon::Info_Flags::Homing_javelin] && tobjp->type == OBJ_SHIP && Player->locking_subsys != NULL) { vec3d subobj_pos; vm_vec_unrotate(&subobj_pos, &Player->locking_subsys->system_info->pnt, &tobjp->orient); vm_vec_add2(&subobj_pos, &tobjp->pos); int target_subsys_in_sight = ship_subsystem_in_sight(tobjp, Player->locking_subsys, &Player_obj->pos, &subobj_pos); if (!target_subsys_in_sight || Player->locking_subsys->system_info->type != SUBSYSTEM_ENGINE) { Player->locking_subsys = ship_get_closest_subsys_in_sight(&Ships[tobjp->instance], SUBSYSTEM_ENGINE, &Player_obj->pos); } } if (wip->wi_flags[Weapon::Info_Flags::Homing_javelin] && tobjp->type == OBJ_SHIP && Player->locking_subsys == NULL) { Player->locking_subsys = ship_get_closest_subsys_in_sight(&Ships[tobjp->instance], SUBSYSTEM_ENGINE, &Player_obj->pos); if (Player->locking_subsys == NULL) { hud_lock_reset(); return; } } hud_lock_determine_lock_point(&lock_world_pos); if ( !hud_lock_has_homing_point() ) { Player->target_in_lock_cone=0; } hud_lock_check_if_target_in_lock_cone(); // check if the target is within range of the current secondary weapon. If it is not, // a lock will not be detected if ( !hud_lock_target_in_range() ) { Player->target_in_lock_cone = 0; } // If locking on a subsystem, and not in sight... can't lock // Changed by MK on 4/3/98. It was confusing me that my hornets would not lock on my target. // It will now be confusing that they lock, but don't home on your subsystem, but I think that's preferable. // Often you really care about destroying the target, not just the subsystem. /*if ( Player_ai->targeted_subsys ) { if ( !hud_lock_on_subsys_ok() ) { Player->target_in_lock_cone=0; } }*/ if ( !Player->target_in_lock_cone ) { Player->locking_on_center=0; Player->locking_subsys_parent=-1; Player->locking_subsys=NULL; } hud_calculate_lock_position(frametime); if (!Players[Player_num].lock_indicator_visible) return; if (Player_ai->current_target_is_locked) { if ( Missile_track_loop > -1 ) { snd_stop(Missile_track_loop); Missile_track_loop = -1; if (wip->hud_locked_snd >= 0) { Missile_lock_loop = snd_play(&Snds[wip->hud_locked_snd]); } else { Missile_lock_loop = snd_play(&Snds[ship_get_sound(Player_obj, SND_MISSILE_LOCK)]); } } } else { Player_ai->ai_flags.set(AI::AI_Flags::Seek_lock); // set this flag so multiplayer's properly track lock on other ships if ( Missile_lock_loop != -1 && snd_is_playing(Missile_lock_loop) ) { snd_stop(Missile_lock_loop); Missile_lock_loop = -1; } } }