UnitAi questions

Calavente

Richard's voice
Joined
Jun 4, 2006
Messages
2,880
Location
France
I'm supposing that UnitAi meaning, and especially the way the AI shuffles through them, has been modified by Tholal.

So I have a question:
I found this, here:
Spoiler :
fulano said:
UNITAI_ANIMAL: Animal, explores and attacks, avoids culture
UNITAI_SETTLE: Settler, use this to create settlements
UNITAI_WORKER: Worker, use this to improve terrain
UNITAI_ATTACK: Use this to attack other units
UNITAI_ATTACK_CITY: Use this to attack cities
UNITAI_COLLATERAL: Use this to cause collateral to wear down stronger units
UNITAI_PILLAGE: Use this to destroy improvements
UNITAI_RESERVE: Build this unit when nothing else is immediately needed (build lots of them)
UNITAI_COUNTER: Use this unit to protect against specific units
UNITAI_PARADROP: This unit can paradrop (when does the AI use this?)
UNITAI_CITY_DEFENSE: Use this to defend cities
UNITAI_CITY_COUNTER: Units with bonuses against others that are to defend cities.
UNITAI_CITY_SPECIAL: Leave this unit in cities (like machine guns)
UNITAI_EXPLORE: Use this for exploring
UNITAI_MISSIONARY: Used to spread religion
UNITAI_ATTACK_AIR: Air unit used for attacking
UNITAI_DEFENSE_AIR: Air unit for defending against air units
UNITAI_CARRIER_AIR: Use to fill carriers
UNITAI_MISSILE_AIR: AI for missiles
UNITAI_ATTACK_CITY_LEMMING: Use to attack cities, ignoring combat odds. (Used for barbarian revolt events)
UNITAI_ICBM: Use for nukes
UNITAI_SPY: Use as a spy.


UNITAI_ATTACK: General purpose; unit prioritizes joining an attack stack, but also may wander off on search and destroy/explore, sit in a city and defend it, etc.
UNITAI_ATTACK_CITY: Join an attack stack -> If in an attack stack, lead assault on a city once the AI decides the stack should attack a city
UNITAI_COLLATERAL: Similar to UNITAI_ATTACK_CITY, but may also attack enemy stacks in the field
UNITAI_PILLAGE: Causes unit to wander off by itself into enemy territory and pillage stuff
UNITAI_RESERVE: Primary use - Floating defenders to shuffle around between threatened cities. Also is a priority UNITAI type for the AI to change if it needs units of another type (the AI will frequently change reserve units to attack units once it starts warplans, for instance)
UNITAI_COUNTER: Join an attack stack -> if in stack may leave stack to attack adjacent tiles with enemy units
UNITAI_CITY_COUNTER: Same as UNITAI_COUNTER, but for cities instead of stacks
UNITAI_PARADROP: Hold in reserve and drop into enemy territory; very similar to UNITAI_PILLAGE, except units drop deep into enemy territory
UNITAI_CITY_DEFENSE: Defend a city, never leave the city
UNITAI_CITY_SPECIAL: Basically the same as UNITAI_CITY_DEFENSE, except the AI deprioritizes this type if a city already has a defender of this AI type, meaning that the AI in unmodded BtS, the AI only ever builds a single machine gun in it's cities
UNITAI_EXPLORE: Wander around prioritizing terrain that hasn't been revealed until unit is killed
UNITAI_ATTACK_AIR: Air Unit used for bombing
UNITAI_CARRIER_AIR: Similar to UNITAI_ATTACK_AIR, but prioritizes filling up carriers
UNITAI_ATTACK_CITY_LEMMING: beeline enemy cities and Suicide against enemy units
UNITAI_ICBM: Hold unit, and then launch when at war
UNITAI_SPY: Basic spy AI (prioritize going into enemy territory and running spy missions - In base BtS this is purely random, with the spys basically wandering around and rolling dice, in BBAI the spys prioritize high value missions and improvements)
UNITAI_WORKER_SEA: Build sea improvement, if none is available explore
UNITAI_ATTACK_SEA: Basic sea AI, wander around the oceans in search and destroy mode, join a stack, etc
UNITAI_RESERVE_SEA: Similar to UNITAI_RESERVE except for sea units
UNITAI_ESCORT_SEA: Join a stack
UNITAI_EXPLORE_SEA: Wander around the oceans prioritizing moving into unexplored territory until unit dies
UNITAI_ASSAULT_SEA: Transport land units for sea assault, launch when a sufficient assault stack is ready; forms core of water domain stacks
UNITAI_SETTLER_SEA: Ferry settlers and workers over water tiles
UNITAI_MISSIONARY_SEA: Ferry missionaries over water tiles
UNITAI_SPY_SEA: Ferry spys over water tiles
UNITAI_CARRIER_SEA: Be a mobile air base for UNITAI_CARRIER_AIR units
UNITAI_MISSILE_CARRIER_SEA: similar to UNITAI_CARRIER_SEA but for missiles
UNITAI_PIRATE_SEA: Wander around pointlessly, sometimes run a blockade if the die roll tells you to and you are in enemy territory
is it still true ?
When does the AI change from the default unitAI to another one ?
What is the impact of having an unitAI on board ?
Is there a way to add an unitAI when a promotion is given ?
(like melee sucks against archer, but with coverI-III it becomes a good counter unit.... does the AI knows to use the unitAI_counter in that case only ?)

