Development Thread

Well I have reason to believe that m_aBuildingHappyChange is stored, so even if there is a chance that the building might not get the bonus of its own effect the same turn it is built, it would definitely get it the next turn.
 
It depends on how the code works. Some values are stored over time with deltas being applied as buildings are built. Other values are recalculated each turn. I forget which case applies to building happiness which is the source of my doubt. I'm putting together a simple test now. I don't know of any existing mods that have this.
 
For my test I added +1:) for Market and Library to Library. In my game I added a Market to two cities. Then I added a Library to one of them. All this is through WorldBuilder.

  1. The non-Library city shows +1:) as expected in the building list and the :) hover.
  2. The Library city shows +2:) as expected in the building list (for for each building) and the :) hover.
  3. I reran the test, first making the Library city +2:(. When I added the building, the :( indicator on the map did not disappear until I exited WB.
Without doing a real test by building the Library normally I can't be sure--or better reading through the code--but I think #3 proves that the effect a) is incorrect when the building is processed but b) recalculated at some point (each turn or exiting WB).

Since the effect is eventually taken into account, I'm inclined to account for it and let the mods sort it out. ;)

Edit: I ran the test, building the Library in the city normally, and I saw the full :) effect immediately. So it must be recalculated between adding the building and beginning my next turn.
 
Well, that was certainly easy enough. :)

Code:
(getNumBuilding(eLoopBuilding) [B]+ (eBuilding == eLoopBuilding ? 1 : 0)[/B])

Committed as r156. Thanks!
 
Committed as r45, thank you :)
.. But you were thanking me too soon I think.


