[PYTHONCOMP] Civ4lerts: Alert messages about in game events

I haven't tried it yet and won't until sometime after next week, but my gut feeling is that it will probably work, and if it doesn't, the changes should be simple. There were no changes necessary for the last patch.
 
Officer Reene said:
@TheLopez

Will that apply to all .py changes in any mod that changes some py files or only this particular py mod :confused:

Only the ones that use Dr. Elmer's ini parsing code.
 
TheLopez said:
Only the ones that use Dr. Elmer's ini parsing code.


ah ok...thx
 
mikezang said:
Did you solve your problems?

Actually I abandoned my efforts to incorporate Dr Jiggle's design for the event manager. I couldn't understand it well enough to know how to incorporate other mods into my fused mod.

Instead, I created a modcomp "ExecutiveBriefing" that is invoked in the event manager by "onCityDoTurn" (see code herein). It provides staggered messages about various aspects of your cities.

Good luck with your coding!
Spocko

Code:
## ExecutiveBriefing by Spocko
## Inspired by Dr Jiggle's Civ4Lerts mod
##

from CvPythonExtensions import *
import CvUtil
import PyHelpers
import Popup as PyPopup
import CvCameraControls

# globals
gc = CyGlobalContext()

class ExecutiveBriefing:

	def onCityDoTurn(self, argsList):
		pCity = argsList[0]
		iPlayer = argsList[1]
		iturn = gc.getGame().getGameTurn()

		if ((not CyGame().isNetworkMultiPlayer()) and (pCity.getOwner() == CyGame().getActivePlayer()) and (not gc.getPlayer(iPlayer).isAnarchy())):

			# City is about to grow and not because of it finishing producing a unit (settler or worker) using food
			NoGrowthEmphasis = 5
			if ((pCity.getFoodTurnsLeft() == 1) and not pCity.isFoodProduction() and (not pCity.AI_isEmphasize(NoGrowthEmphasis))):
				CyInterface().addMessage(CyGame().getActivePlayer(),True,25,'%s will grow to size %s next turn...' %((pCity.getName()), (pCity.getPopulation() + 1)),'',1,'Art/Interface/Buttons/Units/Settler.dds',ColorTypes(8),pCity.getX(),pCity.getY(),True,True)

				# City is about to grow and, by doing so, create one too many unhealthy people
				if (pCity.goodHealth() <= pCity.badHealth(False)):
					CyInterface().addMessage(CyGame().getActivePlayer(),True,10,'%s will become unhealthy next turn...' %(pCity.getName()),'',1,'Art/Interface/Buttons/General/unhealthy_person.dds',ColorTypes(10),pCity.getX(),pCity.getY(),True,True)

				# City is about to grow and, by doing so, create one too many unhappy people
				if (pCity.happyLevel() <= pCity.unhappyLevel(0)):
					CyInterface().addMessage(CyGame().getActivePlayer(),True,10,'%s will become unhappy next turn...' %(pCity.getName()),'SND_CITY_REVOLT',1,'Art/Interface/Buttons/General/resistance.dds',ColorTypes(7),pCity.getX(),pCity.getY(),True,True)

			# Give a periodic status report on which cities are unhappy
			if ((iturn % 4) == 0):
				if (pCity.angryPopulation(0) > 0):
					CyInterface().addMessage(CyGame().getActivePlayer(),True,10,'The people of %s are angry!' %(pCity.getName()),'',1,'Art/Interface/Population Heads/angrycitizen.dds',ColorTypes(7),pCity.getX(),pCity.getY(),True,True)

			# Give a periodic status report on which cities are unhealthy
			if (((iturn + 1) % 4) == 0):
				if (pCity.healthRate(False, 0) < 0):
					CyInterface().addMessage(CyGame().getActivePlayer(),True,10,'The people of %s are not in good health!' %(pCity.getName()),'',1,'Art/Interface/Buttons/General/unhealthy_person.dds',ColorTypes(10),pCity.getX(),pCity.getY(),True,True)

			# Give a periodic status report on which cities have evenly split health/unhealthy (and the city is not about to grow - handled elsewhere)
			if ((iturn % 5) == 0):
				if ((pCity.getFoodTurnsLeft() != 1) and (pCity.goodHealth() == pCity.badHealth(0))):
					CyInterface().addMessage(CyGame().getActivePlayer(),True,10,'%s is half healthy, half unhealthy...' %(pCity.getName()),'',1,'Art/Interface/Buttons/General/unhealthy_person.dds',ColorTypes(13),pCity.getX(),pCity.getY(),True,True)

			# Give a periodic status report on which cities have evenly split happy/unhappy (and the city is not about to grow - handled elsewhere)
			if ((iturn +1 % 5) == 0):
				if ((pCity.getFoodTurnsLeft() != 1) and (pCity.happyLevel() == pCity.unhappyLevel(0))):
					CyInterface().addMessage(CyGame().getActivePlayer(),True,10,'%s is poised between happiness and unhappiness...' %(pCity.getName()),'',1,'Art/Interface/Buttons/General/resistance.dds',ColorTypes(12),pCity.getX(),pCity.getY(),True,True)

			# Give a periodic status report on which cities are either starving or close to it
			if (((iturn - 1) % 3) == 0):
				if (pCity.foodDifference(True) < 0):
					CyInterface().addMessage(CyGame().getActivePlayer(),True,10,'%s needs more food...' %(pCity.getName()),'',1,'Art/Interface/Symbols/Food/food05.dds',ColorTypes(7),pCity.getX(),pCity.getY(),True,True)

			# Give a periodic report on cities that have a long wait before finishing their current production
			if ((iturn % 20) == 0):
				if (pCity.getGeneralProductionTurnsLeft() > 30):
					CyInterface().addMessage(CyGame().getActivePlayer(),True,10,'%s needs %d turns to build a %s...' %(pCity.getName(),pCity.getGeneralProductionTurnsLeft(),pCity.getProductionName()),'',1,'Art/Interface/Symbols/Production/production05.dds',ColorTypes(78),pCity.getX(),pCity.getY(),True,True)

			# Give a periodic report on cities that are unproductive
			if ((iturn % 16) == 0):
				if ((pCity.getPopulation() > 3) and (pCity.getPopulation() > (pCity.getYieldRate(YieldTypes.YIELD_PRODUCTION)*1.5))):
					CyInterface().addMessage(CyGame().getActivePlayer(),True,10,'%s is woefully unproductive ( %s )...' %(pCity.getName(),pCity.getProductionName()),'',1,'Art/Interface/Symbols/Production/production05.dds',ColorTypes(11),pCity.getX(),pCity.getY(),True,True)

			# Give a periodic report on small cities that would benefit from Hurrying production
			if (((iturn + 1) % 7) == 0):
				civGovernment = gc.getPlayer(iPlayer).getCivics(0)
				civLabor = gc.getPlayer(iPlayer).getCivics(2)
				if (((civGovernment == gc.getInfoTypeForString('CIVIC_UNIVERSAL_SUFFRAGE')) or (civLabor == gc.getInfoTypeForString('CIVIC_SLAVERY'))) and ((pCity.getPopulation() < 4) and (pCity.getGeneralProductionTurnsLeft() > 30))):
					CyInterface().addMessage(CyGame().getActivePlayer(),True,10,'%s could use some hurry-up production for its %s...' %(pCity.getName(),pCity.getProductionName()),'',1,'Art/Interface/Symbols/Production/production05.dds',ColorTypes(11),pCity.getX(),pCity.getY(),True,True)

			# Give a periodic status report on which cities are set to emphasize NO GROWTH
			if (((iturn - 2) % 7) == 0):
				if (pCity.AI_isEmphasize(NoGrowthEmphasis)):
					CyInterface().addMessage(CyGame().getActivePlayer(),True,10,'The city governor of %s is emphasizing No Growth policies...' %(pCity.getName()),'',1,'Art/Interface/Buttons/Units/Settler.dds',ColorTypes(12),pCity.getX(),pCity.getY(),True,True)

			# Give a periodic report on cities that are not connected to the civ trade network
			if ((iturn % 9) == 0):
				if (not pCity.isConnectedToCapital(0)):
					CyInterface().addMessage(CyGame().getActivePlayer(),True,10,'%s is not connected to the capital city...' %(pCity.getName()),'',1,'Art/Interface/Buttons/Governor/commerce.dds',ColorTypes(13),pCity.getX(),pCity.getY(),True,True)

			# Give a periodic report on cities that have a long wait before growing
			if ((iturn % 15) == 0):
				if ((pCity.getFoodTurnsLeft() > 30) and not pCity.isFoodProduction() and (not pCity.AI_isEmphasize(NoGrowthEmphasis)) and (pCity.getPopulation() > 3) and (pCity.getPopulation() < 9)):
					CyInterface().addMessage(CyGame().getActivePlayer(),True,10,'%s needs %d turns to grow to size %d...' %(pCity.getName(),pCity.getFoodTurnsLeft(),(pCity.getPopulation() + 1)),'',1,'Art/Interface/Buttons/Units/Settler.dds',ColorTypes(7),pCity.getX(),pCity.getY(),True,True)





