Unit Prereq BuildingClass Array

I haven't played with the schema and XML stuff in BTS, so I don't know how errors show up. You said you were getting parsing errors via asserts, so this was my guess. Can you humor me and move the singular ElementType above the plural one?
 
I haven't played with the schema and XML stuff in BTS, so I don't know how errors show up. You said you were getting parsing errors via asserts, so this was my guess. Can you humor me and move the singular ElementType above the plural one?

Consider yourself humored:

Code:
    <ElementType name="BuildingClassType" content="textOnly"/>
    <ElementType name="bPrereq" content="textOnly" dt:type="boolean"/>
    <ElementType name="PrereqBuildingClass" content="eltOnly">
        <element type="BuildingClassType"/>
        <element type="bPrereq"/>
    </ElementType>
    <ElementType name="PrereqBuildingClasses" content="eltOnly">
        <element type="PrereqBuildingClass" minOccurs="0" maxOccurs="*"/>
    </ElementType>

This still fired that assert. :(
 
CvInfos,cpp since that's what's failing.


Okay, here goes:
Code:
CvUnitInfo::CvUnitInfo() :
...
m_pbPrereqBuildingClass(NULL),
...

CvUnitInfo::~CvUnitInfo()
{...
    SAFE_DELETE_ARRAY(m_pbPrereqBuildingClass);
...}

bool CvUnitInfo::getPrereqBuildingClass(int i) const    //Afforess
{
    FAssertMsg(i < GC.getNumBuildingClassInfos(), "Index out of bounds");
    FAssertMsg(i > -1, "Index out of bounds");
    return m_pbPrereqBuildingClass ? m_pbPrereqBuildingClass[i] : false;
}
...}

void CvUnitInfo::read(FDataStreamBase* stream)
{...
    SAFE_DELETE_ARRAY(m_pbPrereqBuildingClass);
    m_pbPrereqBuildingClass = new bool[GC.getNumBuildingClassInfos()];
    stream->Read(GC.getNumBuildingClassInfos(), m_pbPrereqBuildingClass);
...}

void CvUnitInfo::write(FDataStreamBase* stream)
{...
    stream->Write(GC.getNumBuildingClassInfos(), m_pbPrereqBuildingClass); 
...}

bool CvUnitInfo::read(CvXMLLoadUtility* pXML)
{...
    pXML->SetVariableListTagPair(&m_pbPrereqBuildingClass, "PrereqBuildingClass", sizeof(GC.getBuildingClassInfo((BuildingClassTypes)0)), GC.getNumBuildingClassInfos());
...}

void CvUnitInfo::copyNonDefaults(CvUnitInfo* pClassInfo)
{ ...

    for ( int i = 0; i < GC.getNumBuildingClassInfos(); i++) //Afforess
    {
        if ( getPrereqBuildingClass(i) == bDefault )
        {
            m_pbPrereqBuildingClass[i] = pClassInfo->getPrereqBuildingClass(i);
        }
    }
...}
 
Don't you need to specify the outermost element with SetVariableListTagPair()?

Code:
pXML->SetVariableListTagPair(&m_pbPrereqBuildingClass, "[B]PrereqBuildingClasses[/B]", sizeof(GC.getBuildingClassInfo((BuildingClassTypes)0)), GC.getNumBuildingClassInfos());
 
Don't you need to specify the outermost element with SetVariableListTagPair()?

Code:
pXML->SetVariableListTagPair(&m_pbPrereqBuildingClass, "[B]PrereqBuildingClasses[/B]", sizeof(GC.getBuildingClassInfo((BuildingClassTypes)0)), GC.getNumBuildingClassInfos());

Maybe that's it. I decided on the schema after I coded the C++.
 
I just tested it. The Assert is still there, but the requirement works. I can't build a spearman until I build the forge.

Is the assert phoney, or is their a real problem?
 
Post the latest assert and the code surrounding where it is being fired.

Asserts the same as the first one. It's here:

