Vikings shouldnt get kjøbmandehavn(Copenhagen)

As for the culture issue with Forts, this is something I've wanted to implement for some time now. But I'm not sure how to achieve this, at least with Python. Because the rules state that there can be no cultural borders without a city present...

I compared the two Barbs files and these lines didn't match:
Code:
lRoskilde = [60, 55, [COLOR="Red"]0[/COLOR], con.iVikings] #990AD
lWashington = [[COLOR="Red"]63[/COLOR], [COLOR="Red"]58[/COLOR], [COLOR="Red"]2[/COLOR], iIndependent2]#1775CE
Note that if you tried this with the AD 600 scenario then the first turn is actually #181.

As for custom functions we're discussing some more in the Celtic mod release thread. :D There is also some discussion on Python in general, if someone is interested in learning some basic stuff.

I'll try to make a handful new functions this weekend, if life doesn't get in the way... :rolleyes:
 
Well I just used your "BarbsMe.txt" and it worked fine.

I tried it again, and it worked too, I think that I must have saved it incorrectely or something... :sad:

You should remember that a city will not spawn if it is in a major civ's culture area. If by 1775AD, Washington's plot is part of Britain, France, Spain, or some other major civ (i.e: not Independent, Barbarian or Native) then it will not spawn.

Even though the comment said 1775, I had set the turn to near the beginning of the game, so I would not have to wait so long to see if it worked, so there was no culture, I think I messed up somewhere with saving it or something, because it worked now.

As for custom functions we're discussing some more in the Celtic mod release thread. There is also some discussion on Python in general, if someone is interested in learning some basic stuff.

:woohoo: :woohoo: :woohoo: :woohoo: :woohoo: :woohoo: :woohoo:
 
The city spawn forcing will only force spawn if the city is in a minor civ's area, if my understanding is correct. Baldyr? ;)
Actually, I changed the default setting a bit compared to Rhye's function. The original checkRegion() function only allowed cities to spawn in not owned territory or in Barbarian territory. I changed the default setting (bForce = False) to also allow spawns in one's own and in territory controlled by any minor Civ.

Also, the default setting doesn't allow for any units belonging to the human player in any adjacent tile.

What the force spawn setting (bForce = True) does is that it takes away all these conditions, allowing cities to spawn on any tile. The only thing that would deny a spawn is a city belonging to a major Civ - or a unit belonging to the human player - blocking the tile. If a city belonging to a minor Civ is blocking the tile that city is razed to accommodate the spawn!

Does this seem useful enough, or should something be changed?

ps I spotted a bug in the code looking the above conditions up, by the way. It will be corrected in the next version.
 
I used the foundCity function to create some cities in Indonesia (settlements existed there before the time biology is discovered in game, and the spices were important historically). The dates are more or less random, I could not find any sources for them, but the names are those of modern-day cities in the region.

Overall, it is a great function! :goodjob:
 

Attachments

  • Civ4ScreenShot0003.JPG
    Civ4ScreenShot0003.JPG
    152.9 KB · Views: 92
  • Civ4ScreenShot0004.JPG
    Civ4ScreenShot0004.JPG
    172.4 KB · Views: 102
I've attached an updated Custom.py file with tons of new toys for you to tinker with! :king: Testing is encouraged and appreciated! :goodjob:

edit: download here

