code:
//=============================================================================
// バトルイベントを拡張するプラグイン
// FTKR_ExBattleEvent.js
// プラグインNo : 40
// 作成者     : フトコロ
// 作成日     : 2017/05/25
// 最終更新日 : 2020/03/02
// バージョン : v1.3.6
//=============================================================================

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

var FTKR = FTKR || {};
FTKR.EBE = FTKR.EBE || {};

/*:
 * @plugindesc v1.3.6 バトルイベントを拡張するプラグイン
 * @author フトコロ
 *
 * @param Battle Event
 * @desc 戦闘中に実行するコモンイベントID
 * 0 - 実行しない、カンマ(,)で区切って複数設定できます
 * @default
 *
 * @param --勝利時イベント--
 * @desc
 *
 * @param Custom Victory Event
 * @desc 戦闘勝利時の処理を変更できるようにするか
 * 0 - 変更しない, 1 - 変更する
 * @type select
 * @option 変更しない
 * @value 0
 * @option 変更する
 * @value 1
 * @default 0
 *
 * @param Victory Event
 * @desc 戦闘勝利時に実行するコモンイベントID
 * 0 - 実行しない
 * @type common_event
 * @default
 *
 * @param --敗北時イベント--
 * @desc
 *
 * @param Custom Defeat Event
 * @desc 戦闘敗北時の処理を変更できるようにするか
 * 0 - 変更しない, 1 - 変更する
 * @type select
 * @option 変更しない
 * @value 0
 * @option 変更する
 * @value 1
 * @default 0
 *
 * @param Defeat Event
 * @desc 戦闘敗北時に実行するコモンイベントID
 * 0 - 実行しない
 * @type common_event
 * @default
 *
 * @param --逃走時イベント--
 * @desc
 *
 * @param Custom Escape Event
 * @desc 戦闘逃走時の処理を変更できるようにするか
 * 0 - 変更しない, 1 - 変更する
 * @type select
 * @option 変更しない
 * @value 0
 * @option 変更する
 * @value 1
 * @default 0
 *
 * @param Escape Event
 * @desc 戦闘逃走時に実行するコモンイベントID
 * 0 - 実行しない
 * @type common_event
 * @default
 *
 * @param --中断時イベント--
 * @desc
 *
 * @param Custom Abort Event
 * @desc 戦闘中断時の処理を変更できるようにするか
 * 0 - 変更しない, 1 - 変更する
 * @type select
 * @option 変更しない
 * @value 0
 * @option 変更する
 * @value 1
 * @default 0
 *
 * @param Abort Event
 * @desc 戦闘中断時に実行するコモンイベントID
 * 0 - 実行しない
 * @type common_event
 * @default
 *
 * @param Abort BugFix
 * @desc コアスクリプトにおける戦闘中断時のバグ修正を行う。他のプラグインと競合する場合は、無効にしてください。
 * @type boolean
 * @on 有効
 * @off 無効
 * @default false
 *
 * @param --戦闘行動の強制--
 * @desc
 *
 * @param Invalid Battle Phase
 * @desc ここで規定したバトルフェーズ中に戦闘行動の強制が有効になる。複数規定する場合はカンマ(,)で区切る。
 * @default action
 *
 * @help
 *-----------------------------------------------------------------------------
 * 概要
 *-----------------------------------------------------------------------------
 * 本プラグインを実装することで、バトル終了時または中断時に
 * 指定したイベントを実行します。
 *
 * 実行可能なタイミング
 *      １．勝利時（敵が全滅した後）
 *      ２．敗北時（パーティーが全滅した後）
 *      ３．逃走時（パーティーコマンド「逃げる」やスキルの逃げる効果使用後）
 *      ４．中断時（イベントコマンド「バトルの中断」実行後）
 *
 * 戦闘終了時のイベントの処理が終了すると、バトル画面が終了します。
 *
 *
 * プラグインの使い方は、下のオンラインマニュアルページを見てください。
 * https://github.com/futokoro/RPGMaker/blob/master/FTKR_ExBattleEvent.ja.md
 *
 *
 *-----------------------------------------------------------------------------
 * 設定方法
 *-----------------------------------------------------------------------------
 * 1.「プラグインマネージャー(プラグイン管理)」に、本プラグインを追加して
 *    ください。
 *
 * 2. 以下のプラグインと組み合わせる場合は、プラグイン管理の順番に注意してください。
 *
 *    FTKR_CSS_CustomizeBattleResults.js
 *    ↑このプラグインよりも上に登録↑
 *    FTKR_ExBattleEvent.js
 *    ↓このプラグインよりも下に登録↓
 *    FTKR_ExVariablesChange.js
 *
 *
 *-----------------------------------------------------------------------------
 * 本プラグインのライセンスについて(License)
 *-----------------------------------------------------------------------------
 * 本プラグインはMITライセンスのもとで公開しています。
 * This plugin is released under the MIT License.
 *
 * Copyright (c) 2019 Futokoro
 * http://opensource.org/licenses/mit-license.php
 *
 *
 * プラグイン公開元
 * https://github.com/futokoro/RPGMaker/blob/master/README.md
 *
 *
 *-----------------------------------------------------------------------------
 * 変更来歴
 *-----------------------------------------------------------------------------
 *
 * v1.3.6 - 2020/03/02 : 機能追加
 *    1. 逃走時と中断時に指定のイベントを実行する機能を追加。
 *
 * v1.3.5 - 2020/01/15 : 不具合修正
 *    1. 戦闘終了時イベントで「戦闘行動の強制」を実行できない不具合を修正。
 *
 * v1.3.4 - 2019/12/29 : 仕様見直し
 *    1. 戦闘終了時イベントの実行処理を見直し。
 *
 * v1.3.3 - 2018/02/19 : 不具合修正
 *    1. Custom Victory Eventが0の時に、戦闘勝利イベントを実行すると
 *       戦闘勝利回数が2回増加してしまう不具合を修正。
 *
 * v1.3.2 - 2018/01/13 : 機能追加
 *    1. メッセージ表示関係のプラグインコマンドに、イベント処理を止める機能を追加。
 *
 * v1.3.1 - 2018/01/12 : 不具合修正
 *    1. 戦闘終了時イベント中にウェイトコマンドを実行すると、アクターの
 *       モーションが正常に再生されない不具合を修正。
 *
 * v1.3.0 - 2017/06/30 : 機能追加
 *    1. 戦闘終了時のイベントの後に、MVデフォルトの戦闘終了処理を実行する
 *       機能を追加。
 *
 * v1.2.0 - 2017/06/01 : 機能追加
 *    1. 敵キャラの戦闘行動を再設定するプラグインコマンドを追加。
 *
 * v1.1.0 - 2017/05/26 : 機能追加
 *    1. バトル中にコモンイベントを実行できる機能を追加。
 *    2. モーション実行コマンドにアクターを対象にできる機能を追加。
 *    3. 画面に数字をポップアップさせるプラグインコマンドを追加。
 *
 * v1.0.0 - 2017/05/25 : 初版作成
 *
 *-----------------------------------------------------------------------------
 */
//=============================================================================

var paramParse = function (obj) {
  return JSON.parse(JSON.stringify(obj, paramReplace));
};

var paramReplace = function (key, value) {
  try {
    return JSON.parse(value || null);
  } catch (e) {
    return value;
  }
};

var matchTextToRegs = function (test, regs) {
  return regs.some(function (reg) {
    return test.match(reg);
  });
};

var readCommentMeta = function (comment, metacodes) {
  if (!comment) return false;
  return metacodes.some(function (metacode) {
    var metaReg = new RegExp("<" + metacode + ">", "i");
    return metaReg.test(comment);
  });
};

var splitConvertNumber = function (param) {
  var results = [];
  (param + "").split(",").forEach(function (split) {
    match = /[ ]*(\d+)[ ]*-[ ]*(\d+)/.exec(split);
    if (match) {
      for (var i = Number(match[1]); i <= Number(match[2]); i++) {
        results.push(i);
      }
    } else {
      if (!isNaN(split)) results.push(Number(split));
    }
  });
  return results;
};

// textを条件式に使える状態に変換する
var convertTextToConditions = function (text) {
  var result = "";
  if (text) {
    var datas = text.split(";");
    datas.forEach(function (data, i) {
      result += data;
      if (datas[i + 1]) result += ")&&(";
    });
    result = "(" + result + ")";
  }
  return result;
};

var convertEscapeCharacters = function (text) {
  if (text == null) text = "";
  var window = SceneManager._scene._windowLayer.children[0];
  return window ? window.convertEscapeCharacters(text) : text;
};

//=============================================================================
// 自作関数(グローバル)
//=============================================================================

FTKR.gameData = FTKR.gameData || {
  user: null,
  target: null,
  item: null,
  number: 0,
};

if (!FTKR.setGameData) {
  FTKR.setGameData = function (user, target, item, number) {
    FTKR.gameData = {
      user: user || null,
      target: target || null,
      item: item || null,
      number: number || 0,
    };
  };
}

if (!FTKR.evalFormula) {
  FTKR.evalFormula = function (formula) {
    var datas = FTKR.gameData;
    try {
      var s = $gameSwitches._data;
      var v = $gameVariables._data;
      var a = datas.user;
      var b = datas.target;
      var item = datas.item;
      var number = datas.number;
      if (b) var result = b.result();
      var value = eval(formula);
      if (isNaN(value)) value = 0;
      return value;
    } catch (e) {
      console.error(e);
      return 0;
    }
  };
}

//=============================================================================
// プラグイン パラメータ
//=============================================================================
var parameters = PluginManager.parameters("FTKR_ExBattleEvent");

FTKR.EBE.battleEvents = splitConvertNumber(parameters["Battle Event"]);
FTKR.EBE.battleEnd = {
  victory: paramParse(parameters["Victory Event"] || 0),
  customV: paramParse(parameters["Custom Victory Event"] || 0),
  defeat: paramParse(parameters["Defeat Event"] || 0),
  customD: paramParse(parameters["Custom Defeat Event"] || 0),
  escape: paramParse(parameters["Escape Event"] || 0),
  customE: paramParse(parameters["Custom Escape Event"] || 0),
  abort: paramParse(parameters["Abort Event"] || 0),
  customA: paramParse(parameters["Custom Abort Event"] || 0),
  abortBF: paramParse(parameters["Abort BugFix"] || false),
  invalid: parameters["Invalid Battle Phase"] || "",
};

//=============================================================================
// プラグインコマンド
//=============================================================================

Game_Interpreter.prototype.setArgNumber = function (arg) {
  try {
    var arg = convertEscapeCharacters(arg);
    return Number(eval(arg));
  } catch (e) {
    console.error(e);
    return 0;
  }
};

var _EBE_Game_Interpreter_pluginCommand =
  Game_Interpreter.prototype.pluginCommand;
Game_Interpreter.prototype.pluginCommand = function (command, args) {
  _EBE_Game_Interpreter_pluginCommand.call(this, command, args);
  if (!command.match(/EBE_(.+)/i)) return;
  command = (RegExp.$1 + "").toUpperCase();
  switch (command) {
    case "戦闘終了時ステート解除":
    case "REMOVE_BATTLE_STATES":
      $gameParty.removeBattleStates();
      break;
    case "勝利モーション実行":
    case "PREFORM_VICTORY":
      $gameParty.performVictory();
      break;
    case "モーション実行":
    case "REQUEST_MOTION":
      if (!args[1] || args[1] === "全員" || args[1].toUpperCase() === "ALL") {
        $gameParty.requestMotion(args[0]);
      } else if (Number(args[1]) >= 0) {
        var actor = $gameActors.actor(Number(args[1]));
        if (actor) actor.requestMotion(args[0]);
      }
      break;
    case "勝利ME演奏":
    case "PLAY_VICTORY_ME":
      BattleManager.playVictoryMe();
      break;
    case "敗北ME演奏":
    case "PLAY_DEFEAT_ME":
      BattleManager.playDefeatMe();
      break;
    case "BGMBGS再開":
    case "REPLAY_BGM_AND_BGS":
      BattleManager.replayBgmAndBgs();
      break;
    case "BGM停止":
    case "STOP_BGM":
      AudioManager.stopBgm();
      break;
    case "戦闘報酬計算":
    case "MAKE_REWARDS":
      BattleManager.makeRewards();
      break;
    case "勝利メッセージ表示":
    case "DISPLAY_VICTORY_MESSAGE":
      BattleManager.displayVictoryMessage();
      if (args[0] === "-s") this.setWaitMode("message");
      break;
    case "敗北メッセージ表示":
    case "DISPLAY_DEFEAT_MESSAGE":
      BattleManager.displayDefeatMessage();
      if (args[0] === "-s") this.setWaitMode("message");
      break;
    case "戦闘報酬表示":
    case "DISPLAY_REWARDS":
      BattleManager.displayRewards();
      if (args[0] === "-s") this.setWaitMode("message");
      break;
    case "戦闘報酬入手":
    case "GAIN_REWARDS":
      BattleManager.gainRewards();
      break;
    case "戦闘再開":
    case "RESTART_BATTLE":
      BattleManager._checkEbeBattleEvent = false;
      break;
    case "数字ポップアップ":
    case "POPUP_NUMBER":
      this.setupNumberPopup(args);
      break;
    case "敵キャラの戦闘行動の設定":
    case "SET_BATTLE_ENEMY_ACTION":
      var memberId = this.setArgNumber(args[0]);
      $gameTroop.members()[memberId].makeActions();
      break;
  }
};

