mirror of
https://github.com/ddnet/ddnet.git
synced 2024-11-10 10:08:18 +00:00
Use existing code for rendering the ghost
This commit is contained in:
parent
5cc0d16029
commit
d09e825065
|
@ -6,9 +6,7 @@
|
|||
#include <engine/storage.h>
|
||||
#include <engine/shared/config.h>
|
||||
|
||||
#include <game/generated/client_data.h>
|
||||
#include <game/client/animstate.h>
|
||||
|
||||
#include "players.h"
|
||||
#include "race.h"
|
||||
#include "skins.h"
|
||||
#include "menus.h"
|
||||
|
@ -16,7 +14,7 @@
|
|||
|
||||
CGhost::CGhost() : m_StartRenderTick(-1), m_LastDeathTick(-1), m_Rendering(false), m_Recording(false) {}
|
||||
|
||||
void CGhost::GetGhostCharacter(CGhostCharacter_NoTick *pGhostChar, const CNetObj_Character *pChar)
|
||||
void CGhost::GetGhostCharacter(CGhostCharacter *pGhostChar, const CNetObj_Character *pChar)
|
||||
{
|
||||
pGhostChar->m_X = pChar->m_X;
|
||||
pGhostChar->m_Y = pChar->m_Y;
|
||||
|
@ -29,6 +27,25 @@ void CGhost::GetGhostCharacter(CGhostCharacter_NoTick *pGhostChar, const CNetObj
|
|||
pGhostChar->m_HookX = pChar->m_HookX;
|
||||
pGhostChar->m_HookY = pChar->m_HookY;
|
||||
pGhostChar->m_AttackTick = pChar->m_AttackTick;
|
||||
pGhostChar->m_Tick = pChar->m_Tick;
|
||||
}
|
||||
|
||||
void CGhost::GetNetObjCharacter(CNetObj_Character *pChar, const CGhostCharacter *pGhostChar)
|
||||
{
|
||||
mem_zero(pChar, sizeof(CNetObj_Character));
|
||||
pChar->m_X = pGhostChar->m_X;
|
||||
pChar->m_Y = pGhostChar->m_Y;
|
||||
pChar->m_VelX = pGhostChar->m_VelX;
|
||||
pChar->m_VelY = 0;
|
||||
pChar->m_Angle = pGhostChar->m_Angle;
|
||||
pChar->m_Direction = pGhostChar->m_Direction;
|
||||
pChar->m_Weapon = pGhostChar->m_Weapon == WEAPON_GRENADE ? WEAPON_GRENADE : WEAPON_GUN;
|
||||
pChar->m_HookState = pGhostChar->m_HookState;
|
||||
pChar->m_HookX = pGhostChar->m_HookX;
|
||||
pChar->m_HookY = pGhostChar->m_HookY;
|
||||
pChar->m_AttackTick = pGhostChar->m_AttackTick;
|
||||
pChar->m_HookedPlayer = -1;
|
||||
pChar->m_Tick = pGhostChar->m_Tick;
|
||||
}
|
||||
|
||||
void CGhost::AddInfos(const CNetObj_Character *pChar)
|
||||
|
@ -60,7 +77,6 @@ void CGhost::AddInfos(const CNetObj_Character *pChar)
|
|||
|
||||
CGhostCharacter GhostChar;
|
||||
GetGhostCharacter(&GhostChar, pChar);
|
||||
GhostChar.m_Tick = pChar->m_Tick;
|
||||
m_CurGhost.m_lPath.add(GhostChar);
|
||||
if(GhostRecorder()->IsRecording())
|
||||
GhostRecorder()->WriteData(GHOSTDATA_TYPE_CHARACTER, (const char*)&GhostChar, sizeof(CGhostCharacter));
|
||||
|
@ -141,8 +157,9 @@ void CGhost::OnRender()
|
|||
|
||||
int CurPos = pGhost->m_PlaybackPos;
|
||||
int PrevPos = max(0, CurPos - 1);
|
||||
CGhostCharacter Player = pGhost->m_lPath[CurPos];
|
||||
CGhostCharacter Prev = pGhost->m_lPath[PrevPos];
|
||||
CNetObj_Character Player, Prev;
|
||||
GetNetObjCharacter(&Player, &pGhost->m_lPath[CurPos]);
|
||||
GetNetObjCharacter(&Prev, &pGhost->m_lPath[PrevPos]);
|
||||
|
||||
int TickDiff = Player.m_Tick - Prev.m_Tick;
|
||||
float IntraTick = 0.f;
|
||||
|
@ -151,100 +168,14 @@ void CGhost::OnRender()
|
|||
|
||||
Player.m_AttackTick += Client()->GameTick() - GhostTick;
|
||||
|
||||
RenderGhostHook(&Prev, &Player, IntraTick);
|
||||
RenderGhost(&Prev, &Player, &pGhost->m_RenderInfo, IntraTick);
|
||||
m_pClient->m_pPlayers->RenderHook(&Prev, &Player, &pGhost->m_RenderInfo , -2, vec2(), vec2(), IntraTick);
|
||||
m_pClient->m_pPlayers->RenderPlayer(&Prev, &Player, &pGhost->m_RenderInfo, -2, vec2(), IntraTick);
|
||||
}
|
||||
|
||||
if(!ActiveGhosts)
|
||||
StopRender();
|
||||
}
|
||||
|
||||
void CGhost::RenderGhost(const CGhostCharacter_NoTick *pPrev, const CGhostCharacter_NoTick *pPlayer, CTeeRenderInfo *pInfo, float IntraTick)
|
||||
{
|
||||
float Angle = mix((float)pPrev->m_Angle, (float)pPlayer->m_Angle, IntraTick)/256.0f;
|
||||
vec2 Direction = GetDirection((int)(Angle*256.0f));
|
||||
vec2 Position = mix(vec2(pPrev->m_X, pPrev->m_Y), vec2(pPlayer->m_X, pPlayer->m_Y), IntraTick);
|
||||
vec2 Vel = mix(vec2(pPrev->m_VelX/256.0f, pPrev->m_VelY/256.0f), vec2(pPlayer->m_VelX/256.0f, pPlayer->m_VelY/256.0f), IntraTick);
|
||||
|
||||
bool Stationary = pPlayer->m_VelX <= 1 && pPlayer->m_VelX >= -1;
|
||||
bool InAir = !Collision()->CheckPoint(pPlayer->m_X, pPlayer->m_Y+16);
|
||||
bool WantOtherDir = (pPlayer->m_Direction == -1 && Vel.x > 0) || (pPlayer->m_Direction == 1 && Vel.x < 0);
|
||||
|
||||
float WalkTime = fmod(absolute(Position.x), 100.0f)/100.0f;
|
||||
CAnimState State;
|
||||
State.Set(&g_pData->m_aAnimations[ANIM_BASE], 0);
|
||||
|
||||
if(InAir)
|
||||
State.Add(&g_pData->m_aAnimations[ANIM_INAIR], 0, 1.0f);
|
||||
else if(Stationary)
|
||||
State.Add(&g_pData->m_aAnimations[ANIM_IDLE], 0, 1.0f);
|
||||
else if(!WantOtherDir)
|
||||
State.Add(&g_pData->m_aAnimations[ANIM_WALK], WalkTime, 1.0f);
|
||||
|
||||
if (pPlayer->m_Weapon == WEAPON_GRENADE)
|
||||
{
|
||||
Graphics()->TextureSet(g_pData->m_aImages[IMAGE_GAME].m_Id);
|
||||
Graphics()->QuadsBegin();
|
||||
Graphics()->QuadsSetRotation(State.GetAttach()->m_Angle*pi*2+Angle);
|
||||
Graphics()->SetColor(1.0f, 1.0f, 1.0f, 0.5f);
|
||||
|
||||
// normal weapons
|
||||
int iw = clamp(pPlayer->m_Weapon, 0, NUM_WEAPONS-1);
|
||||
RenderTools()->SelectSprite(g_pData->m_Weapons.m_aId[iw].m_pSpriteBody, Direction.x < 0 ? SPRITE_FLAG_FLIP_Y : 0);
|
||||
|
||||
vec2 Dir = Direction;
|
||||
float Recoil = 0.0f;
|
||||
// TODO: is this correct?
|
||||
float a = (Client()->PredGameTick()-pPlayer->m_AttackTick+IntraTick)/5.0f;
|
||||
if(a < 1)
|
||||
Recoil = sinf(a*pi);
|
||||
|
||||
vec2 p = Position + Dir * g_pData->m_Weapons.m_aId[iw].m_Offsetx - Direction*Recoil*10.0f;
|
||||
p.y += g_pData->m_Weapons.m_aId[iw].m_Offsety;
|
||||
RenderTools()->DrawSprite(p.x, p.y, g_pData->m_Weapons.m_aId[iw].m_VisualSize);
|
||||
Graphics()->QuadsEnd();
|
||||
}
|
||||
|
||||
// Render ghost
|
||||
RenderTools()->RenderTee(&State, pInfo, 0, Direction, Position, true);
|
||||
}
|
||||
|
||||
void CGhost::RenderGhostHook(const CGhostCharacter_NoTick *pPrev, const CGhostCharacter_NoTick *pPlayer, float IntraTick)
|
||||
{
|
||||
if(pPrev->m_HookState<=0 || pPlayer->m_HookState<=0)
|
||||
return;
|
||||
|
||||
vec2 Pos = mix(vec2(pPrev->m_X, pPrev->m_Y), vec2(pPlayer->m_X, pPlayer->m_Y), IntraTick);
|
||||
|
||||
vec2 HookPos = mix(vec2(pPrev->m_HookX, pPrev->m_HookY), vec2(pPlayer->m_HookX, pPlayer->m_HookY), IntraTick);
|
||||
float d = distance(Pos, HookPos);
|
||||
vec2 Dir = normalize(Pos-HookPos);
|
||||
|
||||
Graphics()->TextureSet(g_pData->m_aImages[IMAGE_GAME].m_Id);
|
||||
Graphics()->QuadsBegin();
|
||||
Graphics()->QuadsSetRotation(GetAngle(Dir)+pi);
|
||||
Graphics()->SetColor(1.0f, 1.0f, 1.0f, 0.5f);
|
||||
|
||||
// render head
|
||||
RenderTools()->SelectSprite(SPRITE_HOOK_HEAD);
|
||||
IGraphics::CQuadItem QuadItem(HookPos.x, HookPos.y, 24, 16);
|
||||
Graphics()->QuadsDraw(&QuadItem, 1);
|
||||
|
||||
// render chain
|
||||
RenderTools()->SelectSprite(SPRITE_HOOK_CHAIN);
|
||||
IGraphics::CQuadItem Array[1024];
|
||||
int j = 0;
|
||||
for(float f = 24; f < d && j < 1024; f += 24, j++)
|
||||
{
|
||||
vec2 p = HookPos + Dir*f;
|
||||
Array[j] = IGraphics::CQuadItem(p.x, p.y, 24, 16);
|
||||
}
|
||||
|
||||
Graphics()->QuadsDraw(Array, j);
|
||||
Graphics()->QuadsSetRotation(0);
|
||||
Graphics()->QuadsEnd();
|
||||
}
|
||||
|
||||
void CGhost::InitRenderInfos(CTeeRenderInfo *pRenderInfo, const char *pSkinName, int UseCustomColor, int ColorBody, int ColorFeet)
|
||||
{
|
||||
int SkinId = m_pClient->m_pSkins->Find(pSkinName);
|
||||
|
|
|
@ -81,7 +81,8 @@ private:
|
|||
bool m_Recording;
|
||||
bool m_Rendering;
|
||||
|
||||
static void GetGhostCharacter(CGhostCharacter_NoTick *pGhostChar, const CNetObj_Character *pChar);
|
||||
static void GetGhostCharacter(CGhostCharacter *pGhostChar, const CNetObj_Character *pChar);
|
||||
static void GetNetObjCharacter(CNetObj_Character *pChar, const CGhostCharacter *pGhostChar);
|
||||
|
||||
void AddInfos(const CNetObj_Character *pChar);
|
||||
int GetSlot() const;
|
||||
|
@ -91,9 +92,6 @@ private:
|
|||
void StartRender();
|
||||
void StopRender();
|
||||
|
||||
void RenderGhost(const CGhostCharacter_NoTick *pPrev, const CGhostCharacter_NoTick *pPlayer, CTeeRenderInfo *pInfo, float IntraTick);
|
||||
void RenderGhostHook(const CGhostCharacter_NoTick *pPrev, const CGhostCharacter_NoTick *pPlayer, float IntraTick);
|
||||
|
||||
void InitRenderInfos(CTeeRenderInfo *pRenderInfo, const char *pSkinName, int UseCustomColor, int ColorBody, int ColorFeet);
|
||||
|
||||
static void ConGPlay(IConsole::IResult *pResult, void *pUserData);
|
||||
|
|
|
@ -219,10 +219,11 @@ vec2 NonPredPos = mix(vec2(Prev.m_X, Prev.m_Y), vec2(Player.m_X, Player.m_Y), In
|
|||
void CPlayers::RenderHook(
|
||||
const CNetObj_Character *pPrevChar,
|
||||
const CNetObj_Character *pPlayerChar,
|
||||
const CNetObj_PlayerInfo *pPrevInfo,
|
||||
const CNetObj_PlayerInfo *pPlayerInfo,
|
||||
const CTeeRenderInfo *pRenderInfo,
|
||||
int ClientID,
|
||||
const vec2 &parPosition,
|
||||
const vec2 &PositionTo
|
||||
const vec2 &PositionTo,
|
||||
float Intra
|
||||
)
|
||||
{
|
||||
CNetObj_Character Prev;
|
||||
|
@ -230,23 +231,30 @@ void CPlayers::RenderHook(
|
|||
Prev = *pPrevChar;
|
||||
Player = *pPlayerChar;
|
||||
|
||||
CNetObj_PlayerInfo pInfo = *pPlayerInfo;
|
||||
CTeeRenderInfo RenderInfo = m_aRenderInfo[pInfo.m_ClientID];
|
||||
CTeeRenderInfo RenderInfo = *pRenderInfo;
|
||||
|
||||
bool AntiPingPlayers = m_pClient->AntiPingPlayers();
|
||||
bool Local = m_pClient->m_Snap.m_LocalClientID == ClientID;
|
||||
|
||||
// don't render hooks to not active character cores
|
||||
if (pPlayerChar->m_HookedPlayer != -1 && !m_pClient->m_Snap.m_aCharacters[pPlayerChar->m_HookedPlayer].m_Active)
|
||||
return;
|
||||
|
||||
float IntraTick = Client()->IntraGameTick();
|
||||
if(ClientID < 0)
|
||||
{
|
||||
IntraTick = Intra;
|
||||
AntiPingPlayers = false;
|
||||
}
|
||||
|
||||
bool OtherTeam;
|
||||
|
||||
if (m_pClient->m_aClients[m_pClient->m_Snap.m_LocalClientID].m_Team == TEAM_SPECTATORS && m_pClient->m_Snap.m_SpecInfo.m_SpectatorID == SPEC_FREEVIEW)
|
||||
if (m_pClient->m_aClients[m_pClient->m_Snap.m_LocalClientID].m_Team == TEAM_SPECTATORS && m_pClient->m_Snap.m_SpecInfo.m_SpectatorID == SPEC_FREEVIEW || ClientID < 0)
|
||||
OtherTeam = false;
|
||||
else if (m_pClient->m_Snap.m_SpecInfo.m_Active && m_pClient->m_Snap.m_SpecInfo.m_SpectatorID != SPEC_FREEVIEW)
|
||||
OtherTeam = m_pClient->m_Teams.Team(pInfo.m_ClientID) != m_pClient->m_Teams.Team(m_pClient->m_Snap.m_SpecInfo.m_SpectatorID);
|
||||
OtherTeam = m_pClient->m_Teams.Team(ClientID) != m_pClient->m_Teams.Team(m_pClient->m_Snap.m_SpecInfo.m_SpectatorID);
|
||||
else
|
||||
OtherTeam = m_pClient->m_Teams.Team(pInfo.m_ClientID) != m_pClient->m_Teams.Team(m_pClient->m_Snap.m_LocalClientID);
|
||||
OtherTeam = m_pClient->m_Teams.Team(ClientID) != m_pClient->m_Teams.Team(m_pClient->m_Snap.m_LocalClientID);
|
||||
|
||||
if (OtherTeam)
|
||||
{
|
||||
|
@ -257,10 +265,10 @@ void CPlayers::RenderHook(
|
|||
// set size
|
||||
RenderInfo.m_Size = 64.0f;
|
||||
|
||||
if (!m_pClient->AntiPingPlayers())
|
||||
if (!AntiPingPlayers)
|
||||
{
|
||||
// use preditect players if needed
|
||||
if(pInfo.m_Local && g_Config.m_ClPredict && Client()->State() != IClient::STATE_DEMOPLAYBACK)
|
||||
if(Local && g_Config.m_ClPredict && Client()->State() != IClient::STATE_DEMOPLAYBACK)
|
||||
{
|
||||
if(!m_pClient->m_Snap.m_pLocalCharacter || (m_pClient->m_Snap.m_pGameInfoObj && m_pClient->m_Snap.m_pGameInfoObj->m_GameStateFlags&GAMESTATEFLAG_GAMEOVER))
|
||||
{
|
||||
|
@ -281,8 +289,8 @@ void CPlayers::RenderHook(
|
|||
if(m_pClient->m_Snap.m_pLocalCharacter && !(m_pClient->m_Snap.m_pGameInfoObj && m_pClient->m_Snap.m_pGameInfoObj->m_GameStateFlags&GAMESTATEFLAG_GAMEOVER))
|
||||
{
|
||||
// apply predicted results
|
||||
m_pClient->m_aClients[pInfo.m_ClientID].m_Predicted.Write(&Player);
|
||||
m_pClient->m_aClients[pInfo.m_ClientID].m_PrevPredicted.Write(&Prev);
|
||||
m_pClient->m_aClients[ClientID].m_Predicted.Write(&Player);
|
||||
m_pClient->m_aClients[ClientID].m_PrevPredicted.Write(&Prev);
|
||||
|
||||
IntraTick = Client()->PredIntraGameTick();
|
||||
}
|
||||
|
@ -290,7 +298,7 @@ void CPlayers::RenderHook(
|
|||
}
|
||||
|
||||
vec2 Position;
|
||||
if (!m_pClient->AntiPingPlayers())
|
||||
if (!AntiPingPlayers)
|
||||
Position = mix(vec2(Prev.m_X, Prev.m_Y), vec2(Player.m_X, Player.m_Y), IntraTick);
|
||||
else
|
||||
Position = parPosition;
|
||||
|
@ -302,14 +310,17 @@ void CPlayers::RenderHook(
|
|||
Graphics()->QuadsBegin();
|
||||
//Graphics()->QuadsBegin();
|
||||
|
||||
if(ClientID < 0)
|
||||
Graphics()->SetColor(1.0f, 1.0f, 1.0f, 0.5f);
|
||||
|
||||
vec2 Pos = Position;
|
||||
vec2 HookPos;
|
||||
|
||||
if (!m_pClient->AntiPingPlayers())
|
||||
if (!AntiPingPlayers)
|
||||
{
|
||||
if(pPlayerChar->m_HookedPlayer != -1)
|
||||
{
|
||||
if(m_pClient->m_Snap.m_pLocalInfo && pPlayerChar->m_HookedPlayer == m_pClient->m_Snap.m_pLocalInfo->m_ClientID && !m_pClient->m_Snap.m_SpecInfo.m_Active)
|
||||
if(m_pClient->m_Snap.m_LocalClientID != -1 && pPlayerChar->m_HookedPlayer == m_pClient->m_Snap.m_LocalClientID && !m_pClient->m_Snap.m_SpecInfo.m_Active)
|
||||
{
|
||||
if(Client()->State() == IClient::STATE_DEMOPLAYBACK) // only use prediction if needed
|
||||
HookPos = vec2(m_pClient->m_LocalCharacterPos.x, m_pClient->m_LocalCharacterPos.y);
|
||||
|
@ -317,7 +328,7 @@ void CPlayers::RenderHook(
|
|||
HookPos = mix(vec2(m_pClient->m_PredictedPrevChar.m_Pos.x, m_pClient->m_PredictedPrevChar.m_Pos.y),
|
||||
vec2(m_pClient->m_PredictedChar.m_Pos.x, m_pClient->m_PredictedChar.m_Pos.y), Client()->PredIntraGameTick());
|
||||
}
|
||||
else if(pInfo.m_Local)
|
||||
else if(Local)
|
||||
{
|
||||
HookPos = mix(vec2(m_pClient->m_Snap.m_aCharacters[pPlayerChar->m_HookedPlayer].m_Prev.m_X,
|
||||
m_pClient->m_Snap.m_aCharacters[pPlayerChar->m_HookedPlayer].m_Prev.m_Y),
|
||||
|
@ -374,9 +385,10 @@ void CPlayers::RenderHook(
|
|||
void CPlayers::RenderPlayer(
|
||||
const CNetObj_Character *pPrevChar,
|
||||
const CNetObj_Character *pPlayerChar,
|
||||
const CNetObj_PlayerInfo *pPrevInfo,
|
||||
const CNetObj_PlayerInfo *pPlayerInfo,
|
||||
const vec2 &parPosition
|
||||
const CTeeRenderInfo *pRenderInfo,
|
||||
int ClientID,
|
||||
const vec2 &parPosition,
|
||||
float Intra
|
||||
/* vec2 &PrevPos,
|
||||
vec2 &SmoothPos,
|
||||
int &MoveCnt
|
||||
|
@ -387,27 +399,34 @@ void CPlayers::RenderPlayer(
|
|||
Prev = *pPrevChar;
|
||||
Player = *pPlayerChar;
|
||||
|
||||
CNetObj_PlayerInfo pInfo = *pPlayerInfo;
|
||||
CTeeRenderInfo RenderInfo = m_aRenderInfo[pInfo.m_ClientID];
|
||||
CTeeRenderInfo RenderInfo = *pRenderInfo;
|
||||
|
||||
bool AntiPingPlayers = m_pClient->AntiPingPlayers();
|
||||
bool Local = m_pClient->m_Snap.m_LocalClientID == ClientID;
|
||||
|
||||
bool NewTick = m_pClient->m_NewTick;
|
||||
|
||||
bool OtherTeam;
|
||||
|
||||
if (m_pClient->m_aClients[m_pClient->m_Snap.m_LocalClientID].m_Team == TEAM_SPECTATORS && m_pClient->m_Snap.m_SpecInfo.m_SpectatorID == SPEC_FREEVIEW)
|
||||
if (m_pClient->m_aClients[m_pClient->m_Snap.m_LocalClientID].m_Team == TEAM_SPECTATORS && m_pClient->m_Snap.m_SpecInfo.m_SpectatorID == SPEC_FREEVIEW || ClientID < 0)
|
||||
OtherTeam = false;
|
||||
else if (m_pClient->m_Snap.m_SpecInfo.m_Active && m_pClient->m_Snap.m_SpecInfo.m_SpectatorID != SPEC_FREEVIEW)
|
||||
OtherTeam = m_pClient->m_Teams.Team(pInfo.m_ClientID) != m_pClient->m_Teams.Team(m_pClient->m_Snap.m_SpecInfo.m_SpectatorID);
|
||||
OtherTeam = m_pClient->m_Teams.Team(ClientID) != m_pClient->m_Teams.Team(m_pClient->m_Snap.m_SpecInfo.m_SpectatorID);
|
||||
else
|
||||
OtherTeam = m_pClient->m_Teams.Team(pInfo.m_ClientID) != m_pClient->m_Teams.Team(m_pClient->m_Snap.m_LocalClientID);
|
||||
OtherTeam = m_pClient->m_Teams.Team(ClientID) != m_pClient->m_Teams.Team(m_pClient->m_Snap.m_LocalClientID);
|
||||
|
||||
// set size
|
||||
RenderInfo.m_Size = 64.0f;
|
||||
|
||||
float IntraTick = Client()->IntraGameTick();
|
||||
if(ClientID < 0)
|
||||
{
|
||||
IntraTick = Intra;
|
||||
AntiPingPlayers = false;
|
||||
}
|
||||
|
||||
float Angle;
|
||||
if(pInfo.m_Local && Client()->State() != IClient::STATE_DEMOPLAYBACK)
|
||||
if(Local && Client()->State() != IClient::STATE_DEMOPLAYBACK)
|
||||
{
|
||||
// just use the direct input if it's the local player we are rendering
|
||||
Angle = GetAngle(m_pClient->m_pControls->m_MousePos[g_Config.m_ClDummy]);
|
||||
|
@ -436,9 +455,9 @@ void CPlayers::RenderPlayer(
|
|||
|
||||
|
||||
// use preditect players if needed
|
||||
if (!m_pClient->AntiPingPlayers())
|
||||
if (!AntiPingPlayers)
|
||||
{
|
||||
if(pInfo.m_Local && g_Config.m_ClPredict && Client()->State() != IClient::STATE_DEMOPLAYBACK)
|
||||
if(Local && g_Config.m_ClPredict && Client()->State() != IClient::STATE_DEMOPLAYBACK)
|
||||
{
|
||||
if(!m_pClient->m_Snap.m_pLocalCharacter || (m_pClient->m_Snap.m_pGameInfoObj && m_pClient->m_Snap.m_pGameInfoObj->m_GameStateFlags&GAMESTATEFLAG_GAMEOVER))
|
||||
{
|
||||
|
@ -460,8 +479,8 @@ void CPlayers::RenderPlayer(
|
|||
if(m_pClient->m_Snap.m_pLocalCharacter && !(m_pClient->m_Snap.m_pGameInfoObj && m_pClient->m_Snap.m_pGameInfoObj->m_GameStateFlags&GAMESTATEFLAG_GAMEOVER))
|
||||
{
|
||||
// apply predicted results
|
||||
m_pClient->m_aClients[pInfo.m_ClientID].m_Predicted.Write(&Player);
|
||||
m_pClient->m_aClients[pInfo.m_ClientID].m_PrevPredicted.Write(&Prev);
|
||||
m_pClient->m_aClients[ClientID].m_Predicted.Write(&Player);
|
||||
m_pClient->m_aClients[ClientID].m_PrevPredicted.Write(&Prev);
|
||||
|
||||
IntraTick = Client()->PredIntraGameTick();
|
||||
NewTick = m_pClient->m_NewPredictedTick;
|
||||
|
@ -471,7 +490,7 @@ void CPlayers::RenderPlayer(
|
|||
|
||||
vec2 Direction = GetDirection((int)(Angle*256.0f));
|
||||
vec2 Position;
|
||||
if (!m_pClient->AntiPingPlayers())
|
||||
if (!AntiPingPlayers)
|
||||
Position = mix(vec2(Prev.m_X, Prev.m_Y), vec2(Player.m_X, Player.m_Y), IntraTick);
|
||||
else
|
||||
Position = parPosition;
|
||||
|
@ -539,7 +558,7 @@ void CPlayers::RenderPlayer(
|
|||
|
||||
// draw gun
|
||||
{
|
||||
if (Player.m_PlayerFlags&PLAYERFLAG_AIM && ((!pPlayerInfo->m_Local && g_Config.m_ClShowHookCollOther) || (pPlayerInfo->m_Local && g_Config.m_ClShowHookCollOwn)))
|
||||
if (ClientID >= 0 && Player.m_PlayerFlags&PLAYERFLAG_AIM && ((!Local && g_Config.m_ClShowHookCollOther) || (Local && g_Config.m_ClShowHookCollOwn)))
|
||||
{
|
||||
float Alpha = 1.0f;
|
||||
if (OtherTeam)
|
||||
|
@ -547,7 +566,7 @@ void CPlayers::RenderPlayer(
|
|||
|
||||
vec2 ExDirection = Direction;
|
||||
|
||||
if (pPlayerInfo->m_Local && Client()->State() != IClient::STATE_DEMOPLAYBACK)
|
||||
if (Local && Client()->State() != IClient::STATE_DEMOPLAYBACK)
|
||||
ExDirection = normalize(vec2(m_pClient->m_pControls->m_InputData[g_Config.m_ClDummy].m_TargetX, m_pClient->m_pControls->m_InputData[g_Config.m_ClDummy].m_TargetY));
|
||||
|
||||
Graphics()->TextureSet(-1);
|
||||
|
@ -583,7 +602,7 @@ void CPlayers::RenderPlayer(
|
|||
Graphics()->SetColor(130.0f/255.0f, 232.0f/255.0f, 160.0f/255.0f, Alpha);
|
||||
}
|
||||
|
||||
if(m_pClient->m_Tuning[g_Config.m_ClDummy].m_PlayerHooking && m_pClient->IntersectCharacter(OldPos, FinishPos, FinishPos, pPlayerInfo->m_ClientID) != -1)
|
||||
if(m_pClient->m_Tuning[g_Config.m_ClDummy].m_PlayerHooking && m_pClient->IntersectCharacter(OldPos, FinishPos, FinishPos, ClientID) != -1)
|
||||
{
|
||||
Graphics()->SetColor(1.0f, 1.0f, 0.0f, Alpha);
|
||||
break;
|
||||
|
@ -611,6 +630,9 @@ void CPlayers::RenderPlayer(
|
|||
Graphics()->QuadsBegin();
|
||||
Graphics()->QuadsSetRotation(State.GetAttach()->m_Angle*pi*2+Angle);
|
||||
|
||||
if(ClientID < 0)
|
||||
Graphics()->SetColor(1.0f, 1.0f, 1.0f, 0.5f);
|
||||
|
||||
// normal weapons
|
||||
int iw = clamp(Player.m_Weapon, 0, NUM_WEAPONS-1);
|
||||
RenderTools()->SelectSprite(g_pData->m_Weapons.m_aId[iw].m_pSpriteBody, Direction.x < 0 ? SPRITE_FLAG_FLIP_Y : 0);
|
||||
|
@ -772,7 +794,7 @@ void CPlayers::RenderPlayer(
|
|||
}
|
||||
|
||||
// render the "shadow" tee
|
||||
if(pInfo.m_Local && (g_Config.m_Debug || g_Config.m_ClUnpredictedShadow))
|
||||
if(Local && (g_Config.m_Debug || g_Config.m_ClUnpredictedShadow))
|
||||
{
|
||||
vec2 GhostPosition = mix(vec2(pPrevChar->m_X, pPrevChar->m_Y), vec2(pPlayerChar->m_X, pPlayerChar->m_Y), Client()->IntraGameTick());
|
||||
CTeeRenderInfo Ghost = RenderInfo;
|
||||
|
@ -789,7 +811,7 @@ void CPlayers::RenderPlayer(
|
|||
RenderInfo.m_ColorFeet.a = g_Config.m_ClShowOthersAlpha / 100.0f;
|
||||
}
|
||||
|
||||
if (g_Config.m_ClShowDirection && (!pInfo.m_Local || DemoPlayer()->IsPlaying()))
|
||||
if (g_Config.m_ClShowDirection && ClientID >= 0 && (Local || DemoPlayer()->IsPlaying()))
|
||||
{
|
||||
if (Player.m_Direction == -1)
|
||||
{
|
||||
|
@ -825,7 +847,7 @@ void CPlayers::RenderPlayer(
|
|||
}
|
||||
}
|
||||
|
||||
RenderTools()->RenderTee(&State, &RenderInfo, Player.m_Emote, Direction, Position, OtherTeam);
|
||||
RenderTools()->RenderTee(&State, &RenderInfo, Player.m_Emote, Direction, Position, OtherTeam || ClientID < 0);
|
||||
|
||||
if(Player.m_PlayerFlags&PLAYERFLAG_CHATTING)
|
||||
{
|
||||
|
@ -839,13 +861,16 @@ void CPlayers::RenderPlayer(
|
|||
Graphics()->QuadsEnd();
|
||||
}
|
||||
|
||||
if (m_pClient->m_aClients[pInfo.m_ClientID].m_EmoticonStart != -1 && m_pClient->m_aClients[pInfo.m_ClientID].m_EmoticonStart + 2 * Client()->GameTickSpeed() > Client()->GameTick())
|
||||
if(ClientID < 0)
|
||||
return;
|
||||
|
||||
if (m_pClient->m_aClients[ClientID].m_EmoticonStart != -1 && m_pClient->m_aClients[ClientID].m_EmoticonStart + 2 * Client()->GameTickSpeed() > Client()->GameTick())
|
||||
{
|
||||
Graphics()->TextureSet(g_pData->m_aImages[IMAGE_EMOTICONS].m_Id);
|
||||
Graphics()->QuadsBegin();
|
||||
|
||||
int SinceStart = Client()->GameTick() - m_pClient->m_aClients[pInfo.m_ClientID].m_EmoticonStart;
|
||||
int FromEnd = m_pClient->m_aClients[pInfo.m_ClientID].m_EmoticonStart + 2 * Client()->GameTickSpeed() - Client()->GameTick();
|
||||
int SinceStart = Client()->GameTick() - m_pClient->m_aClients[ClientID].m_EmoticonStart;
|
||||
int FromEnd = m_pClient->m_aClients[ClientID].m_EmoticonStart + 2 * Client()->GameTickSpeed() - Client()->GameTick();
|
||||
|
||||
float a = 1;
|
||||
|
||||
|
@ -868,29 +893,29 @@ void CPlayers::RenderPlayer(
|
|||
if (OtherTeam)
|
||||
Graphics()->SetColor(1.0f, 1.0f, 1.0f, a * (float)g_Config.m_ClShowOthersAlpha / 100.0f);
|
||||
// client_datas::emoticon is an offset from the first emoticon
|
||||
RenderTools()->SelectSprite(SPRITE_OOP + m_pClient->m_aClients[pInfo.m_ClientID].m_Emoticon);
|
||||
RenderTools()->SelectSprite(SPRITE_OOP + m_pClient->m_aClients[ClientID].m_Emoticon);
|
||||
IGraphics::CQuadItem QuadItem(Position.x, Position.y - 23 - 32*h, 64, 64*h);
|
||||
Graphics()->QuadsDraw(&QuadItem, 1);
|
||||
Graphics()->QuadsEnd();
|
||||
}
|
||||
|
||||
if(g_Config.m_ClNameplates && m_pClient->AntiPingPlayers())
|
||||
if(g_Config.m_ClNameplates && AntiPingPlayers)
|
||||
{
|
||||
float FontSize = 18.0f + 20.0f * g_Config.m_ClNameplatesSize / 100.0f;
|
||||
float FontSizeClan = 18.0f + 20.0f * g_Config.m_ClNameplatesClanSize / 100.0f;
|
||||
// render name plate
|
||||
if(!pPlayerInfo->m_Local)
|
||||
if(Local)
|
||||
{
|
||||
float a = 1;
|
||||
if(g_Config.m_ClNameplatesAlways == 0)
|
||||
a = clamp(1-powf(distance(m_pClient->m_pControls->m_TargetPos[g_Config.m_ClDummy], Position)/200.0f,16.0f), 0.0f, 1.0f);
|
||||
|
||||
const char *pName = m_pClient->m_aClients[pPlayerInfo->m_ClientID].m_aName;
|
||||
const char *pName = m_pClient->m_aClients[ClientID].m_aName;
|
||||
float tw = TextRender()->TextWidth(0, FontSize, pName, -1);
|
||||
|
||||
vec3 rgb = vec3(1.0f, 1.0f, 1.0f);
|
||||
if(g_Config.m_ClNameplatesTeamcolors && m_pClient->m_Teams.Team(pPlayerInfo->m_ClientID))
|
||||
rgb = HslToRgb(vec3(m_pClient->m_Teams.Team(pPlayerInfo->m_ClientID) / 64.0f, 1.0f, 0.75f));
|
||||
if(g_Config.m_ClNameplatesTeamcolors && m_pClient->m_Teams.Team(ClientID))
|
||||
rgb = HslToRgb(vec3(m_pClient->m_Teams.Team(ClientID) / 64.0f, 1.0f, 0.75f));
|
||||
|
||||
if (OtherTeam)
|
||||
{
|
||||
|
@ -904,9 +929,9 @@ void CPlayers::RenderPlayer(
|
|||
}
|
||||
if(g_Config.m_ClNameplatesTeamcolors && m_pClient->m_Snap.m_pGameInfoObj && m_pClient->m_Snap.m_pGameInfoObj->m_GameFlags&GAMEFLAG_TEAMS)
|
||||
{
|
||||
if(pPlayerInfo->m_Team == TEAM_RED)
|
||||
if(m_pClient->m_aClients[ClientID].m_Team == TEAM_RED)
|
||||
TextRender()->TextColor(1.0f, 0.5f, 0.5f, a);
|
||||
else if(pPlayerInfo->m_Team == TEAM_BLUE)
|
||||
else if(m_pClient->m_aClients[ClientID].m_Team == TEAM_BLUE)
|
||||
TextRender()->TextColor(0.7f, 0.7f, 1.0f, a);
|
||||
}
|
||||
|
||||
|
@ -914,7 +939,7 @@ void CPlayers::RenderPlayer(
|
|||
|
||||
if(g_Config.m_ClNameplatesClan)
|
||||
{
|
||||
const char *pClan = m_pClient->m_aClients[pPlayerInfo->m_ClientID].m_aClan;
|
||||
const char *pClan = m_pClient->m_aClients[ClientID].m_aClan;
|
||||
float tw_clan = TextRender()->TextWidth(0, FontSizeClan, pClan, -1);
|
||||
TextRender()->Text(0, Position.x-tw_clan/2.0f, Position.y-FontSize-FontSizeClan-38.0f, FontSizeClan, pClan, -1);
|
||||
}
|
||||
|
@ -922,7 +947,7 @@ void CPlayers::RenderPlayer(
|
|||
if(g_Config.m_Debug) // render client id when in debug aswell
|
||||
{
|
||||
char aBuf[128];
|
||||
str_format(aBuf, sizeof(aBuf),"%d", pPlayerInfo->m_ClientID);
|
||||
str_format(aBuf, sizeof(aBuf),"%d", ClientID);
|
||||
float Offset = g_Config.m_ClNameplatesClan ? (FontSize * 2 + FontSizeClan) : (FontSize * 2);
|
||||
float tw_id = TextRender()->TextWidth(0, FontSize, aBuf, -1);
|
||||
TextRender()->Text(0, Position.x-tw_id/2.0f, Position.y-Offset-38.0f, 28.0f, aBuf, -1);
|
||||
|
@ -1027,7 +1052,7 @@ void CPlayers::OnRender()
|
|||
if(pPrevInfo && pInfo)
|
||||
{
|
||||
//
|
||||
bool Local = ((const CNetObj_PlayerInfo *)pInfo)->m_Local !=0;
|
||||
bool Local = m_pClient->m_Snap.m_LocalClientID == i;
|
||||
if((p % 2) == 0 && Local) continue;
|
||||
if((p % 2) == 1 && !Local) continue;
|
||||
|
||||
|
@ -1040,8 +1065,8 @@ void CPlayers::OnRender()
|
|||
RenderHook(
|
||||
&PrevChar,
|
||||
&CurChar,
|
||||
(const CNetObj_PlayerInfo *)pPrevInfo,
|
||||
(const CNetObj_PlayerInfo *)pInfo,
|
||||
&m_aRenderInfo[i],
|
||||
i,
|
||||
PredictedPos[i],
|
||||
PredictedPos[PrevChar.m_HookedPlayer]
|
||||
);
|
||||
|
@ -1049,8 +1074,8 @@ void CPlayers::OnRender()
|
|||
RenderHook(
|
||||
&PrevChar,
|
||||
&CurChar,
|
||||
(const CNetObj_PlayerInfo *)pPrevInfo,
|
||||
(const CNetObj_PlayerInfo *)pInfo,
|
||||
&m_aRenderInfo[i],
|
||||
i,
|
||||
PredictedPos[i],
|
||||
PredictedPos[i]
|
||||
);
|
||||
|
@ -1060,8 +1085,8 @@ void CPlayers::OnRender()
|
|||
RenderPlayer(
|
||||
&PrevChar,
|
||||
&CurChar,
|
||||
(const CNetObj_PlayerInfo *)pPrevInfo,
|
||||
(const CNetObj_PlayerInfo *)pInfo,
|
||||
&m_aRenderInfo[i],
|
||||
i,
|
||||
PredictedPos[i]
|
||||
);
|
||||
}
|
||||
|
|
|
@ -6,14 +6,17 @@
|
|||
|
||||
class CPlayers : public CComponent
|
||||
{
|
||||
friend class CGhost;
|
||||
|
||||
CTeeRenderInfo m_aRenderInfo[MAX_CLIENTS];
|
||||
void RenderHand(class CTeeRenderInfo *pInfo, vec2 CenterPos, vec2 Dir, float AngleOffset, vec2 PostRotOffset);
|
||||
void RenderPlayer(
|
||||
const CNetObj_Character *pPrevChar,
|
||||
const CNetObj_Character *pPlayerChar,
|
||||
const CNetObj_PlayerInfo *pPrevInfo,
|
||||
const CNetObj_PlayerInfo *pPlayerInfo,
|
||||
const vec2 &Position
|
||||
const CTeeRenderInfo *pRenderInfo,
|
||||
int ClientID,
|
||||
const vec2 &Position,
|
||||
float Intra = 0.f
|
||||
/* vec2 &PrevPredPos,
|
||||
vec2 &SmoothPos,
|
||||
int &MoveCnt
|
||||
|
@ -22,10 +25,11 @@ class CPlayers : public CComponent
|
|||
void RenderHook(
|
||||
const CNetObj_Character *pPrevChar,
|
||||
const CNetObj_Character *pPlayerChar,
|
||||
const CNetObj_PlayerInfo *pPrevInfo,
|
||||
const CNetObj_PlayerInfo *pPlayerInfo,
|
||||
const CTeeRenderInfo *pRenderInfo,
|
||||
int ClientID,
|
||||
const vec2 &Position,
|
||||
const vec2 &PositionTo
|
||||
const vec2 &PositionTo,
|
||||
float Intra = 0.f
|
||||
);
|
||||
|
||||
void Predict(
|
||||
|
|
|
@ -155,6 +155,7 @@ void CGameClient::OnConsoleInit()
|
|||
m_pBackGround = &::gs_BackGround;
|
||||
|
||||
m_pMapSounds = &::gs_MapSounds;
|
||||
m_pPlayers = &::gs_Players;
|
||||
|
||||
m_pRaceDemo = &::gs_RaceDemo;
|
||||
m_pGhost = &::gs_Ghost;
|
||||
|
@ -178,7 +179,7 @@ void CGameClient::OnConsoleInit()
|
|||
m_All.Add(&gs_MapLayersBackGround); // first to render
|
||||
m_All.Add(&m_pParticles->m_RenderTrail);
|
||||
m_All.Add(m_pItems);
|
||||
m_All.Add(&gs_Players);
|
||||
m_All.Add(m_pPlayers);
|
||||
m_All.Add(m_pGhost);
|
||||
m_All.Add(&gs_MapLayersForeGround);
|
||||
m_All.Add(&m_pParticles->m_RenderExplosions);
|
||||
|
|
|
@ -354,6 +354,7 @@ public:
|
|||
class CBackground *m_pBackGround;
|
||||
|
||||
class CMapSounds *m_pMapSounds;
|
||||
class CPlayers *m_pPlayers;
|
||||
|
||||
// DDRace
|
||||
|
||||
|
|
Loading…
Reference in a new issue