Simple Python Things

I knew I saw that somewhere ^^.


Why I'm posting:

Event: Civil War

Spoiler :


civilwar_event_1_wY9.jpg


civilwar_event_2_4H1.jpg


civilwar_event_3_9YS.jpg


This small mod component ads 2 events to the game.
The event triggers if you have an unhappy city, and it will lead to a creation of a new civ with this city.
The new civ will be on the same tech level, will get all the units in the city (+2 additional defenders), and will declare war on the previous owner of the city.
The first event has some specific options: You can edit it in the python file that the event should be restricted to only one civ, and that exactly another civ with a defined leader should spawn (as example: Rome gets an event where the Byzantines appear, with Justinian as leader).
The second event is without these restrictions. Is not restricted to any civ, and will first check if the derivative civ is present, and if not it will spawn a random civ.

Contents:
3 XML files:
- Events\EventInfos.xml
- Events\EventTriggerInfos.xml
- Text\CIV4GameText_CivilWar.xml
1 Python file:
- Python\EntryPoints\CvRandomEventInterface.py

The both event files contain 2 new entries at the end of the file, EVENT_CIVIL_WAR_ROME and EVENT_CIVIL_WAR_GENERIC / EVENTTRIGGER_CIVIL_WAR_ROME and EVENTTRIGGER_CIVIL_WAR_GENERIC.
In the python file the event code is at the end, search for civil war - custom event

