Failing to load BuildingInfos.xml

Black Whole

Dancing Condor
Joined
Dec 21, 2005
Messages
534
Location
Theatre of Dreams
Ok now I am lost.

All I wanted to do is to create a new XML tag, which allows buildings to create commerce from features in the city radius.
Here are the code parts:
BuildinsSchema.xml
Code:
<ElementType name="BonusYieldModifiers" content="eltOnly">
        <element type="BonusYieldModifier" minOccurs="0" maxOccurs="*"/>
    </ElementType>
    [COLOR="Lime"]<!--RFCA start-->[/COLOR]
    <ElementType name="FeatureCommerceChange" content="eltOnly">
        <element type="FeatureType"/>
        <element type="CommerceChanges"/>
    </ElementType>
    <ElementType name="FeatureCommerceChanges" content="eltOnly">
        <element type="FeatureCommerceChange" minOccurs="0" maxOccurs="*"/>
    </ElementType>
    [COLOR="Lime"]<!--RFCA end-->[/COLOR]
    <ElementType name="ImprovementFreeSpecialist" content="eltOnly">
        <element type="ImprovementType"/>
        <element type="iFreeSpecialistCount"/>
    </ElementType>

BuildingInfos.xml
Code:
<BonusYieldModifiers/>
            <FeatureCommerceChanges>
                <FeatureCommerceChange>
                    <FeatureType>FEATURE_FOREST</FeatureType>
                    <iCommerce>0</iCommerce>
                    <iCommerce>0</iCommerce>
                    <iCommerce>2</iCommerce>
                </FeatureCommerceChange>
            </FeatureCommerceChanges>
            <ImprovementFreeSpecialists/>

CvInfos.cpp
Code:
.
.
.
m_ppaiBonusYieldModifier(NULL),
m_ppaiFeatureCommerceChange(NULL)[COLOR="Lime"] //RFCA[/COLOR]
....
-----------------------------------------
...
[COLOR="Lime"]//RFCA START[/COLOR]
    if (m_ppaiFeatureCommerceChange != NULL)
    {
        for(int i=0;i<GC.getNumFeatureInfos();i++)
        {
            SAFE_DELETE_ARRAY(m_ppaiFeatureCommerceChange[i]);
        }
        SAFE_DELETE_ARRAY(m_ppaiFeatureCommerceChange);
    }
   [COLOR="Lime"] //RFCA END[/COLOR]
...
--------------------------------------------------
...
[COLOR="Lime"]//RFCA START[/COLOR]
int CvBuildingInfo::getFeatureCommerceChange(int i, int j) const
{
    FAssertMsg(i < GC.getFeatureInfos(), "Index out of bounds");
    FAssertMsg(i > -1, "Index out of bounds");
    FAssertMsg(j < NUM_COMMERCE_TYPES, "Index out of bounds");
    FAssertMsg(j > -1, "Index out of bounds");
    return m_ppaiFeatureCommerceChange ? m_ppaiFeatureCommerceChange[i][j] : -1;
}

int* CvBuildingInfo::getFeatureCommerceChangeArray(int i) const
{
    FAssertMsg(i < GC.getNumFeatureInfos(), "Index out of bounds");
    FAssertMsg(i > -1, "Index out of bounds");
    return m_ppaiFeatureCommerceChange[i];
}
[COLOR="Lime"]//RFCA END[/COLOR]
...
------------------------------------------------------
...
[COLOR="Lime"]//RFCA START[/COLOR]
    if (m_ppaiFeatureCommerceChange != NULL)
    {
        for(i=0;i<GC.getNumFeatureInfos();i++)
        {
            SAFE_DELETE_ARRAY(m_ppaiFeatureCommerceChange[i]);
        }
        SAFE_DELETE_ARRAY(m_ppaiFeatureCommerceChange);
    }

    m_ppaiFeatureCommerceChange = new int*[GC.getNumFeatureInfos()];
    for(i=0;i<GC.getNumFeatureInfos();i++)
    {
        m_ppaiFeatureCommerceChange[i]  = new int[NUM_COMMERCE_TYPES];
        stream->Read(NUM_COMMERCE_TYPES, m_ppaiFeatureCommerceChange[i]);
    }
   [COLOR="Lime"] //RFCA END[/COLOR]
...
----------------------------------------------------------
...
   [COLOR="Lime"] //RFCA START[/COLOR]
    for(i=0;i<GC.getNumFeatureInfos();i++)
    {
        stream->Write(NUM_COMMERCE_TYPES, m_ppaiFeatureCommerceChange[i]);
    }
    [COLOR="Lime"]//RFCA[/COLOR]
