X-Git-Url: http://de.git.xonotic.org/?a=blobdiff_plain;f=qcsrc%2Fclient%2Fview.qc;h=95167a1c4c752c4189d6a6e5568f02b6d0c2d5fa;hb=3e5bd9a991152c2572cd696570ce4ab0fc2c6ce1;hp=1e4d666e9cb64c28f2399fb52ebdb5da05d2cf18;hpb=eeec5ec4584c71acbb89db6eea843b48d6ca4c26;p=xonotic%2Fxonotic-data.pk3dir.git diff --git a/qcsrc/client/view.qc b/qcsrc/client/view.qc index 1e4d666e9..95167a1c4 100644 --- a/qcsrc/client/view.qc +++ b/qcsrc/client/view.qc @@ -1,4 +1,3 @@ -#include "_all.qh" #include "announcer.qh" #include "hook.qh" @@ -7,27 +6,60 @@ #include "mapvoting.qh" #include "scoreboard.qh" #include "shownames.qh" +#include "quickmenu.qh" #include "mutators/events.qh" +#include "../common/anim.qh" #include "../common/constants.qh" #include "../common/mapinfo.qh" -#include "../common/nades.qh" +#include "../common/gamemodes/all.qh" +#include "../common/nades/all.qh" #include "../common/stats.qh" #include "../common/triggers/target/music.qh" #include "../common/teams.qh" -#include "../common/util.qh" +#include "../common/vehicles/all.qh" #include "../common/weapons/all.qh" +#include "../common/viewloc.qh" +#include "../common/minigames/cl_minigames.qh" +#include "../common/minigames/cl_minigames_hud.qh" -#include "../csqcmodellib/cl_player.qh" +#include "../lib/csqcmodel/cl_player.qh" -#include "../warpzonelib/client.qh" -#include "../warpzonelib/common.qh" +#include "../lib/warpzone/client.qh" +#include "../lib/warpzone/common.qh" + +#define EFMASK_CHEAP (EF_ADDITIVE | EF_DOUBLESIDED | EF_FULLBRIGHT | EF_NODEPTHTEST | EF_NODRAW | EF_NOSHADOW | EF_SELECTABLE | EF_TELEPORT_BIT) + +void viewmodel_draw(entity this) +{ + int mask = (intermission || (getstati(STAT_HEALTH) <= 0) || autocvar_chase_active) ? 0 : MASK_NORMAL; + int c = stof(getplayerkeyvalue(current_player, "colors")); + vector g = colormapPaletteColor(c & 0x0F, true) * 2; + entity me = CSQCModel_server2csqc(player_localentnum); + int fx = ((me.csqcmodel_effects & EFMASK_CHEAP) + | EF_NODEPTHTEST) + &~ (EF_FULLBRIGHT); // can mask team color, so get rid of it + for (entity e = this; e; e = e.weaponchild) + { + e.drawmask = mask; + e.colormap = c; + e.glowmod = g; + e.csqcmodel_effects = fx; + WITH(entity, self, e, CSQCModel_Effects_Apply()); + } +} + +entity viewmodel; +STATIC_INIT(viewmodel) { + viewmodel = new(viewmodel); + viewmodel.draw = viewmodel_draw; +} entity porto; vector polyline[16]; -void Porto_Draw() +void Porto_Draw(entity this) { vector p, dir, ang, q, nextdir; float portal_number, portal1_idx; @@ -321,6 +353,7 @@ float TrueAimCheck() { case WEP_TUBA.m_id: // no aim case WEP_PORTO.m_id: // shoots from eye + case WEP_NEXBALL.m_id: // shoots from eye case WEP_HOOK.m_id: // no trueaim case WEP_MORTAR.m_id: // toss curve return SHOTTYPE_HITWORLD; @@ -393,8 +426,6 @@ float TrueAimCheck() return SHOTTYPE_HITWORLD; } -void CSQC_common_hud(void); - void PostInit(void); void CSQC_Demo_Camera(); float HUD_WouldDrawScoreboard(); @@ -440,7 +471,7 @@ bool WantEventchase() return true; if(MUTATOR_CALLHOOK(WantEventchase, self)) return true; - if(autocvar_cl_eventchase_nexball && gametype == MAPINFO_TYPE_NEXBALL && !(WepSet_GetFromStat() & WepSet_FromWeapon(WEP_PORTO.m_id))) + if(autocvar_cl_eventchase_nexball && gametype == MAPINFO_TYPE_NEXBALL && !(WepSet_GetFromStat() & WepSet_FromWeapon(WEP_NEXBALL.m_id))) return true; if(autocvar_cl_eventchase_death && (getstati(STAT_HEALTH) <= 0)) { @@ -456,6 +487,15 @@ bool WantEventchase() return false; } +void HUD_Crosshair_Vehicle() +{ + if(hud != HUD_BUMBLEBEE_GUN) + { + Vehicle info = get_vehicleinfo(hud); + info.vr_crosshair(info); + } +} + vector damage_blurpostprocess, content_blurpostprocess; float unaccounted_damage = 0; @@ -483,7 +523,7 @@ void UpdateDamage() spectatee_status_prev = spectatee_status; } -void UpdateHitsound() +void HitSound() { // varying sound pitch @@ -517,7 +557,7 @@ void UpdateHitsound() // 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); + sound7(world, CH_INFO, SND(HIT), VOL_BASE, ATTN_NONE, pitch_shift * 100, 0); } unaccounted_damage = 0; hitsound_time_prev = time; @@ -527,46 +567,31 @@ void UpdateHitsound() 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); + sound(world, CH_INFO, SND_TYPEHIT, VOL_BASE, ATTN_NONE); typehit_time_prev = typehit_time; } } -void UpdateCrosshair() +void HUD_Crosshair() {SELFPARAM(); static float rainbow_last_flicker; - static vector rainbow_prev_color; + 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_TYPE_HEAL.m_color, 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 && !csqcplayer.viewloc && + if(!scoreboard_active && !camera_active && intermission != 2 && + spectatee_status != -1 && !csqcplayer.viewloc && !HUD_MinigameMenu_IsOpened() ) { if (!autocvar_crosshair_enabled) // main toggle for crosshair rendering return; + if (hud != HUD_NORMAL) + { + HUD_Crosshair_Vehicle(); + return; + } + string wcross_style; float wcross_alpha, wcross_resolution; wcross_style = autocvar_crosshair; @@ -1006,6 +1031,40 @@ void UpdateCrosshair() } } +void HUD_Draw() +{ + 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_TYPE_HEAL.m_color, 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) + { + if(!(gametype == MAPINFO_TYPE_RACE || gametype == MAPINFO_TYPE_CTS)) + Accuracy_LoadLevels(); + + HUD_Main(); + HUD_DrawScoreboard(); + } + + // crosshair goes VERY LAST + UpdateDamage(); + HUD_Crosshair(); + HitSound(); +} + bool ov_enabled; float oldr_nearclip; float oldr_farclip_base; @@ -1026,7 +1085,6 @@ void CSQC_UpdateView(float w, float h) entity e; float fov; float f; - int i; vector vf_size, vf_min; float a; @@ -1077,8 +1135,7 @@ void CSQC_UpdateView(float w, float h) if(myteam != prev_myteam) { myteamcolors = colormapPaletteColor(myteam, 1); - for(i = 0; i < HUD_PANEL_NUM; ++i) - hud_panel[i].update_time = time; + FOREACH(hud_panels, true, LAMBDA(it.update_time = time)); prev_myteam = myteam; } @@ -1205,6 +1262,18 @@ void CSQC_UpdateView(float w, float h) WarpZone_FixView(); //WarpZone_FixPMove(); + { + static string name_last; + string name = get_weaponinfo(switchingweapon).mdl; + if (name != name_last) + { + name_last = name; + CL_WeaponEntity_SetModel(viewmodel, name); + updateanim(viewmodel); + if (!viewmodel.animstate_override) + setanim(viewmodel, viewmodel.anim_idle, true, false, false); + } + } vector ov_org = '0 0 0'; vector ov_mid = '0 0 0'; @@ -1467,7 +1536,7 @@ void CSQC_UpdateView(float w, float h) */ for(entity e = NULL; (e = nextent(e)); ) if (e.draw) { - WITH(entity, self, e, e.draw()); + WITH(entity, self, e, e.draw(e)); } addentities(MASK_NORMAL | MASK_ENGINE | MASK_ENGINEVIEWMODELS); @@ -1531,6 +1600,7 @@ void CSQC_UpdateView(float w, float h) if(autocvar_cl_reticle) { + Weapon wep = get_weaponinfo(activeweapon); // 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 @@ -1540,7 +1610,7 @@ void CSQC_UpdateView(float w, float h) // no zoom reticle while dead reticle_type = 0; } - else if(WEP_ACTION(activeweapon, WR_ZOOMRETICLE) && autocvar_cl_reticle_weapon) + else if(wep.wr_zoomreticle(wep) && autocvar_cl_reticle_weapon) { if(reticle_image != "") { reticle_type = 2; } else { reticle_type = 0; } @@ -1711,16 +1781,15 @@ void CSQC_UpdateView(float w, float h) if(autocvar_cl_gentle_damage == 2) { if(myhealth_flash < pain_threshold) // only randomize when the flash is gone - { myhealth_gentlergb = eX * random() + eY * random() + eZ * random(); - } } else myhealth_gentlergb = stov(autocvar_hud_damage_gentle_color); - drawfill('0 0 0', eX * vid_conwidth + eY * vid_conheight, myhealth_gentlergb, autocvar_hud_damage_gentle_alpha_multiplier * bound(0, myhealth_flash_temp, 1) * autocvar_hud_damage, DRAWFLAG_NORMAL); + if(myhealth_flash_temp > 0) + drawfill('0 0 0', eX * vid_conwidth + eY * vid_conheight, myhealth_gentlergb, autocvar_hud_damage_gentle_alpha_multiplier * bound(0, myhealth_flash_temp, 1) * autocvar_hud_damage, DRAWFLAG_NORMAL); } - else + else if(myhealth_flash_temp > 0) drawpic(splash_pos, "gfx/blood", splash_size, stov(autocvar_hud_damage_color), bound(0, myhealth_flash_temp, 1) * autocvar_hud_damage, DRAWFLAG_NORMAL); if(autocvar_hud_postprocessing) // we still need to set this anyway even when chase_active is set, this way it doesn't get stuck on. @@ -1804,15 +1873,13 @@ void CSQC_UpdateView(float w, float h) // draw 2D entities for (entity e = NULL; (e = nextent(e)); ) if (e.draw2d) { - WITH(entity, self, e, e.draw2d()); + WITH(entity, self, e, e.draw2d(e)); } Draw_ShowNames_All(); scoreboard_active = HUD_WouldDrawScoreboard(); - UpdateDamage(); - UpdateCrosshair(); - UpdateHitsound(); + HUD_Draw(); if(NextFrameCommand) { @@ -1856,12 +1923,6 @@ void CSQC_UpdateView(float w, float h) else HUD_Radar_Mouse(); - if(hud && !intermission) - if(hud == HUD_BUMBLEBEE_GUN) - CSQC_BUMBLE_GUN_HUD(); - else - VEH_ACTION(hud, VR_HUD); - cl_notice_run(); // let's reset the view back to normal for the end @@ -1870,20 +1931,6 @@ void CSQC_UpdateView(float w, float h) } -void CSQC_common_hud(void) -{ - if(!(gametype == MAPINFO_TYPE_RACE || gametype == MAPINFO_TYPE_CTS)) - Accuracy_LoadLevels(); - - HUD_Main(); // always run these functions for alpha checks - HUD_DrawScoreboard(); - - // scoreboard/accuracy, map/gametype voting screen - if (scoreboard_active || intermission == 2) - HUD_Reset(); -} - - // following vectors must be global to allow seamless switching between camera modes vector camera_offset, current_camera_offset, mouse_angles, current_angles, current_origin, current_position; void CSQC_Demo_Camera()