I'm looking at r524->r526 BBAI CvCityAI line ~3550 again now where jdog starts using your functions, yet is still leaving in some other checks, which was what made me take another good look at the actual building effect functions in the first place.
Commerce and local warweariness additional values are just minor leftovers, Global happy and other buildingclasses are now handled in r156.
kBuilding.isNoUnhappiness is handled, right? Maybe jdog just forgot to remove that.
But iGlobalWarWearinessModifer, I overlooked that :( I thought this was handled in the big chunk that starts with // War Weariness Modifier but I can't see the global variant now that I actually read it.

Spoiler :
(BBAI r526, excerpt from CvCityAI::AI_buildingValueThreshold())
Code:
			if (((iFocusFlags & BUILDINGFOCUS_HAPPY) || (iPass > 0)) && !isNoUnhappiness())
			{
				int iBestHappy = 0;
				for (iI = 0; iI < GC.getNumHurryInfos(); iI++)
				{
					if (canHurryBuilding((HurryTypes)iI, eBuilding, true))
					{
						int iHappyFromHurry = AI_getHappyFromHurry((HurryTypes)iI, eBuilding, true);
						if (iHappyFromHurry > iBestHappy)
						{
							iBestHappy = iHappyFromHurry;
						}
					}
				}
				iValue += iBestHappy * 10;

[B]				if (kBuilding.isNoUnhappiness())
				{
					iValue += ((iAngryPopulation * 10) + getPopulation());
				}[/B]
[COLOR="Green"]/************************************************************************************************/
/* BETTER_BTS_AI_MOD                      02/24/10                              jdog5000        */
/*                                                                                              */
/* City AI                                                                                      */
/************************************************************************************************/[/COLOR]
				int iGood, iBad = 0;
				int iBuildingActualHappiness = getAdditionalHappinessByBuilding(eBuilding,iGood,iBad);

				if( iBuildingActualHappiness < 0 )
				{
					[COLOR="Green"]// Building causes net decrease in city happiness[/COLOR]
					iValue -= (-iBuildingActualHappiness + iAngryPopulation) * 6
						+ (-iBuildingActualHappiness) * iHappyModifier;

					[COLOR="Green"]// BBAI TODO: Check for potential shrink in populatio[/COLOR]n
					
				}
				else if( iBuildingActualHappiness > 0 )
				{
					[COLOR="Green"]// Building causes net increase in city happiness[/COLOR]
					iValue += (std::min(iBuildingActualHappiness, iAngryPopulation) * 10) 
						+ (std::max(0, iBuildingActualHappiness - iAngryPopulation) * iHappyModifier);
				}

				iValue += (-kBuilding.getHurryAngerModifier() * getHurryPercentAnger()) / 100;

				for (iI = 0; iI < NUM_COMMERCE_TYPES; iI++)
				{
					iValue += (kBuilding.getCommerceHappiness(iI) * iHappyModifier) / 4;
				}

				int iWarWearinessModifer = kBuilding.getWarWearinessModifier();
				if (iWarWearinessModifer != 0)
				{
					iValue += (-iWarWearinessModifer * iHappyModifier) / 16;
				}

				iValue += (kBuilding.getAreaHappiness() * (iNumCitiesInArea - 1) * 8);
				iValue += (kBuilding.getGlobalHappiness() * iNumCities * 8);

				int iWarWearinessPercentAnger = kOwner.getWarWearinessPercentAnger();
[B]				int iGlobalWarWearinessModifer = kBuilding.getGlobalWarWearinessModifier();
				if (iGlobalWarWearinessModifer != 0)
				{
					iValue += (-(((iGlobalWarWearinessModifer * iWarWearinessPercentAnger / 100) / GC.getPERCENT_ANGER_DIVISOR())) * iNumCities);[/B]
					iValue += (-iGlobalWarWearinessModifer * iHappyModifier) / 16;
				[B]}[/B]

				for (iI = 0; iI < GC.getNumBuildingClassInfos(); iI++)
				{
					if (kBuilding.getBuildingHappinessChanges(iI) != 0)
					{
						iValue += (kBuilding.getBuildingHappinessChanges(iI) * kOwner.getBuildingClassCount((BuildingClassTypes)iI) * 8);
					}
				}
[COLOR="Green"]/************************************************************************************************/
/* BETTER_BTS_AI_MOD                       END                                                  */
/************************************************************************************************/[/COLOR]
			}

			if (((iFocusFlags & BUILDINGFOCUS_HEALTHY) || (iPass > 0)) && !isNoUnhealthyPopulation())
			{
[COLOR="Green"]/************************************************************************************************/
/* BETTER_BTS_AI_MOD                      02/24/10                          jdog5000 & Fuyu     */
/*                                                                                              */
/* City AI                                                                                      */
/************************************************************************************************/[/COLOR]
				int iGood, iBad = 0;
				int iBuildingActualHealth = getAdditionalHealthByBuilding(eBuilding,iGood,iBad);

				if( iBuildingActualHealth < 0 )
				{
					[COLOR="Green"]// Building causes net decrease in city health[/COLOR]
					iValue -= (-iBuildingActualHealth + iBadHealth) * 6
						+ (-iBuildingActualHealth) * iHealthModifier;

					/[COLOR="Green"]/ BBAI TODO: Check for potential shrink in population[/COLOR]
					
				}
				else if( iBuildingActualHealth > 0 )
				{
					[COLOR="Green"]// Building causes net increase in city health[/COLOR]
					iValue += (std::min(iBuildingActualHealth, iBadHealth) * 10)
						+ (std::max(0, iBuildingActualHealth - iBadHealth) * iHealthModifier);
				}

				iValue += (kBuilding.getAreaHealth() * (iNumCitiesInArea-1) * 4);
				iValue += (kBuilding.getGlobalHealth() * iNumCities * 4);
[COLOR="Green"]/************************************************************************************************/
/* BETTER_BTS_AI_MOD                       END                                                  */
/************************************************************************************************/[/COLOR]
			}
 
I've just added the Actual Effects for Angry Population (caused by :) and :() and Spoiled Food (caused by :health: and :yuck:). This is important because adding :) or :health: doesn't always buy you an immediate benefit, and when it does it's good to know.

For example, say your city is at 5:) and 6:( leaving you with 1:mad: citizen who won't work. A Market with Ivory and Silk will show +2:) and -1:mad:.

I've already tested and committed the Angry Population changes; I'm testing the Spoiled Food changes now.

I'm very stoked that jdog has been able to make use of these APIs to improve the AI. It gives me a warm fuzzy feeling when I make the lives of other developers better. :)

Edit: Completed in r159. I also exposed all the values to Python with four functions for each type (happiness and health) to return all four values (total, good, bad, angry pop / spoiled food) since I don't want to bother figuring out how to return a tuple to Python right now. :p
 
That argument list is getting longer and longer .. if I may request this for BULL:

function overloading for actual building effects (happy/health):
Code:
int CvCity::getAdditionalHealthByBuilding(BuildingTypes eBuilding) const
{
	int iGood = 0; int iBad = 0; int iSpoiledFood = 0;
	return getAdditionalHealthByBuilding(eBuilding, iGood, iBad, iSpoiledFood);
}

and similar
Code:
int CvCity::getAdditionalHappinessByBuilding(BuildingTypes eBuilding) const
{
	int iGood = 0; int iBad = 0; int iAngryPop = 0;
	return getAdditionalHappinessByBuilding(eBuilding, iGood, iBad, iAngryPop);
}
Just a simpler way for other people to use it :)
I know you want to return as much info as possible with a single function but when I'm calling these functions, all I'm interested in are the building effects themselves.
 