Here's what is there as of this version:
custom.foundCity(lCity, name, iPopulation, bForce, iCityCulture, iCulture, iUnitType, iNumUnits, iReligion, lBuildings)
This works the same as before, but I've managed to get rid of a bug and added a new functionality to it: If you set iUnitType to "-1" but have a value higher than "0" in iNumUnits, then the function will automatically detect what the conscripted unit type of that city would be, and creates this type of units instead. Note however that pre Gunpowder these units are actually melee units - and without the prerequisite strategic resources they will be Warriors... :rolleyes:
custom.flipCity(tCityPlot, iNewOwner, bOnlyAI, iOldOwner, bAIOnly, bMinorsOnly, bConquest, bFlipUnits, iNumGarrison, bConscript)
This is a very useful new function that is covered in great detail in this post. :D
custom.createGarrison(iCiv, bHuman, tCityPlot, iUnitType, iNumUnits, bConscript)
This is actually the function used in both custom.foundCity and custom.flipCity, but it works individually also. Its also possible to use it to spawn any unit type in any city, but with iUnitType set to the default value of "-1" it will automatically determine what units to create. (Also, the bConscript setting affects this.)
custom.setReligions(tCityPlot, lReligions, bErase, bMessage)
You feed the function a list of what religions will be present in the city located at tCityPlot (works also with the standard lCity lists). The bErase boolean can be used to also erase religions that are present in the city but not in the list. (An empty list ("[]") together with bErase = "True" would wipe all religions from the city.)
custom.spreadReligion(iReligion, TL, BR, bMessage)
This function gives all cities inside the specified area the religion specified by iReligion. Note that the TL and BR coordinates must be entered within brackets ([])!

The bMessage boolean for both above functions is used for enabling the religion spread announcement.
custom.eradicateReligion(iReligion, TL, BR)
This function can be used to wipe the iReligion religion clean out of an area! :eek:
custom.setBuildings(tCityPlot, lBuildings)
This function works just like it does in custom.foundCity() but can be used separately to add any buildings to any city at any point.
custom.setGlobalBuilding(iCiv, iBuilding)
And finally, this function will give all cities belonging to iCiv the building specified in iBuilding. (Note that this is not a list of buildings, but only one integer value or variable.)

Happy mod-modding! :goodjob: This is actually only the beginning, as the next batch of functions will make it possible to have dynamic starting Techs and world maps for any Civ...
 
My question is, do you think I should give it (the city) to Spain (Panamá) or to the USA (Panama City)? I mean technically it should be independent of course, but that would mean that no one would have an open borders agreement with them. Spawn date would be 1914AD, turn 402, tile 26,31.
This would be the solution I was suggesting earlier:
Code:
                custom.foundCity([26, 31, 289, con.iSpain], "Panama", 2, True, 10, 50, -1, 2, con.iChristianity, [])
                if (iGameTurn == 402):
                        custom.flipCity([26, 31], con.iAmerica, True, -1, True, True, False, False, 2, True)
What it does (or should do, at least) is that it spawns the city Panama on in AD 1540. It will be Spanish unless Spain is played by the human player (then it will belong to a minor Civ). If the city is independent in AD 1914 it flips to the Americans - unless the Americans are player by a human.

There could also be an even earlier Native spawn and then two consecutive AI only flips - first to Spain and later to America. There really are many choices as to your actual design...

One function or help I could use is a way to make it so China flips all the cities in China if the player is non-human. In some of my games, the AI just takes Qufu and Xian and ignores Hangzhou and Guangzhou for some reason.
This is next on my agenda and its actually long overdue. It will be a function than can be used with any imaginable area - not only the three pre-defined in Consts.py.
 
One function or help I could use is a way to make it so China flips all the cities in China if the player is non-human. In some of my games, the AI just takes Qufu and Xian and ignores Hangzhou and Guangzhou for some reason.
You can download yet another version of Custom.py from this post. There's also full documentation available (including another feature for custom.flipCity()).

Give it a try! :goodjob:

edit: This is what the Chinese flip could look like (if used with the Broader Area):
custom.flipArea(con.tBroaderAreasTL[con.iChina], con.tBroaderAreasBR[con.iChina], [], con.iChina, False, True, True, False)
This would give all cities belonging to the minor Civs to China peacefully, also converting any units in or near these cities. (You could define another area also, or have cities belonging to the major Civs - or even the human player - flipped.)
 
Some tests:

Spoiler :
SUCESSFUL: Flipping the Chinese cities works perfectly.

SUCESSFUL: createGarrison() was used to add 4 archers to the Mayans(if they are the AI), because they always die. They now survive, I think it might be a few archers too many; they should die sometimes.

SUCESSFUL: spreadReligion() was used to spread Christanity to England and the Netherlands, I've often seen Islam there.

