Help with CvGameTextMgr

Afforess

The White Wizard
Joined
Jul 31, 2007
Messages
12,239
Location
Austin, Texas
I'm having trouble having the effects of one of my new CvBuildingInfos arrays show up. Despite having the code in CvGameTextMgr, it refuses to show up. My change, which is an array called PrereqNotBuildingClass checks to see that a city doesn't have the specified building before it can construct this one. If it does have the building, you can't build the building. For Instance, so you can't build in the Versailles in the same city as your palace. Anyway, that isn't the problem, my code works perfectly, except with CvGameTextMgr, can someone tell me what I did wrong?

My Code:
Code:
void CvGameTextMgr::setBuildingHelpActual(CvWStringBuffer &szBuffer, BuildingTypes eBuilding, bool bCivilopediaText, bool bStrategyText, bool bTechChooserText, CvCity* pCity, bool bActual)
{
...
    bFirst = true;

    for (iI = 0; iI < GC.getNumBuildingClassInfos(); ++iI)
    {
        if (ePlayer != NO_PLAYER)
        {
            eLoopBuilding = ((BuildingTypes)(GC.getCivilizationInfo(GET_PLAYER(ePlayer).getCivilizationType()).getCivilizationBuildings(iI)));
        }
        else
        {
            eLoopBuilding = (BuildingTypes)GC.getBuildingClassInfo((BuildingClassTypes)iI).getDefaultBuildingIndex();
        }
        if (eLoopBuilding != NO_BUILDING)
        {
            if (GC.getBuildingInfo(eLoopBuilding).isPrereqNotBuildingClass(kBuilding.getBuildingClassType()))
            {
                if ((pCity == NULL) || !(pCity->canConstruct(eLoopBuilding)))
                {
                    szFirstBuffer.Format(L"%s%s", NEWLINE, gDLL->getText("TXT_KEY_BUILDING_NOT_REQUIRED_TO_BUILD").c_str());
                    szTempBuffer.Format(SETCOLR L"<link=literal>%s</link>" ENDCOLR, TEXT_COLOR("COLOR_BUILDING_TEXT"), GC.getBuildingInfo(eLoopBuilding).getDescription());
                    setListHelp(szBuffer, szFirstBuffer, szTempBuffer, L", ", bFirst);
                    bFirst = false;
                }
            }
        }
    }
...
}
 
Since your loop is BuildingClasses, and your tag is for class, I would check against your tag before finding what the Unique or Default Version is for the class. Saves some steps since most classes won't be blocked.


It seems this might be easier to do without the setListHelp function, just grant each building which is required to NOT be present a line to itself. (ie - work with szBuffer.apped(...))
 
Anyway, that isn't the problem, my code works perfectly, except with CvGameTextMgr, can someone tell me what I did wrong?

My Code:
Code:
void CvGameTextMgr::setBuildingHelpActual(CvWStringBuffer &szBuffer, BuildingTypes eBuilding, bool bCivilopediaText, bool bStrategyText, bool bTechChooserText, CvCity* pCity, bool bActual)
{
...
    bFirst = true;

    for (iI = 0; iI < GC.getNumBuildingClassInfos(); ++iI)
    {
        if (ePlayer != NO_PLAYER)
        {
            eLoopBuilding = ((BuildingTypes)(GC.getCivilizationInfo(GET_PLAYER(ePlayer).getCivilizationType()).getCivilizationBuildings([COLOR="Red"]iI[/COLOR])));
This "iI" should be a "(BuildingClassTypes)iI".
Code:
        }
        else
        {
            eLoopBuilding = (BuildingTypes)GC.getBuildingClassInfo((BuildingClassTypes)iI).getDefaultBuildingIndex();
        }
        if (eLoopBuilding != NO_BUILDING)
        {
            if (GC.getBuildingInfo(eLoopBuilding).isPrereqNotBuildingClass([COLOR="#ff0000"]kBuilding[/COLOR].getBuildingClassType()))
"kBuilding"? You mean "eBuilding", I think.
Code:
            {
                if ((pCity == NULL) || !(pCity->canConstruct(eLoopBuilding)))
                {
                    szFirstBuffer.Format(L"%s%s", NEWLINE, gDLL->getText("TXT_KEY_BUILDING_NOT_REQUIRED_TO_BUILD").c_str());
                    szTempBuffer.Format(SETCOLR L"<link=literal>%s</link>" ENDCOLR, TEXT_COLOR("COLOR_BUILDING_TEXT"), GC.getBuildingInfo(eLoopBuilding).getDescription());
                    setListHelp(szBuffer, szFirstBuffer, szTempBuffer, L", ", bFirst);
                    bFirst = false;
                }
            }
        }
    }
...
}

That's the pair of problems I see. I didn't check the logic, just the more basic stuff.
 
