The 3rd Age

Gladiator Heroes

Gladiator Heroes

6 heroes are remade with powerful new spells

Button for The 3rd AgeButton for The Dwarf HoldsButton for The Elven AllianceButton for Helm's Deep Last HopeButton for GothmogtheOrcButton for BFME+Button for The Four AgesButton for HDR HeadquartersButton for Middle Earth CenterButton for Project Perfect Mod

Become an affiliate!

   

Quick Lists

Top Rated Popular New Updated Last Comments Users

Register and log in to move these advertisements down

In-depth AI Coding

Avatar of Sulherokhh

Sulherokhh

Category: Code
Level: Expert
Created: Wednesday October 3, 2007 - 8:28
Updated: Friday August 27, 2010 - 21:26
Views: 21648
Summary: The beginning of a comprehensive guide to AI-modding for BfME2

Rating

Staff says

4.8

Members say

4.9

Average

4.9/5.0

20 votes

Page 1 2 3 4 5 6 7 8 9 10 11
B4. Practical Use of 'AutoAbilityBehavior' for the AI controlled unit.

Now, here is one example, using Faramir, to show how the 'AutoAbilityBehavior' (from A1) can be put to use for an AI controlled unit (from B1), without forcing the human player controlling this unit to also be subject to the auto-triggering traits of this module.

EXAMPLE:

The 'usual' code to be used when you want a unit like a hero to use it's special powers is the 'AISpecialPowerUpdate'. The following piece is simple yet limiting.
              
Code
Behavior = AISpecialPowerUpdate SpecialWoundingArrow
    CommandButtonName = Command_SpecialAbilityWoundArrow
    SpecialPowerAIType = AI_SPECIAL_POWER_ENEMY_TYPE_KILLER
End

The problem with this is the fact the rather 'wild' AI uses this at the most inopportune times, like when mounted or with a sword in hand. There are obviously no animations going to play when mounted, and you don't want the AI to use stuff that the unit should not be allowed to use.
So we better use something (the 'AutoAbilityBehavior') to make the AI conform to all the usual limitations. The way to achieve this is to duplicate the power involved, but make it only available to the AI, while removing the AI's ability to use the normal power.

Step 1: The SpecialPower
- First, we need a carbon copy of this power:
              
Code
SpecialPower SpecialAbilityWoundArrow
    Enum = SPECIAL_WOUND_ARROW
    ReloadTime = 30000 ; in milliseconds
    InitiateAtLocationSound = GenericSpell
    ObjectFilter = ALL -STRUCTURE -BASE_FOUNDATION -INERT -IGNORED_IN_GUI -WALK_ON_TOP_OF_WALL -BLOCKING_GATE -WALL_UPGRADE -UNATTACKABLE -MOVE_ONLY
End

- it will look like this (identical except for the name):
              
Code
SpecialPower SpecialAbilityWoundArrow_AI
    Enum = SPECIAL_WOUND_ARROW
    ReloadTime = 30000 ; in milliseconds
    InitiateAtLocationSound = GenericSpell
    ObjectFilter = ALL -STRUCTURE -BASE_FOUNDATION -INERT -IGNORED_IN_GUI -WALK_ON_TOP_OF_WALL -BLOCKING_GATE -WALL_UPGRADE -UNATTACKABLE -MOVE_ONLY
End


Step 2: The Ability Code
- Next we adjust the following (original) code ...
              
Code
Behavior = UnpauseSpecialPowerUpgrade ModuleTag_UnpauseWoundArrow
    SpecialPowerTemplate = SpecialAbilityWoundArrow
    TriggeredBy = Upgrade_ObjectLevel2
End
Behavior = SpecialPowerModule ModuleTag_WoundArrow
    SpecialPowerTemplate = SpecialAbilityWoundArrow
    UpdateModuleStartsAttack    = Yes
    InitiateSound = FaramirRangerVoiceWoundingArrow
    StartsPaused = Yes
End
Behavior = WeaponFireSpecialAbilityUpdate ModuleTag_WoundArrowUpdate
    SpecialPowerTemplate = SpecialAbilityWoundArrow
    SkipContinue = Yes
    UnpackTime = 2000
    PreparationTime = 1
    PersistentPrepTime = 1000
    PackTime = 1
    AwardXPForTriggering = 0
    StartAbilityRange = #SUBTRACT( FARAMIR_WOUNDING_ARROW_RANGE 25 )
    ApproachRequiresLOS = Yes
    SpecialWeapon = FaramirWoundArrow
    WhichSpecialWeapon = 1
