code:
//=============================================================================
// ItemBook.js
//=============================================================================

/*:
 * @plugindesc Displays detailed statuses of items.
 * @author Yoji Ojima
 *
 * @param Unknown Data
 * @desc The index name for an unknown item.
 * @default ??????
 *
 * @param Price Text
 * @desc The text for "Price".
 * @default Price
 *
 * @param Equip Text
 * @desc The text for "Equip".
 * @default Equip
 *
 * @param Type Text
 * @desc The text for "Type".
 * @default Type
 *
 * @help
 *
 * Plugin Command:
 *   ItemBook open            # Open the item book screen
 *   ItemBook add weapon 3    # Add weapon #3 to the item book
 *   ItemBook add armor 4     # Add armor #4 to the item book
 *   ItemBook remove armor 5  # Remove armor #5 from the item book
 *   ItemBook remove item 6   # Remove item #6 from the item book
 *   ItemBook complete        # Complete the item book
 *   ItemBook clear           # Clear the item book
 *
 * Item (Weapon, Armor) Note:
 *   <book:no>                # This item does not appear in the item book
 */

/*:ja
 * @plugindesc アイテム図鑑です。アイテムの詳細なステータスを表示します。
 * @author Yoji Ojima
 *
 * @param Unknown Data
 * @desc 未確認のアイテムの索引名です。
 * @default ？？？？？？
 *
 * @param Price Text
 * @desc 「価格」の文字列です。
 * @default 価格
 *
 * @param Equip Text
 * @desc 「装備」の文字列です。
 * @default 装備
 *
 * @param Type Text
 * @desc 「タイプ」の文字列です。
 * @default タイプ
 *
 * @help
 *
 * プラグインコマンド:
 *   ItemBook open            # 図鑑画面を開く
 *   ItemBook add weapon 3    # 武器３番を図鑑に追加
 *   ItemBook add armor 4     # 防具４番を図鑑に追加
 *   ItemBook remove armor 5  # 防具５番を図鑑から削除
 *   ItemBook remove item 6   # アイテム６番を図鑑から削除
 *   ItemBook complete        # 図鑑を完成させる
 *   ItemBook clear           # 図鑑をクリアする
 *
 * アイテム（武器、防具）のメモ:
 *   <book:no>                # 図鑑に載せない場合
 */

(function() {

    var parameters = PluginManager.parameters('ItemBook');
    var unknownData = String(parameters['Unknown Data'] || '??????');
    var priceText = String(parameters['Price Text'] || 'Price');
    var equipText = String(parameters['Equip Text'] || 'Equip');
    var typeText = String(parameters['Type Text'] || 'Type');

    var _Game_Interpreter_pluginCommand =
            Game_Interpreter.prototype.pluginCommand;
    Game_Interpreter.prototype.pluginCommand = function(command, args) {
        _Game_Interpreter_pluginCommand.call(this, command, args);
        if (command === 'ItemBook') {
            switch (args[0]) {
            case 'open':
                SceneManager.push(Scene_ItemBook);
                break;
            case 'add':
                $gameSystem.addToItemBook(args[1], Number(args[2]));
                break;
            case 'remove':
                $gameSystem.removeFromItemBook(args[1], Number(args[2]));
                break;
            case 'complete':
                $gameSystem.completeItemBook();
                break;
            case 'clear':
                $gameSystem.clearItemBook();
                break;
            }
        }
    };

    Game_System.prototype.addToItemBook = function(type, dataId) {
        if (!this._ItemBookFlags) {
            this.clearItemBook();
        }
        var typeIndex = this.itemBookTypeToIndex(type);
        if (typeIndex >= 0) {
            this._ItemBookFlags[typeIndex][dataId] = true;
        }
    };

    Game_System.prototype.removeFromItemBook = function(type, dataId) {
        if (this._ItemBookFlags) {
            var typeIndex = this.itemBookTypeToIndex(type);
            if (typeIndex >= 0) {
                this._ItemBookFlags[typeIndex][dataId] = false;
            }
        }
    };

    Game_System.prototype.itemBookTypeToIndex = function(type) {
        switch (type) {
        case 'item':
            return 0;
        case 'weapon':
            return 1;
        case 'armor':
            return 2;
        default:
            return -1;
        }
    };

    Game_System.prototype.completeItemBook = function() {
        var i;
        this.clearItemBook();
        for (i = 1; i < $dataItems.length; i++) {
            this._ItemBookFlags[0][i] = true;
        }
        for (i = 1; i < $dataWeapons.length; i++) {
            this._ItemBookFlags[1][i] = true;
        }
        for (i = 1; i < $dataArmors.length; i++) {
            this._ItemBookFlags[2][i] = true;
        }
    };

    Game_System.prototype.clearItemBook = function() {
        this._ItemBookFlags = [[], [], []];
    };

    Game_System.prototype.isInItemBook = function(item) {
        if (this._ItemBookFlags && item) {
            var typeIndex = -1;
            if (DataManager.isItem(item)) {
                typeIndex = 0;
            } else if (DataManager.isWeapon(item)) {
                typeIndex = 1;
            } else if (DataManager.isArmor(item)) {
                typeIndex = 2;
            }
            if (typeIndex >= 0) {
                return !!this._ItemBookFlags[typeIndex][item.id];
            } else {
                return false;
            }
        } else {
            return false;
        }
    };

    var _Game_Party_gainItem = Game_Party.prototype.gainItem;
    Game_Party.prototype.gainItem = function(item, amount, includeEquip) {
        _Game_Party_gainItem.call(this, item, amount, includeEquip);
        if (item && amount > 0) {
            var type;
            if (DataManager.isItem(item)) {
                type = 'item';
            } else if (DataManager.isWeapon(item)) {
                type = 'weapon';
            } else if (DataManager.isArmor(item)) {
                type = 'armor';
            }
            $gameSystem.addToItemBook(type, item.id);
        }
    };

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

    Scene_ItemBook.prototype = Object.create(Scene_MenuBase.prototype);
    Scene_ItemBook.prototype.constructor = Scene_ItemBook;

    Scene_ItemBook.prototype.initialize = function() {
        Scene_MenuBase.prototype.initialize.call(this);
    };

    Scene_ItemBook.prototype.create = function() {
        Scene_MenuBase.prototype.create.call(this);
        this._indexWindow = new Window_ItemBookIndex(0, 0);
        this._indexWindow.setHandler('cancel', this.popScene.bind(this));
        var wy = this._indexWindow.height;
        var ww = Graphics.boxWidth;
        var wh = Graphics.boxHeight - wy;
        this._statusWindow = new Window_ItemBookStatus(0, wy, ww, wh);
        this.addWindow(this._indexWindow);
        this.addWindow(this._statusWindow);
        this._indexWindow.setStatusWindow(this._statusWindow);
    };

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

    Window_ItemBookIndex.prototype = Object.create(Window_Selectable.prototype);
    Window_ItemBookIndex.prototype.constructor = Window_ItemBookIndex;

    Window_ItemBookIndex.lastTopRow = 0;
    Window_ItemBookIndex.lastIndex  = 0;

    Window_ItemBookIndex.prototype.initialize = function(x, y) {
        var width = Graphics.boxWidth;
        var height = this.fittingHeight(6);
        Window_Selectable.prototype.initialize.call(this, x, y, width, height);
        this.refresh();
        this.setTopRow(Window_ItemBookIndex.lastTopRow);
        this.select(Window_ItemBookIndex.lastIndex);
        this.activate();
    };

    Window_ItemBookIndex.prototype.maxCols = function() {
        return 3;
    };

    Window_ItemBookIndex.prototype.maxItems = function() {
        return this._list ? this._list.length : 0;
    };

    Window_ItemBookIndex.prototype.setStatusWindow = function(statusWindow) {
        this._statusWindow = statusWindow;
        this.updateStatus();
    };

    Window_ItemBookIndex.prototype.update = function() {
        Window_Selectable.prototype.update.call(this);
        this.updateStatus();
    };

    Window_ItemBookIndex.prototype.updateStatus = function() {
        if (this._statusWindow) {
            var item = this._list[this.index()];
            this._statusWindow.setItem(item);
        }
    };

    Window_ItemBookIndex.prototype.refresh = function() {
        var i, item;
        this._list = [];
        for (i = 1; i < $dataItems.length; i++) {
            item = $dataItems[i];
            if (item.name && item.itypeId === 1 && item.meta.book !== 'no') {
                this._list.push(item);
            }
        }
        for (i = 1; i < $dataWeapons.length; i++) {
            item = $dataWeapons[i];
            if (item.name && item.meta.book !== 'no') {
                this._list.push(item);
            }
        }
        for (i = 1; i < $dataArmors.length; i++) {
            item = $dataArmors[i];
            if (item.name && item.meta.book !== 'no') {
                this._list.push(item);
            }
        }
        this.createContents();
        this.drawAllItems();
    };

    Window_ItemBookIndex.prototype.drawItem = function(index) {
        var item = this._list[index];
        var rect = this.itemRect(index);
        var width = rect.width - this.textPadding();
        if ($gameSystem.isInItemBook(item)) {
            this.drawItemName(item, rect.x, rect.y, width);
        } else {
            var iw = Window_Base._iconWidth + 4;
            this.drawText(unknownData, rect.x + iw, rect.y, width - iw);
        }
    };

    Window_ItemBookIndex.prototype.processCancel = function() {
        Window_Selectable.prototype.processCancel.call(this);
        Window_ItemBookIndex.lastTopRow = this.topRow();
        Window_ItemBookIndex.lastIndex = this.index();
    };

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

    Window_ItemBookStatus.prototype = Object.create(Window_Base.prototype);
    Window_ItemBookStatus.prototype.constructor = Window_ItemBookStatus;

    Window_ItemBookStatus.prototype.initialize = function(x, y, width, height) {
        Window_Base.prototype.initialize.call(this, x, y, width, height);
    };

    Window_ItemBookStatus.prototype.setItem = function(item) {
        if (this._item !== item) {
            this._item = item;
            this.refresh();
        }
    };

    Window_ItemBookStatus.prototype.refresh = function() {
        var item = this._item;
        var x = 0;
        var y = 0;
        var lineHeight = this.lineHeight();

        this.contents.clear();

        if (!item || !$gameSystem.isInItemBook(item)) {
            return;
        }

        this.drawItemName(item, x, y);

        x = this.textPadding();
        y = lineHeight + this.textPadding();

        var price = item.price > 0 ? item.price : '-';
        this.changeTextColor(this.systemColor());
        this.drawText(priceText, x, y, 120);
        this.resetTextColor();
        this.drawText(price, x + 120, y, 120, 'right');
        y += lineHeight;

        if (DataManager.isWeapon(item) || DataManager.isArmor(item)) {
            var etype = $dataSystem.equipTypes[item.etypeId];
            this.changeTextColor(this.systemColor());
            this.drawText(equipText, x, y, 120);
            this.resetTextColor();
            this.drawText(etype, x + 120, y, 120, 'right');
            y += lineHeight;

            var type;
            if (DataManager.isWeapon(item)) {
                type = $dataSystem.weaponTypes[item.wtypeId];
            } else {
                type = $dataSystem.armorTypes[item.atypeId];
            }
            this.changeTextColor(this.systemColor());
            this.drawText(typeText, x, y, 120);
            this.resetTextColor();
            this.drawText(type, x + 120, y, 120, 'right');

            x = this.textPadding() + 300;
            y = lineHeight + this.textPadding();
            for (var i = 2; i < 8; i++) {
                this.changeTextColor(this.systemColor());
                this.drawText(TextManager.param(i), x, y, 160);
                this.resetTextColor();
                this.drawText(item.params[i], x + 160, y, 60, 'right');
                y += lineHeight;
            }
        }

        x = 0;
        y = this.textPadding() * 2 + lineHeight * 7;
        this.drawTextEx(item.description, x, y);
    };

})();


