Troubles with Arrays and Arrays of Arrays...

Do the building changes show up in the building list of the city screen?

Yes. They appear on the left side of the screen, and act as if the building normally gave that amount of happy, healthy... (Yes, the healthy shows up as doubled on the left side too.)
 
That's a good clue. CvCity::getBuildingHealth() calls both CvCity::getBuildingGoodHealth() and (if you don't have a Recycling Center) CvCity::getBuildingBadHealth(). You added a line of code to each of these to call CvTeam::getTechBuildingHealth(), right? I would double-check these calls, that you are using min() and max() for the correct calls, min() to get negative values and max() to get positive values.

Do the happy values show up doubled as well?
 
That's a good clue. CvCity::getBuildingHealth() calls both CvCity::getBuildingGoodHealth() and (if you don't have a Recycling Center) CvCity::getBuildingBadHealth(). You added a line of code to each of these to call CvTeam::getTechBuildingHealth(), right? I would double-check these calls, that you are using min() and max() for the correct calls, min() to get negative values and max() to get positive values.

Think I caught the problem:

Code:
                        else if (iOldValue < 0)
                        {
                            pLoopCity->changeBuildingBadHealth(iOldValue * iNumBuildings);
                        }

This is wrong. Bad Health is a positive value as well, so your just adding the old value to it again, effectively doubling it.
(At least, I think that's it.)

.
Do the happy values show up doubled as well?

No Happiness works 100% correctly.
 
Apparently, I'm incorrect, on both counts.

1.) That logic doesn't seem to be problematic. In fact, when I changed it, nothing happened. The healthiness was still double.

2.) Happiness isn't working 100%. I just gave myself the tech, then build the building, to double check, and the happiness and healthiness shows on the building panel, but not on the city gauges.
 
I work much better with numbers. Can you give me an example of what you do and what you see precisely? Also, it would be good to test both ways: tech first then building first. If happiness is broken in exactly the same way then there's no need to post those results. If it is broken in a different way, post the tests you run.

For example: Biology gives +1:health: to Granary.
Tech then building: city screen shows +2:health: (bad)
Building then tech: city screen shows +1:health: (good)

Are the x:health: > y:yuck: next to the food bar correct? What about its hover text? What are the city gauges?

As for that calculation you posted, it needs to add the old negative value to the bad health (a positive value) to remove it, as it's doing, whereas below it subtracts the new negative value from the bad health to add it. When changing here, first remove old then add new.
 
I work much better with numbers. Can you give me an example of what you do and what you see precisely? Also, it would be good to test both ways: tech first then building first. If happiness is broken in exactly the same way then there's no need to post those results. If it is broken in a different way, post the tests you run.

For example: Biology gives +1:health: to Granary.
Tech then building: city screen shows +2:health: (bad)
Building then tech: city screen shows +1:health: (good)

Are the x:health: > y:yuck: next to the food bar correct? What about its hover text? What are the city gauges?

As for that calculation you posted, it needs to add the old negative value to the bad health (a positive value) to remove it, as it's doing, whereas below it subtracts the new negative value from the bad health to add it. When changing here, first remove old then add new.


Okay.

Building, Then Tech


  • Happiness shows correctly on building left panel and city overall happiness
  • Healthiness shows doubled on building left panel and city overall heathiness

Tech, Then Building


  • Happiness shows correctly on building left panel, has no effect on city overall happiness
  • Healthiness shows up doubled on building left panel, and has no effect on city overall healthiness
 
Holy #&^%: Apparently the building bad happiness and health are actually stored as negative values after all. Looking at the calls to changeBuildingGood/BadHealth/Happiness() in processBuilding() confirms this. Grr, how did I mess that up? :mad: See if you can fix all the calls to those functions in the code I've sent you and redo the tests.​

The two no effect problems are because we still need to add code to processBuilding() as I said above. In processTech(), each city with the building gets a call to changeBuildingGood/BadHealth/Heappiness(). The same type of calls are needed in processBuilding(), only you won't need to loop over any cities or check if the city has the building.

