adapt a script

Yeah, it seems that you didn't copy the
Code:
DataPlotX = 3
DataPlotY = 3
from CvEventManager. Putting that somewhere near the top of your module should work.
 
it does not work yet
 

Attachments

  • Screenshot 2024-03-01 234613.png
    Screenshot 2024-03-01 234613.png
    209.8 KB · Views: 16
  • Screenshot 2024-03-01 234707.png
    Screenshot 2024-03-01 234707.png
    223.8 KB · Views: 13
  • Screenshot 2024-03-01 235108.png
    Screenshot 2024-03-01 235108.png
    35.1 KB · Views: 13
This one's not a simple syntax error. I've inserted some logging output to diagnose where it's going wrong; didn't really figure it out. My best bet is to change the start of AddCivAlreadySpawnedInfo as follows:
Code:
def AddCivAlreadySpawnedInfo(SpawnCivList,DataPlotX,DataPlotY):
        DataPlot = CyMap().plot(DataPlotX,DataPlotY)
        if not DataPlot.getScriptData (): # Workaround for empty data at game start
                return
        # (etc.)
This is only a workaround, but at least I'm getting the Americans to spawn on a particular turn this way; hopefully sufficient for your needs. This script is perhaps too complex to be quickly converted for BUG with our limited Python skills.
 
I found this script in this mod dawnoftime, which I adapted for Americans, could it adapt more easily?

#reads the date regardless of game speed
def isDate(iDate):
return cyGame.getTurnYear(cyGame.getGameTurn() +1) > iDate and cyGame.getGameTurnYear() <= iDate

#searches in the dictionary to get a name for a key tile
def nameNorm(pCity):
coord = (pCity.getX(), pCity.getY())
if coord in cityNameDict:
name = cityNameDict[coord]
pCity.setName(name, True)
return True
else:
return False

#compiles a list of plots
def getPlotList(tBL, tTR):
lPlotList = []
for x in range(tBL[0], tTR[0]+1):
for y in range(tBL[1], tTR[1]+1):
lPlotList.append((x, y))
return lPlotList

#gets all tiles within the given distance of the tile given
def getSquareList(tCoords, iDistance):
return getPlotList((tCoords[0]-iDistance, tCoords[1]-iDistance), (tCoords[0]+iDistance, tCoords[1]+iDistance))

#gets all tiles adjacent to the tile given
def getAdjacentList(tCoords):
return getSquareList(tCoords, 1)