SUCESSFUL: eradicateReligion() was used to remove Islam from these areas.

UNSURE: setGlobalBuilding() was used to give the (AI)Russians research institutes in all cities(likely overpowered, especially if they have many cities) in the early 1900's, the AI usually falls too far behind, I havent reached this point to see if it has worked though.

IDEA: flip Italy from the AI a few times from 1000 until 1800, I have noticed that Europe requires Italy to be controlled (usually by France or Germany) in order to dominate. If nobody does they have a tech rate 100 years or so behind normal; but if the do control Italy, by the 1700's "normal" is approaching infantry and destroyers, and space flight in the late 1800's.

IDEA: flip more of the Middle East to the (AI)Arabs, it is never conquered, and then flip a bit more to the (AI?)Turks to give them more of a chance.

IDEA: flip the core area of America to the (AI)Americans in the mid 1800's. If the AI does not settle this area, it is very weak

IDEA: spread Islam to the cities of the Indian Ocean, it rarely reaches there, unlike it did historically, same with Christanity in the Americas.

EXTREME IDEA: spawn an ICBM or 2 to the barbarians in the very late game (maybe with a warning message if I can figure that out, and then it will be a race to find the location before the nukes spawn and launch):nuke:

I will try these ideas and post the results.:)


EDIT: I remember reading that it is possible to reveal the entire map and play as a minor civ, so you can observe the game. Is this possible and if so, how could I do this?
 
I think you mostly have sound ideas. :goodjob:
IDEA: flip the core area of America to the (AI)Americans in the mid 1800's. If the AI does not settle this area, it is very weak
AI America is something I'm gonna work on myself after I'm done with the Russians, because they never make any noise at all. (Also, no possibility of Cold War between Russians and Americans. But that could be fixed... :mischief:) Maybe I'll make it into a proper modmod?
EXTREME IDEA: spawn an ICBM or 2 to the barbarians in the very late game (maybe with a warning message if I can figure that out, and then it will be a race to find the location before the nukes spawn and launch):nuke:
This is really a "scenario" idea but sure, why not? Note that Barbarians really aren't present in the late game, as Civs collapse into Independents only after Nationalism. So your "rogue states" would probably be independents then. Or, you could flip any "rogue states" to the Barbarians - even if that would make it very easy to figure out they have nukes...

Regarding messages and pop-ups and the like, I've dabbled a bit with that previously, but I intend to learn more. Once I get around to it, I'll make nice functions for them. It will be required to create a custom XML file for the all the text though, but I could provide a template (Civ4GameText_Custom.xml).

Right now I'm working on some functions for effective and easy unit spawning. The ones Rhye has done in Barbs.py work just fine for Barbarians spawns (imitating the default barbarians spawns in CivIV) but aren't all that useful for scenario making. This will probably be the biggest relief for me personally, since I've really struggled with spawning units with the Barbs.py file.

What sort of unit spawns would be useful for you? Right now I'm making one for spawning domestic units (inside or outside of domestic culture, depending on settings) and one for spawning hostile units (inside or outside of foreign culture, depending on settings). Also, I'm making a wrapper function of sorts to spawn units on random locations within a defined area, at set intervals. There will probably also be some support for spawns on completely random turns. Everything can of course be limited to AI only if need be.
 
EDIT: I remember reading that it is possible to reveal the entire map and play as a minor civ, so you can observe the game. Is this possible and if so, how could I do this?
First off you need to enable cheat mode by setting it to "chipotle" in Civilization4.ini.

The way I do it is that I start the scenario as the Americans and once the autoplay begins, i press the Pause key to get control over the interface (it will lag otherwise). Then I press Ctrl + Z to reveal the world map. Pause resumes the autoplay and when the Dawn of Man pop-up appears I open up one of the advisors (top right) and close again to get rid of it.

Usually I also open up World Builder and give the American leader Calendar to reveal the year date. Once something interesting happens I will pause the autoplay, zoom in for a closer look, and often switch to the PythonDbg.log file to see what actually is happening behind the scenes.

