Пример #1
0
    def checkTurn(self, iGameTurn):

        for i in range(iNumTotalPlayers + 1):
            if (gc.getPlayer(i).isAlive()):
                iCountdown = sd.getPlagueCountdown(i)
                if (iCountdown > 0):
                    iCountdown -= 1
                    sd.setPlagueCountdown(i, iCountdown)
                    if (iCountdown == 2):
                        self.preStopPlague(i)
                    if (iCountdown == 0):
                        self.stopPlague(i)
                elif (iCountdown < 0):
                    sd.setPlagueCountdown(i, iCountdown + 1)

        for i in range(iNumPlagues):
            if (iGameTurn == sd.getGenericPlagueDates(i)):
                self.startPlague(i)

            #retry if the epidemic is dead too quickly
            if iGameTurn == sd.getGenericPlagueDates(i) + 4 and i > 0:
                iInfectedCounter = 0
                for j in range(iNumTotalPlayers + 1):
                    if (gc.getPlayer(j).isAlive()
                            and sd.getPlagueCountdown(j) > 0):
                        iInfectedCounter += 1
                if (iInfectedCounter <= 1):
                    self.startPlague(i)
Пример #2
0
    def onCityRazed(self, argsList):
        city, iNewOwner = argsList

        if (city.getNumRealBuilding(iPlague) > 0):
            if (sd.getPlagueCountdown(iNewOwner) > 0):
                apCityList = PyPlayer(iNewOwner).getCityList()
                iNumCitiesInfected = 0
                for pCity in apCityList:
                    otherCity = pCity.GetCy()
                    if (otherCity.getX() != city.getX()
                            or otherCity.getY() != city.getY()
                        ):  #because the city razed still has the plague
                        if (otherCity.getNumRealBuilding(iPlague) > 0):
                            iNumCitiesInfected += 1
                if (iNumCitiesInfected == 0):
                    sd.setPlagueCountdown(
                        iNewOwner,
                        0)  #undo spreadPlague called in onCityAcquired()
Пример #3
0
    def onCityAcquired(self, iOldOwner, iNewOwner, city):

        if (city.getNumRealBuilding(iPlague) > 0):
            if (
                    sd.getPlagueCountdown(iNewOwner) <= 0
                    and gc.getGame().getGameTurn() > getTurnForYear(
                        con.tBirth[iNewOwner]) + utils.getTurns(iImmunity)
            ):  #skip immunity in this case (to prevent expoiting of being immune to conquer weak civs), but not for the new born civs
                self.spreadPlague(iNewOwner)
                apCityList = PyPlayer(iNewOwner).getCityList()
                for pCity in apCityList:
                    cityNear = pCity.GetCy()
                    if (utils.calculateDistance(city.getX(), city.getY(),
                                                cityNear.getX(),
                                                cityNear.getY()) <= 3):
                        self.infectCity(cityNear)
                return
            city.setNumRealBuilding(iPlague, 0)
Пример #4
0
    def isVulnerable(self, iPlayer):

        iCountdown = sd.getPlagueCountdown(iPlayer)  # less pickling

        if (iPlayer >= iNumPlayers):
            if (iCountdown <= 0 and iCountdown > -10):  #more vulnerable
                return True
        else:
            pPlayer = gc.getPlayer(iPlayer)
            if (iCountdown == 0):  #vulnerable
                #if (not gc.getTeam(pPlayer.getTeam()).isHasTech(con.iSanitation)):
                iHealth = -30
                if (pPlayer.calculateTotalCityHealthiness() > 0):
                    iHealth = int((1.0 * pPlayer.calculateTotalCityHealthiness()) / (pPlayer.calculateTotalCityHealthiness() + \
                     pPlayer.calculateTotalCityUnhealthiness()) * 100) - 60
                if (iHealth < 15):  #no spread for iHealth >= 75 years
                    return True
            return False
