code:
//=============================================================================
// StatusBustImage.js
// ----------------------------------------------------------------------------
// (C) 2016 Triacontane
// This software is released under the MIT License.
// http://opensource.org/licenses/mit-license.php
// ----------------------------------------------------------------------------
// Version
// 1.9.0 2020/04/22 各画像に拡大率を設定できる設定を追加
// 1.8.1 2019/11/10 1.8.0でZ座標の指定された装備、ステート画像を複数表示すると、アクター追加画像の表示順が入れ替わる場合がある問題を修正
// 1.8.0 2019/11/02 装備品以外にもステートや職業でも追加画像を表示できる機能を追加
// 1.7.4 2019/01/02 MOG_SceneMenu.jsと併用した場合、アイテムを使用時に2回使用してしまう場合がある問題を修正
// 1.7.3 2018/11/04 GraphicalDesignMode.jsとの間で競合が発生する場合がある問題を修正
// 1.7.2 2018/09/17 TMSoloMenu.jsと両立できるよう修正（TMSoloMenu.js側の修正も必須）
// 1.7.1 2017/02/02 特定条件下で戦闘画面にもバストアップが表示されていた問題を修正
// 1.7.0 2017/09/25 ベース画像と追加画像に原点を変更できる機能を追加
// 1.6.0 2017/09/25 バストアップ画像に表情差分用の追加グラフィックを重ねて表示できる機能を追加
// 1.5.0 2017/09/04 バストアップ画像をウィンドウの下に表示できる機能を追加
// 1.4.0 2017/07/05 メインメニュー画面でも先頭アクターの画像を表示できる機能を追加
// 1.3.2 2017/02/20 装備画面での「最強装備」と「全て外す」時に装備品画像が更新されなかった問題を修正
// 1.3.1 2016/10/13 装備品の画像がトリミングの対象外になっていたのを修正
// 1.3.0 2016/10/13 画像を指定した矩形でトリミングして表示できる機能を追加
// 1.2.0 2016/10/08 装備品画像にZ座標を付与できるよう修正
// 1.1.0 2016/10/06 装備画面とスキル画面にも画像を表示できる機能を追加
// 1.0.1 2016/08/12 キャラクターを切り替えたときにグラフィックが切り替わらない問題を修正
// 1.0.0 2016/07/19 初版
// ----------------------------------------------------------------------------
// [Blog]   : https://triacontane.blogspot.jp/
// [Twitter]: https://twitter.com/triacontane/
// [GitHub] : https://github.com/triacontane/
//=============================================================================

/*:
 * @plugindesc StatusBustImagePlugin
 * @author triacontane
 *
 * @param BustImageX
 * @desc バストアップ画像を表示するX座標(足下原点)です。
 * @default 640
 *
 * @param BustImageY
 * @desc バストアップ画像を表示するY座標(足下原点)です。
 * @default 620
 *
 * @param EquipBustImageX
 * @desc 装備画面でバストアップ画像を表示するX座標(足下原点)です。指定しない場合、表示されなくなります。
 * @default
 *
 * @param EquipBustImageY
 * @desc 装備画面でバストアップ画像を表示するY座標(足下原点)です。指定しない場合、表示されなくなります。
 * @default
 *
 * @param SkillBustImageX
 * @desc スキル画面でバストアップ画像を表示するX座標(足下原点)です。指定しない場合、表示されなくなります。
 * @default
 *
 * @param SkillBustImageY
 * @desc スキル画面でバストアップ画像を表示するY座標(足下原点)です。指定しない場合、表示されなくなります。
 * @default
 *
 * @param MainBustImageX
 * @desc メインメニュー画面でバストアップ画像を表示するY座標(足下原点)です。指定しない場合、表示されなくなります。
 * @default
 *
 * @param MainBustImageY
 * @desc メインメニュー画面でバストアップ画像を表示するY座標(足下原点)です。指定しない場合、表示されなくなります。
 * @default
 *
 * @param BustPriority
 * @desc バストアップ画像の表示優先度（プライオリティ）です。
 * @default 0
 * @type select
 * @option ウィンドウの下
 * @value 0
 * @option ウィンドウの内容の下
 * @value 1
 * @option ウィンドウの上
 * @value 2
 *
 * @param BaseImageOrigin
 * @desc ベース画像の原点です。
 * @default 2
 * @type select
 * @option 左上
 * @value 0
 * @option 中央
 * @value 1
 * @option 足下
 * @value 2
 *
 * @param AddImageOrigin
 * @desc 追懐画像および装備品画像の原点です。
 * @default 2
 * @type select
 * @option 左上
 * @value 0
 * @option 中央
 * @value 1
 * @option 足下
 * @value 2
 *
 * @help ステータス画面にアクターごとのバストアップ画像を表示します。
 * 足下を原点として表示位置を自由に調整できます。
 *
 * 装備画面とスキル画面にも同一のバストアップ画像を表示できますが
 * デフォルト画面サイズではスペースがないので、使用する場合は必要に応じて
 * 画面サイズを変更してください。
 *
 * また、メインメニュー画面にも同一のバストアップ画像を表示できますが
 * 表示されるのは「先頭のアクター」のみです。
 * 主にアクターが一人の場合に使用します。
 *
 * アクターのメモ欄に以下の通り指定してください。
 *
 * <SBI画像:file>   # /img/pictures/file.pngが表示されます。
 * <SBIImage:file>  # /img/pictures/file.pngが表示されます。
 * <SBI矩形:0,0,100,100> # 画像を指定した矩形(X座標、Y座標、横幅、高さ)で
 * <SBIRect:0,0,100,100> # 切り出して（トリミング）表示します。(カンマ区切り)
 * <SBI画像拡大率X:100>  # 画像の横方向の拡大率を設定します。
 * <SBIImageScaleX:100> # 同上
 * <SBI画像拡大率Y:100>  # 画像の縦方向の拡大率を設定します。
 * <SBIImageScaleY:100> # 同上
 *
 * さらに以下のメモ欄で追加差分を複数表示することが可能です。
 * <SBI追加画像1:file2>       # /img/pictures/file2.pngが表示されます。
 * <SBIAddImage1:file2>       # 同上
 * <SBI追加条件1:\v[1] === 3> # 変数[1]が[3]と等しい時のみ追加画像が表示されます。
 * <SBIAddCond1:\v[1] === 3>  # 同上
 * <SBI追加座標X1:30>         # 追加画像のX座標を[30]に設定します。
 * <SBIAddPosX1:30>           # 同上
 * <SBI追加座標Y1:30>         # 追加画像のY座標を[30]に設定します。
 * <SBIAddPosY1:30>           # 同上
 * <SBI追加座標拡大率X1:100>   # 追加画像の横方向の拡大率を設定します。
 * <SBIAddPosScaleX1:100>     # 同上
 * <SBI追加座標拡大率Y1:100>   # 追加画像の縦方向の拡大率を設定します。
 * <SBIAddPosScaleY1:100>     # 同上
 * 複数の追加画像を表示したい場合は最後の数字を[2]以降に変更してください。
 *
 * 指定する座標はベース画像の足下からの相対座標です。
 *
 * 計算式中で不等号を使いたい場合、以下のように記述してください。
 * < → <
 * > → >
 * 例：<SBIAddCond1:\v[2] > 1> // 変数[2]が1より大きい場合
 *
 * さらに動画(データベースのアニメーション)を再生することもできます。
 * 画像の上に重ねてまばたき等を表現するのに使用します。
 *
 * <SBI動画:1>      # ID[1]のアニメーションがループ再生されます。
 * <SBIAnimation:1> # ID[1]のアニメーションがループ再生されます。
 *
 * 装備品、ステート、職業ごとに画像を上乗せできます。
 * それぞれデータベースのメモ欄に以下の通り指定してください。
 * <SBI画像:item>   # /img/pictures/item.pngが表示されます。
 * <SBIImage:item>  # /img/pictures/item.pngが表示されます。
 * <SBIPosX:30>     # 装備品画像のX座標を[30]に設定します。
 * <SBI座標X:30>    # 装備品画像のX座標を[30]に設定します。
 * <SBIPosY:30>     # 装備品画像のY座標を[30]に設定します。
 * <SBI座標Y:30>    # 装備品画像のY座標を[30]に設定します。
 * <SBIPosZ:3>      # 装備品画像のZ座標を[3]に設定します。
 * <SBI座標Z:3>     # 装備品画像のZ座標を[3]に設定します。
 * <SBI矩形:0,0,100,100> # 画像を指定した矩形(X座標、Y座標、横幅、高さ)で
 * <SBIRect:0,0,100,100> # 切り出して（トリミング）表示します。(カンマ区切り)
 * <SBIScaleX:100>   # 装備品画像の横方向の拡大率を設定します。
 * <SBI拡大率X:100>   # 同上
 * <SBIScaleY:100>   # 装備品画像の縦方向の拡大率を設定します。
 * <SBI拡大率Y:100>   # 同上
 *
 * 指定する座標はベース画像の足下からの相対座標です。
 *
 * Z座標が大きい値ほど手前に表示されます。指定しない場合は[1]になります。
 * アクター画像のZ座標は[0]で固定です。
 *
 * プラグインコマンドの実行により画像や動画を変更することもできます。
 * ストーリーの進行によって差し替えたい場合に使用します。
 *
 * プラグインコマンド詳細
 *  イベントコマンド「プラグインコマンド」から実行。
 *  （パラメータの間は半角スペースで区切る）
 *
 * SBI画像差し替え 1 file2  # ID[1]のアクターの画像を
 *                          「file2.png」に差し替えます。
 * SBI_IMAGE_CHANGE 1 file2 # ID[1]のアクターの画像を
 *                          「file2.png」に差し替えます。
 * SBI動画差し替え 1 3  # ID[1]のアクターの動画を「3」に差し替えます。
 * SBI_ANIME_CHANGE 1 3 # ID[1]のアクターの動画を「3」に差し替えます。
 *
 * 利用規約：
 *  作者に無断で改変、再配布が可能で、利用形態（商用、18禁利用等）
 *  についても制限はありません。
 *  このプラグインはもうあなたのものです。
 *
 * This plugin is released under the MIT License.
 */
/*:ja
 * @plugindesc バストアップ表示プラグイン
 * @author トリアコンタン
 *
 * @param 画像X座標
 * @desc バストアップ画像を表示するX座標(足下原点)です。
 * @default 640
 *
 * @param 画像Y座標
 * @desc バストアップ画像を表示するY座標(足下原点)です。
 * @default 620
 *
 * @param 装備_画像X座標
 * @desc 装備画面でバストアップ画像を表示するX座標(足下原点)です。指定しない場合、表示されなくなります。
 * @default
 *
 * @param 装備_画像Y座標
 * @desc 装備画面でバストアップ画像を表示するY座標(足下原点)です。指定しない場合、表示されなくなります。
 * @default
 *
 * @param スキル_画像X座標
 * @desc スキル画面でバストアップ画像を表示するX座標(足下原点)です。指定しない場合、表示されなくなります。
 * @default
 *
 * @param スキル_画像Y座標
 * @desc スキル画面でバストアップ画像を表示するY座標(足下原点)です。指定しない場合、表示されなくなります。
 * @default
 *
 * @param メイン_画像X座標
 * @desc メインメニュー画面でバストアップ画像を表示するY座標(足下原点)です。指定しない場合、表示されなくなります。
 * @default
 *
 * @param メイン_画像Y座標
 * @desc メインメニュー画面でバストアップ画像を表示するY座標(足下原点)です。指定しない場合、表示されなくなります。
 * @default
 *
 * @param 表示優先度
 * @desc バストアップ画像の表示優先度（プライオリティ）です。
 * @default 0
 * @type select
 * @option ウィンドウの下
 * @value 0
 * @option ウィンドウの内容の下
 * @value 1
 * @option ウィンドウの上
 * @value 2
 *
 * @param ベース画像原点
 * @desc ベース画像の原点です。
 * @default 2
 * @type select
 * @option 左上
 * @value 0
 * @option 中央
 * @value 1
 * @option 足下
 * @value 2
 *
 * @param 追加画像原点
 * @desc 追懐画像および装備品画像の原点です。
 * @default 2
 * @type select
 * @option 左上
 * @value 0
 * @option 中央
 * @value 1
 * @option 足下
 * @value 2
 *
 * @help ステータス画面にアクターごとのバストアップ画像を表示します。
 * 足下を原点として表示位置を自由に調整できます。
 *
 * 装備画面とスキル画面にも同一のバストアップ画像を表示できますが
 * デフォルト画面サイズではスペースがないので、使用する場合は必要に応じて
 * 画面サイズを変更してください。
 *
 * また、メインメニュー画面にも同一のバストアップ画像を表示できますが
 * 表示されるのは「先頭のアクター」のみです。
 * 主にアクターが一人の場合に使用します。
 *
 * アクターのメモ欄に以下の通り指定してください。
 *
 * <SBI画像:file>   # /img/pictures/file.pngが表示されます。
 * <SBIImage:file>  # 同上
 * <SBI矩形:0,0,100,100> # 画像を指定した矩形(X座標、Y座標、横幅、高さ)で
 * <SBIRect:0,0,100,100> # 切り出して（トリミング）表示します。(カンマ区切り)
 * <SBI画像拡大率X:100>  # 画像の横方向の拡大率を設定します。
 * <SBIImageScaleX:100> # 同上
 * <SBI画像拡大率Y:100>  # 画像の縦方向の拡大率を設定します。
 * <SBIImageScaleY:100> # 同上
 *
 * さらに以下のメモ欄で追加差分を複数表示することが可能です。
 * <SBI追加画像1:file2>       # /img/pictures/file2.pngが表示されます。
 * <SBIAddImage1:file2>       # 同上
 * <SBI追加条件1:\v[1] === 3> # 変数[1]が[3]と等しい時のみ追加画像が表示されます。
 * <SBIAddCond1:\v[1] === 3>  # 同上
 * <SBI追加座標X1:30>         # 追加画像のX座標を[30]に設定します。
 * <SBIAddPosX1:30>           # 同上
 * <SBI追加座標Y1:30>         # 追加画像のY座標を[30]に設定します。
 * <SBIAddPosY1:30>           # 同上
 * <SBI追加座標拡大率X1:100>   # 追加画像の横方向の拡大率を設定します。
 * <SBIAddPosScaleX1:100>     # 同上
 * <SBI追加座標拡大率Y1:100>   # 追加画像の縦方向の拡大率を設定します。
 * <SBIAddPosScaleY1:100>     # 同上
 *
 * 複数の追加画像を表示したい場合は最後の数字を[2]以降に変更してください。
 *
 * 指定する座標はベース画像の足下からの相対座標です。
 *
 * 計算式中で不等号を使いたい場合、以下のように記述してください。
 * < → <
 * > → >
 * 例：<SBIAddCond1:\v[2] > 1> // 変数[2]が1より大きい場合
 *
 * さらに動画(データベースのアニメーション)を再生することもできます。
 * 画像の上に重ねてまばたき等を表現するのに使用します。
 *
 * <SBI動画:1>      # ID[1]のアニメーションがループ再生されます。
 * <SBIAnimation:1> # ID[1]のアニメーションがループ再生されます。
 *
 * 装備品、ステート、職業ごとに画像を上乗せできます。
 * それぞれデータベースのメモ欄に以下の通り指定してください。
 * <SBI画像:item>   # /img/pictures/item.pngが表示されます。
 * <SBIImage:item>  # /img/pictures/item.pngが表示されます。
 * <SBIPosX:30>     # 装備品画像のX座標を[30]に設定します。
 * <SBI座標X:30>    # 装備品画像のX座標を[30]に設定します。
 * <SBIPosY:30>     # 装備品画像のY座標を[30]に設定します。
 * <SBI座標Y:30>    # 装備品画像のY座標を[30]に設定します。
 * <SBIPosZ:3>      # 装備品画像のZ座標を[3]に設定します。
 * <SBI座標Z:3>     # 装備品画像のZ座標を[3]に設定します。
 * <SBI矩形:0,0,100,100> # 画像を指定した矩形(X座標、Y座標、横幅、高さ)で
 * <SBIRect:0,0,100,100> # 切り出して（トリミング）表示します。(カンマ区切り)
 * <SBIScaleX:100>   # 装備品画像の横方向の拡大率を設定します。
 * <SBI拡大率X:100>   # 同上
 * <SBIScaleY:100>   # 装備品画像の縦方向の拡大率を設定します。
 * <SBI拡大率Y:100>   # 同上
 *
 * 指定する座標はベース画像の足下からの相対座標です。
 *
 * Z座標が大きい値ほど手前に表示されます。指定しない場合は[1]になります。
 * アクター画像のZ座標は[0]で固定です。
 *
 * プラグインコマンドの実行により画像や動画を変更することもできます。
 * ストーリーの進行によって差し替えたい場合に使用します。
 *
 * プラグインコマンド詳細
 *  イベントコマンド「プラグインコマンド」から実行。
 *  （パラメータの間は半角スペースで区切る）
 *
 * SBI画像差し替え 1 file2  # ID[1]のアクターの画像を
 *                          「file2.png」に差し替えます。
 * SBI_IMAGE_CHANGE 1 file2 # ID[1]のアクターの画像を
 *                          「file2.png」に差し替えます。
 * SBI動画差し替え 1 3  # ID[1]のアクターの動画を「3」に差し替えます。
 * SBI_ANIME_CHANGE 1 3 # ID[1]のアクターの動画を「3」に差し替えます。
 *
 * 利用規約：
 *  作者に無断で改変、再配布が可能で、利用形態（商用、18禁利用等）
 *  についても制限はありません。
 *  このプラグインはもうあなたのものです。
 */

