• Welcome to Freedom Reborn Archive.
 

Making custom AI's target Buildings

Started by vortex, October 21, 2007, 06:25:15 PM

Previous topic - Next topic

vortex

How do you make a Custom AI target buildings in FF?  I've tried this for a ranged explosive:  "TRangedExplosive('dr missiles',energy=50,pct=80,time=4,subtype='building')", but it doesn't seem to work.  I also have a Special Targets entry set for 'building'.  The attack works on normal targets when I delete the subtype, so I don't think there's anything else wrong with it.

Thanks!

TaskMasterX

Try adding type='any' to the Tactic line.

Like so:
"TRangedExplosive('dr missiles',energy=50,pct=80,time=4,type='any',subtype='building')",

vortex

Hmmm!  No dice, TaskMasterX!  :(

Closest thing I can think of to simulating this is making it a DisruptObject Tactic.  This doesn't target buildings, however.  If you think of anything else, let me know!


GGiant

Maybe you change  building to game_obj_building?
Actually, I don't know anything about this? :banghead:

M25

If you are using the custom AI for the original  :ff:, I don't think it can target buildings.

You have to use an in-game AI that targets buildings (like the mechman), and then add custom AI to it.


vortex

Quote from: M25 on October 23, 2007, 08:50:37 AM
If you are using the custom AI for the original  :ff:, I don't think it can target buildings.

Yeah, I think you may be right, M25!  I've tried several different things (including yours GGiant, thanks!) to no avail.  The Mr. Mechanical and Mechman AI's don't seem to have any interest in wholesale distruction in the Danger Room for FF, either.  <_<

GGiant

Quote from: vortex on October 23, 2007, 07:20:32 PM
The Mr. Mechanical and Mechman AI's don't seem to have any interest in wholesale distruction in the Danger Room for FF, either.  <_<
What? :blink:
I've tried this and they destroyed some buildings in the danger room.

TaskMasterX

Sorry, I thought you were talking about :ffvstr:. Using the Built-In AI as M25 suggested should work. I made the Custom AI (available at my site or Yahoo! Group) for  :ff: and the Wrecking Crew have the Mr Mechanical and MechRobot AIs and they attack buildings. Also, I have the ManBull AI for Abomination and that particular AI will attack buildings if the target is on top of a building to bring them down. Try that AI, too to see what happens.

M25

Remember that powers have to be in certain slots in each power tier before the built-in AI will use them.  Look at the mechman character to see how its powers are set up.


vortex

Yes, I'm aware of that M25 (Thanks!  ;) ).  After playing around with it a little bit, I did notice that the character with the MechMan AI does attack buildings, but it is very infrequently!  I had to use several of them in the Danger Room to notice one of them attacking a building briefly.  Some of the other AI's I've been trying don't seem to work so well, either!  For example, one character has a ranged attack in the first slot.  Neither CAlienSergeant nor CSilverBacchite seem to exhibit any sort of desire to flee melee situations (character does have flight).  As far as the description in the AIs.doc goes, the only requirement is that a ranged attack be in the first slot! 

I've tried a number of possible things - there's no 'M25AI only' line in the m25newaidata2 file, I've even went so far as erasing the entire script I wrote to see if the AI would work on it's own.  Other things I've tried are:  checking and unchecking the 'Campaign Only' box in FFEdit, switching between game_obj_minion, villain, and hero, checked for spacing at the end of the name in the 'Powers' tab, I run FFXControlCentre after making any changes, too.

Today, I even put a few Bacchites and Alien Sergeants through the Danger Room.  Even they didn't act like themselves!



M25

Hmmm.  Make sure the Alien Sergeant and bacchites don't have entries in the m25newaidata2 file (they shouldn't).

You may also need to run the ffx control centre to make sure the characters are branded correctly.

I believe the mechman AI attacks buildings when it doesn't have any enemy targets nearby.


vortex

I've figured out the basic problem that the MechMan AI has been giving me.  When I was trying it before, There were several opponents in the Danger Room along with a few of those with the AI.  What was happening, I beleive, is that those with the AI were being targeted from across the map and therefore went over to see what was attacking them and take retaliotory action.  When I tried this time with only one powerful opponent and several of those with the AI, only a couple of them attacked the foe, while the others went after the building.

