code:
//
//  入手インフォメーション ver1.13
//
// ------------------------------------------------------
// Copyright (c) 2016 Yana
// Released under the MIT license
// http://opensource.org/licenses/mit-license.php
// ------------------------------------------------------
//
// author Yana
//

var Imported = Imported || {};
Imported['GetInformation'] = 1.13;

if (!Imported.CommonPopupCore) {
	console.error('CommonPopupCoreを導入してください。')
}
/*:
 * @plugindesc ver1.13/アイテムの入手などにスライドアニメするインフォメーションを追加するプラグインです。
 * @author Yana
 *
 * @param Info Disable Switch Id
 * @desc 入手インフォメーションを無効化するためのスイッチのIDです。
 * このスイッチがONの時、インフォメーションが無効化されます。
 * @default 10
 *
 * @param Use Battle Info
 * @desc 入手インフォメーションを戦闘中に使用するかの設定です。
 * true/falseで設定してください。
 * @default true
 *
 * @param Use Rewards Info
 * @desc 戦利品を入手インフォメーションで表示するかの設定です。
 * true/falseで設定してください。
 * @default true
 *
 * @param Info Pattern
 * @desc 入手インフォメーションの動作パターンです。
 * Normal:普通 GrowUp:にょき Stretch:うにょーん
 * @default GrowUp
 *
 * @param Info Font Size
 * @desc 入手インフォメーションの文字サイズです。
 * @default 20
 *
 * @param Info Count
 * @desc 入手インフォメーションの表示時間です。
 * @default 120
 *
 * @param Info Delay
 * @desc 入手インフォメーションのディレイです。
 * 連続で設定された時、この数値の表示ディレイがかかります。
 * @default 20
 *
 * @param Info MoveWait
 * @desc 入手インフォメーションが完全に表示された状態の時間です。
 * @default 100
 *
 * @param Info MoveFade
 * @desc 入手インフォメーションのフェードの時間です。
 * @default 10
 *
 * @param Info Position
 * @desc 入手インフォメーションの表示位置です。
 * Upを指定すると、画面上部になります。
 * @default
 *
 * @param Info Slide Action
 * @desc 入手インフォメーションのスライド方向です。
 * Downを指定すると、上から下になります。
 * @default
 *
 * @param Info Sup X
 * @desc 入手インフォメーションの表示位置補正X座標です。
 * @default 0
 *
 * @param Info Sup Y
 * @desc 入手インフォメーションの表示位置補正Y座標です。
 * @default 0
 *
 * @param Info Width
 * @desc 入手インフォメーションの横幅です。
 * @default 816
 *
 * @param Gold Icon Index
 * @desc 所持金のアイコンとして使用するアイコンのインデックスです。
 * @default 314
 *
 * @param Actor Icon Start Index
 * @desc アクターのアイコンとして使用するアイコンの最初のインデックスです。
 * @default 320
 *
 * @param Reward Popup Delay
 * @desc 戦利品表示時に表示開始までにかけるディレイの数値です。
 * @default 0
 *
 * @param Battle Show List
 * @desc 戦闘中に表示するインフォメーションのリストです。item,gold,
 * exp,skill,params,level,abp,classLevelで指定してください。
 * @default item,gold,exp,skill,params,level,abp,classLevel
 *
 * @param Get Gold Text
 * @desc 所持金の増加で表示されるテキストです。。
 * _icon:上記で設定したアイコンインデックス _num:金額
 * @default 「\I[_icon]_num\C[14]\G\C[0]」 を\C[24]手に入れた！
 *
 * @param Lost Gold Text
 * @desc 所持金の減少で表示されるテキストです。
 * _icon:上記で設定したアイコンインデックス _num:金額
 * @default 「\I[_icon]_num\C[14]\G\C[0]」 を\C[2]失った・・・
 *
 * @param Get Item Text
 * @desc アイテムの増加で表示されるテキストです。
 * _icon:アイコン _name:名前　_desc1:解説1行目 _desc2:解説2行目
 * @default 「\I[_icon]_name」 を\C[24]手に入れた！\n\C[6]_desc1
 *
 * @param Lost Item Text
 * @desc アイテムの減少で表示されるテキストです。
 * _icon:アイコン _name:名前　_desc1:解説1行目 _desc2:解説2行目
 * @default 「\I[_icon]_name」 を\C[2]失った・・・\n\C[6]_desc1
 *
 * @param Get Item Text Num
 * @desc アイテム増加。2個以上。_icon:アイコン
 * _name:名前　_num:個数 _desc1:解説1行目 _desc2:解説2行目
 * @default 「\I[_icon]_name」 を\C[14]_num個\C[24]手に入れた！\n\C[6]_desc1
 *
 * @param Lost Item Text Num
 * @desc アイテム減少。2個以上。_icon:アイコン
 * _name:名前　_num:個数 _desc1:解説1行目 _desc2:解説2行目
 * @default 「\I[_icon]_name」を\C[14]_num個\C[2]失った・・・\n\C[6]_desc1
 *
 * @param Get Skill Text
 * @desc スキルの習得で表示されるテキストです。_actor:アクター名
 * _icon:アイコン _name:名前　_desc1:解説1行目 _desc2:解説2行目
 * @default _actorは「\I[_icon]_name」 を\C[24]覚えた！\n\C[6]_desc1
 *
 * @param Lost Skill Text
 * @desc スキルの忘却で表示されるテキストです。_actor:アクター名
 * _icon:アイコン _name:名前　_desc1:解説1行目 _desc2:解説2行目
 * @default _actorは「\I[_icon]_name」を \C[2]忘れてしまった・・・\n\C[6]_desc1
 *
 * @param Exp Up Text
 * @desc 経験値の増加で表示されるテキストです。
 * _actor:アクター名  _name:経験値の名前 _num:経験値
 * @default _actorは\C[14]_numポイント\C[0]の\C[4]_name\C[0]を\C[24]得た！
 *
 * @param Exp Down Text
 * @desc 経験値の減少で表示されるテキストです。
 * _actor:アクター名  _name:経験値の名前　_num:経験値
 * @default _actorは\C[14]_numポイント\C[0]の\C[4]_name\C[0]を\C[2]失った・・・
 *
 * @param Lv Up Text
 * @desc レベルの増加で表示されるテキストです。
 * _actor:アクター名  _name:レベルの名前 _num:上がったレベル
 * @default _actorは\C[4]_name\C[0]が\C[14]_numポイント\C[24]上がった！
 *
 * @param Lv Down Text
 * @desc レベルの減少で表示されるテキストです。
 * _actor:アクター名  _name:レベルの名前　_num:下がったレベル
 * @default _actorは\C[4]_name\C[0]が\C[14]_numポイント\C[2]下がった・・・
 *
 * @param Param Up Text
 * @desc 能力値の増加で表示されるテキストです。
 * _actor:アクター名  _name:能力値の名前 _num:上がったレベル
 * @default _actorは\C[4]_name\C[0]が\C[14]_numポイント\C[24]上がった！
 *
 * @param Param Down Text
 * @desc 能力値の減少で表示されるテキストです。
 * _actor:アクター名  _name:能力値の名前　_num:下がったレベル
 * @default _actorは\C[4]_name\C[0]が\C[14]_numポイント\C[2]下がった・・・
 *
 * @param Abp Up Text
 * @desc クラス経験値の増加で表示されるテキストです。
 * _actor:アクター名  _name:経験値の名前 _num:経験値
 * @default _actorは\C[14]_numポイント\C[0]の\C[4]_name\C[0]を\C[24]得た！
 *
 * @param Abp Down Text
 * @desc クラス経験値の減少で表示されるテキストです。
 * _actor:アクター名  _name:経験値の名前　_num:経験値
 * @default _actorは\C[14]_numポイント\C[0]の\C[4]_name\C[0]を\C[2]失った・・・
 *
 * @param Class Lv Up Text
 * @desc クラスレベルの増加で表示されるテキストです。 _class:クラス名
 * _actor:アクター名  _name:レベルの名前 _num:上がったレベル
 * @default _actorは\C[4]_classの_name\C[0]が\C[14]_numポイント\C[24]上がった！
 *
 * @param Class Lv Down Text
 * @desc クラスレベルの減少で表示されるテキストです。 _class:クラス名
 * _actor:アクター名  _name:レベルの名前　_num:下がったレベル
 * @default _actorは\C[4]_classの_name\C[0]が\C[14]_numポイント\C[2]下がった・・・
 *
 * @param Formation Lv Up Text
 * @desc 陣形レベルの増加で表示されるテキストです。
 * _name:陣形の名前　_num:上がったレベル
 * @default \C[4]_nameの熟練度\C[0]が\C[14]_numポイント\C[24]上がった！
 *
 * @param Formation Lv Max Text
 * @desc 陣形をマスターした時に表示されるテキストです。
 * _name:陣形の名前
 * @default \C[4]_name\C[0]を\C[14]マスターした！
 *
 * @help------------------------------------------------------
 * プラグインコマンド
 * ------------------------------------------------------
 * ShowInfo 表示したいテキスト
 * インフォ表示 表示したいテキスト
 *
 * ※スペースは必ず半角で入力してください。
 * ------------------------------------------------------
 * このプラグインには「汎用ポップアップベース」のプラグインが必要です。
 * 汎用ポップアップベースより下に配置してください。
 * また、それぞれの表示テキストに何も記載しない場合、そのインフォメーションを無効化できます。
 * ------------------------------------------------------
 * 使い方
 * ------------------------------------------------------
 * 導入するだけで動作します。
 * 詳細な設定は、プラグインパラメータを参照してください。
 * ------------------------------------------------------
 * 利用規約
 * ------------------------------------------------------
 * 当プラグインはMITライセンスで公開されています。
 * 使用に制限はありません。商用、アダルト、いずれにも使用できます。
 * 二次配布も制限はしませんが、サポートは行いません。
 * 著作表示は任意です。行わなくても利用できます。
 * 要するに、特に規約はありません。
 * バグ報告や使用方法等のお問合せはネ実ツクールスレ、または、Twitterにお願いします。
 * https://twitter.com/yanatsuki_
 * 素材利用は自己責任でお願いします。
 * ------------------------------------------------------
 * 更新履歴:
 * ver1.13:
 * 戦闘中のポップアップ位置を調整しました。
 * 戦闘終了時の戦利品表示にディレイをかける設定を追加しました。
 * 陣形レベルが上がった時にポップアップを表示する機能を追加しました。
 * ver1.12:
 * 利用規約をMITライセンスに変更しました。
 * 一度も仲間になっていないアクターに対してポップアップを表示すると、無限ループに陥るバグを修正しました。
 * ver1.11:
 * 動作パターンの設定を追加しました。
 * プラグインパラメータを追加しました。
 * ver1.10:
 * 処理内容を少し変更しました。
 * ヘルプを追加・修正しました。
 * 任意のテキストを表示するプラグインコマンドを追加しました。
 * ver1.09:
 * スキルを忘れさせた際のポップアップが表示されないバグを修正しました。
 * レベルアップ時やクラスレベルアップ時のスキル習得の表示位置を調整しました。
 * ver1.08:
 * 戦闘中の表示をexpとabpを無効化すると、経験値やABPが入らないバグを修正しました。
 * ver1.07:
 * インフォメーションを無効化する機能が正常に機能していなかったバグを修正しました。
 * 戦闘時に表示するインフォメーションを設定するBattle Show Listの設定項目を追加しました。
 * ver1.06:
 * 戦闘中のポップアップの位置が正常でなかったバグを修正しました。
 * var1.05:
 * 表示位置を補正するためのプラグインパラメータを追加しました。
 * 上から下へ動作する設定を追加しました。
 * var1.04:
 * 任意のテキストを渡せるように修正しました。
 * ver1.03:
 * ABPとクラスレベルのポップアップ処理を追加しました。
 * ver1.02:
 * レベルアップ処理でポップアップ表示が逆になっていたバグを修正しました。
 * ver1.01:
 * valueが0の状態でもポップアップしていたバグを修正しました。
 * YEP_CoreEngineとの競合回避処理を追加しました。
 * ver1.00:
 * 公開
 */

