X-Git-Url: http://git.xonotic.org/?a=blobdiff_plain;f=qcsrc%2Fclient%2FView.qc;h=70c9ae65ea6ba4c1e743f2a563d2a8bff85b8cce;hb=845401fd312c66c059aaee1772ac5d79555ab4fc;hp=5e162cb7c96fe4c4267592ff482f4726e85f8344;hpb=a5b077eb799e456094034cdc0dd0d5b5a7e1119e;p=xonotic%2Fxonotic-data.pk3dir.git diff --git a/qcsrc/client/View.qc b/qcsrc/client/View.qc index 5e162cb7c..70c9ae65e 100644 --- a/qcsrc/client/View.qc +++ b/qcsrc/client/View.qc @@ -3,7 +3,7 @@ vector polyline[16]; void Porto_Draw() { vector p, dir, ang, q, nextdir; - float idx, portal_number, portal1_idx; + float portal_number, portal1_idx; if(activeweapon != WEP_PORTO || spectatee_status || gametype == MAPINFO_TYPE_NEXBALL) return; @@ -27,14 +27,14 @@ void Porto_Draw() p = view_origin; polyline[0] = p; - idx = 1; + int idx = 1; portal_number = 0; nextdir = dir; - for(;;) + for(0;;) { dir = nextdir; - traceline(p, p + 65536 * dir, TRUE, porto); + traceline(p, p + 65536 * dir, true, porto); if(trace_dphitq3surfaceflags & Q3SURFACEFLAG_NOIMPACT) return; nextdir = dir - 2 * (dir * trace_plane_normal) * trace_plane_normal; // mirror dir at trace_plane_normal @@ -47,7 +47,7 @@ void Porto_Draw() continue; ++portal_number; ang = vectoangles2(trace_plane_normal, dir); - ang_x = -ang_x; + ang_x = -ang.x; makevectors(ang); if(!CheckWireframeBox(porto, p - 48 * v_right - 48 * v_up + 16 * v_forward, 96 * v_right, 96 * v_up, 96 * v_forward)) return; @@ -162,13 +162,13 @@ vector GetCurrentFov(float fov) else setsensitivityscale(1); - makevectors(view_angles); - - if(autocvar_cl_velocityzoom && autocvar_cl_velocityzoom_type) // _type = 0 disables velocity zoom too + if(autocvar_cl_velocityzoom_enabled && autocvar_cl_velocityzoom_type) // _type = 0 disables velocity zoom too { if(intermission) { curspeed = 0; } else { + + makevectors(view_angles); v = pmove_vel; if(csqcplayer) v = csqcplayer.velocity; @@ -183,7 +183,7 @@ vector GetCurrentFov(float fov) velocityzoom = bound(0, drawframetime / max(0.000000001, autocvar_cl_velocityzoom_time), 1); // speed at which the zoom adapts to player velocity avgspeed = avgspeed * (1 - velocityzoom) + (curspeed / autocvar_cl_velocityzoom_speed) * velocityzoom; - velocityzoom = exp(float2range11(avgspeed * -autocvar_cl_velocityzoom / 1) * 1); + velocityzoom = exp(float2range11(avgspeed * -autocvar_cl_velocityzoom_factor / 1) * 1); //print(ftos(avgspeed), " avgspeed, ", ftos(curspeed), " curspeed, ", ftos(velocityzoom), " return\n"); // for debugging } @@ -202,8 +202,8 @@ vector GetCurrentFov(float fov) vector GetOrthoviewFOV(vector ov_worldmin, vector ov_worldmax, vector ov_mid, vector ov_org) { float fovx, fovy; - float width = (ov_worldmax_x - ov_worldmin_x); - float height = (ov_worldmax_y - ov_worldmin_y); + float width = (ov_worldmax.x - ov_worldmin.x); + float height = (ov_worldmax.y - ov_worldmin.y); float distance_to_middle_of_world = vlen(ov_mid - ov_org); fovx = atan2(width/2, distance_to_middle_of_world) / M_PI * 360.0; fovy = atan2(height/2, distance_to_middle_of_world) / M_PI * 360.0; @@ -230,10 +230,10 @@ float wcross_ring_prev; entity trueaim; entity trueaim_rifle; -#define SHOTTYPE_HITTEAM 1 -#define SHOTTYPE_HITOBSTRUCTION 2 -#define SHOTTYPE_HITWORLD 3 -#define SHOTTYPE_HITENEMY 4 +const float SHOTTYPE_HITTEAM = 1; +const float SHOTTYPE_HITOBSTRUCTION = 2; +const float SHOTTYPE_HITWORLD = 3; +const float SHOTTYPE_HITENEMY = 4; void TrueAim_Init() { @@ -328,16 +328,16 @@ float TrueAimCheck() if(vlen(trueaimpoint - traceorigin) < g_trueaim_minrange) trueaimpoint = traceorigin + view_forward * g_trueaim_minrange; - if(vecs_x > 0) - vecs_y = -vecs_y; + if(vecs.x > 0) + vecs_y = -vecs.y; else vecs = '0 0 0'; - dv = view_right * vecs_y + view_up * vecs_z; + dv = view_right * vecs.y + view_up * vecs.z; w_shotorg = traceorigin + dv; // now move the vecs forward as much as requested if possible - tracebox(w_shotorg, mi, ma, w_shotorg + view_forward * (vecs_x + nudge), MOVE_NORMAL, ta); // FIXME this MOVE_NORMAL part will misbehave a little in csqc + tracebox(w_shotorg, mi, ma, w_shotorg + view_forward * (vecs.x + nudge), MOVE_NORMAL, ta); // FIXME this MOVE_NORMAL part will misbehave a little in csqc w_shotorg = trace_endpos - view_forward * nudge; tracebox(w_shotorg, mi, ma, trueaimpoint, MOVE_NORMAL, ta); @@ -373,11 +373,9 @@ void CSQC_RAPTOR_HUD(); vector freeze_org, freeze_ang; entity nightvision_noise, nightvision_noise2; -#define MAX_TIME_DIFF 5 +const float MAX_TIME_DIFF = 5; float pickup_crosshair_time, pickup_crosshair_size; -float hit_time, typehit_time; -float nextsound_hit_time, nextsound_typehit_time; -float hitindication_crosshair_time, hitindication_crosshair_size; +float hitindication_crosshair_size; float use_vortex_chargepool; float myhealth, myhealth_prev; @@ -392,24 +390,589 @@ float contentavgalpha, liquidalpha_prev; vector liquidcolor_prev; float eventchase_current_distance; +float eventchase_running; +float WantEventchase() +{ + if(autocvar_cl_orthoview) + return false; + if(intermission) + return true; + if(spectatee_status >= 0) + { + if(autocvar_cl_eventchase_nexball && gametype == MAPINFO_TYPE_NEXBALL && !(WepSet_GetFromStat() & WepSet_FromWeapon(WEP_PORTO))) + return true; + if(autocvar_cl_eventchase_death && (getstati(STAT_HEALTH) <= 0)) + { + if(autocvar_cl_eventchase_death == 2) + { + // don't stop eventchase once it's started (even if velocity changes afterwards) + if(self.velocity == '0 0 0' || eventchase_running) + return true; + } + else return true; + } + } + return false; +} vector damage_blurpostprocess, content_blurpostprocess; float checkfail[16]; -float rainbow_last_flicker; -vector rainbow_prev_color; +float unaccounted_damage = 0; +void UpdateDamage() +{ + // accumulate damage with each stat update + static float damage_total_prev = 0; + float damage_total = getstati(STAT_DAMAGE_DEALT_TOTAL); + float unaccounted_damage_new = COMPARE_INCREASING(damage_total, damage_total_prev); + damage_total_prev = damage_total; + + static float damage_dealt_time_prev = 0; + float damage_dealt_time = getstatf(STAT_HIT_TIME); + if (damage_dealt_time != damage_dealt_time_prev) + { + unaccounted_damage += unaccounted_damage_new; + dprint("dmg total: ", ftos(unaccounted_damage), " (+", ftos(unaccounted_damage_new), ")", "\n"); + } + damage_dealt_time_prev = damage_dealt_time; + + // prevent hitsound when switching spectatee + static float spectatee_status_prev = 0; + if (spectatee_status != spectatee_status_prev) + unaccounted_damage = 0; + spectatee_status_prev = spectatee_status; +} + +void UpdateHitsound() +{ + // varying sound pitch + + static float hitsound_time_prev = 0; + // HACK: the only way to get the arc to sound consistent with pitch shift is to ignore cl_hitsound_antispam_time + float arc_hack = activeweapon == WEP_ARC && autocvar_cl_hitsound >= 2; + if (arc_hack || COMPARE_INCREASING(time, hitsound_time_prev) > autocvar_cl_hitsound_antispam_time) + { + if (autocvar_cl_hitsound && unaccounted_damage) + { + // customizable gradient function that crosses (0,a), (c,1) and asymptotically approaches b + float a = autocvar_cl_hitsound_max_pitch; + float b = autocvar_cl_hitsound_min_pitch; + float c = autocvar_cl_hitsound_nom_damage; + float x = unaccounted_damage; + float pitch_shift = (b*x*(a-1) + a*c*(1-b)) / (x*(a-1) + c*(1-b)); + + // if sound variation is disabled, set pitch_shift to 1 + if (autocvar_cl_hitsound == 1) + pitch_shift = 1; + + // if pitch shift is reversed, mirror in (max-min)/2 + min + if (autocvar_cl_hitsound == 3) + { + float mirror_value = (a-b)/2 + b; + pitch_shift = mirror_value + (mirror_value - pitch_shift); + } + + dprint("dmg total (dmg): ", ftos(unaccounted_damage), " , pitch shift: ", ftos(pitch_shift), "\n"); + + // todo: avoid very long and very short sounds from wave stretching using different sound files? seems unnecessary + // todo: normalize sound pressure levels? seems unnecessary + + sound7(world, CH_INFO, "misc/hit.wav", VOL_BASE, ATTN_NONE, pitch_shift * 100, 0); + } + unaccounted_damage = 0; + hitsound_time_prev = time; + } + + static float typehit_time_prev = 0; + float typehit_time = getstatf(STAT_TYPEHIT_TIME); + if (COMPARE_INCREASING(typehit_time, typehit_time_prev) > autocvar_cl_hitsound_antispam_time) + { + sound(world, CH_INFO, "misc/typehit.wav", VOL_BASE, ATTN_NONE); + typehit_time_prev = typehit_time; + } +} + +void UpdateCrosshair() +{ + static float rainbow_last_flicker; + static vector rainbow_prev_color; + entity e = self; + float f, i, j; + vector v; + if(getstati(STAT_FROZEN)) + drawfill('0 0 0', eX * vid_conwidth + eY * vid_conheight, ((getstatf(STAT_REVIVE_PROGRESS)) ? ('0.25 0.90 1' + ('1 0 0' * getstatf(STAT_REVIVE_PROGRESS)) + ('0 1 1' * getstatf(STAT_REVIVE_PROGRESS) * -1)) : '0.25 0.90 1'), autocvar_hud_colorflash_alpha, DRAWFLAG_ADDITIVE); + else if (getstatf(STAT_HEALING_ORB)>time) + drawfill('0 0 0', eX * vid_conwidth + eY * vid_conheight, Nade_Color(NADE_TYPE_HEAL), autocvar_hud_colorflash_alpha*getstatf(STAT_HEALING_ORB_ALPHA), DRAWFLAG_ADDITIVE); + if(!intermission) + if(getstatf(STAT_NADE_TIMER) && autocvar_cl_nade_timer) // give nade top priority, as it's a matter of life and death + { + DrawCircleClippedPic(eX * 0.5 * vid_conwidth + eY * 0.6 * vid_conheight, 0.1 * vid_conheight, "gfx/crosshair_ring.tga", getstatf(STAT_NADE_TIMER), '0.25 0.90 1' + ('1 0 0' * getstatf(STAT_NADE_TIMER)) - ('0 1 1' * getstatf(STAT_NADE_TIMER)), autocvar_hud_colorflash_alpha, DRAWFLAG_ADDITIVE); + drawstring_aspect(eY * 0.64 * vid_conheight, ((autocvar_cl_nade_timer == 2) ? _("Nade timer") : ""), eX * vid_conwidth + eY * 0.025 * vid_conheight, '1 1 1', 1, DRAWFLAG_NORMAL); + } + else if(getstatf(STAT_REVIVE_PROGRESS)) + { + DrawCircleClippedPic(eX * 0.5 * vid_conwidth + eY * 0.6 * vid_conheight, 0.1 * vid_conheight, "gfx/crosshair_ring.tga", getstatf(STAT_REVIVE_PROGRESS), '0.25 0.90 1', autocvar_hud_colorflash_alpha, DRAWFLAG_ADDITIVE); + drawstring_aspect(eY * 0.64 * vid_conheight, _("Revival progress"), eX * vid_conwidth + eY * 0.025 * vid_conheight, '1 1 1', 1, DRAWFLAG_NORMAL); + } + + if(autocvar_r_letterbox == 0) + if(autocvar_viewsize < 120) + CSQC_common_hud(); + + // crosshair goes VERY LAST + if(!scoreboard_active && !camera_active && intermission != 2 && spectatee_status != -1 && hud == HUD_NORMAL) + { + if (!autocvar_crosshair_enabled) // main toggle for crosshair rendering + return; + + string wcross_style; + float wcross_alpha, wcross_resolution; + wcross_style = autocvar_crosshair; + if (wcross_style == "0") + return; + wcross_resolution = autocvar_crosshair_size; + if (wcross_resolution == 0) + return; + wcross_alpha = autocvar_crosshair_alpha; + if (wcross_alpha == 0) + return; + + // TrueAim check + float shottype; + + // wcross_origin = '0.5 0 0' * vid_conwidth + '0 0.5 0' * vid_conheight; + wcross_origin = project_3d_to_2d(view_origin + MAX_SHOT_DISTANCE * view_forward); + wcross_origin_z = 0; + if(autocvar_crosshair_hittest) + { + vector wcross_oldorigin; + wcross_oldorigin = wcross_origin; + shottype = TrueAimCheck(); + if(shottype == SHOTTYPE_HITWORLD) + { + v = wcross_origin - wcross_oldorigin; + v.x /= vid_conwidth; + v.y /= vid_conheight; + if(vlen(v) > 0.01) + shottype = SHOTTYPE_HITOBSTRUCTION; + } + if(!autocvar_crosshair_hittest_showimpact) + wcross_origin = wcross_oldorigin; + } + else + shottype = SHOTTYPE_HITWORLD; + + vector wcross_color = '0 0 0', wcross_size = '0 0 0'; + string wcross_name = ""; + float wcross_scale, wcross_blur; + + if(autocvar_crosshair_per_weapon || (autocvar_crosshair_color_special == 1)) + { + e = get_weaponinfo(switchingweapon); + if(e) + { + if(autocvar_crosshair_per_weapon) + { + // WEAPONTODO: access these through some general settings (with non-balance config settings) + //wcross_resolution *= cvar(strcat("crosshair_", wcross_wep, "_size")); + //if (wcross_resolution == 0) + //return; + + //wcross_style = cvar_string(strcat("crosshair_", wcross_wep)); + wcross_resolution *= e.w_crosshair_size; + wcross_name = e.w_crosshair; + } + } + } + + if(wcross_name == "") + wcross_name = strcat("gfx/crosshair", wcross_style); + + // MAIN CROSSHAIR COLOR DECISION + switch(autocvar_crosshair_color_special) + { + case 1: // crosshair_color_per_weapon + { + if(e) + { + wcross_color = e.wpcolor; + break; + } + else { goto normalcolor; } + } + + case 2: // crosshair_color_by_health + { + 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; + } + break; + } + + case 3: // crosshair_color_rainbow + { + if(time >= rainbow_last_flicker) + { + rainbow_prev_color = randomvec() * autocvar_crosshair_color_special_rainbow_brightness; + rainbow_last_flicker = time + autocvar_crosshair_color_special_rainbow_delay; + } + wcross_color = rainbow_prev_color; + break; + } + :normalcolor + default: { wcross_color = stov(autocvar_crosshair_color); break; } + } + + if(autocvar_crosshair_effect_scalefade) + { + wcross_scale = wcross_resolution; + wcross_resolution = 1; + } + else + { + wcross_scale = 1; + } + + if(autocvar_crosshair_pickup) + { + float stat_pickup_time = getstatf(STAT_LAST_PICKUP); + + if(pickup_crosshair_time < stat_pickup_time) + { + if(time - stat_pickup_time < MAX_TIME_DIFF) // don't trigger the animation if it's too old + pickup_crosshair_size = 1; + + pickup_crosshair_time = stat_pickup_time; + } + + if(pickup_crosshair_size > 0) + pickup_crosshair_size -= autocvar_crosshair_pickup_speed * frametime; + else + pickup_crosshair_size = 0; + + wcross_scale += sin(pickup_crosshair_size) * autocvar_crosshair_pickup; + } + + // todo: make crosshair hit indication dependent on damage dealt + if(autocvar_crosshair_hitindication) + { + vector hitindication_color = ((autocvar_crosshair_color_special == 1) ? stov(autocvar_crosshair_hitindication_per_weapon_color) : stov(autocvar_crosshair_hitindication_color)); + + if(unaccounted_damage) + { + hitindication_crosshair_size = 1; + } + + if(hitindication_crosshair_size > 0) + hitindication_crosshair_size -= autocvar_crosshair_hitindication_speed * frametime; + else + hitindication_crosshair_size = 0; + + wcross_scale += sin(hitindication_crosshair_size) * autocvar_crosshair_hitindication; + wcross_color.x += sin(hitindication_crosshair_size) * hitindication_color.x; + wcross_color.y += sin(hitindication_crosshair_size) * hitindication_color.y; + wcross_color.z += sin(hitindication_crosshair_size) * hitindication_color.z; + } + + if(shottype == SHOTTYPE_HITENEMY) + wcross_scale *= autocvar_crosshair_hittest; // is not queried if hittest is 0 + if(shottype == SHOTTYPE_HITTEAM) + wcross_scale /= autocvar_crosshair_hittest; // is not queried if hittest is 0 + + f = fabs(autocvar_crosshair_effect_time); + if(wcross_scale != wcross_scale_goal_prev || wcross_alpha != wcross_alpha_goal_prev || wcross_color != wcross_color_goal_prev) + { + wcross_changedonetime = time + f; + } + if(wcross_name != wcross_name_goal_prev || wcross_resolution != wcross_resolution_goal_prev) + { + wcross_name_changestarttime = time; + wcross_name_changedonetime = time + f; + if(wcross_name_goal_prev_prev) + strunzone(wcross_name_goal_prev_prev); + wcross_name_goal_prev_prev = wcross_name_goal_prev; + wcross_name_goal_prev = strzone(wcross_name); + wcross_name_alpha_goal_prev_prev = wcross_name_alpha_goal_prev; + wcross_resolution_goal_prev_prev = wcross_resolution_goal_prev; + wcross_resolution_goal_prev = wcross_resolution; + } + + wcross_scale_goal_prev = wcross_scale; + wcross_alpha_goal_prev = wcross_alpha; + wcross_color_goal_prev = wcross_color; + + if(shottype == SHOTTYPE_HITTEAM || (shottype == SHOTTYPE_HITOBSTRUCTION && autocvar_crosshair_hittest_blur && !autocvar_chase_active)) + { + wcross_blur = 1; + wcross_alpha *= 0.75; + } + else + wcross_blur = 0; + // *_prev is at time-frametime + // * is at wcross_changedonetime+f + // what do we have at time? + if(time < wcross_changedonetime) + { + f = frametime / (wcross_changedonetime - time + frametime); + wcross_scale = f * wcross_scale + (1 - f) * wcross_scale_prev; + wcross_alpha = f * wcross_alpha + (1 - f) * wcross_alpha_prev; + wcross_color = f * wcross_color + (1 - f) * wcross_color_prev; + } + + wcross_scale_prev = wcross_scale; + wcross_alpha_prev = wcross_alpha; + wcross_color_prev = wcross_color; + + wcross_scale *= 1 - autocvar__menu_alpha; + wcross_alpha *= 1 - autocvar__menu_alpha; + wcross_size = draw_getimagesize(wcross_name) * wcross_scale; + + if(wcross_scale >= 0.001 && wcross_alpha >= 0.001) + { + // crosshair rings for weapon stats + if (autocvar_crosshair_ring || autocvar_crosshair_ring_reload) + { + // declarations and stats + float ring_value = 0, ring_scale = 0, ring_alpha = 0, ring_inner_value = 0, ring_inner_alpha = 0; + string ring_image = string_null, ring_inner_image = string_null; + vector ring_rgb = '0 0 0', ring_inner_rgb = '0 0 0'; + + ring_scale = autocvar_crosshair_ring_size; + + float weapon_clipload, weapon_clipsize; + weapon_clipload = getstati(STAT_WEAPON_CLIPLOAD); + weapon_clipsize = getstati(STAT_WEAPON_CLIPSIZE); + + float ok_ammo_charge, ok_ammo_chargepool; + ok_ammo_charge = getstatf(STAT_OK_AMMO_CHARGE); + ok_ammo_chargepool = getstatf(STAT_OK_AMMO_CHARGEPOOL); + + float vortex_charge, vortex_chargepool; + vortex_charge = getstatf(STAT_VORTEX_CHARGE); + vortex_chargepool = getstatf(STAT_VORTEX_CHARGEPOOL); + + float arc_heat = getstatf(STAT_ARC_HEAT); + + if(vortex_charge_movingavg == 0) // this should only happen if we have just loaded up the game + vortex_charge_movingavg = vortex_charge; + + + // handle the values + if (autocvar_crosshair_ring && activeweapon == WEP_VORTEX && vortex_charge && autocvar_crosshair_ring_vortex) // ring around crosshair representing velocity-dependent damage for the vortex + { + if (vortex_chargepool || use_vortex_chargepool) { + use_vortex_chargepool = 1; + ring_inner_value = vortex_chargepool; + } else { + vortex_charge_movingavg = (1 - autocvar_crosshair_ring_vortex_currentcharge_movingavg_rate) * vortex_charge_movingavg + autocvar_crosshair_ring_vortex_currentcharge_movingavg_rate * vortex_charge; + ring_inner_value = bound(0, autocvar_crosshair_ring_vortex_currentcharge_scale * (vortex_charge - vortex_charge_movingavg), 1); + } + + ring_inner_alpha = autocvar_crosshair_ring_vortex_inner_alpha; + ring_inner_rgb = eX * autocvar_crosshair_ring_vortex_inner_color_red + eY * autocvar_crosshair_ring_vortex_inner_color_green + eZ * autocvar_crosshair_ring_vortex_inner_color_blue; + ring_inner_image = "gfx/crosshair_ring_inner.tga"; + + // draw the outer ring to show the current charge of the weapon + ring_value = vortex_charge; + ring_alpha = autocvar_crosshair_ring_vortex_alpha; + ring_rgb = wcross_color; + ring_image = "gfx/crosshair_ring_nexgun.tga"; + } + else if (autocvar_crosshair_ring && activeweapon == WEP_MINE_LAYER && minelayer_maxmines && autocvar_crosshair_ring_minelayer) + { + ring_value = bound(0, getstati(STAT_LAYED_MINES) / minelayer_maxmines, 1); // if you later need to use the count of bullets in another place, then add a float for it. For now, no need to. + ring_alpha = autocvar_crosshair_ring_minelayer_alpha; + ring_rgb = wcross_color; + ring_image = "gfx/crosshair_ring.tga"; + } + else if (activeweapon == WEP_HAGAR && getstati(STAT_HAGAR_LOAD) && autocvar_crosshair_ring_hagar) + { + ring_value = bound(0, getstati(STAT_HAGAR_LOAD) / hagar_maxrockets, 1); + ring_alpha = autocvar_crosshair_ring_hagar_alpha; + ring_rgb = wcross_color; + ring_image = "gfx/crosshair_ring.tga"; + } + else if (ok_ammo_charge) + { + ring_value = ok_ammo_chargepool; + ring_alpha = autocvar_crosshair_ring_reload_alpha; + ring_rgb = wcross_color; + ring_image = "gfx/crosshair_ring.tga"; + } + else if(autocvar_crosshair_ring_reload && weapon_clipsize) // forces there to be only an ammo ring + { + ring_value = bound(0, weapon_clipload / weapon_clipsize, 1); + ring_scale = autocvar_crosshair_ring_reload_size; + ring_alpha = autocvar_crosshair_ring_reload_alpha; + ring_rgb = wcross_color; + + // Note: This is to stop Taoki from complaining that the image doesn't match all potential balances. + // if a new image for another weapon is added, add the code (and its respective file/value) here + if ((activeweapon == WEP_RIFLE) && (weapon_clipsize == 80)) + ring_image = "gfx/crosshair_ring_rifle.tga"; + else + ring_image = "gfx/crosshair_ring.tga"; + } + else if ( autocvar_crosshair_ring && autocvar_crosshair_ring_arc && arc_heat && activeweapon == WEP_ARC ) + { + ring_value = arc_heat; + ring_alpha = (1-arc_heat)*autocvar_crosshair_ring_arc_cold_alpha + + arc_heat*autocvar_crosshair_ring_arc_hot_alpha; + ring_rgb = (1-arc_heat)*wcross_color + arc_heat*autocvar_crosshair_ring_arc_hot_color; + ring_image = "gfx/crosshair_ring.tga"; + } + + // if in weapon switch animation, fade ring out/in + if(autocvar_crosshair_effect_time > 0) + { + f = (time - wcross_name_changestarttime) / autocvar_crosshair_effect_time; + if (f >= 1) + { + wcross_ring_prev = ((ring_image) ? true : false); + } + + if(wcross_ring_prev) + { + if(f < 1) + ring_alpha *= fabs(1 - bound(0, f, 1)); + } + else + { + if(f < 1) + ring_alpha *= bound(0, f, 1); + } + } + + if (autocvar_crosshair_ring_inner && ring_inner_value) // lets draw a ring inside a ring so you can ring while you ring + DrawCircleClippedPic(wcross_origin, wcross_size.x * ring_scale, ring_inner_image, ring_inner_value, ring_inner_rgb, wcross_alpha * ring_inner_alpha, DRAWFLAG_ADDITIVE); + + if (ring_value) + DrawCircleClippedPic(wcross_origin, wcross_size.x * ring_scale, ring_image, ring_value, ring_rgb, wcross_alpha * ring_alpha, DRAWFLAG_ADDITIVE); + } + +#define CROSSHAIR_DO_BLUR(M,sz,wcross_name,wcross_alpha) \ + do \ + { \ + if(wcross_blur > 0) \ + { \ + for(i = -2; i <= 2; ++i) \ + for(j = -2; j <= 2; ++j) \ + M(i,j,sz,wcross_name,wcross_alpha*0.04); \ + } \ + else \ + { \ + M(0,0,sz,wcross_name,wcross_alpha); \ + } \ + } \ + while(0) + +#define CROSSHAIR_DRAW_SINGLE(i,j,sz,wcross_name,wcross_alpha) \ + drawpic(wcross_origin - ('0.5 0 0' * (sz * wcross_size.x + i * wcross_blur) + '0 0.5 0' * (sz * wcross_size.y + j * wcross_blur)), wcross_name, sz * wcross_size, wcross_color, wcross_alpha, DRAWFLAG_NORMAL) + +#define CROSSHAIR_DRAW(sz,wcross_name,wcross_alpha) \ + CROSSHAIR_DO_BLUR(CROSSHAIR_DRAW_SINGLE,sz,wcross_name,wcross_alpha) + + if(time < wcross_name_changedonetime && wcross_name != wcross_name_goal_prev_prev && wcross_name_goal_prev_prev) + { + f = (wcross_name_changedonetime - time) / (wcross_name_changedonetime - wcross_name_changestarttime); + wcross_size = draw_getimagesize(wcross_name_goal_prev_prev) * wcross_scale; + CROSSHAIR_DRAW(wcross_resolution_goal_prev_prev, wcross_name_goal_prev_prev, wcross_alpha * f * wcross_name_alpha_goal_prev_prev); + f = 1 - f; + } + else + { + f = 1; + } + wcross_name_alpha_goal_prev = f; + + wcross_size = draw_getimagesize(wcross_name) * wcross_scale; + CROSSHAIR_DRAW(wcross_resolution, wcross_name, wcross_alpha * f); -#define BUTTON_3 4 -#define BUTTON_4 8 + if(autocvar_crosshair_dot) + { + vector wcross_color_old; + wcross_color_old = wcross_color; + + if((autocvar_crosshair_dot_color_custom) && (autocvar_crosshair_dot_color != "0")) + wcross_color = stov(autocvar_crosshair_dot_color); + + CROSSHAIR_DRAW(wcross_resolution * autocvar_crosshair_dot_size, "gfx/crosshairdot.tga", f * autocvar_crosshair_dot_alpha); + // FIXME why don't we use wcross_alpha here?cl_notice_run(); + wcross_color = wcross_color_old; + } + } + } + else + { + wcross_scale_prev = 0; + wcross_alpha_prev = 0; + wcross_scale_goal_prev = 0; + wcross_alpha_goal_prev = 0; + wcross_changedonetime = 0; + if(wcross_name_goal_prev) + strunzone(wcross_name_goal_prev); + wcross_name_goal_prev = string_null; + if(wcross_name_goal_prev_prev) + strunzone(wcross_name_goal_prev_prev); + wcross_name_goal_prev_prev = string_null; + wcross_name_changestarttime = 0; + wcross_name_changedonetime = 0; + wcross_name_alpha_goal_prev = 0; + wcross_name_alpha_goal_prev_prev = 0; + wcross_resolution_goal_prev = 0; + wcross_resolution_goal_prev_prev = 0; + } +} + +const float BUTTON_3 = 4; +const float BUTTON_4 = 8; float cl_notice_run(); float prev_myteam; void CSQC_UpdateView(float w, float h) { entity e; float fov; - float f, i, j; - vector v; + float f; + int i; vector vf_size, vf_min; float a; @@ -445,8 +1008,8 @@ void CSQC_UpdateView(float w, float h) vf_size = getpropertyvec(VF_SIZE); vf_min = getpropertyvec(VF_MIN); - vid_width = vf_size_x; - vid_height = vf_size_y; + vid_width = vf_size.x; + vid_height = vf_size.y; vector reticle_pos = '0 0 0', reticle_size = '0 0 0'; vector splash_pos = '0 0 0', splash_size = '0 0 0'; @@ -455,12 +1018,7 @@ void CSQC_UpdateView(float w, float h) CSQCPlayer_SetCamera(); -#ifdef COMPAT_XON050_ENGINE - if(spectatee_status) - myteam = GetPlayerColor(spectatee_status - 1); - else -#endif - myteam = GetPlayerColor(player_localentnum - 1); + myteam = GetPlayerColor(player_localentnum - 1); if(myteam != prev_myteam) { @@ -487,24 +1045,25 @@ void CSQC_UpdateView(float w, float h) { // no zoom while dead or in intermission please localcmd("-zoom\n"); - button_zoom = FALSE; + button_zoom = false; } // event chase camera if(autocvar_chase_active <= 0) // greater than 0 means it's enabled manually, and this code is skipped { - WepSet weapons_stat = WepSet_GetFromStat(); - if(((spectatee_status >= 0 && (autocvar_cl_eventchase_death && is_dead)) || intermission) && !autocvar_cl_orthoview || (autocvar_cl_eventchase_nexball && gametype == MAPINFO_TYPE_NEXBALL && !(weapons_stat & WepSet_FromWeapon(WEP_PORTO)))) + if(WantEventchase()) { + eventchase_running = true; + // make special vector since we can't use view_origin (It is one frame old as of this code, it gets set later with the results this code makes.) vector current_view_origin = (csqcplayer ? csqcplayer.origin : pmove_org); // detect maximum viewoffset and use it if(autocvar_cl_eventchase_viewoffset) { - WarpZone_TraceLine(current_view_origin, current_view_origin + autocvar_cl_eventchase_viewoffset + ('0 0 1' * autocvar_cl_eventchase_maxs_z), MOVE_WORLDONLY, self); + WarpZone_TraceLine(current_view_origin, current_view_origin + autocvar_cl_eventchase_viewoffset + ('0 0 1' * autocvar_cl_eventchase_maxs.z), MOVE_WORLDONLY, self); if(trace_fraction == 1) { current_view_origin += autocvar_cl_eventchase_viewoffset; } - else { current_view_origin_z += max(0, (trace_endpos_z - current_view_origin_z) - autocvar_cl_eventchase_maxs_z); } + else { current_view_origin.z += max(0, (trace_endpos.z - current_view_origin.z) - autocvar_cl_eventchase_maxs.z); } } // We must enable chase_active to get a third person view (weapon viewmodel hidden and own player model showing). @@ -528,7 +1087,7 @@ void CSQC_UpdateView(float w, float h) { eventchase_target_origin = (current_view_origin - (v_forward * eventchase_current_distance)); WarpZone_TraceLine(current_view_origin, eventchase_target_origin, MOVE_WORLDONLY, self); - setproperty(VF_ORIGIN, (trace_endpos - (v_forward * autocvar_cl_eventchase_mins_z))); + setproperty(VF_ORIGIN, (trace_endpos - (v_forward * autocvar_cl_eventchase_mins.z))); } else { setproperty(VF_ORIGIN, trace_endpos); } @@ -536,6 +1095,7 @@ void CSQC_UpdateView(float w, float h) } else if(autocvar_chase_active < 0) // time to disable chase_active if it was set by this code { + eventchase_running = false; cvar_set("chase_active", "0"); eventchase_current_distance = 0; // start from 0 next time } @@ -572,30 +1132,30 @@ void CSQC_UpdateView(float w, float h) ov_worldmin = mi_picmin; ov_worldmax = mi_picmax; - float ov_width = (ov_worldmax_x - ov_worldmin_x); - float ov_height = (ov_worldmax_y - ov_worldmin_y); + float ov_width = (ov_worldmax.x - ov_worldmin.x); + float ov_height = (ov_worldmax.y - ov_worldmin.y); float ov_distance = (max(vid_width, vid_height) * max(ov_width, ov_height)); ov_mid = ((ov_worldmax + ov_worldmin) * 0.5); - ov_org = vec3(ov_mid_x, ov_mid_y, (ov_mid_z + ov_distance)); + ov_org = vec3(ov_mid.x, ov_mid.y, (ov_mid.z + ov_distance)); float ov_nearest = vlen(ov_org - vec3( - bound(ov_worldmin_x, ov_org_x, ov_worldmax_x), - bound(ov_worldmin_y, ov_org_y, ov_worldmax_y), - bound(ov_worldmin_z, ov_org_z, ov_worldmax_z) + bound(ov_worldmin.x, ov_org.x, ov_worldmax.x), + bound(ov_worldmin.y, ov_org.y, ov_worldmax.y), + bound(ov_worldmin.z, ov_org.z, ov_worldmax.z) )); float ov_furthest = 0; float dist = 0; - if((dist = vlen(vec3(ov_worldmin_x, ov_worldmin_y, ov_worldmin_z) - ov_org)) > ov_furthest) { ov_furthest = dist; } - if((dist = vlen(vec3(ov_worldmax_x, ov_worldmin_y, ov_worldmin_z) - ov_org)) > ov_furthest) { ov_furthest = dist; } - if((dist = vlen(vec3(ov_worldmin_x, ov_worldmax_y, ov_worldmin_z) - ov_org)) > ov_furthest) { ov_furthest = dist; } - if((dist = vlen(vec3(ov_worldmin_x, ov_worldmin_y, ov_worldmax_z) - ov_org)) > ov_furthest) { ov_furthest = dist; } - if((dist = vlen(vec3(ov_worldmax_x, ov_worldmax_y, ov_worldmin_z) - ov_org)) > ov_furthest) { ov_furthest = dist; } - if((dist = vlen(vec3(ov_worldmin_x, ov_worldmax_y, ov_worldmax_z) - ov_org)) > ov_furthest) { ov_furthest = dist; } - if((dist = vlen(vec3(ov_worldmax_x, ov_worldmin_y, ov_worldmax_z) - ov_org)) > ov_furthest) { ov_furthest = dist; } - if((dist = vlen(vec3(ov_worldmax_x, ov_worldmax_y, ov_worldmax_z) - ov_org)) > ov_furthest) { ov_furthest = dist; } + if((dist = vlen(vec3(ov_worldmin.x, ov_worldmin.y, ov_worldmin.z) - ov_org)) > ov_furthest) { ov_furthest = dist; } + if((dist = vlen(vec3(ov_worldmax.x, ov_worldmin.y, ov_worldmin.z) - ov_org)) > ov_furthest) { ov_furthest = dist; } + if((dist = vlen(vec3(ov_worldmin.x, ov_worldmax.y, ov_worldmin.z) - ov_org)) > ov_furthest) { ov_furthest = dist; } + if((dist = vlen(vec3(ov_worldmin.x, ov_worldmin.y, ov_worldmax.z) - ov_org)) > ov_furthest) { ov_furthest = dist; } + if((dist = vlen(vec3(ov_worldmax.x, ov_worldmax.y, ov_worldmin.z) - ov_org)) > ov_furthest) { ov_furthest = dist; } + if((dist = vlen(vec3(ov_worldmin.x, ov_worldmax.y, ov_worldmax.z) - ov_org)) > ov_furthest) { ov_furthest = dist; } + if((dist = vlen(vec3(ov_worldmax.x, ov_worldmin.y, ov_worldmax.z) - ov_org)) > ov_furthest) { ov_furthest = dist; } + if((dist = vlen(vec3(ov_worldmax.x, ov_worldmax.y, ov_worldmax.z) - ov_org)) > ov_furthest) { ov_furthest = dist; } cvar_settemp("r_nearclip", ftos(ov_nearest)); cvar_settemp("r_farclip_base", ftos(ov_furthest)); @@ -713,13 +1273,13 @@ void CSQC_UpdateView(float w, float h) if(button_zoom && autocvar_cl_unpress_zoom_on_weapon_switch) { localcmd("-zoom\n"); - button_zoom = FALSE; + button_zoom = false; } if(autocvar_cl_unpress_attack_on_weapon_switch) { localcmd("-fire\n"); localcmd("-fire2\n"); - button_attack2 = FALSE; + button_attack2 = false; } } if(last_activeweapon != activeweapon) @@ -735,15 +1295,9 @@ void CSQC_UpdateView(float w, float h) // ALWAYS Clear Current Scene First clearscene(); -#ifdef WORKAROUND_XON010 - if(checkextension("DP_CSQC_ROTATEMOVES")) - { -#endif + setproperty(VF_ORIGIN, view_origin); setproperty(VF_ANGLES, view_angles); -#ifdef WORKAROUND_XON010 - } -#endif // FIXME engine bug? VF_SIZE and VF_MIN are not restored to sensible values by this setproperty(VF_SIZE, vf_size); @@ -770,7 +1324,7 @@ void CSQC_UpdateView(float w, float h) { cvar_set("chase_active", ftos(chase_active_backup)); cvar_set("cl_demo_mousegrab", "0"); - camera_active = FALSE; + camera_active = false; } } #ifdef CAMERATEST @@ -783,8 +1337,8 @@ void CSQC_UpdateView(float w, float h) chase_active_backup = autocvar_chase_active; cvar_set("chase_active", "2"); cvar_set("cl_demo_mousegrab", "1"); - camera_active = TRUE; - camera_mode = FALSE; + camera_active = true; + camera_mode = false; } // Draw the Crosshair @@ -819,10 +1373,7 @@ void CSQC_UpdateView(float w, float h) { // apply night vision effect vector tc_00, tc_01, tc_10, tc_11; - vector rgb; - rgb_x = 0; // fteqcc sucks - rgb_y = 0; // fteqcc sucks - rgb_z = 0; // fteqcc sucks + vector rgb = '0 0 0'; if(!nightvision_noise) { @@ -903,8 +1454,8 @@ void CSQC_UpdateView(float w, float h) { 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; + reticle_pos_x = (vid_conwidth - reticle_size.x) / 2; + reticle_pos_y = (vid_conheight - reticle_size.y) / 2; } if(zoomscript_caught) @@ -997,8 +1548,8 @@ void CSQC_UpdateView(float w, float h) { 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; + 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); @@ -1088,10 +1639,10 @@ void CSQC_UpdateView(float w, float h) if(cvar("r_glsl_postprocess_uservec2_enable") != e2) { cvar_set("r_glsl_postprocess_uservec2_enable", ftos(e2)); } // blur postprocess handling done first (used by hud_damage and hud_contents) - if((damage_blurpostprocess_x || content_blurpostprocess_x)) + if((damage_blurpostprocess.x || content_blurpostprocess.x)) { - float blurradius = bound(0, damage_blurpostprocess_y + content_blurpostprocess_y, autocvar_hud_postprocessing_maxblurradius); - float bluralpha = bound(0, damage_blurpostprocess_z + content_blurpostprocess_z, autocvar_hud_postprocessing_maxbluralpha); + float blurradius = bound(0, damage_blurpostprocess.y + content_blurpostprocess.y, autocvar_hud_postprocessing_maxblurradius); + float bluralpha = bound(0, damage_blurpostprocess.z + content_blurpostprocess.z, autocvar_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")); @@ -1151,464 +1702,9 @@ void CSQC_UpdateView(float w, float h) scoreboard_active = HUD_WouldDrawScoreboard(); - hit_time = getstatf(STAT_HIT_TIME); - if(hit_time > nextsound_hit_time && autocvar_cl_hitsound) - { - if(time - hit_time < MAX_TIME_DIFF) // don't play the sound if it's too old. - sound(world, CH_INFO, "misc/hit.wav", VOL_BASE, ATTEN_NONE); - - nextsound_hit_time = time + autocvar_cl_hitsound_antispam_time; - } - typehit_time = getstatf(STAT_TYPEHIT_TIME); - if(typehit_time > nextsound_typehit_time) - { - if(time - typehit_time < MAX_TIME_DIFF) // don't play the sound if it's too old. - sound(world, CH_INFO, "misc/typehit.wav", VOL_BASE, ATTEN_NONE); - - nextsound_typehit_time = time + autocvar_cl_hitsound_antispam_time; - } - - //else - { - if(gametype == MAPINFO_TYPE_FREEZETAG) - { - if(getstati(STAT_FROZEN)) - drawfill('0 0 0', eX * vid_conwidth + eY * vid_conheight, '0.25 0.90 1', autocvar_hud_colorflash_alpha, DRAWFLAG_ADDITIVE); - if(getstatf(STAT_REVIVE_PROGRESS)) - { - DrawCircleClippedPic(eX * 0.5 * vid_conwidth + eY * 0.6 * vid_conheight, 0.1 * vid_conheight, "gfx/crosshair_ring.tga", getstatf(STAT_REVIVE_PROGRESS), '0.25 0.90 1', autocvar_hud_colorflash_alpha, DRAWFLAG_ADDITIVE); - drawstring_aspect(eY * 0.64 * vid_conheight, _("Revival progress"), eX * vid_conwidth + eY * 0.025 * vid_conheight, '1 1 1', 1, DRAWFLAG_NORMAL); - } - } - - if(autocvar_r_letterbox == 0) - if(autocvar_viewsize < 120) - CSQC_common_hud(); - - // crosshair goes VERY LAST - if(!scoreboard_active && !camera_active && intermission != 2 && spectatee_status != -1 && hud == HUD_NORMAL) - { - if (!autocvar_crosshair_enabled) // main toggle for crosshair rendering - return; - - string wcross_style; - float wcross_alpha, wcross_resolution; - wcross_style = autocvar_crosshair; - if (wcross_style == "0") - return; - wcross_resolution = autocvar_crosshair_size; - if (wcross_resolution == 0) - return; - wcross_alpha = autocvar_crosshair_alpha; - if (wcross_alpha == 0) - return; - - // TrueAim check - float shottype; - - // wcross_origin = '0.5 0 0' * vid_conwidth + '0 0.5 0' * vid_conheight; - wcross_origin = project_3d_to_2d(view_origin + MAX_SHOT_DISTANCE * view_forward); - wcross_origin_z = 0; - if(autocvar_crosshair_hittest) - { - vector wcross_oldorigin; - wcross_oldorigin = wcross_origin; - shottype = TrueAimCheck(); - if(shottype == SHOTTYPE_HITWORLD) - { - v = wcross_origin - wcross_oldorigin; - v_x /= vid_conwidth; - v_y /= vid_conheight; - if(vlen(v) > 0.01) - shottype = SHOTTYPE_HITOBSTRUCTION; - } - if(!autocvar_crosshair_hittest_showimpact) - wcross_origin = wcross_oldorigin; - } - else - shottype = SHOTTYPE_HITWORLD; - - vector wcross_color = '0 0 0', wcross_size = '0 0 0'; - string wcross_name = ""; - float wcross_scale, wcross_blur; - - if(autocvar_crosshair_per_weapon || (autocvar_crosshair_color_special == 1)) - { - e = get_weaponinfo(switchingweapon); - if(e) - { - if(autocvar_crosshair_per_weapon) - { - // WEAPONTODO: access these through some general settings (with non-balance config settings) - //wcross_resolution *= cvar(strcat("crosshair_", wcross_wep, "_size")); - //if (wcross_resolution == 0) - //return; - - //wcross_style = cvar_string(strcat("crosshair_", wcross_wep)); - wcross_resolution *= e.w_crosshair_size; - wcross_name = e.w_crosshair; - } - } - } - - if(wcross_name == "") - wcross_name = strcat("gfx/crosshair", wcross_style); - - // MAIN CROSSHAIR COLOR DECISION - switch(autocvar_crosshair_color_special) - { - case 1: // crosshair_color_per_weapon - { - if(e) - { - wcross_color = e.wpcolor; - break; - } - else { goto normalcolor; } - } - - case 2: // crosshair_color_by_health - { - 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; - } - break; - } - - case 3: // crosshair_color_rainbow - { - if(time >= rainbow_last_flicker) - { - rainbow_prev_color = randomvec() * autocvar_crosshair_color_special_rainbow_brightness; - rainbow_last_flicker = time + autocvar_crosshair_color_special_rainbow_delay; - } - wcross_color = rainbow_prev_color; - break; - } - :normalcolor - default: { wcross_color = stov(autocvar_crosshair_color); break; } - } - - if(autocvar_crosshair_effect_scalefade) - { - wcross_scale = wcross_resolution; - wcross_resolution = 1; - } - else - { - wcross_scale = 1; - } - - if(autocvar_crosshair_pickup) - { - float stat_pickup_time = getstatf(STAT_LAST_PICKUP); - - if(pickup_crosshair_time < stat_pickup_time) - { - if(time - stat_pickup_time < MAX_TIME_DIFF) // don't trigger the animation if it's too old - pickup_crosshair_size = 1; - - pickup_crosshair_time = stat_pickup_time; - } - - if(pickup_crosshair_size > 0) - pickup_crosshair_size -= autocvar_crosshair_pickup_speed * frametime; - else - pickup_crosshair_size = 0; - - wcross_scale += sin(pickup_crosshair_size) * autocvar_crosshair_pickup; - } - - if(autocvar_crosshair_hitindication) - { - vector hitindication_color = ((autocvar_crosshair_color_special == 1) ? stov(autocvar_crosshair_hitindication_per_weapon_color) : stov(autocvar_crosshair_hitindication_color)); - - if(hitindication_crosshair_time < hit_time) - { - if(time - hit_time < MAX_TIME_DIFF) // don't trigger the animation if it's too old - hitindication_crosshair_size = 1; - - hitindication_crosshair_time = hit_time; - } - - if(hitindication_crosshair_size > 0) - hitindication_crosshair_size -= autocvar_crosshair_hitindication_speed * frametime; - else - hitindication_crosshair_size = 0; - - wcross_scale += sin(hitindication_crosshair_size) * autocvar_crosshair_hitindication; - wcross_color_x += sin(hitindication_crosshair_size) * hitindication_color_x; - wcross_color_y += sin(hitindication_crosshair_size) * hitindication_color_y; - wcross_color_z += sin(hitindication_crosshair_size) * hitindication_color_z; - } - - if(shottype == SHOTTYPE_HITENEMY) - wcross_scale *= autocvar_crosshair_hittest; // is not queried if hittest is 0 - if(shottype == SHOTTYPE_HITTEAM) - wcross_scale /= autocvar_crosshair_hittest; // is not queried if hittest is 0 - - f = fabs(autocvar_crosshair_effect_time); - if(wcross_scale != wcross_scale_goal_prev || wcross_alpha != wcross_alpha_goal_prev || wcross_color != wcross_color_goal_prev) - { - wcross_changedonetime = time + f; - } - if(wcross_name != wcross_name_goal_prev || wcross_resolution != wcross_resolution_goal_prev) - { - wcross_name_changestarttime = time; - wcross_name_changedonetime = time + f; - if(wcross_name_goal_prev_prev) - strunzone(wcross_name_goal_prev_prev); - wcross_name_goal_prev_prev = wcross_name_goal_prev; - wcross_name_goal_prev = strzone(wcross_name); - wcross_name_alpha_goal_prev_prev = wcross_name_alpha_goal_prev; - wcross_resolution_goal_prev_prev = wcross_resolution_goal_prev; - wcross_resolution_goal_prev = wcross_resolution; - } - - wcross_scale_goal_prev = wcross_scale; - wcross_alpha_goal_prev = wcross_alpha; - wcross_color_goal_prev = wcross_color; - - if(shottype == SHOTTYPE_HITTEAM || (shottype == SHOTTYPE_HITOBSTRUCTION && autocvar_crosshair_hittest_blur && !autocvar_chase_active)) - { - wcross_blur = 1; - wcross_alpha *= 0.75; - } - else - wcross_blur = 0; - // *_prev is at time-frametime - // * is at wcross_changedonetime+f - // what do we have at time? - if(time < wcross_changedonetime) - { - f = frametime / (wcross_changedonetime - time + frametime); - wcross_scale = f * wcross_scale + (1 - f) * wcross_scale_prev; - wcross_alpha = f * wcross_alpha + (1 - f) * wcross_alpha_prev; - wcross_color = f * wcross_color + (1 - f) * wcross_color_prev; - } - - wcross_scale_prev = wcross_scale; - wcross_alpha_prev = wcross_alpha; - wcross_color_prev = wcross_color; - - wcross_scale *= 1 - autocvar__menu_alpha; - wcross_alpha *= 1 - autocvar__menu_alpha; - wcross_size = draw_getimagesize(wcross_name) * wcross_scale; - - if(wcross_scale >= 0.001 && wcross_alpha >= 0.001) - { - // crosshair rings for weapon stats - if (autocvar_crosshair_ring || autocvar_crosshair_ring_reload) - { - // declarations and stats - float ring_value = 0, ring_scale = 0, ring_alpha = 0, ring_inner_value = 0, ring_inner_alpha = 0; - string ring_image = string_null, ring_inner_image = string_null; - vector ring_rgb = '0 0 0', ring_inner_rgb = '0 0 0'; - - ring_scale = autocvar_crosshair_ring_size; - - float weapon_clipload, weapon_clipsize; - weapon_clipload = getstati(STAT_WEAPON_CLIPLOAD); - weapon_clipsize = getstati(STAT_WEAPON_CLIPSIZE); - - float vortex_charge, vortex_chargepool; - vortex_charge = getstatf(STAT_VORTEX_CHARGE); - vortex_chargepool = getstatf(STAT_VORTEX_CHARGEPOOL); - - if(vortex_charge_movingavg == 0) // this should only happen if we have just loaded up the game - vortex_charge_movingavg = vortex_charge; - - - // handle the values - if (autocvar_crosshair_ring && activeweapon == WEP_VORTEX && vortex_charge && autocvar_crosshair_ring_vortex) // ring around crosshair representing velocity-dependent damage for the vortex - { - if (vortex_chargepool || use_vortex_chargepool) { - use_vortex_chargepool = 1; - ring_inner_value = vortex_chargepool; - } else { - vortex_charge_movingavg = (1 - autocvar_crosshair_ring_vortex_currentcharge_movingavg_rate) * vortex_charge_movingavg + autocvar_crosshair_ring_vortex_currentcharge_movingavg_rate * vortex_charge; - ring_inner_value = bound(0, autocvar_crosshair_ring_vortex_currentcharge_scale * (vortex_charge - vortex_charge_movingavg), 1); - } - - ring_inner_alpha = autocvar_crosshair_ring_vortex_inner_alpha; - ring_inner_rgb = eX * autocvar_crosshair_ring_vortex_inner_color_red + eY * autocvar_crosshair_ring_vortex_inner_color_green + eZ * autocvar_crosshair_ring_vortex_inner_color_blue; - ring_inner_image = "gfx/crosshair_ring_inner.tga"; - - // draw the outer ring to show the current charge of the weapon - ring_value = vortex_charge; - ring_alpha = autocvar_crosshair_ring_vortex_alpha; - ring_rgb = wcross_color; - ring_image = "gfx/crosshair_ring_nexgun.tga"; - } - else if (autocvar_crosshair_ring && activeweapon == WEP_MINE_LAYER && minelayer_maxmines && autocvar_crosshair_ring_minelayer) - { - ring_value = bound(0, getstati(STAT_LAYED_MINES) / minelayer_maxmines, 1); // if you later need to use the count of bullets in another place, then add a float for it. For now, no need to. - ring_alpha = autocvar_crosshair_ring_minelayer_alpha; - ring_rgb = wcross_color; - ring_image = "gfx/crosshair_ring.tga"; - } - else if (activeweapon == WEP_HAGAR && getstati(STAT_HAGAR_LOAD) && autocvar_crosshair_ring_hagar) - { - ring_value = bound(0, getstati(STAT_HAGAR_LOAD) / hagar_maxrockets, 1); - ring_alpha = autocvar_crosshair_ring_hagar_alpha; - ring_rgb = wcross_color; - ring_image = "gfx/crosshair_ring.tga"; - } - - if(autocvar_crosshair_ring_reload && weapon_clipsize) // forces there to be only an ammo ring - { - ring_value = bound(0, weapon_clipload / weapon_clipsize, 1); - ring_scale = autocvar_crosshair_ring_reload_size; - ring_alpha = autocvar_crosshair_ring_reload_alpha; - ring_rgb = wcross_color; - - // Note: This is to stop Taoki from complaining that the image doesn't match all potential balances. - // if a new image for another weapon is added, add the code (and its respective file/value) here - if ((activeweapon == WEP_RIFLE) && (weapon_clipsize == 80)) - ring_image = "gfx/crosshair_ring_rifle.tga"; - else - ring_image = "gfx/crosshair_ring.tga"; - } - - // if in weapon switch animation, fade ring out/in - if(autocvar_crosshair_effect_time > 0) - { - f = (time - wcross_name_changestarttime) / autocvar_crosshair_effect_time; - if (!(f < 1)) - { - wcross_ring_prev = ((ring_image) ? TRUE : FALSE); - } - - if(wcross_ring_prev) - { - if(f < 1) - ring_alpha *= fabs(1 - bound(0, f, 1)); - } - else - { - if(f < 1) - ring_alpha *= bound(0, f, 1); - } - } - - if (autocvar_crosshair_ring_inner && ring_inner_value) // lets draw a ring inside a ring so you can ring while you ring - DrawCircleClippedPic(wcross_origin, wcross_size_x * ring_scale, ring_inner_image, ring_inner_value, ring_inner_rgb, wcross_alpha * ring_inner_alpha, DRAWFLAG_ADDITIVE); - - if (ring_value) - DrawCircleClippedPic(wcross_origin, wcross_size_x * ring_scale, ring_image, ring_value, ring_rgb, wcross_alpha * ring_alpha, DRAWFLAG_ADDITIVE); - } - -#define CROSSHAIR_DO_BLUR(M,sz,wcross_name,wcross_alpha) \ - do \ - { \ - if(wcross_blur > 0) \ - { \ - for(i = -2; i <= 2; ++i) \ - for(j = -2; j <= 2; ++j) \ - M(i,j,sz,wcross_name,wcross_alpha*0.04); \ - } \ - else \ - { \ - M(0,0,sz,wcross_name,wcross_alpha); \ - } \ - } \ - while(0) - -#define CROSSHAIR_DRAW_SINGLE(i,j,sz,wcross_name,wcross_alpha) \ - drawpic(wcross_origin - ('0.5 0 0' * (sz * wcross_size_x + i * wcross_blur) + '0 0.5 0' * (sz * wcross_size_y + j * wcross_blur)), wcross_name, sz * wcross_size, wcross_color, wcross_alpha, DRAWFLAG_NORMAL) - -#define CROSSHAIR_DRAW(sz,wcross_name,wcross_alpha) \ - CROSSHAIR_DO_BLUR(CROSSHAIR_DRAW_SINGLE,sz,wcross_name,wcross_alpha) - - if(time < wcross_name_changedonetime && wcross_name != wcross_name_goal_prev_prev && wcross_name_goal_prev_prev) - { - f = (wcross_name_changedonetime - time) / (wcross_name_changedonetime - wcross_name_changestarttime); - wcross_size = draw_getimagesize(wcross_name_goal_prev_prev) * wcross_scale; - CROSSHAIR_DRAW(wcross_resolution_goal_prev_prev, wcross_name_goal_prev_prev, wcross_alpha * f * wcross_name_alpha_goal_prev_prev); - f = 1 - f; - } - else - { - f = 1; - } - wcross_name_alpha_goal_prev = f; - - wcross_size = draw_getimagesize(wcross_name) * wcross_scale; - CROSSHAIR_DRAW(wcross_resolution, wcross_name, wcross_alpha * f); - - if(autocvar_crosshair_dot) - { - vector wcross_color_old; - wcross_color_old = wcross_color; - - if((autocvar_crosshair_dot_color_custom) && (autocvar_crosshair_dot_color != "0")) - wcross_color = stov(autocvar_crosshair_dot_color); - - CROSSHAIR_DRAW(wcross_resolution * autocvar_crosshair_dot_size, "gfx/crosshairdot.tga", f * autocvar_crosshair_dot_alpha); - // FIXME why don't we use wcross_alpha here?cl_notice_run(); - wcross_color = wcross_color_old; - } - } - } - else - { - wcross_scale_prev = 0; - wcross_alpha_prev = 0; - wcross_scale_goal_prev = 0; - wcross_alpha_goal_prev = 0; - wcross_changedonetime = 0; - if(wcross_name_goal_prev) - strunzone(wcross_name_goal_prev); - wcross_name_goal_prev = string_null; - if(wcross_name_goal_prev_prev) - strunzone(wcross_name_goal_prev_prev); - wcross_name_goal_prev_prev = string_null; - wcross_name_changestarttime = 0; - wcross_name_changedonetime = 0; - wcross_name_alpha_goal_prev = 0; - wcross_name_alpha_goal_prev_prev = 0; - wcross_resolution_goal_prev = 0; - wcross_resolution_goal_prev_prev = 0; - } - } + UpdateDamage(); + UpdateCrosshair(); + UpdateHitsound(); if(NextFrameCommand) { @@ -1698,9 +1794,9 @@ void CSQC_Demo_Camera() camera_offset = '0 0 0'; current_angles = '0 0 0'; camera_direction = '0 0 0'; - camera_offset_z += 30; - camera_offset_x += 30 * -cos(current_angles_y * DEG2RAD); - camera_offset_y += 30 * -sin(current_angles_y * DEG2RAD); + camera_offset.z += 30; + camera_offset.x += 30 * -cos(current_angles.y * DEG2RAD); + camera_offset.y += 30 * -sin(current_angles.y * DEG2RAD); current_origin = view_origin; current_camera_offset = camera_offset; cvar_set("camera_reset", "0"); @@ -1709,7 +1805,7 @@ void CSQC_Demo_Camera() // Camera angles if( camera_roll ) - mouse_angles_z += camera_roll * autocvar_camera_speed_roll; + mouse_angles.z += camera_roll * autocvar_camera_speed_roll; if(autocvar_camera_look_player) { @@ -1717,9 +1813,9 @@ void CSQC_Demo_Camera() float n; dir = normalize(view_origin - current_position); - n = mouse_angles_z; + n = mouse_angles.z; mouse_angles = vectoangles(dir); - mouse_angles_x = mouse_angles_x * -1; + mouse_angles_x = mouse_angles.x * -1; mouse_angles_z = n; } else @@ -1727,21 +1823,21 @@ void CSQC_Demo_Camera() tmp = getmousepos() * 0.1; if(vlen(tmp)>autocvar_camera_mouse_threshold) { - mouse_angles_x += tmp_y * cos(mouse_angles_z * DEG2RAD) + (tmp_x * sin(mouse_angles_z * DEG2RAD)); - mouse_angles_y -= tmp_x * cos(mouse_angles_z * DEG2RAD) + (tmp_y * -sin(mouse_angles_z * DEG2RAD)); + mouse_angles.x += tmp.y * cos(mouse_angles.z * DEG2RAD) + (tmp.x * sin(mouse_angles.z * DEG2RAD)); + mouse_angles.y -= tmp.x * cos(mouse_angles.z * DEG2RAD) + (tmp.y * -sin(mouse_angles.z * DEG2RAD)); } } - while (mouse_angles_x < -180) mouse_angles_x = mouse_angles_x + 360; - while (mouse_angles_x > 180) mouse_angles_x = mouse_angles_x - 360; - while (mouse_angles_y < -180) mouse_angles_y = mouse_angles_y + 360; - while (mouse_angles_y > 180) mouse_angles_y = mouse_angles_y - 360; + while (mouse_angles.x < -180) mouse_angles_x = mouse_angles.x + 360; + while (mouse_angles.x > 180) mouse_angles_x = mouse_angles.x - 360; + while (mouse_angles.y < -180) mouse_angles_y = mouse_angles.y + 360; + while (mouse_angles.y > 180) mouse_angles_y = mouse_angles.y - 360; // Fix difference when angles don't have the same sign delta = '0 0 0'; - if(mouse_angles_y < -60 && current_angles_y > 60) + if(mouse_angles.y < -60 && current_angles.y > 60) delta = '0 360 0'; - if(mouse_angles_y > 60 && current_angles_y < -60) + if(mouse_angles.y > 60 && current_angles.y < -60) delta = '0 -360 0'; if(autocvar_camera_look_player) @@ -1752,35 +1848,35 @@ void CSQC_Demo_Camera() attenuation = 1 / max(1, attenuation); current_angles += (mouse_angles - current_angles + delta) * attenuation; - while (current_angles_x < -180) current_angles_x = current_angles_x + 360; - while (current_angles_x > 180) current_angles_x = current_angles_x - 360; - while (current_angles_y < -180) current_angles_y = current_angles_y + 360; - while (current_angles_y > 180) current_angles_y = current_angles_y - 360; + while (current_angles.x < -180) current_angles_x = current_angles.x + 360; + while (current_angles.x > 180) current_angles_x = current_angles.x - 360; + while (current_angles.y < -180) current_angles_y = current_angles.y + 360; + while (current_angles.y > 180) current_angles_y = current_angles.y - 360; // Camera position tmp = '0 0 0'; dimensions = 0; - if( camera_direction_x ) + if( camera_direction.x ) { - tmp_x = camera_direction_x * cos(current_angles_y * DEG2RAD); - tmp_y = camera_direction_x * sin(current_angles_y * DEG2RAD); + tmp_x = camera_direction.x * cos(current_angles.y * DEG2RAD); + tmp_y = camera_direction.x * sin(current_angles.y * DEG2RAD); if( autocvar_camera_forward_follows && !autocvar_camera_look_player ) - tmp_z = camera_direction_x * -sin(current_angles_x * DEG2RAD); + tmp_z = camera_direction.x * -sin(current_angles.x * DEG2RAD); ++dimensions; } - if( camera_direction_y ) + if( camera_direction.y ) { - tmp_x += camera_direction_y * -sin(current_angles_y * DEG2RAD); - tmp_y += camera_direction_y * cos(current_angles_y * DEG2RAD) * cos(current_angles_z * DEG2RAD); - tmp_z += camera_direction_y * sin(current_angles_z * DEG2RAD); + tmp.x += camera_direction.y * -sin(current_angles.y * DEG2RAD); + tmp.y += camera_direction.y * cos(current_angles.y * DEG2RAD) * cos(current_angles.z * DEG2RAD); + tmp.z += camera_direction.y * sin(current_angles.z * DEG2RAD); ++dimensions; } - if( camera_direction_z ) + if( camera_direction.z ) { - tmp_z += camera_direction_z * cos(current_angles_z * DEG2RAD); + tmp.z += camera_direction.z * cos(current_angles.z * DEG2RAD); ++dimensions; }