X-Git-Url: https://de.git.xonotic.org/?p=xonotic%2Fxonotic-data.pk3dir.git;a=blobdiff_plain;f=qcsrc%2Fclient%2Fview.qc;h=f64e2c21f62d95ffee269be1c6b72a1422ef85ec;hp=70de314efd34b8a8259ec77d38267feac012d234;hb=f41f81f37e3ecf5a2d14f7bc7ffd7bbf09fff32e;hpb=175b123de833e7964cd69cf8110e4e785c65bd88 diff --git a/qcsrc/client/view.qc b/qcsrc/client/view.qc index 70de314ef..f64e2c21f 100644 --- a/qcsrc/client/view.qc +++ b/qcsrc/client/view.qc @@ -1,5 +1,7 @@ #include "view.qh" +#include "autocvars.qh" +#include "miscfunctions.qh" #include "announcer.qh" #include "hud/_mod.qh" #include "mapvoting.qh" @@ -10,6 +12,7 @@ #include "mutators/events.qh" #include +#include #include #include #include @@ -21,12 +24,15 @@ #include #include #include +#include #include #include #include +#include #include +#include #include #include @@ -311,6 +317,7 @@ void viewmodel_draw(entity this) e.csqcmodel_effects = fx; CSQCModel_Effects_Apply(e); } + if(a >= 0) { string name = wep.mdl; string newname = wep.wr_viewmodel(wep, this); @@ -364,6 +371,35 @@ STATIC_INIT(viewmodel) { viewmodels[slot] = new(viewmodel); } +float showfps_prevfps; +float showfps_prevfps_time; +int showfps_framecounter; + +void fpscounter_update() +{ + if(!STAT(SHOWFPS)) + return; + + float currentTime = gettime(GETTIME_REALTIME); + showfps_framecounter += 1; + if(currentTime - showfps_prevfps_time > STAT(SHOWFPS)) + { + showfps_prevfps = showfps_framecounter/(currentTime - showfps_prevfps_time); + showfps_framecounter = 0; + showfps_prevfps_time = currentTime; + + int channel = MSG_C2S; + WriteHeader(channel, fpsreport); + WriteShort(channel, bound(0, rint(showfps_prevfps), 65535)); // prevent insane fps values + } +} + +STATIC_INIT(fpscounter_init) +{ + float currentTime = gettime(GETTIME_REALTIME); + showfps_prevfps_time = currentTime; // we must initialize it to avoid an instant low frame sending +} + void Porto_Draw(entity this); STATIC_INIT(Porto) { @@ -465,9 +501,14 @@ vector GetCurrentFov(float fov) for(int slot = 0; slot < MAX_WEAPONSLOTS; ++slot) { entity wepent = viewmodels[slot]; - if(wepent.switchweapon == wepent.activeweapon) - if((wepent.activeweapon == WEP_VORTEX && !WEP_CVAR(vortex, secondary)) || (wepent.activeweapon == WEP_RIFLE && !WEP_CVAR(rifle, secondary))) // do NOT use switchweapon here - zoomdir += button_attack2; + if(wepent.switchweapon != wepent.activeweapon) + continue; + Weapon wep = wepent.activeweapon; + if(wep != WEP_Null && wep.wr_zoomdir) + { + bool do_zoom = wep.wr_zoomdir(wep); // TODO: merge this with wr_zoom? + zoomdir += do_zoom; + } } } if(spectatee_status > 0 || isdemo()) @@ -658,6 +699,7 @@ float TrueAimCheck(entity wepent) case WEP_MORTAR: // toss curve return SHOTTYPE_HITWORLD; case WEP_VORTEX: + case WEP_OVERKILL_NEX: case WEP_VAPORIZER: mv = MOVE_NORMAL; break; @@ -906,7 +948,8 @@ vector crosshair_getcolor(entity this, float health_stat) case 2: // crosshair_color_by_health { - float hp = health_stat; + vector v = healtharmor_maxdamage(health_stat, STAT(ARMOR), armorblockpercent, DEATH_WEAPON.m_id); + float hp = floor(v.x + 1); //x = red //y = green @@ -972,7 +1015,7 @@ void HUD_Crosshair(entity this) float f, i, j; vector v; if(!scoreboard_active && !camera_active && intermission != 2 && !STAT(GAME_STOPPED) && - spectatee_status != -1 && !csqcplayer.viewloc && !MUTATOR_CALLHOOK(DrawCrosshair) && + spectatee_status != -1 && (!csqcplayer.viewloc || (!spectatee_status && (csqcplayer.viewloc.spawnflags & VIEWLOC_FREEAIM))) && !MUTATOR_CALLHOOK(DrawCrosshair) && !HUD_MinigameMenu_IsOpened() ) { if (!autocvar_crosshair_enabled) // main toggle for crosshair rendering @@ -990,6 +1033,8 @@ void HUD_Crosshair(entity this) string wcross_style; float wcross_alpha, wcross_resolution; wcross_style = autocvar_crosshair; + if (csqcplayer.viewloc && (csqcplayer.viewloc.spawnflags & VIEWLOC_FREEAIM) && autocvar_crosshair_2d != "") + wcross_style = autocvar_crosshair_2d; if (wcross_style == "0") return; wcross_resolution = autocvar_crosshair_size; @@ -1003,7 +1048,10 @@ void HUD_Crosshair(entity this) 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); + if(csqcplayer.viewloc && (csqcplayer.viewloc.spawnflags & VIEWLOC_FREEAIM)) + wcross_origin = viewloc_mousepos; + else + wcross_origin = project_3d_to_2d(view_origin + max_shot_distance * view_forward); wcross_origin.z = 0; if(autocvar_crosshair_hittest) { @@ -1174,30 +1222,29 @@ void HUD_Crosshair(entity this) ring_scale = autocvar_crosshair_ring_size; - float weapon_clipload, weapon_clipsize; - weapon_clipload = STAT(WEAPON_CLIPLOAD); - weapon_clipsize = STAT(WEAPON_CLIPSIZE); + entity wepent = viewmodels[0]; // TODO: unhardcode - float vortex_charge, vortex_chargepool; - vortex_charge = STAT(VORTEX_CHARGE); - vortex_chargepool = STAT(VORTEX_CHARGEPOOL); + int weapon_clipload = wepent.clip_load; + int weapon_clipsize = wepent.clip_size; - float arc_heat = STAT(ARC_HEAT); + float arc_heat = wepent.arc_heat_percent; + float vcharge = wepent.vortex_charge; + float vchargepool = wepent.vortex_chargepool_ammo; + float oknex_charge_ = wepent.oknex_charge; + float oknex_chargepool_ = wepent.oknex_chargepool_ammo; if(vortex_charge_movingavg == 0) // this should only happen if we have just loaded up the game - vortex_charge_movingavg = vortex_charge; - - entity wepent = viewmodels[0]; // TODO: unhardcode + vortex_charge_movingavg = vcharge; // handle the values - if (autocvar_crosshair_ring && wepent.activeweapon == WEP_VORTEX && vortex_charge && autocvar_crosshair_ring_vortex) // ring around crosshair representing velocity-dependent damage for the vortex + if (autocvar_crosshair_ring && wepent.activeweapon == WEP_VORTEX && vcharge && autocvar_crosshair_ring_vortex) // ring around crosshair representing velocity-dependent damage for the vortex { - if (vortex_chargepool || use_vortex_chargepool) { + if (vchargepool || use_vortex_chargepool) { use_vortex_chargepool = 1; - ring_inner_value = vortex_chargepool; + ring_inner_value = vchargepool; } 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); + vortex_charge_movingavg = (1 - autocvar_crosshair_ring_vortex_currentcharge_movingavg_rate) * vortex_charge_movingavg + autocvar_crosshair_ring_vortex_currentcharge_movingavg_rate * vcharge; + ring_inner_value = bound(0, autocvar_crosshair_ring_vortex_currentcharge_scale * (vcharge - vortex_charge_movingavg), 1); } ring_inner_alpha = autocvar_crosshair_ring_vortex_inner_alpha; @@ -1205,21 +1252,41 @@ void HUD_Crosshair(entity this) 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_value = vcharge; + ring_alpha = autocvar_crosshair_ring_vortex_alpha; + ring_rgb = wcross_color; + ring_image = "gfx/crosshair_ring_nexgun.tga"; + } + else if (autocvar_crosshair_ring && (wepent.activeweapon == WEP_OVERKILL_NEX) && oknex_charge_ && autocvar_crosshair_ring_vortex) + { + if (oknex_chargepool_ || use_vortex_chargepool) { + use_vortex_chargepool = 1; + ring_inner_value = oknex_chargepool_; + } else { + vortex_charge_movingavg = (1 - autocvar_crosshair_ring_vortex_currentcharge_movingavg_rate) * vortex_charge_movingavg + autocvar_crosshair_ring_vortex_currentcharge_movingavg_rate * oknex_charge_; + ring_inner_value = bound(0, autocvar_crosshair_ring_vortex_currentcharge_scale * (oknex_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 = oknex_charge_; ring_alpha = autocvar_crosshair_ring_vortex_alpha; ring_rgb = wcross_color; ring_image = "gfx/crosshair_ring_nexgun.tga"; } else if (autocvar_crosshair_ring && wepent.activeweapon == WEP_MINE_LAYER && WEP_CVAR(minelayer, limit) && autocvar_crosshair_ring_minelayer) { - ring_value = bound(0, STAT(LAYED_MINES) / WEP_CVAR(minelayer, limit), 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_value = bound(0, wepent.minelayer_mines / WEP_CVAR(minelayer, limit), 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 (wepent.activeweapon == WEP_HAGAR && STAT(HAGAR_LOAD) && autocvar_crosshair_ring_hagar) + else if (wepent.activeweapon == WEP_HAGAR && wepent.hagar_load && autocvar_crosshair_ring_hagar) { - ring_value = bound(0, STAT(HAGAR_LOAD) / WEP_CVAR_SEC(hagar, load_max), 1); + ring_value = bound(0, wepent.hagar_load / WEP_CVAR_SEC(hagar, load_max), 1); ring_alpha = autocvar_crosshair_ring_hagar_alpha; ring_rgb = wcross_color; ring_image = "gfx/crosshair_ring.tga"; @@ -1379,8 +1446,8 @@ void SpecialCommand() vector slot = specialcommand_slots[j]; if(slot.y) slot.y += SPECIALCOMMAND_SPEED * frametime; - if(slot.z) - slot.z = sin(SPECIALCOMMAND_TURNSPEED * M_PI * time); + //if(slot.z) + //slot.z = sin(SPECIALCOMMAND_TURNSPEED * M_PI * time); if(slot.y >= vid_conheight) slot = '0 0 0'; @@ -1390,7 +1457,7 @@ void SpecialCommand() { slot.x = bound(0, (random() * vid_conwidth + 1), vid_conwidth); slot.y = 1; // start it off 0 so we can use it - slot.z = random(); + slot.z = floor(random() * Weapons_MAX); sc_spawntime = time + bound(0.4, random(), 0.75); // prevent spawning another one for this amount of time! vector newcolor = randomvec() * 2; newcolor.x = bound(0.4, newcolor.x, 1); @@ -1404,7 +1471,11 @@ void SpecialCommand() vector splash_size = '0 0 0'; splash_size.x = max(vid_conwidth, vid_conheight) * SPECIALCOMMAND_SIZE; splash_size.y = max(vid_conwidth, vid_conheight) * SPECIALCOMMAND_SIZE; - drawpic(vec2(slot), "gfx/smile", vec2(splash_size), specialcommand_colors[j], 0.95, DRAWFLAG_NORMAL); + entity wep = Weapons_from(slot.z); + if(wep == WEP_Null) + drawpic(vec2(slot), "gfx/smile", vec2(splash_size), specialcommand_colors[j], 0.95, DRAWFLAG_NORMAL); + else + drawpic_skin(vec2(slot), wep.model2, vec2(splash_size), specialcommand_colors[j], 0.95, DRAWFLAG_NORMAL); //drawrotpic(vec2(slot), slot.z, "gfx/smile", vec2(splash_size), vec2(splash_size) / 2, specialcommand_colors[j], 0.95, DRAWFLAG_NORMAL); } @@ -1473,6 +1544,19 @@ void HUD_Draw(entity this) HitSound(); } +void ViewLocation_Mouse() +{ + if(spectatee_status) + return; // don't draw it as spectator! + + viewloc_mousepos += getmousepos() * autocvar_menu_mouse_speed; + viewloc_mousepos.x = bound(0, viewloc_mousepos.x, vid_conwidth); + viewloc_mousepos.y = bound(0, viewloc_mousepos.y, vid_conheight); + + //float cursor_alpha = 1 - autocvar__menu_alpha; + //draw_cursor(viewloc_mousepos, '0.5 0.5 0', "/cursor_move", '1 1 1', cursor_alpha); +} + bool ov_enabled; float oldr_nearclip; float oldr_farclip_base; @@ -1570,6 +1654,11 @@ void CSQC_UpdateView(entity this, float w, float h) button_zoom = false; } + // abused multiple places below + entity local_player = ((csqcplayer) ? csqcplayer : CSQCModel_server2csqc(player_localentnum - 1)); + if(!local_player) + local_player = this; // fall back! + // event chase camera if(autocvar_chase_active <= 0) // greater than 0 means it's enabled manually, and this code is skipped { @@ -1621,10 +1710,6 @@ void CSQC_UpdateView(entity this, float w, float h) } eventchase_running = true; - entity local_player = ((csqcplayer) ? csqcplayer : CSQCModel_server2csqc(player_localentnum - 1)); - if(!local_player) - local_player = this; // fall back! - // 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); if (custom_eventchase) @@ -1778,7 +1863,7 @@ void CSQC_UpdateView(entity this, float w, float h) ov_enabled = true; #if 0 - LOG_INFOF("OrthoView: org = %s, angles = %s, distance = %f, nearest = %f, furthest = %f\n", + LOG_INFOF("OrthoView: org = %s, angles = %s, distance = %f, nearest = %f, furthest = %f", vtos(ov_org), vtos(getpropertyvec(VF_ANGLES)), ov_distance, @@ -1834,6 +1919,7 @@ void CSQC_UpdateView(entity this, float w, float h) TargetMusic_Advance(); Fog_Force(); + fpscounter_update(); if(drawtime == 0) drawframetime = 0.01666667; // when we don't know fps yet, we assume 60fps @@ -2056,7 +2142,7 @@ void CSQC_UpdateView(entity this, float w, float h) // 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 || is_dead || hud != HUD_NORMAL) + if(spectatee_status || is_dead || hud != HUD_NORMAL || local_player.viewloc) { // no zoom reticle while dead reticle_type = 0; @@ -2369,6 +2455,8 @@ void CSQC_UpdateView(entity this, float w, float h) HUD_Minigame_Mouse(); else if(QuickMenu_IsOpened()) QuickMenu_Mouse(); + else if(local_player.viewloc && (local_player.viewloc.spawnflags & VIEWLOC_FREEAIM)) + ViewLocation_Mouse(); // NOTE: doesn't use cursormode else HUD_Radar_Mouse();