diff --git a/cl_dll/ammo.cpp b/cl_dll/ammo.cpp index c2ea1461..b94f4a78 100644 --- a/cl_dll/ammo.cpp +++ b/cl_dll/ammo.cpp @@ -74,10 +74,14 @@ void WeaponsResource :: LoadWeaponSprites( WEAPON *pWeapon ) { int i, iRes; - if (ScreenWidth < 640) - iRes = 320; - else + if (ScreenWidth > 2560 && ScreenHeight > 1600) + iRes = 2560; + else if (ScreenWidth >= 1280 && ScreenHeight > 720) + iRes = 1280; + else if (ScreenWidth >= 640) iRes = 640; + else + iRes = 320; char sz[256]; @@ -327,16 +331,15 @@ int CHudAmmo::VidInit(void) // If we've already loaded weapons, let's get new sprites gWR.LoadAllWeaponSprites(); - if (ScreenWidth >= 640) - { - giABWidth = 20; - giABHeight = 4; - } - else - { - giABWidth = 10; - giABHeight = 2; - } + int nScale = 1; + if (ScreenWidth > 2560 && ScreenHeight > 1600) + nScale = 4; + else if (ScreenWidth >= 1280 && ScreenHeight > 720) + nScale = 3; + else if (ScreenWidth >= 640) + nScale = 2; + giABWidth = 10 * nScale; + giABHeight = 2 * nScale; return 1; } @@ -873,8 +876,8 @@ int CHudAmmo::Draw(float flTime) ScaleColors(r, g, b, a ); - // Does this weapon have a clip? y = ScreenHeight - gHUD.m_iFontHeight - gHUD.m_iFontHeight/2; + y += (int)(gHUD.m_iFontHeight * 0.2f); if (hud_weapon->value != 0.0f) { diff --git a/cl_dll/ammohistory.cpp b/cl_dll/ammohistory.cpp index 885ec995..7c51e183 100644 --- a/cl_dll/ammohistory.cpp +++ b/cl_dll/ammohistory.cpp @@ -130,7 +130,7 @@ int HistoryResource :: DrawAmmoHistory( float flTime ) // Draw the pic int ypos = ScreenHeight - (AMMO_PICKUP_PICK_HEIGHT + (AMMO_PICKUP_GAP * i)); - int xpos = ScreenWidth - 24; + int xpos = ScreenWidth - (rcPic.right - rcPic.left) - 4; if ( spr && *spr ) // weapon isn't loaded yet so just don't draw the pic { // the dll has to make sure it has sent info the weapons you need SPR_Set( *spr, r, g, b ); diff --git a/cl_dll/battery.cpp b/cl_dll/battery.cpp index c3c0850b..bd568e9b 100644 --- a/cl_dll/battery.cpp +++ b/cl_dll/battery.cpp @@ -134,7 +134,9 @@ int CHudBattery::Draw(float flTime) int iOffset = (m_prc1->bottom - m_prc1->top)/6; y = ScreenHeight - gHUD.m_iFontHeight - gHUD.m_iFontHeight / 2; - x = ScreenWidth/5; + int width = (m_prc1->right - m_prc1->left); + // this used to just be ScreenWidth/5 but that caused real issues at higher resolutions. Instead, base it on the width of this sprite. + x = 3 * width; // make sure we have the right sprite handles if ( !m_hSprite1 ) @@ -151,7 +153,8 @@ int CHudBattery::Draw(float flTime) SPR_DrawAdditive( 0, x, y - iOffset + (rc.top - m_prc2->top), &rc); } - x += (m_prc1->right - m_prc1->left); + x += width; + y += (int)(gHUD.m_iFontHeight * 0.2f); x = gHUD.DrawHudNumber(x, y, DHN_3DIGITS | DHN_DRAWZERO, m_iBat, r, g, b); return 1; diff --git a/cl_dll/death.cpp b/cl_dll/death.cpp index 71a609a8..ce4be8f7 100644 --- a/cl_dll/death.cpp +++ b/cl_dll/death.cpp @@ -97,7 +97,12 @@ int CHudDeathNotice :: VidInit( void ) int CHudDeathNotice :: Draw( float flTime ) { - int x, y, r, g, b; + int x, y, r, g, b, texty; + + int gap = 20; + + rect_s sprite = gHUD.GetSpriteRect(m_HUD_d_skull); + gap = sprite.bottom - sprite.top; for ( int i = 0; i < MAX_DEATHNOTICES; i++ ) { @@ -118,10 +123,11 @@ int CHudDeathNotice :: Draw( float flTime ) if ( gViewPort && gViewPort->AllowedToPrintText() ) { // Draw the death notice - y = DEATHNOTICE_TOP + 2 + (20 * i); //!!! + y = DEATHNOTICE_TOP + 2 + (gap * i); //!!! + texty = y + 4; int id = (rgDeathNoticeList[i].iId == -1) ? m_HUD_d_skull : rgDeathNoticeList[i].iId; - x = ScreenWidth - ConsoleStringLen(rgDeathNoticeList[i].szVictim) - (gHUD.GetSpriteRect(id).right - gHUD.GetSpriteRect(id).left); + x = ScreenWidth - ConsoleStringLen(rgDeathNoticeList[i].szVictim) - (gHUD.GetSpriteRect(id).right - gHUD.GetSpriteRect(id).left) - 4; if ( !rgDeathNoticeList[i].iSuicide ) { @@ -131,7 +137,7 @@ int CHudDeathNotice :: Draw( float flTime ) if ( rgDeathNoticeList[i].KillerColor ) x = 5 + gHUD.DrawConsoleStringWithColorTags( x, - y, + texty, rgDeathNoticeList[i].szKiller, true, rgDeathNoticeList[i].KillerColor[0], @@ -168,7 +174,7 @@ int CHudDeathNotice :: Draw( float flTime ) rgDeathNoticeList[i].VictimColor[2] ); else - x = DrawConsoleString( x, y, rgDeathNoticeList[i].szVictim ); + x = DrawConsoleString( x, texty, rgDeathNoticeList[i].szVictim ); } } } diff --git a/cl_dll/ev_hldm.cpp b/cl_dll/ev_hldm.cpp index 1006b6fe..95ce83e2 100644 --- a/cl_dll/ev_hldm.cpp +++ b/cl_dll/ev_hldm.cpp @@ -98,6 +98,7 @@ float EV_HLDM_PlayTextureSound( int idx, pmtrace_t *ptr, float *vecSrc, float *v { // hit the world, try to play sound based on texture material type char chTextureType = CHAR_TEX_CONCRETE; + cl_entity_t* cl_entity = NULL; float fvol; float fvolbar; const char *rgsz[4]; @@ -116,12 +117,7 @@ float EV_HLDM_PlayTextureSound( int idx, pmtrace_t *ptr, float *vecSrc, float *v chTextureType = 0; // Player - if ( entity >= 1 && entity <= gEngfuncs.GetMaxClients() ) - { - // hit body - chTextureType = CHAR_TEX_FLESH; - } - else if ( entity == 0 ) + if (entity == 0) { // get texture from entity or world (world is ent(0)) pTextureName = (char *)gEngfuncs.pEventAPI->EV_TraceTexture( ptr->ent, vecSrc, vecEnd ); @@ -150,6 +146,19 @@ float EV_HLDM_PlayTextureSound( int idx, pmtrace_t *ptr, float *vecSrc, float *v chTextureType = PM_FindTextureType( szbuffer ); } } + else + { + // JoshA: Look up the entity and find the EFLAG_FLESH_SOUND flag. + // This broke at some point then TF:C added prediction. + // + // It used to use Classify of pEntity->Classify() != CLASS_NONE && pEntity->Classify() != CLASS_MACHINE + // to determine what sound to play, but that's server side and isn't available on the client + // and got lost in the translation to that. + // Now the server will replicate that state via an eflag. + cl_entity = gEngfuncs.GetEntityByIndex(entity); + if (cl_entity && !!(cl_entity->curstate.eflags & EFLAG_FLESH_SOUND)) + chTextureType = CHAR_TEX_FLESH; + } switch (chTextureType) { @@ -401,8 +410,16 @@ void EV_HLDM_FireBullets( int idx, float *forward, float *right, float *up, int gEngfuncs.pEventAPI->EV_SetSolidPlayers ( idx - 1 ); gEngfuncs.pEventAPI->EV_SetTraceHull( 2 ); - gEngfuncs.pEventAPI->EV_PlayerTrace( vecSrc, vecEnd, PM_STUDIO_BOX, -1, &tr ); - + // JoshA: Changed from PM_NORMAL to PM_NORMAL in prediction code as otherwise if you hit an NPC or player's + // bounding box but not one of their hitboxes, the shot won't hit on the server but it will + // play a hit sound on the client and not make a decal (as if it hit the NPC/player). + // We should mirror the way the server does the test here as close as possible. + // + // I initially thought I was just fixing some stupid Half-Life bug but no, + // this is *the* root cause of all the ghost shot bad prediction bugs in Half-Life Deathmatch! + // + // Also... CStrike was always using PM_NORMAL for all of these so it didn't have the problem. + gEngfuncs.pEventAPI->EV_PlayerTrace(vecSrc, vecEnd, PM_NORMAL, -1, &tr); tracer = EV_HLDM_CheckTracer( idx, vecSrc, tr.endpos, forward, right, iBulletType, iTracerFreq, tracerCount ); // do damage, paint decals @@ -913,7 +930,7 @@ void EV_FireGauss( event_args_t *args ) gEngfuncs.pEventAPI->EV_SetSolidPlayers ( idx - 1 ); gEngfuncs.pEventAPI->EV_SetTraceHull( 2 ); - gEngfuncs.pEventAPI->EV_PlayerTrace( vecSrc, vecDest, PM_STUDIO_BOX, -1, &tr ); + gEngfuncs.pEventAPI->EV_PlayerTrace( vecSrc, vecDest, PM_NORMAL, -1, &tr ); gEngfuncs.pEventAPI->EV_PopPMStates(); @@ -1035,7 +1052,7 @@ void EV_FireGauss( event_args_t *args ) gEngfuncs.pEventAPI->EV_SetSolidPlayers ( idx - 1 ); gEngfuncs.pEventAPI->EV_SetTraceHull( 2 ); - gEngfuncs.pEventAPI->EV_PlayerTrace( start, vecDest, PM_STUDIO_BOX, -1, &beam_tr ); + gEngfuncs.pEventAPI->EV_PlayerTrace( start, vecDest, PM_NORMAL, -1, &beam_tr ); if ( !beam_tr.allsolid ) { @@ -1044,7 +1061,7 @@ void EV_FireGauss( event_args_t *args ) // trace backwards to find exit point - gEngfuncs.pEventAPI->EV_PlayerTrace( beam_tr.endpos, tr.endpos, PM_STUDIO_BOX, -1, &beam_tr ); + gEngfuncs.pEventAPI->EV_PlayerTrace( beam_tr.endpos, tr.endpos, PM_NORMAL, -1, &beam_tr ); VectorSubtract( beam_tr.endpos, tr.endpos, delta ); @@ -1240,7 +1257,7 @@ void EV_FireCrossbow2( event_args_t *args ) // Now add in all of the players. gEngfuncs.pEventAPI->EV_SetSolidPlayers ( idx - 1 ); gEngfuncs.pEventAPI->EV_SetTraceHull( 2 ); - gEngfuncs.pEventAPI->EV_PlayerTrace( vecSrc, vecEnd, PM_STUDIO_BOX, -1, &tr ); + gEngfuncs.pEventAPI->EV_PlayerTrace( vecSrc, vecEnd, PM_NORMAL, -1, &tr ); //We hit something if ( tr.fraction < 1.0 ) @@ -1445,7 +1462,7 @@ void EV_EgonFire( event_args_t *args ) gEngfuncs.pEventAPI->EV_SetSolidPlayers ( idx - 1 ); gEngfuncs.pEventAPI->EV_SetTraceHull( 2 ); - gEngfuncs.pEventAPI->EV_PlayerTrace( vecSrc, vecEnd, PM_STUDIO_BOX, -1, &tr ); + gEngfuncs.pEventAPI->EV_PlayerTrace( vecSrc, vecEnd, PM_NORMAL, -1, &tr ); gEngfuncs.pEventAPI->EV_PopPMStates(); diff --git a/cl_dll/geiger.cpp b/cl_dll/geiger.cpp index 99442677..a8594d91 100644 --- a/cl_dll/geiger.cpp +++ b/cl_dll/geiger.cpp @@ -64,14 +64,18 @@ int CHudGeiger::MsgFunc_Geiger(const char *pszName, int iSize, void *pbuf) int CHudGeiger::Draw (float flTime) { int pct; - float flvol; + float flvol = 0; int rg[3]; int i; - if (m_iGeigerRange <= 800 && m_iGeigerRange > 0) + if (m_iGeigerRange <= 1000 && m_iGeigerRange > 0) { // peicewise linear is better than continuous formula for this - if (m_iGeigerRange > 600) + if (m_iGeigerRange > 800) + { + pct = 0; // Con_Printf ( "range > 800\n ); + } + else if (m_iGeigerRange > 600) { pct = 2; flvol = 0.4; //Con_Printf ( "range > 600\n"); diff --git a/cl_dll/health.cpp b/cl_dll/health.cpp index 7fbc354c..074612eb 100644 --- a/cl_dll/health.cpp +++ b/cl_dll/health.cpp @@ -212,6 +212,7 @@ int CHudHealth::Draw(float flTime) y = ScreenHeight - gHUD.m_iFontHeight - gHUD.m_iFontHeight / 2; x = CrossWidth /2; + y += (int)(gHUD.m_iFontHeight * 0.2f); SPR_Set(gHUD.GetSprite(m_HUD_cross), r, g, b); SPR_DrawAdditive(0, x, y, &gHUD.GetSpriteRect(m_HUD_cross)); @@ -309,49 +310,49 @@ int CHudHealth::DrawPain(float flTime) if (m_fAttackFront > 0.4) { GetPainColor(r,g,b); - shade = a * max( m_fAttackFront, 0.5 ); + shade = a * max( m_fAttackFront, 0.5f ); ScaleColors(r, g, b, shade); SPR_Set(m_hSprite, r, g, b ); x = ScreenWidth/2 - SPR_Width(m_hSprite, 0)/2; y = ScreenHeight/2 - SPR_Height(m_hSprite,0) * 3; SPR_DrawAdditive(0, x, y, NULL); - m_fAttackFront = max( 0, m_fAttackFront - fFade ); + m_fAttackFront = max( 0.0f, m_fAttackFront - fFade ); } else m_fAttackFront = 0; if (m_fAttackRight > 0.4) { GetPainColor(r,g,b); - shade = a * max( m_fAttackRight, 0.5 ); + shade = a * max( m_fAttackRight, 0.5f ); ScaleColors(r, g, b, shade); SPR_Set(m_hSprite, r, g, b ); x = ScreenWidth/2 + SPR_Width(m_hSprite, 1) * 2; y = ScreenHeight/2 - SPR_Height(m_hSprite,1)/2; SPR_DrawAdditive(1, x, y, NULL); - m_fAttackRight = max( 0, m_fAttackRight - fFade ); + m_fAttackRight = max( 0.0f, m_fAttackRight - fFade ); } else m_fAttackRight = 0; if (m_fAttackRear > 0.4) { GetPainColor(r,g,b); - shade = a * max( m_fAttackRear, 0.5 ); + shade = a * max( m_fAttackRear, 0.5f ); ScaleColors(r, g, b, shade); SPR_Set(m_hSprite, r, g, b ); x = ScreenWidth/2 - SPR_Width(m_hSprite, 2)/2; y = ScreenHeight/2 + SPR_Height(m_hSprite,2) * 2; SPR_DrawAdditive(2, x, y, NULL); - m_fAttackRear = max( 0, m_fAttackRear - fFade ); + m_fAttackRear = max( 0.0f, m_fAttackRear - fFade ); } else m_fAttackRear = 0; if (m_fAttackLeft > 0.4) { GetPainColor(r,g,b); - shade = a * max( m_fAttackLeft, 0.5 ); + shade = a * max( m_fAttackLeft, 0.5f ); ScaleColors(r, g, b, shade); SPR_Set(m_hSprite, r, g, b ); @@ -359,7 +360,7 @@ int CHudHealth::DrawPain(float flTime) y = ScreenHeight/2 - SPR_Height(m_hSprite,3)/2; SPR_DrawAdditive(3, x, y, NULL); - m_fAttackLeft = max( 0, m_fAttackLeft - fFade ); + m_fAttackLeft = max( 0.0f, m_fAttackLeft - fFade ); } else m_fAttackLeft = 0; diff --git a/cl_dll/hl/hl_weapons.cpp b/cl_dll/hl/hl_weapons.cpp index dc308c83..31efb438 100644 --- a/cl_dll/hl/hl_weapons.cpp +++ b/cl_dll/hl/hl_weapons.cpp @@ -815,6 +815,8 @@ void HUD_WeaponsPostThink( local_state_s *from, local_state_s *to, usercmd_t *cm player.m_afButtonPressed = buttonsChanged & cmd->buttons; // The ones not down are "released" player.m_afButtonReleased = buttonsChanged & (~cmd->buttons); + player.pev->v_angle = cmd->viewangles; + player.pev->origin = from->client.origin; // Set player variables that weapons code might check/alter player.pev->button = cmd->buttons; diff --git a/cl_dll/hud.cpp b/cl_dll/hud.cpp index 8d06d504..2b464283 100644 --- a/cl_dll/hud.cpp +++ b/cl_dll/hud.cpp @@ -650,10 +650,14 @@ void CHud :: VidInit( void ) m_hsprLogo = 0; m_hsprCursor = 0; - if (ScreenWidth < 640) - m_iRes = 320; - else + if (ScreenWidth > 2560 && ScreenHeight > 1600) + m_iRes = 2560; + else if (ScreenWidth >= 1280 && ScreenHeight > 720) + m_iRes = 1280; + else if (ScreenWidth >= 640) m_iRes = 640; + else + m_iRes = 320; // Only load this once if ( !m_pSpriteList ) diff --git a/cl_dll/util.cpp b/cl_dll/util.cpp index 68566ebf..00394a39 100644 --- a/cl_dll/util.cpp +++ b/cl_dll/util.cpp @@ -118,15 +118,20 @@ void VectorMA (const float *veca, float scale, const float *vecb, float *vecc) HSPRITE LoadSprite(const char *pszName) { - int i; + int iRes; char sz[256]; - if (ScreenWidth < 640) - i = 320; + if (ScreenWidth > 2560 && ScreenHeight > 1600) + iRes = 2560; + else if (ScreenWidth >= 1280 && ScreenHeight > 720) + iRes = 1280; + else if (ScreenWidth >= 640) + iRes = 640; else - i = 640; + iRes = 320; - sprintf(sz, pszName, i); + + sprintf(sz, pszName, iRes); return SPR_Load(sz); } diff --git a/cl_dll/view.cpp b/cl_dll/view.cpp index 4d410bc2..4faee6f1 100644 --- a/cl_dll/view.cpp +++ b/cl_dll/view.cpp @@ -208,8 +208,8 @@ float V_CalcBob ( struct ref_params_s *pparams ) bob = sqrt( vel[0] * vel[0] + vel[1] * vel[1] ) * cl_bob->value; bob = bob * 0.3 + bob * 0.7 * sin(cycle); - bob = min( bob, 4 ); - bob = max( bob, -7 ); + bob = min( bob, 4.0f ); + bob = max( bob, -7.0f ); return bob; } @@ -384,8 +384,8 @@ void V_CalcGunAngle ( struct ref_params_s *pparams ) viewent->angles[PITCH] -= v_idlescale * sin(pparams->time*v_ipitch_cycle.value) * (v_ipitch_level.value * 0.5); viewent->angles[YAW] -= v_idlescale * sin(pparams->time*v_iyaw_cycle.value) * v_iyaw_level.value; - VectorCopy( viewent->angles, viewent->curstate.angles ); - VectorCopy( viewent->angles, viewent->latched.prevangles ); + // VectorCopy( viewent->angles, viewent->curstate.angles ); + // VectorCopy( viewent->angles, viewent->latched.prevangles ); } /* @@ -863,6 +863,15 @@ void V_CalcNormalRefdef ( struct ref_params_s *pparams ) } } + // Update the latched view origin/angles here, this was + // previously done in V_CalcGunAngle but that happens + // before a bunch of other stuff happens, which nukes + // a bunch of the viewbob fx. + VectorCopy(view->origin, view->curstate.origin); + VectorCopy(view->origin, view->latched.prevorigin); + VectorCopy(view->angles, view->curstate.angles); + VectorCopy(view->angles, view->latched.prevangles); + lasttime = pparams->time; v_origin = pparams->vieworg; @@ -1787,7 +1796,7 @@ void V_Init (void) v_centerspeed = gEngfuncs.pfnRegisterVariable( "v_centerspeed","500", 0 ); cl_bobcycle = gEngfuncs.pfnRegisterVariable( "cl_bobcycle","0.8", 0 );// best default for my experimental gun wag (sjb) - cl_bob = gEngfuncs.pfnRegisterVariable( "cl_bob","0.01", 0 );// best default for my experimental gun wag (sjb) + cl_bob = gEngfuncs.pfnRegisterVariable( "cl_bob","0.01", FCVAR_ARCHIVE );// best default for my experimental gun wag (sjb) cl_bobup = gEngfuncs.pfnRegisterVariable( "cl_bobup","0.5", 0 ); cl_waterdist = gEngfuncs.pfnRegisterVariable( "cl_waterdist","4", 0 ); cl_chasedist = gEngfuncs.pfnRegisterVariable( "cl_chasedist","112", 0 ); diff --git a/common/const.h b/common/const.h index 9eee1bd5..13b0d70e 100644 --- a/common/const.h +++ b/common/const.h @@ -116,6 +116,7 @@ // entity flags #define EFLAG_SLERP 1 // do studio interpolation of this entity +#define EFLAG_FLESH_SOUND 2 // JoshA: Whether this entity should sound like flesh. (ie. pEntity->Classify() != CLASS_NONE && pEntity->Classify() != CLASS_MACHINE) // // temp entity events