AlliedModders

AlliedModders (https://forums.alliedmods.net/index.php)
-   Coding MM:S Plugins & SM Extensions (https://forums.alliedmods.net/forumdisplay.php?f=75)
-   -   Team Question (https://forums.alliedmods.net/showthread.php?t=57601)

API 07-09-2007 00:50

Re: Team Question
 
In my opinion you shouldn't use cbase.h, if you MUST use it (you don't, trust me), do:
Code:

#define GAME_DLL 1
#include "cbase.h"


BAILOPAN 07-09-2007 11:31

Re: Team Question
 
If you need to include cbase you're probably already going in the wrong direction.

Aidan 07-09-2007 12:00

Re: Team Question
 
Quote:

Originally Posted by BAILOPAN (Post 501024)
If you need to include cbase you're probably already going in the wrong direction.


Okay, so now that I'm good and lost....

Here's what I'm trying to do.

CTeam *t, *ct;

t = CBasePlayer->GetTeam( );
ct = CBasePlayer2->GetTeam( );

int score[2];
score[0] = t->GetScore( );
score[1] = ct->GetScore( );

Anyone have any suggestions on where to start since I'm going the wrong way?

(The code above is very rough and in no way comparable to what I'm writing, its just an example.)

BAILOPAN 07-09-2007 12:57

Re: Team Question
 
We're going in circles here... including this post I've now made 4 total that tell you to use network properties. You simply can't do normal calls against the SDK since CS:S changes class layouts.

Recap: All you need is a few CBaseEntity pointers and you can grab everything you need from network props. A network property is a named offset from the CBaseEntity pointer, i.e. grabbing an int looks like:
Code:

int val = *(int *)((char *)pEntity + offset);
1) Get a player's team index with the "m_iTeamNum" prop
2) Loop through all entities and find one that a) Has a "CCSTeam" network class and b) Has an "m_iTeamNum" property value that matches the number
3) Get the "m_iScore" property of that CCSTeam entity

L. Duke 07-09-2007 13:09

Re: Team Question
 
Here's some example code of how I do it.

In ServerActivate I find the team pointers and save them for later use:
Code:

    // find team entities and store in teamT and teamCT pointers
    int i;
    edict_t* pEnt=pEdictList;
    CBaseEntity *pBase=NULL;
    CTeam *tmpTeam = NULL;
    for (i=0;i<edictCount;i++)
    {
        if(V_stricmp(pEnt->GetClassName(),"cs_team_manager")==0)
        {   

            int team_number;
            team_number = gDBUtils->GetTeamTeamNum(pEnt);
            META_CONPRINTF("  team: %d\n", team_number);
            if (team_number == TERRORISTS)
            {
                teamT = pEnt;
                META_CONPRINTF("TeamT found");
            }
            if (team_number == COUNTERTERRORISTS)
            {
                teamCT = pEnt;
                META_CONPRINTF("TeamCT found");
            }
        }
        pEnt++;
    }

Then my function for getting team score looks like:
Code:

int DBUtils::GetTeamScore(edict_t *team)
{

    static int Offset = 0;
    if (Offset==0)
    {
        Offset = FindOffset("CTeam", "m_iScore");
    }

    if (Offset==0)
        return 0;

    CBaseEntity *pBase = team->GetUnknown()->GetBaseEntity();
    if (pBase)
    {
        return *(int *)((char *)pBase + Offset );
    }
    else
    {
        return 0;
    }
}

You'll also need something like this to find the offset from the server class table:
Code:

// find an offset for PropertyName listed in the server class send table for ClassName
int DBUtils::FindOffset(const char *ClassName, const char *PropertyName)
{
    ServerClass *sc = m_ServerDll->GetAllServerClasses();
    while (sc)
    {
        if (FStrEq(sc->GetName(), ClassName))
        {
            int NumProps = sc->m_pTable->GetNumProps();
            for (int i=0; i<NumProps; i++)
            {
                if (stricmp(sc->m_pTable->GetProp(i)->GetName(), PropertyName) == 0)
                {
                    return sc->m_pTable->GetProp(i)->GetOffset();
                }
            }
            return 0;
        }
        sc = sc->m_pNext;
    }

    return 0;
}