#spawns the classical civs
def classicalSpawn():
pAmerica= cyMap.plot(60, 44)
if isDate(-770):
if PyPlayer(0).isAlive():
gc.getTeam(7).declareWar(0, True, -1)
if PyPlayer(5).isAlive():
gc.getTeam(7).declareWar(5, True, -1)
for tCoords in getAdjacentList((60, 44)):
x, y = tCoords
pCurrentPlot = cyMap.plot(x, y)
if pCurrentPlot.isCity():
pCity = pCurrentPlot.getPlotCity()
pCity.kill()
PyPlayer(7).initCity(60, 44)
CyEngine().removeLandmark(pAmerica)
pAmerica.getPlotCity().setPopulation(8)
pAmerica.getPlotCity().setCulture(7, 3000, True)
pAmerica.getPlotCity().setNumRealBuilding(3, 1)
pAmerica.getPlotCity().setNumRealBuilding(7, 1)
pAmerica getPlotCity().setNumRealBuilding(9, 1)
pAmerica.getPlotCity().setNumRealBuilding(13, 1)
pAmerica.getPlotCity().setNumRealBuilding(15, 1)
pAmerica.getPlotCity().setNumRealBuilding(20, 1)
pAmerica.getPlotCity().setNumRealBuilding(22, 1)
pAmerica.getPlotCity().setNumRealBuilding(59, 1)
pAmerica.getPlotCity().setNumRealBuilding(43, 1)
gc.getTeam(7).setHasTech(0, true, 7, false, false)
gc.getTeam(7).setHasTech(1, true, 7, false, false)
gc.getTeam(7).setHasTech(2, true, 7, false, false)
gc.getTeam(7).setHasTech(3, true, 7, false, false)
gc.getTeam(7).setHasTech(4, true, 7, false, false)
gc.getTeam(7).setHasTech(25, true, 7, false, false)
gc.getTeam(7).setHasTech(26, true, 7, false, false)
gc.getTeam(7).setHasTech(27, true, 7, false, false)
gc.getTeam(7).setHasTech(28, true, 7, false, false)
gc.getTeam(7).setHasTech(30, true, 7, false, false)
gc.getTeam(7).setHasTech(31, true, 7, false, false)
gc.getTeam(7).setHasTech(59, true, 7, false, false)
gc.getTeam(7).setHasTech(60, true, 7, false, false)
gc.getTeam(7).setHasTech(61, true, 7, false, false)
gc.getTeam(7).setHasTech(62, true, 7, false, false)
gc.getTeam(7).setHasTech(63, true, 7, false, false)
gc.getTeam(7).setHasTech(64, true, 7, false, false)
for tCoords in getPlotList((58, 40), (63, 47)):
x, y = tCoords
pCurrentPlot = cyMap.plot(x,y)
pPotentialCity = pCurrentPlot.getPlotCity()
iUnhappy = pPotentialCity.unhappyLevel(0)
if pPotentialCity != None:
iHappy = pPotentialCity.happyLevel()
if iUnhappy * 4 >= iHappy:
pCurrentPlot.setOwner(7)
PyPlayer(7).initUnit(4, 60, 44, 2)
PyPlayer(7).initUnit(5, 60, 44, 2)
PyPlayer(7).initUnit(57, 60, 44, 20)
PyPlayer(7).initUnit(29, 60, 44, 30)
americaMessage = "Britishhave united and declare their independence. A new civilization is born!"
CyInterface().addImmediateMessage(americaMessage,"")
CvUtil.pyPrint(americaMessage)
 

Attachments

Last edited:
This one's not a simple syntax error. I've inserted some logging output to diagnose where it's going wrong; didn't really figure it out. My best bet is to change the start of AddCivAlreadySpawnedInfo as follows:
Code:
def AddCivAlreadySpawnedInfo(SpawnCivList,DataPlotX,DataPlotY):
        DataPlot = CyMap().plot(DataPlotX,DataPlotY)
        if not DataPlot.getScriptData (): # Workaround for empty data at game start
                return
        # (etc.)
This is only a workaround, but at least I'm getting the Americans to spawn on a particular turn this way; hopefully sufficient for your needs. This script is perhaps too complex to be quickly converted for BUG with our limited Python skills.
now it hasn't given me any errors :), thank you very much for the time you have dedicated to me so far.
edit: unfortunately it gives me an error during the game, it doesn't give me an error at the beginning, if so can you give me the files you used to test, because I don't know what I'm doing wrong. Thank you
 

Attachments

  • Screenshot 2024-03-02 171323.png
    Screenshot 2024-03-02 171323.png
    848.1 KB · Views: 11
Last edited:
I notice in one of your screenshots that you've written "ReadMyFile.TriggerCiv". That should only be TriggerCiv (and TestIfBarb instead of ReadMyFile.TestIfBarb). Probably the cause of this latest error. As for the Dawn Of Time code – let's hope that SpawnACiv will work. Dawn Of Time looks less complex, but, for a start, I'd have to read all of it to be able to do anything with it.
 
hello, I will never stop thanking you. now the Americans are spawning, but I don't know, it still gives me these errors. and i don't knw if it does create problems for me in the future, it could be fine like this, but if can be corrected better.
I have also attached the modified files, in case you need them
 

Attachments

  • Screenshot 2024-03-02 231553.png
    Screenshot 2024-03-02 231553.png
    1.8 MB · Views: 10
  • Screenshot 2024-03-02 231256.png
    Screenshot 2024-03-02 231256.png
    974.1 KB · Views: 12
  • Screenshot 2024-03-02 231235.png
    Screenshot 2024-03-02 231235.png
    908.8 KB · Views: 11
  • Screenshot 2024-03-02 231152.png
    Screenshot 2024-03-02 231152.png
    775.1 KB · Views: 10
  • Spawncivtest.rar
    Spawncivtest.rar
    8.4 KB · Views: 8
