veBears Civs

@PIE
Code:
if CyGame().getSorenRandNum(2, "Random number for Unit Bandeirantes to get Worker or Settler") == 0:
Yours have a 50% chance for worker and 50% chance for settler though.

@veBear
Checking num of cities and num of buildings is easy. However, I don't see how to trigger victory in python
 
A senario makes my wok easier. I read somewhere about victories so I will work on it today and see where I get. I will use the buildings aswell
 
do you mind if I could have the mod itself to test my code when it comes to it!
 
Nono, not at all, but it is still quite Alpha, so much work will be needed first (mainly removing the whole tech-three, something that WILL take time as I will have to remove quite a lot of units and buildings).
 
fair enough, I am done then (unless you find problems :p)

Firstly you will need to get this tool (put the module in the python folder, the setup code you will merge yourself from my code :p)

then in eventmanager:
Code:
Under the last import statement:
## Victory Condition - Start ##
import CivPlayer
## Victory Condition - End ##

Under onLoadGame (between the return statement and the other statement)
                ## Victory Condition - Start ##
                CivPlayer.setupCivPlayer()
                ## Victory Condition - End ##

Under onGameStart (put under the string above the rest of code):
		## Victory Condition - Start ##
                CivPlayer.setupCivPlayer()
                ## Victory Condition - End ##

and under onBeginGameTurn (anywhere you want I would think):

		## Victory Condition - Start ##
		iRequiredCities = 20
                eRequiredBuilding = "BUILDING_IMPERIAL_SQUARE"
                iRequiredBuildings = 3
                eVictoryType = "VICTORY_SPECIAL"
                Game = CyGame()
		for pCivPlayer in CivPlayer.CivPlayer.getCivs():
                        pPlayer = pCivPlayer.get(1)
                        eTeam = pCivPlayer.get(2)
                        if pPlayer.getNumCities >= iRequiredCities:
                                if pPlayer.countNumBuildings(gc.getInfoTypeForString(eRequiredBuilding)) >= iRequiredBuildings:
                                        Game.setWinner(eTeam, gc.getInfoTypeForString(eVictoryType))                                
                                
		## Victory Condition - End ##

put this right at the very end of the file!
## Victory Condition - Start ##
if gc.getGame().isFinalInitialized():
        CivPlayer.setupCivPlayer()
## Victory Condition - End ##

You can edit the variables of iRequiredCities, iRequiredBuildings, eRequiredBuilding and eVictoryType as you want! also I took the liberty of adding this for the CIV4VictoryInfo.xml
Code:
		<VictoryInfo>
			<Type>VICTORY_SPECIAL</Type>
			<Description>TXT_KEY_VICTORY_SPECIAL</Description>
			<Civilopedia>TXT_KEY_VICTORY_SPECIAL_PEDIA</Civilopedia>
			<bTargetScore>0</bTargetScore>
			<bEndScore>0</bEndScore>
			<bConquest>0</bConquest>
			<bDiploVote>0</bDiploVote>
			<bPermanent>0</bPermanent>
			<iPopulationPercentLead>0</iPopulationPercentLead>
			<iLandPercent>0</iLandPercent>
			<iMinLandPercent>0</iMinLandPercent>
			<iReligionPercent>0</iReligionPercent>
			<CityCulture>NONE</CityCulture>
			<iNumCultureCities>0</iNumCultureCities>
			<iTotalCultureRatio>0</iTotalCultureRatio>
			<iVictoryDelayTurns>0</iVictoryDelayTurns>
			<VictoryMovie/>
		</VictoryInfo>

Hope it works!

as a side note, I hope setWinner does what I think it does! :rolleyes: So I will sit here in anticipation for you to test it!
 
Seem like it's working ATM. Thanks. When I'll get close enough to a Beta, maybe you could do some playtesting for me? I think you'll like it :)
 
maybe I could :p I must warn you though, my computer isn't the fastest thing in the world :lol:

Out of interest what's the mod about?

and also, feel free to ask me for other python work again!
 
hmmm, I think I made a mistake there, Can you change this line:

Code:
for pCivPlayer in CivPlayer.CivPlayer.getCivs():

to

Code:
for pCivPlayer in CivPlayer.CivPlayer.getPlayers():

that should fix a problem you will have down the line (the difference is that the original needs a name provided), of course it could be that I am wron g and it should be the original, in that case just change it back. When it is shown in use in documentation it is shown without parameters, which is confusing me...
 