End
Behavior = AutoAbilityBehavior ModuleTag_WoundArrowAutoAbility
    SpecialAbility = SpecialAbilityWoundArrow
    MaxScanRange = #SUBTRACT( FARAMIR_WOUNDING_ARROW_RANGE 25 )
    Query = 1 ALL ENEMIES -STRUCTURE
End

... by making it unavailable to the AI:
              
Code
Behavior = UnpauseSpecialPowerUpgrade ModuleTag_UnpauseWoundArrow
    SpecialPowerTemplate = SpecialAbilityWoundArrow
    TriggeredBy = Upgrade_ObjectLevel2
    ConflictsWith    = Upgrade_ObjectUnderAIControl
End
...


The AI will use a new set of behaviors, identical but for the name of the SpecialPower used and with unique tags and a unique trigger:
              
Code
Behavior = UnpauseSpecialPowerUpgrade ModuleTag_UnpauseWoundArrow_AI
    SpecialPowerTemplate = SpecialAbilityWoundArrow_AI
    TriggeredBy = Upgrade_ObjectLevel2 Upgrade_ObjectUnderAIControl
    RequiresAllTriggers = Yes
End
Behavior = SpecialPowerModule ModuleTag_WoundArrow_AI
    SpecialPowerTemplate = SpecialAbilityWoundArrow_AI
    UpdateModuleStartsAttack = Yes
    InitiateSound = FaramirRangerVoiceWoundingArrow
    StartsPaused = Yes
End
Behavior = WeaponFireSpecialAbilityUpdate ModuleTag_WoundArrowUpdate_AI
    SpecialPowerTemplate = SpecialAbilityWoundArrow_AI
    SkipContinue = Yes
    UnpackTime = 2000
    PreparationTime = 1
    PersistentPrepTime = 1000
    PackTime = 1
    AwardXPForTriggering = 0
    StartAbilityRange = #SUBTRACT( FARAMIR_WOUNDING_ARROW_RANGE 25 )
    ApproachRequiresLOS = Yes
    SpecialWeapon = FaramirWoundArrow
    WhichSpecialWeapon = 1
End
Behavior = AutoAbilityBehavior ModuleTag_WoundArrowAutoAbility_AI
    SpecialAbility = SpecialAbilityWoundArrow_AI
    StartsActive = Yes
    MaxScanRange = #SUBTRACT( FARAMIR_WOUNDING_ARROW_RANGE 25 )
    Query = 1 ANY +HERO +MONSTER +BIG_MONSTER ENEMIES
End

The differences are ...
              
Code
Behavior = UnpauseSpecialPowerUpgrade ModuleTag_UnpauseWoundArrow_AI
    SpecialPowerTemplate = SpecialAbilityWoundArrow_AI
    TriggeredBy = Upgrade_ObjectLevel2 Upgrade_ObjectUnderAIControl
    RequiresAllTriggers = Yes
End
...

... and ...
              
Code
...
Behavior = AutoAbilityBehavior ModuleTag_WoundArrowAutoAbility_AI
    SpecialAbility = SpecialAbilityWoundArrow_AI
    StartsActive = Yes
    MaxScanRange = #SUBTRACT( FARAMIR_WOUNDING_ARROW_RANGE 25 )
    Query = 1 ANY +HERO +MONSTER +BIG_MONSTER ENEMIES
End


The module 'AutoAbilityBehavior' is much more flexible when it comes to target acquisition. What i would like Faramir to do is use this power only on heroes and monster.
So i changed the query line to something i liked better. But you can insert any KindOf you can think of

Okay. So, even though the module 'AutoAbilityBehavior' references a SpecialPower, it actually runs from a CommandButton and is thus subject to all the CommandButton's restrictions and limitations (see below).
Since we are using a new SpecialPower, the AI-only ability will need it's own CommandButton. I made one for you:
              
Code
CommandButton Command_SpecialAbilityWoundArrow_AI
    Command = SPECIAL_POWER
    WeaponSlot = SECONDARY
    SpecialPower = SpecialAbilityWoundArrow_AI
    Options = NEED_TARGET_ENEMY_OBJECT UNMOUNTED_ONLY
    TextLabel = CONTROLBAR:WoundingArrow
    ButtonImage = HSFaramirWoundingArrow
    CursorName = Bombard
    InvalidCursorName = GenericInvalid
    ButtonBorderType = ACTION
    DescriptLabel = CONTROLBAR:ToolTipWoundingArrow
    InPalantir = Yes
    AutoAbility = Yes
    DisableOnModelCondition = WEAPONSET_TOGGLE_1 ;disable if currently using sword