Game_Interpreter.prototype.setupNumberPopup = function (args) {
  var index = this.setArgNumber(args[0]);
  for (var i = 1; i < args.length; i++) {
    var arg = (args[i] + "").toUpperCase();
    switch (arg) {
      case "画像番号":
      case "IMAGENUM":
        i++;
        var baseRow = this.setArgNumber(args[i]);
        break;
      case "表示内容":
      case "VALUE":
        i++;
        var value = this.setArgNumber(args[i]);
        break;
      case "ポップアップ高さ":
      case "POPUP_HEIGHT":
        i++;
        var height = this.setArgNumber(args[i]);
        if (!isNaN(args[i + 1])) {
          i++;
          var offsetY = this.setArgNumber(args[i]);
        }
        break;
      case "表示時間":
      case "DURATION":
        i++;
        var duration = this.setArgNumber(args[i]);
        break;
      case "表示差":
      case "DIFF_COUNT":
        i++;
        var maxcount = this.setArgNumber(args[i]);
        break;
      case "表示座標":
      case "POSITION":
        i++;
        var x = this.setArgNumber(args[i]);
        i++;
        var y = this.setArgNumber(args[i]);
        break;
      case "消去しない":
      case "REMAIN":
        var remain = true;
        break;
      case "消去":
      case "ERASE":
        BattleManager.eraseNumberPopup(index);
        return;
    }
  }
  var sprite = BattleManager.setupNumberPopup(index);
  if (!isNaN(baseRow)) sprite.setBaseRow(baseRow);
  if (!isNaN(height)) sprite.setPopupHeight(height, offsetY);
  if (!isNaN(duration)) sprite.setDuration(duration);
  if (!isNaN(maxcount)) sprite.setMaxcount(maxcount);
  if (!isNaN(x) && !isNaN(y)) sprite.setPosition(x, y);
  if (remain) sprite.setRemain();
  if (!isNaN(value)) sprite.setValue(value);
};

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

var _EBE_BattleManager_initMembers = BattleManager.initMembers;
BattleManager.initMembers = function () {
  _EBE_BattleManager_initMembers.call(this);
  this._checkEbeBattleEvent = false;
  this._battleEndPattern = 0;
  this._numberSprite = [];
  this._invalidPhase = FTKR.EBE.battleEnd.invalid.split(",");
};

var _EBE_Game_Party_requestMotionRefresh =
  Game_Party.prototype.requestMotionRefresh;
Game_Party.prototype.requestMotionRefresh = function () {
  if (!BattleManager.isBattleEndEvent()) {
    _EBE_Game_Party_requestMotionRefresh.call(this);
  }
};

BattleManager.isBattleEndEvent = function () {
  return $gameParty.inBattle() && this._checkEbeBattleEvent;
};

BattleManager.isInvalidPhase = function () {
  return this._invalidPhase.contains(this._phase);
};

var _EBE_BattleManager_updateEvent = BattleManager.updateEvent;
BattleManager.updateEvent = function () {
  if (this.isBattleEndEvent() && !this.isInvalidPhase()) {
    if (this.isActionForced()) {
      this.processForcedAction();
      return true;
    } else {
      return this.updateEventMain();
    }
  } else {
    return _EBE_BattleManager_updateEvent.call(this);
  }
};

var _EBE_BattleManager_checkBattleEnd = BattleManager.checkBattleEnd;
BattleManager.checkBattleEnd = function () {
  if (this.isBattleEndEvent()) {
    this._checkEbeBattleEvent = false;
    switch (this._battleEndPattern) {
      case 0: //勝利
        if (FTKR.EBE.battleEnd.customV) break;
        _EBE_BattleManager_processVictory.call(this);
        return true;
      case 1: //逃走
        if (FTKR.EBE.battleEnd.customE) break;
        _EBE_BattleManager_processAbort.call(this);
        return true;
      case 2: //敗北
        if (FTKR.EBE.battleEnd.customD) break;
        _EBE_BattleManager_processDefeat.call(this);
        return true;
      case 3: //中断
        this._battleEndPattern = 1;
        if (FTKR.EBE.battleEnd.customA) break;
        _EBE_BattleManager_processAbort.call(this);
        return true;
    }
    this.endBattle(this._battleEndPattern);
    return true;
  }
  return _EBE_BattleManager_checkBattleEnd.call(this);
};

var _EBE_BattleManager_processVictory = BattleManager.processVictory;
BattleManager.processVictory = function () {
  if (FTKR.EBE.battleEnd.victory && !this.isBattleEndEvent()) {
    if ($gameTroop.setupEbeBattleEvent("victory", ["EBE_戦闘勝利時"])) {
      this._checkEbeBattleEvent = true;
      this._battleEndPattern = 0;
    }
    return true;
  }
  _EBE_BattleManager_processVictory.call(this);
};

var _EBE_BattleManager_processDefeat = BattleManager.processDefeat;
BattleManager.processDefeat = function () {
  if (FTKR.EBE.battleEnd.defeat && !this.isBattleEndEvent()) {
    if ($gameTroop.setupEbeBattleEvent("defeat", ["EBE_戦闘敗北時"])) {
      this._checkEbeBattleEvent = true;
      this._battleEndPattern = 2;
    }
    return true;
  }
  _EBE_BattleManager_processDefeat.call(this);
};

var _EBE_BattleManager_checkAbort = BattleManager.checkAbort;
BattleManager.checkAbort = function () {
  if (FTKR.EBE.battleEnd.abortBF) {
    if ($gameParty.isEmpty()) {
      SoundManager.playEscape();
      this._escaped = true;
      this.processAbort();
    } else if (this.isAborting()) {
      this._escaped = true;
      this.processAbort();
    }
    return false;
  } else {
    _EBE_BattleManager_checkAbort.call(this);
  }
};

var _EBE_BattleManager_processAbort = BattleManager.processAbort;
BattleManager.processAbort = function () {
  if (
    FTKR.EBE.battleEnd.abort &&
    !this.isBattleEndEvent() &&
    this.isAborting()
  ) {
    if ($gameTroop.setupEbeBattleEvent("abort", ["EBE_戦闘中断時"])) {
      this._checkEbeBattleEvent = true;
      this._battleEndPattern = 3;
      this._phase = "battleEnd";
    }
    return true;
  } else if (FTKR.EBE.battleEnd.escape && !this.isBattleEndEvent()) {
    if ($gameTroop.setupEbeBattleEvent("escape", ["EBE_戦闘逃走時"])) {
      this._checkEbeBattleEvent = true;
      this._battleEndPattern = 1;
      this._phase = "battleEnd";
    }
    return true;
  }
  _EBE_BattleManager_processAbort.call(this);
};

BattleManager.setupNumberPopup = function (index) {
  if (!this._numberSprite[index]) {
    var sprite = new Sprite_Number();
    this._numberSprite[index] = sprite;
    this._spriteset._battleField.addChild(this._numberSprite[index]);
  }
  return this._numberSprite[index];
};

BattleManager.eraseNumberPopup = function (index) {
  this._spriteset._battleField.removeChild(this._numberSprite[index]);
  this._numberSprite[index] = {};
};

BattleManager.isActed = function (battler) {
  return !this._actionBattlers.contains(battler);
};

BattleManager.isActedEnemy = function (battlerId) {
  return !this.isActed($gameTroop.members()[battlerId]);
};

BattleManager.isActedActor = function (battlerId) {
  return !this.isActed($gameParty.members()[battlerId]);
};

//=============================================================================
// Game_Party
//=============================================================================

Game_Party.prototype.requestMotion = function (motionName) {
  this.members().forEach(function (actor) {
    if (actor.canMove()) actor.requestMotion(motionName);
  });
};

//=============================================================================
// Game_Troop
//=============================================================================

FTKR.EBE.Game_Troop_clear = Game_Troop.prototype.clear;
Game_Troop.prototype.clear = function () {
  FTKR.EBE.Game_Troop_clear.call(this);
  this._commonEventFlags = [];
};

FTKR.EBE.Game_Troop_setupBattleEvent = Game_Troop.prototype.setupBattleEvent;
Game_Troop.prototype.setupBattleEvent = function () {
  FTKR.EBE.Game_Troop_setupBattleEvent.call(this);
  if (!this._interpreter.isRunning()) {
    if (this._interpreter.setupReservedCommonEvent()) {
      return;
    }
    var eventIds = FTKR.EBE.battleEvents;
    for (var i = 0; i < eventIds.length; i++) {
      if (eventIds[i]) {
        var event = $dataCommonEvents[eventIds[i]];
        if (
          this.meetsCommonEventCommentConditions(event) &&
          !this._commonEventFlags[i]
        ) {
          this._interpreter.setup(event.list, this.troop().id);
          if (this.commonEventSpan(event) <= 1) {
            this._commonEventFlags[i] = true;
          }
          break;
        }
      }
    }
  }
};

FTKR.EBE.Game_Troop_increaseTurn = Game_Troop.prototype.increaseTurn;
Game_Troop.prototype.increaseTurn = function () {
  var eventIds = FTKR.EBE.battleEvents;
  for (var i = 0; i < eventIds.length; i++) {
    if (eventIds[i]) {
      var event = $dataCommonEvents[eventIds[i]];
      if (this.commonEventSpan(event) === 1) {
        this._commonEventFlags[i] = false;
      }
    }
  }
  FTKR.EBE.Game_Troop_increaseTurn.call(this);
};

Game_Troop.prototype.setupEbeBattleEvent = function (condition, metacodes) {
  if (!this._interpreter.isRunning()) {
    if (this._interpreter.setupReservedCommonEvent()) {
      return false;
    }
    var pages = this.troop().pages;
    for (var i = 0; i < pages.length; i++) {
      var page = pages[i];
      if (
        this.meetsPagesCommentConditions(page, metacodes) &&
        !this._eventFlags[i]
      ) {
        this._interpreter.setup(page.list, this.troop().id);
        this._eventFlags[i] = true;
        return true;
      }
    }
    var event = $dataCommonEvents[FTKR.EBE.battleEnd[condition]];
    this._interpreter.setup(event.list, this.troop().id);
    return true;
  }
  return false;
};

Game_Troop.prototype.meetsPagesCommentConditions = function (page, metacodes) {
  for (var v = 0; v < page.list.length; v++) {
    var list = page.list[v];
    if (list && [108, 408].contains(list.code)) {
      return readCommentMeta(list.parameters[0], metacodes);
    }
  }
};

Game_Troop.prototype.commonEventSpan = function (event) {
  for (var v = 0; v < event.list.length; v++) {
    var list = event.list[v];
    if (list && [108, 408].contains(list.code)) {
      var match = /<([^<>:]+)(:?)([^>]*)>/g.exec(list.parameters[0]);
      switch ((match[1] + "").toUpperCase()) {
        case "スパン":
        case "SPAN":
          switch ((match[3] + "").toUpperCase()) {
            case "バトル":
            case "BATTLE":
              return 0;
            case "ターン":
            case "TURN":
              return 1;
            case "モーメント":
            case "MOMENT":
              return 2;
          }
      }
    }
  }
  return 0;
};

Game_Troop.prototype.meetsCommonEventCommentConditions = function (event) {
  return this.meetsConditions(this.convertCommonEventConditions(event));
};

Game_Troop.prototype.convertCommonEventConditions = function (event) {
  var conditions = {};
  var code = false;
  for (var i = 0; i < event.list.length; i++) {
    var list = event.list[i];
    if (list && [108, 408].contains(list.code)) {
      var match = /<([^<>:]+)(:?)([^>]*)>/g.exec(list.parameters[0]);
      if (match) {
        switch ((match[1] + "").toUpperCase()) {
          case "ターン終了":
          case "TURNEND":
            conditions.turnEnding = true;
            break;
          case "ターン":
          case "TURN":
            if (match[2] === ":") {
              var turn = /(\d+)[ ]*\+[ ]*(\d+)[ ]*\*X/i.exec(match[3]);
              if (turn) {
                conditions.turnValid = true;
                conditions.turnA = Number(turn[1]);
                conditions.turnB = Number(turn[2]);
              }
            }
            break;
          case "敵キャラHP":
          case "ENEMY_HP":
            if (match[2] === ":") {
              var value = /#(\d+)[ ]*(\d+)[ ]*\%以下/i.exec(match[3]);
              if (!value)
                value = /#(\d+)[ ]*less[ ]than[ ]*(\d+)[ ]*\%/i.exec(match[3]);
              if (value) {
                conditions.enemyValid = true;
                conditions.enemyIndex = Number(value[1]);
                conditions.enemyHp = Number(value[2]);
              }
            }
            break;
          case "アクターHP":
          case "ACTOR_HP":
            if (match[2] === ":") {
              var value = /#(\d+)[ ]*(\d+)[ ]*\%以下/i.exec(match[3]);
              if (!value)
                value = /#(\d+)[ ]*less[ ]than[ ]*(\d+)[ ]*\%/i.exec(match[3]);
              if (value) {
                conditions.actorValid = true;
                conditions.actorId = Number(value[1]);
                conditions.actorHp = Number(value[2]);
              }
            }
            break;
          case "スイッチ":
          case "SWITCH":
            if (match[2] === ":") {
              conditions.switchValid = true;
              conditions.switchId = Number(match[3]);
            }
            break;
          case "/実行条件":
          case "/CONDITIONS":
            code = false;
            break;
          case "実行条件":
          case "CONDITIONS":
            conditions.customValid = true;
            conditions.custom = "";
            code = true;
            break;
        }
      } else {
        if (code) conditions.custom += list.parameters[0] + ";";
      }
    }
  }
  var page = { conditions: conditions };
  return page;
};

Game_Troop.prototype.evalConditionsFormula = function (text) {
  var formula = convertTextToConditions(text);
  if (!formula) return true;
  return FTKR.evalFormula(formula);
};

FTKR.EBE.Game_Troop_meetsConditions = Game_Troop.prototype.meetsConditions;
Game_Troop.prototype.meetsConditions = function (page) {
  var c = page.conditions;
  var result = FTKR.EBE.Game_Troop_meetsConditions.call(this, page);
  if (!c.turnEnding && !result) {
    return false;
  }
  if (
    (c.turnEnding ||
      c.turnValid ||
      c.enemyValid ||
      c.actorValid ||
      c.switchValid) &&
    !result
  ) {
    return false;
  }
  if (c.customValid && !this.evalConditionsFormula(c.custom)) {
    return false;
  }
  return true;
};

