[Python] Spawn Barbarians in player territory

jkp1187

Unindicted Co-Conspirator
Joined
Aug 29, 2004
Messages
2,496
Location
Pittsburgh, Pennsylvania
Okay, this is for a NextWar random event. When the event is fired, I want Barbarians to spawn inside the player's territory (as this is happening late in the game, there probably won't be many unsettled squares). I'm having trouble getting the event to work at all, so I thought I'd post what I have here and see what you guys thought. Yes, as far as I can tell, all of the event criteria are met.

This is the script that determines whether or not the event will fire. There are no other prerequisites.


Code:
def canTriggerNWTheCylons(argsList):

    kTriggeredData = argsList[0]
    pPlayer = gc.getPlayer(kTriggeredData.ePlayer)
    
#   If Barbarians are disabled in this game, this event will not occur.
    if gc.getGame().isOption(GameOptionTypes.GAMEOPTION_NO_BARBARIANS):
        return false
            
#   At least one civ on the board must know TECH_CYBERNETICS.
    bFoundValid = false
    iTech = CvUtil.findInfoTypeNum(gc.getTechInfo, gc.getNumTechInfos(), 'TECH_CYBERNETICS')
    for iPlayer in range(gc.getMAX_CIV_PLAYERS()):            
        loopPlayer = gc.getPlayer(iPlayer)
        if loopPlayer.isAlive():
            if gc.getTeam(loopPlayer.getTeam()).isHasTech(iTech):
                bFoundValid = true
                break        
    if not bFoundValid:
        return false

#    Find an eligible plot
    map = gc.getMap()    
    for i in range(map.numPlots()):
        plot = map.plotByIndex(i)
        if (plot.getOwner() == pPlayer and not plot.isWater() and not plot.isImpassable()):
            return true

    return false

What am I doing wrong (other than not going to sleep yet)?
 
Code:
    kTriggeredData = argsList[0]
    pPlayer = gc.getPlayer(kTriggeredData.ePlayer)

        if (plot.getOwner() == [COLOR="Red"]pPlayer[/COLOR] and not plot.isWater() and not plot.isImpassable()):
            return true

    return false

plot.getOwner() is an integer so you should test plot.getOwner() == kTriggeredData.ePlayer .

Tcho !
 
plot.getOwner() is an integer so you should test plot.getOwner() == kTriggeredData.ePlayer .

Tcho !

Interesting. I thought kTriggeredData.ePlayer would return an integer (i.e., the list number of the player).

I'll give this a try. Thanks again.
 
Well, your suggestion worked. Thanks.

There is one thing, though: the barbarian units spawn inside the player's territory, but instead of one group of barbarians, TWO groups spawn at two different points.

This isn't bad (at least, not for me -- it's bad for the player!) and I may leave it as-is, but I was wondering why this was happening. Any ideas?


Code:
def applyNWTheCylons1(argsList):
    iEvent = argsList[0]
    kTriggeredData = argsList[1]
    pPlayer = gc.getPlayer(kTriggeredData.ePlayer)

    listPlots = []
    map = gc.getMap()    
    for i in range(map.numPlots()):
        plot = map.plotByIndex(i)
        if (plot.getOwner() == kTriggeredData.ePlayer and not plot.isWater() and not plot.isImpassable() and not plot.isCity() and plot.area().getCitiesPerPlayer(kTriggeredData.ePlayer) > 0):
            listPlots.append(i)
    
    if 0 == len(listPlots):
        return
            
    plot = map.plotByIndex(listPlots[gc.getGame().getSorenRandNum(len(listPlots), "Cylons event location")])
    
    if map.getWorldSize() == CvUtil.findInfoTypeNum(gc.getWorldInfo, gc.getNumWorldInfos(), 'WORLDSIZE_DUEL'):
        iNumUnits  = 1
    elif map.getWorldSize() == CvUtil.findInfoTypeNum(gc.getWorldInfo, gc.getNumWorldInfos(), 'WORLDSIZE_TINY'):
        iNumUnits  = 1
    elif map.getWorldSize() == CvUtil.findInfoTypeNum(gc.getWorldInfo, gc.getNumWorldInfos(), 'WORLDSIZE_SMALL'):
        iNumUnits  = 2
    elif map.getWorldSize() == CvUtil.findInfoTypeNum(gc.getWorldInfo, gc.getNumWorldInfos(), 'WORLDSIZE_STANDARD'):
        iNumUnits  = 3
    elif map.getWorldSize() == CvUtil.findInfoTypeNum(gc.getWorldInfo, gc.getNumWorldInfos(), 'WORLDSIZE_LARGE'):
        iNumUnits  = 4
    else: 
        iNumUnits  = 5
        
    iUnitType = CvUtil.findInfoTypeNum(gc.getUnitInfo, gc.getNumUnitInfos(), 'UNIT_AUTOMATONS')

    barbPlayer = gc.getPlayer(gc.getBARBARIAN_PLAYER())
    for i in range(iNumUnits):
        barbPlayer.initUnit(iUnitType, plot.getX(), plot.getY(), UnitAITypes.UNITAI_ATTACK_CITY_LEMMING, DirectionTypes.DIRECTION_SOUTH)
 
I think you should test if the plot already have units too . Another thing is to change the test with the serial of "and" by doing a serial of "if " . if not "" : continue ... That will improve the time of calculation . The only thing i think is that the event is called two times . perhaps you should add a print at the beginning to check that . It's not a good thing to put the unitAITypes while creating the unit ... you should do unit = bPlayer.initUnit(....,UnitAITypes.NO_UNITAI, ....) then do unit.setUnitAIType(UnitAITypes....)

Tcho !
 
This was an XML glitch on my part. :blush: I had the python callback listed under "Cando" in the XML, not callback, which meant that the event happened twice -- once when it "checked" to see if it could do the event, then the second time when the event was actually chosen.

I think I will add the unit check as you suggested, though. THank you again, sir!


:bowdown:
 
Hi guys,

Im adapting your events JKP1187, but im trying to get my rebel peasants etc to spawn in the radius of the affecting city- not just randomly in the empire.

Hmm,..whats the code for this? Ive bene bashing my head off it for a while, and dammnit i finally caved and came begging for help :/

Regards,
HDK
 
Back
Top Bottom