code:
//=============================================================================
// Yanfly Engine Plugins - Battle Engine Extension - Action Sequence Pack 1
// YEP_X_ActSeqPack1.js
//=============================================================================

var Imported = Imported || {};
Imported.YEP_X_ActSeqPack1 = true;

var Yanfly = Yanfly || {};
Yanfly.ASP1 = Yanfly.ASP1 || {};
Yanfly.ASP1.version = 1.13;

//=============================================================================
 /*:
 * @plugindesc v1.13 (Requires YEP_BattleEngineCore.js) Basic functions are
 * added to the Battle Engine Core's action sequences.
 * @author Yanfly Engine Plugins
 *
 * @param Default Volume
 * @desc This will be the volume of the BGM played.
 * @type number
 * @min 0
 * @max 100
 * @default 90
 *
 * @param Default Pitch
 * @type number
 * @min 0
 * @max 100
 * @desc This will be the pitch of the BGM played.
 * @default 100
 *
 * @param Default Pan
 * @type number
 * @min 0
 * @max 100
 * @desc This will be the pan of the BGM played.
 * @default 0
 *
 * @help
 * ============================================================================
 * Introduction
 * ============================================================================
 *
 * The Action Sequence Pack 1 plugin is an extension plugin for Yanfly Engine
 * Plugins' Battle Engine Core. This extension plugin will not work without the
 * main plugin.
 *
 * This extension plugin contains the more basic functions used for customized
 * action sequences on a technical scale. Here, you are able to change switches,
 * operate variables, add states, change damage rates, and more.
 *
 * ============================================================================
 * Action Sequences - ala Melody
 * ============================================================================
 *
 * Battle Engine Core includes Yanfly Engine Melody's Battle Engine system,
 * where each individual aspect of the skill and item effects can be controlled
 * to a degree. These are called Action Sequences, where each command in the
 * action sequence causes the game to perform a distinct individual action.
 *
 * Each skill and item consists of five different action sequences. They are as
 * follows:
 *
 * 1. Setup Actions
 *   They prepare the active battler before carrying out the bulk of the action
 * and its individual effects. Usually what you see here are things such as the
 * active battler moving forward a bit, unsheathing their weapon, etc. This step
 * will occur before the active battler expends their skill or item costs.
 *
 * 2. Whole Actions
 *   These actions will affect all of the targets simultaneously. Although this
 * section does not need to be used, most actions will use this for displaying
 * animations upon all enemies. This step occurs after skill and item costs.
 *
 * 3. Target Actions
 *   This section will affect all of the targets individually. Used primarily
 * for physical attacks that will deliver more personal forms of damage. Actions
 * that occur here will not affect other targets unless specifically ordered to
 * do so otherwise.
 *
 * 4. Follow Actions
 *   This section will dedicate towards cleanup work after the individual
 * targeting actions. Here, it'll do things such as removing immortal flags,
 * start up common events, and more.
 *
 * 5. Finish Actions
 *   This section will have the active battler close up the action sequence.
 * Usually stuff like running waits and holds at the last minute for skills and
 * items, moving back to place, and others.
 *
 * Now that you know each of the five steps each action sequence goes through,
 * here's the tags you can insert inside of skills and items. Pay attention to
 * each tag name.
 *
 * 1. <setup action>                                5. <finish action>
 *     action list                                      action list
 *     action list                                      action list
 *    </setup action>                                  </finish action>
 *
 * 2. <whole action>       3. <target action>       4. <follow action>
 *     action list             action list              action list
 *     action list             action list              action list
 *    </whole action>         </target action>         </follow action>
 *
 * They will do their own respective action sets. The methods to insert for the
 * action list can be found below in the core of the Help Manual.
 *
 * Furthermore, to prevent overflooding every single one of your database item's
 * noteboxes with action sequence lists, there's a shortcut you can take to copy
 * all of the setup actions, whole actions, target actions, follow actions, and
 * finish actions with just one line.
 *
 * <action copy: x:y>
 *
 * Replace x with "item" or "skill" to set the type for the action list code to
 * directly copy. The integer y is then the ID assigned for that particular
 * object type. For example, to copy 45th skill's action sequences, the code
 * would be <action copy: skill:45> for anything that will accept these action
 * codes. If you do use this notetag, it will take priority over any custom
 * that you've placed in the notebox.
 *
 * ============================================================================
 * Target Typing
 * ============================================================================
 *
 * You may notice that in some of the actions below will say "refer to target
 * typing" which is this section right here. Here's a quick run down on the
 * various targets you may select.
 *
 *   user; This will select the active battler.
 *   target, targets; These will select the active targets in question.
 *   actors, existing actors; These will select all living actors.
 *   all actors; This will select all actors including dead ones.
 *   dead actors: This will select only dead actors.
 *   actors not user; This will select all living actors except for the user.
 *   actor x; This will select the actor in slot x.
 *   character x; This will select the specific character with actor ID x.
 *   enemies, existing enemies; This will select all living enemies.
 *   all enemies; This will select all enemies, even dead.
 *   dead enemies: This will select only dead enemies.
 *   enemies not user; This will select all enemies except for the user.
 *   enemy x; This will select the enemy in slot x.
 *   friends; This will select the battler's alive allies.
 *   all friends; This will select the all of battler's allies, even dead.
 *   dead friends; This will select the battler's dead allies.
 *   friends not user; This will select the battler's allies except itself.
 *   friend x: This will select the battler's ally in slot x.
 *   opponents; This will select the battler's alive opponents.
 *   all opponents; This will select the all of the battler's opponents.
 *   dead opponents; This will select the battler's dead opponents.
 *   opponent x: This will select the battler's opponent in slot x.
 *   all alive; Selects all living actors and enemies.
 *   all members; Selects all living and dead actors and enemies.
 *   all dead; Selects all dead actors and enemies.
 *   all not user; This will select all living battlers except user.
 *   focus; Selects the active battler and its targets.
 *   not focus; Selects everything but the active battler and its targets.
 *
 * ============================================================================
 * Action Sequences - Action List
 * ============================================================================
 *
 * The following contains a list of the actions you can use inside the five
 * action sequences. Each action has a unique function and requires certain
 * formats to operate properly.
 *
 *=============================================================================
 * ACTION ANIMATION: (target), (mirror)
 *- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 * Plays the animation assigned to the skill/item. The animation will
 * automatically select the skill's/item's assigned targets. If 'target' is
 * used, it will specify a target to play the animation on. If 'mirror' is
 * used, it will mirror the animation.
 *- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 * Usage Example: action animation
 *                action animation: target
 *                action animation: user, mirror
 *=============================================================================
 *
 *=============================================================================
 * ACTION COMMON EVENT
 *- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 * Plays the common event found within the skill's/item's traits list. This
 * will only play the last common event on the list, following the game
 * engine's original process. Nothing else will continue on the action list
 * until the common event is finished (unless it is a forced action, in which
 * case, it will wait until the action is complete first).
 *- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 * Usage Example: action common event
 *=============================================================================
 *
 *=============================================================================
 * ACTION EFFECT: target
 *- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 * Causes the target(s) to take damage/healing from the skill/item and
 * incurs any changes made to the target(s) such as buffs and states.
 *- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 * Usage Example: action effect
 *=============================================================================
 *
 *=============================================================================
 * ADD stat BUFF: target, (turns), (show)
 *- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 * Affects the target with 'stat' buff. Replace 'stat' with 'hp', 'mp', 'atk',
 * 'def', 'mat', 'mdf', 'agi', or 'luk'. If you include a number after the
 * target, it will buff the target by that many turns. Include 'show' and it
 * will show the target getting the buff applied in the battle log.
 *- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 * Usage Example: add atk buff: user, 3, show
 *                add def buff: target, 8
 *=============================================================================
 *
 *=============================================================================
 * ADD stat DEBUFF: target, (turns), (show)
 *- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 * Affects the target with 'stat' debuff. Replace 'stat' with 'hp', 'mp',
 * 'atk', 'def', 'mat', 'mdf', 'agi', or 'luk'. If you include a number after
 * the target, it will debuff the target by that many turns. Include 'show' and
 * it will show the target getting the debuff applied in the battle log.
 *- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 * Usage Example: add atk debuff: user, 3, show
 *                add def debuff: target, 8
 *=============================================================================
 *
 *=============================================================================
 * ADD STATE X: target, (show)
 * ADD STATE X, Y, Z: target (show)
 *- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 * Affects the target with X state (including Y and Z if used in that format).
 * If 'show' is included, it will display any state related messages.
 *- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 * Usage Example: add state 5: target
 *                add state 6, 7, 8: user, show
 *=============================================================================
 *
 *=============================================================================
 * ANIMATION X: target, (mirror)
 *- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 * Plays animation X on target. 'Mirror' will cause the animation to appear
 * mirrored. Keep in mind that animations played on actors will automatically
 * be mirrored and setting the mirror option will reverse it and have it appear
 * unmirrored.
 *- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 * Usage Example: animation 5: user
 *                animation 6: target, mirror
 *=============================================================================
 *
 *=============================================================================
 * ANIMATION WAIT: X
 *- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 * Waits x animaiton frames. Each frame for an animation does not last one game
 * frame, but instead, several. To make life easier, you can use this to have
 * the game wait x frames played for the animation.
 *- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 * Usage Example: animation 5: user
 *                animation 6: target, mirror
 *=============================================================================
 *
 *=============================================================================
 * BGM: STOP
 * BGM: MEMORIZE
 * BGM: MEMORY
 * BGM: filename, (volume), (pitch), (pan)
 *- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 * Changes the current background music at hand. 'Stop' will stop any BGM from
 * playing. 'Memorize' will memorize the current BGM. 'Memory' will replay the
 * memorized BGM if there is one playing. If you choose a filename (without the
 * filename extensions), the game will play that BGM instead. Using this
 * option opens up access to the volume, pitch, and pan control, all of which
 * are optional to use. If no values are inputed for volume, pitch, and pan,
 * the game will use the settings in this plugin's parameters.
 *- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 * Usage Example: bgm: stop
 *                bgm: memorize
 *                bgm: memory
 *                bgm: Battle7
 *                bgm: Theme2, 80, 100, 0
 *=============================================================================
 *
 *=============================================================================
 * BGS: STOP
 * BGS: MEMORIZE
 * BGS: MEMORY
 * BGS: filename, (volume), (pitch), (pan)
 *- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 * Changes the current background sound at hand. 'Stop' will stop any BGS from
 * playing. 'Memorize' will memorize the current BGS. 'Memory' will replay the
 * memorized BGS if there is one playing. If you choose a filename (without the
 * filename extensions), the game will play that BGS instead. Using this
 * option opens up access to the volume, pitch, and pan control, all of which
 * are optional to use. If no values are inputed for volume, pitch, and pan,
 * the game will use the settings in this plugin's parameters.
 *- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 * Usage Example: bgs: stop
 *                bgs: memorize
 *                bgs: memory
 *                bgs: City
 *                bgs: Darkness, 80, 100, 0
 *=============================================================================
 *
 *=============================================================================
 * BREAK ACTION
 *- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 * This will force the remainder of the action sequences for the part of the
 * skill/item to shut down and be skipped.
 *- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 * Usage Example: break action
 *=============================================================================
 *
 *=============================================================================
 * CAST ANIMATION
 *- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 * Plays an animation on the skill's user. Will not occur if the action is
 * an item or the user's default normal attack.
 *- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 * Usage Example: cast animation
 *=============================================================================
 *
 *=============================================================================
 * CLEAR BATTLE LOG
 *- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 * Clears all the messages at the top of the screen.
 *- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 * Usage Example: clear battle log
 *=============================================================================
 *
 *=============================================================================
 * CHANGE SWITCH X: on/off/toggle/switch z
 * CHANGE SWITCH X..Y: on/off/toggle/switch z
 * CHANGE SWITCH X TO Y: on/off/toggle/switch z
 *- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 * Changes Game Switch X to on, off, toggle (switching between on/off), or
 * to whatever value the switch y is.
 *- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 * Usage Example: change switch 1: on
 *                change switch 2..4: off
 *                change switch 5 to 8: toggle
 *                change switch 9: switch 5
 *=============================================================================
 *
 *=============================================================================
 * CHANGE VARIABLE X = Y
 * CHANGE VARIABLE X += Y
 * CHANGE VARIABLE X -= Y
 * CHANGE VARIABLE X *= Y
 * CHANGE VARIABLE X /= Y
 * CHANGE VARIABLE X %= Y
 *- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 * Changes variable X in the middle of the action sequence to be modified
 * by value Y. Y can be either an integer or a piece of code.
 *- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 * Usage Example: change variable 1 = 2
 *                change variable 3 += 4
 *                change variable 5 -= 6
 *                change variable 7 *= 8
 *                change variable 9 /= 10
 *                change variable 11 %= 12
 *=============================================================================
 *
 *=============================================================================
 * COLLAPSE: target, (force)
 *- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 * If the target is to be dead at this point, this will be the point in the
 * action sequence where you can promt the game to kill the target as long
 * as the target has 0 HP. If you want to force the death of the target,
 * include the 'force' command after the targets.
 *- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 * Usage Example: collapse: user
 *                collapse: target, force
 *=============================================================================
 *
 *=============================================================================
 * COMMON EVENT: X
 *- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 * Plays common event X at that point in the action sequence. Nothing else
 * will continue until the common event is finished (unless it is a forced
 * action, in which case, it will wait until the action is complete first).
 *- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 * Usage Example: common event: 1
 *=============================================================================
 *
 *=============================================================================
 * DEATH BREAK
 *- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 * If a user were to die for any reason during the middle of the skill
 * (either via counter attack or reflection), this will force the remainder
 * of the action sequences for the part of the skill/item to shut down and
 * be skipped.
 *- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 * Usage Example: death break
 *=============================================================================
 *
 *=============================================================================
 * DISPLAY ACTION
 *- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 * Displays the action's name at the top of the battle log. It will remain
 * there until the battle log is cleared.
 *- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 * Usage Example: display action
 *=============================================================================
 *
 *=============================================================================
 * EVAL: code
 *- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 * For those who'd like to do something that the current Battle Engine doesn't
 * support, you can use an eval function to have a piece of code occur. Users
 * beware, for those unfamiliar with JavaScript should avoid handling this
 * action sequence command.
 *- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 * Usage Example: eval: $gameParty.loseItem($dataItems[3], 10)
 *=============================================================================
 *
 *=============================================================================
 * GAIN ITEM X: Y           LOSE ITEM X: Y
 * GAIN WEAPON X: Y         LOSE WEAPON X: Y
 * GAIN ARMOR X: Y          LOSE ARMOR X: Y
 *- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 * Your party will gain/lose item x, weapon x, or armor x in the amount of
 * y. If you choose to omit y, it will default to 1.
 *- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 * Usage Example: gain item 1: 20
 *                lose weapon 2
 *                gain armor 3: 50
 *=============================================================================
 *
 *=============================================================================
 * GOLD +x
 * GOLD -x
 *- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 * Your party will gain/lose gold in the middle of battle by x amount.
 *- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 * Usage Example: gold +2000
 *                gold -500
 *=============================================================================
 *
 *=============================================================================
 * IF ... ELSE STATEMENTS
 *- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 * For those familiar with programming, you can use if...else statements to
 * perform different actions based on different conditions. Use 'if' to
 * specify a block of code to be executed, if a specified condition is true.
 * Use 'else'  to specify a block of code to be executed, if the same
 * condition is false. Use 'else if' to specify a new condition to test, if
 * the first condition is false. Use 'end' to specify where the conditions
 * are to end.
 *- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 * Usage Example:
 *     if $gameSwitches.value(1)
 *         action effect
 *     else if $gameSwitches.value(2)
 *         action effect
 *         action effect
 *     else
 *         action effect
 *         action effect
 *         action effect
 *     end
 *
 * *Note: You do not have to indent the code in between to work. It just
 * looks better that way in your action sequences.
 *=============================================================================
 *
 *=============================================================================
 * IMMORTAL: targets, true/false
 *- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 * Sets the targets to a state of immortality so that they don't die in the
 * middle of an attack. This is to ensure every action effect goes through.
 *- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 * Usage Example: immortal: targets true
 *=============================================================================
 *
 *=============================================================================
 * HP +X: target, (show)
 * HP -X: target, (show)
 * HP +X%: target, (show)
 * HP -X%: target, (show)
 * HP +VARIABLE X: target, (show)
 * HP -VARIABLE X: target, (show)
 * HP +VARIABLE X%: target, (show)
 * HP -VARIABLE X%: target, (show)
 *- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 * Target(s) gains HP equal to X values. To show the popup, insert 'show'
 * after the target in the action sequence line. Including 'show' is
 * entirely optional. If 'show' is omitted, no popup will be displayed.
 *- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 * Usage Example: hp +500: user
 *                hp -variable 5: target
 *                hp +25%: target
 *                hp -variable 7: user
 *=============================================================================
 *
 *=============================================================================
 * ME: STOP
 * ME: filename, (volume), (pitch), (pan)
 *- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 * Causes the battle to play a music fanfare. 'Stop' will stop any ME from
 * playing. If you choose a filename (without the filename extensions), the
 * game will play that ME instead. Using this option opens up access to the
 * volume, pitch, and pan control, all of which are optional to use. If no
 * values are inputed for volume, pitch, and pan, the game will use the
 * settings in this plugin's parameters.
 *- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 * Usage Example: me: stop
 *                me: Victory1
 *                me: Darkness, 80, 100, 0
 *=============================================================================
 *
 *=============================================================================
 * MOTION WAIT: target
 *- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 * Makes the game wait 12 frames if the target(s) performing the action is an
 * actor. If the target(s) is not an actor, no waiting will be done.
 *- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 * Usage Example: motion wait: user
 *=============================================================================
 *
 *=============================================================================
 * MP +X: target, (show)
 * MP -X: target, (show)
 * MP +X%: target, (show)
 * MP -X%: target, (show)
 * MP +VARIABLE X: target, (show)
 * MP -VARIABLE X: target, (show)
 * MP +VARIABLE X%: target, (show)
 * MP -VARIABLE X%: target, (show)
 *- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 * Target(s) gains MP equal to X values. To show the popup, insert 'show'
 * after the target in the action sequence line. Including 'show' is
 * entirely optional. If 'show' is omitted, no popup will be displayed.
 *- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 * Usage Example: mp +500: user
 *                mp -variable 5: target
 *                mp +25%: target
 *                mp -variable 7: user
 *=============================================================================
 *
 *=============================================================================
 * PERFORM ACTION
 *- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 * Causes actors to step forward and swing their weapon, thrust it, however
 * the motion that is determined will be automatically done by the game.
 *- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 * Usage Example: perform action
 *=============================================================================
 *
 *=============================================================================
 * PERFORM FINISH
 *- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 * Causes actor to move back to its home spot.
 *- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 * Usage Example: perform finish
 *=============================================================================
 *
 *=============================================================================
 * PERFORM START
 *- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 * Causes actor to move forward from its home spot.
 *- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 * Usage Example: perform start
 *=============================================================================
 *
 *=============================================================================
 * REFRESH STATUS
 *- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 * Refreshes the status window in the middle of an action sequence.
 *- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 * Usage Example: refresh status
 *=============================================================================
 *
 *=============================================================================
 * REMOVE stat BUFF: target, (show)
 *- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 * Removes the 'stat' buff from target. Replace 'stat' with 'hp', 'mp', 'atk',
 * 'def', 'mat', 'mdf', 'agi', or 'luk'. Include 'show' and it  will show the
 * target getting the buff removed in the battle log.
 *- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 * Usage Example: remove atk buff: user, show
 *                remove def buff: target
 *=============================================================================
 *
 *=============================================================================
 * REMOVE stat DEBUFF: target, (show)
 *- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 * Removes the 'stat' debuff from target. Replace 'stat' with 'hp', 'mp',
 * 'atk', 'def', 'mat', 'mdf', 'agi', or 'luk'. Include 'show' and it  will
 * show the target getting the debuff removed in the battle log.
 *- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 * Usage Example: remove atk debuff: user, show
 *                remove def debuff: target
 *=============================================================================
 *
 *=============================================================================
 * REMOVE STATE X: target (show)
 * REMOVE STATE X, Y, Z: target (show)
 *- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 * Removes X state (including Y and Z if used in that format) from target.
 * If 'show' is included, it will display any state related messages.
 *- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 * Usage Example: remove state 5: target
 *                remove state 6, 7, 8: user, show
 *=============================================================================
 *
 *=============================================================================
 * SE: filename, (volume), (pitch), (pan)
 * SE: PLAY OK
 * SE: PLAY CURSOR
 * SE: PLAY CANCEL
 * SE: PLAY BUZZER
 * SE: PLAY EQUIP
 * SE: PLAY SAVE
 * SE: PLAY LOAD
 * SE: PLAY BATTLE START
 * SE: PLAY ESCAPE
 * SE: PLAY ENEMY ATTACK
 * SE: PLAY ENEMY DAMAGE
 * SE: PLAY ENEMY COLLAPSE
 * SE: PLAY BOSS COLLAPSE 1
 * SE: PLAY BOSS COLLAPSE 2
 * SE: PLAY ACTOR DAMAGE
 * SE: PLAY ACTOR COLLAPSE
 * SE: PLAY RECOVERY
 * SE: PLAY MISS
 * SE: PLAY EVASION
 * SE: PLAY MAGIC EVASION
 * SE: PLAY REFLECTION
 * SE: PLAY SHOP
 * SE: PLAY USE ITEM
 * SE: PLAY USE SKILL
 *- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 * Causes the battle to play a Sound Effect. If you choose a filename (without
 * the filename extensions), the game will play that ME instead. Using this
 * option opens up access to the volume, pitch, and pan control, all of which
 * are optional to use. If no values are inputed for volume, pitch, and pan,
 * the game will use the settings in this plugin's parameters. Using the action
 * sequences with 'play x' in them will cause the game to play a system sound
 * set within RPG Maker's database.
 *- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 * Usage Example: se: play enemy attack
 *                se: Ice1
 *                se: Laser2, 80, 100, 0
 *=============================================================================
 *
 *=============================================================================
 * TP +X: target, (show)
 * TP -X: target, (show)
 * TP +X%: target, (show)
 * TP -X%: target, (show)
 * TP +VARIABLE X: target, (show)
 * TP -VARIABLE X: target, (show)
 * TP +VARIABLE X%: target, (show)
 * TP -VARIABLE X%: target, (show)
 *- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 * Target(s) gains TP equal to X values. To show the popup, insert 'show'
 * after the target in the action sequence line. Including 'show' is
 * entirely optional. If 'show' is omitted, no popup will be displayed. For
 * TP to actually show popups, another plugin is needed to display TP popups.
 *- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 * Usage Example: tp +500: user
 *                tp -variable 5: target
 *                tp +25%: target
 *                tp -variable 7: user
 *=============================================================================
 *
 *=============================================================================
 * WAIT: frames
 *- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 * Makes the game wait a certain amount of frames before going on to the
 * next action in the action sequence.
 *- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 * Usage Example: wait: 60
 *=============================================================================
 *
 *=============================================================================
 * WAIT FOR ANIMATION
 *- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 * Waits for all animations to finish before going on to the next action in
 * the action sequence.
 *- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 * Usage Example: wait for animation
 *=============================================================================
 *
 *=============================================================================
 * WAIT FOR EFFECT
 *- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 * Waits for all effects to finish playing before continuing on.
 *- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 * Usage Example: wait for effect
 *=============================================================================
 *
 *=============================================================================
 * WAIT FOR MOVEMENT
 *- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 * Waits for all battler movements to finish before going on to the next
 * action in the action sequence.
 *- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 * Usage Example: wait for movement
 *=============================================================================
 *
 *=============================================================================
 * WAIT FOR NEW LINE
 *- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 * Waits for a new line to appear in the log window before going on to the
 * next action in the action sequence.
 *- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 * Usage Example: wait for new line
 *=============================================================================
 *
 *=============================================================================
 * WAIT FOR POPUPS
 *- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 * Waits for all popups to finish playing before going on to the next action.
 *- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 * Usage Example: wait for popups
 *=============================================================================
 *
 * ============================================================================
 * Changelog
 * ============================================================================
 *
 * Version 1.13:
 * - 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.12:
 * - Updated for RPG Maker MV version 1.5.0.
 *
 * Version 1.11:
 * - Lunatic Mode fail safes added.
 *
 * Version 1.10a:
 * - Changed the 'Change Variable' action sequence to read more effectively.
 * - Documentation update for 'Action Common Event' and 'Common Event' to
 * indicate that they will not work immediately if used as a forced action
 * since another event is already running.
 *
 * Version 1.09:
 * - Fixed a bug that didn't allow for HP and MP buff/debuff removal.
 *
 * Version 1.08:
 * - Added 'Break Action' action sequence effect to completely cancel out all
 * of the remaining action effects.
 *
 * Version 1.07:
 * - Fixed a bug with the forcing a Collapse action sequence.
 *
 * Version 1.06:
 * - If using the Add State action sequence to add the Death state, it will
 * remove immortality settings.
 *
 * Version 1.05:
 * - Optimized status window to refresh at a minimum.
 *
 * Version 1.04:
 * - Updated help file to include Character X for target typing.
 *
 * Version 1.03:
 * - Fixed a bug that didn't make the sounds played work properly (again).
 *
 * Version 1.02:
 * - Fixed a bug that didn't make the sounds played work properly.
 *
 * Version 1.01:
 * - Fixed a small bug that didn't allow Change Variable to work properly with
 * evaluated strings.
 *
 * Version 1.00:
 * - Finished plugin!
 */
