adapt a script

I don't think there's a Python callback dealing with revolts directly. The CvCity functions doCulture and doPlotCulture do perform Python calls. The former is responsible for border expansion, the latter for culture spread to foreign tiles that will cause cities to flip. On the DLL side, doCulture looks like this (might be a bit different in K-Mod/ Realism Invictus):
Spoiler :
Code:
void CvCity::doCulture()
{
	CyCity* pyCity = new CyCity(this);
	CyArgsList argsList;
	argsList.add(gDLL->getPythonIFace()->makePythonObject(pyCity));	// pass in city class
	long lResult=0;
	gDLL->getPythonIFace()->callFunction(PYGameModule, "doCulture", argsList.makeFunctionArgs(), &lResult);
	delete pyCity;	// python fxn must not hold on to this pointer 
	if (lResult == 1)
	{
		return;
	}

	changeCultureTimes100(getOwnerINLINE(), getCommerceRateTimes100(COMMERCE_CULTURE), false, true);
}
Which means that, if the Python function doCulture returns the value 1, the (once per turn) increase in city culture does not take place. So something like
Code:
if pCity.getNameKey() == "TXT_KEY_CITY_NAME_MEMPHIS":
    return True
return False
might prevent a particular city from ever increasing its culture level. (True should correspond to an integer value of 1 in the DLL.)

Preventing doPlotCulture from adding culture to particular plots would be difficult to do through the Python callback. A different approach would be to periodically reset everyone's plot culture in the city plot to 0 – and I guess also in the inner ring of adjacent plots. Foreign plot culture is what causes revolts. (At least the kinds of revolts that can flip cities; spy revolts don't count in that context.) This could be done in any Python function that gets called at least once per turn. For convenience, I'd just try it in doCulture, right before the return True in the code snippet above. This will require two (nested) loops; one over the plots, one over the players. I can try to write those, but perhaps best to wait and see if this approach will work at all.

In the context of your scenario, there might also be an XML-only solution: Against revolts, you could try giving the city a free unit with a special promotion that grants a high iRevoltProtection value. For preventing border spread, perhaps all cultural building classes could be denied to the city owner through Civ4CivilizationInfos.xml, as is already (mostly) the case for CIVILIZATION_BARBARIAN. Could also try a Python approach against border spread and XML against revolts.