code:
//=============================================================================
// KMS_AltGauge.js
//  last update: 2017/01/14
//=============================================================================

/*:
 * @plugindesc
 * [v0.2.0] Display alternative gauge.
 *
 * @author TOMY (Kamesoft)
 *
 * @param HP gauge image
 * @default GaugeHP
 * @require 1
 * @dir img/system/
 * @type file
 * @desc HP gauge image. Load from 'img/system'.
 *
 * @param HP gauge config
 * @default -31, -2, -4, 30
 * @desc
 * Specify HP gauge position/width/angle.
 * Format: X, Y, Width, Angle (deg)
 *
 * @param MP gauge image
 * @default GaugeMP
 * @require 1
 * @dir img/system/
 * @type file
 * @desc MP gauge image. Load from 'img/system'.
 *
 * @param MP gauge config
 * @default -31, -2, -4, 30
 * @desc
 * Specify MP gauge position/width/angle.
 * Format: X, Y, Width, Angle (deg)
 *
 * @param TP gauge image
 * @default GaugeTP
 * @require 1
 * @dir img/system/
 * @type file
 * @desc TP gauge image. Load from 'img/system'.
 *
 * @param TP gauge config
 * @default -31, -2, -4, 30
 * @desc
 * Specify TP gauge position/width/angle.
 * Format: X, Y, Width, Angle (deg)
 *
 * @param EXP gauge image
 * @default GaugeEXP
 * @require 1
 * @dir img/system/
 * @type file
 * @desc EXP gauge image. Load from 'img/system'.
 *
 * @param EXP gauge config
 * @default -31, -2, -4, 30
 * @desc
 * Specify EXP gauge position/width/angle.
 * Format: X, Y, Width, Angle (deg)
 *
 * @param Use exp gauge
 * @default 1
 * @desc 0: Hide exp gauge  1: Show exp gauge
 *
 * @help This plugin does not provide plugin commands.
 */

/*:ja
 * @plugindesc
 * [v0.2.0] 画像を使用した汎用のゲージです。
 *
 * @author TOMY (Kamesoft)
 *
 * @param HP gauge image
 * @default GaugeHP
 * @require 1
 * @dir img/system/
 * @type file
 * @desc HP ゲージ画像です。'img/system' から読み込みます。
 *
 * @param HP gauge config
 * @default -31, -2, -4, 30
 * @desc
 * HP ゲージの位置、幅、傾き (度) を指定します。
 * 書式: X, Y, 幅, 傾き
 *
 * @param MP gauge image
 * @default GaugeMP
 * @require 1
 * @dir img/system/
 * @type file
 * @desc MP ゲージ画像です。'img/system' から読み込みます。
 *
 * @param MP gauge config
 * @default -31, -2, -4, 30
 * @desc
 * MP ゲージの位置、幅、傾き (度) を指定します。
 * 書式: X, Y, 幅, 傾き
 *
 * @param TP gauge image
 * @default GaugeTP
 * @require 1
 * @dir img/system/
 * @type file
 * @desc TP ゲージ画像です。'img/system' から読み込みます。
 *
 * @param TP gauge config
 * @default -31, -2, -4, 30
 * @desc
 * TP ゲージの位置、幅、傾き (度) を指定します。
 * 書式: X, Y, 幅, 傾き
 *
 * @param EXP gauge image
 * @default GaugeEXP
 * @require 1
 * @dir img/system/
 * @type file
 * @desc EXP ゲージ画像です。'img/system' から読み込みます。
 *
 * @param EXP gauge config
 * @default -31, -2, -4, 30
 * @desc
 * EXP ゲージの位置、幅、傾き (度) を指定します。
 * 書式: X, Y, 幅, 傾き
 *
 * @param Use exp gauge
 * @default 1
 * @desc
 * EXP ゲージを表示するか指定します。
 * 0: 表示しない  1: 表示する
 *
 * @help このプラグインには、プラグインコマンドはありません。
 */

