code:
//=============================================================================
// TkoolMV_PluginCommandBook.js
// https://github.com/AlecYawata/TkoolMV_PluginCommandBook
//=============================================================================
//
// Copyright (c) 2015 Alec
// This software is released under the MIT License.
// http://opensource.org/licenses/mit-license.php
//
//=============================================================================
/*:
 * @plugindesc プラグインコマンド集
 * @author 有志の皆さん
 *
 * @param 制御文字の拡張
 * @desc このプラグインで使えるパラメータの制御文字を
 * 通常のメッセージなどで使用できるようにするか(はい/いいえ)
 * Default: はい
 * @default はい
 *
 * @param スクリプトに制御文字適用
 * @desc スクリプト実行時に制御文字を使用できるようにするか(はい/いいえ)
 * Default: いいえ
 * @default いいえ
 *
 * @help
 *  Copyright (c) 2015 Alec
 *  This software is released under the MIT License.
 *  http://opensource.org/licenses/mit-license.php
 *
 * このプラグインは有志によるプラグインコマンド集です。
 * 商用利用、年齢制限のあるゲームへの使用、改変が可能です。
 * クレジットは不要です。
 *
 * ■使い方
 * イベントのコマンド追加からプラグインコマンドを選択し、
 * 以下のプラグインコマンドから好きなモノを選んで入力して下さい。
 *
 * ■パラメータについて
 * プラグインコマンドの右に空白をつけてパラメータを追記することができます。
 * パラメータは数字、英数字、日本語、記号など以外にも以下のような制御文字が使えます。
 * （各数字部分には全角数字も使えます）
 * \V[n] 変数n番目の値に置き換えられます
 * \N[n] アクターn番の名前に置き換えられます
 * \P[n] パーティメンバーn番の値に置き換えられます
 * \G 　　通貨単位に置き換えられます
 * \In[n] アイテムn番の名前に置き換えられます
 * \Ip[n] アイテムn番の価格に置き換えられます
 * \Sn[n] スキルn番の名前に置き換えられます
 * \Js[X]\Js XをJavaScriptとして評価した値に置き換えられます
 *
 * その他使用可能な制御文字や、\Js[X]\Jsで使えるスクリプトについては、下記シートを参照してください。
 * https://docs.google.com/spreadsheets/d/1rOIzDuhLC6IqJPEFciYOmXWL_O7X9-hMValMs7DpWCk/
 *
 * ■プラグインコマンド
 *
 * ===========================================================================
 * 「名前の変更」
 *  主人公の名前を変更する
 *  製作者 Alec
 *
 *  使用例
 *  名前の変更 1 ライアン　　（アクター0001の名前をライアンに変更
 *  名前の変更 2 \V[1]　　　（アクター0002の名前を変数0001の内容に変更
 *
 * ===========================================================================
 * 呼び出し元アイテム取得
 *  コモンイベントを呼び出したアイテムのIDを変数に入れる
 *  製作者 Alec
 *
 *  使用例
 *  呼び出し元アイテム取得 1　　（変数0001にコモンイベントを呼び出したアイテムIDを入れる
 *
 * ===========================================================================
 * 呼び出し元スキル取得
 *  コモンイベントを呼び出したスキルのIDを変数に入れる
 *  製作者 Alec
 *
 *  使用例
 *  呼び出し元スキル取得 1　　（変数0001にコモンイベントを呼び出したスキルIDを入れる
 *
 * ===========================================================================
 * レベルの変更
 *  アクターのレベルを変更します。増減ではなく変更後のレベルを指定できます。
 *  製作者 Alec
 *
 *  パラメータ
 *  　アクターのID（もし0なら全員）
 *    変更後のレベル
 *    レベルアップをメッセージで表示するかどうか（表示・非表示）
 *
 *  使用例
 *  レベルの変更 1 50 表示　　（アクター0001のレベルを50に変更
 *  レベルの変更 0 10 非表示　（仲間全員のレベルを10に変更、レベルアップは表示しない
 *
 * ===========================================================================
 * バイブレーション(English:Vibration)
 *  実行中のAndroid端末を振動させます。
 *  製作者 トリアコンタン
 *
 *  パラメータ
 *  　振動するフレーム数(1/60秒単位)
 *    振動が完了するまでウェイト(ウェイトあり or ウェイトなし)
 *    　デフォルトは「ウェイトなし」
 *
 *  使用例
 *  バイブレーション 60 ウェイトあり
 *  Vibration 120
 * ===========================================================================
 * 指定位置の通行情報取得(English:Get_Location_Pass)
 *  指定した座標のマップ通行情報を取得して、変数に格納します。
 *  製作者 トリアコンタン
 *
 *  以下の法則に従って格納されます。
 *  上方向へ通行可能：千の位が 1、上方向へ通行不可能：千の位が 0
 *  右方向へ通行可能：百の位が 1、右方向へ通行不可能：百の位が 0
 *  下方向へ通行可能：十の位が 1、下方向へ通行不可能：十の位が 0
 *  左方向へ通行可能：一の位が 1、左方向へ通行不可能：一の位が 0
 *
 *  パラメータ
 *  　結果を格納する変数の番号
 *    X座標
 *    Y座標
 *
 *  使用例
 *  指定位置の通行情報取得 1 17 13
 *  Get_Location_Pass 2 \V[1] \V[2]
 * ===========================================================================
 * 変数の初期化(English:Init_Variables)
 *  全ての変数を初期化します。（例外指定可能）
 *  製作者 トリアコンタン
 *
 *  パラメータ
 *  　初期化したくない変数番号（半角スペースで区切って複数指定可能）
 *
 *  使用例
 *  変数の初期化
 *  Init_Variables 1 2 \V[3]
 * ===========================================================================
 * スイッチの初期化(English:Init_Switches)
 *  全てのスイッチを初期化します。（例外指定可能）
 *  製作者 トリアコンタン
 *
 *  パラメータ
 *  　初期化したくないスイッチ番号（半角スペースで区切って複数指定可能）
 *
 *  使用例
 *  スイッチの初期化
 *  Init_Switches 1 2 \V[3]
 * ===========================================================================
 * セルフスイッチの初期化(English:Init_Self_Switch)
 *  全てのセルフスイッチを初期化します。
 *  製作者 トリアコンタン
 *
 *  パラメータ
 *  　なし
 *
 *  使用例
 *  セルフスイッチの初期化
 *  Init_Self_Switch
 * ===========================================================================
 * セルフスイッチの遠隔操作(English:Remote_Control_Self_Switch)
 *  マップID、イベントID、種別（A, B, C, D）を指定してセルフスイッチを操作します。
 *  製作者 トリアコンタン
 *
 *  パラメータ
 *  　マップID
 *  　イベントID
 *  　種別（A, B, C, D）
 *  　設定値（ON or OFF）
 *
 *  使用例
 *  セルフスイッチの遠隔操作 1 3 A ON
 *  Remote_Control_Self_Switch 1 3 D OFF
 * ===========================================================================
 * ピクチャの読み込み(English:Load_Picture)
 *  指定したファイル名のピクチャを事前に読み込んでキャッシュに保存します。
 *  製作者 トリアコンタン
 *
 *  パラメータ
 *  　ファイル名（拡張子は指定しないでください）
 *
 *  使用例
 *  ピクチャの読み込み filename
 *  Load_Picture filename
 * ===========================================================================
 * 戦闘アニメの読み込み(English:Load_Animation)
 *  指定したファイル名の戦闘アニメを事前に読み込んでキャッシュに保存します。
 *  製作者 トリアコンタン
 *
 *  パラメータ
 *  　ファイル名（拡張子は指定しないでください）
 *  　色相（0-360）
 *
 *  使用例
 *  戦闘アニメの読み込み filename
 *  Load_Animation filename
 * ===========================================================================
 * シャットダウン(English:Shutdown)
 *  ゲームウィンドウを閉じて強制終了します。
 *  この操作はブラウザ実行、スマホ実行では無効です。
 *  製作者 トリアコンタン
 *
 *  パラメータ
 *  　なし
 *
 *  使用例
 *  シャットダウン
 *  Shutdown
 * ===========================================================================
 * ウェブサイト起動(English:Startup_Website)
 *  別ウィンドウで指定されたURLのウェブサイトを起動します。
 *  この操作はブラウザ実行、スマホ実行では無効です。
 *  製作者 トリアコンタン
 *
 *  パラメータ
 *  　表示したいサイトのURL
 *  　ウィンドウのX座標（指定しなかった場合は0）
 *  　ウィンドウのY座標（指定しなかった場合は0）
 *  　ウィンドウの横幅（指定しなかった場合はゲーム画面と同じサイズ）
 *  　ウィンドウの高さ（指定しなかった場合はゲーム画面と同じサイズ）
 *
 *  使用例
 *  ウェブサイト起動 https://www.google.co.jp/
 *  Startup_Website https://www.google.co.jp/
 * ===========================================================================
 * 変数の操作(English:ControlVariable)
 * 指定の変数の値を操作(代入、加算、減算、乗算、除算、剰余)します。
 * 変数の指定について、イベントエディタのコマンドと同じ#0001なども使用できます。
 * プラグインコマンドで[変数の操作]もしくは[ControlVariable]か[ConVar]を記述して使用します。
 *
 * パラメータ：
 *  引数1：操作する変数
 *  引数2：操作する内容   [代入：=  加算:+=  減算：-=  乗算：*=  除算：/=  剰余：%=]
 *                                                  or
 *                        [代入：set  加算:add  減算：sub  乗算：mult  除算：div  剰余：mod]
 *  引数3：操作用の値
 *  引数4：値の型(省略可) [数字優先(省略値)：0  文字優先:1]
 *
 * 使用例：
 *   変数の操作 #0001 += \V[2]         //変数1に変数2の値を加算
 *   変数の操作 \V[2] = \V[3]          //変数2の値と同番号の変数に変数3の値を代入
 *   変数の操作 1 mod \V[2]            //変数1を変数2の値で除算した余りを代入
 *   変数の操作 1 = \In[\V[2]]         //変数1に変数2のアイテム番号の名前を代入
 *   変数の操作 #0001 = 10 1           //変数1に'10'(文字)を代入
 *   変数の操作 5 = \Js[$dataMap.note] //変数5に個別マップのメモを代入
 *   ControlVariable 1 += 2            //変数1に2を加算
 *   ConVar 1 mult \V[5]               //変数1を変数5の値で乗算
 *
 * ===========================================================================
 * タッチ座標の取得(English:Get_Touch_Info)
 *  タッチ位置のX座標とY座標を指定された変数に格納します。
 *  画面上の実座標とマップ上のタイル座標の二種類が取得できます。
 *  製作者 トリアコンタン
 *
 *  パラメータ
 *  　X座標が格納される変数の番号（1-5000）
 *  　Y座標が格納される変数の番号（1-5000）
 *  　取得タイプ（画面座標 or マップ座標）※指定しない場合は画面座標
 *
 *  使用例
 *  タッチ座標の取得 1 2
 *  Get_Touch_Info \V[1] \V[2] マップ座標
 * ===========================================================================
 * マップタッチ禁止の変更(English:Change_Map_Touch)
 *  マップタッチによるプレイヤーの移動禁止を変更します。
 *  製作者 トリアコンタン
 *
 *  パラメータ
 *  　設定値（禁止 or 許可）
 *
 *  使用例
 *  マップタッチ禁止の変更 禁止
 *  Change_Map_Touch 許可
 * ===========================================================================
 * マップタッチ移動中判定(English:Get_Map_Touch_Moving)
 *  マップタッチによるプレイヤーの移動中かどうかを
 *  指定されたスイッチに格納します。
 *  製作者 トリアコンタン
 *
 *  パラメータ
 *  　結果が格納されるスイッチの番号（1-5000）
 *
 *  使用例
 *  マップタッチ移動中判定 1
 *  Get_Map_Touch_Moving \V[1]
 * ===========================================================================
 * マップタッチ移動(English:Map_Touch_Move)
 *  マップをタッチしたのと同じ要領で指定位置にプレイヤーを移動します。
 *  障害物やキー入力により移動は中断されます。
 *  製作者 トリアコンタン
 *
 *  パラメータ
 *  　移動先X座標
 *  　移動先Y座標
 *
 *  使用例
 *  マップタッチ移動 17 13
 *  Map_Touch_Move \V[1] \V[2]
 * ===========================================================================
 * ピクチャの移動(English:Move_Picture)
 *  イベントコマンド「ピクチャの移動」と同じ動作をします。
 *  それぞれのパラメータを制御文字で変数指定できるのが特徴で減算合成も可能です。
 *  製作者 トリアコンタン
 *
 *  パラメータ
 *  　ピクチャ番号（1-100）
 *  　原点（左上 or 中央）
 *  　移動先X座標
 *  　移動先Y座標
 *  　X方向拡大率（マイナス値で画像反転）
 *  　Y方向拡大率（マイナス値で画像反転）
 *  　不透明度（0-255）
 *  　合成方法（通常 or 加算 or 減算）
 *  　移動フレーム数
 *  　移動完了までウェイト（指定する場合「ウェイトあり」）
 *
 *  使用例
 *  ピクチャの移動 1 左上 300 200 200 200 128 減算 240 ウェイトあり
 *  Move_Picture \V[1] 中央 \V[2] \V[3] \V[4] \V[5] \V[6] 減算 \V[7]
 * ===========================================================================
 * 数値入力範囲の設定(English:Set_Input_Num_Range)
 *  イベントコマンド「数値入力の処理」で入力可能な値の最小値と最大値を設定します。
 *  入力可能桁数と併せて考慮されます。
 *  この設定は解除忘れ防止のため、数値入力の処理を終えた時点で初期化されます。
 *
 *  製作者 トリアコンタン
 *
 *  パラメータ
 *  　入力可能最小値（0-99999999）
 *  　入力可能最大値（0-99999999）
 *
 *  使用例
 *  数値入力範囲の設定 0 500
 *  Set_Input_Num_Range \V[1] \V[2]
 * ===========================================================================
 * 数値入力ウィンドウの設定(English:Set_Num_Input_Window)
 *  イベントコマンド「数値入力の処理」で表示されるウィンドウの背景と位置を設定します。
 *  製作者 トリアコンタン
 *
 *  パラメータ
 *  　背景（ウィンドウ or 暗くする or 透明）
 *  　位置（左 or 中 or 右）
 *
 *  使用例
 *  数値入力ウィンドウの設定 ウィンドウ 左
 *  Set_Num_Input_Window 暗くする 中
 * ===========================================================================
 * 数値入力有効桁の設定(English:Set_Num_Input_Valid_Digit)
 *  イベントコマンド「数値入力の処理」で入力可能な有効桁を設定します。
 *  有効桁より小さい桁は変更できなくなります。(1桁目を0で固定したい場合などに使用)
 *  1を指定すると通常通り、全ての桁を入力できます。
 *  この設定は解除忘れ防止のため、数値入力の処理を終えた時点で初期化されます。
 *  製作者 トリアコンタン
 *
 *  パラメータ
 *  　有効桁（1-8）
 *
 *  使用例
 *  数値入力有効桁の設定 2
 *  Set_Num_Input_Valid_Digit \v[1]
 * ===========================================================================
 * ピクチャの有効判定(English:Get_Picture_Valid)
 *  指定された番号のピクチャが現在、使われているかを判定して結果をスイッチに格納します。
 *  「ピクチャの表示」で使用状態になり、「ピクチャの消去」で非使用状態になります。
 *  製作者 トリアコンタン
 *
 *  パラメータ
 *  　結果が格納されるスイッチの番号（1-5000）
 *  　ピクチャ番号（1-100）
 *
 *  使用例
 *  ピクチャの有効判定 2 1
 *  Get_Picture_Valid \v[1] \v[2]
 * ===========================================================================
 * ピクチャの表示優先度設定(English:Set_Picture_Priority)
 *  指定した番号のピクチャの表示優先度を設定します。表示優先度の高いピクチャほど
 *  画面の前面に表示されます。この設定はピクチャ番号よりも優先されます。
 *  デフォルト値は100です。
 *  製作者 トリアコンタン
 *
 *  パラメータ
 *  　ピクチャ番号（1-100）
 *  　表示優先度の値（デフォルト100）
 *
 *  使用例
 *  ピクチャの表示優先度設定 1 101
 *  Set_Picture_Priority \v[1] \v[2]
 * ===========================================================================
 * ピクチャの表示優先度設定(English:Set_Picture_Priority)
 *  指定した番号のピクチャの表示優先度を設定します。表示優先度の高いピクチャほど
 *  画面の前面に表示されます。この設定はピクチャ番号よりも優先されます。
 *  デフォルト値は100です。
 *  製作者 トリアコンタン
 *
 *  パラメータ
 *  　ピクチャ番号（1-100）
 *  　表示優先度の値（デフォルト100）
 *
 *  使用例
 *  ピクチャの表示優先度設定 1 101
 *  Set_Picture_Priority \v[1] \v[2]
 * ===========================================================================
 * ピクチャのトリミング(English:Trimming_Picture)
 *  指定した矩形（X座標、Y座標、横幅、高さ）でピクチャを切り出します。
 *  製作者 トリアコンタン
 *
 *  パラメータ
 *  　ピクチャ番号（1-100）
 *  　X座標
 *  　Y座標
 *  　横幅
 *  　高さ
 *
 *  使用例
 *  ピクチャのトリミング 1 0 0 320 240
 *  Trimming_Picture \v[1] \v[2] \v[3] \v[4] \v[5]
 * ===========================================================================
 * ピクチャの回転角設定(English:Angle_Picture)
 *  指定した角度で時計回りにピクチャを回転させます。
 *  「ピクチャの回転」とは異なり回転させた状態のまま保たれます。
 *  製作者 トリアコンタン
 *
 *  パラメータ
 *  　ピクチャ番号（1-100）
 *  　回転角（0-360）
 *
 *  使用例
 *  ピクチャの回転角設定 1 90
 *  Trimming_Picture \v[1] \v[2]
 * * ===========================================================================
 * 文字の連結(English：ConcatenStrings)
 * 文字を連結し、指定の変数に代入します。
 * 変数の指定について、イベントエディタのコマンドと同じ#0001なども使用できます。
 * もちろん\[V]や\JS[X]\JSなどの制御文字も使用可能です。
 * プラグインコマンドで[文字の連結]もしくは[ConcatenStrings]か[CatStr]を記述して使用します。
 *
 * パラメータ：
 *  引数1：結果を代入する変数
 *  引数2：連結する文字1
 *  引数3：連結する文字2
 *  引数4：結果が数値として評価できる場合(省略可)
 *         [0:文字として評価(省略値)  1：数値として評価]
 * 使用例
 *  文字の連結 1 /N[1] は天才！ //ハロルドは天才！
 *  文字の連結 #0001 \JS[$dataMapInfos[1].name]\JS は綺麗 //王都は綺麗
 *  ConcatenStrings 1 TEST OK //TESTOK
 *  CatStr 1 2 1 1 // 21(数値)
 * ===========================================================================
 * 文字の置換(English：ReplaceStrings)
 * 文字を置換し、指定の変数に代入します。
 * 変数の指定について、イベントエディタのコマンドと同じ#0001なども使用できます。
 * もちろん\[V]や\JS[X]\JSなどの制御文字も使用可能です。
 * 特殊文字\と置き換えることにより、指定文字の削除も可能です。
 * プラグインコマンドで[文字の置換]もしくは[ReplaceStrings]か[RepStr]を記述して使用します。
 *
 * パラメータ：
 *  引数1：結果を代入する変数
 *  引数2：置換対象の文字列
 *  引数3：置換前文字
 *  引数4：置換後文字
 *  引数5：置換方法(省略可) [前方 後方 全て(省略値)]
 *                                 or
 *                          [front back all(省略値)]
 * 使用例
 *  文字列の置換 1 ハロルドかっこいいよハロルド ハ Ｈ 全て //ＨロルドかっこいいよＨロルド
 *  文字列の置換 1 \V[1] ハロルド \ 全て //変数1の文字列からハロルドを取り除く
 *  ReplaceStrings 1 ハロルドとハロルドがお見合い ハ Ｈ Front //Ｈロルドとハロルドがお見合い
 *  RepStr 1 ハロルドとハロルドがお見合い ハロルド Ｔレーゼ Back //ハロルドとＴレーゼがお見合い
 * ===========================================================================
 * 文字の切取(English：CutString)
 * 文字を切り取って指定の変数に代入します。
 * 変数の指定について、イベントエディタのコマンドと同じ#0001なども使用できます。
 * もちろん\[V]や\JS[X]\JSなどの制御文字も使用可能です。
 * プラグインコマンドで[文字の切取]もしくは[CutStrings]か[CutStr]を記述して使用します。
 *
 * パラメータ：
 *  引数1：結果を代入する変数
 *  引数2：対象の文字列
 *  引数3：開始位置
 *  引数4：終了位置(End か 最後 の指定で最後まで切り取り)
 *  引数5：開始方向(省略可)[前方(省略値)  後方]
 *                                 or
 *                         [front(省略値) back]
 * 使用例
 *  文字の切取 1 \JS[$dataMap.note]\JS 1 10 前方
 *  文字の切取 1 \JS[$dataMap.note]\JS 10 最後 後方
 *  CutStrings 1 \[V] 2 end back
 *  CutStr 1 \[V] 2
 * ===========================================================================
 * 文字一致カウント(English：CountMatchString)
 * 文字列内で特定の文字に一致した数をカウントし指定の変数に代入します。
 * 変数の指定について、イベントエディタのコマンドと同じ#0001なども使用できます。
 * もちろん\[V]や\JS[X]\JSなどの制御文字も使用可能です。
 * プラグインコマンドで[文字一致カウント]もしくは[CountMatchString]か[CntStr]を記述して使用します。
 *
 * パラメータ：
 *  引数1：結果を代入する変数
 *  引数2：対象の文字列
 *  引数3：検索する文字
 *  引数4：比較方法[0:一致したら一致下部分から先を比較(省略値) 1:1文字ずつ比較]
 * 使用例
 *  文字一致カウント 1 あああああ ああ 0 //2文字一致
 *  文字一致カウント 1 あああああ ああ 1 //4文字一致
 *  CountMatchString 1 \[V] OK
 *  CntStr 1 \N[1] Ｈロルド 0
 * ===========================================================================
 * 文字の検索(English：CountMatchString)
 * 文字列内で特定の文字を検索し、最初に一致した位置を指定の変数に代入します。
 * 変数の指定について、イベントエディタのコマンドと同じ#0001なども使用できます。
 * もちろん\[V]や\JS[X]\JSなどの制御文字も使用可能です。
 * プラグインコマンドで[文字の検索]もしくは[SearchString]か[SchStr]を記述して使用します。
 *
 * パラメータ：
 *  引数1：結果を代入する変数
 *  引数2：対象の文字列
 *  引数3：検索する文字
 *  引数4：開始方向(省略可)[前方(省略値)  後方]
 *                                 or
 *                         [front(省略値) back]
 * 使用例
 *  文字の探索 1 あああああ ああ 前方
 *  SearchString 1 \[V] test back
 *  SchStr 1 \N[1] Ｈロルド
 * ===========================================================================
 * 文字数カウント(English：CountStringlength)
 * 文字数をカウントし指定の変数に代入します。
 * 変数の指定について、イベントエディタのコマンドと同じ#0001なども使用できます。
 * もちろん\[V]や\JS[X]\JSなどの制御文字も使用可能です。
 * プラグインコマンドで[文字数カウント]もしくは[CountStringlength]か[CntLen]を記述して使用します。
 *
 * パラメータ：
 *  引数1：結果を代入する変数
 *  引数2：対象の文字列
 *
 * 使用例
 *  文字数カウント 1 \N[1]
 *  CountStringlength 1 hahaha
 *  CntLen 1
 * ===========================================================================
 * 文字の反転(English：ReverseString)
 * 対象の文字列を逆転させ、指定の変数に代入します。
 * 変数の指定について、イベントエディタのコマンドと同じ#0001なども使用できます。
 * もちろん\[V]や\JS[X]\JSなどの制御文字も使用可能です。
 * プラグインコマンドで[文字の反転]もしくは[ReverseString]か[RevStr]を記述して使用します。
 * パラメータ：
 *  引数1：結果を代入する変数
 *  引数2：対象の文字列
 * 使用例
 *  文字の反転 1 \N[1]
 *  ReverseString 1 逆読みできるかな？
 *  RevStr 1 できると思うよ？
 * ===========================================================================
 * 強制セーブ(English：Force_Save)
 *  セーブ画面を介さずに強制的に状態をセーブします。
 *  更新されるセーブファイルは、最後にセーブ or ロードしたファイルになります。
 *  ニューゲームから直接セーブした場合は空きを探しますが、空きがなければ
 *  もっとも古いファイルを上書きします。
 * パラメータ：
 *  なし
 * 使用例
 *  強制セーブ
 *  Force_Save
 * ===========================================================================
 * 指定位置にアニメーション表示(English：Show_Animation)
 *  画面上の座標を指定してアニメーションを再生します。
 * パラメータ：
 *  引数1：X座標
 *  引数2：Y座標
 *  引数3：アニメーションID
 *  引数4：ウェイトフラグ（指定する場合「ウェイトあり」）
 * 使用例
 *  指定位置にアニメーション表示 320 240 1 ウェイトあり
 *  Show_Animation \v[1] \v[2] 1
 * ===========================================================================
 * 指定位置にループアニメーション表示(English：Show_Loop_Animation)
 *  画面上の座標を指定してアニメーションを再生します。
 *  消去するか新たなアニメーションを指定するまでループ再生されます。
 * パラメータ：
 *  引数1：X座標
 *  引数2：Y座標
 *  引数3：アニメーションID
 * 使用例
 *  指定位置にループアニメーション表示 320 240 1
 *  Show_Loop_Animation \v[1] \v[2] 1
 * ===========================================================================
 * ループアニメーション消去(English：Erase_Loop_Animation)
 *  ループ再生しているアニメーションを消去します。
 * パラメータ：
 *  なし
 * 使用例
 *  ループアニメーション消去
 *  Erase_Loop_Animation
 * ===========================================================================
 */