(function () {
  "use strict";
  var pluginName = "StatusBustImage";
  var metaTagPrefix = "SBI";

  var getCommandName = function (command) {
    return (command || "").toUpperCase();
  };

  var getParamOther = function (paramNames) {
    if (!Array.isArray(paramNames)) paramNames = [paramNames];
    for (var i = 0; i < paramNames.length; i++) {
      var name = PluginManager.parameters(pluginName)[paramNames[i]];
      if (name) return name;
    }
    return null;
  };

  var getParamNumber = function (paramNames, min, max) {
    var value = getParamOther(paramNames);
    if (arguments.length < 2) min = -Infinity;
    if (arguments.length < 3) max = Infinity;
    return (parseInt(value, 10) || 0).clamp(min, max);
  };

  var getMetaValue = function (object, name) {
    var metaTagName = metaTagPrefix + (name ? name : "");
    return object.meta.hasOwnProperty(metaTagName)
      ? object.meta[metaTagName]
      : undefined;
  };

  var getMetaValues = function (object, names) {
    if (!Array.isArray(names)) return getMetaValue(object, names);
    for (var i = 0, n = names.length; i < n; i++) {
      var value = getMetaValue(object, names[i]);
      if (value !== undefined) return value;
    }
    return undefined;
  };

  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 getArgString = function (arg, upperFlg) {
    arg = convertEscapeCharacters(arg);
    return upperFlg ? arg.toUpperCase() : arg;
  };

  var getArgArrayString = function (args, upperFlg) {
    var values = getArgString(args, upperFlg).split(",");
    for (var i = 0; i < values.length; i++) values[i] = values[i].trim();
    return values;
  };

  var getArgArrayEval = function (args, min, max) {
    var values = getArgArrayString(args, false);
    if (arguments.length < 2) min = -Infinity;
    if (arguments.length < 3) max = Infinity;
    for (var i = 0; i < values.length; i++)
      values[i] = eval(values[i]).clamp(min, max);
    return values;
  };

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

  var convertEscapeTags = function (text) {
    if (isNotAString(text)) text = "";
    text = text.replace(/>?/gi, ">");
    text = text.replace(/<?/gi, "<");
    return text;
  };

  var isNotAString = function (args) {
    return String(args) !== args;
  };

  //=============================================================================
  // パラメータの取得と整形
  //=============================================================================
  var paramBustImageX = getParamNumber(["BustImageX", "画像X座標"]);
  var paramBustImageY = getParamNumber(["BustImageY", "画像Y座標"]);
  var paramEquipBustImageX = getParamNumber([
    "EquipBustImageX",
    "装備_画像X座標",
  ]);
  var paramEquipBustImageY = getParamNumber([
    "EquipBustImageY",
    "装備_画像Y座標",
  ]);
  var paramSkillBustImageX = getParamNumber([
    "SkillBustImageX",
    "スキル_画像X座標",
  ]);
  var paramSkillBustImageY = getParamNumber([
    "SkillBustImageY",
    "スキル_画像Y座標",
  ]);
  var paramMainBustImageX = getParamNumber([
    "MainBustImageX",
    "メイン_画像X座標",
  ]);
  var paramMainBustImageY = getParamNumber([
    "MainBustImageY",
    "メイン_画像Y座標",
  ]);
  var paramBustPriority = getParamNumber(["BustPriority", "表示優先度"], 0);
  var paramBaseImageOrigin = getParamNumber(
    ["BaseImageOrigin", "ベース画像原点"],
    0
  );
  var paramAddImageOrigin = getParamNumber(
    ["AddImageOrigin", "追加画像原点"],
    0
  );

  //=============================================================================
  // Game_Interpreter
  //  プラグインコマンドを追加定義します。
  //=============================================================================
  var _Game_Interpreter_pluginCommand =
    Game_Interpreter.prototype.pluginCommand;
  Game_Interpreter.prototype.pluginCommand = function (command, args) {
    _Game_Interpreter_pluginCommand.apply(this, arguments);
    if (!command.match(new RegExp("^" + metaTagPrefix))) return;
    this.pluginCommandBustStatus(command.replace(metaTagPrefix, ""), args);
  };

  Game_Interpreter.prototype.pluginCommandBustStatus = function (
    command,
    args
  ) {
    switch (getCommandName(command)) {
      case "_IMAGE_CHANGE":
      case "画像差し替え":
        var actor1 = $gameActors.actor(getArgNumber(args[0], 1));
        actor1.setBustImageName(getArgString(args[1]));
        break;
      case "_ANIME_CHANGE":
      case "動画差し替え":
        var actor2 = $gameActors.actor(getArgNumber(args[0], 1));
        actor2.setBustAnimationId(getArgNumber(args[1]), 0);
        break;
    }
  };

  //=============================================================================
  // Game_Actor
  //  バスト画像を設定します。
  //=============================================================================
  var _Game_Actor_initMembers = Game_Actor.prototype.initMembers;
  Game_Actor.prototype.initMembers = function () {
    _Game_Actor_initMembers.apply(this, arguments);
    this._bustImageName = null;
    this._bustAnimationId = null;
  };

  Game_Actor.prototype.getMetaInfoForBustImage = function (names) {
    return getMetaValues(this.actor(), names);
  };

  Game_Actor.prototype.setBustImageName = function (value) {
    this._bustImageName = value;
  };

  Game_Actor.prototype.getBustImageName = function () {
    return (
      this._bustImageName || this.getMetaInfoForBustImage(["画像", "Image"])
    );
  };

  Game_Actor.prototype.getBustImageData = function () {
    var name = this.getBustImageName();
    if (!name) {
      return null;
    }
    return {
      name: name,
      scaleX: parseInt(
        this.getMetaInfoForBustImage(["画像拡大率X", "ImageScaleX"])
      ),
      scaleY: parseInt(
        this.getMetaInfoForBustImage(["画像拡大率Y", "ImageScaleY"])
      ),
      rect: this.getBustImageRect(),
    };
  };

  Game_Actor.prototype.getBustImageRect = function () {
    var rectString = this.getMetaInfoForBustImage(["矩形", "Rect"]);
    var rect = rectString ? getArgArrayEval(rectString, 0) : null;
    return rect ? new Rectangle(rect[0], rect[1], rect[2], rect[3]) : null;
  };

  Game_Actor.prototype.setBustAnimationId = function (value) {
    this._bustAnimationId = value || null;
  };

  Game_Actor.prototype.getBustAnimationId = function () {
    if (this._bustAnimationId) return this._bustAnimationId;
    var value = this.getMetaInfoForBustImage(["動画", "Animation"]);
    return value ? getArgNumber(value, 1) : 0;
  };

  Game_Actor.prototype.getAdditionalBustImage = function (index) {
    var fileName = this.getMetaInfoForBustImage([
      "追加画像" + index,
      "AddImage" + index,
    ]);
    if (!fileName) {
      return null;
    }
    var image = {};
    image.fileName = getArgString(fileName);
    image.cond = getArgString(
      this.getMetaInfoForBustImage(["追加条件" + index, "AddCond" + index])
    );
    image.x = getArgNumber(
      this.getMetaInfoForBustImage(["追加座標X" + index, "AddPosX" + index])
    );
    image.y = getArgNumber(
      this.getMetaInfoForBustImage(["追加座標Y" + index, "AddPosY" + index])
    );
    image.scaleX = getArgNumber(
      this.getMetaInfoForBustImage([
        "追加座標拡大率X" + index,
        "AddPosScaleX" + index,
      ])
    );
    image.scaleY = getArgNumber(
      this.getMetaInfoForBustImage([
        "追加座標拡大率Y" + index,
        "AddPosScaleY" + index,
      ])
    );
    return image;
  };

  Game_Actor.prototype.getAdditionalBustImageList = function () {
    var bustList = [];
    var index = 1;
    var image = null;
    do {
      image = this.getAdditionalBustImage(index);
      if (image) {
        bustList.push(image);
      }
      index++;
    } while (image);
    return bustList;
  };

  //=============================================================================
  // Window_Base
  //  バスト画像表示用スプライトを追加定義します。
  //=============================================================================
  var _Window_Base_initialize = Window_Base.prototype.initialize;
  Window_Base.prototype.initialize = function () {
    if (this.isNeedBust()) this._bustSprite = null;
    _Window_Base_initialize.apply(this, arguments);
  };

  Window_Base.prototype._createAllParts = function () {
    Window.prototype._createAllParts.call(this);
    if (this.isNeedBust()) this.createBustSprite();
  };

  Window_Base.prototype.isNeedBust = function () {
    if ($gameParty.inBattle()) {
      return false;
    }
    var pos = this.getBustPosition();
    return pos !== null && (pos[0] !== 0 || pos[1] !== 0);
  };

  Window_Base.prototype.createBustSprite = function () {
    this._bustContainer = new Sprite();
    this._bustSprite = new Sprite_Bust();
    this._bustContainer.addChild(this._bustSprite);
    this._bustAddContainer = false;
  };

  Window_Base.prototype.setBustPosition = function (x, y) {
    if (this.isUnderWindow()) {
      this._bustSprite.move(x, y);
    } else {
      this._bustSprite.move(x - this.x, y - this.y);
    }
  };

  Window_Base.prototype.getBustPosition = function () {
    return null;
  };

  Window_Base.prototype.refreshBust = function () {
    if (this._actor && this.isNeedBust()) {
      this.setBustPosition.apply(this, this.getBustPosition());
      this._bustSprite.refresh(this._actor);
      if (!this._bustAddContainer) {
        this.tryAddBustContainer();
      }
    }
  };

  Window_Base.prototype.tryAddBustContainer = function () {
    if (this.isUnderWindow()) {
      if (!this.parent) {
        return;
      }
      this.parent.parent.addChildAt(this._bustContainer, 1);
    } else {
      this.addChildAt(this._bustContainer, paramBustPriority === 1 ? 2 : 3);
    }
    this._bustAddContainer = true;
  };

  Window_Base.prototype.isUnderWindow = function () {
    return paramBustPriority === 0;
  };

  //=============================================================================
  // Window_MenuStatus
  //  バスト画像表示用スプライトを追加定義します。
  //=============================================================================
  var _Window_MenuStatus_refresh = Window_MenuStatus.prototype.refresh;
  Window_MenuStatus.prototype.refresh = function () {
    _Window_MenuStatus_refresh.apply(this, arguments);
    this._actor = $gameParty.members()[0];
    this.refreshBust();
  };

  var _Window_MenuStatus_setPendingIndex =
    Window_MenuStatus.prototype.setPendingIndex;
  Window_MenuStatus.prototype.setPendingIndex = function (index) {
    _Window_MenuStatus_setPendingIndex.apply(this, arguments);
    var actor = $gameParty.members()[0];
    if (actor === this._actor) return;
    this._actor = actor;
    this.refreshBust();
  };

  Window_MenuStatus.prototype.getBustPosition = function () {
    return [paramMainBustImageX, paramMainBustImageY];
  };

  //=============================================================================
  // Window_MenuActor
  //  アクター選択ウィンドウにはバストアップは表示しない
  //=============================================================================
  Window_MenuActor.prototype.getBustPosition = function () {
    return null;
  };

  // Resolve conflict for TMSoloMenu.js
  if (typeof Window_SoloStatus !== "undefined") {
    var _Window_SoloStatus_refresh = Window_SoloStatus.prototype.refresh;
    Window_SoloStatus.prototype.refresh = function () {
      _Window_SoloStatus_refresh.apply(this, arguments);
      this._actor = $gameParty.members()[0];
      this.refreshBust();
    };

    Window_SoloStatus.prototype.getBustPosition = function () {
      return [paramMainBustImageX, paramMainBustImageY];
    };
  }

  //=============================================================================
  // Window_Status
  //  バスト画像表示用スプライトを追加定義します。
  //=============================================================================
  var _Window_Status_refresh = Window_Status.prototype.refresh;
  Window_Status.prototype.refresh = function () {
    _Window_Status_refresh.apply(this, arguments);
    this.refreshBust();
  };

  Window_Status.prototype.getBustPosition = function () {
    return [paramBustImageX, paramBustImageY];
  };

  //=============================================================================
  // Window_EquipItem
  //  バスト画像表示用スプライトを追加定義します。
  //=============================================================================
  Window_EquipItem.prototype.refresh = function () {
    if (!this._actor) {
      return;
    }
    Window_ItemList.prototype.refresh.apply(this, arguments);
    this.refreshBust();
  };

  Window_EquipItem.prototype.getBustPosition = function () {
    return [paramEquipBustImageX, paramEquipBustImageY];
  };

  //=============================================================================
  // Window_SkillList
  //  バスト画像表示用スプライトを追加定義します。
  //=============================================================================
  var _Window_SkillList_refresh = Window_SkillList.prototype.refresh;
  Window_SkillList.prototype.refresh = function () {
    _Window_SkillList_refresh.apply(this, arguments);
    this.refreshBust();
  };

  Window_SkillList.prototype.getBustPosition = function () {
    return [paramSkillBustImageX, paramSkillBustImageY];
  };

  //=============================================================================
  // Scene_Equip
  //  装備変更時にバストイメージを更新します。
  //=============================================================================
  var _Scene_Equip_commandOptimize = Scene_Equip.prototype.commandOptimize;
  Scene_Equip.prototype.commandOptimize = function () {
    _Scene_Equip_commandOptimize.apply(this, arguments);
    this._itemWindow.refreshBust();
  };

  var _Scene_Equip_commandClear = Scene_Equip.prototype.commandClear;
  Scene_Equip.prototype.commandClear = function () {
    _Scene_Equip_commandClear.apply(this, arguments);
    this._itemWindow.refreshBust();
  };

  //=============================================================================
  // Sprite_Bust
  //  バスト画像のクラスです。
  //=============================================================================
  function Sprite_Bust() {
    this.initialize.apply(this, arguments);
  }
  Sprite_Bust._anchorListX = [0.0, 0.5, 0.5];
  Sprite_Bust._anchorListY = [0.0, 0.5, 1.0];

  Sprite_Bust.prototype = Object.create(Sprite_Base.prototype);
  Sprite_Bust.prototype.constructor = Sprite_Bust;

  Sprite_Bust.prototype.initialize = function () {
    Sprite_Base.prototype.initialize.call(this);
    this.anchor.x = Sprite_Bust._anchorListX[paramBaseImageOrigin];
    this.anchor.y = Sprite_Bust._anchorListY[paramBaseImageOrigin];
    this._actor = null;
    this._equipSprites = [];
    this._additonalSprite = [];
    this.z = 0;
  };

  Sprite_Bust.prototype.refresh = function (actor) {
    this._actor = actor;
    this.drawMain();
    this.drawAdditions();
    this.drawEquips();
    this.drawAnimation();
  };

  Sprite_Bust.prototype.drawMain = function () {
    var data = this._actor.getBustImageData();
    if (!data) {
      this.bitmap = null;
      return;
    }
    this.bitmap = ImageManager.loadPicture(getArgString(data.name), 0);
    var rect = data.rect;
    if (rect) {
      this.setFrame(rect.x, rect.y, rect.width, rect.height);
    }
    if (data.scaleX) {
      this.scale.x = data.scaleX / 100;
    }
    if (data.scaleY) {
      this.scale.y = data.scaleY / 100;
    }
  };

  Sprite_Bust.prototype.drawAdditions = function () {
    this.clearAdditions();
    var additionalList = this._actor.getAdditionalBustImageList();
    additionalList.forEach(function (additionalImage) {
      this.makeAdditionSprite(additionalImage);
    }, this);
  };

  Sprite_Bust.prototype.clearAdditions = function () {
    this._additonalSprite.forEach(
      function (sprite) {
        this.parent.removeChild(sprite);
      }.bind(this)
    );
    this._additonalSprite = [];
  };

  Sprite_Bust.prototype.drawAnimation = function () {
    var animationId = this._actor.getBustAnimationId();
    if (this._animationId === animationId && this.isAnyAnimationExist()) return;
    this._animationId = animationId;
    if (this.isAnyAnimationExist()) return;
    if (this.isNeedAnimation()) {
      this.startAnimation();
    } else {
      this.stopAnimation();
    }
  };

  Sprite_Bust.prototype.drawEquips = function () {
    this.clearEquips();
    this._actor.traitObjects().forEach(function (traitObj) {
      if (traitObj && traitObj !== this._actor.actor()) {
        this.makeSubSprite(traitObj);
      }
    }, this);
    this.sortEquips();
  };

  Sprite_Bust.prototype.clearEquips = function () {
    this._equipSprites.forEach(
      function (sprite) {
        this.parent.removeChild(sprite);
      }.bind(this)
    );
    this._equipSprites = [];
  };

  Sprite_Bust.prototype.sortEquips = function () {
    this.parent.children.sort(this._compareChildOrder.bind(this));
  };

  Sprite_Bust.prototype._compareChildOrder = function (a, b) {
    if (a.z !== b.z) {
      return a.z - b.z;
    } else if (a.y !== b.y) {
      return a.y - b.y;
    } else {
      return a.spriteId - b.spriteId;
    }
  };

  Sprite_Bust.prototype.makeSubSprite = function (traitObj) {
    var itemFileName = getMetaValues(traitObj, ["画像", "Image"]);
    if (itemFileName) {
      var sprite = new Sprite();
      sprite.anchor.x = Sprite_Bust._anchorListX[paramAddImageOrigin];
      sprite.anchor.y = Sprite_Bust._anchorListY[paramAddImageOrigin];
      sprite.bitmap = ImageManager.loadPicture(getArgString(itemFileName), 0);
      var xStr = getMetaValues(traitObj, ["PosX", "座標X"]);
      sprite.x = this.x + (xStr ? getArgNumber(xStr) : 0);
      var yStr = getMetaValues(traitObj, ["PosY", "座標Y"]);
      sprite.y = this.y + (yStr ? getArgNumber(yStr) : 0);
      var zStr = getMetaValues(traitObj, ["PosZ", "座標Z"]);
      sprite.z = zStr !== undefined ? getArgNumber(zStr) : 1;
      var rectString = getMetaValues(traitObj, ["矩形", "Rect"]);
      if (rectString) {
        var rect = getArgArrayEval(rectString, 0);
        sprite.setFrame(rect[0], rect[1], rect[2], rect[3]);
      }
      var scaleX = getMetaValues(traitObj, ["ScaleX", "拡大率X"]);
      if (scaleX) {
        sprite.scale.x = getArgNumber(scaleX) / 100;
      }
      var scaleY = getMetaValues(traitObj, ["ScaleY", "拡大率Y"]);
      if (scaleY) {
        sprite.scale.y = getArgNumber(scaleY) / 100;
      }
      this.parent.addChild(sprite);
      this._equipSprites.push(sprite);
    }
  };

  Sprite_Bust.prototype.makeAdditionSprite = function (image) {
    if (image.cond && !eval(image.cond)) {
      return;
    }
    var sprite = new Sprite();
    sprite.anchor.x = Sprite_Bust._anchorListX[paramAddImageOrigin];
    sprite.anchor.y = Sprite_Bust._anchorListY[paramAddImageOrigin];
    sprite.bitmap = ImageManager.loadPicture(image.fileName);
    sprite.x = this.x + image.x;
    sprite.y = this.y + image.y;
    sprite.z = 0;
    if (image.scaleX) {
      sprite.scale.x = image.scaleX / 100;
    }
    if (image.scaleY) {
      sprite.scale.y = image.scaleY / 100;
    }
    this.parent.addChild(sprite);
    this._additonalSprite.push(sprite);
  };

  Sprite_Bust.prototype.startAnimation = function () {
    Sprite_Base.prototype.startAnimation.call(
      this,
      $dataAnimations[this._animationId],
      false,
      0
    );
  };

  Sprite_Bust.prototype.update = function () {
    Sprite_Base.prototype.update.call(this);
    if (this.isNeedAnimation()) this.updateAnimation();
  };

  Sprite_Bust.prototype.updateAnimation = function () {
    if (!this.isAnyAnimationExist()) {
      this.startAnimation();
    }
  };

  Sprite_Bust.prototype.isNeedAnimation = function () {
    return this._animationId > 0;
  };

  Sprite_Bust.prototype.isAnyAnimationExist = function () {
    if (this.isAnimationPlaying()) {
      return this._animationSprites.some(function (sprite) {
        return sprite.isPlaying();
      });
    } else {
      return false;
    }
  };

  Sprite_Base.prototype.stopAnimation = function () {
    if (this._animationSprites.length > 0) {
      this._animationSprites.forEach(function (animation) {
        animation.remove();
      });
    }
    this._animationSprites = [];
  };
})();