Last edited:
Looks like this would happen when placing just one city at coordinates (StartX, StartY). Perhaps The_J hadn't tested that case (the coordinates are not used at all in his XML example). Putting this
Code:
        # Bugfix for case NumSetCities==1 and SpawnCiv.NumCities==1
        if NumSetCities > 0:
                SetCity = True
        else:
                SetCity = False # (end of bugfix)
right before the
Code:
        while NumSetCities <SpawnCiv.NumCities:
could fix this problem – though I haven't tested it. (With your CIV4SpawnCivInfos.xml, I could also try to test it.)
hello, I will never stop thanking you.
That's OK; it's not like you're asking me specifically for help, and I'll just say when something is too much effort.
 
putting more cities doesn't give me any errors, but as you can see from the photo, he puts the other cities wherever he wants :)
 

Attachments

  • Screenshot 2024-03-03 100448.png
    Screenshot 2024-03-03 100448.png
    2.5 MB · Views: 12
Then I hope you only need one city per civilization - and that my proposed bugfix works when placing just one city.
 
hello, I ask, if it is possible to add to this event that, for example, team 4, in addition to not being attacked, can always keep the borders open. Thanks


##WarNPeace
###MODDER READ THIS:
###You do not have to change anything in this file
###all changes have to be done in the CvEventManager.
###This file just has to be in the same folder like the CvEventManager.py.

from CvPythonExtensions import *
import sys
import Popup as PyPopup
import CvUtil
import BugGameUtils

gc = CyGlobalContext()
bDebug = False
lEvents = []
lApplicableEvents = []

import BugEventManager

def init():
em = BugEventManager.g_eventManager
em.addEventHandler('LoadGame', loadCustomXML)
em.addEventHandler('GameStart', loadCustomXML)
em.addEventHandler('BeginGameTurn', onBeginGameTurn)
BugGameUtils.addHandler(canDeclareWar)
BugGameUtils.addHandler(cannotFoundCity)
BugGameUtils.addHandler(cannotTrain)

def cannotFoundCity(argsList):
iPlayer, iPlotX, iPlotY = argsList
#City Restriction Part 1 Start
FreeCities = 2
pPlayer = gc.getPlayer(iPlayer)
if ((pPlayer.getNumCities() >= FreeCities)and (pPlayer.getNumCities()>0)):
return True
###City Restriction Part 1 End


return False

def cannotTrain(argsList):
pCity = argsList[0]
eUnit = argsList[1]
bContinue = argsList[2]
bTestVisible = argsList[3]
bIgnoreCost = argsList[4]
bIgnoreUpgrades = argsList[5]
###City Restriction Part 2 Start
ePlayer = pCity.getOwner()
pPlayer = gc.getPlayer(ePlayer)
FreeCities = 2
if (eUnit == gc.getInfoTypeForString("UNIT_SETTLER")):
if not bTestVisible:
if (pPlayer.getNumCities() >= FreeCities):

return True
###City Restriction Part 2 End
return False

def canDeclareWar(argsList):
iAttackingTeam, iDefendingTeam = argsList
if iDefendingTeam == 4 or iAttackingTeam == 4:
return False
return True

def loadCustomXML(argsList):
loadEvents("Mods/Realism Invictus/Assets/XML/CustomXML/WarNPeace.xml")

def onBeginGameTurn(argsList):
iGameTurn = argsList[0]
triggerEvents(iGameTurn)