Пример #5
0
    def checkGrid(self, iCiv):

        pCiv = gc.getPlayer(iCiv)
        tCiv = gc.getTeam(pCiv.getTeam())
        lTargetCivs = []

        #clean it, sometimes it takes old values in memory
        for k in range(iNumTotalPlayers):
            lTargetCivs.append(0)

        #set alive civs to 1 to differentiate them from dead civs
        for k in range(iNumTotalPlayers):
            if gc.getPlayer(k).isAlive() and tCiv.isHasMet(k):
                lTargetCivs[k] = 1

        #set master or vassal to 0
        for k in range(iNumPlayers):
            if gc.getTeam(gc.getPlayer(k).getTeam()).isVassal(
                    iCiv) or tCiv.isVassal(k):
                lTargetCivs[k] = 0

        #if already at war
        for k in range(iNumTotalPlayers):
            if tCiv.isAtWar(k):
                lTargetCivs[k] = 0

        lTargetCivs[iCiv] = 0

        #edead: changed Rhye's code to Regions (provinces)
        map = CyMap()
        for i in range(map.numPlots()):
            plot = map.plotByIndex(i)
            if plot.isCity():
                iOwner = plot.getOwner()
                if iOwner >= 0 and iOwner < iNumTotalPlayers and iOwner != iCiv:
                    if lTargetCivs[iOwner] > 0:
                        regionID = plot.getRegionID()
                        if regionID in utils.getCoreRegions(iCiv):
                            lTargetCivs[iOwner] += 10
                        elif regionID in utils.getNormalRegions(iCiv):
                            lTargetCivs[iOwner] += 5
                        elif regionID in utils.getBroaderRegions(iCiv):
                            lTargetCivs[iOwner] += 2

        #srpt: important war
        if utils.getYear() >= -250 and utils.getYear() < -150:
            if iCiv == con.iRome:
                lTargetCivs[con.iCarthage] += 30
            elif iCiv == con.iCarthage:
                lTargetCivs[con.iRome] += 30

        #srpt: important war
        if utils.getYear() >= -400 and utils.getYear() < -300:
            if iCiv == con.iMacedon:
                lTargetCivs[con.iAthens] += 30
            elif iCiv == con.iAthens:
                lTargetCivs[con.iMacedon] += 30

        #srpt: important war
        if utils.getYear() >= -350 and utils.getYear() < -300:
            if iCiv == con.iQin:
                lTargetCivs[con.iJinState] += 30
            elif iCiv == con.iJinState:
                lTargetCivs[con.iQin] += 30

        #there are other routines for this
        lTargetCivs[iIndependent1] /= 3
        lTargetCivs[iIndependent2] /= 3
        lTargetCivs[iIndependent3] /= 3
        lTargetCivs[iIndependent4] /= 3

        #no random silly wars - edead
        for k in range(iNumTotalPlayers):
            if lTargetCivs[k] == 1:
                lTargetCivs[k] = 0

        print("AIWars grid for ", iCiv)
        print(lTargetCivs)

        #normalization
        iMaxTempValue = -1
        for k in range(iNumTotalPlayers):
            if (lTargetCivs[k] > iMaxTempValue):
                iMaxTempValue = lTargetCivs[k]
        if (iMaxTempValue > 0):
            for k in range(iNumTotalPlayers):
                if (lTargetCivs[k] > 0):
                    lTargetCivs[k] = lTargetCivs[k] * 500 / iMaxTempValue

        print(lTargetCivs)

        for iLoopCiv in range(iNumTotalPlayers):

            if (lTargetCivs[iLoopCiv] <= 0):
                continue

            #add a random value
            if (lTargetCivs[iLoopCiv] <= iThreshold):
                lTargetCivs[iLoopCiv] += gc.getGame().getSorenRandNum(
                    100, 'random modifier')
            if (lTargetCivs[iLoopCiv] > iThreshold):
                lTargetCivs[iLoopCiv] += gc.getGame().getSorenRandNum(
                    300, 'random modifier')

            #balanced with attitude
            attitude = 2 * (pCiv.AI_getAttitude(iLoopCiv) - 2)
            if (attitude > 0):
                lTargetCivs[iLoopCiv] /= attitude

            #exploit plague
            if iLoopCiv < iNumPlayers:
                if (sd.getPlagueCountdown(iLoopCiv) > 0
                        or sd.getPlagueCountdown(iLoopCiv) < -10
                        and not (gc.getGame().getGameTurn() <= getTurnForYear(
                            con.tBirth[iLoopCiv]) + utils.getTurns(20))):
                    lTargetCivs[iLoopCiv] *= 3
                    lTargetCivs[iLoopCiv] /= 2

            #balanced with master's attitude
            for j in range(iNumTotalPlayers):
                if (tCiv.isVassal(j)):
                    attitude = 2 * (gc.getPlayer(j).AI_getAttitude(iLoopCiv) -
                                    2)
                    if (attitude > 0):
                        lTargetCivs[iLoopCiv] /= attitude

            #if already at war
            if (not tCiv.isAtWar(iLoopCiv)):
                #consider peace counter
                iCounter = min(7, max(1, tCiv.AI_getAtPeaceCounter(iLoopCiv)))
                if (iCounter <= 7):
                    lTargetCivs[iLoopCiv] *= 20 + 10 * iCounter
                    lTargetCivs[iLoopCiv] /= 100

            #if under pact
            if (tCiv.isDefensivePact(iLoopCiv)):
                lTargetCivs[iLoopCiv] /= 4

            #if friend of a friend