code:
//============================================================================
// SupponShopStock.js
//============================================================================

/*:
 * @plugindesc 在庫システムを有するお店を設定します。version 1.04m2
 * @author Suppon
 *
 * @param Label of stock Number
 * @text 在庫数表記
 * @desc 在庫数の表記を設定します
 * @default 在庫数
 *
 * @param Label of sold out
 * @text 売り切れ表記
 * @desc 売り切れの表記を設定します
 * @default 売り切れ
 *
 * @param Display option
 * @text 在庫数表示
 * @desc true にすると在庫数が、持っている数の横に表示されます。
 * @default false
 *
 * @param Display option space
 * @text 表示スペース
 * @desc 持っている数と在庫数の表示スペースです。
 * @default 12
 *
 * @help
 * YEP_ShopMenuCoreプラグインと併用するときは、プラグイン管理ウインドウで、
 * このプラグインの順番をYEP_ShopMenuCoreの後に置くようにしてください。
 * また、必ずパラメータのDisplay option (在庫数表示) を true にしてください。
 *
 * 以下のようにプラグインコマンドを入力して使用してください。
 * 文字、数値の間はスペースで区切ってください。
 *
 * <ショップの作成方法>
 * SupponSS makeShop 文字1 数値1
 * 文字1 : ショップの名前です。数値でも構いません。
 * 数値1 : ショップタイプです。0は購買専門（売却不可）
 *           1は購買、売却可能
 *           2は購買、売却可能、全ての売却品がショップの商品に加わります。
 *           省略時は、1になります。
 * 例 : SupponSS makeShop omise 2
 *
 *
 * <アイテムの追加方法>
 * SupponSS addItem 文字1 数値1 数値2 数値3
 * 文字1 : アイテムを追加するショップ名です。
 * 数値1 : 追加するアイテムのIDです。
 * 数値2 : 在庫の個数を割り当てる変数のIDです。-1にすると変数は使わず、
 *         在庫は内部のデータで処理されます。
 * 数値3 : 在庫数の設定値です。省略した場合、
 *         数値2で指定した変数の値が適用されます。
 * 例 : SupponSS addItem omise 1 2 3
 * 例 : SupponSS addItem omise 4 -1 10
 *
 *
 * <武器の追加方法>
 * SupponSS addWeapon 文字1 数値1 数値2 数値3
 *     文字1、数値1~3 : アイテムの追加と同様です。
 *
 * <防具の追加方法>
 * SupponSS addArmor 文字1 数値1 数値2 数値3
 *     文字1、数値1~3 : アイテムの追加と同様です。
 *
 * <アイテムの削除方法>
 * SupponSS removeItem 文字1 数値1
 *     文字1 : 削除したいアイテムがあるショップ名です。
 *     数値1 : 削除するアイテムのIDです。
 * 例 : SupponSS removeItem omise 1
 *
 * <武器の削除方法>
 * SupponSS removeWeapon 文字1 数値1
 *     文字1、数値1 : アイテムの削除方法と同様です。
 *
 * <防具の削除方法>
 * SupponSS removeArmor 文字1 数値1
 *     文字1、数値1 : アイテムの削除方法と同様です。
 *
 * <ショップの起動方法>
 * SupponSS openShop 文字1 数値1
 * 文字1 : 起動するショップ名です。
 * 数値1 : 購買時のソートオプションです。
 *           0は、商品の表示順は追加した順になります。
 *           1は、アイテムID順、次に武器ID順、次に防具ID順になります。
 *           2は、カテゴリー選択できます。さらにID順になります。
 *           省略時は、0と同じになります。
 * 例 : SupponSS openShop omise 2
 *
 *
 * <ショップの削除方法>
 * SupponSS deleteShop 文字1
 *     文字1 : 削除したいショップのショップ名です。
 * 例 : SupponSS deleteShop omise
 *
 *
 * <変数管理しないアイテムの在庫数の取り出し方法>
 * SupponSS getNumItem 文字1 数値1 数値2
 * SupponSS getNumWeapon 文字1 数値1 数値2
 * SupponSS getNumArmor 文字1 数値1 数値2
 *     文字1 : 調べたいアイテムのあるショップ名です。
 *     数値1 : アイテム、武器、防具のIDです。
 *     数値2 : アイテムの個数を格納する変数のIDです。
 * 例 : SupponSS getNumItem omise 1 2
 *
 *
 */