(function()
{

var parseConfig = function(param)
{
    var configReg = /([-]?\d+),\s*([-]?\d+),\s*([-]?\d+),\s*([-]?\d+)/;
    var DefaultGaugeConfig = { x: -31, y: -2, width: -4, angle: 30 };
    var config = {
        x: DefaultGaugeConfig.x,
        y: DefaultGaugeConfig.y,
        width: DefaultGaugeConfig.width,
        angle: DefaultGaugeConfig.angle
    };

    var match = configReg.exec(pluginParams[param]);
    if (match)
    {
        config.x = Number(match[1]);
        config.y = Number(match[2]);
        config.width = Number(match[3]);
        config.angle = Number(match[4]);
    }

    return config;
}

var pluginParams = PluginManager.parameters('KMS_AltGauge');
var Params = {};
Params.imageDir = pluginParams['Image dir'] || 'img/system/';
Params.isEnableExp = Number(pluginParams['Use exp gauge'] || 1);
Params.gaugeImage = {};
Params.gaugeImage.hp = pluginParams['HP gauge image'];
Params.gaugeImage.mp = pluginParams['MP gauge image'];
Params.gaugeImage.tp = pluginParams['TP gauge image'];
Params.gaugeImage.exp = pluginParams['EXP gauge image'];
Params.gaugeConfig = {};
Params.gaugeConfig.hp = parseConfig('HP gauge config');
Params.gaugeConfig.mp = parseConfig('MP gauge config');
Params.gaugeConfig.tp = parseConfig('TP gauge config');
Params.gaugeConfig.exp = parseConfig('EXP gauge config');

var GaugeImageKeys = ['hp', 'mp', 'tp', 'exp'];

//-----------------------------------------------------------------------------
// Bitmap

Bitmap.prototype.skewBlt = function(source, slope, sx, sy, sw, sh, dx, dy, dw)
{
    slope.clamp(-90, 90);
    var offset = sh / Math.tan(Math.PI * (90 - Math.abs(slope)) / 180.0);
    var diff = offset / sh;
    if (slope >= 0)
    {
        dx += Math.round(offset);
        diff = -diff;
    }

    for (var i = 0; i < sh; ++i)
    {
        this.blt(source, sx, sy + i, sw, 1, dx + Math.round(diff * i), dy + i, dw);
    }
};

//-----------------------------------------------------------------------------
// Game_Actor

Game_Actor.prototype.nextExpRate = function()
{
    var diff = Math.max(this.nextLevelExp() - this.currentLevelExp(), 1);
    var rest = Math.max(this.nextRequiredExp(), 1);
    return (diff - rest) / diff;
};

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

var _KMS_AltGauge_Window_Base_initialize = Window_Base.prototype.initialize;
Window_Base.prototype.initialize = function(x, y, width, height)
{
    _KMS_AltGauge_Window_Base_initialize.call(this, x, y, width, height);
    this.loadGaugeImages();
};

Window_Base.prototype.loadGaugeImages = function()
{
    GaugeImageKeys.forEach(function(key)
    {
        this.getGaugeImage(key);
    }, this);
};

Window_Base.prototype.getGaugeImage = function(gaugeType)
{
    if (Params.gaugeImage[gaugeType])
    {
//2021 1025追記 メニュー画面では別のUIを利用する
    	if(gaugeType=="tp" && SceneManager._scene.constructor === Scene_Menu){
	        return ImageManager.loadBitmap(Params.imageDir, "GaugeTP2");
	    }else if(gaugeType=="tp" && SceneManager._scene.constructor === Scene_Item){
	        return ImageManager.loadBitmap(Params.imageDir, "GaugeTP2");
	    }else{
	        return ImageManager.loadBitmap(Params.imageDir, Params.gaugeImage[gaugeType]);
	    }
    }
    else
    {
        return ImageManager.loadEmptyBitmap();
    }
};

Window_Base.prototype.drawKmsGauge = function(x, y, width, rate, gaugeType)
{
    var config = Params.gaugeConfig[gaugeType];
    x += config.x;
    y += config.y;
    width += config.width;

    var grid = 32;
    var fillW = Math.floor(width * rate);
    var bitmap = this.getGaugeImage(gaugeType);
    var gaugeW = bitmap.width / 2;
    var gaugeH = bitmap.height / 3;
    var gaugeY = y + this.lineHeight() - gaugeH - 2;

    // 背景

    if(SceneManager._scene.constructor !== Scene_Menu && gaugeType=="tp"){
		if(SceneManager._scene.constructor === Scene_Item && gaugeType=="tp"){
		    width= 200;
	        fillW = Math.floor(width * rate);
		    y = 70

	   	 	this.contents.skewBlt(bitmap, config.angle, 0, 0, grid, gaugeH, x, gaugeY);
	    	this.contents.skewBlt(bitmap, config.angle, grid, 0, gaugeW, gaugeH, x + grid, gaugeY, width);
	   	 	this.contents.skewBlt(bitmap, config.angle, grid + gaugeW, 0, grid, gaugeH, x + width + grid, gaugeY);

	   	 	// 本体
	   	 	var gw = gaugeW * fillW / width;
	   	 	this.contents.skewBlt(bitmap, config.angle, 0, gaugeH, gw, gaugeH, x + grid, gaugeY, fillW);
		}else{
		    x-=60;
		    width= 608-32;
	        gaugeW = bitmap.width-32;
	        fillW = Math.floor(width * rate);
	    	var gw = gaugeW * fillW / width;

	    	//ゲージの中身を消す処理（不具合が起きたら消してもいい）
	    	var clearX = x;
	    	var clearY = y;
	    	var clearWidth = width+32;
	    	var clearHeight = 32;
	    	this.contents.clearRect(clearX, clearY, clearWidth, clearHeight);

	    	//ゲージの中身
	    	this.contents.skewBlt(bitmap, config.angle, 0, gaugeH, gw, gaugeH, x+32, gaugeY, fillW);
	    	this.contents.skewBlt(bitmap, config.angle, 0, 0, gaugeW, gaugeH, x, gaugeY,width+32);
	    }
	}else{
   	 	this.contents.skewBlt(bitmap, config.angle, 0, 0, grid, gaugeH, x, gaugeY);
    	this.contents.skewBlt(bitmap, config.angle, grid, 0, gaugeW, gaugeH, x + grid, gaugeY, width);
   	 	this.contents.skewBlt(bitmap, config.angle, grid + gaugeW, 0, grid, gaugeH, x + width + grid, gaugeY);

   	 	// 本体
   	 	var gw = gaugeW * fillW / width;
   	 	this.contents.skewBlt(bitmap, config.angle, 0, gaugeH, gw, gaugeH, x + grid, gaugeY, fillW);
	}
};

if (Params.isEnableExp)
{
    var _KMS_AltGauge_Window_Base_drawActorLevel = Window_Base.prototype.drawActorLevel;
    Window_Base.prototype.drawActorLevel = function(actor, x, y, showGauge)
    {
        if (showGauge)
        {
            var width = 120;
            this.drawKmsGauge(x, y, width, actor.nextExpRate(), 'exp');
        }

        _KMS_AltGauge_Window_Base_drawActorLevel.call(this, actor, x, y);
    };
}

Window_Base.prototype.drawActorHp = function(actor, x, y, width)
{
    width = width || 186;

    //リリィの体力は変数で管理するため分岐(メニュー画面の表記は廃止20230825)
    if(actor._actorId == 2){
	    //this.drawKmsGauge(x, y, width, $gameVariables.value(122)/$gameVariables.value(123), 'hp');
    	//this.changeTextColor(this.systemColor());
	    //this.drawText(TextManager.hpA, x, y, 44);
    	//this.drawCurrentAndMax($gameVariables.value(122), $gameVariables.value(123), x, y, width,this.hpColor(actor), this.normalColor());
	}else{
	    this.drawKmsGauge(x, y, width, actor.hpRate(), 'hp');
    	this.changeTextColor(this.systemColor());
	    this.drawText(TextManager.hpA, x, y, 44);
    	this.drawCurrentAndMax(actor.hp, actor.mhp, x, y, width,this.hpColor(actor), this.normalColor());
	}
};

Window_Base.prototype.drawActorMp = function(actor, x, y, width)
{
    width = width || 186;
    this.drawKmsGauge(x, y, width, actor.mpRate(), 'mp');
    this.changeTextColor(this.systemColor());
    this.drawText(TextManager.mpA, x, y, 44);
    this.drawCurrentAndMax(actor.mp, actor.mmp, x, y, width,
                           this.mpColor(actor), this.normalColor());
};

Window_Base.prototype.drawActorTp = function(actor, x, y, width)
{
    width = width || 96;
    this.drawKmsGauge(x+110, y+2, width-110, actor.tpRate(), 'tp');
    this.changeTextColor(this.systemColor());
    //this.drawText(TextManager.tpA, x, y, 120);
    this.changeTextColor(this.tpColor(actor));
    //↓コメントアウトを外せば描画されるけどactor.tpの表示が重なってしまう
    //2021 1025 メニュー画面では数値が表示されるように処理
    if(SceneManager._scene.constructor === Scene_Menu){
	    this.drawTextEx("\\fs[20]" + actor.tp + "/" + $gameVariables.value(82) +"\\fs[0]", x + width - 104, y+9, 480, 'right');
	}
    if(SceneManager._scene.constructor === Scene_Item){
    	this.changeTextColor(this.systemColor());
    	this.drawText(TextManager.tpA, x, y, 120);
	    this.drawTextEx("\\fs[20]" + actor.tp + "/" + $gameVariables.value(82) +"\\fs[28]", x + width + 120, y+9, 480, 'right');
	}
};

Window_Base.prototype.drawActorNextExp = function(actor, x, y, width)
{
    width = width || 270;
    this.drawKmsGauge(x, y, width, actor.nextExpRate(), 'exp');
    this.changeTextColor(this.normalColor());
    var value = actor.isMaxLevel() ? '-------' : actor.nextRequiredExp();
    this.drawText(value, x, y, width, 'right');
};

if (Params.isEnableExp)
{
    Window_Base.prototype.drawActorSimpleStatus = function(actor, x, y, width)
    {
        var lineHeight = this.lineHeight();
        var x2 = x + 180;
        var width2 = Math.min(200, width - 180 - this.textPadding());
        this.drawActorName(actor, x, y);
        this.drawActorLevel(actor, x, y + lineHeight * 1, true);
        this.drawActorIcons(actor, x, y + lineHeight * 2);
        this.drawActorClass(actor, x2, y);
        this.drawActorHp(actor, x2, y + lineHeight * 1, width2);
        this.drawActorMp(actor, x2, y + lineHeight * 2, width2);
    };
}

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

if (Params.isEnableExp)
{
    Window_Status.prototype.drawExpInfo = function(x, y)
    {
        var lineHeight = this.lineHeight();
        var expTotal = TextManager.expTotal.format(TextManager.exp);
        var expNext = TextManager.expNext.format(TextManager.level);
        var value = this._actor.currentExp();
        if (this._actor.isMaxLevel())
        {
            value = '-------';
        }
        this.changeTextColor(this.systemColor());
        this.drawText(expTotal, x, y + lineHeight * 0, 270);
        this.drawText(expNext, x, y + lineHeight * 2, 270);
        this.resetTextColor();
        this.drawText(value, x, y + lineHeight * 1, 270, 'right');
        this.drawActorNextExp(this._actor, x, y + lineHeight * 3, 270);
    };
}

})();

repo_name: dazed/translations

license: unknown


code:
//=============================================================================
// KMS_ShopInventory.js
//   Last update: 2017/02/03
//=============================================================================

/*:
 * @plugindesc
 * [v0.1.0] Add the inventory control function for shops.
 *
 * @author TOMY (Kamesoft)
 *
 * @param Sold out text
 * @default SOLD OUT
 * @desc "Sold out" text which is displayed instead of item's price.
 *
 * @param Caption for stock
 * @default Stock
 * @desc The caption for stocks of items.
 *
 * @param Stock display
 * @default 1
 * @desc
 *  Specify the window for displaying stock numbers.
 *  0: ShopNumber  1: ShopStatus
 *
 * @help
 *
 * ## Plugin commands
 *   ShopInventory apply shop1          # Use an inventory info specified as ID:shop1 when the event command "Shop" is called in the next
 *   ShopInventory supplySpeed shop1 3  # All items are supplied to ID:shop1 by 3x
 *   ShopInventory supplySpeed shop2 0  # Do not supply any item to ID:shop2
 *   ShopInventory restockAll shop1     # Stock of ID:shop1 is replenished fully
 *   ShopInventory resetAll             # Initialize all inventory info
 */

/*:ja
 * @plugindesc
 * [v0.1.0] アイテムの在庫管理機能を追加します。
 *
 * @author TOMY (Kamesoft)
 *
 * @param Sold out text
 * @default SOLD OUT
 * @desc 在庫がない場合、アイテムの価格の代わりに表示するテキストです。
 *
 * @param Caption for stock
 * @default 在庫
 * @desc 在庫表示の名称です。
 *
 * @param Stock display
 * @default 1
 * @desc
 *  在庫数を表示するウィンドウを指定します。
 *  0: 購入数選択  1: ステータス
 *
 * @help
 *
 * ■ プラグインコマンド
 *   ShopInventory apply shop1          # 次の「ショップの処理」で ID:shop1 の在庫情報を使用
 *   ShopInventory supplySpeed shop1 3  # ID:shop1 の在庫を 3 倍速で補充
 *   ShopInventory supplySpeed shop2 0  # ID:shop2 の在庫は補充しない
 *   ShopInventory restockAll shop1     # ID:shop1 の在庫を最大まで補充
 *   ShopInventory resetAll             # 在庫情報を初期化
 */

var KMS = KMS || {};

// セーブデータからの復元を可能にするため、セーブデータに入るクラスをグローバルスコープに置く
function Game_ShopInventory()
{
    this.initialize.apply(this, arguments);
}

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

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