//=============================================================================
// Sprite_Number
// 数字をスプライトで表示する
//=============================================================================

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

Sprite_Number.prototype = Object.create(Sprite.prototype);
Sprite_Number.prototype.constructor = Sprite_Number;

Sprite_Number.prototype.initialize = function () {
  Sprite.prototype.initialize.call(this);
  this._flashColor = [0, 0, 0, 0];
  this._flashDuration = 0;
  this._damageBitmap = ImageManager.loadSystem("Damage");
  this._remain = false;
  this._duration = 30;
  this._maxcount = 0;
  this._count = 0;
  this._baseRow = 0;
  this._value = 0;
  this._index = 0;
  this._popupHeight = 40;
  this._popupOffsetY = 0.5;
  this._fullDuration = this._duration;
};

Sprite_Number.prototype.setupCriticalEffect = function () {
  this._flashColor = [255, 0, 0, 160];
  this._flashDuration = 60;
};

Sprite_Number.prototype.digitWidth = function () {
  return this._damageBitmap ? this._damageBitmap.width / 10 : 0;
};

Sprite_Number.prototype.digitHeight = function () {
  return this._damageBitmap ? this._damageBitmap.height / 5 : 0;
};

Sprite_Number.prototype.setBaseRow = function (baseRow) {
  this._baseRow = baseRow;
};

Sprite_Number.prototype.setDuration = function (duration) {
  this._duration = duration;
};

Sprite_Number.prototype.setValue = function (value) {
  this._value = value;
  this.resetFullDuration();
};

Sprite_Number.prototype.setMaxcount = function (maxcount) {
  this._maxcount = maxcount;
  this._count = this._maxcount;
};

Sprite_Number.prototype.setPosition = function (x, y) {
  this.x = x;
  this.y = y;
};

Sprite_Number.prototype.setRemain = function () {
  this._remain = true;
};

Sprite_Number.prototype.setPopupHeight = function (popupHeight, popupOffsetY) {
  this._popupHeight = popupHeight;
  if (!isNaN(popupOffsetY)) this._popupOffsetY = popupOffsetY;
};

Sprite_Number.prototype.resetFullDuration = function () {
  var string = Math.abs(this._value).toString();
  this._fullDuration = this._duration * string.length;
};

Sprite_Number.prototype.updateOpacity = function () {
  if (this._remain) return;
  if (this._fullDuration < 10) {
    this.opacity = (255 * this._fullDuration) / 10;
  }
};

Sprite_Number.prototype.update = function () {
  Sprite.prototype.update.call(this);
  if (this._count >= this._maxcount) {
    this.createDigit(this._index);
    this._index++;
    this._count = 0;
  } else {
    this._count++;
  }
  if (this._fullDuration > 0) {
    this._fullDuration--;
    for (var i = 0; i < this.children.length; i++) {
      this.updateChild(this.children[i]);
    }
  }
  this.updateFlash();
  this.updateOpacity();
};

Sprite_Number.prototype.createChildSprite = function () {
  var sprite = new Sprite();
  sprite.bitmap = this._damageBitmap;
  sprite.anchor.x = 0.5;
  sprite.anchor.y = 1;
  sprite.y = -this._popupHeight;
  sprite.ry = sprite.y;
  this.addChild(sprite);
  return sprite;
};

Sprite_Number.prototype.createDigit = function (index) {
  var value = this._value;
  var baseRow = this._baseRow;
  var string = Math.abs(value).toString();
  if (index >= string.length) return;
  var row = baseRow + (value < 0 ? 1 : 0);
  var w = this.digitWidth();
  var h = this.digitHeight();
  var sprite = this.createChildSprite();
  var n = Number(string[index]);
  sprite.setFrame(n * w, row * h, w, h);
  sprite.x = (index - (string.length - 1) / 2) * w;
  sprite.dy = -this._popupOffsetY * 2 * index;
};

Sprite_Number.prototype.updateChild = function (sprite) {
  sprite.dy += this._popupOffsetY;
  sprite.ry += sprite.dy;
  if (sprite.ry >= 0) {
    sprite.ry = 0;
    sprite.dy *= -0.6;
  }
  sprite.y = Math.round(sprite.ry);
  sprite.setBlendColor(this._flashColor);
};

Sprite_Number.prototype.updateFlash = function () {
  if (this._flashDuration > 0) {
    var d = this._flashDuration--;
    this._flashColor[3] *= (d - 1) / d;
  }
};

Sprite_Number.prototype.isPlaying = function () {
  return this._duration > 0;
};

/*--------------------------------------

--------------------------------------*/


code:
//=============================================================================
// SVキャラのモーションを拡張するプラグイン
// FTKR_ExSvMotion.js
// プラグインNo : 24
// 作成者     : フトコロ
// 作成日     : 2017/04/19
// 最終更新日 : 2019/04/13
// バージョン : v1.4.0
//=============================================================================

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

var FTKR = FTKR || {};
FTKR.ESM = FTKR.ESM || {};