#			# Give a periodic report on small cities that would benefit from Hurrying production
#			if (((iturn + 1) % 7) == 0):
#				civGovernment = gc.getPlayer(iPlayer).getCivics(0)
#				civLabor = gc.getPlayer(iPlayer).getCivics(2)
#				if (((civGovernment == gc.getInfoTypeForString('CIVIC_POLICE_STATE')) or ( civGovernment == gc.getInfoTypeForString('CIVIC_UNIVERSAL_SUFFRAGE')) or (civLabor == gc.getInfoTypeForString('CIVIC_SLAVERY'))) and ((pCity.getPopulation() < 4) and (pCity.getGeneralProductionTurnsLeft() > 30))):
#					CyInterface().addMessage(CyGame().getActivePlayer(),True,10,'%s could use some hurry-up production for its %s...' %(pCity.getName(),pCity.getProductionName()),'',1,'Art/Interface/Symbols/Production/production05.dds',ColorTypes(11),pCity.getX(),pCity.getY(),True,True)
 
@Spocko

will that work in MP? :confused:

as I found out previously Civlerts will not :sad:

and I am still looking for something like Civlerts to add in my mod


also will it work with the vanilla version (not warlords expansion) of Civ4?

I still have not be able to upgrade my mod to warlords... so I could test it out in vanilla...(if compatable) and then when I upgrade to warlords I could do the same...... :mischief:
 