(function() {

'use strict';

var PluginName = 'KMS_ShopInventory';

KMS.imported = KMS.imported || {};
KMS.imported['ShopInventory'] = true;

var pluginParams = PluginManager.parameters(PluginName);
var Params = {};
Params.soldOutText = pluginParams['Sold out text'] || 'SOLD OUT';
Params.stockCaption = pluginParams['Caption for stock'] || 'Stock';
Params.showStockInStatus = Number(pluginParams['Show stock in status'] || 1);

// 商品の補充モード
var SupplyMode =
{
    playtime:    0,     // プレイ時間
    battleCount: 1,     // 戦闘回数

    max: 1
};

    // 商品の補充モードシンボル
var SupplyModeSymbol =
{
    T: SupplyMode.playtime,
    B: SupplyMode.battleCount
};

// 定数
var Const =
{
    debug:             false,           // デバッグモード
    pluginCommandCode: 'ShopInventory'  // プラグインコマンドコード
};

// デバッグログ
var debuglog;
if (Const.debug)
{
    debuglog = function() { console.log(arguments); }
}
else
{
    debuglog = function() { }
}

// トルコロケールで i の小文字変換が期待と異なる件に対する W/A
var toUpper = function(s) { return s.toUpperCase(); };

if ('I' !== 'i'.toUpperCase())
{
    // トルコ用
    toUpper = function(s) { return s.replace(/[A-Z]/g, function(ch) { return String.fromCharCode(ch.charCodeAt(0) & ~32); }); };
}

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

    if (command !== Const.pluginCommandCode)
    {
        return;
    }

    // TODO: 商品の個別補充

    switch (args[0])
    {
    case 'apply':       // 在庫情報の呼び出し (inventoryId)
        if (args[1] == null)
        {
            console.error('[%1 %2] Inventory ID is not specified.'.format(Const.pluginCommandCode, args[0]));
        }
        else
        {
            $gameTemp.nextInventoryId = args[1];
        }
        break;

    case 'supplySpeed': // 補充速度の変更 (inventoryId speed)
        if (isNaN(args[2]))
        {
            console.error('[%1 %2] Invalid speed (%3).'.format(Const.pluginCommandCode, args[0], args[2]));
        }
        else
        {
            // インベントリ未作成の場合は自動的に作成される
            var speed = Number(args[2]);
            $gameSystem.getInventoryById(args[1]).setSupplySpeed();
        }
        break;

    case 'restockAll':     // 在庫の完全補充 (inventoryId)
        if ($gameSystem.existsInventory(args[1]))
        {
            $gameSystem.getInventoryById(args[1]).initializeStock();
        }
        else
        {
            console.log('[%1 %2] Inventory "%3" is not exist.'.format(Const.pluginCommandCode, args[0], args[1]));
        }
        break;

    case 'resetAll':    // 全ショップの在庫情報初期化
        $gameSystem.clearInventories();
        break;

    default:
        // 不明なコマンド
        console.error('[%1 %2] Unknown command.'.format(Const.pluginCommandCode, args[0]));
        break;
    }
}

//-----------------------------------------------------------------------------
// Item

/**
 * 同一のアイテムであるか
 */
function isSameItem(item1, item2)
{
    if (item1.id !== item2.id)
    {
        return false;
    }

    var result =
        (DataManager.isItem(item1) && DataManager.isItem(item2)) ||
        (DataManager.isWeapon(item1) && DataManager.isWeapon(item2)) ||
        (DataManager.isArmor(item1) && DataManager.isArmor(item2));

    if (KMS.imported['AbilityOrb'])
    {
        result |= DataManager.isAbilityOrb(item1) && DataManager.isAbilityOrb(item2);
    }

    return result;
}

/**
 * 在庫メモの解析
 */
function parseNotesForStock(item)
{
    var note = item.meta['kms_shop_stock'];
    if (note == null)
    {
        return;
    }

    var opts = note.replace(/\s+/g, '').split(/,/);
    if (!opts || opts.length < 2)
    {
        return;
    }

    if (isNaN(opts[0]))
    {
        console.error('%1: Invalid stock count'.format(item.name));
        return;
    }

    if (isNaN(opts[1]))
    {
        console.error('%1: Invalid supply interval'.format(item.name));
        return;
    }

    item.shopStockCountMax       = parseInt(opts[0]);
    item.shopStockSupplyInterval = parseInt(opts[1]);

    if (opts.length >= 3)
    {
        // 補充モードの判定 (不正なモードの場合はプレイ時間にフォールバック)
        var modeSymbol = toUpper(opts[2] || 'T');
        if (SupplyModeSymbol[modeSymbol] != null)
        {
            item.shopStockSupplyMode = SupplyModeSymbol[modeSymbol];
        }
        else
        {
            console.error('%1: Invalid supply mode'.format(item.name));
            item.shopStockSupplyMode = SupplyMode.playtime;
        }
    }
    else
    {
        // モード省略時はプレイ時間扱い
        item.shopStockSupplyMode = SupplyMode.playtime;
    }

    debuglog('%1: Max=%2, Interval=%3, Mode=%4'.format(
        item.name,
        item.shopStockCountMax,
        item.shopStockSupplyInterval,
        item.shopStockSupplyMode));
}

/**
 * 在庫上限の取得
 */
function getStockMax(item)
{
    return item.shopStockCountMax;
}

/**
 * 補充間隔の取得
 */
function getSupplyInterval(item)
{
    return item.shopStockSupplyInterval;
}

/**
 * 補充モードの取得
 */
function getSupplyMode(item)
{
    return item.shopStockSupplyMode;
}

//-----------------------------------------------------------------------------
// DataManager

var _DataManager_onLoad = DataManager.onLoad;
DataManager.onLoad = function(object)
{
    _DataManager_onLoad.call(this, object);

    // 在庫設定の解析
    if (object === $dataItems ||
        object === $dataWeapons ||
        object === $dataArmors ||
        (KMS.imported['AbilityOrb'] && object === $dataKmsAbilityOrbs))
    {
        for (var i = 0; i < object.length; i++)
        {
            var obj = object[i];
            if (obj != null)
            {
                parseNotesForStock(obj);
            }
        }
    }
};

//-----------------------------------------------------------------------------
// Game_Temp

/**
 * 次回呼び出す在庫管理情報の ID
 *
 * @property nextInventoryId
 * @type String
 */
Object.defineProperty(Game_Temp.prototype, 'nextInventoryId', {
    get: function()
    {
        return this._nextInventoryId;
    },
    set: function(value)
    {
        this._nextInventoryId = value;
    },
    configurable: true
});

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

    this._nextInventoryId = null;
};

//-----------------------------------------------------------------------------
// Game_System

var _Game_System_initialize = Game_System.prototype.initialize;
Game_System.prototype.initialize = function()
{
    _Game_System_initialize.call(this);

    this.clearInventories();
};

/**
 * 指定 ID に対応する店舗在庫が存在するか
 */
Game_System.prototype.existsInventory = function(id)
{
    this._inventories = this._inventories || {};
    return this._inventories[id] != null;
};

/**
 * 指定 ID に対応する店舗在庫を取得
 */
Game_System.prototype.getInventoryById = function(id)
{
    if (!this.existsInventory(id))
    {
        this._inventories[id] = new Game_ShopInventory(id);
    }

    return this._inventories[id];
};

/**
 * 店舗在庫の全クリア
 */
Game_System.prototype.clearInventories = function()
{
    this._inventories = {};
    this._inventorySupplier = new Game_ShopInventorySupplier();
};

/**
 * 在庫補充スケジュールの登録
 */
Game_System.prototype.registerInventorySupplySchedule = function(inventoryId, item)
{
    if (!this._inventorySupplier)
    {
        this._inventorySupplier = new Game_ShopInventorySupplier();
    }

    var schedule = new Game_ShopSupplySchedule(inventoryId, item);
    this._inventorySupplier.register(schedule);
};

/**
 * 在庫補充スケジュールの更新
 */
Game_System.prototype.updateInventorySupplier = function()
{
    if (!this._inventorySupplier)
    {
        this._inventorySupplier = new Game_ShopInventorySupplier();
    }

    this._inventorySupplier.update();
};

//-----------------------------------------------------------------------------
// Game_ShopInventory
//
// 店舗の在庫を管理するクラス

Object.defineProperties(Game_ShopInventory.prototype, {
    id: { get: function() { return this._id; }, configurable: true },
    supplySpeed: { get: function() { return this._supplySpeed; }, configurable: true }
});

Game_ShopInventory.prototype.initialize = function(id)
{
    this._id = id;
    this._supplySpeed = 1;

    this.initializeStock();
};

/**
 * コンテナの初期化
 */
Game_ShopInventory.prototype.initializeStock = function(item)
{
    this._itemStock   = {};
    this._weaponStock = {};
    this._armorStock  = {};

    this._abilityOrbStock = {};
};

/**
 * 商品のコンテナを取得
 */
Game_ShopInventory.prototype.itemContainer = function(item)
{
    if (!item)
    {
        return null;
    }
    else if (DataManager.isItem(item))
    {
        return this._itemStock;
    }
    else if (DataManager.isWeapon(item))
    {
        return this._weaponStock;
    }
    else if (DataManager.isArmor(item))
    {
        return this._armorStock;
    }
    else if (KMS.imported['AbilityOrb'] && DataManager.isAbilityOrb(item))
    {
        return this._abilityOrbStock;
    }
    else
    {
        console.error('Game_ShopInventory: Invalid item type');
        return null;
    }
};

/**
 * 商品の補充速度を設定
 */
Game_ShopInventory.prototype.setSupplySpeed = function(speed)
{
    this._supplySpeed = Math.max(speed, 0);
};

/**
 * 商品の補充間隔を取得
 */
Game_ShopInventory.prototype.getSupplyInterval = function(item)
{
    return Math.max(Math.floor(getSupplyInterval(item) * this._supplySpeed), 0);
};

/**
 * 商品の在庫数を取得
 */