Out of interest what's the mod about?
Spoiler You really want to know this? Would spoil the surprise, you know! :
You can look upon it as a better version of the Rise of Rome scen from Warlords with elements of your Rome Mod, PAE and TAM. You won't be able to build cities (all will be preplaced) and you rule 1 out of 6 so called 'Imperial' nations, which all start with 1 city each, and then you have 12 I believe (can't say for sure, don't remember) other, unplayable civs that you conquer cities from. The 'Imperial' civs will be the only ones with the Imperial Square within their capitals, so basically, this means that to win you must conquer the capitals of at least 2 other 'Imperial' civs, while you also need of course need 1 city of Legendary culture (I mean, look at Rome during it's glory days, now that's culture), a 20% lead in population, and you will need to have under your control about 65 % of all the cities on the map. All the Imperial civs have their own special armies, while all non-imperial share a generic army (though flavour art will be used in final version). At least, that's what I plan on doing.

hmmm, I think I made a mistake there, Can you change this line:

Code:
for pCivPlayer in CivPlayer.CivPlayer.getCivs():

to

Code:
for pCivPlayer in CivPlayer.CivPlayer.getPlayers():

that should fix a problem you will have down the line (the difference is that the original needs a name provided), of course it could be that I am wron g and it should be the original, in that case just change it back. When it is shown in use in documentation it is shown without parameters, which is confusing me...
Will do, thx :)
 
Spoiler :

ahhh... sounds great! I guess a little like Rome Total War in respect (with the whole civil war thingy!). what sort of stuff did you take from JRM? I'm guessing the rebellions? edit: Make sure you add the legendary culture into the Victory_Special (but I'm sure you have something else which is why I left it as a variable for you! When do you think release is likely to be then?


Np problem, the mod sounds cool (see above if you dare...)
 
Spoilin still...
Spoiler :
Actually, from JRM, I mostly have some graphics and the idea of controlling huge landmasses, but since domination would be easier for a Mid-Eastern civ with land all around than city-conquest, where every civ have to conquer the same amount, I decided to use city conquest instead of land-control. I believe you could say it's a bit like RTW. All timed events (actually all events) are removed, so is religion and corporations.

IDK about release date, but I'll probably release an Alpha as soon as the Generic Army thingy is finished, so then it will be playable, but miss some functions. The Imperial Victory is all taken care of :)
 
to be honest this whole idea of imperial victory makes me think I could make Historical Victory conditions for my mod (a bit like this and RFC) but in C++ for performance (having 8 or 9 conditions in python would be much slower). I think the rebellion stuff could be an interesting feature for your mod, fail to keep care of your cities and the outer reaches of your empire rebel (as opposed to the solid core) the chance affected by distance to capital. I could always attempt to build something for you if you wanted, I need the challenge. :p
 
You could of course if you want :)
I believe the civil war modcomp might be noce to have a look at then.
 
well lucky for you I have already been working on it :p

It's not finished yet (gotta add some storage systems to make sure that a player doesn't get more than 1 in a city at a time and that they don't have 3 at one time...) Rebellions are terminated when all units/the city is regained by a civ (currently barbarians are the rebels but it is easy to make a new civ to fit in). It also detects the technology of the owner of the city, if it has tech 1 spawn unit 1 else spawn unit 2. Either you can leave this blank or add in another unit and a tech to spawn it with. (current both unit 1 and 2 are archer for garrison and 1 and 2 for attacking are swordsman).

The percentages are actually quite a nice idea here, a rebellion cannot occur within 10 tiles of the capital using a min distance variable(and because distance is a variable the capital canot ever experience a rebellion) and the chance of rebellion increases the further you are away.

the formula is:
iModified Chance = (iChance/100) * (iDistance**1.22222)

where iChance is defaulted at 70 this means a tile is calculated as (where iDistance == 20 tiles away):

20 power 11 = 204800000000000
204800000000000 root 9 = 38.91
38.91 * 0.7 = 27.24% chance of rebellion in city 20 tiles away per turn if it is unhappy enough
at 58 tiles away or more the chance becomes over 100% so it is crucial you keep your cities in far away countries happy and keep your capital central, but 58 tiles is a long way...

in theory if you controlled iberia and a city in italy, you would want your capital to be in eastern iberia as your empire would be central.
 
Can I upload the versions of Kongo and Madagascar that I converted to AND?
 
Of course, just add me as co-author and it's done ;)
 
@Jamie... about that code of yours. While rebellion seems fine and all that, I believe increasing the limit to 15 tiles away from capital would be nice, as you can not move your capital. Also, there will be no city-building, only city conquest, and all cities will be pre-set. I do however like the rebellion concept, as it would force the player to build buildings and not just military to keep his populace happy.

Another question. Any way to disable religions from being founded? No need to remove them, just so their founding will be delayed until the 350th turn or so (which will be the last turn, year 1 AD). Soon moving this discussion into another thread as we're approaching alpha.


I also believe I had a question for Pie_at, but I can't remember it ATM, so I'll see if I remember it later.
 