(function() {
	var parameters = PluginManager.parameters('GetInformation');
	var infoDisableSwitchId = Number(parameters['Info Disable Switch Id'] || 10);
	var getGoldText = String(parameters['Get Gold Text']);
	var lostGoldText = String(parameters['Lost Gold Text']);
	var getInfoText = String(parameters['Get Item Text']);
	var lostInfoText = String(parameters['Lost Item Text']);
	var getInfoTextNum = String(parameters['Get Item Text Num']);
	var lostInfoTextNum = String(parameters['Lost Item Text Num']);
	var getInfoSkillText = String(parameters['Get Skill Text']);
	var lostInfoSkillText = String(parameters['Lost Skill Text']);
	var ExpUpText = String(parameters['Exp Up Text']);
	var ExpDownText = String(parameters['Exp Down Text']);
	var lvUpText = String(parameters['Lv Up Text']);
	var lvDownText = String(parameters['Lv Down Text']);
	var ParamUpText = String(parameters['Param Up Text']);
	var ParamDownText = String(parameters['Param Down Text']);
	var infoFontSize = Number(parameters['Info Font Size'] || 20);
	var infoCount = Number(parameters['Info Count'] || 120);
	var infoDelay = Number(parameters['Info Delay'] || 20);
	var infoMoveWait = Number(parameters['Info MoveWait'] || 100);
	var infoMoveFade = Number(parameters['Info MoveFade'] || 20);
	var goldIconIndex = Number(parameters['Gold Icon Index'] || 314);
	var actorIconStartIndex = Number(parameters['Actor Icon Start Index']);
	var useBattleInfo = String(parameters['Use Battle Info'] || 'true') === 'true';
	var useRewardsInfo = String(parameters['Use Rewards Info'] || 'true') === 'true';
	var infoSlideCount = 60;
	var infoPosition = String(parameters['Info Position'] || '');
	var infoSlideAction = String(parameters['Info Slide Action'] || '');
	var infoSupX = Number(parameters['Info Sup X'] || 0);
	var infoSupY = Number(parameters['Info Sup Y'] || 0);
    var infoPattern = parameters['Info Pattern'] || 'Normal';
	var infoWidth = parameters['Info Width'] || 816;
	var rewardPopupDelay = Number(parameters['Reward Popup Delay']);

	var abpUpText = String(parameters['Abp Up Text']);
	var abpDownText = String(parameters['Abp Down Text']);
	var clvUpText = String(parameters['Class Lv Up Text']);
	var clvDownText = String(parameters['Class Lv Down Text']);

    var fLvUpText = String(parameters['Formation Lv Up Text']);
    var fLvMaxText = String(parameters['Formation Lv Max Text']);

	var battleShowList = String(parameters['Battle Show List']).split(',');

	var _gInfo_GInterpreter_pluginCommand = Game_Interpreter.prototype.pluginCommand;
	Game_Interpreter.prototype.pluginCommand = function(command, args) {
		_gInfo_GInterpreter_pluginCommand.call(this, command, args);
		if (command === 'ShowInfo' || command === 'インフォ表示') {
			CommonPopupManager.showInfo({},args[0],null);
		}
	};

	CommonPopupManager.popEnable = function() {
		var useBattle = $gameParty.inBattle() ? useBattleInfo : true;
		return !$gameSwitches.value(infoDisableSwitchId) && useBattle;
	};

	// Change Gold
	var _gInfo_GInterpreter_command125 = Game_Interpreter.prototype.command125;
	Game_Interpreter.prototype.command125 = function() {
		CommonPopupManager._popEnable = CommonPopupManager.popEnable();
		var result = _gInfo_GInterpreter_command125.call(this);
		CommonPopupManager._popEnable = false;
		return result;
	};
	// Change Item
	var _gInfo_GInterpreter_command126 = Game_Interpreter.prototype.command126;
	Game_Interpreter.prototype.command126 = function() {
		CommonPopupManager._popEnable = CommonPopupManager.popEnable();
		var result = _gInfo_GInterpreter_command126.call(this);
		CommonPopupManager._popEnable = false;
		return result;
	};
	// Change Weapon
	var _gInfo_GInterpreter_command127 = Game_Interpreter.prototype.command127;
	Game_Interpreter.prototype.command127 = function() {
		CommonPopupManager._popEnable = CommonPopupManager.popEnable();
		var result = _gInfo_GInterpreter_command127.call(this);
		CommonPopupManager._popEnable = false;
		return result;
	};
	// Change Armor
	var _gInfo_GInterpreter_command128 = Game_Interpreter.prototype.command128;
	Game_Interpreter.prototype.command128 = function() {
		CommonPopupManager._popEnable = CommonPopupManager.popEnable();
		var result = _gInfo_GInterpreter_command128.call(this);
		CommonPopupManager._popEnable = false;
		return result;
	};
	// Change EXP
	var _gInfo_GInterpreter_command315 = Game_Interpreter.prototype.command315;
	Game_Interpreter.prototype.command315 = function() {
		CommonPopupManager._popEnable = CommonPopupManager.popEnable();
		var result = _gInfo_GInterpreter_command315.call(this);
		CommonPopupManager._popEnable = false;
		return result;
	};
	// Change Level
	var _gInfo_GInterpreter_command316 = Game_Interpreter.prototype.command316;
	Game_Interpreter.prototype.command316 = function() {
		CommonPopupManager._popEnable = CommonPopupManager.popEnable();
		var result = _gInfo_GInterpreter_command316.call(this);
		CommonPopupManager._popEnable = false;
		return result;
	};
	// Change Parameter
	var _gInfo_GInterpreter_command317 = Game_Interpreter.prototype.command317;
	Game_Interpreter.prototype.command317 = function() {
		CommonPopupManager._popEnable = CommonPopupManager.popEnable();
		var result = _gInfo_GInterpreter_command317.call(this);
		CommonPopupManager._popEnable = false;
		return result;
	};
	// Change Skill
	var _gInfo_GInterpreter_command318 = Game_Interpreter.prototype.command318;
	Game_Interpreter.prototype.command318 = function() {
		CommonPopupManager._popEnable = CommonPopupManager.popEnable();
		var result = _gInfo_GInterpreter_command318.call(this);
		CommonPopupManager._popEnable = false;
		return result;
	};

	Game_Actor.prototype.addParam = function(paramId, value) {
		Game_BattlerBase.prototype.addParam.call(this, paramId, value);
		if (CommonPopupManager._popEnable) {
			if ($gameParty.inBattle() && !battleShowList.contains('params')){ return }
			CommonPopupManager.showInfo({
				'name' : TextManager.param(paramId),
				'value' : value > 0
			}, value, 'param',this.actorId());
		}
	};
	var _gInfo_GParty_gainGold = Game_Party.prototype.gainGold;
	Game_Party.prototype.gainGold = function(amount) {
		_gInfo_GParty_gainGold.call(this, amount);
		if (CommonPopupManager._popEnable) {
			if ($gameParty.inBattle() && !battleShowList.contains('gold')){ return }
			var hash = {
				'name' : '',
				'iconIndex' : goldIconIndex,
				'description' : '',
				'value' : Math.abs(amount)
			};
			CommonPopupManager.showInfo(hash, amount, 'gold');
		}
	};
	var _gInfo_GParty_gainItem = Game_Party.prototype.gainItem;
	Game_Party.prototype.gainItem = function(item, amount, includeEquip) {
		var result = _gInfo_GParty_gainItem.call(this, item, amount, includeEquip);
		if (CommonPopupManager._popEnable) {
			if (this.inBattle() && !battleShowList.contains('item')){ return }
			CommonPopupManager.showInfo(item, amount, 'item');
		}
		if (Imported.YEP_CoreEngine) return result;
	};

	var _gInfo_GActor_learnSkill = Game_Actor.prototype.learnSkill;
	Game_Actor.prototype.learnSkill = function(skillId) {
		var isLearn = this.isLearnedSkill(skillId);
		_gInfo_GActor_learnSkill.call(this, skillId);
		if (CommonPopupManager._popEnable && !isLearn) {
			if ($gameParty.inBattle() && !battleShowList.contains('skill')){ return }
			CommonPopupManager.showInfo($dataSkills[skillId], 1, 'skill', this.actorId());
		}
	};
	var _gInfo_GActor_forgetSkill = Game_Actor.prototype.forgetSkill;
	Game_Actor.prototype.forgetSkill = function(skillId) {
		var isLearn = this.isLearnedSkill(skillId);
		_gInfo_GActor_forgetSkill.call(this, skillId);
		if (CommonPopupManager._popEnable && isLearn) {
			if ($gameParty.inBattle() && !battleShowList.contains('skill')){ return }
			CommonPopupManager.showInfo($dataSkills[skillId], 2, 'skill', this.actorId());
		}
	};
	var _gInfo_GActor_changeExp = Game_Actor.prototype.changeExp;
	Game_Actor.prototype.changeExp = function(exp, show) {
		var tExp = exp - this.currentExp();
		var plevel = this.level;
		var pSkills = this._skills.clone();
		if (CommonPopupManager._popEnable) {
			if (!$gameParty.inBattle() || battleShowList.contains('exp')){
				CommonPopupManager.showInfo({
					'name' : TextManager.exp,
					'value' : tExp > 0
				}, tExp, 'exp', this.actorId());
			}
		}
		var tempEnable = CommonPopupManager._popEnable;
		CommonPopupManager._popEnable = false;
		_gInfo_GActor_changeExp.call(this, exp, show);
		CommonPopupManager._popEnable = tempEnable;
		if ((this.level - plevel) !== 0){
			var upLevel = this.level - plevel;
			if (CommonPopupManager._popEnable) {
				if ($gameParty.inBattle() && !battleShowList.contains('level')){ return }
				CommonPopupManager.showInfo({
					'name' : TextManager.level,
					'value' : upLevel > 0
				}, upLevel, 'level', this.actorId());
			}
		}
		if (CommonPopupManager._popEnable) {
			this._skills.forEach(function(skillId){
				if (!pSkills.contains(skillId)){
					CommonPopupManager.showInfo($dataSkills[skillId], 1, 'skill', this.actorId());
				}
			}.bind(this));
		}
	};

	var _gInfo_GActor_changeLevel = Game_Actor.prototype.changeLevel;
	Game_Actor.prototype.changeLevel = function(level, show) {
		var upLevel = level - this.level;
		var tempEnable = CommonPopupManager._popEnable;
		var pSkills = this._skills.clone();
		CommonPopupManager._popEnable = false;
		_gInfo_GActor_changeLevel.call(this, level, show);
		CommonPopupManager._popEnable = tempEnable;
		if (CommonPopupManager._popEnable) {
			if ($gameParty.inBattle() && !battleShowList.contains('level')){ return }
			CommonPopupManager.showInfo({
				'name' : TextManager.level,
				'value' : upLevel > 0
			}, upLevel, 'level', this.actorId());

			this._skills.forEach(function(skillId){
				if (!pSkills.contains(skillId)){
					CommonPopupManager.showInfo($dataSkills[skillId], 1, 'skill', this.actorId());
				}
			}.bind(this));
		}
	};

	if (Imported['VXandAceHybridClass']){

		// Change Class Level
		var _gInfo_GInterpreter_changeClassLevel = Game_Interpreter.prototype.changeClassLevel;
		Game_Interpreter.prototype.changeClassLevel = function(actorId,level,show) {
			CommonPopupManager._popEnable = CommonPopupManager.popEnable();
			_gInfo_GInterpreter_changeClassLevel.call(this,actorId,level,show);
			CommonPopupManager._popEnable = false;
		};

		// Change Abp
		var _gInfo_GInterpreter_changeAbp = Game_Interpreter.prototype.changeAbp;
		Game_Interpreter.prototype.changeAbp = function(actorId,abp,show) {
			CommonPopupManager._popEnable = CommonPopupManager.popEnable();
			var result = _gInfo_GInterpreter_changeAbp.call(this,actorId,abp,show);
			CommonPopupManager._popEnable = false;
			return result;
		};

		var _gInfo_GActor_changeAbp = Game_Actor.prototype.changeAbp;
		Game_Actor.prototype.changeAbp = function(abp, show) {
			var tAbp = abp - this.currentAbp();
			var plevel = this.currentClassLevel();
			var pSkills = this._skills.clone();
			if (CommonPopupManager._popEnable) {
				if (!$gameParty.inBattle() || battleShowList.contains('abp')){
					CommonPopupManager.showInfo({
						'name' : TextManager.abp,
						'value' : tAbp > 0
					}, tAbp, 'abp', this.actorId());
				}
			}

			var tempEnable = CommonPopupManager._popEnable;
			CommonPopupManager._popEnable = false;

			_gInfo_GActor_changeAbp.call(this, abp, show);

			CommonPopupManager._popEnable = tempEnable;

			if ((this.currentClassLevel() - plevel) !== 0){
				var upLevel = this.currentClassLevel() - plevel;
				if (CommonPopupManager._popEnable) {
					if ($gameParty.inBattle() && !battleShowList.contains('classLevel')){ return }
					CommonPopupManager.showInfo({
						'name' : TextManager.classLevel,
						'value' : upLevel > 0
					}, upLevel, 'classLevel', this.actorId(), this.currentClass().name);
				}
			}
			if (CommonPopupManager._popEnable) {
				this._skills.forEach(function(skillId){
					if (!pSkills.contains(skillId)){
						CommonPopupManager.showInfo($dataSkills[skillId], 1, 'skill', this.actorId());
					}
				}.bind(this));
			}
		};

		var _gInfo_GActor_changeClassLevel = Game_Actor.prototype.changeClassLevel;
		Game_Actor.prototype.changeClassLevel = function(level, show) {
			var upLevel = level - this.currentClassLevel();
			var tempEnable = CommonPopupManager._popEnable;
            var pSkills = this._skills.clone();
			CommonPopupManager._popEnable = false;
			_gInfo_GActor_changeClassLevel.call(this, level, show);
			CommonPopupManager._popEnable = tempEnable;
			if (CommonPopupManager._popEnable) {
				if ($gameParty.inBattle() && !battleShowList.contains('classLevel')){ return }
				CommonPopupManager.showInfo({
					'name' : TextManager.classLevel,
					'value' : upLevel > 0
				}, upLevel, 'classLevel', this.actorId(), this.currentClass().name);

				this._skills.forEach(function(skillId){
					if (!pSkills.contains(skillId)){
						CommonPopupManager.showInfo($dataSkills[skillId], 1, 'skill', this.actorId());
					}
				}.bind(this));
			}
		};
	}

    var __BManager_displayRewards = BattleManager.displayRewards;
    BattleManager.displayRewards = function () {
        __BManager_displayRewards.call(this);
        if (Imported['BattleFormation']) {
			$gameTemp._popupDelay = rewardPopupDelay;
            var upLevel = this._upBfLevel;
            var item = $gameParty.battleFormation();
            if (CommonPopupManager.popEnable() && item) {
                if ($gameParty.inBattle() && !battleShowList.contains('formationLevel')) return;
				if ($gameParty.isMaxBfLevel(item.id)) {
					CommonPopupManager.showInfo({
						'name': item.name,
						'iconIndex': item.iconIndex,
						'value': 'max'
					}, upLevel, 'formationLevel', null, null);
				} else {
					CommonPopupManager.showInfo({
						'name': item.name,
						'iconIndex': item.iconIndex,
						'value': upLevel > 0
					}, upLevel, 'formationLevel', null, null);
				}
            }
			$gameTemp._popupDelay = 0;
        }
    };

	CommonPopupManager.showInfo = function(object, value, type, actor, c) {
		var text1 = null;
		if (value === 0) { return }
		switch(type) {
			case 'gold':
				text1 = getGoldText;
				if (value < 0) {
					text1 = lostGoldText
				}
				break;
			case 'item':
				text1 = getInfoText;
				if (value > 1) {
					text1 = getInfoTextNum
				} else if (value === -1) {
					text1 = lostInfoText
				} else if (value < -1) {
					text1 = lostInfoTextNum
				}
				break;
			case 'exp':
				text1 = object.value ? ExpUpText : ExpDownText;
				break;
			case 'level':
				text1 = object.value ? lvUpText : lvDownText;
				break;
			case 'abp':
				text1 = object.value ? abpUpText : abpDownText;
				break;
			case 'classLevel':
				text1 = object.value ? clvUpText : clvDownText;
				break;
			case 'param':
				text1 = object.value ? ParamUpText : ParamDownText;
				break;
			case 'skill':
				text1 = value === 1 ? getInfoSkillText : lostInfoSkillText;
				break;
			case 'formationLevel':
				text1 = object.value === 'max' ? fLvMaxText : fLvUpText;
				break;
			default :
				text1 = value;
		}
		if (text1 === '') { return }
		var descs = object.description ? object.description.split(/\n/) : [];
		if (actor) {
		    actor = $dataActors[actor];
			text1 = text1.replace(/_actor/g, actor.name);
			text1 = text1.replace(/_aicon/g, actor.id+actorIconStartIndex-1);
		}
		if (c) { text1 = text1.replace(/_class/g, c) }
		text1 = text1.replace(/_name/g, object.name);
		text1 = text1.replace(/_icon/g, object.iconIndex);
		text1 = text1.replace(/_num/g, Math.abs(value));
		text1 = descs[0] ? text1.replace(/_desc1/g, descs[0]) : text1.replace(/_desc1/g, '');
		text1 = descs[1] ? text1.replace(/_desc2/g, descs[1]) : text1.replace(/_desc2/g, '');
		var texts = text1.split(/\n|\\n/);
		for (var i = 0; i < texts.length; i++) {
			var text = texts[i].replace(/\\C\[\d+\]/g, '');
			if (text === '') { delete texts[i] }
		}
		texts = texts.compact();
		var oneHeight = (infoFontSize + 8)
		var height = oneHeight * texts.length;
		var bitmap = new Bitmap(Graphics.boxWidth, height);
		bitmap.fillRect(0, 0, infoWidth / 2, bitmap.height, 'rgba(0,0,0,0.5)');
		bitmap.gradientFillRect(infoWidth / 2, 0, infoWidth / 2, bitmap.height, 'rgba(0,0,0,0.5)', 'rgba(0,0,0,0)');
		this.window().contents = bitmap;
		this.window().drawTextEx('\\FS[' + infoFontSize + ']', 0, 0);
		for (var i = 0; i < texts.length; i++) {
			var text = '\\FS[' + infoFontSize + ']' + texts[i]
			this.window().drawTextEx(text, 8, i * oneHeight);
		}
		var arg = this.setPopup([]);
		arg.bitmap = bitmap;
        if (infoPattern === 'GrowUp') {
            arg.x = 0;//Graphics.boxWidth * -1 + infoSupX;
            arg.y = Graphics.boxHeight;// - height;
            arg.moveX = 0;//Graphics.boxWidth;
            arg.anchorX = 0;
            arg.anchorY = 1.0;
            arg.pattern = -2;
            if (infoSlideAction === 'Down') arg.anchorY = 0;
        } else if (infoPattern === 'Stretch'){
            arg.x = 0;
            arg.y = Graphics.boxHeight - height;
            arg.moveX = 0;
            arg.anchorX = 0;
            arg.anchorY = 0;
            arg.pattern = -1;
        } else {
            arg.x = Graphics.boxWidth * -1 + infoSupX;
            arg.y = Graphics.boxHeight - height;
            arg.moveX = Graphics.boxWidth;
            arg.anchorX = 0;
            arg.anchorY = 0;
        }
		if (infoPosition === 'Up'){ arg.y = 0 }
		arg.y += infoSupY;
		if ($gameParty.inBattle() && (SceneManager._scene._messageWindow && SceneManager._scene._messageWindow.active)) {
            var my = SceneManager._scene._messageWindow.y;
            arg.y = Math.min(arg.y,my - height +  height * arg.anchorY);
        }
        if ((SceneManager._scene._statusWindow && SceneManager._scene._statusWindow.isOpen())){
            var sy = SceneManager._scene._statusWindow.y;
            arg.y = Math.min(arg.y,sy - height +  height * arg.anchorY);
		}
		arg.moveY = 0;
		arg.count = infoCount;
		arg.fixed = false;
		arg.extend = [infoMoveFade,infoMoveWait];
		arg.slideCount = infoSlideCount;
		arg.delay = 0;
		arg.slideAction = infoSlideAction;
		var array = CommonPopupManager._tempCommonSprites.compact();
		if (CommonPopupManager._lastIndex && array[CommonPopupManager._lastIndex]){
			array.sort(function(a,b){ return a.delay > b.delay ? -1 : 1 });
			arg.delay = array[0].delay + infoDelay;
		}
		if ($gameTemp._popupDelay && arg.delay === 0) arg.delay += $gameTemp._popupDelay;
		CommonPopupManager._lastIndex = this._tempCommonSprites.setNullPos(arg);
	};

	var _gInfo_BManager_gainRewards = BattleManager.gainRewards;
	BattleManager.gainRewards = function() {
		CommonPopupManager._popEnable = CommonPopupManager.popEnable() && useRewardsInfo;
		$gameTemp._popupDelay = rewardPopupDelay;
		_gInfo_BManager_gainRewards.call(this);
		CommonPopupManager._popEnable = false;
		$gameTemp._popupDelay = 0;
	};
})();