There are no restrictions in the EventTriggerInfos.xml, besides that the city has to have some :mad:. If somebody uses this event, I really suggest that some more restrictions, like a tech, some :yuck:, or a civic are set. Maybe make it also an 1 time event too (haven't set more restrictions myself, because you always forget something during your tests).

This event was requested by Spillsandstains.


It's partially a cut down event from an attempt which j_mie requested long time ago, but at that time it needed to be too much customized for the map. That's why it didn't work out at that time.
I know that the event is not really strong, but more would probably be detrimental for the civ, and it would need too much customization, so not sure how to do it in a good way.
 
The_J, did you ever see the code Baldyr made for the civil war? I would have to say yours is probably smaller and more lag efficient but Baldyr's is a piece of art :D Take a look!

Spoiler :

Code:
iRequiredRebellionCitySize = 3
iRebelReinforcementPercentage = 45
iMaxRebelReinforcementTurns = 5
iNumRebelReinforcements = 1
iCulturalRebellionPercentage = 75
iResistancePercentage = 60
iResistanceDomesticPercentage = 10
iResistanceDomesticTurns = 5
iDomesticRebellionPercentage = 55
iCivilizedPercentageSubtract = 5
iCapitalHappinessPenalty = 2
iMinorRevoltPercentage = 8
iCivilWarPercentage = 20
iCivilWarUnhappyCitiesPercentage = 30
iRequiredNumCivilWarCities = 6
iRequiredNumCivilWarUnhappiness = 2
iCivilWarRebelArmySize = 6
iSlaveRevoltDenominator = 30
iNumSlaveUnitsPerCitizen = 3
tByzantion = (46, 27)
byzansCapital = "Constantinople"
iByzansRebelArmySize = iCivilWarRebelArmySize

eDefaultUnit = eWarrior

tRebelUnits = (
(eBronzeWorking, eAxeman),
(eIronWorking, eSwordsman),
(eAdvancedBronzeWorking, eAdvancedSpearman),
(eAdvanceIronWorking, eAdvancedSwordsman)
)

tCivilized = ( "Carthage", "Greece", "Rome", "Egypt" )

defaultRebellionMessage = "TXT_KEY_REBELLION_REBELLION"
occupationalRebellionMessage = "TXT_KEY_REBELLION_OCCUPATIONAL_REBELLION"
domesticRebellionMessage = "TXT_KEY_REBELLION_DOMESTIC_REBELLION"
mdomesticRebellionMessage = "TXT_KEY_REBELLION_MINOR_DOMESTIC_REBELLION"
culturalRebellionMessage = "TXT_KEY_REBELLION_CULTURAL_REBELLION"
defaultTerminationMessage = "TXT_KEY_REBELLION_TERMINATION"
defaultUnitSpawnMessage = "TXT_KEY_REBELLION_UNITSPAWN"
civilWarMessage = "TXT_KEY_REBELLION_CIVILWAR"
civilWarTerminationMessage = "TXT_KEY_REBELLION_CIVILWAR_TERMINATION"
civilWarUnitSpawnMessage = "TXT_KEY_REBELLION_CIVILWAR_UNITSPAWN"
slaveRevoltMessage = "TXT_KEY_REBELLION_SLAVEREVOLT" 
slaveRevoltTerminationMessage = "TXT_KEY_REBELLION_SLAVEREVOLT_TERMINATION"
byzantiumMessage = "TXT_KEY_REBELLION_ERE"

iRandomSeed = getRandNum(iNumMajorPlayers, "seed") 
tRebellionClasses = (
    "CulturalInfiltration",
    "Resistance",
    "DomesticRebellion",
    "MinorRevolt",
    )

# main functions

def process(iGameTurn):
    for pCurrentRebellion in getRebellions():
        if pCurrentRebellion.checkTermination(iGameTurn):
            removeRebellion(pCurrentRebellion)
            pCurrentRebellion.setDeactivate()
            pCurrentRebellion.addTerminationMessage()
        else:
            pCurrentRebellion.process(iGameTurn)
    checkRebellion(iGameTurn)
    # debug:
    if bDebug and getRebellions():
        lDebugMessages = [("Active on Game Turn %d:" % (iGameTurn,), False )]
        for pCurrentRebellion in getRebellions():
            message = "%s (city: %s, starting turn: %d)" % (str(pCurrentRebellion), str(pCurrentRebellion.getCyCity().getName()), pCurrentRebellion.getRebellionTurn())
            lDebugMessages.append((message, False))
        debug("Rebellion", lDebugMessages)

def checkRebellion(iGameTurn):
    pCivPlayer = instance((iGameTurn + iRandomSeed) % iNumMajorPlayers)
    if not pCivPlayer.isAlive(): return
    lCities = pCivPlayer.get(PyPlayer).getCityList()
    lCities.reverse()
    lDefectingCities = list()
    iNumCities = len(lCities)
    bCivilWarValid = iNumCities >= iRequiredNumCivilWarCities #isCivilWarValid(iNumCities)
    for pCity in (city.GetCy() for city in lCities):
        if not isRebellionValid(pCity): continue
        if checkClasses(pCity, pCivPlayer): return
        if ( bCivilWarValid
             and not CivilWar.isQuota(len(lDefectingCities), iNumCities)
             and CivilWar.checkUnhappiness(pCity) ):
            lDefectingCities.append(pCity)
    if ( bCivilWarValid
         and CivilWar.checkConditions(len(lDefectingCities), iNumCities) ):
        CivilWar.initCivilWar(pCivPlayer, lDefectingCities)

def checkClasses(pCity, pCivPlayer):
    for rebellionClass in tRebellionClasses:
        if eval(rebellionClass + ".checkConditions(pCivPlayer, pCity)"):
            appendRebellion(eval(rebellionClass + "(pCivPlayer, pCity)"))
            return True

def debug(moduleName, lDebugMessages):
    debugString = "\n *** " + moduleName + " Debug ***\n"
    for (string, bBroadcast) in lDebugMessages:
        debugString += (string + "\n")
        if bBroadcast:
            Interface.addImmediateMessage("Rebellion " + string, "")
    print debugString + " ***\n"

# data storage

def setup():
    setGlobalData("lCurrentRebellions", list())

def getRebellions():
    return getGlobalData("lCurrentRebellions")

def appendRebellion(pCurrentRebellion):
    lCurrentRebellions = getRebellions()
    lCurrentRebellions.append(pCurrentRebellion)
    setGlobalData("lCurrentRebellions", lCurrentRebellions)

def removeRebellion(pCurrentRebellion):
    lCurrentRebellions = getRebellions()
    lCurrentRebellions.remove(pCurrentRebellion)
    setGlobalData("lCurrentRebellions", lCurrentRebellions)

# class definitions

class Rebellion:

    @classmethod
    def checkConditions(cls, pCivPlayer, pCity):
        return pCity.isDisorder()

    # initialization

    def __init__(self, pCivPlayer, pCity):
        self.iRebellionTurn = Game.getGameTurn()
        self.plotID = getPlotID(pCity.plot())
        self.eCityOwner = pCivPlayer.get(playerID)
        self.setRebelPlayer(pCity)
        self.setUnitType(pCity)
        self.setNumUnits(pCity)
        self.setRebelUnitSettings(pCity)
        self.setMessages(pCity)
        self.setActivate()
        self.fire()
        self.debug(pCity)

    def setRebelPlayer(self, pCity):
        self.eRebelPlayer = eBarbarian

    def setUnitType(self, pCity):
        self.eUnitType = getTechUnitType(self.getCityOwner().get(CyTeam))

    def setNumUnits(self, pCity):
        iNatives = pCity.getCulturePercentAnger() / 100
        iPopulation = pCity.getPopulation()
        self.iNumUnits = max(3, min(iNatives - 1, iPopulation -2))

    def setRebelUnitSettings(self, pCity):
        self.iUnitAI = int(eAttackCity)
        self.ePromotion = -1
        self.unitFlag = "rebel"

    def setMessages(self, pCity):
        self.rebellionMessage = defaultRebellionMessage
        self.terminationMessage = defaultTerminationMessage
        self.unitSpawnMessage = defaultUnitSpawnMessage

    # class instance interface

    def isRebellionTurn(self):
        return Game.getGameTurn() == self.iRebellionTurn

    def getRebellionTurn(self):
        return self.iRebellionTurn

    def getCityOwner(self):
        return instance(self.eCityOwner)

    def getRebelCiv(self):
        if self.eRebelPlayer == eBarbarian:
            return pBarbarianCiv
        else:
            return instance(self.eRebelPlayer)

    def getRebelPlayer(self):
        return self.eCityOwner + iNumMajorPlayers + 2

    def getUnitType(self):
        return self.eUnitType

    def getPlotID(self):
        return self.plotID

    def getCyPlot(self):
        return Map.plotByIndex(self.getPlotID())

    def getPlotCoords(self):
        return getCoords(self.getCyPlot())

    def getCyCity(self):
        return self.getCyPlot().getPlotCity()

    def getCityName(self):
        return self.getCyCity().getName()

    def getNumUnits(self):
        return self.iNumUnits

    def getUnitAI(self):
        return UnitAITypes(self.iUnitAI)

    def isPromotion(self):
        return self.ePromotion != -1

    def getPromotion(self):
        return self.ePromotion

    def isUnitFlag(self):
        return self.unitFlag != ""

    def getUnitFlag(self):
        return self.unitFlag
    
    def setPromotion(self, pUnit):
        if self.isPromotion():
            pUnit.setHasPromotion(self.getPromotion())

    def setUnitFlag(self, pUnit):
        if self.isUnitFlag():
            pUnit.setScriptData(self.getUnitFlag())

    def setActivate(self):
        self.getCyCity().setScriptData("rebellion")

    def setDeactivate(self):
        self.getCyCity().setScriptData("")

    def isActive(self):
        return self.getCyCity().getScriptData() == "rebellion"

    # shared customizable functionality

    def fire(self):
        self.spawnRebelUnits()
        self.addRebellionMessage()
        
    def process(self, iGameTurn):
        if ( isChance(iRebelReinforcementPercentage)
             and iGameTurn < self.getRebellionTurn() + iMaxRebelReinforcementTurns ):
            self.spawnRebelUnits(iNumRebelReinforcements)

    def checkTermination(self, iGameTurn):
        if self.getCyCity().isDisorder(): return False
        unitFlag = self.getUnitFlag()
        for pUnit in self.getRebelCiv().get(PyPlayer).getUnitList():
            if pUnit.getScriptData() == unitFlag:
                return False
        return True

    def killRebelUnits(self):
        flag = self.getUnitFlag()
        for pUnit in self.getRebelCiv().get(PyPlayer).getUnitList():
            if pUnit.getScriptData() == flag:
                pUnit.kill(True, self.getCityOwner().get(playerID))

    def addMessage(self, message, tColor, sound = ""):
        if not message: return
        if cityKnownByHuman(self.getCyCity()):
            addMessage(message, (self.getCityName(),), getColor(*tColor), (-1, -1), sound)

    def addTerminationMessage(self, bRed=False, bWhite=True):
        bGreen = self.getCityOwner() == pHumanCiv
        self.addMessage(self.terminationMessage, (bGreen, bRed, bWhite), "AS2D_REVOLTEND")
        createReplayMessage(self.terminationMessage, (self.getCityName(),), self.eCityOwner, self.getCyCity(), eMajorEvent, ePurple)

    def addRebellionMessage(self, bGreen=False, bWhite=True):
        bRed = self.getCityOwner() == pHumanCiv
        self.addMessage(self.rebellionMessage, (bGreen, bRed, bWhite), "AS2D_REVOLTSTART")
        createReplayMessage(self.rebellionMessage, (self.getCityName(),), self.eCityOwner, self.getCyCity(), eMajorEvent, ePurple)

    def addUnitSpawnMessage(self, bGreen=False):
        if self.isRebellionTurn(): return
        bRed = self.getCityOwner() == pHumanCiv
        self.addMessage(self.unitSpawnMessage, (bGreen, bRed))

    def spawnRebelUnits(self, iNumUnits=0):
        if not iNumUnits:
            iNumUnits = self.getNumUnits()
        eUnitType, eUnitAI = self.getUnitType(), self.getUnitAI()
        lPlots = self.getPlotList()
        if len(lPlots) == 0: return
        while iNumUnits:
            iX, iY = getRandomCoords(lPlots)
            pUnit = self.getRebelCiv().get(CyPlayer).initUnit(eUnitType, iX, iY, UnitAITypes.UNITAI_ATTACK_CITY, DirectionTypes.NO_DIRECTION)
            self.setPromotion(pUnit)
            self.setUnitFlag(pUnit)
            iNumUnits -= 1
        self.addUnitSpawnMessage()

    def getPlotList(self):
        lPlots = list()
        iX, iY = self.getPlotCoords()
        for eDirection in range(DirectionTypes.NUM_DIRECTION_TYPES):
            pPlot = plotDirection(iX, iY, DirectionTypes(eDirection))
            if isSpawnValid(pPlot):
                lPlots.append(pPlot)
        return lPlots

    def updateRebelTechs(self):
        rebelCiv = self.getRebelCiv().get(PyPlayer)
        for eTech in self.getCityOwner().get(PyPlayer).getResearchedTechList():
            if rebelCiv.hasResearchedTech(eTech): continue
            rebelCiv.setHasTech(eTech)

    def debug(self, pCity):
        if not bDebug: return
        lDebugMessages = [
            ( "Rebellion initialized: " + str(self), False ),
            ( "Date/Turn: %d/%d" % (Game.getGameTurnYear(), Game.getGameTurn()), False ),
            ( "City: %s (%s)" % (str(pCity.getName()), str(self.getCityOwner().getName(False))), True ),
            ( "Units:\nType\tNum\tAI\tProm\tFlag\n%d\t%d\t%d\t%d\t%s"
              % (self.eUnitType, self.iNumUnits, self.iUnitAI, self.ePromotion, self.unitFlag), False )
            ]
        debug("Rebellion", lDebugMessages)

class CivilWar(Rebellion):

    @classmethod        
    def checkUnhappiness(cls, pCity):
        iAngryCitizens = pCity.angryPopulation(0)
        iWarWeariness = pCity.getWarWearinessPercentAnger() / 100
        return iAngryCitizens - iWarWeariness >= iRequiredNumCivilWarUnhappiness

    @classmethod
    def isQuota(cls, iNumRebelCities, iNumTotalCities):
        return iNumRebelCities > iNumTotalCities * iCivilWarUnhappyCitiesPercentage / 100
        
    @classmethod
    def checkConditions(cls, iNumDefectingCities, iNumTotalCities):
        return ( iNumDefectingCities >= iNumTotalCities * iCivilWarUnhappyCitiesPercentage / 100.0
                 and isChance(iCivilWarPercentage) )

    @classmethod
    def initCivilWar(cls, pCivPlayer, lDefectingCities):
        pRebelHQ = cls.initRebellions(pCivPlayer, lDefectingCities)
        if pRebelHQ:
            pRebelHQ.setRebelHQ()

    @classmethod
    def initRebellions(cls, pCivPlayer, lDefectingCities):
        tLargestCity = 0, None
        for pCity in lDefectingCities:
            pCivilWar = CivilWar(pCivPlayer, pCity)
            appendRebellion(pCivilWar)
            pCivilWar.setActivate()
            iPopulation = pCity.getPopulation()
            if iPopulation > tLargestCity[0]:
                tLargestCity = iPopulation, pCivilWar
        return tLargestCity[1]

    def setRebelHQ(self):
        setCapital(self.getCyCity())
        self.spawnRebelUnits()
        self.terminationMessage = civilWarTerminationMessage
        self.addRebellionMessage()

    def __init__(self, pCivPlayer, pCity):
        Rebellion.__init__(self, pCivPlayer, pCity)

    def fire(self):
        self.flipCity()

    def setRebelPlayer(self, pCity):
        self.eRebelPlayer = self.getRebelPlayer()
        self.updateRebelTechs()

    def setNumUnits(self, pCity):
        self.iNumUnits = iCivilWarRebelArmySize

    def setMessages(self, pCity):
        self.rebellionMessage = civilWarMessage
        self.terminationMessage = ""
        self.unitSpawnMessage = civilWarUnitSpawnMessage

    def addMessage(self, message, tColor, sound = ""):
        addMessage(message, (self.getCityOwner().getName(),), getColor(*tColor), (-1, -1), sound)

    def addTerminationMessage(self):
        bGreen = self.getCityOwner() == pHumanCiv
        self.addMessage(self.terminationMessage, (bGreen, False, True))
        createReplayMessage(self.terminationMessage, (self.getCityOwner().getName(),), self.eCityOwner, self.getCyCity(), eMajorEvent, ePurple) #CHECK WORKS

    def addRebellionMessage(self):
        bRed = self.getCityOwner() == pHumanCiv
        self.addMessage(self.rebellionMessage, (False, bRed, True), "AS2D_REVOLTSTART")
        createReplayMessage(self.rebellionMessage, (self.getCityOwner().getName(),), self.eCityOwner, self.getCyCity(), eMajorEvent, ePurple) #CHECK WORKS

    def addUnitSpawnMessage(self):
        bRed = self.getCityOwner() == pHumanCiv
        Rebellion.addMessage(self, self.unitSpawnMessage, (False, bRed))

    def flipCity(self):
        pCity = self.getCyCity()
        iX, iY = self.getPlotCoords()
        pRebelCiv = self.getRebelCiv()
        lCityUnits = getCityUnits(pCity)
        pRebelCiv.get(CyPlayer).acquireCity(pCity, False, False)
        for pUnit in lCityUnits:
            pRebelUnit = pRebelCiv.get(PyPlayer).initUnit(pUnit.getUnitType(), iX, iY)
            pRebelUnit.convert(pUnit)
            self.setUnitFlag(pRebelUnit)

    def checkTermination(self, iGameTurn):
        if self.getRebelCiv().get(CyPlayer).getNumCities() == 0:
            self.getRebelCiv().get(CyPlayer).killUnits()
            return True

    def process(self, iGameTurn):
        pass


class EastRomanEmpire(CivilWar):

    @classmethod
    def initRebellions(cls, pCivPlayer, lDefectingCities):
        tLargestCity = 0, None
        for pCity in lDefectingCities:
            pERE = EastRomanEmpire(pCivPlayer, pCity)
            appendRebellion(pERE)
            pERE.setActivate()
            iPopulation = pCity.getPopulation()
            if getCoords(pCity) == tByzantion:
                iPopulation = 99
            if iPopulation > tLargestCity[0]:
                tLargestCity = iPopulation, pERE
        return tLargestCity[1]

    def setRebelHQ(self):
        setCapital(self.getCyCity())
        self.terminationMessage = civilWarTerminationMessage
        self.addRebellionMessage()
        self.getCyCity().setName(byzansCapital, True)
        self.spawnRebelUnits()

    def setRebelPlayer(self, pCity):
        self.eRebelPlayer = pointer("Byzantium", playerID)
        self.updateRebelTechs()

    def setNumUnits(self, pCity):
        self.iNumUnits = iByzansRebelArmySize

    def setMessages(self, pCity):
        self.rebellionMessage = byzantiumMessage
        self.terminationMessage = ""
        self.unitSpawnMessage = civilWarUnitSpawnMessage

    def addRebellionMessage(self):
        addMessage(self.rebellionMessage, (self.getCyCity().getName(), byzansCapital), getColor(False, True))
        createReplayMessage(self.rebellionMessage, (self.getCyCity().getName(), byzansCapital), self.eCityOwner, self.getCyCity(), eMajorEvent, ePurple) #CHECK WORKS

# helper functions

def getPlotID(pPlot):
    return Map.plotNum(pPlot.getX(), pPlot.getY())

def getCyPlot(iPlot):
    return Map.plotByIndex(iPlot)

def getTechUnitType(pTeam):
    for i in xrange(len(tRebelUnits) - 1, -1, -1):
        eTechType = tRebelUnits[i][0]
        if pTeam.isHasTech(eTechType):
            return tRebelUnits[i][1]
    return eDefaultUnit

def isRebellionValid(pCity):
    return ( not pCity.getScriptData()
             and pCity.getPopulation() >= iRequiredRebellionCitySize )

def isCivilized(pCivPlayer):
    return pCivPlayer.getName(False) in tCivilized


good to know this is released as a standalone though, good job!
 
I don't think it is that much of an exaggeration, I find it nice when I am viewing my own code in debug and watching it perform all it's operations. I think well written code (like Baldyr's) is definately a form of art that only we programmers can truely appriciate :D
 
Nice work on the event! Finally i can have revolutions in my mod without having to merge so many things :lol:

Is it triggered everytime a city is unhappy? If so ill probably just put a 1 in 1500 chance or something like that on it. Can we expect more events in the future? No one really does events and we can definatly used some released, I got plenty of ideas :lol:

@ Jamie
the civil war code, is that generic? Meaning if i put it into my modern mod would i have to change any of it? I definatly want to see that in action in my mod
 
that code standalone will fail... There are other parts to it unfortunatly (many many other rebellions not sure how easy it is to disable) which have to be accounted for, though it is possible you could probably simulate this with simple events. As I said Jamie's Rome's rebellions are quite lag extensive for you will definatly perfer The_J's over ours

Though actually asnwering your question: yes it could be used but not without some hooking up of the civplayer interface (unsure whether it is compatible with the release version, my mod had civplayer before it was properly finished :p), after that it is pretty easy to actually trigger events, one of my first tasks of python was to create a set civil war for the Eastern Roman Empire (shh it is meant to be a secret) by interfacing with the rebellion code. Not sure how easy it would be to do though. And a brief overview of what the code actually does:

If an empire has over 6 cities and 1 third are unhappy then trigger those cities to flip (very small chance, in all my test games I have only seen it once :p), so yes it is generic but can also be used for events
 
Should be doable, but that could be balancing-wise be quite problematic (just imagine, defying some UN resolutions puts you over the limit, and nearly all your cities go away...awful!).

I don't think it is that much of an exaggeration, I find it nice when I am viewing my own code in debug and watching it perform all it's operations. I think well written code (like Baldyr's) is definately a form of art that only we programmers can truely appriciate :D

I find the complexity rather scaring, but that's maybe only me :D.

Nice work on the event! Finally i can have revolutions in my mod without having to merge so many things :lol:

Is it triggered everytime a city is unhappy? If so ill probably just put a 1 in 1500 chance or something like that on it.

Yes, currently it will happen to every city which is unhappy (until all civ slots are full).
That's why I say in the description that you should change some things in the eventTriggerInfos.xml to better match your mod ;).

Can we expect more events in the future? No one really does events and we can definatly used some released, I got plenty of ideas :lol:

Depends on how complicated your ideas are ^^.
 
Should be doable, but that could be balancing-wise be quite problematic (just imagine, defying some UN resolutions puts you over the limit, and nearly all your cities go away...awful!).
You could then put a simple restriction, capping it off at half of your cities, or saying it needs to be a certain number of unhappiness

I find the complexity rather scaring, but that's maybe only me :D.
Nahh me too, dont like giant codes, they are pretty intimidating:lol:

Yes, currently it will happen to every city which is unhappy (until all civ slots are full).
That's why I say in the description that you should change some things in the eventTriggerInfos.xml to better match your mod ;).
If you ever do update it, i would put a random restriction on it, since that way people who just want to play it as a solo mod can do so if they do not have modding capabilities

I would like to see it expanded a bit, since doing a simple check of other cities to see if they are unhappy, if yes give to other civ. If that city has more cities then original, stop. Should be a pretty short code plus it shouldnt take a toll on gameplay since your only checking it when theres already a revolution (then again i could be wrong, dont know python):crazyeye:

Depends on how complicated your ideas are ^^.
I got plenty, and knowing somewhat how python runs, i won't make any crazy requests

You should release more as the only events are mods, and you can't merge those with mods about specific eras (not that i have a biased opinion there:lol:)
 
You could then put a simple restriction, capping it off at half of your cities, or saying it needs to be a certain number of unhappiness

[...]
I would like to see it expanded a bit, since doing a simple check of other cities to see if they are unhappy, if yes give to other civ. If that city has more cities then original, stop. Should be a pretty short code plus it shouldnt take a toll on gameplay since your only checking it when theres already a revolution (then again i could be wrong, dont know python):crazyeye:

:run: too complicated :run:.
How many cities? How much :mad:? What if somebody changes the requirements? What if etc?

If you ever do update it, i would put a random restriction on it, since that way people who just want to play it as a solo mod can do so if they do not have modding capabilities

From the stuff in this thread, nothing is really intended to be used as stand alone mods (besides real OCC and real always war maybe).
Just set it up without any further restrictions, because I hate it when I test my own stuff, and it doesn't work because I forgot to fulfil some XML restrictions ^^.

I got plenty, and knowing somewhat how python runs, i won't make any crazy requests

Then give me 3 ideas, and I'll see.

You should release more as the only events are mods, and you can't merge those with mods about specific eras (not that i have a biased opinion there:lol:)

Not sure if I get you here...
 
Then give me 3 ideas, and I'll see.
hmm just 3..really restricting me here:p
1)Anti-war riots sweep nation, cities become angry while still during war
2)Currupt Mayor in a city, two options
*Cover it up. 50% chance it is leaked and all cities +1 mad for x turns
*Arrest him. +1 Happiness in all cities for x turns, -Y% culture in that city for x turns
3)Politican assasignated by other civ's extremist(ex. German extremist). 2 options
*Go to war, negative relationship bonus, maybe happiness or culture bonus?
*Keep peace, + mad for x turns, bigger negative relationship bonus