//=============================================================================
/*:
 * @plugindesc v1.4.0 SVキャラのモーションを拡張するプラグイン
 * @author フトコロ
 *
 * @noteParam ESM_画像
 * @noteRequire 1
 * @noteDir img/sv_actors/
 * @noteType file
 * @noteData actors
 *
 * @param --行動モーションの設定--
 * @default
 *
 * @param Wait Motion
 * @desc 待機モーションを設定します
 * デフォルト wait
 * @default wait
 *
 * @param Damage Motion
 * @desc ダメージモーションを設定します
 * デフォルト damage
 * @default damage
 *
 * @param Evade Motion
 * @desc 回避モーションを設定します
 * デフォルト evade
 * @default evade
 *
 * @param Thrust Motion
 * @desc 突きモーションを設定します
 * デフォルト thrust
 * @default thrust
 *
 * @param Swing Motion
 * @desc 払いモーションを設定します
 * デフォルト swing
 * @default swing
 *
 * @param Missile Motion
 * @desc 飛び道具モーションを設定します
 * デフォルト missile
 * @default missile
 *
 * @param Skill Motion
 * @desc 防御使用モーションを設定します
 * デフォルト skill
 * @default skill
 *
 * @param Spell Motion
 * @desc 魔法使用モーションを設定します
 * デフォルト spell
 * @default spell
 *
 * @param Item Motion
 * @desc アイテム使用モーションを設定します
 * デフォルト item
 * @default item
 *
 * @param Recovery Motion
 * @desc HP回復時のモーションを設定します
 * @default
 *
 * @param Undecided Motion
 * @desc モーション画像が不明な場合に表示するモーションを設定します : デフォルト walk
 * @default walk
 *
 * @param --状態モーション1 設定--
 * @default
 *
 * @param Motion 1 name
 * @desc モーション1のコードを設定します。
 * デフォルト dying
 * @default dying
 *
 * @param Motion 1 Condition
 * @desc モーション1の状態を設定します。
 * デフォルト dying
 * @default dying
 *
 * @param --状態モーション2 設定--
 * @default
 *
 * @param Motion 2 name
 * @desc モーション2のコードを設定します。
 * デフォルト abnormal
 * @default abnormal
 *
 * @param Motion 2 Condition
 * @desc モーション2の状態を設定します。
 * デフォルト state1
 * @default state1
 *
 * @param --状態モーション3 設定--
 * @default
 *
 * @param Motion 3 name
 * @desc モーション3のコードを設定します。
 * デフォルト guard
 * @default guard
 *
 * @param Motion 3 Condition
 * @desc モーション3の状態を設定します。
 * デフォルト guard
 * @default guard
 *
 * @param --状態モーション4 設定--
 * @default
 *
 * @param Motion 4 name
 * @desc モーション4のコードを設定します。
 * デフォルト chant
 * @default chant
 *
 * @param Motion 4 Condition
 * @desc モーション4の状態を設定します。
 * デフォルト chant
 * @default chant
 *
 * @param --状態モーション5 設定--
 * @default
 *
 * @param Motion 5 name
 * @desc モーション5のコードを設定します。
 * デフォルト sleep
 * @default sleep
 *
 * @param Motion 5 Condition
 * @desc モーション5の状態を設定します。
 * デフォルト state2
 * @default state2
 *
 * @param --状態モーション6 設定--
 * @default
 *
 * @param Motion 6 name
 * @desc モーション6のコードを設定します。
 * デフォルト dead
 * @default dead
 *
 * @param Motion 6 Condition
 * @desc モーション6の状態を設定します。
 * デフォルト state3
 * @default state3
 *
 * @param --状態モーション7 設定--
 * @default
 *
 * @param Motion 7 name
 * @desc モーション7のコードを設定します。
 * @default
 *
 * @param Motion 7 Condition
 * @desc モーション7の状態を設定します。
 * @default
 *
 * @param --状態モーション8 設定--
 * @default
 *
 * @param Motion 8 name
 * @desc モーション8のコードを設定します。
 * @default
 *
 * @param Motion 8 Condition
 * @desc モーション8の状態を設定します。
 * @default
 *
 * @param --状態モーション9 設定--
 * @default
 *
 * @param Motion 9 name
 * @desc モーション9のコードを設定します。
 * デフォルト walk
 * @default walk
 *
 * @param Motion 9 Condition
 * @desc モーション9の状態を設定します。
 * デフォルト input
 * @default input
 *
 * @param --状態モーション10 設定--
 * @default
 *
 * @param Motion 10 name
 * @desc モーション10のコードを設定します。
 * デフォルト victory
 * @default victory
 *
 * @param Motion 10 Condition
 * @desc モーション10の状態を設定します。
 * デフォルト victory
 * @default victory
 *
 * @param --状態モーション11 設定--
 * @default
 *
 * @param Motion 11 name
 * @desc モーション11のコードを設定します。
 * デフォルト escape
 * @default escape
 *
 * @param Motion 11 Condition
 * @desc モーション11の状態を設定します。
 * デフォルト escape
 * @default escape
 *
 * @param --状態モーション12 設定--
 * @default
 *
 * @param Motion 12 name
 * @desc モーション12のコードを設定します。
 * @default
 *
 * @param Motion 12 Condition
 * @desc モーション12の状態を設定します。
 * @default
 *
 * @param --状態モーション13 設定--
 * @default
 *
 * @param Motion 13 name
 * @desc モーション13のコードを設定します。
 * @default
 *
 * @param Motion 13 Condition
 * @desc モーション13の状態を設定します。
 * @default
 *
 * @param --状態モーション14 設定--
 * @default
 *
 * @param Motion 14 name
 * @desc モーション14のコードを設定します。
 * @default
 *
 * @param Motion 14 Condition
 * @desc モーション14の状態を設定します。
 * @default
 *
 * @param --状態モーション15 設定--
 * @default
 *
 * @param Motion 15 name
 * @desc モーション15のコードを設定します。
 * @default
 *
 * @param Motion 15 Condition
 * @desc モーション7の状態を設定します。
 * @default
 *
 * @param --状態モーション16 設定--
 * @default
 *
 * @param Motion 16 name
 * @desc モーション16のコードを設定します。
 * @default
 *
 * @param Motion 16 Condition
 * @desc モーション7の状態を設定します。
 * @default action
 *
 * @param --カスタムモーション1 設定--
 * @default
 *
 * @param Custom 1 Non Loop
 * @desc カスタムモーション1のループしないモーションのコードを設定します。
 * @default
 *
 * @param Custom 1 Loop
 * @desc カスタムモーション1のループするモーションのコードを設定します。
 * @default
 *
 * @param --カスタムモーション2 設定--
 * @default
 *
 * @param Custom 2 Non Loop
 * @desc カスタムモーション2のループしないモーションのコードを設定します。
 * @default
 *
 * @param Custom 2 Loop
 * @desc カスタムモーション2のループするモーションのコードを設定します。
 * @default
 *
 * @param --カスタムモーション3 設定--
 * @default
 *
 * @param Custom 3 Non Loop
 * @desc カスタムモーション3のループしないモーションのコードを設定します。
 * @default
 *
 * @param Custom 3 Loop
 * @desc カスタムモーション3のループするモーションのコードを設定します。
 * @default
 *
 * @param --カスタムモーション4 設定--
 * @default
 *
 * @param Custom 4 Non Loop
 * @desc カスタムモーション4のループしないモーションのコードを設定します。
 * @default
 *
 * @param Custom 4 Loop
 * @desc カスタムモーション4のループするモーションのコードを設定します。
 * @default
 *
 * @param --カスタムモーション5 設定--
 * @default
 *
 * @param Custom 5 Non Loop
 * @desc カスタムモーション5のループしないモーションのコードを設定します。
 * @default
 *
 * @param Custom 5 Loop
 * @desc カスタムモーション5のループするモーションのコードを設定します。
 * @default
 *
 * @param --カスタムモーション6 設定--
 * @default
 *
 * @param Custom 6 Non Loop
 * @desc カスタムモーション6のループしないモーションのコードを設定します。
 * @default
 *
 * @param Custom 6 Loop
 * @desc カスタムモーション6のループするモーションのコードを設定します。
 * @default
 *
 * @param --カスタムモーション7 設定--
 * @default
 *
 * @param Custom 7 Non Loop
 * @desc カスタムモーション7のループしないモーションのコードを設定します。
 * @default
 *
 * @param Custom 7 Loop
 * @desc カスタムモーション7のループするモーションのコードを設定します。
 * @default
 *
 * @param --カスタムモーション8 設定--
 * @default
 *
 * @param Custom 8 Non Loop
 * @desc カスタムモーション8のループしないモーションのコードを設定します。
 * @default
 *
 * @param Custom 8 Loop
 * @desc カスタムモーション8のループするモーションのコードを設定します。
 * @default
 *
 * @param --カスタムコンディション 設定--
 * @default
 *
 * @param Custom Condition 1
 * @desc カスタムコンディション1の条件を設定します。
 * @default
 *
 * @param Custom Condition 2
 * @desc カスタムコンディション2の条件を設定します。
 * @default
 *
 * @param Custom Condition 3
 * @desc カスタムコンディション3の条件を設定します。
 * @default
 *
 * @param Custom Condition 4
 * @desc カスタムコンディション4の条件を設定します。
 * @default
 *
 * @param Custom Condition 5
 * @desc カスタムコンディション5の条件を設定します。
 * @default
 *
 * @param -- 特殊 設定--
 * @default
 *
 * @param Enabled Refresh In PartyCmd
 * @desc パーティーコマンド時にモーションをリフレッシュさせない。
 * パーティーコマンドをスキップするプラグイン使用時に有効にする
 * @type boolean
 * @on 有効
 * @off 無効
 * @default false
 *
 * @param -- デバッグ 設定--
 * @default
 *
 * @param Output Motion Log
 * @desc モーションスプライト情報をログに出力する機能
 * 1 - 有効にする, 0 - 無効にする
 * @default 0
 *
 * @param Output Motion Pattern Log
 * @desc モーションスプライトのパターン更新情報をログに出力する機能
 * 1 - 有効にする, 0 - 無効にする
 * @default 0
 *
 * @help
 *-----------------------------------------------------------------------------
 * 概要
 *-----------------------------------------------------------------------------
 * 本プラグインを実装することで、アクターのさまざまな状態における
 * SVキャラのモーションを変更します。
 *
 *
 *-----------------------------------------------------------------------------
 * 設定方法
 *-----------------------------------------------------------------------------
 * 1.「プラグインマネージャー(プラグイン管理)」に、本プラグインを追加して
 *    ください。
 *
 * 2. 他プラグインと組み合わせる場合
 *    当プラグインは以下のプラグインよりも下にしてください。
 *      YEP_BattleEngineCore
 *      YEP_X_AnimatedSVEnemies
 *      YED_SideviewBattler
 *
 *
 *-----------------------------------------------------------------------------
 * 行動モーションの設定
 *-----------------------------------------------------------------------------
 * アクターの非ダメージ時や、攻撃時など行動時におけるモーション設定します。
 * 設定できる行動モーションは以下の通りです。
 *
 * 待機、ダメージ、回避、突き、払い、飛び道具、スキル、魔法、アイテム
 *
 * プラグインパラメータの行動モーションの設定で、以下のコード名から
 * 指定してください。
 *
 * モーションのコード
 * walk, wait, chant, guard, damage, evade, thrust, swing,
 * missile, skill, spell, item, escape, victory, dying,
 * abnormal, sleep, dead, custom*, other*
 *
 * custom* はカスタムモーションです。(*は番号)
 *
 * other* は別画像モーションです。(*は番号)
 *
 *
 *-----------------------------------------------------------------------------
 * スキル・アイテムに個別でモーションを設定
 *-----------------------------------------------------------------------------
 * スキル、アイテムのメモ欄に以下のタグを設定すると、待機時、使用時のモーションを
 * 変更することができます。
 *
 * <ESM モーション: name>
 * <ESM MOTION: name>
 * 使用時のモーションを name に変更します。
 * name にはモーションのコードを設定してください。
 *
 *
 * <ESM 武器モーション>
 * <ESM WEAPON_MOTION>
 * このタグがあると、手持ちの武器付きのモーションになります。
 *
 *
 * <ESM 詠唱ON>
 * <ESM CHANT_ON>
 * このタグがあると、スキル実行待機中のモーションを詠唱モーションに設定できます。
 *
 *
 * <ESM 詠唱OFF>
 * <ESM CHANT_OFF>
 * このタグがあると、詠唱モーションをOFFに設定できます。
 * SV魔法スキルに設定したスキルであっても、詠唱モーションを実行しません。
 *
 *
 *
 *-----------------------------------------------------------------------------
 * カスタムモーションについて
 *-----------------------------------------------------------------------------
 * custom* (* は数字)で指定するモーションは、本プラグインで新規に設定可能な
 * モーションです。
 *
 * 以下のプラグインパラメータで表示するモーションのコードを設定することで
 * 複数のモーションを連続して表示させることができます。
 * カスタムモーションは、8個まで設定できます。
 *
 * <Custom * Non Loop>
 *    :ここに設定したコードのモーションはループしません。
 * <Custom * Loop>
 *    :ここに設定したコードのモーションをループさせます。
 *
 * モーションのコードは、カンマ(,)を使うことで複数入力できます。
 * これらのパラメータに、custom* を使用することはできません。
 *
 *
 * モーションのループについて
 * <Custom * Loop>に設定したモーションをループさせます。
 * 複数のコードを入力した場合も、それらを順に表示してループします。
 * 設定しない場合は、そのカスタムモーションはループしません。
 *
 * 設定例)
 * <Custom * Non Loop> :victory, skill
 * <Custom * Loop>     :item, walk
 * 上記のように設定した場合、以下の順番でモーションを表示します。
 *
 * victory ⇒ skill ⇒ item ⇒ walk ⇒ item ⇒ walk ⇒ ...
 *                  |→ここからループ
 *
 *
 *-----------------------------------------------------------------------------
 * 別画像モーションについて
 *-----------------------------------------------------------------------------
 * other* (* は数字)で指定するモーションは、本プラグインで新規に設定可能な
 * アクター専用のモーションです。
 *
 * データベースのアクターの「画像」設定で選択したSV戦闘キャラ画像以外の
 * 画像を使用することができます。
 *
 * 使用する画像は、アクターのメモ欄に以下のタグで設定します。
 *
 * <ESM_画像:filename>
 * <ESM_IMAGE:filename>
 *
 * 画像ファイル filename.png は img/sv_actors/ に保存してください。
 * 使用できる画像規格は、SV戦闘キャラ画像と同じです。
 *
 * other*の *番号は、画像内のどの位置のモーションを使用するか設定する番号です。
 * 3枚で1セットで左上のモーションを0番、一つ下を1番、一つ右を6番として数えます。
 * other0 ~ other17 まで使用できます。
 *
 * なお、各別画像モーションはループしません。
 *
 *
 *-----------------------------------------------------------------------------
 * 状態モーションの設定
 *-----------------------------------------------------------------------------
 * アクターの以下の状態におけるモーション設定します。
 *
 *  input   : コマンド入力中
 *  chant   : 詠唱中
 *  guard   : 防御中/防御待機中
 *  state*  : ステート付加中( * がステートモーション番号)(例:state4)
 *  victory : 戦闘勝利中
 *  escape  : 逃走中
 *  dying   : 瀕死時(残りHP25％以下)
 *  custom* : カスタムコンディション(* は番号)(例:custom1)
 *  action  : 行動モーション全般(モーション名は空欄)
 *
 * モーションは、モーション1～モーション16まで設定できます。
 * 数字が大きい方が、モーションの優先度が高くなります。
 *
 * <Motion * Name>
 *    :モーション名のコードを指定してください。
 *    : walk, wait, chant, guard, damage, evade, thrust, swing,
 *    : missile, skill, spell, item, escape, victory, dying,
 *    : abnormal, sleep, dead, custom*, other*
 *
 * <Motion * Condition>
 *    :モーションの状態。上記の9種類から設定してください。
 *    :状態モーションに設定したモーションは、ループします。(action除く)
 *
 * ※action を設定しない場合は、すべての行動モーションよりも優先が高くなります。
 *
 *
 *-----------------------------------------------------------------------------
 * ステートモーションの設定
 *-----------------------------------------------------------------------------
 * ステートのメモ欄に以下のタグを入力することで、ステート付加中のモーションを
 * 設定できます。
 *
 * <ESM モーション: x>
 * <ESM MOTION: x>
 *    :ステートモーション番号を x に設定します。
 *    :タグで設定しない場合は、基本設定の[SV]モーションの設定に従います。
 *
 *
 * <ESM モーション固定>
 * <ESM FIXED_MOTION>
 *    :ステート付与中のモーションの更新を無効にします。
 *    :例えば、防御モーション中にこのステートが付与されると、防御モーションで
 *    :固定され、以降このステートが解除されるまで何があっても防御モーションを
 *    :とり続けます。
 *
 *
 *-----------------------------------------------------------------------------
 * カスタムコンディションの設定
 *-----------------------------------------------------------------------------
 * 状態モーションのプラグインパラメータ<Motion * Condition>に設定できる
 * 独自条件を設定できます。
 *
 * プラグインパラメータ<Custom Condition *> にJS条件式を入力してください。
 *
 * [条件式 の値について]
 * 条件式は、ダメージ計算式のように、計算式を入力することで、固定値以外の値を
 * 使用することができます。以下のコードを使用できます。
 *  a.param - 使用者のパラメータを参照します。(a.hit で使用者の命中率)
 *  v[x]    - 変数ID x の値を参照します。
 *  s[x]    - スイッチID x の値を参照します。
 *
 *
 *-----------------------------------------------------------------------------
 * 本プラグインのライセンスについて(License)
 *-----------------------------------------------------------------------------
 * 本プラグインはMITライセンスのもとで公開しています。
 * This plugin is released under the MIT License.
 *
 * Copyright (c) 2017,2018 Futokoro
 * http://opensource.org/licenses/mit-license.php
 *
 *
 * プラグイン公開元
 * https://github.com/futokoro/RPGMaker/blob/master/README.md
 *
 *
 *-----------------------------------------------------------------------------
 * 変更来歴
 *-----------------------------------------------------------------------------
 *
 * v1.4.0 - 2019/04/13 : 機能追加
 *    1. 状態モーションの優先度に、行動モーション action の状態を設定する機能を追加。
 *
 * v1.3.2 - 2019/03/10 : 機能追加
 *    1. パーティーコマンドをスキップするプラグインに対応するプラグインパラメータ
 *       Enabled Refresh In PartyCmd を追加。
 *
 * v1.3.1 - 2018/05/31 : 不具合修正
 *    1. パーティーの誰かが防御を使用すると、パーティーメンバー全員が防御モーションを
 *       一瞬実行する不具合を修正。
 *
 * v1.3.0 - 2018/05/22 : 機能追加
 *    1. 特定のステート付与中のモーションの更新を無効にする機能を追加。
 *
 * v1.2.10 - 2018/04/29 : 不具合修正
 *    1. 状態モーションにループしないモーションを設定すると、エラーになる不具合を修正。
 *
 * v1.2.9 - 2018/04/28 : 不具合修正
 *    1. デバッグ設定のログ表示を有効にすると、特定のモーション時にエラーになる
 *       不具合を修正。
 *
 * v1.2.8 - 2018/04/28 : 不具合修正
 *    1. YEP_BattleEngineCore.jsと組み合わせている場合に、戦闘不能時の
 *       状態モーションの設定が反映されない不具合を修正。
 *
 * v1.2.7 - 2018/04/12 : 不具合修正
 *    1. YEP_VictoryAftermath.jsと組み合わせた場合に、勝利モーションを実行しない
 *       不具合を修正。
 *
 * v1.2.6 - 2018/04/10 : 不具合修正、機能追加
 *    1. YED_SideviewBattlerと組み合わせた場合に、3フレーム以外のモーションを
 *       表示できない不具合を修正。
 *    2. スキルに詠唱モーションを実行させるタグ付け機能を追加。
 *
 * v1.2.5 - 2017/08/24 : 不具合修正
 *    1. メモ欄の読み取り処理を見直し。
 *
 * v1.2.4 - 2017/07/07 : 不具合修正
 *    1. 状態モーションのescapeが、戦闘時以外でも有効になる不具合を修正。
 *
 * v1.2.3 - 2017/05/19 : 不具合修正
 *    1. 防御モーションの優先度が反映されない不具合を修正。
 *
 * v1.2.2 - 2017/05/11 : 不要な記述を削除
 *    1. 余計なログを出力する箇所を削除。
 *
 * v1.2.1 - 2017/05/10 : 不具合修正
 *    1. FTKR_FacialImageDifference.jsに対応
 *
 * v1.2.0 - 2017/05/09 : 機能追加
 *    1. 別のSV画像を使用したモーションを設定する機能を追加。
 *    2. スキル・アイテムの使用モーションを個別に設定する機能を追加。
 *    3. HP回復時のモーションを設定する機能を追加。
 *    4. 状態モーションに独自条件を設定するカスタムコンディションの機能を追加。
 *
 * v1.1.5 - 2017/05/06 : 不具合修正
 *    1. ステートモーションタグが設定されていない場合に、ステートの
 *       モーションを正しく反映できない不具合を修正。
 *
 * v1.1.4 - 2017/04/30 : 不具合修正
 *    1. YED_SideviewBattler側にモーションデータを正しく渡せていなかった
 *       不具合を修正。
 *
 * v1.1.3 - 2017/04/27 : 不具合修正、機能追加
 *    1. requestMotion()に関する不具合修正。
 *    2. YED_SideviewBattlerのバトラーセットカスタムに対応。
 *    3. YEP_X_AnimatedSVEnemiesのエネミーモーションに対応。
 *
 * v1.1.2 - 2017/04/27 : 不具合修正
 *    1. 状態モーション10 以降が反映されない不具合を修正。
 *
 * v1.1.1 - 2017/04/26 : YEP_BattleEngineCoreに対応
 *
 * v1.1.0 - 2017/04/25 : 仕様変更、機能追加
 *    1. 攻撃等の行動モーションを変更する機能を追加。
 *    2. 状態モーションに、戦闘勝利、逃走、瀕死時のモーションを追加。
 *    3. 状態モーションのデフォルト設定を見直し
 *    4. 複数のモーションを組み合わせて連続で表示する機能を追加。
 *
 * v1.0.1 - 2017/04/21 : 不具合修正
 *    1. ステートのタグ設定が正しく読み取れない不具合を修正。
 *
 * v1.0.0 - 2017/04/19 : 初版作成
 *
 *-----------------------------------------------------------------------------
 */