Hi,
I'm hoping to see this mod work on my games. I play single-player vanilla 1.61. I've seen zero alerts from this in hours of play. I've checked the location I unzipped the files & folders per the instructions:
In the paragraphs that follow, <userdir> refers to the user's personal Civilization 4 directory, typically C:\Documents and Settings\User\My Documents\My Games\Sid Meier's Civilization 4.
The civ4alert files seem present as well as their folders.
Is there a switch in the Civilizationiv.ini I need to enable as well, to permit this to run?
Thank you :)
[edit: Just as additional info, Civ is installed on my F: partition, not my system partition, if it matters.]
 
Caesium said:
@spocko: May I use your code above for my mod?
You certainly may. Keep in mind that some of the logic I borrowed from Dr Jiggle's code, so if you make this public, please give credit to Dr. Jiggle.

Spocko
 
Officer Reene said:
@Spocko

will that work in MP? :confused:

as I found out previously Civlerts will not :sad:

and I am still looking for something like Civlerts to add in my mod


also will it work with the vanilla version (not warlords expansion) of Civ4?

I still have not be able to upgrade my mod to warlords... so I could test it out in vanilla...(if compatable) and then when I upgrade to warlords I could do the same...... :mischief:

I've never played MP, so I don't know anything about the issues associated with modding for MP play. I can say that this class is referenced only once in the event manager, and that it does not alter gameplay (it only reports on existing conditions). And there's the code in the IF statement that reads "if ((not CyGame().isNetworkMultiPlayer())..." implying that this could be used in MP only if the IF statement was changed. It may be that the condition was placed there by Dr Jiggle because his code may not have been MP-ready and it may be that my statements are MP-ready, since they only check existing conditions and use no INI parsing.

This code, now in use with Warlords, is pretty much the same code I used for vanilla 1.61.

Good luck - I'll watch this thread.
Spocko
 
Spocko said:
I've never played MP, so I don't know anything about the issues associated with modding for MP play. I can say that this class is referenced only once in the event manager, and that it does not alter gameplay (it only reports on existing conditions). And there's the code in the IF statement that reads "if ((not CyGame().isNetworkMultiPlayer())..." implying that this could be used in MP only if the IF statement was changed. It may be that the condition was placed there by Dr Jiggle because his code may not have been MP-ready and it may be that my statements are MP-ready, since they only check existing conditions and use no INI parsing.

This code, now in use with Warlords, is pretty much the same code I used for vanilla 1.61.

Good luck - I'll watch this thread.
Spocko


