Troubles with Arrays and Arrays of Arrays...

No worries. I expose most of my new CvCity/Player functions in BULL because I try to keep modders in mind. ;)

In this case, it really helps with testing. Plus if you exposed the required building class from your other thread you could add them to the Civilopedia/Sevopedia as icons instead of boring text. :p
 
Plus if you exposed the required building class from your other thread you could add them to the Civilopedia/Sevopedia as icons instead of boring text. :p

Really? Dang, I'll have to do that too, but you'll need to hold my hand through the python, most of it is french to me...
 
Once you get that function exposed I can do the Python pretty quick for both screens. I've been leaving more up to you with the C++ to help you learn, for example not telling you up front to check that a unit requires each building class before adding it to the hover text. :mischief:
 
I've been leaving more up to you with the C++ to help you learn, for example not telling you up front to check that a unit requires each building class before adding it to the hover text. :mischief:

:lol:

Thanks. I should have caught that, but I think I'm too tired right now. (almost 1am here.)
 
Whenever you add a function to a CyFoo object or CvFooInfo object, you must also add an entry for it in the CyFoointerface[X].cpp file, in this case CyCityInterface1.cpp.

Okay, now that I did that, and am trying to test the funtions out, I get a new error in the python console:

error4.png
 
In the line in CyCityInterface1.cpp that exposes the function to Python, you need to tell it about the BuildingTypes parameter that the CyCity function requires. Look at the other entries to see how to specify a parameter.
 
In the line in CyCityInterface1.cpp that exposes the function to Python, you need to tell it about the BuildingTypes parameter that the CyCity function requires. Look at the other entries to see how to specify a parameter.

I did though, at least, I think i did:
Code:
        .def("getBuildingGoodHealthByBuilding", &CyCity::getBuildingGoodHealth, "int (int eBuilding)")
        .def("getBuildingBadHealthByBuilding", &CyCity::getBuildingGoodHealth, "int (int eBuilding)")
 
It looks like you changed the bindings for the two functions that were already exposed without the BuildingTypes parameter instead of creating two new bindings for the two new functions with ByBuilding at the end of their names. Or maybe you just modified the wrong bindings?
 
It looks like you changed the bindings for the two functions that were already exposed without the BuildingTypes parameter instead of creating two new bindings for the two new functions with ByBuilding at the end of their names. Or maybe you just modified the wrong bindings?

Lol, I think I see what you mean. What a silly mistake... Okay, let's try this again....
 
Hmm. I changed the CyCityInterface1 code, but now I get a different error:

error5.png
 
When exposing functions like this, use int instead of all the FooTypes enumerations. If you look at the other lines you'll notice they put the enumeration type in comments so they show up in the API:

int /* BuildingTypes */ eBuilding​
 
Okay, got the functions reworked, and work in the game. Now, I get strange results. The BuildingGoodHealthByBuilding and BuildingBadHealthByBuilding are returning the same result, "200", which is strange, and the result is twice the XML value.
 
Can you post the latest version of CvTeam::setTechExtraBuildingHealth()? That calls setBuildingGood/BadHealth(), right? CvCity::processBuilding() too, or whatever function it is that you added calls to sBG/BH() to.
 
Can you post the latest version of CvTeam::setTechExtraBuildingHealth()? That calls setBuildingGood/BadHealth(), right? CvCity::processBuilding() too, or whatever function it is that you added calls to sBG/BH() to.


Sure:
Code:
void CvTeam::setTechExtraBuildingHealth(BuildingTypes eIndex, int iNewValue)
{
    if (m_paiTechExtraBuildingHealth[eIndex] != iNewValue)
    {
        int iOldValue = m_paiTechExtraBuildingHealth[eIndex];
        m_paiTechExtraBuildingHealth[eIndex] = iNewValue;
        
        int iI;
        int iLoopCity;
        CvCity* pLoopCity;
        
        for (iI = 0; iI < MAX_PLAYERS; iI++)
        {
            CvPlayer& kLoopPlayer = GET_PLAYER((PlayerTypes)iI);
            if (kLoopPlayer.isAlive() && kLoopPlayer.getTeam() == getID())
            {
                for (pLoopCity = kLoopPlayer.firstCity(&iLoopCity); pLoopCity != NULL; pLoopCity = kLoopPlayer.nextCity(&iLoopCity))
                {
                    int iNumBuildings = pLoopCity->getNumActiveBuilding(eIndex);
                    if (iNumBuildings > 0)
                    {
                        // Remove the old value
                        if (iOldValue > 0)
                        {
                            pLoopCity->changeBuildingGoodHealth(-iOldValue * iNumBuildings);
                        }
                        else if (iOldValue < 0)
                        {
                            pLoopCity->changeBuildingBadHealth(-iOldValue * iNumBuildings);
                        }
                        
                        // Add the new value
                        if (iNewValue > 0)
                        {
                            pLoopCity->changeBuildingGoodHealth(iNewValue * iNumBuildings);
                        }
                        else if (iNewValue < 0)
                        {
                            pLoopCity->changeBuildingBadHealth(iNewValue * iNumBuildings);
                        }
                    }
                }
            }
        }
    }
}