def triggerEvents(iTurn):
iTurn = iTurn+1
iYear = gc.getGame().getTurnYear(iTurn)
if bDebug:CyInterface().addMessage(0,False,15,CyTranslator().getText("trying to trigger at turn "+str(iTurn)+" and year: "+str(iYear),()),'',0,'Art/Interface/Buttons/General/happy_person.dds',ColorTypes(44), 1, 1, True,True)
for item in lApplicableEvents:
if bDebug:
CyInterface().addMessage(0,False,15,CyTranslator().getText("inside loop",()),'',0,'Art/Interface/Buttons/General/happy_person.dds',ColorTypes(44), 1, 1, True,True)
CyInterface().addMessage(0,False,15,str(item.iDate),'',0,'Art/Interface/Buttons/General/happy_person.dds',ColorTypes(44), 1, 1, True,True)
CyInterface().addMessage(0,False,15,str(item.iTurn),'',0,'Art/Interface/Buttons/General/happy_person.dds',ColorTypes(44), 1, 1, True,True)
if (item.iDate==iYear) or (item.iTurn==iTurn) and not(iTurn==-1) and not(iYear==0):
if bDebug:CyInterface().addMessage(0,False,15,CyTranslator().getText("it matches",()),'',0,'Art/Interface/Buttons/General/happy_person.dds',ColorTypes(44), 1, 1, True,True)
if bDebug:CyInterface().addMessage(0,False,15,item.sType,'',0,'Art/Interface/Buttons/General/happy_person.dds',ColorTypes(44), 1, 1, True,True)
iMaxCiv = gc.getMAX_CIV_PLAYERS ()
iAttacker = -1
iDefender = -1
for i in range(iMaxCiv):
curPlayer = gc.getPlayer(i)
iType = curPlayer.getCivilizationType ()
if (gc.getInfoTypeForString(item.sAttacker)==iType):
iAttacker = i
if (gc.getInfoTypeForString(item.sDefender)==iType):
iDefender = i
if (iAttacker!=-1) and (iDefender!=-1):
pAttackerTeam = gc.getTeam(gc.getPlayer(iAttacker).getTeam())
iDefenderTeam = gc.getPlayer(iDefender).getTeam()
pDefenderTeam = gc.getTeam(iDefenderTeam)
bNoPopup = False
if item.sType =="WAR":
if not pAttackerTeam.isAtWar(iDefenderTeam):
pAttackerTeam.declareWar(iDefenderTeam,False,WarPlanTypes.WARPLAN_TOTAL)
bNoPopup = True
pAttackerTeam.setPermanentWarPeace(iDefenderTeam,True)
if item.sType=="PEACE":
if pAttackerTeam.isAtWar(iDefenderTeam):
pAttackerTeam.makePeace(iDefenderTeam)
bNoPopup=True
pAttackerTeam.setPermanentWarPeace(iDefenderTeam,True)
if pAttackerTeam.isHuman() and bNoPopup:
addPopup(item.sMessage,iAttacker)
if pDefenderTeam.isHuman() and bNoPopup:
addPopup(item.sMessage,iDefender)
def addPopup(sText,iPlayer):
if sText!="-1" and iPlayer!=-1:
pPlayer = gc.getPlayer(iPlayer)
popupInfo = CyPopupInfo()
popupInfo.setButtonPopupType(ButtonPopupTypes.BUTTONPOPUP_TEXT)
szText = CyTranslator().getText(sText, ())
popupInfo.setText(szText)
popupInfo.addPopup(iPlayer)


def loadEvents(sFilePath):
del lEvents[:]
MyFile=open(sFilePath)

for CurString in MyFile.readlines():
if "Attacker" in CurString:
CurEvent = Events()
CurEvent.sAttacker = CutString(CurString)
if "Defender" in CurString:
CurEvent.sDefender = CutString(CurString)
if "Type" in CurString:
CurEvent.sType = CutString(CurString)
if "Map" in CurString:
CurEvent.sMap = CutString(CurString)
if "Date" in CurString:
CurEvent.iDate = int(CutString(CurString))

if "Turn" in CurString:
CurEvent.iTurn = int(CutString(CurString))
if "Message" in CurString:
CurEvent.sMessage = CutString(CurString)
lEvents.append(CurEvent)
MyFile.close()
if bDebug: print "all events have been read"
cleanEvents()