I don't know how to run autoplay indefinitely though, so testing becomes somewhat of a hassle after AD 1775. Although you can switch Civs by hitting Alt + Z, I wouldn't recommend playing as any of the Minor Civs. The reason is that there will be error Python related error messages that might cause issues with the Python code (and that is what you would be testing, right?). Try and toggle through to a dead Civ instead and see if that works?
 
First off you need to enable cheat mode by setting it to "chipotle" in Civilization4.ini.

Thank you! :thanx:

What sort of unit spawns would be useful for you?

I think that units spawned with promotions or experience would be useful; it is a little unhistorical for a nomadic barbarian horse archer from the steppes to be only as strong as a Roman horse archer, some promotions could fix the balance. It is also good if cities flip and cause war for the garrison to have some city defender promotions, so the flip is not easily reversed, like with Germany and Russia.

I ran the autoplay:

The game froze in the early 1700's :badcomp: so this is what happened so far.

Spoiler :
Arabia flip did not occour, near the "end" they only had 2 cities.

Turks flip failed too.

Spread of Islam failed.

Spread of Christanity in Europe was a success.

Christanity spread in the Americas failed.

Flip of Italy worked... once. It fliped the cities while Rome was still alive (in 1100), and killed Rome (this was not a collapse-they were all the same Independent). Only France conquered a city, and I think it was by culture, and did not expand any more. Unintended but much more historical.:)

Only 1 of the 7 cities in Indonesia spawned(and China conquered it:confused:), Birka spawned too.

Tucume flipped to the Incas.

Tech rates were good, colonies in the Americas started in 1510.

Strange things like Greece living until the "end", Buddhism widely spread, slow English (had only 2 cities for a long time) and Russian expansion that picked up later, and Chinese and Persian superpowers. I think these are all due to the 3000 BCE start though.

I think the failures are due to my mistakes, because at other times the functions worked.

The ICBM's were mostly just to test if it worked, with some 2012 nuclear fun :nuke:
 
I think that units spawned with promotions or experience would be useful; it is a little unhistorical for a nomadic barbarian horse archer from the steppes to be only as strong as a Roman horse archer, some promotions could fix the balance. It is also good if cities flip and cause war for the garrison to have some city defender promotions, so the flip is not easily reversed, like with Germany and Russia.
Coding as I write this.

I'm not adding settings for promotions to all functions, but I'm doing automatic/preset/optional promotions for units spawned with some functions. Like: Units spawned with custom.foundCity() never get at promotions (just like before). Units spawned with custom.createGarrison() get the City Garrison (for default defensive units) or Drill I (for custom units) or Combat I (for conscript units) promotion if enabled (boolean). Units spawned with custom.spawnBarbs() can get any promotion (but only one) specified. Units spawned directly with custom.makeUnit() can, of course, get any promotions (within a list). Or something - I'm still designing.

How does this sound to you? Is it what you were looking for? Or should certain barbarian units always get some preset promotions instead (maybe with a boolean argument)? Like: Horse Archers get Shock, Axeman get City Raider, and so forth. Or should all functions have the option of specifying any and all promotions? (Less user friendly but complete control.)
 
Have you enabled debugging yet? Because if you had done that, you wouldn't even have continued player past the very first issue... Once you have errors all the Python tends to brake down. That means also Rhye's scenario. :eek:

Here's what you need to do:
http://forums.civfanatics.com/showpost.php?p=3579837&postcount=5

I had not enabled this, I've switched it now, and I'm going to try it out. :)


How does this sound to you? Is it what you were looking for? Or should certain barbarian units always get some preset promotions instead (maybe with a boolean argument)? Like: Horse Archers get Shock, Axeman get City Raider, and so forth. Or should all functions have the option of specifying any and all promotions? (Less user friendly but complete control.)

This sounds very good! I like the idea for the barbarian units. Maybe instead of being able to specify all promotions, what about giving the unit experience and the option of a few promotions that are hard to get normally or do not fit many units? That way it is more user friendly, and still allows a decent amount of flexability. The only problem with that is that the AI could choose poor promotions, and defeat the purpose of simplifing the function.

