Seperate hook collision line from player rendering

This commit is contained in:
Tater 2022-03-22 15:11:01 -05:00
parent 54e8b64136
commit abaf216f5c
4 changed files with 160 additions and 103 deletions

View file

@ -344,6 +344,7 @@ void CGhost::OnRender()
Player.m_AttackTick += Client()->GameTick(g_Config.m_ClDummy) - GhostTick;
m_pClient->m_Players.RenderHook(&Prev, &Player, &Ghost.m_RenderInfo, -2, IntraTick);
m_pClient->m_Players.RenderHookCollLine(&Prev, &Player, -2, IntraTick);
m_pClient->m_Players.RenderPlayer(&Prev, &Player, &Ghost.m_RenderInfo, -2, IntraTick);
}
}

View file

@ -327,7 +327,7 @@ void CNamePlates::OnRender()
vec2 *pRenderPos = &m_pClient->m_aClients[i].m_RenderPos;
if(pRenderPos->x < ScreenX0 || pRenderPos->x > ScreenX1 || pRenderPos->y < ScreenY0 || pRenderPos->y > ScreenY1)
{
continue;
continue;
}
if(m_pClient->m_aClients[i].m_SpecCharPresent)

View file

@ -76,7 +76,156 @@ inline float AngularApproach(float Src, float Dst, float Amount)
return Dst;
return n;
}
void CPlayers::RenderHookCollLine(
const CNetObj_Character *pPrevChar,
const CNetObj_Character *pPlayerChar,
int ClientID,
float Intra)
{
CNetObj_Character Prev;
CNetObj_Character Player;
Prev = *pPrevChar;
Player = *pPlayerChar;
bool Local = m_pClient->m_Snap.m_LocalClientID == ClientID;
bool OtherTeam = m_pClient->IsOtherTeam(ClientID);
float Alpha = (OtherTeam || ClientID < 0) ? g_Config.m_ClShowOthersAlpha / 100.0f : 1.0f;
float IntraTick = Intra;
if(ClientID >= 0)
IntraTick = m_pClient->m_aClients[ClientID].m_IsPredicted ? Client()->PredIntraGameTick(g_Config.m_ClDummy) : Client()->IntraGameTick(g_Config.m_ClDummy);
float Angle;
if(Local && Client()->State() != IClient::STATE_DEMOPLAYBACK)
{
// just use the direct input if it's the local player we are rendering
Angle = angle(m_pClient->m_Controls.m_MousePos[g_Config.m_ClDummy]);
}
else
{
float AngleIntraTick = IntraTick;
// using unpredicted angle when rendering other players in-game
if(ClientID >= 0)
AngleIntraTick = Client()->IntraGameTick(g_Config.m_ClDummy);
// If the player moves their weapon through top, then change
// the end angle by 2*Pi, so that the mix function will use the
// short path and not the long one.
if(Player.m_Angle > (256.0f * pi) && Prev.m_Angle < 0)
Player.m_Angle -= 256.0f * 2 * pi;
else if(Player.m_Angle < 0 && Prev.m_Angle > (256.0f * pi))
Player.m_Angle += 256.0f * 2 * pi;
Angle = mix((float)Prev.m_Angle, (float)Player.m_Angle, AngleIntraTick) / 256.0f;
}
vec2 Direction = direction(Angle);
vec2 Position;
if(in_range(ClientID, MAX_CLIENTS - 1))
Position = m_pClient->m_aClients[ClientID].m_RenderPos;
else
Position = mix(vec2(Prev.m_X, Prev.m_Y), vec2(Player.m_X, Player.m_Y), IntraTick);
// draw hook collision line
{
bool AlwaysRenderHookColl = GameClient()->m_GameInfo.m_AllowHookColl && (Local ? g_Config.m_ClShowHookCollOwn : g_Config.m_ClShowHookCollOther) == 2;
bool RenderHookCollPlayer = ClientID >= 0 && Player.m_PlayerFlags & PLAYERFLAG_AIM && (Local ? g_Config.m_ClShowHookCollOwn : g_Config.m_ClShowHookCollOther) > 0;
bool RenderHookCollVideo = true;
#if defined(CONF_VIDEORECORDER)
RenderHookCollVideo = !IVideo::Current() || g_Config.m_ClVideoShowHookCollOther || Local;
#endif
if((AlwaysRenderHookColl || RenderHookCollPlayer) && RenderHookCollVideo)
{
vec2 ExDirection = Direction;
if(Local && Client()->State() != IClient::STATE_DEMOPLAYBACK)
ExDirection = normalize(vec2((int)m_pClient->m_Controls.m_MousePos[g_Config.m_ClDummy].x, (int)m_pClient->m_Controls.m_MousePos[g_Config.m_ClDummy].y));
Graphics()->TextureClear();
vec2 InitPos = Position;
vec2 FinishPos = InitPos + ExDirection * (m_pClient->m_Tuning[g_Config.m_ClDummy].m_HookLength - 42.0f);
if(g_Config.m_ClHookCollSize > 0)
Graphics()->QuadsBegin();
else
Graphics()->LinesBegin();
ColorRGBA HookCollColor = color_cast<ColorRGBA>(ColorHSLA(g_Config.m_ClHookCollColorNoColl));
float PhysSize = 28.0f;
vec2 OldPos = InitPos + ExDirection * PhysSize * 1.5f;
vec2 NewPos = OldPos;
bool DoBreak = false;
int Hit = 0;
do
{
OldPos = NewPos;
NewPos = OldPos + ExDirection * m_pClient->m_Tuning[g_Config.m_ClDummy].m_HookFireSpeed;
if(distance(InitPos, NewPos) > m_pClient->m_Tuning[g_Config.m_ClDummy].m_HookLength)
{
NewPos = InitPos + normalize(NewPos - InitPos) * m_pClient->m_Tuning[g_Config.m_ClDummy].m_HookLength;
DoBreak = true;
}
int TeleNr = 0;
Hit = Collision()->IntersectLineTeleHook(OldPos, NewPos, &FinishPos, 0x0, &TeleNr);
if(!DoBreak && Hit)
{
if(Hit != TILE_NOHOOK)
{
HookCollColor = color_cast<ColorRGBA>(ColorHSLA(g_Config.m_ClHookCollColorHookableColl));
}
}
if(m_pClient->IntersectCharacter(OldPos, FinishPos, FinishPos, ClientID) != -1)
{
HookCollColor = color_cast<ColorRGBA>(ColorHSLA(g_Config.m_ClHookCollColorTeeColl));
break;
}
if(Hit)
break;
NewPos.x = round_to_int(NewPos.x);
NewPos.y = round_to_int(NewPos.y);
if(OldPos == NewPos)
break;
ExDirection.x = round_to_int(ExDirection.x * 256.0f) / 256.0f;
ExDirection.y = round_to_int(ExDirection.y * 256.0f) / 256.0f;
} while(!DoBreak);
if(AlwaysRenderHookColl && RenderHookCollPlayer)
{
// invert the hook coll colors when using cl_show_hook_coll_always and +showhookcoll is pressed
HookCollColor = color_invert(HookCollColor);
}
Graphics()->SetColor(HookCollColor.WithAlpha(Alpha));
if(g_Config.m_ClHookCollSize > 0)
{
float LineWidth = 0.5f + (float)(g_Config.m_ClHookCollSize - 1) * 0.25f;
vec2 PerpToAngle = normalize(vec2(ExDirection.y, -ExDirection.x)) * GameClient()->m_Camera.m_Zoom;
vec2 Pos0 = FinishPos + PerpToAngle * -LineWidth;
vec2 Pos1 = FinishPos + PerpToAngle * LineWidth;
vec2 Pos2 = InitPos + PerpToAngle * -LineWidth;
vec2 Pos3 = InitPos + PerpToAngle * LineWidth;
IGraphics::CFreeformItem FreeformItem(Pos0.x, Pos0.y, Pos1.x, Pos1.y, Pos2.x, Pos2.y, Pos3.x, Pos3.y);
Graphics()->QuadsDrawFreeform(&FreeformItem, 1);
Graphics()->QuadsEnd();
}
else
{
IGraphics::CLineItem LineItem(InitPos.x, InitPos.y, FinishPos.x, FinishPos.y);
Graphics()->LinesDraw(&LineItem, 1);
Graphics()->LinesEnd();
}
}
}
}
void CPlayers::RenderHook(
const CNetObj_Character *pPrevChar,
const CNetObj_Character *pPlayerChar,
@ -231,7 +380,6 @@ void CPlayers::RenderPlayer(
Position = m_pClient->m_aClients[ClientID].m_RenderPos;
else
Position = mix(vec2(Prev.m_X, Prev.m_Y), vec2(Player.m_X, Player.m_Y), IntraTick);
vec2 Vel = mix(vec2(Prev.m_VelX / 256.0f, Prev.m_VelY / 256.0f), vec2(Player.m_VelX / 256.0f, Player.m_VelY / 256.0f), IntraTick);
m_pClient->m_Flow.Add(Position, Vel * 100.0f, 10.0f);
@ -277,105 +425,6 @@ void CPlayers::RenderPlayer(
// draw gun
{
bool AlwaysRenderHookColl = GameClient()->m_GameInfo.m_AllowHookColl && (Local ? g_Config.m_ClShowHookCollOwn : g_Config.m_ClShowHookCollOther) == 2;
bool RenderHookCollPlayer = ClientID >= 0 && Player.m_PlayerFlags & PLAYERFLAG_AIM && (Local ? g_Config.m_ClShowHookCollOwn : g_Config.m_ClShowHookCollOther) > 0;
bool RenderHookCollVideo = true;
#if defined(CONF_VIDEORECORDER)
RenderHookCollVideo = !IVideo::Current() || g_Config.m_ClVideoShowHookCollOther || Local;
#endif
if((AlwaysRenderHookColl || RenderHookCollPlayer) && RenderHookCollVideo)
{
vec2 ExDirection = Direction;
if(Local && Client()->State() != IClient::STATE_DEMOPLAYBACK)
ExDirection = normalize(vec2((int)m_pClient->m_Controls.m_MousePos[g_Config.m_ClDummy].x, (int)m_pClient->m_Controls.m_MousePos[g_Config.m_ClDummy].y));
Graphics()->TextureClear();
vec2 InitPos = Position;
vec2 FinishPos = InitPos + ExDirection * (m_pClient->m_Tuning[g_Config.m_ClDummy].m_HookLength - 42.0f);
if(g_Config.m_ClHookCollSize > 0)
Graphics()->QuadsBegin();
else
Graphics()->LinesBegin();
ColorRGBA HookCollColor = color_cast<ColorRGBA>(ColorHSLA(g_Config.m_ClHookCollColorNoColl));
float PhysSize = 28.0f;
vec2 OldPos = InitPos + ExDirection * PhysSize * 1.5f;
vec2 NewPos = OldPos;
bool DoBreak = false;
int Hit = 0;
do
{
OldPos = NewPos;
NewPos = OldPos + ExDirection * m_pClient->m_Tuning[g_Config.m_ClDummy].m_HookFireSpeed;
if(distance(InitPos, NewPos) > m_pClient->m_Tuning[g_Config.m_ClDummy].m_HookLength)
{
NewPos = InitPos + normalize(NewPos - InitPos) * m_pClient->m_Tuning[g_Config.m_ClDummy].m_HookLength;
DoBreak = true;
}
int TeleNr = 0;
Hit = Collision()->IntersectLineTeleHook(OldPos, NewPos, &FinishPos, 0x0, &TeleNr);
if(!DoBreak && Hit)
{
if(Hit != TILE_NOHOOK)
{
HookCollColor = color_cast<ColorRGBA>(ColorHSLA(g_Config.m_ClHookCollColorHookableColl));
}
}
if(m_pClient->IntersectCharacter(OldPos, FinishPos, FinishPos, ClientID) != -1)
{
HookCollColor = color_cast<ColorRGBA>(ColorHSLA(g_Config.m_ClHookCollColorTeeColl));
break;
}
if(Hit)
break;
NewPos.x = round_to_int(NewPos.x);
NewPos.y = round_to_int(NewPos.y);
if(OldPos == NewPos)
break;
ExDirection.x = round_to_int(ExDirection.x * 256.0f) / 256.0f;
ExDirection.y = round_to_int(ExDirection.y * 256.0f) / 256.0f;
} while(!DoBreak);
if(AlwaysRenderHookColl && RenderHookCollPlayer)
{
// invert the hook coll colors when using cl_show_hook_coll_always and +showhookcoll is pressed
HookCollColor = color_invert(HookCollColor);
}
Graphics()->SetColor(HookCollColor.WithAlpha(Alpha));
if(g_Config.m_ClHookCollSize > 0)
{
float LineWidth = 0.5f + (float)(g_Config.m_ClHookCollSize - 1) * 0.25f;
vec2 PerpToAngle = normalize(vec2(ExDirection.y, -ExDirection.x)) * GameClient()->m_Camera.m_Zoom;
vec2 Pos0 = FinishPos + PerpToAngle * -LineWidth;
vec2 Pos1 = FinishPos + PerpToAngle * LineWidth;
vec2 Pos2 = InitPos + PerpToAngle * -LineWidth;
vec2 Pos3 = InitPos + PerpToAngle * LineWidth;
IGraphics::CFreeformItem FreeformItem(Pos0.x, Pos0.y, Pos1.x, Pos1.y, Pos2.x, Pos2.y, Pos3.x, Pos3.y);
Graphics()->QuadsDrawFreeform(&FreeformItem, 1);
Graphics()->QuadsEnd();
}
else
{
IGraphics::CLineItem LineItem(InitPos.x, InitPos.y, FinishPos.x, FinishPos.y);
Graphics()->LinesDraw(&LineItem, 1);
Graphics()->LinesEnd();
}
}
Graphics()->SetColor(1.0f, 1.0f, 1.0f, 1.0f);
Graphics()->QuadsSetRotation(State.GetAttach()->m_Angle * pi * 2 + Angle);
@ -724,18 +773,20 @@ void CPlayers::OnRender()
continue;
}
RenderHookCollLine(&m_pClient->m_aClients[ClientID].m_RenderPrev, &m_pClient->m_aClients[ClientID].m_RenderCur, ClientID);
//don't render offscreen
vec2 *pRenderPos = &m_pClient->m_aClients[ClientID].m_RenderPos;
if(pRenderPos->x < ScreenX0 || pRenderPos->x > ScreenX1 || pRenderPos->y < ScreenY0 || pRenderPos->y > ScreenY1)
{
continue;
continue;
}
RenderPlayer(&m_pClient->m_aClients[ClientID].m_RenderPrev, &m_pClient->m_aClients[ClientID].m_RenderCur, &m_aRenderInfo[ClientID], ClientID);
}
if(LocalClientID != -1 && m_pClient->m_Snap.m_aCharacters[LocalClientID].m_Active && IsPlayerInfoAvailable(LocalClientID))
{
const CGameClient::CClientData *pLocalClientData = &m_pClient->m_aClients[LocalClientID];
RenderHookCollLine(&pLocalClientData->m_RenderPrev, &pLocalClientData->m_RenderCur, LocalClientID);
RenderPlayer(&pLocalClientData->m_RenderPrev, &pLocalClientData->m_RenderCur, &m_aRenderInfo[LocalClientID], LocalClientID);
}
}

View file

@ -26,6 +26,11 @@ class CPlayers : public CComponent
const CTeeRenderInfo *pRenderInfo,
int ClientID,
float Intra = 0.f);
void RenderHookCollLine(
const CNetObj_Character *pPrevChar,
const CNetObj_Character *pPlayerChar,
int ClientID,
float Intra = 0.f);
bool IsPlayerInfoAvailable(int ClientID) const;
int m_WeaponEmoteQuadContainerIndex;