Game_ShopInventory.prototype.getStock = function(item)
{
    if (!this.isStockManaged(item))
    {
        // 在庫管理外なら常に MAX 扱い
        return $gameParty.maxItems(item);
    }

    var stock = this.itemContainer(item);
    if (stock[item.id] == null)
    {
        // 初回参照時は在庫をフルにする
        stock[item.id] = this.getStockMax(item);
    }
    //勝手に補充されるので在庫処理
	if(item.id==141 &&($gameParty.hasItem( $dataItems[item.id] ) || $gameActors.actor(1).hasSkill(622))){stock[item.id]=0;}
	if(item.id==142 &&($gameParty.hasItem( $dataItems[item.id] ) || $gameActors.actor(1).hasSkill(623))){stock[item.id]=0;}
	if(item.id==143 &&($gameParty.hasItem( $dataItems[item.id] ) || $gameActors.actor(1).hasSkill(624))){stock[item.id]=0;}
	if(item.id==144 &&($gameParty.hasItem( $dataItems[item.id] ) || $gameActors.actor(1).hasSkill(625))){stock[item.id]=0;}
	if(item.id==145 &&($gameParty.hasItem( $dataItems[item.id] ) || $gameActors.actor(1).hasSkill(626))){stock[item.id]=0;}
	if(item.id==146 &&($gameParty.hasItem( $dataItems[item.id] ) || $gameActors.actor(1).hasSkill(627))){stock[item.id]=0;}
	if(item.id==147 &&($gameParty.hasItem( $dataItems[item.id] ) || $gameActors.actor(1).hasSkill(628))){stock[item.id]=0;}
	if(item.id==148 &&($gameParty.hasItem( $dataItems[item.id] ) || $gameActors.actor(1).hasSkill(629))){stock[item.id]=0;}
	if(item.id==149 &&($gameParty.hasItem( $dataItems[item.id] ) || $gameActors.actor(1).hasSkill(630))){stock[item.id]=0;}
	if(item.id==150 &&($gameParty.hasItem( $dataItems[item.id] ) || $gameActors.actor(1).hasSkill(631))){stock[item.id]=0;}
	if(item.id==151 &&($gameParty.hasItem( $dataItems[item.id] ) || $gameActors.actor(1).hasSkill(632))){stock[item.id]=0;}
	if(item.id==152 &&($gameParty.hasItem( $dataItems[item.id] ) || $gameActors.actor(1).hasSkill(633))){stock[item.id]=0;}
	if(item.id==153 &&($gameParty.hasItem( $dataItems[item.id] ) || $gameActors.actor(1).hasSkill(634))){stock[item.id]=0;}
	if(item.id==154 &&($gameParty.hasItem( $dataItems[item.id] ) || $gameActors.actor(1).hasSkill(635))){stock[item.id]=0;}
	if(item.id==155 &&($gameParty.hasItem( $dataItems[item.id] ) || $gameActors.actor(1).hasSkill(636))){stock[item.id]=0;}
	if(item.id==156 &&($gameParty.hasItem( $dataItems[item.id] ) || $gameActors.actor(1).hasSkill(637))){stock[item.id]=0;}
	if(item.id==157 &&($gameParty.hasItem( $dataItems[item.id] ) || $gameActors.actor(1).hasSkill(638))){stock[item.id]=0;}
	if(item.id==158 &&($gameParty.hasItem( $dataItems[item.id] ) || $gameActors.actor(1).hasSkill(639))){stock[item.id]=0;}

    return stock[item.id];
};

/**
 * 商品の在庫数を設定
 */
Game_ShopInventory.prototype.setStock = function(item, number)
{
    if (!this.isStockManaged(item))
    {
        return;
    }

    var stock = this.itemContainer(item);
    if (stock != null)
    {
        stock[item.id] = number.clamp(0, this.getStockMax(item));
    }
};

/**
 * 商品が在庫管理対象か
 */
Game_ShopInventory.prototype.isStockManaged = function(item)
{
    return getStockMax(item) != null;
};

/**
 * 商品の在庫数上限を取得
 */
Game_ShopInventory.prototype.getStockMax = function(item)
{
    // TODO: 店ごとに上限を指定できるようにしたい
    return this.isStockManaged(item) ? getStockMax(item) : $gameParty.maxItems(item);
};

/**
 * 商品の在庫数が上限か
 */
Game_ShopInventory.prototype.isStockFull = function(item)
{
    return this.getStock(item) >= this.getStockMax(item);
};

/**
 * 商品の在庫数があるか
 */
Game_ShopInventory.prototype.isStockAvailable = function(item)
{
    return this.getStock(item) > 0;
};

/**
 * 商品の在庫数を増やす
 */
Game_ShopInventory.prototype.gainStock = function(item, amount)
{
    var prevStock = this.getStock(item);
    this.setStock(item, prevStock + amount);
    return this.getStock(item) - prevStock;
};

/**
 * 商品の在庫数を減らす
 */
Game_ShopInventory.prototype.loseStock = function(item, amount)
{
    return -this.gainStock(item, -amount);
};

//-----------------------------------------------------------------------------
// Game_ShopSupplySchedule
//
// 店舗の在庫補充タイミングを制御するクラス

Object.defineProperties(Game_ShopSupplySchedule.prototype, {
    inventoryId: { get: function() { return this._inventoryId; },   configurable: true },
    item:        { get: function() { return this._item.object(); }, configurable: true }
});

Game_ShopSupplySchedule.prototype.initialize = function(inventoryId, item)
{
    this._inventoryId = inventoryId;
    this._item        = new Game_Item(item);
    this._startCount  = -1;
};

/**
 * 補充間隔の取得
 */
Game_ShopSupplySchedule.prototype.getSupplyInterval = function()
{
    var inventory = $gameSystem.getInventoryById(this.inventoryId);
    return inventory.getSupplyInterval(this.item);
};

/**
 * 有効なスケジュールであるか
 */
Game_ShopSupplySchedule.prototype.isValid = function()
{
    return this._startCount >= 0;
};

/**
 * 補充を行うか
 */
Game_ShopSupplySchedule.prototype.canSupply = function()
{
    return this.getSupplyInterval() > 0;
};

/**
 * 同一と見なせるスケジュールであるか
 */
Game_ShopSupplySchedule.prototype.logicallyEqual = function(rhs)
{
    return rhs != null &&
        this.isValid() &&
        this.inventoryId === rhs.inventoryId &&
        isSameItem(this.item, rhs.item);
};

/**
 * 補充判定用カウントの現在値を取得
 */
Game_ShopSupplySchedule.prototype.getCurrentCountForSupply = function()
{
    switch (getSupplyMode(this.item))
    {
    case SupplyMode.playtime:    return $gameSystem.playtime();
    case SupplyMode.battleCount: return $gameSystem.battleCount();

    default:
        console.error('Invalid supply mode');
        return -1;
    }
};

/**
 * 補充可能な個数を取得
 */
Game_ShopSupplySchedule.prototype.getSuppliableCount = function()
{
    if (!this.isValid() || !this.canSupply())
    {
        return 0;
    }

    var currentCount = this.getCurrentCountForSupply();
    if (currentCount < 0)
    {
        // 異常なモード設定
        this.stop();
        return;
    }

    // 現在のカウントが開始時のカウントより減っている場合、
    // 値が変更されたと見なしてカウントを初期化
    if (currentCount < this._startCount)
    {
        this._startCount = currentCount;
    }

    return Math.floor((currentCount - this._startCount) / this.getSupplyInterval());
};

/**
 * スケジュールの開始
 */
Game_ShopSupplySchedule.prototype.start = function()
{
    if (!this.canSupply())
    {
        debuglog('%1 is not necessary to supply.'.format(this.item.name));
        return;
    }

    var currentCount = this.getCurrentCountForSupply();
    if (currentCount >= 0)
    {
        this._startCount = currentCount;
    }
    else
    {
        // 無効なスケジュール
        this.stop();
    }
};

/**
 * スケジュールの停止
 */
Game_ShopSupplySchedule.prototype.stop = function()
{
    this._startCount = -1;
    debuglog('Schedule [%1:%2] stopped'.format(this.inventoryId, this.item.name));
};

/**
 * 在庫補充処理
 */
Game_ShopSupplySchedule.prototype.supply = function()
{
    if (!this.canSupply())
    {
        this.stop();
        return;
    }

    var count = this.getSuppliableCount();
    if (count <= 0)
    {
        return;
    }

    var item = this.item;
    var inventory = $gameSystem.getInventoryById(this.inventoryId);
    inventory.gainStock(item, count);

    debuglog('%1: Supplied %2'.format(item.name, count));

    if (inventory.isStockFull(item))
    {
        this.stop();
    }
    else
    {
        // 補充した分カウンタを進める
        this._startCount += count * this.getSupplyInterval();
    }
};

//-----------------------------------------------------------------------------
// Game_ShopInventorySupplier
//
// 店舗の在庫補充を制御するクラス

Game_ShopInventorySupplier.prototype.initialize = function()
{
    this._schedules = [];
};

/**
 * 既に同一アイテムのスケジュールが登録済みか
 */
Game_ShopInventorySupplier.prototype.isRegistered = function(schedule)
{
    return this._schedules.some(function(s)
        {
            return s.logicallyEqual(schedule);
        }, this);
};

/**
 * スケジュール登録
 */
Game_ShopInventorySupplier.prototype.register = function(schedule)
{
    if (this.isRegistered(schedule))
    {
        return;
    }

    schedule.start();
    if (schedule.isValid())
    {
        this._schedules.push(schedule);
        debuglog('Schedule for %1 is registered'.format(schedule.item.name));
    }
};

/**
 * 指定したスケジュールを削除
 */
Game_ShopInventorySupplier.prototype.remove = function(schedule)
{
    this._schedules = this._schedules.filter(function(s)
        {
            return !s.logicallyEqual(schedule);
        }, this);
};

/**
 * 停止済みのスケジュールを削除
 */
Game_ShopInventorySupplier.prototype.removeStopped = function()
{
    this._schedules = this._schedules.filter(function(s)
        {
            return s.isValid();
        }, this);
};

/**
 * 在庫の更新
 */
Game_ShopInventorySupplier.prototype.update = function()
{
    this._schedules.forEach(function(s)
    {
        s.supply();
    }, this);

    this.removeStopped();
};

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

/**
 * 店舗在庫数の描画
 */