And ProcessBuilding():

Code:
        int iTechBuildingHealth = GET_TEAM(getTeam()).getTechExtraBuildingHealth(eBuilding);
        if (iTechBuildingHealth > 0)
        {
            changeBuildingGoodHealth(iTechBuildingHealth * iChange);
        }
        else if (iTechBuildingHealth < 0)
        {
            changeBuildingBadHealth(iTechBuildingHealth * iChange);
        }
 
Both functions look perfect. What test did you do to get 200 from both functions, and was it definitely positive 200 from the Bad function and not -200?
 
Both functions look perfect. What test did you do to get 200 from both functions, and was it definitely positive 200 from the Bad function and not -200?

Yes. It was positive, that's why I thought it was odd...
 
I think at this point you're stuck with building a Debug DLL and stepping through the relevant bits of code. Perhaps there's an errant call to changeBuildingBadHealth() somewhere after all the changes we've made.
 
I think at this point you're stuck with building a Debug DLL and stepping through the relevant bits of code. Perhaps there's an errant call to changeBuildingBadHealth() somewhere after all the changes we've made.

I have to set breakpoints, right? To see what the code does, I need to declare variables, and initialize them to a value, and set a breakpoint there, to see what happens, correct?
 
You don't have to change your code. Just set a breakpoint wherever you want the program to pause. A good place for this is on the start of the call to changeTechExtraBuildingHealth(), right at the start.

When that breakpoint is hit you can inspect the parameters passed in to verify that they are what you expect to see. Then use the "Step Out" button/command to continue the program until that function exits back to the caller, either CvPlayer::processBuilding() or CvTeam::processTech().
 
Well, I stepped out of the code, and this part is working right, anyway:

Code:
void CvTeam::changeTechExtraBuildingHealth(BuildingTypes eIndex, int iChange)
{
	FAssertMsg(eIndex >= 0, "eIndex is expected to be non-negative (invalid Index)");
	FAssertMsg(eIndex < GC.getNumBuildingInfos(), "eIndex is expected to be within maximum bounds (invalid Index)");

	if (iChange != 0)
	{
		setTechExtraBuildingHealth(eIndex, getTechExtraBuildingHappiness(eIndex) + iChange);
	}
}

When eIndex is 400 (I imagine the Zoo is the 400th building in the list) iChange becomes 100, the CORRECT XML value.

Then, I stuck another breakpoint in this function:

Code:
void CvTeam::setTechExtraBuildingHealth(BuildingTypes eIndex, int iNewValue)
{ [B]//BREAKPOINT RIGHT HERE[/B]
	if (m_paiTechExtraBuildingHealth[eIndex] != iNewValue)
	{
		int iOldValue = m_paiTechExtraBuildingHealth[eIndex];
		m_paiTechExtraBuildingHealth[eIndex] = iNewValue;
		
		int iI;
		int iLoopCity;
		CvCity* pLoopCity;
		
		for (iI = 0; iI < MAX_PLAYERS; iI++)
		{
			CvPlayer& kLoopPlayer = GET_PLAYER((PlayerTypes)iI);
			if (kLoopPlayer.isAlive() && kLoopPlayer.getTeam() == getID())
			{
				for (pLoopCity = kLoopPlayer.firstCity(&iLoopCity); pLoopCity != NULL; pLoopCity = kLoopPlayer.nextCity(&iLoopCity))
				{
					int iNumBuildings = pLoopCity->getNumActiveBuilding(eIndex);
					if (iNumBuildings > 0)
					{
						// Remove the old value
						if (iOldValue > 0)
						{
							pLoopCity->changeBuildingGoodHealth(-iOldValue * iNumBuildings);
						}
						else if (iOldValue < 0)
						{
							pLoopCity->changeBuildingBadHealth(-iOldValue * iNumBuildings);
						}
						
						// Add the new value
						if (iNewValue > 0)
						{
							pLoopCity->changeBuildingGoodHealth(iNewValue * iNumBuildings);
						}
						else if (iNewValue < 0)
						{
							pLoopCity->changeBuildingBadHealth(iNewValue * iNumBuildings);
						}
					}
				}
			}
		}
	}
}

And for some reason, iNewValue was 200, the wrong value. So whatever is happening in between the two functions is causing a problem...
 
Back
Top Bottom