def cleanEvents():
del lApplicableEvents[:]
sMapName = getMapname()
iYear = gc.getGame().getGameTurnYear()
iTurn = gc.getGame().getGameTurn ()
lCivs = getCivs()
if bDebug:CyInterface().addMessage(0,False,15,CyTranslator().getText("cleaning",()),'',0,'Art/Interface/Buttons/General/happy_person.dds',ColorTypes(44), 1, 1, True,True)
for item in lEvents:
if item.sMap!=sMapName:continue
if (item.iDate<iYear) and (item.iDate!=0):continue
if (item.iTurn<iTurn) and (item.iTurn!=-1):continue
if bDebug:CyInterface().addMessage(0,False,15,CyTranslator().getText("before civ check",()),'',0,'Art/Interface/Buttons/General/happy_person.dds',ColorTypes(44), 1, 1, True,True)
if (gc.getInfoTypeForString(item.sAttacker) in lCivs) and (gc.getInfoTypeForString(item.sDefender) in lCivs):
lApplicableEvents.append(item)
if bDebug:CyInterface().addMessage(0,False,15,CyTranslator().getText("event is on list",()),'',0,'Art/Interface/Buttons/General/happy_person.dds',ColorTypes(44), 1, 1, True,True)

def getMapname():
MapName = CyMap().getMapScriptName ()
if (".civ" in MapName) or(".Civ" in MapName):
if "civbeyondswordwbsave" in MapName:
MapName = MapName[0:-21]
if "CivBeyondSwordWBSave" in MapName:
MapName = MapName[0:-21]
if "CivWarlordsWBSave" in MapName:
MapName = MapName[0:-18]
if "Civ4WorldBuilderSave" in MapName:
MapName = MapName[0:-21]
if "civ4worldbuildersave" in MapName:
MapName = MapName[0:-21]
return MapName
else:
return "-1"

def getCivs():
iMaxCiv = gc.getMAX_CIV_PLAYERS ()

lCivs = []
del lCivs[:]
for i in range(iMaxCiv):
curPlayer = gc.getPlayer(i)
iType = curPlayer.getCivilizationType ()
lCivs.append(iType)
return lCivs

###generic string cutting function
###first < and > at the end are cut of, then the other
###> and < are searched, and what is between is used as value
def CutString(string):
print "Cutting"
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 Events:
def __init__(self):
self.sAttacker = 0
self.sDefender = 0
self.sType = 0
self.sMap = 0
self.iDate = 0
self.iTurn = 0
self.sMessage = ""
 
Implementing a deal through Python seems complicated, if at all possible. Maybe some other Python mod already does it. Or maybe you could just give everyone a very positive attitude toward the player with whom borders are supposed to be open. And vice versa. Something like ...
Code:
iLikedPlayer = 4
for iPlayer in range(gc.getMAX_CIV_PLAYERS()):
    player = gc.getPlayer(iPlayer)
    # Check cities just to make sure the game state is properly initialized
    if player.isAlive() and and player.getNumCities() > 0 and iPlayer != iLikedPlayer:
        # Shows up as "Past events ..." in AI attitude tooltips
        player.AI_setAttitudeExtra(iLikedPlayer, 30)
        gc.getPlayer(iLikedPlayer).AI_setAttitudeExtra(iPlayer, 30)
in onBeginGameTurn. Should be enough to run this once, e.g. when two players meet for the first time, but, to implement that, I'd have to check what other event handlers there are, and I guess repeating it once per game turn should be OK. Could combine this with a low ContactRand for CONTACT_OPEN_BORDERS in Civ4LeaderHeadInfos.xml if the liked player always has the same leader type.
 
Thank you. I solved it, I changed this
<OpenBordersRefuseAttitudeThreshold>ATTITUDE_FURIOUS</OpenBordersRefuseAttitudeThreshold>
, so now it's difficult for them to refuse
 
hi, I would like to insert the Hunter promotion in my modmod direalism invictus, I want to ask you if I can insert it in the modified WarPeace file
this is the string:
def onCombatResult(self, argsList):
'Combat Result'
pWinner,pLoser = argsList
playerX = PyPlayer(pWinner.getOwner())
unitX = PyInfo.UnitInfo(pWinner.getUnitType())
playerY = PyPlayer(pLoser.getOwner())
unitY = PyInfo.UnitInfo(pLoser.getUnitType())
## Hunter Promotion Start ##
if pLoser.isAnimal():
if pWinner.isHasPromotion(gc.getInfoTypeForString("PROMOTION_HUNTER")):
pPlayer = gc.getPlayer(pWinner.getOwner())
Capital = pPlayer.getCapitalCity()
Capital.changeFood(pLoser.baseCombatStr() * 3)
## Hunter Promotion End ##
if (not self.__LOG_COMBAT):
return
if playerX and playerX and unitX and playerY:
CvUtil.pyPrint('Player %d Civilization %s Unit %s has defeated Player %d Civilization %s Unit %s'
%(playerX.getID(), playerX.getCivilizationName(), unitX.getDescription(),
playerY.getID(), playerY.getCivilizationName(), unitY.getDescription()))
________________________________________________________________
this is WarPeace with the additions and bug fixes done together with you:
##WarNPeace
###MODDER READ THIS:
###You do not have to change anything in this file
###all changes have to be done in the CvEventManager.
###This file just has to be in the same folder like the CvEventManager.py.