(function () {
  var parameters = PluginManager.parameters("SupponShopStock");
  var StockLabel = String(parameters["Label of stock Number"] || "在庫数");
  var SoldOutLabel = String(parameters["Label of sold out"] || "売り切れ");
  var DisplayOption1 = parameters["Display option"] == "true";
  var Option1Space = Number(parameters["Display option space"]);

  var _Game_Interpreter_pluginCommand =
    Game_Interpreter.prototype.pluginCommand;
  Game_Interpreter.prototype.pluginCommand = function (command1, args) {
    _Game_Interpreter_pluginCommand.call(this, command1, args);
    args = args.filter(function (n) {
      return n !== "";
    });
    if (!$gameSystem._supponSS) {
      $gameSystem._supponSS = [];
    }
    if (command1 === "SupponSS") {
      var command2 = args.shift();
      switch (command2) {
        case "makeShop":
          $gameSystem.supponSSmakeShop(args);
          break;
        case "addItem":
          args.splice(1, 0, 0);
          $gameSystem.supponSSaddGoods(args);
          break;
        case "addWeapon":
          args.splice(1, 0, 1);
          $gameSystem.supponSSaddGoods(args);
          break;
        case "addArmor":
          args.splice(1, 0, 2);
          $gameSystem.supponSSaddGoods(args);
          break;
        case "removeItem":
          args.splice(1, 0, 0);
          $gameSystem.supponSSremoveGoods(args);
          break;
        case "removeWeapon":
          args.splice(1, 0, 1);
          $gameSystem.supponSSremoveGoods(args);
          break;
        case "removeArmor":
          args.splice(1, 0, 2);
          $gameSystem.supponSSremoveGoods(args);
          break;
        case "deleteShop":
          $gameSystem.supponSSdeleteShop(args);
          break;
        case "openShop":
          $gameSystem.supponSSopenShop(args);
          break;
        case "getNumItem":
          args.splice(1, 0, 0);
          $gameSystem.supponSSgetNumItem(args);
          break;
        case "getNumWeapon":
          args.splice(1, 0, 1);
          $gameSystem.supponSSgetNumItem(args);
          break;
        case "getNumArmor":
          args.splice(1, 0, 2);
          $gameSystem.supponSSgetNumItem(args);
          break;
      }
    }
  };

  Game_System.prototype.supponSScheckData = function () {
    this._supponSS = this._supponSS || [];
  };

  Game_System.prototype.supponSSmakeShop = function (args) {
    this.supponSScheckData();
    var redundancy = this._supponSS.some(function (element) {
      return element[0] === args[0];
    });
    if (redundancy) {
      return;
    }
    if (!args[1]) {
      args[1] = 1;
    }
    this._supponSS.push([args[0], [], args[1]]); //[shopid, goods, shoptype]
  };

  //args => [shopId, 種類, itemId, 変数id]
  //shop => [id, goods, type]
  //good => [種類, itemId, 価格指定, 価格, 変数id, 在庫数]
  Game_System.prototype.supponSSaddGoods = function (args) {
    var shop = this.supponSSsearchShop(args);
    args.shift();
    args.splice(2, 0, 0, 0);
    if (shop) {
      var redundancy = false;
      shop[1].forEach(function (element) {
        if (element[0] == args[0] && element[1] == args[1]) {
          element = args;
          redundancy = true;
        }
      });
      if (args[5]) {
        args[4] > 0
          ? $gameVariables.setValue(Number(args[4]), Number(args[5]))
          : 0;
      } else {
        args[5] = 0;
      }
      if (!redundancy) {
        shop[1].push(args);
      }
    }
  };

  Game_System.prototype.supponSSremoveGoods = function (args) {
    var shop = this.supponSSsearchShop(args);
    if (!shop) {
      return;
    }
    //shop[1] => goods
    shop[1] = shop[1].filter(function (element) {
      return !(args[1] == element[0] && args[2] == element[1]);
    });
  };

  Game_System.prototype.supponSSsearchShop = function (args) {
    this.supponSScheckData();
    var shop = null;
    this._supponSS.forEach(function (element) {
      if (args[0] === element[0]) {
        shop = element;
      }
    });
    if (!shop) {
      console.log("Not exist shop of " + args[0] + " !!");
    }
    return shop;
  };

  Game_System.prototype.supponSSdeleteShop = function (args) {
    this._supponSS = this._supponSS.filter(function (element) {
      return !(element[0] == args[0]);
    });
  };

  Game_System.prototype.supponSSopenShop = function (args) {
    var shop = this.supponSSsearchShop(args);
    if (shop) {
      SceneManager.push(Scene_supponSSshop);
      var purchaseOnly = shop[2] == 0;
      var sortType = args[1];
      SceneManager.prepareNextScene(shop, purchaseOnly, sortType);
    }
  };

  Game_System.prototype.supponSSgetNumItem = function (args) {
    if (!args[2]) {
      return;
    }
    var shop = this.supponSSsearchShop(args);
    var goodsElement = null;
    if (shop) {
      goodsElement = shop[1].find(function (element) {
        return element[0] == args[1] && element[1] == args[2];
      });
    }
    if (goodsElement) {
      if (Number(goodsElement[4]) > 0) {
        var n = $gameVariables.value(goodsElement[4]);
      } else {
        var n = goodsElement[5];
      }
      $gameVariables.setValue(Number(args[3]), Number(n));
    } else {
      $gameVariables.setValue(Number(args[3]), 0);
    }
  };

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

  SceneManager.isSupponSS = function () {
    return this._scene.constructor === Scene_supponSSshop;
  };

  Scene_supponSSshop.prototype = Object.create(Scene_Shop.prototype);
  Scene_supponSSshop.prototype.constructor = Scene_supponSSshop;

  Scene_supponSSshop.prototype.initialize = function () {
    Scene_Shop.prototype.initialize.call(this);
    this._trade = ""; // 'buy' or 'sell';
  };

  Scene_supponSSshop.prototype.prepare = function (
    shop,
    purchaseOnly,
    sortType
  ) {
    this._shop = shop;
    //this._goods = [];
    this._sortTyep = sortType;
    //_sortTyep => nill,0>従来、1>ID順、2>カテゴリ表示
    //goodelement [0, "2", 0, 0, "-1", "4"] [0, 2, purchaseOnly, 0, v, n];
    //good => [種類, itemId, 価格指定, 価格, 変数id, 在庫数]

    this._originalGoods = this._shop[1];
    this._goods = this._shop[1];
    this._purchaseOnly = purchaseOnly;
    this._item = null;
  };

  Scene_supponSSshop.prototype.sortGoods = function () {
    this._goods = [];
    //        this._originalGoods = this._originalGoods.map(function(e){
    //            return e.map(function(x){return Number(x)})
    //        })
    if (this._sortTyep == 1) {
      for (i = 0; i < this._originalGoods.length; i++) {
        this._goods.push(this._originalGoods[i]);
      }
      this._goods.sort(function (a, b) {
        return a[0] - b[0] || (a[0] == b[0] && a[1] - b[1]);
      });
    } else if (this._sortTyep == 2) {
      var type = this._categoryWindow.index();
      this._goods = this._originalGoods.filter(function (element) {
        return element[0] == type;
      });
      this._goods.sort(function (a, b) {
        return a[1] - b[1];
      });
    } else {
      this._goods = this._originalGoods;
    }
    this._buyWindow._shopGoods = this._goods;
  };

  Scene_supponSSshop.prototype.commandBuy = function () {
    this._trade = "buy";
    if (this._sortTyep == 2) {
      this._categoryWindow._list[3].enabled = false; //大事なもの選択不可
      Window_Selectable.prototype.refresh.call(this._categoryWindow);
      //this._categoryWindow.refresh();
      this._categoryWindow.setItemWindow(null);
      this._categoryWindow.show();
      this._categoryWindow.activate();
      return;
    }
    this.sortGoods();
    Scene_Shop.prototype.commandBuy.call(this);
  };

  Scene_supponSSshop.prototype.onCategoryOk = function () {
    if (this._trade == "sell") {
      Scene_Shop.prototype.onCategoryOk.call(this);
      return;
    }
    this._categoryWindow.hide();
    this.sortGoods();
    this._buyWindow.select(0);
    Scene_Shop.prototype.commandBuy.call(this);
  };

  Scene_supponSSshop.prototype.onCategoryCancel = function () {
    if (this._trade == "sell") {
      Scene_Shop.prototype.onCategoryCancel.call(this);
    } else {
      this._categoryWindow.hide();
      this._categoryWindow.deactivate();
      Scene_Shop.prototype.onBuyCancel.call(this);
    }
  };

  Scene_supponSSshop.prototype.onBuyCancel = function () {
    if (this._sortTyep != 2) {
      Scene_Shop.prototype.onBuyCancel.call(this);
      return;
    }
    //this._commandWindow.activate();
    this._dummyWindow.show();
    this._buyWindow.hide();
    this._statusWindow.hide();
    this._statusWindow.setItem(null);
    this._helpWindow.clear();
    this._categoryWindow.show();
    this._categoryWindow.activate();
  };

  Scene_supponSSshop.prototype.commandSell = function () {
    this._trade = "sell";
    this._categoryWindow._list[3].enabled = true; //大事なもの選択可
    Window_Selectable.prototype.refresh.call(this._categoryWindow);
    this._categoryWindow.setItemWindow(this._sellWindow);
    Scene_Shop.prototype.commandSell.call(this);
  };

  Scene_supponSSshop.prototype.stockNumber = function () {
    if (this._trade == "buy") {
      return this._buyWindow.stockNumber();
    } else if (this._trade == "sell") {
      var goodsElement = this.goodsElement();
      if (goodsElement) {
        if (goodsElement[4] > 0) {
          return $gameVariables.value(Number(goodsElement[4]));
        } else if (goodsElement[4] == -1) {
          return goodsElement[5];
        }
      } else {
        return null;
      }
    }
  };

  Scene_supponSSshop.prototype.stockId = function () {
    if (this._trade == "buy") {
      return this._buyWindow.stockId();
    } else if (this._trade == "sell") {
      var goodsElement = this.goodsElement();
      if (goodsElement) {
        if (goodsElement[4] > 0) {
          return goodsElement[4];
        }
      }
    }
  };

  Scene_supponSSshop.prototype.goodsElement = function () {
    if (this._trade == "buy") {
      return this._goods[this._buyWindow.index()];
    } else if (this._trade == "sell") {
      return this.searchGoodsElement();
    }
  };

  Scene_supponSSshop.prototype.searchGoodsElement = function () {
    var type = this.itemTypeAndId()[0];
    var id = this.itemTypeAndId()[1];
    var goodsElement = null;
    //this._goods.forEach(function(element){
    this._originalGoods.forEach(function (element) {
      if (element[0] == type && element[1] == id) {
        goodsElement = element;
      }
    });
    return goodsElement;
  };

  Scene_supponSSshop.prototype.itemTypeAndId = function () {
    if (DataManager.isItem(this._item)) {
      var type = 0;
    } else if (DataManager.isWeapon(this._item)) {
      var type = 1;
    } else if (DataManager.isArmor(this._item)) {
      var type = 2;
    } else {
      var type = null;
    }
    return [type, this._item ? this._item.id : null];
  };

  Scene_supponSSshop.prototype.makeGoodsElement = function () {
    var type = Number(this.itemTypeAndId()[0]);
    var id = Number(this.itemTypeAndId()[1]);
    return [type, id, 0, 0, -1, 0];
  };

  Scene_supponSSshop.prototype.doBuy = function (number) {
    Scene_Shop.prototype.doBuy.call(this, number);
    this.processStockBuy(number);
    //gameVariables.setValue(this._stockId, this.itemStock()-number);
  };

  Scene_supponSSshop.prototype.processStockBuy = function (number) {
    var element = this.goodsElement();
    if (this.stockId() > 0) {
      $gameVariables.setValue(this.stockId(), this.stockNumber() - number);
    } else if (this.stockId() == -1) {
      var lastStock = element[5];
      element[5] = lastStock - number;
    }
  };

  Scene_supponSSshop.prototype.maxBuy = function () {
    var max = $gameParty.maxItems(this._item) - $gameParty.numItems(this._item);
    max = Math.min(max, this.stockNumber());
    var price = this.buyingPrice();
    if (price > 0) {
      return Math.min(max, Math.floor(this.money() / price));
    } else {
      return max;
    }
  };

  Scene_supponSSshop.prototype.doSell = function (number) {
    $gameParty.gainGold(number * this.sellingPrice());
    $gameParty.loseItem(this._item, number);
    this.processStockSell(number);
    //this._statusWindow.refresh();
  };

  Scene_supponSSshop.prototype.processStockSell = function (number) {
    var goodsElement = this.goodsElement();
    if (goodsElement) {
      if (goodsElement[4] > 0) {
        var lastNumber = $gameVariables.value(goodsElement[4]);
        $gameVariables.setValue(goodsElement[4], lastNumber + number);
      } else if (goodsElement[4] == -1) {
        goodsElement[5] = Number(goodsElement[5]) + number;
      }
    } else if (this._shop[2] == 2) {
      goodsElement = this.makeGoodsElement();
      goodsElement[5] = number;
      //this._goods.push(goodsElement);★
      this._originalGoods.push(goodsElement);
      this.sortGoods();
      //this._goods = this.sortGoods(this._originalGoods);
      //this._buyWindow._shopGoods = this._goods;
    }
  };

  Window_ShopBuy.prototype.stockId = function () {
    if (this._shopGoods.length > 0) {
      return this._shopGoods[this._index][4];
    } else {
      return null;
    }
  };

  Window_ShopBuy.prototype.stockNumber = function () {
    if (this.stockId() > 0) {
      return $gameVariables.value(this.stockId());
    } else if (this.stockId() == -1) {
      return this._shopGoods[this._index][5];
    }
  };

  var _Window_ShopBuy_drawItem = Window_ShopBuy.prototype.drawItem;
  Window_ShopBuy.prototype.drawItem = function (index) {
    if (!SceneManager.isSupponSS()) {
      _Window_ShopBuy_drawItem.call(this, index);
      return;
    }
    var item = this._data[index];
    var rect = this.itemRect(index);
    var priceWidth = 96;
    rect.width -= this.textPadding();
    if (this._shopGoods[index][4] > 0) {
      var stockNumber = $gameVariables.value(this._shopGoods[index][4]);
    } else if (this._shopGoods[index][4] == -1) {
      var stockNumber = this._shopGoods[index][5];
    }
    this.changePaintOpacity(this.isEnabled(item) && stockNumber > 0);
    this.drawItemName(item, rect.x, rect.y, rect.width - priceWidth);
    var text = stockNumber > 0 ? this.price(item) : SoldOutLabel;
    this.drawText(
      text,
      rect.x + rect.width - priceWidth,
      rect.y,
      priceWidth,
      "right"
    );
    this.changePaintOpacity(true);
  };

  var _Window_ShopBuy_isCurrentItemEnabled =
    Window_ShopBuy.prototype.isCurrentItemEnabled;
  Window_ShopBuy.prototype.isCurrentItemEnabled = function () {
    if (SceneManager.isSupponSS()) {
      return (
        _Window_ShopBuy_isCurrentItemEnabled.call(this) &&
        this.stockNumber() > 0
      );
    } else {
      return _Window_ShopBuy_isCurrentItemEnabled.call(this);
    }
  };

  var _Window_ShopBuy_updateHelp = Window_ShopBuy.prototype.updateHelp;
  Window_ShopBuy.prototype.updateHelp = function () {
    if (this._statusWindow && SceneManager.isSupponSS()) {
      this._statusWindow.setStock(this.stockNumber());
    }
    _Window_ShopBuy_updateHelp.call(this);
  };

  var _Window_ShopSell_updateHelp = Window_ShopSell.prototype.updateHelp;
  Window_ShopSell.prototype.updateHelp = function () {
    if (this._statusWindow && SceneManager.isSupponSS()) {
      SceneManager._scene._item = this.item();
      this._statusWindow.setStock(SceneManager._scene.stockNumber());
    }
    _Window_ShopSell_updateHelp.call(this);
  };

  var _Window_ShopStatus_initialize = Window_ShopStatus.prototype.initialize;
  Window_ShopStatus.prototype.initialize = function (x, y, width, height) {
    this._stockNumber = null;
    _Window_ShopStatus_initialize.call(this, x, y, width, height);
  };

  Window_ShopStatus.prototype.setStock = function (number) {
    this._stockNumber = number;
  };

  Window_ShopStatus.prototype.stockNumber = function () {
    return SceneManager._scene.stockNumber();
  };

  var _Window_ShopStatus_drawPossession =
    Window_ShopStatus.prototype.drawPossession;
  Window_ShopStatus.prototype.drawPossession = function (x, y) {
    if (DisplayOption1) {
      this.drawPossession2(x, y);
    } else {
      _Window_ShopStatus_drawPossession.call(this, x, y);
      //if(!SceneManager.isSupponSS() || !this._stockNumber){return}
      if (this.isNeedDrawStock()) {
        var width = this.contents.width - this.textPadding() - x;
        this.drawStockNumber(x, y + this.lineHeight(), width);
      }
    }
  };

  Window_ShopStatus.prototype.isNeedDrawStock = function () {
    return SceneManager.isSupponSS() && this._stockNumber;
  };

  Window_ShopStatus.prototype.drawStockNumber = function (x, y, width) {
    var possessionWidth = this.textWidth("0000");
    this.changeTextColor(this.systemColor());
    this.drawText(StockLabel, x, y, width - possessionWidth);
    this.resetTextColor();
    var n = this._stockNumber || 0;
    this.drawText(this._stockNumber, x, y, width, "right");
  };

  Window_ShopStatus.prototype.drawPossession2 = function (x, y) {
    var width = (this.contents.width - x) / 2;
    var possessionWidth = this.textWidth("0000");
    this.changeTextColor(this.systemColor());
    this.drawText(TextManager.possession, x, y, width - possessionWidth);
    this.resetTextColor();
    this.drawText($gameParty.numItems(this._item), x, y, width, "right");
    if (this.isNeedDrawStock()) {
      this.drawStockNumber(x + width + Option1Space, y, width - Option1Space);
    }
  };

  var _Scene_Shop_onSellOk = Scene_Shop.prototype.onSellOk;
  Scene_Shop.prototype.onSellOk = function () {
    _Scene_Shop_onSellOk.call(this);
    if (this._statusWindow && SceneManager.isSupponSS()) {
      this._statusWindow.setStock(this._statusWindow.stockNumber());
      this._statusWindow.refresh();
    }
  };
})();