As far as the bacchites and aliens, the problem I am having - which I'm beginning to notice with my custom AI's as well, is that although they initiate all offensive powers per their script, when it comes to them taking evasive actions or using Active Defenses as they should, however, no dice.

M25

Are you getting any errors in the script.log?

The defensive abilities for the custom AI in  :ff: were/are a bit flaky as it relies on an in game event that doesn't always trigger.  However, you should be seeing some use of defensive abilities.


Metherian

Quotethe problem I am having - which I'm beginning to notice with my custom AI's as well, is that although they initiate all offensive powers per their script, when it comes to them taking evasive actions or using Active Defenses as they should, however, no dice.

It sounds like you need to add some defensive AI options to whatever it is you're using (and better targeting options, for the building attack problems).  I haven't used the game's default AI options since before the first set of mod tools were made available for the original FF, so I can't say what the "mechman" AI does or doesn't do.  (Paired recursive scripting is your friend.)  I am assuming you're using Python in some capacity to modify the AI's basic attack/defense patterns.

Depending on how you're enhancing the AI, you may be able to add some defensive behavior.  I only use fully-scripted AI that I build "from scratch", which gives me complete control over the behavior of every character object.  The games' default AI's, while simple to implement, are really only reliable in one regard:  they always "get in the way" and make modding more frustrating than it needs to be.   Thus, I don't use them.

Can you modify your Python scripts, and add in specific defensive behavior?  Or, are you just randomly triggering powers?  In either case, you should be able to set up some basic defensive evaluation tests for the characters, based on enemy proximity, power use, current health, etc.   Unless I'm just missing something; I've been 'out of the loop' for a few years, so I may be way off base here.  lol


vortex