from CvPythonExtensions import *
import sys
import Popup as PyPopup
import CvUtil
import BugGameUtils

gc = CyGlobalContext()
bDebug = False
lEvents = []
lApplicableEvents = []

import BugEventManager

def init():
em = BugEventManager.g_eventManager
em.addEventHandler('LoadGame', loadCustomXML)
em.addEventHandler('GameStart', loadCustomXML)
em.addEventHandler('BeginGameTurn', onBeginGameTurn)
BugGameUtils.addHandler(canDeclareWar)
BugGameUtils.addHandler(cannotFoundCity)
BugGameUtils.addHandler(cannotTrain)

def cannotFoundCity(argsList):
iPlayer, iPlotX, iPlotY = argsList
#City Restriction Part 1 Start
FreeCities = 2
pPlayer = gc.getPlayer(iPlayer)
if ((pPlayer.getNumCities() >= FreeCities)and (pPlayer.getNumCities()>0)):
return True
###City Restriction Part 1 End


return False

def cannotTrain(argsList):
pCity = argsList[0]
eUnit = argsList[1]
bContinue = argsList[2]
bTestVisible = argsList[3]
bIgnoreCost = argsList[4]
bIgnoreUpgrades = argsList[5]
###City Restriction Part 2 Start
ePlayer = pCity.getOwner()
pPlayer = gc.getPlayer(ePlayer)
FreeCities = 2
if (eUnit == gc.getInfoTypeForString("UNIT_SETTLER")):
if not bTestVisible:
if (pPlayer.getNumCities() >= FreeCities):

return True
###City Restriction Part 2 End
return False

def canDeclareWar(argsList):
iAttackingTeam, iDefendingTeam = argsList
if iDefendingTeam == 4 or iAttackingTeam == 4:
return False
return True

def loadCustomXML(argsList):
loadEvents("Mods/Realism Invictus/Assets/XML/CustomXML/WarNPeace.xml")

def onBeginGameTurn(argsList):
iGameTurn = argsList[0]
triggerEvents(iGameTurn)