//=============================================================================

(function () {
  var paramParse = function (obj) {
    return JSON.parse(JSON.stringify(obj, paramReplace));
  };

  var paramReplace = function (key, value) {
    try {
      return JSON.parse(value || null);
    } catch (e) {
      return value;
    }
  };

  //=============================================================================
  // プラグイン パラメータ
  //=============================================================================
  var parameters = PluginManager.parameters("FTKR_ExSvMotion");

  FTKR.ESM.skipPartyOn =
    paramParse(parameters["Enabled Refresh In PartyCmd"]) || false;
  FTKR.ESM.motion = {
    debug: {
      enable: Number(parameters["Output Motion Log"] || 0),
      pattern: Number(parameters["Output Motion Pattern Log"] || 0),
    },
    basic: {
      damage: String(parameters["Damage Motion"] || ""),
      evade: String(parameters["Evade Motion"] || ""),
      thrust: String(parameters["Thrust Motion"] || ""),
      swing: String(parameters["Swing Motion"] || ""),
      missile: String(parameters["Missile Motion"] || ""),
      skill: String(parameters["Skill Motion"] || ""),
      speed: String(parameters["Spell Motion"] || ""),
      item: String(parameters["Item Motion"] || ""),
      undecided: String(parameters["Undecided Motion"] || ""),
      wait: String(parameters["Wait Motion"] || ""),
      recovery: String(parameters["Recovery Motion"] || ""),
    },
    state: [
      { name: "", condition: "" },
      {
        name: String(parameters["Motion 1 name"] || ""),
        condition: String(parameters["Motion 1 Condition"] || ""),
      },
      {
        name: String(parameters["Motion 2 name"] || ""),
        condition: String(parameters["Motion 2 Condition"] || ""),
      },
      {
        name: String(parameters["Motion 3 name"] || ""),
        condition: String(parameters["Motion 3 Condition"] || ""),
      },
      {
        name: String(parameters["Motion 4 name"] || ""),
        condition: String(parameters["Motion 4 Condition"] || ""),
      },
      {
        name: String(parameters["Motion 5 name"] || ""),
        condition: String(parameters["Motion 5 Condition"] || ""),
      },
      {
        name: String(parameters["Motion 6 name"] || ""),
        condition: String(parameters["Motion 6 Condition"] || ""),
      },
      {
        name: String(parameters["Motion 7 name"] || ""),
        condition: String(parameters["Motion 7 Condition"] || ""),
      },
      {
        name: String(parameters["Motion 8 name"] || ""),
        condition: String(parameters["Motion 8 Condition"] || ""),
      },
      {
        name: String(parameters["Motion 9 name"] || ""),
        condition: String(parameters["Motion 9 Condition"] || ""),
      },
      {
        name: String(parameters["Motion 10 name"] || ""),
        condition: String(parameters["Motion 10 Condition"] || ""),
      },
      {
        name: String(parameters["Motion 11 name"] || ""),
        condition: String(parameters["Motion 11 Condition"] || ""),
      },
      {
        name: String(parameters["Motion 12 name"] || ""),
        condition: String(parameters["Motion 12 Condition"] || ""),
      },
      {
        name: String(parameters["Motion 13 name"] || ""),
        condition: String(parameters["Motion 13 Condition"] || ""),
      },
      {
        name: String(parameters["Motion 14 name"] || ""),
        condition: String(parameters["Motion 14 Condition"] || ""),
      },
      {
        name: String(parameters["Motion 15 name"] || ""),
        condition: String(parameters["Motion 15 Condition"] || ""),
      },
      {
        name: String(parameters["Motion 16 name"] || ""),
        condition: String(parameters["Motion 16 Condition"] || ""),
      },
    ],
    custom: [
      ["", ""],
      [
        String(parameters["Custom 1 Non Loop"] || ""),
        String(parameters["Custom 1 Loop"] || ""),
      ],
      [
        String(parameters["Custom 2 Non Loop"] || ""),
        String(parameters["Custom 2 Loop"] || ""),
      ],
      [
        String(parameters["Custom 3 Non Loop"] || ""),
        String(parameters["Custom 3 Loop"] || ""),
      ],
      [
        String(parameters["Custom 4 Non Loop"] || ""),
        String(parameters["Custom 4 Loop"] || ""),
      ],
      [
        String(parameters["Custom 5 Non Loop"] || ""),
        String(parameters["Custom 5 Loop"] || ""),
      ],
      [
        String(parameters["Custom 6 Non Loop"] || ""),
        String(parameters["Custom 6 Loop"] || ""),
      ],
      [
        String(parameters["Custom 7 Non Loop"] || ""),
        String(parameters["Custom 7 Loop"] || ""),
      ],
      [
        String(parameters["Custom 8 Non Loop"] || ""),
        String(parameters["Custom 8 Loop"] || ""),
      ],
    ],
    condition: [
      "",
      String(parameters["Custom Condition 1"] || ""),
      String(parameters["Custom Condition 2"] || ""),
      String(parameters["Custom Condition 3"] || ""),
      String(parameters["Custom Condition 4"] || ""),
      String(parameters["Custom Condition 5"] || ""),
    ],
  };

  Game_BattlerBase.ESM_MOTION_NUMBER = 16;

  //objのメモ欄から <metacode: x> の値を読み取って配列で返す
  var readObjectMeta = function (obj, metacodes) {
    if (!obj) return false;
    var match = {};
    metacodes.some(function (metacode) {
      var metaReg = new RegExp("<" + metacode + ":[ ]*(.+)>", "i");
      match = metaReg.exec(obj.note);
      return match;
    });
    return match ? match[1] : "";
  };

  //objのメモ欄から <metacode> があるか真偽を返す
  var testObjectMeta = function (obj, metacodes) {
    if (!obj) return false;
    return metacodes.some(function (metacode) {
      var metaReg = new RegExp("<" + metacode + ">", "i");
      return metaReg.test(obj.note);
    });
  };

  //=============================================================================
  // 自作関数(グローバル)
  //=============================================================================

  FTKR.gameData = FTKR.gameData || {
    user: null,
    target: null,
    item: null,
    number: 0,
  };

  if (!FTKR.setGameData) {
    FTKR.setGameData = function (user, target, item, number) {
      FTKR.gameData = {
        user: user || null,
        target: target || null,
        item: item || null,
        number: number || 0,
      };
    };
  }

  if (!FTKR.evalFormula) {
    FTKR.evalFormula = function (formula) {
      var datas = FTKR.gameData;
      try {
        var s = $gameSwitches._data;
        var v = $gameVariables._data;
        var a = datas.user;
        var b = datas.target;
        var item = datas.item;
        var number = datas.number;
        if (b) var result = b.result();
        var value = eval(formula);
        if (isNaN(value)) value = 0;
        return value;
      } catch (e) {
        console.error(e);
        return 0;
      }
    };
  }

  //=============================================================================
  // 基本モーションの設定を変更
  //=============================================================================

  var _ESM_Game_Battler_onBattleStart = Game_Battler.prototype.onBattleStart;
  Game_Battler.prototype.onBattleStart = function () {
    _ESM_Game_Battler_onBattleStart.call(this);
    this._requestVictory = false;
    this._requestEscape = false;
  };

  //書き換え
  if (!Imported.YEP_BattleEngineCore) {
    Game_Battler.prototype.requestMotion = function (motionType) {
      if (!this.checkActionPriority()) return;
      var motion = FTKR.ESM.motion.basic[motionType];
      this._motionType = motion ? motion : motionType;
    };
  }

  Game_Actor.prototype.performRecovery = function () {
    Game_Battler.prototype.performRecovery.call(this);
    this.requestMotion(FTKR.ESM.motion.basic.recovery);
  };

  //書き換え
  Game_Actor.prototype.performVictory = function () {
    if (this.canMove()) {
      this._requestVictory = true;
      this.requestMotion("refresh");
    }
  };

  //書き換え
  Game_Actor.prototype.performEscape = function () {
    if (this.canMove()) {
      this._requestEscape = true;
      this.requestMotion("refresh");
    }
  };

  //書き換え
  Game_Actor.prototype.performAction = function (action) {
    Game_Battler.prototype.performAction.call(this, action);
    if (action.isAttack()) {
      this.performAttack();
    } else if (action.isGuard()) {
      this.requestMotion("refresh");
      //        this.requestMotion('guard');
    } else if (action.isMagicSkill()) {
      var motion = this.esmMotion(action.item(), "spell");
      this.requestMotion(motion);
    } else if (action.isSkill()) {
      var motion = this.esmMotion(action.item(), "skill");
      this.requestMotion(motion);
    } else if (action.isItem()) {
      var motion = this.esmMotion(action.item(), "item");
      this.requestMotion(motion);
    }
    if (
      motion &&
      testObjectMeta(action.item(), ["ESM 武器モーション", "ESM WEAPON_MOTION"])
    ) {
      var weapons = this.weapons();
      var wtypeId = weapons[0] ? weapons[0].wtypeId : 0;
      var attackMotion = $dataSystem.attackMotions[wtypeId];
      if (attackMotion) {
        this.startWeaponAnimation(attackMotion.weaponImageId);
      }
    }
  };

  Game_Actor.prototype.esmMotion = function (item, motion) {
    return readObjectMeta(item, ["ESM モーション", "ESM MOTION"]) || motion;
  };

  var _ESM_Game_Action_isMagicSkill = Game_Action.prototype.isMagicSkill;
  Game_Action.prototype.isMagicSkill = function () {
    if (testObjectMeta(this.item(), ["ESM 詠唱ON", "ESM CHANT_ON"])) {
      return true;
    } else if (testObjectMeta(this.item(), ["ESM 詠唱OFF", "ESM CHANT_OFF"])) {
      return false;
    } else {
      return _ESM_Game_Action_isMagicSkill.call(this);
    }
  };

  //=============================================================================
  // バトラーの状態からモーション名を取得する
  // Game_BattlerBase
  //=============================================================================

  Game_BattlerBase.prototype.getEsmMotion = function () {
    var index = this.checkConditionAll();
    if (index) {
      return FTKR.ESM.motion.state[index].name;
    } else if (this.isUndecided()) {
      return FTKR.ESM.motion.basic.undecided;
    } else {
      return FTKR.ESM.motion.basic.wait;
    }
  };

  Game_BattlerBase.prototype.checkActionPriority = function () {
    var priority = 16;
    for (var i = Game_BattlerBase.ESM_MOTION_NUMBER; i > 0; i--) {
      if (FTKR.ESM.motion.state[i].condition.toUpperCase() === "ACTION") {
        priority = i;
        break;
      }
    }
    return priority > this.checkConditionAll();
  };

  Game_BattlerBase.prototype.checkConditionAll = function () {
    for (var i = Game_BattlerBase.ESM_MOTION_NUMBER; i > 0; i--) {
      if (this.checkCondition(FTKR.ESM.motion.state[i].condition)) {
        return i;
      }
    }
    return 0;
  };

  Game_BattlerBase.prototype.checkCondition = function (condition) {
    var stateMotion = this.stateMotionIndex();
    if (condition.match(/state(\d+)/i)) {
      return stateMotion === Number(RegExp.$1);
    } else if (condition.match(/custom(\d+)/i)) {
      return this.evalEsmCondition(Number(RegExp.$1));
    }
    switch (true) {
      case /input/i.test(condition):
        return this.isInputting() || this.isActing();
      case /guard/i.test(condition):
        return this.isGuardMotion();
      case /chant/i.test(condition):
        return this.isChanting();
      case /victory/i.test(condition):
        return (
          $gameParty.inBattle() &&
          $gameTroop.isAllDead() &&
          this._requestVictory
        );
      case /escape/i.test(condition):
        return (
          $gameParty.inBattle() &&
          BattleManager.isEscaped() &&
          this._requestEscape
        );
      case /dying/i.test(condition):
        return this.isDying();
      default:
        return false;
    }
  };

  Game_BattlerBase.prototype.isGuardMotion = function () {
    return (
      this.isGuard() ||
      this.isGuardWaiting() ||
      (!!BattleManager._subject &&
        BattleManager._subject === this &&
        !!BattleManager._action &&
        BattleManager._action.isGuard())
    );
  };

  Game_BattlerBase.prototype.evalEsmCondition = function (number) {
    FTKR.setGameData(this, null, null);
    return FTKR.evalFormula(FTKR.ESM.motion.condition[number]);
  };

  //書き換え
  var _ESM_Game_BattlerBase_stateMotionIndex =
    Game_BattlerBase.prototype.stateMotionIndex;
  Game_BattlerBase.prototype.stateMotionIndex = function () {
    if (this.isEnemy() && !FTKR.ESM.enableEnemyMotion) {
      return _ESM_Game_BattlerBase_stateMotionIndex.call(this);
    }
    var states = this.states();
    if (states.length > 0) {
      var motion = readObjectMeta(states[0], ["ESM モーション", "ESM MOTION"]);
      return motion ? Number(motion) : states[0].motion;
    } else {
      return 0;
    }
  };

  Game_Battler.prototype.isFixedMotion = function () {
    var states = this.states();
    if (states.length > 0) {
      return states.some(function (state) {
        return testObjectMeta(state, [
          "ESM モーション固定",
          "ESM FIXED_MOTION",
        ]);
      });
    } else {
      return false;
    }
  };

  //=============================================================================
  // Sprite_Weapon
  // 武器のSVスプライトを修正
  //=============================================================================

  var _ESM_Sprite_Weapon_setup = Sprite_Weapon.prototype.setup;
  Sprite_Weapon.prototype.setup = function (weaponImageId) {
    _ESM_Sprite_Weapon_setup.call(this, weaponImageId);
    this.consoleLog_weaponMotion("setup");
  };

  Sprite_Weapon.prototype.consoleLog_weaponMotion = function (text) {
    if (FTKR.ESM.motion.debug.enable && this._weaponImageId) {
      console.log("********************************************");
      console.log("Weapon Motion <", text, ">");
      console.log("---------------------------");
      console.log("ImageID :", this._weaponImageId);
      console.log("pattern :", this._pattern);
      console.log("********************************************");
    }
  };

  //=============================================================================
  // バトラーの拡張モーション機能を追加
  // Sprite_Battler
  //=============================================================================

  var _ESM_Sprite_Battler_initMembers = Sprite_Battler.prototype.initMembers;
  Sprite_Battler.prototype.initMembers = function () {
    _ESM_Sprite_Battler_initMembers.call(this);
    this._motionIndex = 0;
    this._motionTypes = [[], []];
    this._motionType = "";
    this._index = 0;
    this._otherFile = false;
  };

  Sprite_Battler.ESM_MOTIONS = {
    walk: ["", "walk"],
    wait: ["", "wait"],
    chant: ["", "chant"],
    guard: ["", "guard"],
    damage: ["damage", ""],
    evade: ["evade", ""],
    thrust: ["thrust", ""],
    swing: ["swing", ""],
    missile: ["missile", ""],
    skill: ["skill", ""],
    spell: ["spell", ""],
    item: ["item", ""],
    escape: ["", "escape"],
    victory: ["", "victory"],
    dying: ["", "dying"],
    abnormal: ["", "abnormal"],
    sleep: ["", "sleep"],
    dead: ["", "dead"],
  };

  Sprite_Battler.ESM_MOTION_NAME = [
    "walk",
    "wait",
    "chant",
    "guard",
    "damage",
    "evade",
    "thrust",
    "swing",
    "missile",
    "skill",
    "spell",
    "item",
    "escape",
    "victory",
    "dying",
    "abnormal",
    "sleep",
    "dead",
  ];

  Sprite_Battler.prototype.motion = function () {
    return Sprite_Actor.MOTIONS[this.convertOtherMotion(this.motionName())];
  };

  Sprite_Battler.prototype.convertOtherMotion = function (other) {
    return other && other.match(/other(\d+)/)
      ? Sprite_Battler.ESM_MOTION_NAME[Number(RegExp.$1)]
      : other;
  };

  Sprite_Battler.prototype.isOtherMotion = function () {
    return /other/i.test(this.motionName());
  };

  Sprite_Battler.prototype.motionTypes = function () {
    return this._motionTypes;
  };

  Sprite_Battler.prototype.motions = function () {
    return this._motionTypes[this._motionIndex];
  };

  Sprite_Battler.prototype.hasLoopMotions = function () {
    return (
      !!this.motionTypes() &&
      !!this.motionTypes()[1] &&
      !!this.motionTypes()[1][0]
    );
  };

  Sprite_Battler.prototype.motionName = function () {
    return this._motionTypes[this._motionIndex][this._index];
  };

  Sprite_Battler.prototype.lastMotionType = function () {
    return (
      this.motions().length === 1 || this.motions().length <= this._index + 1
    );
  };

  if (!Imported.YED_SideviewBattler) {
    Sprite_Battler.prototype.motionFrames = function () {
      return 3;
    };
  }

  Sprite_Battler.prototype.setNewMotion = function (battler, motionType) {
    if (battler.isFixedMotion()) return;
    if (!motionType || motionType === "refresh") {
      motionType = battler.getEsmMotion();
    }
    if (this._motionType === motionType) return;
    this._motionType = motionType;
    battler._faceType = motionType;
    this._otherFile = false;
    if (motionType.match(/custom(\d+)/)) {
      var newMotions = FTKR.ESM.motion.custom[Number(RegExp.$1)];
    } else if (motionType.match(/other(\d+)/)) {
      var newMotions = [motionType, ""];
    } else {
      var newMotions = Sprite_Battler.ESM_MOTIONS[motionType];
    }
    this._motionTypes = newMotions.map(function (motions) {
      return motions.split(",");
    });
    this._motionIndex = this.motionTypes()[0][0] ? 0 : 1;
    this._motionCount = 0;
    this._pattern = 0;
    this._index = 0;
    this._motion = this.motion();
    this.consoleLog_BattlerMotion("start");
    this.consoleLog_BattlerMotion("data");
  };

  Sprite_Battler.prototype.esmUpdateMotionCount = function (battler) {
    if (battler.isFixedMotion()) return;
    if (this.motion() && ++this._motionCount >= this.motionSpeed()) {
      if (Imported.YED_SideviewBattler) this._motionName = this.motionName();
      var frames = this.motionFrames();
      var loopFrames =
        Imported.YED_SideviewBattler && battler.isSideviewBattler()
          ? frames
          : frames + 1;
      // ループする場合
      if (this._motionIndex && this.motions().length <= 1) {
        this._pattern = (this._pattern + 1) % loopFrames;
        this.consoleLog_BattlerMotion("pattern");
        // ループしない場合 パターンを増やす
      } else if (this._pattern < frames - 1) {
        this._pattern++;
        this.consoleLog_BattlerMotion("pattern");
        // ループしない場合 パターンをリセット
      } else {
        this.esmUpdateRefreshMotion(battler);
      }
      this._motionCount = 0;
    }
  };

  Sprite_Battler.prototype.esmUpdateRefreshMotion = function (battler) {
    if (battler.isFixedMotion()) return;
    var condition = battler.getEsmMotion();
    this.consoleLog_BattlerMotion("refresh", [condition]);
    if (this._motionType === condition) {
      if (!this._index && !this._pattern) {
        //index の更新
      } else if (!this.lastMotionType()) {
        this._pattern = 0;
        this._index++;
        //motionIndex の更新、index のリセット
      } else {
        if (!this._motionIndex && this.hasLoopMotions()) this._motionIndex = 1;
        this._index = 0;
        this._pattern = 0;
      }
      this._motion = this.motion();
      this.consoleLog_BattlerMotion("data");
      //condition の更新
    } else {
      this._motionIndex = 0;
      this._index = 0;
      this.startMotion(condition);
    }
  };

  Sprite_Battler.prototype.esmRefreshMotion = function (battler) {
    if (battler.isFixedMotion()) return;
    if (
      FTKR.ESM.skipPartyOn &&
      BattleManager.isInputting() &&
      !BattleManager.actor()
    )
      return;
    var condition = battler.getEsmMotion();
    this.consoleLog_BattlerMotion("refresh", [condition]);
    //condition の更新
    if (this._motionType !== condition) {
      this._motionIndex = 0;
      this._index = 0;
      this.startMotion(condition);
    }
  };

  Sprite_Battler.prototype.consoleLog_BattlerMotion = function (type, datas) {
    if (FTKR.ESM.motion.debug.enable) {
      if (!FTKR.ESM.motion.debug.pattern && type === "pattern") return;
      var name = !!this._battler ? this._battler.name() : "";
      console.log("********************************************");
      console.log("Actor motion <", type, ">", name);
      console.log("---------------------------");
      switch (type) {
        case "start":
          console.log("Input Motion   :", this._motionType);
          console.log("motionTypes[0] : " + this.motionTypes()[0]);
          console.log("motionTypes[1] : " + this.motionTypes()[1]);
          break;
        case "refresh":
          console.log("motionType :", this._motionType);
          console.log("condition  :", datas[0]);
          var num = !!this.motions() ? this.motions().length : 0;
          console.log("motion num :", num);
          if (this._motionType !== datas[0]) {
            console.log("⇒ Start Motion");
          }
          break;
        case "data":
          console.log("Motion Name  :", this.motionName());
          var index = !!this.motion() ? this.motion().index : 0;
          console.log("Motion Index :", index);
          console.log("Type Index   :", this._motionIndex);
          console.log("index        :", this._index);
          break;
        case "pattern":
          console.log("Motion Name :", this.motionName());
          console.log("Type Index  :", this._motionIndex);
          console.log("index       :", this._index);
          console.log("pattern     :", this._pattern);
          break;
      }
      console.log("********************************************");
    }
  };

  //=============================================================================
  // Sprite_Actor
  // アクターのSVスプライトを修正
  //=============================================================================

  var _ESM_Sprite_Actor_updateBitmap = Sprite_Actor.prototype.updateBitmap;
  Sprite_Actor.prototype.updateBitmap = function () {
    if (this.isOtherMotion()) {
      Sprite_Battler.prototype.updateBitmap.call(this);
      var name = this.otherBattlerName();
      if (this._battlerName !== name) {
        this._battlerName = name;
        this._mainSprite.bitmap = ImageManager.loadSvActor(name);
      }
    } else {
      _ESM_Sprite_Actor_updateBitmap.call(this);
    }
  };

  Sprite_Actor.prototype.otherBattlerName = function () {
    return readObjectMeta(this._actor.actor(), ["ESM_画像", "ESM_IMAGE"]);
  };

  //書き換え
  Sprite_Actor.prototype.updateMotionCount = function () {
    this.esmUpdateMotionCount(this._actor);
  };

  //書き換え
  Sprite_Actor.prototype.refreshMotion = function () {
    var actor = this._actor;
    if (actor) {
      this.esmRefreshMotion(actor);
    }
  };

  //書き換え
  Sprite_Actor.prototype.startMotion = function (motionType) {
    if (this._motionType !== motionType) {
      this.setNewMotion(this._actor, motionType);
    }
  };

  //=============================================================================
  // 他プラグインの修正
  //=============================================================================
  //-----------------------------------------------------------------
  // YEP_BattleEngineCoreの修正
  //-----------------------------------------------------------------
  if (Imported.YEP_BattleEngineCore) {
    Game_Battler.prototype.idleMotion = function () {
      return "";
    };

    Game_Battler.prototype.deadMotion = function () {
      return "";
    };

    Game_Battler.prototype.sleepMotion = function () {
      return "";
    };

    Game_Battler.prototype.chantMotion = function () {
      return "";
    };

    Game_Battler.prototype.guardMotion = function () {
      return "";
    };

    Game_Battler.prototype.abnormalMotion = function () {
      return "";
    };

    Game_Battler.prototype.dyingMotion = function () {
      return "";
    };

    Game_Battler.prototype.waitMotion = function () {
      return "";
    };

    var _ESM_Game_Battler_requestMotionRefresh =
      Game_Battler.prototype.requestMotionRefresh;
    Game_Battler.prototype.requestMotionRefresh = function () {
      if (this._motionType) {
        if (this.checkActionPriority()) {
          this.requestMotion(this._motionType);
        }
        this.clearMotion();
        return;
      }
      _ESM_Game_Battler_requestMotionRefresh.call(this);
    };

    Sprite_Battler.prototype.checkBattleInputActorUndecided = function (
      battler
    ) {
      return battler.isUndecided();
    };

    //書き換え
    Sprite_Actor.prototype.forceMotion = function (motionType) {
      this.setNewMotion(this._actor, motionType);
    };
  } //Imported.YEP_BattleEngineCore

  //-----------------------------------------------------------------
  // (YEP_X_AnimatedSVEnemiesの修正)
  //-----------------------------------------------------------------
  if (Imported.YEP_X_AnimatedSVEnemies) {
    //書き換え
    Sprite_Enemy.prototype.updateMotionCount = function () {
      if (!this._svBattlerEnabled) return;
      this.esmUpdateMotionCount(this._enemy);
    };

    //書き換え
    Sprite_Enemy.prototype.refreshMotion = function () {
      if (!this._svBattlerEnabled) return;
      var enemy = this._enemy;
      if (!enemy) return;
      this.esmRefreshMotion(enemy);
    };

    //書き換え
    Sprite_Enemy.prototype.startMotion = function (motionType) {
      if (!this._svBattlerEnabled) return;
      if (this._motionType !== motionType) {
        this.setNewMotion(this._enemy, motionType);
      }
    };
  } //Imported.YEP_X_AnimatedSVEnemies

  //-----------------------------------------------------------------
  // YED_SideviewBattlerの修正
  //-----------------------------------------------------------------
  if (Imported.YED_SideviewBattler) {
    //書き換え
    Sprite_Actor.prototype.getCurrentMotion = function () {
      //        console.log(this.motionTypes(), this.motions(), this._motionIndex, this._index, this.motionName());
      return this._actor.getSideviewMotion(this.motionName());
    };

    //書き換え
    Sprite_Enemy.prototype.getCurrentMotion = function () {
      return this._enemy.getSideviewMotion(this.motionName());
    };
  } //Imported.ED_SideviewBattler
})(); //EOF