##					for jLoopCiv in range( iNumTotalPlayers ):
##						if (tCiv.isDefensivePact(jLoopCiv) and gc.getTeam(gc.getPlayer(iLoopCiv).getTeam()).isDefensivePact(jLoopCiv)):
##							lTargetCivs[iLoopCiv] /= 2

        print(lTargetCivs)

        #find max
        iMaxValue = 0
        iTargetCiv = -1
        for iLoopCiv in range(iNumTotalPlayers):
            if (lTargetCivs[iLoopCiv] > iMaxValue):
                iMaxValue = lTargetCivs[iLoopCiv]
                iTargetCiv = iLoopCiv

        print("maxvalue", iMaxValue)
        print("target civ", iTargetCiv)

        if (iMaxValue >= iMinValue):
            return iTargetCiv
        return -1
Пример #6
0
    def chooseAttackingPlayer(self):
        #finding max teams ever alive (countCivTeamsEverAlive() doesn't work as late human starting civ gets killed every turn)
        iMaxCivs = iNumPlayers
        for i in range(iNumPlayers):
            j = iNumPlayers - 1 - i
            if (gc.getPlayer(j).isAlive()):
                iMaxCivs = j
                break
        #print ("iMaxCivs", iMaxCivs)

        if (gc.getGame().countCivPlayersAlive() <= 3):
            return -1
        else:
            iRndnum = gc.getGame().getSorenRandNum(iMaxCivs,
                                                   'attacking civ index')

            # Important war: Carthage vs. Rome
            if utils.getYear() >= -250 and utils.getYear() < -150:
                if gc.getPlayer(con.iRome).isAlive() and gc.getPlayer(
                        con.iCarthage).isAlive():
                    if not gc.getTeam(gc.getPlayer(
                            con.iRome).getTeam()).isAtWar(con.iCarthage):
                        if gc.getPlayer(con.iRome) != utils.getHumanID():
                            iRndnum = con.iRome
                        elif gc.getPlayer(con.iCarthage) != utils.getHumanID():
                            iRndnum = con.iCarthage

            # Important war: Macedon vs. Athens
            if utils.getYear() >= -400 and utils.getYear() < -300:
                if gc.getPlayer(con.iMacedon).isAlive() and gc.getPlayer(
                        con.iAthens).isAlive():
                    if not gc.getTeam(gc.getPlayer(
                            con.iMacedon).getTeam()).isAtWar(con.iAthens):
                        if gc.getPlayer(con.iMacedon) != utils.getHumanID():
                            iRndnum = con.iMacedon
                        elif gc.getPlayer(con.iAthens) != utils.getHumanID():
                            iRndnum = con.iAthens
                            iRndnum = con.iCarthage

            # Important war: Qin vs. Jin
            if utils.getYear() >= -350 and utils.getYear() < -300:
                if gc.getPlayer(con.iQin).isAlive() and gc.getPlayer(
                        con.iJinState).isAlive():
                    if not gc.getTeam(gc.getPlayer(
                            con.iQin).getTeam()).isAtWar(con.iJinState):
                        if gc.getPlayer(con.iQin) != utils.getHumanID():
                            iRndnum = con.iQin
                        elif gc.getPlayer(con.iJinState) != utils.getHumanID():
                            iRndnum = con.iJinState

            #print ("iRndnum", iRndnum)
            iAlreadyAttacked = -100
            iMin = 100
            iCiv = -1
            for i in range(iRndnum, iRndnum + iMaxCivs):
                iLoopCiv = i % iMaxCivs
                pLoopPlayer = gc.getPlayer(iLoopCiv)
                if (pLoopPlayer.isAlive() and not pLoopPlayer.isHuman()):
                    if (sd.getPlagueCountdown(iLoopCiv) >= -10
                            and sd.getPlagueCountdown(iLoopCiv) <= 0
                        ):  #civ is not under plague or quit recently from it
                        iAlreadyAttacked = sd.getAttackingCivsArray(iLoopCiv)
                        if (utils.isAVassal(iLoopCiv)):
                            iAlreadyAttacked += 1  #less likely to attack
                        #check if a world war is already in place
                        iNumAlreadyWar = 0
                        tLoopCiv = gc.getTeam(pLoopPlayer.getTeam())
                        for kLoopCiv in range(iNumPlayers):
                            if (tLoopCiv.isAtWar(kLoopCiv)):
                                if gc.getPlayer(kLoopCiv).isAlive():
                                    iNumAlreadyWar += 1
                        if (iNumAlreadyWar >= 4):
                            iAlreadyAttacked += 2  #much less likely to attack
                        elif (iNumAlreadyWar >= 2):
                            iAlreadyAttacked += 1  #less likely to attack

                        if (iAlreadyAttacked < iMin):
                            iMin = iAlreadyAttacked
                            iCiv = iLoopCiv
                #print ("attacking civ", iCiv)
                if (iAlreadyAttacked != -100):
                    sd.setAttackingCivsArray(iCiv, iAlreadyAttacked + 1)
                    return iCiv
                else:
                    return -1
        return -1