repo_name: dazed/translations

license: unknown


code:
//=============================================================================
// TMPlugin - アニメ付き明かり
// バージョン: 2.0.1
// 最終更新日: 2016/12/02
// 配布元    : http://hikimoki.sakura.ne.jp/
//-----------------------------------------------------------------------------
// Copyright (c) 2016 tomoaky
// Released under the MIT license.
// http://opensource.org/licenses/mit-license.php
//=============================================================================

/*:
 * @plugindesc イベントにアニメーション付きの明かりを表示します。
 *
 * @author tomoaky (http://hikimoki.sakura.ne.jp/)
 *
 * @param range
 * @desc アニメーションの大きさ。
 * 初期値: 0.1 ( 0.1 でプラスマイナス 10% の拡大縮小アニメ)
 * @default 0.1
 *
 * @param defaultZ
 * @desc アニメーションのＺ座標。
 * 初期値: 4
 * @default 4
 *
 * @param frames
 * @desc アニメーションにかけるフレーム数。
 * 初期値: 30
 * @default 30
 *
 * @help
 * 準備:
 *
 *   プラグインと一緒に配布している明かり画像を img/system フォルダに
 *   保存してください。ファイル名は自由に変更可能です。
 *   使用する画像はどんなものでもかまいません、イベントごとに違う画像を
 *   表示することもできます。
 *
 *
 * 使い方:
 *
 *   イベントのメモ欄に <animeLight:ファイル名> というタグを書き込めば、
 *   明かりが表示されるようになります。
 *
 *   明かりの位置もタグを使って調整することができます。
 *
 *   このプラグインは RPGツクールMV Version 1.3.4 で動作確認をしています。
 *
 *
 * メモ欄（イベント）タグ:
 *
 *   <animeLight:TMAnimeLight1 192 24 -44 4>
 *     画像 TMAnimeLight1.png を不透明度 192 で、イベントの足元から右に 24、
 *     上に 44 ドットずらした位置にＺ座標 4 で表示します。
 *     不透明度の最大値は 255 です。
 *
 *   イベントのメモ欄以外に、実行内容の一番上にある注釈コマンド内でも
 *   同様のタグで名前を設定することができます。
 *   メモ欄と注釈の両方にタグがある場合は注釈が優先されます。
 *
 *
 * プラグインコマンド:
 *
 *   animeLight 1 TMAnimeLight1 255 0 -44 4
 *     イベント 1 番に明かりを適用します。
 *     イベント番号、ファイル名、不透明度、Ｘ座標補正、Ｙ座標補正、Ｚ座標
 *     の順に設定してください。
 *     Ｚ座標を省略した場合はプラグインパラメータ animeLightZ の値を
 *     使用します。
 *
 *   animeLight 1
 *     イベント 1 番の明かりを削除します。
 *
 *   イベント番号（ひとつ目の数値）は以下の規則にしたがって対象を指定します。
 *     -1     … プレイヤーを対象にする
 *     0      … コマンドを実行しているイベントを対象にする
 *     1 以上 … その番号のイベントを対象にする
 *
 *
 * おまけ機能:
 *
 *   メモ欄タグ、注釈、プラグインコマンドすべてに共通で、Ｚ座標のあとに
 *   1 という数値を付与することでアニメーションのない画像を表示できます。
 *   例: <animeLight:TMAnimeLight1 192 0 0 4 1>
 *   この場合Ｚ座標を省略することはできません。
 *
 *
 * プラグインパラメータ補足:
 *
 *   defaultZ
 *     明かりの描画順を設定します、これによりイベントよりも下に表示するか
 *     上に表示するかが決まります。
 *     0 … プライオリティ『通常キャラの下』より下
 *     2 … プライオリティ『通常キャラと同じ』より下
 *     4 … プライオリティ『通常キャラと同じ』より上
 *     6 … プライオリティ『通常キャラの上』より上
 */

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

var TMPlugin = TMPlugin || {};
TMPlugin.AnimeLight = {};
TMPlugin.AnimeLight.Parameters = PluginManager.parameters("TMAnimeLight");
TMPlugin.AnimeLight.Range = +(TMPlugin.AnimeLight.Parameters["range"] || 0.1);
TMPlugin.AnimeLight.DefaultZ = +(
  TMPlugin.AnimeLight.Parameters["defaultZ"] || 4
);
TMPlugin.AnimeLight.Frames = +(TMPlugin.AnimeLight.Parameters["frames"] || 30);

if (!TMPlugin.EventBase) {
  TMPlugin.EventBase = true;
  (function () {
    var _Game_Event_setupPage = Game_Event.prototype.setupPage;
    Game_Event.prototype.setupPage = function () {
      _Game_Event_setupPage.call(this);
      if (this._pageIndex >= 0) this.loadCommentParams();
    };

    Game_Event.prototype.loadCommentParams = function () {
      this._commentParams = {};
      var re = /<([^<>:]+)(:?)([^>]*)>/g;
      var list = this.list();
      for (var i = 0; i < list.length; i++) {
        var command = list[i];
        if ((command && command.code == 108) || command.code == 408) {
          for (;;) {
            var match = re.exec(command.parameters[0]);
            if (match) {
              this._commentParams[match[1]] =
                match[2] === ":" ? match[3] : true;
            } else {
              break;
            }
          }
        } else {
          break;
        }
      }
    };

    Game_Event.prototype.loadTagParam = function (paramName) {
      return this._commentParams[paramName] || this.event().meta[paramName];
    };
  })();
} // TMPlugin.EventBase

if (!TMPlugin.InterpreterBase) {
  TMPlugin.InterpreterBase = true;
  (function () {
    Game_Interpreter.prototype.convertEscapeCharactersTM = function (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]));
        }.bind(this)
      );
      text = text.replace(
        /\x1bV\[(\d+)\]/gi,
        function () {
          return $gameVariables.value(parseInt(arguments[1]));
        }.bind(this)
      );
      text = text.replace(
        /\x1bN\[(\d+)\]/gi,
        function () {
          return this.actorNameTM(parseInt(arguments[1]));
        }.bind(this)
      );
      text = text.replace(
        /\x1bP\[(\d+)\]/gi,
        function () {
          return this.partyMemberNameTM(parseInt(arguments[1]));
        }.bind(this)
      );
      text = text.replace(/\x1bG/gi, TextManager.currencyUnit);
      return text;
    };

    Game_Interpreter.prototype.actorNameTM = function (n) {
      var actor = n >= 1 ? $gameActors.actor(n) : null;
      return actor ? actor.name() : "";
    };

    Game_Interpreter.prototype.partyMemberNameTM = function (n) {
      var actor = n >= 1 ? $gameParty.members()[n - 1] : null;
      return actor ? actor.name() : "";
    };
  })();
} // TMPlugin.InterpreterBase

(function () {
  //-----------------------------------------------------------------------------
  // Game_Temp
  //

  var _Game_Temp_initialize = Game_Temp.prototype.initialize;
  Game_Temp.prototype.initialize = function () {
    _Game_Temp_initialize.call(this);
    this.createAnimeLightSinTable();
  };

  Game_Temp.prototype.createAnimeLightSinTable = function () {
    this._animeLightSinTable = [];
    for (var i = 0; i < TMPlugin.AnimeLight.Frames; i++) {
      this._animeLightSinTable[i] =
        Math.sin((Math.PI * i) / (TMPlugin.AnimeLight.Frames / 2)) *
          TMPlugin.AnimeLight.Range +
        1;
    }
  };

  Game_Temp.prototype.animeLightSin = function (index) {
    return this._animeLightSinTable[index];
  };

  //-----------------------------------------------------------------------------
  // Game_CharacterBase
  //

  Game_CharacterBase.prototype.requestAnimeLight = function () {
    this._requestAnimeLight = true;
  };

  Game_CharacterBase.prototype.onChangeAnimeLight = function () {
    this._requestAnimeLight = false;
  };

  Game_CharacterBase.prototype.isAnimeLightRequested = function () {
    return this._requestAnimeLight;
  };

  //-----------------------------------------------------------------------------
  // Game_Event
  //

  var _Game_Event_setupPage = Game_Event.prototype.setupPage;
  Game_Event.prototype.setupPage = function () {
    _Game_Event_setupPage.call(this);
    if (this._pageIndex >= 0) {
      var animeLight = this.loadTagParam("animeLight");
      if (animeLight) {
        var arr = animeLight.split(" ");
        this._animeLight = arr[0];
        this._animeLightOpacity = arr[1] || 255;
        this._animeLightShiftX = arr[2] || 0;
        this._animeLightShiftY = arr[3] || 0;
        this._animeLightZ = arr[4] || TMPlugin.AnimeLight.DefaultZ;
        this._animeLightNone = arr[5] === "1";
      }
    } else {
      this._animeLight = "";
      this._animeLightOpacity = 255;
      this._animeLightShiftX = 0;
      this._animeLightShiftY = 0;
      this._animeLightZ = TMPlugin.AnimeLight.DefaultZ;
      this._animeLightNone = false;
    }
    this.requestAnimeLight();
  };

  //-----------------------------------------------------------------------------
  // Game_Interpreter
  //

  var _Game_Interpreter_pluginCommand =
    Game_Interpreter.prototype.pluginCommand;
  Game_Interpreter.prototype.pluginCommand = function (command, args) {
    _Game_Interpreter_pluginCommand.call(this, command, args);
    if (command === "animeLight") {
      var arr = args.map(this.convertEscapeCharactersTM, this);
      var character = this.character(+arr[0]);
      if (character) {
        character._animeLight = arr[1];
        character._animeLightOpacity = arr[2] || 255;
        character._animeLightShiftX = arr[3] || 0;
        character._animeLightShiftY = arr[4] || 0;
        character._animeLightZ = arr[5] || TMPlugin.AnimeLight.DefaultZ;
        character._animeLightNone = arr[6] === "1";
        character.requestAnimeLight();
      }
    }
  };

  //-----------------------------------------------------------------------------
  // Sprite_Character
  //

  var _Sprite_Character_update = Sprite_Character.prototype.update;
  Sprite_Character.prototype.update = function () {
    _Sprite_Character_update.call(this);
    this.updateAnimeLight();
  };

  Sprite_Character.prototype.updateAnimeLight = function () {
    if (
      this._character.isAnimeLightRequested() ||
      this._animeLight !== this._character._animeLight
    ) {
      this._character.onChangeAnimeLight();
      this._animeLight = this._character._animeLight;
      if (this._animeLight) {
        if (!this._animeLightSprite) {
          this._animeLightSprite = new Sprite_AnimeLight(this);
          this.parent.addChild(this._animeLightSprite);
        }
        this._animeLightSprite.refresh(this._animeLight);
      } else {
        this.parent.removeChild(this._animeLightSprite);
        this._animeLightSprite = null;
      }
    }
  };

  //-----------------------------------------------------------------------------
  // Sprite_AnimeLight
  //

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

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

  Sprite_AnimeLight.prototype.initialize = function (characterSprite) {
    Sprite.prototype.initialize.call(this);
    this._characterSprite = characterSprite;
    this.anchor.x = 0.5;
    this.anchor.y = 0.5;
    this.blendMode = 1;
    this._animeCount = 0;
  };

  Sprite_AnimeLight.prototype.update = function () {
    Sprite.prototype.update.call(this);
    this.x = this._characterSprite.x + this._shiftX;
    this.y = this._characterSprite.y + this._shiftY;
    if (!this._characterSprite._character._animeLightNone) {
      this._animeCount++;
      if (this._animeCount === TMPlugin.AnimeLight.Frames) this._animeCount = 0;
      var n = $gameTemp.animeLightSin(this._animeCount);
      this.scale.set(n, n);
    }
  };

  Sprite_AnimeLight.prototype.refresh = function (fileName) {
    this.bitmap = ImageManager.loadSystem(fileName);
    this.opacity = +this._characterSprite._character._animeLightOpacity;
    this._shiftX = +this._characterSprite._character._animeLightShiftX;
    this._shiftY = +this._characterSprite._character._animeLightShiftY;
    this.x = this._characterSprite.x + this._shiftX;
    this.y = this._characterSprite.y + this._shiftY;
    this.z = +this._characterSprite._character._animeLightZ;
  };
})();