(function(){
    'use strict';

    //制御文字の拡張
    Game_Interpreter.prototype.pluginCommandBook_unescape = function(text) {
        //全角数字を半角数字に変換する
        var wstringToString = function(text) {
            text = text.replace(/[０-９]/g, function(c) {
                return String.fromCharCode(c.charCodeAt(0) - 0xFEE0);
            });
            return text;
        };
        var getActorName = function(n) {
            var actor = n >= 1 ? $gameActors.actor(n) : null;
            return actor ? actor.name() : '';
        };
        var getPartyMemberName = function(n) {
            var actor = n >= 1 ? $gameParty.members()[n - 1] : null;
            return actor ? actor.name() : '';
        };
        var prevText = "";
        text = text.replace(/\\/g, '\x1b');
        while (prevText != text) {
            prevText = text;
            text = text.replace(/\x1b\x1b/g, '\\');
            text = text.replace(/\x1bV\[([０-９\d]+)\]/gi, function() {
                return $gameVariables.value(parseInt(wstringToString(arguments[1]), 10));
            }.bind(this));
            text = text.replace(/\x1bN\[([０-９\d]+)\]/gi, function() {
                return getActorName(parseInt(wstringToString(arguments[1]), 10));
            }.bind(this));
            text = text.replace(/\x1bP\[([０-９\d]+)\]/gi, function() {
                return getPartyMemberName(parseInt(wstringToString(arguments[1]), 10));
            }.bind(this));
            text = text.replace(/\x1bG/gi, TextManager.currencyUnit);
            text = text.replace(/\x1bIn\[([０-９\d]+)\]/gi, function() {
                return $dataItems[parseInt(wstringToString(arguments[1]), 10)].name;
            }.bind(this));
            text = text.replace(/\x1bNi\[([０-９\d]+)\]/gi, function() {
                return $dataItems[parseInt(wstringToString(arguments[1]), 10)].name;
            }.bind(this));
            text = text.replace(/\x1bIp\[([０-９\d]+)\]/gi, function() {
                return $dataItems[parseInt(wstringToString(arguments[1]), 10)].price;
            }.bind(this));
            text = text.replace(/\x1bPi\[([０-９\d]+)\]/gi, function() {
                return $dataItems[parseInt(wstringToString(arguments[1]), 10)].price;
            }.bind(this));
            text = text.replace(/\x1bSn\[([０-９\d]+)\]/gi, function() {
                return $dataSkills[parseInt(wstringToString(arguments[1]), 10)].name;
            }.bind(this));
            text = text.replace(/\x1bNs\[([０-９\d]+)\]/gi, function() {
                return $dataSkills[parseInt(wstringToString(arguments[1]), 10)].name;
            }.bind(this));
            text = text.replace(/\x1bNc\[([０-９\d]+)\]/gi, function() {
                return $dataClasses[parseInt(wstringToString(arguments[1]), 10)].name;
            }.bind(this));
            text = text.replace(/\x1bNt\[([０-９\d]+)\]/gi, function() {
                return $dataStates[parseInt(wstringToString(arguments[1]), 10)].name;
            }.bind(this));
            text = text.replace(/\x1bNw\[([０-９\d]+)\]/gi, function() {
                return $dataWeapons[parseInt(wstringToString(arguments[1]), 10)].name;
            }.bind(this));
            text = text.replace(/\x1bNa\[([０-９\d]+)\]/gi, function() {
                return $dataArmors[parseInt(wstringToString(arguments[1]), 10)].name;
            }.bind(this));
            text = text.replace(/\x1bJs\[(.*)\]\x1bJs/gi, function() {
                try{
                    var value = eval(arguments[1]);
                    if (value != null){return value}else{
                        console.log('制御文字 \\JS のパラメータでエラー  詳細：評価値が無い(null or undefined)');
                        return 0;
                    }
                } catch(ex){
                    console.log( '制御文字 \\JS のパラメータでエラー  詳細： ' + ex.toString());
                    return 0;
                }
            }.bind(this));
        }
        text = text.replace(/\x1bG/gi, TextManager.currencyUnit);
        return text;
    };

    /**
     * 厳密な数値チェックを行います。引数が数値でなければ例外を発生されます。
     * プラグインコマンド集では、例外が発生してもその場でゲームは中断されず
     * 実行したコマンドのみが無効になり、さらにテストプレーなら自動でデベロッパツールが起動します。
     *
     * @method parseIntStrict
     * @param {Number} value
     * @param {String} errorMessage
     * @type Number
     * @return {Number} 数値に変換した結果
     */
    var parseIntStrict = function(value, errorMessage) {
        var result = parseInt(value, 10);
        if (isNaN(result)) throw Error('指定した値[' + value + ']が数値ではありません。' + errorMessage);
        return result;
    };

    var parameters = PluginManager.parameters('TkoolMV_PluginCommandBook');

    var _Game_Interpreter_pluginCommand      = Game_Interpreter.prototype.pluginCommand;
    Game_Interpreter.prototype.pluginCommand = function (command, args) {
        _Game_Interpreter_pluginCommand.call(this, command, args);

        if (command.length == 0) {
            return;
        }

        // コマンドの実行
        this.executePluginCommand(command, args);
    };

    Game_Interpreter.prototype.executePluginCommand = function(command, args) {
        var methodName = 'pluginCommandBook_' + command;
        if (typeof this[methodName] === 'function') {
            // 引数パラメータの制御文字での変換
            for (var i=0; i<args.length; i++) {
                args[i] = Game_Interpreter.prototype.pluginCommandBook_unescape(args[i]);
            }
            try {
                this[methodName](args);
            } catch (e) {
                if ($gameTemp.isPlaytest() && Utils.isNwjs()) {
                    var window = require('nw.gui').Window.get();
                    if (!window.isDevToolsOpen()) {
                        var devTool = window.showDevTools();
                        devTool.moveTo(0, 0);
                        devTool.resizeTo(Graphics.width, Graphics.height);
                        window.focus();
                    }
                }
                console.log('プラグインコマンドの実行中にエラーが発生しました。');
                console.log('- コマンド名 　: ' + command);
                console.log('- コマンド引数 : ' + args);
                console.log('- エラー原因   : ' + e.toString());
            }
        }
    };

    /**
     * 名前の変更
     *  主人公の名前を変更する
     *  製作者 Alec
     *
     *  使用例
     *  名前の変更 1 ライアン　　（アクター0001の名前をライアンに変更
     *  名前の変更 2 \V[1]　　　（アクター0002の名前を変数0001の内容に変更
     */
    Game_Interpreter.prototype.pluginCommandBook_名前の変更 = function(args) {
        var actorId = args[0]; // アクターID
        var name = args[1]; // 名前
        $gameActors.actor(actorId).setName(name);
    };

    /**
     * 呼び出し元アイテム取得
     *  コモンイベントを呼び出したアイテムのIDを変数に入れる
     *  製作者 Alec
     *
     *  使用例
     *  呼び出し元アイテム取得 1　　（変数0001にコモンイベントを呼び出したアイテムIDを入れる
     */
    Game_Interpreter.prototype.pluginCommandBook_呼び出し元アイテム取得 = function(args) {
        var varId = parseInt(args[0]); // 変数ID

        // アイテムを使ってなかったら
        if (!$gameParty.lastItem()) {
            return;
        }
        $gameVariables.setValue(varId, $gameParty.lastItem().id);
    };

    /**
     * 呼び出し元スキル取得
     *  コモンイベントを呼び出したスキルのIDを変数に入れる
     *  製作者 Alec
     *
     *  使用例
     *  呼び出し元スキル取得 1　　（変数0001にコモンイベントを呼び出したスキルIDを入れる
     */
    Game_Interpreter.prototype.pluginCommandBook_呼び出し元スキル取得 = function(args) {
        if (eval(String(parameters['呼び出し元スキルの記録を使わない']||'false'))) {
            window.alert("「呼び出し元スキル取得」を使うにはプラグインマネージャーから「TkoolMV_PluginCommandBook.js」の「呼び出し元スキルの記録を使わない」を「はい」してください");
            return;
        }
        var varId = parseInt(args[0]); // 変数ID
        var skillId = 0;
        if ($gameParty.inBattle()) {
            skillId = BattleManager._subject.lastBattleSkill().id;
        } else {
            skillId = $gameParty.menuActor().lastMenuSkill().id;
        }
        $gameVariables.setValue(varId, skillId);
    };

    /**
     * レベルの変更
     *  アクターのレベルを変更します。増減ではなく変更後のレベルを指定できます。
     *  製作者 Alec
     *
     *  パラメータ
     *  　アクターのID（もし0なら全員）
     *    変更後のレベル
     *    レベルアップをメッセージで表示するかどうか（表示・非表示）
     *
     *  使用例
     *  レベルの変更 1 50 表示　　（アクター0001のレベルを50に変更
     *  レベルの変更 0 10 非表示　（仲間全員のレベルを10に変更、レベルアップは表示しない
     */
    Game_Interpreter.prototype.pluginCommandBook_レベルの変更 = function(args) {
        var actorId = parseInt(args[0], 10);
        var level = parseInt(args[1], 10) || 1;
        var show = {"表示":true,"非表示":false,"はい":true,"いいえ":false}[args[2]||'表示'];
        show = show === null ? false : show;
        console.log(show);
        if (actorId == 0) {
            $gameParty.members().forEach(function(actor){
                var exp = actor.expForLevel(level);
                actor.changeExp(exp, show);
            });
        } else {
            var actor = $gameActors.actor(actorId);
            if (!actor) {
                return;
            }
            var exp = actor.expForLevel(level);
            actor.changeExp(exp, show);
        }
    };

    Game_Interpreter.prototype.pluginCommandBook_バイブレーション = function(args) {
        if(Utils.isMobileDevice() && typeof navigator.vibrate === 'function') {
            var frame = parseIntStrict(args[0]);
            navigator.vibrate(Math.floor(frame * 1000 / 60));
            var wait = (args[1] || '').toUpperCase();
            if (wait === 'ウェイトあり' || wait === 'WAIT') this.wait(frame);
        }
    };
    Game_Interpreter.prototype.pluginCommandBook_Vibration = function(args) {
        this.pluginCommandBook_バイブレーション(args);
    };

    Game_Interpreter.prototype.pluginCommandBook_指定位置の通行判定取得 = function(args) {
        var x = parseIntStrict(args[1]);
        var y = parseIntStrict(args[2]);
        var value = 0;
        value += $gamePlayer.isMapPassable(x, y, 8) ? 1000 : 0;
        value += $gamePlayer.isMapPassable(x, y, 6) ? 100  : 0;
        value += $gamePlayer.isMapPassable(x, y, 2) ? 10   : 0;
        value += $gamePlayer.isMapPassable(x, y, 4) ? 1    : 0;
        $gameVariables.setValue(args[0], value);
    };
    Game_Interpreter.prototype.pluginCommandBook_Get_Location_Pass = function(args) {
        this.pluginCommandBook_指定位置の通行判定取得(args);
    };

    Game_Interpreter.prototype.pluginCommandBook_スイッチの初期化 = function(args) {
        var exceptionValues = [];
        args.forEach(function(arg) {
            arg = parseIntStrict(arg);
            exceptionValues[arg] = $gameSwitches.value(arg);
        });
        $gameSwitches.clear();
        args.forEach(function(arg) {
            arg = parseIntStrict(arg);
            $gameSwitches.setValue(arg, exceptionValues[arg]);
        });
    };
    Game_Interpreter.prototype.pluginCommandBook_Init_Switches = function(args) {
        this.pluginCommandBook_スイッチの初期化(args);
    };

    Game_Interpreter.prototype.pluginCommandBook_変数の初期化 = function(args) {
        var exceptionValues = [];
        args.forEach(function(arg) {
            arg = parseIntStrict(arg);
            exceptionValues[arg] = $gameVariables.value(arg);
        });
        $gameVariables.clear();
        args.forEach(function(arg) {
            arg = parseIntStrict(arg);
            $gameVariables.setValue(arg, exceptionValues[arg]);
        });
    };
    Game_Interpreter.prototype.pluginCommandBook_Init_Variables = function(args) {
        this.pluginCommandBook_変数の初期化(args);
    };

    Game_Interpreter.prototype.pluginCommandBook_セルフスイッチの初期化 = function(args) {
        $gameSelfSwitches.clear();
    };
    Game_Interpreter.prototype.pluginCommandBook_Init_Self_Switch = function(args) {
        this.pluginCommandBook_セルフスイッチの初期化(args);
    };

    Game_Interpreter.prototype.pluginCommandBook_セルフスイッチの遠隔操作 = function(args) {
        var mapId   = Math.max(parseIntStrict(args[0]), 1);
        var eventId = Math.max(parseIntStrict(args[1]), 1);
        var type  = args[2].toUpperCase();
        var value = args[3].toUpperCase();
        $gameSelfSwitches.setValue([mapId, eventId, type], value === 'ON');
    };
    Game_Interpreter.prototype.pluginCommandBook_Remote_Control_Self_Switch = function(args) {
        this.pluginCommandBook_セルフスイッチの遠隔操作(args);
    };

    Game_Interpreter.prototype.pluginCommandBook_ピクチャの読み込み = function(args) {
        ImageManager.loadPicture(args[0], 0);
    };
    Game_Interpreter.prototype.pluginCommandBook_Load_Picture = function(args) {
        this.pluginCommandBook_ピクチャの読み込み();
    };

    Game_Interpreter.prototype.pluginCommandBook_戦闘アニメの読み込み = function(args) {
        var hue = parseInt(args[1], 10).clamp(0, 360);
        ImageManager.loadAnimation(args[0], hue);
    };
    Game_Interpreter.prototype.pluginCommandBook_Load_Animation = function(args) {
        this.pluginCommandBook_戦闘アニメの読み込み(args);
    };

    Game_Interpreter.prototype.pluginCommandBook_シャットダウン = function(args) {
        SceneManager.terminate();
    };
    Game_Interpreter.prototype.pluginCommandBook_Shutdown = function(args) {
        this.pluginCommandBook_シャットダウン(args);
    };

    Game_Interpreter.prototype.pluginCommandBook_ウェブサイト起動 = function(args) {
        if (Utils.isNwjs()) {
            var newWindow = require('nw.gui').Window.open(args[0]);
            var x = parseInt(args[1], 10) || 0;
            var y = parseInt(args[2], 10) || 0;
            var width = parseInt(args[3], 10) || Graphics.width;
            var height = parseInt(args[4], 10) || Graphics.height;
            newWindow.moveTo(x, y);
            newWindow.resizeTo(width, height);
        }
    };
    Game_Interpreter.prototype.pluginCommandBook_Startup_Website = function(args) {
        this.pluginCommandBook_ウェブサイト起動(args);
    };

    Game_Interpreter.prototype.pluginCommandBook_変数の操作 = function(args) {
        args[0]=args[0].replace('#' ,'');
        args[1]=args[1].replace(/set/i,'=');
        args[1]=args[1].replace(/add/i,'+=');
        args[1]=args[1].replace(/sub/i,'-=');
        args[1]=args[1].replace(/mult/i,'*=');
        args[1]=args[1].replace(/div/i,'/=');
        args[1]=args[1].replace(/mod/i,'%=');
        var VarId1 = parseIntStrict(args[0]);
        if(isFinite(args[2]) && args[3]!='1'){
            var Var1 = parseInt(args[2],10);
        } else {
            var Var1 = args[2];
        }
        var Var2 = $gameVariables.value(VarId1);
        switch (args[1]) {
          case '=':
            $gameVariables.setValue(VarId1,Var1);
            break;
          case '+=':
            $gameVariables.setValue(VarId1,Var2+Var1);
            break;
          case '-=':
            Var1 =parseIntStrict(Var1);
            Var2 = parseIntStrict(Var2);
            $gameVariables.setValue(VarId1,Var2-Var1);
            break;
          case '*=':
            Var1 =parseIntStrict(Var1);
            Var2 = parseIntStrict(Var2);
            $gameVariables.setValue(VarId1,Var2*Var1);
            break;
          case '/=':
            Var1 =parseIntStrict(Var1);
            Var2 = parseIntStrict(Var2);
            $gameVariables.setValue(VarId1,(Var2-(Var2%Var1))/Var1);
            break;
          case '%=':
            Var1 =parseIntStrict(Var1);
            Var2 = parseIntStrict(Var2);
            $gameVariables.setValue(VarId1,Var2%Var1);
            break;
        }
    };
    Game_Interpreter.prototype.pluginCommandBook_ControlVariable = function(args) {
        this.pluginCommandBook_変数の操作(args);
    };
    Game_Interpreter.prototype.pluginCommandBook_ConVar = function(args) {
        this.pluginCommandBook_変数の操作(args);
    };

    Game_Interpreter.prototype.pluginCommandBook_タッチ座標の取得 = function(args) {
        var x, y;
        if (TouchInput.isPressed()) {
            if (args[2] === 'マップ座標' || args[2] === 'Map') {
                x = $gameMap.canvasToMapX(TouchInput.x);
                y = $gameMap.canvasToMapY(TouchInput.y);
            } else {
                x = TouchInput.x;
                y = TouchInput.y;
            }
        } else {
            x = -1;
            y = -1;
        }
        $gameVariables.setValue(parseIntStrict(args[0]), x);
        $gameVariables.setValue(parseIntStrict(args[1]), y);
    };
    Game_Interpreter.prototype.pluginCommandBook_Get_Touch_Info = function(args) {
        this.pluginCommandBook_タッチ座標の取得(args);
    };

    Game_Interpreter.prototype.pluginCommandBook_マップタッチ禁止の変更 = function(args) {
        $gameSystem._mapTouchDisable = (args[0] === '禁止' || args[0] === 'Disable');
    };
    Game_Interpreter.prototype.pluginCommandBook_Change_Map_Touch = function(args) {
        this.pluginCommandBook_マップタッチ禁止の変更(args);
    };

    Game_Interpreter.prototype.pluginCommandBook_マップタッチ移動中判定 = function(args) {
        $gameSwitches.setValue(parseIntStrict(args[0]), $gameTemp.isDestinationValid());
    };
    Game_Interpreter.prototype.pluginCommandBook_Get_Map_Touch_Moving = function(args) {
        this.pluginCommandBook_マップタッチ移動中判定(args);
    };

    Game_Interpreter.prototype.pluginCommandBook_マップタッチ移動 = function(args) {
        $gameTemp.setDestination(parseInt(args[0], 10), parseInt(args[1], 10));
    };

    Game_Interpreter.prototype.pluginCommandBook_Map_Touch_Move = function(args) {
        this.pluginCommandBook_マップタッチ移動(args);
    };

    Game_Interpreter.prototype.pluginCommandBook_ピクチャの移動 = function(args) {
        var pictureId = parseInt(args[0], 10);
        var origin = args[1] === '左上' || args[1] === 'Upper_Left' ? 0 : 1;
        var x = parseIntStrict(args[2]);
        var y = parseIntStrict(args[3]);
        var scaleX = parseIntStrict(args[4]);
        var scaleY = parseIntStrict(args[5]);
        var opacity = parseIntStrict(args[6]);
        var blendMode;
        switch ((args[7] || '').toUpperCase()) {
            case '加算':
            case 'ADDITIVE':
                blendMode = 1;
                break;
            case '減算':
            case 'SUBTRACTIVE':
                blendMode = 2;
                break;
            default :
                blendMode = 0;
                break;
        }
        var duration = parseInt(args[8], 10);
        $gameScreen.movePicture(pictureId, origin, x, y, scaleX, scaleY, opacity, blendMode, duration);
        var wait = (args[9] || '').toUpperCase();
        if (wait === 'ウェイトあり' || wait === 'WAIT') this.wait(duration);
    };

    Game_Interpreter.prototype.pluginCommandBook_Move_Picture = function(args) {
        this.pluginCommandBook_ピクチャの移動(args);
    };

    Game_Interpreter.prototype.pluginCommandBook_数値入力範囲の設定 = function(args) {
        $gameMessage.setNumInputRange(
            parseIntStrict(args[0]).clamp(0, 99999999),
            parseIntStrict(args[1]).clamp(0, 99999999));
    };
    Game_Interpreter.prototype.pluginCommandBook_Set_Input_Num_Range = function(args) {
        this.pluginCommandBook_数値入力範囲の設定(args);
    };
    Game_Interpreter.prototype.pluginCommandBook_数値入力ウィンドウの設定 = function(args) {
        var background;
        switch (args[0].toUpperCase()) {
            case 'ウィンドウ':
            case 'WINDOW':
                background = 0;
                break;
            case '暗くする':
            case 'DIM':
                background = 1;
                break;
            case '透明':
            case 'TRANSPARENT':
                background = 2;
                break;
            default:
                throw new Error('背景に指定した値['+ args[0] +']が不正です。');
        }
        var position;
        switch (args[1].toUpperCase()) {
            case '左':
            case 'LEFT':
                position = 0;
                break;
            case '中':
            case 'MIDDLE':
                position = 1;
                break;
            case '右':
            case 'RIGHT':
                position = 2;
                break;
            default:
                throw new Error('位置に指定した値['+ args[1] +']が不正です。');
        }
        $gameMessage.setNumInputBackground(background);
        $gameMessage.setNumInputPositionType(position);
    };
    Game_Interpreter.prototype.pluginCommandBook_Set_Num_Input_Window = function(args) {
        this.pluginCommandBook_数値入力ウィンドウの設定(args);
    };

    Game_Interpreter.prototype.pluginCommandBook_数値入力有効桁の設定 = function(args) {
        $gameMessage._numInputValidDigit = parseIntStrict(args[0]).clamp(1, 8);
    };
    Game_Interpreter.prototype.pluginCommandBook_Set_Num_Input_Valid_Digit = function(args) {
        this.pluginCommandBook_数値入力有効桁の設定(args);
    };

    Game_Interpreter.prototype.pluginCommandBook_ピクチャの有効判定 = function(args) {
        var picture = $gameScreen.picture($gameScreen.realPictureId(parseIntStrict(args[1])));
        $gameSwitches.setValue(parseIntStrict(args[0]), picture != null);
    };
    Game_Interpreter.prototype.pluginCommandBook_Get_Picture_Valid = function(args) {
        this.pluginCommandBook_ピクチャの有効判定(args);
    };

    Game_Interpreter.prototype.pluginCommandBook_ピクチャの表示優先度設定 = function(args) {
        var picture = $gameScreen.picture($gameScreen.realPictureId(parseIntStrict(args[0])));
        if (picture) {
            picture.setZ(parseIntStrict(args[1]));
        } else {
            throw new Error('指定された番号[' + args[0] + ']のピクチャは無効です。');
        }
    };
    Game_Interpreter.prototype.pluginCommandBook_Set_Picture_Priority = function(args) {
        this.pluginCommandBook_ピクチャの表示優先度設定(args);
    };

    Game_Interpreter.prototype.pluginCommandBook_ピクチャのトリミング = function(args) {
        var picture = $gameScreen.picture($gameScreen.realPictureId(parseIntStrict(args[0])));
        if (picture) {
            picture.setFrameDirect(parseIntStrict(args[1]), parseIntStrict(args[2]),
                parseIntStrict(args[3]), parseIntStrict(args[4]));
        } else {
            throw new Error('指定された番号[' + args[0] + ']のピクチャは無効です。');
        }
    };
    Game_Interpreter.prototype.pluginCommandBook_Trimming_Picture = function(args) {
        this.pluginCommandBook_ピクチャのトリミング(args);
    };

    Game_Interpreter.prototype.pluginCommandBook_ピクチャの回転角設定 = function(args) {
        var picture = $gameScreen.picture($gameScreen.realPictureId(parseIntStrict(args[0])));
        if (picture) {
            picture.setAngleDirect(parseIntStrict(args[1]));
        } else {
            throw new Error('指定された番号[' + args[0] + ']のピクチャは無効です。');
        }
    };
    Game_Interpreter.prototype.pluginCommandBook_Angle_Picture = function(args) {
        this.pluginCommandBook_ピクチャの回転角設定(args);
    };

    Game_Interpreter.prototype.pluginCommandBook_文字の連結 = function(args) {
        args[0]=args[0].replace('#' ,'');
        var VarId1 = parseIntStrict(args[0]);
        var Str = String(args[1]) + String(args[2]);
        if(isFinite(Str) && args[3] == '1') Str = parseInt(Str,10);
        $gameVariables.setValue(VarId1,Str);
    };
    Game_Interpreter.prototype.pluginCommandBook_ConcatenStrings = function(args) {
        this.pluginCommandBook_文字の連結(args);
    };
    Game_Interpreter.prototype.pluginCommandBook_CatStr = function(args) {
        this.pluginCommandBook_文字の連結(args);
    };

    Game_Interpreter.prototype.pluginCommandBook_文字の置換 = function(args) {
        args[0]=args[0].replace('#' ,'');
        var VarId1   = parseInt(args[0],10);
        VarId1 = parseIntStrict(VarId1);
        var Str = String(args[1]);
        var Str2 = String(args[2]);
        var Str3 = String(args[3]);
        Str = Str.replace(/\x1b/gi);
        Str2 = Str2.replace(/\x1b/gi);
        Str3 = Str3.replace(/\x1b/gi);
        if (args[4] == null) args[4] = '全て';
        args[4]=args[4].replace(/front/i,'前方');
        args[4]=args[4].replace(/back/i,'後方');
        args[4]=args[4].replace(/all/i,'全て');
        switch (args[4]){
          case '前方':
            Str = Str.replace(Str2,Str3);
            break;
          case '後方':
            Str = RvStr(Str);
            Str2 = RvStr(Str2);
            Str3 = RvStr(Str3);
            Str = Str.replace(Str2,Str3);
            Str = RvStr(Str);
            break;
          case '全て':
          default:
            while (Str.indexOf(Str2,0) != -1 ) Str = Str.replace(Str2,Str3);
            break;
        }
        $gameVariables.setValue(VarId1,Str);
        function RvStr(st) {
            var rv = "";
            for (var i = 0, n = st.length; i < n; i++) rv += st[n - i - 1];
            return rv;
        }
    };
    Game_Interpreter.prototype.pluginCommandBook_ReplaceStrings = function(args) {
        this.pluginCommandBook_文字の置換(args);
    };
    Game_Interpreter.prototype.pluginCommandBook_RepStr = function(args) {
        this.pluginCommandBook_文字の置換(args);
    };

    Game_Interpreter.prototype.pluginCommandBook_文字の切取 = function(args) {
        args[0]=args[0].replace('#' ,'');
        var VarId1 = parseIntStrict(args[0]);
        var Str = String(args[1]);
        var Nm1 = parseIntStrict(args[2]);
        var Nm2 = args[3]
        if (Nm2.toLowerCase() == 'end' || Nm2 == '最後' ) Nm2 = Str.length;
        var Nm2 = parseIntStrict(Nm2);
        if (args[4] == null) args[4] = '前方';
        args[4]=args[4].replace(/front/i,'前方');
        args[4]=args[4].replace(/back/i,'後方');
        switch (args[4]){
          case '前方':
          default:
            Str = Str.substring(Nm1-1,Nm1+Nm2-1);
            break;
          case '後方':
            Str = Str.substring(Str.length-Nm1+1,Str.length-Nm1-Nm2+1);
            break;
        }
        $gameVariables.setValue(VarId1,Str);
    };
    Game_Interpreter.prototype.pluginCommandBook_CutStrings = function(args) {
        this.pluginCommandBook_文字の切取(args);
    };
    Game_Interpreter.prototype.pluginCommandBook_CutStr = function(args) {
        this.pluginCommandBook_文字の切取(args);
    };
    Game_Interpreter.prototype.pluginCommandBook_文字一致カウント = function(args) {
        args[0]=args[0].replace('#' ,'');
        var VarId1 = parseIntStrict(args[0]);
        var Str = String(args[1]);
        var Str2 = String(args[2]);
        var StrCnt = 0
        var StrLen
        if (args[3] == '1') {
          StrCnt = (Str.match(new RegExp(Str2, "g"))||[]).length;
        } else {
          while (Str.indexOf(Str2,0) != -1 ){
          StrCnt ++
          StrLen = Str.indexOf(Str2,0) + 1
          Str = Str.substring(StrLen,Str.length);
          }
        }
        $gameVariables.setValue(VarId1,StrCnt);
    };
    Game_Interpreter.prototype.pluginCommandBook_CountMatchString = function(args) {
        this.pluginCommandBook_文字一致カウント(args);
    };
    Game_Interpreter.prototype.pluginCommandBook_CntStr = function(args) {
        this.pluginCommandBook_文字一致カウント(args);
    };

    Game_Interpreter.prototype.pluginCommandBook_文字の検索 = function(args) {
        args[0]=args[0].replace('#' ,'');
        var VarId1 = parseIntStrict(args[0]);
        var Str = String(args[1]);
        var Str2 = String(args[2]);
        var StrLen
        if (args[3] == null) args[4] = '前方';
        args[3]=args[3].replace(/front/i,'前方');
        args[3]=args[3].replace(/back/i,'後方');
        switch (args[3]){
          case '前方':
          default:
            StrLen = Str.indexOf(Str2) + 1
            break;
          case '後方':
            StrLen = Str.lastIndexOf(Str2) + 1
            break;
        }
        $gameVariables.setValue(VarId1,StrLen);
   };
   Game_Interpreter.prototype.pluginCommandBook_SearchString = function(args) {
        this.pluginCommandBook_文字の検索(args);
   };
   Game_Interpreter.prototype.pluginCommandBook_SchStr = function(args) {
        this.pluginCommandBook_文字の検索(args);
   };

   Game_Interpreter.prototype.pluginCommandBook_文字数カウント = function(args) {
        args[0]=args[0].replace('#' ,'');
        var VarId1 = parseIntStrict(args[0]);
        var Str = String(args[1]);
        var StrLen = Str.length
        $gameVariables.setValue(VarId1,StrLen);
   };
   Game_Interpreter.prototype.pluginCommandBook_CountStringlength = function(args) {
        this.pluginCommandBook_文字数カウント(args);
   };
   Game_Interpreter.prototype.pluginCommandBook_SchStr = function(args) {
        this.pluginCommandBook_文字数カウント(args);
   };

   Game_Interpreter.prototype.pluginCommandBook_文字の反転 = function(args) {
        args[0]=args[0].replace('#' ,'');
        var VarId1 = parseIntStrict(args[0]);
        var Str = String(args[1]);
        var RevStr = "";
        for (var i = 0, n = Str.length; i < n; i++) RevStr += Str[n - i - 1];
        $gameVariables.setValue(VarId1,RevStr);
   };

 Game_Interpreter.prototype.pluginCommandBook_ReverseString = function(args) {
        this.pluginCommandBook_文字の反転(args);
   };
 Game_Interpreter.prototype.pluginCommandBook_RevStr = function(args) {
        this.pluginCommandBook_文字の反転(args);
   };

    Game_Interpreter.prototype.pluginCommandBook_強制セーブ = function(args) {
        $gameSystem.onBeforeSave();
        if (!DataManager.saveGame(DataManager.lastAccessedSavefileId())) {
            throw new Error('！！！セーブに失敗しました。セーブファイルは消去されています。！！！');
        }
    };

    Game_Interpreter.prototype.pluginCommandBook_Force_Save = function(args) {
        this.pluginCommandBook_強制セーブ(args);
    };

    Game_Interpreter.prototype.pluginCommandBook_指定位置にアニメーション表示 = function(args) {
        var x = parseIntStrict(args[0]);
        var y = parseIntStrict(args[1]);
        var id =  parseIntStrict(args[2]);
        var wait = args[3] && (args[3] === 'ウェイトあり' || args[3].toUpperCase() === 'wait');
        $gameScreen.startAnimation(x, y, id, false);
        if (wait) this.wait($dataAnimations[id].frames.length * 4);
    };

    Game_Interpreter.prototype.pluginCommandBook_Show_Animation = function(args) {
        this.pluginCommandBook_指定位置にアニメーション表示(args);
    };

    Game_Interpreter.prototype.pluginCommandBook_指定位置にループアニメーション表示 = function(args) {
        var x = parseIntStrict(args[0]);
        var y = parseIntStrict(args[1]);
        var id =  parseIntStrict(args[2]);
        $gameScreen.startAnimation(x, y, id, true);
    };

    Game_Interpreter.prototype.pluginCommandBook_Show_Loop_Animation = function(args) {
        this.pluginCommandBook_指定位置にループアニメーション表示(args);
    };

    Game_Interpreter.prototype.pluginCommandBook_ループアニメーション消去 = function(args) {
        $gameScreen.animationLoop = false;
    };

    Game_Interpreter.prototype.pluginCommandBook_Erase_Loop_Animation = function(args) {
        this.pluginCommandBook_ループアニメーション消去(args);
    };

    /*
     * ここからはプラグインコマンドの実装のために必要な関数などを追加する
     */
    var はい = true;
    var いいえ = false;

    /*
     * 制御文字の拡張
     *  このプラグインで使っている制御文字の拡張を通常のウィンドウにも適用します
     *  製作者 Alec
     */
    if (eval(String(parameters['制御文字の拡張']||'false'))) {
        (function () {
            var Window_Base_convertEscapeCharacters = Window_Base.prototype.convertEscapeCharacters;
            Window_Base.prototype.convertEscapeCharacters = function(text) {
                text = Game_Interpreter.prototype.pluginCommandBook_unescape(text);
                return Window_Base_convertEscapeCharacters.call(this, text);
            };
        })();
    }

    if (eval(String(parameters['スクリプトに制御文字適用']||'false'))) {
        (function () {
            var _Game_Interpreter_command355 = Game_Interpreter.prototype.command355;
            Game_Interpreter.prototype.command355 = function() {
                var oldParams = [], i = 0, result, index = this._index;
                oldParams.push(this._list[index].parameters[0]);
                this._list[index].parameters[0] = this.pluginCommandBook_unescape(this._list[index].parameters[0]);
                while (this._list[index + ++i].code === 655) {
                    oldParams.push(this._list[index + i].parameters[0]);
                    this._list[index + i].parameters[0] = this.pluginCommandBook_unescape(this._list[index + i].parameters[0]);
                }
                try {
                    result = _Game_Interpreter_command355.apply(this, arguments);
                } catch(e) {
                    console.log('スクリプトの実行中にエラーが発生しました。');
                    console.log('- スクリプト 　: ' + this.currentCommand().parameters[0]);
                    console.log('- エラー原因   : ' + e.toString());
                    result = true;
                }
                this._list[index].parameters[0] = oldParams.shift();
                i = 0;
                while (this._list[index + ++i].code === 655) {
                    this._list[index + i].parameters[0] = oldParams.shift();
                }
                return result;
            };

            var _Game_Interpreter_command111 = Game_Interpreter.prototype.command111;
            Game_Interpreter.prototype.command111 = function() {
                if (this._params[0] === 12) {
                    var oldParam = this._params[1];
                    var result;
                    this._params[1] = this.pluginCommandBook_unescape(this._params[1]);
                    try {
                        result = _Game_Interpreter_command111.apply(this, arguments);
                    } catch(e) {
                        console.log('スクリプトの実行中にエラーが発生しました。');
                        console.log('- スクリプト 　: ' + this._params[1]);
                        console.log('- エラー原因   : ' + e.toString());
                        result = true;
                    }
                    this._params[1] = oldParam;
                } else {
                    result = _Game_Interpreter_command111.apply(this, arguments);
                }
                return result;
            };

            var _Game_Character_processMoveCommand = Game_Character.prototype.processMoveCommand;
            Game_Character.prototype.processMoveCommand = function(command) {
                if (command.code === Game_Character.ROUTE_SCRIPT) {
                    var oldParam = command.parameters[0];
                    command.parameters[0] = Game_Interpreter.prototype.pluginCommandBook_unescape(command.parameters[0]);
                    try {
                        _Game_Character_processMoveCommand.apply(this, arguments);
                    } catch(e) {
                        console.log('スクリプトの実行中にエラーが発生しました。');
                        console.log('- スクリプト 　: ' + command.parameters[0]);
                        console.log('- エラー原因   : ' + e.toString());
                    }
                    command.parameters[0] = oldParam;
                } else {
                    _Game_Character_processMoveCommand.apply(this, arguments);
                }
            };
        })();
    }

    //=============================================================================
    // Gameクラス定義領域
    //=============================================================================
    var _Game_System_initialize = Game_System.prototype.initialize;
    Game_System.prototype.initialize = function() {
        _Game_System_initialize.call(this);
        this._mapTouchDisable = false;
    };

    var _Game_Message_initialize= Game_Message.prototype.initialize;
    Game_Message.prototype.initialize = function() {
        _Game_Message_initialize.call(this);
        this._numInputBackground = 0;
        this._numInputPositionType = 1;
        this._numInputValidDigit = 1;
        this.clearNumInputRange();
    };

    Game_Message.prototype.clearNumInputRange = function() {
        this._numInputMaxValue = Infinity;
        this._numInputMinValue = -Infinity;
        this._numInputValidDigit = 1;
    };

    Game_Message.prototype.setNumInputRange = function(min, max) {
        this._numInputMaxValue = max;
        this._numInputMinValue = min;
    };

    Game_Message.prototype.setNumInputBackground = function(background) {
        this._numInputBackground = background;
    };

    Game_Message.prototype.setNumInputPositionType = function(positionType) {
        this._numInputPositionType = positionType;
    };

    Game_Message.prototype.numInputBackground = function() {
        return this._numInputBackground;
    };

    Game_Message.prototype.numInputPositionType = function() {
        return this._numInputPositionType;
    };

    var _Game_Screen_clear = Game_Screen.prototype.clear;
    Game_Screen.prototype.clear = function() {
        _Game_Screen_clear.apply(this, arguments);
        this.clearAnimation();
    };

    Game_Screen.prototype.startAnimation = function(x, y, id, loop) {
        this._animationContainerX = x;
        this._animationContainerY = y;
        this._animationId         = id;
        this._animationLoop       = loop;
    };

    Game_Screen.prototype.clearAnimation = function() {
        this._animationContainerX = 0;
        this._animationContainerY = 0;
        this._animationId         = 0;
    };

    Object.defineProperty(Game_Screen.prototype, 'animationContainerX', {
        get: function() {
            return this._animationContainerX;
        },
        configurable: false
    });

    Object.defineProperty(Game_Screen.prototype, 'animationContainerY', {
        get: function() {
            return this._animationContainerY;
        },
        configurable: false
    });

    Object.defineProperty(Game_Screen.prototype, 'animationId', {
        get: function() {
            return this._animationId;
        },
        configurable: false
    });

    Object.defineProperty(Game_Screen.prototype, 'animationLoop', {
        get: function() {
            return this._animationLoop;
        },
        set: function(value) {
            this._animationLoop = value;
        },
        configurable: false
    });

    var _Game_Screen_clearPictures = Game_Screen.prototype.clearPictures;
    Game_Screen.prototype.clearPictures = function() {
        _Game_Screen_clearPictures.apply(this, arguments);
        this.needsSortPictures = false;
    };

    var _Game_Picture_initBasic = Game_Picture.prototype.initBasic;
    Game_Picture.prototype.initBasic = function() {
        _Game_Picture_initBasic.apply(this, arguments);
        this._frameX      = 0;
        this._frameY      = 0;
        this._frameWidth  = 0;
        this._frameHeight = 0;
        this.z            = 100;
    };

    Game_Picture.prototype.setZ = function(value) {
        this.z = value;
    };

    Game_Picture.prototype.setFrameDirect = function(x, y, width, height) {
        this._frameX = x;
        this._frameY = y;
        this._frameWidth = width;
        this._frameHeight = height;
    };

    Game_Picture.prototype.isValidFrame = function() {
        return this._frameX + this._frameY + this._frameWidth + this._frameHeight > 0;
    };

    Game_Picture.prototype.setAngleDirect = function(value) {
        this._rotationSpeed = 0;
        this._angle = value % 360;
    };

    //=============================================================================
    // Sceneクラス定義領域
    //=============================================================================
    var _Scene_Map_isMapTouchOk = Scene_Map.prototype.isMapTouchOk;
    Scene_Map.prototype.isMapTouchOk = function() {
        return (!$gameSystem._mapTouchDisable || $gameTemp.isDestinationValid()) && _Scene_Map_isMapTouchOk.call(this);
    };

    //=============================================================================
    // Windowクラス定義領域
    //=============================================================================
    var _Window_NumberInput_refresh = Window_NumberInput.prototype.refresh;
    Window_NumberInput.prototype.refresh = function() {
        if (this._number != null) this._number = this._number.clamp(
            $gameMessage._numInputMinValue, $gameMessage._numInputMaxValue);
        _Window_NumberInput_refresh.apply(this, arguments);
    };

    var _Window_NumberInput_start = Window_NumberInput.prototype.start;
    Window_NumberInput.prototype.start = function() {
        _Window_NumberInput_start.apply(this, arguments);
        this.updateBackground();
    };

    var _Window_NumberInput_processOk = Window_NumberInput.prototype.processOk;
    Window_NumberInput.prototype.processOk = function() {
        _Window_NumberInput_processOk.apply(this, arguments);
        $gameMessage.clearNumInputRange();
    };

    var _Window_NumberInput_updatePlacement = Window_NumberInput.prototype.updatePlacement;
    Window_NumberInput.prototype.updatePlacement = function() {
        _Window_NumberInput_updatePlacement.apply(this, arguments);
        var positionType = $gameMessage.numInputPositionType();
        this.width = this.windowWidth();
        switch (positionType) {
            case 0:
                this.x = 0;
                break;
            case 1:
                this.x = (Graphics.boxWidth - this.width) / 2;
                break;
            case 2:
                this.x = Graphics.boxWidth - this.width;
                break;
        }
    };

    var _Window_NumberInput_changeDigit = Window_NumberInput.prototype.changeDigit;
    Window_NumberInput.prototype.changeDigit = function(up) {
        if (this.maxItems() - this.index() < $gameMessage._numInputValidDigit) {
            return;
        }
        _Window_NumberInput_changeDigit.apply(this, arguments);
    };

    Window_NumberInput.prototype.updateBackground = function() {
        this._background = $gameMessage.numInputBackground();
        this.setBackgroundType(this._background);
    };

    //=============================================================================
    // Spriteクラス定義領域
    //=============================================================================
    var _Sprite_Picture_initialize = Sprite_Picture.prototype.initialize;
    Sprite_Picture.prototype.initialize = function(pictureId) {
        _Sprite_Picture_initialize.apply(this, arguments);
        this.z = 0;
    };

    var _Sprite_Picture_update = Sprite_Picture.prototype.update;
    Sprite_Picture.prototype.update = function() {
        _Sprite_Picture_update.call(this);
        if (this.visible) {
            var newZ = this.picture().z;
            if (newZ != this.z) {
                this.z = newZ;
                $gameScreen.needsSortPictures = true;
            }
            this.updateFrame();
        }
    };

    Sprite_Picture.prototype.updateFrame = function() {
        if (this.picture().isValidFrame()) {
            var p = this.picture();
            this.setFrame(p._frameX, p._frameY, p._frameWidth, p._frameHeight);
        }
    };

    var _Spriteset_Base_createUpperLayer = Spriteset_Base.prototype.createUpperLayer;
    Spriteset_Base.prototype.createUpperLayer = function() {
        _Spriteset_Base_createUpperLayer.apply(this, arguments);
        this.createAnimationContainer();
    };

    Spriteset_Base.prototype.createAnimationContainer = function() {
        this._animationContainer = new Sprite_Base();
        this._animationId = 0;
        this.addChild(this._animationContainer);
    };

    var _Spriteset_Base_update = Spriteset_Base.prototype.update;
    Spriteset_Base.prototype.update = function() {
        _Spriteset_Base_update.call(this);
        if ($gameScreen.needsSortPictures) {
            this.sortPictures();
            $gameScreen.needsSortPictures = false;
        }
        this.updateAnimationContainer();
    };

    Spriteset_Base.prototype.updateAnimationContainer = function() {
        var id = $gameScreen.animationId;
        if (id > 0 && id < $dataAnimations.length) {
            this._animationContainer.x = $gameScreen.animationContainerX;
            this._animationContainer.y = $gameScreen.animationContainerY;
            this._animationContainer.startAnimation($dataAnimations[id], false, 0);
            this._animationId = id;
            $gameScreen.clearAnimation();
        }
        if (!this._animationContainer.isAnimationPlaying() && this._animationId > 0) {
            if ($gameScreen.animationLoop) {
                this._animationContainer.startAnimation($dataAnimations[this._animationId], false, 0);
            } else {
                this._animationId = 0;
            }
        }
    };

    Spriteset_Base.prototype.sortPictures = function() {
        this._pictureContainer.children.sort(this._comparePictureChildOrder.bind(this));
    };

    Spriteset_Base.prototype._comparePictureChildOrder = function(a, b) {
        if (a.z !== b.z) {
            return a.z - b.z;
        } else {
            return a._pictureId - b._pictureId;
        }
    };

})();