repo_name: dazed/translations

license: unknown


code:
//=============================================================================
// アクターの状態によって顔画像を変えるプラグイン
// FTKR_FacialImageDifference2.js
// プラグインNo : 61
// 作成者     : フトコロ
// 作成日     : 2017/12/16
// 最終更新日 : 2017/12/16
// バージョン : v2.0.1
//=============================================================================

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

var FTKR = FTKR || {};
FTKR.FID = FTKR.FID || {};

//=============================================================================
/*:
 * @plugindesc v2.0.1 アクターの状態によって顔画像を変えるプラグイン
 * @author フトコロ
 *
 * @noteParam FID_画像
 * @noteRequire 1
 * @noteDir img/face/
 * @noteType file
 * @noteData actors
 *
 * @param --画像番号変更--
 * @desc
 *
 * @param Walk Face Index
 * @desc 前進時の顔画像番号を設定します
 * @default 0
 *
 * @param Wait Face Index
 * @desc 待機時の顔画像番号を設定します
 * @default 0
 *
 * @param Chant Face Index
 * @desc 詠唱時の顔画像番号を設定します
 * @default 0
 *
 * @param Guard Face Index
 * @desc 防御時の顔画像番号を設定します
 * @default 0
 *
 * @param Damage Face Index
 * @desc ダメージ時の顔画像番号を設定します
 * @default 0
 *
 * @param Evade Face Index
 * @desc 回避時の顔画像番号を設定します
 * @default 0
 *
 * @param Thrust Face Index
 * @desc 突き時の顔画像番号を設定します
 * @default 0
 *
 * @param Swing Face Index
 * @desc 払い時の顔画像番号を設定します
 * @default 0
 *
 * @param Missile Face Index
 * @desc 飛び道具時の顔画像番号を設定します
 * @default 0
 *
 * @param Skill Face Index
 * @desc 防御使用時の顔画像番号を設定します
 * @default 0
 *
 * @param Spell Face Index
 * @desc 魔法使用時の顔画像番号を設定します
 * @default 0
 *
 * @param Item Face Index
 * @desc アイテム使用時の顔画像番号を設定します
 * @default 0
 *
 * @param Escape Face Index
 * @desc 逃走時の顔画像番号を設定します
 * @default 0
 *
 * @param Victory Face Index
 * @desc 戦闘勝利時の顔画像番号を設定します
 * @default 0
 *
 * @param Dying Face Index
 * @desc 瀕死時の顔画像番号を設定します
 * @default 0
 *
 * @param Abnormal Face Index
 * @desc 状態異常時の顔画像番号を設定します
 * @default 0
 *
 * @param Sleep Face Index
 * @desc 睡眠時の顔画像番号を設定します
 * @default 0
 *
 * @param Dead Face Index
 * @desc 戦闘不能時の顔画像番号を設定します
 * @default 0
 *
 * @param --FTKR_ExSvMotionの設定--
 * @desc
 *
 * @param Recovery Face Index
 * @desc HP回復時の顔画像番号を設定します
 * @default 0
 *
 * @param Custom1 Face Index
 * @desc Custom1の時の顔画像番号を設定します
 * @default 0
 *
 * @param Custom2 Face Index
 * @desc Custom2の時の顔画像番号を設定します
 * @default 0
 *
 * @param Custom3 Face Index
 * @desc Custom3の時の顔画像番号を設定します
 * @default 0
 *
 * @param Custom4 Face Index
 * @desc Custom4の時の顔画像番号を設定します
 * @default 0
 *
 * @param Custom5 Face Index
 * @desc Custom5の時の顔画像番号を設定します
 * @default 0
 *
 * @param Custom6 Face Index
 * @desc Custom6の時の顔画像番号を設定します
 * @default 0
 *
 * @param Custom7 Face Index
 * @desc Custom7の時の顔画像番号を設定します
 * @default 0
 *
 * @param Custom8 Face Index
 * @desc Custom8の時の顔画像番号を設定します
 * @default 0
 *
 * @help
 *-----------------------------------------------------------------------------
 * 概要
 *-----------------------------------------------------------------------------
 * 本プラグインを実装することで、戦闘中のアクターの顔画像を、
 * アクターのさまざまな状態によって変更します。
 *
 *
 *-----------------------------------------------------------------------------
 * 設定方法
 *-----------------------------------------------------------------------------
 * 1.「プラグインマネージャー(プラグイン管理)」に、本プラグインを追加して
 *    ください。
 *
 *
 * 2. 他プラグインと組み合わせる場合
 *    当プラグインは以下のプラグインよりも下にしてください。
 *      FTKR_CustomSimpleActorStatus
 *      FTKR_ExSvMotion
 *      FTKR_FVActorAnimation.js
 *
 *
 *-----------------------------------------------------------------------------
 * アクターの顔画像について
 *-----------------------------------------------------------------------------
 * 本プラグインを使用する場合、アクターの顔画像は以下の規格のものを
 * 使用してください。
 *
 * 一つの顔画像サイズ：144 * 144
 * 一つのファイルには、顔画像を横に６列、縦に３行まで配置してください。
 * 顔画像の番号は、左上を 0番、一つ右を 1番、一つ下を 6番と数えます。
 * 一つの画像ファイルで最大18種類の顔画像を設定できます。
 *
 * ファイルは、img/face/ フォルダに保存してください。
 *
 * どの状態で何番の顔画像を使用するかは、プラグインパラメータで
 * 設定してください。
 * なお、指定された番号の箇所に画像がない場合は、空欄で表示されますので
 * 注意してください。
 *
 *
 *-----------------------------------------------------------------------------
 * 基本仕様
 *-----------------------------------------------------------------------------
 * 本プラグインを単独で使用する場合、アクターの状態によって
 * 戦闘画面で表示する顔画像が変わります。
 *
 * デフォルトのプラグインの状態では、すべてのアクターの状態に対して
 * 0番の画像を指定しています。
 * 必要に応じて、プラグインパラメータに値を設定してください。
 *
 * なお、戦闘以外の画面での顔画像は、すべて 0番を使用します。
 *
 *
 *-----------------------------------------------------------------------------
 * FTKR_CustomSimpleActorStatus と併用する場合
 *-----------------------------------------------------------------------------
 * FTKR_CustomSimpleActorStatusの設定によって表示する顔画像を変更します。
 * 有効な状態は、基本仕様と同じです。
 *
 * 以下の拡張プラグインについても同様です。
 * FTKR_CSS_DetailedStatus
 * FTKR_CSS_SkillStatus
 *
 *
 *-----------------------------------------------------------------------------
 * FTKR_CSS_BattleStatus と併用する場合
 *-----------------------------------------------------------------------------
 * バトル中のアクターの状態によって、顔画像を変更します。
 *
 * アクターのアクション時にも、顔画像を変更することができます。
 *
 *
 *-----------------------------------------------------------------------------
 * FTKR_ExSvMotion と併用する場合
 *-----------------------------------------------------------------------------
 * FTKR_ExSvMotionの設定によって表示する顔画像を変更します。
 *
 * FTKR_ExSvMotionの設定で、各状態のモーションを変更していた場合は、
 * その設定に合わせて、顔画像も同じモーションの番号に変更します。
 *
 * また、回復時、およびカスタムモーション時に使用するの顔画像番号を
 * 設定できます。
 *
 *
 * 別画像モーション時には、アクターのメモ欄で設定した顔画像ファイルを
 * 使用します。
 * アクターのメモ欄に以下のタグを追記してください。
 *
 * <FID_顔画像:filename>
 * <FID_FACE_IMAGE:filename>
 *
 * 画像ファイル filename.png は img/face/ に保存してください。
 *
 *
 *-----------------------------------------------------------------------------
 * 本プラグインのライセンスについて(License)
 *-----------------------------------------------------------------------------
 * 本プラグインはMITライセンスのもとで公開しています。
 * This plugin is released under the MIT License.
 *
 * Copyright (c) 2017 Futokoro
 * http://opensource.org/licenses/mit-license.php
 *
 *
 * プラグイン公開元
 * https://github.com/futokoro/RPGMaker/blob/master/README.md
 *
 *-----------------------------------------------------------------------------
 * 変更来歴
 *-----------------------------------------------------------------------------
 *
 * v2.0.1 - 2017/12/16 : 不具合修正
 *    1. FTKR_SvMotion.jsと併用できるように見直し。
 *    2. 戦闘終了後に顔画像がデフォルトに戻らない不具合修正。
 *
 * v2.0.0 - 2017/12/16 : 初版作成(FTKR_FacialImageDifference v1.1.7から派生)
 *    1. アニメーションおよびダメージポップアップ機能を削除。
 *    2. 顔画像のスプライトをFTKR_FVActorAnimation.jsから参照する方式に変更。
 *
 *
 *-----------------------------------------------------------------------------
 */
