X-Git-Url: http://de.git.xonotic.org/?p=voretournament%2Fvoretournament.git;a=blobdiff_plain;f=data%2Fqcsrc%2Fclient%2FView.qc;h=bf89e9a4257dfd24a8333f995bbf25ea87e49747;hp=7d803a60737cc8f4030221bbd7a0acf4d542fc4e;hb=ada65947f4feafbcbe58977f284944398f585d73;hpb=d10de97b9c169bbd5f01beafbefc8c3ce8efc670 diff --git a/data/qcsrc/client/View.qc b/data/qcsrc/client/View.qc index 7d803a60..bf89e9a4 100644 --- a/data/qcsrc/client/View.qc +++ b/data/qcsrc/client/View.qc @@ -250,8 +250,22 @@ void CSQC_Demo_Camera(); float Sbar_WouldDrawScoreboard (); float view_set; float camera_mode; +float reticle_type; float chase_active_old; +float artwork_fade; +float pickup_crosshair_time, pickup_crosshair_size, pickup_flash_time, vore_flash_laststate, respawn_flash_lasthealth; +float myhealth, myhealth_prev, myhealth_flash; +float contentavgalpha, liquidalpha_prev; +float old_blurradius, old_bluralpha, old_sharpen_intensity; +float stomachsplash_alpha, stomachsplash_remove_at_respawn; +float volume_modify_1, volume_modify_2, volume_modify_default_1, volume_modify_default_2; +float volume_modify_changed_1, volume_modify_changed_2; +float eventchase_current_distance; +vector myhealth_gentlergb; +vector liquidcolor_prev; +vector damage_blurpostprocess, content_blurpostprocess; string artwork_image; +string intermission_song; string NextFrameCommand; void CSQC_UpdateView(float w, float h) { @@ -259,7 +273,10 @@ void CSQC_UpdateView(float w, float h) float fov; float f, i, j; vector v, vo; + float a; + vector reticle_pos, reticle_size; + vector splash_pos, splash_size; vector artwork_pos, artwork_size; WaypointSprite_Load(); @@ -278,6 +295,42 @@ void CSQC_UpdateView(float w, float h) pmove_org = warpzone_fixview_origin - vo; input_angles = warpzone_fixview_angles; + // event chase camera + if(cvar("chase_active") <= 0) // greater than 0 means it's enabled manually, and this code is skipped + { + if(!getstati(STAT_VORE_EATEN) && spectatee_status >= 0 && (cvar("cl_eventchase_death") && getstati(STAT_HEALTH) <= 0 && !intermission)) + { + // We must enable chase_active to get a third person view (weapon viewmodel hidden and own player model showing). + // Ideally, there should be another way to enable third person cameras, such as through R_SetView() + if(!cvar("chase_active")) + cvar_set("chase_active", "-1"); // -1 enables chase_active while marking it as set by this code, and not by the user (which would be 1) + + // make the camera smooth back + if(cvar("cl_eventchase_speed") && eventchase_current_distance < cvar("cl_eventchase_distance")) + eventchase_current_distance += cvar("cl_eventchase_speed") * (cvar("cl_eventchase_distance") - eventchase_current_distance) * frametime; // slow down the further we get + else if(eventchase_current_distance != cvar("cl_eventchase_distance")) + eventchase_current_distance = cvar("cl_eventchase_distance"); + + vector eventchase_target_origin; + makevectors(view_angles); + // pass 1, used to check where the camera would go and obtain the trace_fraction + eventchase_target_origin = pmove_org - v_forward * eventchase_current_distance; + + traceline(pmove_org, eventchase_target_origin, MOVE_WORLDONLY, self); + // pass 2, also multiplying view_forward with trace_fraction, to prevent the camera from going through walls + // The 0.1 subtraction is to not limit the camera precisely at the wall surface, as that allows the view to poke through + eventchase_target_origin = pmove_org - v_forward * eventchase_current_distance * (trace_fraction - 0.1); + + R_SetView(VF_ORIGIN, eventchase_target_origin); + R_SetView(VF_ANGLES, view_angles); + } + else if(cvar("chase_active") < 0) // time to disable chase_active if it was set by this code + { + cvar_set("chase_active", "0"); + eventchase_current_distance = 0; // start from 0 next time + } + } + // Render the Scene if(!intermission || !view_set) { @@ -448,6 +501,390 @@ void CSQC_UpdateView(float w, float h) // next R_RenderScene call drawstring('0 0 0', "", '1 1 0', '1 1 1', 0, 0); + // Draw the aiming reticle for weapons that use it + // reticle_type is changed to the item we are zooming / aiming with, to decide which reticle to use + // It must be a persisted float for fading out to work properly (you let go of the zoom button for + // the view to go back to normal, so reticle_type would become 0 as we fade out) + if(spectatee_status || getstati(STAT_HEALTH) <= 0) + reticle_type = 0; // prevent reticle from showing during the respawn zoom effect or for spectators + else if(activeweapon && (button_zoom || zoomscript_caught)) + reticle_type = 2; // weapon zoom + else if(button_zoom || zoomscript_caught) + reticle_type = 1; // normal zoom + + if (reticle_type) + { + if(cvar("cl_reticle_stretch")) + { + reticle_size_x = vid_conwidth; + reticle_size_y = vid_conheight; + reticle_pos_x = 0; + reticle_pos_y = 0; + } + else + { + reticle_size_x = max(vid_conwidth, vid_conheight); + reticle_size_y = max(vid_conwidth, vid_conheight); + reticle_pos_x = (vid_conwidth - reticle_size_x) / 2; + reticle_pos_y = (vid_conheight - reticle_size_y) / 2; + } + + f = current_zoomfraction; + if(zoomscript_caught) + f = 1; + if(cvar("cl_reticle_item_normal")) + { + if(reticle_type == 1 && f) + drawpic(reticle_pos, "gfx/reticle_normal", reticle_size, '1 1 1', f * cvar("cl_reticle_item_normal"), DRAWFLAG_NORMAL); + } + if(cvar("cl_reticle_item_weapon")) + { + if(reticle_type == 2 && f) + drawpic(reticle_pos, "gfx/reticle_weapon", reticle_size, '1 1 1', f * cvar("cl_reticle_item_weapon"), DRAWFLAG_NORMAL); + } + } + + // screen effects + if(cvar("hud_contents")) + { + float contentalpha_temp, incontent, liquidalpha, contentfadetime; + vector liquidcolor; + + if (getstati(STAT_VORE_EATEN)) + { + liquidalpha = cvar("hud_contents_stomach_alpha"); + liquidcolor = stov(cvar_string("hud_contents_stomach_color")); + incontent = 1; + } + else + { + switch(pointcontents(view_origin)) + { + case CONTENT_WATER: + liquidalpha = cvar("hud_contents_water_alpha"); + liquidcolor = stov(cvar_string("hud_contents_water_color")); + incontent = 1; + break; + + case CONTENT_LAVA: + liquidalpha = cvar("hud_contents_lava_alpha"); + liquidcolor = stov(cvar_string("hud_contents_lava_color")); + incontent = 1; + break; + + case CONTENT_SLIME: + liquidalpha = cvar("hud_contents_slime_alpha"); + liquidcolor = stov(cvar_string("hud_contents_slime_color")); + incontent = 1; + break; + + default: + liquidalpha = 0; + liquidcolor = '0 0 0'; + incontent = 0; + break; + } + } + + if(incontent) // fade in/out at different speeds so you can do e.g. instant fade when entering water and slow when leaving it. + { // also lets delcare previous values for blending properties, this way it isn't reset until after you have entered a different content + contentfadetime = cvar("hud_contents_fadeintime"); + liquidalpha_prev = liquidalpha; + liquidcolor_prev = liquidcolor; + } + else + contentfadetime = cvar("hud_contents_fadeouttime"); + + contentalpha_temp = bound(0, drawframetime / max(0.0001, contentfadetime), 1); + contentavgalpha = contentavgalpha * (1 - contentalpha_temp) + incontent * contentalpha_temp; + + if(contentavgalpha) + drawfill('0 0 0', '1 0 0' * vid_conwidth + '0 1 0' * vid_conheight, liquidcolor_prev, contentavgalpha * liquidalpha_prev, DRAWFLAG_NORMAL); + + if(cvar("hud_postprocessing")) + { + if(cvar("hud_contents_liquid_blur") && contentavgalpha) + { + // when inside the stomach, we use different blur settings than when we're inside other fluids + content_blurpostprocess_x = 1; + if(getstati(STAT_VORE_EATEN)) + { + content_blurpostprocess_y = contentavgalpha * cvar("hud_contents_stomach_blur"); + content_blurpostprocess_z = contentavgalpha * cvar("hud_contents_stomach_blur_alpha"); + } + else + { + content_blurpostprocess_y = contentavgalpha * cvar("hud_contents_liquid_blur"); + content_blurpostprocess_z = contentavgalpha * cvar("hud_contents_liquid_blur_alpha"); + } + } + else + { + content_blurpostprocess_x = 0; + content_blurpostprocess_y = 0; + content_blurpostprocess_z = 0; + } + } + } + + if(cvar("hud_damage")) + { + splash_size_x = max(vid_conwidth, vid_conheight); + splash_size_y = max(vid_conwidth, vid_conheight); + splash_pos_x = (vid_conwidth - splash_size_x) / 2; + splash_pos_y = (vid_conheight - splash_size_y) / 2; + + float myhealth_flash_temp; + myhealth = getstati(STAT_HEALTH); + + // fade out + myhealth_flash = max(0, myhealth_flash - cvar("hud_damage_fade_rate") * frametime); + // add new damage + myhealth_flash = bound(0, myhealth_flash + dmg_take * cvar("hud_damage_factor"), cvar("hud_damage_maxalpha")); + + float pain_threshold, pain_threshold_lower, pain_threshold_lower_health; + pain_threshold = cvar("hud_damage_pain_threshold"); + pain_threshold_lower = cvar("hud_damage_pain_threshold_lower"); + pain_threshold_lower_health = cvar("hud_damage_pain_threshold_lower_health"); + + if(pain_threshold_lower && myhealth < pain_threshold_lower_health) + { + pain_threshold = pain_threshold - max(cvar("hud_damage_pain_threshold_pulsating_min"), fabs(sin(M_PI * time / cvar("hud_damage_pain_threshold_pulsating_period")))) * pain_threshold_lower * (1 - max(0, myhealth)/pain_threshold_lower_health); + } + + myhealth_flash_temp = bound(0, myhealth_flash - pain_threshold, 1); + + if(myhealth_prev < 1) + { + if(myhealth >= 1) + { + myhealth_flash = 0; // just spawned, clear the flash immediately + myhealth_flash_temp = 0; + } + else + { + myhealth_flash += cvar("hud_damage_fade_rate") * frametime; // dead + } + } + + if(spectatee_status == -1 || intermission) + { + myhealth_flash = 0; // observing, or match ended + myhealth_flash_temp = 0; + } + + myhealth_prev = myhealth; + + if(cvar("cl_gentle_damage") || cvar("cl_gentle")) + { + if(cvar("cl_gentle_damage") == 2) + { + if(myhealth_flash < pain_threshold) // only randomize when the flash is gone + { + myhealth_gentlergb = '1 0 0' * random() + '0 1 0' * random() + '0 0 1' * random(); + } + } + else + myhealth_gentlergb = stov(cvar_string("hud_damage_gentle_color")); + + drawfill('0 0 0', '1 0 0' * vid_conwidth + '0 1 0' * vid_conheight, myhealth_gentlergb, cvar("hud_damage_gentle_alpha_multiplier") * bound(0, myhealth_flash_temp, 1) * cvar("hud_damage"), DRAWFLAG_NORMAL); + } + else + drawpic(splash_pos, "gfx/blood", splash_size, stov(cvar_string("hud_damage_color")), bound(0, myhealth_flash_temp, 1) * cvar("hud_damage"), DRAWFLAG_NORMAL); + + if(cvar("hud_postprocessing")) + { + if(cvar("hud_damage_blur") && myhealth_flash_temp) + { + damage_blurpostprocess_x = 1; + damage_blurpostprocess_y = bound(0, myhealth_flash_temp, 1) * cvar("hud_damage_blur"); + damage_blurpostprocess_z = bound(0, myhealth_flash_temp, 1) * cvar("hud_damage_blur_alpha"); + } + else + { + damage_blurpostprocess_x = 0; + damage_blurpostprocess_y = 0; + damage_blurpostprocess_z = 0; + } + } + } + + if(cvar("hud_stomach")) + { + if(getstati(STAT_VORE_EATEN)) + { + if(stomachsplash_alpha < cvar("hud_stomach")) + stomachsplash_alpha += cvar("hud_stomach_fade_in") * frametime; + else + stomachsplash_alpha = cvar("hud_stomach"); + } + else if(getstati(STAT_HEALTH) > 0) + { + if(stomachsplash_alpha > 0) + stomachsplash_alpha -= cvar("hud_stomach_fade_out") * frametime; + else + stomachsplash_alpha = 0; + } + if(getstati(STAT_HEALTH) <= 0) + stomachsplash_remove_at_respawn = 1; // schedule the effect to be removed next respawn + + if(getstati(STAT_HEALTH) > 0 && stomachsplash_remove_at_respawn) + stomachsplash_alpha = stomachsplash_remove_at_respawn = 0; // we respawned, remove the effect + if(spectatee_status == -1) + stomachsplash_alpha = 0; + + stomachsplash_alpha = bound(0, stomachsplash_alpha, 1); + drawpic(splash_pos, "gfx/food", splash_size, stov(cvar_string("hud_stomach_color")), stomachsplash_alpha, DRAWFLAG_NORMAL); + } + + if(cvar("hud_postprocessing")) + { + // all of this should be done in the engine eventually + + // disable damage blur when dead, but keep content blur + if(getstati(STAT_HEALTH) <= 0) + damage_blurpostprocess = '0 0 0'; + + // enable or disable rendering types if they are used or not + if(cvar("r_glsl_postprocess_uservec1_enable") != (cvar("hud_postprocessing_maxbluralpha") != 0)) + cvar_set("r_glsl_postprocess_uservec1_enable", ftos(cvar("hud_postprocessing_maxbluralpha") != 0)); + if(cvar("r_glsl_postprocess_uservec2_enable") != (cvar("hud_powerup") != 0)) + cvar_set("r_glsl_postprocess_uservec2_enable", ftos(cvar("hud_powerup") != 0)); + + // lets apply the postprocess effects from the previous two functions if needed + if((damage_blurpostprocess_x || content_blurpostprocess_x) && cvar("chase_active") >= 0) // not while the event chase camera is active + { + float blurradius = bound(0, damage_blurpostprocess_y + content_blurpostprocess_y, cvar("hud_postprocessing_maxblurradius")); + float bluralpha = bound(0, damage_blurpostprocess_z + content_blurpostprocess_z, cvar("hud_postprocessing_maxbluralpha")); + if(blurradius != old_blurradius || bluralpha != old_bluralpha) // reduce cvar_set spam as much as possible + { + cvar_set("r_glsl_postprocess_uservec1", strcat(ftos(blurradius), " ", ftos(bluralpha), " 0 0")); + old_blurradius = blurradius; + old_bluralpha = bluralpha; + } + } + else if(cvar_string("r_glsl_postprocess_uservec1") != "0 0 0 0") // reduce cvar_set spam as much as possible + { + cvar_set("r_glsl_postprocess_uservec1", "0 0 0 0"); + old_blurradius = 0; + old_bluralpha = 0; + } + + float sharpen_intensity; + if (getstatf(STAT_STRENGTH_FINISHED) - time > 0) + sharpen_intensity += (getstatf(STAT_STRENGTH_FINISHED) - time); + if (getstatf(STAT_INVINCIBLE_FINISHED) - time > 0) + sharpen_intensity += (getstatf(STAT_INVINCIBLE_FINISHED) - time); + + if(cvar("hud_powerup") && sharpen_intensity > 0 && cvar("chase_active") >= 0) // not while the event chase camera is active + { + sharpen_intensity = bound(0, sharpen_intensity, 5); // powerup warning time is 5 seconds, so fade the effect from there + + if(sharpen_intensity != old_sharpen_intensity) // reduce cvar_set spam as much as possible + { + cvar_set("r_glsl_postprocess_uservec2", strcat("0 ", ftos(-sharpen_intensity * cvar("hud_powerup")), " 0 0")); + old_sharpen_intensity = sharpen_intensity; + } + } + else if(cvar_string("r_glsl_postprocess_uservec2") != "0 0 0 0") // reduce cvar_set spam as much as possible + { + cvar_set("r_glsl_postprocess_uservec2", "0 0 0 0"); + old_sharpen_intensity = 0; + } + } + + if(cvar("hud_postprocessing") && !cvar("hud_postprocessing_maxbluralpha")) + if(cvar("r_glsl_postprocess_uservec1_enable")) + { + // don't allow blur to get stuck on if we disable the cvar while damaged + cvar_set("r_glsl_postprocess_uservec1", "0 0 0 0"); + cvar_set("r_glsl_postprocess_uservec1_enable", "0"); + } + if(cvar("hud_postprocessing") && !cvar("hud_powerup")) + if(cvar("r_glsl_postprocess_uservec2_enable")) + { + // don't allow sharpen to get stuck on if we disable the cvar while powered up + cvar_set("r_glsl_postprocess_uservec2", "0 0 0 0"); + cvar_set("r_glsl_postprocess_uservec2_enable", "0"); + } + + if(cvar("hud_postprocessing")) + { + // change saturation based on the amount of armor we have + // ranges between 0.5 and 1 saturation, over 0 armor and half the armor limit + + if(cvar("hud_saturation") && armor_max && spectatee_status != -1 && getstati(STAT_HEALTH) > 0) + { + float saturation; + saturation = 0.5 + (getstati(STAT_ARMOR) / armor_max); + saturation = bound(0, saturation, 1); + + if(cvar("r_glsl_saturation") != saturation) + cvar_set("r_glsl_saturation", ftos(saturation)); + } + else if(cvar("r_glsl_saturation") != 1) + cvar_set("r_glsl_saturation", "1"); + } + + // volume cutting + if(cvar("cl_vore_cutvolume_sound") < 1 || cvar("cl_vore_cutvolume_music") < 1) + { + float volume_modify_1_target, volume_modify_2_target, volume_modify_fade; + + if(volume_modify_changed_1 != cvar("menu_volume") || volume_modify_changed_2 != cvar("menu_bgmvolume")) + { + // An ugly hack to allow the cutvolume feature to work with the menu audio sliders. + // Without it, adjusting the music or master sound sliders while fading that volume would have bad results. + // This needs to be done in a better way! Currently, changing the volume sliders will just reset the fading. + + volume_modify_default_1 = cvar("menu_volume"); + volume_modify_default_2 = cvar("menu_bgmvolume"); + + volume_modify_changed_1 = cvar("menu_volume"); + volume_modify_changed_2 = cvar("menu_bgmvolume"); + } + else + { + if(spectatee_status == -1 || intermission) + { + volume_modify_1_target = volume_modify_default_1; + volume_modify_2_target = volume_modify_default_2; + } + else if(getstati(STAT_VORE_EATEN)) + { + volume_modify_1_target = volume_modify_default_1 * cvar("cl_vore_cutvolume_sound"); + volume_modify_2_target = volume_modify_default_2 * cvar("cl_vore_cutvolume_music"); + } + else + { + volume_modify_1_target = volume_modify_default_1; + volume_modify_2_target = volume_modify_default_2; + } + volume_modify_fade = cvar("cl_vore_cutvolume_fade") * frametime; + + if(volume_modify_1 != volume_modify_1_target || volume_modify_2 != volume_modify_2_target) + { + if (volume_modify_1 > volume_modify_1_target + volume_modify_fade) + volume_modify_1 -= volume_modify_fade; + else if (volume_modify_1 < volume_modify_1_target - volume_modify_fade) + volume_modify_1 += volume_modify_fade; + else + volume_modify_1 = volume_modify_1_target; + + if (volume_modify_2 > volume_modify_2_target + volume_modify_fade) + volume_modify_2 -= volume_modify_fade; + else if (volume_modify_2 < volume_modify_2_target - volume_modify_fade) + volume_modify_2 += volume_modify_fade; + else + volume_modify_2 = volume_modify_2_target; + + cvar_set("volume", ftos(volume_modify_1)); + cvar_set("bgmvolume", ftos(volume_modify_2)); + // TODO: Setting the "volume" cvar is a bad way to go, and modifies the menu slider! We need a better way + } + } + } + // Draw the mouse cursor // NOTE: drawpic must happen after R_RenderScene for some reason //drawpic(getmousepos(), "gfx/cursor.tga", '11 14 0', '1 1 1', 1, 0); @@ -470,6 +907,7 @@ void CSQC_UpdateView(float w, float h) if(self.draw2d) self.draw2d(); self = e; + Draw_ShowNames_All(); // draw radar if( @@ -489,6 +927,84 @@ void CSQC_UpdateView(float w, float h) ) teamradar_view(); + // Draw artwork and play intermission music + if(intermission && !isdemo() && gametype != GAME_RPG && !spectatee_status) // the match has ended. Don't do this for RPG because no one wins or loses there + { + if(cvar("cl_artwork")) + { + if(artwork_image == "") + { + if(getstati(STAT_WINNING)) // we are the winner + { + if(cvar("cl_artwork_win")) + { + artwork_image = strcat("gfx/artwork_won_", ftos(floor(1 + (random() * cvar("cl_artwork_win"))))); + artwork_image = strzone(artwork_image); + } + } + else // we have lost + { + if(cvar("cl_artwork_lose")) + { + artwork_image = strcat("gfx/artwork_lost_", ftos(floor(1 + (random() * cvar("cl_artwork_lose"))))); + artwork_image = strzone(artwork_image); + } + } + } + + if(cvar("cl_artwork_stretch")) + { + artwork_size_x = vid_conwidth; + artwork_size_y = vid_conheight; + artwork_pos_x = 0; + artwork_pos_y = 0; + } + else + { + artwork_size_x = max(vid_conwidth, vid_conheight); + artwork_size_y = max(vid_conwidth, vid_conheight); + artwork_pos_x = (vid_conwidth - artwork_size_x) / 2; + artwork_pos_y = (vid_conheight - artwork_size_y) / 2; + } + + if(artwork_fade < cvar("cl_artwork_alpha") && cvar("cl_artwork_fade")) + artwork_fade += frametime * cvar("cl_artwork_fade"); + else + artwork_fade = cvar("cl_artwork_alpha"); + + if(artwork_image != "") + drawpic(artwork_pos, artwork_image, artwork_size, '1 1 1', artwork_fade, DRAWFLAG_NORMAL); + } + + if(cvar("cl_intermission") && intermission_song == "") // don't start the song each frame + { + if(getstati(STAT_WINNING)) + intermission_song = cvar_string("cl_intermission_cdtrack_win"); + else + intermission_song = cvar_string("cl_intermission_cdtrack_lose"); + if(intermission_song != "") + { + localcmd(strcat("\ncd play ", intermission_song, "\n")); + intermission_song = strzone(intermission_song); + } + } + } + else + { + artwork_fade = 0; + if(artwork_image != "") + { + strunzone(artwork_image); + artwork_image = ""; + } + + if(intermission_song != "") + { + strunzone(intermission_song); + intermission_song = ""; + } + } + // draw sbar if(cvar("r_letterbox") == 0) { if (cvar("cl_showpressedkeys")) { // draw pressed keys when spectating and playing @@ -504,6 +1020,12 @@ void CSQC_UpdateView(float w, float h) Sbar_DrawCenterPrint(); // draw centerprint messages even if viewsize >= 120 } + float weapon_clipload, weapon_clipsize, ring_scale; + + float swallow_indicator; + if(cvar("crosshair_swallowindicator")) + swallow_indicator = getstati(STAT_VORE_CANSWALLOW); + float hud; hud = getstati(STAT_HUD); @@ -511,6 +1033,38 @@ void CSQC_UpdateView(float w, float h) if(cvar("viewsize") < 120) CSQC_common_hud(); + if(cvar("cl_flash_pickup")) + if(pickup_flash_time < getstatf(STAT_LAST_PICKUP)) + { + localcmd(strcat("bf ", cvar_string("cl_flash_pickup_color"), " ", cvar_string("cl_flash_pickup"), "\n")); + pickup_flash_time = getstatf(STAT_LAST_PICKUP); + } + if(cvar("cl_flash_vore")) + { + float vore_flash_state; + if(getstati(STAT_VORE_EATEN)) + vore_flash_state = -1; + else + vore_flash_state = getstati(STAT_VORE_LOAD); + + if(vore_flash_state > vore_flash_laststate && vore_flash_state > 0) // stomach load is bigger, so we ate someone + localcmd(strcat("bf ", cvar_string("cl_flash_vore_color_pred"), " ", cvar_string("cl_flash_vore"), "\n")); + if(vore_flash_state < vore_flash_laststate && vore_flash_state < 0) // -1 means we have been eaten + localcmd(strcat("bf ", cvar_string("cl_flash_vore_color_prey"), " ", cvar_string("cl_flash_vore"), "\n")); + + vore_flash_laststate = vore_flash_state; + } + if(cvar("cl_flash_respawn")) + { + float respawn_flash_health; + respawn_flash_health = getstati(STAT_HEALTH); + + if(respawn_flash_lasthealth <= 0 && respawn_flash_health > 0) + localcmd(strcat("bf ", cvar_string("cl_flash_respawn_color"), " ", cvar_string("cl_flash_respawn"), "\n")); + + respawn_flash_lasthealth = respawn_flash_health; + } + if not(getstati(STAT_VORE_EATEN)) // crosshair is useless if we're in the stomach { // crosshair goes VERY LAST @@ -521,6 +1075,7 @@ void CSQC_UpdateView(float w, float h) wcross_origin = project_3d_to_2d(view_origin + MAX_SHOT_DISTANCE * view_forward); wcross_origin_z = 0; if(cvar("crosshair_hittest")) + if(!swallow_indicator) { vector wcross_oldorigin; wcross_oldorigin = wcross_origin; @@ -540,19 +1095,89 @@ void CSQC_UpdateView(float w, float h) shottype = SHOTTYPE_HITWORLD; string wcross_style; - wcross_style = cvar_string("crosshair"); + + if(swallow_indicator > 1) + wcross_style = "_canswallow_team.tga"; + else if(swallow_indicator > 0) + wcross_style = "_canswallow.tga"; + else if(swallow_indicator < 0) + wcross_style = "_canswallow_no.tga"; + else + wcross_style = cvar_string("crosshair"); if (wcross_style != "0") { vector wcross_color, wcross_size; string wcross_name; float wcross_alpha, wcross_scale, wcross_blur, wcross_resolution; - wcross_color_x = cvar("crosshair_color_red"); - wcross_color_y = cvar("crosshair_color_green"); - wcross_color_z = cvar("crosshair_color_blue"); + if(swallow_indicator && (cvar("crosshair_swallowindicator_color_red") || cvar("crosshair_swallowindicator_color_green") || cvar("crosshair_swallowindicator_color_blue"))) + { + wcross_color_x = cvar("crosshair_swallowindicator_color_red"); + wcross_color_y = cvar("crosshair_swallowindicator_color_green"); + wcross_color_z = cvar("crosshair_swallowindicator_color_blue"); + } + else if(cvar("crosshair_color_by_health")) + { + local float x = getstati(STAT_HEALTH); + + //x = red + //y = green + //z = blue + + wcross_color_z = 0; + + if(x > 200) + { + wcross_color_x = 0; + wcross_color_y = 1; + } + else if(x > 150) + { + wcross_color_x = 0.4 - (x-150)*0.02 * 0.4; + wcross_color_y = 0.9 + (x-150)*0.02 * 0.1; + } + else if(x > 100) + { + wcross_color_x = 1 - (x-100)*0.02 * 0.6; + wcross_color_y = 1 - (x-100)*0.02 * 0.1; + wcross_color_z = 1 - (x-100)*0.02; + } + else if(x > 50) + { + wcross_color_x = 1; + wcross_color_y = 1; + wcross_color_z = 0.2 + (x-50)*0.02 * 0.8; + } + else if(x > 20) + { + wcross_color_x = 1; + wcross_color_y = (x-20)*90/27/100; + wcross_color_z = (x-20)*90/27/100 * 0.2; + } + else + { + wcross_color_x = 1; + wcross_color_y = 0; + } + } + else + { + wcross_color_x = cvar("crosshair_color_red"); + wcross_color_y = cvar("crosshair_color_green"); + wcross_color_z = cvar("crosshair_color_blue"); + } wcross_alpha = cvar("crosshair_color_alpha"); wcross_resolution = cvar("crosshair_size"); + if(!activeweapon) + if(!swallow_indicator) + { + if(cvar("crosshair_unarmed_dim_color")) + wcross_color *= cvar("crosshair_unarmed_dim_color"); + if(cvar("crosshair_unarmed_dim_alpha")) + wcross_alpha *= cvar("crosshair_unarmed_dim_alpha"); + } + wcross_name = strcat("gfx/crosshair", wcross_style); if(cvar("crosshair_effect_scalefade")) @@ -564,6 +1189,24 @@ void CSQC_UpdateView(float w, float h) { wcross_scale = 1; } + if(swallow_indicator) + wcross_scale *= cvar("crosshair_swallowindicator_size"); + + if(cvar("crosshair_pickup")) + { + if(pickup_crosshair_time < getstatf(STAT_LAST_PICKUP)) + { + pickup_crosshair_size = 1; + pickup_crosshair_time = getstatf(STAT_LAST_PICKUP); + } + + if(pickup_crosshair_size > 0) + pickup_crosshair_size -= cvar("crosshair_pickup_speed") * frametime; + else + pickup_crosshair_size = 0; + + wcross_scale += sin(pickup_crosshair_size) * cvar("crosshair_pickup"); + } if(shottype == SHOTTYPE_HITENEMY) wcross_scale *= cvar("crosshair_hittest"); // is not queried if hittest is 0 @@ -654,6 +1297,18 @@ void CSQC_UpdateView(float w, float h) wcross_size = drawgetimagesize(wcross_name) * wcross_scale; CROSSHAIR_DRAW(wcross_resolution, wcross_name, wcross_alpha * f); wcross_name_alpha_goal_prev = f; + + // ring around crosshair representing ammo left in weapon clip + weapon_clipload = getstati(STAT_WEAPON_CLIPLOAD); + a = cvar("crosshair_ring_alpha"); + if (weapon_clipload && a) + if (!swallow_indicator) + { + weapon_clipsize = getstati(STAT_WEAPON_CLIPSIZE); + ring_scale = cvar("crosshair_ring_size"); + f = bound(0, weapon_clipload / weapon_clipsize, 1); + DrawCircleClippedPic(wcross_origin, wcross_size_x * ring_scale, "gfx/crosshair_ring.tga", f, wcross_color, wcross_alpha * a, DRAWFLAG_ADDITIVE); + } } } else @@ -678,30 +1333,6 @@ void CSQC_UpdateView(float w, float h) } } - // Draw Artwork - if(intermission && !isdemo()) // match has ended - { - //if(getstati(STAT_WINNING)) - //localcmd("disconnect\n"); - - if(cvar("cl_artwork_stretch")) - { - artwork_size_x = vid_conwidth; - artwork_size_y = vid_conheight; - artwork_pos_x = 0; - artwork_pos_y = 0; - } - else - { - artwork_size_x = max(vid_conwidth, vid_conheight); - artwork_size_y = max(vid_conwidth, vid_conheight); - artwork_pos_x = (vid_conwidth - artwork_size_x) / 2; - artwork_pos_y = (vid_conheight - artwork_size_y) / 2; - } - - drawpic(artwork_pos, "gfx/hslimage", artwork_size, '1 1 1', 1, DRAWFLAG_NORMAL); - } - if(NextFrameCommand) { localcmd("\n", NextFrameCommand, "\n");