code:
//=============================================================================
// TMVplugin - フキダシループ
// 作者: tomoaky (http://hikimoki.sakura.ne.jp/)
// Version: 1.11
// 最終更新日: 2016/06/20
//=============================================================================

/*:
 * @plugindesc フキダシアイコンをループ表示させます。
 *
 * @author tomoaky (http://hikimoki.sakura.ne.jp/)
 *
 * @help
 * 使い方:
 *   プラグインコマンドまたはメモ欄タグを使ってイベントにフキダシループを設
 *   定すると、指定されたフキダシアイコンが繰り返し表示され続けるようになり
 *   ます。
 *
 *   イベントのメモ欄以外に、実行内容の一番上にある注釈コマンド内でも同様の
 *   タグでフキダシループを設定することができます。メモ欄と注釈の両方にタグ
 *   がある場合は注釈が優先されます。
 *
 *   プラグインコマンドによるフキダシループは、イベントページの切り替わりや
 *   イベントコマンド『イベントの一時消去』などによって解除されます。
 *
 * プラグインコマンド:
 *   setBalloonLoop 2 1
 *   ２番のイベントにフキダシループとしてびっくりアイコンを設定します。イベ
 *   ント番号は -1 ならプレイヤー、0 ならコマンドを実行しているイベントが対
 *   象となります。
 *   表示するアイコンの番号はイベントコマンド『フキダシアイコンの表示』での
 *   並びに対応していて、0 を指定するとフキダシループが解除されます。
 *
 * メモ欄タグ（イベント）:
 *   <balloonLoop:1>
 *   このタグがついているイベントは setBalloonLoop を実行しなくても自動的に
 *   フキダシループが設定されます。数値は表示するアイコン番号です。
 *
 */

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

if (!Imported.TMEventBase) {
  Imported.TMEventBase = true;
  (function () {
    //-----------------------------------------------------------------------------
    // Game_Event
    //

    var _Game_Event_setupPage = Game_Event.prototype.setupPage;
    Game_Event.prototype.setupPage = function () {
      _Game_Event_setupPage.call(this);
      if (this._pageIndex >= 0) {
        this.loadCommentParams();
      }
    };

    Game_Event.prototype.loadCommentParams = function () {
      this._commentParams = {};
      var re = /<([^<>:]+)(:?)([^>]*)>/g;
      var list = this.list();
      for (var i = 0; i < list.length; i++) {
        var command = list[i];
        if ((command && command.code == 108) || command.code == 408) {
          for (;;) {
            var match = re.exec(command.parameters[0]);
            if (match) {
              if (match[2] === ":") {
                this._commentParams[match[1]] = match[3];
              } else {
                this._commentParams[match[1]] = true;
              }
            } else {
              break;
            }
          }
        } else {
          break;
        }
      }
    };

    Game_Event.prototype.loadTagParam = function (paramName) {
      if (this._commentParams[paramName]) {
        return this._commentParams[paramName];
      } else if (this.event().meta[paramName]) {
        return this.event().meta[paramName];
      } else {
        return null;
      }
    };
  })();
}

(function () {
  //-----------------------------------------------------------------------------
  // Game_CharacterBase
  //

  var _Game_CharacterBase_endBalloon = Game_CharacterBase.prototype.endBalloon;
  Game_CharacterBase.prototype.endBalloon = function () {
    _Game_CharacterBase_endBalloon.call(this);
    var balloonLoop = this.balloonLoop();
    if (balloonLoop) {
      this.requestBalloon(balloonLoop);
    }
  };

  Game_CharacterBase.prototype.setBalloonLoop = function (balloonLoop) {
    this._balloonLoop = balloonLoop;
  };

  Game_CharacterBase.prototype.balloonLoop = function () {
    return this._balloonLoop;
  };

  //-----------------------------------------------------------------------------
  // Game_Event
  //

  var _Game_Event_setupPage = Game_Event.prototype.setupPage;
  Game_Event.prototype.setupPage = function () {
    _Game_Event_setupPage.call(this);
    if (this._pageIndex >= 0) {
      var balloonLoop = +this.loadTagParam("balloonLoop");
      if (balloonLoop) {
        this.setBalloonLoop(balloonLoop);
      }
    } else {
      this.setBalloonLoop(0);
    }
  };

  //-----------------------------------------------------------------------------
  // Game_Interpreter
  //

  var _Game_Interpreter_pluginCommand =
    Game_Interpreter.prototype.pluginCommand;
  Game_Interpreter.prototype.pluginCommand = function (command, args) {
    _Game_Interpreter_pluginCommand.call(this, command, args);
    if (command === "setBalloonLoop") {
      var character = this.character(+args[0]);
      if (character) {
        character.setBalloonLoop(+args[1]);
      }
    }
  };

  //-----------------------------------------------------------------------------
  // Sprite_Character
  //

  var _Sprite_Character_endBalloon = Sprite_Character.prototype.endBalloon;
  Sprite_Character.prototype.endBalloon = function () {
    var balloonLoop = this._character.balloonLoop();
    if (balloonLoop) {
      this._balloonSprite.setup(balloonLoop);
    } else {
      _Sprite_Character_endBalloon.call(this);
    }
  };
})();


code:
//=============================================================================
// TMPlugin - バトラー表示拡張
// バージョン: 2.0.0
// 最終更新日: 2016/08/12
// 配布元    : http://hikimoki.sakura.ne.jp/
//-----------------------------------------------------------------------------
// Copyright (c) 2016 tomoaky
// Released under the MIT license.
// http://opensource.org/licenses/mit-license.php
//=============================================================================

/*:
 * @plugindesc エネミーに遠近感や息づかいの表現を追加します。
 *
 * @author tomoaky (http://hikimoki.sakura.ne.jp/)
 *
 * @param baseY
 * @desc 拡大率が等倍になるＹ座標。
 * 初期値: 400
 * @default 400
 *
 * @param breathH
 * @desc 息づかいの大きさ。
 * 初期値: 0.05
 * @default 0.05
 *
 * @param mirrorRate
 * @desc 左右反転の確率。
 * 初期値: 0.4（ 0 ～ 1 ）
 * @default 0.4
 *
 * @param breathStop
 * @desc 行動不能時に息づかいを止める。
 * 初期値: 1（ 0 で無効 / 1 で有効 ）
 * @default 1
 *
 * @param shakeEffect
 * @desc 点滅エフェクトを揺れエフェクトに差し替える。
 * 初期値: 1（ 0 で無効 / 1 で有効 ）
 * @default 1
 *
 * @help
 * 使い方:
 *
 *   このプラグインを導入すると、敵キャラの表示に以下の演出が追加されます。
 *     ・画面の上の方に出現する敵が小さく表示される（遠近感）
 *     ・ゆっくりと拡大縮小を繰り返す（息づかい）
 *     ・ランダムに左右が反転する
 *
 *   サイドビューでは左右反転が無効になります。
 *   敵キャラのメモ欄にタグを書き込むことで、敵キャラごとに演出の強弱を
 *   設定することができます。
 *
 *   プラグインコマンドはありません。
 *
 *   このプラグインは RPGツクールMV Version 1.3.0 で動作確認をしています。
 *
 *
 * メモ欄（敵キャラ）タグ:
 *
 *   <scale:1>
 *     拡大率を個別に設定します、このタグがある敵キャラには遠近感の表現が
 *     適用されません。
 *
 *   <breathH:0.05>
 *     息づかいの大きさを個別に設定します。
 *
 *   <noMirror>
 *     左右反転を禁止します。
 */

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

var TMPlugin = TMPlugin || {};
TMPlugin.BattlerEx = {};
TMPlugin.BattlerEx.Parameters = PluginManager.parameters("TMBattlerEx");
TMPlugin.BattlerEx.BaseY = +(TMPlugin.BattlerEx.Parameters["baseY"] || 400);
TMPlugin.BattlerEx.BreathH = +(
  TMPlugin.BattlerEx.Parameters["breathH"] || 0.05
);
TMPlugin.BattlerEx.MirrorRate = +(
  TMPlugin.BattlerEx.Parameters["mirrorRate"] || 0.4
);
TMPlugin.BattlerEx.BreathStop =
  TMPlugin.BattlerEx.Parameters["breathStop"] === "1";
TMPlugin.BattlerEx.ShakeEffect =
  TMPlugin.BattlerEx.Parameters["shakeEffect"] === "1";

(function () {
  //-----------------------------------------------------------------------------
  // Sprite_Enemy
  //

  var _Sprite_Enemy_initialize = Sprite_Enemy.prototype.initialize;
  Sprite_Enemy.prototype.initialize = function (battler) {
    _Sprite_Enemy_initialize.call(this, battler);
    var r = +(
      battler.enemy().meta.scale ||
      this.y / (TMPlugin.BattlerEx.BaseY * 2) + 0.5
    );
    this._baseScale = new Point(r, r);
    if (
      !$gameSystem.isSideView() &&
      Math.random() < TMPlugin.BattlerEx.MirrorRate &&
      !battler.enemy().meta.noMirror
    ) {
      this._baseScale.x = 0 - r;
      this._stateIconSprite.scale.x = -1;
    }
    this._breathMax = Math.randomInt(90) + 90;
    this._breathCount = Math.randomInt(this._breathMax);
  };

  var _Sprite_Enemy_update = Sprite_Enemy.prototype.update;
  Sprite_Enemy.prototype.update = function () {
    _Sprite_Enemy_update.call(this);
    this.updateScaleEx();
  };

  Sprite_Enemy.prototype.updateScaleEx = function () {
    if (TMPlugin.BattlerEx.BreathStop && !this._enemy.canMove()) return;
    this._breathCount++;
    if (this._breathCount >= this._breathMax) {
      this._breathMax = Math.randomInt(90) + 90;
      this._breathCount = 0;
    }
    var scaleX = this._baseScale.x;
    var scaleY = this._baseScale.y;
    var bh = +(this._enemy.enemy().meta.breathH || TMPlugin.BattlerEx.BreathH);
    scaleY +=
      Math.sin((Math.PI * this._breathCount) / (this._breathMax / 2)) * bh;
    this.scale.set(scaleX, scaleY);
  };

  var _Sprite_Enemy_updateBlink = Sprite_Enemy.prototype.updateBlink;
  Sprite_Enemy.prototype.updateBlink = function () {
    if (TMPlugin.BattlerEx.ShakeEffect) {
      var ed = this._effectDuration;
      this.rotation = ed % 4 < 2 ? ed / 200 : 0 - ed / 200;
    } else {
      _Sprite_Enemy_updateBlink.call(this);
    }
  };
})();


code:
//=============================================================================
// TMPlugin - つちけむり
// バージョン: 2.1.0
// 最終更新日: 2017/08/10
// 配布元    : http://hikimoki.sakura.ne.jp/
//-----------------------------------------------------------------------------
// Copyright (c) 2016 tomoaky
// Released under the MIT license.
// http://opensource.org/licenses/mit-license.php
//=============================================================================

/*:
 * @plugindesc ジャンプとダッシュに土煙のエフェクトを追加します。
 * 任意のタイミングで土煙を表示することもできます。
 *
 * @author tomoaky (http://hikimoki.sakura.ne.jp/)
 *
 * @param dustImage
 * @desc 土煙として利用する画像ファイル名。
 * 初期値: Dust1
 * @default Dust1
 * @require 1
 * @dir img/system/
 * @type file
 *
 * @param maxDusts
 * @type number
 * @desc 同時に表示できるスプライトの数。
 * 初期値: 64
 * @default 64
 *
 * @param jumpDusts
 * @type number
 * @desc ジャンプの着地時に表示するスプライト数。
 * 初期値: 5
 * @default 5
 *
 * @param dashDusts
 * @type number
 * @desc ダッシュ時に表示するスプライト数。
 * 初期値: 3
 * @default 3
 *
 * @help
 * TMPlugin - つちけむり ver2.1.0
 *
 * 使い方:
 *
 *   プラグインと一緒に配布している土煙の画像を img/system フォルダに
 *   保存してください。ファイル名は Dust1.png となっています。
 *   ファイル名を変更しなければならない場合はプラグインパラメータの
 *   dustImage も一緒に変更してください。
 *
 *   プラグインを有効にすると、キャラクターがジャンプ後に着地したタイミング
 *   で土煙が表示されるようになります。
 *   また、プレイヤーがダッシュ（shiftキー押しながら or クリック）で移動する
 *   ときにも土煙が表示されます。
 *
 *   プラグインコマンドを使用することによって任意のタイミングで指定した座標
 *   に土煙を表示することもできます。
 *
 *   このプラグインは RPGツクールMV Version 1.5.0 で動作確認をしています。
 *
 *   このプラグインはMITライセンスのもとに配布しています、商用利用、
 *   改造、再配布など、自由にお使いいただけます。
 *
 *
 * プラグインコマンド:
 *
 *   setDustXy 5 8
 *     指定した座標に土煙を表示します。数値はイベントコマンド『場所移動』で
 *     利用する座標と同じです、画面のドット数ではありません。
 *     setDustXy 5.5 8 のように小数点以下を入力することによって座標(5, 8)と
 *     座標(6, 8)の中間を指定することもできます。
 *
 *   setDustXy 5 8 3
 *     指定した座標に土煙を 3 つ表示します。設定が省略された場合は 1 つしか
 *     表示されません。
 *
 *   setDustXy 5 8 1 0.04
 *     表示する土煙の移動速度を設定します。設定が省略された場合は 0.02 が
 *     適用されます。
 *
 *   setDustXy 5 8 1 0.02 3.14
 *     表示する土煙の移動方向を限定します。数値は右を 0 として、時計回りに
 *     6.28 で 1 周となります。
 *     上記のように3.14を指定した場合は土煙が左に向かって少し移動します。
 *
 *   setDustEvent 3
 *     イベント 3 番の足元に土煙を表示します。0 を指定した場合はコマンドを
 *     実行しているイベント自体が、-1 を指定した場合はプレイヤーが対象に
 *     なります。
 *     setDustXy と同様に土煙の数や移動方向、移動速度も指定できます。
 *     イベント番号に続けて、土煙の数、移動速度、移動方向の順に数値を
 *     足していってください。
 *
 *   setJumpDusts 5
 *     ジャンプの着地時に表示するスプライト数を指定した値に変更します。
 *
 *   setDashDusts 3
 *     ダッシュ時に表示するスプライト数を指定した値に変更します。
 *
 *   stopDust
 *     新しい土煙が表示できなくなります。
 *     すでに表示されている土煙には影響しません。
 *
 *   startDust
 *     stopDust の効果を解除し、新しい土煙を表示できるようにします。
 *
 *   コマンドに続くパラメータは、途中のものだけを省略することができません。
 *   移動方向を指定する場合は個数と移動速度も指定する必要があります。
 *
 *
 * プラグインパラメータ補足:
 *
 *   dustImage
 *     土煙の画像ファイル名を拡張子抜きで指定します。ファイルは img/system
 *     フォルダに保存してください。
 *
 *   maxDusts
 *     このパラメータに指定した数を超える土煙を同時に表示しようとした場合は
 *     何も表示されず、プラグインコマンドは無視されます。
 *     数値を大きくすればたくさんの土煙を表示することができますが、それだけ
 *     処理が重くなり、低スペック環境ではFPSが低下する原因になります。
 *
 *   jumpDusts
 *     キャラクターをイベントコマンド『移動ルートの設定』などでジャンプ
 *     させた後、着地の際に表示する土煙の数です。数値の分だけ土煙が重なり、
 *     より濃い土煙になります。
 *     0 を指定すれば着地時の土煙は表示されなくなります。
 *
 *   dashDusts
 *     プレイヤーがダッシュで移動した際に表示する土煙の数です。数値の分だけ
 *     土煙が重なり、より濃い土煙になります。
 *     0 を指定すればダッシュ時の土煙は表示されなくなります。
 *
 */

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