Note that if you try to change the team score it will be reset when the round restarts, but you should be able to read the score at any time.

Aidan 07-09-2007 14:01

Re: Team Question
 
Thanks Bailopan and L. Duke. I just got some free time so I'm going to work on that now.

Bailopan, my apologies for the misunderstanding. I am still trying to learn the SDK and its not the easiest thing to work with. I wasn't trying to be an ignorant pain. :)

I'll let you all know how it goes.

Thanks!
-Rob

Aidan 07-09-2007 14:17

Re: Team Question
 
Quote:

Originally Posted by L. Duke (Post 501064)
Here's some example code of how I do it.

In ServerActivate I find the team pointers and save them for later use:
Code:

    // find team entities and store in teamT and teamCT pointers
    int i;
    edict_t* pEnt=pEdictList;
    CBaseEntity *pBase=NULL;
    CTeam *tmpTeam = NULL;
    for (i=0;i<edictCount;i++)
    {
        if(V_stricmp(pEnt->GetClassName(),"cs_team_manager")==0)
        {   
 
            int team_number;
            team_number = gDBUtils->GetTeamTeamNum(pEnt);
            META_CONPRINTF("  team: %d\n", team_number);
            if (team_number == TERRORISTS)
            {
                teamT = pEnt;
                META_CONPRINTF("TeamT found");
            }
            if (team_number == COUNTERTERRORISTS)
            {
                teamCT = pEnt;
                META_CONPRINTF("TeamCT found");
            }
        }
        pEnt++;
    }

Then my function for getting team score looks like:
Code:

int DBUtils::GetTeamScore(edict_t *team)
{
 
    static int Offset = 0;
    if (Offset==0)
    {
        Offset = FindOffset("CTeam", "m_iScore");
    }
 
    if (Offset==0)
        return 0;
 
    CBaseEntity *pBase = team->GetUnknown()->GetBaseEntity();
    if (pBase)
    {
        return *(int *)((char *)pBase + Offset );
    }
    else
    {
        return 0;
    }
}

You'll also need something like this to find the offset from the server class table:
Code:

// find an offset for PropertyName listed in the server class send table for ClassName
int DBUtils::FindOffset(const char *ClassName, const char *PropertyName)
{
    ServerClass *sc = m_ServerDll->GetAllServerClasses();
    while (sc)
    {
        if (FStrEq(sc->GetName(), ClassName))
        {
            int NumProps = sc->m_pTable->GetNumProps();
            for (int i=0; i<NumProps; i++)
            {
                if (stricmp(sc->m_pTable->GetProp(i)->GetName(), PropertyName) == 0)
                {
                    return sc->m_pTable->GetProp(i)->GetOffset();
                }
            }
            return 0;
        }
        sc = sc->m_pNext;
    }
 
    return 0;
}

Note that if you try to change the team score it will be reset when the round restarts, but you should be able to read the score at any time.


Can I ask where pEdictList comes from? I can't find anything in what I have that says where it is. All I can find is ServerActivate(edict_t *pEdictList), yet nothing defines what it is.

Thanks
Rob

L. Duke 07-09-2007 14:26

Re: Team Question
 
That's exactly where it comes from. It's just the list of edicts. You can get the same thing by looping through engine->PEntityOfEntIndex(i) up to the maximum number of entities.

Aidan 07-09-2007 14:33

Re: Team Question
 
Quote:

Originally Posted by L. Duke (Post 501115)
That's exactly where it comes from. It's just the list of edicts. You can get the same thing by looping through engine->PEntityOfEntIndex(i) up to the maximum number of entities.

Hrm, thats odd. I can't use edictCount either. Maybe I'm missing a header file?

Aidan 07-09-2007 15:14

Re: Team Question
 
durh, i'm an idiot. I just figured out what I did wrong. -.-


All times are GMT -4. The time now is 15:02.

Powered by vBulletin®
Copyright ©2000 - 2024, vBulletin Solutions, Inc.