Sure, that's fine. I exposed them as individual functions to Python since I didn't want to bother figuring out how to return a list to Python. I can expose the same functions in C++ too, or just the one you have requested (iGood - iBad).
 
The ones I requested should be more than enough, for everything else there's still the option to just use the main function with all its arguments.
 
I added the functions you requested and fixed the CyCity::getAdditinoalHappinessByBuilding() functions as they were calling getAdditinoalHealthByBuilding() in r160.
 
Displaying spoiled food:
For food, there are 3 options in gamefonts: the yield food itself, BAD_FOOD_CHAR and EATEN_FOOD_CHAR. You chose to represent spoiled food with EATEN_FOOD_CHAR - which I think looks too much like food itself. Imo you should consider changing that to either BAD_FOOD_CHAR which is a different color at least, or even use (-1)*spoiledfood <food>.
 
I chose the eaten food icon because that's what's used in the City Screen. Look to the right of the food bar when you have :yuck: > :health:. I am honestly tempted to change both to the bad food char, but then the equation on the left will not sync up exactly (four values won't fit there). I don't think the bad food icon is actually used anywhere in the vanilla game--only in the CDA. If so, I'm game to use it instead.

I don't want to show +1 <food> since that would be misleading I think.
 
Not quite, look again. If there is unhealthiness, it says -x EATEN_FOOD_CHAR. To correspond with that, 1 less spoiled food would need to be displayed as +1 EATEN_FOOD_CHAR. Right now it displays -1 EATEN_FOOD_CHAR.
 
Yes, I agree it should say +1 but it is using the eaten food icon, so that's why I went with it. I think the best would be +1 <bad-food>
 
+1 food (probably misleading)
-1 eaten food (current)
+1 eaten food (would match city screen)
-1 bad food (my suggestion)
+1 bad food (your suggestion)

:crazyeye:
 
I'm proposing to match up the City Screen and the hover, definitely with something different from what the City Screen has now.

My reasoning for +1 eaten/bad is because it adds to the badness. -1 <bad> is a good thing. For example, if you have anger and hover over a Temple, it says -1 <angry-pop> to indicate that you will have one less angry citizen.

Of course, we may be talking different things. :lol: I am proposing +1 <eaten/bad-food> for :yuck: things and -1 <same icon> for :health: things.
 
Ok then I misunderstood, I thought we were always talking about the effects of +1 :health: in a city with unhealthiness.
 
I think we started there but then I switched when you mentioned the eaten food on the City Screen. The city screen should say +X since it adds to your bad/eaten food. :health: buildings should say -X bad/eaten food and :yuck: buildings should say +X bad/eaten. Are we agreed on that?

Now, which icon? Bad or eaten food? Or maybe we could get NikNaks to put an angry face on a food icon for Angry Food. ;)
 
Agreed.
+X eaten food
would make more sense there, as it adds to consumption.

Since on the city screen the bad effects from unhappy and unhealthness are red, I think you should color the +x/-x for angrypop/spoiledfood too, to emphasize that the effect is a positive/negative one.
(like +1 :health:, -1 eaten food)
 
Back
Top Bottom