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: 6
  • Screenshot 2024-03-01 234707.png
    Screenshot 2024-03-01 234707.png
    223.8 KB · Views: 6
  • Screenshot 2024-03-01 235108.png
    Screenshot 2024-03-01 235108.png
    35.1 KB · Views: 6
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

  • 45487-dawn_of_time_alternate_starts (1).zip
    524.8 KB · Views: 3
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: 5
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: 4
  • Screenshot 2024-03-02 231256.png
    Screenshot 2024-03-02 231256.png
    974.1 KB · Views: 5
  • Screenshot 2024-03-02 231235.png
    Screenshot 2024-03-02 231235.png
    908.8 KB · Views: 5
  • Screenshot 2024-03-02 231152.png
    Screenshot 2024-03-02 231152.png
    775.1 KB · Views: 4
  • Spawncivtest.rar
    8.4 KB · Views: 4
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: 5
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
 
Top Bottom