You have two options for that :
1) Either you make it a counter. This way, Baku won't waste his turn and will also attack after buffing himself. It's also the safest way to make sure that Baku buffs himself as soon as he gets under 20-25% of max HP.
2) Either you make it a regular move that he'll use instead of a regular attack. If you do it this way, Baku might be tricked by the player to delay his buffing: if the player inputs his attack right before Baku's ATB gets full, he will receive damage after his ATB got full and thus after selecting his move. So he will attack once more (and not buffing himself) even though he's under 20-25% HP. That's kind of a subtility but it's used in speedrun, for instance, to avoid Beatrix 3 healing herself.
For the option 1), you'll do a "Baku_Counter" function.
For the option 2), you'll modify "Baku_ATB" function.
I'll develop the option 1).
- Right click on the function list and chose to add a function for the Baku's entry and of type 6 (counter).
- You want Baku to use his move only when he's under 20-25% HP. Normally, you'd write it like this :
if (FirstOf(SV_FunctionEnemy[HP]) < (FirstOf(SV_FunctionEnemy[MAX_HP])/4)) {
set SV_Target = SV_FunctionEnemy
Attack( 5 ) // or whichever attack ID your buff is
}
return
However, like a lot of bosses, Baku's HP in game are not his real HP. He has 10000 more HP than normally and ends the battle automatically as soon as he gets under 10000.
So the condition is more like this :
if ((FirstOf(SV_FunctionEnemy[HP]) - 10000) < ((FirstOf(SV_FunctionEnemy[MAX_HP]) - 10000) / 4))
Now, there's one more choice for you : as it is, Baku will buff himself every turn as long as he is under 25% HP. You may want him to buff himself only once it the whole fight (in which case, you'll need a local variable serving as a flag) or only if his buff has expired (in which case, you don't need a local variable).
The latter case is done with this kind of condition :
if (!(Matching(SV_FunctionEnemy[STATUS_CURRENT_A], 8388608L) )) {
// Perform the buffing
}
8388608L is the status ID of Protect. So this condition is fulfilled if Baku doesn't have Protect.
To easily get the good ID associated with a status, look at the "Status List A/B" informations on the bottom left of the script window. You can write a status name there and press Enter : it will write the corresponding ID in the code.
The former case (Baku buffs himself only once), you need to declare a local variable in the local variable panel. By default, Baku's script use 34 bytes for local variables (hence the "allocate 34" line you see). Declare your own with these lines :
allocate 35
local uint8 flag_for_baku_buff VAR_B7_34
One of the advantages of importing the file "LocalVariableSettings_v1.hws" is that all the other local variables are already declared and given a name. In that situation, you can ignore the last word and write only "local uint8 flag_for_baku_buff" to declare a local variable. The tool will automatically give it an unused ID ("VAR_B7_34" in this case).
Now, the whole counter function can be written like this :
if ((!flag_for_baku_buff) && (FirstOf(SV_FunctionEnemy[HP]) - 10000) < ((FirstOf(SV_FunctionEnemy[MAX_HP]) - 10000) / 4)) {
set SV_Target = SV_FunctionEnemy
Attack( 5 ) // or whichever attack ID your buff is
set flag_for_baku_buff = 1
}
return
If you go for the option 1), you basically have to do this in the ATB function instead, either at the very beginning, either at the end before the "Attack" line.
if ( Your Condition ) {
set SV_Target = SV_FunctionEnemy
Attack( 5 ) // or whichever attack ID your buff is
return
}
// ... the rest of the function
I hope that you (and other people) will have a better grasp on the AI system after that
I would like to make tutorials for that kind of stuff someday.