Author Topic: Help needed on AI Editing (FFVII)  (Read 18794 times)

Armorvil

  • *
  • Posts: 621
  • Working on : FFVII Total Grudge
    • View Profile
Help needed on AI Editing (FFVII)
« on: 2009-08-08 20:19:36 »
Okay, I'd like to do some AI editing of my own, but no matter how many times I read the tutorial in Wall Market, I can't figure this language out. So I thought I'd ask a kind soul to tell me what I should type to obtain the desired effects. The first thing I'd like to do, is to tell some monsters to die when their MP reach 0 (that's because some weapons can target MP instead of HP). Could someone tell me what I'd need to type in their "general: counter" script ?

Also, I'd like the Mono Drive to stop targeting the ally with the lowest MDef, with its magic (that's because its spell is now a new Enemy Skill, and since Cloud is the one equipped with an Enemy Skill materia right from the beginning, with Barret in the party he can never learn it). Better yet, it would be cool if this monster could target the ally with the highest MDef instead.

I'm sure I'll have other things to ask in the future, if you don't mind. Oh yeah, and I still haven't given up on understanding the AI scripts, but I wish there was a tutorial that gave examples, or simply more explanations about what each line of code does, in Proud Clod. Or am I in the minority ? Are most users able to use this editor with the few docs currently available ? I really wish there was some kind of a "How to make a 2-Faced attack" guide, especially designed to be used by wimps... Seriously, I thought I was a minimum intelligent, but when I click on the Proud Clod's AI tab, I feel I'm the dumbest person on Earth for not understanding all those PUSH, MASK, PSHA, POP, STACKS, Types, etc... ...Gives me the urge to repeatedly bang my head against a nearby wall.
« Last Edit: 2009-08-08 20:44:05 by Armorvil »

Kudistos Megistos

  • Banned
  • *
  • Posts: 3929
    • View Profile
Re: Help needed on AI Editing (FFVII)
« Reply #1 on: 2009-08-08 21:05:06 »
Yeah, it's pretty hard to understand if you don't know any programming languages  :wink:

Unfortunately I can't remember off the top of my head how to make the changes you want to make, but maybe NFITC1 or secondadvent might be able to help you?

Armorvil

  • *
  • Posts: 621
  • Working on : FFVII Total Grudge
    • View Profile
Re: Help needed on AI Editing (FFVII)
« Reply #2 on: 2009-08-08 21:40:01 »
You reassure me, I thought I was stupid, KM ! ;)
And yeah, gotta wait for the experts, I guess. And let's hope they have enough time to spare to teach a noob :P

Yesterday, to try and decipher the IA scripting, I tried to use the Enemy Mechanics FAQ created by Terence Fergusson, and to compare his notes to the values found in Proud Clod's AI editor. For starter, I decided to choose a monster with a really short and seemingly easy AI script : 1st Ray. Here is 1st Ray's AI script, as described by Terence in his FAQ :

Code: [Select]
AI: Main
{
   If (Count = 0) Then
   {
      Choose Random Opponent with Highest HP
      Use <Laser Cannon> on Target
      Count = 1
   } Else {
      Count = 0
   }
}

Simple, isn't it ? Well, in Proud Clod, it translates like this (I put the descriptions inside the brackets):

Code: [Select]
0x000: 00 0000 [PSHA (0000) Type (00)]
0x003: 52 [NOT]
0x004: 70 0023 [JMP0 (0023)]
0x007: 12 2070 [PUSH (2070) Type (12)]
0x00A: 02 20A0 [PSHA (20A0) Type (02)]
0x00D: 03 4160 [PSHA (4160) Type (03)]
0x010: 80 [MASK]
0x011: 84 [HMSK]
0x012: 82 [RBYT]
0x013: 90 [STRA]
0x014: 60 20 [PUSH (20) Type (01)]
0x016: 61 0117 [PUSH (0117) Type (02)]
0x019: 92 [ATTK]
0x01A: 10 0000 [PUSH (0000) Type (10)]
0x01D: 60 01 [PUSH (01) Type (01)]
0x01F: 90 [STRA]
0x020: 72 0029 [JUMP (0029)]
0x023: 10 0000 [PUSH (0000) Type (10)]
0x026: 60 00 [PUSH (00) Type (01)]
0x028: 90 [STRA]
0x029: 73 [END]