//=============================================================================

if (Imported.YEP_BattleEngineCore) {

//=============================================================================
// Parameters
//=============================================================================

Yanfly.Parameters = PluginManager.parameters('YEP_X_ActSeqPack1');
Yanfly.Param = Yanfly.Param || {};

Yanfly.Param.SoundVolume = Number(Yanfly.Parameters['Default Volume']);
Yanfly.Param.SoundPitch = Number(Yanfly.Parameters['Default Pitch']);
Yanfly.Param.SoundPan = Number(Yanfly.Parameters['Default Pan']);

//=============================================================================
// BattleManager
//=============================================================================

Yanfly.ASP1.BattleManager_processActionSequence =
    BattleManager.processActionSequence;
BattleManager.processActionSequence = function(actionName, actionArgs) {
  // ADD X BUFF
  if (actionName.match(/ADD[ ](.*)[ ]BUFF/i)) {
    return this.actionAddBuff(actionName, actionArgs);
  }
  // ADD X DEBUFF
  if (actionName.match(/ADD[ ](.*)[ ]DEBUFF/i)) {
    return this.actionAddDebuff(actionName, actionArgs);
  }
  // ADD STATE X
  if (actionName.match(/(?:ADD_STATE|ADD STATE)[ ](\d+(?:\s*,\s*\d+)*)/i)) {
    return this.actionAddState(actionName, actionArgs);
  }
  // ANIMATION X
  if (actionName.match(/ANIMATION[ ](\d+)/i)) {
    return this.actionAnimation(parseInt(RegExp.$1), actionArgs);
  }
  // BGM, MUSIC, SONG
  if (['BGM', 'MUSIC', 'SONG'].contains(actionName)) {
    return this.actionBgmPlay(actionArgs);
  }
  // BGS, AMBIENCE
  if (['BGS', 'AMBIENCE'].contains(actionName)) {
    return this.actionBgsPlay(actionArgs);
  }
  // BREAK ACTION
  if (actionName === 'BREAK ACTION') {
    return this.actionBreakAction();
  }
  // COLLAPSE: target, (force)
  if (actionName === 'COLLAPSE') {
    return this.actionCollapse(actionArgs);
  }
  // COMMON EVENT: event id
  if (actionName === 'COMMON EVENT') {
    return this.actionCommonEvent(actionArgs[0]);
  }
  // CHANGE SWITCH X
  if (actionName.match(/CHANGE[ ]SWITCH[ ](.*)/i)) {
    return this.actionChangeSwitch(actionName, actionArgs);
  }
  // CHANGE VARIABLE X
  if (actionName.match(/CHANGE[ ]VARIABLE[ ](.*)/i)) {
    return this.actionChangeVariable(actionName);
  }
  // EVAL, SCRIPT
  if (['EVAL', 'SCRIPT'].contains(actionName)) {
    return this.actionEval(actionArgs);
  }
  // GAIN ITEM (item, weapon, armor) X
  if (actionName.match(/GAIN[ ](.*)[ ](\d+)/i) ||
  actionName.match(/LOSE[ ](.*)[ ](\d+)/i)) {
    return this.actionGainItem(actionName, actionArgs);
  }
  // GOLD +/- VALUE
  if (actionName.match(/GOLD[ ]([\+\-]\d+)/i)) {
    return this.actionGoldModify(parseInt(RegExp.$1));
  }
  // ME, FANFARE
  if (['ME', 'FANFARE'].contains(actionName)) {
    return this.actionMePlay(actionArgs);
  }
  // REFRESH STATUS, REFRESH WINDOW
  if (['REFRESH STATUS', 'REFRESH WINDOW'].contains(actionName)) {
    return this.actionRefreshStatus();
  }
  // REMOVE X BUFF
  if (actionName.match(/REMOVE[ ](.*)[ ]BUFF/i)) {
    return this.actionRemoveBuff(actionName, actionArgs);
  }
  // REMOVE X DEBUFF
  if (actionName.match(/REMOVE[ ](.*)[ ]DEBUFF/i)) {
    return this.actionRemoveDebuff(actionName, actionArgs);
  }
  // REMOVE STATE X
  if
  (actionName.match(/(?:REMOVE_STATE|REMOVE STATE)[ ](\d+(?:\s*,\s*\d+)*)/i)) {
    return this.actionRemoveState(actionName, actionArgs);
  }
  // SE, SOUND, SFX
  if (['SE', 'SOUND', 'SFX'].contains(actionName)) {
    return this.actionSePlay(actionArgs);
  }
  // HP +/- VALUE
  if (actionName.match(/HP[ ](.*)/i)) {
    return this.actionHpModify(actionName, actionArgs);
  }
  // MP +/- VALUE
  if (actionName.match(/MP[ ](.*)/i)) {
    return this.actionMpModify(actionName, actionArgs);
  }
  // TP +/- VALUE
  if (actionName.match(/TP[ ](.*)/i)) {
    return this.actionTpModify(actionName, actionArgs);
  }
  return Yanfly.ASP1.BattleManager_processActionSequence.call(this,
    actionName, actionArgs);
};

BattleManager.getParamId = function(stat) {
    switch (stat) {
    case 'HP':
    case 'MAXHP':
    case 'MAX HP':
      return 0;
      break;
    case 'MP':
    case 'MAXMP':
    case 'MAX MP':
    case 'SP':
    case 'MAXSP':
    case 'MAX SP':
      return 1;
      break;
    case 'ATK':
    case 'STR':
      return 2;
      break;
    case 'DEF':
      return 3;
      break;
    case 'MAT':
    case 'INT' || 'SPI':
      return 4;
      break;
    case 'MDF':
    case 'RES':
      return 5;
      break;
    case 'AGI':
    case 'SPD':
      return 6;
      break;
    case 'LUK':
      return 7;
      break;
    }
    return -1;
};

BattleManager.actionAddBuff = function(actionName, actionArgs) {
  var targets = this.makeActionTargets(actionArgs[0]);
  if (targets.length < 1) return false;
  var show = false;
  for (var i = 0; i < actionArgs.length; ++i) {
    var actionArg = actionArgs[i];
    if (actionArg.toUpperCase() === 'SHOW') show = true;
  }
  if (actionName.match(/ADD[ ](.*)[ ]BUFF/i)) {
    var paramId = this.getParamId(String(RegExp.$1).toUpperCase());
  } else {
    return true;
  }
  if (actionArgs[1] && parseInt(actionArgs[1]) > 0) {
    var turns = parseInt(actionArgs[1]);
  } else {
    var turns = 5;
  }
  if (paramId < 0) return true;
  targets.forEach(function(target) {
    target.addBuff(paramId, turns);
    if (show) this._logWindow.displayActionResults(this._subject, target);
  }, this);
  return true;
};

BattleManager.actionAddDebuff = function(actionName, actionArgs) {
  var targets = this.makeActionTargets(actionArgs[0]);
  if (targets.length < 1) return false;
  var show = false;
  for (var i = 0; i < actionArgs.length; ++i) {
    var actionArg = actionArgs[i];
    if (actionArg.toUpperCase() === 'SHOW') show = true;
  }
  if (actionName.match(/ADD[ ](.*)[ ]DEBUFF/i)) {
    var paramId = this.getParamId(String(RegExp.$1).toUpperCase());
  } else {
    return true;
  }
  if (actionArgs[1] && parseInt(actionArgs[1]) > 0) {
    var turns = parseInt(actionArgs[1]);
  } else {
    var turns = 5;
  }
  if (paramId < 0) return true;
  targets.forEach(function(target) {
    target.addDebuff(paramId, turns);
    if (show) this._logWindow.displayActionResults(this._subject, target);
  }, this);
  return true;
};

BattleManager.actionAddState = function(actionName, actionArgs) {
  var targets = this.makeActionTargets(actionArgs[0]);
  if (targets.length < 1) return false;
  var show = false;
  for (var i = 0; i < actionArgs.length; ++i) {
    var actionArg = actionArgs[i];
    if (actionArg.toUpperCase() === 'SHOW') show = true;
  }
  if (actionName.match(/(?:ADD_STATE|ADD STATE)[ ](\d+(?:\s*,\s*\d+)*)/i)) {
    var states = JSON.parse('[' + RegExp.$1.match(/\d+/g) + ']');
  } else {
    return true;
  }
  targets.forEach(function(target) {
    for (var i = 0; i < states.length; ++i) {
      stateId = states[i];
      if (stateId === target.deathStateId()) {
        if (target._prevImmortalState === false) target.forceRemoveImmortal();
      }
      target.addState(stateId);
      if (show) this._logWindow.displayActionResults(this._subject, target);
    }
  }, this);
  return true;
};

BattleManager.actionAnimation = function(aniId, actionArgs) {
  if (aniId <= 0) return;
  var targets = this.makeActionTargets(actionArgs[0]);
  if (targets.length < 1) return false;
  var mirror = false;
  if (actionArgs[1] && actionArgs[1].toUpperCase() === 'MIRROR') mirror = true;
  this._logWindow.showNormalAnimation(targets, aniId, mirror);
  return true;
};

BattleManager.actionBgmPlay = function(actionArgs) {
  if (actionArgs.length < 1) return true;
  if (actionArgs[0].toUpperCase() === 'STOP') {
    AudioManager.stopBgm();
  } else if (actionArgs[0].toUpperCase() === 'MEMORIZE') {
    this._battleMemorizedBgm = AudioManager.saveBgm();
    return true;
  } else if (actionArgs[0].toUpperCase() === 'MEMORY') {
    if (this._battleMemorizedBgm) {
      AudioManager.replayBgm(this._battleMemorizedBgm);
    }
  } else {
    var name = actionArgs[0];
    if (!name) return true;
    var vol = actionArgs[1] || Yanfly.Param.SoundVolume;
    var pitch = actionArgs[2] || Yanfly.Param.SoundPitch;
    var pan = actionArgs[3] || Yanfly.Param.SoundPan;
    var bgm = {
      name: name,
      volume: vol,
      pitch: pitch,
      pan: pan
    };
    AudioManager.playBgm(bgm);
  }
  return true;
};

BattleManager.actionBgsPlay = function(actionArgs) {
  if (actionArgs.length < 1) return true;
  if (actionArgs[0].toUpperCase() === 'STOP') {
    AudioManager.stopBgs();
  } else if (actionArgs[0].toUpperCase() === 'MEMORIZE') {
    this._battleMemorizedBgs = AudioManager.saveBgs();
    return true;
  } else if (actionArgs[0].toUpperCase() === 'MEMORY') {
    if (this._battleMemorizedBgs) {
      AudioManager.replayBgs(this._battleMemorizedBgs);
    }
  } else {
    var name = actionArgs[0];
    if (!name) return true;
    var vol = actionArgs[1] || Yanfly.Param.SoundVolume;
    var pitch = actionArgs[2] || Yanfly.Param.SoundPitch;
    var pan = actionArgs[3] || Yanfly.Param.SoundPan;
    var bgs = {
      name: name,
      volume: vol,
      pitch: pitch,
      pan: pan
    };
    AudioManager.playBgs(bgs);
  }
  return true;
};

BattleManager.actionBreakAction = function() {
    this._targets = [];
    this._actionList = [];
    this._individualTargets = [];
    this._phase = 'phaseChange';
    return false;
};

BattleManager.actionCollapse = function(actionArgs) {
  var targets = this.makeActionTargets(actionArgs[0]);
  var force = false;
  if (actionArgs[1]) var force = (actionArgs[1].toUpperCase() === 'FORCE');
  targets.forEach(function(target) {
    if (force) {
      target.removeImmortal();
      target.addState(target.deathStateId());
    }
    if (target.isDeathStateAffected()) target.performCollapse();

  }, this);
  return false;
};

BattleManager.actionCommonEvent = function(id) {
  if ($gameTroop.isEventRunning()) {
    var ev = $dataCommonEvents[id];
    if (!ev) return;
    var list = ev.list;
    var interpreter = $gameTroop._interpreter;
    interpreter.setupChild(list, 0);
  } else {
    $gameTemp.reserveCommonEvent(id);
  }
  return false;
};

BattleManager.actionChangeSwitch = function(actionName, actionArgs) {
  var subject = this._subject;
  var user = this._subject;
  var target = this._targets[0];
  var targets = this._targets;
  var action = this._action;
  var item = this._action.item();
  var switches = [];
  if (actionName.match(/SWITCH[ ](\d+)/i)) {
    switches = [parseInt(RegExp.$1)];
  } else if (actionName.match(/SWITCH[ ](\d+)..(\d+)/i)) {
    switches = [getRange(parseInt(RegExp.$1), parseInt(RegExp.$2))];
  } else if (actionName.match(/SWITCH[ ](\d+)[ ]TO[ ](\d+)/i)) {
      switches = [getRange(parseInt(RegExp.$1), parseInt(RegExp.$2))];
  } else {
    return true;
  }
  var result = actionArgs[0].toUpperCase();
  var value;
  if (['ON', 'TRUE'].contains(result)) {
    value = true;
  } else if (['OFF', 'FALSE'].contains(result)) {
    value = false;
  } else if (['TOGGLE', 'OPPOSITE', 'REVERSE'].contains(result)) {
    value = 'toggle';
  } else if (result.match(/SWITCH[ ](\d+)/i)) {
    value = $gameSwitches.value(parseInt(RegExp.$1));
  }
  switches.forEach(function(switchId) {
    if (value === 'toggle') {
      $gameSwitches.setValue(switchId, !$gameSwitches.value(switchId));
    } else {
      $gameSwitches.setValue(switchId, value);
    }
  }, this);
  return true;
};

BattleManager.actionChangeVariable = function(actionName) {
  var cV1 =
  /CHANGE[ ](?:VARIABLE|VAR)[ ](\d+)[ ](.*)[ ](?:VARIABLE|VAR)[ ](\d+)/i;
  var cV2 = /CHANGE[ ](?:VARIABLE|VAR)[ ](\d+)[ ](.*?)[ ](.*)/i;
  var subject = this._subject;
  var user = this._subject;
  var target = this._targets[0];
  var targets = this._targets;
  var action = this._action;
  var item = this._action.item();
  if (this._actSeq[0].match(cV1)) {
    var mainVar = parseInt(RegExp.$1);
    var operation = String(RegExp.$2);
    var editVar = $gameVariables.value(parseInt(RegExp.$3));
  } else if (this._actSeq[0].match(cV2)) {
    var mainVar = parseInt(RegExp.$1);
    var operation = String(RegExp.$2);
    var editVar = eval(String(RegExp.$3));
  } else {
    return true;
  }
  var mainValue = $gameVariables.value(mainVar);
  if (['='].contains(operation)) {
    $gameVariables.setValue(mainVar, eval(editVar));
  } else if (['+=', '+'].contains(operation)) {
    $gameVariables.setValue(mainVar, mainValue + eval(editVar));
  } else if (['-=', '-'].contains(operation)) {
    $gameVariables.setValue(mainVar, mainValue - eval(editVar));
  } else if (['*=', '*'].contains(operation)) {
    $gameVariables.setValue(mainVar, mainValue * eval(editVar));
  } else if (['/=', '/'].contains(operation)) {
    $gameVariables.setValue(mainVar, mainValue / eval(editVar));
  } else if (['%=', '%'].contains(operation)) {
    $gameVariables.setValue(mainVar, mainValue % eval(editVar));
  }
  return true;
};

BattleManager.actionEval = function(actionArgs) {
    if (actionArgs.length < 1) return true;
    var subject = this._subject;
    var user = this._subject;
    var target = this._targets[0];
    var targets = this._targets;
    var action = this._action;
    var item = this._action.item();
    var text = String(actionArgs[0]);
    for (var i = 1; i < actionArgs.length; ++i) {
        text = text + ', ' + String(actionArgs[i]);
    }
    try {
      eval(text);
    } catch (e) {
      Yanfly.Util.displayError(e, text, 'ACTION SEQUENCE EVAL ERROR');
    }
    return false;
};

BattleManager.actionGainItem = function(actionName, actionArgs) {
    var gainItem;
    var type;
    var itemId;
    if (actionName.match(/GAIN[ ](.*)[ ](\d+)/i)) {
      gainItem = true;
      type = String(RegExp.$1).toUpperCase();
      itemId = parseInt(RegExp.$2);
    } else if (actionName.match(/LOSE[ ](.*)[ ](\d+)/i)) {
      gainItem = false;
      type = String(RegExp.$1).toUpperCase();
      itemId = parseInt(RegExp.$2);
    } else {
      return true;
    }
    var item;
    if (type === 'ITEM') {
      item = $dataItems[itemId];
    } else if (['WPN', 'WEAPON'].contains(type)) {
      item = $dataWeapons[itemId];
    } else if (['ARM', 'ARMOR', 'ARMOUR'].contains(type)) {
      item = $dataArmors[itemId];
    } else {
      return true;
    }
    var amount = Math.max(1, parseInt(actionArgs[0]));
    if (isNaN(amount)) amount = 1;
    if (gainItem)  $gameParty.gainItem(item, amount);
    if (!gainItem) $gameParty.loseItem(item, amount);
    return true;
};

BattleManager.actionGoldModify = function(value) {
    $gameParty.gainGold(value);
    return true;
};

BattleManager.actionHpModify = function(actionName, actionArgs) {
    var targets = this.makeActionTargets(actionArgs[0]);
    if (targets.length < 1) return false;
    var change;
    var percent;
    if (actionName.match(/HP[ ]([+-])(?:VARIABLE|VAR)[ ](\d+)/i)) {
      change = parseInt($gameVariables.value(parseInt(RegExp.$2)));
      if (String(RegExp.$1) === '-') change *= -1;
      percent = false;
    } else if
    (actionName.match(/HP[ ]([+-])(?:VARIABLE|VAR)[ ](\d+)([%％])/i)) {
      change = parseInt($gameVariables.value(parseInt(RegExp.$2)));
      if (String(RegExp.$1) === '-') change *= -1;
      percent = true;
    } else if (actionName.match(/HP[ ]([\+\-]\d+)([%％])/i)) {
      change = parseInt(RegExp.$1);
      percent = true;
    } else if (actionName.match(/HP[ ]([\+\-]\d+)/i)) {
      change = parseInt(RegExp.$1);
      percent = false;
    } else {
      return false;
    }
    var show = false;
    for (var i = 0; i < actionArgs.length; ++i) {
      var actionArg = actionArgs[i];
      if (actionArg.toUpperCase() === 'SHOW') show = true;
    }
    var value;
    targets.forEach(function(target) {
      target.clearResult();
      value = percent ? (target.mhp * change * 0.01) : change;
      target.gainHp(parseInt(value));
      if (show) {
        target.startDamagePopup();
        this._logWindow.displayActionResults(this._subject, target);
      }
    }, this);
    return true;
};

BattleManager.actionMePlay = function(actionArgs) {
  if (actionArgs.length < 1) return true;
  if (actionArgs[0].toUpperCase() === 'STOP') {
    AudioManager.stopMe();
  } else {
    var name = actionArgs[0];
    if (!name) return true;
    var vol = actionArgs[1] || Yanfly.Param.SoundVolume;
    var pitch = actionArgs[2] || Yanfly.Param.SoundPitch;
    var pan = actionArgs[3] || Yanfly.Param.SoundPan;
    var me = {
      name: name,
      volume: vol,
      pitch: pitch,
      pan: pan
    };
    AudioManager.playMe(me);
  }
  return true;
};

BattleManager.actionMpModify = function(actionName, actionArgs) {
    var targets = this.makeActionTargets(actionArgs[0]);
    if (targets.length < 1) return false;
    var change;
    var percent;
    if (actionName.match(/MP[ ]([+-])(?:VARIABLE|VAR)[ ](\d+)/i)) {
      change = parseInt($gameVariables.value(parseInt(RegExp.$2)));
      if (String(RegExp.$1) === '-') change *= -1;
      percent = false;
    } else if
    (actionName.match(/MP[ ]([+-])(?:VARIABLE|VAR)[ ](\d+)([%％])/i)) {
      change = parseInt($gameVariables.value(parseInt(RegExp.$2)));
      if (String(RegExp.$1) === '-') change *= -1;
      percent = true;
    } else if (actionName.match(/MP[ ]([\+\-]\d+)([%％])/i)) {
      change = parseInt(RegExp.$1);
      percent = true;
    } else if (actionName.match(/MP[ ]([\+\-]\d+)/i)) {
      change = parseInt(RegExp.$1);
      percent = false;
    } else {
      return false;
    }
    var show = false;
    for (var i = 0; i < actionArgs.length; ++i) {
      var actionArg = actionArgs[i];
      if (actionArg.toUpperCase() === 'SHOW') show = true;
    }
    var value;
    targets.forEach(function(target) {
      target.clearResult();
      value = percent ? (target.mmp * change * 0.01) : change;
      target.gainMp(parseInt(value));
      if (show) {
        target.startDamagePopup();
        this._logWindow.displayActionResults(this._subject, target);
      }
    }, this);
    return true;
};

BattleManager.actionRefreshStatus = function() {
    this._statusWindow.refresh();
    return false;
};

BattleManager.actionRemoveBuff = function(actionName, actionArgs) {
  var targets = this.makeActionTargets(actionArgs[0]);
  if (targets.length < 1) return false;
  var show = false;
  for (var i = 0; i < actionArgs.length; ++i) {
    var actionArg = actionArgs[i];
    if (actionArg.toUpperCase() === 'SHOW') show = true;
  }
  if (actionName.match(/REMOVE[ ](.*)[ ]BUFF/i)) {
    var paramId = this.getParamId(String(RegExp.$1).toUpperCase());
  } else {
    return true;
  }
  if (paramId < 0) return true;
  targets.forEach(function(target) {
    if (target.isBuffAffected(paramId)) {
      target.removeBuff(paramId);
      if (show) this._logWindow.displayActionResults(this._subject, target);
    }
  }, this);
  return true;
};

BattleManager.actionRemoveDebuff = function(actionName, actionArgs) {
  var targets = this.makeActionTargets(actionArgs[0]);
  if (targets.length < 1) return false;
  var show = false;
  for (var i = 0; i < actionArgs.length; ++i) {
    var actionArg = actionArgs[i];
    if (actionArg.toUpperCase() === 'SHOW') show = true;
  }
  if (actionName.match(/REMOVE[ ](.*)[ ]DEBUFF/i)) {
    var paramId = this.getParamId(String(RegExp.$1).toUpperCase());
  } else {
    return true;
  }
  if (paramId < 0) return true;
  targets.forEach(function(target) {
    if (target.isDebuffAffected(paramId)) {
      target.removeBuff(paramId);
      if (show) this._logWindow.displayActionResults(this._subject, target);
    }
  }, this);
  return true;
};

BattleManager.actionRemoveState = function(actionName, actionArgs) {
  var targets = this.makeActionTargets(actionArgs[0]);
  if (targets.length < 1) return false;
  var show = false;
  for (var i = 0; i < actionArgs.length; ++i) {
    var actionArg = actionArgs[i];
    if (actionArg.toUpperCase() === 'SHOW') show = true;
  }
  if
  (actionName.match(/(?:REMOVE_STATE|REMOVE STATE)[ ](\d+(?:\s*,\s*\d+)*)/i)) {
    var states = JSON.parse('[' + RegExp.$1.match(/\d+/g) + ']');
  } else {
    return true;
  }
  targets.forEach(function(target) {
    for (var i = 0; i < states.length; ++i) {
      stateId = states[i];
      if (target.isStateAffected(stateId)) {
        target.removeState(stateId);
        if (show) this._logWindow.displayActionResults(this._subject, target);
      }
    }
  }, this);
  return true;
};

BattleManager.actionSePlay = function(actionArgs) {
  if (actionArgs.length < 1) return true;
  if (actionArgs[0].toUpperCase() === 'PLAY CURSOR') {
    SoundManager.playCursor();
  } else if (actionArgs[0].toUpperCase() === 'PLAY OK') {
    SoundManager.playOk();
  } else if (actionArgs[0].toUpperCase() === 'PLAY CANCEL') {
    SoundManager.playCancel();
  } else if (actionArgs[0].toUpperCase() === 'PLAY BUZZER') {
    SoundManager.playBuzzer();
  } else if (actionArgs[0].toUpperCase() === 'PLAY EQUIP') {
    SoundManager.playEquip();
  } else if (actionArgs[0].toUpperCase() === 'PLAY SAVE') {
    SoundManager.playSave();
  } else if (actionArgs[0].toUpperCase() === 'PLAY LOAD') {
    SoundManager.playLoad();
  } else if (actionArgs[0].toUpperCase() === 'PLAY BATTLE START') {
    SoundManager.playBattleStart();
  } else if (actionArgs[0].toUpperCase() === 'PLAY ESCAPE') {
    SoundManager.playEscape();
  } else if (actionArgs[0].toUpperCase() === 'PLAY ENEMY ATTACK') {
    SoundManager.playEnemyAttack();
  } else if (actionArgs[0].toUpperCase() === 'PLAY ENEMY DAMAGE') {
    SoundManager.playEnemyDamage();
  } else if (actionArgs[0].toUpperCase() === 'PLAY ENEMY COLLAPSE') {
    SoundManager.playEnemyCollapse();
  } else if (actionArgs[0].toUpperCase() === 'PLAY BOSS COLLAPSE 1') {
    SoundManager.playBossCollapse1();
  } else if (actionArgs[0].toUpperCase() === 'PLAY BOSS COLLAPSE 2') {
    SoundManager.playBossCollapse2();
  } else if (actionArgs[0].toUpperCase() === 'PLAY ACTOR DAMAGE') {
    SoundManager.playActorDamage();
  } else if (actionArgs[0].toUpperCase() === 'PLAY ACTOR COLLAPSE') {
    SoundManager.playActorCollapse();
  } else if (actionArgs[0].toUpperCase() === 'PLAY RECOVERY') {
    SoundManager.playRecovery();
  } else if (actionArgs[0].toUpperCase() === 'PLAY MISS') {
    SoundManager.playMiss();
  } else if (actionArgs[0].toUpperCase() === 'PLAY EVASION') {
    SoundManager.playEvasion();
  } else if (actionArgs[0].toUpperCase() === 'PLAY MAGIC EVASION') {
    SoundManager.playMagicEvasion();
  } else if (actionArgs[0].toUpperCase() === 'PLAY REFLECTION') {
    SoundManager.playReflection();
  } else if (actionArgs[0].toUpperCase() === 'PLAY SHOP') {
    SoundManager.playShop();
  } else if (actionArgs[0].toUpperCase() === 'PLAY USE ITEM') {
    SoundManager.playUseItem();
  } else if (actionArgs[0].toUpperCase() === 'PLAY USE SKILL') {
    SoundManager.playUseSkill();
  } else {
    var name = actionArgs[0];
    if (!name) return true;
    var vol = actionArgs[1] || Yanfly.Param.SoundVolume;
    var pitch = actionArgs[2] || Yanfly.Param.SoundPitch;
    var pan = actionArgs[3] || Yanfly.Param.SoundPan;
    var se = {
      name: name,
      volume: vol,
      pitch: pitch,
      pan: pan
    };
    AudioManager.playSe(se);
  }
  return true;
};

BattleManager.actionTpModify = function(actionName, actionArgs) {
    var targets = this.makeActionTargets(actionArgs[0]);
    if (targets.length < 1) return false;
    var change;
    var percent;
    if (actionName.match(/TP[ ]([+-])(?:VARIABLE|VAR)[ ](\d+)/i)) {
      change = parseInt($gameVariables.value(parseInt(RegExp.$2)));
      if (String(RegExp.$1) === '-') change *= -1;
      percent = false;
    } else if
    (actionName.match(/TP[ ]([+-])(?:VARIABLE|VAR)[ ](\d+)([%％])/i)) {
      change = parseInt($gameVariables.value(parseInt(RegExp.$2)));
      if (String(RegExp.$1) === '-') change *= -1;
      percent = true;
    } else if (actionName.match(/TP[ ]([\+\-]\d+)([%％])/i)) {
      change = parseInt(RegExp.$1);
      percent = true;
    } else if (actionName.match(/TP[ ]([\+\-]\d+)/i)) {
      change = parseInt(RegExp.$1);
      percent = false;
    } else {
      return false;
    }
    var show = false;
    for (var i = 0; i < actionArgs.length; ++i) {
      var actionArg = actionArgs[i];
      if (actionArg.toUpperCase() === 'SHOW') show = true;
    }
    var value;
    targets.forEach(function(target) {
      target.clearResult();
      value = percent ? (target.maxTp() * change * 0.01) : change;
      target.gainTp(parseInt(value));
      if (show) {
        target.startDamagePopup();
        this._logWindow.displayActionResults(this._subject, target);
      }
    }, this);
    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();
    }
  }
};