code:
//=============================================================================
// GraphicalDesignMode.js
// ----------------------------------------------------------------------------
// Copyright (c) 2015 Triacontane
// This software is released under the MIT License.
// http://opensource.org/licenses/mit-license.php
// ----------------------------------------------------------------------------
// Version
// 2.8.0 2017/07/26 コンソールからの関数実行で直前に編集したウィンドウの位置を変更できる機能を追加
// 2.7.0 2017/04/11 2.6.0の修正で追加ウィンドウの位置変更が正常に動作しない問題を修正
//                  選択肢ウィンドウについて位置変更を一時的に無効化するプラグインコマンドを追加
// 2.6.0 2017/04/07 追加したピクチャやウィンドウについて任意のスイッチがONのときのみ表示できる機能を追加
// 2.5.0 2017/03/11 ウィンドウを非表示にできる機能を追加
// 2.4.0 2017/01/09 カスタムウィンドウに表示する内容に揃えを指定できる機能を追加しました。
// 2.3.1 2016/11/30 RPGアツマールで画面がNowLoadingから進まなくなる場合がある問題を修正しました。
// 2.3.0 2016/11/25 メッセージウィンドウの背景の表示可否を固定にできる機能を追加しました。
// 2.2.1 2016/11/12 Macの場合、Ctrlキーの代わりにoptionキーを使用するようヘルプを追記
// 2.2.0 2016/11/03 ウィンドウごとに使用するフォントを設定できる機能を追加
// 2.1.0 2016/09/28 アイコンサイズをフォントサイズに合わせて自動で拡縮できる機能を追加
//                  操作対象のウィンドウにフォーカスしたときに枠の色を変えて明示する機能を追加
//                  数値項目のプロパティを設定する際にJavaScript計算式を適用できる機能を追加
// 2.0.0 2016/08/22 本体v1.3.0によりウィンドウ透過の実装が変更されたので対応
// 1.1.3 2016/08/05 本体v1.3.0にて表示される警告を抑制
// 1.1.2 2016/07/20 一部のウィンドウでプロパティロード後にコンテンツが再作成されない問題を修正
// 1.1.1 2016/07/17 余白とフォントサイズの変更が、画面切り替え後に元に戻ってしまう問題を修正
// 1.1.0 2016/07/11 メッセージウィンドウのみ位置変更を一時的に無効化するプラグインコマンドを追加
// 1.0.2 2016/04/02 liply_memoryleak_patch.jsとの競合を解消
// 1.0.1 2016/03/28 一部のウィンドウのプロパティを変更しようとするとエラーが発生する現象の修正
// 1.0.0 2016/03/13 初版
// 0.9.0 2016/03/05 ベータ版
// ----------------------------------------------------------------------------
// [Blog]   : http://triacontane.blogspot.jp/
// [Twitter]: https://twitter.com/triacontane/
// [GitHub] : https://github.com/triacontane/
//=============================================================================

