1691 lines
62 KiB
JavaScript
1691 lines
62 KiB
JavaScript
//=============================================================================
|
||
// Yanfly Engine Plugins - Battle Artificial Intelligence Core
|
||
// YEP_BattleAICore.js
|
||
//=============================================================================
|
||
|
||
var Imported = Imported || {};
|
||
Imported.YEP_BattleAICore = true;
|
||
|
||
var Yanfly = Yanfly || {};
|
||
Yanfly.CoreAI = Yanfly.CoreAI || {};
|
||
Yanfly.CoreAI.version = 1.15;
|
||
|
||
//=============================================================================
|
||
/*:
|
||
* @plugindesc v1.15 This plugin allows you to structure battle A.I.
|
||
* patterns with more control.
|
||
* @author Yanfly Engine Plugins
|
||
*
|
||
* @param Dynamic Actions
|
||
* @type boolean
|
||
* @on YES
|
||
* @off NO
|
||
* @desc If enabled, enemy actions are decided on the spot instead
|
||
* of at the start of turn. NO - false YES - true
|
||
* @default true
|
||
*
|
||
* @param Dynamic Turn Count
|
||
* @type boolean
|
||
* @on YES
|
||
* @off NO
|
||
* @desc Decide if the turn count dynamic is counted for earlier or later.
|
||
* true - Current Turn + 1 false - Current Turn
|
||
* @default false
|
||
*
|
||
* @param Element Testing
|
||
* @type boolean
|
||
* @on YES
|
||
* @off NO
|
||
* @desc If enabled, enemies will test actors on their elements by
|
||
* setting them to match first. NO - false YES - true
|
||
* @default true
|
||
*
|
||
* @param Default AI Level
|
||
* @type number
|
||
* @min 0
|
||
* @max 100
|
||
* @desc This is the default AI level of all enemies.
|
||
* Level 0: Very Random Level 100: Very Strict
|
||
* @default 80
|
||
*
|
||
* @help
|
||
* ============================================================================
|
||
* Introduction
|
||
* ============================================================================
|
||
*
|
||
* RPG Maker MV's default enemy AI is a bit lackluster even if you managed to
|
||
* have it based completely on the rates and switches. There is no way to
|
||
* control the way the enemy chooses targets by default, nor are the conditions
|
||
* imposed by the default editor enough to satisfy the majority of checks. This
|
||
* plugin enables you to set a priority list of conditions, actions, and the
|
||
* targets selected for the enemy to go through before making a decision on how
|
||
* to participate in battle.
|
||
*
|
||
* These conditions contain all of the default editor's conditions plus more,
|
||
* such as determining the parameter values of a target, whether or not a state
|
||
* exists on a target, the target's elemental weakness (or resistances), and
|
||
* more before deciding an action. Furthermore, you can set an AI level for the
|
||
* enemies to make them more consistent in the way they go about fighting your
|
||
* players or more random in the way the enemies treat the priority list, too.
|
||
*
|
||
* ============================================================================
|
||
* Parameters
|
||
* ============================================================================
|
||
*
|
||
* Dynamic Actions
|
||
* By default, the enemy's actions are determined at the start of the turn.
|
||
* While this works in its own right, enabling Dynamic Actions allow enemies
|
||
* to make a decision when the enemy's turn comes up instead. This prompts
|
||
* enemies to be more flexible and to appear more intelligent in battle, thus,
|
||
* giving your players a bit more of a challenge.
|
||
*
|
||
* Element Testing
|
||
* If this is disabled, enemies will automatically know the elemental weakness,
|
||
* resistance, etc. about all actors. If enabled, enemies will need to test out
|
||
* the skills on various actors first before making a decision. Until the enemy
|
||
* learns about the actor's elemental rates, the enemy is always willing to try
|
||
* using the skill on the target actor. However, if the skill itself does not
|
||
* possess an element, then no information will be registered. All elemental
|
||
* data is reset at the start of each battle for all enemy parties.
|
||
*
|
||
* Default AI Level
|
||
* Not all enemies are intelligent. In fact, some of them are dumb or random.
|
||
* Setting the AI Level of a foe at a low number means the foe is more random
|
||
* while a higher AI Level foe is more consistent. How the AI Level works is,
|
||
* a random number will be checked from 0 to 99. If that enemy's AI Level is
|
||
* higher than that number, that action is checked to see if the condition is
|
||
* fulfilled or not. If the AI Level is lower than that number, the condition
|
||
* is automatically deemed false and continues on to the next action. The check
|
||
* is ran each time a new action is checked upon. This random factor is only
|
||
* applied to <AI Priority> lists and do not apply to default actions.
|
||
*
|
||
* ============================================================================
|
||
* Enemy AI Level
|
||
* ============================================================================
|
||
*
|
||
* Enemy AI levels do not determine how difficult they are. Instead, they
|
||
* determine how strictly they will follow the <AI Priority> lists. An AI Level
|
||
* of 80 means it has an 80% chance of following the prioritized action on the
|
||
* AI Priority list before moving onto the next one where there will be another
|
||
* 80% chance and so on. If the AI level is lower, the chance is lower, making
|
||
* the AI to be more random.
|
||
*
|
||
* Enemy Notetag:
|
||
* <AI Level: x>
|
||
* Sets the enemy's AI level to x. The lower x, the more random the enemy.
|
||
* The higher for x, the more strict the enemy is about following the AI
|
||
* Priority list found in its notebox, too.
|
||
*
|
||
* ============================================================================
|
||
* Enemy AI Priority
|
||
* ============================================================================
|
||
*
|
||
* If an enemy has an AI Priority list, the enemy will go down that list from
|
||
* top to bottom (giving the actions at the top more priority than the ones at
|
||
* the bottom) looking for any actions whose conditions are fulfilled. If that
|
||
* condition is fulfilled, then that action will be the action the enemy will
|
||
* partake in.
|
||
*
|
||
* To set up a Priority List for the enemy, you must place inside the enemy's
|
||
* notebox notetags that match the following format:
|
||
*
|
||
* <AI Priority> <AI Priority>
|
||
* condition: SKILL x, target or condition: skill name, target
|
||
* condition: SKILL x, target condition: skill name, target
|
||
* </AI Priority> </AI Priority>
|
||
*
|
||
* Any number of conditions and skills can be placed in between the two
|
||
* <AI Priority> tags. You can choose to use skill ID's or the skill names.
|
||
* However, if you use the skill names, keep in mind that it is not case
|
||
* sensitive and if any skills in your database have matching names, the skill
|
||
* with the larger skill ID will be the action used.
|
||
*
|
||
* ============================================================================
|
||
* Conditions
|
||
* ============================================================================
|
||
*
|
||
* The following is a list of ways you can format your conditions for the enemy
|
||
* to choose the right skill. In addition to deciding whether or not the skill
|
||
* will be used, the condition also selects the enemy target. The following
|
||
* list will tell you how the conditions are met and what targets will be
|
||
* selected for battle.
|
||
*
|
||
* =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
|
||
* ALWAYS
|
||
*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||
* This condition will always be fulfilled. The valid target group is all
|
||
* targets within scope.
|
||
*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||
* Example: Always: Skill 10, Lowest HP%
|
||
* =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
|
||
*
|
||
* =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
|
||
* ELEMENT X case
|
||
*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||
* This allows you to match the element rate of element X (use either a number
|
||
* or the name of the element in place of 'X') to see whether or not the
|
||
* conditions for the action are fulfilled. Replace 'case' with 'Neutral' for
|
||
* normal element rate (under 110% and above 90%), 'Weakness' for anything
|
||
* above 100% element rate, 'Resistant' for below 100% element rate, 'Null' for
|
||
* 0% element rate, and 'Absorb' for below 0% element rate. Valid targets will
|
||
* be those with the matching element rates.
|
||
*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||
* Example: Element Fire Weakness: Fireball, Lowest HP%
|
||
* Element Water Resistant: Water Cancel, Highest MAT
|
||
* Element 4 Null: Earthquake, Lowest MDF
|
||
* =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
|
||
*
|
||
* =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
|
||
* EVAL eval
|
||
*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||
* This allows you to use any kind of code to check and fulfill a condition.
|
||
* This condition uses all alive members of the skill's scope as valid targets.
|
||
*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||
* Example: Eval user.name() === 'Bat A': Skill 10, Highest HP%
|
||
* =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
|
||
*
|
||
* =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
|
||
* group ALIVE MEMBERS eval
|
||
*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||
* Replace 'group' with either 'party' for the player's party or 'troop' for
|
||
* the enemy party. This runs the number of party alive members or troop alive
|
||
* members in a check to see if the conditions can be fulfilled.
|
||
*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||
* Example: Party Alive Members > 2: Skill 10, Lowest HP%
|
||
* Troop Alive Members <= 4: Skill 11, Highest HP%
|
||
* Troop Alive Members === $gameVariables.value(3): Skill 12, Random
|
||
* =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
|
||
*
|
||
* =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
|
||
* group DEAD MEMBERS eval
|
||
*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||
* Replace 'group' with either 'party' for the player's party or 'troop' for
|
||
* the enemy party. This runs the number of party dead members or troop dead
|
||
* members in a check to see if the conditions can be fulfilled.
|
||
*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||
* Example: Party Dead Members > 2: Undead, Highest ATK
|
||
* Troop Dead Members <= 4: Life, Highest ATK
|
||
* Troop Dead Members === $gameVariables.value(3): Skill 12, Random
|
||
* =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
|
||
*
|
||
* =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
|
||
* stat PARAM eval
|
||
*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||
* Replace 'stat' with either 'atk', 'def', 'mat', 'mdf', 'agi', 'luk',
|
||
* 'maxhp', 'maxmp', 'hp', 'mp', 'hp%', 'mp%', or 'level' to run it in a
|
||
* condition check again to see if the action gets passed. The group that it
|
||
* checks will be based on the skill's scope. If the skill targets foes, then
|
||
* all foes will take a check to see if they fulfill the conditions. Likewise
|
||
* for party members if the skill is for allies. The valid targets will be
|
||
* those who pass the condition check.
|
||
*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||
* Example: HP% param <= 50%: Heal, Lowest HP%
|
||
* MP param > 90: Mana Drain, Highest MP
|
||
* ATK param > user.atk: Power Break, Highest ATK
|
||
* =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
|
||
*
|
||
* =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
|
||
* type PARTY LEVEL eval
|
||
*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||
* Replace 'type' with either 'highest', 'lowest', or 'average' to get the
|
||
* respective party level for the skill's scope. This will reference the entire
|
||
* party's level. If this condition is fulfilled, all targets would become
|
||
* valid targets.
|
||
*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||
* Example: Highest Party Level > 10: Skill 10, Lowest MP%
|
||
* Lowest Party Level < 12: Skill 11, Lowest HP%
|
||
* Average Party Level > 15: Skill 12, Highest HP%
|
||
* =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
|
||
*
|
||
* =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
|
||
* RANDOM x%
|
||
*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||
* This will make the condition based on a random x percent chance. This
|
||
* condition allows all possible targets to be valid for targeting.
|
||
*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||
* Example: Random 50%: Skill 10, Lowest HP%
|
||
* Random 75%: Skill 11, Highest HP%
|
||
* =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
|
||
*
|
||
* =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
|
||
* STATE === state x
|
||
* STATE === state name
|
||
*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||
* This will detect if the target scope has state x (or state name if you use
|
||
* that instead). If the target does, that target is added into the pool of
|
||
* valid targets. Any targets not affected by the state will be ignored.
|
||
*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||
* Example: State === State 5: DeBlind, Highest ATK
|
||
* State === Knockout: Life, Random
|
||
* =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
|
||
*
|
||
* =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
|
||
* STATE !== state x
|
||
* STATE !== state name
|
||
*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||
* This will detect if the target scope does not have state x (or state name if
|
||
* you use that instead). If the target doesn't, that target is added into the
|
||
* pool of valid targets. Any targets affected by the state will be ignored.
|
||
*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||
* Example: State !== State 12: Haste, Random
|
||
* State !== Courage: Cowardice, Highest ATK
|
||
* =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
|
||
*
|
||
* =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
|
||
* SWITCH X case
|
||
*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||
* Replace 'x' with the ID of the switch you wish to check. Replace 'case' with
|
||
* either 'on' or 'off' (you may also use 'true' or 'false'). If the switch
|
||
* matches the case, the condition is fulfilled and all skill targets become
|
||
* valid targets.
|
||
*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||
* Example: Switch 5 On: Skill 10, Lowest HP%
|
||
* Switch 6 Off: Skill 11, Highest HP%
|
||
* =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
|
||
*
|
||
* =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
|
||
* TURN eval
|
||
*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||
* This will make the condition based on the turn count to be fulfilled by an
|
||
* eval statement. This condition allows all possible targets to be valid for
|
||
* targeting.
|
||
*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||
* Example: Turn > 3: Skill 10, Lowest hp%
|
||
* Turn === 4: Skill 11, Highest hp%
|
||
* Turn <= $gameVariables.value(2): Skill 12, Random
|
||
* =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
|
||
*
|
||
* =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
|
||
* USER stat PARAM eval
|
||
*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||
* Replace 'stat' with either 'atk', 'def', 'mat', 'mdf', 'agi', 'luk',
|
||
* 'maxhp', 'maxmp', 'hp', 'mp', 'hp%', 'mp%', or 'level' to run it in a
|
||
* condition check again to see if the action gets passed. If the user's param
|
||
* matches the conditions, the check is fulfilled.
|
||
*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||
* Example: User HP% param <= 50%: Heal, Lowest HP%
|
||
* User MP param > 90: Mana Drain, Highest MP
|
||
* User ATK param > user.atk: Power Break, Highest ATK
|
||
* =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
|
||
*
|
||
* =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
|
||
* VARIABLE X eval
|
||
*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||
* This will call forth the value of variable 'x' to partake in an eval
|
||
* comparison to see if the condition is fulfilled. If it is, all skill targets
|
||
* become valid targets.
|
||
*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||
* Example: Variable 3 > 10: Skill 10, Lowest HP%
|
||
* Variable 5 <= 100: Skill 11, Highest HP%
|
||
* Variable 2 === user.atk: Skill 12
|
||
* =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
|
||
*
|
||
* ============================================================================
|
||
* Multiple Conditions
|
||
* ============================================================================
|
||
*
|
||
* As of the version 1.11 update, the Battle A.I. Core is now able to support
|
||
* multiple conditions. Setting up multiple conditions is relatively simple to
|
||
* do and still follows the 'condition: SKILL x, target' format.
|
||
*
|
||
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||
*
|
||
* To add multiple conditions, simply insert a +++ between each condition like
|
||
* the following examples:
|
||
*
|
||
* Switch 1 on +++ Switch 2 on: Fire, Lowest HP%
|
||
* Turn 3 > 1 +++ Variable 5 <= 100 +++ Switch 3 on: Ice, Lowest HP%
|
||
* Random 50% +++ Highest Party Level > 50: Thunder, Highest HP%
|
||
*
|
||
* In the above examples, all the conditions must be met in order for the
|
||
* selected skills to be considered for use.
|
||
*
|
||
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||
*
|
||
* For conditions that have strict targeting groups, the targeting group will
|
||
* end up becoming the combination of all of the strict targeting groups. For
|
||
* example:
|
||
*
|
||
* STATE === Blind +++ STATE === Fear: Dark, Lowest HP%
|
||
*
|
||
* In this example, the enemy will only use the 'Dark' skill on a target that
|
||
* is both affected by 'Blind' and 'Fear'. If there are multiple targets, then
|
||
* the target with the lowest HP% will become the target the enemy will cast
|
||
* the 'Dark' on.
|
||
*
|
||
* STATE !== Blind +++ ATK param >= 150: Darkness, Highest ATK
|
||
*
|
||
* In the above example, the enemy will use the 'Darkness' skill against any
|
||
* target that isn't blinded and has an ATK parameter of at least 150. If there
|
||
* are multiple targets, then the enemy will first cast 'Darkness' on the
|
||
* target with the highest ATK before casting it on a target with a lower ATK.
|
||
*
|
||
* ============================================================================
|
||
* Targeting
|
||
* ============================================================================
|
||
*
|
||
* Targeting is optional but can be done via a small change to the condition.
|
||
* All you have to do is add a ',' after the skill to indicate which target in
|
||
* the valid target group you would like to target. For example:
|
||
*
|
||
* Random 50%: Fire, Highest HP%
|
||
*
|
||
* The condition to be met is the 50% random chance, but if it is fulfilled,
|
||
* the target selected will be the member on the targeting scope's team with
|
||
* the highest HP percentage. When that happens, the 'Fire' skill will be used
|
||
* upon that target.
|
||
*
|
||
* If no target is specified, a random target will be selected amongst the
|
||
* group of valid targets. Otherwise, refer to the following list:
|
||
*
|
||
* ----------------------------------------------------------------------------
|
||
* <<nothing>> Selects a random member of the valid target group.
|
||
* First Selects first member of the valid target group.
|
||
* User Selects the user itself.
|
||
* Highest MaxHP Selects highest MaxHP valid target.
|
||
* Highest HP Selects highest HP valid target.
|
||
* Highest HP% Selects highest HP% valid target. *Note1
|
||
* Highest MaxMP Selects highest MaxMP valid target.
|
||
* Highest MP Selects highest MP valid target.
|
||
* Highest MP% Selects highest MP% valid target. *Note1
|
||
* Highest MaxTP Selects highest MaxTP valid target.
|
||
* Highest TP Selects highest TP valid target.
|
||
* Highest TP% Selects highest TP% valid target. *Note1
|
||
* Highest ATK Selects highest ATK valid target.
|
||
* Highest DEF Selects highest DEF valid target.
|
||
* Highest MAT Selects highest MAT valid target.
|
||
* Highest MDF Selects highest MDF valid target.
|
||
* Highest AGI Selects highest AGI valid target.
|
||
* Highest LUK Selects highest LUK valid target.
|
||
* Highest Level Selects highest Level valid target. *Note2
|
||
* Lowest MaxHP Selects lowest MaxHP valid target.
|
||
* Lowest HP Selects lowest HP valid target.
|
||
* Lowest HP% Selects lowest HP% valid target. *Note1
|
||
* Lowest MaxMP Selects lowest MaxMP valid target.
|
||
* Lowest MP Selects lowest MP valid target.
|
||
* Lowest MP% Selects lowest MP% valid target. *Note1
|
||
* Lowest MaxTP Selects lowest MaxMP valid target.
|
||
* Lowest TP Selects lowest MP valid target.
|
||
* Lowest TP% Selects lowest MP% valid target. *Note1
|
||
* Lowest ATK Selects lowest ATK valid target.
|
||
* Lowest DEF Selects lowest DEF valid target.
|
||
* Lowest MAT Selects lowest MAT valid target.
|
||
* Lowest MDF Selects lowest MDF valid target.
|
||
* Lowest AGI Selects lowest AGI valid target.
|
||
* Lowest LUK Selects lowest LUK valid target.
|
||
* Lowest Level Selects lowest Level valid target. *Note2
|
||
*
|
||
* Note1: This is calculated by dividing the current HP with the MaxHP or the
|
||
* current MP with the MaxMP.
|
||
*
|
||
* Note2: If this is used on an enemy without a proper enemy level plugin
|
||
* installed, this will return the player party's highest level.
|
||
*
|
||
* ----------------------------------------------------------------------------
|
||
*
|
||
* ============================================================================
|
||
* Special Notes
|
||
* ============================================================================
|
||
*
|
||
* If you are using YEP_Taunt.js, enemies will automatically not factor in
|
||
* taunts by default. For that matter, targets can be protected by taunts
|
||
* effects, which can effectively shut down an enemy's AI performance. However,
|
||
* if you want some enemies to consider the taunt effects of an opponent,
|
||
* place this notetag inside of the enemy's notebox:
|
||
*
|
||
* <AI Consider Taunt>
|
||
*
|
||
* This will make it that when an enemy makes a decision, it will make a right
|
||
* decision while thinking of the taunted enemies, too. You can use this for
|
||
* smarter enemies while keep this notetag disabled for less intelligent foes.
|
||
*
|
||
* ============================================================================
|
||
* Changelog
|
||
* ============================================================================
|
||
*
|
||
* Version 1.15:
|
||
* - Fixed a bug that caused some TP conditions to not work properly.
|
||
*
|
||
* Version 1.14:
|
||
* - Bypass the isDevToolsOpen() error when bad code is inserted into a script
|
||
* call or custom Lunatic Mode code segment due to updating to MV 1.6.1.
|
||
*
|
||
* Version 1.13:
|
||
* - Updated for RPG Maker MV version 1.5.0.
|
||
*
|
||
* Version 1.12:
|
||
* - Added 'Dynamic Turn Count' plugin parameter for those who wish to push the
|
||
* turn count further by 1 turn in order to adjust for Dynamic Actions. Code
|
||
* provided by Talonos.
|
||
*
|
||
* Version 1.11:
|
||
* - Adding the ability to support multiple conditions. Please Read the
|
||
* 'Multiple Conditions' section in the help file for more details.
|
||
*
|
||
* Version 1.10:
|
||
* - Lunatic Mode fail safes added.
|
||
*
|
||
* Version 1.09:
|
||
* - Added 'user' to the list of valid skill targets.
|
||
* - Added 'USER stat PARAM eval' to valid conditions.
|
||
*
|
||
* Version 1.08:
|
||
* - Neutral elemental resistance is now considered to be above 90% and under
|
||
* 110% for a better range of activation.
|
||
* - Optimization update.
|
||
*
|
||
* Version 1.07:
|
||
* - Fixed a compatibility bug that caused certain conditions to bypass taunts.
|
||
*
|
||
* Version 1.06:
|
||
* - Fixed a bug that caused 'Highest TP' and 'Lowest TP' target searches to
|
||
* crash the game.
|
||
*
|
||
* Version 1.05:
|
||
* - Updated for RPG Maker MV version 1.1.0.
|
||
*
|
||
* Version 1.04a:
|
||
* - Fixed a bug that would cause a crash with the None scope for skills.
|
||
* - Switched over a function to operate in another for better optimization.
|
||
*
|
||
* Version 1.03:
|
||
* - Fixed a bug that returned the wrong MP% rate.
|
||
*
|
||
* Version 1.02:
|
||
* - Fixed a bug that targeted the highest parameter enemy instead of lowest.
|
||
*
|
||
* Version 1.01:
|
||
* - Added 'MaxTP' and 'TP' to targets.
|
||
* - Compatibility update with Battle Engine Core v1.19+. Turn settings are now
|
||
* based 'AI Self Turns' if the enabled.
|
||
*
|
||
* Version 1.00:
|
||
* - Finished Plugin!
|
||
*/
|
||
//=============================================================================
|
||
|
||
//=============================================================================
|
||
// Parameter Variables
|
||
//=============================================================================
|
||
|
||
Yanfly.Parameters = PluginManager.parameters('YEP_BattleAICore');
|
||
Yanfly.Param = Yanfly.Param || {};
|
||
|
||
Yanfly.Param.CoreAIDynamic = String(Yanfly.Parameters['Dynamic Actions']);
|
||
Yanfly.Param.CoreAIDynamic = eval(Yanfly.Param.CoreAIDynamic);
|
||
Yanfly.Param.CoreAIDynTurnCnt = String(Yanfly.Parameters['Dynamic Turn Count']);
|
||
Yanfly.Param.CoreAIDynTurnCnt = eval(Yanfly.Param.CoreAIDynTurnCnt);
|
||
Yanfly.Param.CoreAIElementTest = String(Yanfly.Parameters['Element Testing']);
|
||
Yanfly.Param.CoreAIElementTest = eval(Yanfly.Param.CoreAIElementTest);
|
||
Yanfly.Param.CoreAIDefaultLevel = Number(Yanfly.Parameters['Default AI Level']);
|
||
|
||
//=============================================================================
|
||
// DataManager
|
||
//=============================================================================
|
||
|
||
Yanfly.CoreAI.DataManager_isDatabaseLoaded = DataManager.isDatabaseLoaded;
|
||
DataManager.isDatabaseLoaded = function() {
|
||
if (!Yanfly.CoreAI.DataManager_isDatabaseLoaded.call(this)) return false;
|
||
if (!Yanfly._loaded_YEP_BattleAICore) {
|
||
this.processCoreAINotetags1($dataEnemies);
|
||
this.processCoreAINotetags2($dataSkills);
|
||
this.processCoreAINotetags3($dataStates);
|
||
this.processCoreAINotetags4($dataSystem);
|
||
Yanfly._loaded_YEP_BattleAICore = true;
|
||
}
|
||
return true;
|
||
};
|
||
|
||
DataManager.processCoreAINotetags1 = function(group) {
|
||
var note1 = /<(?:AI PRIORITY)>/i;
|
||
var note2 = /<\/(?:AI PRIORITY)>/i;
|
||
var note3 = /<(?:AI CONSIDER TAUNT|ai considers taunts)>/i;
|
||
var note4 = /<(?:AI LEVEL):[ ](\d+)>/i;
|
||
for (var n = 1; n < group.length; n++) {
|
||
var obj = group[n];
|
||
var notedata = obj.note.split(/[\r\n]+/);
|
||
|
||
obj.aiPattern = [];
|
||
var aiPatternFlag = false;
|
||
obj.aiConsiderTaunt = false;
|
||
obj.aiLevel = Yanfly.Param.CoreAIDefaultLevel * 0.01;
|
||
|
||
for (var i = 0; i < notedata.length; i++) {
|
||
var line = notedata[i];
|
||
if (line.match(note1)) {
|
||
aiPatternFlag = true;
|
||
} else if (line.match(note2)) {
|
||
aiPatternFlag = false;
|
||
} else if (aiPatternFlag) {
|
||
obj.aiPattern.push(line);
|
||
} else if (line.match(note3)) {
|
||
obj.aiConsiderTaunt = true;
|
||
} else if (line.match(note4)) {
|
||
obj.aiLevel = parseFloat(RegExp.$1 * 0.01);
|
||
}
|
||
}
|
||
}
|
||
};
|
||
|
||
DataManager.processCoreAINotetags2 = function(group) {
|
||
if (Yanfly.SkillIdRef) return;
|
||
Yanfly.SkillIdRef = {};
|
||
for (var n = 1; n < group.length; n++) {
|
||
var obj = group[n];
|
||
if (obj.name.length <= 0) continue;
|
||
Yanfly.SkillIdRef[obj.name.toUpperCase()] = n;
|
||
}
|
||
};
|
||
|
||
DataManager.processCoreAINotetags3 = function(group) {
|
||
if (Yanfly.StateIdRef) return;
|
||
Yanfly.StateIdRef = {};
|
||
for (var n = 1; n < group.length; n++) {
|
||
var obj = group[n];
|
||
if (obj.name.length <= 0) continue;
|
||
Yanfly.StateIdRef[obj.name.toUpperCase()] = n;
|
||
}
|
||
};
|
||
|
||
DataManager.processCoreAINotetags4 = function(group) {
|
||
if (Yanfly.ElementIdRef) return;
|
||
Yanfly.ElementIdRef = {};
|
||
for (var i = 0; i < group.elements.length; ++i) {
|
||
var obj = group.elements[i].toUpperCase();
|
||
if (typeof obj === 'string' && obj !== '') Yanfly.ElementIdRef[obj] = i;
|
||
}
|
||
};
|
||
|
||
//=============================================================================
|
||
// BattleManager
|
||
//=============================================================================
|
||
|
||
if (Yanfly.Param.CoreAIDynamic) {
|
||
Yanfly.CoreAI.BattleManager_getNextSubject =
|
||
BattleManager.getNextSubject;
|
||
BattleManager.getNextSubject = function() {
|
||
//this.updateAIPatterns();
|
||
var battler = Yanfly.CoreAI.BattleManager_getNextSubject.call(this);
|
||
if (battler && battler.isEnemy()) battler.setAIPattern();
|
||
return battler;
|
||
};
|
||
};
|
||
|
||
BattleManager.updateAIPatterns = function() {
|
||
$gameTroop.updateAIPatterns()
|
||
};
|
||
|
||
Yanfly.CoreAI.BattleManager_isInputting = BattleManager.isInputting;
|
||
BattleManager.isInputting = function() {
|
||
if ($gameTemp._tauntMode) return false;
|
||
return Yanfly.CoreAI.BattleManager_isInputting.call(this);
|
||
};
|
||
|
||
//=============================================================================
|
||
// Game_Battler
|
||
//=============================================================================
|
||
|
||
Object.defineProperty(Game_Battler.prototype, 'level', {
|
||
get: function() {
|
||
return this.getLevel();
|
||
},
|
||
configurable: true
|
||
});
|
||
|
||
if (!Game_Battler.prototype.getLevel) {
|
||
Game_Battler.prototype.getLevel = function() {
|
||
return $gameTroop.highestLevel();
|
||
};
|
||
};
|
||
|
||
Game_Battler.prototype.setAIPattern = function() {
|
||
Game_Battler.prototype.makeActions.call(this);
|
||
};
|
||
|
||
Game_Battler.prototype.aiConsiderTaunt = function() {
|
||
return false;
|
||
};
|
||
|
||
Game_Battler.prototype.hasSkill = function(skillId) {
|
||
return this.skills().contains($dataSkills[skillId]);
|
||
};
|
||
|
||
Game_Battler.prototype.hasState = function(stateId) {
|
||
return this.states().contains($dataStates[stateId]);
|
||
};
|
||
|
||
Game_Battler.prototype.notState = function(stateId) {
|
||
return !this.isStateAffected(stateId);
|
||
};
|
||
|
||
Game_Battler.prototype.aiLevel = function() {
|
||
return Yanfly.Param.CoreAIDefaultLevel * 0.01;
|
||
};
|
||
|
||
//=============================================================================
|
||
// Game_Enemy
|
||
//=============================================================================
|
||
|
||
Game_Enemy.prototype.skills = function() {
|
||
var skills = []
|
||
for (var i = 0; i < this.enemy().actions.length; ++i) {
|
||
var skill = $dataSkills[this.enemy().actions[i].skillId]
|
||
if (skill) skills.push(skill);
|
||
}
|
||
skills = AIManager.getPatternSkills(skills, this.enemy().aiPattern);
|
||
return skills;
|
||
};
|
||
|
||
Yanfly.CoreAI.Game_Enemy_makeActions = Game_Enemy.prototype.makeActions;
|
||
Game_Enemy.prototype.makeActions = function() {
|
||
if (this.enemy().aiPattern.length > 0) {
|
||
this.setAIPattern();
|
||
this.setActionState('waiting');
|
||
} else {
|
||
Yanfly.CoreAI.Game_Enemy_makeActions.call(this);
|
||
}
|
||
};
|
||
|
||
Game_Enemy.prototype.aiConsiderTaunt = function() {
|
||
if (!Imported.YEP_Taunt) return false;
|
||
return this.enemy().aiConsiderTaunt;
|
||
};
|
||
|
||
Game_Enemy.prototype.setAIPattern = function() {
|
||
Game_Battler.prototype.setAIPattern.call(this);
|
||
if (this.numActions() <= 0) return;
|
||
AIManager.setBattler(this);
|
||
for (var i = 0; i < this.enemy().aiPattern.length; ++i) {
|
||
if (Math.random() > this.aiLevel()) continue;
|
||
var line = this.enemy().aiPattern[i];
|
||
if (AIManager.isDecidedActionAI(line)) return;
|
||
}
|
||
Yanfly.CoreAI.Game_Enemy_makeActions.call(this);
|
||
};
|
||
|
||
Game_Enemy.prototype.aiLevel = function() {
|
||
return this.enemy().aiLevel;
|
||
};
|
||
|
||
//=============================================================================
|
||
// Game_Unit
|
||
//=============================================================================
|
||
|
||
Game_Unit.prototype.highestLevel = function() {
|
||
return $gameParty.highestLevel();
|
||
};
|
||
|
||
Game_Unit.prototype.lowestLevel = function() {
|
||
return $gameParty.lowestLevel();
|
||
};
|
||
|
||
Game_Unit.prototype.averageLevel = function() {
|
||
return $gameParty.averageLevel();
|
||
};
|
||
|
||
Yanfly.CoreAI.Game_Unit_onBattleStart = Game_Unit.prototype.onBattleStart;
|
||
Game_Unit.prototype.onBattleStart = function() {
|
||
Yanfly.CoreAI.Game_Unit_onBattleStart.call(this);
|
||
};
|
||
|
||
Game_Unit.prototype.aiElementRateKnown = function(target, elementId) {
|
||
return true;
|
||
};
|
||
|
||
Game_Unit.prototype.aiRegisterElementRate = function(target, elementId) {
|
||
};
|
||
|
||
//=============================================================================
|
||
// Game_Party
|
||
//=============================================================================
|
||
|
||
Game_Party.prototype.lowestLevel = function() {
|
||
return Math.min.apply(null, this.members().map(function(actor) {
|
||
return actor.level;
|
||
}));
|
||
};
|
||
|
||
Game_Party.prototype.averageLevel = function() {
|
||
var level = 0;
|
||
for (var i = 0; i < this.members().length; ++i) {
|
||
var member = this.members()[i];
|
||
if (member) level += member.level;
|
||
}
|
||
level /= this.members().length;
|
||
return level;
|
||
};
|
||
|
||
//=============================================================================
|
||
// Game_Troop
|
||
//=============================================================================
|
||
|
||
Game_Troop.prototype.updateAIPatterns = function() {
|
||
for (var i = 0; i < this.aliveMembers().length; ++i) {
|
||
var member = this.aliveMembers()[i];
|
||
if (member) member.setAIPattern();
|
||
}
|
||
};
|
||
|
||
Yanfly.CoreAI.Game_Troop_setup = Game_Troop.prototype.setup;
|
||
Game_Troop.prototype.setup = function(troopId) {
|
||
Yanfly.CoreAI.Game_Troop_setup.call(this, troopId);
|
||
this._aiKnownElementRates = {};
|
||
};
|
||
|
||
Game_Troop.prototype.aiElementRateKnown = function(target, elementId) {
|
||
if (target.isEnemy()) return true;
|
||
if (!Yanfly.Param.CoreAIElementTest) return true;
|
||
var index = target.index();
|
||
if (this._aiKnownElementRates[index] === undefined) {
|
||
this._aiKnownElementRates[index] = [];
|
||
}
|
||
return this._aiKnownElementRates[index].contains(elementId);
|
||
};
|
||
|
||
Game_Troop.prototype.aiRegisterElementRate = function(target, elementId) {
|
||
if (!Yanfly.Param.CoreAIElementTest) return;
|
||
var index = target.index();
|
||
if (this._aiKnownElementRates[index] === undefined) {
|
||
this._aiKnownElementRates[index] = [];
|
||
}
|
||
if (!this._aiKnownElementRates[index].contains(elementId)) {
|
||
this._aiKnownElementRates[index].push(elementId);
|
||
}
|
||
};
|
||
|
||
//=============================================================================
|
||
// Game_Action
|
||
//=============================================================================
|
||
|
||
Yanfly.CoreAI.Game_Action_apply = Game_Action.prototype.apply;
|
||
Game_Action.prototype.apply = function(target) {
|
||
Yanfly.CoreAI.Game_Action_apply.call(this, target);
|
||
this.aiRegisterElementRate(target);
|
||
};
|
||
|
||
Game_Action.prototype.aiRegisterElementRate = function(target) {
|
||
if (this.item().damage.elementId < 0) return;
|
||
var elementId = this.item().damage.elementId;
|
||
if (this.subject().isActor()) {
|
||
$gameParty.aiRegisterElementRate(target, elementId);
|
||
} else {
|
||
$gameTroop.aiRegisterElementRate(target, elementId);
|
||
}
|
||
};
|
||
|
||
//=============================================================================
|
||
// AIManager
|
||
//=============================================================================
|
||
|
||
function AIManager() {
|
||
throw new Error('This is a static class');
|
||
}
|
||
|
||
AIManager.setBattler = function(battler) {
|
||
this._battler = battler;
|
||
this._action = battler.action(0);
|
||
};
|
||
|
||
AIManager.battler = function() {
|
||
return this._battler;
|
||
};
|
||
|
||
AIManager.action = function() {
|
||
return this._action;
|
||
};
|
||
|
||
AIManager.isDecidedActionAI = function(line) {
|
||
if (line.match(/[ ]*(.*):[ ](?:SKILL)[ ](\d+),[ ](.*)/i)) {
|
||
this._origCondition = String(RegExp.$1);
|
||
var condition = String(RegExp.$1);
|
||
this._aiSkillId = parseInt(RegExp.$2);
|
||
this._aiTarget = String(RegExp.$3);
|
||
} else if (line.match(/[ ]*(.*):[ ](?:SKILL)[ ](\d+)/i)) {
|
||
this._origCondition = String(RegExp.$1);
|
||
var condition = String(RegExp.$1);
|
||
this._aiSkillId = parseInt(RegExp.$2);
|
||
this._aiTarget = 'RANDOM';
|
||
} else if (line.match(/[ ]*(.*):[ ](.*),[ ](.*)/i)) {
|
||
this._origCondition = String(RegExp.$1);
|
||
var condition = String(RegExp.$1);
|
||
this._aiSkillId = Yanfly.SkillIdRef[String(RegExp.$2).toUpperCase()];
|
||
this._aiTarget = String(RegExp.$3);
|
||
} else if (line.match(/[ ]*(.*):[ ](.*)/i)) {
|
||
this._origCondition = String(RegExp.$1);
|
||
var condition = String(RegExp.$1);
|
||
this._aiSkillId = Yanfly.SkillIdRef[String(RegExp.$2).toUpperCase()];
|
||
this._aiTarget = 'RANDOM';
|
||
} else {
|
||
return false;
|
||
}
|
||
if (!this.initialCheck(this._aiSkillId)) return false;
|
||
if (!this.meetCustomAIConditions(this._aiSkillId)) return false;
|
||
this.action().setSkill(this._aiSkillId);
|
||
if (!this.passAllAIConditions(condition)) return false;
|
||
return true;
|
||
};
|
||
|
||
AIManager.getPatternSkills = function(array, patterns) {
|
||
for (var i = 0; i < patterns.length; ++i) {
|
||
var line = patterns[i];
|
||
if (line.match(/[ ]*(.*):[ ](?:SKILL)[ ](\d+),[ ](.*)/i)) {
|
||
var skillId = parseInt(RegExp.$2);
|
||
} else if (line.match(/[ ]*(.*):[ ](?:SKILL)[ ](\d+)/i)) {
|
||
var skillId = parseInt(RegExp.$2);
|
||
} else if (line.match(/[ ]*(.*):[ ](.*),[ ](.*)/i)) {
|
||
var skillId = Yanfly.SkillIdRef[String(RegExp.$2).toUpperCase()];
|
||
} else if (line.match(/[ ]*(.*):[ ](.*)/i)) {
|
||
var skillId = Yanfly.SkillIdRef[String(RegExp.$2).toUpperCase()];
|
||
} else {
|
||
continue;
|
||
}
|
||
if ($dataSkills[skillId]) array.push($dataSkills[skillId]);
|
||
}
|
||
return array;
|
||
};
|
||
|
||
AIManager.initialCheck = function(skillId) {
|
||
if (!$dataSkills[skillId]) return false;
|
||
if (!this.hasSkill(skillId)) return false;
|
||
return this.battler().meetsSkillConditions($dataSkills[skillId]);
|
||
};
|
||
|
||
AIManager.hasSkill = function(skillId) {
|
||
return this.battler().hasSkill(skillId);
|
||
};
|
||
|
||
AIManager.meetCustomAIConditions = function(skillId) {
|
||
return true;
|
||
};
|
||
|
||
AIManager.getActionGroup = function() {
|
||
var action = this.action();
|
||
if (Imported.YEP_X_SelectionControl) action.setSelectionFilter(true);
|
||
if (!action) return [];
|
||
if (action.isForUser()) {
|
||
var group = [this.battler()];
|
||
} else if (action.isForDeadFriend()) {
|
||
var group = action.friendsUnit().deadMembers();
|
||
} else if (action.isForFriend()) {
|
||
var group = action.friendsUnit().aliveMembers();
|
||
} else if (action.isForOpponent()) {
|
||
if (this.battler().aiConsiderTaunt()) {
|
||
$gameTemp._tauntMode = true;
|
||
$gameTemp._tauntAction = action;
|
||
var group = action.opponentsUnit().tauntMembers();
|
||
$gameTemp._tauntMode = false;
|
||
$gameTemp._tauntAction = undefined;
|
||
} else {
|
||
var group = action.opponentsUnit().aliveMembers();
|
||
}
|
||
} else {
|
||
var group = [];
|
||
}
|
||
if (this._setActionGroup !== undefined) {
|
||
group = Yanfly.Util.getCommonElements(this._setActionGroup, group);
|
||
}
|
||
this._setActionGroup = group;
|
||
return this._setActionGroup;
|
||
};
|
||
|
||
AIManager.setActionGroup = function(group) {
|
||
this._setActionGroup = group;
|
||
};
|
||
|
||
AIManager.setProperTarget = function(group) {
|
||
this.setActionGroup(group);
|
||
var action = this.action();
|
||
var randomTarget = group[Math.floor(Math.random() * group.length)];
|
||
if (!randomTarget) return action.setTarget(0);
|
||
if (group.length <= 0) return action.setTarget(randomTarget.index());
|
||
var line = this._aiTarget.toUpperCase();
|
||
if (line.match(/FIRST/i)) {
|
||
action.setTarget(0);
|
||
} else if (line.match(/USER/i)) {
|
||
var index = group.indexOf();
|
||
action.setTarget(action.subject().index());
|
||
} else if (line.match(/HIGHEST[ ](.*)/i)) {
|
||
var param = this.getParamId(String(RegExp.$1));
|
||
if (param < 0) return action.setTarget(randomTarget.index());
|
||
if (param === 8) return this.setHighestHpFlatTarget(group);
|
||
if (param === 9) return this.setHighestMpFlatTarget(group);
|
||
if (param === 10) return this.setHighestHpRateTarget(group);
|
||
if (param === 11) return this.setHighestMpRateTarget(group);
|
||
if (param === 12) return this.setHighestLevelTarget(group);
|
||
if (param === 13) return this.setHighestMaxTpTarget(group);
|
||
if (param === 14) return this.setHighestTpTarget(group);
|
||
if (param > 15) return action.setTarget(randomTarget.index());
|
||
this.setHighestParamTarget(group, param);
|
||
} else if (line.match(/LOWEST[ ](.*)/i)) {
|
||
var param = this.getParamId(String(RegExp.$1));
|
||
if (param < 0) return action.setTarget(randomTarget.index());
|
||
if (param === 8) return this.setLowestHpFlatTarget(group);
|
||
if (param === 9) return this.setLowestMpFlatTarget(group);
|
||
if (param === 10) return this.setLowestHpRateTarget(group);
|
||
if (param === 11) return this.setLowestMpRateTarget(group);
|
||
if (param === 12) return this.setLowestLevelTarget(group);
|
||
if (param === 13) return this.setLowestMaxTpTarget(group);
|
||
if (param === 14) return this.setLowestTpTarget(group);
|
||
if (param > 15) return action.setTarget(randomTarget.index());
|
||
this.setLowestParamTarget(group, param);
|
||
} else {
|
||
this.setRandomTarget(group);
|
||
}
|
||
};
|
||
|
||
AIManager.getParamId = function(string) {
|
||
string = string.toUpperCase()
|
||
switch (string) {
|
||
case 'MAXHP':
|
||
case 'MAX HP':
|
||
return 0;
|
||
break;
|
||
case 'MAXMP':
|
||
case 'MAX MP':
|
||
case 'MAXSP':
|
||
case 'MAX SP':
|
||
return 1;
|
||
break;
|
||
case 'ATK':
|
||
case 'STR':
|
||
return 2;
|
||
break;
|
||
case 'DEF':
|
||
return 3;
|
||
break;
|
||
case 'MAT':
|
||
case 'INT':
|
||
case 'SPI':
|
||
return 4;
|
||
break;
|
||
case 'MDF':
|
||
case 'RES':
|
||
return 5;
|
||
break;
|
||
case 'AGI':
|
||
case 'SPD':
|
||
return 6;
|
||
break;
|
||
case 'LUK':
|
||
return 7;
|
||
break;
|
||
case 'HP':
|
||
return 8;
|
||
break;
|
||
case 'MP':
|
||
case 'SP':
|
||
return 9;
|
||
break;
|
||
case 'HP%':
|
||
return 10;
|
||
break;
|
||
case 'MP%':
|
||
case 'SP%':
|
||
return 11;
|
||
break;
|
||
case 'LEVEL':
|
||
case 'LV':
|
||
case 'LVL':
|
||
return 12;
|
||
break;
|
||
case 'MAXTP':
|
||
return 13;
|
||
break;
|
||
case 'TP':
|
||
return 14;
|
||
break;
|
||
}
|
||
return -1;
|
||
};
|
||
|
||
AIManager.setHighestHpRateTarget = function(group) {
|
||
var maintarget = group[Math.floor(Math.random() * group.length)];
|
||
for (var i = 0; i < group.length; ++i) {
|
||
var target = group[i];
|
||
if (target.hp / target.mhp > maintarget.hp / maintarget.mhp) {
|
||
maintarget = target;
|
||
}
|
||
}
|
||
this.action().setTarget(maintarget.index())
|
||
};
|
||
|
||
AIManager.setHighestHpFlatTarget = function(group) {
|
||
var maintarget = group[Math.floor(Math.random() * group.length)];
|
||
for (var i = 0; i < group.length; ++i) {
|
||
var target = group[i];
|
||
if (target.hp > maintarget.hp) maintarget = target;
|
||
}
|
||
this.action().setTarget(maintarget.index())
|
||
};
|
||
|
||
AIManager.setLowestHpRateTarget = function(group) {
|
||
var maintarget = group[Math.floor(Math.random() * group.length)];
|
||
for (var i = 0; i < group.length; ++i) {
|
||
var target = group[i];
|
||
if (target.hp / target.mhp < maintarget.hp / maintarget.mhp) {
|
||
maintarget = target;
|
||
}
|
||
}
|
||
this.action().setTarget(maintarget.index())
|
||
};
|
||
|
||
AIManager.setLowestHpFlatTarget = function(group) {
|
||
var maintarget = group[Math.floor(Math.random() * group.length)];
|
||
for (var i = 0; i < group.length; ++i) {
|
||
var target = group[i];
|
||
if (target.hp < maintarget.hp) maintarget = target;
|
||
}
|
||
this.action().setTarget(maintarget.index())
|
||
};
|
||
|
||
AIManager.setHighestMpRateTarget = function(group) {
|
||
var maintarget = group[Math.floor(Math.random() * group.length)];
|
||
for (var i = 0; i < group.length; ++i) {
|
||
var target = group[i];
|
||
if (target.mp / target.mmp > maintarget.mp / maintarget.mmp) {
|
||
maintarget = target;
|
||
}
|
||
}
|
||
this.action().setTarget(maintarget.index())
|
||
};
|
||
|
||
AIManager.setHighestMpFlatTarget = function(group) {
|
||
var maintarget = group[Math.floor(Math.random() * group.length)];
|
||
for (var i = 0; i < group.length; ++i) {
|
||
var target = group[i];
|
||
if (target.mp > maintarget.mp) maintarget = target;
|
||
}
|
||
this.action().setTarget(maintarget.index())
|
||
};
|
||
|
||
AIManager.setLowestMpRateTarget = function(group) {
|
||
var maintarget = group[Math.floor(Math.random() * group.length)];
|
||
for (var i = 0; i < group.length; ++i) {
|
||
var target = group[i];
|
||
if (target.mp / target.mmp < maintarget.mp / maintarget.mmp) {
|
||
maintarget = target;
|
||
}
|
||
}
|
||
this.action().setTarget(maintarget.index())
|
||
};
|
||
|
||
AIManager.setLowestMpFlatTarget = function(group) {
|
||
var maintarget = group[Math.floor(Math.random() * group.length)];
|
||
for (var i = 0; i < group.length; ++i) {
|
||
var target = group[i];
|
||
if (target.mp < maintarget.mp) maintarget = target;
|
||
}
|
||
this.action().setTarget(maintarget.index())
|
||
};
|
||
|
||
AIManager.setHighestParamTarget = function(group, id) {
|
||
var maintarget = group[Math.floor(Math.random() * group.length)];
|
||
for (var i = 0; i < group.length; ++i) {
|
||
var target = group[i];
|
||
if (target.param(id) > maintarget.param(id)) maintarget = target;
|
||
}
|
||
this.action().setTarget(maintarget.index())
|
||
};
|
||
|
||
AIManager.setLowestParamTarget = function(group, id) {
|
||
var maintarget = group[Math.floor(Math.random() * group.length)];
|
||
for (var i = 0; i < group.length; ++i) {
|
||
var target = group[i];
|
||
if (target.param(id) < maintarget.param(id)) maintarget = target;
|
||
}
|
||
this.action().setTarget(maintarget.index())
|
||
};
|
||
|
||
AIManager.setHighestLevelTarget = function(group, id) {
|
||
var maintarget = group[Math.floor(Math.random() * group.length)];
|
||
for (var i = 0; i < group.length; ++i) {
|
||
var target = group[i];
|
||
if (target.level > maintarget.level) maintarget = target;
|
||
}
|
||
this.action().setTarget(maintarget.index())
|
||
};
|
||
|
||
AIManager.setLowestLevelTarget = function(group, id) {
|
||
var maintarget = group[Math.floor(Math.random() * group.length)];
|
||
for (var i = 0; i < group.length; ++i) {
|
||
var target = group[i];
|
||
if (target.level < maintarget.level) maintarget = target;
|
||
}
|
||
this.action().setTarget(maintarget.index())
|
||
};
|
||
|
||
AIManager.setHighestMaxTpTarget = function(group, id) {
|
||
var maintarget = group[Math.floor(Math.random() * group.length)];
|
||
for (var i = 0; i < group.length; ++i) {
|
||
var target = group[i];
|
||
if (target.tp > maintarget.maxTp()) maintarget = target;
|
||
}
|
||
this.action().setTarget(maintarget.index())
|
||
};
|
||
|
||
AIManager.setLowestMaxTpTarget = function(group, id) {
|
||
var maintarget = group[Math.floor(Math.random() * group.length)];
|
||
for (var i = 0; i < group.length; ++i) {
|
||
var target = group[i];
|
||
if (target.tp < maintarget.maxTp()) maintarget = target;
|
||
}
|
||
this.action().setTarget(maintarget.index())
|
||
};
|
||
|
||
AIManager.setHighestTpTarget = function(group, id) {
|
||
var maintarget = group[Math.floor(Math.random() * group.length)];
|
||
for (var i = 0; i < group.length; ++i) {
|
||
var target = group[i];
|
||
if (target.tp > maintarget.tp) maintarget = target;
|
||
}
|
||
this.action().setTarget(maintarget.index())
|
||
};
|
||
|
||
AIManager.setLowestTpTarget = function(group, id) {
|
||
var maintarget = group[Math.floor(Math.random() * group.length)];
|
||
for (var i = 0; i < group.length; ++i) {
|
||
var target = group[i];
|
||
if (target.tp < maintarget.tp) maintarget = target;
|
||
}
|
||
this.action().setTarget(maintarget.index())
|
||
};
|
||
|
||
AIManager.setRandomTarget = function(group) {
|
||
var target = group[Math.floor(Math.random() * group.length)];
|
||
this.action().setTarget(target.index())
|
||
};
|
||
|
||
AIManager.convertIntegerPercent = function(n) {
|
||
n *= 0.01
|
||
return String(n);
|
||
};
|
||
|
||
AIManager.elementRateMatch = function(target, elementId, type) {
|
||
var rate = target.elementRate(elementId).toFixed(2);
|
||
if (this.battler().isActor()) {
|
||
if (!$gameParty.aiElementRateKnown(target, elementId)) return true;
|
||
} else {
|
||
if (!$gameTroop.aiElementRateKnown(target, elementId)) return true;
|
||
}
|
||
if (['NEUTRAL', 'NORMAL'].contains(type)) {
|
||
return rate >= 0.90 && rate <= 1.10;
|
||
} else if (['WEAK', 'WEAKNESS', 'VULNERABLE'].contains(type)) {
|
||
return rate > 1.00;
|
||
} else if (['RESIST', 'RESISTANT', 'STRONG'].contains(type)) {
|
||
return rate < 1.00;
|
||
} else if (['NULL', 'CANCEL', 'NO EFFECT'].contains(type)) {
|
||
return rate === 0.00;
|
||
} else if (['ABSORB', 'HEAL'].contains(type)) {
|
||
return rate < 0.00;
|
||
}
|
||
return false;
|
||
};
|
||
|
||
AIManager.passAllAIConditions = function(line) {
|
||
this._setActionGroup = undefined;
|
||
var conditions = line.split('+++');
|
||
if (conditions.length <= 0) return false;
|
||
while (conditions.length > 0) {
|
||
var condition = conditions.shift().trim();
|
||
if (!this.passAIConditions(condition)) return false;
|
||
}
|
||
return true;
|
||
};
|
||
|
||
AIManager.passAIConditions = function(line) {
|
||
// ALWAYS
|
||
if (line.match(/ALWAYS/i)) {
|
||
return this.conditionAlways();
|
||
}
|
||
// ELEMENT
|
||
if (line.match(/ELEMENT[ ](.*)/i)) {
|
||
return this.conditionElement();
|
||
}
|
||
// EVAL
|
||
if (line.match(/EVAL[ ](.*)/i)) {
|
||
var condition = String(RegExp.$1);
|
||
return this.conditionEval(condition);
|
||
}
|
||
// GROUP ALIVE MEMBERS EVAL
|
||
if (line.match(/(.*)[ ]ALIVE[ ]MEMBERS[ ](.*)/i)) {
|
||
var members = String(RegExp.$1);
|
||
var condition = String(RegExp.$2);
|
||
return this.conditionGroupAlive(members, condition);
|
||
}
|
||
// GROUP DEAD MEMBERS EVAL
|
||
if (line.match(/(.*)[ ]DEAD[ ]MEMBERS[ ](.*)/i)) {
|
||
var members = String(RegExp.$1);
|
||
var condition = String(RegExp.$2);
|
||
return this.conditionGroupDead(members, condition);
|
||
}
|
||
// USER PARAM EVAL
|
||
if (line.match(/USER[ ](.*)[ ]PARAM[ ](.*)/i)) {
|
||
var paramId = this.getParamId(String(RegExp.$1));
|
||
var condition = String(RegExp.$2);
|
||
return this.conditionUserParamEval(paramId, condition);
|
||
}
|
||
// PARAM EVAL
|
||
if (line.match(/(.*)[ ]PARAM[ ](.*)/i)) {
|
||
var paramId = this.getParamId(String(RegExp.$1));
|
||
var condition = String(RegExp.$2);
|
||
return this.conditionParamEval(paramId, condition);
|
||
}
|
||
// PARTY LEVEL
|
||
if (line.match(/(.*)[ ]PARTY[ ]LEVEL[ ](.*)/i)) {
|
||
var type = String(RegExp.$1);
|
||
var condition = String(RegExp.$2);
|
||
return this.conditionPartyLevel(type, condition);
|
||
}
|
||
// RANDOM x%
|
||
if (line.match(/RANDOM[ ](\d+)([%%])/i)) {
|
||
return this.conditionRandom(parseFloat(RegExp.$1 * 0.01));
|
||
}
|
||
// STATE === X
|
||
if (line.match(/STATE[ ]===[ ](.*)/i)) {
|
||
return this.conditionStateHas(String(RegExp.$1));
|
||
}
|
||
// STATE !== X
|
||
if (line.match(/STATE[ ]!==[ ](.*)/i)) {
|
||
return this.conditionStateNot(String(RegExp.$1));
|
||
}
|
||
// SWITCH X case
|
||
if (line.match(/SWITCH[ ](\d+)[ ](.*)/i)) {
|
||
var switchId = parseInt(RegExp.$1);
|
||
var value = String(RegExp.$2)
|
||
return this.conditionSwitch(switchId, value);
|
||
}
|
||
// TURN EVAL
|
||
if (line.match(/TURN[ ](.*)/i)) {
|
||
return this.conditionTurnCount(String(RegExp.$1));
|
||
}
|
||
// VARIABLE X eval
|
||
if (line.match(/VARIABLE[ ](\d+)[ ](.*)/i)) {
|
||
var variableId = parseInt(RegExp.$1);
|
||
var condition = String(RegExp.$2)
|
||
return this.conditionVariable(variableId, condition);
|
||
}
|
||
return false;
|
||
};
|
||
|
||
AIManager.conditionAlways = function() {
|
||
var group = this.getActionGroup();
|
||
this.setProperTarget(group);
|
||
return true;
|
||
};
|
||
|
||
AIManager.conditionElement = function() {
|
||
var line = this._origCondition;
|
||
if (line.match(/ELEMENT[ ](\d+)[ ](.*)/i)) {
|
||
var elementId = parseInt(RegExp.$1);
|
||
var type = String(RegExp.$2).toUpperCase();
|
||
} else if (line.match(/ELEMENT[ ](.*)[ ](.*)/i)) {
|
||
var elementId = Yanfly.ElementIdRef[String(RegExp.$1).toUpperCase()];
|
||
var type = String(RegExp.$2).toUpperCase();
|
||
} else {
|
||
return false;
|
||
}
|
||
var group = this.getActionGroup();
|
||
var validTargets = [];
|
||
for (var i = 0; i < group.length; ++i) {
|
||
var target = group[i];
|
||
if (!target) continue;
|
||
if (this.elementRateMatch(target, elementId, type)) {
|
||
validTargets.push(target);
|
||
}
|
||
}
|
||
if (validTargets.length <= 0) return false;
|
||
this.setProperTarget(validTargets);
|
||
return true;
|
||
};
|
||
|
||
AIManager.conditionEval = function(condition) {
|
||
var action = this.action();
|
||
var item = action.item();
|
||
var user = this.battler();
|
||
var s = $gameSwitches._data;
|
||
var v = $gameVariables._data;
|
||
try {
|
||
if (!eval(condition)) return false;
|
||
} catch (e) {
|
||
Yanfly.Util.displayError(e, condition, 'A.I. EVAL ERROR');
|
||
return false;
|
||
}
|
||
var group = this.getActionGroup();
|
||
this.setProperTarget(group);
|
||
return true;
|
||
};
|
||
|
||
AIManager.conditionGroupAlive = function(members, condition) {
|
||
var action = this.action();
|
||
var item = action.item();
|
||
var user = this.battler();
|
||
var s = $gameSwitches._data;
|
||
var v = $gameVariables._data;
|
||
members = members.toUpperCase();
|
||
if (['TROOP', 'TROOPS', 'ENEMY', 'ENEMIES'].contains(members)) {
|
||
members = $gameTroop.aliveMembers();
|
||
} else if (['PARTY', 'PLAYER'].contains(members)) {
|
||
members = $gameParty.aliveMembers();
|
||
} else {
|
||
return false;
|
||
}
|
||
if (members.length <= 0) return false;
|
||
condition = 'members.length ' + condition;
|
||
try {
|
||
if (!eval(condition)) return false;
|
||
} catch (e) {
|
||
Yanfly.Util.displayError(e, condition, 'A.I. GROUP ALIVE ERROR');
|
||
return false;
|
||
}
|
||
var group = this.getActionGroup();
|
||
this.setProperTarget(group);
|
||
return true;
|
||
};
|
||
|
||
AIManager.conditionGroupDead = function(members, condition) {
|
||
var action = this.action();
|
||
var item = action.item();
|
||
var user = this.battler();
|
||
var s = $gameSwitches._data;
|
||
var v = $gameVariables._data;
|
||
members = members.toUpperCase();
|
||
if (['TROOP', 'TROOPS', 'ENEMY', 'ENEMIES'].contains(members)) {
|
||
members = $gameTroop.deadMembers();
|
||
} else if (['PARTY', 'PLAYER'].contains(members)) {
|
||
members = $gameParty.deadMembers();
|
||
} else {
|
||
return false;
|
||
}
|
||
if (members.length <= 0) return false;
|
||
condition = 'members.length ' + condition;
|
||
try {
|
||
if (!eval(condition)) return false;
|
||
} catch (e) {
|
||
Yanfly.Util.displayError(e, condition, 'A.I. GROUP DEAD ERROR');
|
||
return false;
|
||
}
|
||
var group = this.getActionGroup();
|
||
this.setProperTarget(group);
|
||
return true;
|
||
};
|
||
|
||
AIManager.conditionPartyLevel = function(type, condition) {
|
||
if (type.match(/HIGHEST/i)) {
|
||
condition = '.highestLevel() ' + condition;
|
||
} else if (type.match(/LOWEST/i)) {
|
||
condition = '.lowestLevel() ' + condition;
|
||
} else if (type.match(/AVERAGE/i)) {
|
||
condition = '.averageLevel() ' + condition;
|
||
} else {
|
||
return false;
|
||
}
|
||
var action = this.action();
|
||
var item = action.item();
|
||
var user = this.battler();
|
||
var s = $gameSwitches._data;
|
||
var v = $gameVariables._data;
|
||
if (action.isForFriend()) {
|
||
condition = 'action.friendsUnit()' + condition;
|
||
} else if (action.isForOpponent()) {
|
||
condition = 'action.opponentsUnit()' + condition;
|
||
}
|
||
try {
|
||
if (!eval(condition)) return false;
|
||
} catch (e) {
|
||
Yanfly.Util.displayError(e, condition, 'A.I. PARTY LEVEL ERROR');
|
||
return false;
|
||
}
|
||
var group = this.getActionGroup();
|
||
this.setProperTarget(group);
|
||
return true;
|
||
};
|
||
|
||
AIManager.conditionUserParamEval = function(paramId, condition) {
|
||
var action = this.action();
|
||
var item = action.item();
|
||
var user = this.battler();
|
||
var s = $gameSwitches._data;
|
||
var v = $gameVariables._data;
|
||
condition = condition.replace(/(\d+)([%%])/g, function() {
|
||
return this.convertIntegerPercent(parseInt(arguments[1]));
|
||
}.bind(this));
|
||
if (paramId < 0) return false;
|
||
if (paramId >= 0 && paramId <= 7) {
|
||
condition = 'user.param(paramId) ' + condition;
|
||
} else if (paramId === 8) {
|
||
condition = 'user.hp ' + condition;
|
||
} else if (paramId === 9) {
|
||
condition = 'user.mp ' + condition;
|
||
} else if (paramId === 10) {
|
||
condition = 'user.hp / user.mhp ' + condition;
|
||
} else if (paramId === 11) {
|
||
condition = 'user.mp / user.mmp ' + condition;
|
||
} else if (paramId === 12) {
|
||
condition = 'user.level ' + condition;
|
||
}
|
||
var group = this.getActionGroup();
|
||
var validTargets = [];
|
||
for (var i = 0; i < group.length; ++i) {
|
||
var target = group[i];
|
||
if (!target) continue;
|
||
try {
|
||
if (eval(condition)) validTargets.push(target);
|
||
} catch (e) {
|
||
Yanfly.Util.displayError(e, condition, 'A.I. USER PARAM ERROR')
|
||
}
|
||
}
|
||
if (validTargets.length <= 0) return false;
|
||
this.setProperTarget(validTargets);
|
||
return true;
|
||
};
|
||
|
||
AIManager.conditionParamEval = function(paramId, condition) {
|
||
var action = this.action();
|
||
var item = action.item();
|
||
var user = this.battler();
|
||
var s = $gameSwitches._data;
|
||
var v = $gameVariables._data;
|
||
condition = condition.replace(/(\d+)([%%])/g, function() {
|
||
return this.convertIntegerPercent(parseInt(arguments[1]));
|
||
}.bind(this));
|
||
if (paramId < 0) return false;
|
||
if (paramId >= 0 && paramId <= 7) {
|
||
condition = 'target.param(paramId) ' + condition;
|
||
} else if (paramId === 8) {
|
||
condition = 'target.hp ' + condition;
|
||
} else if (paramId === 9) {
|
||
condition = 'target.mp ' + condition;
|
||
} else if (paramId === 10) {
|
||
condition = 'target.hp / target.mhp ' + condition;
|
||
} else if (paramId === 11) {
|
||
condition = 'target.mp / target.mmp ' + condition;
|
||
} else if (paramId === 12) {
|
||
condition = 'target.level ' + condition;
|
||
}
|
||
var group = this.getActionGroup();
|
||
var validTargets = [];
|
||
for (var i = 0; i < group.length; ++i) {
|
||
var target = group[i];
|
||
if (!target) continue;
|
||
try {
|
||
if (eval(condition)) validTargets.push(target);
|
||
} catch (e) {
|
||
Yanfly.Util.displayError(e, condition, 'A.I. PARAM ERROR')
|
||
}
|
||
}
|
||
if (validTargets.length <= 0) return false;
|
||
this.setProperTarget(validTargets);
|
||
return true;
|
||
};
|
||
|
||
AIManager.conditionRandom = function(rate) {
|
||
if (Math.random() >= rate) return false;
|
||
var group = this.getActionGroup();
|
||
this.setProperTarget(group);
|
||
return true;
|
||
};
|
||
|
||
AIManager.conditionStateHas = function(condition) {
|
||
if (condition.match(/STATE[ ](\d+)/i)) {
|
||
var stateId = parseInt(RegExp.$1);
|
||
} else {
|
||
var stateId = Yanfly.StateIdRef[condition.toUpperCase()];
|
||
if (!stateId) return false;
|
||
}
|
||
if (!$dataStates[stateId]) return false;
|
||
var group = this.getActionGroup();
|
||
var validTargets = [];
|
||
for (var i = 0; i < group.length; ++i) {
|
||
var target = group[i];
|
||
if (!target) continue;
|
||
if (target.hasState(stateId)) validTargets.push(target);
|
||
}
|
||
if (validTargets.length <= 0) return false;
|
||
this.setProperTarget(validTargets);
|
||
return true;
|
||
};
|
||
|
||
AIManager.conditionStateNot = function(condition) {
|
||
if (condition.match(/STATE[ ](\d+)/i)) {
|
||
var stateId = parseInt(RegExp.$1);
|
||
} else {
|
||
var stateId = Yanfly.StateIdRef[condition.toUpperCase()];
|
||
if (!stateId) return false;
|
||
}
|
||
if (!$dataStates[stateId]) return false;
|
||
var group = this.getActionGroup();
|
||
var validTargets = [];
|
||
for (var i = 0; i < group.length; ++i) {
|
||
var target = group[i];
|
||
if (!target) continue;
|
||
if (target.notState(stateId)) validTargets.push(target);
|
||
}
|
||
if (validTargets.length <= 0) return false;
|
||
this.setProperTarget(validTargets);
|
||
return true;
|
||
};
|
||
|
||
AIManager.conditionSwitch = function(switchId, value) {
|
||
if (['ON', 'TRUE', 'YES'].contains(value.toUpperCase())) {
|
||
value = true;
|
||
} else if (['OFF', 'FALSE', 'NO'].contains(value.toUpperCase())) {
|
||
value = false;
|
||
} else {
|
||
return false;
|
||
}
|
||
if ($gameSwitches.value(switchId) !== value) return false;
|
||
var group = this.getActionGroup();
|
||
this.setProperTarget(group);
|
||
return true;
|
||
};
|
||
|
||
if (!Yanfly.Param.CoreAIDynTurnCnt) {
|
||
|
||
AIManager.conditionTurnCount = function(condition) {
|
||
var action = this.action();
|
||
var item = action.item();
|
||
var user = this.battler();
|
||
var s = $gameSwitches._data;
|
||
var v = $gameVariables._data;
|
||
if (Imported.YEP_BattleEngineCore) {
|
||
condition = 'user.turnCount() ' + condition;
|
||
} else {
|
||
condition = '$gameTroop.turnCount() ' + condition;
|
||
}
|
||
try {
|
||
if (!eval(condition)) return false;
|
||
} catch (e) {
|
||
Yanfly.Util.displayError(e, condition, 'A.I. TURN COUNT ERROR');
|
||
return false;
|
||
}
|
||
var group = this.getActionGroup();
|
||
this.setProperTarget(group);
|
||
return true;
|
||
};
|
||
|
||
} else {
|
||
// Alternative provided by Talonos
|
||
|
||
AIManager.conditionTurnCount = function(condition) {
|
||
var action = this.action();
|
||
var item = action.item();
|
||
var user = this.battler();
|
||
var s = $gameSwitches._data;
|
||
var v = $gameVariables._data;
|
||
if (Imported.YEP_BattleEngineCore) {
|
||
if (BattleManager._phase === "input" && BattleManager.isTurnBased()) {
|
||
condition = '(user.turnCount() + 1) ' + condition;
|
||
} else {
|
||
condition = 'user.turnCount() ' + condition;
|
||
}
|
||
} else {
|
||
if (BattleManager._phase === "input") {
|
||
condition = '($gameTroop.turnCount() + 1) ' + condition;
|
||
} else {
|
||
condition = '$gameTroop.turnCount() ' + condition;
|
||
}
|
||
}
|
||
try {
|
||
if (!eval(condition)) return false;
|
||
} catch (e) {
|
||
Yanfly.Util.displayError(e, condition, 'A.I. TURN COUNT ERROR');
|
||
return false;
|
||
}
|
||
var group = this.getActionGroup();
|
||
this.setProperTarget(group);
|
||
return true;
|
||
};
|
||
|
||
} // Yanfly.Param.CoreAIDynamic
|
||
|
||
|
||
AIManager.conditionVariable = function(variableId, condition) {
|
||
var action = this.action();
|
||
var item = action.item();
|
||
var user = this.battler();
|
||
var s = $gameSwitches._data;
|
||
var v = $gameVariables._data;
|
||
condition = '$gameVariables.value(' + variableId + ') ' + condition;
|
||
try {
|
||
if (!eval(condition)) return false;
|
||
} catch (e) {
|
||
Yanfly.Util.displayError(e, condition, 'A.I. VARIABLE ERROR');
|
||
return false;
|
||
}
|
||
var group = this.getActionGroup();
|
||
this.setProperTarget(group);
|
||
return true;
|
||
};
|
||
|
||
//=============================================================================
|
||
// Utilities
|
||
//=============================================================================
|
||
|
||
Yanfly.Util = Yanfly.Util || {};
|
||
|
||
Yanfly.Util.displayError = function(e, code, message) {
|
||
console.log(message);
|
||
console.log(code || 'NON-EXISTENT');
|
||
console.error(e);
|
||
if (Utils.RPGMAKER_VERSION && Utils.RPGMAKER_VERSION >= "1.6.0") return;
|
||
if (Utils.isNwjs() && Utils.isOptionValid('test')) {
|
||
if (!require('nw.gui').Window.get().isDevToolsOpen()) {
|
||
require('nw.gui').Window.get().showDevTools();
|
||
}
|
||
}
|
||
};
|
||
|
||
Yanfly.Util.getCommonElements = function(array1, array2) {
|
||
var elements = [];
|
||
var length = array1.length;
|
||
for (var i = 0; i < length; ++i) {
|
||
var element = array1[i];
|
||
if (array2.contains(element)) elements.push(element);
|
||
}
|
||
return elements;
|
||
};
|
||
|
||
//=============================================================================
|
||
// End of File
|
||
//=============================================================================
|