Messages with python

Mind though that the player that gets the popup will be able to select what the terraformed plot becomes. So addPopup needs to be called for the player that built the improvement. The code you posted just loops through all players and gives the popup to all which are human.

Ok. I checked the codes and it seems to me, that the popup will only be shown to the owner of the plot, which would be ok, because the improvements can only be build in your own territory. It would be very nice if you could check the codes too, if I´m right or wrong.

Code:
	def onImprovementBuilt(self, argsList):
		'Improvement Built'
		iImprovement, iX, iY = argsList
##neu Alrik Beginn
		pPlot = CyMap().plot(iX, iY)
		[COLOR="Red"]iPlayer = pPlot.getOwner()
		pPlayer = gc.getPlayer(iPlayer)[/COLOR]		
## Terraform Begin (avain)

		if(iImprovement==gc.getInfoTypeForString('IMPROVEMENT_FOREST')):
			pPlot.setBonusType(-1)		
			pPlot.setFeatureType(gc.getInfoTypeForString('FEATURE_FOREST'), 0)
			pPlot.setImprovementType(-1)

###neuBeginn Popup1 terraforming
		if iImprovement == gc.getInfoTypeForString('IMPROVEMENT_LANDAUFSCHUETTUNG'):
			pPlot.setPlotType(PlotTypes.PLOT_LAND, True, True)
		    	pPlot.setImprovementType(-1)
##neu Alrik Beginn
			[COLOR="Red"]if (pPlayer.isAlive() and pPlayer.isHuman()):[/COLOR]
##neu Alrik Ende				
				CyCamera().JustLookAtPlot( CyMap().plot(iX, iY))
				popupInfo = CyPopupInfo()
				popupInfo.setButtonPopupType(ButtonPopupTypes.BUTTONPOPUP_PYTHON)
				popupInfo.setText(CyTranslator().getText("TXT_KEY_POPUP_SELECT_TERRAINTYPE",()))
				popupInfo.setData1(iPlayer)
				popupInfo.setData2(iX)
				popupInfo.setData3(iY)
				popupInfo.setOnClickedPythonCallback("SelectTerrainType")
				popupInfo.addPythonButton(CyTranslator().getText("TXT_KEY_POPUP_GRAS", ()), "")
				popupInfo.addPythonButton(CyTranslator().getText("TXT_KEY_POPUP_EBENE", ()), "")
				popupInfo.addPythonButton(CyTranslator().getText("TXT_KEY_POPUP_WÜSTE", ()), "")
				popupInfo.addPythonButton(CyTranslator().getText("TXT_KEY_POPUP_TUNDRA", ()), "")
				popupInfo.addPythonButton(CyTranslator().getText("TXT_KEY_POPUP_SCHNEE", ()), "")
				popupInfo.addPopup(iPlayer)
###Ende Popup1
		if iImprovement == gc.getInfoTypeForString('IMPROVEMENT_LANDVERAENDERUNG'):
			pPlot.setImprovementType(-1)
##neu Alrik Beginn			
			if (pPlayer.isAlive() and pPlayer.isHuman()):
##neu Alrik Ende			
				CyCamera().JustLookAtPlot( CyMap().plot(iX, iY))
				popupInfo = CyPopupInfo()
				popupInfo.setButtonPopupType(ButtonPopupTypes.BUTTONPOPUP_PYTHON)
				popupInfo.setText(CyTranslator().getText("TXT_KEY_POPUP_SELECT_TERRAINTYPE",()))
				popupInfo.setData1(iPlayer)
				popupInfo.setData2(iX)
				popupInfo.setData3(iY)
				popupInfo.setOnClickedPythonCallback("SelectTerrainType")
				popupInfo.addPythonButton(CyTranslator().getText("TXT_KEY_POPUP_GRAS", ()), "")
				popupInfo.addPythonButton(CyTranslator().getText("TXT_KEY_POPUP_EBENE", ()), "")
				popupInfo.addPythonButton(CyTranslator().getText("TXT_KEY_POPUP_WÜSTE", ()), "")
				popupInfo.addPythonButton(CyTranslator().getText("TXT_KEY_POPUP_TUNDRA", ()), "")
				popupInfo.addPythonButton(CyTranslator().getText("TXT_KEY_POPUP_SCHNEE", ()), "")
				popupInfo.addPopup(iPlayer)