I moded that archers get -25% city attackn but flaming arrows give +35% for a total of +10%. ARchers become then 5str 10%CA, 15%withdrawal : better than unpromoted bronze axeman.
I want the AI to use those flaming arrows archers to attack cities..
But I don't want the AI to think archers without flaming arrows are useful against cities.

should I put UnitAI_Attack_City on archers ?

If I do it, will the AI think that it can plan a city attack with only archers ? (which don't have yet flaming arrows) ?? if yes it is a big NOGO.

is there a way that this UnitAI_Attack_City tag is only available to units with flaming arrows ?
So the AI will not plan to tech to flaming arrows archers when it plans to attack cities, but IF/WHEN it get flaming arrows archers, it will not hesitate to get them into cityattack stacks.

etc.

thanks in advance...
 
thx.. I'll wait for the long answer.

but if it is how you say... why do each unitClass have multiple UnitAI_ on top of the <DefaultUnitAI> ?
 
but can the AI assigne UnitAI functions different than the default one ?
 
found my answer at the last post of this archived thread
phungus420 said:
If a human builds a unit, it always gets the default AI type (which causes much havoc when enabling AI autoplay). For the AI on the other hand it decides a UNITAI type it wants, then builds a unit that can use that type. Sometimes the AI can even assign a UNITAI type that's not specified for the unit (assuming it's not in the notUnitAItype field), but that's rare, which is why you never see MG's because they are basically only built as UNITAI_CITY_DEFENSE_SPECIAL a position the AI only tries to fill once per city.
so it seems that if I allow unitAI_attack_city to archers, occasionnaly the AI might send some archer-only stack to attack cities, disregarding the presence or absence of the -25%cityattack.
 
When a city decides to build a unit, it first starts with a UNITAI type (ie, the city AI decides it needs defense, so it says, I need a unit with UNITAI_CITY_DEFENSE). Then it looks through all the available units it can build, sorts out the ones who are allowed to have that UNITAI type and then values each unit for the job based on what it knows from the UnitInfos.xml file

The AI will switch the UNITAI type on a unit if it upgrades into another unit that does not allowed to have the current UNITAI (for example, a Doviello Worker upgrades into a Beastman). It will also sometimes switch a unit to UNITAI_CITY_DEFENSE when it conquers a city and needs someone to defend. There are a few other special cases, but for the most part, once a unit is built and assigned an initial AI type, it keeps that AI for the rest of its existence.

A modder can manually switch a unit's AI Type via python simply using the setUnitAIType() function (there are a number of examples already in the python code).

Most of what that list of UNITAI types and their function states is correct, though UNITAI_PIRATE_SEA does go do Pirate stuff, and many of those others are never used in FFH.

Sephi added the concept of Groupflags. As far as I can tell, the main purpose of Groupflags is to allow units of different AI types to act together. These are used mainly for ATTACK_CITY groups (CONQUEST) and ATTACK groups (PATROL).

Archers are already allowed to be built as UNITAI_ATTACK_CITY.