//=============================================================================
// End of File
//=============================================================================
};


code:
//=============================================================================
// Yanfly Engine Plugins - Party System Extension - Actor Party Switch
// YEP_X_ActorPartySwitch.js
//=============================================================================

var Imported = Imported || {};
Imported.YEP_X_ActorPartySwitch = true;

var Yanfly = Yanfly || {};
Yanfly.PartySwitch = Yanfly.PartySwitch || {};
Yanfly.PartySwitch.version = 1.05;

//=============================================================================
 /*:
 * @plugindesc v1.05 (Req YEP_PartySystem.js and YEP_BattleEngineCore.js)
 * Allow actors to switch with other party members mid-battle.
 * @author Yanfly Engine Plugins
 *
 * @param ---General---
 * @default
 *
 * @param Switch Command
 * @parent ---General---
 * @desc The text that appears in the actor command window to switch allies.
 * @default Switch
 *
 * @param Switch Cooldown
 * @parent ---General---
 * @type number
 * @desc When an actor switches out, how many turns must the actor wait before
 * the actor can switch back in? Use 0 to disable this.
 * @default 1
 *
 * @param Show Command
 * @parent ---General---
 * @type boolean
 * @on Show
 * @off Hide
 * @desc Show party switching by default?
 * NO - false     YES - true
 * @default true
 *
 * @param Enable Command
 * @parent ---General---
 * @type boolean
 * @on Enable
 * @off Disable
 * @desc Enable party switching by default?
 * NO - false     YES - true
 * @default true
 *
 * @param ---Window---
 * @default
 *
 * @param Window X
 * @parent ---Window---
 * @desc The x position of the party switch window.
 * This is a formula.
 * @default 0
 *
 * @param Window Y
 * @parent ---Window---
 * @desc The y position of the party switch window.
 * This is a formula.
 * @default 0
 *
 * @param Window Width
 * @parent ---Window---
 * @desc The width of the party switch window.
 * This is a formula.
 * @default Graphics.boxWidth / 2
 *
 * @param Window Height
 * @parent ---Window---
 * @desc The height of the party switch window.
 * This is a formula.
 * @default Graphics.boxHeight - this.fittingHeight(4)
 *
 * @param Actor Graphic
 * @parent ---Window---
 * @type select
 * @option None
 * @value 0
 * @option Character
 * @value 1
 * @option Face
 * @value 2
 * @option Sideview Battler
 * @value 3
 * @desc What kind of graphic do you wish to associate with actors?
 * 0: None; 1: Character; 2: Face; 3: SV Battler
 * @default 2
 *
 * @param Font Size
 * @parent ---Window---
 * @type number
 * @min 1
 * @desc The font size used for the Actor Party Switch window.
 * Default: 28
 * @default 20
 *
 * @param Rect Height
 * @parent ---Window---
 * @type number
 * @min 0
 * @desc The height for each actor entry's height in pixels.
 * Use 0 for automatic detection.
 * @default 0
 *
 * @help
 * ============================================================================
 * Introduction
 * ============================================================================
 *
 * This plugin requires YEP_PartySystem and YEP_BattleEngineCore. Make sure
 * this plugin is located under both plugins in the plugin list.
 *
 * For games that benefit more from individual party switching, this plugin
 * grants players the ability to switch party members on an individual basis
 * rather than entire parties at a time mid-battle. However, actors that have
 * just switched in and are on cooldown, required for battle, or locked in the
 * party position cannot switch out.
 *
 * ============================================================================
 * Plugin Commands
 * ============================================================================
 *
 * For those who'd like to be able to change the settings of Actor Part Switch
 * midway through the game, use the following plugin commands:
 *
 * Plugin Commands:
 *
 *   ShowActorPartySwitch
 *   HideActorPartySwitch
 *   - Shows/hides the 'Switch' command from the actor command window from
 *   being visible.
 *
 *   EnableActorPartySwitch
 *   DisableActorPartySwitch
 *   - Enables/disables the 'Switch' command from the actor command window
 *   from being able to selected.
 *
 *   ResetActorPartySwitchCooldowns
 *   - Resets all cooldowns for actor party switching.
 *
 * ============================================================================
 * Changelog
 * ============================================================================
 *
 * Version 1.05:
 * - Updated for RPG Maker MV version 1.5.0.
 *
 * Version 1.04:
 * - Fixed a bug that caused the on-map party layout to not update if switching
 * has been used in battle.
 *
 * Version 1.03:
 * - Fixed a bug that prevented 'HideActorPartySwitch' from working properly.
 *
 * Version 1.02:
 * - Fixed a bug that caused subsequent battles to have actors appear in the
 * wrong positions.
 *
 * Version 1.01:
 * - Added compatibility check for people who weren't using Row Formations.
 * - Turning of 'Display TP in Battle' from the Database > System tab will now
 * turn off TP from displaying in the party list, too.
 *
 * Version 1.00:
 * - Finished Plugin!
 */