Here's what my script.log looks like in a DR scenario in which I faced villains who use the CThugGun AI against some bat thugs. 
[spoiler]>>> system/init.py executed
>>> system\tredir.py executed
importing customhelper.py
using standard custom settings
using standard puppet settings
using standard ffx ID list
using standard builtins list
using standard extra code
using standard fx lists
using standard transmutation lists
using standard custom settings
using standard puppet settings
using standard ffx ID list
using standard builtins list
using standard extra code
using standard fx lists
using standard transmutes lists
using standard voice ID traits list
using standard multiple attribute sets
using standard AI character data
using standard AI configuration data
using standard object list
>>> C:\Program Files\Irrational Games\Freedom Force\data\temp\Skirmish Watch Mode.py executed
>>> C:\Program Files\Irrational Games\Freedom Force\data\temp\Skirmish Watch Mode.py executed
>>> OnReceiveSelectedEnemies(('oconnor', 'sukhov', 'pin_stripe', 'cop_crooked', '------------', 'thug_with_bat', 'thug_with_bat', 'thug_with_bat', 'thug_with_bat', 'thug_with_bat', 'thug_with_bat', 'thug_with_bat', 'thug_with_bat', ))
initialising FFX: skirmish=1
SetupAI:oconnor_1_1
addFFXTactics:oconnor_1_1
['oconnor', ['timer', 4]]
oconnor_1_1 has no random start markers defined.
SetupAI:pin_stripe_2_3
addFFXTactics:pin_stripe_2_3
['pin_stripe', ['timer', 4]]
remedy for pin_stripe_2_3 1.0
pin_stripe_2_3 has no random start markers defined.
SetupAI:sukhov_21_2
addFFXTactics:sukhov_21_2
['sukhov', ['timer', 4]]
sukhov_21_2 has no random start markers defined.
SetupAI:cop_crooked_22_4
addFFXTactics:cop_crooked_22_4
['cop_crooked', ['timer', 4]]
cop_crooked_22_4 has no random start markers defined.
SetupAI:thug_with_bat_14_7
addFFXTactics:thug_with_bat_14_7
['thug_with_bat', ['timer', 4]]
thug_with_bat_14_7 has no random start markers defined.
SetupAI:------------_3_5
addFFXTactics:------------_3_5
['------------', ['timer', 4]]
------------_3_5 has no random start markers defined.
SetupAI:thug_with_bat_10_6
addFFXTactics:thug_with_bat_10_6
['thug_with_bat', ['timer', 4]]
thug_with_bat_10_6 has no random start markers defined.
SetupAI:thug_with_bat_16_8
addFFXTactics:thug_with_bat_16_8
['thug_with_bat', ['timer', 4]]
thug_with_bat_16_8 has no random start markers defined.
SetupAI:thug_with_bat_4_9
addFFXTactics:thug_with_bat_4_9
['thug_with_bat', ['timer', 4]]
thug_with_bat_4_9 has no random start markers defined.
SetupAI:thug_with_bat_5_10
addFFXTactics:thug_with_bat_5_10
['thug_with_bat', ['timer', 4]]
thug_with_bat_5_10 has no random start markers defined.
SetupAI:thug_with_bat_17_11
addFFXTactics:thug_with_bat_17_11
['thug_with_bat', ['timer', 4]]
thug_with_bat_17_11 has no random start markers defined.
SetupAI:thug_with_bat_6_12
addFFXTactics:thug_with_bat_6_12
['thug_with_bat', ['timer', 4]]
thug_with_bat_6_12 has no random start markers defined.
SetupAI:thug_with_bat_7_13
addFFXTactics:thug_with_bat_7_13
['thug_with_bat', ['timer', 4]]
thug_with_bat_7_13 has no random start markers defined.
hero_0 has no random start markers defined.
SetupAI:ffxtarget
addFFXTactics:ffxtarget
['ffx_tiggot', ['timer', 4]]
ffxtarget has no random start markers defined.
SetupAI:ffxgun
addFFXTactics:ffxgun
['ffx_tiggot', ['timer', 4]]
ffxgun has no random start markers defined.
initialising FFQ_initialiseExtras()
setting default sun
initCarriers on oconnor_1_1(oconnor)
oconnor
determining gender oconnor_1_1 (team=1)
initCarriers on pin_stripe_2_3(pin_stripe)
pin_stripe
determining gender pin_stripe_2_3 (team=1)
initCarriers on sukhov_21_2(sukhov)
sukhov
determining gender sukhov_21_2 (team=1)
initCarriers on cop_crooked_22_4(cop_crooked)
cop_crooked
determining gender cop_crooked_22_4 (team=1)
initCarriers on thug_with_bat_14_7(thug_with_bat)
thug_with_bat
determining gender thug_with_bat_14_7 (team=2)
M25 evil!
initCarriers on ------------_3_5(------------)
------------
determining gender ------------_3_5 (team=0)
initCarriers on thug_with_bat_10_6(thug_with_bat)
thug_with_bat
determining gender thug_with_bat_10_6 (team=2)
M25 evil!
initCarriers on thug_with_bat_16_8(thug_with_bat)
thug_with_bat
determining gender thug_with_bat_16_8 (team=2)
M25 evil!
initCarriers on thug_with_bat_4_9(thug_with_bat)
thug_with_bat
determining gender thug_with_bat_4_9 (team=2)
M25 evil!
initCarriers on thug_with_bat_5_10(thug_with_bat)
thug_with_bat
determining gender thug_with_bat_5_10 (team=2)
M25 evil!
initCarriers on thug_with_bat_17_11(thug_with_bat)
thug_with_bat
determining gender thug_with_bat_17_11 (team=2)
M25 evil!
initCarriers on thug_with_bat_6_12(thug_with_bat)
thug_with_bat
determining gender thug_with_bat_6_12 (team=2)
M25 evil!
initCarriers on thug_with_bat_7_13(thug_with_bat)
thug_with_bat
determining gender thug_with_bat_7_13 (team=2)
M25 evil!
initCarriers on hero_0(------------)
------------
determining gender hero_0 (team=1)
Welcome to the fight of the century!
First up on team 1 we have:
- oconnor - sukhov - pin_stripe - cop_crooked
Opposing them on team 2 are:
- thug_with_bat - thug_with_bat - thug_with_bat - thug_with_bat - thug_with_bat - thug_with_bat - thug_with_bat - thug_with_bat
doBrawl:oconnor_1_1
50000
thug_with_bat_6_12
doBrawl:pin_stripe_2_3
50000
thug_with_bat_4_9
doBrawl:sukhov_21_2
50000
thug_with_bat_16_8
doBrawl:cop_crooked_22_4
50000
thug_with_bat_10_6
doBrawl:thug_with_bat_14_7
50000
cop_crooked_22_4
doBrawl:thug_with_bat_10_6
50000
cop_crooked_22_4
doBrawl:thug_with_bat_16_8
50000
sukhov_21_2
doBrawl:thug_with_bat_4_9
50000
pin_stripe_2_3
doBrawl:thug_with_bat_5_10
50000
cop_crooked_22_4
doBrawl:thug_with_bat_17_11
50000
oconnor_1_1
doBrawl:thug_with_bat_6_12
50000
oconnor_1_1
doBrawl:thug_with_bat_7_13
50000
sukhov_21_2
doBrawl:oconnor_1_1
50000
thug_with_bat_17_11
doBrawl:pin_stripe_2_3
50000
thug_with_bat_4_9
doBrawl:sukhov_21_2
50000
thug_with_bat_16_8
doBrawl:cop_crooked_22_4
50000
thug_with_bat_10_6
doBrawl:thug_with_bat_14_7
50000
cop_crooked_22_4
doBrawl:thug_with_bat_10_6
50000
cop_crooked_22_4
doBrawl:thug_with_bat_16_8
50000
sukhov_21_2
doBrawl:thug_with_bat_4_9
50000
pin_stripe_2_3
doBrawl:thug_with_bat_5_10
50000
cop_crooked_22_4
doBrawl:thug_with_bat_17_11
50000
oconnor_1_1
doBrawl:thug_with_bat_6_12
50000
oconnor_1_1
doBrawl:thug_with_bat_7_13
50000
sukhov_21_2
Team 2 loses thug_with_bat
checking against team 1
doBrawl:oconnor_1_1
50000
thug_with_bat_17_11
doBrawl:pin_stripe_2_3
50000
thug_with_bat_4_9
doBrawl:sukhov_21_2
50000
thug_with_bat_7_13
doBrawl:cop_crooked_22_4
50000
thug_with_bat_10_6
doBrawl:thug_with_bat_14_7
50000
cop_crooked_22_4
doBrawl:thug_with_bat_10_6
50000
cop_crooked_22_4
doBrawl:thug_with_bat_4_9
50000
pin_stripe_2_3
doBrawl:thug_with_bat_5_10
50000
cop_crooked_22_4
doBrawl:thug_with_bat_17_11
50000
oconnor_1_1
doBrawl:thug_with_bat_6_12
50000
oconnor_1_1
doBrawl:thug_with_bat_7_13
50000
sukhov_21_2
doBrawl:oconnor_1_1
50000
thug_with_bat_17_11
doBrawl:pin_stripe_2_3
50000
thug_with_bat_17_11
doBrawl:sukhov_21_2
50000
thug_with_bat_7_13
doBrawl:cop_crooked_22_4
50000
thug_with_bat_10_6
doBrawl:thug_with_bat_14_7
50000
cop_crooked_22_4
doBrawl:thug_with_bat_10_6
50000
cop_crooked_22_4
doBrawl:thug_with_bat_5_10
50000
cop_crooked_22_4
doBrawl:thug_with_bat_17_11
50000
oconnor_1_1
doBrawl:thug_with_bat_6_12
50000
oconnor_1_1
doBrawl:thug_with_bat_7_13
50000
sukhov_21_2
Team 2 loses thug_with_bat
checking against team 1
Team 2 loses thug_with_bat
checking against team 1
doBrawl:oconnor_1_1
50000
thug_with_bat_6_12
doBrawl:pin_stripe_2_3
50000
thug_with_bat_17_11
doBrawl:sukhov_21_2
50000
thug_with_bat_5_10
doBrawl:cop_crooked_22_4
50000
thug_with_bat_10_6
doBrawl:thug_with_bat_14_7
50000
cop_crooked_22_4
doBrawl:thug_with_bat_10_6
50000
cop_crooked_22_4
doBrawl:thug_with_bat_5_10
50000
cop_crooked_22_4
doBrawl:thug_with_bat_17_11
50000
oconnor_1_1
doBrawl:thug_with_bat_6_12
50000
oconnor_1_1
Team 2 loses thug_with_bat
checking against team 1
doBrawl:oconnor_1_1
50000
thug_with_bat_17_11
doBrawl:pin_stripe_2_3
50000
thug_with_bat_17_11
doBrawl:sukhov_21_2
50000
thug_with_bat_5_10
doBrawl:cop_crooked_22_4
50000
thug_with_bat_10_6
doBrawl:thug_with_bat_14_7
50000
cop_crooked_22_4
doBrawl:thug_with_bat_10_6
50000
cop_crooked_22_4
doBrawl:thug_with_bat_5_10
50000
cop_crooked_22_4
doBrawl:thug_with_bat_17_11
50000
oconnor_1_1
doBrawl:oconnor_1_1
50000
thug_with_bat_17_11
doBrawl:pin_stripe_2_3
50000
thug_with_bat_17_11
doBrawl:sukhov_21_2
50000
thug_with_bat_5_10
doBrawl:cop_crooked_22_4
50000
thug_with_bat_10_6
doBrawl:thug_with_bat_14_7
50000
cop_crooked_22_4
doBrawl:thug_with_bat_10_6
50000
cop_crooked_22_4
doBrawl:thug_with_bat_5_10
50000
cop_crooked_22_4
doBrawl:thug_with_bat_17_11
50000
oconnor_1_1
Team 2 loses thug_with_bat
checking against team 1
Team 1 loses cop_crooked
checking against team 1
doBrawl:oconnor_1_1
50000
thug_with_bat_17_11
doBrawl:pin_stripe_2_3
50000
thug_with_bat_17_11
doBrawl:sukhov_21_2
50000
thug_with_bat_5_10
doBrawl:thug_with_bat_14_7
50000
sukhov_21_2
doBrawl:thug_with_bat_5_10
50000
sukhov_21_2
doBrawl:thug_with_bat_17_11
50000
oconnor_1_1
Team 2 loses thug_with_bat
checking against team 1
doBrawl:oconnor_1_1
50000
thug_with_bat_14_7
doBrawl:pin_stripe_2_3
50000
thug_with_bat_14_7
doBrawl:sukhov_21_2
50000
thug_with_bat_14_7
doBrawl:thug_with_bat_14_7
50000
sukhov_21_2
doBrawl:thug_with_bat_5_10
50000
sukhov_21_2
doBrawl:oconnor_1_1
50000
thug_with_bat_14_7
doBrawl:pin_stripe_2_3
50000
thug_with_bat_14_7
doBrawl:sukhov_21_2
50000
thug_with_bat_5_10
doBrawl:thug_with_bat_14_7
50000
sukhov_21_2
doBrawl:thug_with_bat_5_10
50000
sukhov_21_2
doBrawl:oconnor_1_1
50000
thug_with_bat_14_7
doBrawl:pin_stripe_2_3
50000
thug_with_bat_14_7
doBrawl:sukhov_21_2
50000
thug_with_bat_14_7
doBrawl:thug_with_bat_14_7
50000
sukhov_21_2
doBrawl:thug_with_bat_5_10
50000
sukhov_21_2
Team 2 loses thug_with_bat
checking against team 1
doBrawl:oconnor_1_1
50000
thug_with_bat_14_7
doBrawl:pin_stripe_2_3
50000
thug_with_bat_14_7
doBrawl:sukhov_21_2
50000
thug_with_bat_14_7
doBrawl:thug_with_bat_14_7
50000
sukhov_21_2
Team 2 loses thug_with_bat
checking against team 1
Team 1 is the victor!!!
WinMission() called
playing CS
cshelper: Cutscene [unknown] submitted for playing
cshelper: Now playing cutscene [unknown]
Step 1 of 2
doBrawl:oconnor_1_1
50000