###Ende Popups
		if iImprovement == gc.getInfoTypeForString('IMPROVEMENT_LANDABTRAGUNG'):
			pPlot.setPlotType(PlotTypes.PLOT_OCEAN, True, True)
		    	pPlot.setImprovementType(-1)
		if iImprovement == gc.getInfoTypeForString('IMPROVEMENT_PLATTMACHEN'):
			pPlot.setPlotType(PlotTypes.PLOT_LAND, True, True)
		    	pPlot.setImprovementType(-1)
###Ende alles

# Aggriculture Mod
		# Purpose: Places a agricultural bonus on plot upon worker
		# completion of an improvement (Corn, Rice or Wheat)

		if (iImprovement == gc.getInfoTypeForString('IMPROVEMENT_CORN')) :
			pPlot.setImprovementType(-1)
			pPlot.setBonusType(gc.getInfoTypeForString("BONUS_CORN"))	
							CyInterface().addMessage(CyMap().plot(iX,iY).getOwner(),True,25,'Mais wurde gepflanzt!','AS2D_DISCOVERBONUS',1,'Art/Interface/Buttons/general/happy_person.dds',ColorTypes(8),iX,iY,False,False)

		if (iImprovement == gc.getInfoTypeForString('IMPROVEMENT_RICE')) :
			pPlot.setImprovementType(0)
			pPlot.setBonusType(gc.getInfoTypeForString("BONUS_RICE"))
						CyInterface().addMessage(CyMap().plot(iX,iY).getOwner(),True,25,'Reis wurde gepflanzt!','AS2D_DISCOVERBONUS',1,'Art/Interface/Buttons/general/happy_person.dds',ColorTypes(8),iX,iY,False,False)

		if (iImprovement == gc.getInfoTypeForString('IMPROVEMENT_WHEAT')) :
			pPlot.setImprovementType(0)
			pPlot.setBonusType(gc.getInfoTypeForString("BONUS_WHEAT"))
							CyInterface().addMessage(CyMap().plot(iX,iY).getOwner(),True,25,'Weizen wurde gepflanzt!','AS2D_DISCOVERBONUS',1,'Art/Interface/Buttons/general/happy_person.dds',ColorTypes(8),iX,iY,False,False)
# End Aggriculture Mod		
		
		if (not self.__LOG_IMPROVEMENT):
			return
		CvUtil.pyPrint('Improvement %s was built at %d, %d'
			%(PyInfo.ImprovementInfo(iImprovement).getDescription(), iX, iY))
 
Ok. I checked the codes and it seems to me, that the popup will only be shown to the owner of the plot, which would be ok, because the improvements can only be build in your own territory. It would be very nice if you could check the codes too, if I´m right or wrong.
Looks good. The important part was that you set iPlayer to the owner of the plot.
 
Hi,

I´ve tried to test the MP in my mod and right at the beginning I get OOS errors while founding a city. I believe it could be because of extended traits that I´ve added. Could you please have a look at them. The OOS came up with the traits creative and philosophical but I think it could be, that the others will cause OOS too in the later game.

The red lines could be the problematic things I believe, the green perhaps later in the game. Is this correct? Aren´t these informations synchronized of the game itself, so that the code will run on every machine with the same variables without ModNetMessages?

Code:
	def onCityBuilt(self, argsList):
		'City Built'
		city = argsList[0]
		iPlayer = city.getOwner()
		pPlayer = gc.getPlayer(city.getOwner())
		iTeam = pPlayer.getTeam()
		pTeam = gc.getTeam(iTeam)
## Traits ##
## Creative Trait ##
		if pPlayer.hasTrait(gc.getInfoTypeForString("TRAIT_CREATIVE")):
			FledgingInfo = gc.getCultureLevelInfo(gc.getInfoTypeForString("CULTURELEVEL_FLEDGLING"))
			[COLOR="Red"]city.changeCulture(iPlayer, FledgingInfo.getSpeedThreshold(CyGame().getGameSpeedType()), true)[/COLOR]
		
## Industrious Trait ##
		if pPlayer.hasTrait(gc.getInfoTypeForString("TRAIT_INDUSTRIOUS")):
			[COLOR="SeaGreen"]city.setBuildingYieldChange(gc.getInfoTypeForString("BUILDINGCLASS_FORGE"), YieldTypes.YIELD_PRODUCTION, 2)
			city.setBuildingYieldChange(gc.getInfoTypeForString("BUILDINGCLASS_FACTORY"), YieldTypes.YIELD_PRODUCTION, 2)
			city.setBuildingYieldChange(gc.getInfoTypeForString("BUILDINGCLASS_INDUSTRIAL_PARK"), YieldTypes.YIELD_PRODUCTION, 2)[/COLOR]
