[BTS] Mongol Camp

Fierabras

Emperor
Joined
Dec 26, 2006
Messages
1,120
Description:

This is a conversion of the Mongol Camp unit from the Warlords Genghis Khan scenario. The Python script is based on the original code written by Jon 'Trip' Shafer.

Functionality:

Camps have a chance of producing a unit every turn. That chance is increased between five turns. Additionally, the type of unit a Camp produces can be altered depending on what type of terrain and feature it's on. The odds of the type of unit can be greatly favored based on the following:

- Plains: Horse Archer
- Desert: Keshik
- Hills: Archer
- Forest: Trebuchet

You do not begin the game with the ability to spawn Trebuchets. If on Forest prior to obtaining 'Engineering' or any plot type not listed above the chance of each unit being created will not be modified by any bonuses.



Extra:

Included in this mod is a scenario named 'Earth1000AD - Mongol Camp'. It's the BTS version of 'Earth1000AD' with the 2 Mongol settlers and 2 workers removed and 2 camps added.

Download:

http://forums.civfanatics.com/downloads.php?do=file&id=8847

Changelog:
Spoiler :

[BTS] Mongol Camp changelog
---------------------------

version 1.3:

- fixed load game/scenario problem

version 1.2:

- fixed bug in unit chance calculation

version 1.1:

- changed DefaultUnitAI and UnitAIs for UNIT_CAMP
- commented out pUnit.NotifyEntity(MissionTypes.MISSION_FOUND)

version 1.0:

- public release
 
uber pimp. Nice job, downloading now :thumbsup:

edit: I got a message saying I don't have permission.
 
Hmm, ok... I really don't get it. I tried adding it to my mod and I got all sorts of errors when I started it up. And an error every turn in the game.

The only changes I made were to get rid of the CustomCivilization folder (since my mod obviously doesn't need the Mongols and it was causing errors earlier since it refers to techs and leaders who don't exist) and adjusted MongolCamp.py so it wouldn't refer to units and civs that didn't exist (or so I thought):

Code:
        self.iHorseArcherID = CvUtil.findInfoTypeNum(gc.getUnitInfo, gc.getNumUnitInfos(), 'UNIT_HORSE_ARCHER')
        self.iKeshikID = CvUtil.findInfoTypeNum(gc.getUnitInfo, gc.getNumUnitInfos(), 'UNIT_KNIGHT')
        self.iArcherID = CvUtil.findInfoTypeNum(gc.getUnitInfo, gc.getNumUnitInfos(), 'UNIT_ARCHER')
        self.iCampID = CvUtil.findInfoTypeNum(gc.getUnitInfo, gc.getNumUnitInfos(), 'UNIT_CAMP')
        self.iTrebuchetID = CvUtil.findInfoTypeNum(gc.getUnitInfo, gc.getNumUnitInfos(), 'UNIT_MUSKETMAN')

        self.iTechEngineeringID = CvUtil.findInfoTypeNum(gc.getTechInfo,gc.getNumTechInfos(),'TECH_MILITARY_TRADITION')

        self.iPlains = CvUtil.findInfoTypeNum(gc.getTerrainInfo,gc.getNumTerrainInfos(),'TERRAIN_PLAINS')
        self.iDesert = CvUtil.findInfoTypeNum(gc.getTerrainInfo,gc.getNumTerrainInfos(),'TERRAIN_DESERT')
		self.iForest = CvUtil.findInfoTypeNum(gc.getFeatureInfo,gc.getNumFeatureInfos(),'FEATURE_FOREST')

        for iPlayer in range(gc.getMAX_PLAYERS()):
            player = gc.getPlayer(iPlayer)
            if (player.getCivilizationType() == gc.getInfoTypeForString('CIVILIZATION_SIOUX')):
                self.iMongolsID = iPlayer

I changed modular loading on my mod's .ini file to "1". and just put the Python folder and Modules folder into my Assets folder.

What did I do wrong and why doesn't it work?
 
What did I do wrong and why doesn't it work?

Very hard to tell if I can't have a look at the whole thing, but how about CIVILIZATION_SIOUX ? That's not a standard civ...

I have a question: can the AI use this?

No, the AI probably just thinks it's a settler. The only way to make the AI use this as a human would do, is to write a new UNITAI in SDK
 