/*:
 * @plugindesc GUI画面デザインプラグイン
 * パラメータを変更したら「プロジェクトの保存」（Ctrl+S）
 * @author トリアコンタン
 *
 * @param デザインモード
 * @desc デザインモードでゲームを起動します。(ON/OFF)
 * モード中はドラッグ＆ドロップで位置を調整できます。
 * @default true
 * @type boolean
 *
 * @param 自動保存
 * @desc 位置を変更したときに自動で変更を保存します。(ON/OFF)
 * 通常は、Ctrl+Sで保存します。
 * @default false
 * @type boolean
 *
 * @param モバイル版作成
 * @desc モバイル版のウィンドウ配置を別に作成します。(ON/OFF)
 * モバイル版とPC版とでウィンドウ配置を変えたい場合のみONにしてください。
 * @default false
 * @type boolean
 *
 * @param モバイル偽装
 * @desc モバイル実行を偽装します。(ON/OFF)
 * モバイル版のウィンドウ作成やテスト時にONにしてください。
 * @default false
 * @type boolean
 *
 * @param ウィンドウ透過
 * @desc ウィンドウが重なったときに透過表示します。(ON/OFF)
 * 他のプラグインで同様機能を実現している場合はOFF。
 * @default false
 * @type boolean
 *
 * @param グリッドサイズ
 * @desc ウィンドウ調整中に指定サイズでグリッドを表示します。
 * 0を指定すると非表示になります。
 * @default 48
 * @type number
 *
 * @param パディング
 * @desc ウィンドウ余白のデフォルト値です。入力した場合、適用されます。デフォルト：18
 * @default 0
 * @type number
 *
 * @param フォントサイズ
 * @desc ウィンドウフォントサイズのデフォルト値です。入力した場合、適用されます。デフォルト：28
 * @default 0
 * @type number
 *
 * @param 行の高さ
 * @desc ウィンドウの行高のデフォルト値です。入力した場合、適用されます。デフォルト：36
 * @default 0
 * @type number
 *
 * @param 背景透明度
 * @desc ウィンドウの背景透明度デフォルト値です。入力した場合、適用されます。デフォルト：192
 * @default 0
 * @type number
 *
 * @param アイコンサイズ調整
 * @desc フォントサイズが変更された場合にアイコンのサイズを自動で調整します。
 * @default false
 * @type boolean
 *
 * @param 背景表示可否固定
 * @desc メッセージウィンドウ等でイベント命令ごとに指定する背景の表示設定を無視して、プラグインの設定値で固定します。
 * @default false
 * @type boolean
 *
 * @param 右クリックで消去
 * @desc デザインモードで右クリックしたときにウィンドウ全体を非表示にします。(OFFの場合は枠のみ消去)
 * @default false
 * @type boolean
 *
 * @help メニュー画面や戦闘画面など各画面のウィンドウや画像の表示位置を
 * ドラッグ＆ドロップで微調整して画面の外観をグラフィカルに設計できます。
 * 横幅、高さ、余白、背景画像なども画面上で変更できます。
 *
 * デフォルトの画面のほかプラグインによって追加された画面についても
 * 位置のカスタマイズが可能です。
 * (ただし、相手の実装に依存するので動作保証はできません)
 *
 * 以下の手順で実行してください。
 *
 * 1. パラメータ「デザインモード」を「ON」にする。
 *   - デフォルトで「ON」になっています。
 *
 * 2. テストプレー、戦闘テスト、イベントテストを開始する。
 *
 * 3. マウスでオブジェクトを掴んで好きな場所に配置する。
 *   - マウスによる通常のウィンドウ操作は無効になります。
 *   - 他のウィンドウや画面端に自動でスナップします。(Shiftで無効化)
 *   - Ctrlを押していると、グリッドにスナップします。(Macの場合はoptionキー)
 *   - Ctrl+Zで直前の変更を元に戻します。
 *   - Ctrl+Shift+Enterで現在のシーンの変更を全て初期化します。
 *   - ウィンドウ内で右クリックすると、枠の透明/不透明を切り替えます。
 *     パラメータを変更している場合は、ウィンドウ全体の表示/非表示を切り替えます。
 *     一度非表示にすると、画面全体をリセットしない限り再表示できません。
 *   - ウィンドウ内で数字キー(※)を押下すると、各プロパティを変更できます。
 *   - コンソールに「changePos(x, y);」(x:X座標、y:Y座標)と打ち込むと
 *     直前に編集したウィンドウ位置を変更できます。
 *
 * 4. Ctrl+Sでカスタマイズした位置を保存する。
 *
 * 5. 通常のテストプレー時は「デザインモード」を「OFF」にする。
 *
 * ※数字とプロパティの対応（テンキーでない方の数字キーです）
 *
 * 1. ウィンドウの横幅(※1)
 * 2. ウィンドウの高さ(直接指定)(※1)
 * 3. ウィンドウの余白(※2)
 * 4. ウィンドウのフォントサイズ(※2)
 * 5. ウィンドウの1行のあたりの高さ(※2)
 * 6. ウィンドウの背景透明度(※2)
 * 7. ウィンドウの行数(※2)
 * 8. ウィンドウの背景画像ファイル名
 * 9. ウィンドウのフォント名(※3)
 *
 * ※1 JS計算式を適用できます。計算式は入力したその場で1回だけ評価されます。
 * ※2 JS計算式を適用できます。計算式は保存され、画面表示のたびに再評価されます。
 * 分からない場合、今まで通り数値を設定すれば問題ありません。
 * ※3 フォントをロードする必要があります。「フォントロードプラグイン」をお使いください。
 * 入手先：raw.githubusercontent.com/triacontane/RPGMakerMV/master/FontLoad.js
 * ※4 Macの場合、Ctrlキーはoptionキーで代用してください。（commandキーでは反応しません）
 *
 * また、任意のピクチャやウィンドウを追加表示することができます。
 * 詳細はソースコードの「ユーザ書き換え領域」を参照してください。
 * 追加表示したものも、ドラッグ＆ドロップで位置を調整できます。
 *
 * ウィンドウに表示する内容は、以下の制御文字で揃えを変更することができます。
 * \\AL[left]   # 左揃え(未記入の場合も左揃えになります)
 * \\AL[0]      # 同上
 * \\AL[center] # 中央揃え
 * \\AL[1]      # 同上
 * \\AL[right]  # 右揃え
 * \\AL[2]      # 同上
 *
 * セーブした内容は「data/ContainerProperties.json」に保存されます。
 * JSONエディタ等で編集することも可能です。
 *
 * さらに、モバイル端末用に異なるウィンドウ配置を定義することもできます。
 * モバイル用の配置情報は「data/ContainerPropertiesMobile.json」に保存されます。
 *
 * モバイル偽装のオプションを有効にすると、モバイル端末での実行をPC上で
 * 再現できます。モバイル実行を再現すると音声や動画ファイルの使用形式が
 * 変化したり、音声ファイルの再生が行われなくなったりする可能性があります。
 *
 * 本プラグインで位置を変更したウィンドウは、以後位置を変更することができなくなります。
 * よって、ゲーム中に動的に位置が変更されるウィンドウに対して本プラグインで
 * 位置を固定すると正常に表示されなくなる場合があります。
 *
 * そういったケースを含め、表示がおかしくなった場合は
 * 一旦、Ctrl+Shift+Enterを実行して画面中の全てのウィンドウを初期化することを勧めます。
 *
 * 要注意！　追加したピクチャは、デプロイメント時に
 * 未使用ファイルとして除外される可能性があります。
 * その場合、削除されたファイルを入れ直す等の対応が必要です。
 *
 * 注意！
 * 他のプラグインの使用状況によってウィンドウの位置やサイズが
 * 正しく保存されない場合があります。
 *
 * プラグインコマンド詳細
 *  イベントコマンド「プラグインコマンド」から実行。
 *  （パラメータの間は半角スペースで区切る）
 *
 * GDM解除_メッセージウィンドウ
 * GDM_UNLOCK_MESSAGE_WINDOW
 *  メッセージウィンドウの位置変更を一時的に解除します。
 *  プラグインで変更した座標が無効になり
 *  イベント「メッセージ表示」で指定したウィンドウ位置が有効になります。
 *
 * GDM固定_メッセージウィンドウ
 * GDM_LOCK_MESSAGE_WINDOW
 *  メッセージウィンドウの位置変更を再度、有効にします。
 *  プラグインで変更した座標が有効になり
 *  イベント「メッセージ表示」で指定したウィンドウ位置は無視されます。
 *
 * GDM解除_選択肢ウィンドウ
 * GDM_UNLOCK_CHOICE_WINDOW
 *  選択肢ウィンドウの位置変更を一時的に解除します。
 *  プラグインで変更した座標が無効になり
 *  イベント「選択肢の表示」で指定したウィンドウ位置が有効になります。
 *
 * GDM固定_選択肢ウィンドウ
 * GDM_LOCK_CHOICE_WINDOW
 *  メッセージウィンドウの位置変更を再度、有効にします。
 *  プラグインで変更した座標が有効になり
 *  イベント「選択肢の表示」で指定したウィンドウ位置は無視されます。
 *
 * 利用規約：
 *  作者に無断で改変、再配布が可能で、利用形態（商用、18禁利用等）
 *  についても制限はありません。
 *  このプラグインはもうあなたのものです。
 */
var $dataContainerProperties = null;