//=============================================================================

(function () {
  //=============================================================================
  // プラグイン パラメータ
  //=============================================================================
  var parameters = PluginManager.parameters("FTKR_FacialImageDifference2");

  //オリジナルステータス設定オブジェクト
  FTKR.FID.faces = {
    wait: Number(parameters["Wait Face Index"] || 0),
    walk: Number(parameters["Walk Face Index"] || 0),
    chant: Number(parameters["Chant Face Index"] || 0),
    guard: Number(parameters["Guard Face Index"] || 0),
    damage: Number(parameters["Damage Face Index"] || 0),
    evade: Number(parameters["Evade Face Index"] || 0),
    thrust: Number(parameters["Thrust Face Index"] || 0),
    swing: Number(parameters["Swing Face Index"] || 0),
    missile: Number(parameters["Missile Face Index"] || 0),
    skill: Number(parameters["Skill Face Index"] || 0),
    spell: Number(parameters["Spell Face Index"] || 0),
    item: Number(parameters["Item Face Index"] || 0),
    escape: Number(parameters["Escape Face Index"] || 0),
    victory: Number(parameters["Victory Face Index"] || 0),
    dying: Number(parameters["Dying Face Index"] || 0),
    abnormal: Number(parameters["Abnormal Face Index"] || 0),
    sleep: Number(parameters["Sleep Face Index"] || 0),
    dead: Number(parameters["Dead Face Index"] || 0),
    recovery: Number(parameters["recovery Face Index"] || 0),
    custom1: Number(parameters["Custom1 Face Index"] || 0),
    custom2: Number(parameters["Custom2 Face Index"] || 0),
    custom3: Number(parameters["Custom3 Face Index"] || 0),
    custom4: Number(parameters["Custom4 Face Index"] || 0),
    custom5: Number(parameters["Custom5 Face Index"] || 0),
    custom6: Number(parameters["Custom6 Face Index"] || 0),
    custom7: Number(parameters["Custom7 Face Index"] || 0),
    custom8: Number(parameters["Custom8 Face Index"] || 0),
  };

  //objのメモ欄から <metacode: x> の値を読み取って配列で返す
  var readObjectMeta = function (obj, metacodes) {
    if (!obj) return false;
    var match = {};
    metacodes.some(function (metacode) {
      var metaReg = new RegExp("<" + metacode + ":[ ]*(.+)>", "i");
      match = metaReg.exec(obj.note);
      return match;
    });
    return match ? match[1] : "";
  };

  //=============================================================================
  // バトラーに顔画像の設定を追加
  //=============================================================================

  var _FID_Game_Battler_initMembers = Game_Battler.prototype.initMembers;
  Game_Battler.prototype.initMembers = function () {
    _FID_Game_Battler_initMembers.call(this);
    this._faceType = null;
    this._faceIndex = 0;
  };

  Game_Battler.prototype.clearFace = function () {
    this._faceIndex = 0;
  };

  var _FID_Game_Battler_requestMotion = Game_Battler.prototype.requestMotion;
  Game_Battler.prototype.requestMotion = function (motionType) {
    _FID_Game_Battler_requestMotion.call(this, motionType);
    this._faceType = this._motionType;
  };

  if (!Imported.FTKR_FAA) {
    var _FID_Game_Actor_performDamage = Game_Actor.prototype.performDamage;
    Game_Actor.prototype.performDamage = function () {
      _FID_Game_Actor_performDamage.call(this);
      this.requestMotion("damage");
    };
  }

  //=============================================================================
  // Sprite_Actorの修正
  // アクターの顔画像表示処理を追加
  //=============================================================================

  var _FID_Sprite_Actor_startMotion = Sprite_Actor.prototype.startMotion;
  Sprite_Actor.prototype.startMotion = function (motionType) {
    _FID_Sprite_Actor_startMotion.call(this, motionType);
    this.refreshFace(this.faceTypeIndex(motionType));
  };

  Sprite_Actor.prototype.faceTypeIndex = function (motionType) {
    if (!motionType) return 0;
    if (Imported.FTKR_ESM && !this._motion) return 0;
    var faceType = Imported.FTKR_ESM
      ? this.convertOtherMotion(this.motionName())
      : motionType;
    return FTKR.FID.faces[faceType];
  };

  Sprite_Actor.prototype.refreshFace = function (faceIndex) {
    if (this._actor && this._actor._faceIndex !== faceIndex) {
      this._actor._faceIndex = faceIndex;
      if (BattleManager._statusWindow) BattleManager._statusWindow.refresh();
    }
  };

  //書き換え
  Window_BattleStatus.prototype.drawActorFace = function (
    actor,
    x,
    y,
    width,
    height
  ) {
    this.drawFace(actor.faceName(), actor._faceIndex, x, y, width, height);
  };

  //書き換え
  Window_BattleStatus.prototype.drawFace = function (
    faceName,
    faceIndex,
    x,
    y,
    width,
    height
  ) {
    width = width || Window_Base._faceWidth;
    height = height || Window_Base._faceHeight;
    var bitmap = ImageManager.loadFace(faceName);
    var pw = Window_Base._faceWidth;
    var ph = Window_Base._faceHeight;
    var sw = Math.min(width, pw);
    var sh = Math.min(height, ph);
    var dx = Math.floor(x + Math.max(width - pw, 0) / 2);
    var dy = Math.floor(y + Math.max(height - ph, 0) / 2);
    var sx = (faceIndex % 6) * pw + (pw - sw) / 2;
    var sy = Math.floor(faceIndex / 6) * ph + (ph - sh) / 2;
    this.contents.blt(bitmap, sx, sy, sw, sh, dx, dy);
  };

  //書き換え
  Window_Base.prototype.drawCssFace = function (actor, dx, dy, width, height) {
    var len = Math.min(width, height);
    var dh = len || Window_Base._faceHeight;
    var dw = len || Window_Base._faceWidth;
    var offsetX = (FTKR.CSS.cssStatus.face.posiX * (width - dw)) / 2;
    dx = Math.floor(dx + offsetX);
    var bitmap = ImageManager.loadFace(actor.faceName());
    var sw = Window_Base._faceWidth;
    var sh = Window_Base._faceHeight;
    var sx = (actor._faceIndex % 6) * sw;
    var sy = Math.floor(actor.faceIndex() / 6) * sh;
    this.contents.blt(bitmap, sx, sy, sw, sh, dx, dy, dw, dh);
  };

  //=============================================================================
  // FTKR_FVActorAnimation.jsの修正
  // アクターの顔画像表示処理を修正
  //=============================================================================
  if (Imported.FTKR_FAA && FTKR.FAA.destination == 1) {
    Sprite_ActorFace.prototype.refreshFace = function (faceIndex) {};

    Sprite_ActorFace.prototype.updateFrame = function () {
      Sprite_Battler.prototype.updateFrame.call(this);
      var bitmap = this._mainSprite.bitmap;
      if (bitmap) {
        var cw = Sprite_ActorFace._imageWidth;
        var ch = Sprite_ActorFace._imageHeight;
        var motionIndex = this._actor._faceIndex;
        var cx = motionIndex % 6;
        var cy = Math.floor(motionIndex / 6);
        this._mainSprite.setFrame(cx * cw, cy * ch, cw, ch);
      }
    };
  }
  //=============================================================================
  // Scene_Base
  // シーン変更時に顔番号をリセット
  //=============================================================================

  var _FID_Scene_Base_start = Scene_Base.prototype.start;
  Scene_Base.prototype.start = function () {
    _FID_Scene_Base_start.call(this);
    this.resetActorFaceType();
  };

  Scene_Base.prototype.resetActorFaceType = function () {
    if (!$gameParty) return;
    $gameParty.members().forEach(function (member) {
      member.clearFace();
    });
  };
})(); //EOF


