Requesting following features

This doesn't seem reasonable:
Type - Domestic Rebellion

Sample Conditions - Disorder for whatever reason 12% for barbs and 7% for civilized

Civ Claimant - Civ Specific rebels (I will send you the current mod soon)

Number of Units - Revolt turns * Military Garrison strength + 1 strength (may be unbalanced but testing will see) OR iPopulation / 2 * iUnhappyLevel + iDistance possibly?

Type - Current owner's tech level

Termination - None

Misc - Revival would be for rebels, Always present, War weariness
The number of units calculation seems a bit excessive. Tarentum just got hit with 26 rebel units! :eek2: (With reinforcements on their way.)

Since city size is 7 the unhappy level is also 7 (at the default difficulty level). Tarentum's distance to Rome is 5. This gives us 7/2 (rounded down) * 7 + 5 = 26 rebel units.

Would it be sufficient to just spawn iDistance number of units? Or perhaps whatever is highest of iDistance and iUnhappyLevel. So Tarentum would have received 7 rebels in this test, because 7 (unhappy level) is greater than 5 (distance).

Your call.
 
I'm second guessing what you actually mean:
Type - Civil War (VERY RARE)

Sample Conditions - Unhappiness in approx 30% of cites over 2 Angry Citizens (excludes War Weariness), has a 15% chance of starting every turn the conditions are in effect

Civ Claimant - Civ Specific Rebels

Number of Units - 6 outside of highest pop city owned by rebels

Type - Rebel's tech level (if never spawned before takes the Tech of current owner, or once again gains counterparts techs on first spawn)

Termination - None (and in my notes it says: Mwahahahaha!!!! :D)

Misc - Defection of the 30% of cities specified earlier, always vunerable to this
Do you mean that once the Civil War starts - all cities that qualify for the 2 unhappy citizens prerequisite will flip to the rebels? (All cities could very well qualify!) Or should it only be 30% of the cities that are qualifying for the unhappiness? Which cities should it be? Those added last to the Empire? Those with the most unhappiness? Random cities?
 
ok a lot to go though...

Yes you should use the idistance or iUnhappy that seems logical (I guess tarentum got smashed then :D)

ok I will elaborate... for this event to happen it needs 30% of ALL cities to be over 2 angery citizens and then these 30% flip to the rebels and the war begins! If for some reson 100% of the cities are like this at the same time... well just have 30% flip (the newest cities preferably whether newest founded or newest conquored?)

bRandom sounds good! We will have to figure out others to use

What I am thinking is that if we link missions together they should have a bCompleted variable which connects to the next mission for example
Code:
def HoldByzantiumFire:
	if bByzantiumCompleted == True:
		HoldByzantium() #event function itself
and in the Byzantium code:
Code:
##Byzantium Senate Prompt##
iSenateYear = -3800
iSenateEndYear = -3000
iSenateGold = 1000
senateHeader = "Senate"
senateMessage1 = "The glorius Senate of Rome requests that you take the city of Byzantium. If you take it and hold it at the end of 30 turns (turn 195) you will be greatly rewarded"
senateMessage2 = "The glorius Senate of Rome wishes that you make sure that you keep control of Byzantium by the end of 30 turns (turn 195). If you successful, you will be rewarded!"
senateMessage3 = "The Senate notes that you have succeeded and has gifted you 1000 gold!"
senateMessage4 = "The Senate notes that you have failed to control Byzantium and you will not be rewarded!"  
tByzantium = (46, 23)
bByzantiumComplete = False
def eventSenate():
    if isHuman("Rome") == True:
        if isDate(iSenateYear):
            if isPlotOwner(tByzantium, eRome) == False and isPlotCity(tByzantium) == True:
                showPopup(senateHeader, senateMessage1)
            else:
                bByzantiumComplete = True
        elif isDate(iSenateEndYear):
            if isPlotOwner(tByzantium, eRome) == True and isPlotCity(tByzantium) == True:
                giveGold(iSenateGold, eRome)
                showPopup(senateHeader, senateMessage3)
            else:
                showPopup(senateHeader, senateMessage4)
as you can see this removes the need for popup2...

of course your methods fine too :D

I could tacke The Marius Reform myself but for this I would think some sort of counter could be useful if I add somesort of return function for bComplete aswell and each time it returns true the counter records it with something like this:
Code:
X = 0
def Counter():
	if bByzantiumComplete == True:
		X = X + 1
		if bByzantiumHoldComplete == True:
			X = X + 1
these would go in order of exucution and for the marius code:
Code:
if Counter() >= 10 and iCites >=10:
	etc

or something simmilar, as this may not work...

Spawning AI rome cities sounds good but how will it become balanced? I will make some sort of list soon

I see what you mean by buttons now!

Well we will have to see about espionage then :think:

