[SDK] C++ Determining Team (and Tech) for a Given Player

LPlate2

Warlord
Joined
Dec 27, 2018
Messages
299
Hi,

So, I've managed to begin some DLL modding; adjusting parameters and creating new usable xml entries.

I've a query, which hopefully has a really simple answer. I wish to determine the team associated with a given player within c++. Specifically, I'm interested in what techs they have researched.

Within CvCity::init in CvCity.cpp, I want be able to see what techs the owners of a city have. How do I relate the owner back to the team and its tech in c++?

In CvCity::init, it uses getOwnerINLINE().

thanks
 
PHP:
TeamTypes CvPlayer::getTeam() const;
This means you should be able to make a call like:
PHP:
GET_TEAM(getOwnerINLINE().getTeam())
If you want to use the same team multiple times, you can do this:
PHP:
const CvTeamAI& kteam = GET_TEAM(getOwnerINLINE().getTeam());
Including the & is very important as it will result in a severe bug if you forget*. You can remove the const if you plan to alter the team, but if you only want to check the techs, then const would be the way to go. It tells the compiler that you do in fact not want to alter the team and it will cause an error if you alter it anyway by mistake. Also in theory it allows the compiler to optimize better.

* the bug in question is that you will make a copy of the team instead of a reference. When you are done with the copy, it will release the memory, including some arrays. However because there is no copy constructor, it will share the arrays with the original, hence the original will lose the arrays and crash the next time you try to access them. You can avoid this by telling the compiler you don't want to be able to copy a class by inheriting boost::noncopyable, like:
PHP:
class CvInfoBase : private boost::noncopyable
I spent ages pinpointing the cause for those random crashes. The main problem is that it's not crashing at the bug, but instead it's crashing at locations usually without any bugs. This makes it very hard to figure out.
 
Hi,

I've tried using the above,
GET_TEAM(getOwnerINLINE().getTeam()), but when I build I get the message,
Spoiler :

1>CvCity.cpp(184): error C2228: left of '.getTeam' must have class/struct/union type
1> type is 'PlayerTypes'
1>CvCity.cpp(201): error C2228: left of '.getTeam' must have class/struct/union type
1> type is 'PlayerTypes'


What is wrong with the following code? Note, the commented out isOwnableTerrain is my new function. I'm using isNetworkTerrain, which is an existing function, BOOL isNetworkTerrain (TeamType eTeam) to test initially.
Spoiler :
Code:
    if (pPlot->isNetworkTerrain(GET_TEAM(getOwnerINLINE().getTeam())))
//   if (pPlot->isOwnableTerrain(GET_TEAM(getOwnerINLINE().getTeam())))
   {
       if (pPlot->getCulture(getOwnerINLINE()) < GC.getDefineINT("FREE_CITY_CULTURE"))
       {
           pPlot->setCulture(getOwnerINLINE(), GC.getDefineINT("FREE_CITY_CULTURE"), bBumpUnits, false);
       }
       pPlot->setOwner(getOwnerINLINE(), bBumpUnits, false);
       pPlot->setPlotCity(this);

I'm getting the error message in relation to the first line above and in an identical later line.
 
Looks like a typo in the code that Nightinggale suggested. CvCity::getOwnerINLINE returns a player id, not a CvPlayer reference. So the correct call is
GET_TEAM(GET_PLAYER(getOwnerINLINE()).getTeam())
Alternatively, you could use CvCity::getTeam:
GET_TEAM(getTeam())
 
Hi,

I tried this,
Code:
    if (pPlot->isNetworkTerrain(GET_TEAM(GET_PLAYER(getOwnerINLINE()).getTeam())))

but when I try to build, I now get the following in relation to this line,
1> CvCity.cpp
1>CvCity.cpp(184): error C2664: 'CvPlot::isNetworkTerrain' : cannot convert parameter 1 from 'CvTeamAI' to 'TeamTypes'
1> No user-defined-conversion operator available that can perform this conversion, or the operator cannot be called

The definition of CvPlot::isNetworkTerrain in CvPlot.cpp is
Spoiler :
Code:
bool CvPlot::isNetworkTerrain(TeamTypes eTeam) const
{
   FAssertMsg(eTeam != NO_TEAM, "eTeam is not assigned a valid value");
   FAssertMsg(getTerrainType() != NO_TERRAIN, "TerrainType is not assigned a valid value");

   if (GET_TEAM(eTeam).isTerrainTrade(getTerrainType()))
   {
       return true;
   }

   if (isWater())
   {
       if (getTeam() == eTeam)
       {
           return true;
       }
   }

   return false;
}

In CvPlot.h, it has the folllowing in relation to isNetworkTerrain,
Code:
    bool isNetworkTerrain(TeamTypes eTeam) const;
 
@LPlate2

The argument to CvPlot::isNetworkTerrain needs to be TeamTypes (the enum identifying the team) rather than CvTeamAI& (the actual refence to the instance) which means you should pass somethink like kPlayer.getTeam() rather than GET_TEAM() . (Writing this from my phone to I can't actually check the code at the moment...)

If this stuff is confusing to you, consider this general rule:

Whenever you want to call a member function on some instance, you need the reference so you should use this syntax GET_TEAM().function(...) where function is a member of CvTeam(AI)

When you need to provide something that identifies the team, player etc. and pass that as a parameter you usually want something like this myfunction(kPlayer.getTeam());
 
Last edited:
So still not being entirely sure of what way to do it, I decided to brute force it by putting in every combo of terms I thought had a chance of working and hitting build. The two that did not trigger error message turned out to be essentially the same, so I'm presuming that one of these will do the job for me. Thanks for all the advice and support.
Option 1
Code:
    CvPlayer& kPlayer = GET_PLAYER(getOwnerINLINE());
   if (pPlot->isNetworkTerrain(kPlayer.getTeam()))
Option 2
Code:
    if (pPlot->isNetworkTerrain(GET_PLAYER(getOwnerINLINE()).getTeam()))
 
but when I try to build, I now get the following [...]
> cannot convert parameter 1 from 'CvTeamAI' to 'TeamTypes'
Embarassing to be the third person to get it wrong ... Glad that you still found the right solution.
Code:
if (pPlot->isNetworkTerrain(getTeam())
should also work (assuming that your code is in the body of a CvCity function).
 
Back
Top Bottom