Vis_Mage

Novice Magician
Veteran
Joined
Jul 28, 2013
Messages
634
Reaction score
209
First Language
English
Primarily Uses
RMMV
Hello!

Would someone be able to help me out with setting up a few conditions using Yanfly's Battle AI Core plugin?

The conditions that I am looking to check are:

1. If variable A is equal or greater to variable B
2. Check if target has a certain buff/debuff
3. Check is the target has a skill of a specific element
4. Check if the result of a battle formula is greater of equal to the user's current HP.
5. Check is a certain Enemy ID (or name, either works) is currently alive in the troop
6. Check to see if 2 or more troop members or party members has a certain state

I hope I explained this all well enough. If you're not sure what I mean by something, definitely feel free to ask.

Thank you!
 

TheTitan99

Veteran
Veteran
Joined
Nov 2, 2015
Messages
219
Reaction score
104
First Language
English
Primarily Uses
RMMV
Some of this can be done with just the default plugin. Some, though, you'll need a second plugin for.

To check just game information, use the handy dandy Eval checker. So, if you want the enemy to use Skill 50 only when Variable 1 is greater than Variable 2, this would be the notetag:

Code:
<AI Priority>

Eval $gameVariables.value(1) > $gameVariables.value(2): Skill 50

</AI Priority>

The Eval function can be great if you want to check a lot of weird things, or if you want to check complex functions.

However, you also want to check information on specific targets. The Yanfly Ai plugin has trouble with that by default. I use this addon plugin:


This plugin lets you check information on targets, and only have the enemy use a skill if the target is valid.

So, to only use skill 50 on a target that has State 5, you would use this:


Code:
<AI Priority>

 Eval AIManager.targetCondition("target.isStateAffected(5)"): Skill 50

</AI Priority>

This will have the enemy AI only use the skill on a target with that state on it.

As this is just Javascript now, you can get crazier from here. You could check if a target has a certain name. You can have and/or checks, to only use skills on targets that have multiple conditions.

So, to go through each of your points:

1) Eval $gameVariables.value(VAR_ID) > $gameVariables.value(VAR_ID): Skill SKILL_ID

2) Eval AIManager.targetCondition("target.isBuffAffected(BUFF_ID)"): Skill SKILL_ID

3) This one is complicated. If there's only one skill you're looking for, use

Eval AIManager.targetCondition("target.hasSkill(SKILL_CHECK_ID)"): Skill SKILL_ID

If you want to check for a ton of skills, you'd be best using a outside function, say called hasAnyOfTheseSkills(), with the inside of the function being checking for a lot of skills, then run this AI notetag:

Eval AIManager.targetCondition("target.hasAnyOfTheseSkills()"): Skill SKILL_ID

4) I'm not sure. Sorry.

5) Eval AIManager.targetCondition("(target.enemyId() == ENEMY_ID && target.isStateAffected(DEATH_STATE))"): Skill SKILL_ID

6) I guess you could write an outside function to go into the Eval, the function being a loop that checks every member of $gameTroop, seeing if at least two of the members return true on isStateAffected(STATE_ID). There may be a better way of doing that.
 

Vis_Mage

Novice Magician
Veteran
Joined
Jul 28, 2013
Messages
634
Reaction score
209
First Language
English
Primarily Uses
RMMV
Thank you for all your help! :kaothx:

I do have a couple of questions regarding the solutions, if you don't mind.

Regarding number 5, will this eval work for skills that don't actually target the enemyID that is being checked (and instead, whether that enemyID is still alive just acts as a condition on whether or not the enemy can use that skill)? Also, is there a way to check if multiple of that enemyID is alive?

In the same vein as above, for number 2, is it possible to check for a buff or state, while not necessarily targeting the person with the buff/state?

Also, for number 6, could you go into a little more detail on what you mean by an outside function?
 

TheTitan99

Veteran
Veteran
Joined
Nov 2, 2015
Messages
219
Reaction score
104
First Language
English
Primarily Uses
RMMV
No worries!

As written, #5 will check only that target, and it'll use the skill on that target. So, the way it's written right now, I guess it's really more of use for revive spells. If you want to use the skill when a specific enemy is dead, but have it not target the dead battler, then use this:

Code:
Eval $gameTroop.members()[ENEMY_PLACEMENT_IN_TROOP].isStateAffected(DEATH_STATE): Skill SKILL_ID

That'll check if, say, Enemy 1 in the troop is dead, or Enemy 2, or whatever spot you select. This isn't a dynamic system, it's always checking if that one enemy is dead.

If you want to check if there is any dead enemy, use this:

Code:
Eval $gameTroop.deadMembers().length > 0: Skill SKILL_ID

That'll run when there's at least 1 dead enemy, though it doesn't matter what enemy is dead.

What I mean by outside function is... say, see this enemy AI command:

Code:
Eval twoOrMoreInTroop(STATE_ID): Skill SKILL_ID

The function twoOrMoreInTroop() doesn't exist by default. However, you could write the function in a plugin! I do this all the time for more complex checks, especially in damage formulas.

This is an example of the function, though you can write whatever you want here:

Code:
twoOrMoreInTroop = function(nState) {

    var n = 0;

    for (var i = 0; i < $gameTroop.aliveMembers().length; ++i) {
       if ($gameTroop.aliveMembers()[i].isStateAffected(nState))
         n = n + 1;
    }

    if(n >= 2)
        return true;
    else
        return false;
};