If you give the "Camp" unit the default UnitAI:

Code:
<DefaultUnitAI>UNITAI_RESERVE</DefaultUnitAI>

then give it:

Code:
                        <UnitAIs>
				<UnitAI>
					<UnitAIType>UNITAI_RESERVE</UnitAIType>
					<bUnitAI>1</bUnitAI>
				</UnitAI>
				<UnitAI>
					<UnitAIType>UNITAI_COUNTER</UnitAIType>
					<bUnitAI>1</bUnitAI>
				</UnitAI>				
			</UnitAIs>

for its other UnitAI's, and it'll mostly keep it in the big group with the rest of the stack. I tried it out in my mod (converted it to the Sioux Camp), and ran AutoAI for about 100 turns and watched it. It did pretty good, not losing either of them (I gave it two), even during a war for over 40 turns.
 
Very hard to tell if I can't have a look at the whole thing, but how about CIVILIZATION_SIOUX ? That's not a standard civ...

The only things I did or changed were in my post. The Sioux are in my mod, and I loaded a game with them. I don't know what you mean by not standard...

I guess I'll just wait till Shiggs713 releases v .37 and use his modifications.

But I'm sure we'll have different visions for it, so I'd really like to understand how to adjust things in the Python without screwing everything up.
 
basically the only things you want to change in the python are the variables that it calls.

for example, in my mod the only parts I changed to make it work was;

Code:
def onGameStart(self, argsList):

        self.iHorseArcherID = CvUtil.findInfoTypeNum(gc.getUnitInfo, gc.getNumUnitInfos(), '[B]UNIT_SIOUX_MUSKETMAN[/B]')
        self.iKeshikID = CvUtil.findInfoTypeNum(gc.getUnitInfo, gc.getNumUnitInfos(), '[B]UNIT_SIOUX_RIFLEMAN[/B]')
        self.iArcherID = CvUtil.findInfoTypeNum(gc.getUnitInfo, gc.getNumUnitInfos(), '[B]UNIT_SIOUX_GRENADIER[/B]')
        self.iCampID = CvUtil.findInfoTypeNum(gc.getUnitInfo, gc.getNumUnitInfos(), 'UNIT_CAMP')
        self.iTrebuchetID = CvUtil.findInfoTypeNum(gc.getUnitInfo, gc.getNumUnitInfos(), '[B]UNIT_SIOUX_CUIRASSIER[/B]')

        self.iTechEngineeringID = CvUtil.findInfoTypeNum(gc.getTechInfo,gc.getNumTechInfos(),'[B]TECH_MILITARY_SCIENCE[/B]')

        self.iPlains = CvUtil.findInfoTypeNum(gc.getTerrainInfo,gc.getNumTerrainInfos(),'TERRAIN_PLAINS')
        self.iDesert = CvUtil.findInfoTypeNum(gc.getTerrainInfo,gc.getNumTerrainInfos(),'[B]TERRAIN_GRASSLANDS[/B]')
        self.iForest = CvUtil.findInfoTypeNum(gc.getFeatureInfo,gc.getNumFeatureInfos(),'FEATURE_FOREST')

        for iPlayer in range(gc.getMAX_PLAYERS()):
            player = gc.getPlayer(iPlayer)
            if (player.getCivilizationType() == gc.getInfoTypeForString('[B]CIVILIZATION_SIOUX[/B]')):
                self.iMongolsID = iPlayer

the way I have it now, grasslands gives the bonus that desert used to, and military science is required to be able to spawn the Cuirassier.

you might have to also remove the technology requirement of the other units (not the Cuirassier)
 
The only things I did or changed were in my post. The Sioux are in my mod, and I loaded a game with them. I don't know what you mean by not standard...

Standard as in from the default Firaxis civs. The Sioux is not one of those civs. CIVILIZATION_NATIVE_AMERICA for example is. As I don't know in what mod you are trying to merge it, I can't give any sensible comment.
 
basically the only things you want to change in the python are the variables that it calls.

for example, in my mod the only parts I changed to make it work was;