that's fine! Thats why I left you variables to play with :p the code itself doesn't care whether you conquor or found cities so that doesn't matter. However are you sure you don't want to include building a palace so that civs can still move capital (the crucial victory building itself wouldn't be able to move meaning the capital could be a different city but that shouldn't matter)

That way it means the player has more freedom, for example it could put people off capturing cities in the middle east because their imperial maintenance would be distributed unevenly. Constantinople would be a nicer capital in that respect, and after it is changed the building that is needed for victory would still be in the original capital's place.

Just a thought :p Btw the code is ready I just need to find the time to test it for when it goes horribly wrong :p but anyway the code looks like this:

Spoiler :

Code:
from CvPythonExtensions import *
from CivPlayer import *

##Helpers##
def getIndex(category, entry):
    """
    Returns the enumerated index value (integer) of the specified entry belonging to the
    specified category, as specified by the XML.
    """
    key = category.replace(" ", "") + "_" + entry.replace(" ", "_")
    return gc.getInfoTypeForString(key.upper())

def initActiveRebellions():
    setGlobalData("Active Rebellions", ([], 0))

def getActiveRebellions():
    return getGlobalData("Active Rebellions")

def setActiveRebellions(pRebellion):
    n = getActiveRebellions()[1] + 1
    lRebellions = getActiveRebellions()[0]
    lRebellions.append(pRebellion)
    setGlobalData("Active Rebellions", (lRebellions, n))

def removeRebellion(pRebellion):
    n = getActiveRebellions()[1] - 1
    lRebellions = getActiveRebellions()[0]
    lRebellions.remove(pRebellion)
    setGlobalData("Active Rebellions", (lRebellions, n))
    
def createRebellion(pCity, pCivPlayer):
    pRebellion = Rebellion(pCity, pCivPlayer)
    setActiveRebellions(pRebellion)
    if Game.getSorenRandNum(100, "Rebellion Chance") >= iFlipChance:
        pRebellion.spawnRebels()
    else:
        pRebellion.flipCity()
        pRebellion.spawnGarrison()

def isRebellionActive(pRebellion):
    sUnitData = "RebelUnit City:%s" % pRebellion.pCity.getName()
    for pUnit in (eRebelCiv.get(CyPlayer).getUnit(iNum) for iNum in xrange(eRebelCiv.get(CyPlayer).getNumUnits())):
        if pUnit.getScriptData() == sUnitData:
            return True
    for pCity in (eRebelCiv.get(CyPlayer).getCity(iNum) for iNum in xrange(eRebelCiv.get(CyPlayer).getNumCities())):
        if pCity.getName() == pRebellion.pCity.getName():
            return True
    return False
    
##Constants##
bActive = True #set to False to turn rebels off
gc = CyGlobalContext()
Game = CyGame()
#eRebelCiv = pointer("Rome", playerID) #edit if you want a rebel player, use short desc of civ
eRebelCiv = instance(gc.getBARBARIAN_PLAYER())
tGarrisonUnits = (getIndex("Unit", "Archer"), getIndex("Unit", "Archer"))
tRebelUnits = (getIndex("Unit", "Swordsman"), getIndex("Unit", "Swordsman"))
eTransitionTech1 = getIndex("Tech", "Archery")
eTransitionTech2 = getIndex("Tech", "Iron Working")
iChance = 100
iMinUnhappy = 4
iMinUnhealthy = 6
iMinDistance = 15
iFlipChance = 25
maxRebellionsPerPlayer = 3