var TMPlugin = TMPlugin || {};
TMPlugin.CloudDust = {};
TMPlugin.CloudDust.Parameters = PluginManager.parameters("TMCloudDust");
TMPlugin.CloudDust.DustImage =
  TMPlugin.CloudDust.Parameters["dustImage"] || Dust1;
TMPlugin.CloudDust.MaxDusts = +(
  TMPlugin.CloudDust.Parameters["maxDusts"] || 64
);
TMPlugin.CloudDust.JumpDusts = +(
  TMPlugin.CloudDust.Parameters["jumpDusts"] || 5
);
TMPlugin.CloudDust.DashDusts = +(
  TMPlugin.CloudDust.Parameters["dashDusts"] || 3
);

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

if (!TMPlugin.InterpreterBase) {
  TMPlugin.InterpreterBase = true;
  (function () {
    Game_Interpreter.prototype.convertEscapeCharactersTM = function (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]));
        }.bind(this)
      );
      text = text.replace(
        /\x1bV\[(\d+)\]/gi,
        function () {
          return $gameVariables.value(parseInt(arguments[1]));
        }.bind(this)
      );
      text = text.replace(
        /\x1bN\[(\d+)\]/gi,
        function () {
          return this.actorNameTM(parseInt(arguments[1]));
        }.bind(this)
      );
      text = text.replace(
        /\x1bP\[(\d+)\]/gi,
        function () {
          return this.partyMemberNameTM(parseInt(arguments[1]));
        }.bind(this)
      );
      text = text.replace(/\x1bG/gi, TextManager.currencyUnit);
      return text;
    };

    Game_Interpreter.prototype.actorNameTM = function (n) {
      var actor = n >= 1 ? $gameActors.actor(n) : null;
      return actor ? actor.name() : "";
    };

    Game_Interpreter.prototype.partyMemberNameTM = function (n) {
      var actor = n >= 1 ? $gameParty.members()[n - 1] : null;
      return actor ? actor.name() : "";
    };
  })();
} // TMPlugin.InterpreterBase

(function () {
  //-----------------------------------------------------------------------------
  // Game_System
  //

  Game_System.prototype.jumpDusts = function () {
    if (this._jumpDusts != null) return this._jumpDusts;
    return TMPlugin.CloudDust.JumpDusts;
  };

  Game_System.prototype.dashDusts = function () {
    if (this._dashDusts != null) return this._dashDusts;
    return TMPlugin.CloudDust.DashDusts;
  };

  Game_System.prototype.setJumpDusts = function (n) {
    this._jumpDusts = n;
  };

  Game_System.prototype.setDashDusts = function (n) {
    this._dashDusts = n;
  };

  Game_System.prototype.isDustEnabled = function () {
    if (this._dustEnabled == null) this._dustEnabled = true;
    return this._dustEnabled;
  };

  Game_System.prototype.enableDust = function () {
    this._dustEnabled = true;
  };

  Game_System.prototype.disableDust = function () {
    this._dustEnabled = false;
  };

  //-----------------------------------------------------------------------------
  // Game_Map
  //

  var _Game_Map_setup = Game_Map.prototype.setup;
  Game_Map.prototype.setup = function (mapId) {
    _Game_Map_setup.call(this, mapId);
    this.setupCloudDusts();
  };

  Game_Map.prototype.setupCloudDusts = function () {
    this._cloudDusts = [];
    for (var i = 0; i < TMPlugin.CloudDust.MaxDusts; i++) {
      this._cloudDusts.push(new Game_CloudDust());
    }
  };

  Game_Map.prototype.cloudDusts = function () {
    return this._cloudDusts;
  };

  Game_Map.prototype.addCloudDust = function (x, y, speed, radian) {
    if (!$gameSystem.isDustEnabled()) return;
    for (var i = 0; i < TMPlugin.CloudDust.MaxDusts; i++) {
      if (!this._cloudDusts[i].exists()) {
        this._cloudDusts[i].setup(x, y, speed, radian);
        break;
      }
    }
  };

  var _Game_Map_update = Game_Map.prototype.update;
  Game_Map.prototype.update = function (sceneActive) {
    _Game_Map_update.call(this, sceneActive);
    this.updateCloudDusts();
  };

  Game_Map.prototype.updateCloudDusts = function () {
    this.cloudDusts().forEach(function (cloudDust) {
      cloudDust.update();
    });
  };

  //-----------------------------------------------------------------------------
  // Game_CloudDust
  //

  Game_CloudDust.prototype.initialize = function () {
    this._x = 0;
    this._y = 0;
    this._count = 0;
    this._scale = new Point(1.0, 1.0);
  };

  Game_CloudDust.prototype.setup = function (x, y, speed, radian) {
    this._x = +x;
    this._y = +y;
    this._opacity = 180;
    this._count = 30;
    if (radian != null) {
      radian = +radian + Math.random() * 1.5 - 0.75;
    } else {
      radian = Math.random() * Math.PI * 2;
    }
    speed = +(speed || 0.02);
    this._vx = Math.cos(radian) * speed;
    this._vy = Math.sin(radian) * speed;
    this._rotation = radian;
    this._scale.x = 1.0;
    this._scale.y = 1.0;
  };

  Game_CloudDust.prototype.screenX = function () {
    var tw = $gameMap.tileWidth();
    return Math.round($gameMap.adjustX(this._x) * tw);
  };

  Game_CloudDust.prototype.screenY = function () {
    var th = $gameMap.tileHeight();
    return Math.round($gameMap.adjustY(this._y) * th);
  };

  Game_CloudDust.prototype.opacity = function () {
    return this._opacity;
  };

  Game_CloudDust.prototype.rotation = function () {
    return this._rotation;
  };

  Game_CloudDust.prototype.scale = function () {
    return this._scale;
  };

  Game_CloudDust.prototype.exists = function () {
    return this._count > 0;
  };

  Game_CloudDust.prototype.update = function () {
    if (this._count > 0) {
      this._count--;
      this._x += this._vx;
      this._y += this._vy;
      this._vy -= 0.0008;
      this._opacity -= 6;
      this._scale.x += 0.02;
      this._scale.y += 0.02;
    }
  };

  //-----------------------------------------------------------------------------
  // Game_CharacterBase
  //

  Game_CharacterBase.prototype.addCloudDust = function (speed, radian) {
    $gameMap.addCloudDust(this._realX + 0.5, this._realY + 1.0, speed, radian);
  };

  var _Game_CharacterBase_updateJump = Game_CharacterBase.prototype.updateJump;
  Game_CharacterBase.prototype.updateJump = function () {
    _Game_CharacterBase_updateJump.call(this);
    if (this._jumpCount === 0) {
      for (var i = 0; i < $gameSystem.jumpDusts(); i++) {
        this.addCloudDust(0.02, (i % 2) * Math.PI);
      }
    }
  };

  //-----------------------------------------------------------------------------
  // Game_Player
  //

  var _Game_Player_moveStraight = Game_Player.prototype.moveStraight;
  Game_Player.prototype.moveStraight = function (d) {
    var n = $gameSystem.dashDusts();
    if (n > 0) {
      if (this.isDashing() && this.canPass(this.x, this.y, d)) {
        if (d === 2) {
          var radian = Math.PI * 1.5;
        } else if (d === 4) {
          var radian = 0;
        } else if (d === 6) {
          var radian = Math.PI;
        } else {
          var radian = Math.PI / 2;
        }
        for (var i = 0; i < n; i++) {
          this.addCloudDust(0.03, radian);
        }
      }
    }
    _Game_Player_moveStraight.call(this, d);
  };

  //-----------------------------------------------------------------------------
  // Game_Interpreter
  //

  var _Game_Interpreter_pluginCommand =
    Game_Interpreter.prototype.pluginCommand;
  Game_Interpreter.prototype.pluginCommand = function (command, args) {
    _Game_Interpreter_pluginCommand.call(this, command, args);
    if (command === "setDustXy") {
      var arr = args.map(this.convertEscapeCharactersTM, this);
      var n = parseInt(arr[2] || 1);
      for (var i = 0; i < n; i++) {
        $gameMap.addCloudDust(arr[0], arr[1], arr[3], arr[4]);
      }
    } else if (command === "setDustEvent") {
      var arr = args.map(this.convertEscapeCharactersTM, this);
      var character = this.character(+arr[0]);
      if (character) {
        var n = parseInt(arr[1] || 1);
        for (var i = 0; i < n; i++) {
          character.addCloudDust(arr[2], arr[3]);
        }
      }
    } else if (command === "setJumpDusts") {
      var arr = args.map(this.convertEscapeCharactersTM, this);
      $gameSystem.setJumpDusts(+arr[0]);
    } else if (command === "setDashDusts") {
      var arr = args.map(this.convertEscapeCharactersTM, this);
      $gameSystem.setDashDusts(+arr[0]);
    } else if (command === "stopDust") {
      $gameSystem.disableDust();
    } else if (command === "startDust") {
      $gameSystem.enableDust();
    }
  };

  //-----------------------------------------------------------------------------
  // Sprite_CloudDust
  //

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

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

  Sprite_CloudDust.prototype.initialize = function (cloudDust) {
    Sprite.prototype.initialize.call(this);
    this._cloudDust = cloudDust;
    this.scale = this._cloudDust.scale();
    this.visible = false;
    this.createBitmap();
  };

  Sprite_CloudDust.prototype.update = function () {
    Sprite.prototype.update.call(this);
    if (this._cloudDust.exists()) {
      this.visible = true;
      this.x = this._cloudDust.screenX();
      this.y = this._cloudDust.screenY();
      this.opacity = this._cloudDust.opacity();
      this.rotation = this._cloudDust.rotation();
    } else {
      this.visible = false;
    }
  };

  Sprite_CloudDust.prototype.createBitmap = function () {
    this.bitmap = ImageManager.loadSystem(TMPlugin.CloudDust.DustImage);
    this.anchor.x = 0.5;
    this.anchor.y = 0.5;
    this.z = 3;
  };

  //-----------------------------------------------------------------------------
  // Spriteset_Map
  //

  var _Spriteset_Map_createLowerLayer =
    Spriteset_Map.prototype.createLowerLayer;
  Spriteset_Map.prototype.createLowerLayer = function () {
    _Spriteset_Map_createLowerLayer.call(this);
    this.createCloudDust();
  };

  Spriteset_Map.prototype.createCloudDust = function () {
    this._cloudDustSprites = [];
    $gameMap.cloudDusts().forEach(function (cloudDust) {
      this._cloudDustSprites.push(new Sprite_CloudDust(cloudDust));
    }, this);
    for (var i = 0; i < this._cloudDustSprites.length; i++) {
      this._tilemap.addChild(this._cloudDustSprites[i]);
    }
  };
})();


code:
//=============================================================================
// TMPlugin - 装備スロット拡張
// バージョン: 1.0.0
// 最終更新日: 2017/02/09
// 配布元    : http://hikimoki.sakura.ne.jp/
//-----------------------------------------------------------------------------
// Copyright (c) 2016 tomoaky
// Released under the MIT license.
// http://opensource.org/licenses/mit-license.php
//=============================================================================

/*:
 * @plugindesc アクターごとに部位設定を自由に変更できるようにします。
 *
 * @author tomoaky (http://hikimoki.sakura.ne.jp/)
 *
 * @help
 * TMPlugin - 装備スロット拡張 ver1.0.0
 *
 * 使い方:
 *
 *   アクターのメモ欄に <equipSlotEx:1 2 5 5 5> のようなタグを書き込んで
 *   ください。この例では武器、盾、装飾品３つという部位構成になります。
 *   タグがなければ通常の部位構成が採用されます。また、二刀流が設定されて
 *   いる場合は２つ目の部位が武器に置き換わります。
 *
 *
 * プラグインコマンド:
 *
 *   changeEquipSlotEx 1 3 10
 *   アクター１番の装備スロット 3 番（一番上を 0 番とする）に 10 番の装備品を
 *   装備します。装備品が武器か防具かは指定したスロットによって自動的に判断
 *   されます。
 *
 *   forceChangeEquipSlotEx 1 3 10
 *   changeEquipSlotEx とは違い、パーティが対象となる装備品を所持している必要
 *   がありません。
 *
 *   clearEquipmentsSlotEx 1
 *   アクター 1 番の装備をすべてはずします。
 *
 *
 * 注意事項:
 *
 *   データベースの初期装備やイベントコマンド『装備の変更』など、エディタ側は
 *   スロット拡張に対応していないため、イベント処理としてアクターの装備を変更
 *   したい場合はプラグインコマンドを使ってください。
 */

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

var TMPlugin = TMPlugin || {};

