(FF7) Enemy AI: Referring to other enemies

  • Thread starter Thread starter Karifean
  • Start date Start date
Status
Not open for further replies.
K

Karifean

Guest
I seriously do not get how this works. As far as I can tell, there are two different lines that end up storing another enemy in a variable:

Code: [Select]
Code:
LocalVar:00XX <-  (AllyMask.EnemyID == ???) andLocalVar:00XX <-  (BitCount(Self.FormationNumber) == ActiveMask.FormationNumber) LocalVar:00XX <-  (LocalVar:00XX.EnemyID == ???)
Both of them are used quite a bunch of times. The Rufus battle uses both; Rufus uses the top version, Dark Nation uses the bottom version. And yet, I can't quite see through it. Sometimes it randomly stops working, especially when using "manipulation" - as in changing the Self variable for a moment to have another enemy execute an attack. And what is does that line in the middle actually do?

To give a more concrete example, I have modified Dark Nation to use a custom skill (ID 03E9h/1001) on Rufus if it dies and Rufus is still alive. The following code comes into play:

Dark Nation's Pre-Battle Script:

Code: [Select]
Code:
0x000LocalVar:0020 <-  (BitCount(Self.FormationNumber) == ActiveMask.FormationNumber) 0x014LocalVar:0020 <-  (LocalVar:0020.EnemyID == 68) 0x022TargetMask <- AllyMask0x029Perform("Reflect"[0011], EnemyAttack)0x02FSCRIPT END
and Dark Nation's Death Counter Script, naturally:

Code: [Select]
Code:
0x000 If ( (LocalVar:0020.Status:Death == 0) )0x000 {0x00D TargetMask <- LocalVar:00200x014 Perform(1001, EnemyAttack)0x01ASCRIPT END
And yet, Dark Nation did nothing. How come?
 
Don't use BitCount. It's a pretty stupid function, I think.

EDIT:
Turns out BitCount is only one function of code 83.

If the structure of the first pop is type 2X (a list) then
   Find first non-null value in list
   All values in list become first non-null value
Code: [Select]
Code:
Pre-83    Post-8310        00         00         00         00         00*        00         01         00         00         0* - Since Self.FormationNumber is the only valid value at the time, this is considered non-null
The the 40 code comes around:

Code: [Select]
Code:
List 1    List 2 (result of the ActiveMask.FormationNumber)0         100         F1*0         F1*0         F1*0         00         00         00         10         F1*0         F1*This means not present
The result is that the three enemies are "equal" and the value of the result is 70, which becomes the new Mask for list 1 and that gets pushed to the stack and written in LocalVar:0000.

Then the Enemy ID of each of these masks gets checked and the one with a value of 68 gets saved as the new mask and gets set to LocalVar:0000. Then you have your target mask of enemy 68. Pretty round-about way of doing this. It's just as easy to do
Code: [Select]
Code:
LocalVar:0000 <- ActiveMask.EnemyID == 68
with the same result. 14 bytes vs 35. The caveat to this is that if there are multiple Rufuses, it would target all of them.

We can also see from this that "FormationNumber" is NOT FormationNumber or it would be numbered sequentially with Cloud being 0, Rufus being 4, and Dark Nation being 5. It's more like "Instance" as in, this is the 0th instance of Gagighandi, labeled Gagighandi A when Sensed, and 1st instance of Gagighandi, labeled Gagighandi B. For playable characters this is always 10h + CharacterID. That 1 toward the end? That's an invisible Helicopter actor that is....just there. It doesn't seem to serve any significance.
So Dark Nation is looking for all the zeroth instances of battle actors and then looking for the EnemyID within the results of that. If there were multiple Rufuses, it would only care about the first one.
 
Last edited:
So basically, use the BitCount(Self.FormationNumber) == ActiveMask.FormationNumber variant if there are multiple instances of one enemy and you want to refer to the first of them? Or... in the reverse case, there are multiple instances of your own enemy type, then only the first of you can successfully refer to the boss (the monsters in the Sample:H0512 fight do this)?

Edit: And one thing that would definitely help - can you refer to other instances of your own Enemy ID by using the ActiveMask.EnemyID method and then doing a bitwise AND with NOT Self? I haven't quite understood how exactly masks and lists work yet. Edit2: Okay, just found that Nibel Wolf does that so it should work.
 
Last edited:
So basically, use the BitCount(Self.FormationNumber) == ActiveMask.FormationNumber variant if there are multiple instances of one enemy and you want to refer to the first of them? Or... in the reverse case, there are multiple instances of your own enemy type, then only the first of you can successfully refer to the boss (the monsters in the Sample:H0512 fight do this)?
The first one.
 
Status
Not open for further replies.
Back
Top