End

The line 'AutoAbility = Yes' is obviously of vital importance for the AutoAbilityBehavior to work at all. So remember to add it if you are duplicating CommandButtons that originally didn't have it!

Now the new CommandButton needs to be added to his CommandSet, like this:
              
Code
CommandSet GondorFaramirCommandSet
    1 = Command_ToggleStance
    2 = Command_ToggleFaramirWeapon
    3 = Command_SpecialAbilityWoundArrow
    4 = Command_ToggleMounted
    5 = Command_FaramirFakeLeadershipButton
    6 = Command_SpecialAbilityCaptainOfGondor
    7 = Command_SpecialAbilityWoundArrow_AI
    12 = Command_CaptureBuilding
    13 = Command_AttackMove
    14 = Command_Stop
End

Yes, it will be invisible to the player.
One important sidenote. As already noted on previous pages, a unit may have several CommandSets, for being mounted, for having a certain upgrade, etc. just to be save that the behavior 'grips'. The new button should be present on ALL OF THEM!
The human player cannot use it anyway (they are missing the AI-upgrade), and the AI can't use it when it is not suitable anyway, because of the CommandButton's limitations (aye, they work now!):
              
Code
...
Options = NEED_TARGET_ENEMY_OBJECT UNMOUNTED_ONLY
...
DisableOnModelCondition = WEAPONSET_TOGGLE_1 ;disable if currently using sword



Thank you for reading this far. This concludes the lesson for today.
More is to come about creating different AI strategies and an in-depth look in how the AI prioritizes it's spending of cash.
Good day!

Sûlherokhh.
-------------------------------------------------------------------------------------------------------------------------------------------------------------------

Comments

Display order: Newest first | Page: 1, 2

Prolong - Thursday July 29, 2010 - 11:21

Very nice guide, even though it never got finished there is still a ton of great information here.

Elrond99 - Sunday February 15, 2009 - 8:52

Thanks for updating the Tutorial
It´s great to hear that it´s possible to make a new AI from scratch

Can´t wait for section F, custom AI scripts, that sounds really interesting
Especially since I know D and E already ;)

Sulherokhh (Team Chamber Member) - Saturday February 14, 2009 - 22:19

After 'D. The Faction Base and Fortress', i guess.
If you are asking for a date, you are asking the wrong guy. I don't have one. I work on modding related stuff mostly when i find the time and the mood strikes me. It's supposed to be fun, right? :)

Edit: But i might do it before the fortress and base setup. Depends on, well, which kind of work is going to be most interesting to me at the time. Scripts should be easier to do then the Basebuilding stuff, but a bit more to write as well, at least if i am going to do it right. I am starting to ramble... :O

jakonic - Saturday February 14, 2009 - 13:05

when will be finished Spell Purchase Scripts???please answer

Sulherokhh (Team Chamber Member) - Thursday November 29, 2007 - 18:26

I sure will...

Edit: Do you have any particular requests? If i have done it already, it shouldn't be hard to post a solution here. If it's not, chances are that i was going to look into it anyway. Except for the general skirmishsetup and bases, since those will require extesive explanations which i was planning to do anyway when i find the time.

So shoot! :)

Rob38 (Team Chamber Member) - Thursday November 29, 2007 - 12:00

This is by far one of my favorite tutorials on T3A! Please continue to add more :)

Sulherokhh (Team Chamber Member) - Thursday October 4, 2007 - 1:07

I am glad you can put it to use, Rob! Your feedback means a lot to me. :D

Rob38 (Team Chamber Member) - Thursday October 4, 2007 - 0:27

Amazing! I also found a way to recognize if a player is controlled by the AI, but this looks to be a much easier method to use. Thank you for all your wonderful knowledge as there is some really cool stuff in here.

Sulherokhh (Team Chamber Member) - Wednesday October 3, 2007 - 21:18

I'll split it up. Let's see what would be a good way. - Edit: Done. I hope you like it.

Crashdoc - Wednesday October 3, 2007 - 18:48

Nice findings and interesting ways to use them. Thanks for sharing the knowledge!

Go to top

 

"One site to rule them all, one site to find them,
one site to host them all, and on the network bind them."

 
22:40:15