Пример #7
0
    def checkPlayerTurn(self, iGameTurn, iPlayer):

        if (iPlayer < iNumTotalPlayers + 1):
            if (sd.getPlagueCountdown(iPlayer) > 0):
                self.processPlague(iPlayer)
Пример #8
0
    def processPlague(self, iPlayer):

        pPlayer = gc.getPlayer(iPlayer)
        #first spread to close locations
        cityList = []  #see below
        apCityList = PyPlayer(iPlayer).getCityList()
        for pCity in apCityList:
            city = pCity.GetCy()
            cityList.append(city)  #see below
            if (city.getNumRealBuilding(iPlague) > 0):
                #print ("plague in city", city.getName())
                if (city.getPopulation() > 1):
                    #print("healthRate in city", 35 + 5*city.healthRate(False, 0))
                    if utils.getYear() < 1250:
                        iMin = 80
                    elif city.plot().getRegionID() in con.lBlackDeathRegions:
                        if city.getOwner() in con.lBlackDeathSurvivors:
                            iMin = 80
                        else:
                            iMin = 50
                    else:
                        iMin = 90
                    if (gc.getGame().getSorenRandNum(100, 'roll') >
                            iMin + 5 * city.healthRate(False, 0)):
                        city.changePopulation(-1)
                if (city.isCapital()):  #delete in vanilla
                    for iLoopCiv in range(iNumPlayers):
                        if (gc.getTeam(pPlayer.getTeam()).isVassal(iLoopCiv) or \
                        gc.getTeam(gc.getPlayer(iLoopCiv).getTeam()).isVassal(iPlayer)):
                            if (
                                    gc.getPlayer(iLoopCiv).getNumCities() > 0
                            ):  #this check is needed, otherwise game crashes
                                capital = gc.getPlayer(
                                    iLoopCiv).getCapitalCity()
                                if (self.isVulnerable(iLoopCiv) == True):
                                    if (sd.getPlagueCountdown(iPlayer) >
                                            2):  #don't spread the last turns
                                        self.spreadPlague(iLoopCiv)
                                        self.infectCity(capital)
                                        #print ("infect master/vassal", city.getName(), "to", capital.getName())
                for x in range(city.getX() - 2, city.getX() + 3):
                    for y in range(city.getY() - 2, city.getY() + 3):
                        ##print ("plagueXY", x, y)
                        pCurrent = gc.getMap().plot(x, y)
                        if (pCurrent.getOwner() != iPlayer
                                and pCurrent.getOwner() >= 0):
                            if (sd.getPlagueCountdown(iPlayer) >
                                    2):  #don't spread the last turns
                                if (self.isVulnerable(
                                        pCurrent.getOwner()) == True):
                                    self.spreadPlague(pCurrent.getOwner())
                                    self.infectCitiesNear(
                                        pCurrent.getOwner(), x, y)
                                    #print ("infect foreign near", city.getName())
                        else:
                            if (pCurrent.isCity()
                                    and not (x == city.getX()
                                             and y == city.getY())):
                                #print ("is city", x, y)
                                cityNear = pCurrent.getPlotCity()
                                if (not cityNear.getNumRealBuilding(iPlague) >
                                        0):
                                    if (sd.getPlagueCountdown(iPlayer) >
                                            2):  #don't spread the last turns
                                        self.infectCity(cityNear)
                                        #print ("infect near", city.getName(), "to", cityNear.getName())
                            else:
                                if (x == city.getX() and y == city.getY()):
                                    self.killUnitsByPlague(
                                        city, pCurrent, 0, 42, 2)
                                else:
                                    if (pCurrent.isRoute()):
                                        self.killUnitsByPlague(
                                            city, pCurrent, 10, 35, 0)
                                    elif (pCurrent.isWater()):
                                        self.killUnitsByPlague(
                                            city, pCurrent, 30, 35, 0)
                                    else:
                                        self.killUnitsByPlague(
                                            city, pCurrent, 30, 35, 0)
                for x in range(city.getX() - 3, city.getX() + 4):
                    pCurrent = gc.getMap().plot(x, city.getY() - 3)
                    if (pCurrent.getOwner() == iPlayer
                            or not pCurrent.isOwned()):
                        if (not pCurrent.isCity()):
                            if (pCurrent.isRoute() or pCurrent.isWater()):
                                self.killUnitsByPlague(city, pCurrent, 30, 35,
                                                       0)
                    pCurrent = gc.getMap().plot(x, city.getY() + 4)
                    if (pCurrent.getOwner() == iPlayer
                            or not pCurrent.isOwned()):
                        if (not pCurrent.isCity()):
                            if (pCurrent.isRoute() or pCurrent.isWater()):
                                self.killUnitsByPlague(city, pCurrent, 30, 35,
                                                       0)
                for y in range(city.getY() - 2, city.getY() + 3):
                    pCurrent = gc.getMap().plot(city.getX() - 3, y)
                    if (pCurrent.getOwner() == iPlayer
                            or not pCurrent.isOwned()):
                        if (not pCurrent.isCity()):
                            if (pCurrent.isRoute() or pCurrent.isWater()):
                                self.killUnitsByPlague(city, pCurrent, 30, 35,
                                                       0)
                    pCurrent = gc.getMap().plot(city.getX() + 4, y)
                    if (pCurrent.getOwner() == iPlayer
                            or not pCurrent.isOwned()):
                        if (not pCurrent.isCity()):
                            if (pCurrent.isRoute() or pCurrent.isWater()):
                                self.killUnitsByPlague(city, pCurrent, 30, 35,
                                                       0)

                #spread to trade route cities
                if (sd.getPlagueCountdown(iPlayer) >
                        2):  #don't spread the last turns
                    for i in range(city.getTradeRoutes()):
                        #for i in range(gc.getDefineINT("MAX_TRADE_ROUTES")):
                        loopCity = city.getTradeCity(i)
                        if (not loopCity.isNone()):
                            if (not loopCity.getNumRealBuilding(iPlague) > 0):
                                #utils.echo("Plagued caravan arrives at %s" %(loopCity.getName()))
                                iOwner = loopCity.getOwner()
                                if (iPlayer == iOwner or gc.getTeam(pPlayer.getTeam()).isOpenBorders(iOwner) or \
                                 gc.getTeam(pPlayer.getTeam()).isVassal(iOwner) or \
                                 gc.getTeam(gc.getPlayer(iOwner).getTeam()).isVassal(iPlayer)): #own city, or open borders, or vassal
                                    if (iPlayer != iOwner):
                                        if (self.isVulnerable(iOwner) == True):
                                            self.spreadPlague(iOwner)
                                            self.infectCity(loopCity)
                                            #utils.echo("infect by trade route: %s to %s" %(city.getName(), loopCity.getName()))
                                            iHuman = utils.getHumanID()
                                            if (gc.getPlayer(
                                                    iHuman).canContact(iOwner)
                                                    and iHuman != iOwner):
                                                CyInterface().addMessage(
                                                    iHuman, True,
                                                    con.iDuration / 2,
                                                    CyTranslator().getText(
                                                        "TXT_KEY_PLAGUE_SPREAD_CITY",
                                                        ()) + " " +
                                                    loopCity.getName() + " (" +
                                                    gc.getPlayer(iOwner).
                                                    getCivilizationAdjective(0)
                                                    + ")",
                                                    "AS2D_PLAGUE", 0, "",
                                                    ColorTypes(con.iLime), -1,
                                                    -1, True, True)
                                    else:
                                        self.infectCity(loopCity)
                                        #utils.echo("infect by trade route: %s to %s" %(city.getName(), loopCity.getName()))

        #spread to other cities of the empire
        if (len(cityList)):
            if (sd.getPlagueCountdown(iPlayer) >
                    2):  #don't spread the last turns
                for city1 in cityList:
                    ##print ("citylist", city1.getName())
                    if (not city1.getNumRealBuilding(iPlague) > 0):
                        for city2 in cityList:
                            if (city1 != city2):
                                if (city2.getNumRealBuilding(iPlague) > 0):
                                    if (city1.isConnectedTo(city2)):
                                        ##print ("infect distant", city1.getName(), "to", city2.getName(), utils.calculateDistance(city1.getX(), city1.getY(), city2.getX(), city2.getY()))
                                        if (utils.calculateDistance(
                                                city1.getX(), city1.getY(),
                                                city2.getX(), city2.getY()) <=
                                                6):
                                            #print ("infect distant", city2.getName(), "to", city1.getName())
                                            self.infectCity(city1)
                                            return