P.S. My free time is now limited, so I might not be able to respond as often. :(
 
This sounds very good! I like the idea for the barbarian units. Maybe instead of being able to specify all promotions, what about giving the unit experience and the option of a few promotions that are hard to get normally or do not fit many units? That way it is more user friendly, and still allows a decent amount of flexability. The only problem with that is that the AI could choose poor promotions, and defeat the purpose of simplifing the function.
I have thought about going with "unit level" instead of choosing promotions. That way the modder only has to enter a integer value instead of looking up the index number for a promotion or several promotions (and having to specify them as a list to boot) - or looking up what amount of XP corresponds to what level. The level would then be translated into a number of XP which would then be available for promotions. I'm not sure exactly how to enable those XP to be "available" for promotion but it shouldn't be impossible to achieve.

One limitation with spawning units and promotions/XP though: There seems to be no simple or obvious way of giving units any of this at the spawn itself, but the unit or units must be identified afterwards and only then can they be promoted. The problem is that the only reliable way (without giving the units scripts or something) is to do this to every unit on a specific tile. This also means that units that get promoted at spawn can't spawn on a tile with other units present, because then those units will also get promoted!

One option could be to only give promotions/xp/whatever to units that 1. have no XP and 2. are undamaged. Because this would exclude many previous units from getting the promotion. But the wrong units would still get promoted from time to time. Can anyone think of any additional ways of distinguishing between pre-existing and newly spawned units on a tile? (Maybe there is some way of finding out what game turn a units was built, or something?)

What's worse, then? Not being able to spawn pre-promoted units on tiles with other units - or previously units getting promoted together with spawning units?

P.S. My free time is now limited, so I might not be able to respond as often. :(
Yeah, likewise... :p
 
There seems to be no simple or obvious way of giving units any of this at the spawn itself
Enable the onUnitCreated callback (PythonCallbackDefines.xml).
Then, in the event handler, add this line:
Code:
		eventManager.addEventHandler("unitCreated",self.onUnitCreated)
and later create the function
Code:
	def onUnitCreated(self, argsList):
		'Unit Completed'
		unit = argsList[0]
		(your code here)

Why do I know this? Because I did it to get the promotion-based unique powers working in the Mac version.
 
Enable the onUnitCreated callback (PythonCallbackDefines.xml).
Then, in the event handler, add this line:
Code:
		eventManager.addEventHandler("unitCreated",self.onUnitCreated)
and later create the function
Code:
	def onUnitCreated(self, argsList):
		'Unit Completed'
		unit = argsList[0]
		(your code here)
So, if I get this right I'm supposed to call on my own function (in Custom.py) from this one. But how do I connect the dots, so to speak? The unit is spawned with a makeUnit() function using CyUnit.initUnit() (triggered by checkGameTurn() in any .py file running this function) - do I pickle the promotion(s) data or what? Because how will the onUnitCreated() function know that the unit just created is supposed to get promotions?

The way I would try to do it would probably be to pickle lPromotions, make the unit with CyUnit.initUnit(), and then erase the pickled data before leaving the makeUnit() function. That way the next unit created won't automatically get the same promotions. This is dependent on the game pausing the onBeginGameTurn() function while it's doing the onUnitCreated()...

There is a lot yet to learn about this Python stuff... :rolleyes:
 
I'm not sure how you would go about the full flexibility version, but something like promoting all barbarian units of a certain type that spawn in a certain area is easy with that callback. Essentially, anything you can query about the unit is fair game to test for.

Oh, wait. initUnit returns a CyUnit. Capture that return and do stuff with it. Much simpler for your purposes.
 
Oh, wait. initUnit returns a CyUnit. Capture that return and do stuff with it. Much simpler for your purposes.
It does? :confused: You mean like:
Code:
unit = player.initUnit(...)
That would then both make the unit an set the variable to that unit instance.

Could it be that easy?
 
Back
Top Bottom