## Philosophical Trait Start ##
		if pPlayer.hasTrait(gc.getInfoTypeForString("TRAIT_PHILOSOPHICAL")) and city.isCapital():
			[COLOR="Red"]city.setNumRealBuilding(gc.getInfoTypeForString("BUILDING_DORMITORY"), 1)[/COLOR]
## Spiritual Trait ##
		if pPlayer.hasTrait(gc.getInfoTypeForString("TRAIT_SPIRITUAL")):
			iStateReligion = pPlayer.getStateReligion()
			if iStateReligion > -1:
				[COLOR="SeaGreen"]city.setHasReligion(iStateReligion,True,True,True)[/COLOR]
## Traits End ##
 
Ok. I solved the OOS when founding a city and tested several other parts of the mod. Almost everything worked fine, but I´ve one "problem". I´ve added some code for terraforming with a popup. This works fine and the popup is only shown to the player which has built the "improvement".

But in the code there is a line in which the plot is shown. This part works for every player, so when player A has built the improvement, the plot is shown to player B too, just without the popup. Could that be changed? Here is the code:

Code:
	def onImprovementBuilt(self, argsList):
		'Improvement Built'
		iImprovement, iX, iY = argsList
##neu Alrik Beginn
		pPlot = CyMap().plot(iX, iY)
		iPlayer = pPlot.getOwner()
		pPlayer = gc.getPlayer(iPlayer)		
		if iImprovement == gc.getInfoTypeForString('IMPROVEMENT_LANDAUFSCHUETTUNG'):
			pPlot.setPlotType(PlotTypes.PLOT_LAND, True, True)
			pPlot.setImprovementType(-1)
			if (pPlayer.isAlive() and pPlayer.isHuman()):
				[COLOR="Red"]CyCamera().JustLookAtPlot( CyMap().plot(iX, iY))[/COLOR]
				popupInfo = CyPopupInfo()
				popupInfo.setButtonPopupType(ButtonPopupTypes.BUTTONPOPUP_PYTHON)
				popupInfo.setText(CyTranslator().getText("TXT_KEY_POPUP_SELECT_TERRAINTYPE",()))
				popupInfo.setData1(iPlayer)
				popupInfo.setData2(iX)
				popupInfo.setData3(iY)
				popupInfo.setOnClickedPythonCallback("SelectTerrainType")
				popupInfo.addPythonButton(CyTranslator().getText("TXT_KEY_POPUP_GRAS", ()), "")
				popupInfo.addPythonButton(CyTranslator().getText("TXT_KEY_POPUP_EBENE", ()), "")
				popupInfo.addPythonButton(CyTranslator().getText("TXT_KEY_POPUP_WÜSTE", ()), "")
				popupInfo.addPythonButton(CyTranslator().getText("TXT_KEY_POPUP_TUNDRA", ()), "")
				popupInfo.addPythonButton(CyTranslator().getText("TXT_KEY_POPUP_SCHNEE", ()), "")
				popupInfo.addPopup(iPlayer)

A second thing is, that it´s possible to build land where coast was before with the code above. But when I have a city beside the plot, which is a coastal city before, and I change the terrain type for the only adjactent coastal plot, I would like to destroy harbour and lighthouse, if they are already built in this city. Is there any code which could do this?

Thanks again and good night.:)
 
Ok. I believe I can live with showing the plot to everyone.

For the second thing: The code is on the function onImprovementBuilt. How do I get from the plot where the improvment is build to the city to check if its still coastal?
 
Use a for loop to loop through 1 radius around the plot to see if there is any coastal city nearby.
Then do a check for that city. This will solve the issue for cities directly adjacent to the plot.

Once again, for the destroy building code, you have to take note of UBs rather than just "destroy lighthouse", I think I told you before.

However, take note that coastal cities which are "far away" from the plot may also be affected even if they are like 5 tiles away since the other 4 tiles may now become fresh water lake because the 5th tile was the only outlet of a narrow coastal route.
I guess you know what I mean, lazy to draw map.
 
Ok. I´ll try to make my first loop. :)

I remembered the thing with the unique buildings last night. So I´ll destroy them too.

I understand the thing with the fresh water lake. I see only two possibiltities for that problem:

1. Check all cities on the map if they are still coastal. In this case, I assume a code, oriented on the code of platyping´s Bell Rock Lighthouse would be the best.
2. Let this failure be like it is, because it´s not so common and the advantage wouldn´t be too big.

For number 1: Do you think this could be a problem regarding the performance, because usually we play on the biggest map possible with about 14 players (AI and human).
 
Shouldn't be hard to make a for loop like that.
Since you are using 80+ of mine, some of them do have loops like that, Helsinki Cathedral and Knossos Labyrinth are some of them.