Window_Base.prototype.drawShopStockNumber = function(item, inventory, x, y, width)
{
    if (!inventory.isStockManaged(item))
    {
        return;
    }

    var valueWidth = this.textWidth('000');
    var slashWidth = this.textWidth('/');
    var captionWidth = this.textWidth(Params.stockCaption) + 8;

    this.changeTextColor(this.systemColor());
    this.drawText(Params.stockCaption, x, y, captionWidth);

    var numX = x + width - (valueWidth * 2 + slashWidth);
    var stock = inventory.getStock(item);
    var stockMax = inventory.getStockMax(item);
    this.resetTextColor();
    this.drawText(stock, numX, y, valueWidth, 'right');
    this.drawText('/', numX + valueWidth, y, slashWidth, 'right');
    this.drawText(stockMax, numX + valueWidth + slashWidth, y, valueWidth, 'right');
};

//-----------------------------------------------------------------------------
// Window_ShopBuy

var _Window_ShopBuy_isEnabled = Window_ShopBuy.prototype.isEnabled;
Window_ShopBuy.prototype.isEnabled = function(item)
{
    var enabled = _Window_ShopBuy_isEnabled.call(this, item);

    if (this._inventory)
    {
        return enabled && this._inventory.isStockAvailable(item);
    }
    else
    {
        return enabled;
    }
};

var _Window_ShopBuy_drawItem = Window_ShopBuy.prototype.drawItem;
Window_ShopBuy.prototype.drawItem = function(index)
{
    var item = this._data[index];
    if (this._inventory && !this._inventory.isStockAvailable(item))
    {
        // 売り切れ表示
        var rect = this.itemRect(index);
        var priceWidth = 96;
        rect.width -= this.textPadding();
        this.changePaintOpacity(this.isEnabled(item));
        this.drawItemName(item, rect.x, rect.y, rect.width - priceWidth);
        this.drawText(
            Params.soldOutText,
            rect.x + rect.width - priceWidth,
            rect.y,
            priceWidth,
            'right');
        this.changePaintOpacity(true);
    }
    else
    {
        _Window_ShopBuy_drawItem.call(this, index);
    }
};

/**
 * 在庫管理オブジェクトの設定
 */
Window_ShopBuy.prototype.setInventory = function(inventory)
{
    this._inventory = inventory;
};

//-----------------------------------------------------------------------------
// Window_ShopNumber

var _Window_ShopNumber_refresh = Window_ShopNumber.prototype.refresh;
Window_ShopNumber.prototype.refresh = function()
{
    _Window_ShopNumber_refresh.call(this);

    if (!Params.showStockInStatus)
    {
        this.drawStockNumber();
    }
};

/**
 * 在庫数の描画
 */
Window_ShopNumber.prototype.drawStockNumber = function()
{
    if (!this._item || !this._inventory)
    {
        return;
    }

    var valueWidth = this.textWidth('000');
    var slashWidth = this.textWidth('/');
    var captionWidth = this.textWidth(Params.stockCaption) + this.textPadding() * 2 + 8;
    var width = captionWidth + valueWidth * 2 + slashWidth;
    var x = this.contents.width - width - this.textPadding() * 2;
    var y = this.stockY();
    this.drawShopStockNumber(this._item, this._inventory, x, y, width);
};

/**
 * 在庫数 Y 座標
 */
Window_ShopNumber.prototype.stockY = function()
{
    return this.itemY() - this.lineHeight() * 2;
};

/**
 * 在庫管理オブジェクトの設定
 */
Window_ShopNumber.prototype.setInventory = function(inventory)
{
    this._inventory = inventory;
};

//-----------------------------------------------------------------------------
// Window_ShopStatus

var _Windowe_ShopStatus_refresh = Window_ShopStatus.prototype.refresh;
Window_ShopStatus.prototype.refresh = function()
{
    _Windowe_ShopStatus_refresh.call(this);

    if (Params.showStockInStatus)
    {
        var x = this.textPadding();
        this.drawStockNumber(x, this.lineHeight());
    }
};

/**
 * 在庫数の描画
 */
Window_ShopStatus.prototype.drawStockNumber = function(x, y)
{
    if (!this._item || !this._inventory)
    {
        return;
    }

    var width = this.contents.width - this.textPadding() * 2;
    this.drawShopStockNumber(this._item, this._inventory, x, y, width);
};

/**
 * 在庫管理オブジェクトの設定
 */
Window_ShopStatus.prototype.setInventory = function(inventory)
{
    this._inventory = inventory;
};

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

var _Scene_Shop_prepare = Scene_Shop.prototype.prepare;
Scene_Shop.prototype.prepare = function(goods, purchaseOnly)
{
    _Scene_Shop_prepare.call(this, goods, purchaseOnly);

    // 在庫補充
    $gameSystem.updateInventorySupplier();

    // 予約されている在庫管理情報を呼び出す
    var id = $gameTemp.nextInventoryId;
    if (id != null)
    {
        this._inventory = $gameSystem.getInventoryById(id);
        $gameTemp.nextInventoryId = null;
    }
    else
    {
        this._inventory = null;
    }
};

var _Scene_Shop_createBuyWindow = Scene_Shop.prototype.createBuyWindow;
Scene_Shop.prototype.createBuyWindow = function()
{
    _Scene_Shop_createBuyWindow.call(this);

    this._buyWindow.setInventory(this._inventory);
};

var _Scene_Shop_createNumberWindow = Scene_Shop.prototype.createNumberWindow;
Scene_Shop.prototype.createNumberWindow = function()
{
    _Scene_Shop_createNumberWindow.call(this);

    this._numberWindow.setInventory(this._inventory);
};

var _Scene_Shop_createStatusWindow = Scene_Shop.prototype.createStatusWindow;
Scene_Shop.prototype.createStatusWindow = function()
{
    _Scene_Shop_createStatusWindow.call(this);

    this._statusWindow.setInventory(this._inventory);
};

var _Scene_Shop_maxBuy = Scene_Shop.prototype.maxBuy;
Scene_Shop.prototype.maxBuy = function()
{
    var count = _Scene_Shop_maxBuy.call(this);

    if (this._inventory)
    {
        // 既に所持金に応じた cap がかかっているので、在庫数と比較して少ない方を採用
        count = Math.min(count, this._inventory.getStock(this._item));
    }

    return count;
};

var _Scene_Shop_doBuy = Scene_Shop.prototype.doBuy;
Scene_Shop.prototype.doBuy = function(number)
{
    _Scene_Shop_doBuy.call(this, number);

    // 在庫を減らす
    if (this._inventory)
    {
        this._inventory.loseStock(this._item, number);

        // 在庫補充を開始
        $gameSystem.registerInventorySupplySchedule(this._inventory.id, this._item);
    }
};

var _Scene_Shop_doSell = Scene_Shop.prototype.doSell;
Scene_Shop.prototype.doSell = function(number)
{
    _Scene_Shop_doSell.call(this, number);

    // 買戻し用に在庫を増やす
    if (this._inventory)
    {
        this._inventory.gainStock(this._item, number);
    }
};

})();


code:
//=============================================================================
// KuishibariState.js (プラグインパラメータ対応版)
//=============================================================================

/*:
 * @plugindesc 「HPが2以上ある状態でダメージを受けた場合、一定確率でHP1残る」ステートを作成します。
 * @author 奏ねこま（おとぶきねこま）
 *
 * @param DamageMessage
 * @text ダメージメッセージ
 * @desc ダメージを与えた際に表示するメッセージ。
 *  {damage}：ダメージ量 {enemy}：敵の名前
 * @default \\I[1023]{enemy}に {damage} ポイントのダメージを与えた！
 *
 * @param SurvivalMessage1
 * @text 生存メッセージ1
 * @desc 一定確率でHP1残った際に表示するメッセージ（グループ1）。
 * {enemy}：敵の名前
 * @default \\I[2465]{enemy}は漢気を見せて\\n[281]の攻撃を耐えた！
 *
 * @param SurvivalMessage2
 * @text 生存メッセージ2
 * @desc 一定確率でHP1残った際に表示するメッセージ（グループ2-1）。
 * {enemy}：敵の名前
 * @default \\I[2465]{enemy}は強い意志で\\n[281]の攻撃を耐えている！
 *
 *
 * @param SurvivalMessage3
 * @text 生存メッセージ3
 * @desc 一定確率でHP1残った際に表示するメッセージ（グループ2-2）。
 * {enemy}：敵の名前
 * @default \\I[2465]{enemy}は瀕死になってなお戦う意思を見せている！
 *
 *
 * @param SurvivalMessage4
 * @text 生存メッセージ4
 * @desc 一定確率でHP1残った際に表示するメッセージ（グループ2-3）。
 * {enemy}：敵の名前
 * @default \\I[2465]{enemy}は洗脳によって戦い続けることを強制されている！
 *
 * @help
 * ステートのメモ欄に、以下のように記述してください。
 * 確率値は正の整数で指定してください。
 *
 *  <kuishibari:[確率]>
 *
 * 例：HP2以上で被ダメージ時、必ずHP1残る
 *  <kuishibari:100>
 *
 * 例：HP2以上で被ダメージ時、50%の確率でHP1残る
 *  <kuishibari:50>
 */