I simply think that the Senate would suggest a civics change - like "we need slavery back!" - and the option would be to accept this proposal or not. Not accepting it could of course cause anarchy instead!

Yeah you are right, this could even cause slave rebellions :lol: the anarchy instead sounds good, like the Punishment.

50% roman or more should definatly stop the procedure!

I don't think there is anything else I need to add... but I will put in a new post if there is...
 
Ok, I actually made a companion module to CivPlayer called DataStorage. This is used both for saving custom values for each player - and for saving global custom values. Its basically an application interface just like CivPlayer. So you can totally have your own custom values for whatever you like and they will be available everywhere and also get saved with games. The main functions are:
Code:
setGlobalData(key, value)
getGlobalData(key)
The key argument is always a string type - the name of the custom value. In the Rebellion module I'm using DataStorage to hold a list of current rebellions called "lCurrentRebellions". To get hold of the list I can fetch it with getGlobalData() and assign the returned value (the list) to a name:
Code:
lCurrentRebellions = getGlobalData("lCurrentRebellions")
And to store the list I use setGlobalData():
Code:
setGlobalData("lCurrentRebellions", lCurrentRebellions")
The string key value could of course be anything.

So if you need a mission counter you need to initialize it at game startup by setting it to the default value:
Code:
setGlobalData("iMissionCounter", 0)
To add to the counter you could have a util:
Code:
def increaseMissionCounter():
    iMissionCounter = getGlobalData("iMissionCounter")
    setGlobalData("iMissionCounter", iMissionCounter + 1)
And you can fetch the value any time with:
Code:
getGlobalData("iMissionCounter")
You could use it in a if statement:
Code:
if getGlobalData("iMissionCounter") >= 10:
The module of course does all sorts of interesting things, but its all about a class holding a dictionary with keys and values. The dictionary gets "pickled" and saved with the game - and loaded and "unpickled" again on loading the game. You will get access to the functions by importing the CivPlayer module. I will include the actual module with the rest of the files once I'm done.

Regarding the slave rebellions (I'm down to testing the last one now) it seems like it isn't possible to get the number of unhappy citizens from whip anger. :p This is strange when its spelled out right there in the interface. So I'm gonna have to figure out some other calculation for the trigger.
 
ok good luck and thanks for the thing I await those new files!
 
I'll have another look at what has been said on the senate missions and make a sample class for you, once I get around to it.

Will the Byzantium spawn be a senate mission thing or a rebellion thing? Both? Neither?
 
I mean that its supposed to happen on a set date, like a senate mission. But the effect would be rather like a Civil War rebellion?

I guess I could make a special sub-sub-class for the Byzantine spawn. The rebellion is then triggered from the ModEvents module. I'll supply you with the constructor and you work it into the events structure. Good? :king:

You'd probably end up something like this:
Spoiler :
EasternRomanEmpire(instance(eRome), getAreaCities(tEasterEmpire1, tEasternEmpire2))
 
do you understand the circumstances of the spawn?

all cities inside the coordinates are fliped to the ERE and all the units in those cities with it. The ERE is instantly at war with rome. Byzantium should always be the capital and should be renamed apon capture to Constantinople. The coordinates for byzantium are 46, 23

If Byzantium cannot be the capital then it should go to the next highest pop city (or whatever is easiest for you), make sure that the capital receives the palace building!

only Roman cites can flip (maybee Byzantium from who ever owns it?)

Good Luck! ( I know I will construct it but you now have the nessicary info to make sure you know what to do.

The Byzantine Empire is at the top of CivInfos.xml for you if you need it!
 
Ok, I'm still working on the slave rebellions and would like to suggest a dynamic chance to fire percentage equal to iHurryAngerTimer * iSlaveRebellionDenominator. So if iHurryAngerTimer equals to 10 more turns of hurry anger and iSlaveRebellionDenominator is 5, then we get a 50% chance of the event firing on any slave revolt (random) event. As an example - you might wanna lower iSlaveRebellionDenominator to something like 1 for a 1-10% chance.

This also means that there can be no rebellion event without whip anger! So you can "safely" run Slavery as long as you don't hurry build in poorly defended cities. You might run into the random event from time to time, but there will only be slave units forming if the city in question exhibits unhappiness because of hurry building.

Sounds good?
 
Good Luck! ( I know I will construct it but you now have the nessicary info to make sure you know what to do.
I think that we pretty much already have all the things needed. I'll just whip together a sub-class to the CivilWar class that defines the capital as Byzantium (with the name and the palace).

I foresee no problems with this. You on the other hand need to make sure that the event fires on date and that you supply the cities affected to the constructor in the form of a list. Could you manage a helper function like getPlayerAreaCities() that takes both the coordinates of the area and the PlayerType involved? (You could use findAreaCities() and isPlayerCity() to create a list of CyCity objects. But you need to know a little about list arrays.) Good luck yourself! :D
 
yep the slave thing sounds good.

:think: I will have a go... I will do a little learning!
 
ok after some deliberation... (never good with me :p) I made a helper function which I gather will most likely fail on me, due to what you said, There should be something more and this will do something strange...Anyway :rolleyes:

Code:
def findPlayerAreaCities(tCoords1, tCoords2, ePlayer):
    for pCity in findAreaCities(tCoords1, tCoords2):
        if isPlayerCity(pCity, ePlayer) == True:
            yield pCity

Am I correct in thinking that something is fishy with this? :lol: It just seemed too easy... :think:
 
The main thing you're missing is that the new function should return a list array. So you need to figure out how to:
  1. initiate a empty list type
  2. populate the list with valid CyCity instances
  3. supply the list array as the return value of the function
Also, you can't use the yield command as that turns the function into a generator function.

Hint: You should read up on lists. ;)
 
1. [] the textbook doesn't say much else on empties... what are they to be used for?
2. stumped :(
3:
Code:
x = 0
while x < len(CityList):
    return CityList[x]
    x = x + 1
Am I on the right track? :confused:
I just dont know CityList yet...
 
You could cheat by looking in PyHelpers. The main reason for using the PyPlayer class, besides for PyPlayer.initUnit() are the quintessential methods PyPlayer.getUnitList() and PyPlayer.getCityList(). Do you know where PyHelpers is located?
Spoiler :
edit: I actually need this function for my own testing, so here it is:
PHP:
def getPlayerAreaCities(tCoords1, tCoords2, ePlayer):
	"""
	Returns a list of all CyCity instances corresponding to cities belonging 
	to ePlayer inside the map area defined by tCoords1 and tCoords2.
	"""
	lPlayerAreaCities = list()
	for pCity in findAreaCities(tCoords1, tCoords2):
		if isPlayerCity(pCity, ePlayer):
			lPlayerAreaCities.append(pCity)
	return lPlayerAreaCities
 
By the way, I simplified the Civil War code and allowed multiple civil wars at the same time. I'm not sure if it will affect game play or not. But it would both be possible for two rivals to experience a Civil War at the same time - or for a player to have its empire split more than once during the course of a "civil war".
 
Since I'm done with my preliminary testing of the Rebellion module now I was looking at the CivilWar class to figure out what would set the sub-class EasternRomanEmpire apart from it. It dawned on me that the CivilWar class has a very simple termination condition: the rebel civ is dead.

Now this would automatically be inherited by the EasternRomanEmpire class, but what about making the capital (Byzantion by default) the termination clause? Take the city and end the war - what do you think? (This is somewhat how the non-playable Byzantium operates in RFC - when Constantinople falls, the Empire falls.)

Or should it perhaps only apply if Byzantion is in fact the capital - because this would make the player wanna capture Byzantion pre-spawn. This would give the human player a clear goal as how to change history in one single blow. (It might be a effective cheat, however. Capture Byzantion, fortify the army outside of the city, recapture after flip.)

edit: Also, can we always name the Byzantine capital Constantinople? Because if Byzantion isn't in Roman hands at the civil war event, then history is already broken. But it still makes sense that the founding place of the East Roman Empire is named after its founder, right? (I think I'll make a dummy message heralding Constantin and his new capital. :D You can change it later.)
 
Ok, this is a draft for the EastRomanEmpire sub-class:
Spoiler :
Code:
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(),), (False, True))

    def checkTermination(self, iGameTurn):
        if ( not self.getRebelCiv().isAlive()
             or ( self.getPlotCoords() == tByzantion
                  and isPlayerCity(self.getCyCity(), pointer("Rome", playerID)) ) ):
            SlaveRevolt.revertSlaveCities(self)
            return True
        return False
Byzantion is chosen as the capital by giving it a artificially high population score. That way the rest of the original CivilWar logic remains the same.

And you fire the event from ModEvents with this statement:
Code:
EastRomanEmpire.initCivilWar(Civ("Rome"), lDefectingCities)
The trick, of course, is to compile the lDefectingCities array holding all Roman cities in the east.
Code:
lDefectingCities = getPlayerAreaCities(tERE1, tERE2, eRome)
You of course need to import the EastRomanEmpire class from the Rebellion module in order to be able to access it:
Code:
from Rebellion import EastRomanEmpire
 
By the way, I haven't been able to get rid of all the extinction messages shown after the first game turn. I suggest you add those dummy units in the no-mans-land area of the map in order to always keep the rebels (and Byzantium) alive. :p

Other than that, all I have left to test is the ERE rebellion. I'm going to try that one in the console. :eek2: edit: done! :king:

This pretty much concludes my work on this mod, but there will of course be debugging to do. :p

I think I'll organize the utils/helpers and the constants before I bundle up everything and send over to you. :goodjob:
 
Back
Top Bottom