• Our friends from AlphaCentauri2.info are in need of technical assistance. If you have experience with the LAMP stack and some hours to spare, please help them out and post here.

Need help with ModNetMessage

Xyth

History Rewritten
Joined
Jul 14, 2004
Messages
4,106
Location
Aotearoa
A user of my mod has reported Out of Sync errors occurring when a religion is founded. This is the relevant section:

Code:
	def onGreatPersonBorn(self, argsList):
		'Unit Promoted'
		pUnit, iPlayer, pCity = argsList
		player = PyPlayer(iPlayer)

# BEGIN Founding Religions

		game = CyGame()
		pPlayer = gc.getPlayer(iPlayer)
		iUnitType = pUnit.getUnitType()
		iMaxCiv = gc.getGame().countCivPlayersEverAlive()
		iReligionCount = 0
		FoundRel = False

		if iPlayer > -1:
			#Is it a Great Prophet?
			if iUnitType == gc.getInfoTypeForString('UNIT_PROPHET'):
				# Skip dead players and barbarians
				if pPlayer.isAlive() and not pPlayer.isBarbarian():
					# Find out how many religions have been founded
					for ixReligion in range(gc.getNumReligionInfos()):
						# If the religion has not been founded
						if gc.getGame().isReligionFounded(ixReligion):
							iReligionCount = iReligionCount + 1

					# Number of religions founded cannot exceed number of players
					if iReligionCount < iMaxCiv:
						# Loop through all religions
						for iSlot in range(gc.getNumReligionInfos()):
							# Must be at least one religion slot available
							if not game.isReligionSlotTaken(iSlot):
								# Preconditions are met to found a religion.
								# If the active player is human
								if iPlayer == gc.getGame().getActivePlayer() and pPlayer.isHuman():
									# If Autoplay is running, let the game pick the religion.
									if( game.getAIAutoPlay() > 0 ):
										FoundRel = True
										break

									else:
										#Display the popup for the player to pick a religion
										popupInfo = CyPopupInfo()
										popupInfo.setButtonPopupType(ButtonPopupTypes.BUTTONPOPUP_FOUND_RELIGION)
										popupInfo.setData1(iSlot)
										popupInfo.addPopup(iPlayer)
										break

								else:
									# Not Human, so let the game pick the religion.
									#CyInterface().addImmediateMessage("Found a Religion", "")
									FoundRel = True
									break

					if FoundRel:
						# Get Civ's favorite religion or random choice if favorite religion is not available
						iFavourite = gc.getLeaderHeadInfo(pPlayer.getLeaderType()).getFavoriteReligion()

						if iFavourite > -1 and not CyGame().isReligionFounded(iFavourite):
							iNewReligion = iFavourite

						else:
							aeReligions = list()
							for i in range(gc.getNumReligionInfos()):
								if not CyGame().isReligionFounded(i):
									aeReligions.append(i)

							if len(aeReligions) > 0:
								iNewReligion = aeReligions[CyGame().getSorenRandNum(len(aeReligions), "AI pick religion")]
							else:
								iNewReligion = -1

						if iNewReligion != -1:
							# Found the religion
							#CyInterface().addImmediateMessage("Found Favorite Religion", "")
							pPlayer.foundReligion(iNewReligion, iSlot, True)

# END Founding Religions

		if pUnit.isNone() or pCity.isNone():
			return
		if (not self.__LOG_GREATPERSON):
			return
		CvUtil.pyPrint('A %s was born for %s in %s' %(pUnit.getName(), player.getCivilizationName(), pCity.getName()))

I was under the misguided impression that because I'd used the default religion selection dialog there wouldn't be any multiplayer problems. However, from researching and reviewing the help this forum has given me in the past it seems I need to get the dialog to "call modnetmessage instead of doing anything, and then the receiving callback should change the database."

While I understand the concept I have no idea how to do such a thing or what the required syntax would be. Could anyone help? Are there any tutorials or useful examples anywhere on how to do this?
 
This guide explains the "why" of this problem. I am sure that I recall seeing a guide explaining about modnetmessage, but I cannot find it anymore. I learned about this by examining the mod "Gods Of Old", which uses modnetmessage correctly in python. Both of my mods Fury Road and Dune Wars use modnetmessage; you may be able to pick it up from there also.
 
Thanks all, I think I've got it sussed now :)
 
you don't need ModNetMessage here, because BUTTONPOPUP_FOUND_RELIGION already sends the information to all clients (via CvMessageControl::getInstance().sendFoundReligion in OnOkClicked).
The Problem is the if else logic.

you need to change
Code:
if iPlayer == gc.getGame().getActivePlayer() and pPlayer.isHuman():
to
Code:
if pPlayer.isHuman():
    if iPlayer == gc.getGame().getActivePlayer():
that way the AI code is run only for actual AI players, not for human players who happen not to be the active player (which is a local condition and thus will get you out of sync)
 
that way the AI code is run only for actual AI players, not for human players who happen not to be the active player (which is a local condition and thus will get you out of sync)

Funny how it's utterly obvious once someone has pointed it out. Thanks!
 
Back
Top Bottom