(function() {
    'use strict';
    //=============================================================================
    // ユーザ書き換え領域 - 開始 -
    //  pictures : 各画面で表示するピクチャ情報
    //  windows  : 各画面で表示するウィンドウ情報
    // （ここで指定したファイル名は、デプロイメント時に
    // 　未使用ファイルとして除外される可能性があります）
    // ※コピー＆ペーストしやすくするために最後の項目にもカンマを付与しています。
    //=============================================================================
    var settings = {
        /* タイトル画面の追加情報 */
        Scene_Title   : {
            /* pictures:シーンに追加表示する画像です。無条件で表示されます。 */
            pictures: [
                /* file:「img/pictures/」以下のファイルを拡張子なしで指定します  switchId: 表示条件となるスイッチIDです*/
                {file: '', switchId: 0},
            ],
            /* windows:シーンに追加表示するウィンドウです。*/
            windows : [
                /* lines:表示内容の配列です。 制御文字が利用できます。「\\i[n]」と「\」をひとつ多く指定してください。*/
                /* switchId:出現条件となるスイッチIDです */
                /* 位置を調整後に新しいウィンドウを追加する場合は、必ず「配列の末尾に追加」してください */
                {lines: [], switchId: 0},
            ],
        },
        /* メインメニュー画面の追加情報 */
        Scene_Menu    : {
            pictures: [
                {file: '', switchId: 0},
            ],
            windows : [
                {lines: [], switchId: 0},
            ],
        },
        /* 戦闘画面の追加情報 */
        Scene_Battle  : {
            pictures: [
                {file: '', switchId: 0},
            ],
            windows : [
                {lines: [], switchId: 0},
            ],
        },
        /* アイテムメニュー画面の追加情報 */
        Scene_Item    : {
            pictures: [
                {file: '', switchId: 0},
            ],
            windows : [
                {lines: [], switchId: 0},
            ],
        },
        /* スキルメニュー画面の追加情報 */
        Scene_Skill   : {
            pictures: [
                {file: '', switchId: 0},
            ],
            windows : [
                {lines: [], switchId: 0},
            ],
        },
        /* 装備メニュー画面の追加情報 */
        Scene_Equip   : {
            pictures: [
                {file: '', switchId: 0},
            ],
            windows : [
                {lines: [], switchId: 0},
            ],
        },
        /* ステータスメニュー画面の追加情報 */
        Scene_Status  : {
            pictures: [
                {file: '', switchId: 0},
            ],
            windows : [
                {lines: [], switchId: 0},
            ],
        },
        /* オプション画面の追加情報 */
        Scene_Options : {
            pictures: [
                {file: '', switchId: 0},
            ],
            windows : [
                {lines: [], switchId: 0},
            ],
        },
        /* セーブ画面の追加情報 */
        Scene_Save    : {
            pictures: [
                {file: '', switchId: 0},
            ],
            windows : [
                {lines: [], switchId: 0},
            ],
        },
        /* ロード画面の追加情報 */
        Scene_Load    : {
            pictures: [
                {file: '', switchId: 0},
            ],
            windows : [
                {lines: [], switchId: 0},
            ],
        },
        /* ショップ画面の追加情報 */
        Scene_Shop    : {
            pictures: [
                {file: '', switchId: 0},
            ],
            windows : [
                {lines: [], switchId: 0},
            ],
        },
        /* 名前入力画面の追加情報 */
        Scene_Name    : {
            pictures: [
                {file: '', switchId: 0},
            ],
            windows : [
                {lines: [], switchId: 0},
            ],
        },
        /* ゲームオーバー画面の追加情報 */
        Scene_Gameover: {
            pictures: [
                {file: '', switchId: 0},
            ],
            windows : [
                {lines: [], switchId: 0},
            ],
        },
    };
    //=============================================================================
    // ユーザ書き換え領域 - 終了 -
    //=============================================================================
    var pluginName    = 'GraphicalDesignMode';
    var metaTagPrefix = 'GDM';

    if (!Utils.RPGMAKER_VERSION || Utils.RPGMAKER_VERSION.match(/^1\.2./)) {
        console.error('!!!このプラグインは本体バージョン1.3系以降でないと使用できません。!!!');
        return;
    }

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

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

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

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

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

    var checkTypeFunction = function(value) {
        return checkType(value, 'Function');
    };

    var checkType = function(value, typeName) {
        return Object.prototype.toString.call(value).slice(8, -1) === typeName;
    };

    var getClassName = function(object) {
        return object.constructor.toString().replace(/function\s+(.*)\s*\([\s\S]*/m, '$1');
    };

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

    var paramDesignMode      = getParamBoolean(['DesignMode', 'デザインモード']);
    var paramThroughWindow   = getParamBoolean(['ThroughWindow', 'ウィンドウ透過']);
    var paramAutoSave        = getParamBoolean(['AutoSave', '自動保存']);
    var paramGridSize        = getParamNumber(['GridSize', 'グリッドサイズ'], 0) || 0;
    var paramPadding         = getParamNumber(['Padding', 'パディング']);
    var paramFontSize        = getParamNumber(['FontSize', 'フォントサイズ']);
    var paramLineHeight      = getParamNumber(['LineHeight', '行の高さ']);
    var paramBackOpacity     = getParamNumber(['LineHeight', '背景透明度']);
    var paramMobileMake      = getParamBoolean(['MobileMake', 'モバイル版作成']);
    var paramFakeMobile      = getParamBoolean(['FakeMobile', 'モバイル偽装']);
    var paramIconSizeScale   = getParamBoolean(['IconSizeScale', 'アイコンサイズ調整']);
    var paramBackgroundFixed = getParamBoolean(['BackgroundFixed', '背景表示可否固定']);
    var paramRightClickHide  = getParamBoolean(['RightClickHide', '右クリックで消去']);

    //=============================================================================
    // Utils
    //  デザインモード判定を追加します。
    //=============================================================================
    Utils.isDesignMode = function() {
        return (this.isOptionValid('test') || this.isOptionValid('btest') || this.isOptionValid('etest')) &&
            this.isNwjs() && paramDesignMode;
    };

    //=============================================================================
    // デザインモードの場合のみ実装する
    //=============================================================================
    if (Utils.isDesignMode()) {

        //=============================================================================
        // グローバル関数
        //=============================================================================
        window.changePos = function(x, y) {
            SceneManager.setLastWindowPosition(x, y);
        };

        //=============================================================================
        // Input
        //  コピーと上書き保存用のボタンを追加定義します。
        //=============================================================================
        Input.keyMapper[67] = 'copy';
        Input.keyMapper[83] = 'save';
        for (var i = 49; i < 58; i++) {
            Input.keyMapper[i] = 'num' + (i - 48);
        }

        var _Input__wrapNwjsAlert = Input._wrapNwjsAlert;
        Input._wrapNwjsAlert      = function() {
            _Input__wrapNwjsAlert.apply(this, arguments);
            var _prompt   = window.prompt;
            window.prompt = function() {
                var gui    = require('nw.gui');
                var win    = gui.Window.get();
                var result = _prompt.apply(this, arguments);
                win.focus();
                Input.clear();
                return result;
            };
        };

        var _Input_isRepeated = Input.isRepeated;
        Input.isRepeated      = function(keyName) {
            if (keyName === 'ok' && this.isPressed('control')) {
                return false;
            }
            return _Input_isRepeated.apply(this, arguments);
        };

        //=============================================================================
        // TouchInput
        //  ポインタ位置を常に記憶します。
        //=============================================================================
        TouchInput._onMouseMove = function(event) {
            var x = Graphics.pageToCanvasX(event.pageX);
            var y = Graphics.pageToCanvasY(event.pageY);
            this._onMove(x, y);
        };

        //=============================================================================
        // SceneManager
        //  ウィンドウポジションをjson形式で保存する処理を追加定義します。
        //=============================================================================
        SceneManager.controlNumber = 0;

        var _SceneManager_initialize = SceneManager.initialize;
        SceneManager.initialize      = function() {
            _SceneManager_initialize.call(this);
            this.lastWindowX            = null;
            this.lastWindowY            = null;
            this._lastWindow            = null;
            this._windowPositionChanged = false;
            this.infoWindow             = '';
            this.infoExtend             = '';
            this._copyCount             = 0;
            this._infoHelp              = 'デザインモードで起動しています。 ';
            this._documentTitle         = '';
            this._changeStack           = [];
            this.showDevToolsForGdm();
        };

        SceneManager.setLastWindow = function(windowObject) {
            this._lastWindow = windowObject;
        };

        SceneManager.setLastWindowPosition = function(x, y) {
            if (!this._lastWindow) {
                this.setInfoExtend('直前に触れたオブジェクトが存在しないため、この操作は無効です。', 0);
                return;
            }
            this._lastWindow.position.x = x;
            this._lastWindow.position.y = y;
            this._windowPositionChanged = true;
        };

        SceneManager.isWindowPositionChanged = function(windowObject) {
            if (this._windowPositionChanged && windowObject === this._lastWindow) {
                this._windowPositionChanged = false;
                return true;
            }
            return false;
        };

        SceneManager.showDevToolsForGdm = function() {
            var nwWin = require('nw.gui').Window.get();
            if (!nwWin.isDevToolsOpen()) {
                var devTool = nwWin.showDevTools();
                devTool.moveTo(0, 0);
                devTool.resizeTo(window.screenX + window.outerWidth, window.screenY + window.outerHeight);
                nwWin.focus();
            }
            this.outputStartLog();
        };

        SceneManager.outputStartLog = function() {
            var logValue = [
                '☆☆☆ようこそ、デザインモードで起動しました。☆☆☆\n',
                'デザインモードでは、オブジェクトの配置やプロパティを自由に設定して実際のゲーム画面上から画面設計できます。\n',
                '--------------------操 作 方 法----------------------------------------------------------------------\n',
                'ドラッグ&ドロップ ： ウィンドウや画像を掴んで好きな場所に再配置します。\n',
                'Ctrl+マウス ： ウィンドウや画像がグリッドにスナップします。(Macの場合はoptionキー)\n',
                'Shift+マウス ： ウィンドウや画像がオブジェクトや画面端にスナップしなくなります。\n',
                'コンソールに「changePos(x, y);」(x:X座標、y:Y座標)と打ち込むと直前に編集したウィンドウ位置を変更できます。\n',
                'Ctrl+S ： 全ての変更を保存します。\n',
                'Ctrl+C ： 直前に操作した座標をクリップボードにコピーします。\n',
                'Ctrl+Z ： 直前に行った操作を元に戻します。\n',
                'Ctrl+Shift+Enter ： 表示している画面の配置を全てリセットしてロードし直します。\n',
                '右クリック ： ウィンドウの枠（もしくはウィンドウ全体）の表示/非表示を切り替えます。\n',
                '数字キー ： ウィンドウの範囲内で押下すると、以下のとおり対応するプロパティを変更できます。\n',
                ' 1. ウィンドウの横幅(※1)\n',
                ' 2. ウィンドウの高さ(直接指定)(※1)\n',
                ' 3. ウィンドウの余白(※2)\n',
                ' 4. ウィンドウのフォントサイズ(※2)\n',
                ' 5. ウィンドウの1行のあたりの高さ(※2)\n',
                ' 6. ウィンドウの背景透明度(※2)\n',
                ' 7. ウィンドウの行数(※2)\n',
                ' 8. ウィンドウの背景画像ファイル名\n',
                ' 9. ウィンドウのフォント名(※3)\n',
                '※1 JS計算式を適用できます。計算式は入力したその場で1回だけ評価されます。\n',
                '※2 JS計算式を適用できます。計算式は保存され、画面表示のたびに再評価されます。\n',
                '分からない場合、今まで通り数値を設定すれば問題ありません。\n',
                '※3 あらかじめフォントをロードする必要があります。「フォントロードプラグイン」をお使いください。\n',
                '入手先：raw.githubusercontent.com/triacontane/RPGMakerMV/master/FontLoad.js\n',
                '※4 Macの場合、Ctrlキーはoptionキーで代用してください。（commandキーでは反応しません）\n',
                '-----------------------------------------------------------------------------------------------------\n',
                '以下の操作ログが表示されます。\n'
            ];
            console.log.apply(console, logValue);
        };

        var _SceneManager_onSceneCreate = SceneManager.onSceneCreate;
        SceneManager.onSceneCreate      = function() {
            _SceneManager_onSceneCreate.apply(this, arguments);
            this._changeStack = [];
        };

        SceneManager.pushChangeStack = function(child) {
            var index = child.parent.getChildIndex(child);
            var info  = {parent: child.parent, index: index};
            child.saveProperty(info);
            this._changeStack.push(info);
        };

        SceneManager.popChangeStack = function() {
            var info = this._changeStack.pop();
            if (info) {
                var child = info.parent.children[info.index];
                if (child) {
                    child.loadProperty(info);
                    child.saveContainerInfo();
                    return true;
                }
            }
            return false;
        };

        var _SceneManager_update = SceneManager.updateMain;
        SceneManager.updateMain  = function() {
            _SceneManager_update.apply(this, arguments);
            this.updateDragInfo();
        };

        SceneManager.updateDragInfo = function() {
            if (Input.isPressed('control') && Input.isTriggered('copy')) {
                SoundManager.playOk();
                if (this.lastWindowX == null || this.lastWindowY == null) return;
                var clipboard = require('nw.gui').Clipboard.get();
                var copyValue = '';
                if (this._copyCount % 2 === 0) {
                    copyValue = this.lastWindowX.toString();
                    this.setInfoExtend('X座標[' + copyValue + ']をクリップボードにコピーしました。', 0);
                } else {
                    copyValue = this.lastWindowY.toString();
                    this.setInfoExtend('Y座標[' + copyValue + ']をクリップボードにコピーしました。', 0);
                }
                clipboard.set(copyValue, 'text');
                this._copyCount++;
            }
            if (Input.isPressed('control') && Input.isTriggered('save')) {
                SoundManager.playSave();
                DataManager.saveDataFileWp();
                this.setInfoExtend('すべての変更を保存しました。', 0);
            }
            if (Input.isPressed('control') && Input.isTriggered('ok')) {
                if (this.popChangeStack()) {
                    SoundManager.playCancel();
                    this.setInfoExtend('左記の番号の操作を元に戻しました。', -1);
                    if (paramAutoSave) DataManager.saveDataFileWp();
                }
            }
            if (Input.isPressed('control') && Input.isPressed('shift') && Input.isPressed('ok')) {
                $dataContainerProperties[this.getSceneName()] = {};
                DataManager.saveDataFileWp();
                location.reload();
            }
            var docTitle        = this._infoHelp + this.infoWindow + this.infoExtend;
            document.title      = docTitle;
            this._documentTitle = docTitle;
        };

        SceneManager.setInfoExtend = function(value, add) {
            this.controlNumber += add;
            this.infoExtend = ' ' + value;
            console.log(add ? this.controlNumber + (add < 0 ? 1 : 0) + ' : ' + value : value);
            if (paramAutoSave && add !== 0) {
                console.log('自動保存により変更が保存されました。');
            }
        };

        //=============================================================================
        // DataManager
        //  ウィンドウポジションをjson形式で保存する処理を追加定義します。
        //=============================================================================
        DataManager.saveDataFileWp = function() {
            StorageManager.saveToLocalDataFile(this._databaseFileCp.src, window[this._databaseFileCp.name]);
        };

        //=============================================================================
        // StorageManager
        //  ウィンドウポジションをjson形式で保存する処理を追加定義します。
        //=============================================================================
        StorageManager.saveToLocalDataFile = function(fileName, json) {
            var data     = JSON.stringify(json);
            var fs       = require('fs');
            var dirPath  = this.localDataFileDirectoryPath();
            var filePath = dirPath + fileName;
            if (!fs.existsSync(dirPath)) {
                fs.mkdirSync(dirPath);
            }
            fs.writeFileSync(filePath, data);
        };

        StorageManager.localDataFileDirectoryPath = function() {
            var path = window.location.pathname.replace(/(\/www|)\/[^\/]*$/, '/data/');
            if (path.match(/^\/([A-Z]\:)/)) {
                path = path.slice(1);
            }
            return decodeURIComponent(path);
        };

        //=============================================================================
        // Scene_Base
        //  ウィンドウをドラッグ＆ドロップします。
        //=============================================================================
        var _Scene_Base_update      = Scene_Base.prototype.update;
        Scene_Base.prototype.update = function() {
            _Scene_Base_update.apply(this, arguments);
            if (this._windowLayer) this.updateDrag();
        };

        Scene_Base.prototype.updateDrag = function() {
            this._windowLayer.isFrameChanged = false;

            var result = this._windowLayer.children.clone().reverse().some(function(container) {
                return checkTypeFunction(container.processDesign) && container.processDesign();
            }, this);
            if (result) return;
            this.children.clone().reverse().some(function(container) {
                return checkTypeFunction(container.processDesign) && container.processDesign();
            }, this);
        };

        var _Scene_Base_createWindowLayer      = Scene_Base.prototype.createWindowLayer;
        Scene_Base.prototype.createWindowLayer = function() {
            if (!(this instanceof Scene_Boot) && !(this instanceof Scene_Map)) this.createGridSprite();
            _Scene_Base_createWindowLayer.apply(this, arguments);
        };

        Scene_Base.prototype.createGridSprite = function() {
            var size = paramGridSize;
            if (size === 0) return;
            var width        = Graphics.boxWidth;
            var height       = Graphics.boxHeight;
            this._gridSprite = new Sprite();
            this._gridSprite.setFrame(0, 0, width, height);
            var bitmap = new Bitmap(width, height);
            for (var x = 0; x < width; x += size) {
                bitmap.fillRect(x, 0, 1, height, 'rgba(255,255,255,1.0)');
            }
            for (var y = 0; y < height; y += size) {
                bitmap.fillRect(0, y, width, 1, 'rgba(255,255,255,1.0)');
            }
            this._gridSprite.bitmap      = bitmap;
            this._gridSprite.moveDisable = true;
            this.addChild(this._gridSprite);
        };

        //=============================================================================
        // PIXI.Container およびそのサブクラス
        //  コンテナをドラッグ＆ドロップします。
        //=============================================================================
        var _PIXI_DisplayObjectContainer_initialize = PIXI.Container.prototype.initialize;
        PIXI.Container.prototype.initialize         = function(x, y, width, height) {
            _PIXI_DisplayObjectContainer_initialize.apply(this, arguments);
            this._holding      = false;
            this._dx           = 0;
            this._dy           = 0;
            this.moveDisable   = false;
            this._positionLock = false;
        };

        PIXI.Container.prototype.processDesign = function() {
            var result = false;
            if (!this.moveDisable) {
                if (this.processPosition()) {
                    var info                 = 'X:[' + this.x + '] Y:[' + this.y + ']';
                    SceneManager.lastWindowX = this.x;
                    SceneManager.lastWindowY = this.y;
                    SceneManager.infoWindow  = info;
                    SceneManager.infoCopy    = '';
                    if (!this._holding) SceneManager.setInfoExtend('位置を変更しました。' + info, 1);
                    result = true;
                }
                if (this.processOpacity()) {
                    SceneManager.setInfoExtend('背景の表示/非表示を変更しました。', 1);
                    result = true;
                }
                if (this.processInput()) {
                    SceneManager.setInfoExtend(this._propLabel + 'の値を' + this._propValue + 'に変更しました。', 1);
                    result = true;
                }
                this.processFrameChange();
            }
            return result;
        };

        PIXI.Container.prototype.processPosition = function() {
            if (SceneManager.isWindowPositionChanged(this)) {
                return true;
            }
            if (this.isTouchEvent(TouchInput.isTriggered) || (this._holding && TouchInput.isPressed())) {
                if (!this._holding) this.hold();
                var x = TouchInput.x - this._dx;
                var y = TouchInput.y - this._dy;
                if (Input.isPressed('control')) {
                    var size = paramGridSize;
                    if (size !== 0) {
                        x += (x % size > size / 2 ? size - x % size : -(x % size));
                        y += (y % size > size / 2 ? size - y % size : -(y % size));
                    }
                } else if (!Input.isPressed('shift') && !this.isAnchorChanged()) {
                    x = this.updateSnapX(x);
                    y = this.updateSnapY(y);
                }
                this.position.x    = x;
                this.position.y    = y;
                this._positionLock = true;
                return true;
            } else if (this._holding) {
                this.release();
                return true;
            }
            return false;
        };

        PIXI.Container.prototype.processFrameChange = function() {};

        Window_Base.prototype.processFrameChange = function() {
            if (this._holding || !TouchInput.isMoved()) return;
            if (this.isPreparedEvent() && !this.parent.isFrameChanged) {
                this._windowFrameSprite.setBlendColor([255, 128, 0, 192]);
                this.parent.isFrameChanged = true;
                SceneManager.setLastWindow(this);
            } else {
                this._windowFrameSprite.setBlendColor([0, 0, 0, 0]);
            }
        };

        PIXI.Container.prototype.processOpacity = function() {};

        Window_Base.prototype.processOpacity = function() {
            if (this.isTouchEvent(TouchInput.isCancelled)) {
                SoundManager.playMiss();
                SceneManager.pushChangeStack(this);
                if (paramRightClickHide) {
                    this.visible = !this.visible;
                } else {
                    this.opacity = (this.opacity === 255 ? 0 : 255);
                }
                this.saveContainerInfo();
                return true;
            }
            return false;
        };

        PIXI.Container.prototype.processInput = function() {};

        Window_Base.prototype.processInput = function() {
            if (this.isPreparedEvent()) {
                var params = [
                    ['num1', '横幅', 'width', 1, 2000, null],
                    ['num2', '高さ', 'height', 1, 2000, null],
                    ['num3', 'パディング', '_customPadding', 1, 100, this.updatePadding.bind(this), true],
                    ['num4', 'フォントサイズ', '_customFontSize', 1, 100, this.resetFontSettings.bind(this), true],
                    ['num5', '行の高さ', '_customLineHeight', 1, 2000, this.setFittingHeight.bind(this), true],
                    ['num6', '背景の透明度', '_customBackOpacity', 0, 255, this.updateBackOpacity.bind(this), true],
                    ['num7', '行数', '_customLineNumber', 0, 999, this.setFittingHeight.bind(this), true],
                    ['num8', '背景画像のファイル名', '_customBackFileName', null, null, this.createBackSprite.bind(this), true],
                    ['num9', 'フォント名', '_customFontFace', null, null, this.resetFontSettings.bind(this), true]
                ];
                return params.some(function(param) {
                    return this.processSetProperty.apply(this, param);
                }.bind(this));
            }
            return false;
        };

        Window_Base.prototype.setFittingHeight = function() {
            if (this._customLineNumber) this.height = this.fittingHeight(this._customLineNumber);
        };

        Window_Base.prototype.processSetProperty = function(keyCode, propLabel, propName, min, max,
                                                            callBack, stringFlg) {
            if (this[propName] === undefined) return null;
            if (Input.isTriggered(keyCode)) {
                var result = window.prompt(propLabel + 'を入力してください。', this[propName].toString());
                if (result || (stringFlg && result === '')) {
                    this._windowFrameSprite.setBlendColor([0, 0, 0, 0]);
                    SceneManager.pushChangeStack(this);
                    this[propName] = stringFlg ? getArgString(result) : getArgEval(result, min, max);
                    if (callBack) callBack();
                    this.reDrawContents();
                    SoundManager.playMagicEvasion();
                    this.saveContainerInfo();
                    this._propLabel = propLabel;
                    this._propValue = this[propName];
                    return true;
                }
            }
            return null;
        };

        Window_Base.prototype.reDrawContents = function() {
            this.createContents();
            this.refresh();
        };

        Window_Selectable.prototype.reDrawContents = function() {
            Window_Base.prototype.reDrawContents.apply(this, arguments);
            this.updateCursor();
        };

        PIXI.Container.prototype.isAnchorChanged = function() {
            return false;
        };

        Sprite.prototype.isAnchorChanged = function() {
            return this.anchor.x !== 0 || this.anchor.y !== 0;
        };

        PIXI.Container.prototype.hold = function() {
            this._holding = true;
            this._dx      = TouchInput.x - this.x;
            this._dy      = TouchInput.y - this.y;
            SceneManager.pushChangeStack(this);
        };

        Window_Base.prototype.hold = function() {
            PIXI.Container.prototype.hold.call(this);
            this._windowBackSprite.setBlendColor([255, 255, 255, 192]);
            this._windowContentsSprite.setBlendColor([255, 128, 0, 192]);
        };

        Sprite.prototype.hold = function() {
            PIXI.Container.prototype.hold.call(this);
            this.setBlendColor([255, 255, 255, 192]);
        };

        PIXI.Container.prototype.release = function() {
            this._holding = false;
            this.saveContainerInfo();
        };

        Window_Base.prototype.release = function() {
            PIXI.Container.prototype.release.call(this);
            this._windowBackSprite.setBlendColor([0, 0, 0, 0]);
            this._windowContentsSprite.setBlendColor([0, 0, 0, 0]);
        };

        Sprite.prototype.release = function() {
            PIXI.Container.prototype.release.call(this);
            this.setBlendColor([0, 0, 0, 0]);
        };

        PIXI.Container.prototype.updateSnapX = function(x) {
            var minDistanceL = 16, minIndexL = -1, minDistanceR = 16, minIndexR = -1;
            var children     = this.parent.children, endX = x + this.width;
            for (var i = 0, n = children.length; i < n; i++) {
                var child = children[i];
                if (child !== this && this.isSameInstance(child) && child.isTouchable() && child.isOverlapY(this)) {
                    var distanceL = Math.abs(x - child.endX);
                    if (minDistanceL > distanceL) {
                        minDistanceL = distanceL;
                        minIndexL    = i;
                    }
                    var distanceR = Math.abs(endX - child.x);
                    if (minDistanceR > distanceR) {
                        minDistanceR = distanceR;
                        minIndexR    = i;
                    }
                }
            }
            if (minDistanceL > Math.abs(x)) return 0;
            if (minDistanceR > Math.abs(Graphics.boxWidth - endX)) return Graphics.boxWidth - this.width;
            if (minDistanceR > minDistanceL) {
                return minIndexL === -1 ? x : children[minIndexL].endX;
            } else {
                return minIndexR === -1 ? x : children[minIndexR].x - this.width;
            }
        };

        PIXI.Container.prototype.updateSnapY = function(y) {
            var minDistanceU = 16, minIndexU = -1, minDistanceD = 16, minIndexD = -1;
            var children     = this.parent.children, endY = y + this.height;
            for (var i = 0, n = children.length; i < n; i++) {
                var child = children[i];
                if (child !== this && this.isSameInstance(child) && child.isTouchable() && child.isOverlapX(this)) {
                    var distanceU = Math.abs(y - child.endY);
                    if (minDistanceU > distanceU) {
                        minDistanceU = distanceU;
                        minIndexU    = i;
                    }
                    var distanceD = Math.abs(endY - child.y);
                    if (minDistanceD > distanceD) {
                        minDistanceD = distanceD;
                        minIndexD    = i;
                    }
                }
            }
            if (minDistanceU > Math.abs(y)) return 0;
            if (minDistanceD > Math.abs(Graphics.boxHeight - endY)) return Graphics.boxHeight - this.height;
            if (minDistanceD > minDistanceU) {
                return minIndexU === -1 ? y : children[minIndexU].endY;
            } else {
                return minIndexD === -1 ? y : children[minIndexD].y - this.height;
            }
        };

        PIXI.Container.prototype.isSameInstance = function() {
            return false;
        };

        Window_Base.prototype.isSameInstance = function(objectContainer) {
            return objectContainer instanceof Window_Base;
        };

        Sprite.prototype.isSameInstance = function(objectContainer) {
            return objectContainer instanceof Sprite;
        };

        PIXI.Container.prototype.isTouchPosInRect = function() {
            var tx = TouchInput.x;
            var ty = TouchInput.y;
            return (tx >= this.x && tx <= this.endX &&
            ty >= this.y && ty <= this.endY);
        };

        Sprite.prototype.isTouchPosInRect = function() {
            if (this.isTransparent()) return false;
            var dx  = TouchInput.x - this.x;
            var dy  = TouchInput.y - this.y;
            var sin = Math.sin(-this.rotation);
            var cos = Math.cos(-this.rotation);
            var rx  = this.x + Math.floor(dx * cos + dy * -sin);
            var ry  = this.y + Math.floor(dx * sin + dy * cos);
            return (rx >= this.minX() && rx <= this.maxX() &&
            ry >= this.minY() && ry <= this.maxY());
        };

        Sprite.prototype.isTransparent = function() {
            var dx  = TouchInput.x - this.x;
            var dy  = TouchInput.y - this.y;
            var sin = Math.sin(-this.rotation);
            var cos = Math.cos(-this.rotation);
            var bx  = Math.floor(dx * cos + dy * -sin) / this.scale.x + this.anchor.x * this.width;
            var by  = Math.floor(dx * sin + dy * cos) / this.scale.y + this.anchor.y * this.height;
            return this.bitmap.getAlphaPixel(bx, by) === 0;
        };

        Sprite.prototype.screenWidth = function() {
            return (this.width || 0) * this.scale.x;
        };

        Sprite.prototype.screenHeight = function() {
            return (this.height || 0) * this.scale.y;
        };

        Sprite.prototype.screenX = function() {
            return (this.x || 0) - this.anchor.x * this.screenWidth();
        };

        Sprite.prototype.screenY = function() {
            return (this.y || 0) - this.anchor.y * this.screenHeight();
        };

        Sprite.prototype.minX = function() {
            return Math.min(this.screenX(), this.screenX() + this.screenWidth());
        };

        Sprite.prototype.minY = function() {
            return Math.min(this.screenY(), this.screenY() + this.screenHeight());
        };

        Sprite.prototype.maxX = function() {
            return Math.max(this.screenX(), this.screenX() + this.screenWidth());
        };

        Sprite.prototype.maxY = function() {
            return Math.max(this.screenY(), this.screenY() + this.screenHeight());
        };

        PIXI.Container.prototype.isTouchable = function() {
            return false;
        };

        Window_Base.prototype.isTouchable = function() {
            return (this.opacity > 0 || this.contentsOpacity > 0) && this.visible && this.isOpen();
        };

        Window_BattleLog.prototype.isTouchable = function() {
            return Window.prototype.isTouchable.call(this) && this._lines.length > 0;
        };

        Sprite.prototype.isTouchable = function() {
            return this.visible && this.bitmap != null && this.scale.x !== 0 && this.scale.y !== 0;
        };

        PIXI.Container.prototype.isTouchEvent = function(triggerFunc) {
            return this.isTouchable() && triggerFunc.call(TouchInput) && this.isTouchPosInRect();
        };

        PIXI.Container.prototype.isPreparedEvent = function() {
            return this.isTouchable() && this.isTouchPosInRect();
        };

        PIXI.Container.prototype.isRangeX = function(x) {
            return this.x <= x && this.endX >= x;
        };

        PIXI.Container.prototype.isRangeY = function(y) {
            return this.y <= y && this.endY >= y;
        };

        PIXI.Container.prototype.isOverlapX = function(win) {
            return this.isRangeX(win.x) || this.isRangeX(win.endX) || win.isRangeX(this.x) || win.isRangeX(this.endX);
        };

        PIXI.Container.prototype.isOverlapY = function(win) {
            return this.isRangeY(win.y) || this.isRangeY(win.endY) || win.isRangeY(this.y) || win.isRangeY(this.endY);
        };

        Object.defineProperty(PIXI.Container.prototype, 'endX', {
            get: function() {
                return this.x + this.width;
            },
            set: function(value) {
                this.x = value - this.width;
            },

            configurable: true
        });

        Object.defineProperty(PIXI.Container.prototype, 'endY', {
            get: function() {
                return this.y + this.height;
            },
            set: function(value) {
                this.y = value - this.height;
            },

            configurable: true
        });

        //=============================================================================
        //  Window_Selectable
        //   通常のタッチ操作を無効化します。
        //=============================================================================
        Window_Selectable.prototype.processTouch = function() {};
    }

    //=============================================================================
    // ウィンドウを透過して重なり合ったときの表示を自然にします。
    //=============================================================================
    if (paramThroughWindow && !WindowLayer.throughWindow) {
        WindowLayer.throughWindow = true;
        //=============================================================================
        //  WindowLayer
        //   ウィンドウのマスク処理を除去します。
        //=============================================================================
        WindowLayer.prototype._maskWindow = function(window) {};

        WindowLayer.prototype._canvasClearWindowRect = function(renderSession, window) {};
    }

    if (paramFakeMobile) {
        Utils.isMobileDevice = function() {
            return true;
        };
    }

    //=============================================================================
    // Game_Interpreter
    //  プラグインコマンドを追加定義します。
    //=============================================================================
    var _Game_Interpreter_pluginCommand      = Game_Interpreter.prototype.pluginCommand;
    Game_Interpreter.prototype.pluginCommand = function(command, args) {
        _Game_Interpreter_pluginCommand.apply(this, arguments);
        if (!command.match(new RegExp('^' + metaTagPrefix))) return;
        try {
            this.pluginCommandGraphicalDesignMode(command.replace(metaTagPrefix, ''), 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(window.screenX + window.outerWidth, window.screenY + window.outerHeight);
                    window.focus();
                }
            }
            console.log('プラグインコマンドの実行中にエラーが発生しました。');
            console.log('- コマンド名 　: ' + command);
            console.log('- コマンド引数 : ' + args);
            console.log('- エラー原因   : ' + e.stack || e.toString());
        }
    };

    Game_Interpreter.prototype.pluginCommandGraphicalDesignMode = function(command) {
        switch (getCommandName(command)) {
            case '解除_メッセージウィンドウ' :
            case '_UNLOCK_MESSAGE_WINDOW':
                SceneManager._scene._messageWindow.unlockPosition();
                break;
            case '固定_メッセージウィンドウ' :
            case '_LOCK_MESSAGE_WINDOW':
                SceneManager._scene._messageWindow.lockPosition();
                break;
            case '解除_選択肢ウィンドウ' :
            case '_UNLOCK_CHOICE_WINDOW':
                SceneManager._scene._messageWindow._choiceWindow.unlockPosition();
                break;
            case '固定_選択肢ウィンドウ' :
            case '_LOCK_CHOICE_WINDOW':
                SceneManager._scene._messageWindow._choiceWindow.lockPosition();
                break;
        }
    };

    //=============================================================================
    // DataManager
    //  ContainerProperties.jsonの読み込み処理を追記します。
    //=============================================================================
    DataManager._databaseFileCp = {name: '$dataContainerProperties', src: 'ContainerProperties.json'};
    if (paramMobileMake && Utils.isMobileDevice()) {
        DataManager._databaseFileCp.src = 'ContainerPropertiesMobile.json';
    }

    var _DataManager_loadDatabase = DataManager.loadDatabase;
    DataManager.loadDatabase      = function() {
        _DataManager_loadDatabase.apply(this, arguments);
        var errorMessage = this._databaseFileCp.src + 'が見付かりませんでした。';
        this.loadDataFileAllowError(this._databaseFileCp.name, this._databaseFileCp.src, errorMessage);
    };

    DataManager.loadDataFileAllowError = function(name, src, errorMessage) {
        var xhr = new XMLHttpRequest();
        var url = 'data/' + src;
        xhr.open('GET', url);
        xhr.overrideMimeType('application/json');
        xhr.onload   = function() {
            if (xhr.status < 400) {
                window[name] = JSON.parse(xhr.responseText);
                DataManager.onLoad(window[name]);
            } else {
                DataManager.onDataFileNotFound(name, errorMessage);
            }
        };
        xhr.onerror  = function() {
            DataManager.onDataFileNotFound(name, errorMessage);
        };
        window[name] = null;
        xhr.send();
    };

    DataManager.onDataFileNotFound = function(name, errorMessage) {
        window[name] = {};
        console.warn(errorMessage);
    };

    var _DataManager_isDatabaseLoaded = DataManager.isDatabaseLoaded;
    DataManager.isDatabaseLoaded      = function() {
        return _DataManager_isDatabaseLoaded.apply(this, arguments) && window[this._databaseFileCp.name];
    };

    //=============================================================================
    // SceneManager
    //  現在のシーン名を返します。
    //=============================================================================
    SceneManager.getSceneName = function() {
        return getClassName(this._scene);
    };

    var _SceneManager_updateScene = SceneManager.updateScene;
    SceneManager.updateScene      = function() {
        _SceneManager_updateScene.apply(this, arguments);
        if (this._scene) {
            this._scene.updateCustomContainer();
        }
    };

    //=============================================================================
    // Scene_Base
    //  ウィンドウ追加時に位置をロードします。
    //=============================================================================
    var _Scene_Base_addWindow      = Scene_Base.prototype.addWindow;
    Scene_Base.prototype.addWindow = function(child) {
        _Scene_Base_addWindow.apply(this, arguments);
        child.loadContainerInfo();
    };

    var _Scene_Base_addChild      = Scene_Base.prototype.addChild;
    Scene_Base.prototype.addChild = function(child) {
        _Scene_Base_addChild.apply(this, arguments);
        child.loadContainerInfo();
    };

    var _Scene_Base_createWindowLayer2     = Scene_Base.prototype.createWindowLayer;
    Scene_Base.prototype.createWindowLayer = function() {
        this.createCustomPicture();
        _Scene_Base_createWindowLayer2.apply(this, arguments);
        this.createCustomWindow();
    };

    Scene_Base.prototype.createCustomPicture = function() {
        var setting = settings[getClassName(this)];
        if (setting) {
            var pictures         = setting.pictures;
            this._customPictures = [];
            if (pictures) {
                pictures.forEach(function(picture) {
                    if (!picture.file) return;
                    var sprite    = new Sprite();
                    sprite.bitmap = ImageManager.loadPicture(picture.file, 0);
                    this._customPictures.push(sprite);
                    this.addChild(sprite);
                    sprite.switchId = picture.switchId || 0;
                }.bind(this));
            }
        }
    };

    Scene_Base.prototype.createCustomWindow = function() {
        var setting = settings[getClassName(this)];
        if (setting) {
            var windows         = setting.windows;
            this._customWindows = [];
            if (windows) {
                windows.forEach(function(windowItem) {
                    if (!windowItem.lines || windowItem.lines.length < 1) return;
                    var win = new Window_Custom(windowItem.lines);
                    this._customWindows.push(win);
                    win.switchId = windowItem.switchId || 0;
                }.bind(this));
            }
            this.updateCustomWindowVisible();
        }
    };

    Scene_Base.prototype.updateCustomContainer = function() {
        if (this._customPictures) {
            this.updateCustomPicture();
        }
        if (this._customWindows) {
            this.updateCustomWindow();
        }
    };

    Scene_Base.prototype.updateCustomPicture = function() {
        this._customPictures.forEach(function(picture) {
            if (picture.switchId > 0) {
                picture.visible = $gameSwitches.value(picture.switchId);
            }
        });
    };

    Scene_Base.prototype.updateCustomWindow = function() {
        this.updateCustomWindowVisible();
        if (!this._windowAdd) {
            this._customWindows.forEach(function(windowItem) {
                this.addWindow(windowItem);
            }, this);
            this._windowAdd = true;
        }
    };

    Scene_Base.prototype.updateCustomWindowVisible = function() {
        this._customWindows.forEach(function(windowItem) {
            if (windowItem.switchId > 0) {
                if ($gameSwitches.value(windowItem.switchId)) {
                    windowItem.show();
                } else {
                    windowItem.hide();
                }
            }
        }, this);
    };

    //=============================================================================
    // PIXI.Container
    //  表示位置のセーブとロードを行います。
    //=============================================================================
    Object.defineProperty(PIXI.Container.prototype, 'x', {
        get: function() {
            return this.position.x;
        },
        set: function(value) {
            if (this._positionLock) return;
            this.position.x = value;
        }
    });

    Object.defineProperty(PIXI.Container.prototype, 'y', {
        get: function() {
            return this.position.y;
        },
        set: function(value) {
            if (this._positionLock) return;
            this.position.y = value;
        }
    });

    PIXI.Container.prototype.loadContainerInfo = function() {
        var sceneName  = SceneManager.getSceneName();
        var parentName = getClassName(this.parent);
        var sceneInfo  = $dataContainerProperties[sceneName];
        if (sceneInfo) {
            var containerInfo = sceneInfo[parentName];
            var key           = [this.parent.getChildIndex(this), getClassName(this)];
            if (containerInfo && containerInfo[key]) {
                this.loadProperty(containerInfo[key]);
                this._positionLock = true;
            }
        }
    };

    PIXI.Container.prototype.unlockPosition = function() {
        this._positionLock    = false;
        this._customPositionX = this.position.x;
        this._customPositionY = this.position.y;
    };

    PIXI.Container.prototype.lockPosition = function() {
        this._positionLock = true;
        if (this._customPositionX) {
            this.position.x = this._customPositionX;
        }
        if (this._customPositionY) {
            this.position.y = this._customPositionY;
        }
    };

    PIXI.Container.prototype.loadProperty = function(containerInfo) {
        this.position.x = containerInfo.x;
        this.position.y = containerInfo.y;
    };

    Window_Base.prototype.loadProperty = function(containerInfo) {
        PIXI.Container.prototype.loadProperty.apply(this, arguments);
        this.width               = containerInfo.width;
        this.height              = containerInfo.height;
        this.opacity             = containerInfo.opacity;
        this.visible             = this.visible && !containerInfo.hidden;
        this._customFontSize     = containerInfo._customFontSize;
        this._customPadding      = containerInfo._customPadding;
        this._customLineHeight   = containerInfo._customLineHeight;
        this._customBackOpacity  = containerInfo._customBackOpacity;
        this._customBackFileName = containerInfo._customBackFileName;
        this._customFontFace     = containerInfo._customFontFace;
        this.updatePadding();
        this.resetFontSettings();
        this.updateBackOpacity();
        this.createContents();
        this.refresh();
        this.createBackSprite();
    };

    Window_Base.prototype.refresh = function() {};

    Window_Selectable.prototype.loadProperty = function(containerInfo) {
        Window_Base.prototype.loadProperty.apply(this, arguments);
        this.updateCursor();
    };

    PIXI.Container.prototype.saveContainerInfo = function() {
        var sceneName  = SceneManager.getSceneName();
        var parentName = getClassName(this.parent);
        if (!$dataContainerProperties[sceneName]) $dataContainerProperties[sceneName] = {};
        var sceneInfo = $dataContainerProperties[sceneName];
        if (!sceneInfo[parentName]) sceneInfo[parentName] = {};
        var containerInfo = sceneInfo[parentName];
        var key           = [this.parent.getChildIndex(this), getClassName(this)];
        if (!containerInfo[key]) containerInfo[key] = {};
        this.saveProperty(containerInfo[key]);
        if (paramAutoSave) {
            DataManager.saveDataFileWp();
        }
    };

    PIXI.Container.prototype.saveProperty = function(containerInfo) {
        containerInfo.x = this.x;
        containerInfo.y = this.y;
    };

    Window_Base.prototype.saveProperty = function(containerInfo) {
        PIXI.Container.prototype.saveProperty.apply(this, arguments);
        containerInfo.width               = this.width;
        containerInfo.height              = this.height;
        containerInfo.opacity             = this.opacity;
        containerInfo.hidden              = !this.visible;
        containerInfo._customFontSize     = this._customFontSize;
        containerInfo._customPadding      = this._customPadding;
        containerInfo._customLineHeight   = this._customLineHeight;
        containerInfo._customBackOpacity  = this._customBackOpacity;
        containerInfo._customBackFileName = this._customBackFileName;
        containerInfo._customFontFace     = this._customFontFace;
    };

    //=============================================================================
    // Window_Base
    //  プロパティの値をカスタマイズします。
    //=============================================================================
    var _Window_Base_initialize      = Window_Base.prototype.initialize;
    Window_Base.prototype.initialize = function(x, y, width, height) {
        _Window_Base_initialize.apply(this, arguments);
        this._customFontSize     = this.standardFontSize();
        this._customPadding      = this.standardPadding();
        this._customLineHeight   = this.lineHeight();
        this._customLineNumber   = 0;
        this._customBackOpacity  = this.standardBackOpacity();
        this._customBackSprite   = null;
        this._customBackFileName = '';
        this._customFontFace     = '';
    };

    Window_Base.prototype.createBackSprite = function() {
        if (this._customBackFileName) {
            if (!this._customBackSprite) {
                this._customBackSprite = new Sprite();
                this.addChildToBack(this._customBackSprite);
            }
            this._customBackSprite.bitmap = ImageManager.loadPicture(this._customBackFileName, 0);
        } else if (this._customBackSprite) {
            this.removeChild(this._customBackSprite);
            this._customBackSprite = null;
        }
        if (Utils.isDesignMode() && this._customBackSprite && this._customBackSprite.bitmap) {
            var bitmap            = this._customBackSprite.bitmap;
            bitmap._image.onerror = function() {
                this._customBackFileName                 = '';
                this._customBackSprite.bitmap._isLoading = false;
                this._customBackSprite.bitmap            = null;
                this._customBackSprite                   = null;
                SceneManager.popChangeStack();
                SceneManager.setInfoExtend('ファイルが見付からなかったので、左記の番号の変更を戻しました。', -1);
            }.bind(this);
        }
    };

    var _Window_Selectable_initialize      = Window_Selectable.prototype.initialize;
    Window_Selectable.prototype.initialize = function(x, y, width, height) {
        _Window_Selectable_initialize.apply(this, arguments);
        this._customLineNumber = this.maxRows();
    };

    var _Window_Base_standardFontFace      = Window_Base.prototype.standardFontFace;
    Window_Base.prototype.standardFontFace = function() {
        return this._customFontFace ? this._customFontFace : _Window_Base_standardFontFace.apply(this, arguments);
    };

    var _Window_Base_standardFontSize      = Window_Base.prototype.standardFontSize;
    Window_Base.prototype.standardFontSize = function() {
        return this._customFontSize ? eval(this._customFontSize) :
            paramFontSize ? paramFontSize : _Window_Base_standardFontSize.apply(this, arguments);
    };

    var _Window_Base_standardPadding      = Window_Base.prototype.standardPadding;
    Window_Base.prototype.standardPadding = function() {
        return this._customPadding ? eval(this._customPadding) :
            paramPadding ? paramPadding : _Window_Base_standardPadding.apply(this, arguments);
    };

    var _Window_Base_lineHeight      = Window_Base.prototype.lineHeight;
    Window_Base.prototype.lineHeight = function() {
        return this._customLineHeight ? eval(this._customLineHeight) :
            paramLineHeight ? paramLineHeight : _Window_Base_lineHeight.apply(this, arguments);
    };

    var _Window_Base_standardBackOpacity      = Window_Base.prototype.standardBackOpacity;
    Window_Base.prototype.standardBackOpacity = function() {
        return this._customBackOpacity ? eval(this._customBackOpacity) :
            paramBackOpacity ? paramBackOpacity : _Window_Base_standardBackOpacity.apply(this, arguments);
    };

    Window_Base._iconSrcWidth  = Window_Base._iconWidth;
    Window_Base._iconSrcHeight = Window_Base._iconHeight;

    Window_Base.prototype.getIconScale = function() {
        var defaultFontSize = _Window_Base_standardFontSize.apply(this, arguments);
        var fontSize        = this.contents.fontSize;
        return paramIconSizeScale && defaultFontSize !== fontSize ? fontSize / defaultFontSize : null;
    };

    Window_Base.prototype.changeIconSize = function() {
        var iconScale = this.getIconScale();
        if (iconScale) {
            Window_Base._iconWidth *= iconScale;
            Window_Base._iconHeight *= iconScale;
        }
    };

    Window_Base.prototype.restoreIconSize = function() {
        var iconScale = this.getIconScale();
        if (iconScale) {
            Window_Base._iconWidth  = Window_Base._iconSrcWidth;
            Window_Base._iconHeight = Window_Base._iconSrcHeight;
        }
    };

    var _Window_Base_drawActorIcons      = Window_Base.prototype.drawActorIcons;
    Window_Base.prototype.drawActorIcons = function(actor, x, y, width) {
        this.changeIconSize();
        _Window_Base_drawActorIcons.apply(this, arguments);
        this.restoreIconSize();
    };

    var _Window_Base_drawItemName      = Window_Base.prototype.drawItemName;
    Window_Base.prototype.drawItemName = function(item, x, y, width) {
        this.changeIconSize();
        _Window_Base_drawItemName.apply(this, arguments);
        this.restoreIconSize();
    };

    var _Window_Base_processDrawIcon      = Window_Base.prototype.processDrawIcon;
    Window_Base.prototype.processDrawIcon = function(iconIndex, textState) {
        this.changeIconSize();
        _Window_Base_processDrawIcon.apply(this, arguments);
        this.restoreIconSize();
    };

    var _Window_Base_drawIcon      = Window_Base.prototype.drawIcon;
    Window_Base.prototype.drawIcon = function(iconIndex, x, y) {
        var iconScale = this.getIconScale();
        if (iconScale) {
            var bitmap = ImageManager.loadSystem('IconSet');
            var pw     = Window_Base._iconSrcWidth;
            var ph     = Window_Base._iconSrcHeight;
            var sx     = iconIndex % 16 * pw;
            var sy     = Math.floor(iconIndex / 16) * ph;
            var dw     = Math.floor(pw * iconScale);
            var dh     = Math.floor(ph * iconScale);
            var dx     = x;
            var dy     = y + (this.lineHeight() - dh) / 2 - 2;
            this.contents.blt(bitmap, sx, sy, pw, ph, dx, dy, dw, dh);
        } else {
            _Window_Base_drawIcon.apply(this, arguments);
        }
    };

    var _Window_Base_setBackgroundType      = Window_Base.prototype.setBackgroundType;
    Window_Base.prototype.setBackgroundType = function(type) {
        if (!paramBackgroundFixed) {
            _Window_Base_setBackgroundType.apply(this, arguments);
        }
    };

    //=============================================================================
    // Window_Custom
    //  任意配置可能なウィンドウです。
    //=============================================================================
    function Window_Custom() {
        this.initialize.apply(this, arguments);
    }

    Window_Custom._textAligns = {
        'left'  : 0,
        '0'     : 0,
        'center': 1,
        '1'     : 1,
        'right' : 2,
        '2'     : 2
    };

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

    Window_Custom.prototype.initialize = function(lines) {
        this._lines = lines || [];
        Window_Selectable.prototype.initialize.call(this, 0, 0, 320, this.fittingHeight(this._lines.length));
        this.refresh();
    };

    Window_Custom.prototype.refresh = function() {
        this.createContents();
        Window_Selectable.prototype.refresh.apply(this, arguments);
    };

    Window_Custom.prototype.drawItem = function(index) {
        var rect = this.itemRectForText(index);
        var text = this._lines[index];
        this.resetTextColor();
        text = this.changeTextAlign(text);
        if (this._textAlign > 0) {
            rect.x = this.getTextAlignStartX(text);
        }
        this.drawTextEx(text, rect.x, rect.y);
    };

    Window_Custom.prototype.getTextAlignStartX = function(text) {
        var width = this.drawTextEx(text, this.contentsWidth(), 0);
        if (this._textAlign === 1) {
            return this.contentsWidth() / 2 - width / 2;
        } else {
            return this.contentsWidth() - width;
        }
    };

    Window_Custom.prototype.maxItems = function() {
        return this._lines.length;
    };

    Window_Custom.prototype.changeTextAlign = function(text) {
        this._textAlign = 0;
        text            = text.replace(/\\al\[(.*)\]/gi, function() {
            this._textAlign = Window_Custom._textAligns[arguments[1].toLowerCase()] || 0;
            return '';
        }.bind(this));
        return text;
    };
})();