...
----------------------------------------------------
...
    pXML->Init2DIntList(&m_ppaiFeatureCommerceChange, GC.getNumFeatureInfos(), NUM_COMMERCE_TYPES);
    if (gDLL->getXMLIFace()->SetToChildByTagName(pXML->GetXML(),"FeatureCommerceChanges"))
    {
        iNumChildren = gDLL->getXMLIFace()->GetNumChildren(pXML->GetXML());

        if (gDLL->getXMLIFace()->SetToChildByTagName(pXML->GetXML(),"FeatureCommerceChange"))
        {
            for(int j=0;j<iNumChildren;j++)
            {
                pXML->GetChildXmlValByName(szTextVal, "FeatureType");
                int k = pXML->FindInInfoClass(szTextVal);
                if (k > -1)
                {
                    // delete the array since it will be reallocated
                    SAFE_DELETE_ARRAY(m_ppaiFeatureCommerceChange[k]);
                    if (gDLL->getXMLIFace()->SetToChildByTagName(pXML->GetXML(),"CommerceChanges"))
                    {
                        // call the function that sets the commerce change variable
                        pXML->SetCommerce(&m_ppaiFeatureCommerceChange[k]);
                        gDLL->getXMLIFace()->SetToParent(pXML->GetXML());
                    }
                    else
                    {
                        pXML->InitList(&m_ppaiFeatureCommerceChange[k], NUM_COMMERCE_TYPES);
                    }

                }

                if (!gDLL->getXMLIFace()->NextSibling(pXML->GetXML()))
                {
                    break;
                }
            }

            // set the current xml node to it's parent node
            gDLL->getXMLIFace()->SetToParent(pXML->GetXML());
        }

        // set the current xml node to it's parent node
        gDLL->getXMLIFace()->SetToParent(pXML->GetXML());
    }

CvInfos.h
Code:
...
   [COLOR="Lime"] //RFCA START[/COLOR]
    int getFeatureCommerceChange(int i, int j) const;                // Exposed to Python
    int* getFeatureCommerceChangeArray(int i) const;
    [COLOR="Lime"]//RFCA END[/COLOR]
...
------------------------------------------------------------------
...
    int** m_ppaiFeatureCommerceChange;  [COLOR="Lime"]//RFCA[/COLOR]

CvCity.cpp
Code:
int CvCity::getBuildingCommerceByBuilding(CommerceTypes eIndex, BuildingTypes eBuilding) const
{
    int iCommerce;

    FAssertMsg(eIndex >= 0, "eIndex expected to be >= 0");
    FAssertMsg(eIndex < NUM_COMMERCE_TYPES, "eIndex expected to be < NUM_COMMERCE_TYPES");
    FAssertMsg(eBuilding >= 0, "eBuilding expected to be >= 0");
    FAssertMsg(eBuilding < GC.getNumBuildingInfos(), "GC.getNumBuildingInfos expected to be >= 0");

    iCommerce = 0;

    if (getNumBuilding(eBuilding) > 0)
    {
        CvBuildingInfo& kBuilding = GC.getBuildingInfo(eBuilding);
        if (!(kBuilding.isCommerceChangeOriginalOwner(eIndex)) || (getBuildingOriginalOwner(eBuilding) == getOwnerINLINE()))
        {
            iCommerce += kBuilding.getObsoleteSafeCommerceChange(eIndex) * getNumBuilding(eBuilding);

            if (getNumActiveBuilding(eBuilding) > 0)
            {
                iCommerce += (GC.getBuildingInfo(eBuilding).getCommerceChange(eIndex) + [COLOR="Lime"][B]GC.getBuildingInfo(eBuilding).getFeatureCommerceChange(eIndex, eIndex)[/B][/COLOR] + getBuildingCommerceChange((BuildingClassTypes)GC.getBuildingInfo(eBuilding).getBuildingClassType(), eIndex)) * getNumActiveBuilding(eBuilding); [COLOR="Lime"]//RFCA[/COLOR]

                if (GC.getBuildingInfo(eBuilding).getReligionType() != NO_RELIGION)
                {
                    if (GC.getBuildingInfo(eBuilding).getReligionType() == GET_PLAYER(getOwnerINLINE()).getStateReligion())
                    {
                        iCommerce += GET_PLAYER(getOwnerINLINE()).getStateReligionBuildingCommerce(eIndex) * getNumActiveBuilding(eBuilding);
                    }
                }

                if (GC.getBuildingInfo(eBuilding).getGlobalReligionCommerce() != NO_RELIGION)
                {
                //Rhye - start (max commerce from a shrine)
                //iCommerce += (GC.getReligionInfo((ReligionTypes)(GC.getBuildingInfo(eBuilding).getGlobalReligionCommerce())).getGlobalReligionCommerce(eIndex) * GC.getGameINLINE().countReligionLevels((ReligionTypes)(GC.getBuildingInfo(eBuilding).getGlobalReligionCommerce())));
                iCommerce += std::min(MAX_COM_SHRINE, (GC.getReligionInfo((ReligionTypes)(GC.getBuildingInfo(eBuilding).getGlobalReligionCommerce())).getGlobalReligionCommerce(eIndex) * GC.getGameINLINE().countReligionLevels((ReligionTypes)(GC.getBuildingInfo(eBuilding).getGlobalReligionCommerce()))));
                //Rhye - end
                }

                if (GC.getBuildingInfo(eBuilding).getGlobalCorporationCommerce() != NO_CORPORATION)
                {
                    iCommerce += (GC.getCorporationInfo((CorporationTypes)(GC.getBuildingInfo(eBuilding).getGlobalCorporationCommerce())).getHeadquarterCommerce(eIndex) * GC.getGameINLINE().countCorporationLevels((CorporationTypes)(GC.getBuildingInfo(eBuilding).getGlobalCorporationCommerce()))) * getNumActiveBuilding(eBuilding);
                }
            }

            if ((GC.getBuildingInfo(eBuilding).getCommerceChangeDoubleTime(eIndex) != 0) &&
                (getBuildingOriginalTime(eBuilding) != MIN_INT) &&
                ((GC.getGameINLINE().getGameTurnYear() - getBuildingOriginalTime(eBuilding)) >= GC.getBuildingInfo(eBuilding).getCommerceChangeDoubleTime(eIndex)))
            {
                return (iCommerce * 2);
            }

            return iCommerce;
        }
    }

    return 0;
}

