PDA

View Full Version : Function Damned Unreachable


bloody skull
08-06-2007, 05:15 AM
I defined a public
int GetClass() {return m_iClass; }
in hl2mp_player.h

and I wanted to use it in this CLIENT VGUI-CONTROLLING file.



// ============================================//
// About: Display class logo
// Notes: It doesn't actually, since it doesn't work
// ============================================//

#include "hud.h"
#include "cbase.h"
#include "classlogo.h"
#include "iclientmode.h"
#include "hud_macros.h"
#include "c_team.h"
#include "vgui_controls/controls.h"
#include "vgui/ISurface.h"
#include "hl2mp_gamerules.h"

#include "tier0/memdbgon.h"

using namespace vgui;

//-----------------------------------------------------------
// Purpose:
//-----------------------------------------------------------
CRClassLogo::CRClassLogo( const char *pElementName ) : CHudElement( pElementName ), BaseClass( NULL, "CRClassLogo" )
{
// nothing useful for you to see
}

//-----------------------------------------------------------
// Purpose:
// Purpose:
//-----------------------------------------------------------
void CRClassLogo::PaintBackground()
{
SetBgColor(Color(0,0,0,0));
//My function GetClass is
//DEFINED in hl2mp_player.h, but I cannot use it from here
//So, what to do?
//SOMETHING *pPlayer = SOMETHING TO GetLocalPlayer());
if(pPlayer->GetClass() == 0 )
{
vgui::surface()->DrawSetColor(GetFgColor());
vgui::surface()->DrawSetTexture( m_nAssaultIcon );
vgui::surface()->DrawTexturedRect(0, 0, GetWide(), GetTall());

DevMsg("Class 0 displayed\n");
}
else if(pPlayer->GetClass() == 1 )
{
vgui::surface()->DrawSetColor(GetFgColor());
vgui::surface()->DrawSetTexture( m_nSupportIcon );
vgui::surface()->DrawTexturedRect(0, 0, GetWide(), GetTall());

DevMsg("Class 1 displayed. if you can read this, it works!\n");
}
else if(pPlayer->GetClass() == 2 )
{
vgui::surface()->DrawSetColor(GetFgColor());
vgui::surface()->DrawSetTexture( m_nSniperIcon );
vgui::surface()->DrawTexturedRect(0, 0, GetWide(), GetTall());
}
else if(pPlayer->GetClass() == 3 )
{
vgui::surface()->DrawSetColor(GetFgColor());
vgui::surface()->DrawSetTexture( m_nMachineIcon );
vgui::surface()->DrawTexturedRect(0, 0, GetWide(), GetTall());
}
else
{
vgui::surface()->DrawSetColor(GetFgColor());
vgui::surface()->DrawSetTexture( m_nAssaultIcon );
vgui::surface()->DrawTexturedRect(0, 0, GetWide(), GetTall());
}

SetPaintBorderEnabled(false);

BaseClass::PaintBackground();
}


DECLARE_HUDELEMENT( CRClassLogo );


what am I gonna do? I tried creating a m_Local variable, setting
m_Local.m_iClass = GetClass();
inside hl2mp_player.cpp, but when I use it in my file calling
CBasePlayer *pPlayer = UTIL_PlayerByIndex(engine->GetLocalPlayer());
and then
pPlayer->m_Local.m_iClass
that variable is ALWAYS = 0 and I don't know why :(

plz help me guys.
thanks for reading.