##Class code##
class Rebellion:
    def __init__(self, pCity, pOwner):
        self.pCity = pCity
        self.pOwner = pOwner

    @classmethod
    def refreshRebels(cls):
        for pRebellion in getActiveRebllions()[0]:
            if not isRebellionActive(pRebellion): removeRebellion(pRebellion)

    @classmethod
    def runCheck(cls):
        if not bActive: return
        for pCivPlayer in CivPlayer.getPlayers():
            pPlayer = CivPlayer.get(CyPlayer)
            n = 0
            for pRebellion in getActiveRebellions()[0]:
                if pRebellion.pOwner == pCivPlayer: n+=1
            if n > 3: continue
            for i in range(pPlayer.getNumCities()):
                pCity = pPlayer.getCity(i)
                bInRebellion = False
                for pRebellion in getActiveRebellions()[0]:
                    if pRebellion.pCity == pCity: bInRebellion = True
                if bInRebellion: continue
                if cls.calculateChance(pCity, pPlayer):
                    createRebellion(pCity, pCivPlayer)

    @classmethod
    def calculateChance(cls, pCity, pOwner):
        pCapital = pOwner.get(CyPlayer).getCapitalCity()
        iDistance = max((pCity.getX() - pCapital.getX()),(pCity.getY() - pCapital.getY()))
        if iDistance >= iMinDistance and (pCity.angryPopulation(0) - (pCity.getWarWearinessPercentAnger()/100)) >= iMinUnhappy:
            #y is directly proportional to ((x power 11) power 0.11111) * iChance/100 math FTW :p
            iModifiedChance = (float(iChance)/100) * (float(iDistance) ** (11.0 / 9.0))
            return (Game.getSorenRandNum(100, "Rebellion Chance") <= iModifiedChance)
        else: return False

    def spawnRebels(self):
        if self.pOwner.get(CyTeam).isHasTech(eTransitionTech2):
            eUnit = tRebelUnits[1]
            lPlots = [self.pCity.getCityIndexPlot(iIndex) for iIndex in xrange(19) if not ( self.pCity.getCityIndexPlot(iIndex).isPeak() or
                                                                                            self.pCity.getCityIndexPlot(iIndex).isWater() or
                                                                                            self.pCity.getCityIndexPlot(iIndex).isCity() )]
            pRandPlot = lPlots[Game.getSorenRandNum(len(lPlots), "Rand Plot")]
            CivPlayer(eRebelCiv).get(PyPlayer).initUnit(pUnit.getUnitTpe(), pPlot.getX(), pPlot.getY(), 8)
            
        else:
            eUnit = tRebelUnits[0]
            lPlots = [self.pCity.getCityIndexPlot(iIndex) for iIndex in xrange(19) if not ( self.pCity.getCityIndexPlot(iIndex).isPeak() or
                                                                                            self.pCity.getCityIndexPlot(iIndex).isWater() or
                                                                                            self.pCity.getCityIndexPlot(iIndex).isCity() )]
            pRandPlot = lPlots[Game.getSorenRandNum(len(lPlots), "Rand Plot")]
            CivPlayer(eRebelCiv).get(PyPlayer).initUnit(pUnit.getUnitTpe(), pPlot.getX(), pPlot.getY(), 8)

        for pUnit in (pRandPlot.getUnit(iUnit) for iUnit in range(pRandPlot.getNumUnits())):
            if pUnit.getOwner == eRebelCiv:
                sUnitData = "RebelUnit City:%s" % self.pCity.getName()
                pUnit.setScriptData(sUnitData)
            
    def flipCity(self):
        pPlot = self.pCity.plot()
        lUnits = [pUnit for pUnit in (pPlot.getUnit(iUnit) for iUnit in range(pPlot.getNumUnits())) if pUnit.getOwner() == self.pCity.getOwner()]
        lUnitsData = lUnits
        for pUnit in lUnits:
            pUnit.kill(False, self.pCity.getOwner())
        CivPlayer(eRebelCiv).get(CyPlayer).acquireCity(self.pCity, True, False)
        for pUnit in lUnitsData:
            CivPlayer(eRebelCiv).get(PyPlayer).initUnit(pUnit.getUnitTpe(), self.pCity.getX(), self.pCity.getY(), 1)
            
    def spawnGarrison(self):
        if self.pOwner.get(CyTeam).isHasTech(eTransitionTech1):
            eUnit = tGarrisonUnits[1]
            CivPlayer(eRebelCiv).get(PyPlayer).initUnit(eUnit, self.pCity.getX(), self.pCity.getY(), 6)
        else:
            eUnit = tGarrisonUnits[0]
            CivPlayer(eRebelCiv).get(PyPlayer).initUnit(eUnit, self.pCity.getX(), self.pCity.getY(), 6)


edit: if running HR military still will provide the happy :p

I might have a solution to the religion problem aswell I will see what I can do...
 
ok on the religion thing, I think I can work something out, but you need to disable the foundin gof christanity from tech and I will attempt to trigger manually with python, let me have a look
 
ok finished!

Code:
                ## Found Christianity ##
                iTurn = 350
                tHolyCoords = (0,0) #coords of Rome or Jerusalem
                eChrist = gc.getInfoTypeForString("RELIGION_CHRISTIANITY")
                Map = CyMap()
                if iGameTurn == iTurn - 1:
                        iX, iY = tHolyCoords
                        pHolyCity = Map.plot(iX, iY).getPlotCity() 
                        pHolyCity.setHasReligion(eChrist, True, True, True)
                        Game.setHolyCity(eChrist, pHolyCity, True)
                ## Found Christianity ##

put this in onBeginGameTurn under the victory condition stuff

founds christianity on iTurn in city on tHolyCoords. The player gets a do you wish to convert to christanity popup and there is a message: christanity has been founded in X

If your mod has multiple speeds then I will need to work out something that will trigger on 0AD instead of on turns but I'm sure you can work out 0AD's turn ingame (and add it as the variable!)

Make sure you remove the founding tech of cristanity so it can't be founded by research and you should be fine.
 
Top Bottom