Lastly, I wonder if figuring out how to recompile the (Realism Invictus) DLL might not be less trouble for you than finetuning your Python solutions. I still assume (though I'm not certain) that movement across isthmuses could be cleanly implemented in the DLL by removing a few lines of code. Whereas the canal cities may still have a bunch of undesirable interactions with AI players; they might e.g. assign espionage points to the city owner or blockade them with Privateers. On the other hand, those remaining issues could all be minor (or Privateers even interesting), and the canal cities, in principle, allow the canals to be opened up (through Python) on some particular game turn, whereas passable isthmuses allow movement from the beginning.
 
the xml approach, it seems to me that it could work.
I was thinking if the phyton script could be made that every time the city is about to switch to another civilization, the next turn, the result is false , and therefore it remains with the owner, I don't know it could also be in the form of a custom event, limited only to that city. What do you think about it
like this, but obviously inserted into another event, with the right script
 

Attachments

  • Screenshot 2024-02-12 121439.jpg
    Screenshot 2024-02-12 121439.jpg
    84.2 KB · Views: 7
[...] every time the city is about to switch to another civilization, the next turn, the result is false [...]
Checking the city's foreign plot culture once per turn is easy to do. There is not a DLL-to-Python call right before the city will flip. Also, the functions for obtaining the revolt probability and number of prior revolts are not exposed to Python. So I could only picture a periodic test based on foreign plot culture. And telling the DLL pre-emptively not to let the city revolt is also not possible, I think. Preventing foreign plot culture from increasing past a certain point would seem like the most straightforward Python-based approach. Python also receives a call once the city actually changes hands. It might be possible to roll that ownership back immediately, but that'll probably lead to some strange side-effects, especially when the city flip will also kill the city owner's civilization.

Random event - don't know what that would be triggered by.
What do you think about it
like this, but obviously inserted into another event, with the right script
For the doCulture callback that might work, i.e. with
Code:
BugGameUtils.addHandler(doCulture)
in the init function. To prevent the city from ever gaining city culture. Also requires an XML value to be toggled in K-Mod (USE_DO_CULTURE_CALLBACK).
Or also if you want to identify particular cities in some other place, yes, getNameKey should work.
 
can it work like this? is it written well?
 

Attachments

  • Screenshot 2024-02-17 011548.png
    Screenshot 2024-02-17 011548.png
    43.8 KB · Views: 8
Looks reasonable. If the borders of the city no longer expand that way, then it probably works as intended.
 
hi I was thinking of inserting the city restriction, into the worldpeace script. can this work or did I do something wrong? Thank you
 

Attachments

  • city rescri.png
    city rescri.png
    54.2 KB · Views: 3
The only likely error I'm seeing is the missing return False at the end of cannotFoundCity. Well, it might even work without a return value; hard to say.
 
I added false, but it gives me an error, maybe I did something wrong
edit:

Now it works I had to delete "self". thx
 

Attachments

  • Screenshot 2024-02-23 012635.jpg
    Screenshot 2024-02-23 012635.jpg
    143.5 KB · Views: 3
  • Screenshot 2024-02-23 012340.jpg
    Screenshot 2024-02-23 012340.jpg
    65.4 KB · Views: 4
Last edited:
I'm trying to adapt spawnciv,
I tried to follow how you did for spawn unit. let's hope so
I also link the file
Thank you
I hope I did well:
##SpawnCivUtil
###MODDER READ THIS:
###You do not have to change anything in this file (only if you changed default terrain)
###all changes have to be done in the CvEventManager.
###This file has to be in the same folder like the CvEventManager.py.

from CvPythonExtensions import *
import sys
import pickle
gc = CyGlobalContext()
SpawnCivList = []
import BugEventManager
import BugPath

def init():
em = BugEventManager.g_eventManager
em.addEventHandler('LoadGame', loadCustomXML)
em.addEventHandler('GameStart', loadCustomXML)
em.addEventHandler('BeginGameTurn', onBeginGameTurn)

def onGameStart(self, argsList):
'Called at the start of the game'
###spawn a civ part 3 start###
MyFile=open("Mods/SpawnACiv_v2/Assets/XML/CustomXML/CIV4SpawnCivInfos.xml")
SpawnCivUtil.ReadMyFile(MyFile,DataPlotX,DataPlotY)
MyFile.close()
###spawn a civ part 3 end###
if (gc.getGame().getGameTurnYear() == gc.getDefineINT("START_YEAR") and not gc.getGame().isOption(GameOptionTypes.GAMEOPTION_ADVANCED_START)):
for iPlayer in range(gc.getMAX_PLAYERS()):
player = gc.getPlayer(iPlayer)
if (player.isAlive() and player.isHuman()):
popupInfo = CyPopupInfo()
popupInfo.setButtonPopupType(ButtonPopupTypes.BUTTONPOPUP_PYTHON_SCREEN)
popupInfo.setText(u"showDawnOfMan")
popupInfo.addPopup(iPlayer)
else:
CyInterface().setSoundSelectionReady(true)

if gc.getGame().isPbem():
for iPlayer in range(gc.getMAX_PLAYERS()):
player = gc.getPlayer(iPlayer)
if (player.isAlive() and player.isHuman()):
popupInfo = CyPopupInfo()
popupInfo.setButtonPopupType(ButtonPopupTypes.BUTTONPOPUP_DETAILS)
popupInfo.setOption1(true)
popupInfo.addPopup(iPlayer)

CvAdvisorUtils.resetNoLiberateCities()

def onBeginGameTurn(self, argsList):
'Called at the beginning of the end of each turn'
iGameTurn = argsList[0]
###spawn a civ part 6 start###
if gc.getMAX_CIV_PLAYERS ()>CyGame().countCivPlayersAlive ():
SpawnCivUtil.TriggerCiv(gc.getActivePlayer().getID(),None,DataPlotX,DataPlotY,iGameTurn)
###spawn a civ part 6 end###
CvTopCivs.CvTopCivs().turnChecker(iGameTurn)

def onEndPlayerTurn(self, argsList):
'Called at the end of a players turn'
iGameTurn, iPlayer = argsList

if (gc.getGame().getElapsedGameTurns() == 1):
if (gc.getPlayer(iPlayer).isHuman()):
if (gc.getPlayer(iPlayer).canRevolution(0)):
popupInfo = CyPopupInfo()
popupInfo.setButtonPopupType(ButtonPopupTypes.BUTTONPOPUP_CHANGECIVIC)
popupInfo.addPopup(iPlayer)

CvAdvisorUtils.resetAdvisorNags()
CvAdvisorUtils.endTurnFeats(iPlayer)

def process(iTurn):
for entry in SpawnCivList:
if entry.iTurn == iTurn:
AddCiv(entry)

def onFirstContact(self, argsList):
'Contact'
iTeamX,iHasMetTeamY = argsList
### spawn a civ - part 5 start
SpawnCivUtil.TestIfBarb(iTeamX,iHasMetTeamY)
### spawn a civ - part 5 end
if (not self.__LOG_CONTACT):
return
CvUtil.pyPrint('Team %d has met Team %d' %(iTeamX, iHasMetTeamY))

def onTechAcquired(self, argsList):
'Tech Acquired'
iTechType, iTeam, iPlayer, bAnnounce = argsList
# Note that iPlayer may be NULL (-1) and not a refer to a player object

# Show tech splash when applicable
if (iPlayer > -1 and bAnnounce and not CyInterface().noTechSplash()):
if (gc.getGame().isFinalInitialized() and not gc.getGame().GetWorldBuilderMode()):
if ((not gc.getGame().isNetworkMultiPlayer()) and (iPlayer == gc.getGame().getActivePlayer())):
popupInfo = CyPopupInfo()
popupInfo.setButtonPopupType(ButtonPopupTypes.BUTTONPOPUP_PYTHON_SCREEN)
popupInfo.setData1(iTechType)
popupInfo.setText(u"showTechSplash")
popupInfo.addPopup(iPlayer)
###spawn a civ part 4 start###
if gc.getMAX_CIV_PLAYERS ()>CyGame().countCivPlayersAlive ():
SpawnCivUtil.TriggerCiv(iPlayer,iTechType,DataPlotX,DataPlotY,None)
###spawn a civ part 4 end###



if (not self.__LOG_TECH):
return
CvUtil.pyPrint('%s was finished by Team %d'
%(PyInfo.TechnologyInfo(iTechType).getDescription(), iTeam))

def TriggerCiv(iPlayer,iTechType,DataPlotX,DataPlotY,iTurn):
PopList = []
for i in xrange(len(SpawnCivList)):
Spawned = SpawnACiv(SpawnCivList,i,iPlayer,iTechType,iTurn)
if Spawned:
PopList.append(SpawnCivList)
iMaxLoadCiv = len(SpawnCivList)
bListSpawnedCiv = []
for j in range(iMaxLoadCiv):
bListSpawnedCiv.append(SpawnCivList[j].AlreadyTriggered)
DataPlot = CyMap().plot(DataPlotX,DataPlotY)
DataPlot.setScriptData(pickle.dumps(bListSpawnedCiv))

###obsolete
#for i in xrange(len(PopList),0,1):
#SpawnCivList.pop(PopList)


def SpawnACiv(SpawnCiv,ListNum,iPlayer,iTechType,iTurn):
###Test if right tech###
Tech = SpawnCiv.SpawnTech
iHumanTech = SpawnCiv.SpawnTechHumanOnly
bHumanTech = False
#CyInterface().addMessage(0,False,15,"entered code",()),'',0,'Art/Interface/Buttons/General/happy_person.dds',ColorTypes(44), 1, 1, True,True)
if iTechType:
if not ((iTechType ==gc.getInfoTypeForString(Tech)) or (iTechType == gc.getInfoTypeForString(iHumanTech))):
return
if iTechType == gc.getInfoTypeForString(iHumanTech):
bHumanTech = True
if not gc.getPlayer(iPlayer).isHuman():
return
TechCounter=0
for i in xrange (gc.getMAX_CIV_TEAMS ()):
Team = gc.getTeam(i)
if Team.isHasTech(iTechType):
TechCounter=TechCounter+1
if TechCounter>=SpawnCiv.SpawnTechNumber:
break

if (not TechCounter>=SpawnCiv.SpawnTechNumber) and (not bHumanTech):
return

if iTurn:
#CyInterface().addMessage(0,False,15,str(CyGameTextMgr().getDateStr (iTurn+1, False, CyGame().getCalendar (), CyGame().getStartYear (), CyGame().getGameSpeedType ())),'',0,'Art/Interface/Buttons/General/happy_person.dds',ColorTypes(44), 1, 1, True,True)
if not ((iTurn+1 == SpawnCiv.iTurn) or (str(CyGame().getTurnYear(iTurn+1))==SpawnCiv.iYear)):
return
if (str(CyGame().getTurnYear(iTurn+1))==SpawnCiv.iYear):
if SpawnCiv.iMonth>0 and SpawnCiv.iMonth<13:
strDate = CyGameTextMgr().getDateStr (iTurn+1, False, CyGame().getCalendar (), CyGame().getStartYear (), CyGame().getGameSpeedType ())
if "," in strDate:
month, junk = strDate.split(",",1)
month = month.strip()
sMonth = gc.getMonthInfo(SpawnCiv.iMonth-1).getDescription()
if not sMonth in month:
return


if SpawnCiv.AlreadyTriggered:
return
###test, if right number of civs have tech


SpawningChance = CyGame().getSorenRandNum(100, "HowGoodIsTheChance")
if SpawningChance>SpawnCiv.SpawnChance:
SpawnCiv.AlreadyTriggered = True
return
###test, if spawn civ is not already alive
for i in xrange (gc.getMAX_CIV_PLAYERS ()):
pPlayer = gc.getPlayer(i)
myName = pPlayer.getCivilizationType ()
otherName = gc.getInfoTypeForString(SpawnCiv.CivString)
if myName ==otherName:
return
###Find a ID for the civ###

NewID = -1
for NumCiv in xrange (gc.getMAX_PLAYERS ()):
PotPlayer = gc.getPlayer(NumCiv)
if not PotPlayer.isAlive():
NewID = NumCiv
break
if NewID ==-1:
return
###Add Civ to game
iCiv = gc.getInfoTypeForString(SpawnCiv.CivString)
if not str(SpawnCiv.LeaderString)=="-1":
NewLeaderID=gc.getInfoTypeForString(SpawnCiv.LeaderString)
if str(SpawnCiv.LeaderString)=="-1":

CurCiv = gc.getCivilizationInfo(iCiv)
NumLeaders = CurCiv.getNumLeaders ()
dice = gc.getGame().getMapRand()
LeaderNum = dice.get(NumLeaders , "OracleSayMeTheLeader" )
LeaderCounter=0
for iLeaders in range(gc.getNumLeaderHeadInfos ()):
if CurCiv.isLeaders(iLeaders):
if NumLeaders==1:
NewLeaderID =iLeaders
break
else:
if LeaderCounter==LeaderNum:
NewLeaderID=iLeaders
break
LeaderCounter=LeaderCounter+1
CyGame().addPlayer(NewID,NewLeaderID,iCiv)
NewPlayer = gc.getPlayer(NewID)
NewTeam = gc.getTeam(NewPlayer.getTeam())
NewTeamID = NewTeam.getID()

###from an old version, may be reactived later, you never
###now; declareWar is custom function in this file, not used
###at the moment
### function testIfBarb is current version
#declareWar(NewID,SpawnCiv)
#if SpawnCiv.bBarb==True:
#MaxCivs = gc.getMAX_CIV_TEAMS()
#for i in xrange (MaxCivs):
#if i==NewTeamID:continue
#NewTeam.setPermanentWarPeace(i,True)
maxX = CyMap().getGridWidth ()
maxY = CyMap().getGridHeight ()
iTundra = gc.getInfoTypeForString("TERRAIN_TUNDRA")
iDesert = gc.getInfoTypeForString("TERRAIN_DESERT")
iSnow = gc.getInfoTypeForString("TERRAIN_SNOW")
NumSetCities = 0
Counter=0
NewPlayer.setGold(SpawnCiv.Gold)
if SpawnCiv.SpawnX>-1 and SpawnCiv.SpawnY>-1:
if SpawnCiv.SpawnX<CyMap().getGridWidth () and SpawnCiv.SpawnY<CyMap().getGridHeight ():
pPlot = CyMap().plot(SpawnCiv.SpawnX,SpawnCiv.SpawnY)
if not pPlot.isCity():
numUnits = pPlot.getNumUnits ()
for iUnits in xrange(numUnits):
pUnit = pPlot.getUnit(iUnits)
UnitX = pUnit.getX()
UnitY = pUnit.getY()
NewPlot = CyMap().plot(UnitX+1,UnitY+1)
if not NewPlot.isNone() and not NewPlot.isCity():
pUnit.setXY(UnitX+1,UnitY+1,True,True,True)
elif not CyMap().plot(UnitX-1,UnitY-1).isNone() and not CyMap().plot(UnitX-1,UnitY-1).isCity():
pUnit.setXY(UnitX-1,UnitY-1,True,True,True)
elif not CyMap().plot(UnitX+1,UnitY-1).isNone() and not CyMap().plot(UnitX+1,UnitY-1).isCity():
pUnit.setXY(UnitX+1,UnitY-1,True,True,True)
elif not CyMap().plot(UnitX-1,UnitY+1).isNone() and not CyMap().plot(UnitX-1,UnitY+1).isCity():
pUnit.setXY(UnitX-1,UnitY+1,True,True,True)

NewPlayer.initCity(SpawnCiv.SpawnX,SpawnCiv.SpawnY)
NumSetCities = NumSetCities+1
AddTechToPlayer(iPlayer,NewID,SpawnCiv.TechPercent)
AddUnitsToCity(SpawnCiv.SpawnX,SpawnCiv.SpawnY,NewID,SpawnCiv)

while NumSetCities <SpawnCiv.NumCities:
EndangeredPlot = []
CrapPlot = []
SetCity = False
Counter=Counter+1
Endangered = False
if Counter>100:return
if Counter>SpawnCiv.NumCities:return
for iX in xrange (maxX):
for iY in xrange(maxY):
pPlot = CyMap().plot(iX,iY)
if pPlot.isWater() or pPlot.isImpassable():
continue
if pPlot.isOwned():
continue
if pPlot.isUnit():
continue
if SpawnCiv.bCoast:
if not pPlot.isCoastalLand ():
continue
if (pPlot.getTerrainType ()==iDesert) or(pPlot.getTerrainType()==iSnow)or(pPlot.getTerrainType()==iTundra):
CrapPlot.append([pPlot.getX(),pPlot.getY()])
continue
if pPlot.isAdjacentOwned ():
continue

IsCity = checkCity(iX,iY)
if IsCity:continue
for iXLoop in xrange(iX - 2, iX + 3, 1):
for iYLoop in xrange(iY - 2, iY + 3, 1):
TempPlot = CyMap().plot(iXLoop,iYLoop)
if TempPlot.isOwned() or TempPlot.isUnit():
EndangeredPlot.append([pPlot.getX(),pPlot.getY()])
Endangered = True
break
if (Endangered == False):
NewPlayer.initCity(iX,iY)
NumSetCities = NumSetCities+1
SetCity = True
AddTechToPlayer(iPlayer,NewID,SpawnCiv.TechPercent)
AddUnitsToCity(iX,iY,NewID,SpawnCiv)
break

if SetCity ==False:
if len(EndangeredPlot)>0:
iRandPlot = CyGame().getSorenRandNum(len(EndangeredPlot), 'EndangeredPlot')
RandPlot = EndangeredPlot[iRandPlot]
CityX=RandPlot[0]
CityY=RandPlot[1]
NewPlayer.initCity(CityX,CityY)
NumSetCities = NumSetCities+1
AddTechToPlayer(iPlayer,NewID,SpawnCiv.TechPercent)
AddUnitsToCity(CityX,CityY,NewID,SpawnCiv)
elif len(CrapPlot)>0:
iRandPlot = CyGame().getSorenRandNum(len(CrapPlot), 'Crap Plot')
RandPlot = EndangeredPlot[iRandPlot]
CityX=RandPlot[0]
CityY=RandPlot[1]
NewPlayer.initCity(CityX,CityY)
NumSetCities = NumSetCities+1
AddTechToPlayer(iPlayer,NewID,SpawnCiv.TechPercent)
AddUnitsToCity(CityX,CityY,NewID,SpawnCiv)
if SetCity == True:
AddUnitsToCapital(NewID,SpawnCiv)
SpawnCiv.AlreadyTriggered = True
return True

###function should be obsolete
###not used at the moment
### function testIfBarb is current version
def declareWar(iPlayer,SpawnCiv):
if SpawnCiv.bBarb==True:
NewPlayer = gc.getPlayer(iPlayer)
TeamID = NewPlayer.getTeam()
NewTeam = gc.getTeam(TeamID)
for i in xrange(gc.getMAX_CIV_TEAMS ()):
if i==TeamID:continue
NewTeam.declareWar(i,False,WarPlanTypes.WARPLAN_TOTAL)
CurTeam = gc.getTeam(i)
CurTeam.declareWar(TeamID,False,WarPlanTypes.WARPLAN_TOTAL)
for i in range(gc.getMAX_CIV_PLAYERS()):
if i==iPlayer:continue
NewPlayer.AI_setAttitudeExtra(i,-999)
CurPlayer = gc.getPlayer(i)
CurPlayer.AI_setAttitudeExtra(iPlayer,-999)



def AddTechToPlayer(iPlayer,iNewPlayer,TechPercent):
pPlayer = gc.getPlayer(iPlayer)
pTeam = gc.getTeam(pPlayer.getTeam())
NewPlayer = gc.getPlayer(iNewPlayer)
NewTeam = gc.getTeam(NewPlayer.getTeam())
TechPercent = float(TechPercent)/100
TotalTechCounter=0
GridWidth=0
for i in xrange(gc.getNumTechInfos ()):
if pTeam.isHasTech(i):
TotalTechCounter=TotalTechCounter+1
CurTech= gc.getTechInfo(i)
if CurTech.getGridX()>GridWidth:
GridWidth=CurTech.getGridX()
TotalTechCounter=int(TotalTechCounter*TechPercent)
TempTechCounter=0
#CyInterface().addMessage(0,False,15,CyTranslator().getText(str(TotalTechCounter),()),'',0,'Art/Interface/Buttons/General/happy_person.dds',ColorTypes(44), 1, 1, True,True)
for j in xrange(GridWidth):
for i in xrange(gc.getNumTechInfos ()):
CurTech= gc.getTechInfo(i)
if pTeam.isHasTech(i):
if CurTech.getGridX()==j:
NewTeam.setHasTech(i,True,iNewPlayer,False,False)
TempTechCounter=TempTechCounter+1
if TempTechCounter>=TotalTechCounter:
break
if TempTechCounter>=TotalTechCounter:
break


def AddUnitsToCapital(iNewID,SpawnCiv):
pPlayer = gc.getPlayer(iNewID)
Capital = pPlayer.getCapitalCity()
iX = Capital.getX()
iY = Capital.getY()
if SpawnCiv.CapitalUnit !="NONE" and SpawnCiv.CapitalUnit !=-1:
if SpawnCiv.NumberCapitalUnit>0:
for i in xrange(SpawnCiv.NumberCapitalUnit):
pPlayer.initUnit( gc.getInfoTypeForString(SpawnCiv.CapitalUnit), iX,iY, UnitAITypes.NO_UNITAI, DirectionTypes.NO_DIRECTION )

def AddUnitsToCity(iX,iY,iNewPlayer,SpawnCiv):
NewPlayer = gc.getPlayer(iNewPlayer)
if SpawnCiv.NumWorker>0:
for i in xrange(SpawnCiv.NumWorker):
NewPlayer.initUnit( gc.getInfoTypeForString("UNIT_WORKER"), iX,iY, UnitAITypes.UNITAI_WORKER, DirectionTypes.NO_DIRECTION )
pCity = CyMap().plot(iX,iY).getPlotCity()
if SpawnCiv.DefenderUnit !="NONE":
if SpawnCiv.DefenderUnit=="-1":
Defender = pCity.getConscriptUnit ()
else:
Defender = gc.getInfoTypeForString(SpawnCiv.DefenderUnit)
if SpawnCiv.NumberDefenderUnit>0:
for i in xrange(SpawnCiv.NumberDefenderUnit):
NewPlayer.initUnit( Defender, iX,iY, UnitAITypes.NO_UNITAI, DirectionTypes.NO_DIRECTION )
if SpawnCiv.SecondUnit !="NONE":
if SpawnCiv.SecondUnit=="-1":
Second = pCity.getConscriptUnit ()
else:
Second = gc.getInfoTypeForString(SpawnCiv.SecondUnit)
if SpawnCiv.NumSecondUnit>0:
for i in xrange(SpawnCiv.NumSecondUnit):
NewPlayer.initUnit( Second, iX,iY, UnitAITypes.NO_UNITAI, DirectionTypes.NO_DIRECTION )
if pCity.isCoastal(20):
if ((not SpawnCiv.Ships=="-1")and(not SpawnCiv.Ships=="NONE")) and (not SpawnCiv.NumberShips<1):
ThisShip = SpawnCiv.Ships
CurShip = gc.getInfoTypeForString(ThisShip)
NumShip = SpawnCiv.NumberShips
for i in xrange(NumShip):
NewPlayer.initUnit( CurShip, iX,iY, UnitAITypes.NO_UNITAI, DirectionTypes.NO_DIRECTION )


def checkCity(iX,iY):
for iXLoop in xrange(iX - 2, iX + 3, 1):
for iYLoop in xrange(iY - 2, iY + 3, 1):
TempPlot = CyMap().plot(iXLoop,iYLoop)
if TempPlot.isCity():return True
return False

def ReadMyFile(MyFile,DataPlotX,DataPlotY):
del SpawnCivList[:]
for CurString in MyFile.readlines():
if "CIVILIZATION_" in CurString:
CurCiv = SpawningCiv()
CurCiv.CivString = CutString(CurString)
elif "Leader" in CurString:
CurCiv.LeaderString = CutString(CurString)
elif "SpawnTech>" in CurString:
CurCiv.SpawnTech = CutString(CurString)
elif "NumberOfSpawnTech" in CurString:
CurCiv.SpawnTechNumber = int(CutString(CurString))
elif "SpawnTechHumanOnly" in CurString:
CurCiv.SpawnTechHumanOnly = CutString(CurString)
elif "iTurn" in CurString:
CurCiv.iTurn = int(CutString(CurString))
elif "iYear" in CurString:
CurCiv.iYear = CutString(CurString)
elif "iMonth" in CurString:
CurCiv.iMonth = int(CutString(CurString))
elif "SpawnChance" in CurString:
CurCiv.SpawnChance = float(CutString(CurString))
elif "IsBarbarianCiv" in CurString:
CuttedString = CutString(CurString)
CurCiv.bBarb = bool(eval(CuttedString))
elif "StartAtCoast" in CurString:
CuttedString = CutString(CurString)
CurCiv.bCoast = bool(eval(CuttedString))
elif "TotalGold" in CurString:
CurCiv.Gold = int(CutString(CurString))
elif "TechPercent" in CurString:
CurCiv.TechPercent =int(CutString(CurString))
elif "DefaultShips" in CurString:
CurCiv.Ships = CutString(CurString)
elif "NumberShipsPerCity" in CurString:
CurCiv.NumberShips = int(CutString(CurString))
elif "NumberOfCities" in CurString:
CurCiv.NumCities = int(CutString(CurString))
elif "StartX" in CurString:
CurCiv.SpawnX = int(CutString(CurString))
elif "StartY" in CurString:
CurCiv.SpawnY = int(CutString(CurString))
elif "NumWorkerPerCity" in CurString:
CurCiv.NumWorker = int(CutString(CurString))
elif "CapitalCityUnit" in CurString:
CurCiv.CapitalUnit = CutString(CurString)
elif "NumCapitalUnit" in CurString:
CurCiv.NumberCapitalUnit = int(CutString(CurString))
elif "DefaultCityDefender" in CurString:
CurCiv.DefenderUnit = CutString(CurString)
elif "NumberCityDefendersPerCity" in CurString:
CurCiv.NumberDefenderUnit = int(CutString(CurString))
elif "DefaultSecondUnit" in CurString:
CurCiv.SecondUnit = CutString(CurString)
elif "NumberSecondUnit" in CurString:
CurCiv.NumSecondUnit = int(CutString(CurString))
SpawnCivList.append(CurCiv)
AddCivAlreadySpawnedInfo(SpawnCivList,DataPlotX,DataPlotY)

def AddCivAlreadySpawnedInfo(SpawnCivList,DataPlotX,DataPlotY):
DataPlot = CyMap().plot(DataPlotX,DataPlotY)
bListSpawnedCiv = pickle.loads(DataPlot.getScriptData ())
iMaxLoadCiv = len(SpawnCivList)
if len(bListSpawnedCiv)>0:
for i in range (iMaxLoadCiv):
SpawnCivList.AlreadyTriggered = bListSpawnedCiv

def TestIfBarb(iTeamX,iHasMetTeamY):
if iTeamX == iHasMetTeamY:
return False
TeamOne = gc.getTeam(iTeamX)
TeamTwo = gc.getTeam(iHasMetTeamY)
pPlayerOne = gc.getPlayer(TeamOne.getLeaderID())
pPlayerTwo = gc.getPlayer(TeamTwo.getLeaderID())
iLenSpawnCiv = len(SpawnCivList)
for i in range(iLenSpawnCiv):
if SpawnCivList.bBarb:
if (gc.getInfoTypeForString(SpawnCivList.CivString)== pPlayerOne.getCivilizationType () ):
TeamOne.declareWar(iHasMetTeamY,False,WarPlanTypes.WARPLAN_TOTAL)
TeamOne.setPermanentWarPeace(iHasMetTeamY,True)
elif (gc.getInfoTypeForString(SpawnCivList.CivString)== pPlayerTwo.getCivilizationType () ):
TeamTwo.declareWar(iTeamX,False,WarPlanTypes.WARPLAN_TOTAL)
TeamTwo.setPermanentWarPeace(iTeamX,True)

def CutString(string):
string = str(string)
string = string.strip()
string = string[2:-1]
BeginPos=-1
EndPos = -1
for i in xrange(len(string)):
if string==">":
BeginPos=i
elif string=="<":
EndPos=i
break
else:
return "-1"
NewString = string[BeginPos+1:EndPos]
return str(NewString)

class SpawningCiv:
def __init__(self):
self.CivString = 0
self.LeaderString = 0
self.SpawnTech = 0
self.SpawnTechHumanOnly = 0
self.SpawnTechNumber = 0
self.iTurn = 0
self.iYear = 0
self.iMonth = 0
self.SpawnChance = 0
self.bCoast = 0
self.Ships = 0
self.NumberShips = 0
self.bBarb = 0
self.NumCities = 0
self.SpawnX = 0
self.SpawnY = 0
self.CapitalUnit = 0
self.NumberCapitalUnit = 0
self.DefenderUnit = 0
self.NumberDefenderUnit = 0
self.NumWorker=0
self.Gold = 0
self.SecondUnit=0
self.NumSecondUnit=0
self.TechPercent=0
self.AlreadyTriggered = False
 

Attachments

  • SpawnCivUtil.rar
    5.6 KB · Views: 1
You'll also need to add the onFirstContact and onTechAcquired handlers to the BugEventManager. If loadCustomXML is supposed to handle GameStart and LoadGame, then onGameStart will need to be renamed to loadCustomXML. In the definitions of the handler functions ("on..."), you need to lose the self arguments because these functions don't belong to a class anymore (you've moved them away from CvEventManager). Moreover, the handler functions should only contain the code for unpacking the argsList (if any) and the code added by the mod ("spawn a civ part ..."). The rest, e.g. showing the DawnOfManscreen, will be handled by the original CvEventManager (if your mod doesn't contain a copy of that file, then the BtS version gets used). If you do copy that code, it'll run twice. Copying onEndPlayerTurn is harmless (so long as you don't register the copied version), but also unnecessary. The
Code:
DataPlotX = 3
DataPlotY = 3
definition seems to have been lost; should be somewhere near the top of the file. I don't think the "process" function is needed for anything. Your current code never calls it, and there is no AddCiv function. There is AddCivAlreadySpawnedInfo, and The_J's code seems to call that as necessary.
 
