Qhimm.com Forums

Miscellaneous Forums => Archive => Topic started by: Armorvil on 2009-08-08 20:19:36

Title: Help needed on AI Editing (FFVII)
Post by: Armorvil 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.
Title: Re: Help needed on AI Editing (FFVII)
Post by: Kudistos Megistos 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?
Title: Re: Help needed on AI Editing (FFVII)
Post by: Armorvil 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.
Title: Re: Help needed on AI Editing (FFVII)
Post by: Kudistos Megistos 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.
Title: Re: Help needed on AI Editing (FFVII)
Post by: Armorvil 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 ^__^
Title: Re: Help needed on AI Editing (FFVII)
Post by: Kudistos Megistos 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
Title: Re: Help needed on AI Editing (FFVII)
Post by: nfitc1 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.
Title: Re: Help needed on AI Editing (FFVII)
Post by: Armorvil 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 ?
Title: Re: Help needed on AI Editing (FFVII)
Post by: nfitc1 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.

Title: Re: Help needed on AI Editing (FFVII)
Post by: Armorvil 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).
Title: Re: Help needed on AI Editing (FFVII)
Post by: nfitc1 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.
Title: Re: Help needed on AI Editing (FFVII)
Post by: Kudistos Megistos 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.
Title: Re: Help needed on AI Editing (FFVII)
Post by: Armorvil 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
Title: Re: Help needed on AI Editing (FFVII)
Post by: titeguy3 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 (http://forums.qhimm.com/index.php?topic=8664.0) 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?
Title: Re: Help needed on AI Editing (FFVII)
Post by: Armorvil on 2009-08-09 22:01:09
Wow, titeguy3, you rock !!  :-o
I gotta try this ASAP :D
Title: Re: Help needed on AI Editing (FFVII)
Post by: nfitc1 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.
Title: Re: Help needed on AI Editing (FFVII)
Post by: Armorvil 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.
Title: Re: Help needed on AI Editing (FFVII)
Post by: titeguy3 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...
Title: Re: Help needed on AI Editing (FFVII)
Post by: Armorvil 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
Title: Re: Help needed on AI Editing (FFVII)
Post by: nfitc1 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.
Title: Re: Help needed on AI Editing (FFVII)
Post by: titeguy3 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.
Title: Re: Help needed on AI Editing (FFVII)
Post by: nfitc1 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.
Title: Re: Help needed on AI Editing (FFVII)
Post by: Xelane 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?
Title: Re: Help needed on AI Editing (FFVII)
Post by: Kudistos Megistos 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
Title: Re: Help needed on AI Editing (FFVII)
Post by: titeguy3 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
}
Title: Re: Help needed on AI Editing (FFVII)
Post by: nfitc1 on 2009-08-10 11:43:21
This would all be better in Post-Attack, it fires more often and would catch Dual and Poison-induced critical damage sooner.
Title: Re: Help needed on AI Editing (FFVII)
Post by: secondadvent on 2009-08-10 12:45:42
@xelane: yeah, post attack is sort of a general counter for any attack made, not just on the user, so if something has to be activated fast, this is where it should go. it still will not likely always activate right away for dual drain/poison cases (unless they count as an attack :P), but it can be faster than general, as nfitc1 said. now i do not know if any of the unknown sections are actually usable, but if they actually do something, then i would not be surprised if one of them acted every time a unit of time passed, which could be how doom/dual drain acts, and could be useful to make something activate a countdown timer of sorts outside of the main AI of an enemy, especially since you'd be able to make the enemy attack/react even if it isn't it's turn yet :P.

now i am not entirely sure if there is a section that is like that, if there is you'd have to be careful what you put into it, or you could be making the game work too hard since it has to do the calculations a massive amount of times, but it would have it's advantages, like with setting a status at a certain time, that has to be done asap. i could think of a few ways to use a section like that ^_^ *hopes that there is one like that, or a way to do it  :roll:*.

@nfitc1: now sort of off topic, how exactly does your jump pointer update work, do you have to point it to a specific point and it auto updates as you add more before that spot (like if you point to offset 0x021 and add stuff there to kick down the original jump to 0x027, it will make the jump stick to the original spot, regardless of how far down it moves)? that does sound pretty good, but what about when starting from a fresh section, all that is there would be whatever you add, and if you were to point at a location right as you start to build an if, the only place you could really jump would be the end statement, and so no matter what you add, it will still point there, and if you had wanted to point at something before the end, but after the if's data, you would still have to manually edit that. also, if you were to add something (like something after an if's data for example), and some jump is already pointing to that specific data, and you had to add something before that to make it work right, all of the jumps would still follow the old data, you would have to manually update there as well, or overwrite the data in the same location to make them work right.