doBrawl:pin_stripe_2_3
50000

doBrawl:sukhov_21_2
50000

Step 2 of 2
cshelper: Cutscene [unknown] has ended
doBrawl:oconnor_1_1
50000

doBrawl:pin_stripe_2_3
50000

doBrawl:sukhov_21_2
50000

doBrawl:oconnor_1_1
50000

doBrawl:pin_stripe_2_3
50000

doBrawl:sukhov_21_2
50000

[/spoiler]

Theoretically, at some point they should attempt to put some distance between themselves and the thugs, but it never happens.

To answer your question, Metherian - yes, I generally prefer to make my own AI's from scratch.  I hadn't made any in a while, and one of the first ones I started with recently was one which I wanted to attack buildings.  Specifically, one of their powers was one to be used only on buildings, so an AI from scratch would have actually been preferable.  I couldn't figure out how to do it, though. 

In the process of trying to figure it out, I've found that there seem to be a few glitches in the way my game is working.  I'm only using the in-game AI's here as an example to eliminate the possibility that people might mistake the problem as being my poor script writing skills. :cool: I'm sure we'll eventually find it's some other silly mistake on my part, though! :lol:

Metherian

One thing you can do is create a list of 'building targets' for the character, which, in turn, can be passed to, or simply accessed directly by, your scripted AI functions.  This list can be static, or it can be continuously updated as the building-smashing character moves about the map.  As conditions which trigger a 'destroy building' response are met, you can force the character to start destroying things.  The main problem, though, is that you can't control the game's standard AI behavior; it will always override what you want the character to do unless you remove it completely.  You almost have to use fully-scripted AI.

