As part of the B5 mod we have introduced a new Starbase that replaces the standard starbase I for the Earth Alliance. I've gone through Python and looked at everything to do with the construction of a Starbase by a construction unit.
First, this is what the standard Starbase construction Python code looks like in CVFinalFrontierEvents.py
So far so good.
And this is what my version now looks like to try and build the Orion Starbase
I'm fairly sure some of it is correct but but i can't figure out from looking at other bits of Python exactly which parts are right and which are wrong. Is there a program i can download that will at least show me where the problem is? (or better yet, fix the problem).
Alternatively, can someone have a look at what i've done and tell me what my errors are, i'm trying to learn this stuff and i'm a patient man but i also know my limitations and at the moment i'm limited to copying other lines of python so it at least looks like it should work.
Thanks in advance
First, this is what the standard Starbase construction Python code looks like in CVFinalFrontierEvents.py
Spoiler :
Code:
def onUnitBuildImprovement(self, argsList):
'Unit begins enacting a Build (building an Improvement or Route)'
pUnit, iBuild, bFinished = argsList
iBuildStarbaseID = CvUtil.findInfoTypeNum(gc.getBuildInfo,gc.getNumBuildInfos(),'BUILD_STARBASE')
# Starbase WAS built
if (iBuild == iBuildStarbaseID):
pUnit.setScriptData("BuildingStarbase")
def onImprovementBuilt(self, argsList):
'Improvement Built'
iImprovement, iX, iY = argsList
iImprovementStarbaseID = CvUtil.findInfoTypeNum(gc.getImprovementInfo,gc.getNumImprovementInfos(),'IMPROVEMENT_STARBASE')
iUnitConstructShipID = CvUtil.findInfoTypeNum(gc.getUnitInfo,gc.getNumUnitInfos(),'UNIT_CONSTRUCT_SHIP')
# Starbase finished
if (iImprovement == iImprovementStarbaseID):
pPlot = CyMap().plot(iX, iY)
pPlot.setImprovementType(-1)
# Look for Construction Ship on this plot
for iUnitLoop in range(pPlot.getNumUnits()):
pUnit = pPlot.getUnit(iUnitLoop)
if (pUnit.getScriptData() == "BuildingStarbase"):
self.doMakeStarbase(pUnit.getOwner(), iX, iY)
self.aiKillTimerData = [3, pUnit.getOwner(), pUnit.getID()]
# pUnit.kill(true, -1)
def doMakeStarbase(self, iPlayer, iX, iY):
pPlayer = gc.getPlayer(iPlayer)
pPlot = CyMap().plot(iX, iY)
# Create Starbase Unit
iUnitStarbaseID = CvUtil.findInfoTypeNum(gc.getUnitInfo,gc.getNumUnitInfos(),'UNIT_STARBASE_I')
pPlayer.initUnit(iUnitStarbaseID, iX, iY, UnitAITypes.UNITAI_ATTACK, DirectionTypes.NO_DIRECTION)
self.updateStarbaseCulture(iPlayer, iX, iY)
def updateStarbaseCulture(self, iPlayer, iX, iY):
# Create culture around unit
for iXLoop in range(iX-2, iX+3):
for iYLoop in range(iY-2, iY+3):
iActiveX = iXLoop
iActiveY = iYLoop
if (iActiveX < 0):
iActiveX = CyMap().getGridWidth() + iActiveX
if (iActiveY < 0):
iActiveY = CyMap().getGridHeight() + iActiveY
pLoopPlot = CyMap().plot(iActiveX, iActiveY)
# pPlotLoop = CyMap().plot(iXLoop, iYLoop)
# printd("Setting Player %d as the owner of %d, %d" %(iPlayer, iXLoop, iYLoop))
# Don't override culture that's already here
if (pLoopPlot.getOwner() == -1):
pLoopPlot.setOwnerNoUnitCheck(iPlayer)
def updateAllStarbases(self):
# Update Starbase culture
iUnitStarbaseID = CvUtil.findInfoTypeNum(gc.getUnitInfo,gc.getNumUnitInfos(),'UNIT_STARBASE_I')
iUnitStarbaseIID = CvUtil.findInfoTypeNum(gc.getUnitInfo,gc.getNumUnitInfos(),'UNIT_STARBASE_II')
iUnitStarbaseIIID = CvUtil.findInfoTypeNum(gc.getUnitInfo,gc.getNumUnitInfos(),'UNIT_STARBASE_III')
iUnitMissileI = CvUtil.findInfoTypeNum(gc.getUnitInfo,gc.getNumUnitInfos(),'UNIT_MISSILE_I')
iUnitMissileII = CvUtil.findInfoTypeNum(gc.getUnitInfo,gc.getNumUnitInfos(),'UNIT_MISSILE_II')
iUnitMissileIII = CvUtil.findInfoTypeNum(gc.getUnitInfo,gc.getNumUnitInfos(),'UNIT_MISSILE_III')
# List made to preserve culture of units built first
aaiStarbaseList = []
for iPlayerLoop in range(gc.getMAX_CIV_PLAYERS()):
pPlayer = gc.getPlayer(iPlayerLoop)
pTeam = gc.getTeam(pPlayer.getTeam())
pyPlayer = PyPlayer(iPlayerLoop)
iUnitToCreate = -1
aiPossibleUnitList = [iUnitMissileI, iUnitMissileII, iUnitMissileIII]
for iUnitLoop in aiPossibleUnitList:
pUnitInfo = gc.getUnitInfo(iUnitLoop)
iNeededTech = pUnitInfo.getPrereqAndTech()
if (pTeam.isHasTech(iNeededTech)):
iUnitToCreate = iUnitLoop
apUnitList = pyPlayer.getUnitList()
for pUnitLoop in apUnitList:
if (pUnitLoop.getUnitType() == iUnitStarbaseID or pUnitLoop.getUnitType() == iUnitStarbaseIID or pUnitLoop.getUnitType() == iUnitStarbaseIIID):
aaiStarbaseList.append([pUnitLoop.getGameTurnCreated(), iPlayerLoop, pUnitLoop.getX(), pUnitLoop.getY()])
# Need appropriate tech to create Missile
if (iUnitToCreate != -1):
# Need appropriate turn to create
iTurnCreated = pUnitLoop.getGameTurnCreated()
iCurrentTurn = CyGame().getGameTurn()
if (iTurnCreated != iCurrentTurn):
iTurnsSinceCreation = iCurrentTurn - iTurnCreated
# Produce Missile every 15 turns
if (iTurnsSinceCreation % 15 == 0):
print "UnitID: %d, X: %d, Y: %d" %(iUnitToCreate, pUnitLoop.getX(), pUnitLoop.getY())
pUnit = pPlayer.initUnit(iUnitToCreate, pUnitLoop.getX(), pUnitLoop.getY(), UnitAITypes.NO_UNITAI, DirectionTypes.NO_DIRECTION)
# Load Missile onto Starbase... the C++ doesn't like this but it can deal :)
pUnit.setTransportUnit(pUnitLoop)
# printd("\n\nXXX: There are %d Starbases on the map" %(len(aaiStarbaseList)))
# printd(aaiStarbaseList)
if (len(aaiStarbaseList) > 0):
# Make order such that units built first get culture preference
aaiStarbaseList.sort()
# aaiStarbaseList.reverse()
for iStarbaseLoop in range(len(aaiStarbaseList)):
self.updateStarbaseCulture(aaiStarbaseList[iStarbaseLoop][1], aaiStarbaseList[iStarbaseLoop][2], aaiStarbaseList[iStarbaseLoop][3])
def canBuildStarbase(self, pPlot, iOffset=0):
# Starbase restriction
iBuildStarbase = CvUtil.findInfoTypeNum(gc.getBuildInfo,gc.getNumBuildInfos(),'BUILD_STARBASE')
# Can't build on a Solar System
iFeatureIDSolarSystem = CvUtil.findInfoTypeNum(gc.getFeatureInfo,gc.getNumFeatureInfos(),'FEATURE_SOLAR_SYSTEM')
if (pPlot.getFeatureType() == iFeatureIDSolarSystem):
return 0
# Can't build on top of another Starbase
iUnitStarbaseI = CvUtil.findInfoTypeNum(gc.getUnitInfo,gc.getNumUnitInfos(),'UNIT_STARBASE_I')
iUnitStarbaseII = CvUtil.findInfoTypeNum(gc.getUnitInfo,gc.getNumUnitInfos(),'UNIT_STARBASE_II')
iUnitStarbaseIII = CvUtil.findInfoTypeNum(gc.getUnitInfo,gc.getNumUnitInfos(),'UNIT_STARBASE_III')
iNumUnits = iOffset # Offset so that Interface can disable button
# Loop through all units on the plot
for iUnitLoop in range(pPlot.getNumUnits()):
pUnit = pPlot.getUnit(iUnitLoop)
# Can't build on top of another Starbase
if (pUnit.getUnitType() == iUnitStarbaseI or pUnit.getUnitType() == iUnitStarbaseII or pUnit.getUnitType() == iUnitStarbaseIII):
return 0
# if there are any Construction Ships already building a Starbase then disallow more
if (pUnit.getBuildType() == iBuildStarbase):
iNumUnits += 1
if (iNumUnits > 1): # Account for the one unit actually performing the mission
return 0
return 1
So far so good.
And this is what my version now looks like to try and build the Orion Starbase
Spoiler :
Code:
def onUnitBuildImprovement(self, argsList):
'Unit begins enacting a Build (building an Improvement or Route)'
pUnit, iBuild, bFinished = argsList
iBuildStarbaseID = CvUtil.findInfoTypeNum(gc.getBuildInfo,gc.getNumBuildInfos(),'BUILD_STARBASE')
iBuildOrionStarbaseD = CvUtil.findInfoTypeNum(gc.getBuildInfo,gc.getNumBuildInfos(),'BUILD_ORION_STARBASE')
# Starbase WAS built
if (iBuild == iBuildStarbaseID):
pUnit.setScriptData("BuildingStarbase")
def onImprovementBuilt(self, argsList):
'Improvement Built'
iImprovement, iX, iY = argsList
iImprovementStarbaseID = CvUtil.findInfoTypeNum(gc.getImprovementInfo,gc.getNumImprovementInfos(),'IMPROVEMENT_STARBASE')
iImprovementOrionStarbaseD = CvUtil.findInfoTypeNum(gc.getImprovementInfo,gc.getNumImprovementInfos(),'IMPROVEMENT_ORION_STARBASE')
iUnitConstructShipID = CvUtil.findInfoTypeNum(gc.getUnitInfo,gc.getNumUnitInfos(),'UNIT_CONSTRUCT_SHIP')
# Starbase finished
if (iImprovement() == iImprovementStarbaseID or iImprovement() == iImprovementOrionStarbaseD):
pPlot = CyMap().plot(iX, iY)
pPlot.setImprovementType(-1)
# Look for Construction Ship on this plot
for iUnitLoop in range(pPlot.getNumUnits()):
pUnit = pPlot.getUnit(iUnitLoop)
if (pUnit.getScriptData() == "BuildingStarbase"):
self.doMakeStarbase(pUnit.getOwner(), iX, iY)
self.aiKillTimerData = [3, pUnit.getOwner(), pUnit.getID()]
# pUnit.kill(true, -1)
def doMakeStarbase(self, iPlayer, iX, iY):
pPlayer = gc.getPlayer(iPlayer)
pPlot = CyMap().plot(iX, iY)
# Create Starbase Unit
iUnitStarbaseID = CvUtil.findInfoTypeNum(gc.getUnitInfo,gc.getNumUnitInfos(),'UNIT_STARBASE_I')
iUnitOrionStarbaseD = CvUtil.findInfoTypeNum(gc.getUnitInfo,gc.getNumUnitInfos(),'UNIT_ORION_STARBASE')
pPlayer.initUnit(iUnitStarbaseID, iX, iY, UnitAITypes.UNITAI_ATTACK, DirectionTypes.NO_DIRECTION)
pPlayer.initUnit(iUnitOrionStarbaseD, iX, iY, UnitAITypes.UNITAI_ATTACK, DirectionTypes.NO_DIRECTION)
self.updateStarbaseCulture(iPlayer, iX, iY)
def updateStarbaseCulture(self, iPlayer, iX, iY):
# Create culture around unit
for iXLoop in range(iX-2, iX+3):
for iYLoop in range(iY-2, iY+3):
iActiveX = iXLoop
iActiveY = iYLoop
if (iActiveX < 0):
iActiveX = CyMap().getGridWidth() + iActiveX
if (iActiveY < 0):
iActiveY = CyMap().getGridHeight() + iActiveY
pLoopPlot = CyMap().plot(iActiveX, iActiveY)
# pPlotLoop = CyMap().plot(iXLoop, iYLoop)
# printd("Setting Player %d as the owner of %d, %d" %(iPlayer, iXLoop, iYLoop))
# Don't override culture that's already here
if (pLoopPlot.getOwner() == -1):
pLoopPlot.setOwnerNoUnitCheck(iPlayer)
def updateAllStarbases(self):
# Update Starbase culture
iUnitStarbaseID = CvUtil.findInfoTypeNum(gc.getUnitInfo,gc.getNumUnitInfos(),'UNIT_STARBASE_I')
iUnitOrionStarbaseD = CvUtil.findInfoTypeNum(gc.getUnitInfo,gc.getNumUnitInfos(),'UNIT_ORION_STARBASE')
iUnitStarbaseIID = CvUtil.findInfoTypeNum(gc.getUnitInfo,gc.getNumUnitInfos(),'UNIT_STARBASE_II')
iUnitStarbaseIIID = CvUtil.findInfoTypeNum(gc.getUnitInfo,gc.getNumUnitInfos(),'UNIT_STARBASE_III')
iUnitMissileI = CvUtil.findInfoTypeNum(gc.getUnitInfo,gc.getNumUnitInfos(),'UNIT_MISSILE_I')
iUnitMissileII = CvUtil.findInfoTypeNum(gc.getUnitInfo,gc.getNumUnitInfos(),'UNIT_MISSILE_II')
iUnitMissileIII = CvUtil.findInfoTypeNum(gc.getUnitInfo,gc.getNumUnitInfos(),'UNIT_MISSILE_III')
# List made to preserve culture of units built first
aaiStarbaseList = []
for iPlayerLoop in range(gc.getMAX_CIV_PLAYERS()):
pPlayer = gc.getPlayer(iPlayerLoop)
pTeam = gc.getTeam(pPlayer.getTeam())
pyPlayer = PyPlayer(iPlayerLoop)
iUnitToCreate = -1
aiPossibleUnitList = [iUnitMissileI, iUnitMissileII, iUnitMissileIII]
for iUnitLoop in aiPossibleUnitList:
pUnitInfo = gc.getUnitInfo(iUnitLoop)
iNeededTech = pUnitInfo.getPrereqAndTech()
if (pTeam.isHasTech(iNeededTech)):
iUnitToCreate = iUnitLoop
apUnitList = pyPlayer.getUnitList()
for pUnitLoop in apUnitList:
if (pUnitLoop.getUnitType() == iUnitStarbaseID or pUnitLoop.getUnitType() == iUnitOrionStarbaseD or pUnitLoop.getUnitType() == iUnitStarbaseIID or pUnitLoop.getUnitType() == iUnitStarbaseIIID):
aaiStarbaseList.append([pUnitLoop.getGameTurnCreated(), iPlayerLoop, pUnitLoop.getX(), pUnitLoop.getY()])
# Need appropriate tech to create Missile
if (iUnitToCreate != -1):
# Need appropriate turn to create
iTurnCreated = pUnitLoop.getGameTurnCreated()
iCurrentTurn = CyGame().getGameTurn()
if (iTurnCreated != iCurrentTurn):
iTurnsSinceCreation = iCurrentTurn - iTurnCreated
# Produce Missile every 15 turns
if (iTurnsSinceCreation % 15 == 0):
print "UnitID: %d, X: %d, Y: %d" %(iUnitToCreate, pUnitLoop.getX(), pUnitLoop.getY())
pUnit = pPlayer.initUnit(iUnitToCreate, pUnitLoop.getX(), pUnitLoop.getY(), UnitAITypes.NO_UNITAI, DirectionTypes.NO_DIRECTION)
# Load Missile onto Starbase... the C++ doesn't like this but it can deal :)
pUnit.setTransportUnit(pUnitLoop)
# printd("\n\nXXX: There are %d Starbases on the map" %(len(aaiStarbaseList)))
# printd(aaiStarbaseList)
if (len(aaiStarbaseList) > 0):
# Make order such that units built first get culture preference
aaiStarbaseList.sort()
# aaiStarbaseList.reverse()
for iStarbaseLoop in range(len(aaiStarbaseList)):
self.updateStarbaseCulture(aaiStarbaseList[iStarbaseLoop][1], aaiStarbaseList[iStarbaseLoop][2], aaiStarbaseList[iStarbaseLoop][3])
def canBuildStarbase(self, pPlot, iOffset=0):
# Starbase restriction
iBuildStarbase = CvUtil.findInfoTypeNum(gc.getBuildInfo,gc.getNumBuildInfos(),'BUILD_STARBASE')
iBuildOrionStarbase = CvUtil.findInfoTypeNum(gc.getBuildInfo,gc.getNumBuildInfos(),'BUILD_ORION_STARBASE')
# Can't build on a Solar System
iFeatureIDSolarSystem = CvUtil.findInfoTypeNum(gc.getFeatureInfo,gc.getNumFeatureInfos(),'FEATURE_SOLAR_SYSTEM')
if (pPlot.getFeatureType() == iFeatureIDSolarSystem):
return 0
# Can't build on top of another Starbase
iUnitStarbaseI = CvUtil.findInfoTypeNum(gc.getUnitInfo,gc.getNumUnitInfos(),'UNIT_STARBASE_I',)
iUnitOrionStarbase = CvUtil.findInfoTypeNum(gc.getUnitInfo,gc.getNumUnitInfos(),'UNIT_ORION_STARBASE',)
iUnitStarbaseII = CvUtil.findInfoTypeNum(gc.getUnitInfo,gc.getNumUnitInfos(),'UNIT_STARBASE_II')
iUnitStarbaseIII = CvUtil.findInfoTypeNum(gc.getUnitInfo,gc.getNumUnitInfos(),'UNIT_STARBASE_III')
iNumUnits = iOffset # Offset so that Interface can disable button
# Loop through all units on the plot
for iUnitLoop in range(pPlot.getNumUnits()):
pUnit = pPlot.getUnit(iUnitLoop)
# Can't build on top of another Starbase
if (pUnit.getUnitType() == iUnitStarbaseI or pUnit.getUnitType()== iUnitOrionStarbase or pUnit.getUnitType() == iUnitStarbaseII or pUnit.getUnitType() == iUnitStarbaseIII):
return 0
# if there are any Construction Ships already building a Starbase then disallow more
if (pUnit.getBuildType() == iBuildStarbase or pUnit.getBuildType()== iBuildOrionStarbase):
iNumUnits += 1
if (iNumUnits > 1): # Account for the one unit actually performing the mission
return 0
return 1
I'm fairly sure some of it is correct but but i can't figure out from looking at other bits of Python exactly which parts are right and which are wrong. Is there a program i can download that will at least show me where the problem is? (or better yet, fix the problem).
Alternatively, can someone have a look at what i've done and tell me what my errors are, i'm trying to learn this stuff and i'm a patient man but i also know my limitations and at the moment i'm limited to copying other lines of python so it at least looks like it should work.
Thanks in advance