(function(){
	'use strict';

	var parameters = PluginManager.parameters('KuishibariState');
	var damageMessage = parameters['DamageMessage'] || "\\I[1023]{enemy} に {damage} ポイントのダメージを与えた！";
	var survivalMessage1 = parameters['SurvivalMessage1'] || "\\I[2465]{enemy}は漢気を見せて\\n[281]の攻撃を耐えた！";
	var survivalMessage2 = parameters['SurvivalMessage2'] || "\\I[2465]{enemy}は強い意志で\\n[281]の攻撃を耐えている！";
	var survivalMessage3 = parameters['SurvivalMessage3'] || "\\I[2465]{enemy}は瀕死になってなお戦う意思を見せている！";
	var survivalMessage4 = parameters['SurvivalMessage4'] || "\\I[2465]{enemy}は洗脳によって戦い続けることを強制されている！";

	var _Game_Action_executeHpDamage = Game_Action.prototype.executeHpDamage;
	Game_Action.prototype.executeHpDamage = function(target, value) {
		var original_value = value;
		if (target._hp >= 1 && value >= target._hp) {
			var kuishibari = 0;
			target._states.forEach(function(state) {
				if ($dataStates[state].meta['kuishibari']) {
					kuishibari = Math.max(kuishibari, $dataStates[state].meta['kuishibari']);
				}
			});
			if (kuishibari) {
				if ((Math.floor(Math.random() * 100) + 1) <= kuishibari) {
					value = target._hp - 1;
				}
			}
		}
		if(kuishibari){
			// 嘘メッセージの表示
			BattleManager._actionList = []
			$gameTroop.members()[0].addState(44);//ダミーステート
			$gameParty.members().forEach(function(actor) {actor._actions = [];});
			AudioManager.playSe({"name":"Damage4","volume":90,"pitch":100,"pan":0})
			if (target.result().critical){
				var text = "\\I[2526]\\C[18]" + TextManager.criticalToEnemy + "\\C[0]"
				BattleManager._logWindow.push('addText', text);
				target.result().critical = false
			}
			var text = damageMessage.replace("{damage}", original_value).replace("{enemy}", $dataEnemies[target._enemyId].name)
			BattleManager._logWindow.push('addText', text);
			target.setHp(1);
			$gameTemp.reserveCommonEvent(144);

			if($gameTroop.troop().id == 43){
				$gameTroop.members()[target.index()].startAnimation(288, false, 0);
				text = survivalMessage1.replace("{enemy}", $dataEnemies[target._enemyId].name);
			} else if($gameTroop.troop().id == 9){
				$gameTroop.members()[target.index()].startAnimation(288, false, 0);
				if(!$gameTroop.members()[target.index()].isStateAffected(15)){
					$gameTroop.members()[target.index()].addState(15);
					text = survivalMessage2.replace("{enemy}", $dataEnemies[target._enemyId].name);
				}else if(!$gameTroop.members()[target.index()].isStateAffected(14)){
					$gameTroop.members()[target.index()].addState(14);
					text = survivalMessage3.replace("{enemy}", $dataEnemies[target._enemyId].name);
				}else if(!$gameTroop.members()[target.index()].isStateAffected(13)){
					$gameTroop.members()[target.index()].addState(13);
					text = survivalMessage4.replace("{enemy}", $dataEnemies[target._enemyId].name);
				}
			}
			target.result().success=true
			BattleManager._logWindow.push('addText', text);
			$gameTemp.reserveCommonEvent(144);
		} else {
			_Game_Action_executeHpDamage.call(this, target, value);
		}
	};
})();


code:
/*:
 * @target MV
 * @plugindesc 文字の縁取り色を自動で判定して切替します。
 * @author ルルの教会
 * @url https://nine-yusha.com/plugin-autooutlinecolor/
 *
 * @help LL_OutlineColorAutoMV.js
 *
 * プラグインコマンドはありません。
 *
 * 利用規約:
 *   ・著作権表記は必要ございません。
 *   ・利用するにあたり報告の必要は特にございません。
 *   ・商用・非商用問いません。
 *   ・R18作品にも使用制限はありません。
 *   ・ゲームに合わせて自由に改変していただいて問題ございません。
 *   ・プラグイン素材としての再配布（改変後含む）は禁止させていただきます。
 *
 * 作者: ルルの教会
 * 作成日: 2021/7/30
 *
 * @param outlineColorBlack
 * @text 縁取り色(黒)
 * @desc 文字の縁取り色(黒)です。
 * @default rgba(0, 0, 0, 0.5)
 * @type string
 *
 * @param outlineColorDeepBlack
 * @text 縁取り色(濃い黒)
 * @desc 文字の縁取り色(濃い黒)です。
 * @default rgba(0, 0, 0, 0.15)
 * @type string
 *
 * @param outlineSwitchId
 * @text 縁取り切替スイッチID
 * @desc 縁取り色を変更するスイッチのIDを指定します。
 * @default 1
 * @type switch
 */

(function() {
    "use strict";
    var pluginName = "LL_OutlineColorAutoMV";

    var parameters = PluginManager.parameters(pluginName);
    var outlineSwitchId = Number(parameters["outlineSwitchId"] || 1);
    var outlineColorBlack = String(parameters["outlineColorBlack"] || "rgba(0, 0, 0, 0.5)");
    var outlineColorDeepBlack = String(parameters["outlineColorDeepBlack"] || "rgba(0, 0, 0, 0.15)");

    var _Window_Base_resetTextColor = Window_Base.prototype.resetTextColor;
    Window_Base.prototype.resetTextColor = function() {
        _Window_Base_resetTextColor.apply(this, arguments);
        if($gameParty.inBattle())this.changeOutlineColorAuto(this.normalColor());
    };

    var _Window_Base_changeTextColor = Window_Base.prototype.changeTextColor;
    Window_Base.prototype.changeTextColor = function(color) {
        _Window_Base_changeTextColor.apply(this, arguments, color);
        if($gameParty.inBattle())this.changeOutlineColorAuto(color);
    };

    Window_Base.prototype.changeOutlineColorAuto = function(color) {
        var value = !$gameSwitches.value(outlineSwitchId);
        this.contents.outlineColor = value ? outlineColorBlack : outlineColorDeepBlack;
    };
})();


code:
//=============================================================================
// LightSaveData.js
// ----------------------------------------------------------------------------
// Copyright (c) 2016 Triacontane
// This software is released under the MIT License.
// http://opensource.org/licenses/mit-license.php
// ----------------------------------------------------------------------------
// Version
// 1.1.0 2016/11/21 削除対象外のアクターIDを指定できる機能を追加
// 1.0.0 2016/11/21 初版
// ----------------------------------------------------------------------------
// [Blog]   : http://triacontane.blogspot.jp/
// [Twitter]: https://twitter.com/triacontane/
// [GitHub] : https://github.com/triacontane/
//=============================================================================

/*:
 * @plugindesc LightSaveDataPlugin
 * @author triacontane
 *
 * @param SaveOnlyInParty
 * @desc 一度抜けたアクターの情報も含めて破棄して、セーブ時点でパーティに加わっているアクター情報のみを残します。(ON/OFF)
 * @default OFF
 *
 * @param 例外アクターID
 * @desc 報削除の対象外になるアクターIDをカンマ区切りで指定してください。(1,2,3)
 * @default
 *
 * @help セーブ実行時に、アクター情報の中から「今まで一度もパーティに加わっていない」
 * アクターの情報を削除することでセーブデータの容量を減らします。
 *
 * セーブ時に「Save data too big!」という警告ログが出力されたり、
 * セーブ時の硬直が長い場合に、当プラグインを使用すると状況が改善する可能性があります。
 *
 * 注意！
 * 1. 本プラグインはあらゆるセーブデータの肥大化に対して有効とは限りません。
 * 削除するのはアクター情報のみなので、原因が他に存在する場合は対処できません。
 *
 * 2. 導入しているプラグインによっては、必要なデータが消される可能性があります。
 *
 * このプラグインにはプラグインコマンドはありません。
 */
/*:ja
 * @plugindesc セーブデータ軽量化プラグイン
 * @author トリアコンタン
 *
 * @param 現パーティのみ保持
 * @desc 一度抜けたアクターの情報も含めて破棄して、セーブ時点でパーティに加わっているアクター情報のみを残します。(ON/OFF)
 * @default OFF
 *
 * @param ExceptionActorIds
 * @desc 削除の対象外になるアクターIDをカンマ区切りで指定してください。(1,2,3)
 * @default
 *
 * @help セーブ実行時に、アクター情報の中から「今まで一度もパーティに加わっていない」
 * アクターの情報を削除することでセーブデータの容量を減らします。
 *
 * セーブ時に「Save data too big!」という警告ログが出力されたり、
 * セーブ時の硬直が長い場合に、当プラグインを使用すると状況が改善する可能性があります。
 *
 * 注意！
 * 1. 本プラグインはあらゆるセーブデータの肥大化に対して有効とは限りません。
 * 削除するのはアクター情報のみなので、原因が他に存在する場合は対処できません。
 *
 * 2. 導入しているプラグインによっては、必要なデータが消される可能性があります。
 *
 * このプラグインにはプラグインコマンドはありません。
 *
 * 利用規約：
 *  作者に無断で改変、再配布が可能で、利用形態（商用、18禁利用等）
 *  についても制限はありません。
 *  このプラグインはもうあなたのものです。
 */