i know that those are things that are probably not easy to fix and should be left to the user to do anyway, but it IS me, and i like to be picky  :roll:. ignoring my smart @$$ comments for a second, it does sound like it will be a very nice feature, and i will be happy to take advantage of it when i get back to ffvii hacking ^_^.

@armorvil: as for the 0mp kill thingy, i had tried last night to get that to work, but it didn't go over so well. i first tried 0hp, which as i thought wouldn't kill it, so i then tried just setting the death flag, which worked at first, but after actually giving the enemy some mp, and causing it to lower to 0, it stopped killing them, or even doing anything (using an if self.mp == 0 statement, it may work with a self.mp < 1 line, but i don't see why that would be needed :/). i also tried the "normal" killing method used by other enemies to kill off the enemy at 0hp, but for some reason the enemy wouldn't even disappear like normal when that part activates, i don't know what was up... maybe i have just been away for too long :/.

anyhow, even if you use the normal killing method (setting those values to 0), if you want to have any battle spoils from the enemy, you will have to set death to 1, i noticed at least that much in my testing. maybe you will have more luck than me, use nfitc1's ai script for killing the enemies (though he is using the max hp value instead of the current hp, not sure how the game reacts to that :/), and just to be safe (if you don't get exp or whatever from it), set death status to 1 as well, maybe you will have more luck than i did :P. as far as i can tell though, the death animation will not play, the enemy "should" only disappear and make itself inactive (should, as in mine didn't but my current scene.bin is a mess anyway from testing crap :P), there is probably a way to manually activate the death animation, but i do not know how to do that, i even tried to set the idle animation to 2 which iirc is the death animation for enemies, but it just froze the game  :-(. just try niftc1's code and if needed the death flag to 1 code by titeguy and see what happens... i will have to crack open a fresh scene.bin backup sometime soon :P.

hp being locked at 0 is a fun little way to make an enemy invincible even though you are still doing damage... kinda fun to beat up on an enemy for a while while it just laughs at you, until you realize that healing it and then taking that hp away = death XD.
Title: Re: Help needed on AI Editing (FFVII)
Post by: nfitc1 on 2009-08-10 13:41:38
@nfitc1: now sort of off topic, how exactly does your jump pointer update work, do you have to point it to a specific point and it auto updates as you add more before that spot (like if you point to offset 0x021 and add stuff there to kick down the original jump to 0x027, it will make the jump stick to the original spot, regardless of how far down it moves)? that does sound pretty good, but what about when starting from a fresh section, all that is there would be whatever you add, and if you were to point at a location right as you start to build an if, the only place you could really jump would be the end statement, and so no matter what you add, it will still point there, and if you had wanted to point at something before the end, but after the if's data, you would still have to manually edit that. also, if you were to add something (like something after an if's data for example), and some jump is already pointing to that specific data, and you had to add something before that to make it work right, all of the jumps would still follow the old data, you would have to manually update there as well, or overwrite the data in the same location to make them work right.

i know that those are things that are probably not easy to fix and should be left to the user to do anyway, but it IS me, and i like to be picky  :roll:. ignoring my smart @$$ comments for a second, it does sound like it will be a very nice feature, and i will be happy to take advantage of it when i get back to ffvii hacking ^_^.

It's as user-friendly as it can possibly be. The user doesn't have to make any additional labels or points or anything. Just write the code as usual. If you tell the code to jump to an address and that address moves because you inserted code before it, the jump address will update. If you insert code after the jump, the address won't be affected. I can see two potentially destructive parts about this:

#1. You tell it to jump to an address that doesn't exist. WM/PrC won't crash, but the game will likely freak out on you. In one of the test monsters (those pyramids) there is a jump to 0x64 when the end script code is at 0x63. I don't know if this enemy can be encountered as it's a debug enemy. What will happen is......nothing. Since the address doesn't exist it won't update. You can tell it to jump to 0x5F32 (an impossible address as it virtually can't exceed 0x0FD8) then it will just remain being 5F32 until you are ready to give it a position.
#1b. If you give it an address that BECOMES usable later, it will still function like normal.
#2. You want to jump to 0x00 to start a script over then add code at the beginning. This one's more rare to happen. Indeed, I'm not even sure that you can jump backwards. I've never gotten it to work. But as you add code to the beginning, it will continue to push the 0x00 address forward. You'll have to manually change the jump address or consider changing where you're inserting code.