Code:
                if ( !GC.isAnyDependency() )
                {
                    CvString szAssertBuffer;
                    szAssertBuffer.Format("OWN TYPE - dependency not found: %s, in file: \"%s\"", pClassInfo->getType(), GC.getModDir().c_str());
                    FAssertMsg(bSuccess, szAssertBuffer.c_str());
                    if (!bSuccess)
                    {
                    //#ifdef _DEBUG
                        logXmlDependencyTypes("\n\nOWN TYPE - dependency not found: %s, in file: \"%s\"", pClassInfo->getType(), GC.getModDir().c_str());
                        logXmlDependencyTypes("My new check!");
                    //#endif
                        delete pClassInfo;
                        break;
                    }
                }
 
I have no clue. The assert message has zero information in it: class type is null and XML file is just the mod folder. I'd ask the WoC team what that is supposed to signify.
 
I have no clue. The assert message has zero information in it: class type is null and XML file is just the mod folder. I'd ask the WoC team what that is supposed to signify.

Are any of the C++ coders from the WoC team even left?

The code works, and the assert seems to be meaningless, so I'm going to ignore it (I hate ignoring asserts though, I always get the feeling they mean bad things are going to happen)
 
Another question, I set up the CvGameTextMgr, and it compiled, but in game, when the spearman was set to require the forge, it said "Requires Forbidden Palace". So, out of curiosity, I gave the city a forbidden palace, and I still couldn't built it. However, when I gave myself a forge, I could built the spearman. Therefore, I think I set up the code wrong. Could you tell me what I did wrong?

Code:
void CvGameTextMgr::setUnitHelp(CvWStringBuffer &szBuffer, UnitTypes eUnit, bool bCivilopediaText, bool bStrategyText, bool bTechChooserText, CvCity* pCity)
{...

		for (iI = 0; iI < GC.getNumBuildingClassInfos(); iI++) //Afforess
		{
			if (GC.getUnitInfo(eUnit).getPrereqBuildingClass(iI))
			{
				if ((pCity == NULL) || (pCity->getNumActiveBuilding((BuildingTypes)GC.getCivilizationInfo(pCity->getCivilizationType()).getCivilizationBuildings(iI)) <= 0))
				{
					szBuffer.append(NEWLINE);
					szBuffer.append(gDLL->getText("TXT_KEY_UNIT_REQUIRES_STRING", GC.getBuildingClassInfo((BuildingClassTypes)(GC.getUnitInfo(eUnit).getPrereqBuildingClass(iI))).getTextKeyWide()));
				}
			}
		}
...}
 
I'll give you a clue: if you had named the loop counter iBuildingClass, you probably wouldn't have made this error.

Spoiler Clue 2, only after you try to figure it out from clue 1 :
What type does getPrereqBuildingClass() return?
Spoiler Fix, only after you try to figure it out from clue 2 :
You shouldn't call getPrereqBuildingClass() a second time. Instead, pass iI directly to getBuildingClassInfo().
 
I'll give you a clue: if you had named the loop counter iBuildingClass, you probably wouldn't have made this error.

Spoiler Clue 2, only after you try to figure it out from clue 1 :
What type does getPrereqBuildingClass() return?
Spoiler Fix, only after you try to figure it out from clue 2 :
You shouldn't call getPrereqBuildingClass() a second time. Instead, pass iI directly to getBuildingClassInfo().

D'oh. Right you are.

The text displays correctly, however, if I play as the Malinese, who have a UB for the forge, it still says "requires forge", but their UB, the Mint, should be their. (Building the Mint unlocks spearman, so the code works, just the text displays wrong) Anyway to fix this?
 
Do the same trick to get from building class to building type that you use to enforce the prereq and lookup the CvBuildingInfo. Note that you may have a civilization context (player), and you may not. You need to check and display the class or the type appropriately.
 
Do the same trick to get from building class to building type that you use to enforce the prereq and lookup the CvBuildingInfo. Note that you may have a civilization context (player), and you may not. You need to check and display the class or the type appropriately.

What, trick, this?

Code:
getPlotCity()->getCivilizationType()).getCivilizationBuildings(iI)
 
Yes, but you'll probably have to go through a CvPlayer. I don't know what function you're adding this to.
 
Back
Top Bottom