code:
//=============================================================================
// FatefulLocationUF.js
//=============================================================================

/*:ja
 * @plugindesc 場所移動時の自動演奏の制御等
 * @author まっつＵＰ
 *
 * @param bgmSwitch
 * @desc オンにしていると場所移動時設定したBGMを自動演奏しません。
 * @default 10
 *
 * @param bgsSwitch
 * @desc オンにしていると場所移動時設定したBGSを自動演奏しません。
 * @default 11
 *
 * @help
 *
 * RPGで笑顔を・・・
 *
 * このヘルプとパラメータの説明をよくお読みになってからお使いください。
 *
 * FatefulLocationの簡易バージョンです。
 *
 * bgmSwitchは任意のスイッチのIDを設定します。
 * このスイッチをオンにすると場所移動後のマップの自動演奏が設定されていても
 * そのBGMの自動演奏を行われません。
 *
 * bgsSwitchは任意のスイッチのIDを設定します。
 * このスイッチをオンにすると場所移動後のマップの自動演奏が設定されていても
 * そのBGSの自動演奏を行われません。
 *
 * このプラグインを利用する場合は
 * readmeなどに「まっつＵＰ」の名を入れてください。
 * また、素材のみの販売はダメです。
 * 上記以外の規約等はございません。
 * もちろんツクールMVで使用する前提です。
 * 何か不具合ありましたら気軽にどうぞ。
 *
 * 免責事項：
 * このプラグインを利用したことによるいかなる損害も制作者は一切の責任を負いません。
 *
 */

(function () {
  var parameters = PluginManager.parameters("FatefulLocationUF");
  var APbgmSwitch = Number(parameters["bgmSwitch"] || 10);
  var APbgsSwitch = Number(parameters["bgsSwitch"] || 11);

  Game_Map.prototype.autoplay = function () {
    if ($dataMap.autoplayBgm && !$gameSwitches.value(APbgmSwitch)) {
      AudioManager.playBgm($dataMap.bgm);
    }
    if ($dataMap.autoplayBgs && !$gameSwitches.value(APbgsSwitch)) {
      AudioManager.playBgs($dataMap.bgs);
    }
  };
})();


code:
//=============================================================================
// FixImageLoading.js
// ----------------------------------------------------------------------------
// Copyright (c) 2015-2017 Triacontane
// This software is released under the MIT License.
// http://opensource.org/licenses/mit-license.php
// ----------------------------------------------------------------------------
// Version
// 2.0.1 2019/04/06 MoviePicture.jsとの競合を修正
// 2.0.0 2017/06/09 本体ver1.5.0に合わせて再作成
// 1.1.1 2016/11/20 ロード完了時にframeが更新されない不具合を修正
//                  ロード中にframeが変更された場合に、ロード完了まで反映を遅らせる仕様を追加
// 1.1.0 2016/11/16 liply_GC.jsとの競合を解消 by 奏 ねこま様
// 1.0.0 2016/05/02 初版
// ----------------------------------------------------------------------------
// [Blog]   : http://triacontane.blogspot.jp/
// [Twitter]: https://twitter.com/triacontane/
// [GitHub] : https://github.com/triacontane/
//=============================================================================

/*:ja
 * @plugindesc 画像ロード時のチラつき防止プラグイン
 * @author トリアコンタン
 *
 * @help キャッシュしていない画像を表示したときに
 * 一瞬発生するチラつきを防止します。
 * 画像のロードが完了するまで以前に表示していた画像を残します。
 *
 * 逆に画像を消したいときは明示的にピクチャの消去等を行ってから
 * 表示してください。
 *
 * このプラグインにはプラグインコマンドはありません。
 *
 * 利用規約：
 *  作者に無断で改変、再配布が可能で、利用形態（商用、18禁利用等）
 *  についても制限はありません。
 *  このプラグインはもうあなたのものです。
 */

(function () {
  "use strict";

  var _Sprite__renderCanvas = Sprite.prototype._renderCanvas;
  Sprite.prototype._renderCanvas = function (renderer) {
    _Sprite__renderCanvas.apply(this, arguments);
    if (this.isExistLoadingBitmap()) {
      this._renderCanvas_PIXI(renderer);
    }
  };

  var _Sprite__renderWebGL = Sprite.prototype._renderWebGL;
  Sprite.prototype._renderWebGL = function (renderer) {
    _Sprite__renderWebGL.apply(this, arguments);
    if (this.isExistLoadingBitmap()) {
      if (this._isPicture) {
        this._speedUpCustomBlendModes(renderer);
        renderer.setObjectRenderer(renderer.plugins.picture);
        if (!this.isVideoPicture || !this.isVideoPicture()) {
          renderer.plugins.picture.render(this);
        }
      } else {
        renderer.setObjectRenderer(renderer.plugins.sprite);
        renderer.plugins.sprite.render(this);
      }
    }
  };

  Sprite.prototype.isExistLoadingBitmap = function () {
    return this.bitmap && !this.bitmap.isReady();
  };
})();


code:
//=============================================================================
// FlexibleBattleBgm.js
// ----------------------------------------------------------------------------
// Copyright (c) 2015 Triacontane
// This software is released under the MIT License.
// http://opensource.org/licenses/mit-license.php
// ----------------------------------------------------------------------------
// Version
// 1.0.1 2017/05/27 競合の可能性のある記述（Objectクラスへのプロパティ追加）をリファクタリング
// 1.0.0 2016/01/07 初版
// ----------------------------------------------------------------------------
// [Blog]   : http://triacontane.blogspot.jp/
// [Twitter]: https://twitter.com/triacontane/
// [GitHub] : https://github.com/triacontane/
//=============================================================================

/*:
 * @plugindesc 敵グループごとの戦闘BGM設定プラグイン
 * @author トリアコンタン
 *
 * @help 敵グループごとに戦闘BGM設定できるようになるプラグインです。
 * この設定はシステムの戦闘BGMよりも優先され、設定されていない場合のみ
 * システムの戦闘BGMが演奏されます。
 * 指定はプラグインコマンドから行い、敵グループIDは一括で指定できます。
 * 一度実行した設定はセーブファイルに保存されるので、
 * ゲーム開始時に1回実行すればOKです。
 *
 * プラグインコマンド詳細
 *  イベントコマンド「プラグインコマンド」から実行。
 *  （パラメータの間は半角スペースで区切る）
 *
 * 敵グループBGM追加 [敵グループID開始位置] [敵グループID終了位置]
 * 　[BGM名称] [BGM音量] [BGMピッチ] [BGM位相]
 *
 * （例1）敵グループ「1」の戦闘BGMを「Battle1」にしたい場合
 * 敵グループBGM追加 1 1 Battle1 100 100 0
 *
 * （例2）敵グループ「1」～「20」の戦闘BGMを「Battle2」にしたい場合
 * 敵グループBGM追加 1 20 Battle2
 * ※ 音量、ピッチ、位相は省略するとそれぞれ「90」「100」「0」になります。
 *
 * 利用規約：
 *  作者に無断で改変、再配布が可能で、利用形態（商用、18禁利用等）
 *  についても制限はありません。
 *  このプラグインはもうあなたのものです。
 */
(function () {
  "use strict";

  //=============================================================================
  // ローカル関数
  //  プラグインパラメータやプラグインコマンドパラメータの整形やチェックをします
  //=============================================================================
  var getCommandName = function (command) {
    return (command || "").toUpperCase();
  };

  var getArgString = function (args, upperFlg) {
    args = convertEscapeCharacters(args);
    return upperFlg ? args.toUpperCase() : args;
  };

  var getArgNumber = function (arg, min, max) {
    if (arguments.length <= 2) min = -Infinity;
    if (arguments.length <= 3) max = Infinity;
    return (parseInt(convertEscapeCharacters(arg), 10) || 0).clamp(min, max);
  };

  var convertEscapeCharacters = function (text) {
    if (
      typeof Game_Interpreter.prototype.pluginCommandBook_unescape ===
      "function"
    ) {
      return Game_Interpreter.prototype.pluginCommandBook_unescape(text);
    }
    if (text == null) text = "";
    text = text.replace(/\\/g, "\x1b");
    text = text.replace(/\x1b\x1b/g, "\\");
    text = text.replace(
      /\x1bV\[(\d+)\]/gi,
      function () {
        return $gameVariables.value(parseInt(arguments[1], 10));
      }.bind(window)
    );
    text = text.replace(
      /\x1bV\[(\d+)\]/gi,
      function () {
        return $gameVariables.value(parseInt(arguments[1], 10));
      }.bind(window)
    );
    text = text.replace(
      /\x1bN\[(\d+)\]/gi,
      function () {
        var n = parseInt(arguments[1]);
        var actor = n >= 1 ? $gameActors.actor(n) : null;
        return actor ? actor.name() : "";
      }.bind(window)
    );
    text = text.replace(
      /\x1bP\[(\d+)\]/gi,
      function () {
        var n = parseInt(arguments[1]);
        var actor = n >= 1 ? $gameParty.members()[n - 1] : null;
        return actor ? actor.name() : "";
      }.bind(window)
    );
    text = text.replace(/\x1bG/gi, TextManager.currencyUnit);
    return text;
  };

  //=============================================================================
  // Object
  //  プロパティの定義
  //=============================================================================
  var iterate = function (that, handler) {
    Object.keys(that).forEach(function (key, index) {
      handler.call(that, key, that[key], index);
    });
  };

  //=============================================================================
  // Game_Interpreter
  //  プラグインコマンドを追加定義します。
  //=============================================================================
  var _Game_Interpreter_pluginCommand =
    Game_Interpreter.prototype.pluginCommand;
  Game_Interpreter.prototype.pluginCommand = function (command, args) {
    _Game_Interpreter_pluginCommand.apply(this, arguments);
    try {
      this.pluginCommandFlexibleBattleBgm(command, args);
    } catch (e) {
      if ($gameTemp.isPlaytest() && Utils.isNwjs()) {
        var window = require("nw.gui").Window.get();
        if (!window.isDevToolsOpen()) {
          var devTool = window.showDevTools();
          devTool.moveTo(0, 0);
          devTool.resizeTo(Graphics.width, Graphics.height);
          window.focus();
        }
      }
      console.log("プラグインコマンドの実行中にエラーが発生しました。");
      console.log("- コマンド名 　: " + command);
      console.log("- コマンド引数 : " + args);
      console.log("- エラー原因   : " + e.toString());
    }
  };

  Game_Interpreter.prototype.pluginCommandFlexibleBattleBgm = function (
    command,
    args
  ) {
    switch (getCommandName(command)) {
      case "敵グループBGM追加":
      case "ADD_TROOP_BGM":
        var start = getArgNumber(args[0], 1, 5000);
        var end = getArgNumber(args[1], 1, 5000);
        var name = getArgString(args[2]);
        var volume = args[3] !== undefined ? getArgNumber(args[3]) : null;
        var pitch = args[4] !== undefined ? getArgNumber(args[4]) : null;
        var pan = args[5] !== undefined ? getArgNumber(args[5]) : null;
        $gameSystem.addTroopBattleBgm(start, end, name, volume, pitch, pan);
        break;
    }
  };

  //=============================================================================
  // Game_System
  //  敵グループごとの戦闘BGMの取得と設定処理を追加定義します。
  //=============================================================================
  var _Game_System_battleBgm = Game_System.prototype.battleBgm;
  Game_System.prototype.battleBgm = function () {
    var id = $gameTroop._troopId;
    if (this._troopsBattleBgm && id !== 0) {
      var bgm = null;
      iterate(this._troopsBattleBgm, function (key, value) {
        if (
          id >= parseInt(key.split(":")[0], 10) &&
          id <= parseInt(key.split(":")[1], 10)
        )
          bgm = value;
      });
      if (bgm) return bgm;
    }
    return _Game_System_battleBgm.apply(this, arguments);
  };

  Game_System.prototype.addTroopBattleBgm = function (
    start,
    end,
    name,
    volume,
    pitch,
    pan
  ) {
    if (volume === null) volume = 90;
    if (pitch === null) pitch = 100;
    if (pan === null) pan = 0;
    if (!this._troopsBattleBgm) this._troopsBattleBgm = {};
    this._troopsBattleBgm[start + ":" + end] = {
      name: name,
      pan: pan.clamp(-100, 100),
      volume: volume.clamp(0, 100),
      pitch: pitch.clamp(50, 150),
    };
  };
})();