I alreday looked through the forum but nothing helped. FeatureInfos are loaded before BuildingInfos, so there isn't a problem, I guess. Has anyone an idea?
If you need anything I'll post it here.
 
a. Please post more detail than "it doesn't work". Does the game load? Does any error appear? Does a problem come even when you don't use the attribute in the xml?

b. In your schema, one part is missing. In the definition of the building object itself, you must add a reference. Since your new part is added just after BonusYieldModifiers, search for BonusYieldModifiers elsewhere in the file. You will find one reference inside BuildingInfo. Add a similar reference for yours, right after that.
 
First, sorry for the confuse post, I was trying to solve the problem for six hours when I wrote here... I wasn't in the best mood ;).

The problem is the following: With these changes (schema file had the missing part here, just forgot to add that), the mod loads. BUT I get XML load errors while loading, which tell me that it was impossible to load BuildingInfos.xml, SpecialBuildingInfos.xml, BuildingClassInfos.xml. Then it tells me that there is zero or less memory available in CvXMLLoadUtility::VariableListTagPair. Yet, the error occurs in CivicInfos/GameInfoSchema, where I didn't modify anything. Additionally, it tels me, that there are more siblings than memory allocated for them in the same area.
After clicking all those messages away, the game starts but without buildings and wonders.

The game doesn't even load correctly with only the Schema changes active... I really don't what causes that.
 
Your posted schema and XML do not match.

BuildinsSchema.xml
Code:
<ElementType name="BonusYieldModifiers" content="eltOnly">
        <element type="BonusYieldModifier" minOccurs="0" maxOccurs="*"/>
    </ElementType>
    [COLOR=Lime]<!--RFCA start-->[/COLOR]
    <ElementType name="FeatureCommerceChange" content="eltOnly">
        <element type="FeatureType"/>
        <element type="CommerceChanges"/>
    </ElementType>
    <ElementType name="FeatureCommerceChanges" content="eltOnly">
        <element type="FeatureCommerceChange" minOccurs="0" maxOccurs="*"/>
    </ElementType>
    [COLOR=Lime]<!--RFCA end-->[/COLOR]
    <ElementType name="ImprovementFreeSpecialist" content="eltOnly">
        <element type="ImprovementType"/>
        <element type="iFreeSpecialistCount"/>
    </ElementType>

This schema expects your XML to look like this:

BuildingInfos.xml
Code:
<BonusYieldModifiers/>
            <FeatureCommerceChanges>
                <FeatureCommerceChange>
                    <FeatureType>FEATURE_FOREST</FeatureType>
                    <CommerceChanges>
                        <iCommerce>0</iCommerce>
                        <iCommerce>0</iCommerce>
                        <iCommerce>2</iCommerce>
                    </CommerceChanges>
                </FeatureCommerceChange>
            </FeatureCommerceChanges>
            <ImprovementFreeSpecialists/>