Keep in mind, there are MUCH better ways of writing the above code. I want to make it easier to read, so I'm using some sloppier coding to make it easy to read.

What this function will do is go through all living enemies in the battle, and check if that are under the state nState. You decide what the variable nState is, based on whatever number you put in the enemy AI command.

If at least 2 enemies are under the state, then the function is true, and the AI command will run. Otherwise, the function is false, and the AI command will not run.

By using functions like this, you can make AI evaluations as complex as you want. As long as the function returns either true or false in the end, it can be as convoluted as you want. You could have a function that checks if the combined number of letters in the bio of all living actors is more than 400 words. I... don't know WHY you would want to check that, but by writing a function, you could!
 

Vis_Mage

Novice Magician
Veteran
Joined
Jul 28, 2013
Messages
634
Reaction score
209
First Language
English
Primarily Uses
RMMV
Sorry for the late response, have been away for holidays the last few days.

Thank you very much for all of your help! :kaoblush:

One last question regarding the function, in the line:
$gameTroop.aliveMembers().length; ++i
What does the ++i do exactly? If I were to create a copy of this function for checking the party for states, would just replacing Troop with Party still work?
 

TheTitan99

Veteran
Veteran
Joined
Nov 2, 2015
Messages
219
Reaction score
104
First Language
English
Primarily Uses
RMMV
Don't feel like you need to apologize! I'm happy to help.

So, that is a "for loop". I'm not sure how much or how little you know about Javascript, so you may or may not know this stuff already. Sorry if I'm covering what you know!

A for loop runs a bunch a code a number of times. I'll break down this code:

Code:
for (var i = 0; i < $gameTroop.aliveMembers().length; ++i) {
       if ($gameTroop.aliveMembers()[i].isStateAffected(nState))
         n = n + 1;
    }

There is a variable, called "i". i is set, initially, to 0. The for loop is set to run over and over again for each enemy that is alive. So, if there are 3 alive enemies, the for loop will run 3 times.

++i is a phrase that adds 1 to the variable i. That's what makes the loop only happen 3 times, instead of infinitely.

So, to break down the for loop into common language:

Code:
for (variable "i" starts at 0; loop while variable "i" is less than the number of living enemies; add 1 to variable "i" after every loop) {
       if (enemy in slot "i" is effected by the chosen state)
         add 1 to variable "n";
    }

The thing about $gameTroop, is that the 1st enemy is considered Enemy 0, the second enemy is Enemy 1, and so on. That's why the for loop starts at 0, and continues while the variable is less than the length. Because, if there are three enemies, the final Enemy will be in slot 2, not slot 3.

I hope that helps! And I hope I'm not getting anything wrong! Most of Javascript I learned through RPG Maker, so I hope I'm no getting anything wrong here!

(And I am repeating the fact that the code I'm giving you is meant to be easy to read and edit. There is much smoother code that you could write, but it gets harder to read. Many times, you can compress multiple lines of code into a single line. I'm not doing that here, to make it all easier to read.)

For more information on for loops, check out this helpful link:


That website is great for learning Javascript in general (as well as other programming languages). This specific page is on for loops.

To answer your second question, yes, $gameParty is the actor based equivalent to $gameTroop. In fact, you don't even need to copt the function. You can just use one function, like this:

Code:
twoOrMoreInUnit = function(nState, nUnit) {

    var n = 0;

    for (var i = 0; i < nUnit.aliveMembers().length; ++i) {
       if (nUnit.aliveMembers()[i].isStateAffected(nState))
         n = n + 1;
    }

    if(n >= 2)
        return true;
    else
        return false;
};

This function now can check either $gameTroop or $gameParty. Just insert either you want into the parameters.

So, to check if there are at least 2 enemies effected by state 5, use this:

twoOrMoreInUnit(5, $gameTroop);

Or, to check if there are at least 2 actors in the party effected by state 8, use this:

twoOrMoreInUnit(8, $gameParty);
 

Vis_Mage

Novice Magician
Veteran
Joined
Jul 28, 2013
Messages
634
Reaction score
209
First Language
English
Primarily Uses
RMMV
Thank you for taking the time to explain all of that for me. My JavaScript knowledge doesn't go much further than stumbling through eval notetags for some of Yanfly's plugins, so this has been very helpful.

Looking over what you have, I took a shot at building on it a bit too. I've tried to add an option to set how many units would need the state, so that the code unitStateCheck(5, $gameTroop, 3); would check for 3 or more enemies with state 5, for example. Does this look like it would work?

Code:
unitStateCheck = function(nState, nUnit, nCount) {

    var n = 0;

    for (var i = 0; i < nUnit.aliveMembers().length; ++i) {
       if (nUnit.aliveMembers()[i].isStateAffected(nState))
         n = n + 1;
    }

    if(n >= nCount)
        return true;
    else
        return false;
};
 

TheTitan99

Veteran
Veteran
Joined
Nov 2, 2015
Messages
219
Reaction score
104
First Language
English
Primarily Uses
RMMV
That seems like it'll work, yes! You'll need to test it for sure, but that seems like it'll work.
 

Latest Threads

Latest Posts

Latest Profile Posts

Squashing some bugs before releasing plugin :LZScool:The testing phase is taking more time than what I expected...
On cloud 9. My latest game got a 4/5 review today :)

Forum statistics

Threads
110,323
Messages
1,052,344
Members
143,360
Latest member
Jesse94
Top