However, if you are going to loop through every city on the map, then there is no need to do the for loop already, since the city loop will cover the city adjacent to the plot as well, since it covers ALL cities.

You are right that you have to loop through every city on the map, even those not belonging to plot owner, because it is possible that it may affect them as well.
As for performance, it depends on how often is this supposed to trigger?
Do you think there are going to be 20 plots being terraformed each turn for instance.
If so, you are gonna loop through 100 cities 20 times each turn.
And for each city that is no longer coastal, you are probably gonna loop through the whole list of buildings (close to 200?) just to check is the building present and then to remove it. Don't forget lighthouse and harbour are not the only coastal buildings. There are even some coastal wonders...
This will not be a big deal, since chance of this happening won't be that frequent.

The real question is, does AI know how to terraform at all, since this looks like python work to me.
 
But in the code there is a line in which the plot is shown. This part works for every player, so when player A has built the improvement, the plot is shown to player B too, just without the popup. Could that be changed?
Yes, do it like this:
Code:
if (iPlayer  == gc.getGame().getActivePlayer()):
  CyCamera().JustLookAtPlot( CyMap().plot(iX, iY))
 
Shouldn't be hard to make a for loop like that.
Since you are using 80+ of mine, some of them do have loops like that, Helsinki Cathedral and Knossos Labyrinth are some of them.

However, if you are going to loop through every city on the map, then there is no need to do the for loop already, since the city loop will cover the city adjacent to the plot as well, since it covers ALL cities.

You are right that you have to loop through every city on the map, even those not belonging to plot owner, because it is possible that it may affect them as well.
As for performance, it depends on how often is this supposed to trigger?
Do you think there are going to be 20 plots being terraformed each turn for instance.
If so, you are gonna loop through 100 cities 20 times each turn.
And for each city that is no longer coastal, you are probably gonna loop through the whole list of buildings (close to 200?) just to check is the building present and then to remove it. Don't forget lighthouse and harbour are not the only coastal buildings. There are even some coastal wonders...
This will not be a big deal, since chance of this happening won't be that frequent.

The real question is, does AI know how to terraform at all, since this looks like python work to me.

Ok. I´ve checked all the buildings in the mod and it seems that 20 are effected, wonders included. I believe it will be not as often, so I would like too loop through all cities. The AI doesn´t know how to use it, but we only play in MP and the focus is on the challenge between the human players, so it´s ok for us so far.


For the loop. Since now, I´ve only found loops which are looping through cities of a specific player. F.e. the Montreal Biodome of platyping:
Code:
		if pCity.getNumActiveBuilding(gc.getInfoTypeForString("BUILDING_MONTREAL_BIODOME")):
			(loopCity, iter) = pPlayer.firstCity(false)
			while(loopCity):
				loopCity.changeImprovementFreeSpecialists(gc.getInfoTypeForString("IMPROVEMENT_CAMP"), -1)
				(loopCity, iter) = pPlayer.nextCity(iter, false)

How do I loop through all cities on the map?

btw...would this kind of code above (Montreal Biodome) run on all computers in a MP game, like I hope, or will it cause an OOS?
It´s in the function onCityAcquired of the CvEventManager.py:
Code:
	def onCityAcquired(self, argsList):
		'City Acquired'
		iPreviousOwner,iNewOwner,pCity,bConquest,bTrade = argsList
		
		pPlayer = gc.getPlayer(iPreviousOwner)
 
How do I loop through all cities on the map?

Loop through every city of every player ;).

btw...would this kind of code above (Montreal Biodome) run on all computers in a MP game, like I hope, or will it cause an OOS?
It´s in the function onCityAcquired of the CvEventManager.py:

Since this doesn't require any user input, it should AFAIK not cause any OOS.
(but I've never really dealt with it, so I'd not bet on it)
 
Loop through every city of every player ;).

And how could I do this?:blush:

With a loop within a loop? First loop the players and inside of this the loop of the cities of each player?

For the loop of the cities of one player I´ve found serveral examples but not for looping through all players.
 
Thanks to both of you! I took the code of cure for cancer, since it was almost ready.

It worked for the lighthouse. :thumbsup:

Now I´ve only to add the other buildings.
 
Ok. I´ve added the buildings but I´ve a problem left. The Netherland Dike can be build if the city coastal or at a river. Even if it´s right that the city no more coastal it can be, that it´s still besides a river. In this case the dike shouln´t be destroyed.

Since I didn´t find any check like "if not city is coastal" for rivers, do you have any idea how I could realize the check?
 
Top Bottom