There is no onPromote() call for python (though MagisterCultuum did make a request for this feature sometime back. (edit: actually, there is an onUnitPromoted function in python. Perhaps its not working? Worth trying it anyway)
 
how would I access this "onUnitPromoted" function??
should there be an xmlTAG referring to that function and I just add something in the xml ?
or should I dabble in python and code the use of the function ?
and which "file" should I open to find it ?
 
The function def onUnitPromoted(self, argsList): is found in CvEventManager.py.

It is called when a unit levels up by purchasing a promotion using xp.

It is not called when the unit is given the promotion through python, when the unit is granted a free promotion from a building, when the unit it starts with a promotion from its XML defines, or when a unit is upgraded and the new unit is given the promotions and other data from its previous form.

My feature request was for a function that would be called when promotions are applied those ways too.



I use the existing function oin the last several versions of my modmod.

One of my uses for it is settings units that purchase Nature II to have UNITAI_TERRAFORMER, so that the AI will make use of the Bloom spell.

I also use it to give free mana and unique feature mased promotions for units that purchase the Unholy Taint and Pilgrim promotions.

All of the things are also handled in the code that initializes units which start with those promotions.
 
Looks like the python call for onUnitPromoted is accessed via the promote() function in the DLL. Calling setHasPromotion() bypasses this. Try using the promote() function instead and see if that works.

void promote(int /*PromotionTypes*/ ePromotion, int iLeaderUnitId);
 
Using pUnit.promote(iPromotion, iLeaderUnitID) does nothing whatsoever if the pUnit.canPromote(iPromotion, iLeaderUnitID) returns false, which it always is when the unit cannot purchase the promotion the normal way.
 
well, I was wondering about going in a roundabout way :

creating a "double" longbow unit
same stat as longbow, but with flaming arrows promotion
cost 150 instead of 120
available with bowyer and sorcery (when you get mages)
needs enchantement mana
needs archery range (bowyer?) and alchemist lab

(is there a tag so that AI doesn't need building requirements only for this unit)?

then, longbows are not allowed unitAI_attack_city.
enchanted longows are given unitAI_attack_city as default unitAI.

thus:
-AI will not use longbows without firearrows in city attack stacks
-AI will build stacks of longbows WITH firearrows for attacking cities.
:D

2 issues:
-how to get the building requirements only work for player...?
-it will create a double unit in the building list.. :(
 
Just trigger the onUnitPromoted function manually when setHasPromotion is used and you are done.
At least for the python part, the others free from XML will still not be available though.

Code:
	def onUnitBuilt(self, argsList):
		'Unit Completed'
		city = argsList[0]
		unit = argsList[1]
##
		iPromotion = gc.getInfoTypeForString("PROMOTION_MARCH")
		unit.setHasPromotion(iPromotion, True)
		self.onUnitPromoted([unit, iPromotion])
##

Of course, if it is done outside of CvEventManager, import it.

You will notice the same problem with setHasTech, setNumRealBuildings which is why I never use those functions, except in WB.
 
That would cover many cases, but not those where triggering onUnitPromoted might be most desirable.

It would not apply to the various XML-only spells in FfH2 which grant promotions either to the caster, to the qualifying units in the caster's stack, or to a unit which the caster is summoning. It would not apply to summons which are given promotions as perks from their summoner's promotions.

(Obviously these would not be an issue except in FfH2 and derived modmods, so it is understandable that a modder who works off of the vanilla game would overlook it.)

It would also not apply when a unit is upgraded and the newly initialized unit is passed the promotions from its previous form.
 
You can further eliminate those problems by doing the same thing onUnitCreated, which will solve those free promotions granted via Traits, Buildings or even those summoned units which I assume will be created using python initUnit function.

Upgrading of units though cannot be solved this way, because it does trigger onUnitCreated, but there is nothing you can do to change the unit itself.
 
XML-only spells do not use any python.

While a few spells do manually initiate summons through python, most of them create such units directly in C++.

A few spells a tag like <CreateUnitPromotion>PROMOTION_ENRAGED</CreateUnitPromotion>, which tells the DLL that it should give the newly summoned unit PROMOTION_ENRAGED directly in C++.

Some promotions also have tags like <PromotionSummonPerk>PROMOTION_ILLUSION</PromotionSummonPerk>, which tells the DLL that it should use C++ to grant the promotion found within that tag to any unit summoned by a caster that has the promotion with that tag.


I actually misread onUnitBuilt as onUnitCreated when you first suggested it, as that made more sense to me.

I am well aware that upgrading units involves triggering onUnitCreated when the upgrade form is created, but before the promotions or any other date from the old unit is passed on to the new.


There are of course also some issues if someone tried use your method and import CvEventManager in a file like ScenarioFunction.py, which is imported by CvEventManager.py.
 
1) well unit AI alternatives doesn't really seems to have any effect at the moment, as I've not yet seen flaming arrows longbow in attack stacks...

2) Question : is there a way to make a promotion have a duration of 2 turns ? (how did the former "blinding light" work ?)

/regards
 
Back
Top Bottom