Code:
def onGameStart(self, argsList):

        self.iHorseArcherID = CvUtil.findInfoTypeNum(gc.getUnitInfo, gc.getNumUnitInfos(), '[B]UNIT_SIOUX_MUSKETMAN[/B]')
        self.iKeshikID = CvUtil.findInfoTypeNum(gc.getUnitInfo, gc.getNumUnitInfos(), '[B]UNIT_SIOUX_RIFLEMAN[/B]')
        self.iArcherID = CvUtil.findInfoTypeNum(gc.getUnitInfo, gc.getNumUnitInfos(), '[B]UNIT_SIOUX_GRENADIER[/B]')
        self.iCampID = CvUtil.findInfoTypeNum(gc.getUnitInfo, gc.getNumUnitInfos(), 'UNIT_CAMP')
        self.iTrebuchetID = CvUtil.findInfoTypeNum(gc.getUnitInfo, gc.getNumUnitInfos(), '[B]UNIT_SIOUX_CUIRASSIER[/B]')

        self.iTechEngineeringID = CvUtil.findInfoTypeNum(gc.getTechInfo,gc.getNumTechInfos(),'[B]TECH_MILITARY_SCIENCE[/B]')

        self.iPlains = CvUtil.findInfoTypeNum(gc.getTerrainInfo,gc.getNumTerrainInfos(),'TERRAIN_PLAINS')
        self.iDesert = CvUtil.findInfoTypeNum(gc.getTerrainInfo,gc.getNumTerrainInfos(),'[B]TERRAIN_GRASSLANDS[/B]')
        self.iForest = CvUtil.findInfoTypeNum(gc.getFeatureInfo,gc.getNumFeatureInfos(),'FEATURE_FOREST')

        for iPlayer in range(gc.getMAX_PLAYERS()):
            player = gc.getPlayer(iPlayer)
            if (player.getCivilizationType() == gc.getInfoTypeForString('[B]CIVILIZATION_SIOUX[/B]')):
                self.iMongolsID = iPlayer

the way I have it now, grasslands gives the bonus that desert used to, and military science is required to be able to spawn the Cuirassier.

you might have to also remove the technology requirement of the other units (not the Cuirassier)

Yea, that's exactly what I did. You can see my code above. Did you delete the Mongol civ from the module? Or did you keep it?
 
Shiggs713, nice idea about the UNITAI's. I hadn't thought about using that particular combination.

OzzyKP, deleting the modular Mongol civ shouldn't give any problems. I only added it to make the Mongols start with a camp instead of a settler. With Python you have to be careful to not mess up any of the tabs/spaces. Sometimes the problem is in that what you cannot see :scan:
 
I thought about that and I considered removing that particular piece of code. The problem is that when you loop through all units in a game to match if they are a camp, the script becomes very slow (I think).

It's definitely possible to modify the script to also check units for other civilizations or civilization with a certain trait (or anything else for that matter, like artstyle). It probably needs a more optimal way of scripting, but as this was my first piece of Civ Python, I tried to keep it small and simple.

Are you trying to use this in the American Civil War mod?

I made some minor changes and re-uploaded this mod. I have changed the UNITAI as per Shiggs137's suggestion and I have commented out the following on line 69

Code:
pUnit.NotifyEntity(MissionTypes.MISSION_FOUND)

This was causing the camp to repeat the founding animation every turn.
 
Excuse my complete lack of knowledge regarding Python, but how would I replace the civ requirement with a trait requirement? Like specifically, what code would I need?
Are you trying to use this in the American Civil War mod?

I"m using it in the Fractured States of America mod. It'll have a pretty big role. I've got 4 native tribes who will be depending on the camp heavily.

Also, is it possible to give units produced by the camp a certain promotion?
 
It's all possible, just needs writing and testing, which takes time. Off the top of my head in Civ Python you have a hasTrait() function for leaderheads and a promote() function for units.

I would suggest to try to use BTS events to accomplish what you want to achieve in your mod. With lack of knowledge about Python I tried to make this mod XML-only at first. The only real problem I encountered was that at least 1 city was required for events that gave free units. If you are willing to allow at least 1 city for each civ, you could implement your idea much easier.
 
Very nice job Fierabras. :) Glad to hear you changed the unitai's. I hope it works well enough. When I was watching it, it did not always have the camp in the large stack, but it usually did.... at one point when I stopped the autoAI, it had both camp units in a large stack with like 8 other defensive units!!! surprisingly good actually. :)

Obviously its still not as good as a player, but its acceptable.
 
Top Bottom