repo_name: Rexhunk/karryn

license: unknown


code:
/*:
-------------------------------------------------------------------------
@title Change Battleback
@author Hime --> HimeWorks (http://himeworks.com)
@date Apr 16, 2016
@version 1.1
@filename HIME_ChangeBattleback.js
@url http://himeworks.com/2015/11/change-battleback/

If you enjoy my work, consider supporting me on Patreon!

* https://www.patreon.com/himeworks

If you have any questions or concerns, you can contact me at any of
the following sites:

* Main Website: http://himeworks.com
* Facebook: https://www.facebook.com/himeworkscom/
* Twitter: https://twitter.com/HimeWorks
* Youtube: https://www.youtube.com/c/HimeWorks
* Tumblr: http://himeworks.tumblr.com/

-------------------------------------------------------------------------------
@plugindesc v1.1 Allows you to change battle background images during battle.
@help
-------------------------------------------------------------------------------
== Description ==

Video: https://www.youtube.com/watch?v=KHA6yRAMhMk

Battle backgrounds can be used to provide some sense of atmosphere.
For example, if you're walking through a forest and you encounter an enemy,
seeing some cute bunnies and trees in the background makes it feel like a
forest.

However, if you see dead bunnies and dying trees in the background, it feels
much different. What happens if an enemy can cast a spell that will cause all
of those bunnies and trees to die during battle?

RPG Maker MV comes with an event command that allows you to change battlebacks.
However, if you try to change battlebacks during battle, you'll notice that
nothing happens.

Instead, the change will only appear in the next battle.
This plugin allows you to change battle backgrounds during battle.

== Terms of Use ==

- Free for use in non-commercial projects with credits
- Contact me for commercial use

== Change Log ==

1.1 - Apr 19, 2016
 * Implemented support for saving and loading battlebacks
1.0 - Nov 22, 2015
 * initial release

== Usage ==

During battle, use the "Change Battleback" event command located on the
third page of the event commands.

This will change the battleback immediately.
The changes will only last for the current battle, and will revert
after the battle finishes.

-- Saving and Restoring Battlebacks --

There may be situations where you want to change the battleback, and you want
to restore it to what it was before you changed it, but you didn't know what
the battlebacks were because they could have been anything at that point.

This plugin provides functionality for saving the current battlebacks and then
restoring them.

To save battlebacks, use the script call

  BattleManager.saveBattlebacks()

To restore battlebacks, use the script call

  BattleManager.restoreBattlebacks()

-------------------------------------------------------------------------------
 */
