ConnorMcLeod
01-23-2013 01:11
Re: StatusValue player is not looks at players.
Quote:
Originally Posted by Emp`
(Post 1878275)
The StatusValue message is sent after a Traceline that happens for the client (I assume every "think").
In CBasePlayer::UpdateClientData, pdata m_flNextSBarUpdateTime is checked, if time is passed, CBasePlayer::UpdateStatusBar is called and m_flNextSBarUpdateTime is set to gametime + 0.2.
( m_flNextSBarUpdateTime is 449 on windows, +5 on linux ).
hlsdk UpdateStatusBar code for reference :
Spoiler
Code:
void CBasePlayer::UpdateStatusBar()
{
int newSBarState[ SBAR_END ];
char sbuf0[ SBAR_STRING_SIZE ];
char sbuf1[ SBAR_STRING_SIZE ];
memset( newSBarState, 0, sizeof(newSBarState) );
strcpy( sbuf0, m_SbarString0 );
strcpy( sbuf1, m_SbarString1 );
// Find an ID Target
TraceResult tr;
UTIL_MakeVectors( pev->v_angle + pev->punchangle );
Vector vecSrc = EyePosition();
Vector vecEnd = vecSrc + (gpGlobals->v_forward * MAX_ID_RANGE);
UTIL_TraceLine( vecSrc, vecEnd, dont_ignore_monsters, edict(), &tr);
if (tr.flFraction != 1.0)
{
if ( !FNullEnt( tr.pHit ) )
{
CBaseEntity *pEntity = CBaseEntity::Instance( tr.pHit );
if (pEntity->Classify() == CLASS_PLAYER )
{
newSBarState[ SBAR_ID_TARGETNAME ] = ENTINDEX( pEntity->edict() );
strcpy( sbuf1, "1 %p1\n2 Health: %i2%%\n3 Armor: %i3%%" );
// allies and medics get to see the targets health
if ( g_pGameRules->PlayerRelationship( this, pEntity ) == GR_TEAMMATE )
{
newSBarState[ SBAR_ID_TARGETHEALTH ] = 100 * (pEntity->pev->health / pEntity->pev->max_health);
newSBarState[ SBAR_ID_TARGETARMOR ] = pEntity->pev->armorvalue; //No need to get it % based since 100 it's the max.
}
m_flStatusBarDisappearDelay = gpGlobals->time + 1.0;
}
}
else if ( m_flStatusBarDisappearDelay > gpGlobals->time )
{
// hold the values for a short amount of time after viewing the object
newSBarState[ SBAR_ID_TARGETNAME ] = m_izSBarState[ SBAR_ID_TARGETNAME ];
newSBarState[ SBAR_ID_TARGETHEALTH ] = m_izSBarState[ SBAR_ID_TARGETHEALTH ];
newSBarState[ SBAR_ID_TARGETARMOR ] = m_izSBarState[ SBAR_ID_TARGETARMOR ];
}
}
BOOL bForceResend = FALSE;
if ( strcmp( sbuf0, m_SbarString0 ) )
{
MESSAGE_BEGIN( MSG_ONE, gmsgStatusText, NULL, pev );
WRITE_BYTE( 0 );
WRITE_STRING( sbuf0 );
MESSAGE_END();
strcpy( m_SbarString0, sbuf0 );
// make sure everything's resent
bForceResend = TRUE;
}
if ( strcmp( sbuf1, m_SbarString1 ) )
{
MESSAGE_BEGIN( MSG_ONE, gmsgStatusText, NULL, pev );
WRITE_BYTE( 1 );
WRITE_STRING( sbuf1 );
MESSAGE_END();
strcpy( m_SbarString1, sbuf1 );
// make sure everything's resent
bForceResend = TRUE;
}
// Check values and send if they don't match
for (int i = 1; i < SBAR_END; i++)
{
if ( newSBarState[i] != m_izSBarState[i] || bForceResend )
{
MESSAGE_BEGIN( MSG_ONE, gmsgStatusValue, NULL, pev );
WRITE_BYTE( i );
WRITE_SHORT( newSBarState[i] );
MESSAGE_END();
m_izSBarState[i] = newSBarState[i];
}
}
}
cs UpdateStatusBar code from ida (gonna hurt eyes !!), quite similar with HL one.
Spoiler
Code:
void __cdecl CBasePlayer::UpdateStatusBar(CBasePlayer *this)
{
long double v1; // fst6@1
long double v2; // fst7@1
long double v3; // fst7@2
long double v4; // t0@4
long double v5; // fst5@4
__int16 v6; // fps@4
bool v7; // c0@4
char v8; // c2@4
bool v9; // c3@4
signed int v10; // esi@5
edict_t *v11; // eax@9
__int16 v12; // fps@15
long double v13; // fst7@15
bool v14; // c0@15
char v15; // c2@15
bool v16; // c3@15
_vt_CBasePlayer *v17; // eax@29
BOOL (__cdecl *v18)(CBasePlayer *); // eax@29
int v19; // esi@29
__int16 v20; // fps@30
long double v21; // fst6@30
bool v22; // c0@30
char v23; // c2@30
bool v24; // c3@30
int v25; // eax@34
int v26; // ecx@41
__int16 v27; // fps@42
bool v28; // c0@42
char v29; // c2@42
bool v30; // c3@42
int v31; // eax@43
CBasePlayer *v32; // ecx@46
CBasePlayer *v33; // eax@49
int v34; // ecx@51
int v35; // edi@65
int v36; // [sp-20h] [bp-158h]@47
float v37; // [sp-1Ch] [bp-154h]@47
char v38; // [sp-18h] [bp-150h]@47
CBasePlayer *v39; // [sp-14h] [bp-14Ch]@29
int v40; // [sp-14h] [bp-14Ch]@47
char *v41; // [sp+20h] [bp-118h]@64
int v42; // [sp+24h] [bp-114h]@64
signed int v43; // [sp+28h] [bp-110h]@62
bool v44; // [sp+2Fh] [bp-109h]@13
void *v45; // [sp+30h] [bp-108h]@11
Vector v46; // [sp+58h] [bp-E0h]@4
Vector v47; // [sp+64h] [bp-D4h]@1
TraceResult v48; // [sp+70h] [bp-C8h]@4
char src[4]; // [sp+A8h] [bp-90h]@1
char v50; // [sp+B8h] [bp-80h]@40
char s[4]; // [sp+128h] [bp-10h]@1
int v52; // [sp+12Ch] [bp-Ch]@19
int v53; // [sp+130h] [bp-8h]@18
int v54; // [sp+134h] [bp-4h]@27
memset(s, 0, 0x10u);
strcpy(src, this->m_SbarString0);
v1 = this->pev->v_angle[2] + this->pev->punchangle[2];
v2 = this->pev->v_angle[0] + this->pev->punchangle[0];
v47[1] = this->pev->v_angle[1] + this->pev->punchangle[1];
v47[2] = v1;
v47[0] = v2;
UTIL_MakeVectors(v47);
(this->vtable->CBaseEntity__EyePosition)(v47, this);
if ( BYTE3(this->pev->flags) & 4 )
v3 = 8192.0;
else
v3 = 2048.0;
v4 = v3 * gpGlobals->v_forward[2];
v5 = gpGlobals->v_forward[0] * v3;
v46[1] = gpGlobals->v_forward[1] * v3 + v47[1];
v46[0] = v5 + v47[0];
v46[2] = v4 + v47[2];
UTIL_TraceLine(v47, v46, 0, this->pev->pContainingEntity, &v48);
UNDEF(v6);
v7 = 1.0 < v48.flFraction;
v8 = 0;
v9 = 1.0 == v48.flFraction;
if ( (HIBYTE(v6) & 0x45) == 64 )
{
if ( gpGlobals->time < this->m_flStatusBarDisappearDelay )
{
v52 = this->m_izSBarState[0];
v53 = this->m_izSBarState[1];
v54 = this->m_izSBarState[2];
}
}
else
{
v10 = 0;
if ( !v48.pHit || !g_engfuncs.pfnEntOffsetOfPEntity(v48.pHit) )
v10 = 1;
if ( !v10 )
{
v11 = v48.pHit;
if ( v48.pHit || (v11 = g_engfuncs.pfnPEntityOfEntOffset(0)) != 0 )
v45 = v11->pvPrivateData;
else
v45 = 0;
v44 = (*(*(v45 + 37) + 44))(v45) == 2;
if ( CBotManager::IsLineBlockedBySmoke(TheBots, this->pev->origin, (*v45 + 8)) )
v44 = 0;
v13 = this->m_flFlashedUntil;
UNDEF(v12);
v14 = v13 < gpGlobals->time;
v15 = 0;
v16 = v13 == gpGlobals->time;
if ( ((HIBYTE(v12) & 0x45) - 1) >= 0x40u )
v44 = 0;
if ( v44 )
{
v53 = g_engfuncs.pfnIndexOfEdict(*(*v45 + 520));
if ( *(v45 + 119) == this->m_iTeam )
v52 = 1;
else
v52 = 2;
if ( this->m_iTeam == *(v45 + 119) || this->pev->iuser1 )
{
if ( playerid.value == 2.0 || this->pev->iuser1 )
memcpy(src, "1 %c1: %p2\n2 %h: %i3%%", 0x18u);
else
strcpy(src, " ");
v54 = (*(*v45 + 352) / *(*v45 + 432) * 100.0);
if ( SLOBYTE(this->m_bitHudTextArgsDontResend) < 0 || BYTE3(this->pev->flags) & 4 )
goto LABEL_59;
v17 = this->vtable;
LOBYTE(this->m_bitHudTextArgsDontResend) |= 0x80u;
v39 = this;
v18 = v17->CBasePlayer__IsAlive;
v19 = "#Hint_spotted_a_friend";
}
else
{
v21 = playerid.value;
UNDEF(v20);
v22 = v21 < 1.0;
v23 = 0;
v24 = v21 == 1.0;
if ( (HIBYTE(v20) & 0x45) != 64 && 2.0 == playerid.value )
strcpy(src, "1 %c1: %p2");
else
strcpy(src, " ");
v25 = this->m_bitHudTextArgsDontResend;
if ( BYTE1(v25) & 1 )
goto LABEL_59;
BYTE1(v25) |= 1u;
this->m_bitHudTextArgsDontResend = v25;
v39 = this;
v18 = this->vtable->CBasePlayer__IsAlive;
v19 = "#Hint_spotted_an_enemy";
}
LABEL_54:
if ( !v18(v39) || (v32 = this, !this->m_bHasAutoHelp) )
goto LABEL_59;
v40 = 0;
v38 = 1;
v37 = 6.0;
v36 = v19;
goto LABEL_57;
}
if ( (*(*(v45 + 37) + 44))(v45) == 3 )
{
if ( playerid.value == 2.0 || this->pev->iuser1 )
{
memcpy(src, "1 %c1 %h: %i3%%", 0x10u);
v50 = a1C1HI3[16];
}
else
{
strcpy(src, " ");
}
v52 = 3;
v54 = (*(*v45 + 352) / *(*v45 + 432) * 100.0);
v26 = this->m_bitHudTextArgsDontResend;
if ( v26 & 4
|| (UNDEF(v27),
v28 = v48.flFraction < 0.1,
v29 = 0,
v30 = v48.flFraction == 0.1,
((HIBYTE(v27) & 0x45) - 1) < 0x40u) )
{
if ( this->m_iTeam != 2 || (v34 = this->m_bitHudTextArgsDontResend, v34 & 8) || v48.flFraction > 0.1 )
goto LABEL_59;
this->m_bitHudTextArgsDontResend = v34 | 0xC;
v39 = this;
v18 = this->vtable->CBasePlayer__IsAlive;
v19 = "#Hint_press_use_so_hostage_will_follow";
goto LABEL_54;
}
this->m_bitHudTextArgsDontResend = v26 | 4;
v31 = this->m_iTeam;
if ( v31 != 1 )
{
if ( v31 != 2 || !this->m_bHasAutoHelp )
goto LABEL_59;
v40 = 0;
v38 = 1;
v37 = 6.0;
v36 = "#Hint_rescue_the_hostages";
v33 = this;
goto LABEL_58;
}
v32 = this;
if ( this->m_bHasAutoHelp )
{
v40 = 0;
v38 = 1;
v37 = 6.0;
v36 = "#Hint_prevent_hostage_rescue";
LABEL_57:
v33 = v32;
LABEL_58:
CHintMessageQueue::AddMessage(&v33->m_fNextHudTextArgsGameTime, v36, v37, v38, v40);
goto LABEL_59;
}
}
LABEL_59:
this->m_flStatusBarDisappearDelay = gpGlobals->time + 2.0;
goto LABEL_62;
}
}
LABEL_62:
v43 = 0;
if ( strcmp(src, this->m_SbarString0) )
{
g_engfuncs.pfnMessageBegin(1, gmsgStatusText, 0, this->pev->pContainingEntity);
g_engfuncs.pfnWriteByte(0);
g_engfuncs.pfnWriteString(src);
g_engfuncs.pfnMessageEnd();
strcpy(this->m_SbarString0, src);
v43 = 1;
}
v42 = 1;
v41 = &this->m_iRespawnFrames;
while ( 1 )
{
v35 = 4 * v42;
if ( *&s[4 * v42] != *&v41[4 * v42] || v43 )
{
g_engfuncs.pfnMessageBegin(1, gmsgStatusValue, 0, this->pev->pContainingEntity);
g_engfuncs.pfnWriteByte(v42);
g_engfuncs.pfnWriteShort(*&s[v35]);
g_engfuncs.pfnMessageEnd();
*&v41[v35] = *&s[v35];
}
++v42;
if ( v42 > 3 )
JUMPOUT(*nullsub_14);
}
}
CS Pdatas are :
Code:
enum sbar_data
{
SBAR_ID_TARGETCLASS = 1,
SBAR_ID_TARGEINDEX,
SBAR_ID_TARGETHEALTH,
SBAR_END,
};
stock const m_izSBarState[SBAR_END] = {446,447,448}
stock const m_flNextSBarUpdateTime = 449;
stock const m_flStatusBarDisappearDelay = 450;
stock const m_SbarString0 = 1804; // 451*4 // [SBAR_STRING_SIZE] // 128 char // 32