Ok Ill test it... and tell you how it works.... :eek:


and if I use it in my mod.... I'll give you and the good doctor credit....

now where do place the code (specific file and line please :p )... and any specific instructions on installation.....? :mischief:
 
Officer Reene said:
Ok Ill test it... and tell you how it works.... :eek:

now where do place the code (specific file and line please :p )... and any specific instructions on installation.....? :mischief:

I've attached a zip file with ExecutiveBriefing.py and my event manager. Place ExecutiveBriefing.py into your mod's Assets/Python/ folder, and edit your mod's eventmanager as follows:

At the top, where you declare your Imports, include (without the quotes):

"import ExecutiveBriefing"

... and then just below that where you see assignments that look like "gc = CyGlobalContext()", etc., include the statement (without the quotes):

"eb = ExecutiveBriefing.ExecutiveBriefing()"

These two lines should be within the first dozen or so lines of your mod's eventmanager.

Here's how the top of my eventmanager looks:

Code:
## Sid Meier's Civilization 4
## Copyright Firaxis Games 2005
## 
## CvEventManager
## This class is passed an argsList from CvAppInterface.onEvent
## The argsList can contain anything from mouse location to key info
## The EVENTLIST that are being notified can be found 

from CvPythonExtensions import *
import CvUtil
import CvEventManager

import CvAdvisorUtils
import CvCameraControls
import CvDebugTools
import CvScreensInterface
import CvTechChooser
import CvTopCivs
import CvWBPopups
import CvWorldBuilderScreen
import Popup as PyPopup
import PyHelpers
import random
import sys

#INSERT IMPORTS
import ExecutiveBriefing

eb = ExecutiveBriefing.ExecutiveBriefing()
gc = CyGlobalContext()
...
Then, add one more statement that is to be invoked whenever the game calls "onCityDoTurn", which is every turn for every city in the game. Search your mod's eventmanager for "onCityDoTurn" and insert the code "eb.onCityDoTurn(argsList)" at some point in the block of code such that "eb.onCity..." will be called each time. My block of code looks like this:
Code:
	def onCityDoTurn(self, argsList):
		'City Production'
		self.parent.onCityDoTurn(self, argsList);
		#INSERT MODS
		eb.onCityDoTurn(argsList)
If these instructions are insufficient, let me know (you can pm me if you like). I'll help you as best I can. Much of this depends on how your mod's eventmanager file is structured...

I'm off now to continue my re-engineering of Religions and Civics. I'll check back either later this evening or sometime tomorrow evening. Good luck!

And be sure to back up your files before you dig in :)

Spocko

ps: As usual, I'm having tremendous difficulty using this forum to upload files, ZIPs are invalid, ACE's are invalid. So, you can copy the code I posted for ExecutiveBriefing http://forums.civfanatics.com/showpost.php?p=4365291&postcount=69 into a new file and name it ExecutiveBriefing.py. That code is the same as what I've tried to upload, and I've explained the significant points from my eventmanager. Sorry for this inconvenience - if you've been modding Civ4, these instructions should be workable; if you're new to modding, let me know and I'll work with you via PM or even direct email if you're willing (I can email you directly the two files I tried to upload). I will keep watching for your messages.
 
For uploading, I'm confused on how you are trying to upload your files. I go to the toolbar at the top of the pages and click on the 'Quick Links' tab and then pick the 'Upload File' option. This will allow you to upload zip, rar, ect file types.

You can also upload the file to the File Database, this also takes many different file extensions. :)
 
@Spocko


ok... I think I understand you (sorry I cay code python as well as I can fly in the air on my own :crazyeye: )... but I'll try it :goodjob:


due to my own beta testing requirements... I wont be able to test this till the end of next week (hopefully) when I start a new testing cycle and add this code :eek:

I'll PM u if I have any problems ....


....and report my progress...


One question... does your events "pop up" like the DR in the events log?
(I just want to know where to look for the changes :p )


thanks for all your help and patience with this noob modder! ;)
 
Jeckel said:
For uploading, I'm confused on how you are trying to upload your files. I go to the toolbar at the top of the pages and click on the 'Quick Links' tab and then pick the 'Upload File' option. This will allow you to upload zip, rar, ect file types.

You can also upload the file to the File Database, this also takes many different file extensions. :)

Thanks, Jeckel - I'll check this out during this week, if only to help Officer Reene (if he needs help that is...) :p
 
Top Bottom