Well, with the changes, I don't understand the part
The rest, e.g. showing the DawnOfManscreen, will be handled by the original CvEventManager (if your mod doesn't contain a copy of that file, then the BtS version gets used). If you do copy that code, it'll run twice.

##SpawnCivUtil
###MODDER READ THIS:
###You do not have to change anything in this file (only if you changed default terrain)
###all changes have to be done in the CvEventManager.
###This file has to be in the same folder like the CvEventManager.py.

from CvPythonExtensions import *
import sys
import pickle
gc = CyGlobalContext()
SpawnCivList = []
import BugEventManager
import BugPath

def init():
em = BugEventManager.g_eventManager
em.addEventHandler('LoadGame', loadCustomXML)
em.addEventHandler('GameStart', loadCustomXML)
em.addEventHandler('BeginGameTurn', onBeginGameTurn)
em.addEventHandler('FirstContact', onFirstContact)
em.addEventHandler('TechAcquired', onTechAcquired)

def loadCustomXML(argsList):
'Called at the start of the game'
###spawn a civ part 3 start###
MyFile=open("Mods/SpawnACiv_v2/Assets/XML/CustomXML/CIV4SpawnCivInfos.xml")
SpawnCivUtil.ReadMyFile(MyFile,DataPlotX,DataPlotY)
MyFile.close()
###spawn a civ part 3 end###
if (gc.getGame().getGameTurnYear() == gc.getDefineINT("START_YEAR") and not gc.getGame().isOption(GameOptionTypes.GAMEOPTION_ADVANCED_START)):
for iPlayer in range(gc.getMAX_PLAYERS()):
player = gc.getPlayer(iPlayer)
if (player.isAlive() and player.isHuman()):
popupInfo = CyPopupInfo()

if gc.getGame().isPbem():
for iPlayer in range(gc.getMAX_PLAYERS()):
player = gc.getPlayer(iPlayer)
if (player.isAlive() and player.isHuman()):
popupInfo = CyPopupInfo()
popupInfo.setButtonPopupType(ButtonPopupTypes.BUTTONPOPUP_DETAILS)
popupInfo.setOption1(true)
popupInfo.addPopup(iPlayer)

CvAdvisorUtils.resetNoLiberateCities()

def onBeginGameTurn(argsList):
'Called at the beginning of the end of each turn'
iGameTurn = argsList[0]
###spawn a civ part 6 start###
if gc.getMAX_CIV_PLAYERS ()>CyGame().countCivPlayersAlive ():
SpawnCivUtil.TriggerCiv(gc.getActivePlayer().getID(),None,DataPlotX,DataPlotY,iGameTurn)
###spawn a civ part 6 end###
CvTopCivs.CvTopCivs().turnChecker(iGameTurn)

def onFirstContact(argsList):
'Contact'
iTeamX,iHasMetTeamY = argsList
### spawn a civ - part 5 start
SpawnCivUtil.TestIfBarb(iTeamX,iHasMetTeamY)
### spawn a civ - part 5 end
if (not self.__LOG_CONTACT):
return
CvUtil.pyPrint('Team %d has met Team %d' %(iTeamX, iHasMetTeamY))

def onTechAcquired(argsList):
'Tech Acquired'
iTechType, iTeam, iPlayer, bAnnounce = argsList
# Note that iPlayer may be NULL (-1) and not a refer to a player object

# Show tech splash when applicable
if (iPlayer > -1 and bAnnounce and not CyInterface().noTechSplash()):
if (gc.getGame().isFinalInitialized() and not gc.getGame().GetWorldBuilderMode()):
if ((not gc.getGame().isNetworkMultiPlayer()) and (iPlayer == gc.getGame().getActivePlayer())):
popupInfo = CyPopupInfo()
popupInfo.setButtonPopupType(ButtonPopupTypes.BUTTONPOPUP_PYTHON_SCREEN)
popupInfo.setData1(iTechType)
popupInfo.setText(u"showTechSplash")
popupInfo.addPopup(iPlayer)
###spawn a civ part 4 start###
if gc.getMAX_CIV_PLAYERS ()>CyGame().countCivPlayersAlive ():
SpawnCivUtil.TriggerCiv(iPlayer,iTechType,DataPlotX,DataPlotY,None)
###spawn a civ part 4 end###



if (not self.__LOG_TECH):
return
CvUtil.pyPrint('%s was finished by Team %d'
%(PyInfo.TechnologyInfo(iTechType).getDescription(), iTeam))

def TriggerCiv(iPlayer,iTechType,DataPlotX,DataPlotY,iTurn):
PopList = []
for i in xrange(len(SpawnCivList)):
Spawned = SpawnACiv(SpawnCivList,i,iPlayer,iTechType,iTurn)
if Spawned:
PopList.append(SpawnCivList)
iMaxLoadCiv = len(SpawnCivList)
bListSpawnedCiv = []
for j in range(iMaxLoadCiv):
bListSpawnedCiv.append(SpawnCivList[j].AlreadyTriggered)
DataPlot = CyMap().plot(DataPlotX,DataPlotY)
DataPlot.setScriptData(pickle.dumps(bListSpawnedCiv))

###obsolete
#for i in xrange(len(PopList),0,1):
#SpawnCivList.pop(PopList)


def SpawnACiv(SpawnCiv,ListNum,iPlayer,iTechType,iTurn):
###Test if right tech###
Tech = SpawnCiv.SpawnTech
iHumanTech = SpawnCiv.SpawnTechHumanOnly
bHumanTech = False
#CyInterface().addMessage(0,False,15,"entered code",()),'',0,'Art/Interface/Buttons/General/happy_person.dds',ColorTypes(44), 1, 1, True,True)
if iTechType:
if not ((iTechType ==gc.getInfoTypeForString(Tech)) or (iTechType == gc.getInfoTypeForString(iHumanTech))):
return
if iTechType == gc.getInfoTypeForString(iHumanTech):
bHumanTech = True
if not gc.getPlayer(iPlayer).isHuman():
return
TechCounter=0
for i in xrange (gc.getMAX_CIV_TEAMS ()):
Team = gc.getTeam(i)
if Team.isHasTech(iTechType):
TechCounter=TechCounter+1
if TechCounter>=SpawnCiv.SpawnTechNumber:
break

if (not TechCounter>=SpawnCiv.SpawnTechNumber) and (not bHumanTech):
return

if iTurn:
#CyInterface().addMessage(0,False,15,str(CyGameTextMgr().getDateStr (iTurn+1, False, CyGame().getCalendar (), CyGame().getStartYear (), CyGame().getGameSpeedType ())),'',0,'Art/Interface/Buttons/General/happy_person.dds',ColorTypes(44), 1, 1, True,True)
if not ((iTurn+1 == SpawnCiv.iTurn) or (str(CyGame().getTurnYear(iTurn+1))==SpawnCiv.iYear)):
return
if (str(CyGame().getTurnYear(iTurn+1))==SpawnCiv.iYear):
if SpawnCiv.iMonth>0 and SpawnCiv.iMonth<13:
strDate = CyGameTextMgr().getDateStr (iTurn+1, False, CyGame().getCalendar (), CyGame().getStartYear (), CyGame().getGameSpeedType ())
if "," in strDate:
month, junk = strDate.split(",",1)
month = month.strip()
sMonth = gc.getMonthInfo(SpawnCiv.iMonth-1).getDescription()
if not sMonth in month:
return


if SpawnCiv.AlreadyTriggered:
return
###test, if right number of civs have tech


SpawningChance = CyGame().getSorenRandNum(100, "HowGoodIsTheChance")
if SpawningChance>SpawnCiv.SpawnChance:
SpawnCiv.AlreadyTriggered = True
return
###test, if spawn civ is not already alive
for i in xrange (gc.getMAX_CIV_PLAYERS ()):
pPlayer = gc.getPlayer(i)
myName = pPlayer.getCivilizationType ()
otherName = gc.getInfoTypeForString(SpawnCiv.CivString)
if myName ==otherName:
return
###Find a ID for the civ###

NewID = -1
for NumCiv in xrange (gc.getMAX_PLAYERS ()):
PotPlayer = gc.getPlayer(NumCiv)
if not PotPlayer.isAlive():
NewID = NumCiv
break
if NewID ==-1:
return
###Add Civ to game
iCiv = gc.getInfoTypeForString(SpawnCiv.CivString)
if not str(SpawnCiv.LeaderString)=="-1":
NewLeaderID=gc.getInfoTypeForString(SpawnCiv.LeaderString)
if str(SpawnCiv.LeaderString)=="-1":

CurCiv = gc.getCivilizationInfo(iCiv)
NumLeaders = CurCiv.getNumLeaders ()
dice = gc.getGame().getMapRand()
LeaderNum = dice.get(NumLeaders , "OracleSayMeTheLeader" )
LeaderCounter=0
for iLeaders in range(gc.getNumLeaderHeadInfos ()):
if CurCiv.isLeaders(iLeaders):
if NumLeaders==1:
NewLeaderID =iLeaders
break
else:
if LeaderCounter==LeaderNum:
NewLeaderID=iLeaders
break
LeaderCounter=LeaderCounter+1
CyGame().addPlayer(NewID,NewLeaderID,iCiv)
NewPlayer = gc.getPlayer(NewID)
NewTeam = gc.getTeam(NewPlayer.getTeam())
NewTeamID = NewTeam.getID()

###from an old version, may be reactived later, you never
###now; declareWar is custom function in this file, not used
###at the moment
### function testIfBarb is current version
#declareWar(NewID,SpawnCiv)
#if SpawnCiv.bBarb==True:
#MaxCivs = gc.getMAX_CIV_TEAMS()
#for i in xrange (MaxCivs):
#if i==NewTeamID:continue
#NewTeam.setPermanentWarPeace(i,True)
maxX = CyMap().getGridWidth ()
maxY = CyMap().getGridHeight ()
iTundra = gc.getInfoTypeForString("TERRAIN_TUNDRA")
iDesert = gc.getInfoTypeForString("TERRAIN_DESERT")
iSnow = gc.getInfoTypeForString("TERRAIN_SNOW")
NumSetCities = 0
Counter=0
NewPlayer.setGold(SpawnCiv.Gold)
if SpawnCiv.SpawnX>-1 and SpawnCiv.SpawnY>-1:
if SpawnCiv.SpawnX<CyMap().getGridWidth () and SpawnCiv.SpawnY<CyMap().getGridHeight ():
pPlot = CyMap().plot(SpawnCiv.SpawnX,SpawnCiv.SpawnY)
if not pPlot.isCity():
numUnits = pPlot.getNumUnits ()
for iUnits in xrange(numUnits):
pUnit = pPlot.getUnit(iUnits)
UnitX = pUnit.getX()
UnitY = pUnit.getY()
NewPlot = CyMap().plot(UnitX+1,UnitY+1)
if not NewPlot.isNone() and not NewPlot.isCity():
pUnit.setXY(UnitX+1,UnitY+1,True,True,True)
elif not CyMap().plot(UnitX-1,UnitY-1).isNone() and not CyMap().plot(UnitX-1,UnitY-1).isCity():
pUnit.setXY(UnitX-1,UnitY-1,True,True,True)
elif not CyMap().plot(UnitX+1,UnitY-1).isNone() and not CyMap().plot(UnitX+1,UnitY-1).isCity():
pUnit.setXY(UnitX+1,UnitY-1,True,True,True)
elif not CyMap().plot(UnitX-1,UnitY+1).isNone() and not CyMap().plot(UnitX-1,UnitY+1).isCity():
pUnit.setXY(UnitX-1,UnitY+1,True,True,True)

NewPlayer.initCity(SpawnCiv.SpawnX,SpawnCiv.SpawnY)
NumSetCities = NumSetCities+1
AddTechToPlayer(iPlayer,NewID,SpawnCiv.TechPercent)
AddUnitsToCity(SpawnCiv.SpawnX,SpawnCiv.SpawnY,NewID,SpawnCiv)

while NumSetCities <SpawnCiv.NumCities:
EndangeredPlot = []
CrapPlot = []
SetCity = False
Counter=Counter+1
Endangered = False
if Counter>100:return
if Counter>SpawnCiv.NumCities:return
for iX in xrange (maxX):
for iY in xrange(maxY):
pPlot = CyMap().plot(iX,iY)
if pPlot.isWater() or pPlot.isImpassable():
continue
if pPlot.isOwned():
continue
if pPlot.isUnit():
continue
if SpawnCiv.bCoast:
if not pPlot.isCoastalLand ():
continue
if (pPlot.getTerrainType ()==iDesert) or(pPlot.getTerrainType()==iSnow)or(pPlot.getTerrainType()==iTundra):
CrapPlot.append([pPlot.getX(),pPlot.getY()])
continue
if pPlot.isAdjacentOwned ():
continue

IsCity = checkCity(iX,iY)
if IsCity:continue
for iXLoop in xrange(iX - 2, iX + 3, 1):
for iYLoop in xrange(iY - 2, iY + 3, 1):
TempPlot = CyMap().plot(iXLoop,iYLoop)
if TempPlot.isOwned() or TempPlot.isUnit():
EndangeredPlot.append([pPlot.getX(),pPlot.getY()])
Endangered = True
break
if (Endangered == False):
NewPlayer.initCity(iX,iY)
NumSetCities = NumSetCities+1
SetCity = True
AddTechToPlayer(iPlayer,NewID,SpawnCiv.TechPercent)
AddUnitsToCity(iX,iY,NewID,SpawnCiv)
break

if SetCity ==False:
if len(EndangeredPlot)>0:
iRandPlot = CyGame().getSorenRandNum(len(EndangeredPlot), 'EndangeredPlot')
RandPlot = EndangeredPlot[iRandPlot]
CityX=RandPlot[0]
CityY=RandPlot[1]
NewPlayer.initCity(CityX,CityY)
NumSetCities = NumSetCities+1
AddTechToPlayer(iPlayer,NewID,SpawnCiv.TechPercent)
AddUnitsToCity(CityX,CityY,NewID,SpawnCiv)
elif len(CrapPlot)>0:
iRandPlot = CyGame().getSorenRandNum(len(CrapPlot), 'Crap Plot')
RandPlot = EndangeredPlot[iRandPlot]
CityX=RandPlot[0]
CityY=RandPlot[1]
NewPlayer.initCity(CityX,CityY)
NumSetCities = NumSetCities+1
AddTechToPlayer(iPlayer,NewID,SpawnCiv.TechPercent)
AddUnitsToCity(CityX,CityY,NewID,SpawnCiv)
if SetCity == True:
AddUnitsToCapital(NewID,SpawnCiv)
SpawnCiv.AlreadyTriggered = True
return True

###function should be obsolete
###not used at the moment
### function testIfBarb is current version
def declareWar(iPlayer,SpawnCiv):
if SpawnCiv.bBarb==True:
NewPlayer = gc.getPlayer(iPlayer)
TeamID = NewPlayer.getTeam()
NewTeam = gc.getTeam(TeamID)
for i in xrange(gc.getMAX_CIV_TEAMS ()):
if i==TeamID:continue
NewTeam.declareWar(i,False,WarPlanTypes.WARPLAN_TOTAL)
CurTeam = gc.getTeam(i)
CurTeam.declareWar(TeamID,False,WarPlanTypes.WARPLAN_TOTAL)
for i in range(gc.getMAX_CIV_PLAYERS()):
if i==iPlayer:continue
NewPlayer.AI_setAttitudeExtra(i,-999)
CurPlayer = gc.getPlayer(i)
CurPlayer.AI_setAttitudeExtra(iPlayer,-999)



def AddTechToPlayer(iPlayer,iNewPlayer,TechPercent):
pPlayer = gc.getPlayer(iPlayer)
pTeam = gc.getTeam(pPlayer.getTeam())
NewPlayer = gc.getPlayer(iNewPlayer)
NewTeam = gc.getTeam(NewPlayer.getTeam())
TechPercent = float(TechPercent)/100
TotalTechCounter=0
GridWidth=0
for i in xrange(gc.getNumTechInfos ()):
if pTeam.isHasTech(i):
TotalTechCounter=TotalTechCounter+1
CurTech= gc.getTechInfo(i)
if CurTech.getGridX()>GridWidth:
GridWidth=CurTech.getGridX()
TotalTechCounter=int(TotalTechCounter*TechPercent)
TempTechCounter=0
#CyInterface().addMessage(0,False,15,CyTranslator().getText(str(TotalTechCounter),()),'',0,'Art/Interface/Buttons/General/happy_person.dds',ColorTypes(44), 1, 1, True,True)
for j in xrange(GridWidth):
for i in xrange(gc.getNumTechInfos ()):
CurTech= gc.getTechInfo(i)
if pTeam.isHasTech(i):
if CurTech.getGridX()==j:
NewTeam.setHasTech(i,True,iNewPlayer,False,False)
TempTechCounter=TempTechCounter+1
if TempTechCounter>=TotalTechCounter:
break
if TempTechCounter>=TotalTechCounter:
break


def AddUnitsToCapital(iNewID,SpawnCiv):
pPlayer = gc.getPlayer(iNewID)
Capital = pPlayer.getCapitalCity()
iX = Capital.getX()
iY = Capital.getY()
if SpawnCiv.CapitalUnit !="NONE" and SpawnCiv.CapitalUnit !=-1:
if SpawnCiv.NumberCapitalUnit>0:
for i in xrange(SpawnCiv.NumberCapitalUnit):
pPlayer.initUnit( gc.getInfoTypeForString(SpawnCiv.CapitalUnit), iX,iY, UnitAITypes.NO_UNITAI, DirectionTypes.NO_DIRECTION )

def AddUnitsToCity(iX,iY,iNewPlayer,SpawnCiv):
NewPlayer = gc.getPlayer(iNewPlayer)
if SpawnCiv.NumWorker>0:
for i in xrange(SpawnCiv.NumWorker):
NewPlayer.initUnit( gc.getInfoTypeForString("UNIT_WORKER"), iX,iY, UnitAITypes.UNITAI_WORKER, DirectionTypes.NO_DIRECTION )
pCity = CyMap().plot(iX,iY).getPlotCity()
if SpawnCiv.DefenderUnit !="NONE":
if SpawnCiv.DefenderUnit=="-1":
Defender = pCity.getConscriptUnit ()
else:
Defender = gc.getInfoTypeForString(SpawnCiv.DefenderUnit)
if SpawnCiv.NumberDefenderUnit>0:
for i in xrange(SpawnCiv.NumberDefenderUnit):
NewPlayer.initUnit( Defender, iX,iY, UnitAITypes.NO_UNITAI, DirectionTypes.NO_DIRECTION )
if SpawnCiv.SecondUnit !="NONE":
if SpawnCiv.SecondUnit=="-1":
Second = pCity.getConscriptUnit ()
else:
Second = gc.getInfoTypeForString(SpawnCiv.SecondUnit)
if SpawnCiv.NumSecondUnit>0:
for i in xrange(SpawnCiv.NumSecondUnit):
NewPlayer.initUnit( Second, iX,iY, UnitAITypes.NO_UNITAI, DirectionTypes.NO_DIRECTION )
if pCity.isCoastal(20):
if ((not SpawnCiv.Ships=="-1")and(not SpawnCiv.Ships=="NONE")) and (not SpawnCiv.NumberShips<1):
ThisShip = SpawnCiv.Ships
CurShip = gc.getInfoTypeForString(ThisShip)
NumShip = SpawnCiv.NumberShips
for i in xrange(NumShip):
NewPlayer.initUnit( CurShip, iX,iY, UnitAITypes.NO_UNITAI, DirectionTypes.NO_DIRECTION )


def checkCity(iX,iY):
for iXLoop in xrange(iX - 2, iX + 3, 1):
for iYLoop in xrange(iY - 2, iY + 3, 1):
TempPlot = CyMap().plot(iXLoop,iYLoop)
if TempPlot.isCity():return True
return False

def ReadMyFile(MyFile,DataPlotX,DataPlotY):
del SpawnCivList[:]
for CurString in MyFile.readlines():
if "CIVILIZATION_" in CurString:
CurCiv = SpawningCiv()
CurCiv.CivString = CutString(CurString)
elif "Leader" in CurString:
CurCiv.LeaderString = CutString(CurString)
elif "SpawnTech>" in CurString:
CurCiv.SpawnTech = CutString(CurString)
elif "NumberOfSpawnTech" in CurString:
CurCiv.SpawnTechNumber = int(CutString(CurString))
elif "SpawnTechHumanOnly" in CurString:
CurCiv.SpawnTechHumanOnly = CutString(CurString)
elif "iTurn" in CurString:
CurCiv.iTurn = int(CutString(CurString))
elif "iYear" in CurString:
CurCiv.iYear = CutString(CurString)
elif "iMonth" in CurString:
CurCiv.iMonth = int(CutString(CurString))
elif "SpawnChance" in CurString:
CurCiv.SpawnChance = float(CutString(CurString))
elif "IsBarbarianCiv" in CurString:
CuttedString = CutString(CurString)
CurCiv.bBarb = bool(eval(CuttedString))
elif "StartAtCoast" in CurString:
CuttedString = CutString(CurString)
CurCiv.bCoast = bool(eval(CuttedString))
elif "TotalGold" in CurString:
CurCiv.Gold = int(CutString(CurString))
elif "TechPercent" in CurString:
CurCiv.TechPercent =int(CutString(CurString))
elif "DefaultShips" in CurString:
CurCiv.Ships = CutString(CurString)
elif "NumberShipsPerCity" in CurString:
CurCiv.NumberShips = int(CutString(CurString))
elif "NumberOfCities" in CurString:
CurCiv.NumCities = int(CutString(CurString))
elif "StartX" in CurString:
CurCiv.SpawnX = int(CutString(CurString))
elif "StartY" in CurString:
CurCiv.SpawnY = int(CutString(CurString))
elif "NumWorkerPerCity" in CurString:
CurCiv.NumWorker = int(CutString(CurString))
elif "CapitalCityUnit" in CurString:
CurCiv.CapitalUnit = CutString(CurString)
elif "NumCapitalUnit" in CurString:
CurCiv.NumberCapitalUnit = int(CutString(CurString))
elif "DefaultCityDefender" in CurString:
CurCiv.DefenderUnit = CutString(CurString)
elif "NumberCityDefendersPerCity" in CurString:
CurCiv.NumberDefenderUnit = int(CutString(CurString))
elif "DefaultSecondUnit" in CurString:
CurCiv.SecondUnit = CutString(CurString)
elif "NumberSecondUnit" in CurString:
CurCiv.NumSecondUnit = int(CutString(CurString))
SpawnCivList.append(CurCiv)
AddCivAlreadySpawnedInfo(SpawnCivList,DataPlotX,DataPlotY)

def AddCivAlreadySpawnedInfo(SpawnCivList,DataPlotX,DataPlotY):
DataPlot = CyMap().plot(DataPlotX,DataPlotY)
bListSpawnedCiv = pickle.loads(DataPlot.getScriptData ())
iMaxLoadCiv = len(SpawnCivList)
if len(bListSpawnedCiv)>0:
for i in range (iMaxLoadCiv):
SpawnCivList.AlreadyTriggered = bListSpawnedCiv

def TestIfBarb(iTeamX,iHasMetTeamY):
if iTeamX == iHasMetTeamY:
return False
TeamOne = gc.getTeam(iTeamX)
TeamTwo = gc.getTeam(iHasMetTeamY)
pPlayerOne = gc.getPlayer(TeamOne.getLeaderID())
pPlayerTwo = gc.getPlayer(TeamTwo.getLeaderID())
iLenSpawnCiv = len(SpawnCivList)
for i in range(iLenSpawnCiv):
if SpawnCivList.bBarb:
if (gc.getInfoTypeForString(SpawnCivList.CivString)== pPlayerOne.getCivilizationType () ):
TeamOne.declareWar(iHasMetTeamY,False,WarPlanTypes.WARPLAN_TOTAL)
TeamOne.setPermanentWarPeace(iHasMetTeamY,True)
elif (gc.getInfoTypeForString(SpawnCivList.CivString)== pPlayerTwo.getCivilizationType () ):
TeamTwo.declareWar(iTeamX,False,WarPlanTypes.WARPLAN_TOTAL)
TeamTwo.setPermanentWarPeace(iTeamX,True)

def CutString(string):
string = str(string)
string = string.strip()
string = string[2:-1]
BeginPos=-1
EndPos = -1
for i in xrange(len(string)):
if string==">":
BeginPos=i
elif string=="<":
EndPos=i
break
else:
return "-1"
NewString = string[BeginPos+1:EndPos]
return str(NewString)

class SpawningCiv:
def __init__(self):
self.CivString = 0
self.LeaderString = 0
self.SpawnTech = 0
self.SpawnTechHumanOnly = 0
self.SpawnTechNumber = 0
self.iTurn = 0
self.iYear = 0
self.iMonth = 0
self.SpawnChance = 0
self.bCoast = 0
self.Ships = 0
self.NumberShips = 0
self.bBarb = 0
self.NumCities = 0
self.SpawnX = 0
self.SpawnY = 0
self.CapitalUnit = 0
self.NumberCapitalUnit = 0
self.DefenderUnit = 0
self.NumberDefenderUnit = 0
self.NumWorker=0
self.Gold = 0
self.SecondUnit=0
self.NumSecondUnit=0
self.TechPercent=0
self.AlreadyTriggered = False
 
Last edited:
If I understand correctly I have to delete this part
 

Attachments

  • Screenshot 2024-02-29 234254.jpg
    Screenshot 2024-02-29 234254.jpg
    72.9 KB · Views: 4
Yes, also the part above; only the parts added by The_J should be there, plus any code dealing with the argsList (above his code).


If I understand correctly I have to delete this part,
from "def TriggerCiv(iPlayer,iTechType,DataPlotX,DataPlotY,iTurn)" here on everything is the same
 

Attachments

  • Screenshot 2024-03-01 000252.jpg
    Screenshot 2024-03-01 000252.jpg
    141.9 KB · Views: 5
  • Screenshot 2024-03-01 000446.jpg
    Screenshot 2024-03-01 000446.jpg
    82.8 KB · Views: 3
  • Screenshot 2024-03-01 001543.png
    Screenshot 2024-03-01 001543.png
    90.2 KB · Views: 6
Last edited:
I tried to load, it gives me 4 errors
 

Attachments

  • Screenshot 2024-03-01 120916.png
    Screenshot 2024-03-01 120916.png
    180.7 KB · Views: 5
  • Screenshot 2024-03-01 120948.png
    Screenshot 2024-03-01 120948.png
    144.2 KB · Views: 4
  • Screenshot 2024-03-01 121019.png
    Screenshot 2024-03-01 121019.png
    221.2 KB · Views: 3
  • Screenshot 2024-03-01 121037.png
    Screenshot 2024-03-01 121037.png
    227.1 KB · Views: 3
I attach the complete modified files
 

Attachments

  • spawnciv.rar
    8.6 KB · Views: 5
Last edited:
Since you've renamed the file, the reference to SpawnCivUtil can't work. I guess SpawnCivs would work, but, as it's all within a single module, no dot notation is needed at all, i.e. just ReadMyFile instead of SpawnCivUtil.ReadMyFile; same for the other three occurrences of SpawnCivUtil.
 
then I replaced SpawnCivUtil, with SpawnACiv, in the 4 parts, and I added import SpawnACIV, but unfortunately it gives me these 4 errors
 

Attachments

  • Screenshot 2024-03-01 222316.png
    Screenshot 2024-03-01 222316.png
    219.4 KB · Views: 4
  • Screenshot 2024-03-01 222339.png
    Screenshot 2024-03-01 222339.png
    208.9 KB · Views: 2
  • Screenshot 2024-03-01 222401.png
    Screenshot 2024-03-01 222401.png
    233.3 KB · Views: 5
  • Screenshot 2024-03-01 222909.png
    Screenshot 2024-03-01 222909.png
    29.4 KB · Views: 4
  • Screenshot 2024-03-01 222509.png
    Screenshot 2024-03-01 222509.png
    80.3 KB · Views: 4
Just ReadMyFile should work, without a module name in front. And the module shouldn't import itself.
 
Just ReadMyFile should work, without a module name in front. And the module shouldn't import itself.
done, but it gives me these errors now
 

Attachments

  • Screenshot 2024-03-01 231826.png
    Screenshot 2024-03-01 231826.png
    57.4 KB · Views: 4
  • Screenshot 2024-03-01 232705.png
    Screenshot 2024-03-01 232705.png
    212.3 KB · Views: 3
  • Screenshot 2024-03-01 222339.png
    Screenshot 2024-03-01 222339.png
    208.9 KB · Views: 3
  • Screenshot 2024-03-01 222401.png
    Screenshot 2024-03-01 222401.png
    233.3 KB · Views: 2
Top Bottom