got plenty but those are just off the top of my head

Not sure if I get you here...
theres not a lot of indivisual mod comps for events, where it just adds one event. Events usually just come in mods, so it is hard to extract just that event, expecially when its with python.
 
This is fantastic, thanks!

A quick question, what happens to the culture of the rebel city?
 
Edit: No culture. But there's an XML option for that :).
And thanks :).


hmm just 3..really restricting me here:p
1)Anti-war riots sweep nation, cities become angry while still during war
2)Currupt Mayor in a city, two options
*Cover it up. 50% chance it is leaked and all cities +1 mad for x turns
*Arrest him. +1 Happiness in all cities for x turns, -Y% culture in that city for x turns
3)Politican assasignated by other civ's extremist(ex. German extremist). 2 options
*Go to war, negative relationship bonus, maybe happiness or culture bonus?
*Keep peace, + mad for x turns, bigger negative relationship bonus

got plenty but those are just off the top of my head

1) can be done purely with XML (if only 1 city is targeted)
2) Without the chance and with only 1 city already doable in XML (I thought there was some percentage modifier somewhere :hmm:)
3) Already doable in XML

Okay, give me 3 ideas where more Python work than XML work is required :p ;).

theres not a lot of indivisual mod comps for events, where it just adds one event. Events usually just come in mods, so it is hard to extract just that event, expecially when its with python.

There's already plenty doable with the XML only, so don't blame me for that :D.
 
No one really does events and we can definatly used some released, I got plenty of ideas :lol:

I could do some. Sometimes I get bored and events are easy.
 
Back
Top Bottom