Author Topic: [FFVII] AI script "selector" opcodes' actual function?  (Read 3219 times)

Husbjörn

  • *
  • Posts: 36
    • View Profile
I wonder if someone would be able to elaborate on exactly how the "select greatest / least from list" instructions (opcodes 0x84 and 0x85) work?
Let's take an example of trying to select an opponent with the lowest HP to illustrate my point:


02    20b0                # Push current actor's active enemy mask
03    4160                # Push offset to HP value of (target) actor(s) as given in the above mask
80                        # Pop last two values from the stack and push a list of all HP values for the current actor's active enemies
85                        # Select the lowest value(s?) from the list at the top of the stack


I would have assumed that the above would push a 16-bit mask onto the stack with the bit corresponding to the enemy actor with the lowest HP set.
This does not seem to be the case however as more than one bit seems to be set. I could kind of understand if this happened if two actors had the same health which also happened to be the lowest but that is not the case. I then thought that it might push the actual index corresponding to the bit to be set instead (such that it for example pushes 3 for actor 3, rather than a 0%0010 mask) but that doesn't seem to be it either. The last possibility I can imagine is that it pushes the actual lowest HP value, but if this was the case what good is the instruction? While it would be possible to get the actual lowest HP value if we knew the actor to whom it belonged, the same cannot be done in reverse.
Or am I missing the point of these instructions entirely?


Another kind of associated question while we're at it, are lists on the stack formed in some way that they can be manually constructed (or read) by pushing / popping values / addresses or are they their own thing beyond manual control from a script perspective? I am guessing the latter since they tend to be described merely as "datatype 2X".
« Last Edit: 2015-06-01 14:57:28 by Husbjörn »

Ansem

  • *
  • Posts: 136
    • View Profile
Re: [FFVII] AI script "selector" opcodes' actual function?
« Reply #1 on: 2015-06-01 15:16:11 »
EDIT: Nevermind, totally missed the question here.
« Last Edit: 2015-06-01 15:20:26 by Ansem Darkseeker »

nfitc1

  • *
  • Posts: 3011
  • I just don't know what went wrong.
    • View Profile
    • WM/PrC Blog
Re: [FFVII] AI script "selector" opcodes' actual function?
« Reply #2 on: 2015-06-01 17:33:08 »
80 will determine the 4XXX values (determined by the first pop) of all actors that have active bits in the second pop. For your example, let's say that an enemy runs that code and party member 1 is dead:

(this gets pushed to the stack)
Actor 0: 345
Actor 1: 65535 (this is universally considered to be a non-value so doesn't meet the "greatest value" criteria)
Actor 2: 144
Actor 3: 65535
Actor 4: 65535
Actor 5: 65535
Actor 6: 65535
Actor 7: 65535
Actor 8: 65535
Actor 9: 65535

Then, 85 pulls that entire list and creates an identical list with the bit mask of that actor indicating whether or not that actor fits the parameter:

(this gets pushed to the stack)
Actor 0: 0
Actor 1: 0
Actor 2: 2
Actor 3: 0
Actor 4: 0
Actor 5: 0
Actor 6: 0
Actor 7: 0
Actor 8: 0
Actor 9: 0

Confusing, I know. The next opcode to pop a value will decide what to do with this set. They might do a bit-wise OR or perhaps just take the top value and ignore the rest.

I tried to type up some C-based structure for the stack, but I just can't figure it out. It is a list of pairings: a type, and a value. The types are either magnitude (raw numbers), addresses( usually between 0000 and 4260, but can go all the way to FFFF), or Actor Masks (type 2X) as mentioned.
If you know how each opcode handles values on the stack it's completely possible to construct it at any point in the program flow. I've done it lots of times.

Husbjörn

  • *
  • Posts: 36
    • View Profile
Re: [FFVII] AI script "selector" opcodes' actual function?
« Reply #3 on: 2015-06-02 09:57:01 »
Ah, so that's how it goes... quite confusing indeed, I would probably not have guessed that. Thanks a lot for clearing it up.

Regarding the lists, I take that to mean that you cannot explicitly create one from within an AI script then, since all your pushes will have an automatic data type set and you cannot set this to the list/item identifier?
I suppose you could work around this by temporarily changing some actor values, having the battle engine populate a list with those values and then reset them to their previous values though, is this what you were implying with this quote?
Quote
If you know how each opcode handles values on the stack it's completely possible to construct it at any point in the program flow. I've done it lots of times.


Again, thanks for the rundown :)

nfitc1

  • *
  • Posts: 3011
  • I just don't know what went wrong.
    • View Profile
    • WM/PrC Blog
Re: [FFVII] AI script "selector" opcodes' actual function?
« Reply #4 on: 2015-06-02 13:31:38 »
I'm not sure why you'd want to create one of these entries manually. You certainly can't do it one value at a time, the 2X entries are all-or-nothing things.

Husbjörn

  • *
  • Posts: 36
    • View Profile
Re: [FFVII] AI script "selector" opcodes' actual function?
« Reply #5 on: 2015-06-02 21:30:22 »
Yeah, I figured as much.
No particular reason, just considering whether it would be possible for any possible future situation, but it's quite likely you would never have a need to do that. I'm still kind of new to this and I like to know what is available in the tool set so to say.