Winston
08-06-2007, 06:49 AM
hl2mp_player.h is a server dll file, and VGUI is all client dll stuff. I'm not saying it can't work like this, but I believe the correct way would be to syncronise your player boolean between the server and client player classes, and then access them through the client player class, rather than the server player class (which is what you're trying to do now).

Marine
08-06-2007, 06:51 AM
Notice, CBasePlayer

You are not defining it in the base player class (player.cpp), you are defining it in the hl2mp_player class which is derived from player.cpp.

You either need to do CHL2MPPlayer OR define GetClass as a shared function in player.cpp, baseplayershared.cpp and c_baseplayer.cpp

bloody skull
08-06-2007, 08:47 AM
ok, now I defined the function in player.h, c_baseplayer.h, and hl2mp_player.h. now from hl2mp_player.cpp I called this way:


// code to change the class began
//.....
CBasePlayer::ChangeClass( m_iClass );
//...
// end of the function


but it still doesnt work. it seems like m_iClass is always to zero, and it isnt changed... any hint?

Winston
08-06-2007, 09:45 AM
Firstly, make sure you're linking m_iClass between server and client player classes, see how everything else is sent/received from within player.cpp and c_baseplayer.cpp.

Secondly, in your VGUI code, you can't (to my knowledge) get the server player class like you have in your first post, instead C_BasePlayer::GetLocalPlayer()->m_iClass

Thirdly, be aware that the name "m_iClass" may be being used by the engine for things other than your player classes. Might not though, I've not got the code right now. That shouldn't be a problem, unless you muddle them up, which I do regularly.

Marine
08-06-2007, 12:47 PM
You will need to use a NetworkVar on the server side: player.cpp,

Define Setting/Getting functions in baseplayershared.cpp

And then be able to retrieve it n the client side in c_baseplayer.cpp.

bloody skull
08-06-2007, 01:39 PM
Secondly, in your VGUI code, you can't (to my knowledge) get the server player class like you have in your first post, instead C_BasePlayer::GetLocalPlayer()->m_iClass



ok I'm almost done.
this is my function:

void CHL2MP_Player::SetClass(int NewClass)
{
m_iClass = NewClass;

CBasePlayer::ChangeClass( m_iClass );

DevMsg(1,"assigned class %d, test string with %d",m_iClass,CBasePlayer::GetClass());

//Loadout();
}


finally now from my dev console I see when I change to class 1:
"assigned class 1, test string with 1", this means it works the assignment. what still refuses to work is the call in classlogo.cpp

I tried what you suggested, and also this

CBasePlayer *pPlayer = CBasePlayer::GetLocalPlayer();
int i_class = pPlayer->GetClass();

but it still doesn't work. no errors, but i_class is always 0.
I know I'm close...

Winston
08-06-2007, 01:56 PM
To synchronise between server and client class, can I suggest copying how they do it with an existing value. Let's say, m_iFOV. All I'm doing here is finding every instance of m_iFOV in player.cpp, player.h, c_baseplayer.cpp and c_baseplayer.h, copying the line, and replacing the variable name. If you've defined your value in hl2mp_player.h instead of player.h, then you'll need to adapt it to those instead.

player.h, ~line 737 CNetworkVar( int, m_iClass );

player.cpp, ~line 227 DEFINE_FIELD( m_iClass, FIELD_INTEGER ),

player.cpp, ~line 7029 SendPropInt (SENDINFO(m_iClass), 10 ),

c_baseplayer.h, ~line 316 int m_iClass;

c_baseplayer.cpp, ~line 222 RecvPropInt (RECVINFO(m_iClass), 0),

c_baseplayer.cpp, ~line 289 DEFINE_PRED_FIELD( m_iClass, FIELD_INTEGER, FTYPEDESC_INSENDTABLE ),

And that's networking a variable in a nutshell. Hopefully, that should get you working!

bloody skull
08-06-2007, 02:36 PM
this is my call inside classlogo.cpp

C_BasePlayer *pPlayer = C_BasePlayer::GetLocalPlayer();
int i_class = pPlayer->m_Local.m_iClassN;

I think it's wrong, because it doesnt work...

this is my function in hl2mp_player.cpp

void CHL2MP_Player::SetClass(int NewClass)
{
m_iClass = NewClass;

m_iClassN = m_iClass;
ChangeClass( m_iClass );

DevMsg(1,"assigned class %d, test string with %d",m_iClass,m_iClassN);
}

and It prints, for example, "assigned class 3, test string with 3" when I type joinclass 3... but in classlogo.cpp it doesnt work. but I think the call is wrong. c'mon I'm almost done :)

Winston
08-06-2007, 03:42 PM
What is m_Local anyway? I never really understood that. As far as I know, you don't want that bit, instead just C_BasePlayer *pPlayer = C_BasePlayer::GetLocalPlayer();
int i_class = pPlayer->m_iClassN;

bloody skull
08-06-2007, 03:50 PM
What is m_Local anyway? I never really understood that. As far as I know, you don't want that bit, instead just C_BasePlayer *pPlayer = C_BasePlayer::GetLocalPlayer();
int i_class = pPlayer->m_iClassN;

GREAT NOW IT WORKS! I WANT TO THANK YOU EVERYBODY FOR YOUR TIME, EXPECIALLY WINSTON FOR YOUR LAST HINTS. I TRIED SETTING UP A NETWORK VAR, BUT I FAILED THE FIRST TIME. THERE WAS SOMETHING WITH m_Local.... that's why I added m_Local to my line of code... now it works perfectly! THANKS AGAIN! I'm very happy!

Marine
08-06-2007, 04:08 PM
Glad it worked -- i implemented somerthing like this in my mod, but it never materialised.

Winston
08-06-2007, 04:17 PM
No problem mate, glad to be of help, have fun!

bloody skull
08-06-2007, 04:25 PM
i implemented somerthing like this in my mod, but it never materialised. why not? mine works perfectly, no bugs at all. I just followed "add a team icon (http://developer.valvesoftware.com/wiki/Team_Icons)" and edit a lot to show my class icon. actually I have two panels to show both team and class, both as pictures, but one is the team logo, while the other is the class name colored like camoflage.