You want to know the mechanics behind it? Renumbering the address grid is the second-to-last step (right before writing the AI into memory to be written to the scene.bin/KERNEL.BIN). Also notice that when you add a row it adds a blank address header and displaces all the others? Well, as a testament to my genius as a programmer, right before all the addresses get renumbered I go through and find the jumps and which address they point to and make a note of which row that equates to. After it finishes making that assessment for all jumps and all row addresses are updated, it goes BACK through the jumps it found and changes the address if the address it jumps to and the address in the row header is different. Then the AI is written back to memory with the jumps updated.
Brilliant, no? ;) This function has a "big O (http://en.wikipedia.org/wiki/Big_O_notation)" (not to be confused with The Big O (http://en.wikipedia.org/wiki/The_Big_O) with the retarded theme song) of log(n) so it's super fast and runs every time data is changed. It'll probably even be fast on Eligor's script! :O I only really tested it on a few things. Guard Scorpion was the biggest script I tested. On the laptop I use to develop this I saw no performance hit for doing this function.
It's LIKE having labels, but the user doesn't ever have to make one. It's amazing sometimes how the simplest things work the best.
Title: Re: Help needed on AI Editing (FFVII)
Post by: Armorvil on 2009-08-10 20:09:38
About my 0 MP = Death problem...

NFITC1's script, at the bottom of page 1, doesn't seem to work. But Titeguy's new script in post-attack does work :

02    2060
02    4140
80
60    00
40
70    0017
12    2060
10    4000
80
60   01
90
73

The only problem is the fact that the enemy doesn't do its death animation... So, I tried to add this new line, between 60 01 and 90, near the end of the script :

93    Devil Ride's brain was crushed!  (:-P)

Because yeah, if we can't make an enemy disappear, then we can at least let a player know it's dead... ...the problem though, is the fact that this message keeps displaying as the battle goes on, over and over...  :-(
Is there a way to display the message only once, just as the enemy dies ?
Title: Re: Help needed on AI Editing (FFVII)
Post by: Akari on 2009-08-10 20:16:02
About my 0 MP = Death problem...

NFITC1's script, at the bottom of page 1, doesn't seem to work. But Titeguy's new script in post-attack does work :

02    2060
02    4140
80
60    00
40
70    0017
12    2060
10    4000
80
60   01
90
73

The only problem is the fact that the enemy doesn't do its death animation... So, I tried to add this new line, between 60 01 and 90, near the end of the script :

93    Devil Ride's brain was crushed!  (:-P)

Because yeah, if we can't make an enemy disappear, then we can at least let a player know it's dead... ...the problem though, is the fact that this message keeps displaying as the battle goes on, over and over...  :-(
Is there a way to display the message only once, just as the enemy dies ?

It you want to show enemy die - just call it's death animation scripts. You can do it by create dummy attack and assosiate it with death animation script. Example of dummy attack you can see in Guard Scorpion (when he rise and down it's tail). For enemy death animation script should be 0x01. But note that animation scripts check if HP == 0 so you need to set enemy HP equal to 0.
Title: Re: Help needed on AI Editing (FFVII)
Post by: Armorvil on 2009-08-10 20:55:35
Thanks for the info. I looked at Guard Scorpion's script, but I fear that my eyes aren't trained enough to see which lines are the ones that call a different animation. Besides, if I had to create a dummy attack for each monster susceptible to MP-Killing, it would be too time-consuming. The whole full-game hack I have in the works is trouble enough already, so I figure my line "[monster name] lived on MP..." is sufficient if the AI script can't make an enemy disappear. Now if only I knew how to make the text box display only once...
Title: Re: Help needed on AI Editing (FFVII)
Post by: nfitc1 on 2009-08-10 21:13:51
Akari's not saying a line in the script calls the animation (although you could set the idle animation). He means that you should create a blank attack and use the animations/formations tab to associate its death animation (somewhere between 0-2, I'm not clear on this) with that attack. Perform that attack right before inflicting the death status and it will appear to die like normal. Then you can just perform a text display as you call the attack and inflict death.
Title: Re: Help needed on AI Editing (FFVII)
Post by: titeguy3 on 2009-08-10 21:37:56
@NFITC1, I've discovered through half-assed mistakes that if you jump to a point beyond a script's boundary, it'll jump to the next script. For example, with guard scorpion, I accidentally made a jump to a point out of bounds, and it used tail laser, meaning it jumped to the point in it's General Counter Script where tail laser is called. I can't prove this, since I'm not the one of the ones who decrypted scene.bin, but I'm fairly certain that's what happens...

It's bizarre that it's so difficult to kill an enemy. Isn't there a RunScript(x) function that can be used to just call a death script?

Whatever, I digress. Armorvil, ever notice how some enemies have a "(report)" attack? These are basically suicide attacks. You need to make an attack like this, once you do it once, you don't have to do it again, just use the same attack.

Let me break it down...
1. Make an attack in Proud Clod, name it "MPDeath" or something
2. set it's Attack ID to something unused...let's say...x0166.
3. Set the MP Cost to 0, set the Attack damage to "00 No Damage Calculation (Name not displayed)", Check "Ignore Stat Def" and make it cause "Death" status with 63 Chance
4. Use this code: (in the post-attack script)
Assembly:
Code: [Select]
; Die when MP reaches zero
PSHA02 SELF
PSHA02 MP
MASK
PUSH 0
EQU
JMP0 FIN
PUSH12 TARGETMASK
PSHA02 SELF
STRA
PUSH 20
PUSH 166 ; MPDeath attack
ATTK
PUSH12 SELF
PUSH12 MP
MASK
PUSH 1
STRA
FIN END

Hex:
Code: [Select]
02 2060
02 4140
80
60 00
40
70 0024
12 2070
02 2060
90
60 20
61 0166
92
12 2060
12 4140
80
60 01
90
73

This shouldn't have any problems, I've tested this method out before and works in every case.

EDIT: I noticed that this could make it go awry is if something bad happens when it tries to use this attack after it's dead...better add a line in to set it's MP to one so this only happens once...(adds line in)

If you need to have another enemy die by MP, put the code in their post-attack as well, then give them an attack with ID x0166 (or whatever you used), then right click the ORIGINAL attack, and click "Sync attack with Given ID". That'll essentially copy over the attack properties to every other with the same ID, so you don't have to put in the attack info more than once.
Title: Re: Help needed on AI Editing (FFVII)
Post by: Armorvil on 2009-08-10 22:06:24
Urgh, I did exactly as you wrote Titeguy3, and I get a "Data Error - scene 35 code 32" for Devil Ride (scene10).
I don't know what I do wrong... And thanks for the right click thing ! Wow, Proud Clod has some pretty neat functionalities  8-)
Title: Re: Help needed on AI Editing (FFVII)
Post by: titeguy3 on 2009-08-10 22:09:46
Oh, I may have forgotten to mention that you also have to assign the attack to him in Animations/Formations. Guess and check which animation works the best... One of them has to be the Idle one....
Title: Re: Help needed on AI Editing (FFVII)
Post by: Armorvil on 2009-08-10 22:24:50
OK, thank you : it works now, but there's a new problem : I tested it in a battle formation of two Devil Rides, and once I MP-defeated one, the other took his turn (by attacking or whatever) and the battle ended as if I also defeated the second Devil Ride (meaning, this second one didn't use the death animation, which is normal since he wasn't MP damaged - but then why did its HP go to 0 ? I never attacked it).

Man, I would never have guessed implementing this function would be so troublesome  :-o
Title: Re: Help needed on AI Editing (FFVII)
Post by: Akari on 2009-08-10 23:33:09
associate its death animation (somewhere between 0-2, I'm not clear on this) with that attack

Animation script 1 is the script that plays hurt animation and do check for death. If unit is dead it plays death effect set in this model.

ps: Animation script id 1 - idle.
pps: please don't confuse animation script id with animation id. Animation script can call a lot of animations as well as play effects and load new one from disk.
enemy MP animation script 3 (assosiate with mashingun attack) calls 4 different animations in model.
// mashingun
Code: [Select]
action = 3
// sequence
FC EA 02    AD07B801010A D8011000 F708 03    04    05    E5EE
// opcodes
// FC set direction for animation for target and attacker based on target and other things.
// EA show attack name
// 02 play animation 2 (jump to half enemy)
// AD[07][B801][01][0A] Attach effect to joint 07 with lenght 1B8 which starts at 01 and ends at 0x0a. Always mashingun fire.
// D8[01][1000] some effect related???
// F7[08] time before target plays hurt action. This will display damage and effect.
// 03 play animation 3 (looks like 1 frame only ???)
// 04 play animation 4 (looks like 1 frame only ???)
// 05 play animation 5 (attack and jump back)
// E5 return direction (oposite of FC)
// EE reset to idle.
Title: Re: Help needed on AI Editing (FFVII)
Post by: titeguy3 on 2009-08-10 23:59:12
OK, thank you : it works now, but there's a new problem : I tested it in a battle formation of two Devil Rides, and once I MP-defeated one, the other took his turn (by attacking or whatever) and the battle ended as if I also defeated the second Devil Ride (meaning, this second one didn't use the death animation, which is normal since he wasn't MP damaged - but then why did its HP go to 0 ? I never attacked it).

Man, I would never have guessed implementing this function would be so troublesome  :-o

That...I can't explain... did you update both instances of Devil Ride's AI? (scene 8 and 10)
Although I can't imagine why a single battle would want to call instances of the same monster from different scenes...

He couldn't have used up his own mp though, devil rides don't have any attacks that consume MP.

But yeah, that's AI Scripting for ya. It can be pretty chaotic...try to gather some more information. Find out why the round is ending by sensing the second devil ride and seeing if it's HP or MP is going to zero.