code:
//=============================================================================
// RPG Maker MZ - Plugin Analysis Common Base
//=============================================================================

/*:
 * @target MZ
 * @plugindesc Plugin Analysis Common Base
 * @author triacontane
 *
 * @help PluginCommonBase.js
 *
 * This plugin is a base plugin that is meant to be referenced from other plugins.
 * This plugin allows you to use the following control characters in a variety of situations.
 *
 * Usable Control Characters
 * \v[n]  : nis converted to the value of the nth variable.
 * \s[n]  : nis converted to the value (true, false) of the nth switch.
 * \ss[n] : nis converted to the value (true, false) of the nth self switch.
 * n -> A, B, C, D
 *
 * The situations where control characters can be used are as follows.
 * -Text display
 * -Notes field (*)
 * -Plugin command (*)
 * -Plugin parameter (*)
 * -Explanation fields for skills, etc.
 * *Only for plugins that take PluginCommonBase.js as a base.
 *
 * Below is an explanation for developers.
 *
 * Introducing this plugin as a base allows conversion of parameter types and control characters,
 * when analyzing parameters or fetching plugin commands/note fields, to be automated.
 * Standardizing control character allows conversion processing, and consistent
 * control character conversion specs to be implemented in all subordinate plugins.
 *
 * -Plugin Parameter Type Analysis
 * Automatically analyzes type and converts plugin parameters.
 * Also automatically converts control characters when the parameter is fetched.
 * Calls the following methods to fetch return values.
 *  Always specifies "document.currentScript" in the argument.
 *
 * PluginManagerEx.createParameter(document.currentScript);
 *
 * However, if the end of the parameter name (regardless of case)
 * is one of the following values, the value will be returned as-is without control character or type conversion.
 * text
 * name
 * note
 * desc
 * script
 *
 * -Plugin Command Parameter Type Analysis
 * Automatically analyzes type and converts plugin command parameters.
 * Also automatically converts control characters when the parameter is fetched.
 * Uses the following in place of PluginManager.registerCommand.
 * Always specifies "document.currentScript" in the argument.
 *
 * PluginManagerEx.registerCommand(document.currentScript, "command", args => {
 * });
 *
 * -Notes Field Analysis
 * Retrieves notes field information from specified objects.
 * Automatically converts control characters.
 * Multiple names can be specified.
 *
 * PluginManagerEx.findMetaValue(obj, tagName1, tagName2...);
 *
 * -Dynamic Common Event Execution
 * Executions dynamic common events.
 * Dynamic common events are stacked parallel processed common events.
 * Use to execute as many common events with the same ID in parallel as you want.
 * It can register as many common events as you want and automatically discards those that have been executed.
 *
 * $gameMap.setupDynamicCommon(commonEventId);
 *
 */

