Help with Dynamic Improvements

Baldyr

"Hit It"
Joined
Dec 5, 2009
Messages
5,530
Location
Sweden
I'm currently trying to use the Resources.py file, that it used to spawns "dynamic resources" at set dates, to also spawn terrain improvements. Rhye has been helpful enough to include a template for this, but that isn't doing me much good since I really don't know my Python.

This is an example of code that spawns a Resource:
gc.getMap().plot(71, 30).setBonusType(iSugar) #Egypt
And the template for improvements looks like this:
setImprovementType(ImprovementType eNewValue)
So I'm thinking you use it something like this:
gc.getMap().plot(68, 56).setImprovementType(ImprovementType iTown) #Novgorod
But all it does is end the game on the first turn (#181 in this case since I'm using the 600AD start). Clearly I'm not using it right...:sad:

What should the syntax be, and should I specify (define?) any parameters somewhere? (I tried "iTown = con.iTown" but it did me no good.)

I also noticed that "iTown" has been given the value of 22 in Consts.py, but maybe that has nothing to do with this? I tried substituting the "iTown" with "22" but it didn't work either.

Can anyone help with this? Even a qualified guess would be appreciated!
 
Thanks!:goodjob:

Works like a charm, after I added the following to the file:
Code:
iTown = con.iTown
The next thing I needed to do was to get it to work with other Improvements as well. So, I also added:
Code:
iFort = con.iFort
It just made the game end on the first turn, all over again, so I added this line in Consts.py:
Code:
iFort = 23
If anyone else wants to mess around with spawning Improvements (useful for spawning Goody Huts, or re-spawning them), this is the code I use to get the tile for Novgorod to first spawn as a Fort on 800AD, and then become a Town on 900AD. (Next I'll have to get an actual city to spawn on 1000AD, but that's in another file.)
Code:
		if (iGameTurn == con.i800AD):
			gc.getMap().plot(68, 56).setImprovementType(iFort) #Novgorod
		if (iGameTurn == con.i900AD):
			gc.getMap().plot(68, 56).setImprovementType(iTown) #Novgorod
Also, I had to add the first spawning date into Consts.py:
Code:
i800AD = 201
 
The entries that start with "i" are integer variables. You need to define them before use, either in the file itself or in Consts.py, because the functions themselves only care about integers.

Check out my Dynamic Terrain mod component to see what other things you can do with Resources.py.
 
Yeah, good stuff. I'll be adding that to my RFC eventually...

Thanks again for all the help! :)

Another thing I'm struggling with is enlarging the Mongol spawn area. They seem to lose their entire spawn area when I try this, so I end up changing it back.

What I do is I change the coordinates of the Core Area in Consts.py, and I have done this before with other Civs. (Right now I'm changing the Russian spawn area all the time, so I know how to do this.)

I'm guessing there is some kind of issue with the other areas, Normal and Broader Area respectively. What exactly are these, by the way? I think I'll need to change these also, so I might as well know what exactly they do.

I have, how ever, noticed some correlation with the stability maps, but these aren't them, right?
 
I don't know much about that. The stability maps are based on the Areas, so that's why they are correlated.
 
Yeah, I actually got the spawn area to work, somehow. (I believe that the Normal Area has to be within the Core Area, and the Core Area must be within the Broader Area.)

Next problem: I've tried my best to make the Mongols declare war on Japan (and others) on a certain turn with the CyTeam.setAtWar function, but I just don't know the syntax. This is what the error log says (example):
ArgumentError: Python argument types in
CyTeam.setAtWar(CyTeam, CyTeam, bool)
Well at least I know it's not done like this (or a dozen other variations on the theme):
Code:
                if (iGameTurn == con.i1200AD):
                        CyTeam.setAtWar(teamJapan, teamMongolia, True)
The only place I could find this function was in "def warOnSpawn(self)" in RiseAndFall.py:
Spoiler :
Code:
        def warOnSpawn(self):
                for iCiv in range(iNumMajorPlayers):
                        if (not gc.getPlayer(0).isPlayable() and con.tIsActiveOnLateStart[iCiv]==0): #late start condition
                                continue #skip          
                        pCiv = gc.getPlayer(iCiv)
                        teamCiv = gc.getTeam(pCiv.getTeam())
                        iMin = 20
                        if (pCiv.isHuman()):
                                iMin = 20 #can be set to 100 for skipping human player
                        if (gc.getGame().getSorenRandNum(100, 'first roll') >= iMin):
                                for iLoopCiv in con.lEnemyCivsOnSpawn[iCiv]:
                                        if (not gc.getPlayer(0).isPlayable() and con.tIsActiveOnLateStart[iLoopCiv]==0): #late start condition
                                                continue #skip
                                        iLoopMin = 50
                                        if (iLoopCiv >= iNumMajorPlayers):
                                                iLoopMin = 30
                                        if (pCiv.isHuman() or gc.getPlayer(iLoopCiv).isHuman()):
                                                iLoopMin += 25
                                        if (gc.getGame().getSorenRandNum(100, 'loopCiv roll') >= iLoopMin):
                                                gc.getTeam(gc.getPlayer(iLoopCiv).getTeam()).[COLOR="Red"]setAtWar[/COLOR](iCiv, True)
                                                teamCiv.[COLOR="Red"]setAtWar[/COLOR](iLoopCiv, True)
                                                #print("civs will start at war:", iCiv, iLoopCiv)
I tried to add some code to always make the folks in the lEnemyCivsOnSpawn list declare war on the Mongols, but that didn't yield any positive results either.

My first attempt was to get the iMin integer to have the value of 1 if the iCiv was infact the Mongols (iMongolia, I suppose).

My second idea was to add an "or" clause on line 19 (with varied syntax):
Code:
if (gc.getGame().getSorenRandNum(100, 'loopCiv roll') >= iLoopMin [B][COLOR="Red"]or iCiv == con.iMongolia[/COLOR][/B]):

My third option was to add this piece of code (tried different syntax also):
Code:
                                        elif (teamCiv == teamMongolia):
                                                gc.getTeam(gc.getPlayer(iLoopCiv).getTeam()).setAtWar(iCiv, True)
                                                teamCiv.setAtWar(iLoopCiv, True)
Any ideas?
 
What I quite don't get is why it doesn't matter what value I set the iMin integer to. The default is 20 and if you set it to 100 that should (according to the commenting) disable the chance of rivals declaring war when you spawn. But, when I lower it to 1 it still doesn't get me an automatic DoW.

The way I interpret the code is that the clause "if (gc.getGame().getSorenRandNum(100, 'first roll') >= iMin):" gives you iMin chances in 100 for not getting a DoW. So, iMin = 1 should give you 100% chance, iMin = 20 would be 80% and iMin = 100 would be 1%. But since the value 100 would be 0% (because of ">=" instead of ">"), I'm clearly not getting this right.
 
Aha, I see there are actually who sets of random rolls, and this is causing the confusing results. All I have to do then is to give both integers (iMin and iLoopMin) the value of 1 if iCiv is iMongolia, right? Now, how do I get the syntax right...

edit: Done! Its actually working as intended! :)
 
Back
Top Bottom