if (!TMPlugin.InterpreterBase) {
  TMPlugin.InterpreterBase = true;
  (function () {
    Game_Interpreter.prototype.convertEscapeCharactersTM = function (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]));
        }.bind(this)
      );
      text = text.replace(
        /\x1bV\[(\d+)\]/gi,
        function () {
          return $gameVariables.value(parseInt(arguments[1]));
        }.bind(this)
      );
      text = text.replace(
        /\x1bN\[(\d+)\]/gi,
        function () {
          return this.actorNameTM(parseInt(arguments[1]));
        }.bind(this)
      );
      text = text.replace(
        /\x1bP\[(\d+)\]/gi,
        function () {
          return this.partyMemberNameTM(parseInt(arguments[1]));
        }.bind(this)
      );
      text = text.replace(/\x1bG/gi, TextManager.currencyUnit);
      return text;
    };

    Game_Interpreter.prototype.actorNameTM = function (n) {
      var actor = n >= 1 ? $gameActors.actor(n) : null;
      return actor ? actor.name() : "";
    };

    Game_Interpreter.prototype.partyMemberNameTM = function (n) {
      var actor = n >= 1 ? $gameParty.members()[n - 1] : null;
      return actor ? actor.name() : "";
    };
  })();
} // TMPlugin.InterpreterBase

(function () {
  //-----------------------------------------------------------------------------
  // Game_Actor
  //

  var _Game_Actor_equipSlots = Game_Actor.prototype.equipSlots;
  Game_Actor.prototype.equipSlots = function () {
    var equipSlotEx = this.actor().meta.equipSlotEx;
    if (equipSlotEx) {
      var slots = equipSlotEx.split(" ").map(Number);
      if (slots.length >= 2 && this.isDualWield()) slots[1] = 1;
      return slots;
    } else {
      return _Game_Actor_equipSlots.call(this);
    }
  };

  //-----------------------------------------------------------------------------
  // Game_Interpreter
  //

  var _Game_Interpreter_pluginCommand =
    Game_Interpreter.prototype.pluginCommand;
  Game_Interpreter.prototype.pluginCommand = function (command, args) {
    _Game_Interpreter_pluginCommand.call(this, command, args);
    if (command === "changeEquipSlotEx") {
      var arr = args.map(this.convertEscapeCharactersTM, this);
      var actor = $gameActors.actor(+arr[0]);
      if (actor) {
        var item =
          +arr[1] === 0 || (+arr[1] === 1 && actor.isDualWield())
            ? $dataWeapons[+arr[2]]
            : $dataArmors[+arr[2]];
        actor.changeEquip(+arr[1], item);
      }
    } else if (command === "forceChangeEquipSlotEx") {
      var arr = args.map(this.convertEscapeCharactersTM, this);
      var actor = $gameActors.actor(+arr[0]);
      if (actor) {
        var item =
          +arr[1] === 0 || (+arr[1] === 1 && actor.isDualWield())
            ? $dataWeapons[+arr[2]]
            : $dataArmors[+arr[2]];
        actor.forceChangeEquip(+arr[1], item);
      }
    } else if (command === "clearEquipmentsSlotEx") {
      var arr = args.map(this.convertEscapeCharactersTM, this);
      var actor = $gameActors.actor(+arr[0]);
      if (actor) actor.clearEquipments();
    }
  };
})();


code:
//=============================================================================
// TMPlugin - アイテムカテゴリ拡張
// バージョン: 1.0.1
// 最終更新日: 2018/05/01
// 配布元    : http://hikimoki.sakura.ne.jp/
//-----------------------------------------------------------------------------
// Copyright (c) 2017 tomoaky
// Released under the MIT license.
// http://opensource.org/licenses/mit-license.php
//=============================================================================

/*:
 * @target MZ MV
 * @url https://raw.githubusercontent.com/munokura/tomoaky-MV-plugins/master/TMItemCategoryEx.js
 * @author tomoaky (https://twitter.com/tomoaky/)
 * @plugindesc アイテムカテゴリの追加、削除をおこないます。
 *
 * @param categoryList
 * @text アイテムカテゴリ一覧
 * @desc アイテムカテゴリの一覧 (詳しくはヘルプにて)
 * 初期値: item weapon armor keyItem
 * @default item weapon armor keyItem
 *
 * @help
 * TMPlugin - アイテムカテゴリ拡張 ver1.0.1
 *
 * 使い方:
 *
 *   プラグインパラメータでアイテムカテゴリを設定してください。
 *   item, weapon, armor, keyItem は アイテム, 武器, 防具, 大事なもの に
 *   対応しています。
 *   たとえばアイテムと武器の間に 書物 というカテゴリを追加したい場合は
 *   item 書物 weapon armor keyItem
 *   というような設定になります。
 *
 *   追加したカテゴリは itemCategory タグを使ってアイテムに設定することが
 *   できます。タグを設定したアイテムは通常のアイテムカテゴリには
 *   表示されなくなります。
 *
 *   また、不要なカテゴリを削除することもできます。
 *   カテゴリが 1 個しかない場合はカテゴリ選択の処理自体が省略されます。
 *
 *   プラグインコマンドはありません。
 *
 *
 * メモ欄タグ（アイテム）:
 *
 *   <itemCategory:書物>
 *     このアイテムのカテゴリを 書物 に設定します。
 *     プラグインパラメータ categoryList に 書物 というカテゴリが
 *     あればそこに表示されます。
 *
 *
 * 利用規約:
 *   MITライセンスです。
 *   https://ja.osdn.net/projects/opensource/wiki/licenses%2FMIT_license
 *   作者に無断で改変、再配布が可能で、
 *   利用形態（商用、18禁利用等）についても制限はありません。
 */

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

(function () {
  "use strict";

  var parameters = PluginManager.parameters("TMItemCategoryEx");
  var categoryList = (
    parameters["categoryList"] || "item weapon armor keyItem"
  ).split(" ");

  //-----------------------------------------------------------------------------
  // Window_ItemCategory
  //

  Window_ItemCategory.prototype.maxCols = function () {
    return categoryList.length;
  };

  Window_ItemCategory.prototype.makeCommandList = function () {
    var symbol;
    for (var i = 0; i < this.maxCols(); i++) {
      symbol = categoryList[i];
      if (symbol === "item") {
        this.addCommand(TextManager.item, "item");
      } else if (symbol === "weapon") {
        this.addCommand(TextManager.weapon, "weapon");
      } else if (symbol === "armor") {
        this.addCommand(TextManager.armor, "armor");
      } else if (symbol === "keyItem") {
        this.addCommand(TextManager.keyItem, "keyItem");
      } else {
        this.addCommand(symbol, symbol);
      }
    }
  };

  //-----------------------------------------------------------------------------
  // Window_ItemList
  //

  var _Window_ItemList_includes = Window_ItemList.prototype.includes;
  Window_ItemList.prototype.includes = function (item) {
    if (item && item.meta.itemCategory)
      return this._category === item.meta.itemCategory;
    return _Window_ItemList_includes.call(this, item);
  };

  //-----------------------------------------------------------------------------
  // Scene_Item
  //

  var _Scene_Item_create = Scene_Item.prototype.create;
  Scene_Item.prototype.create = function () {
    _Scene_Item_create.call(this);
    if (categoryList.length === 1) {
      this._categoryWindow.deactivate();
      this._categoryWindow.hide();
      this._itemWindow.move(
        this._itemWindow.x,
        this._categoryWindow.y,
        this._itemWindow.width,
        this._itemWindow.height + this._categoryWindow.height
      );
      this._itemWindow.setHandler("cancel", this.popScene.bind(this));
      this._itemWindow.setCategory(this._categoryWindow.currentSymbol());
      this.onCategoryOk();
    }
  };

  //-----------------------------------------------------------------------------
  // Scene_Shop
  //

  var _Scene_Shop_create = Scene_Shop.prototype.create;
  Scene_Shop.prototype.create = function () {
    _Scene_Shop_create.call(this);
    if (categoryList.length === 1) {
      this._sellWindow.move(
        this._sellWindow.x,
        this._categoryWindow.y,
        this._sellWindow.width,
        this._sellWindow.height + this._categoryWindow.height
      );
      this._sellWindow.setCategory(this._categoryWindow.currentSymbol());
    }
  };

  var _Scene_Shop_commandSell = Scene_Shop.prototype.commandSell;
  Scene_Shop.prototype.commandSell = function () {
    _Scene_Shop_commandSell.call(this);
    if (categoryList.length === 1) {
      this._sellWindow.activate();
      this._statusWindow.hide();
      this._sellWindow.select(0);
      this._categoryWindow.hide();
    }
  };

  var _Scene_Shop_onSellCancel = Scene_Shop.prototype.onSellCancel;
  Scene_Shop.prototype.onSellCancel = function () {
    _Scene_Shop_onSellCancel.call(this);
    if (categoryList.length === 1) {
      this.onCategoryCancel();
    }
  };
})();


code:
//=============================================================================
// TMPlugin - メニューバトラー
// バージョン: 0.1.1b
// 最終更新日: 2020/04/06
// 配布元　　: https://hikimoki.sakura.ne.jp/
//-----------------------------------------------------------------------------
// Copyright (c) 2020 tomoaky
// Released under the MIT license.
// http://opensource.org/licenses/mit-license.php
//=============================================================================

/*:
 * @plugindesc メニュー画面の顔画像をサイドビューバトラーに変更します。
 *
 * @author tomoaky (https://hikimoki.sakura.ne.jp/)
 *
 * @param faceImageRule
 * @type select
 * @option 表示しない
 * @value 0
 * @option サイドビュー画像がない場合のみ表示
 * @value 1
 * @option 表示する
 * @value 2
 * @desc 顔画像の表示条件
 * @default 0
 *
 * @param shiftBattlerX
 * @type number
 * @min -9999
 * @desc サイドビュー画像を横方向にずらす量
 * 初期値: 0
 * @default 0
 *
 * @param shiftBattlerY
 * @type number
 * @min -9999
 * @desc サイドビュー画像を縦方向にずらす量
 * 初期値: -24
 * @default -24
 *
 * @help
 * TMPlugin - メニューバトラー ver0.1.1b
 *
 * 使い方:
 *
 * 　データベースのシステムタブにある『サイドビュー戦闘を使用』に
 * 　チェックを入れた状態でこのプラグインを導入すると
 * 　メニュー画面の顔画像がサイドビューバトラーに変わります。
 * 　プラグインパラメータで顔画像の表示条件を設定できます。
 *
 *   このプラグインは RPGツクールMV Version 1.6.2 で動作確認をしています。
 *
 *   このプラグインはMITライセンスのもとに配布しています、商用利用、
 *   改造、再配布など、自由にお使いいただけます。
 */

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

(function () {
  var parameters = PluginManager.parameters("TMMenuBattler");
  var faceImageRule = +(parameters["faceImageRule"] || 0);
  var shiftBattlerX = +(parameters["shiftBattlerX"] || 0);
  var shiftBattlerY = +(parameters["shiftBattlerY"] || 0);

  //-----------------------------------------------------------------------------
  // Window_Base
  //

  Window_Base.prototype.drawMenuBattler = function (
    actor,
    x,
    y,
    width,
    height
  ) {
    if (this.needsFaceDraw(actor)) {
      this.drawFace(actor.faceName(), actor.faceIndex(), x, y, width, height);
    }
    width = Math.floor((width || Window_Base._faceWidth) / 2);
    height = height || Window_Base._faceHeight;
    this.menuBattlerSprite(x + width, y + height).setBattler(actor);
  };

  Window_Base.prototype.needsFaceDraw = function (actor) {
    return (faceImageRule === 1 && !actor.battlerName()) || faceImageRule === 2;
  };

  Window_Base.prototype.menuBattlerSprite = function (x, y) {
    if (!this._menuBattlerSprite) {
      this._menuBattlerSprite = new Sprite_MenuBattler();
      x += this.padding + shiftBattlerX;
      y += this.padding + shiftBattlerY;
      this._menuBattlerSprite.setHome(x, y);
      this.addChild(this._menuBattlerSprite);
    }
    return this._menuBattlerSprite;
  };

  //-----------------------------------------------------------------------------
  // Window_MenuStatus
  //

  Window_MenuStatus.prototype.menuBattlerSprite = function (index) {
    if (!this._menuBattlerSprites) {
      this._menuBattlerSprites = [];
    }
    var i = index - this.topIndex();
    if (!this._menuBattlerSprites[i]) {
      this._menuBattlerSprites[i] = new Sprite_MenuBattler();
      var rect = this.itemRect(index);
      var x =
        rect.x +
        1 +
        Math.floor(Window_Base._faceWidth / 2) +
        this.padding +
        shiftBattlerX;
      var y =
        rect.y + 1 + Window_Base._faceHeight + this.padding + shiftBattlerY;
      this._menuBattlerSprites[i].setHome(x, y);
      this.addChild(this._menuBattlerSprites[i]);
    }
    return this._menuBattlerSprites[i];
  };

  var _Window_MenuStatus_drawItemImage =
    Window_MenuStatus.prototype.drawItemImage;
  Window_MenuStatus.prototype.drawItemImage = function (index) {
    var actor = $gameParty.members()[index];
    if (this.needsFaceDraw(actor)) {
      _Window_MenuStatus_drawItemImage.call(this, index);
    }
    this.menuBattlerSprite(index).setBattler(actor);
  };

  //-----------------------------------------------------------------------------
  // Window_SkillStatus
  //

  Window_SkillStatus.prototype.drawActorFace = function (
    actor,
    x,
    y,
    width,
    height
  ) {
    this.drawMenuBattler(actor, x, y, width, height);
  };

  //-----------------------------------------------------------------------------
  // Window_Status
  //

  Window_Status.prototype.drawActorFace = function (
    actor,
    x,
    y,
    width,
    height
  ) {
    this.drawMenuBattler(actor, x, y, width, height);
  };

  //-----------------------------------------------------------------------------
  // Sprite_MenuBattler
  //

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

  Sprite_MenuBattler.prototype = Object.create(Sprite_Actor.prototype);
  Sprite_MenuBattler.prototype.constructor = Sprite_MenuBattler;

  Sprite_MenuBattler.prototype.setBattler = function (battler) {
    Sprite_Battler.prototype.setBattler.call(this, battler);
    var changed = battler !== this._actor;
    if (changed) {
      this._actor = battler;
      this.refreshMotion();
      this._stateSprite.setup(battler);
    }
  };

  Sprite_MenuBattler.prototype.updateVisibility = function () {
    var actor = this._actor;
    this.visible = actor && actor.battlerName();
  };

  Sprite_MenuBattler.prototype.startMove = function (x, y, duration) {};

  Sprite_Actor.prototype.refreshMotion = function () {
    var actor = this._actor;
    if (actor) {
      var stateMotion = actor.stateMotionIndex();
      if (stateMotion === 3) {
        this.startMotion("dead");
      } else if (stateMotion === 2) {
        this.startMotion("sleep");
      } else if (stateMotion === 1) {
        this.startMotion("abnormal");
      } else if (actor.isDying()) {
        this.startMotion("dying");
      } else if (actor.isBattleMember()) {
        this.startMotion("walk");
      } else {
        this.startMotion("wait");
      }
    }
  };
})();