/*:ja
* @target MZ
* @plugindesc パラメータ解析を提供する共通基盤です
* @author トリアコンタン
*
* @help PluginCommonBase.js
*
* 本プラグインは他のプラグインから参照されることを前提としたベースプラグインです。
* 本プラグインを導入すると様々な場面で以下の制御文字が使えるようになります。
*
* 利用可能な制御文字
* \v[n]  : n番目の変数の値に変換されます。
* \s[n]  : n番目のスイッチの値(true, false)に変換されます。
* \ss[n] : セルフスイッチの値(true, false)に変換されます。
* n -> A, B, C, D
*
* 制御文字を利用可能な場面は以下の通りです。
* ・文章の表示
* ・メモ欄(※)
* ・プラグインコマンド(※)
* ・プラグインパラメータ(※)
* ・スキルなどの説明欄
* ※ PluginCommonBase.jsをベースとして取り込んだプラグインのみ
*
* 以下は開発者向けの解説です。
*
* このプラグインをベースとして取り込むことで、パラメータの解析や
* プラグインコマンド、メモ欄の取得時にパラメータ型および制御文字の変換を自動化します。
* 制御文字の変換処理を共通化することで配下の全てのプラグインで一貫した
* 制御文字の変換仕様を実現します。
*
* ・プラグインパラメータの型解析
* プラグインパラメータを自動で型解析し変換します。
* また、パラメータ取得時に制御文字の変換を自動で行います。
* 以下のメソッドを呼んで戻り値を取得します。
* 引数には必ず「document.currentScript」を指定します。
*
* PluginManagerEx.createParameter(document.currentScript);
*
* ただし、パラメータ名の末尾が(大文字小文字問わず)以下の値の場合
* 制御文字や型の変換は行われず、そのままの値を返します。
* text
* name
* note
* desc
* script
*
* ・プラグインコマンドパラメータの型解析
* プラグインコマンドパラメータを自動で型解析し変換します。
* また、パラメータ取得時に制御文字の変換を自動で行います。
* PluginManager.registerCommandの代わりに以下を使用します。
* 引数には必ず「document.currentScript」を指定します。
*
* PluginManagerEx.registerCommand(document.currentScript, "command", args => {
* });
*
* ・メモ欄の解析
* 指定したオブジェクトからメモ欄情報を取得します。
* 制御文字の変換を自動で行います。
* 名称は複数指定することも可能です。
*
* PluginManagerEx.findMetaValue(obj, tagName1, tagName2...);
*
* ・動的コモンイベントの実行
* 動的コモンイベントを実行できます。
* 動的コモンイベントとは、スタック型の並列処理コモンイベントです。
* 同一IDのコモンイベントも好きなだけ並列実行できます。
* 実行が終わったものから自働で破棄されます。
*
* $gameMap.setupDynamicCommon(commonEventId);
*/