I don't know what kind of element CommerceChanges is, I just ASSUME it is defined somewhere else and happens to have iCommerce defined within it as a multiple occurance. If it isn't defined anywhere, you would need to define it.



What you posted in BuildingInfos for your XML

BuildingInfos.xml
Code:
<BonusYieldModifiers/>
            <FeatureCommerceChanges>
                <FeatureCommerceChange>
                    <FeatureType>FEATURE_FOREST</FeatureType>
                    <iCommerce>0</iCommerce>
                    <iCommerce>0</iCommerce>
                    <iCommerce>2</iCommerce>
                </FeatureCommerceChange>
            </FeatureCommerceChanges>
            <ImprovementFreeSpecialists/>

Would require a different schema:

BuildinsSchema.xml
Code:
<ElementType name="BonusYieldModifiers" content="eltOnly">
         <element type="BonusYieldModifier" minOccurs="0" maxOccurs="*"/>
     </ElementType>
     [COLOR=Lime]<!--RFCA start-->[/COLOR]
     <ElementType name="FeatureCommerceChange" content="eltOnly">
         <element type="FeatureType"/>
         <element type="iCommerce" minOccurs="0" maxOccurs="*"/>
     </ElementType>
     <ElementType name="FeatureCommerceChanges" content="eltOnly">
         <element type="FeatureCommerceChange" minOccurs="1" maxOccurs="4"/>
     </ElementType>
     [COLOR=Lime]<!--RFCA end-->[/COLOR]
     <ElementType name="ImprovementFreeSpecialist" content="eltOnly">
         <element type="ImprovementType"/>
         <element type="iFreeSpecialistCount"/>
     </ElementType>


I didn't look at the rest of your code to see which of the two (if either) would actually work with how you wrote the loading method in CvInfos, don't have much time at the moment. I would assume you are copy/pasting from something else, if that is the case, the first correction (making XML match Schema) would be the correct option.
 
Okay, this is frustrating now:
I tried xienwolf's proposed changes in both ways, shifted the place, where I defined the new tag, but nothing helped. It still gave mwe the same error as mentioned above. And that, while I only made XML chnges (Schema and BuildingInfos). It should have loaded normally... Oh well, I will leave that for now and try to achieve this with python...
Thanks, anyway.
 
There is a second place where you have to modify the Schema, since you hadn't posted your full XML entry for where you used this I assumed you knew about it and considered it useless to post, but maybe you do not...

In the set for "BuildingInfo" you have to list the new tag in there so that the XML knows to allow it to exist within a BuildingInfo structure, and where to expect to find it. You'll also want to make it an optional field so you don't have to edit EVERY building in the file to contain a blank value.
 
Hi.
first of all: thank you very much Black Whole for your scripts. =)
It's exactly what I was aiming for..


...the problem is that it doesn't seem to work at all. =(
I resolved the loading errors (they were caused simply by some BuildingSchema omissions).
However, even if the game loads perfectly, the building doesn't give commerce types (like culture, for example).

I gently ask, xienwolf too, if you already managed to resolve the problem or not.
I'm not very skilled in SDK (I'm a total beginner) so I really don't know how to read the CvInfos.ccp added script...
I suppose it's there that lies the problem.

Probably (I'm just guessing), Black Whole, in your script you told to change the commerce of a specific feature plot.
If that's the case, I'm sorry to tell you it should be impossible, since plots don't give commerce at all (only yields, such production, food and raw commerce).
So telling the game to change commerce values it's useless.

Instead, I suppose is very simple to tell the game to change the building's commerce value per number of specific features plots in city area (note: it's similar to what National Park does).
 
Never looked at any code other than what he posted here for this. Reviewing it now I don't see where he added anything at all to CvCity.cpp to increase the commerce of the building with his new tag. Nor is there anything in CvBuildingInfos::read function to actually load the data out of the XML and into the arrays. All that is accomplished is to create the arrays to hold the data at some point in the future.
 
Oh my... >__<''
Then I'm afraid that a whole part of the work is missing...
I'm afraid I'm still not able to write the Python part (is it Python, regarding CvCity.cpp and CvBuildingInfos, right? not SDK, isn't it?).
I suppose I should ask some serious help opneing a new thread.
(xienwolf, if you have some hint about it, they will be very appreciated. =D
Anyway: thanks a lot.)
 
Top Bottom