CvFooInfo functions don't use the FooTypes enumerations and instead take and return normal ints. As long as you are looping over building classes with iI, you can safely pass it to getCivilizationBuildings(int) without casting. This is why you need to cast the return value (which is an int) to a BuildingTypes to pass it to CvCity functions and the like.

As for kBuilding, k is the mnemonic used to denote CvFoo references:

Code:
CvBuildingInfo& kBuilding = GC.getBuildingInfo((BuildingTypes)iI);

How have you structured your data? Does the Library building say that it cannot be built in a city with a Market building class?

Code:
GC.getBuildingType(BUILDING_LIBRARY).isPrereqNotBuildingClass(BUILDINGCLASS_MARKET) == false

What are you expecting to see in your hover text. As always, a good example with the data, XML, and what you want to have happen would be very helpful. We can't check your logic if we don't know what it is supposed to do.
 
CvFooInfo functions don't use the FooTypes enumerations and instead take and return normal ints. As long as you are looping over building classes with iI, you can safely pass it to getCivilizationBuildings(int) without casting. This is why you need to cast the return value (which is an int) to a BuildingTypes to pass it to CvCity functions and the like.

As for kBuilding, k is the mnemonic used to denote CvFoo references:

Code:
CvBuildingInfo& kBuilding = GC.getBuildingInfo((BuildingTypes)iI);

Argh. 0 for 2. That's what I get for not looking at the whole thing (and posting when I should have been doing something else). I saw no kBuilding defined in what he posted, but there was an eBuilding so... oops. The "e" version I suggested was clearly not correct since it would not have the method that was being run for the thing. Must remember the basic rule: think before posting. (Or was that: 1) think, 2) post, 3) ???, 4) profit.)
 
CvFooInfo functions don't use the FooTypes enumerations and instead take and return normal ints. As long as you are looping over building classes with iI, you can safely pass it to getCivilizationBuildings(int) without casting. This is why you need to cast the return value (which is an int) to a BuildingTypes to pass it to CvCity functions and the like.

As for kBuilding, k is the mnemonic used to denote CvFoo references:

Code:
CvBuildingInfo& kBuilding = GC.getBuildingInfo((BuildingTypes)iI);
How have you structured your data? Does the Library building say that it cannot be built in a city with a Market building class?

Code:
GC.getBuildingType(BUILDING_LIBRARY).isPrereqNotBuildingClass(BUILDINGCLASS_MARKET) == false
What are you expecting to see in your hover text. As always, a good example with the data, XML, and what you want to have happen would be very helpful. We can't check your logic if we don't know what it is supposed to do.

This is the text in my gametext file:
[COLOR_WARNING_TEXT]Can Not be Built in the Same City as[SPACE][COLOR_REVERT]

I'm not sure what you mean by what it's supposed to do, I outlined it in the OP. If the city has that buildingclass, you can't build this building in the same city. I know it works, I have it set up perfectly in the XML, and buildings can't be built when I have the other NOT buildingclass in the city, so it is working.
 
Here's the answer I was looking for:

Feature: A Sacrificial Altar cannot be built in a city with a Market class (including Mint).

To do this, you place the building class that blocks a building type in the building type's XML block: the SA building type must reference the Market building class.

Exacmple: When you hover over the Sacrificial Altar button in a city with a Mint, the hover text should say

* Cannot be built in a city with a Mint​

If the above is correct--especially the bit about where the XML goes--I can see that your logic test is backwards. For each building class you check if the current building type being hovered over blocks it. You need to reverse that.

Code:
for each building class
  if kBuilding.isPrereqNotBuildingClass(class)
    if no active player (main menu civilopedia)
      blocking building type = generic building for class
    else
      blocking building type = player's civ-specific building for class
      if city is not null and city doesn't have blocking building type
        blocking building type = null
    if blocking building type != null
      show message
 
Here's the answer I was looking for:

Feature: A Sacrificial Altar cannot be built in a city with a Market class (including Mint).

To do this, you place the building class that blocks a building type in the building type's XML block: the SA building type must reference the Market building class.

Exacmple: When you hover over the Sacrificial Altar button in a city with a Mint, the hover text should say
* Cannot be built in a city with a Mint​
If the above is correct--especially the bit about where the XML goes--I can see that your logic test is backwards. For each building class you check if the current building type being hovered over blocks it. You need to reverse that.

Code:
for each building class
  if kBuilding.isPrereqNotBuildingClass(class)
    if no active player (main menu civilopedia)
      blocking building type = generic building for class
    else
      blocking building type = player's civ-specific building for class
      if city is not null and city doesn't have blocking building type
        blocking building type = null
    if blocking building type != null
      show message

Oh, that's why... Thanks!
 
Back
Top Bottom