(() => {
    'use strict';

    /**
     * PluginParam
     */
    class PluginParam {

        constructor(parameter, needParse = true) {
            if (needParse) {
                parameter = JSON.parse(JSON.stringify(parameter, this._paramReplacer));
            }
            this.setup(parameter);
        }

        setup(parameter) {
            this._parameter = parameter;
            for(let paramName in parameter) {
                if (!parameter.hasOwnProperty(paramName)) {
                    continue;
                }
                const subParam = parameter[paramName];
                if (this._isStructArray(subParam)) {
                    subParam.forEach((subParamItem, index) => {
                        subParam[index] = new PluginParam(subParamItem, false);
                    });
                } else if (this._isStruct(subParam)) {
                    parameter[paramName] = new PluginParam(subParam, false);
                }
                this._createAccessor(paramName);
            }
        }

        _createAccessor(paramName) {
            Object.defineProperty(this, paramName, {
                get() {
                    return this._convert(this._param(paramName), paramName);
                },
                set(value) {
                    this._parameter[paramName] = value;
                },
                configurable: true
            });
        }

        _convert(param, paramName) {
            if (this._isStruct(param) || this._isStructArray(param)) {
                return param;
            } else if (Array.isArray(param)) {
                return param.map(paramItem => this._convert(paramItem, paramName));
            }
            if (!this._findTextParamSuffixList().some(regExp => paramName.match(regExp))) {
                return PluginManagerEx.convertVariables(param);
            } else {
                return String(param);
            }
        }

        _findTextParamSuffixList() {
            return [/text$/gi, /name$/gi, /desc$/gi, /note$/gi, /script$/gi];
        }

        _isStructArray(param) {
            return Array.isArray(param) && (param.length === 0 || this._isStruct(param));
        }

        _isStruct(param) {
            return Object.prototype.toString.call(param) === '[object Object]';
        }

        _param(name) {
            return this._parameter[name];
        }

        _paramReplacer(key, value) {
            if (value === 'null') {
                return value;
            }
            if (value[0] === '"' && value[value.length - 1] === '"') {
                return value;
            }
            try {
                return JSON.parse(value);
            } catch (e) {
                return value;
            }
        }
    }

    /**
     * PluginManagerEx
     */
    class PluginManagerEx {
        static convertVariables(text, data = null) {
            if (text !== String(text)) {
                return text;
            }
            text = this.convertEscapeCharacters(text, data);
            if (text === 'true') {
                return true;
            } else if (text === 'false') {
                return false;
            } else if (Number(text) === parseFloat(text)) {
                return parseFloat(text);
            } else {
                return text;
            }
        }

        static convertEscapeCharacters(text, data = null) {
            text = TextConverter.convertEscapeCharactersBase(text, data);
            text = this.convertEscapeCharactersEx(text, data);
            text = TextConverter.convertEscapeCharactersBase(text, data);
            return text;
        }

        // Additional Escape Characters
        static convertEscapeCharactersEx(text, data = null) {
            text = text.replace(/\x1bS\[(.+)]/gi, (_, p1) => {
                return $gameSwitches ? $gameSwitches.value(parseInt(p1)) : '';
            });
            const key = this._selfSwitchKey;
            if (!key) {
                return text;
            }
            text = text.replace(/\x1bSS\[(.+)]/gi, (_, p1) => {
                key[2] = p1;
                return $gameSelfSwitches ? $gameSelfSwitches.value(key) : '';
            });
            return text;
        }

        static createParameter(currentScript) {
            const paramText = PluginManager.parameters(this.findPluginName(currentScript));
            return new PluginParam(paramText);
        }

        static createCommandArgs(args) {
            const hasObject = Object.keys(args).some(key => {
                return args[key].match(/^[\[{].*[}\]]$/);
            });
            if (hasObject) {
                return new PluginParam(args);
            }
            const newArgs = {};
            Object.keys(args).forEach(key => {
                newArgs[key] = this.convertVariables(args[key]);
            });
            return newArgs;
        }

        static findMetaValue(object, nameList) {
            if (!Array.isArray(nameList)) {
                nameList = [nameList];
            }
            const meta = this.findMetaProperty(object);
            this.generateSelfSwitchKey(object.id);
            for (const name of nameList) {
                if (meta.hasOwnProperty(name)) {
                    return this.convertVariables(meta[name], object);
                }
            }
        }

        static findMetaObject(object, nameList) {
            if (!Array.isArray(nameList)) {
                nameList = [nameList];
            }
            const meta = this.findMetaProperty(object);
            this.generateSelfSwitchKey(object.id);
            for (const name of nameList) {
                if (meta.hasOwnProperty(name)) {
                    return new PluginParam(meta[name]);
                }
            }
        }

        static findMetaProperty(object) {
            const meta = object.meta;
            if (!meta) {
                throw new Error(`Meta property not found : ${object}`)
            }
            return meta;
        }

        static findPluginName(currentScript) {
            return currentScript.src.replace(/^.*\/(.*).js$/, function() {
                return arguments[1];
            });
        }

        static registerCommand(currentScript, commandName, funcName) {
            const pluginName = this.findPluginName(currentScript);
            const key = pluginName + ":" + commandName;
            const func = typeof funcName === 'function' ? funcName : Game_Interpreter.prototype[funcName];
            if (!func) {
                throw new Error(`Not found function Game_Interpreter : ${funcName}`)
            }
            PluginManager.registerCommand(pluginName, commandName, function(args) {
                func.call(this, PluginManagerEx.createCommandArgs(args, key));
            });
        }

        static isExistPlugin(pluginName) {
            return Object.keys(PluginManager.parameters(pluginName)).length > 0;
        }

        static generateSelfSwitchKey(eventId) {
            if (!$gameMap) {
                return;
            }
            this._selfSwitchKey = [$gameMap.mapId(), eventId, null];
        }

        static findClassName(object) {
            const define = object.constructor.toString();
            if (define.match(/^class/)) {
                return define.replace(/class\s+(.*?)\s+[\s\S]*/m, '$1');
            }
            return define.replace(/function\s+(.*)\s*\([\s\S]*/m, '$1');
        }

        static throwError(message, currentScript) {
            const pluginName = this.findPluginName(currentScript);
            throw new Error(`By ${pluginName} : ${message}`);
        }

        static escapeXmlTag(text) {
            text = text.replace(/>?/gi, '>');
            return text.replace(/<?/gi, '<');
        }
    }
    window.PluginManagerEx = PluginManagerEx;

    class TextConverter {
        // Copy of Window_Base.prototype.convertEscapeCharacters
        static convertEscapeCharactersBase(text, data = null) {
            text = text.replace(/\\/g, "\x1b");
            text = text.replace(/\x1b\x1b/g, "\\");
            text = text.replace(/\x1bV\[(\d+)]/gi, (_, p1) =>
                $gameVariables ? $gameVariables.value(parseInt(p1)) : ''
            );
            text = text.replace(/\x1bV\[(\d+)]/gi, (_, p1) =>
                $gameVariables ? $gameVariables.value(parseInt(p1)) : ''
            );
            text = text.replace(/\x1bN\[(\d+)]/gi, (_, p1) =>
                this.actorName(parseInt(p1))
            );
            text = text.replace(/\x1bP\[(\d+)]/gi, (_, p1) =>
                this.partyMemberName(parseInt(p1))
            );
            if ($dataSystem) {
                text = text.replace(/\x1bG/gi, TextManager.currencyUnit);
            }
            return text;
        }

        static actorName(n) {
            const actor = n >= 1 && $gameActors ? $gameActors.actor(n) : null;
            return actor ? actor.name() : '';
        }

        static partyMemberName(n) {
            const actor = n >= 1 && $gameParty ? $gameParty.members()[n - 1] : null;
            return actor ? actor.name() : "";
        }
    }

    const _PluginManager_callCommand = PluginManager.callCommand;
    PluginManager.callCommand = function(self, pluginName, commandName, args) {
        PluginManagerEx.generateSelfSwitchKey(self.eventId());
        _PluginManager_callCommand.apply(this, arguments);
    };

    const _Window_Base_convertEscapeCharacters = Window_Base.prototype.convertEscapeCharacters;
    Window_Base.prototype.convertEscapeCharacters = function(text) {
        text = _Window_Base_convertEscapeCharacters.apply(this, arguments);
        return PluginManagerEx.convertEscapeCharacters(text);
    };

    const _Game_System_onAfterLoad = Game_System.prototype.onAfterLoad;
    Game_System.prototype.onAfterLoad = function() {
        _Game_System_onAfterLoad.apply(this, arguments);
        $gameMap.initDynamicEvents();
    };

    /**
     * Game_Map
     * Support dynamic events.
     */
    const _Game_Map_setupEvents = Game_Map.prototype.setupEvents;
    Game_Map.prototype.setupEvents = function() {
        _Game_Map_setupEvents.apply(this, arguments);
        this.initDynamicEvents();
    };

    Game_Map.prototype.initDynamicEvents = function() {
        if (!this._dynamicEvents) {
            this._dynamicEvents = [];
        }
    };

    Game_Map.prototype.isInterpreterOf = function(interpreter) {
        return this._interpreter === interpreter;
    };

    Game_Map.prototype.setupDynamicCommon = function(id) {
        const event = $dataCommonEvents[id];
        if (event) {
            this.setupDynamicInterpreter(event.list);
        }
    };

    Game_Map.prototype.setupDynamicInterpreter = function(list) {
        const interpreter = new Game_Interpreter();
        interpreter.setup(list, 0);
        this._dynamicEvents.push(interpreter);
        this._dynamicEvents = this._dynamicEvents.filter(
            interpreter => interpreter.isRunning());
    };

    const _Game_Map_updateEvents = Game_Map.prototype.updateEvents;
    Game_Map.prototype.updateEvents = function() {
        _Game_Map_updateEvents.apply(this, arguments);
        this._dynamicEvents.forEach(interpreter => interpreter.update());
    };

    /**
     * Game_Event
     */
    Game_Event.prototype.findMeta = function(metaNames) {
        return PluginManagerEx.findMetaValue(this.event(), metaNames)
    };

    /**
     * Game_Interpreter
     */
    const _Game_Interpreter_setup = Game_Interpreter.prototype.setup;
    Game_Interpreter.prototype.setup = function(list, eventId) {
        _Game_Interpreter_setup.apply(this, arguments);
        if (eventId) {
            PluginManagerEx.generateSelfSwitchKey(eventId);
        }
    };
})();

repo_name: onms/sister

license: unknown


code:
//=============================================================================
// RTK_ActorTraits.js  ver 1.01 2016/08/03
// The MIT License (MIT)
//=============================================================================

/*:
 * @plugindesc Plugin commands to add traits against actors
 * @author Toshio Yamashita (yamachan)
 *
 * @help
 * Add plugin commands to add traits against actors.
 * Plugin commands:
 *  RTK_ActorTraits list	# List actors' current traits to the console
 *  RTK_ActorTraits add n {}	# Add {} trait against #n actor
 *  RTK_ActorTraits remove n {}	# Remove {} trait from #n actor
 *  RTK_ActorTraits clear n	# Remove #n actor's all addtional traits
 *  RTK_ActorTraits clear all	# Remove all actors' all addtional traits
 *
 * The prefix "n" shows the actor's id. This is a default, so you can omit it.
 * e.g. RTK_ActorTraits add n3 {} => Add {} trait against #3 actor
 *
 * The prefix "v" shows the game valiable. The value will be used as the actor #.
 * 例) RTK_ActorTraits add v10 {} => Add {} trait against the actor which is found by the game valiable #10.
 *
 * The prefix "p" shows the party member. The value will be used as the order # of the party member list.
 * 例) RTK_ActorTraits add p1 {} => Add {} trait against the 1st actor in the party.
 *
 * To know the correct trait object value {}, set the trait to an actor, then use "list" command
 * e.g. {"code":43,"dataId":13,"value":1} is to enable to use #13 skill
 * e.g. {"code":51,"dataId":7,"value":1} is to enable to equip #7 weapon
 * e.g. {"code":52,"dataId":3,"value":1} is to enable to equip #3 armor
 */

/*:ja
 * @plugindesc アクターに特徴を追加するプラグインコマンド
 * @author Toshio Yamashita (yamachan)
 *
 * @help
 * アクターに特徴を追加するプラグインコマンドを追加します。
 * プラグインコマンド:
 *  RTK_ActorTraits list	# 現在のアクターの特徴をコンソールにリスト表示する
 *  RTK_ActorTraits add n {}	# n番のアクターに {} の特徴を追加
 *  RTK_ActorTraits remove n {}	# n番のアクターから {} の特徴を削除
 *  RTK_ActorTraits clear n	# n番のアクターの特徴を初期状態に戻す
 *  RTK_ActorTraits clear all	# 全てのアクターの特徴を初期状態に戻す
 *
 * n番を示す数値の前に "n" を付与すると、その番号が対象アクターのIDになる
 * これはデフォルトの動作のためこの "n" は省略可能です
 * 例) RTK_ActorTraits add n3 {} は3番のアクターに {} の特徴を追加する
 *
 * n番を示す数値の前に "v" を付与すると、その番号が示すゲーム変数の値がアクターの番号になる
 * 例) RTK_ActorTraits add v10 {} は変数10番に入っている値が示すアクターに {} の特徴を追加する
 *
 * n番を示す数値の前に "p" を付与すると、パーティメンバーの n 番目のアクターが対象になる
 * 例) RTK_ActorTraits add p1 {} はパーティ先頭のアクターに {} の特徴を追加する
 *
 * 特徴を表現するオブジェクト {} は、いったんアクターに設定して list コマンドで調査してください
 * 例) {"code":43,"dataId":13,"value":1} は 13番のスキルを使えるようにする
 * 例) {"code":51,"dataId":7,"value":1} は 7番の種類の武器を装備できるようにする
 * 例) {"code":52,"dataId":3,"value":1} は 3番の種類の防具を装備できるようにする
 */

(function(_global) {
	var N = 'RTK_ActorTraits';
	var param = PluginManager.parameters(N);
	var backup = [];

	var _DataManager_extractSaveContents = DataManager.extractSaveContents;
	DataManager.extractSaveContents = function(contents) {
		var ret = _DataManager_extractSaveContents.call(this, contents);
		var list = $gameSystem[N]||[];
		for (var l=0; l<list.length; l++) {
			if (list[l] && list[l].length > 0) {
				if (!backup[l]) {
					backup[l] = $gameActors.actor(l).actor().traits.clone();
				}
				list[l].forEach(function(json){
					$gameActors.actor(l).actor().traits.push(JsonEx.parse(json));
				});
			}
		}
		return ret;
	};

	function convId(_s) {
		if (_s.match(/^\d+$/)) {
			return Number(_s) || 0;;
		}
		var ret = _s.match(/^n(\d+)$/i);
		if (ret) {
			return Number(ret[1]) || 0;
		}
		ret = _s.match(/^v(\d+)$/i);
		if (ret) {
			return $gameVariables.value(Number(ret[1]));
		}
		ret = _s.match(/^p(\d+)$/i);
		if (ret) {
			var actor = $gameParty.allMembers()[Number(ret[1]) - 1];
			if (actor) {
				return actor.actor().id
			}
		}
		return 0;
	}
	function clearTrait(_id) {
		if (_id > 0 && backup[_id]) {
			$gameActors.actor(_id).actor().traits = backup[_id];
			backup[_id] = undefined;
			var gsys = $gameSystem[N]||[];
			if (gsys[_id]) {
				gsys[_id] = undefined;
				$gameSystem[N] = gsys;
			}
		}
	}

	var _Game_Interpreter_pluginCommand = Game_Interpreter.prototype.pluginCommand;
	Game_Interpreter.prototype.pluginCommand = function(command, args) {
		_Game_Interpreter_pluginCommand.call(this, command, args);
		if (command == N) {
			if (args[0] == "list") {
				$gameParty.allMembers().forEach(function(actor){
					console.log(actor.name());
					actor.actor().traits.forEach(function(trait){
						console.log(JsonEx.stringify(trait));
					});
				});
			}
			if (args[0] == "add" && args.length > 2) {
				var id = convId(args[1]);
				var json = args.slice(2).join(" ");
				if (id > 0 && json != "") {
					var gsys = $gameSystem[N]||[];
					var dat = gsys[id]||[];
					if (!dat.contains(json)) {
						if (!backup[id]) {
							backup[id] = $gameActors.actor(id).actor().traits.clone();
						}
						dat.push(json);
						gsys[id] = dat;
						$gameSystem[N] = gsys;
						$gameActors.actor(id).actor().traits.push(JsonEx.parse(json));
					}
				}
			}
			if (args[0] == "remove" && args.length > 2) {
				var id = convId(args[1]);
				var json = args.slice(2).join(" ");
				if (id > 0 && json != "") {
					var gsys = $gameSystem[N]||[];
					var dat = gsys[id]||[];
					if (dat.contains(json)) {
						dat.splice(dat.indexOf(json),1);
						gsys[id] = dat.length == 0 ? undefined : dat;
						$gameSystem[N] = gsys;
						$gameActors.actor(id).actor().traits = $gameActors.actor(id).actor().traits.filter(function(o){
							return JsonEx.stringify(o) != json;
						});
					}
				}
			}
			if (args[0] == "clear" && args.length > 1) {
				if (args[1] == "all") {
					for (var l=1; l<backup.length; l++) {
						if (backup[l]) {
							clearTrait(l);
						}
					}
				} else {
					clearTrait(convId(args[1]));
				}
			}
		}
	};
})(this);


code:
//=============================================================================
// Plugin_Name : セルフスイッチの一括操作MV＆MZ
// File_Name   : RX_T_SelfSw_BatCtrl.js
// Version     : 1.01
// Copylight   : 2020 TYPE74RX-T
//=============================================================================

//=============================================================================
/*:
 * @target MZ
 * @plugindesc You will be able to operate the self-switch in batches.
 * @author TYPE74RX-T
 * @url https://w.atwiki.jp/type74rx-t/pages/221.html
 *
 * @command selfSwitches
 * @text Self-Switches
 * @desc You can operate the Self-Switch in batches.
 *
 * @arg events
 * @text Events
 * @desc Events where you want to operate the self-switch in batches
 * @default []
 * @type struct<RXSelfSwitch>[]
 *
 * @command selfSwitchesEX
 * @text Self-SwitchesEX
 * @desc Batch operate of the same type of self-switch(mostly manual input)Warning:Be careful not to let the configuration fail!
 *
 * @arg eventIDEX
 * @text [EX]Event ID
 * @desc Eligible event IDs. Multiple selections are possible.
 * For example:6, 4-33, 40, 64-72, 80
 * @type string
 *
 * @arg switchTypeEX
 * @text [EX]Self-Switch Type
 * @desc The type of self-switch.
 * You can also set other settings than A to D.
 * @type string
 *
 * @arg statusEX
 * @text Switch Status
 * @desc This is a self-switching state (ON/OFF).
 * @default false
 * @type boolean
 *
 * @arg mapIDEX
 * @text [Ex]MAP ID
 * @desc Eligible map IDs. Multiple selections are possible.
 * For example:1, 7, 13-24, 30
 * @type string
 *
 * @command getSelfSwitches
 * @text Get the Self-Switch infos
 * @desc Get the state of any self-switch as a game-variables.
 *
 * @arg getEventID
 * @text Event ID
 * @desc Eligible Event IDs.
 * @default 1
 * @min 1
 * @type number
 *
 * @arg getSwitchType
 * @text Self-Switch Type
 * @desc The type of self-switch.
 * You can also set other settings than A to D.
 * @type string
 *
 * @arg getMapID
 * @text Map ID
 * @desc Eligible Map IDs.
 * @default 1
 * @min 1
 * @type number
 *
 * @arg putSwitchID
 * @text Game Switches ID
 * @desc A switch ID to obtain the target self-switch information.
 * @default 1
 * @min 1
 * @type switch
 *
 * @help Batch operation of self-switch
 *
 * This plugin is compatible with RPG Maker MV and RPG Maker MZ.
 *
 * To use by MZ version, you need the official Plugin "CommonBase.js" plugin to use this plugin.
 * You need the official Plugin "CommonBase.js" plugin to use this plugin.
 * Stote:C:\Program Files\KADOKAWA\RPGMZ\dlc\BasicResources\plugins\official
 * Steam:C:\Program Files (x86)\Steam\steamapps\common\RPG Maker MZ\dlc\BasicResources\plugins\official
 *
 * ◆Summary
 * You will be able to operate the self-switch in batches.
 * You can also use the game-switch to get information on self-switch.
 *
 * ◆Plugin Command for MZ
 * Plugin File：RX_T_SelfSw_BatCtrl
 *
 * ★Self-Switches
 * Click "Events" under "Arguments".
 * When a new window appears, double-click on the blank space next to
 * the numbered field.
 * The event ID, self-switch type, switch state, and map ID are
 * specified respectively.
 * Do this operation as many times as you need.
 *
 * Sorry, but this parameter setting is only available in Japanese
 * due to programmatic reasons...
 *
 * ★Self-SwitchesEX
 * It's a little different from the way the above is set up.
 * Map IDs and event IDs are easier to specify, and self-switch types
 * other than A to D cann be specified (strings of two or more bytes
 * are also possible).
 * However, the self-switch type and switch state cannot be set
 * individually.
 * If you want to initialize the self-switch to a large extent, this
 * may be easier.
 * However, be very careful not to make a mistake in setting up the
 * self-switch, because it is mainly based on keyboard input.
 *
 * ★Get the Self-Switch infos
 * You can store the specified map ID, event ID, and self-switch
 * type status in the specified game switch.
 * It would be useful in a conditional branching event.
 *
 * ◆Plugin Command for MV
 * Example: If you want to turn on the self-switch B of events with a map ID of
 * 3, ID 3 to 5, and 7, set up as follows.
 *
 * rx_selfsw 3 3-5 7 B ON
 *
 * Open a space and don't separate them with a comma.
 * The first number is the map ID, the second from the end is the self-switch
 * type, the last is the switch state, and all others are recognized as event
 * IDs.
 * If you set the map ID to 0, it will automatically specify the map ID for the
 * event being edited.
 *
 * ◆License
 * This plugin is released under MIT license.
 * http://opensource.org/licenses/mit-license.php
*/
/*:ja
 * @target MZ
 * @plugindesc セルフスイッチを一括操作できるようになります。
 * @author TYPE74RX-T
 * @url https://mdc-light.jpn.org/TYPE74RX-T/
 *
 * @command selfSwitches
 * @text セルフスイッチ
 * @desc セルフスイッチを一括操作できます。
 *
 * @arg events
 * @text イベント
 * @desc セルフスイッチを一括操作したいイベント
 * @default []
 * @type struct<RXSelfSwitch>[]
 *
 * @command selfSwitchesEX
 * @text セルフスイッチEX
 * @desc 同種セルフスイッチの一括操作（ほぼ手入力）
 * 【設定ミスにご注意ください。】
 *
 * @arg eventIDEX
 * @text [EX]イベントID
 * @desc 対象となるイベントIDです。こちらは複数選択可能です。
 * 例：2, 4-8, 11, 21-25, 37, 56, 48
 * @type string
 *
 * @arg switchTypeEX
 * @text [EX]セルフスイッチタイプ
 * @desc セルフスイッチの種類です。
 * こちらはA～D以外も設定可能です。
 * @type string
 *
 * @arg statusEX
 * @text スイッチ状態
 * @desc セルフスイッチの状態です（ON/OFF）。
 * @default false
 * @type boolean
 *
 * @arg mapIDEX
 * @text [Ex]マップID
 * @desc 対象となるマップIDです。こちらは複数選択可能です。
 * 例：1-4, 5, 14, 59-63
 * @type string
 *
 * @command getSelfSwitches
 * @text セルフスイッチ情報取得
 * @desc 任意のセルフスイッチの状態を
 * 変数で取得します。
 *
 * @arg getEventID
 * @text イベントID
 * @desc 対象となるイベントIDです。
 * @default 1
 * @min 1
 * @type number
 *
 * @arg getSwitchType
 * @text セルフスイッチタイプ
 * @desc セルフスイッチの種類です。
 * こちらはA～D以外も設定可能です。
 * @type string
 *
 * @arg getMapID
 * @text マップID
 * @desc 対象となるマップIDです。
 * @default 1
 * @min 1
 * @type number
 *
 * @arg putSwitchID
 * @text ゲームスイッチID
 * @desc 対象のセルフスイッチ情報を取得するための
 * スイッチIDです。
 * @default 1
 * @min 1
 * @type switch
 *
 * @help セルフスイッチの一括操作MV＆MZ
 *
 * このプラグインはRPGツクールMV、RPGツクールMZに対応しています。
 *
 * MZ版でのご利用には公式プラグインの「PluginCommonBase.js」が必要です。
 * Stote:C:\Program Files\KADOKAWA\RPGMZ\dlc\BasicResources\plugins\official
 * Steam:C:\Program Files (x86)\Steam\steamapps\common\RPG Maker MZ\dlc\BasicResources\plugins\official
 *
 * ◆概要
 * セルフスイッチの一括操作できるようになります。
 * また、セルフスイッチの情報をゲームスイッチで取得することもできます。
 *
 * ◆プラグインコマンド（MZ）
 * プラグインファイル：RX_T_SelfSw_BatCtrl
 *
 * ★セルフスイッチ
 * 「引数」の「イベント」をクリックします。
 * 新しいウィンドウが現れたら、番号が振られた欄の横にある空白を
 * ダブルクリックします。
 * イベントID、セルフスイッチタイプ、スイッチ状態、マップIDを
 * それぞれ指定します。
 * この操作を必要な数だけ行います。
 *
 * ★セルフスイッチEX
 * 上記の設定方法とは少し異なります。
 * マップID、イベントIDは指定しやすくなり、セルフスイッチタイプも
 * A～D以外（文字列でも可能）のものになりますが
 * セルフスイッチタイプとスイッチ状態は個別設定できません。
 * 大幅な範囲でセルフスイッチを初期化する場合は
 * こちらの方が手軽かもしれません。
 * ただし、キーボード入力が主体になりますので
 * 設定ミスには充分に注意してください。
 *
 * ★セルフスイッチ情報取得
 * こちらは指定したマップID、イベントID、セルフスイッチタイプの
 * 状態を指定したゲームスイッチに格納することができます。
 * 条件分岐イベントにお役立てください。
 *
 * ◆プラグインコマンド（MV）
 * 例：マップIDが3で、イベントID3～5番、そして7番のセルフスイッチBを
 * ONにしたい場合は以下のように設定します。
 *
 * rx_selfsw 3 3-5 7 B ON
 *
 * カンマで区切らずスペースを開けて設定します。
 * 数値の先頭がマップID、末尾から二番目はセルフスイッチのタイプ
 * 末尾はスイッチの状態、その他はすべてイベントIDとして認識します。
 * マップIDを0に設定すると、自動的にイベント編集中のマップIDを指定します。
 *
 * ◆ライセンス
 * このプラグインはMITライセンスで公開されています。
 * http://opensource.org/licenses/mit-license.php
*/
/*~struct~RXSelfSwitch:
 *
 * @param eventID
 * @text Event ID
 * @desc Target Event ID
 * @default 1
 * @min 1
 * @type number
 *
 * @param switchType
 * @text Self-Switch Type
 * @desc Self-Switch Type; A～D
 * @default A
 * @type select
 * @option A
 * @value A
 * @option B
 * @value B
 * @option C
 * @value C
 * @option D
 * @value D
 *
 * @param status
 * @text SwitchState
 * @desc Self-Switch Status; ON/OFF
 * Self-Switch Status
 * @default false
 * @type boolean
 *
 * @param mapID
 * @text Map ID
 * @desc Target Map ID
 * @default 1
 * @min 1
 * @type number
 */
/*~struct~RXSelfSwitch:ja
 *
 * @param eventID
 * @text イベントID
 * @desc 対象となるイベントIDです。
 * @default 1
 * @min 1
 * @type number
 *
 * @param switchType
 * @text セルフスイッチタイプ
 * @desc セルフスイッチの種類です（A～D）。
 * @default A
 * @type select
 * @option A
 * @value A
 * @option B
 * @value B
 * @option C
 * @value C
 * @option D
 * @value D
 *
 * @param status
 * @text スイッチ状態
 * @desc セルフスイッチの状態です（ON/OFF）。
 * @default false
 * @type boolean
 *
 * @param mapID
 * @text マップID
 * @desc 対象となるマップIDです。
 * @default 1
 * @min 1
 * @type number
 */

(() => {
	'use strict';
    const script = document.currentScript;

    if (PluginManager._commands !== undefined) {
        //PluginManager
        PluginManagerEx.registerCommand(script, "selfSwitches", args => {
            const rx_selfSwParams = args.events
            let imax = rx_selfSwParams.length
            let rx_key = [];
            for (let i = 0; i < imax; i++){
                rx_key = [rx_selfSwParams[i].mapID, rx_selfSwParams[i].eventID, rx_selfSwParams[i].switchType];
                $gameSelfSwitches.setValue(rx_key, rx_selfSwParams[i].status === true);
            }
        });
        PluginManager.registerCommand("RX_T_SelfSw_BatCtrl", "selfSwitchesEX", args => {
            let rx_key = [];
            let rx_mapID = [];
            let rx_evID = [];
            let rx_sswType = args.switchTypeEX;
            let rx_sswState = args.statusEX;
            let rx_getEX = args.mapIDEX.split(',');
            for (let i = 0; i < rx_getEX.length; i++){
                if (rx_getEX[i].indexOf('-') > -1){
                    let k = rx_getEX[i].split('-');
                    for(let j = parseInt(k[0]); j <= parseInt(k[1]); j++){
                        rx_mapID.push(j);
                    }
                }else{
                    rx_mapID.push(parseInt(rx_getEX[i]));
                }
            }
            rx_getEX = args.eventIDEX.split(',');
            for (let i = 0; i < rx_getEX.length; i++){
                if (rx_getEX[i].indexOf('-') > -1){
                    let k = rx_getEX[i].split('-');
                    for(let j = parseInt(k[0]); j <= parseInt(k[1]); j++){
                        rx_evID.push(j);
                    }
                }else{
                    rx_evID.push(parseInt(rx_getEX[i]));
                }
            }
            for (let i = 0; i < rx_mapID.length; i++){
                for (let j = 0; j < rx_evID.length; j++){
                    rx_key = [rx_mapID[i], rx_evID[j], rx_sswType];
                    $gameSelfSwitches.setValue(rx_key, rx_sswState === "true");
                }
            }
        });
        PluginManager.registerCommand("RX_T_SelfSw_BatCtrl", "getSelfSwitches", args => {
            let rx_key = [];
            let rx_mapID = args.getMapID;
            let rx_evID = args.getEventID;
            let rx_sswType = args.getSwitchType;
            let rx_putSwitchID = args.putSwitchID;
            rx_key = [rx_mapID, rx_evID, rx_sswType];
            $gameSwitches.setValue(rx_putSwitchID, $gameSelfSwitches.value(rx_key));
        });
    } else {
        //Game_Interpreter
        const rx_t_gipc200916_pluginCommand = Game_Interpreter.prototype.pluginCommand;
        Game_Interpreter.prototype.pluginCommand = function(command, args) {
            rx_t_gipc200916_pluginCommand.call(this, command, args);
            if (command === 'rx_selfsw') {
                console.log(args);
                const rx_sswType = args[args.length - 2];
                const rx_sswState = args[args.length - 1] === "ON" ? true : false;
                const rx_mapID = parseInt(args[0]) < 1 ? $gameMap._mapId : parseInt(args[0]);
                let rx_evID = [];
                let rx_key = [];
                for (let i = 1; i <= args.length - 3; i++){
                    if (args[i].indexOf('-') > -1){
                        let k = args[i].split('-');
                        for(let j = parseInt(k[0]); j <= parseInt(k[1]); j++){
                            rx_evID.push(parseInt(j));
                        }
                    }else{
                        rx_evID.push(parseInt(args[i]));
                    }
                }
                for (let i = 0; i < rx_evID.length; i++){
                    rx_key = [rx_mapID, rx_evID[i], rx_sswType];
                    $gameSelfSwitches.setValue(rx_key, rx_sswState === true);
                }
            }
        };
    }
})();