def triggerEvents(iTurn):
iTurn = iTurn+1
iYear = gc.getGame().getTurnYear(iTurn)
if bDebug:CyInterface().addMessage(0,False,15,CyTranslator().getText("trying to trigger at turn "+str(iTurn)+" and year: "+str(iYear),()),'',0,'Art/Interface/Buttons/General/happy_person.dds',ColorTypes(44), 1, 1, True,True)
for item in lApplicableEvents:
if bDebug:
CyInterface().addMessage(0,False,15,CyTranslator().getText("inside loop",()),'',0,'Art/Interface/Buttons/General/happy_person.dds',ColorTypes(44), 1, 1, True,True)
CyInterface().addMessage(0,False,15,str(item.iDate),'',0,'Art/Interface/Buttons/General/happy_person.dds',ColorTypes(44), 1, 1, True,True)
CyInterface().addMessage(0,False,15,str(item.iTurn),'',0,'Art/Interface/Buttons/General/happy_person.dds',ColorTypes(44), 1, 1, True,True)
if (item.iDate==iYear) or (item.iTurn==iTurn) and not(iTurn==-1) and not(iYear==0):
if bDebug:CyInterface().addMessage(0,False,15,CyTranslator().getText("it matches",()),'',0,'Art/Interface/Buttons/General/happy_person.dds',ColorTypes(44), 1, 1, True,True)
if bDebug:CyInterface().addMessage(0,False,15,item.sType,'',0,'Art/Interface/Buttons/General/happy_person.dds',ColorTypes(44), 1, 1, True,True)
iMaxCiv = gc.getMAX_CIV_PLAYERS ()
iAttacker = -1
iDefender = -1
for i in range(iMaxCiv):
curPlayer = gc.getPlayer(i)
iType = curPlayer.getCivilizationType ()
if (gc.getInfoTypeForString(item.sAttacker)==iType):
iAttacker = i
if (gc.getInfoTypeForString(item.sDefender)==iType):
iDefender = i
if (iAttacker!=-1) and (iDefender!=-1):
pAttackerTeam = gc.getTeam(gc.getPlayer(iAttacker).getTeam())
iDefenderTeam = gc.getPlayer(iDefender).getTeam()
pDefenderTeam = gc.getTeam(iDefenderTeam)
bNoPopup = False
if item.sType =="WAR":
if not pAttackerTeam.isAtWar(iDefenderTeam):
pAttackerTeam.declareWar(iDefenderTeam,False,WarPlanTypes.WARPLAN_TOTAL)
bNoPopup = True
pAttackerTeam.setPermanentWarPeace(iDefenderTeam,True)
if item.sType=="PEACE":
if pAttackerTeam.isAtWar(iDefenderTeam):
pAttackerTeam.makePeace(iDefenderTeam)
bNoPopup=True
pAttackerTeam.setPermanentWarPeace(iDefenderTeam,True)
if pAttackerTeam.isHuman() and bNoPopup:
addPopup(item.sMessage,iAttacker)
if pDefenderTeam.isHuman() and bNoPopup:
addPopup(item.sMessage,iDefender)
def addPopup(sText,iPlayer):
if sText!="-1" and iPlayer!=-1:
pPlayer = gc.getPlayer(iPlayer)
popupInfo = CyPopupInfo()
popupInfo.setButtonPopupType(ButtonPopupTypes.BUTTONPOPUP_TEXT)
szText = CyTranslator().getText(sText, ())
popupInfo.setText(szText)
popupInfo.addPopup(iPlayer)


def loadEvents(sFilePath):
del lEvents[:]
MyFile=open(sFilePath)

for CurString in MyFile.readlines():
if "Attacker" in CurString:
CurEvent = Events()
CurEvent.sAttacker = CutString(CurString)
if "Defender" in CurString:
CurEvent.sDefender = CutString(CurString)
if "Type" in CurString:
CurEvent.sType = CutString(CurString)
if "Map" in CurString:
CurEvent.sMap = CutString(CurString)
if "Date" in CurString:
CurEvent.iDate = int(CutString(CurString))

if "Turn" in CurString:
CurEvent.iTurn = int(CutString(CurString))
if "Message" in CurString:
CurEvent.sMessage = CutString(CurString)
lEvents.append(CurEvent)
MyFile.close()
if bDebug: print "all events have been read"
cleanEvents()

def cleanEvents():
del lApplicableEvents[:]
sMapName = getMapname()
iYear = gc.getGame().getGameTurnYear()
iTurn = gc.getGame().getGameTurn ()
lCivs = getCivs()
if bDebug:CyInterface().addMessage(0,False,15,CyTranslator().getText("cleaning",()),'',0,'Art/Interface/Buttons/General/happy_person.dds',ColorTypes(44), 1, 1, True,True)
for item in lEvents:
if item.sMap!=sMapName:continue
if (item.iDate<iYear) and (item.iDate!=0):continue
if (item.iTurn<iTurn) and (item.iTurn!=-1):continue
if bDebug:CyInterface().addMessage(0,False,15,CyTranslator().getText("before civ check",()),'',0,'Art/Interface/Buttons/General/happy_person.dds',ColorTypes(44), 1, 1, True,True)
if (gc.getInfoTypeForString(item.sAttacker) in lCivs) and (gc.getInfoTypeForString(item.sDefender) in lCivs):
lApplicableEvents.append(item)
if bDebug:CyInterface().addMessage(0,False,15,CyTranslator().getText("event is on list",()),'',0,'Art/Interface/Buttons/General/happy_person.dds',ColorTypes(44), 1, 1, True,True)