I'm sure that for people who know this language, this must be simple. But for the others...
Still, I'm not completely stupid : I know the first values, like "0x000", are the addresses. I have no problem with the [END] opcode either. And finally, I also know that the opcode is some kind a global command, while the other bytes (the arguments, if I understood correctly) are the details of the command.

Using the Wall Market help file, I'll try to decipher this code (correct me if I'm wrong):
0x000: 00 0000 [PSHA (0000) Type (00)] = Read and push 0000 to the stack. Does that mean it saves the zero value to compare it to the "Count" value later ?
0x003: 52 [NOT] = "Known as a Logical NOT (!), this will return a non-zero if either of the top value on the stack zero. Otherwise, a 0 is pushed"... ...okaayyy, so what is "returned" ? It's a non-zero, cool, so it's something. Maybe "1" ? I really need explanations here.
0x004: 70 0023 [JMP0 (0023)] = "This will perform a jump to absolute script address indicated by the argument if the value of the pop is 0". Okay, this is understand (I think). This must mean that if the Count is 1, the Ai skips the next parts and jumps straight to another address. My guess is, since (0023) is written, this address is at 0x023... ?

...I'll stop here for now, it takes a long time to type all this and I gotta go.
« Last Edit: 2009-08-08 21:52:37 by Armorvil »

Kudistos Megistos

  • Banned
  • *
  • Posts: 3929
    • View Profile
Re: Help needed on AI Editing (FFVII)
« Reply #3 on: 2009-08-08 21:53:24 »
Looking at that 1st Ray script reminded me of how the Mono Drive could be programmed to attack the character with the highest mag def...

the 85 opcode pushes the lowest value in a set and the 84 opcode pushes the highest one; I suggest you change the 85 opcode at 0x104 to 84. I haven't checked this, so I can't confirm it, but it might work.

Armorvil

  • *
  • Posts: 621
  • Working on : FFVII Total Grudge
    • View Profile
Re: Help needed on AI Editing (FFVII)
« Reply #4 on: 2009-08-08 21:58:54 »
Aaaahhh, you're a god, KM  :-D
You're right, in the help file, NFITC1 described these two opcodes that way. I'll try to change this byte, and see what it does  :-)

EDIT : it works !! You indeed are a god ^__^
« Last Edit: 2009-08-08 22:08:02 by Armorvil »

Kudistos Megistos

  • Banned
  • *
  • Posts: 3929
    • View Profile
Re: Help needed on AI Editing (FFVII)
« Reply #5 on: 2009-08-08 22:11:28 »
Aaaahhh, you're a god, KM  :-D
You're right, in the help file, NFITC1 described these two opcodes that way. I'll try to change this byte, and see what it does  :-)

EDIT : it works !! You indeed are a god ^__^

Of course I am!  :-D

It's good to see that someone else recognises my true nature  :-P

nfitc1

  • *
  • Posts: 3011
  • I just don't know what went wrong.
    • View Profile
    • WM/PrC Blog
Re: Help needed on AI Editing (FFVII)
« Reply #6 on: 2009-08-09 07:22:05 »
Awww, I missed this. That's what I get for doing work at work. :P

Seriously though (this is the second post in about 15 mins that I've typed that), I appear to have neglected some opcodes in my disassembling (the 84 wasn't displaying in the disassembly).... how embarrassing  :oops:. I'll make note of these when the next version is to come around.

Armorvil

  • *
  • Posts: 621
  • Working on : FFVII Total Grudge
    • View Profile
Re: Help needed on AI Editing (FFVII)
« Reply #7 on: 2009-08-09 10:04:22 »
Awww, I missed this. That's what I get for doing work at work. :P

Seriously though (this is the second post in about 15 mins that I've typed that), I appear to have neglected some opcodes in my disassembling (the 84 wasn't displaying in the disassembly).... how embarrassing  :oops:. I'll make note of these when the next version is to come around.

Err... ...Cool. But now that you're in this topic NFITC1, do you know what kind of AI script would allow an enemy to die, once its MP reach 0 ?

EDIT:

Okay, just as a test, I tried to make the Mono Drive enemy cast Fire two times, instead of just once. So I go to the 0x10A address, press Enter to add a line, and type 60 49 again (now there are two 60 49 lines). Tested it in-game, but the game just froze when it was time for Mono Drive to cast Fire... ...What am I doing wrong ?
« Last Edit: 2009-08-09 10:53:02 by Armorvil »

nfitc1

  • *
  • Posts: 3011
  • I just don't know what went wrong.
    • View Profile
    • WM/PrC Blog
Re: Help needed on AI Editing (FFVII)
« Reply #8 on: 2009-08-09 15:18:44 »
I know the theory behind making an enemy die, but I don't put a lot of this into practice. That said there's a number of ways you could try.

Probably the easiest way to try is put a script in the enemy's post-attack that checks its MP. If it's 0, force-inflict the death status. You could also set its HP to 0. Normally when a game wants to out-right kill an enemy it sets its 4020, 4022, 4023, and 4024 values to 0. I don't know if this causes the death animation, but it might.

About your Mono Drive question:

For starters, there's no attack with the index 49 (which is L4 Suicide) in the scenes with Mono Drive. Fire is 1B.
Secondly, you can't just push values to the stack, that can seriously screw with the logic of the script.
Thirdly, you'll have to do the entire "perform action combo" as I call it. Push 20, then the attack index, then run command (60 20 60 1B 92). You can add all this where you put in that extra 60 49 to make him do fire whenever he gets to that segment of script.


Armorvil

  • *
  • Posts: 621
  • Working on : FFVII Total Grudge
    • View Profile
Re: Help needed on AI Editing (FFVII)
« Reply #9 on: 2009-08-09 16:15:14 »
Thanks a lot for your reply, I really appreciate it.  :-D

Quote
Probably the easiest way to try is put a script in the enemy's post-attack that checks its MP. If it's 0, force-inflict the death status. You could also set its HP to 0. Normally when a game wants to out-right kill an enemy it sets its 4020, 4022, 4023, and 4024 values to 0. I don't know if this causes the death animation, but it might.

Yeah, in theory, I know what to do... And if I had to do this with FF3usMe, this wouldn't be a problem :P
To tell you the truth, I kinda hoped an answer such as : "insert 3 lines between the 0x012 and 0x013 offsets, and type in the first one : 14 80 54, in the second one : 92, and in the third one : 10 00 82". Obviously, I'm writing rubbish, but it was just to show you the only kind of answer that would actually help me. I don't think I'll need any more AI editing than this anyway, so I promise : once I know what to type to get the "death at zero MP" effect, I won't bother you (or anyone else for that matter) anymore.

Trust me, if I knew how to make a script that checks for an enemy's MP and how to set an enemy's HP to 0, I wouldn't have created this topic. I appreciate the fact that you replied, though (and I don't really care if such a script doesn't cause the death animation, the end result is all that matters to me).

Quote
About your Mono Drive question:

For starters, there's no attack with the index 49 (which is L4 Suicide) in the scenes with Mono Drive. Fire is 1B.

Oh yeah, I said "Fire", but in my patch, Mono Drive actually uses L4 Suicide (which was turned into an Enemy Skill called Fury that casts the Fury status (there are no Hypers and Tranquilizers anymore)). And with one "60 49" line, it works normally (even though the L4 suicide data doesn't exist in its scene file, heh).

Quote
Secondly, you can't just push values to the stack, that can seriously screw with the logic of the script.

Such lines tell me I really need a better explanation about pushing, poping, and the stack in general... What do these two bytes (60 49) have to do with pushing values to the stack ? I thought they just meant : "cast L4 Suicide on target". Because yeah, that's what they do.

Quote
Thirdly, you'll have to do the entire "perform action combo" as I call it. Push 20, then the attack index, then run command (60 20 60 1B 92). You can add all this where you put in that extra 60 49 to make him do fire whenever he gets to that segment of script.

Okay, thanks a lot ! Now this is the kind of answer I like  :-) So in place of my 60 49, I can add those three lines :
60 20
60 49
92
and it will work ? I'm going to try this right away  :-D
And if I want another enemy to double-cast, or perform a random attack twice in a row, will this same script work ? Such as 60 20 60 *desired attack ID* 92 ?

EDIT:

Well, it doesn't seem to work. At first, Mono Drive kept displaying the messages "Enemy sighted!" and "Warning! Warning!" ; it didn't attack anymore. So, I decided to add a 92 just above the code you gave me, and it fixed the problem. Still, Mono Drive still casts L4 Suicide only once per turn, not twice. I don't know what I'm doing wrong here (oh yeah, and if you're wondering, I don't want Mono Drive to cast two L4 Suicide per turn; I'm doing this for testing purposes - that way I'd know what to do to make any enemy act twice (or more) a turn).
« Last Edit: 2009-08-09 16:42:07 by Armorvil »

nfitc1

  • *
  • Posts: 3011
  • I just don't know what went wrong.
    • View Profile
    • WM/PrC Blog
Re: Help needed on AI Editing (FFVII)
« Reply #10 on: 2009-08-09 18:44:36 »
OK, biggest thing I forgot to mention is that inserting lines will screw up the jumps in the scripts. If these jumps are off then it's likely nothing will work properly. The next version of WM/PrC should will account for this and update jumps as you enter new lines (slightly harder than it sounds so be patient with me on that NOT! That was a piece of cake :D It's working now and will be in the newest version of both).

WM's readme has a lot of info about the stack and its function. It's basically a list of values that the script stores and reads from, but it can only read from the top of the list at any given time.

All this said, there's not much I can help you with without seeing the entire code.

I really think that it's time to start a AI Editing sub-forum (or forum). I've been seeing a lot of requests for things like this and because it's so much more complicated than FF3USME there should be a more centralized location for such questions so they don't clog up the other sub-forums.
« Last Edit: 2009-08-10 01:10:01 by NFITC1 »

Kudistos Megistos

  • Banned
  • *
  • Posts: 3929
    • View Profile
Re: Help needed on AI Editing (FFVII)
« Reply #11 on: 2009-08-09 18:52:13 »
An AI forum would be very handy. Didn't we have an AI scripting thread at some point? Anyway, it might be a good idea to speak to Halkun or Qhimm about it.

Armorvil

  • *
  • Posts: 621
  • Working on : FFVII Total Grudge
    • View Profile
Re: Help needed on AI Editing (FFVII)
« Reply #12 on: 2009-08-09 19:33:38 »
I agree, all discussions regarding AI editing should have their own place. I'm sure some of my questions have already been answered somewhere, and I'd love to do my searches without bothering anyone.
 
And yeah, I know how wrong jumps would screw everything up, since I have very basic notions of 65816 assembly. Thanks for reminding me that they'd need to be updated. I *should* be able to fix the jumps, if my understanding of the script is correct (that is, if 0x004: 70 0023 really means that the script is supposed to jump at offset 0x023 - so, if, as an example, I added two bytes between the jump command and the target offset, then I would have to replace 70 0023 with 70 0025).

Quote
All this said, there's not much I can help you with without seeing the entire code.

Do you want me to type all of Mono Drive's main script here ? Oh man  :-P

titeguy3

  • *
  • Posts: 1283
  • A jack of all trades
    • View Profile
Re: Help needed on AI Editing (FFVII)
« Reply #13 on: 2009-08-09 20:01:41 »
If you're having trouble updating those jump points, you can write the code in assembly rather than raw hex using this assembler until NFITC1 comes up with a new version of PrC. You can use labels rather than having to use raw hex jump points, the  downfall is that you have to insert the final hex code yourself--it can't stuff it into Scene.bin for you.

