View Full Version : Celtic Mod v2.0 Release
antaine Feb 09, 2010, 09:45 AM Here is the Celtic Mod version 2.0. This one definitely autoplays better, but as a consequence the British city spawns have been changed to Independents and lower sizes ( and since they're not barbarians, there is no free warriors spawn for the Celts anymore). The English core area has been increased to cover the entire island of Britain, so two of the flipped Indy cities are going to want to flip to England, and England shouldn't be content to sit in its little corner, begging to become the human player's vassal.
Because two, if not three, cities will want to automatically flip to the Celts on the British Isles, I have also changed the Celtic UHV that required three British Isles cities by 200AD to be four British Isles cities, two Gallic cities and one city in northern Spain by 500 AD. The Gaulish and Spanish areas are part of the Celts normal and broader areas, but are no longer part of their core. I don't want to make it impossible for the human player to stave off collapse should they find themselves limited to Ireland with three other civs designed to carve out chunks of their core area.
This can be done by founding the capital on the square where you start and using your second settler in northwest France. Allow Cork and Cardiff to flip to you, capturing Edinburgh with troops from Cardiff (or possibly waiting for a flip, but you may never get there) and founding two more Continental cities (one in in western France (Bordeaux is a good choice) and one in northern Spain). You might be thinking," only build two settlers?" but this is easier said than done with Roman expansion, barbarian invasions and a 500 AD deadline that may cause you to expand too fast with stability problems. Success in this UHV will require either granting independence, flipping your cities to France, Spain and England and/or war with the three of them.
The English starting army has been increased since they'll be starting on an island with a hostile civ instead of a few Indy cities (the Celts had been taking London on the first turn, with the English popping back on the next, but with the capital now at Cardiff).
On the first autoplay run, the English took the whole island of Britain, causing the Celts to eventually collapse into Indy cities on Ireland which could be easily picked off by the English (historically accurate). While the English culture per se is only "native" to England and not Scotland, Wales or Cornwall, for the sake of making a playable England (and a scenario resulting in England conquering the Celts more often than not should the human player not be playing the Celts) I went with their historical drive to claim the whole island. I was also hoping that a Celtic resurrection might be better limited to Ireland in that way and not 75% of the English home island cities.
http://www.filefactory.com/file/b005fe3/n/RFC_with_Celts.zip
Baldyr Feb 09, 2010, 10:09 AM The Gaulish and Spanish areas are part of the Celts normal and broader areas, but are no longer part of their core. I don't want to make it impossible for the human player to stave off collapse should they find themselves limited to Ireland with three other civs designed to carve out chunks of their core area.
I don't know how much of this you have been able to test yourself, but I'm not sure what exactly the Core Area (as defined in the Consts.py file) does for stability. There is however a special kind of collapse designed by Rhye for AI Civs (and AI Civs only). It happens if the Civ in question is completely out of both its Normal and Broader Area, and triggers every few turns (so it in effect becomes a countdown until the actual collapse).
There is also another form of AI collapse that triggers once a Civ loses more than half of its cities (by any means). This is also checked every few turns and thus there's a chance of the Civ to either recapture enough cities to get out of the pickle - or to vasallize to another Civ in order to not collapse. Note that the Medieval spawns in Europe could very well trigger a collapse of this kind.
Use the PythonDbg.log file to see what type of collapse the Celts are actually falling victim to. The standard one would be "collapse: civil war" and triggers when a Civ has less than -40 in stability. The other ones are "collapse: motherland" and "collapse: generic" respectively. (There's actually one more: "collapse: barbarians" that triggers when a Civ loses cities to the minor Civs.)
I was also hoping that a Celtic resurrection might be better limited to Ireland in that way and not 75% of the English home island cities.
A respawn always happens inside the Normal Area (not the Core Area) and there is a limit of a maximum of 5 cities that can flip. So a larger Normal Area would result in a more random outcome, as there would be more cities to potentially flip.
So what I suppose you want is a Normal Area confined to Ireland (and perhaps western Britain or even Bretagne) - and a Broader Area encompassing all of the historical Celtic areas. Design the Celtic Core Area based on where you want them to initially spawn - and maybe even taking stability issues (the "stabilty map") into consideration.
antaine Feb 09, 2010, 11:15 AM ah, well, I suppose it would have been historically possible to have had Ireland remain occupied while Wales or Scotland delcared independence. It's even possible for Brittany to have done so, so I guess it's not that bad to have the normal area as-is.
on another note, if the Celtic player is looking to conquer/destroy/prevent the English from popping up, they may very well be looking to take the place of the British Empire in history. Pursuant to that, I'd like to increase the Celts' broader area to include not only what is included now (which would not be part of the English area) but also areas of strong Celtic influence (albeit due to Irish and Scottish emigration from the UK), namely the US, Canada, Australia and New Zealand (but not India or British holdings in Africa or Asia). That, and some better names in place of the Latin Continental space fillers I've been using...
Baldyr Feb 09, 2010, 11:25 AM I couldn't resist the temptation of taking a look at your own Python work. :D First of all let me congratulate you on making your first bit of actual programming and making it work as you intended! :goodjob:
The code isn't in the best shape though, so I gave it a quick cleanup, made the structure easier to see, deleted the old Carthaginian code that wasn't doing anything, and added comments to the code. This is what your code probably should or could look like:
#Celtic UHVs
elif (iPlayer == iCeltia): #only check the following code if its the Celtic player's turn
if (pCeltia.isAlive()): #...and only if the Celtic player is alive
#UHV 1
if (iGameTurn <= i450AD): #check if the UHV is completed only if there is still time
if (self.checkOwnedArea(iCeltia, tRoimhTL, tRoimhBR, 1)): #UHV condition
self.setGoal(iCeltia, 0, 1) #set UHV to achieved
elif (iGameTurn == i450AD and self.getGoal(iCeltia, 0) == -1): #...and fail it if its the last turn and it hasn't been completed
self.setGoal(iCeltia, 0, 0) #...then set UHV to failed
#UHV 2
if (iGameTurn <= i500AD): #check if the UHV is completed only if there is still time
bIsles = self.checkOwnedArea(iCeltia, tBritishIslesTL, tBritishIslesBR, 4) #first UHV condition
bGaul = self.checkOwnedArea(iCeltia, tGaulTL, tGaulBR, 2) #second UHV condition
bIberia = self.checkOwnedArea(iCeltia, tIberiaTL, tIberiaBR, 1) #third UHV condition
if (bIsles and bGaul and bIberia): #check if all conditions are met
self.setGoal(iCeltia, 1, 1) #set UHV to achieved
elif (iGameTurn == i500AD and self.getGoal(iCeltia, 1) == -1): #...and fail it if its the last turn and it hasn't been completed
self.setGoal(iCeltia, 1, 0) #...then set UHV to failed
#UHV 3
if (iGameTurn == i1700AD and self.getGoal(iCeltia, 2) == -1): #check if its the last turn and the UHV hasn't been completed
self.setGoal(iCeltia, 2, 1) #set UHV to achieved since it hasn't been failed
#the code for failing the third UHV is in another location
This could seem like nitpicking as you've actually confirmed that the code works, and that's what matters, right? No, unfortunately there was actually an issue or two with the code, that wouldn't be obvious if you can't actually read Python. For instance, one of the UHVs would have failed if it would have been achieved on the last turn - that wasn't you intention, right?
I suggest you replace your own code with the one above and use it as a basis for any further development. (You can of course delete any of my commenting if you like, as it has no bearing what-so-ever on performance.) A more logical structure will allow you to make changes more easily without causing errors or unintended results (bugs, really). Note how the first and second UHVs follow the same basic structure. You should keep this structure in order to avoid any possible issues going forward.
One thing you probably should try and pick up at this juncture is the indentation of Python code. Every 8th blank spaces at the beginning of a line equates to one hierarchy level. This is key to understanding how the code is structured. Note how the hierarchy goes up one level after every "if" (or "elif") statement, and how every "elif" statement is matched by a "if" statement on the same hierarchy level above it in the code.
Its a matter of logic, really, and this insight will give you that much more power as a Python programmer. :king:
Also, a quick note about "if" and "elif": You could probably rewrite the code to get rid of all the "elif" statements, but those are actually something you wanna use! Because if a "if" statement means, for example, "is the goal completed?" the corresponding "elif" statement could be "or is the goal failed?".
There is also an "else" statement allowing you to throw all the possibilities not covered by the initial "if" statement or the following "elif" statement(s) into one last outcome. So the "if" statement of "is it the color blue?" and the "elif" statement "or is it the color red?" would make all the other possible outcomes fit under "or is it some other color?". It would translate into something like this:
if (blue):
some.outcome(here)
elif (red):
another.outcome(here)
else:
default.outcome(here)
Makes sense? :crazyeye: (Edited file attached, but the edited code should of course be tested properly before adding it to any kind of release.)
Baldyr Feb 09, 2010, 11:32 AM Pursuant to that, I'd like to increase the Celts' broader area to include not only what is included now (which would not be part of the English area) but also areas of strong Celtic influence (albeit due to Irish and Scottish emigration from the UK), namely the US, Canada, Australia and New Zealand (but not India or British holdings in Africa or Asia). That, and some better names in place of the Latin Continental space fillers I've been using...
No, no... You use the Broader Area to encompass that area on the map where the AI Celts must have a presence - or they will inevitably collapse. I don't believe you meant that only having one city in New Zeeland (and not any other city) would save the AI from collapsing (thus not allowing them to respawn in their Normal Area later on).
What you need to figure out is how to make a stability map. Take a look at these (http://rhye.civfanatics.net/wiki/index.php?title=Rhye%27s_and_Fall_of_Civilization_ stability_maps#England). My best guess is that you should edit those tiles you wanna make "Celtic" (on another continents and whatnot) as for stability purposes into the Settler map, and not use the "areas" defined in the Python code for this purpose.
Baldyr Feb 09, 2010, 12:17 PM I ran some autoplay to see what you actually have come up with, and noticed something weird: Christianity seems to have been founded by the Independents - in Scotland! :eek: (Screen shot attached.)
Are you messing around with those religion settings again? :rolleyes:
Also, I noticed that the three independent cities that spawned on the isled did so on the same turn. That seemed a bit... scripted. Maybe you could base the spawn dates on some historical dates or something, making it seem like something else was actually going on. You could also put a Goody Hut on those locations from the get go, to indicate local population and also encourage exploration. If the Celtic player isn't cashing in on those the benefit will be lost, but on the other hand his units might prevent the cities from spawning. So the results could be a bit unexpected - in a good way.
Another thing you could consider is to make the Celtic independents be a variety of minor Civs. They represent independent tribes, right? And the Scottish one could be Picts (Barbarians in Civ terms). Because you would wanna be able to declare war on one of the tribes and not end up fighting an United Celtic League, right?
To add some spice to the independent Celts, you could have them spawn with Gallic Swordmen instead of plain Archers. (They are still Celts, after all!) The independent AI(s) won't build more of those units though, so you could actually spawn additional Gallic Swordmen of the various independent flavors in the (independent) Celtic areas. If you use the innerInvasion function I mentioned in another thread those units would only spawn inside their domestic cultural borders, which makes them fairly safe to use in the modmod. (No independent units popping up inside Roman borders or adjacent to cities belong to another Celtic AI.)
I could create a sample Barbs.py file that you could take out for a spin, and use the parts that you like, if you want. Otherwise I'm all too happy to leave the actual development and coding to you. :king:
Baldyr Feb 09, 2010, 12:24 PM And here's the screen shot... :rolleyes:
Baldyr Feb 09, 2010, 12:30 PM Another note: No other city spawns in France? Surely there should be historical Celtic sites in western France?
Also, I'm not so sure about having the Celtic Civ spawn on Ireland in 820 BC. I'm no historian but shouldn't the Celts really originate from the Halstatt region (in the Alps) and first spread to Western Europe and only then take the leap to Britain and finally end up on Ireland?
I kinda liked the previous version where Ireland was the respawn area, not the original spawn area... Not that the Bordeux area seemed like an obvious choice either...
I do however understand that its a matter of design choices and that you have to take playability and AI performance into account. This is why you're the designer and I'm coming up with constructive criticism. :D
antaine Feb 09, 2010, 02:43 PM well, it is true that the Celts originated on the Continent (actually, there are some historians that argue that they began south of the Caspian Sea and migrated to Europ through Scythia). (Ireland was invaded by Celts from Spain, but about 800 years before the start of the Celts in the game (Milesian invasion), and it is also agued by some historians and linguists that the people they found there were but another type of Celts. Without a doubt, Celtic culture predates the Greeks, who gave them their name, Keltoi. As such, I am comfortable starting them in Ireland c800 BC. Besides, the will absolutely refuse to settle the Isles at all if they don't start there.
Their historic area included northern Spain, all of France and the low countries, northern Italy, a huge, tapering swath to the Black Sea, Galatia in central Turkey and the British Isles, so anywhere in there would make sense. Other than those on the British Isles, which are best known today, the historical record of Celts really picks up with Ceasar's conquest of Gaul, providing my reasoning for the choice of western France in the first place. Honestly, it would still be if only I could figure out how to get them into the British Isles voluntarily. If you feel so inclined, you can move their spawn point back to France, let the four cities pop up as Indy and see if they ever make an attempt to capture them, but I would suspect we'll be waving goodbye to them long before the idea strikes them...
As for those cities, they spring up at the same time because if I wait too much longer, the borders of the capital will expand and swallow their spawn points and so they won't show up at all. Perhaps I could spawn them before the Celts show up, but I don't know if that will send the first settler wandering rather than settling, and it will definitely cut off sea passage to the Continent for the second settler until after Cardiff is absorbed (by which time the AI is not looking to settle so fast. I like the idea of starting them with Gallic Warriors, however.
Besides, I could see how the question of a Celtic league might make sense. If Rome attacked one tribe, it might pull together with neighboring tribes to help defend, whereas some would cast their lot with the Romans.
PS - I thought lutetia and burdigala still popped up there...well, i'll be adding more anyway...
antaine Feb 09, 2010, 02:47 PM pps - I added the coding that reassigns a razed holy city, which is probably how it wound up going to edinburgh.
Still, think historically again, the original holy city of Christianity was Jerusalem, but when that city was razed and the culture cut off from it, it became Rome...then Constantinople...then Avignon got into the mix. Other contenders would also be Bethlehem, Nazareth, Ephesus and Nicaea. While it never really "replaced" Jerusalem, there was a point at which Alexandria was as much a center of Judaism as Jerusalem...replacement cities can wind up in strange places, far flung from their original location...
Baldyr Feb 09, 2010, 03:09 PM Last post for tonight: It feels comfortable enough that you seem to know your history, so I'm probably not gonna question your design choices any further. I'll just focus on game mechanics instead.
I do believe that you need to try out different setups and run all those autoplays in order to get the best balance. There really is no other way to do it. Eventually you'll find something that's good enough.
By the way, keep in mind than if you spawn cities inside the Core Area before the spawn, those cities will flip. This could be good - or bad. Other than that it really doens't make things easier for you having the Celtic capitol i Dublin, with all that culture accumulating... In a worst case scenario we could ignore the limitations set by Rhye in Barbs.py and make our own Python code that behaves the way we want it to.
The option to have a second spawn area in mid game for the Celtic AI is still open, but that would probably be very hard for you to code yourself. And I think we both feel most comfortable if you take over the coding duties from here on... All I'm saying is that would probably be within my own capabilities if you think that it would solve some problems for you. (Either have the isles flip to the AI Celts based on the continent, or the other way around.) Personally I don't think of it as a "bad" solution, albeit a work intensive one. I would probably reuse that code in my own modding and make my idea of a second spawn reality - for all Civs!
And lastly, I think I forgot to compliment you on a dawn fine modmod! :king: Nice work! :goodjob:
antaine Feb 09, 2010, 03:39 PM Thank you ever so much...thank you for your patience and help.
The other reason I wanted to start them in Ireland is that there is a stability hit for moving your palace, so why force them to do something detrimental? I also didn't want second spawns for everyone, nor something like that only for the Celts (makes them too special).
Rhye didn't start the English out in Saxony and then try to entice them to pack up shop and move to another country (or in game terms, another continent). The modern capital of Celtdom is Ireland and the center of whatever political unity and autonomy Celtic civilization ever managed to achieve was in Ireland (although arguably Scotland as well), so it makes sense to have the core area center around that. There was no vast Celtic civilization I'm overlooking in Gaul, just a bunch of disunited tribes. I think the state of modern Breton culture as compared to the Irish and Scots (who were themselves descended from Irish colonists in the post-Roman period) should make that most reasonable.
antaine Feb 09, 2010, 04:29 PM I put bordeaux back in and changed the starting units of Melpum, Burdigala, Lutetia, Lugodunon, Corcaigh, Caerdydd and Dún Éideann to Gallic Warriors. I may also be adding Naoned (Nantes) as an indy spawn as well, but I have to play it this way a bit first...
as an aside, this is part of Rhye's original code, I believe this is why we keep winding up with Christianity in Lugodunon or Edinburgh. I think it's telling the game to self-found Christianity in Jerusalem, but if it can't to found it in a Independent or Barbarian city. I wonder if we could put a second or third modifier in there to try Jerusalem first, then Rome, then Constantinople, then a random city...
I'm going to script tRome and try to change the primary second attempt to Rome...that should give better european if it happens anyway...
if (not gc.getGame().isReligionFounded(iChristianity)):
iEthiopianModifier = 0
if (gc.getPlayer(con.iEthiopia).isHuman()):
iEthiopianModifier = 15 #for the UHV
if (iGameTurn == i33AD + 8*self.getSeed()/100 + iEthiopianModifier): #Christianity up to 190AD (15 = 330AD)
pJerusalem = gc.getMap().plot(tJerusalem[0], tJerusalem[1])
if (not pJerusalem.getPlotCity().isNone()):
if (pJerusalem.getPlotCity().getOwner() == iIndependent or pJerusalem.getPlotCity().getOwner() == iIndependent2 or pJerusalem.getPlotCity().getOwner() == iBarbarian):
bChristianResult = self.foundReligion(tJerusalem, iChristianity)
tCity = tJerusalem
else:
tCity = self.selectRandomCityReligionCiv(iJudaism, iIndependent)
bChristianResult = self.foundReligion(tCity, iChristianity)
if (bChristianResult == False):
tCity = self.selectRandomCityReligionCiv(iJudaism, iBarbarian)
bChristianResult = self.foundReligion(tCity, iChristianity)
if (bChristianResult == False):
tCity = self.selectRandomCityAreaCiv(tJewishTL, tJewishBR, iIndependent)
bChristianResult = self.foundReligion(tCity, iChristianity)
if (bChristianResult == False):
tCity = self.selectRandomCityAreaCiv(tJewishTL, tJewishBR, iIndependent2)
bChristianResult = self.foundReligion(tCity, iChristianity)
if (bChristianResult == False):
tCity = self.selectRandomCityAreaCiv(tJewishTL, tJewishBR, iBarbarian)
bChristianResult = self.foundReligion(tCity, iChristianity)
if (bChristianResult == False):
tCity = self.selectRandomCityAreaCiv(tEuropeTL, tEuropeBR, iIndependent)
bChristianResult = self.foundReligion(tCity, iChristianity)
if (bChristianResult == False):
tCity = self.selectRandomCityAreaCiv(tEuropeTL, tEuropeBR, iIndependent2)
bChristianResult = self.foundReligion(tCity, iChristianity)
if (bChristianResult == False):
tCity = self.selectRandomCityAreaCiv(tEuropeTL, tEuropeBR, iBarbarian)
bChristianResult = self.foundReligion(tCity, iChristianity)
if (bChristianResult == True):
self.spreadReligion(tCity, 3, iMissionary_Christian)
antaine Feb 09, 2010, 05:39 PM the changes I made to the Christian holy city code seems to have worked as Christianity was founded two turns after 33AD in Rome without the Romans having discovered Theology (I'm not entirely sure I understand why it passed over Jerusalem, but Rome was the first second choice...maybe it was because Jerusalem wasn't Indy...the code seemed to be looking to assign the holy city to a non-civ...well, that's Rome's reward for having to put up with beefy Celts, lol).
as for the new victory coding, I have to stick with my original until I can debug it...it didn't register as achieved when it was...
antaine Feb 09, 2010, 07:04 PM Also, Baldyr, I know at some point you made other civs less friendly to the Celts on startup, but how can I decrease that. The Dutch are beginning in a state of war with me, which should not be, and so did France even though I agreed to the flip and gave them four cities. I could see extra unfriendliness in the Roman, English and Vikings, but the French, Spanish and Dutch should really be more of a neutral start...
Baldyr Feb 09, 2010, 10:20 PM Also, Baldyr, I know at some point you made other civs less friendly to the Celts on startup, but how can I decrease that.
This is in Consts.py:
#rnf. Some civs have a double entry, for a higher chance
lEnemyCivsOnSpawn = [
[], #Egypt
[], #India
[iIndependent,iIndependent2,iIndependent2], #China
[iIndependent,iIndependent2], #Babylonia
[iIndependent,iIndependent2,iBabylonia], #Greece
[iBabylonia,iBabylonia,iGreece], #Persia
[], #Celtia
[iCeltia,iCeltia,iEgypt,iGreece,iGreece,iCarthage,i Carthage], #Rome
[], #Japan
[], #Ethiopia
[], #Maya
[iRome,iEngland,iFrance,iGermany,iNetherlands,iInde pendent,iIndependent2], #Vikings
[iEgypt,iBabylonia,iBabylonia,iGreece,iPersia,iCart hage,iRome,iSpain,iFrance,iIndependent,iIndependen t2], #Arabia
[], #Khmer
[iCeltia,iArabia], #Spain
[iCeltia,iCeltia,iArabia], #France
[iCeltia,iCeltia], #England
[iCeltia,iRome], #Germany
[], #Russia
[iCeltia,], #Netherlands
[], #Mali
[iCeltia,], #Portugal
[], #Inca
[iIndia,iChina,iChina,iJapan,iPersia,iKhmer,iRussia ,iRussia,iIndependent,iIndependent,iIndependent2,i Independent2], #Mongolia
[iMaya], #Aztec
[iEgypt,iBabylonia,iGreece,iGreece], #Turkey
[iSpain,iFrance,iEngland,iIndependent,iIndependent2] #America
]
All the Celtic entries are marked with red, and every single instance increases the chance of being at war wit that Civ from start. So if you take away one out of two there's only haft the chance of war, and if you have none there is also no risk of war on spawn.
It could be noted that you can put in instances of iIndependent in there if you want Civs to be hostile against your spawned Celtic independents...
I only edited this portion because some Civs were still coded to have a go at Carthage, when it had in fact been turned into Celts... Also, I was assuming the Celtic players spawned in France. So you would wanna reedit this yourself!
There's a couple of other edits in there also, that I need to get back to you about.
As for the Victory.py stuff - I can debug that once I get the chance. I'll also have a look at the Religions.py later. Now I'm off to work!
antaine Feb 09, 2010, 10:32 PM Yeah, I did find that. Also, I managed to do the religion one...if the game wants to pass over Judaism it will found Christianity in Rome, so long as it exists (or a city on that tile)...only if Rome has been razed and the square empty would it then go through the rest of the Indy/Barb routine.
I've managed to achieve two out of three UHVs (haven't gotten to 1700 yet) with the Celts. I'd founded all of France and northern Spain (and the free cities in Britain) by the time of the Eurospawns. I wound up doing a Dunkirk-style army evacuation on the eve of them, and then allowed Spain and France to flip. On one run I tried to resist England...bad idea. I went back to the save at that point, evacuated my units from Britain (I was very unstable at that point for losing more than 50% of my cities in less than ten turns). I granted Scotland and Wales their independence (so I wouldn't actually lose them to the English) and a few turns after the English spawned civil war broke out and Galway and Cork went Indy. Coincidentally, war with one does not equal war with both. In any event, I now had a big army to take them back. For some reason, Milan flipped to me during revolt so I took it, and used that to then take Rome and found two more cities in southern Italy. I'm now very stable and slowly rebuilding my prosperity. So I don't risk losing the 3rd UHV after all that, I'm going to wait 200 years and pass the third UHV, and then try to take back Britain. :evil::evil::evil:
I traded Rome back to the Romans with the peace treaty back in ancient times, so we'll see if that counts as a loss (my UHV still says "not yet" and not "no").
antaine Feb 10, 2010, 12:05 AM Historic victory, but because of all the cities I'd lost I've fallen so far behind in tech I don't think I'll ever manage to retake Britain. Next time, I'm going to just build up there and concentrate on having the units to prevent their spawn and/or sack London when they pop up (harder, because I increased their starting units to they could war with the AI)....then try to take their empire's place in history...
Baldyr Feb 10, 2010, 10:15 AM Also, I managed to do the religion one...if the game wants to pass over Judaism it will found Christianity in Rome, so long as it exists (or a city on that tile)...only if Rome has been razed and the square empty would it then go through the rest of the Indy/Barb routine.
Are you happy with how it works now? Because the thing to remember about this Python thing is that even if Rhye might have supplied you with an option A and an option B with his code, there really isn't any reason not to go for option C instead - and code that one yourself. I understand you still have much to learn about Python (and so do I) but anyway. Sometimes all it takes is one line of code, or a couple of edits in some line of code.
Coincidentally, war with one does not equal war with both.
Sure, as they might be different Independents. You realize there is Independent and then there is Independent2? This is actually what I was talking about earlier about the city spawns. I still suggest you make some of those cities Independent2 instead of Independent. You could at the very least differentiate between British tribes and continental tribes. (Personally I would pretty much mix them up.)
Historic victory
Congrats! :king: Not to winning the game but to haven verified that the code does what its supposed to. I understand you used your own code in that game? I actually never doubted that the UHVs would work, but I do see an obvious bug in there nevertheless. This is why I posted the corrected code earlier, but also because you seem to have made it work simply by trial and error. (You won't be able to change much without relying on mere luck in order to getting it to work again.) If you don't understand why you should use my code instead, I could always explain in more detail.
In short: Your code is far from optimal, but you will of course use the code you need to use. Its out of my hands! :p
One thing I was meaning to get back to you about was the fact that I did another edit on your Consts.py file (edit in red):
#AIWars
tAggressionLevel = (
0, #Egypt
0, #India
1, #China
1, #Babylonia
1, #Greece
2, #Persia
2, #Celtia
2, #Rome
1, #Japan
0, #Ethiopia
1, #Maya
2, #Viking
2, #Arabia
1, #Khmer
2, #Spain
1, #France
1, #England
2, #Germany
1, #Russia
0, #Holland
0, #Mali
0, #Portugal
1, #Inca
2, #Mongolia
1, #Aztec
2, #Turkey
2, #America
0) #Barbs
Now, I'm not exactly sure about what this does, but AFAIK the value is only used in the file AIWars.py to subtract it from a stored value (lAttackingCivsArray) on certain game turns. Since you actually didn't do anything else besides change the name in the code commenting (from "#Carthage" to "#Celtia"), the old value (zero) of the Carthaginians was still in effect.
I simply figured that the warlike Celts would have the same setting as the other warmongers in the game, instead of that of the mercantile Carthage. Since I don't know exactly what it does you might as well experiment with it - or change it back. (There doesn't seem to be any limit on what value you can give it, but Rhye has only used values ranging from 0 to 2, so much higher ones could give unexpected results.) It should work out just fine as it is now though, so I'd recommend to leave it unless you have reason to believe its causing some kind of problem with AI behavior.
Also, I commented out the lines #757-758 in RiseAndFall.py as mentioned in another thread:
## if (iGameTurn == con.i400BC):
## self.giveEarlyColonists(iCeltia)
This bit of code activates the free Galley with colonist units (Settler and Archer) that the AI Carthaginians were getting. As you probably can see for yourself, this event is triggered on game turn #114 (year 400 BC) so if you wanna use it for the Celts (AI only) all you have to do is delete the commenting (red) and perhaps also modify the date to better reflect Celtic colonization.
Note that it could be hard to predict what an AI Celtic player would do with those units, but I now know that the units end up on a Coastal tile adjacent to the Celtic capital (regardless of where it is located). As I initially figured the units would spawn in the Mediterranean I promptly commented out those lines... This would be a judgment call for you to make.
You could also create additional such spawn via the RiseAndFall.py file by adding dates to line #757. Like this (example):
if (iGameTurn == con.i400BC or iGameTurn == con.i250BC or iGameTurn == 155):
Note that the last instance is an actual game turn number and not a variable. You can always substitute one of the con.iDates (which you can find in Consts.py by the way) with a numerical value if you like. This makes it possible to use game turns not predefined by Rhye, because not all game turns are defined with variables!
I believe this would be the last edit I've yet to comment on. Oh yes, and it turns out that the line #352 in CvRFCEventHandler.py should in fact not be commented out. Its pure dumb luck that I noticed that one, as the original code would make the third Celtic UHV less reliable, because there would (most of the time) be a delay - potentially ending up neither granting nor failing the UHV on the specified game turn! If I hadn't already taken care of this issue it could very well have remained a "mystery bug" forever, because I doubt I would have been able to find it if I've tried... :rolleyes:
antaine Feb 10, 2010, 10:52 AM Thanks, I think the warlike decision was wise. I would love for you to explain what the bug is in that UHV code though, because I'd like to get it straightened out, although the current version works passably well but the first attempted fix did not tick as achieved when it was.
I have no problem with the elimination of future colonists for the Celts, although what do you think of a military unit spawn at that time? v2.1 is going to include more Indy and Barb cities, so Celtic settlement will largely be one of conquest (as will Roman). This would be more accurate historically (most Celtic tribes were already in place shortly after the Celtic spawn point in the game. Some geneticists believe that proto-celts and proto-basques may very well have been Europe's aboriginal peoples). They will get a few cities by simply sitting there and accruing culture, but most will have to be taken by force if desired.
If you work more on victory.py, know that I'm adding the Vikings to the list of civs the Celts must not lose cities to.
Baldyr Feb 10, 2010, 10:57 AM One more thought: Since the Celts are a new addition to RFC Rhye hasn't been able to tweak it as for stability. This is in fact something that could be done if need be. I know that Rhye has alleviated some of the instability due to isolation and stagnation for some Civs, or taken account the starting location/date of other ones.
So if you feel, or if play report eventually will show, that something needs to be tweaked, that could then be taken care of. Any tweaks to stabiltiy would require rigorous testing though...
Also, if you conclude that all the Medieval spawns in Western Europe is making the Celtic AI too prone to collapse, something could be done about this also. Its simply a matter of adding some line of code excepting the Celts from some of the prerequisites for collapse. It would hardly brake the mod since the Celts weren't supposed to be playable to begin with... There could also be a grace period of sorts during the period when all that spawning is taking place - if the objective here would be to keep the Celts in the game.
Talking about stability brings these settings (Consts.py) to mind:
#for stability hit on spawn
lOlderNeighbours = [
[], #Egypt
[], #India
[], #China
[], #Babylonia
[iEgypt, iBabylonia], #Greece
[iEgypt, iBabylonia, iGreece], #Persia
[iGreece], #Celtia
[iEgypt, iGreece, iCeltia], #Rome
[], #Japan
[iEgypt], #Ethiopia
[], #Maya
[], #Vikings
[iEgypt, iPersia], #Arabia
[iIndia], #Khmer
[iCeltia, iRome], #Spain
[iCeltia, iRome], #France
[iCeltia], #England
[iGreece, iRome, iVikings], #Germany
[iPersia, iGreece], #Russia
[iRome, iGermany], #Netherlands
[iEthiopia], #Mali
[iCeltia, iRome], #Portugal
[], #Inca
[iChina, iJapan, iKhmer, iRussia], #Mongolia
[iMaya], #Aztec
[iBabylonia, iGreece, iPersia], #Turkey
[iSpain, iFrance, iEngland, iNetherlands, iPortugal, iAztecs, iMaya] #America
]
I'm afraid I don't remember whether or not I actually edited this portion of your Consts.py :rolleyes:, but I do believe I did! :eek: As I understand it (I haven't bothered to look this up in RiseAndFall.py for sure) the line commented as "#Celtia" (green) is where those Civs that get hit by the Celtic spawn would be entered. (iGreece is there at the moment as the only default Carthaginian neighbor, but that could of course be changed.) Any instance of iCeltia on any other line would give a stability hit for the Celtic player when these Civs spawn! (Right now those would be, in order, Spain, France, England and Portugal.) You should probably go through these settings and try different variations out.
As an afterthought, the American spawn will affect all the Western European Civs negatively. Does this mean that also the Celts should be negatively affected by the coming of the Americans? (If they in fact are still around - or have already respawned.)
One interesting aspect of your modmod, by the way, is that it could make things much more interesting regarding the English AI! I can see how England might end up not being as prominent or advanced due to the Celtic presence. And the mere thought of having Ireland pop up later as a major Civ is sending sensations of excitement up my spine! :king:
The Celts might, as well, end up breaking the English... :rolleyes:
antaine Feb 10, 2010, 11:13 AM I had originally included stability hits on the Celts for every western european civ, but now that they are basically Gaels who might possibly have continental holdings they must relinquish (which would have originally been indy tribes), I think I'll just leave in the Romans and English for now (maybe I'll put the French back in eventually).
As for the whole English thing, here's what I'm finding happens...the Celts are limited to the British Isles by the time the English spawn, and then England takes whatever cities they have on Britain (accurate). This is usually half or one more than half, so it causes stability problems for the Celts, but the English seem to do just fine (originally, dublin or belfast/cork were indy/minor spawns and not set to automatically flip). I've found that simply being in the area doens't prompt an automatic flip, there still needs to be cultural pressure from a neighboring city. The Celts tend to collapse and then can be absorbed by the English no harm no foul (history back on track). Honestly, as much as I'd like to see Ireland kick England's butt (and am looking forward to doing that myself), I feel that the history produced by the game in the Isles shouldn't be fundamentally different from real history if the human is playing a civ other than the Celts.
In reality, the Irish were not even close to resisting the English invasion due to disunity and technological disadvantage. By making them a major civ in the game, I'm giving the human player a *chance* to make better choices at key points in history and perhaps produce a different result, but I think the AI should behave as close to its historical counterpart as possible. In short, I'm very happy to see the AI collapse and lose every time to the English but knowing that a human could possibly to better by thinking outside the box.
Baldyr Feb 10, 2010, 11:37 AM I would love for you to explain what the bug is in that UHV code though, because I'd like to get it straightened out, although the current version works passably well but the first attempted fix did not tick as achieved when it was.
First of all you could just use my code, as it should take care of any issues with your code. I will in fact test that tonight to see I perhaps overlooked something. If I don't get back to you with any correction then it works fine. No harm in trying it out in a real game, though...
But here goes:
This is what your code for the second UHV looks like (with my comments added):
elif (iGameTurn == i500AD): #you ask if its game turn 174
if (self.getGoal(iCeltia, 1) == -1): #you ask if the UHV is still undecided
self.setGoal(iCeltia, 1, 0) #because then you set it to failed
if (iPlayer == iCeltia): #you first check if it really is the Celtic players turn (why?)
if (iGameTurn <= i500AD): #you check if its game turn 174 or any previous turn
bIsles = self.checkOwnedArea(iCeltia, tBritishIslesTL, tBritishIslesBR, 4) #you get condition 1
bGaul = self.checkOwnedArea(iCeltia, tGaulTL, tGaulBR, 2) #you get condition 2
bIberia = self.checkOwnedArea(iCeltia, tIberiaTL, tIberiaBR, 1) #you get condition 3
if (bIsles and bGaul and bIberia): #you check if all the conditions are met
self.setGoal(iCeltia, 1, 1) #only then do you set the UHV to achieved
First of all about everything is in the wrong place (see my version for the correction) and the line marked with red is totally redundant, except that it adds to the hierarchy of indentation. But you did make it work by, evidently, changing the indentation around. (I'll get back to that in a moment.)
Second of all, you should have the code for failing the UHV after the code that lets the player achieve it. Since the game will run the code in sequence, the UHV could already have been set to failed once it checks if its in fact achieved. This would get very confusing if its actually game turn #174! :eek:
I still believe the code could work just fine, but you'd have to double check if there can be an exception as for the last turn. It is very confusing to try and read in any case.
If you wanna have any control over what you do with your Python, it needs to be as readable to you as would plain English. This is one reason to have the code logically structured and in sequence. The other reason would be that a computer will only understand logic, and if you make any changes to you code it could very easily become illogical - to the game. And thus not work as intended.
Sure, you've managed to get by by the skin of your teeth on this occasion, but you might not be as lucky next time. Or the time after that.
As for indentation, its not there to make the code readable to the programmer himself - or to any other person viewing the code. It actually is required to follow principles of logic - in order to work! (Some programming languages would allow you to use any indentation that you feel is comfortable or practical - but not Python.) So you can't decide how much indentation to use for a line - or for a piece of code - on a whim. This can actually be a hassle sometimes, as long stretches of code can make it unclear where in the hierarchy some piece of code really is. But that is something we have to live and learn to cope with.
You could learn how this works in practice by simply looking at the code Rhye has done, or you could read up on the subject. Its not very hard, honestly! :king:
If you're unclear about these matters or if you for some reason can't seem to make a piece of code work, you could always send it to me privately and I'll take a look. Most of the time its really basic stuff and you will be able to learn from your mistakes instead of repeating them and ending up changing the indentation around randomly the next time you need to add a piece of code.
I have no problem with the elimination of future colonists for the Celts, although what do you think of a military unit spawn at that time?
As it would make sense historically I'm not opposed to it, as long as its only for the AI. I do believe that the human player should be required to build units of his own, and also make his own decisions as to what the goal or strategy of the game will be. Getting free units to do a scripted invasion... no. Not for me at least.
But you could, and should, try anything out. You might think its the best idea ever once you try it!
If you work more on victory.py, know that I'm adding the Vikings to the list of civs the Celts must not lose cities to.
No, not doing any more work on your files. :p Its really not practical to have several people work on the same set of files, and you seem to be doing well enough on your own now. And how would you ever learn if you don't at least try? :goodjob:
antaine Feb 10, 2010, 11:44 AM No problem with the victory file, it does create issues while you're correcting one aspect while i'm developing the next version separately. v2.1 will probably include the same code I had, but I'll be working on fixing it up for v2.2
And I agree about the free units, I'm not going to give them to either the human or to the AI.
Baldyr Feb 10, 2010, 11:52 AM ...the Celts are limited to the British Isles by the time the English spawn, and then England takes whatever cities they have on Britain (accurate). This is usually half or one more than half, so it causes stability problems for the Celts, but the English seem to do just fine (...)
It should be noted that its not actually instability that makes a Civ that looses half (or more) of its cities collapse. The Civ might as well be having a Golden Age with +50 stability, AFAIK. Its only determined by the number of cities lost, even if there are some exceptions also (like being a vassal).
I've found that simply being in the area doens't prompt an automatic flip, there still needs to be cultural pressure from a neighboring city.
No, I don't believe this to be true. There could be a limit on how many cities that can flip in one spawn though, but I'd have to check the actual code to find that out for sure. (With respawns its max 5 cities, I believe.)
In short, I'm very happy to see the AI collapse and lose every time to the English but knowing that a human could possibly to better by thinking outside the box.
Ok, I understand you standpoint and I don't disagree myself. Some folks might however think its a bit scripted to have the same (albeit historical) thing happen every single time. (Like have the Celts collapse on cue, because of whatever calamity hits them first.)
So, as for the design of your modmod, the outcome of the English spawn visa-vi the AI Celts could be made a bit more open-ended. There could at least be a grace period for the turns following the English spawn, disabling the AI only collapse trigger due to losing cities. The Celts should still collapse due to the loss of stability (caused by the loss of the cities) though, but in the rare case when they have enough stability they might actually survive long enough to put up a united fight once the English actually invade. And then collapse. :lol:
Baldyr Feb 10, 2010, 11:55 AM No problem with the victory file, it does create issues while you're correcting one aspect while i'm developing the next version separately. v2.1 will probably include the same code I had, but I'll be working on fixing it up for v2.2
Yeah, you should probably do that. But do take a closer look at my example to see how the whole thing could be improved and cleaned up. There is a lesson there for you to learn, if you're interested. :king:
antaine Feb 10, 2010, 12:18 PM Well, a little more variety could perhaps be added by allowing the English to try to flip London, York, Cornwall and Wales, but leaving Scotland outside their core...then they might take it in war sometimes and not take it at others...
as it is, the result isn't *always* the same, just "usually similar"
Baldyr Feb 10, 2010, 12:46 PM Yeah, Scotland actually has a history of independence, so I'd leave them out.
One thing I noticed about the English while running autoplay, by the way, was that they founded Hamburg and Copenhagen! :eek: I've never seen them do that before, so your modding would be to thank/blame for this development! :crazyeye:
edit: This makes me think that the AI will only make an effort to settle land that it knows about. Make sense?
antaine Feb 10, 2010, 12:51 PM I was just thinking that maybe i'd eliminate that second settler...they also sometimes got to Sweden (all historic locations for Saxons and their ancestors), but Hamburg-area cities are lost after the Germans and Dutch spawn, so perhaps it's okay. I think they're just looking for open space and now have a major civ to contend with.
In my autoplays, the English tend not to rename the Celtic cities they flip, even though their namemap has English names for them. Any idea why?
antaine Feb 10, 2010, 01:02 PM also, how would I change this in consts to make the celts more likely to sometimes fight civ spawns (especially the english)?
#war during rise of new civs
tAIStopBirthThreshold = (
80, #Egypt
80, #India
60, #China
50, #Babylonia
50, #Greece #would be 80 but with Turks must be lower
70, #Persia
80, #Celtia
80, #Rome
80, #Japan
80, #Ethiopia
80, #Maya
80, #Viking
80, #Arabia
80, #Khmer
80, #Spain #60 in vanilla and Warlords
80, #France #60 in vanilla and Warlords
50, #England
80, #Germany #70 in vanilla and Warlords
50, #Russia
80, #Holland
70, #Mali
60, #Portugal
70, #Inca
70, #Mongolia
50, #Aztec
70, #Turkey
50, #America
100,
100,
100,
100,
100)
Baldyr Feb 10, 2010, 01:04 PM I was just thinking that maybe i'd eliminate that second settler...they also sometimes got to Sweden (all historic locations for Saxons and their ancestors), but Hamburg-area cities are lost after the Germans and Dutch spawn, so perhaps it's okay. I think they're just looking for open space and now have a major civ to contend with.
You could try this as an experiment:
Edit the scenario file (World Builder save) to reveal some desirable tiles to the Celts, so that they actually know about the areas you have marked up for them in the Settler maps.
There should be several ways to achieve this, the simplest could be to just give them a Workboat at the shores you'd like them to colonize. Since the Civ hasn't spawned yet that unit should do exactly nothing, but just to be sure, edit in a Barbarian Galley on an adjacent tile. Both will be gone forever once the first turn is over, but once the Celts spawn they will have knowledge of the area surrounding the former unit. (This is true both for the human player and the AI.)
In my autoplays, the English tend not to rename the Celtic cities they flip, even though their namemap has English names for them. Any idea why?
This would be because the actual plotting isn't achieving the dynamic names. Its actually the code beneath, in the lower section of the CityManager.py file. I can actually see that you haven't added any dynamic names for the Celts either (although some seem to already be there). The code is pretty straight forward though, so you shouldn't have any problems editing it.
Start with the Celts first (line #4552+) and work your way through the rest of the Civs. Good luck! :goodjob:
antaine Feb 10, 2010, 01:08 PM oh, i didn't mean the celtic settler, which they invariably take to western france, but the english settler. the celtic settler actually allows for variation depending on whichof their favorite four tiles they choose, affecting indy city spawns...
Baldyr Feb 10, 2010, 01:11 PM also, how would I change this in consts to make the celts more likely to sometimes fight civ spawns (especially the english)?
This is actually so simple I'm surprised you ask, but since there are no stupid questions regarding Python, here's an answer:
The entry on the line commented as "#iCeltia" is the percentile probability for the AI Celts to declare on a spawning Civ trying to take over cities or units. Since its already 80% this should happen most of the time. Not?
Well, if you rise it to an even 100% it should happen every single time, at least that's what the code reads like to me... Get back to me if it doesn't and I'll take another look.
Baldyr Feb 10, 2010, 01:13 PM oh, i didn't mean the celtic settler, which they invariably take to western france, but the english settler. the celtic settler actually allows for variation depending on whichof their favorite four tiles they choose, affecting indy city spawns...
I guess I'm still thinking about v1 where you wanted the Celts to move to Britain. Maybe they would have, if they'd known about such a thing as "Britain". But since they had ships and all I might just be wrong on this.
antaine Feb 10, 2010, 01:14 PM no, they wouldn't use settlers even when I put them on the island, exposing the tiles.
The Celts rarely contest a spawn...I dont' think i've seen it yet...but I dont' want them to do it all the time, either.
i'll get to work fixing the names
Baldyr Feb 10, 2010, 01:23 PM The Celts rarely contest a spawn...I dont' think i've seen it yet...but I dont' want them to do it all the time, either.
Hmm... How would you know? Have you been playing as the English then?
I believe the only thing AI Civs will do to newcomers is to declare war on them. I don't even think they get the option "contest" anything. They lose the cities and units, and sometimes declare war on the perpetrator. End of story.
There is however some extra units in it for the spawning Civ. For every old Civ that reacts by declaring war, the new Civ will get some extra units.
In my Russia scenario I made it so that the Mongols would always be at war with pretty much everyone when they spawned. I remember having problems with achieving this at first though, and I don't quite recall how I solved the problem either. But it works now, that much I know...
Now its sleepy time for me, since I feel I really need to get some shut eye this week... :rolleyes: Be good! :goodjob:
antaine Feb 10, 2010, 01:26 PM I wonder if doubling the name entries in "stability hit on spawn" works like in the other similar list, making the english give the celts a double stability hit...especially good if they're not autoflipping edinburgh, too...
antaine Feb 10, 2010, 02:24 PM there seems to be two celtic dynamic city names lists down there...does it matter that the main bulk of the city names are in the list labeled "#late start condition?" Will it simply read those names as long as Celtia "isalive," or only if the old 600AD start is chosen?
***apparently it works either way :goodjob:
antaine Feb 10, 2010, 03:43 PM Changes made in v2.1
http://www.filefactory.com/file/b00bcd7/n/RFC_with_Celts.zip
- I have added more Indy city popups at staggered intervals (when the cities actually came to be)
- Celtic (and Roman and English) expansion will largely be of conquest rather than settlement (historically accurate for this period).
- The second English settler has been eliminated, since their island is already pretty full by spawntime and they tend to just use it to settle in Sweden or Germany anyway.
- This produces more accurate Roman, French, Spanish and English AI expansion. Even the Vikings tend to like to take the Independent Eabhrac (York) if the AI Celts don't, which is also historically accurate (Celtic Eabhrac -> Roman Eboracum -> Viking Jorvik -> English York).
- If the Celtic capital is founded on the start square, or north of it, Independent Irish cities of Gaillimh (Galway) and Corcaigh (Cork) will eventually spawn, as well as Independent Welsh Caerdydd (Cardiff). Other British spawns representing independent Celtic tribes are eventually Dún Éideann (Edinburgh) and Eabhrac (York). A barbarian Londinium (London) representing the Roman settlement (the Roman AI never makes the attempt to settle there) will also pop up.
- In Gaul there is one addition to Rhye's original three Lutetia, Burdigala and Lugdonum (Paris, Bordeaux, Lyon), Roazhon (Rennes).
- In Galicia, the Independent city of Xixón (Gijón) will self-found.
-All independent Celtic cities will self-found with two Galician Warriors, to represent their symbolic culture.
- Settling one square south of the start location of Tara and founding Dublin will prevent Cork and Cardiff from showing up. Likewise, settling one square south of Rennes and founding Nantes will prevent Bordeaux and Rennes from showing up. I mention the one about Nantes because half the time the Celtic AI uses a starting settler to found it.
-for the UHV, the territory of Gaul now covers all of historic Gaul instead of just the western seaboard.
- The Celts now must not lose cities to the Romans, English OR the Vikings.
- stability hits on spawn for Spain, Portugal and the Netherlands have been removed. Celtic stability hits still occur for the English, French and Romans.
- Dynamic city names have been updated (mostly) for the English, French and Celts
This scenario usually results in AI Roman Italy, Gaul and Iberia and AI Celtic Britain and Ireland giving way to Portugal, Spain France and a still-strong England with an AI Celtic collapse and loss (or similar situation…never been exactly the same twice). Basically, when all civs are played by the computer the scenario produces something very close to history as it was :king:
Still to be corrected are the following:
- "Rome declares war on Rome" type errors
- Celts still absent from the civilopedia
- translations need to be done for the UHVs
Baldyr Feb 10, 2010, 09:42 PM I wonder if doubling the name entries in "stability hit on spawn" works like in the other similar list, making the english give the celts a double stability hit...especially good if they're not autoflipping edinburgh, too...
I doubt it. It should be a regular list, as "if name in list" - then... I could look it up though.
there seems to be two celtic dynamic city names lists down there...does it matter that the main bulk of the city names are in the list labeled "#late start condition?" Will it simply read those names as long as Celtia "isalive," or only if the old 600AD start is chosen?
The other ("late") set of code is for Byzantium. As the Celtic Civ gets replaced by the Byzantine one in the AD 600 start.
If you see a reference to "late start condition" in the Python the code following this "if" statement doens't concern your modmod. (This is in fact what I meant previously by you breaking the AD 600 scenario. Since you replaced Byzantium with Carthage... :rolleyes:)
antaine Feb 10, 2010, 10:29 PM I tested it and the list works, even though it says "late start."
Nalim Feb 11, 2010, 03:32 AM Hello
I've translate UHV in french, here. As i don't know where it goes, i paste it here:
- Contrôler la ville de Rome en 450 ap. J.-C.
- Contrôler 4 villes dans les Iles Britanniques, 2 villes en Gaule et 1 ville en Galice avant 500 ap. J.-C.
- Ne perdre aucune ville aux Romains, aux Anglais ou aux Vikings avant 1700 ap. J.-C.
For all it's for your last version, v2.1
Very nice work :)
antaine Feb 11, 2010, 08:05 AM merci beaucoup!
Baldyr Feb 11, 2010, 09:20 AM I tested it and the list works, even though it says "late start."
It shouldn't. Did you only list everything once or did you double up on the lists? Because if you did, you also gave the Byzantines (in the AD 600 start) the Celtic dynamic city names. But that has no effect what so ever on your modmod, as you haven't supplied an actual AD 600 scenario...
Rhye has used a rather... interesting way of determining which scenario is actually playing. Since the Python for both the 3000 BC and the AD 600 start is the same, his code looks for Player #0, that is the Egyptians. If Egypt is available on the active start then its the 3000 BC start, otherwise its 600 AD. Nifty, eh?
Did you realize, by the way, that by replacing iCeltia with iCarthage in all the code, you've really just replaced the value 6 with the value 30, and vice versa. Because those are the values given to these variables by Rhye in Consts.py. So, the game has no idea what "Celts" or "iCeltia" actually is, other than that those variables happen to correspond to those specific Civs in the game.
antaine Feb 11, 2010, 09:22 AM yup...that's why I don't think of it as swapping the celts and carthaginians, but renaming the carthaginians celts and celts carthaginians...and then writing new info for "celts" which the game just knows as "team 6"
Baldyr Feb 11, 2010, 09:32 AM Changes made in v2.1
I must admit, this sound like a very solid modmod! :king: I haven't actually played any of the version yet, but once I can spare the time I might just do that. :D
I thought I'd take a look at the Civilopedia thing for you. I have never really dabbled with that myself, but I bet its really easy to achieve. Too bad the community hasn't stepped up to help you with this one yet... :p
antaine Feb 11, 2010, 09:35 AM yup, I think the text is from the original game, it's just flagged to include carth at the moment
Baldyr Feb 11, 2010, 09:52 AM yup, I think the text is from the original game, it's just flagged to include carth at the moment
I believe that you would be correct on this. Lots of stuff isn't present in the Civilopedia, like minor Civs or the Plague "building" or Mercenary only units.
So, somewhere there is some piece of code, or something, that is dictating what info is actually shown and not.
I'll look around some to see what I can find out.
patkog Feb 11, 2010, 10:04 AM Downloading the new version, i could make the German translation for the UHV's
Here they are:
Kontrollieren Sie die Stadt Rom im Jahr 450 n. Chr.
Kontrollieren Sie 4 Städte auf den Britischen Inseln, 2 Städte in Gallien und 1 Stadt in Galicien vor 500 n. Chr
Verlieren Sie bis zum bis zum Jahr 1700 n. Chr. keine einzige Stadt an die Römer, Engländer oder Wikinger
Baldyr Feb 11, 2010, 10:44 AM Done. I changed the value on line #504 in CvPediaMain.py (located in ...\Assets\Python\screens\) and that did it. It did nothing to do the same for the leader and the UU, but at least the Celtic ones show up now. But I believe that both Hannibal and the Numidian Cavalry should still be in the Civilopedia, anyway...
File attached.
This takes care of all but the Civs declaring on themselves bug, then? I believe this bug to be found elsewhere also, so it could already be fixed by other modders. Look for it and implement it on your own modmod.
antaine Feb 11, 2010, 10:58 AM I saw a cryptic answer once by Rhye that it's caused by messing around with the DLL and there's not place to just go and fix it. I'm still looking for answers and am open to suggestions, though.
Thanks for the german and the 'pedia fix.
antaine Feb 11, 2010, 11:14 AM .....removed because I found it....
antaine Feb 11, 2010, 11:18 AM need to get the dun in there as well...
I can see the lines, I just don't know what to do with them.
In the meantime, I'm going to set about trying to replace the writeup about Brennus with one for Brian Boru
Baldyr Feb 11, 2010, 11:35 AM need to get the dun in there as well...
Try and comment out line #357 in CvPediaBuilding.py - I actually forgot about the UBs... If you wanna take away the Carthaginian UB try replacing the value 1 on that line with 20.
It should work...
jmerry Feb 11, 2010, 11:35 AM The dun is in CvPediaBuilding.py, in getBuildingSortedList.
Oh, and thanks for the tip- I'm going to release version 1.1 of my mod, making the extra building I created invisible in the pedia.
antaine Feb 11, 2010, 11:54 AM how is it determined when leaders are replaced with later leaders?
if it is broken down by ages, I'd like to do
ancient, Brennus agg, exp
classical, Boudica agg, prot
medieval, Briain Boroimhe fin, imp
renaissance, Aodh Mór Ó Néill prot, cre
modern, Michael Collins cha, cre
I would do a write-up for each of the new ones myself, and just use the animation they provide ...although I think the celts start off in the classical period, in which case I'd use boudica but make her agg/exp
Baldyr Feb 11, 2010, 12:12 PM how is it determined when leaders are replaced with later leaders?
if it is broken down by ages, I'd like to do
ancient, Brennus agg, exp
classical, Boudica agg, prot
medieval, Briain Boroimhe fin, imp
renaissance, Aodh Mór Ó Néill prot, cre
modern, Michael Collins cha, cre
I would do a write-up for each of the new ones myself, and just use the animation they provide ...although I think the celts start off in the classical period, in which case I'd use boudica but make her agg/exp
Note that there are no leader traits in RFC! We get the UPs instead.
I haven't done any work involving switching leaders myself yet, but I have thought of making Brennus into the mythical forefather of the royal Russian Rurikid lineage, Rurik I. So I'd come there eventually.
Just a observation: Since you seem to be like me you will actually never finish your modmod, but will continue to see potential for improvement and expansion, ad infinitum. As soon as you sit down and actually play the mod, you will wanna change something and restart with that setting instead. And I'm not counting any kind of play testing as "playing" the mod.
I myself started out with plans for some light modding on RFC in order to create a scenario about Russian history (mostly involving a new set of starting condition). Then I learned Python. Right now I'm far beyond any kind of point of no return with this modding business, as I have more loose ends than I can keep track of...
The thing I was working on before I pretty much devoted my time to your mod was actually decolonialism. My plans for it are so ambitious I don't even dare to continue! Also, I have plans for adding a system of political (and revolutionary) oppositions, resulting in a political aspect to the game. This is such a huge undertaking I haven't even started taking notes yet...
I'm not seeing how I'm ever gonna actually get to play the damned Russia scenario, since it will never be finished and since I've run enough autoplay on RFC to make the whole idea seem... already done. Oh, well... :rolleyes:
jmerry Feb 11, 2010, 12:20 PM The leader switch happens during anarchy, switching to a random early leader early in the game and a random late leader late in the game. This is controlled by game turn, not era. By the way, leader changes that change traits are bad. I tested a leader with a research bonus trait and one without for the Maya; when the switch triggered, the display went away and the actual research bonus didn't. Leader switches only work nicely in RFC because there aren't any traits- and in my modmod, because every leader for a civ has the same traits.
The Celts should probably have Brennus and Boudica as early leaders, then maybe one of your choice as a late leader.
antaine Feb 11, 2010, 12:22 PM heh...oh, I'm very wary of that. I have to keep reminding myself that I started this whole thing so I could play the Celts in a whole-earth scenario according to Rhye's rules. It was all for naught if I don't ever get to do that. Maybe I'll just do a writeup for Brian Boru and not worry about the other leaders...with no traits there's really not much point anyway.
I'm nearing completion, acutally. I need to fix the leader and add North American cities to everybody's city name map.(the Americans won't rename New York if it's "Grenoble" when they start). Other than that, unless people have balance complaints in the next week or so, I'm done.
Then I can start trying to port all my Celtic additions over to the multiplayer version (which I've never even seen...I'm assuming it's basically the same as RFC with multiplayer function added). I'm happy with the locations, the spawns, the uhvs and all the rest...
antaine Feb 11, 2010, 12:24 PM jmerry, that's not a bad idea. I can just keep them as-is and add brian boru as a late leader.
btw...thanks so much for doing the holy city relocation patch, it's a lifesaver.
Baldyr Feb 11, 2010, 12:33 PM how is it determined when leaders are replaced with later leaders?
I took a closer look at the code (found in RiseAndFall.py) and the leader switch seems to be triggered by Anarchy, mostly. The settings for leaders are found in Consts.py and there are three sets of these. The code differentiates between "early" and "late" leaders, and there are actually dates associated for each "late" leader:
tLateLeaders = ( #all up to 300 turns earlier because the switch is triggered after a few years
(iRamesses,),
(iGandhi, i1700AD, 5, 4),
(iMing_Tai_Zu, i1400AD, 10, 3, iMao, i1800AD, 10, 5),
(iHammurabi, i1600BC, 10, 1),
(iAlexander, i10BC, 5, 2),
(iDarius, i10BC, 5, 2),
(iBrennus,),
tRomanLateLeaders,
(iTokugawa,),
(iZara_Yaqob,),
(iPacal,),
(iRagnar,),
(iSaladin,),
(iSuryavarman,),
(iIsabella,),
(iNapoleon, i1700AD, 10, 4, iDe_Gaulle, i1940AD, 10, 5),
(iVictoria, i1600AD, 15, 3, iChurchill, i1930AD, 10, 5),
(iFrederick, i1500AD, 10, 3, iBismarck, i1760AD, 10, 4),
(iCatherine, i1600AD, 15, 4, iStalin, i1800AD, 15, 5),
(iWillem_Van_Oranje,),
(iMansa_Musa,),
(iJoao,),
(iHuayna_Capac,),
(iKublai_Khan, i1500AD, 10, 3),
(iMontezuma,),
(iSuleiman, i1500AD, 10, 3),
(iLincoln, i1800AD, 15, 5, iFranklin_Roosevelt, i1900AD, 15, 5))
Just like the commenting says on the first line, the dates are actually not historical but rather based upon the randomness of the game mechanics involved (Anarchy, depression, instability and plague). You could use the dates above as a guideline, as they give you the earlies possible switch for each leader.
The current code only allows for two "late" leaders per Civ (for a total of 3 per Civ), but the code itself could always be expanded to make room for more. :D It should be a piece of cake, actually.
What the numerical values do is a bit sketchy for the moment, but as far as I can tell - without analyzing the code in great detail - these seem to be the percentile probability for the leader to actually switch, and the era at which that leader would be twice as probable to show up, respectively.
So start the groundwork on this and well make it happen, eventually. :king:
Baldyr Feb 11, 2010, 12:44 PM The leader switch happens during anarchy, switching to a random early leader early in the game and a random late leader late in the game. This is controlled by game turn, not era.
I checked and there was actually more to it than I would have thought. So, based on mere observation of the gameplay I would have thought your answer was fairly accurate, but it turns out there is far less randomness to it and that the eras actually do matter.
Heck, I might just make that Brennus guy appear as the default (early) Russian leader, after all. Since I've already figured most of this stuff out its no longer a pipe dream. :king:
I'm learning tons of stuff just trying to answer antaines questions the best I can! :goodjob:
jmerry Feb 11, 2010, 12:56 PM Ah- I wasn't reading the whole thing. The distinction between early and late is by game turn only, but which late leader is picked is affected by era.
Incidentally, initial anarchy (in the first 3 turns) is exempted from any leader change.
Baldyr Feb 11, 2010, 01:08 PM Incidentally, initial anarchy (in the first 3 turns) is exempted from any leader change.
Yeah? This actually has some implications for my own modding... (As there is much, much more Anarchy in my game.) Thanks for pointing this out, as I would have surely missed it otherwise. Its not like I would notice leader switching in autoplay anyway...
Panopticon Feb 11, 2010, 01:16 PM The current code only allows for two "late" leaders per Civ (for a total of 3 per Civ), but the code itself could always be expanded to make room for more. :D It should be a piece of cake, actually.
I have done the relevant code in an earlier leaderhead discussion.
if (len(tLeaders[iPlayer]) > 1):
if (len(tLateLeaders[iPlayer]) > 9):
if (iGameTurn >= tLateLeaders[iPlayer][9]):
self.switchLateLeaders(iPlayer, 8)
elif (iGameTurn >= tLateLeaders[iPlayer][5]):
self.switchLateLeaders(iPlayer, 4)
elif (iGameTurn >= tLateLeaders[iPlayer][1]):
self.switchLateLeaders(iPlayer, 0)
elif (len(tLateLeaders[iPlayer]) > 5):
if (iGameTurn >= tLateLeaders[iPlayer][5]):
self.switchLateLeaders(iPlayer, 4)
elif (iGameTurn >= tLateLeaders[iPlayer][1]):
self.switchLateLeaders(iPlayer, 0)
else:
if (iGameTurn >= tLateLeaders[iPlayer][1]):
self.switchLateLeaders(iPlayer, 0)
This can be iterated for multiple leader switches.
Baldyr Feb 11, 2010, 01:26 PM I have done the relevant code in an earlier leaderhead discussion.
:goodjob: The solution was in line with my own thinking. :king:
Baldyr Feb 11, 2010, 01:35 PM I'm yet to actually test your modmod :rolleyes: but I ran some autoplay on this latest version I really liked what i saw. :goodjob: (The Celts actually founded a city in Bretagne, and flipped Whales. Very nice!)
My only real issue is with this feature:
A barbarian Londinium (London) representing the Roman settlement (the Roman AI never makes the attempt to settle there) will also pop up.
It doesn't make any kind of sense to me. I'm all for not having a unpopulated England before the English, but shouldn't there be Celtic tribes (independents) in that area?
Sure, I wouldn't argue with giving the Roman Civ a free city in England if they actually controlled an Atlantic port (and this could be coded). That would make sense.
Also, I guess you've noticed how the Celtic Civ always collapses into different Independents, and not just one variety? This is how I believe Rhye has intended tribal societies to be represented. Thus your city spawns should also be of the two independent variants. It makes a lot of sense and is in line with the rest of the design. (Could someone agree with me on this point?)
I'm not gonna look at your Python this time around, unless you have some issues you actually need help with... :p
hix Feb 11, 2010, 01:48 PM I am playing your mod right now and am unable to achieve the 2nd UHV. Even went into world builder, moving cities around, and was unable to get it. I would assume that cities in France and Spain's spawns would count, but didn't work for me. Do you have a map or a clear description of the uhv areas?
Baldyr Feb 11, 2010, 02:03 PM I am playing your mod right now and am unable to achieve the 2nd UHV. Even went into world builder, moving cities around, and was unable to get it. I would assume that cities in France and Spain's spawns would count, but didn't work for me. Do you have a map or a clear description of the uhv areas?
It would be helpful if you attached a save file from the game.
Otherwise you could describe the circumstances in some detail.
antaine: You can tell me when I need to check your actual code. ;)
hix Feb 11, 2010, 02:14 PM I am on my laptop right now, so I don't have the savegame, but I had the capital built on spot, bordeaux, a coastal city in northern France(near Calais), and a city on the horse next to madrid, the two cities that flip from capital, and the city in scotland (inverness?)...should've triggered, right?
antaine Feb 11, 2010, 02:44 PM It sounds like your Spanish city is one or two tiles too far south. This is how I've got it set up (to the best of my recollection, see attached picture).
I used Londinium for two reasons, first, there's no Celtic settlement of note in the area. Yes, they provided the population, but I don't have anything else city-wise to put on that spot and name. The other reason is that left to its own devices, the Celtic AI makes no effort to spawn a settler and put it anywhere on either island.
I did have Londinium spawn with Gallic Warriors to represent the Celtic tribes in the area, but I would be amenable to providing barbarian Roman units or simply giving the Romans a free city, but I tried to shy away from simply handing a city over even to the AI. As it is I only begrudgingly gave sure-to-flip cities to the Celts, but felt a little more comfortable as Rhye gave the Romans two or three of them himself.
So, I'm open to suggestions...how would you, as players, like to see me handle the great open space in southeast Britain? I suppose I could always leave that blank and allow Cornwal, Wales, York and Scotland be it for the auto spawns.
As for the independent/independent2/barb spawns, you are right, they should be different; I'll go in and mix them up now.
Baldyr Feb 11, 2010, 02:58 PM I'm browsing through a book on prehistoric London and in the timeline there are four "Middle Iron Age" (600-400 BC) settlements noted: Rainham, Dawley, Bedfond and Heathrow. A caption inside the book tells me about the temple in Heathrow pictured in an illustration.
Around the year 200 BC there is a mention of the "Occupation of Uphall Camp". The settlement in question is described as a trading outpost in yet another caption adjacent to a picture of a hillfort.
I'd suggest searching the Wikipedia on these settlements to find out more. (Dates and the such.)
Another suggestion would be to call the city "Thames", or any Celtic equivalent to the river's name. According to my source, the plot has been populated since long before recorded history. Actually well before the advent of Homo Sapiens.
antaine Feb 11, 2010, 03:03 PM awesome. I will check into that and adjust the name accordingly. I also have to do the North American additions for everybody likely to beat the US to the continent (so that the names will be predictable for the dynamic names). I'm still going to keep the Celtic dynamic name as Londain, since that is the modern Irish name for the city and it should be renamed that if captured from the English, who would have named it London, but I'll come up with something suitable as a spawn name and tell the English to rename whatever makes the final cut London. That way, if the Celts take it from the Barbs, they'll keep the spawn name, but if they capture it from the english they'll change it from London to Londain.
antaine Feb 11, 2010, 03:05 PM Also, is there a way to disable the "don't spawn if a unit is in an adjacent square" thing? Or is there a truly compelling reason that should be left in?
jmerry Feb 11, 2010, 03:37 PM I took another look at the leader switch code- it's quite squirrely. Since it's a digression, I'll hide it in a spoiler.
There are up to four leaders for each civ: an initial leader (in WB save, first in leaders list), an early leader, and up to two late leaders. In practice, the initial leader is always either the early leader or one of the late leaders - but there's nothing in the code forcing this.
In the WB save, everyone is the initial leader.
When the game starts, for everyone that's not human, switch to the early leader.
At the beginning of the turn, if it's more than 3 and less than 50 turns after spawning and the civ is in anarchy, switch to the initial leader.
In any other anarchy, if it's after the first late leader's date, switch to that late leader. (This block is entirely redundant, as the next switch condition always triggers)
At the beginning of the turn, if it's after one of the late leader's dates and the civ is in anarchy/plague/depression or just randomly (chance dependent on leader and era), switch to that late leader. This late switch can also trigger the Soviet city names.
Example: Russia's initial leader is Stalin, their early leader is Peter, and their late leaders are Catherine (1600) and Stalin (1800).
A hypothetical path: The AI Russians spawn in 860 AD led by Peter (their early leader). They immediately switch civics, triggering no leader change. That egotist founds his city Sankt-Petersburg. Twenty turns later, a religion spreads to one of their cities. They convert, and become Stalin. In 1620 AD, they go into anarchy and become Catherine. In 1814 AD, the 15% random chance hits and Stalin takes over again. Sankt-Petersburg is renamed Leningrad.
There's no randomness in the choice of leaders; the only random component is the chance to switch when nothing special is happening. It's a good enough chance (5-15%, doubled if it's that leader's era or later) that those switches should account for most late leader changes.
As for the early switches- they only ever change anything for the human if you started as another civ and took over midgame.
hix Feb 11, 2010, 04:29 PM alright, I think I have looked at this thouroughly, and I don't see why the 2nd uhv hasnt triggered, I think this is a genuine problem, but I may be a little mixed up (good green around)
antaine Feb 11, 2010, 05:29 PM found the problem...I hadn't saved a change I made to the definition of "Gaul." In the version you have "Gaul" only extends as far east as the Cherbourg peninsula (one tile west of Paris). La Tene is east of that. I have fixed the code and it will cover all of France in the next (which should be "final") release.
If you'd like to fix it yourself in the meantime, simply replace the coordinates in Victory.py (in Assets/Python) to read:
tGaulTL = (51, 47)
tGaulBR = (56, 52)
You should only have to change tGaulBR.
In addition, it was my mistake, but I've found that tGalicia extends one row farther south than I indicated in the drawing (one row of tiles south of the river), but stops one column west of it (at the middle, instead of the easternmost of the Pyrenees). That gives more area, but does not include the tiles right on the Mediterranean. Sorry for the mixup there, I was drawing the map from memory.
antaine Feb 11, 2010, 05:37 PM Also, it looks like you might have v2.0 instead of v2.1. There have been some changes to naming and city spawns. I plan to release the final version (v3.0) within the next two weeks (hopfully sooner than that). You're welcome to download 2.1 in the meantime or simply continue playing 2.0 until the final release. There shouldn't be any other changes or versions before that.
antaine Feb 11, 2010, 05:49 PM The following quotes come from wikipedia
"Rainham as it is known today has grown from a Roman village, which is now at the centre of the town. Until occupation by the Romans, Rainham itself had neither a name or identity."
"Referred to in the Domesday Book as “Bedefunde”, the name is thought to be derived from Anglo-Saxon Bedfunta = "Bed’s spring", or Bydenfunta = "spring provided with a drinking-vessel"."
I can't find a Celtic name connection for Dawley or Heathrow.
I'm going to follow your advice and use the name of the Thames
antaine Feb 11, 2010, 09:20 PM alright, so I'm done with the city name and autospawn tweaking and am not going to mess with the leaders. As far as I'm concerned, this mod is done. I'll give a preliminary release that I expect to officially become the final release in about two weeks (I want to give time for bugs and imbalances to pop up.
preliminary final release:
http://www.filefactory.com/file/b00g3dc/n/RFC_with_Celts.zip
Baldyr Feb 11, 2010, 10:10 PM Also, is there a way to disable the "don't spawn if a unit is in an adjacent square" thing? Or is there a truly compelling reason that should be left in?
Yes, I've disabled some stuff in Barbs.py in my own mod/game/whatever. So now the code doesn't take any notice of units or culture, among other things. (I also added code to spread foreign culture in tiles. I created Poland with Independent cities this way.) But as I've learned more and more Python I've also realized that I could have just made my own code instead of breaking Rhye's... It works nonetheless.
If you wanna use something like that it would require a lot of testing to make absolutely sure no issues arise from doing so. There might be good reasons for Rhye to have put those limitations in there, but it might also just be to somewhat "hide" the spawns. (It would seem like the city was actually founded outside of view.)
antaine Feb 11, 2010, 10:31 PM I'd just assumed it was to prevent the human from camping the location with a stack and sacking it the minute it appeared.
btw - just had the first test run where the Celts were still alive at turn 330, with only Ireland, achieved one UHV, stayed stable, and actually founded Nova Scotia.
Baldyr Feb 12, 2010, 08:27 AM I'd just assumed it was to prevent the human from camping the location with a stack and sacking it the minute it appeared.
Na, when I disabled the limitations all units on the spot got moved outside the cultural borders. So it would be the same as camping outside the location.
You know what, I actually think I'll get rid off all my own issues with city spawns this weekend by creating new code and restore Rhye's code to its original shape. This time I'll get it right (since I actually know what I'm doing) and gain total control over my city spawns. Plot-culture, preset buildings, religions, the works. Why settle with anything less when the power is right there at your fingertips?
You could of course use the new code also, if you want to. It'll be in a separate .py file altogether so there would be no need for me to edit any of your stuff. I think I'll post it on the forums as a mod component for anyone to use. City spawning might be the most obvious entry point for Python modding within the RFC setup - as it was for me and I believe also you - so that would give more people incentive to get involved in modding.
antaine Feb 12, 2010, 08:40 AM Well, I'd love to learn more, but after sleeping on it I think I'm going to leave the city spawns alone as well. some not popping up provides variety. to the development.
Two things I wish I could fix...First, I wish that the English were more aggressive with the Celts (especially since they don't collapse in the middle ages every time now) and with building culture...French culture usually pushes in all around London while they just sit there building archers.
Second, the English seem to like sending colonists into sweden and northern russia (around arkangel) before it ever occurs to them to attack the three cities on the island to their west. I think making the English automatically at war with both independents might help that...I can see them not bothering to declare war when they're off their main island, but still. Perhaps automatic war with the celts would be helpful as well.
I don't want to make things *too* hard for the human, but I don't want to automatically prevent the British Empire when the Celts are non-human.
Baldyr Feb 12, 2010, 08:41 AM By the way, I let a session of autoplay run its course last night while doing something else, and once it was done I noticed that the Celts had respawned with half of Britain and western France. So I took a closer look at your Consts.py and realized that you enlarged the Celtic Normal Area. Maybe i shouldn't question your judgment on this, but wasn't the idea to have the Celts respawn as the Republic of Ireland? :confused:
antaine Feb 12, 2010, 08:48 AM I've yet to see them respawn...ever...
Still, consider that a revitalized pan-celtic nation, if established today, could include ireland, scotland, wales, brittany, the isle of man (not on the civ map) and possibly cornwall.
I needed to enlarge the normal area (which was actually done way, way back) to aid flipping (as it is, the vikings usually claim edinburgh when the celts are AI), desire to expand and possibly provoke collapse with the english spawn.
I thought you also had a resurrection that only flipped ireland and scotland, no?
antaine Feb 12, 2010, 08:51 AM also, did this flip provoke war with france and england? I would imagine that those cities would have been hard for the ai to defend and would have been lost in short order, no?
antaine Feb 12, 2010, 08:55 AM http://en.wikipedia.org/wiki/Celtic_League_%28political_organisation%29
"Politically, the Celtic league seeks to create six sovereign states from the six Celtic nations it acknowledges as existing, unified in some way. There is some variation in the understanding of these aims, which ranges from general meetings, to an actual federation along the lines of the Nordic Council."
Not that they're anwhere near achieving an independent Pan-Celtia, but the idea is out there...
http://pl-pl.facebook.com/note.php?note_id=53855795310
Apparently, in your alternate history, these guys succeeded...lol...now, what I want to know is, will it *always* flip five cities if they are available, or could it be less? I could envision an alternate history where Brittany gains its independence in 1921 instead of Ireland, or what have you...
Baldyr Feb 12, 2010, 08:56 AM Well, I'd love to learn more, but after sleeping on it I think I'm going to leave the city spawns alone as well. some not popping up provides variety. to the development.
I'll just create the code and you could use it or not. I know I will use it, as I believe anyone would who tries to create a historical scenario. (Not that that's what you're doing.) It would be as simple to use as substituting the function self.foundCity() with custom.foundCity() and use a separate set of settings and values. I imagine it could be useful to spawn independent Celtic cities with pre-built Duns, for example. Personally I tend to spread some culture around newly founded cities, and this approach will make this less of a hassle also.
Two things I wish I could fix...First, I wish that the English were more aggressive with the Celts (especially since they don't collapse in the middle ages every time now) and with building culture...French culture usually pushes in all around London while they just sit there building archers.
Second, the English seem to like sending colonists into sweden and northern russia (around arkangel) before it ever occurs to them to attack the three cities on the island to their west. I think making the English automatically at war with both independents might help that...I can see them not bothering to declare war when they're off their main island, but still. Perhaps automatic war with the celts would be helpful as well.
I don't want to make things *too* hard for the human, but I don't want to automatically prevent the British Empire when the Celts are non-human.
First of all you can make the English be at war with the Independents by editing Consts.py - even if there would still be a random element to it. You could also increase the probability of the English being at war with the Celts on spawn. (Simply add instances of iCeltia on the their line.)
Secondly, anything you do could always be excluded from either the human player or the AI. So, there could be automatic war between AI England and AI Celts, but not between AI England and human Celts, or between human England and AI Celts. Its just a matter of adding a line of code excluding either the human player or the AI.
Since you mentioned it, I could include a setting in my expanded city spawn function for war-on-spawn. So if flagged "True" (instead of "False") the city would make the Civ who's Core Area the city is encroaching (if any) automatically declare on the city owner. (That would be optional and determined case by case, that is.)
antaine Feb 12, 2010, 09:11 AM another interesting thing...I staggered the Independents that spawn, so they are always neighbors with a different type than themselves. Sometimes, the Celtic tribes in britain prove pushovers and cardiff falls due to culture in short order. Sometimes, the (same type) independents of edinburgh and penzance flip cardiff, and unite into that "celtic league" you mentioned...both historically feasible...good variety there, I think...
Baldyr Feb 12, 2010, 09:15 AM I didn't actually follow any of the autoplay, but I'll attach a autosave. (I also see now that it was only Ireland and western France that flipped, or so it would seem.)
The ideas you put forward are interesting so you could very well be right on this. Since I do believe there is a 5 city limit that could mean different outcomes in different games. I'll just take another look at the code for the specifics and get back to you.
You could try and run autoplays as the Americans and give yourself (as Washington) Calendar and Nationalism (after the Celts have collapsed). Once you give yourself the latter respawning will be enabled and its only a matter of time before they reappear. There is a period of no-spawn for any collapsed Civ though, so you'd have to wait for some number of turns before they are enabled again. This is a pretty sure way of testing it, even if the actual respawn would happen in the wrong era.
If you enable the game option Random Seed on Reload (in the WB save) you can reload the same autosave several times to get different outcomes.
antaine Feb 12, 2010, 09:42 AM so, what do you think of the following re: english colonizing russia and scandinavia:
I place a deep ocean at the tip of denmark, cutting off galley passage to the baltic sea, and a deep ocean at the north tip of norway (nordkapp) to prevent galley passage over the kola peninsula?
the english may yet land a settler around oslo or something, but it would force them to look west more than east for expansion opportunities, no?
or would this mess with a balance issue i'm not seeing?
Baldyr Feb 12, 2010, 10:22 AM I place a deep ocean at the tip of denmark, cutting off galley passage to the baltic sea, and a deep ocean at the north tip of norway (nordkapp) to prevent galley passage over the kola peninsula?
I'd say test anything if you got the time to spare.
the english may yet land a settler around oslo or something, but it would force them to look west more than east for expansion opportunities, no?
I believe the better route would be to see to it that those areas are already populated, so that the English have nowhere to settle those cities. Spawning more cities works. Or take away the English Settlers as they are no longer needed for populating Britain.
or would this mess with a balance issue i'm not seeing?
Balance is an issue that will have to be tested and maybe tweaked down the line. But you're already nearing the point of making this a scenario instead of a version of RFC - with the addition of Celts.
You should probably take away everything but some of you additional city spawn if you really wanna call it RFC. But I'm personally all for going the scenario route, so you'll hear no complaints from me. :goodjob:
antaine Feb 12, 2010, 10:26 AM I took away England's settlers...they build more and send them there. I guess self-spawing might be the way to go, but still...that might throw off other things...I'm going to try testing the tiles first
Baldyr Feb 12, 2010, 10:48 AM I took away England's settlers...they build more and send them there. I guess self-spawing might be the way to go, but still...that might throw off other things...I'm going to try testing the tiles first
Yeah, you do that. But also consider what the consequences will be to other Civs. You'd still want the modmod to be fully viable to play as the Viking - with Celts thrown in - right?
Civs settling via the northern passage above Scandinavia is something that bugs me also, so I think I might add some Ice there to prevent passage. I believe someone actually made a modmod with dynamic terrain, so I might just hijack his code for it.
Did you know that the Ocean tile separating Iceland from Britain turns into a Coast tile once the Vikings discover some Tech? (So that they may colonize without Astronomy.) So Rhye uses this also...
About city spawns, I think I'll eventually end up spawning all the cities on the map... :crazyeye: Since I've already done Russian territories and Germany, and am pretty much doing Scandinavia as the moment, there really isn't a good reason to stop. It adds so much the mod to have different areas populated without the AIs totally messing everything up. I'll definitely look at your work once I get to spawning the Celtic iron age settlements. Maybe I'll end up with a game without buildable Settlers, then? :eek:
antaine Feb 12, 2010, 10:55 AM well, you'll still want buildable settlers for later or razed cities. I've decided to put ocean at the top of Norway, this way the Russian arctic fleet can pass (if there ever is such a thing) but not until astronomy. I didn't cut off the baltic, I spawned oslo and stockholm (and enabled nidaros and a redundant uppsala). I also gave the russians more units and settlers to start, but i still wind up with a german russia and russians in only moscow...might needs spawns there as well...
Baldyr Feb 12, 2010, 11:21 AM I checked the respawn code again and it turns out I was getting confused with regular spawning. As it turns out, the 5 city limit is for the initial spawn, not the respawn.
When a resurrection happens its the mostly the stability of the owner of the cities that determine which are lost. Because the conditions for flip vary with stabiltity. This is why a stable England would loose few to none cities during a Celtic respawn, while an unstable France might loose all cities inside the Normal Area, or vice versa. The important thing would be that the results may vary from session to session, even if some outcomes might be more or less usual.
antaine Feb 12, 2010, 11:25 AM I've had France turn out to be a powerhouse, taking over indy cities in ireland after collapse, as well as the dutch and romans, and i've had paris taken over by the dutch and the spanish take everything else...i think that kind of outcome would be relatively random.
Baldyr Feb 12, 2010, 11:32 AM I also gave the russians more units and settlers to start, but i still wind up with a german russia and russians in only moscow...might needs spawns there as well...
Yeah, the AI behavior is pretty universal and you'll only end up spawning the cities of all Civs. If that is the route you wanna take, that would require quite a lot of testing (with about every Civ in the game).
Maybe you should keep it as simple as possible and to hell with stupid/weird AI behavior. If you've already done what you can in the Settler maps, no one can really blame you for the way the game is designed.
The root of the problem would be the city spawns you've added. They take away the land the other Civs use to expand, so they end up expanding into some other territory. The problem will transplant itself in different areas as this settling hurts both its own stability and the stability of the land-owner Civ.
And by spawning yet more cities in another area you simply move these problems further and further away...
antaine Feb 12, 2010, 11:36 AM heh...yeah, but i might move the "problem" to siberia and the russians, which would actually be okay...
honestly, though, i *think* i'm leaving it alone after this...
Baldyr Feb 12, 2010, 11:54 AM The core of the problem remains that the English have nowhere to expand, right? The question is why the English AI feels the need to expand beyond the cities they flip/conquer... Maybe you could point them in a less annoying direction with the Settler maps or something? Make northern Africa or something a desirable location to settle, or somewhere they will inevitably get taken over...
Right now they seem to favor areas belonging to other Civs. I wonder why some Civs (like the Russians) tend to turtle up as they do and not found any cities, while the English both build Settlers and use them. They will actually build ships, load those and send eastward! :eek: The Celts certainly wasn't doing that when you had them in Gaul...
I honestly have no idea whatsoever what makes the AI do these bizarre things. Other than the Settler maps or the like. :confused:
In my own Russia scenario the AI is dead set against expanding into Siberia even if I spawn free Settlers for them. They first build any feasible city in European Russia, so that one could have to do with the continents being defined as different "areas" in the game.
edit: Ah, could it be that Rhye has coded the English AI to actually pursuit their UHV? They need to build a number of cities on every continent, right? So they are simply fulfilling the condition of founding cities in Europe, since you took away their home areas.
antaine Feb 12, 2010, 11:59 AM the celts now start with two settlers, which they tend to send to europe (fine). The british settler maps were only changed to increase ireland from "very desirable" to "highly desirable." perhaps they just shy from amphibious invasions with 2-unit galleys...i just wish they'd concentrate on building more culture...it would help them take ireland regardless of whether or not the celts are around, and definitely help them with france...
antaine Feb 12, 2010, 11:59 AM not to mention once they get caravels they can't use them for invasions and have to wait for astronomy
antaine Feb 12, 2010, 12:01 PM i could potentially script "if irish cities are independent or barbarian in 1600 they automatically become english" but 1) that gives away free cities and 2) takes away the fun for the anglophile player in crushing the irish :rolleyes:
Baldyr Feb 12, 2010, 12:05 PM edit: Ah, could it be that Rhye has coded the English AI to actually pursuit their UHV? They need to build a number of cities on every continent, right? So they are simply fulfilling the condition of founding cities in Europe, since you took away their home areas.
So, if I was to device a solution to this possible issue, I could take one of two available approaches:
1. Try and make city flips count as "founded" cities. This could either be a global change to the code (affecting all spawns for all Civs) - or an exception that only affects the English.
2. Utilize a function sometimes used in Rhye's own code in order to kill everything in an area (like Britain) so that the English AI can settle those cities by itself. This would only happen if the human player hasn't got any cities in that area! Other than that the result as for the setup of Britain would be about the same - the isle would still be populated and the Celts would loose their dominance.
What do you think?
antaine Feb 12, 2010, 12:19 PM the english uhv only specifies founded cities in
bNCAmerica = self.checkFoundedArea(iEngland, tNCAmericaTL, tNCAmericaBR, 3)
bSAmerica = self.checkFoundedArea(iEngland, tSAmericaTL, tSAmericaBR, 3)
bAfrica = self.checkFoundedArea(iEngland, tAfricaTL, tAfricaBR, 3)
bAsia = self.checkFoundedArea(iEngland, tAsiaTL, tAsiaBR, 3)
bOceania = self.checkFoundedArea(iEngland, tOceaniaTL, tOceaniaBR, 3)
if (bNCAmerica and bSAmerica and bAfrica and bAsia and bOceania):
self.setGoal(iEngland, 1, 1)
none in europe or the isles...
I think it's just the ai trying to expand without war before it has the boats to do it. my concern is that even with an empty britain, they would do what the celts were doing and found london and still take their other settlers to the continent...
antaine Feb 12, 2010, 12:28 PM Well, I was also having a problem with the vikings not expanding and leaving scandinavia empty to modern times...they'd go into eastern europe...so I've spawned four cities in scandinavia, one of each indy and two barb...should get them to expand while preventing the english from going there. then i'm done...the russians are on their own...
Baldyr Feb 12, 2010, 12:31 PM Ok... False alarm. I checked up the UHV code for the English an they are in fact not required to build any cities in Europe. I should just have checked that up right away...
So, no, I don't have a clue about why the English will spam Settlers and settle them in Europe.
Maybe I could create a code that kills any English Settler once it is built - until a certain date or other setting (like Astronomy)? It would surely take care of the problem, but there could also be a actual need for settling cities on the isles (if the spawned ones have been razed). To avoid issues like this the code could just look for English Settlers in Galleys - and kill them off!
Straight forward enough?
antaine Feb 12, 2010, 12:35 PM that could work, but I don't want to limit the human. still, i'm sure you're going to tell me that it can be flagged to only affect the ai (am I catching on yet? lol). I'm going to run a test with the four scandinavian cities as that may be killing two birds with one stone. I'll be away for the weekend (Irish language immersion program), and then I'll reassess when I get back...
antaine Feb 12, 2010, 12:39 PM you know...easier than that...why can't i then write code for "if english is AI and X city is indy or on Y turn, city becomes english" with X being either a city name or tile location? That would give them three more cities, hopefully mitigating the need to expand in the event of a celtic collapse (something like Teamhair na Rí on 1400, Corcaigh on 1500 and Gaillimh on 1600), while still making the human conquer Ireland manually
antaine Feb 12, 2010, 12:42 PM I'm actually liking that idea, but I have no model code for it
Baldyr Feb 12, 2010, 12:48 PM Oh, thats very simple. You use this statement to ask the code whether the Celts are controlled by the human:
if (pCeltia.isHuman()):
...and this code whether the Celts are controlled by the AI (not human):
if (not pCeltia.isHuman()):
You need to understand how indentation works in Python in order to get it to work though, but thats pretty much the first thing one should learn about Python. :rolleyes:
So if you, as an example, wanna except the Dublin spawn to only happen if the Celtic player is an AI, your Barbs.py code would look like this (changes and additions marked):
self.foundCity(iIndependent, lLyon, "Lugodunon", iGameTurn, 2, con.iCelticGallicWarrior, 2)
if (not pCeltia.isHuman()):
self.foundCity(iIndependent, lDublin, "Teamhair na Rí", iGameTurn, 2, con.iCelticGallicWarrior, 2)
self.foundCity(iIndependent, lCardiff, "Caerdydd", iGameTurn, 2, con.iCelticGallicWarrior, 2)
Did you want me to kill off any English AI Settler on the same tile as a Galley (city tiles could be excepted)? Because I could code this for you over the weekend so that you would be able to test it out next week...
Will the Baldyr finally get to do some Python on this modmod? This is the question. :lol:
Baldyr Feb 12, 2010, 12:53 PM you know...easier than that...why can't i then write code for "if english is AI and X city is indy or on Y turn, city becomes english" with X being either a city name or tile location? That would give them three more cities, hopefully mitigating the need to expand in the event of a celtic collapse (something like Teamhair na Rí on 1400, Corcaigh on 1500 and Gaillimh on 1600), while still making the human conquer Ireland manually
What you're basically describing is a somewhat enlarged spawn zone for the English, then. This could be done quite easily as an exception affecting only the English AI. (You add or substract some number to their X and/or Y coordinate or coordinates, enlarging or decreasing the spawn area.)
Or would you wanna make cities change hands on specified turns - and not on the third turn after the initial spawn?
Which ever is of course possible to code, its merely a task of finding out which one is simpler to do and which one will be more efficient.
antaine Feb 12, 2010, 12:58 PM lol...alright, you want a custom project, here it is:
on turn i1400ad
see if england is human
if England is AI
see if lDublin (as defined in barbs.py - although this may acutally be one tile south of the celts start, in which case the celts start should be used) is Independent, Independent2 or Barbarian
if yes, flip to england
do the same for lGalway in i1450ad and iCork in i1500ad
It can't be a few turns after the english spawn because sometimes the ai celts don't collapse for centuries (if at all) and i want to give them a chance to make alternate history...it's just that if they do collapse, we're back to real history so we might as well make it look that way. They almost never collapse right away.
antaine Feb 12, 2010, 01:01 PM Dublin is one tile south...in consts.py I defined tTara as 49,57 with Átha Cliath (dublin) at 49,56 in barbs...the english will rename both of them "Dublin" and if they take it back, the celts will rename Dublin "Átha Cliath," which would be historically accurate
antaine Feb 12, 2010, 01:09 PM I could probably use that to fix the russian issue as well, but once i have code to model it on it can do that...something like, "if russia and germany are both ai, and if cities X XX and XXX are german, flip them russian on date YYY"
sort of like a one-time "reality check." i think this was why rhye included a 600 ad start in the first place, because the AIs rarely do what you want them to do in the long term, and if you're interested in endgame the world should at least loosely look like what you'd expect
Baldyr Feb 12, 2010, 01:27 PM Ok, I'm looking into how to best implement this and there is also the matter of culture presence to consider. I should however have something for you to try out once you come back.
What should happen to the units in the city, by the way. Would they be killed off, or flip also? In the units don't flip also there would have to be units spawning - those would also have to be specified for each city. Or maybe they should always be the default city defender for that Civ at that juncture? How many units are sufficient? Or would this be set on a case by case basis?
I imagine you wanna keep things as simple and straight forward as possible...
Baldyr Feb 12, 2010, 01:44 PM I'm actually thinking you need something to use for flipping entire areas on the map, since you wouldn't know exactly where those German cities in Russia would be located. So you could basically search the Russian Core Area for any German cities, then.
This would be quite different from simply checking if Dublin is owned by a minor Civ.
It wouldn't be so practical to use the same code or function for both purposes, so I think I'll just focus on the city flips on the Isles for now. If you need another one to correct the ownership in Russia... then I could always give them a second spawn at a specified date! :D
Baldyr Feb 14, 2010, 04:20 AM on turn i1400ad
see if england is human
if England is AI
see if lDublin (as defined in barbs.py - although this may acutally be one tile south of the celts start, in which case the celts start should be used) is Independent, Independent2 or Barbarian
if yes, flip to england
do the same for lGalway in i1450ad and iCork in i1500ad
So I took a closer look at what Rhye had already done with this mod, and he has defined (each starting with "def") literary 100s of functions! I believe the flipCity function in RFCUtils.py do what you want to achieve, so there should be no need for me to make my own function for this particular task.
So in order to get the city flips you requested, add this piece of line somewhere after "def checkTurn(...):" in Barbs.py:
#Minor secessions to England
pEngland = gc.getPlayer(con.iEngland)
if (pEngland.isAlive() and not pEngland.isHuman()):
if (iGameTurn == con.i1300AD):
utils.flipCity(lDublin, True, True, con.iEngland, lMinors) #Teamhair
utils.flipCity(con.tCapitals[iCeltia], True, True, con.iEngland, lMinors) #Tara
if (iGameTurn == con.i1450AD):
utils.flipCity(lGalway, True, True, con.iEngland, lMinors)
if (iGameTurn == con.i1500AD):
utils.flipCity(lCork, True, True, con.iEngland, lMinors)
I included a separate flip for both locations of Dublin, but you could probably delete one of them. You could also add more flips if you like - it should be pretty straight forward. Just follow the indentation modeled above and you should be fine.
Note that I reused your list variables for the cities in order to get their coordinates, but I could have added them manually like "[49, 57]" also. Speaking of which, you also need to define the last argument, which is another list variable called "lMinors". Add this definition somewhere at the beginning of Barbs.py:
lMinors = [iIndependent, iIndependent2, iBarbarian]
Or you could just add the contents of the list directly to each utils.flipCity() function like: "[iIndependent, iIndependent2, iBarbarian]"
The utils.flipCity() function has some features to it, if you wanna learn how to get the most of it. If you take a look at the function itself you'll find that Rhye has actually supplied documentation! (The red text doesn't apply. By the way, the "!=" bit is the opposite of "==" (equal) to and thus means basically "not".)
def flipCity(self, tCityPlot, bFlipType, bKillUnits, iNewOwner, iOldOwners):
"""Changes owner of city specified by tCityPlot.
bFlipType specifies if it's conquered or traded.
If bKillUnits != 0 all the units in the city will be killed.
iRetainCulture will determine the split of the current culture between old and new owner. -1 will skip
iOldOwners is a list. Flip happens only if the old owner is in the list.
An empty list will cause the flip to always happen."""
pNewOwner = gc.getPlayer(iNewOwner)
city = gc.getMap().plot(tCityPlot[0], tCityPlot[1]).getPlotCity()
if (gc.getMap().plot(tCityPlot[0], tCityPlot[1]).isCity()):
if not city.isNone():
iOldOwner = city.getOwner()
if (iOldOwner in iOldOwners or not iOldOwners):
if (bKillUnits):
killPlot = gc.getMap().plot( tCityPlot[0], tCityPlot[1] )
for i in range(killPlot.getNumUnits()):
unit = killPlot.getUnit(0)
unit.kill(False, iNewOwner)
if (bFlipType): #conquest
if (city.getPopulation() == 2):
city.setPopulation(3)
if (city.getPopulation() == 1):
city.setPopulation(2)
pNewOwner.acquireCity(city, True, False)
else: #trade
pNewOwner.acquireCity(city, False, True)
return True
return False
There is also a function for creating era appropriate defensive units in cities (like after a flip):
def createGarrisons(self, tCityPlot, iNewOwner, iNumUnits):
plotCity = gc.getMap().plot(tCityPlot[0], tCityPlot[1])
city = plotCity.getPlotCity()
iNumUnitsInAPlot = plotCity.getNumUnits()
pCiv = gc.getPlayer(iNewOwner)
if (gc.getTeam(pCiv.getTeam()).isHasTech(con.iAssembl yLine) and gc.getTeam(pCiv.getTeam()).isHasTech(con.iRifling) ):
iUnitType = con.iInfantry
elif (gc.getTeam(pCiv.getTeam()).isHasTech(con.iRifling )):
if (iNewOwner != con.iEngland):
iUnitType = con.iRifleman
else:
iUnitType = con.iEnglishRedcoat
elif (gc.getTeam(pCiv.getTeam()).isHasTech(con.iGunpowd er)):
if (iNewOwner != con.iFrance):
iUnitType = con.iMusketman
else:
iUnitType = con.iFrenchMusketeer
else:
iUnitType = con.iLongbowman
self.makeUnit(iUnitType, iNewOwner, [tCityPlot[0], tCityPlot[1]], iNumUnits)
Ask for support if you can't figure out for yourself how to use it. (Because you should, by comparing the definition line of both functions. You can always ignore the "self" argument, by the way.)
There is no reason for you not to understand how I used the function and why my code looks like it does. If something in particular is unclear I could explain.
Baldyr Feb 14, 2010, 05:08 AM I actually have some custom code you could use in your modmod if you like. :king:
Since the limitations built into Rhye's own foundCity() function wasn't allowing me to do what I needed to achieve in my own modmod I created my own custom function. While Rhye's function is located in the Barbs.py file (and thus called with the prefix "self."), mine is located on another file altogether called Custom.py and need therefore to be imported into the Barbs.py file. This is achieved by adding this line somewhere after "from CvPythonExtensions import *" (line #3):
import Custom
And by adding this definition after the "# globals" comment line (#11) you can use the prefix "custom." to call on my function like "custom.foundCity()":
custom = Custom.Custom()
The actual Custom.py file can be downloaded from this post (http://forums.civfanatics.com/showpost.php?p=8897296&postcount=22) - and there is also full documentation available.
The reason you might wanna use my function instead of Rhye's is that it gives you more options (like pre-building Duns in your spawned cities) and also the power to force spawns regardless of the normal limitations. (This setting is enabled or disabled on a city by city basis, so you could still use it to achieve exactly what the default function will give you, plus any extra feature you'd wanna use.)
One benefit from the custom.foundCity() function to your modmod could be to make all the Celtic city spawns actually belong to the Celtic Civ. It should be noted however that when the Celts are controlled by a human player these spawns actually become random independents instead. What this would give you is a greater challenge for the Roman, English and other players in your mod - when played by the human.
Once the Celts collapse - and they will whenever they lose at least half of their cities within a short period of time - you still get the fragmentation into independents that you have now by default. Its just a suggestion, but don't be surprised if I post this very setup as a, well... modmod to your modmod :rolleyes: once you've done your definitive release. :mischief: (Note how non-consolidated peoples like the Germans or the Vikings get to show a united front in RFC and in Civ in general. Why should an AI Celtia be any different?)
Lastly, you could just use the Barbs.py file included in the download (link above) as it already has the stuff you need to use the custom function. Then you could transfer all the settings for your city spawns to the new file, as you need to reformat everything to fit into the new function anyway. I also suggest you add the two Viking spawns included as examples into your modmod, as they are historical spawns. (Cities like Oslo, Göteborg or Stockholm are actually relatively modern and not as suitable in the Middle-Ages.)
antaine Feb 15, 2010, 06:36 AM Thank you so much, I implemented the flip code. It flipped the cities, but they were lost again to barbarians, so I'm going to have to use the defensive unit code as well (I'll test that later today).
As for Oslo and Stockholm, I'm having them spawn at their founding dates (according to wikipedia)...that's enough to keep the english from going there (I also had to found two in northern scandinavia...i'm going to have to do copenhangen as wel...sigh...silly english).
I've decided to solve my russia problem like rhye did for the romans and i did for the celts...simply spawn 3-5 indy cities on the border at intervals so they're there before the Germans get there...
One other thing occurred to me, as I was on the Irish weekend, singing the rebel songs. I'd like to script two unit spawns, but I'm not sure how to allow them to spawn within english borders.
If the English are in control of Ireland by these times (they should be):
I'd like to spawn five Celtic pikemen (even though Celtia is tecnhically dead) at 49,55 in 1798 (United Irishmen rising in Wexford) and seven Celtic riflemen at 49,56 in 1916 (the Easter Rising). I'm not sure how to get the units to spawn within english cultural borders and to ensure that war exists between them (I imagine if I spawn them, Celtia exists, but war will then move them to a free tile outside the cultural borders...I figure these were the two big rebellions (but there was one every 50 years or so for centuries) that had slim chances of success. if they could capture a city Celtia would be back on the map, no?
In reality they failed rather definitively, but I figure those would be historically accurate times for the possible re-emergence of a dead celtia.
In any event, today I'll test the defensive unit code and script the russian cities. I don't think there's anything else for me to do after that, pending your answer about the Irish rebellions.
Baldyr Feb 15, 2010, 09:35 AM I'm not so sure about this turning into a historical scenario of sorts, but you're the designer so its up to you. Because nothing is really impossible to do.
The functions set up by Rhye for spawning units and cities aren't at all suited for anything like this, as they rather mimic the way barbarians spawn in the core game. But there's nothing forcing you to use Rhye's functions, so you could either make your own or find another one to use instead. But I'll just solve this one for you.
If you look at the function used in Barbs.py for spawning units, it looks like this:
def spawnUnits(self, iCiv, tTopLeft, tBottomRight, iUnitType, iNumUnits, iTurn, iPeriod, iRest, function, iForceAttack):
if (iTurn % iPeriod == iRest):
dummy, plotList = utils.squareSearch( tTopLeft, tBottomRight, function, [] )
if (len(plotList)):
rndNum = gc.getGame().getSorenRandNum(len(plotList), 'Spawn units')
result = plotList[rndNum]
if (result):
self.makeUnit(iUnitType, iCiv, result, iNumUnits, iForceAttack)
What the function spawnUnits() actually does is that it selects a random tile within the coordinates (basically an "area" like core or the normal one) fed into the function. To determine whether or not there is a permitted tile available the spawnUnits() uses another function called utils.squareSearch(). This is why your Celtic rebels would fail to materialize, as anything with cultural borders would be of limits.
But if a tile is actually found it calls upon another function called makeUnit() to spawn the actual unit:
def makeUnit(self, iUnit, iPlayer, tCoords, iNum, iForceAttack):
'Makes iNum units for player iPlayer of the type iUnit at tCoords.'
for i in range(iNum):
player = gc.getPlayer(iPlayer)
if (iForceAttack == 0):
player.initUnit(iUnit, tCoords[0], tCoords[1], UnitAITypes.NO_UNITAI, DirectionTypes.DIRECTION_SOUTH)
elif (iForceAttack == 1):
player.initUnit(iUnit, tCoords[0], tCoords[1], UnitAITypes.UNITAI_ATTACK, DirectionTypes.DIRECTION_SOUTH)
elif (iForceAttack == 2):
player.initUnit(iUnit, tCoords[0], tCoords[1], UnitAITypes.UNITAI_ATTACK_SEA, DirectionTypes.DIRECTION_SOUTH)
What the "if/elif" statements do is assign different Unit AI Types to the unit, but thats really nothing you'd need to think about. (Defensive units mostly will set themselves to defend and offensive units will revert to attack.) The unit itself is actually created with the function(s) called CyPlayer.initUnit().
So, for you to achieve any imaginable Unit spawn you could just use the makeUnit() function instead of spawnUnit(). Or, if you want to, you could skip even this and use the function CyPlayer.initUnit() directly. Two examples:
self.makeUnit(con.iRifleman, iCeltia, [49, 56], 7, 0)
...or (more directly):
pCeltia.initUnit(con.iRifleman, 49, 56, UnitAITypes.NO_UNITAI, DirectionTypes.DIRECTION_SOUTH)
The second option would only produce one unit though, so you'd have to know how to loop it seven times (or you could just copy-paste the function seven times on consecutive lines, but then you wouldn't be able to show your code to anyone :p). So most of the times there is a point in using one of the functions set up by Rhye. :king:
Baldyr Feb 15, 2010, 10:52 AM Yeah, you also need some way of knowing if England controls Ireland, and the easiest way to determine this could be to check if the target tile (for the unit spawn) is owned by the English. You could try this code:
if (gc.getMap().plot(iX, iY).getOwner() == con.iEngland):
You'd have know where to put this line and what amount of indentation to use though. You replace the variables iX and iY with the actual coordinates, of course. (Or you could actually use variables, so that you don't have to type the same values over and over again.)
Then you need to check whether Celtia is alive, because you wouldn't wanna give free unit to an active Celtic player, right?
if (not pCeltia.isAlive()):
edit: Oh, you do remember how to make a Civ declare war on another, right? In case you have forgotten:
teamCeltia.declareWar(con.iEngland, False, -1)
Also, if you don't wanna keep typing con.iEngland you could just define the variable iEngland = con.iEngland at the beginning of Barbs.py.
Baldyr Feb 15, 2010, 01:53 PM As for Oslo and Stockholm, I'm having them spawn at their founding dates (according to wikipedia)...that's enough to keep the english from going there (I also had to found two in northern scandinavia...i'm going to have to do copenhangen as wel...sigh...silly english).
My point would be that Birka would be located on the same tile as Stockholm and Roskilde would become Copenhagen. And Oslo was named Christiania way back when.
The dates would then be AD 790 for Birka/Stockholm, AD 990 for Roskilde/Copenhagen and AD 1000 for Christiania/Olso.
antaine Feb 15, 2010, 02:50 PM heh...I have Oslo spawn as Christiania already, lol...I may not know as much scandinavian history as Irish, but I have some odds and ends... ;-)
I think you're right about the historical mod thing. It would really be a change that is out of place. I'm going to tinker with the city flipping and try to strengthen Russia a bit in the early years and beyond that, consider the next version a final release.
Then I'll start looking at the multiplayer version and see if the same stuff (celts, uhv's, etc) can be added in a similar fashion (I don't know how similar the multiplayer version is to the single player version).
antaine Feb 15, 2010, 03:15 PM two final questions...which impassable terrain is supposed to change when the vikings pop up? I don't see anything change for pre-astronomy passage.
Second, is there any way to reveal a large block of map to the Americans on spawn? It really doesn't make sense that the US doesn't know of Europe or the old world in the 1700s...
jmerry Feb 15, 2010, 04:55 PM (49, 62) becomes coast instead of ocean when the Vikings learn Compass. It's in onTechAcquired in CvRFCEventHandler.py, as the following block:
if (argsList[0] == con.iCompass):
if (iPlayer == con.iVikings):
gc.getMap().plot(49, 62).setTerrainType(con.iCoast, True, True)
The appropriate function to reveal/hide a piece of terrain is setRevealed; here's a line I used for my patch to hide stuff the debug catapult reveals:
gc.getMap().plot(0, 0).setRevealed(iOwner, False, True, -1)
(That first "False" should be "True" if you want to reveal instead of hiding)
That needs to be called for each plot hidden/revealed, so you'd want to set up some loops.
Of course, it also doesn't make much sense when America spawns several techs ahead of anybody else.
antaine Feb 15, 2010, 06:55 PM hm...is there a way to force-share maps with the british?
antaine Feb 15, 2010, 07:01 PM also...how does this look? I wanted to spawn several cities for the russians, but they are spaced such that they may not automatically flip, and may indeed wind up getting snatched by the Germans or Greeks. I figured I'd do a flip-script similar to the english one for the russians, but it's not just the minors this time. I referenced iGermany and iGreece...will this script work to flip those cities as long as the owner is one of those three? Also, how do I get it to flip the units inside with the cities for these scripts rather than kill them?
#secessions to Russia
pRussia = gc.getPlayer(con.iRussia)
if (pRussia.isAlive() and not pRussia.isHuman()):
if (iGameTurn == con.i1730AD):
utils.flipCity(lMinsk, True, True, con.iRussia, lMinors)
utils.flipCity(lKiev, True, True, con.iRussia, lMinors)
utils.flipCity(lPeter, True, True, con.iRussia, lMinors)
utils.flipCity(lVilnius, True, True, con.iRussia, lMinors)
utils.flipCity(lOdessa, True, True, con.iRussia, lMinors)
#secessions to Russia
pRussia = gc.getPlayer(con.iRussia)
if (pRussia.isAlive() and not pRussia.isHuman() and not pGermany.isHuman()):
if (iGameTurn == con.i1730AD):
utils.flipCity(lMinsk, True, True, con.iRussia, iGermany)
utils.flipCity(lKiev, True, True, con.iRussia, iGermany)
utils.flipCity(lPeter, True, True, con.iRussia, iGermany)
utils.flipCity(lVilnius, True, True, con.iRussia, iGermany)
utils.flipCity(lOdessa, True, True, con.iRussia, iGermany)
#secessions to Russia
pRussia = gc.getPlayer(con.iRussia)
if (pRussia.isAlive() and not pRussia.isHuman() and not pGreece.isHuman()):
if (iGameTurn == con.i1730AD):
utils.flipCity(lMinsk, True, True, con.iRussia, lGreece)
utils.flipCity(lKiev, True, True, con.iRussia, lGreece)
utils.flipCity(lPeter, True, True, con.iRussia, lGreece)
utils.flipCity(lVilnius, True, True, con.iRussia, lGreece)
utils.flipCity(lOdessa, True, True, con.iRussia, lGreece)
antaine Feb 15, 2010, 07:08 PM I actually don't need to flip the existing units if I could get the defensive unit code to work. Pasting what you posted didn't spawn the units (or return an error), but I'm not sure if I'm supposed to be plugging in coordinates or names there anywhere. Looking at it, it appears that it is code to make the defensive spawn happen whenever england or france flips a city (unless I'm reading it wrong, which I probably am)
antaine Feb 15, 2010, 08:38 PM oh, so rather than list them separately, I've created a group, lCentrals comprised of lMinors, Germany and Greece...however, I'm not sure how to execute the script only if the civ in question is minor, since it's possible for each of the 5 cities to be owned by a different civ, one of which might be human (germans or greeks)
Baldyr Feb 15, 2010, 10:04 PM It could be problematic to use the flipCity function for other than cities that you've already spawned yourself, because you can't predict where they are built. I'd suggest another method entirely - something along the lines of a spawn zone. Perhaps its possible to use the default one since you'd wanna flip cities inside the Russians Core Area anyways, right? I'll have a look after work. Otherwise I might just make another custom function for additional spawn areas for Civs already spawned.
Looking at your code you could do without repeating some line of code. This bit could only be used once:
pRussia = gc.getPlayer(con.iRussia)
if (pRussia.isAlive() and not pRussia.isHuman() and not pGermany.isHuman()):Also, the first line could be defined at the start of the file (if you like), together with iRussia = con.iRussia.
But you don't need to repeat anything (as long as everything happens on the same game turn) if you put all the Civs concerned into a list - just line lMinors. So, you could add this line of code along the other lists defined in Barbs.py:
lMajors = [iGermany, iGreece]
You could just add other possible culprits also, like iNetherlands or iVikings, if you like. Then you use this list in the flipCity() function, like:
utils.flipCity(lMinsk, True, True, con.iRussia, lMajors)
The other settings or arguments are, as defined on the "def flipCity(...)" line in RFCUtils.py, 1. whether or not the city should be aquired by force (True or False) and 2. whether or not you wanna kill all the units inside the city (True or False). I don't believe the default flipCity() function can be used to also flip units inside the city though, but one could always code that oneself...
This is how you should spawn the garrisons, by the way:
createGarrisons(lMinsk, iRussia, 2):
This gives the Russian Civ 2 default defensive units on the location defined in lMinsk, as an example.
How to make Civs share world maps I wouldn't know right now, but you are absolute right on the issue, so I actually think I'll take a closer look at it. It smells like a custom function to me... :mischief:
Baldyr Feb 15, 2010, 10:12 PM however, I'm not sure how to execute the script only if the civ in question is minor, since it's possible for each of the 5 cities to be owned by a different civ, one of which might be human (germans or greeks)
So, what you pretty much need is a function that lets you flip cities in a pre-defined area that are not controlled by the human player - for a Civ not controlled by a human player.
To use the flipCity() function really seems suboptimal. So I'll just make something along the lines of cusom.flipArea() for you instead.
But if you're not going the historical scenario route, why flip any cities to the Russians? :crazyeye:
antaine Feb 15, 2010, 10:15 PM I want to flip them because I get the same result every single time...a german russia with a Moscow city-state...there's basically no Russia in the game then. I just want to make sure that they get into the Belarus/Ukraine area so that they might actually get to do something. I only spawned the cities mentioned above, so I don't mind flipping just them, as long as they are not human controlled.
antaine Feb 16, 2010, 07:32 AM hm...I'm not sure about the syntax, but couldn't I simply call for the flip of those five specific cities as long as russia and the city owner are both are not human? perhaps something like
#secessions to Russia
pRussia = gc.getPlayer(con.iRussia)
if (pRussia.isAlive() and not pRussia.isHuman() and not iOwner.isHuman()):
if (iGameTurn == con.i1730AD):
utils.flipCity(lMinsk, True, True, con.iRussia, iOwner)
utils.flipCity(lKiev, True, True, con.iRussia, iOwner)
utils.flipCity(lPeter, True, True, con.iRussia, iOwner)
utils.flipCity(lVilnius, True, True, con.iRussia, iOwner)
utils.flipCity(lOdessa, True, True, con.iRussia, iOwner)
I don't know if that will make sense to the computer, or how I should define iOwner to mean a non-human owner of the cities in question...
Baldyr Feb 16, 2010, 09:30 AM hm...I'm not sure about the syntax, but couldn't I simply call for the flip of those five specific cities as long as russia and the city owner are both are not human? perhaps something like
#secessions to Russia
pRussia = gc.getPlayer(con.iRussia)
if (pRussia.isAlive() and not pRussia.isHuman() and not iOwner.isHuman()):
if (iGameTurn == con.i1730AD):
utils.flipCity(lMinsk, True, True, con.iRussia, iOwner)
utils.flipCity(lKiev, True, True, con.iRussia, iOwner)
utils.flipCity(lPeter, True, True, con.iRussia, iOwner)
utils.flipCity(lVilnius, True, True, con.iRussia, iOwner)
utils.flipCity(lOdessa, True, True, con.iRussia, iOwner)
I don't know if that will make sense to the computer, or how I should define iOwner to mean a non-human owner of the cities in question...
First of all, you seem to have grasped the indentation business now. That's good! :goodjob:
The utils.flipCity() function is used for secession and for congresses, so it's not exactly what you need. If you you can hold on awhile I will make a custom function with settings (arguments) for pretty much anything one could need for making "historical" scenarios, like restricting the flip to AIs only. But in the meanwhile we could bring some order to your code.
Ok, here goes. I guess that you want the iOwner variable to hold the index number of all the Civs that could possibly be owners of the cities in question? The name you've chosen for this variable indicates to me that its an integer value, hence the name iOwner. What you need is a list (or all tuple) variable instead. So that would be called lOwner if we're gonna keep to the way Python is usually done. This list or variable could be defined something along the lines of:
lOwner = [iGermany, iVikings, iNetherlands, iTurkey]
(Or whatever.)
So, before you call on the utils.flipCity() function you wanna check if the integer values (iGermany, iViking and so on) inside the list variable (lOwner) correspond to the human player. A good start would be to identify the human player, then. First order of business could be to set up a variable (of the integer kind) that holds the index number of the human player, by using the utils.getHumanID() function supplied by Rhye:
iHuman = utils.getHumanID()
Now you check if any of the integer values in your list variable corresponds to this value. You do this by looping the contents of the list and comparing each of the values to "iHuman". And if you find the human ID in the list, you remove that entry from the list before going forward and calling on the flipCity() function.
numCivs = len(lOwner)
for num in range (numCivs):
iCiv = lOwner[num]
if (iCiv == iHuman):
lOwner.remove(iCiv)
break
What this code does is that it creates as many loops as there are entries in lOwner, checking the contents of the list one by one.
First we retrieve the number of entries with the command "len" and assign this value to the variable "numCivs". Then you loop the variable "num" as many times as the value of "numCivs". "num" will thus have the value corresponding to the active loop, so on the first loop it will be 0 (zero), on the second it will be 1, and then 2, and so on. So if the list has has 5 entries, then num will get the values 0-4 in that order.
Next the variable "iCiv" will be set to the "num" number entry in the list. So on the first loop "iCiv" will be entry #0 (the first one), on the next loop #1, and the third entry #2, and so on until the loop cycle is completed.
Then we use an "if" statement to see whether "iCiv" is a the human player, by comparing it to "iHuman" (see above). And if so, we take that entry out from the list with the command "remove" - and we quit the entire loop cycle with the command "break" as we've already found the human player. (No need to run any more checks.)
Note that this code will not be sufficient for you multiplayer version, since the lOwner list will actually get shortened by removing the human ID. Because, there could also be another human lurking in there, and the following entry would get a free pass. Also, the last loop wouldn't have any value to compare since one entry would be missing.
But when you get around to these issues I'll have a better function ready you could use. :king:
Also, the solution above would still be insufficient if say Rome has survived and occupies those parts of Russia. You'd have to enter pretty much all the Civs into the lOwner list to avoid those instances... It doesn't seem all too practical, now does it? :rolleyes:
Baldyr Feb 16, 2010, 11:58 AM ...you could also use the PyPlayer.isHuman() function to check whether or not an entry in lOwners is the human player. Since its a PyPlayer function it requires you to fetch a "player instance" first. (That would be the actual Civ and not its index number. Obviously there would be a difference.)
You've already done this with CyGlobalContext.getPlayer() (commonly abbreviated to gc.getPlayer() as it states "gc = CyGlobalContext" at the start of Barbs.py). So the code above could also work with this setup:
numCivs = len(lOwner)
for num in range (numCivs):
iCiv = lOwner[num]
pCiv = gc.getPlayer(iCiv)
if (pCiv.isHuman() == True):
lOwner.remove(iCiv)
break
It could be noted that you've used an abbreviated version of the "if" statement before, because the " == True" part doesn't really add anything other than a bit of clarity to the code.
By the way, I've concisely tried to make my code above as clear as possible, but it could also be condensed so that it takes up fewer lines:
for n in range (len(lOwner)):
if (gc.getPlayer(lOwner[n]).isHuman()):
lOwner.remove(lOwner[n])
break
Kinda blows your mind, eh? :eek: I got rid of the variables "numCivs", "iCiv" and "pCiv" entirely and I abbreviated "num" to simply "n". Since these variables aren't constants (those would be the ones you recognize from Consts.py) they are mostly in the code for clarity anyway. (Also with a longer code it would be less to actually type.) It really does get blurred up though, not? :crazyeye:
antaine Feb 16, 2010, 02:26 PM so at the top in the definitions I'd put
iHuman = utils.getHumanID()
lOwner = [iGermany, iVikings, iNetherlands, iTurkey, iRome, iGreece, iEngland, iFrance, iSpain]
and be sure to define each "i" civ as well.
Then, down farther, I'd put
numCivs = len(lOwner)
for num in range (numCivs):
iCiv = lOwner[num]
if (iCiv == iHuman):
lOwner.remove(iCiv)
break
#secessions to Russia
pRussia = gc.getPlayer(con.iRussia)
if (pRussia.isAlive() and not pRussia.isHuman() and not lOwner.isHuman()):
if (iGameTurn == con.i1730AD):
utils.flipCity(lMinsk, True, True, con.iRussia, lOwner)
utils.flipCity(lKiev, True, True, con.iRussia, lOwner)
utils.flipCity(lPeter, True, True, con.iRussia, lOwner)
utils.flipCity(lVilnius, True, True, con.iRussia, lOwner)
utils.flipCity(lOdessa, True, True, con.iRussia, lOwner)
is that correct? I also need to get that code working for spawning defensive units or flipping of existing units for both the Russians and the English ones we did before (they don't spawn, and so free range barbarians (those outside of cities at the flip) just take the flipped cities back on the following turn)...
Baldyr Feb 16, 2010, 03:53 PM Ok, lets see. Its all about the logic, since we're trying to give orders to a computer chip... :p
You can't define anything but constants at the beginning of the file, because they will not be updated again once the file has loaded (during initializing). So you need to move out "iHuman = utils.getHumanID()" since that one might not be accurate otherwise. (If no human player is chosen before the game starts. Or what if the human player switches Civs in-game?) We'll just put that under "def checkGameTurn(...)", so that it get defined only when its actually used (see below).
So you trigger your "flip event" with the "if" statement about "iGameTurn" being this or that value, and you lose the code that does nothing (marked red):
pRussia = gc.getPlayer(con.iRussia)
if (pRussia.isAlive() and not pRussia.isHuman() and not lOwner.isHuman()):
if (iGameTurn == con.i1730AD):
Because you can only feed the PyPlayer.isHuman() function a player instance, not a list variable like lOwner.
Next you check for the human player and remove that Civ's index number with this bit of code I dreamed up before (the loop is color marked so that you keep that separate in regard to the rest of the indentation):
iHuman = utils.getHumanID()
numCivs = len(lOwner)
for num in range (numCivs):
iCiv = lOwner[num]
if (iCiv == iHuman):
lOwner.remove(iCiv)
break
What you get is the lOwner list without the human player (if there ever was one), so you're good to continue to the actual flip. (Without risking to flip any cities belonging to the human player.)
utils.flipCity(lMinsk, True, True, con.iRussia, lOwner)
utils.flipCity(lKiev, True, True, con.iRussia, lOwner)
utils.flipCity(lPeter, True, True, con.iRussia, lOwner)
utils.flipCity(lVilnius, True, True, con.iRussia, lOwner)
utils.flipCity(lOdessa, True, True, con.iRussia, lOwner)
This is pretty much it, but you need to get all that indentation to match up exactly according to the rules of logic. :crazyeye: (By the way, if you put iRussia = con.iRussia at the beginning of the file you don't need to call on Consts.py with the con. prefix every time you use the Russian index number. But thats optional, I was just thinking that you might have defined the other Civs already.)
Regarding the utils.createGarrisons() function (oh, I guess I forgot about the utils. prefix earlier, because the function is in RFCUtils.py and it is defined as "utils = RFCUtils.RFCUtils()" at the beginning of the file) you should do one for each city.
Lets see if you get it right, otherwise you could just post your code for proofreading. But I'm pretty confident you can manage by now! :goodjob:
antaine Feb 16, 2010, 07:02 PM alright, this is what I have for proofreading...but the defensive units still won't spawn in flipped cities
Baldyr Feb 16, 2010, 09:54 PM Ok, here's your code with the indentation fixed. You could also lose the bits marked red, since you've already defined iEngland, iRussia and pRussia at the beginning. (You could do the same with pEngland if you like.)
#Minor secessions to England
pEngland = gc.getPlayer(con.iEngland)
if (pEngland.isAlive() and not pEngland.isHuman()):
if (iGameTurn == con.i1450AD):
utils.flipCity(lCork, True, True, con.iEngland, lMinors)
utils.flipCity(lGalway, True, True, con.iEngland, lMinors)
utils.flipCity(lDublin, True, True, con.iEngland, lMinors) #Teamhair
utils.flipCity(con.tCapitals[iCeltia], True, True, con.iEngland, lMinors) #Tara
utils.createGarrisons(lCork, iEngland, 2)
utils.createGarrisons(lGalway, iEngland, 2)
utils.createGarrisons(lDublin, iEngland, 2)
utils.createGarrisons(con.tCapitals[iCeltia], iEngland, 2)
#secessions to Russia
pRussia = gc.getPlayer(con.iRussia)
if (pRussia.isAlive() and not pRussia.isHuman()):
if (iGameTurn == con.i1730AD):
iHuman = utils.getHumanID()
numCivs = len(lOwner)
for num in range (numCivs):
iCiv = lOwner[num]
if (iCiv == iHuman):
lOwner.remove(iCiv)
break
utils.flipCity(lMinsk, True, True, con.iRussia, lOwner)
utils.flipCity(lKiev, True, True, con.iRussia, lOwner)
utils.flipCity(lPeter, True, True, con.iRussia, lOwner)
utils.flipCity(lVilnius, True, True, con.iRussia, lOwner)
utils.flipCity(lOdessa, True, True, con.iRussia, lOwner)
utils.createGarrisons(lMinsk, iRussia, 2)
utils.createGarrisons(lKiev, iRussia, 2)
utils.createGarrisons(lPeter, iRussia, 2)
utils.createGarrisons(lVilnius, iRussia, 2)
utils.createGarrisons(lOdessa, iRussia, 2)
About indentation, every level has 8 more blank spaces than the previous, so you should count those to make sure. I put blank lines between the blocks of code also, to try and make things clearer. Once you get why its formated in this way I'd say your pretty much ready to try your hand at some Python yourself.
I'll try the code out myself once I get home, to make sure the units are created and whatnot.
Also, I'll get to work on creating a custom function for city flipping, since the method above is very cumbersome and nothing I'd wanna use myself...
antaine Feb 17, 2010, 08:55 AM ah, that worked...excellent!
I was putting in the definition of creategarrison but not actually telling the game to do it.
I'm going to toy with it for a week or so, but I think I'm done...final release is forthcoming...
Baldyr Feb 17, 2010, 09:15 AM Further on indentation, just so you're able to follow my trail of though.
Note how a new level of additional 8 blank spaces is added to every line that ends with a colon. So everything that is typed into that new level - and to any further level - "belongs" to the line with the colon. Most of the time its an "if" statement or a "for (...) in" loop or a definition line (starts with "def").
Once the business conducted at those "new" levels is done the code reverts back to the original level and continues from there. There is nothing random, arbitrary or mystical with indentation in Python - its rather logical.
An example (I've marked every new level with a "->"):
pRussia = gc.getPlayer(con.iRussia)
if (pRussia.isAlive() and not pRussia.isHuman()):
->
if (iGameTurn == con.i1730AD):
->
iHuman = utils.getHumanID()
numCivs = len(lOwner)
for num in range (numCivs):
->
iCiv = lOwner[num]
<- if (iCiv == iHuman):
->
lOwner.remove(iCiv)
<- break
utils.flipCity(lMinsk, True, True, con.iRussia, lOwner)
Note how the "if" statements get nested into each other, so that the levels keep adding up. The loop ("for num in range (numCivs):" or "loop the variable this many times") is broken once it has run its course - or with the "break" command if it produces a hit in the form of a human player. This is why the indentation returns to the original level - and commences with the actual city flip.
A good rule of thumb :goodjob: is to always add a new level of indentation when a line ends with a colon. The trick is to know where to come back to the original level - and to figure out what level that is. But it should be pretty logical - you just need to think of the code as a script that the game engine is reading. It starts at the first line and follows on through to the end. So you need to go through the code line by line and interpret what instructions the computer is being fed.
One good thing to know is that the "break" command ends a loop entirely - and thus the indentation returns the same level as the line initializing the loop. And also that a "continue" command skips the present loop and start the next one. (If its the last loop it will of course break the loop.)
I'm not sure if your taking any of this in, but I feel pretty committed to force feeding you this stuff so that you will be able sort out all this Python business yourself going forward. If I managed to work all this out by myself you should also be able to.
edit: You did it! Congrats! :king:
Baldyr Feb 18, 2010, 09:50 AM The appropriate function to reveal/hide a piece of terrain is setRevealed;
I think I'm actually gonna create a custom function that lets you do these things by giving it the ID of the Civ who's map you wanna copy (and the target Civ, of course). It should be easy enough.
There seems to be a lot of setRevealed() functions in the API though, but guess I'd have to use the one listed under CyPlot:
185. VOID setRevealed (TeamType eTeam, BOOL bNewValue, BOOL bTerrainOnly, TeamType eFromTeam)
void (int /*TeamTypes*/ eTeam, bool bNewValue, bool bTerrainOnly, int /*TeamTypes*/ eFromTeam)
Does anyone know how that last argument (eFrom) is used? I guess you give it the index number of a team (with CyPlayer.getTeam()) but what does it do?
There is one under CyMap also, I wonder if that one reveals the whole map then? :confused: Under CyMap there's also setRevealedPlots() which seems to be able to reveal many plots on one single command - but how is it determined what plots? (What is a CyMap instance, anyway? Is it the entire map as defined by the scenario file or is it the map revealed to one Civ? :confused:)
Of course, it also doesn't make much sense when America spawns several techs ahead of anybody else.
This is another good point. I think I'll just mod my own game so that it looks for what Civs are present in the American Core Area at spawn, and then grants all the Techs and Maps of those Civs. But no Techs beyond that - or maybe just Liberalism/Nationalism or something...? :confused:
So there's another function I could do. (Copy Techs of another Civ.)
edit: I'd need some method of looking whether or not a Civ has revealed a tile or not. I'm guessing the function to use would be CyPlot.getRevealedTeam() then? Or maybe CyPlot.isRevealed()?
antaine Feb 18, 2010, 09:56 AM "so that it looks for what Civs are present in the American Core Area at spawn, and then grants all the Techs and Maps of those Civs."
this should be done for all spawns throughout the game. if you'd done it, i'd include it!
Baldyr Feb 18, 2010, 11:00 AM this should be done for all spawns throughout the game. if you'd done it, i'd include it!
No, I don't believe so. The Americans are special because they're actually a European colony or several colonies. Thus they should know what they knew before they declared independence.
In my own Russia scenario the Russians start out as Kievan Rus and are thus varangians (vikings). I'll implement this function so that the Russians get maps of Scandinavia and beyond, and that the Vikings get maps of the Novgorod area (the new starting location - before Kiev flips).
It would also be cool to have an American spawn date that depends on the stability of the colonies themselves, as well as whether or not Nationalism and Liberalism are discovered. I'm not sure if it would work so well, though...
antaine Feb 18, 2010, 11:03 AM that does seem rather complex, and you're right, the franks and the goths did not know what the romans knew even though they repopulated the same area...
Baldyr Feb 18, 2010, 11:30 AM What about Portugal then? Should they know what Spain knows? The Netherlands? It seems rather silly that these two Civs are more advanced than their neighbors, and have no knowledge of the world around them.
Changes like this are bound to effect game balance, though. It could be another case of AI only features...
Too bad I don't have the time or the energy to do any Python tonight, but I'll try to figure this thing out during the weekend. I how have several new functions to work on... :king:
antaine Feb 18, 2010, 11:34 AM I think it would be a balance issue...and the techs they start with are an attempt to predict where the world is at that time (or where it was historically). I like the idea of giving civs typical starting lists, but there should be a function that shares the map with civs in its normal area and eliminates any techs not found in the tech lists of civs there at the time of spawning.
Baldyr Feb 18, 2010, 01:44 PM Ok, good stuff, taking notes. :goodjob:
Take a look at the list lNeighbours (and possibly lOlderNeighbours) in Consts.py - what about a function that grants a Civ all Techs already known by two or more neighbors - and/or a map of all tiles already known by two or more of them? :king:
When used for a spawning Civ it wouldn't make the newcomer the most advanced Civ in the neighborhood, but also not the least advanced one.
Baldyr Feb 18, 2010, 02:43 PM Did you ever test this properly? Because I was just improvising as I was typing you a responce. :mischief:
iHuman = utils.getHumanID()
numCivs = len(lOwner)
for num in range (numCivs):
iCiv = lOwner[num]
if (iCiv == iHuman):
lOwner.remove(iCiv)
break
It dawned on me that there's a much simpler way of doing what I was trying to achieve with the code above:
iHuman = utils.getHumanID()
if (iHuman in lOwner):
lOwner.remove(iHuman)
Since the variable iHuman is a integer value from 0 to 30, and since all the variables in the list are also integer values, its possible to simply check with the command "in" whether or not this value is already in the list. And if so, remove this value from the list. Plain and simple.
To put it in a simpler form we could just replace all the variables with the numerical values and type in the list without using the list variable. If we assume that the human player is Germany (Civ #17) - this is what the computer is actually seeing:
if (17 in [17, 11, 19, 25, 7, 4, 16, 15, 14]):
[17, 11, 19, 25, 7, 4, 16, 15, 14].remove(17)
It would be great if you could actually test this for me! :goodjob:
jmerry Feb 18, 2010, 03:32 PM On the balance: I've noticed that tech nearly always runs slow in my games; thus this plan would effectively nerf most late-spawning civs. Perhaps a slight global reduction in tech costs, to make research easier?
Also, I had this experience several times with the Americans:
Spawn several techs ahead.
Build initial cities, flip a few, get one in a congress. Conquer a canal city in Central America.
Economy crashes due to 150% inflation. All workers, and most of the army, disband.
That convinced me to drastically cut inflation, to 1/3 of its former value. (Not included in my bugfix patch)
OK, what would this change look like:
Neighbors with earlier spawn date (not the same as "older neighbors" list):
Egypt, Babylon, China, India: None. Starting techs, map should be unchanged.
Greece: None. Unchanged.
Persia: Babylon, India. Sharing fits well; guarantee techs for starting units as well.
Carthage: Egypt, Greece. Sharing sounds good; Carthage should know something about the Mediterranean. Guarantee techs up to Sailing, HBR, Archery as well.
Rome: Egypt, Babylon, Greece, Carthage. Should guarantee Iron Working.
Ethiopia: Egypt. Starting state should be unchanged (they need to be able to research Theology immediately for the UHV).
Maya: None. Unchanged.
Vikings: None. Unchanged.
Japan: China. Starting techs should be unchanged.
Arabia: Egypt, Babylon, Persia, Ethiopia. Lots of good shared stuff, should guarantee Guilds, HBR, and prereqs. On 600 AD start, give them unchanged techs and a bunch of map info.
Khmer: India, China, Japan. Should guarantee techs for elephants.
Spain: Carthage, Rome. Guarantee IW, Feudalism, what else? They're going to hurt if Carthage is already collapsed.
France: Rome, Vikings, Spain. A lot like Spain, but the Vikings are a very predictable tech list.
England: Rome, Vikings, Spain, France. OK, they'll know everything the French do.
Germany: Rome, Vikings, France, England. More of the same.
Russia: Persia, Vikings, Germany. That should get them some western map knowledge.
Netherlands: Vikings, France, England, Germany.
Mali: Egypt, Carthage, Ethiopia. That's a way to get screwed. Should guarantee a bunch of stuff, maybe add Arabia as a neighbor.
Portugal: Carthage, Rome, Spain, France. Guarantee Guilds; they need to be close to Optics to have a decent shot at anything.
Inca: Spain. Unchanged.
Mongolia: India, China, Japan, Russia, Persia. Guarantee techs for starting units.
Aztecs: Spain. Unchanged.
Turkey: Babylon, Greece, Persia, Russia, Mongolia. Add Arabia. Guarantee Gunpowder.
America: Japan, Spain, France, England, Russia, Inca, Aztecs. Wrong list entirely. Build a new list of any Old World civ with a city in North or Central America, plus their default neighbors. Also guarantee Democracy and prereqs. They can get their advanced military units, but they only get techs to replace them if some Old World civs know.
There are a lot of places where the 600 AD start would have to be treated differently if implementing this idea.
antaine Feb 18, 2010, 04:45 PM baldyr...at least for my mod, but perhaps for the original as well...couldn't map tiles simply be revealed in the WB save, and contact established with select civs there as well?
Baldyr Feb 19, 2010, 08:12 AM OK, what would this change look like:
(---)
There are a lot of places where the 600 AD start would have to be treated differently if implementing this idea.
You seem to have an idea so I say run with it. I'll try to figure out how to make the functions to use with it - you focus on the design aspects, ok? :goodjob:
I'd use such a modmod myself for sure, so I'm looking forward to your design. :king: If done right it could be released as something like "Dynamic Starts Modmod" and I think it would get some downloads also. By the way, we could make it a custom option whether to use dynamic starts - or perhaps only use them for the AI Civs. It shouldn't be too hard to do, I think... :p
Baldyr Feb 19, 2010, 08:16 AM baldyr...at least for my mod, but perhaps for the original as well...couldn't map tiles simply be revealed in the WB save, and contact established with select civs there as well?
I believe I've already tried all that for my own scenario, and since it didn't work I started to poke around with Python instead...
But you should probably try it! It would help me out for sure if you figure out how to get it working. (I ended up giving the Russians a Workboat on the first turn instead, to reveal some coastal west of Novgorod. I've been meaning to find a better way of revealing tiles though.)
jmerry Feb 19, 2010, 12:09 PM You seem to have an idea so I say run with it. I'll try to figure out how to make the functions to use with it - you focus on the design aspects, ok?
I'm not ideal as a speculative modder; I'm working on Mac, so I'm stuck with not quite the latest version and with no DLL changes. Also, I can't clone the folder and have two working copies at once. Still, this could probably be done Python-only, confined to the RiseAndFall file (aside from the option)...
All right, I'll do it.
Baldyr Feb 19, 2010, 12:57 PM Still, this could probably be done Python-only, confined to the RiseAndFall file (aside from the option)...
All right, I'll do it.
Yeah, I was also thinking Python only. :king:
I've started working on functions you could use. This is what I have so far:
### dynamic starts within RiseAndFall.py ###
## def getAreaCivs(self, TL, BR, lExceptions, bMajorOnly, bAIOnly):
## def makeTechList(self, iCiv, bTraded):
## def copyTechs(self, iCiv, tTechList, iNumHits, bHuman):
## def copyWorldMap(self, iReceiver, lProviders, iNumHits, bHuman):
custom.getAreaCivs() returns a list of all the Civs with cities present inside an predefined area. You can use any of the Core/Normal/Broader Areas or any other area, and it also handles exceptions (used to define Core/Normal area).
custom.makeTechList() returns a list containing all the Techs owned by iCiv. I'll look into making it possible to except traded Techs (as Tech brokering isn't allowed in RFC) with bTraded.
custom.copyTechs() takes a tuple list containing several merged Tech lists (above function) as an argument with a target value to determine what Techs iReceiver should get.
custom.copyWorldMap() takes a list of Civs and a target value to determine which map plots should be revealed to iReceiver.
Other functions I'm working on at the moment include:
def foundCity(self, lCity, name, iPopulation, bForce, iCityCulture, iCulture, iUnitType, iNumUnits, iReligion, lBuildings):
def flipCity(self, tCityPlot, iNewOwner, bOnlyAI, iOldOwner, bAIOnly, bMinorsOnly, bConquest, bKillUnits, iNumGarrison, bConscript):
def createGarrison(self, iCiv, bHuman, tCityPlot, iNumUnits, bConscript):
def setBuildings(self, tCityPlot, lBuildings):
def setGlobalBuilding(self, iCiv, iBuilding):
Any other suggestions are also welcome! :king:
Baldyr Feb 20, 2010, 08:43 AM Ok, here's the long advertised custom function for city flipping then. I urge antaine to use this instead of the default utils.flipCity() function, as it isn't designed to be used for scenario making or the like. There is no extra code (except the turn trigger) required and no list of possible owners need to be defined!
In short, my custom.flipCity() function allows to control what Civ can be the original owner, and whether or not the old owner or the new owner can be the human player, or if the original owner must be a minor Civ (useful for flipping independent cities only). Also, spawning defending units is built into the custom.flipCity() function and it uses an enhanced custom.createGarrison() function which allows for more unit types - and Unique Units - to be created. (Number of available unit types has gone up from 6 to 14, making it suitable for use in all ages and with all Civs.)
Here's the breakdown for all the arguments or settings:
custom.flipCity(tCityPlot, iNewOwner, bOnlyAI, iOldOwner, bAIOnly, bMinorsOnly, bConquest, bFlipUnits, iNumGarrison, bConscript)
tCityPlot: This a tuple and the city coordinates must be entered within brackets ([...]). It could also be a tuple variable or a list variable (the lCity lists can be used conveniently enough).
iNewOwner: This is a integer value or variable for the index number of the receiving Civ.
bOnlyAI: This is a boolean ("True" or "False") that determines if the receiving Civ can be the human player. The "True" setting makes it AI only and the "False" setting also enables the human player.
iOldOwner: This is another integer value or variable corresponding to the original owner. It can be set to "-1" as default for allowing any Civ to be the original owner.
bAIOnly: This is another boolean determining whether or not the owner can be the human player. ("False" = human player enabled.)
bMinorsOnly: This boolean can be used to restrict the owner to minor Civs only ("True").
bConquest: This boolean determines whether or not the city will be conquered or traded. (This should also affect UHVs!) If set to "True" the city will go into resistance and lose population points (if over size 2). Any units belonging to the previous owner are killed off and there will be a state of war between the receiving Civ and the previous owner.
bFlipUnits: This boolean determines whether or not also units inside the city will flip. This option is only available if the previous boolean is set to "False".
iNumGarrison: This integer value determines whether or not and how many units will be automatically spawned in the flipped city. Note that no units will spawn if the previous boolean is enabled ("True").
bConscript: This boolean determines if the units spawned are to be the default defensive unit of the era (from Warrior all the way to Mech Infantry) for the city's new owner ("False") - or if the units are the unit type that would be available for drafting with the Nationhood Civic ("True"). Pre Gunpowder these are actually melee units, and if the prerequisite strategic resources aren't available in the city this means that Warrior units will be spawned instead.
In order to use this (and other custom functions) the attached Custom.py file must be present in the \Assets\Python\ folder. Also, the file itself must be imported into the .py files where it is used (like Barbs.py) with this line (under "from CvPythonExtensions import *"):
import Custom
If the custom. prefix is to work this line must be entered (preferable under "# globals"):
custom = Custom.Custom()
The entire code we made earlier for flipping cities for Russia and creating the garrisons can be replaced by this:
#secessions to Russia
if (iGameTurn == con.i1730AD):
custom.flipCity(lMinsk, iRussia, True, -1, True, False, True, False, 2, False)
custom.flipCity(lKiev, iRussia, True, -1, True, False, True, False, 2, False)
custom.flipCity(lPeter, iRussia, True, -1, True, False, True, False, 2, False)
custom.flipCity(lVilnius, iRussia, True, -1, True, False, True, False, 2, False)
custom.flipCity(lOdessa, iRussia, True, -1, True, False, True, False, 2, False)
It does everything that the previous code did and it does it better, as there are fewer built in glitches and limitations. There's also more options available (see the documentation above) and it will also be very easy to go forward with additional city flips.
Note that the code above makes Russia go to war with whatever Civ that controls any of these cities! This can be avoided by changing the bConquest boolean to "False" - then the units in the city will also be moved out instead of killed off. (It could break the balance of power if the previous owner had a huge stack of units inside the city when it is "conquered"! Those units would simply vanish into thin air, opening the way for further Russian territorial gains...)
antaine Feb 20, 2010, 08:59 AM great...I'm testing it out today. as for the listing capability...can it be used to simply flip all nonhuman holdings in the nonhuman Russian core territory? I've found that by 1720, germany has completely swamped russia (both west and east of moscow), all the way to the urals...so flipping those five cities doesn't really help all that much...
Baldyr Feb 20, 2010, 09:22 AM great...I'm testing it out today. as for the listing capability...can it be used to simply flip all nonhuman holdings in the nonhuman Russian core territory? I've found that by 1720, germany has completely swamped russia (both west and east of moscow), all the way to the urals...so flipping those five cities doesn't really help all that much...
So, we're back at the "second spawn" discussion again, then? :rolleyes: This is pretty much what I've been saying all along so I'm agreeing with you whole-heartedly on this subject.
I haven't made that one yet but It's on the agenda. I was gonna go forward with the stuff for the dynamic starting conditions stuff we discussed earlier, but I guess it can wait...
In the meanwhile, here's some other stuff I have been spending the last day doing:
http://forums.civfanatics.com/showpost.php?p=8917744&postcount=66
You should find some of it very useful for making historical scenarios and such!
Also, the custom.foundCity() function is still available (with added functionality) if you change your mind...
http://forums.civfanatics.com/showpost.php?p=8897296&postcount=22
antaine Feb 20, 2010, 02:24 PM hm...I rigged up a "dirty" fix to see how it would basically play out...just flipping the original five cities insures a german collapse.
I have actually started flipping the cities one at a time starting in 1200 or 1250 from the west and working my way eastward (leaving the germans to keep vilnius). Even though St. Petersburg hasn't spawned (because it wasn't founded) yet, the germans always seem to found it as Wiburg anyway.
then, in 1400 and in 1720 I have the 59 tiles north of Moscow flip en masse (I've defined a bum city for each tile). My hope is that after safely and slowly flipping the cities on Russia's western core border (without causing war between russia and the former owners, if any), it will head off german expansion to the northeast and there will be nothing to flip in 1400 and 1720 anyway.
I'm sure I just made you cringe, but I'm afraid a second spawn would have the same effect and collapse germany, swapping one imbalance for another.
Baldyr Feb 20, 2010, 03:13 PM hm...I rigged up a "dirty" fix to see how it would basically play out...just flipping the original five cities insures a german collapse.
(---)
I'm sure I just made you cringe, but I'm afraid a second spawn would have the same effect and collapse germany, swapping one imbalance for another.
Yeah, you should probably not spawn or flip any cities beyond the British Isles anyway. The RFC + Celts modmod quickly becomes antaine's privat modmod... :rolleyes:
The reason the Germans collapse is probably because they lose half of their cities in a short period of time. In that case it has nothing to do with stability.
It is possible, though, to build in functionality that compensates for both the stability hit for losing cities and to resets the counter for lost cities. So thanks for the idea! :goodjob:
I'm already done with the rest of the code - all that's left is the actual testing - and the inevitable bug hunt. :rolleyes: I'll add the anti-collapse code in there as an additional setting once the function itself behaves as intended.
Oh my, I'm having the most fun I've had in ages with this programming business. :king:
antaine Feb 20, 2010, 03:23 PM lol, I'm happy to..."help"...I wonder if this germany/russia thing was a problem in the original. I'd imagine it would almost have to be, as the Celts and Carthaginians shouldn't have had an effect on Russian development.
In any event, what you're working on sounds like a much better fix than my "dirty" method, but for now I'll just leave what I've done alone. If the cities can be transferred to russia without hurting the other civs so much the better (and cleaner, codewise).
Baldyr Feb 20, 2010, 03:42 PM lol, I'm happy to..."help"...I wonder if this germany/russia thing was a problem in the original. I'd imagine it would almost have to be, as the Celts and Carthaginians shouldn't have had an effect on Russian development.
Yeah, it kinda is and this is also one of the reasons I've been going on about the "second spawn dates" and whatnot. Well, now I'm actually coding this stuff so I won't be having these "issues" myself for much longer...
In any event, what you're working on sounds like a much better fix than my "dirty" method, but for now I'll just leave what I've done alone. If the cities can be transferred to russia without hurting the other civs so much the better (and cleaner, codewise).
You will be able to replace everything with one "if" statement and call on one single function to achieve everything you've described - and more.
antaine Feb 20, 2010, 04:52 PM I eagerly await the new code. I love the idea of periodic "reality checks" for nations important to the modern world.
antaine Feb 20, 2010, 04:54 PM ps - I made those 59 "cities" easy to remove as soon as the better option is complete.
Baldyr Feb 20, 2010, 05:23 PM I'm debugging like crazy, but now I have to get some sleep as its 1 AM over here.
It turns out Rhye has been forced to overcome some pretty weird obstacles with his city flip code, and I was forced to follow suite before I got it working. Right now I'm struggling with how to use the len command with tuples... (To get a value of how many entries there is in the turple.) All this is pretty new to me so I'll just get a fresh start on it tomorrow.
Baldyr Feb 21, 2010, 02:56 AM Ok, here's custom.flipArea() as promised. The breakdown:
custom.flipArea(TL, BR, tExceptions, iReceiver, bHuman, bMinorOnly, bAIOnly, bConquest)
TL: This is the first coordinate for defining the area. Use any pair of values inside parenthesis and divided by a comma - or use a variable with similar content.
BR: This is the second coordinate, like above.
tExceptions: This is a turple containing any exceptions to the area defined by the values above. (It can be used both for adding tiles outside of the coordinates and for taking away tiles within the defined area.) The coordinates must be set in pairs within parentheses (divided by comma) set within yet another set of parenthesis (and divided by comma). Or use a tuple variable.
iReceiver: This integer value is the index number of the Civ getting the flip.
bHuman: This boolean determined whether or not iReceiver can be the human player ("True") or not ("False").
bMinorOnly: Boolean determining whether or not the cities and units inside the area must belong to a minor Civ ("True") or not ("False").
bAIOnly: Boolean allowing only AI controlled cities and units to flip ("True").
bConquest: Boolean determining whether or not the cities will flip peacefully ("False") or not ("True"). If set to disabled ("False") there will be some stability given to the target Civ to compensate for the lost city. Also there shouldn't be any default collapse just because the Civ lost too many cities in a short period of time. (This is also true for custom.cityFlip() as of this update.)I made this function with the default areas defined in Consts.py in mind, so it would probably be easier to use with those variables (tuples). So, in your case a peaceful transition of all non-human cities within the Russian Broader Area would look like this:
custom.flipArea(con.tBroaderAreasTL[con.iRussia], con.tBroaderAreasBR[con.iRussia], [], con.iRussia, False, False, True, False)
Note that there are no tiles added or subtracted in the Broader Area, this is why tExceptions = "[]" (as in empty list).
If you wanna flip the Russian Normal Area your code would look like this:
custom.flipArea(con.tNormalAreasTL[con.iRussia], con.tNormalAreasBR[con.iRussia], con.tNormalAreasSubtract[con.iRussia], con.iRussia, False, False, True, False)
Don't forget about the tNormalAreaSubtract tuple when using Normal Areas, as it is used for taking away some tiles from the Normal Area. Otherwise the area might be larger than defined in Consts.py by Rhye.
And finally the Russian Core Area:
custom.flipArea(con.tCoreAreasTL[con.iRussia], con.tCoreAreasBR[con.iRussia], con.tExceptions[con.iRussia], con.iRussia, False, False, True, False)
As you can see for yourself, you simply substitute tNormalAreaSubtract with tExceptions from Consts.py when adding tiles to the Core Area. You should know from the RFC Atlas that Core Areas (and also Normal Areas) aren't always rectangular in shape, and this is what those extra tuple lists are for. (Since you didn't delete the Carthaginian entries for your Celts they had a spawn area in the Levant... Well, until I deleted those entries for you.)
If you wanna define your own areas for custom.flipArea() you can choose between two different methods. Here's the first one exemplified with the Russian Core Area:
custom.flipArea((67, 50), (74, 57), ((68, 58), (69, 58), (70, 58), (65, 55), (66, 55), (66, 56)), con.iRussia, False, False, True, False)
That's a lot of parenthesis and commas to get right, so you might as well define you own variables instead (the other method):
tRussianCoreTL = (67, 50)
tRussianCoreBR = (74, 57)
tRussianExceptions = ((68, 58), (69, 58), (70, 58), (65, 55), (66, 55), (66, 56))
custom.flipArea(tRussianCoreTL, tRussianCoreBR, tRussianExceptions, con.iRussia, False, False, True, False)
As you would expect, it does exactly the same as the above methods of using the same Core Area.
Now give it a try and report back. Please keep an eye out for any errors or exceptions, because I haven't been able to test every imaginable scenario myself.
Yeah, and you still need to have a "if" statement in order to trigger the function on the right game turn. But there need be no check for human player or player alive (as this is already a feature in custom.flipCity() - the area flipping function uses the city flipping function to do its dirty work)
edit: Adding this to Barbs.py (or whatever file you're using for you flips and whatnot) could make it easier to work with:
tCoreAreasTL = con.tCoreAreasTL
tCoreAreasBR = con.tCoreAreasBR
tExceptions = con.tExceptions
tNormalAreasTL = con.tNormalAreasTL
tNormalAreasBR = con.tNormalAreasBR
tNormalAreasSubtract = con.tNormalAreasSubtract
tBroaderAreasTL = con.tBroaderAreasTL
tBroaderAreasBR = con.tBroaderAreasBR
Because then you don't have to remember to type in the con. prefix every time to fetch the values from Consts.py (as they will already be defined in the file you're working with).
antaine Feb 21, 2010, 11:20 AM awesome...it appears the coreflip works, but it's still penalyzing germany, which is now on the brink of collapse.
Baldyr Feb 21, 2010, 11:30 AM awesome...it appears the coreflip works, but it's still penalyzing germany, which is now on the brink of collapse.
You should keep track of the German stability in PythonDbg.log to see what the impact really is. If its merely a case of upping the stability bonus, that would be easy to do. (Right now the Civ losing cities to - peaceful - flips get a +2 boost. Its the same amount used by Rhye to compensate for secessions, but it might not be enough. I'll just have to look up what the stability penalty for losing cities is, then...)
Also, you need to look up what kind of collapse has occurred once it does happen. Because there are four kinds of collapse for the AI! Its hard to fix this issue if we don't know what causes the collapse in the first place.
Previously I suspected a "COLLAPSE: Generic" which is caused by losing half of your cities within a certain turn interval. I actually haven't tested if my fix for this works, so I'm pretty much counting on you to do it.
If its "COLLAPSE: Civil War", then its solely caused by instability (less than -40 to be exact).
antaine Feb 21, 2010, 11:34 AM kk, I'll try to check that, I have all debugging on, but I don't see anything in there that seems to apply. Is the error message always the same, "the X empire is descending into civil war?" Perhaps germany's instability is merely a coincidence
Baldyr Feb 21, 2010, 11:54 AM As far as I can tell, the basic stability loss for losing a city (via "trade", not "conquest") is a function of 16 - (number of cities / 2) + 2.
So if the Germans have, say, 10 cities and they lose 5 of them to the Russians on a custom flip, the penalty for the first one would then be 16 - 4 (rounded down from 9 / 2) +2 = 14. The second one would also be 14, the third and the fourth 13 and the fifth 12.
It adds up to a hypothetical total stability loss of -66, which would pretty much ensure a collapse, even with the +10 compensation (5 * 2). Also, there is secondary stability penalties for the expansion (and perhaps diplomacy) category. But we could probably up the stability boost to at least +10 or something (14 would be an average stability loss in the German example above, rounded up).
There is another set of numbers involved in proper spawns and respawns, but I haven't tried emulating those with my code in regard to stability. But we could test the new value first - change the value 2 on line #320 in Custom.py to 10 (or whatever you wanna test out). If it proves unreliable, I could just add that code to custom.cityFlip() (which is actually used to flip the cities).
antaine Feb 21, 2010, 11:58 AM thanks, i'm going to try that.
Baldyr Feb 21, 2010, 12:09 PM kk, I'll try to check that, I have all debugging on, but I don't see anything in there that seems to apply. Is the error message always the same, "the X empire is descending into civil war?" Perhaps germany's instability is merely a coincidence
In PythonDbg.log you could keep an eye out for this entry:
(u'Germany', 'PLOT OWNERSHIP ABROAD:', 0, 'CITY OWNERSHIP LOST:', 0)
It turns up every few turns in the log. As does this one:
('Base:', -8, 'Modifier:', 4, 'Total:', -4, 'civic', 25, u'Holy Roman Empire')
This is what a German collapse from stability would look like:
('COLLAPSE: CIVIL WAR', u'German')
The other one reads:
('COLLAPSE GENERIC', u'German' 10 <= 10)
Have you even located the debug log on your machine yet?
antaine Feb 21, 2010, 12:12 PM I have, but it doesn't appear to have logged anything from this game. As it is, Germany didn't collapse, but has leveled out.
Baldyr Feb 21, 2010, 12:21 PM This is what should be enabled/disabled in CivilizationIV.ini (or whatever is used for Mac):
HidePythonExceptions = 0
ShowPythonDebugMsgs = 1
LoggingEnabled = 1
OverwriteLogs = 1
SynchLog = 1
RandLog = 1
MessageLog = 1
I don't think there will be anything showing in the logs otherwise...
(I didn't actually find one of the settings myself, but I don't remember which one. But try to find as many as you can.)
jmerry Feb 21, 2010, 12:35 PM It's CivilizationIV.ini, located in (user)/Documents/Civilization IV Beyond the Sword. If you enable logging without any other changes, it can spot Python exceptions but not much else. That's still useful for spotting typos and the like.
antaine Feb 22, 2010, 02:40 PM I wonder how much faster the world advances if tech brokering is enabled...does that balance out the old civs vs the new civs better, or does that make everything advance way too fast?
Beornhard Apr 03, 2010, 08:32 PM The download link in the first post is dead. Is there any other place to get the files from?
antaine Apr 03, 2010, 08:37 PM Yes, the old versions were removed. The final release was Celtic Mod v3.0, it has its own thread in the same list where you found this one. Honestly, though, RFC Irish (released this week) makes for a better mod altogether, and really what I should have been doing from the start
RFC Irish
http://forums.civfanatics.com/showthread.php?t=359542
RFC with Celts
http://forums.civfanatics.com/showthread.php?t=354996
zettawatt Oct 02, 2010, 11:14 AM Just a quick question, what files have you been editing to make this? I have been starting to work on an Austro-Hungarian modmod for Rhye's and Fall, and just need a headstart.
zettawatt Oct 02, 2010, 11:15 AM Thanks in Advance! :goodjob:
antaine Oct 02, 2010, 11:24 AM wow...well...more than I want to count. The big ones I've altered have been barbs.py (for random events), victory.py, riseandfall.py, AIWars.py, RFCUtils.py, CvEventManager.py and a whole new Custom.py file as well as CvGame.cpp, CvRhyes.cpp, CvTeamAI.cpp, CvPlayerAI.cpp, CvTeam.cpp, CvInfos.cpp, CvCity.cpp, CvPlayer.cpp, a host of XML files and more. All the cpp alterations require a recompiling of the DLL in order to take effect. Editing of Python and XML just requires reloading of the mod.
It's been a long time since I tinkered with this, so I don't remember precisely every file I altered, but that's just going by the last round of things with the latest "Date Modified" tag.
antaine Oct 02, 2010, 11:25 AM It was actually easier to make my own mod from scratch that mimics a lot of what Rhyes does than it was to actually figure out Rhye's code and alter it.
zettawatt Oct 02, 2010, 11:38 AM Thanks Again.
|
|