(function() {
    'use strict';
    var pluginName = 'LightSaveData';

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

    var getParamString = function(paramNames) {
        var value = getParamOther(paramNames);
        return value === null ? '' : value;
    };

    var getParamBoolean = function(paramNames) {
        var value = getParamOther(paramNames);
        return (value || '').toUpperCase() === 'ON';
    };

    var getParamArrayString = function(paramNames) {
        var values = getParamString(paramNames).split(',');
        for (var i = 0; i < values.length; i++) values[i] = values[i].trim();
        return values;
    };

    var getParamArrayNumber = function(paramNames, min, max) {
        var values = getParamArrayString(paramNames);
        if (arguments.length < 2) min = -Infinity;
        if (arguments.length < 3) max = Infinity;
        for (var i = 0; i < values.length; i++) {
            if (!isNaN(parseInt(values[i], 10))) {
                values[i] = (parseInt(values[i], 10) || 0).clamp(min, max);
            } else {
                values.splice(i--, 1);
            }
        }
        return values;
    };

    //=============================================================================
    // パラメータの取得と整形
    //=============================================================================
    var paramSaveOnlyInParty   = getParamBoolean(['SaveOnlyInParty', '現パーティのみ保持']);
    var paramExceptionActorIds = getParamArrayNumber(['ExceptionActorIds', '例外アクターID']);

    //=============================================================================
    // Game_System
    //  パーティに加わっていないアクター情報を破棄します。
    //=============================================================================
    var _Game_System_onAfterLoad      = Game_System.prototype.onAfterLoad;
    Game_System.prototype.onAfterLoad = function() {
        _Game_System_onAfterLoad.apply(this, arguments);
        $gameParty.initValidActors();
    };

    var _Game_System_onBeforeSave      = Game_System.prototype.onBeforeSave;
    Game_System.prototype.onBeforeSave = function() {
        _Game_System_onBeforeSave.apply(this, arguments);
        $gameActors.deleteActorNeverInParty();
    };

    //=============================================================================
    // Game_Party
    //  一度でもパーティに加わったアクターを保持します。
    //=============================================================================
    var _Game_Party_initialize      = Game_Party.prototype.initialize;
    Game_Party.prototype.initialize = function() {
        _Game_Party_initialize.apply(this, arguments);
        this.initValidActors();
    };

    var _Game_Party_setupStartingMembers      = Game_Party.prototype.setupStartingMembers;
    Game_Party.prototype.setupStartingMembers = function() {
        _Game_Party_setupStartingMembers.apply(this, arguments);
        $dataSystem.partyMembers.forEach(function(actorId) {
            this.addValidActor(actorId);
        }, this);
    };

    var _Game_Party_addActor      = Game_Party.prototype.addActor;
    Game_Party.prototype.addActor = function(actorId) {
        _Game_Party_addActor.apply(this, arguments);
        this.addValidActor(actorId);
    };

    Game_Party.prototype.addValidActor = function(actorId) {
        if (!this._validActors.contains(actorId)) {
            this._validActors.push(actorId);
        }
    };

    Game_Party.prototype.initValidActors = function() {
        this._validActors = this._validActors || [];
    };

    Game_Party.prototype.isValidActors = function(actorId) {
        return this._validActors.contains(actorId) || this._actors.contains(actorId);
    };

    var _Game_Party_removeActor      = Game_Party.prototype.removeActor;
    Game_Party.prototype.removeActor = function(actorId) {
        _Game_Party_removeActor.apply(this, arguments);
        this.removeValidActor(actorId);
    };

    Game_Party.prototype.removeValidActor = function(actorId) {
        if (this._validActors.contains(actorId) && paramSaveOnlyInParty) {
            this._validActors.splice(this._validActors.indexOf(actorId), 1);
        }
    };

    //=============================================================================
    // Game_Actors
    //  パーティに加わっていないアクター情報を破棄します。
    //=============================================================================
    Game_Actors.prototype.deleteActorNeverInParty = function() {
        for (var i = 0; i < this._data.length; i++) {
            if (!$gameParty.isValidActors(i) && this._data[i] && !paramExceptionActorIds.contains(i)) {
                delete this._data[i];
                if ($gameTemp.isPlaytest()) console.log('Actor[%1] Deleted!!'.format(i));
            }
        }
    };
})();


code:
//=============================================================================
// MKR_ControlCharacterEx.js
//=============================================================================
// Copyright (c) 2016 mankind_robo
// This software is released under the MIT License.
// http://opensource.org/licenses/mit-license.php
// ----------------------------------------------------------------------------
// Version
// 1.0.1 2016/07/22 一部制御文字が動作しなくなるバグを修正。
// 1.0.0 2016/07/21 初版公開。
// ----------------------------------------------------------------------------
// [Twitter] https://twitter.com/mankind_robo/
//=============================================================================

/*:
 *
 * @plugindesc メッセージ内で使用可能な制御文字を追加します。
 * @author mankind
 *
 * @help
 * メッセージ内で利用可能な制御文字を追加します。
 * 現在追加で使用可能な制御文字は以下の通りです。
 *
 * 制御文字:
 *    \SE[SE名,SE音量,SEピッチ,SE位相]
 *      ・メッセージ表示中にSEを演奏します。
 *        SE名は必須です。拡張子を抜いたSEファイル名を
 *        指定してください。
 *
 *        音量、ピッチ、位相は数値で指定、または
 *        制御文字の\v[n](変数n番の数値)を利用可能です。
 *
 *        なお、ここでの音量、ピッチ、位相設定は
 *        プラグインパラメータで指定できる
 *        初期値設定より優先されます。
 *
 *        音量、ピッチ、位相を初期設定値のまま利用する場合は、
 *        SE名のみ指定してください。
 *        (音量のみを指定して
 *         残りを初期設定値で再生させることも可能です)
 *
 *
 *
 *
 * 制御文字の設定例:
 *   \se[CAT,20,100,0]
 *     ・猫の効果音を音量20、ピッチ100、位相0で再生します。
 *
 *   \SE[BELL1]
 *     ・ベル1の効果音を初期値設定で再生します。
 *
 *   \SE[Coin,\v[20]]
 *     ・コインの効果音を音量[変数20番]、
 *       他は初期値設定を使い再生します。
 *
 *
 * プラグインコマンド:
 *    ありません。
 *
 *
 * スクリプトコマンド:
 *    ありません。
 *
 *
 * ※ プラグインのパラメータにおいて、数値を指定するパラメータには
 *    制御文字\v[n]が使用可能です。
 *    制御文字を指定したパラメータは、パラメータの使用時に
 *    変数の値を取得するため、リアルタイムにパラメータの変更が可能です。
 *
 *
 * 利用規約:
 *    ・作者に無断で本プラグインの改変、再配布が可能です。
 *      (ただしヘッダーの著作権表示部分は残してください。)
 *
 *    ・利用形態(フリーゲーム、商用ゲーム、R-18作品等)に制限はありません。
 *      ご自由にお使いください。
 *
 *    ・本プラグインを使用したことにより発生した問題について作者は一切の責任を
 *      負いません。
 *
 *    ・要望などがある場合、本プラグインのバージョンアップを行う
 *      可能性がありますが、
 *      バージョンアップにより本プラグインの仕様が変更される可能性があります。
 *      ご了承ください。
 *
 *
 * @param Default_SE_Volume
 * @desc [初期設定値] 制御文字でSE再生時に使われる音量です。
 * @default 90
 *
 * @param Default_SE_Pitch
 * @desc [初期設定値] 制御文字でSE再生時に使われるピッチです。
 * @default 100
 *
 * @param Default_SE_Pan
 * @desc [初期設定値] 制御文字でSE再生時に使われる位相です。
 * @default 0
 *
 * @param Default_Wait_Period
 * @desc [初期設定値] 制御文字\.利用時に待機するフレーム数です。(60フレーム=1秒)
 * @default 15
 *
 * @param Default_Wait_Line
 * @desc [初期設定値] 制御文字\|利用時に待機するフレーム数です。(60フレーム=1秒)
 * @default 60
 *
 *
 *
 * *
*/
(function () {
    'use strict';
    var Parameters, SeVolumeDef, SePitchDef, SePanDef,
        WaitPeriodDef, WaitLineDef;

    var CheckParam = function(type, param, def) {
        var regExp;

        regExp = /^\x1bV\[\d+\]$/i;
        param = param.replace(/\\/g, '\x1b');
        if(regExp.test(param)) {
            return param;
        }
        switch(type) {
            case "bool":
                return param.toUpperCase() === "ON";
            case "num":
                return (isFinite(param))? parseInt(param, 10) : (def)? def : 0;
            default:
                return param;
        }
    }

    var ConvertEscapeCharacters = function(text) {
        text = String(text);
        text = text.replace(/\\/g, '\x1b');
        text = text.replace(/\x1b\x1b/g, '\\');

        text = text.replace(/\x1bV\[(\d+)\]/gi, function() {
            return $gameVariables.value(parseInt(arguments[1]));
        }.bind(this));

        text = text.replace(/\x1bV\[(\d+)\]/gi, function() {
            return $gameVariables.value(parseInt(arguments[1]));
        }.bind(this));

        return text;
    };

    Parameters = PluginManager.parameters('MKR_ControlCharacterEx');
    SeVolumeDef = CheckParam("num", Parameters['Default_SE_Volume'], 90);
    SePitchDef = CheckParam("num", Parameters['Default_SE_Pitch'], 100);
    SePanDef = CheckParam("num", Parameters['Default_SE_Pan']);
    WaitPeriodDef = CheckParam("num", Parameters['Default_Wait_Period'], 15);
    WaitLineDef = CheckParam("num", Parameters['Default_Wait_Line'], 60);

    //=========================================================================
    // Window_Base
    //  エスケープコマンドを追加定義します。
    //
    //=========================================================================

    var _Window_Base_obtainEscapeCode = Window_Base.prototype.obtainEscapeCode;
    Window_Base.prototype.obtainEscapeCode = function(textState) {
        var regExp, arr;

        textState.index++;
        regExp = /^SE\[.*?\]/i;
        arr = regExp.exec(textState.text.slice(textState.index));

        if (arr) {
            textState.index += arr[0].length;
            return arr[0];
        } else {
            textState.index--;
            return _Window_Base_obtainEscapeCode.call(this, textState);
        }
    };

    //=========================================================================
    // Window_Messge
    //  エスケープコマンドを追加定義します。
    //
    //=========================================================================

    var _Window_Message_processEscapeCharacter = Window_Message.prototype.processEscapeCharacter;
    Window_Message.prototype.processEscapeCharacter = function(code, textState) {
        var regExp, arr, res, se;
        se = {};

        regExp = /^(SE)\[(.*?)\]$/i;
        arr = regExp.exec(code);

        if (arr) {
            switch(arr[1].toUpperCase()) {
                case "SE":
                    res = arr[2].split(",");
                    se["name"] = (res[0])? res[0].trim() : "";
                    se["volume"] = (isFinite(res[1]))? parseInt(res[1],10) : ConvertEscapeCharacters(SeVolumeDef);
                    se["pitch"] = (isFinite(res[2]))? parseInt(res[2],10) : ConvertEscapeCharacters(SePitchDef);
                    se["pan"] = (isFinite(res[3]))? parseInt(res[3],10) : ConvertEscapeCharacters(SePanDef);
                    AudioManager.playSe(se);
                    break;
                default:
                    _Window_Message_processEscapeCharacter.call(this, code, textState);
            }
        } else {
            switch(code) {
                case '.':
                    this.startWait(ConvertEscapeCharacters(WaitPeriodDef));
                    break;
                case '|':
                    this.startWait(ConvertEscapeCharacters(WaitLineDef));
                    break;
                default:
                    _Window_Message_processEscapeCharacter.call(this, code, textState);
            }
        }
    };

})();