Dynamically change commerce for buildings

tesb

Emperor
Joined
Jan 16, 2010
Messages
1,593
Hi,

i have a python function that determines a certain variable. based on the variable i want to change the commerce of a building, e.g.:

commerce = base commerce (as defined in the xml) + bonus (determined in python)

the bonus is calculated per city and per turn (i.e. iBonus might be 5 one turn and 2 the next). i just want to know what would be the way to implement that commerce change, e.g. would
Code:
pCity.setBuildingCommerceChange(gc.getBuildingInfo(iBuilding).getBuildingClassType(), CommerceTypes.COMMERCE_GOLD, iBonus)
work?

i don't want to use
Code:
pPlayer.changeGold(iBonus)
because that would circumvent bonuses from other buildings that have a % modifier for that commerce type.
 
1) If you only intend to have this feature for particular players, then it will be a problem, because cities retain that bonus when ownership transferred.

2) Certain events add bonus yield/commerce to buildings.
Using set will remove those.
 
1) the building can not be captured
2) for that building there are no events

somehow i got weird behavior from that function:

-if the iBonus is 0 the commerce does not reset to the base xml value but keeps at iBonus = 1, although i know that iBonus is zero.

here is a minimal code snippet:
Code:
	iNrCy = pPlayer.getNumCities()

	
	if iNrCy > 0:
		for pyCity in PyPlayer(iPlayer).getCityList():
			pCity = pyCity.GetCy()
			iBonus = 0
			
			#<snip>
			#claculates iIncome (can only be 0, 1 or 2)
			#iBuilding = ...
			#<snip>
			
			if pCity.getNumRealBuilding(iBuilding) > 0:
				if iIncome > 0:
					iBonus = iIncome*2					
				pCity.setBuildingCommerceChange(gc.getBuildingInfo(iBuilding).getBuildingClassType(), CommerceTypes.COMMERCE_CULTURE, iBonus)

in the xml the base culture of iBuilding is 0
when i place the building it goes to 4 culture (since iIncome is 2)
however when iIncome (due to other means i can control) goes to 0, the culture of the building stays 2, but it should be 0.

i can easly check the value of iIncome, so i am really at a loss
 
1) It does not matter if the building is captured or not.
Say, the building is Oxford University.
And currently bonus is + 5 :gold:

When it is captured, obviously OU is destroyed.
But when a new OU is built, it comes with +5 :gold:

2) When in doubt, use my WorldBuilder to check what is the current Building Commerce Change

Anyway, it is changing culture of iDefCat and not iBuilding.
 
sorry was a posting issue, the code is consistent with iDefCat. i just changed it to iBuilding to make the code a bit easier to read and forgot change all iDefCat entries.


1) maybe i made a bad assumption: the Bonus should only applied for the building in the current city. for example in city A the bonus might be 1 in city B it might be 0 and so on. that means the building in city A should have 1 culture and the building in city B should have 0 culture.
also the function is called every turn and the default bonus is 0, unless you have that particular building, see the function above.

2) huh? should simply looking at the building in the city be enough to see the commerce change (i know the base xml values)
 
i tested a bit and it works until the bonus lowers itself, i.e.
turn 1:
iBonus = 0 -> 0 culture
turn 2:
iBonus = 4 -> 4 culture
turn 3:
iBonus = 0 -> culture should be 0, but is too high
 
Doing a simple with WB proves that setting Bonus Culture back to 0 removes all extra Culture added (screenshots)

Thus, it depends where your codes are done.
1) onCityDoTurn?
2) getCity is outdated method of looping through all cities. Some cities are skipped when cities are captured.
3) getNumRealBuilding only counts those there are built. If there is a wonder that grants free ones, it is screwed.
4) Culture may differ from XML base values due to many reasons, such as 1000 years passed, change of ownership, obsolete

Edit:
Refer to Airport in screenshots 5 and 6.
It does not matter how much culture is boosted. It will still be removed totally when Culture is set to 0.
 

Attachments

  • Civ4ScreenShot0004.JPG
    Civ4ScreenShot0004.JPG
    137.8 KB · Views: 50
  • Civ4ScreenShot0005.JPG
    Civ4ScreenShot0005.JPG
    102.4 KB · Views: 79
  • Civ4ScreenShot0006.JPG
    Civ4ScreenShot0006.JPG
    137.5 KB · Views: 49
  • Civ4ScreenShot0007.JPG
    Civ4ScreenShot0007.JPG
    104.3 KB · Views: 55
  • Civ4ScreenShot0008.JPG
    Civ4ScreenShot0008.JPG
    99.8 KB · Views: 78
  • Civ4ScreenShot0009.JPG
    Civ4ScreenShot0009.JPG
    100.9 KB · Views: 74
i got it to work, was indeed a stupid little error i made within the loop.


2) what is a better method?

3)+4) are no problem
 
Code:
(loopCity, iter) = pPlayer.firstCity(False)
while(loopCity):
	if not loopCity.isHasReligion(iReligion):
		loopCity.setHasReligion(iReligion, True, True, True)
	(loopCity, iter) = pPlayer.nextCity(iter, False)
 
The PyPlayer's getCityList function is already doing it that way. In fact, that is where most people, like me, steal the code from (only requireing a couple of minor tweaks) to do it manually (when all that additional stuff in PyHelpers is not going to be used for anything) instead of typing it in every time.
 
just a quick related question

is there a corresponding function to
Code:
pCity.setBuildingCommerceChange(gc.getBuildingInfo(iBuilding).getBuildingClassType(), CommerceTypes.COMMERCE_CULTURE, iBonus)
for production and what would COMMERCE_CULTURE correspond to?
 
Back
Top Bottom