def getMapname():
MapName = CyMap().getMapScriptName ()
if (".civ" in MapName) or(".Civ" in MapName):
if "civbeyondswordwbsave" in MapName:
MapName = MapName[0:-21]
if "CivBeyondSwordWBSave" in MapName:
MapName = MapName[0:-21]
if "CivWarlordsWBSave" in MapName:
MapName = MapName[0:-18]
if "Civ4WorldBuilderSave" in MapName:
MapName = MapName[0:-21]
if "civ4worldbuildersave" in MapName:
MapName = MapName[0:-21]
return MapName
else:
return "-1"

def getCivs():
iMaxCiv = gc.getMAX_CIV_PLAYERS ()

lCivs = []
del lCivs[:]
for i in range(iMaxCiv):
curPlayer = gc.getPlayer(i)
iType = curPlayer.getCivilizationType ()
lCivs.append(iType)
return lCivs

###generic string cutting function
###first < and > at the end are cut of, then the other
###> and < are searched, and what is between is used as value
def CutString(string):
print "Cutting"
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 Events:
def __init__(self):
self.sAttacker = 0
self.sDefender = 0
self.sType = 0
self.sMap = 0
self.iDate = 0
self.iTurn = 0
self.sMessage = ""
 
Hopefully, it's only a matter of adding an event handler ...
em.addEventHandler('CombatResult', onCombatResult)
... and defining onCombatResult as you've quoted it, just without the self argument. (Maybe there's some difficulty that I'm missing here.)
 
Thank you. I did this, I don't know if I had to copy the whole file def on Combatresult
 

Attachments

  • Screenshot 2024-06-01 203534.jpg
    Screenshot 2024-06-01 203534.jpg
    217 KB · Views: 6
Oh, I see, the logging code is from BtS ... I believe BUG will call CvEventManager.onCombatResult even when an additional handler gets added, i.e. your WarNPeace.onCombatResult. So, you're right, the code from the original CvEventManager shouldn't be copied. Well, the first line ...
Code:
pWinner,pLoser = argsList
... is needed because the Hunter code makes use of those two variables. The logging in the end shouldn't be copied – and also wouldn't work because of the self.__LOG_COMBAT check. So I guess it's only:
Code:
def onCombatResult(argsList):
        pWinner,pLoser = argsList
        ## Hunter Promotion Start ##
        if pLoser.isAnimal():
                if pWinner.isHasPromotion(gc.getInfoTypeForString("PROMOTION_HUNTER")):
                        pPlayer = gc.getPlayer(pWinner.getOwner())
                        Capital = pPlayer.getCapitalCity()
                        Capital.changeFood(pLoser.baseCombatStr() * 3)
        ## Hunter Promotion End ##
 
it doesn't give me errors, but unfortunately when I kill an animal, with a unit with the hunter promotion, it doesn't give me any food in the capital
the original script is this:
 
Last edited:
And I take it that you've added the Promotion XML and still have the addEventHandler line. Can only use print statements then to trace the execution:
Code:
def onCombatResult(argsList):
        print "onCombatResult called"
        pWinner,pLoser = argsList
        ## Hunter Promotion Start ##
        if pLoser.isAnimal():
                print "Animal killed"
                print "Hunter promo ID is " + str(gc.getInfoTypeForString("PROMOTION_HUNTER"))
                if pWinner.isHasPromotion(gc.getInfoTypeForString("PROMOTION_HUNTER")):
                        print "Winner has Hunter promo"
                        pPlayer = gc.getPlayer(pWinner.getOwner())
                        Capital = pPlayer.getCapitalCity()
                        print "Winner capital at " + str(Capital.getX()) + ", " + str(Capital.getY())
                        print "Loser strength: " + str(pLoser.baseCombatStr())
                        Capital.changeFood(pLoser.baseCombatStr() * 3)
        ## Hunter Promotion End ##
The print statements write to PythonDbg.log if LoggingEnabled is set in CivilizationIV.ini. Might be prudent to put one after the addEventHandler call as well, if only to make sure that printing works correctly. (Seems pretty safe to assume that the init function is getting executed.)
 
Top Bottom