//=============================================================================

if (Imported.YEP_PartySystem && Imported.YEP_BattleEngineCore) {

//=============================================================================
// Parameter Variables
//=============================================================================

Yanfly.Parameters = PluginManager.parameters('YEP_X_ActorPartySwitch');
Yanfly.Param = Yanfly.Param || {};

Yanfly.Param.PartySwitchCmd = String(Yanfly.Parameters['Switch Command']);
Yanfly.Param.PartySwitchCooldown = Number(Yanfly.Parameters['Switch Cooldown']);
Yanfly.Param.PartySwitchShow = String(Yanfly.Parameters['Show Command']);
Yanfly.Param.PartySwitchShow = eval(Yanfly.Param.PartySwitchShow);
Yanfly.Param.PartySwitchEnable = String(Yanfly.Parameters['Enable Command']);
Yanfly.Param.PartySwitchEnable = eval(Yanfly.Param.PartySwitchEnable);

Yanfly.Param.PartySwitchWinX = String(Yanfly.Parameters['Window X']);
Yanfly.Param.PartySwitchWinY = String(Yanfly.Parameters['Window Y']);
Yanfly.Param.PartySwitchWinW = String(Yanfly.Parameters['Window Width']);
Yanfly.Param.PartySwitchWinH = String(Yanfly.Parameters['Window Height']);
Yanfly.Param.PartySwitchActGraphic = Number(Yanfly.Parameters['Actor Graphic']);
Yanfly.Param.PartySwitchFontSize = Number(Yanfly.Parameters['Font Size']);
Yanfly.Param.PartySwitchRectHeight = Number(Yanfly.Parameters['Rect Height']);

//=============================================================================
// BattleManager
//=============================================================================

Yanfly.PartySwitch.BattleManager_endBattle = BattleManager.endBattle;
BattleManager.endBattle = function(result) {
  Yanfly.PartySwitch.BattleManager_endBattle.call(this, result);
  this.resetActorPartySwitchCooldowns();
};

BattleManager.resetActorPartySwitchCooldowns = function() {
  var group = $gameParty.allMembers();
  var length = group.length;
  for (var i = 0; i < length; ++i) {
    var member = group[i];
    if (member) member.setPartySwitchCooldown(0);
  }
};

//=============================================================================
// Game_System
//=============================================================================

Yanfly.PartySwitch.Game_System_initialize = Game_System.prototype.initialize;
Game_System.prototype.initialize = function() {
  Yanfly.PartySwitch.Game_System_initialize.call(this);
  this.initActorPartySwitch();
};

Game_System.prototype.initActorPartySwitch = function() {
  this._showActorPartySwitch = Yanfly.Param.PartySwitchShow;
  this._enableActorPartySwitch = Yanfly.Param.PartySwitchEnable;
};

Game_System.prototype.isShowActorPartySwitch = function() {
  if (this._showActorPartySwitch === undefined) this.initActorPartySwitch();
  return this._showActorPartySwitch;
};

Game_System.prototype.setShowActorPartySwitch = function(value) {
  if (this._showActorPartySwitch === undefined) this.initActorPartySwitch();
  this._showActorPartySwitch = value;
};

Game_System.prototype.isActorPartySwitchEnabled = function() {
  if (this._enableActorPartySwitch === undefined) this.initActorPartySwitch();
  return this._enableActorPartySwitch;
};

Game_System.prototype.setActorPartySwitchEnabled = function(value) {
  if (this._enableActorPartySwitch === undefined) this.initActorPartySwitch();
  this._enableActorPartySwitch = value;
};

//=============================================================================
// Game_Battler
//=============================================================================

Yanfly.PartySwitch.Game_Battler_onTurnStart =
  Game_Battler.prototype.onTurnStart;
Game_Battler.prototype.onTurnStart = function() {
  Yanfly.PartySwitch.Game_Battler_onTurnStart.call(this);
  if (this.isActor()) this.updatePartySwitchCooldown();
};

//=============================================================================
// Game_Actor
//=============================================================================

Yanfly.PartySwitch.Game_Actor_initMembers = Game_Actor.prototype.initMembers;
Game_Actor.prototype.initMembers = function() {
  Yanfly.PartySwitch.Game_Actor_initMembers.call(this);
  this.initActorPartySwitch();
};

Game_Actor.prototype.initActorPartySwitch = function() {
  this._partySwitchCooldown = 0;
};

Game_Actor.prototype.getPartySwitchCooldown = function() {
  if (this._partySwitchCooldown === undefined) this.initActorPartySwitch();
  return this._partySwitchCooldown;
};

Game_Actor.prototype.setPartySwitchCooldown = function(value) {
  if (this._partySwitchCooldown === undefined) this.initActorPartySwitch();
  this._partySwitchCooldown = value;
};

Game_Actor.prototype.updatePartySwitchCooldown = function() {
  if (this._partySwitchCooldown === undefined) this.initActorPartySwitch();
  this._partySwitchCooldown -= 1;
};

//=============================================================================
// Game_Interpreter
//=============================================================================

Yanfly.PartySwitch.Game_Interpreter_pluginCommand =
    Game_Interpreter.prototype.pluginCommand;
Game_Interpreter.prototype.pluginCommand = function(command, args) {
  Yanfly.PartySwitch.Game_Interpreter_pluginCommand.call(this, command, args);
  if (command === 'ShowActorPartySwitch') {
    $gameSystem.setShowActorPartySwitch(true);
  } else if (command === 'HideActorPartySwitch') {
    $gameSystem.setShowActorPartySwitch(false);
  } else if (command === 'EnableActorPartySwitch') {
    $gameSystem.setActorPartySwitchEnabled(true);
  } else if (command === 'DisableActorPartySwitch') {
    $gameSystem.setActorPartySwitchEnabled(false);
  } else if (command === 'ResetActorPartySwitchCooldowns') {
    BattleManager.resetActorPartySwitchCooldowns();
  }
};

//=============================================================================
// Window_Base
//=============================================================================

Window_Base.prototype.drawSvActor = function(actor, x, y) {
  var filename = actor.battlerName();
  var bitmap = ImageManager.loadSvActor(filename);
  var pw = bitmap.width / 9;
  var ph = bitmap.height / 6;
  var sx = 0;
  var sy = 0;
  this.contents.blt(bitmap, sx, sy, pw, ph, x - pw / 2, y - ph);
};

//=============================================================================
// Window_ActorCommand
//=============================================================================

Yanfly.PartySwitch.Window_ActorCommand_makeCommandList =
  Window_ActorCommand.prototype.makeCommandList;
Window_ActorCommand.prototype.makeCommandList = function() {
  Yanfly.PartySwitch.Window_ActorCommand_makeCommandList.call(this);
  this.addSwitchCommand();
};

Window_ActorCommand.prototype.addSwitchCommand = function() {
  if (!$gameSystem.isShowActorPartySwitch()) return;
  var enabled = this.isActorPartySwitchEnabled();
  var text = Yanfly.Param.PartySwitchCmd;
  this.addCommand(text, 'partyswitch', enabled);
};

Window_ActorCommand.prototype.isActorPartySwitchEnabled = function() {
  if (!$gameSystem.isActorPartySwitchEnabled()) return false;
  if (!this._actor) return false;
  if (this._actor._locked) return false;
  if (this._actor._required) return false;
  return this._actor.getPartySwitchCooldown() <= 0;
};

//=============================================================================
// Window_ActorPartySwitch
//=============================================================================

function Window_ActorPartySwitch() {
  this.initialize.apply(this, arguments);
}

Window_ActorPartySwitch.prototype = Object.create(Window_Command.prototype);
Window_ActorPartySwitch.prototype.constructor = Window_ActorPartySwitch;

Window_ActorPartySwitch.prototype.initialize = function() {
  var x = eval(Yanfly.Param.PartySwitchWinX);
  var y = eval(Yanfly.Param.PartySwitchWinY);
  Window_Command.prototype.initialize.call(this, x, y);
  this.openness = 0;
  this.deactivate();
};

Window_ActorPartySwitch.prototype.standardFontSize = function() {
    return Yanfly.Param.PartySwitchFontSize;
};

Window_ActorPartySwitch.prototype.standardPadding = function() {
  if (this._calc) return Window_Base.prototype.standardPadding.call(this);
  return 6;
};

Window_ActorPartySwitch.prototype.windowWidth = function() {
  this._calc = true;
  var width = eval(Yanfly.Param.PartySwitchWinW);
  this._calc = false;
  return width;
};

Window_ActorPartySwitch.prototype.windowHeight = function() {
  this._calc = true;
  var height = eval(Yanfly.Param.PartySwitchWinH);
  this._calc = false;
  return height;
};

Window_ActorPartySwitch.prototype.itemHeight = function() {
  var height = Yanfly.Param.PartySwitchRectHeight || this.autoHeight();
  return Math.max(height, this.lineHeight() * 2);
};

Window_ActorPartySwitch.prototype.autoHeight = function() {
  switch (this.graphicType()) {
  case 3:
    return this.lineHeight() * 3;
    break;
  }
  return this.lineHeight() * 2;
};

Window_ActorPartySwitch.prototype.graphicType = function() {
  return Yanfly.Param.PartySwitchActGraphic;
};

Window_ActorPartySwitch.prototype.makeCommandList = function() {
  var array = $gameParty._actors;
  var length = array.length;
  for (var i = 0; i < length; ++i) {
    var actorId = array[i];
    var actor = $gameActors.actor(actorId);
    if (actor.isBattleMember()) continue;
    var enabled = this.isActorEnabled(actor);
    this.addCommand(actor.name(), 'switch', enabled, actorId);
  }
};

Window_ActorPartySwitch.prototype.isActorEnabled = function(actor) {
  if (actor.isDead()) return false;
  if (!actor.canMove()) return false;
  return true;
};

Window_ActorPartySwitch.prototype.drawItem = function(index) {
  var actorId = this._list[index].ext;
  var actor = $gameActors.actor(actorId);
  this.changePaintOpacity(this.isActorEnabled(actor));
  this.drawActorGraphic(actor, index);
};

Window_ActorPartySwitch.prototype.drawActorGraphic = function(actor, index) {
  var type = this.graphicType();
  if (type <= 0) {
    this.drawActorData(actor, index, this.textPadding());
  } else if (type === 1) {
    this.drawActorCharGfx(actor, index);
  } else if (type === 2) {
    this.drawActorFaceGfx(actor, index);
  } else if (type >= 3) {
    this.drawActorSvGfx(actor, index);
  }
};

Window_ActorPartySwitch.prototype.drawActorData = function(actor, index, dx) {
  var rect = this.itemRect(index);
  rect.x = dx;
  rect.width -= dx + this.textPadding();
  var dw = Math.floor(rect.width / 2);
  var dw2 = Math.ceil(dw / 2);
  var dx2 = dx + dw;
  var dy = rect.y;
  this.drawActorName(actor, dx, dy, dw);
  this.drawActorHp(actor, dx2, dy, dw);
  dy += this.lineHeight();
  this.drawActorIcons(actor, dx, dy, dw);
  if (this.itemHeight() >= this.lineHeight() * 3 ||
  !$dataSystem.optDisplayTp) {
    this.drawActorMp(actor, dx2, dy, dw);
    if ($dataSystem.optDisplayTp) {
      this.drawActorTp(actor, dx2, dy + this.lineHeight(), dw);
    }
  } else {
    this.drawActorMp(actor, dx2, dy, dw2);
    this.drawActorTp(actor, dx2 + dw2, dy, dw2);
  }
};

Window_ActorPartySwitch.prototype.drawActorCharGfx = function(actor, index) {
  var bitmap = ImageManager.loadCharacter(actor.characterName());
  if (bitmap.width <= 0) {
    return setTimeout(this.drawActorCharGfx.bind(this, actor, index), 5);
  }
  var rect = this.itemRect(index);
  var big = ImageManager.isBigCharacter(actor.characterName());
  var pw = bitmap.width / (big ? 3 : 12);
  var ph = bitmap.height / (big ? 4 : 8);
  var x = Math.ceil(pw / 2 + this.textPadding());
  var y = rect.y + rect.height;
  if (rect.height > ph) y -= Math.ceil((rect.height - ph) / 2);
  this.drawActorCharacter(actor, x, y);
  this.drawActorData(actor, index, Math.floor(x * 2) + this.textPadding() * 2);
};

Window_ActorPartySwitch.prototype.drawActorFaceGfx = function(actor, index) {
  var bitmap = ImageManager.loadFace(actor.faceName());
  if (bitmap.width <= 0) {
    return setTimeout(this.drawActorFaceGfx.bind(this, actor, index), 5);
  }
  var rect = this.itemRect(index);
  var big = ImageManager.isBigCharacter(actor.faceName());
  var w = Window_Base._faceWidth;
  var h = Math.min(Window_Base._faceHeight, rect.height - 4);
  var x = rect.x + 2;
  var y = rect.y + 2;
  this.drawActorFace(actor, x, y, w, h);
  this.drawActorData(actor, index, w + this.textPadding() + 2);
};

Window_ActorPartySwitch.prototype.drawActorSvGfx = function(actor, index) {
  var bitmap = ImageManager.loadSvActor(actor.battlerName());
  if (bitmap.width <= 0) {
    return setTimeout(this.drawActorSvGfx.bind(this, actor, index), 5);
  }
  var rect = this.itemRect(index);
  var pw = bitmap.width / 9;
  var ph = bitmap.height / 6;
  var x = Math.ceil(pw / 2 + this.textPadding());
  var y = rect.y + rect.height;
  if (rect.height > ph) y -= Math.ceil((rect.height - ph) / 2);
  this.drawSvActor(actor, x, y);
  this.drawActorData(actor, index, Math.floor(x * 2) + this.textPadding() * 2);
};

//=============================================================================
// Scene_Battle
//=============================================================================

Yanfly.PartySwitch.Scene_Battle_isAnyInputWindowActive =
  Scene_Battle.prototype.isAnyInputWindowActive;
Scene_Battle.prototype.isAnyInputWindowActive = function() {
  if (Yanfly.PartySwitch.Scene_Battle_isAnyInputWindowActive.call(this)) {
    return true;
  }
  if (this._actorPartySwitchWindow) {
    var win = this._actorPartySwitchWindow;
    return win.isOpen() || win.isOpening();
  }
};

Yanfly.PartySwitch.Scene_Battle_createAllWindows =
  Scene_Battle.prototype.createAllWindows;
Scene_Battle.prototype.createAllWindows = function() {
  Yanfly.PartySwitch.Scene_Battle_createAllWindows.call(this);
  this.createActorPartySwitchWindow();
};

Yanfly.PartySwitch.Scene_Battle_createActorCommandWindow =
  Scene_Battle.prototype.createActorCommandWindow;
Scene_Battle.prototype.createActorCommandWindow = function() {
  Yanfly.PartySwitch.Scene_Battle_createActorCommandWindow.call(this);
  var win = this._actorCommandWindow;
  win.setHandler('partyswitch', this.commandPartySwitch.bind(this));
};

Scene_Battle.prototype.createActorPartySwitchWindow = function() {
  this._actorPartySwitchWindow = new Window_ActorPartySwitch();
  this.addChild(this._actorPartySwitchWindow);
  var win = this._actorPartySwitchWindow;
  win.setHandler('cancel', this.partySwitchCancel.bind(this));
  win.setHandler('switch', this.processPartySwitch.bind(this));
};

Scene_Battle.prototype.commandPartySwitch = function() {
  this._actorPartySwitchWindow.activate();
  this._actorPartySwitchWindow.refresh();
  this._actorPartySwitchWindow.select(0);
  this._actorPartySwitchWindow.open();
};

Scene_Battle.prototype.partySwitchCancel = function() {
  this._actorPartySwitchWindow.deactivate();
  this._actorPartySwitchWindow.close();
  this._actorCommandWindow.activate();
};

Scene_Battle.prototype.processPartySwitch = function() {
  var actorId = this._actorPartySwitchWindow.currentExt();
  var swapIn = $gameActors.actor(actorId);
  if (!swapIn) return this.partySwitchCancel();
  var swapOut = this._actorCommandWindow._actor;
  var index = $gameParty._battleMembers.indexOf(swapOut.actorId());
  var distance = Graphics.boxWidth - swapOut.spritePosX();
  distance += swapOut.spriteWidth();
  swapOut.battler().startMove(distance, 0, 20);
  swapOut.requestMotion('escape');
  setTimeout(this.processPartySwitching.bind(this, index, actorId), 300)
};

Scene_Battle.prototype.processPartySwitching = function(index, actorId) {
  var sprite = BattleManager.actor().battler();
  var swapOut = this._actorCommandWindow._actor;
  $gameParty._battleMembers[index] = actorId;
  this._actorPartySwitchWindow.deactivate();
  this._actorPartySwitchWindow.close();
  BattleManager.actor().setBattler(sprite);
  sprite.setBattler(BattleManager.actor());
  this.refreshBattleMembers();
  BattleManager.actor().requestMotion('walk');
  BattleManager.actor().spriteStepForward();
  $gameParty.reconstructActions();
  this.postPartySwitch(index, swapOut, BattleManager.actor());
  $gameParty.rearrangeActors();
  $gamePlayer.refresh();
};

Scene_Battle.prototype.postPartySwitch = function(index, swapOut, swapIn) {
  var cooldown = Yanfly.Param.PartySwitchCooldown;
  BattleManager.actor().setPartySwitchCooldown(cooldown)
  if (Imported.YEP_X_BattleSysATB && BattleManager.isATB()) {
    if (swapIn._atbSpeed === undefined) swapIn.onATBStart();
    swapIn._atbSpeed = swapOut._atbSpeed + BattleManager.atbTarget();
  }
  if (Imported.YEP_X_BattleSysCTB && BattleManager.isCTB()) {
    if (swapIn._ctbSpeed === undefined) swapIn.onCTBStart();
    swapIn._ctbSpeed = swapOut._ctbSpeed + BattleManager.ctbTarget();
  }
  if (Imported.YEP_RowFormation) {
    var subject = BattleManager._subject;
    BattleManager._subject = undefined;
    this.refreshRowPositions();
    BattleManager._subject = subject;
  }
  if (BattleManager.actor().isAutoBattle()) {
    BattleManager.actor().makeAutoBattleActions();
    this.selectNextCommand();
  } else if (BattleManager.actor().isConfused()) {
    BattleManager.actor().makeConfusionActions();
    this.selectNextCommand();
  } else {
    this._actorCommandWindow.setup(BattleManager.actor());
  }
};

Scene_Battle.prototype.refreshBattleMembers = function() {
  var members = $gameParty.battleMembers();
  var length = members.length;
  for (var i = 0; i < length; ++i) {
    var member = members[i];
    if (!member) continue;
    member.refresh();
    if (Imported.YEP_RowFormation) member.battler().refreshActorRow();
  }
  this.refreshStatus();
};

//=============================================================================
// End of File
//=============================================================================
};

repo_name: voidljb/karryn

license: unknown