EDIT: Just for the record, if you want an enemy to die when it's MP reaches 0, you'd have to write the code *twice*. Once in post attack, and once in General Counter (otherwise, the said enemy would still be allowed to perform an attack even after it's MP was taken to zero by an attack like Magic Hammer). It would probably look something like this
Code: [Select]
; Die when MP reaches zero
PSHA02 SELF
PSHA02 MP
MASK
PUSH 0
EQU
JMP0 FIN
PUSH12 SELF
PUSH13 HP
MASK
PUSH 0
STRA
FIN END

which in hex is

Code: [Select]
02 2060
02 4140
80
60 00
40
70 0017
12 2060
13 4160
80
60 00
90
73

assuming it's the only thing in that section of the script, otherwise the jump point would be different. Again, I'm not sure if this would trigger the death animation, but you never know until you try, right?
« Last Edit: 2009-08-09 20:29:07 by titeguy3 »

Armorvil

  • *
  • Posts: 621
  • Working on : FFVII Total Grudge
    • View Profile
Re: Help needed on AI Editing (FFVII)
« Reply #14 on: 2009-08-09 22:01:09 »
Wow, titeguy3, you rock !!  :-o
I gotta try this ASAP :D

nfitc1

  • *
  • Posts: 3011
  • I just don't know what went wrong.
    • View Profile
    • WM/PrC Blog
Re: Help needed on AI Editing (FFVII)
« Reply #15 on: 2009-08-09 22:04:42 »
EDIT: Just for the record, if you want an enemy to die when it's MP reaches 0, you'd have to write the code *twice*. Once in post attack, and once in General Counter (otherwise, the said enemy would still be allowed to perform an attack even after it's MP was taken to zero by an attack like Magic Hammer).

Just once in Post-Attack would suffice. Post-Attack runs on all characters/enemies at the end of ANY attack by ANY character/enemy.

But that code looks good and is probably the easiest way to do it.

Armorvil

  • *
  • Posts: 621
  • Working on : FFVII Total Grudge
    • View Profile
Re: Help needed on AI Editing (FFVII)
« Reply #16 on: 2009-08-09 23:00:07 »
I tested it on Devil Ride... ...and it doesn't work  :cry:
I inserted this script in both Post Attack & General Counter, for Devil Ride in both scene files where it appears (scene 8 and 10). I also made sure my changes were saved, since if the little asterisk next to "post battle" or "general counter" doesn't appear, it won't save even though I pasted the script.
I start the battle against Devil Ride. It has 50 MP. Tifa, equipped with a new Rasp Glove, attacks first. She deals ~250 MP damage, but Devil Ride is still there and starts mauling on the team...

Are you sure this script should be in the Post Attack ? Not in Physical Counter or Death Counter ?

EDIT: I also tried inserting the script in Physical Counter, and it doesn't work either  :-(
Once again, any help would be greatly appreciated.
« Last Edit: 2009-08-09 23:07:19 by Armorvil »

titeguy3

  • *
  • Posts: 1283
  • A jack of all trades
    • View Profile
Re: Help needed on AI Editing (FFVII)
« Reply #17 on: 2009-08-09 23:35:58 »
Keep in mind that there are TWO copies of Devil Ride and its AI in scene.bin. Make sure you modify them both or that you're modifying the right one.

That being said, you should sense it after hitting it to check to see if it's HP is indeed going to zero.

If it is, try replacing
Code: [Select]
PUSH12 SELF
PUSH13 HP
MASK
PUSH 0

with

Code: [Select]
PUSH12 SELF
PUSH10 STATUS:DEATH
MASK
PUSH 1

in other words, replace
"13   4160" with
"10   4000" and
"60   00" with
"60   01"

This will just give it the Death status outright instead of setting its HP to zero. I'm sure this will kill it, but it might not perform any custom death animation if it has one.

Also, General counter calls the script every time the character is hit, Physical and Magic Counter call their scripts every time the character is hit with physical/magical attacks respectively, and death counter is called when a character dies (hp --> 0). Post-attack, in theory, is called right after the character performs an attack, but in reality, it's called far more often than just that sometimes...
« Last Edit: 2009-08-09 23:44:24 by titeguy3 »

Armorvil

  • *
  • Posts: 621
  • Working on : FFVII Total Grudge
    • View Profile
Re: Help needed on AI Editing (FFVII)
« Reply #18 on: 2009-08-09 23:54:36 »
Wow, you're right ! Its HP is indeed going to zero, but it doesn't die. Better yet, it makes the thing invincible :P
I'll try your new script tomorrow, since it's 2 am here and I have to get up early.

Just a question though : will this new script force the Death status on the enemy, or will Death immunity still take effect ? I sure hope it's the former.

And thanks for the explanations about the different AI scripts :)

Anyways I want to thank everyone who participated in this topic, and nighty night to you all  :-D

nfitc1

  • *
  • Posts: 3011
  • I just don't know what went wrong.
    • View Profile
    • WM/PrC Blog
Re: Help needed on AI Editing (FFVII)
« Reply #19 on: 2009-08-10 01:19:59 »
I thought I posted this, but I guess I didn't.

#1. I suppose setting the HP to 0 doesn't kill it as the damage calculation detects if its HP changes to 0 upon hitting it. If it was 0 before and 0 after then this is never triggered. Try setting the death status instead.

#2. If that doesn't work you'll have to do the following on the post-attack *only*:

02  2060
03  4180
80
60  00
40
70  0035
12  2060
10  4022
80
60  00
90
12  2060
10  4020
80
60  00
90
12  2060
10  4023
80
60  00
90
12  2060
10  4024
80
60  00
90
73

This is how the game kills via script. Likely the safest method.

#3. Notice the post I made a few back. The new WM/PrC will update jump addresses. This was super easy to do. I'm surprised I didn't do it before. I figured it would be harder than what it turned out to be. At least, it worked in the few cases I tested it in.

titeguy3

  • *
  • Posts: 1283
  • A jack of all trades
    • View Profile
Re: Help needed on AI Editing (FFVII)
« Reply #20 on: 2009-08-10 02:46:28 »
#3. Notice the post I made a few back. The new WM/PrC will update jump addresses. This was super easy to do. I'm surprised I didn't do it before. I figured it would be harder than what it turned out to be. At least, it worked in the few cases I tested it in.

That's great news! I hope it works for Debug/String/Push Type 03 operations as well.
« Last Edit: 2009-08-10 03:03:55 by titeguy3 »

nfitc1

  • *
  • Posts: 3011
  • I just don't know what went wrong.
    • View Profile
    • WM/PrC Blog
Re: Help needed on AI Editing (FFVII)
« Reply #21 on: 2009-08-10 03:06:56 »
#3. Notice the post I made a few back. The new WM/PrC will update jump addresses. This was super easy to do. I'm surprised I didn't do it before. I figured it would be harder than what it turned out to be. At least, it worked in the few cases I tested it in.

That's great news! I hope it works for Debug/String/Push Type 03 operations as well.

That's one of the things I tested it on. Admittedly, though, I only tested it mechanically and haven't tested it in the game yet. I only took about 30 mins to play with it.

Xelane

  • *
  • Posts: 477
    • View Profile
Re: Help needed on AI Editing (FFVII)
« Reply #22 on: 2009-08-10 03:12:42 »
Bit off topic but i have an interesting question. is there a way you can program AI so that a status effect is activated when in critical condition?

if for example cait sith got to critical hp (yellow), he would turn small.

is it possible to pull off something like that?

and if so, how would you do it?

Kudistos Megistos

  • Banned
  • *
  • Posts: 3929
    • View Profile
Re: Help needed on AI Editing (FFVII)
« Reply #23 on: 2009-08-10 03:18:50 »
Yes, I'm pretty sure that could be done. You'd have to work out how to get the game to check when his HP reaches a certain proportion of its maximum value and then have it set his status to whatever. Actually, I wonder if you could just make it check whether he's in the "near-death" status?

It would have to go in the general counter script.

BTW, I'm too tired right now to work this out myself  :-P

titeguy3

  • *
  • Posts: 1283
  • A jack of all trades
    • View Profile
Re: Help needed on AI Editing (FFVII)
« Reply #24 on: 2009-08-10 05:58:37 »
^^Pretty much. Although I don't know if it'll account for Dual Drain HP reduction...that's a one-in-a-million case anyway.
It'd look like something like this:
Code: [Select]
;Cait Sith General Counter
PSHA02 SELF
PSHA00 STATUS:NEARDEATH
MASK
PUSH 1
EQU
JMP0 FIN
PUSH12 SELF
PUSH10 STATUS:SMALL
MASK
PUSH 1
STRA
FIN END

which in hex would be

Code: [Select]
02 2060
00 4001
80
60 01
40
70 0017
12 2060
10 400C
80
60 01
90
73

...of course keep in mind that this is just a one way code. If you want him to grow back to normal size after his HP is healed, you'll need to create a bit sized LocalVar and set it to one when his HP is critical, then make a check for:

Code: [Select]
if(Not(Self.Status:NearDeath) And LocalVar:XXXX)
{
LocalVar:XXXX <- 0
Self.Status:Small <- 0
}
« Last Edit: 2009-08-10 06:05:48 by titeguy3 »