var Imported = Imported || {} ;
var TH = TH || {};
Imported.ChangeBattleback = 1;
TH.ChangeBattleback = TH.ChangeBattleback || {};

(function ($) {

  /* Battlebacks are battle-specific */
  var TH_BattleManager_initMembers = BattleManager.initMembers;
  BattleManager.initMembers = function() {
    TH_BattleManager_initMembers.call(this);
    this._battleback1Name = '';
    this._battleback2Name = '';
  };

  BattleManager.saveBattlebacks = function() {
    this._oldBattleback1Name = this._battleback1Name;
    this._oldBattleback2Name = this._battleback2Name;
  }

  BattleManager.restoreBattlebacks = function() {
    this.changeBattleback(this._oldBattleback1Name, this._oldBattleback2Name);
  };

  BattleManager.changeBattleback = function(name1, name2) {
    this._battleback1Name = name1;
    this._battleback2Name = name2;
    this._spriteset.refreshBattleback();
  }

  BattleManager.battleback1Name = function() {
    return this._battleback1Name;
  }

  BattleManager.battleback2Name = function() {
    return this._battleback2Name;
  }

  /***************************************************************************/

  Spriteset_Battle.prototype.refreshBattleback = function() {
    this._back1Sprite.bitmap = this.battleback1Bitmap();
    this._back2Sprite.bitmap = this.battleback2Bitmap();
  };

  var TH_SpritesetBattle_battleback1Name = Spriteset_Battle.prototype.battleback1Name;
  Spriteset_Battle.prototype.battleback1Name = function() {
    //console.log(BattleManager.battleback1Name())
    if (BattleManager.battleback1Name()) {
      return BattleManager.battleback1Name();
    }
    else {
      return TH_SpritesetBattle_battleback1Name.call(this);
    }
  };

  var TH_SpritesetBattle_battleback2Name = Spriteset_Battle.prototype.battleback2Name;
  Spriteset_Battle.prototype.battleback2Name = function() {
    if (BattleManager.battleback2Name()) {
      return BattleManager.battleback2Name();
    }
    else {
      return TH_SpritesetBattle_battleback2Name.call(this);
    }
  };

  Spriteset_Battle.prototype.update = function() {
    Spriteset_Base.prototype.update.call(this);
    this.updateActors();
    this.updateBattleback();
  };

  /***************************************************************************/

  /* Default only changes the map's battleback, but does not change
   * it if we are already in battle.
   */
  var TH_GameInterpreter_command283 = Game_Interpreter.prototype.command283;
  Game_Interpreter.prototype.command283 = function() {
    if ($gameParty.inBattle()) {
      BattleManager.changeBattleback(this._params[0], this._params[1])
      return true;
    }
    else {
      return TH_GameInterpreter_command283.call(this);
    }
  };
})(TH.ChangeBattleback);