A long, long time ago I created a map scenario for the original FF where I had the Hulk rampaging through a large city map.  The objective was to stop him somehow before he destroyed too many buildings.  I added a 'rampage' mode to my ai_hulk script which would force the Hulk to start destroying buildings if no non-stunned/non-KO'd characters were in close proximity to him.  Adding the use of a specific building-destroyer power would have been easy to do.

I'm not sure how you're building your AI scripts.  I find that people have their own 'take' on how to do these kinds of things.  Most of us are code-monkeys in some capacity or another, so we like to experiment a lot, and do things our own way.  :).  My own 'flavor' of AI scripting goes back to the days when the original FF forums were still around. 

Someone (I don't remember who) very early on discovered that you could force all kinds of things in the game by using object spawn calls, etc.  Shortly after that, some guy named MajorSlam explained how you could create a looping script with recursive function calls which spawned enemies over and over, with increasing difficulty.  (A precursor to the rumble room.)  This "main loop" functionality "clicked" for a lot of the scripting crowd and a lot of what we take for granted today suddenly came into focus.

I create AI scripts by using an outer "processing loop" and a main AI function call for each character object.  The outer loop runs continuously, passing the object into the main function every few seconds, along with any updated attributes, etc. The outer loop handles health regen, attribute checks against being 'staticked', stunned, player character dialogue, etc.  Because Python passes things to functions by reference, this makes getting, setting, and using the attributes in the passed character object very, very easy.  You evaluate the object's current attributes (ai mode, health, energy points, location, current target, tactics, etc.) and then invoke the proper response functions  (melee combat, ranged combat, flanking, retreat, guard, move, rampage, etc.)

With this design you can easily set up different behavioral responses based on the character's attributes.  You can control how they target things, what powers they use, what's their preferred mode of travel, what their targeting preferences are, whether they can exploit vulnerabilities, even how aggressive they are.  All kinds of things. You can create different modes that have the character guarding, patrolling, etc.  I even implemented something I called "tactics", a varying, weighted value that would shift based on the character's target and specific 'feelings' toward the target; the final result would be used to determine whether or not the character was aggressive, or used certain powers, fighting modes, etc. against the target.  For those "signature fights" (spider-man v. Green Goblin) it was ideal.

You can even do team-oriented AI this way, by checking the object's  team ai variable inside of the main loop.  If active, you know the main loop is to be bypassed, or surpressed, while a completely different AI process (a team-oriented one) takes over.  Coordinated attacks, defense behavior, etc. are pretty cool to see, especially since I have triggered dialogue that goes with a lot of this stuff.  Attacks, defenses, etc.--even certain targeting--has a chance of displaying in-fight dialogue that makes the game a bit more 'immersive'.

The down side of all this is that it's not very "rumble room" friendly, and more or less requires you to use FFEdit, do a lot of scripting, and then package it together in campaign mode.  I've never used FFX, but it shouldn't be too difficult to adapt.  I tried to 'genericize' things a while back, so as to make something more conventional, and downloadable, for people--but it didn't work so well. lol   Then I tried moving the scripts into an object-based model, but OOP in Python is kind of 'flaky', to say the least, so I abandoned that idea.

Anyway, I don't know if any of this rambling helps ... it's been a while since I even looked at this stuff.  :D   



M25

Vortex, I don't see any problems with the log, and since you weren't running custom AI, it looks like there might be an issue with the game itself, but it has been a while since I've used the first game.

Metharian, looking forward to seeing what you've produced.