Code:
void CvCity::processBuilding(BuildingTypes eBuilding, int iChange, bool bObsolete)
{
	...
	int iTechBuildingHealth = GET_TEAM(getTeam()).getTechBuildingHealth(eBuilding);
	if (iTechBuildingHealth > 0)
	{
		changeBuildingGoodHealth(iTechBuildingHealth * iChange);
	}
	else if (iTechBuildingHealth < 0)
	{
		changeBuildingBadHealth(iTechBuildingHealth * iChange);
	}
	[I]... same for happiness ...[/I]
}

Another place you'll need to add similar code is wherever buildings get obsoleted by techs. If a tech grants +1:) to Monument, should that extra happiness disappear once you research Astronomy? Use CvBuilding[Class?]Info's function to get its obsoleting tech to find where in the code this happens. It's probably triggered by processTech().

The above code treats bad health as a negative value as per the note at the start of this post. The other calls to changeBuildingBadHealth/Happiness() need to be fixed.
 
Okay, well that ProcessBuild code fixes the no effect parts. However, I still get double health. Here's my CvTeam::setTechExtraBuildingHealth():

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);
						}
					}
				}
			}
		}
	}
}

At this point I'm a little confused. Good Health is Positive and Bad Health is Negative? Why not just use one function?
 
It is confusing. I have no idea why they chose to do it that way, but they did. What does the equivalent happiness function look like?
 
It is confusing. I have no idea why they chose to do it that way, but they did. What does the equivalent happiness function look like?

I think it's silly, but maybe they have a reason. (I hope they do.)

Here's the Happy Function:

Code:
void CvTeam::setTechExtraBuildingHappiness(BuildingTypes eIndex, int iNewValue)
{
    if (m_paiTechExtraBuildingHappiness[eIndex] != iNewValue)
    {
        int iOldValue = m_paiTechExtraBuildingHappiness[eIndex];
        m_paiTechExtraBuildingHappiness[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->changeBuildingGoodHappiness(-iOldValue * iNumBuildings);
                        }
                        
                        // Add the new value
                        if (iNewValue != 0)
                        {
                            pLoopCity->changeBuildingGoodHappiness(iNewValue * iNumBuildings);
                        }
                    }
                }
            }
        }
    }
}
 
There is a changeBuildingBadHappiness() function as well, so I would modify the code you just posted to do the same thing as the health function. Then retest. If the happiness display still works correctly, we know the problems aren't in these functions.

Post all the CvCity functions that call CvTeam::getTechBuildingHealth() (just the relevant bits of course).
 
There is a changeBuildingBadHappiness() function as well, so I would modify the code you just posted to do the same thing as the health function. Then retest. If the happiness display still works correctly, we know the problems aren't in these functions.

Post all the CvCity functions that call CvTeam::getTechBuildingHealth() (just the relevant bits of course).

Okay, but in the morning? I can't think at 2am very well... :lol:
 
There is a changeBuildingBadHappiness() function as well, so I would modify the code you just posted to do the same thing as the health function. Then retest. If the happiness display still works correctly, we know the problems aren't in these functions.

I copied that healthiness sections for removing the old value and adding the new one, edited them to be for happiness, and tested it, and the happiness is still the correct amount. Oh, and I saw why they split bad and good health and bad and good happiness. It's for the building that removes all the unhappiness from your city, and for the building that removes all unhealthiness... Makes sense.

Post all the CvCity functions that call CvTeam::getTechBuildingHealth() (just the relevant bits of course).

Okay:
in Process Building:

Code:
int iTechBuildingHealth = GET_TEAM(getTeam()).getTechExtraBuildingHealth(eBuilding);
        if (iTechBuildingHealth > 0)
        {
            changeBuildingGoodHealth(iTechBuildingHealth * iChange);
        }
        else if (iTechBuildingHealth < 0)
        {
            changeBuildingBadHealth(iTechBuildingHealth * iChange);
        }
        int iTechBuildingHappiness = GET_TEAM(getTeam()).getTechExtraBuildingHappiness(eBuilding);
        if (iTechBuildingHappiness != 0)
        {
            changeBuildingGoodHappiness(iTechBuildingHappiness * iChange);
        }

In

Code:
int CvCity::getBuildingGoodHealth(BuildingTypes eBuilding) const
{...
    iHealth += std::max(0, GET_TEAM(getTeam()).getTechExtraBuildingHealth(eBuilding));
...}

int CvCity::getBuildingBadHealth(BuildingTypes eBuilding) const
{...
    iHealth += std::min(0, GET_TEAM(getTeam()).getTechExtraBuildingHealth(eBuilding));
...
}

int CvCity::getBuildingHappiness(BuildingTypes eBuilding) const
{...
    iHappiness += GET_TEAM(getTeam()).getTechExtraBuildingHappiness(eBuilding);
...}
 
I saw why they split bad and good health and bad and good happiness.

They are also displayed separately in the happiness and health hovers in CvGameTextMgr.

In processBuilding() you should split the happiness between good and bad calls just like you did for health.

happyLevel() and unhappyLevel() use getBuildingGood/BadHappiness(), the stored totals for all buildings. The same for goodHealth() and badHealth(). Are you calling getTechExtraBuildingHealth() from CvPlayer or anywhere else other than changeTechExtraBuildingHealth()?

At this point you either need to add logging code to trace through the code or use a debug DLL and actually trace through the code. To make this easier, add some temporary code to getTechExtraBuildingHealth():

Code:
int getTechExtraBuildingHealth(BuildingTypes eIndex)
{
    if (m_piTechExtraBuildingHealth[eIndex] != 0)
        int x = 5;  // set the breakpoint here
    ...
}

This way the program stops for debugging only when a non-zero value is found.
 
They are also displayed separately in the happiness and health hovers in CvGameTextMgr.

In processBuilding() you should split the happiness between good and bad calls just like you did for health.

Done.
happyLevel() and unhappyLevel() use getBuildingGood/BadHappiness(), the stored totals for all buildings. The same for goodHealth() and badHealth(). Are you calling getTechExtraBuildingHealth() from CvPlayer or anywhere else other than changeTechExtraBuildingHealth()?

Not that I know of.

I found something interesting that might help. When I added the building, then the tech, I had the health doubled. When I removed the tech, I was left with the right health, but negative.

So, the building (A Zoo)
Gave +200 Health with the tech, when it should give +100. Then, on removing the tech, the Zoo gave -100 Health.
 
So adding the Zoo does nothing. Adding the tech adds +200 health (should be +100). Removing the tech adds -300, leaving -100 in the end? What does readding the tech give you?

Try the same test the other way: add tech, building, remove building, add building.

Also try adding both then removing both in different orders. See if you can discern any pattern in the noise.
 
So adding the Zoo does nothing. Adding the tech adds +200 health (should be +100). Removing the tech adds -300, leaving -100 in the end? What does readding the tech give you?

That's the pattern. It seems to be adding -100 unhealthiness and 300 healthiness... I added and removed the tech several times, and it repeated that.
 
That didn't make sense. It sounds like adding the tech adds a different amount of health than removing the tech removes. Can you please give precise numbers of before and after each step? Remember that I cannot run your code so I'm very much in the dark. I only know what you specifically tell me.
 
That didn't make sense. It sounds like adding the tech adds a different amount of health than removing the tech removes. Can you please give precise numbers of before and after each step? Remember that I cannot run your code so I'm very much in the dark. I only know what you specifically tell me.

Sure:

City 1 Starts with Zoo

City 2 starts w/o Zoo

Add The Tech

City 1 has +200 Health
City 2 has 0

Add Zoo to City 2

City 1 Has +200 Health
City 2 Has +200 Health

Remove Tech

City 1 & 2 both have -100 Health.

Add Tech again

City 1&2 Have +200 Health

Repeat.
 
So the first time the tech is added, it adds 200:health:. From then on, adding or removing it does 300:health:. Very odd.

What about adding/removing the building? Does that work the same way?
 
Back
Top Bottom