code:
//=============================================================================
// MovieManager.js
// ----------------------------------------------------------------------------
// (C)2015 Triacontane
// This software is released under the MIT License.
// http://opensource.org/licenses/mit-license.php
// ----------------------------------------------------------------------------
// Version
// 1.0.4 2018/03/28 ムービー再生後、ロード完了前にムービーを停止するとムービーが停止されない問題を修正
// 1.0.3 2018/03/27 Saba_SimpleScenario.jsとの競合を解消（こちらの設定で上書き）
// 1.0.2 2018/01/30 ヘルプの記述を修正
// 1.0.1 2016/06/24 メニューを開いたときに最後に表示していたムービーが写り込む不具合を修正
// 1.0.0 2016/06/09 初版
// ----------------------------------------------------------------------------
// [Blog]   : https://triacontane.blogspot.jp/
// [Twitter]: https://twitter.com/triacontane/
// [GitHub] : https://github.com/triacontane/
//=============================================================================

/*:
 * @plugindesc 動画管理プラグイン
 * @author トリアコンタン
 *
 * @help イベントコマンド「ムービーの再生」で再生できる動画をピクチャのように
 * コントロールできるようになります。
 * 座標や拡大率はもちろん、ループ可否や再生速度を自由に調整可能です。
 * イベントコマンド「ムービーの再生」後に以下のプラグインコマンドを実行します。
 * （大抵のコマンドは「ムービーの再生」前でも機能しますが「MM_ウェイト」のみ
 * 　「ムービーの再生」前では機能しません）
 *
 * プラグインコマンド詳細
 *  イベントコマンド「プラグインコマンド」から実行。
 *  （パラメータの間は半角スペースで区切る）
 *
 * すべてのプラグインコマンドはムービーが再生中でなくても有効です。
 *
 * MM_移動_座標 [X座標] [Y座標] [移動時間(f)] [待ちフラグ(ON/OFF)]
 *  ムービーの表示座標を時間を掛けて変更します。
 *  下記の例は、座標[100:100]に[60]フレーム掛けて移動し、処理中はウェイトします。
 *  ex:MM_移動_座標 100 100 60 ON
 *
 * MM_移動_拡大率 [X拡大率(100%)] [Y拡大率(100%)] [時間(f)] [待ちフラグ(ON/OFF)]
 *  ムービーの拡大率を時間を掛けて変更します。
 *  下記の例は、縦横の拡大率を[50%]に60フレーム掛けて縮小し、
 *  処理中はウェイトしません。
 *  ex:MM_移動_拡大率 50 50 60
 *
 * MM_移動_不透明度 [不透明度(0-256)] [時間(f)] [ウェイトフラグ(ON/OFF)]
 *  ムービーの不透明度を時間を掛けて変更します。
 *  下記の例は、不透明度が変数[1]の値に即座に変更されます。
 *  ex:MM_移動_不透明度 \v[1] 0 ON
 *
 * MM_設定_再生速度 [再生速度(標準:1.0)]
 *  ムービーの再生速度倍率を変更します。
 *  下記の例は、再生速度が1.5倍になります。
 *  ex:MM_設定_再生速度 1.5
 *
 * MM_設定_再生位置 [再生位置(S)]
 *  ムービーの再生位置を変更します。
 *  ただしChromeの場合ロードしていない位置に移動すると再生が終了してしまうため
 *  使用には注意が必要です。(2016/06/12時点での最新版で確認)
 *  下記の例は、100秒目の再生位置にジャンプします。
 *  ex:MM_設定_再生位置 100
 *
 * MM_設定_画面に合わせる [設定値(ON/OFF)]
 *  ONにすると拡大率が100%の状態でムービーのサイズが画面にフィットするように
 *  調整されます。OFFにすると元の動画ファイルのサイズに合わせます。
 *  ex:MM_設定_画面に合わせる ON
 *
 * MM_設定_ループ [設定値(ON/OFF)]
 *  ONにすると、再生終了後に最初からループ再生します。
 *  ex:MM_設定_ループ ON
 *
 * MM_一時停止
 *  再生を一時停止します。
 *  ex:MM_一時停止
 *
 * MM_再生
 *  一時停止した状態から再生します。初回はイベントコマンドだけで再生されるので
 *  このコマンドの実行は不要です。
 *  ex:MM_再生
 *
 * MM_停止
 *  再生を終了してムービーを消去します。
 *  ex:MM_停止
 *
 * MM_ウェイト
 *  ムービーの再生が終了するまでイベント実行を待機します。
 *  ループ再生している場合はゲームの進行が停止するので注意してください。
 *  このコマンドはイベント「ムービーの再生」の直後に実行してください。
 *  ex:MM_ウェイト
 *
 * スクリプトコマンド詳細
 *
 * MovieManager.isPlaying();
 * ムービーが再生中の場合にtrueを返します。
 *
 * 制約事項
 * 現状、ムービーの表示状態はセーブできません。
 *
 * 利用規約：
 *  作者に無断で改変、再配布が可能で、利用形態（商用、18禁利用等）
 *  についても制限はありません。
 *  このプラグインはもうあなたのものです。
 */

/**
 * 動画管理モジュールです。
 * @constructor
 */
function MovieManager() {
    throw new Error('This is a static class');
}

(function() {
    'use strict';
    var metaTagPrefix = 'MM_';

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

    var getArgFloat = function(arg, min, max) {
        if (arguments.length < 2) min = -Infinity;
        if (arguments.length < 3) max = Infinity;
        return (parseFloat(convertEscapeCharactersAndEval(arg, true)) || 0).clamp(min, max);
    };

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

    var getArgBoolean = function(arg) {
        return (arg || '').toUpperCase() === 'ON';
    };

    var convertEscapeCharactersAndEval = function(text, evalFlg) {
        if (text === null || text === undefined) {
            text = evalFlg ? '0' : '';
        }
        var windowLayer = SceneManager._scene._windowLayer;
        if (windowLayer) {
            var result = windowLayer.children[0].convertEscapeCharacters(text);
            return evalFlg ? eval(result) : result;
        } else {
            return text;
        }
    };

    //=============================================================================
    // Bitmap
    //  キャプチャに表示中のムービーを含めます。
    //=============================================================================
    var _Bitmap_snap = Bitmap.snap;
    Bitmap.snap      = function(stage) {
        var bitmap = _Bitmap_snap.apply(this, arguments);
        if (Graphics.isVideoPlaying()) {
            var video  = Graphics.getVideo();
            bitmap.context.drawImage(video, video.x, video.y, video.width, video.height);
        }
        return bitmap;
    };

    //=============================================================================
    // Graphics
    //  ムービー再生に必要なタグを動的に生成します。
    //=============================================================================
    Graphics._videoScaleFitScreen = false;

    Graphics._createVideo = function() {
        this._videoFrame    = document.createElement('div');
        this._videoFrame.id = 'GameVideoFrame';
        this._video         = document.createElement('video');
        this._video.id      = 'GameVideo';
        this._videoVisible  = false;
        document.body.appendChild(this._videoFrame);
        this._videoFrame.appendChild(this._video);
        this.setVideoContentsPosition(0, 0);
        this.setVideoContentsScale(1.0, 1.0);
        this._updateVideo();
        this._centerElement(this._video);
        this._video.style.margin = 0;
        this._videoLoading       = false;
    };

    Graphics.getVideo = function() {
        return this._video;
    };

    var _Graphics_playVideo = Graphics.playVideo;
    Graphics.playVideo      = function(src) {
        _Graphics_playVideo.apply(this, arguments);
        this._videoLoading = true;
    };

    Graphics.stopVideo = function() {
        if (!this._isVideoVisible() && this.isVideoLoading()) {
            this._needVideoStop = true;
        }
        this._video.pause();
        this._updateVisibility(false);
    };

    Graphics.setVisibleMovie = function(value) {
        this._videoFrame.style.visibility = (value ? 'visible' : 'hidden');
    };

    Graphics.setVideoScaleFitScreen = function(value) {
        this._videoScaleFitScreen = value;
        this.setVideoContentsScale(this._video.scaleX, this._video.scaleY);
    };

    var _Graphics_isVideoPlaying = Graphics.isVideoPlaying;
    Graphics.isVideoPlaying      = function() {
        return _Graphics_isVideoPlaying.apply(this, arguments) || this.isVideoLoading();
    };

    Graphics.isVideoLoading = function() {
        return this._videoLoading;
    };

    Graphics._updateVisibility = function(videoVisible) {
        this._videoVisible           = videoVisible;
        this._video.style.visibility = (videoVisible ? 'visible' : 'hidden');
        this._videoLoading           = false;
    };

    Graphics._isVideoVisible = function() {
        return this._videoVisible;
    };

    var _Graphics__onVideoLoad = Graphics._onVideoLoad;
    Graphics._onVideoLoad      = function() {
        _Graphics__onVideoLoad.apply(this, arguments);
        if (this._needVideoStop) {
            this._needVideoStop = false;
            this.stopVideo();
        } else {
            this.setVideoContentsScale(this._video.scaleX, this._video.scaleY);
        }
    };

    var _Graphics__updateVideo = Graphics._updateVideo;
    Graphics._updateVideo      = function() {
        var prevVideo = this._video;
        this._video   = this._videoFrame;
        _Graphics__updateVideo.apply(this, arguments);
        this._video = prevVideo;
        this._updateVideoContents();
    };

    Graphics.setVideoContentsPosition = function(x, y) {
        this._video.x = x;
        this._video.y = y;
        this._updateVideoContents();
    };

    Graphics.setVideoContentsScale = function(scaleX, scaleY) {
        this._video.scaleX = scaleX;
        this._video.scaleY = scaleY;
        this._video.width  = (this._videoScaleFitScreen ? this._width : this._video.videoWidth) * scaleX;
        this._video.height = (this._videoScaleFitScreen ? this._height : this._video.videoHeight) * scaleY;
        this._updateVideoContents();
    };

    Graphics._updateVideoContents = function() {
        var video          = this._video;
        video.style.width  = video.width * this._realScale + 'px';
        video.style.height = video.height * this._realScale + 'px';
        video.style.left   = video.x * this._realScale + 'px';
        video.style.top    = video.y * this._realScale + 'px';
    };

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

    Game_Interpreter.prototype.pluginCommandMovieManager = function(command, args) {
        var waitTime = 0;
        switch (getCommandName(command)) {
            case '設定_ループ':
            case 'SETTING_LOOP':
                MovieManager.setLoop(getArgBoolean(args[0]));
                break;
            case '設定_画面に合わせる':
            case 'SETTING_FIT_SCREEN':
                MovieManager.setScaleFitScreen(getArgBoolean(args[0]));
                break;
            case '設定_再生速度':
            case 'SETTING_PLAY_RATE':
                MovieManager.setPlaybackRate(getArgFloat(args[0], 0));
                break;
            case '設定_再生位置':
            case 'SETTING_CURRENT_TIME':
                MovieManager.setCurrentTime(getArgFloat(args[0], 0));
                break;
            case '移動_不透明度':
            case 'MOVE_OPACITY':
                waitTime = getArgNumber(args[1], 0);
                MovieManager.moveOpacity(getArgNumber(args[0], 0, 256), waitTime);
                if (getArgBoolean(args[2])) this.wait(waitTime);
                break;
            case '移動_座標':
            case 'MOVE_POSITION':
                waitTime = getArgNumber(args[2], 0);
                MovieManager.movePosition(getArgNumber(args[0]), getArgNumber(args[1]), waitTime);
                if (getArgBoolean(args[3])) this.wait(waitTime);
                break;
            case '移動_拡大率':
            case 'MOVE_SCALE':
                waitTime = getArgNumber(args[2], 0);
                MovieManager.moveScale(getArgNumber(args[0]), getArgNumber(args[1]), waitTime);
                if (getArgBoolean(args[3])) this.wait(waitTime);
                break;
            case '停止':
            case 'STOP':
                MovieManager.stop();
                break;
            case 'ウェイト':
            case 'WAIT':
                this.setWaitMode('video');
                break;
            case '一時停止':
            case 'PAUSE':
                MovieManager.pause();
                break;
            case '再生':
            case 'PLAY':
                MovieManager.play();
                break;
        }
    };

    var _Game_Interpreter_command261      = Game_Interpreter.prototype.command261;
    Game_Interpreter.prototype.command261 = function() {
        var result = _Game_Interpreter_command261.apply(this, arguments);
        this._waitMode = '';
        $gameTemp.sabaWaitForMovieMode = 0;
        return result;
    };

    var _Game_Interpreter_command354 = Game_Interpreter.prototype.command354;
    Game_Interpreter.prototype.command354 = function() {
        MovieManager.stop();
        return  _Game_Interpreter_command354.apply(this, arguments);
    };

    //=============================================================================
    // SceneManager
    //  動画管理モジュールを操作します。
    //=============================================================================
    var _SceneManager_initialize = SceneManager.initialize;
    SceneManager.initialize      = function() {
        _SceneManager_initialize.apply(this, arguments);
        MovieManager.initTarget();
    };

    var _SceneManager_updateScene = SceneManager.updateScene;
    SceneManager.updateScene      = function() {
        _SceneManager_updateScene.apply(this, arguments);
        MovieManager.update();
    };

    //=============================================================================
    // MovieManager
    //  動画管理モジュールです。
    //=============================================================================
    MovieManager.initTarget = function() {
        this._targetX          = this.getPositionX();
        this._targetY          = this.getPositionY();
        this._durationPosition = 0;
        this._targetScaleX     = this.getScaleX();
        this._targetScaleY     = this.getScaleY();
        this._durationScale    = 0;
        this._targetOpacity    = this.getOpacity();
        this._durationOpacity  = 0;
    };

    MovieManager.update = function() {
        this.updatePosition();
        this.updateScale();
        this.updateOpacity();
    };

    MovieManager.updatePosition = function() {
        if (this._durationPosition > 0) {
            var x = this.getPositionX();
            var y = this.getPositionY();
            var d = this._durationPosition;
            x     = (x * (d - 1) + this._targetX) / d;
            y     = (y * (d - 1) + this._targetY) / d;
            this.setPosition(x, y);
            this._durationPosition--;
        }
    };

    MovieManager.updateScale = function() {
        if (this._durationScale > 0) {
            var sx = this.getScaleX();
            var sy = this.getScaleY();
            var d  = this._durationScale;
            sx     = (sx * (d - 1) + this._targetScaleX) / d;
            sy     = (sy * (d - 1) + this._targetScaleY) / d;
            this.setScale(sx, sy);
            this._durationScale--;
        }
    };

    MovieManager.updateOpacity = function() {
        if (this._durationOpacity > 0) {
            var opacity = this.getOpacity();
            var d       = this._durationOpacity;
            opacity     = (opacity * (d - 1) + this._targetOpacity) / d;
            this.setOpacity(opacity);
            this._durationOpacity--;
        }
    };

    MovieManager.getVideo = function() {
        return Graphics.getVideo();
    };

    MovieManager.isPlaying = function() {
        return Graphics._isVideoVisible();
    };

    MovieManager.play = function() {
        if (!Graphics.isVideoLoading()) {
            this.getVideo().play();
        }
    };

    MovieManager.pause = function() {
        this.getVideo().pause();
    };

    MovieManager.stop = function() {
        Graphics.stopVideo();
        this.initTarget();
    };

    MovieManager.setLoop = function(value) {
        this.getVideo().loop = !!value;
    };

    MovieManager.getLoop = function() {
        return this.getVideo().loop;
    };

    MovieManager.setScaleFitScreen = function(value) {
        Graphics.setVideoScaleFitScreen(!!value);
    };

    MovieManager.setCurrentTime = function(value) {
        this.getVideo().currentTime = value;
    };

    MovieManager.getCurrentTime = function() {
        return this.getVideo().currentTime;
    };

    MovieManager.setPlaybackRate = function(value) {
        this.getVideo().playbackRate = value;
    };

    MovieManager.getPlaybackRate = function() {
        return this.getVideo().playbackRate;
    };

    MovieManager.moveOpacity = function(opacity, duration) {
        if (duration === 0) {
            this.setOpacity(opacity);
        } else {
            this._targetOpacity   = opacity;
            this._durationOpacity = duration;
        }
    };

    MovieManager.setOpacity = function(opacity) {
        var realOpacity = opacity / 256;
        if (realOpacity !== this.getOpacity()) {
            this.getVideo().style.opacity = String(realOpacity);
        }
    };

    MovieManager.getOpacity = function() {
        return this.getVideo().style.opacity * 256;
    };

    MovieManager.moveScale = function(scaleX, scaleY, duration) {
        if (duration === 0) {
            this.setScale(scaleX, scaleY);
        } else {
            this._targetScaleX  = scaleX;
            this._targetScaleY  = scaleY;
            this._durationScale = duration;
        }
    };

    MovieManager.setScale = function(scaleX, scaleY) {
        if (scaleX !== this.getScaleX() || scaleY !== this.getScaleY()) {
            Graphics.setVideoContentsScale(scaleX / 100, scaleY / 100);
        }
    };

    MovieManager.getScaleX = function() {
        return this.getVideo().scaleX * 100;
    };

    MovieManager.getScaleY = function() {
        return this.getVideo().scaleY * 100;
    };

    MovieManager.movePosition = function(x, y, duration) {
        if (duration === 0) {
            this.setPosition(x, y);
        } else {
            this._targetX          = x;
            this._targetY          = y;
            this._durationPosition = duration;
        }
    };

    MovieManager.setPosition = function(x, y) {
        if (this.getPositionX() !== x || this.getPositionY() !== y) {
            Graphics.setVideoContentsPosition(x, y);
        }
    };

    MovieManager.getPositionX = function() {
        return this.getVideo().x;
    };

    MovieManager.getPositionY = function() {
        return this.getVideo().y;
    };
})();


code:
//=============================================================================
// NeMV - Tags
// NeMV_Tags.js
//=============================================================================

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

var NeMV = NeMV || {};
NeMV.Tags = NeMV.Tags || {};

//=============================================================================
 /*:
 * @plugindesc v1.3.1 Allows objects and events to be tagged and those tags to be easily retrieved and manipulated via script.
 * @author Nekoyoubi
 *
 * @help
 * ============================================================================
 * Introduction
 * ============================================================================
 *
 * This plugin allows actors, enemies, classes, skills, states, items, weapons,
 * armors, and events to be tagged and those tags to be easily retrieved via
 * script.
 *
 * ============================================================================
 * Usage
 * ============================================================================
 *
 * Add a tag to your actor, class, enemy, item, weapon, armor, or event as
 * below. Multiple tags per entry can be separated by whitespace or commas, and tags
 * are case insensitive. Add tags to events via the Comment event command.
 *
 * <Tags: Plant>
 *
 * ... or...
 *
 * <TAGS: root, red, alchemy>
 *
 * ... or...
 *
 * <tags: BOSS FIRERESIST EXTRAGOLD>
 *
 * ----------------------------------------------------------------------------
 *
 * Once your tags are added, they can be accessed in almost any location via:
 *
 * [Object].hasTag("plant")
 *
 * ... or wild-card the tag with an asterisk to get partial matches...
 *
 * [Object].hasTag("extra*")
 *
 * This will return a boolean result indicating whether your object contains
 * that tag (or any tag that matches your wild-card search) or not.
 *
 * Tags can also be added and removed programmatically by calling either:
 *
 * [Object].addTag("good")
 *
 * ... or...
 *
 * [Object].removeTag("bad")
 *
 * Removing a tag that does not exist will NOT throw an error.
 *
 * Tag addition and removal with these methods may be deprecated in the future.
 *
 * Events Note: Due to the volatile nature of events, adding and removing tags
 * dynamically is not currently possible. Tags on events do change between
 * the events pages; they simply cannot be addTag()/removeTag()'d.
 *
 * ----------------------------------------------------------------------------
 *
 * A couple of utility methods have also been added to allow you to quickly
 * scan the party for tags on items they either possess or have equipped, or
 * tags on states they may have active.
 *
 * NeMV.Tags.partyItemsWithTag("magical")
 *
 * ... will return true if the party possesses any items tagged as "magical".
 *
 * NeMV.Tags.partyStatesWithTag("weapon")
 *
 * ... will return true if a party actor has a state tagged as "weapon".
 *
 * NeMV.Tags.eventsWithTag("harvestable")
 *
 * ... will return a collection of Game_Event objects tagged as "harvestable".
 *
 * ============================================================================
 * Support
 * ============================================================================
 *
 * Compatibility with YEP - Item Core exists to a degree, but may require
 * additional effort when checking specific items. It's always advisable to
 * use...
 *
 * DataManager.getBaseItem(item)
 *
 * ... if you are using YEP - Item Core.
 *
 * Should this plugin not work for you for any reason, please notify me by
 * creating a Github issue, emailing me at lance-at-nekoyoubi.com, or message
 * me in any social convention you happen to see me in.
 *
 * Thanks, and happy tagging!
 *
 * ============================================================================
 * Changelog
 * ============================================================================
 *
 * Version 1.3.1:
 * - re-fixed the previously fixed bug that was ever so recently unfixed
 * - deprecated old utility methods
 *
 * Version 1.3.0:
 * - moved event tagging off of underlying event and put it on Game_Event
 * - corrected improper event page tagging issues
 *
 * Version 1.2.3:
 * - added better event loading after issues with some blank states
 *
 * Version 1.2.2:
 * - added EventsThatHaveTag() utility method
 *
 * Version 1.2.1:
 * - fixed up event tagging a bit
 *
 * Version 1.2.0:
 * - added event tagging!
 *
 * Version 1.1.1:
 * - added Game_Item protos
 * - reorderd object additions
 *
 * Version 1.1.0:
 * - added wild-card searches on .hasTag()
 *
 * Version 1.0.0:
 * - initial plugin
 *
 */
//=============================================================================

// INITIALIZATION -------------------------------------------------------------

NeMV.Tags.init = function() {
	if ($dataActors !== null && $dataActors !== undefined) this.processNotetags($dataActors);
	if ($dataEnemies !== null && $dataEnemies !== undefined) this.processNotetags($dataEnemies);
	if ($dataClasses !== null && $dataClasses !== undefined) this.processNotetags($dataClasses);
	if ($dataSkills !== null && $dataSkills !== undefined) this.processNotetags($dataSkills);
	if ($dataStates !== null && $dataStates !== undefined) this.processNotetags($dataStates);
	if ($dataItems !== null && $dataItems !== undefined) this.processNotetags($dataItems);
	if ($dataWeapons !== null && $dataWeapons !== undefined) this.processNotetags($dataWeapons);
	if ($dataArmors !== null && $dataArmors !== undefined) this.processNotetags($dataArmors);
};

NeMV.Tags.processNotetags = function(data) {
	var tagsRegex = /<(?:TAGS):[ ](.*)>/i;
	for (var n = 1; n < data.length; n++) {
		var obj = data[n];
		if (obj === null || obj === undefined) continue;
		obj.tags = obj.tags || [];
		var notelines = obj.note.split(/[\r\n]+/);
		obj.hasTag = function(tag) {
			return NeMV.Tags.baseHasTag(tag, this.tags);
		};
		obj.removeTag = function(tag) {
			var index = this.tags.indexOf(tag.toUpperCase());
			if (index > -1) this.tags.splice(index, 1);
		};
		obj.addTag = function(tag) {
			this.removeTag(tag.toUpperCase());
			this.tags.push(tag.toUpperCase());
		};
		for (var i = 0; i < notelines.length; i++) {
			var line = notelines[i];
			lineMatch = line.match(tagsRegex);
			if (lineMatch) {
				var tagData = lineMatch[1].toUpperCase().match(/\w+/gi);
	    		obj.tags = obj.tags.concat(tagData);
			}
		}
	}
};

// BASE METHODS ---------------------------------------------------------------

NeMV.Tags.baseHasTag = function(tag, tags) {
	for (var t = 0; t < tags.length; t++) {
		tag = tag.toUpperCase();
		var regex = "^"+tag+"$";
		if (tag.indexOf("*") >= 0) {
			if (tag.charAt(0) == "*") {
				regex = tag.replace("*","")+"$";
			} else if (tag.charAt(tag.length-1) == "*") {
				regex = "^"+tag.replace("*","");
			} else {
				regex = "^"+tag.replace("*","\\w*")+"$";
			}
		}
		var currentTag = tags[t].toUpperCase();
		var exp = new RegExp(regex, "i");
		if (exp.exec(currentTag) !== null)
			return true;
	}
	return false;
};

NeMV.Tags.baseEventSetup = function(gameEvent) {
	if (gameEvent === null ||
		gameEvent === undefined ||
		gameEvent.event === undefined) return;
	var e = gameEvent.event();
	gameEvent.tags = [];
	gameEvent.hasTag = function(tag) {
		return NeMV.Tags.baseHasTag(tag, this.tags);
	};
	gameEvent.removeTag = function(tag) {
		var index = this.tags.indexOf(tag.toUpperCase());
		if (index > -1) this.tags.splice(index, 1);
	};
	gameEvent.addTag = function(tag) {
		this.removeTag(tag.toUpperCase());
		this.tags.push(tag.toUpperCase());
	};
	if (gameEvent.page() && gameEvent.list()) {
		for (var l = 0; l < gameEvent.list().length; l++) {
			if (gameEvent.list()[l].code == 108) {
				var tagLine = gameEvent.list()[l].parameters[0].toUpperCase().match(/<TAGS:[ ](.+)>/gi);
				if (tagLine !== null && tagLine !== undefined) {
					var tagData = tagLine[0].match(/<TAGS:[ ](.+)>/i)[1].match(/\w+/gi);
					gameEvent.tags = tagData;
				}
			}
		}
	}
};

// OVERRIDES ------------------------------------------------------------------

NeMV.Tags.Scene_Boot_terminate = Scene_Boot.prototype.terminate;
Scene_Boot.prototype.terminate = function() {
	NeMV.Tags.Scene_Boot_terminate.call(this);
	NeMV.Tags.init();
};

// UTILITIES ------------------------------------------------------------------

NeMV.Tags.partyItemsWithTag = function(tag) {
	if (Imported.YEP_ItemCore) {
		return $gameParty._actors.reduce(function(a,b) {
			return $gameActors.actor(b)._equips.reduce(function(c,d) {
				return c || ((d.object() !== null) ? DataManager.getBaseItem(d.object()).hasTag(tag) : false);
			},a);
		}, false) ||
		$gameParty.equipItems().reduce(function(e,f) {
			return e || DataManager.getBaseItem(f).hasTag(tag);
		}, false) ||
		$gameParty.items().reduce(function(g,h) {
			return g || DataManager.getBaseItem(h).hasTag(tag);
		}, false);
	} else {
		return $gameParty._actors.reduce(function(a,b) {
			return $gameActors.actor(b)._equips.reduce(function(c,d) {
				return c || ((d.object() !== null) ? d.object().hasTag(tag) : false);
			},a);
		}, false) ||
		$gameParty.equipItems().reduce(function(e,f) {
			return e || f.hasTag(tag);
		}, false) ||
		$gameParty.items().reduce(function(g,h) {
			return g || h.hasTag(tag);
		}, false);
	}
};

NeMV.Tags.partyStatesWithTag = function(tag) {
	return $gameParty._actors.reduce(function(a,b) {
		return $gameActors.actor(b).states().reduce(function(c,d) {
			return c||d.hasTag(tag);}, a);
	}, false);
};

NeMV.Tags.eventsWithTag = function(tag) {
	var events = [];
	$gameMap.events().forEach(function(e) {
		if (e.hasTag(tag))
			events.push(e);
	});
	if (events.length === 0) return null;
	else return events;
};

// deprecated; please use new methods
NeMV.Tags.AnyItemsHaveTag = NeMV.Tags.partyItemsWithTag;
NeMV.Tags.AnyPartyStatesHaveTag = NeMV.Tags.partyStatesWithTag;
NeMV.Tags.EventsThatHaveTag = NeMV.Tags.eventsWithTag;

// ENEMY PROTO ----------------------------------------------------------------

Game_Enemy.prototype.hasTag = function(tag) {
	return NeMV.Tags.baseHasTag(tag, this.enemy().tags);
};

Game_Enemy.prototype.removeTag = function(tag) {
	var index = this.enemy().tags.indexOf(tag.toUpperCase());
	if (index > -1) this.enemy().tags.splice(index, 1);
};

Game_Enemy.prototype.addTag = function(tag) {
	this.enemy().removeTag(tag.toUpperCase());
	this.enemy().tags.push(tag.toUpperCase());
};

// ACTOR PROTO ----------------------------------------------------------------

Game_Actor.prototype.hasTag = function(tag) {
	return NeMV.Tags.baseHasTag(tag, this.actor().tags);
};

Game_Actor.prototype.removeTag = function(tag) {
	var index = this.actor().tags.indexOf(tag.toUpperCase());
	if (index > -1) this.actor().tags.splice(index, 1);
};

Game_Actor.prototype.addTag = function(tag) {
	this.actor().removeTag(tag.toUpperCase());
	this.actor().tags.push(tag.toUpperCase());
};

// ITEM PROTO ----------------------------------------------------------------

Game_Item.prototype.hasTag = function(tag) {
	return NeMV.Tags.baseHasTag(tag, this.object().tags);
};

Game_Item.prototype.removeTag = function(tag) {
	var index = this.object().tags.indexOf(tag.toUpperCase());
	if (index > -1) this.object().tags.splice(index, 1);
};

Game_Item.prototype.addTag = function(tag) {
	this.object().removeTag(tag.toUpperCase());
	this.object().tags.push(tag.toUpperCase());
};

// EVENT PROTO ----------------------------------------------------------------

Game_Event.prototype.hasTag = function(tag) {
	return NeMV.Tags.baseHasTag(tag, this.event().tags);
};

// Game_Event.prototype.removeTag = function(tag) {
// 	var index = this.event().tags.indexOf(tag.toUpperCase());
// 	if (index > -1) this.event().tags.splice(index, 1);
// };
//
// Game_Event.prototype.addTag = function(tag) {
// 	this.event().removeTag(tag.toUpperCase());
// 	this.event().tags.push(tag.toUpperCase());
// };

NeMV.Tags.Game_Event_initialize = Game_Event.prototype.initialize;
Game_Event.prototype.initialize = function(mapId, eventId) {
	NeMV.Tags.Game_Event_initialize.call(this, mapId, eventId);
	NeMV.Tags.baseEventSetup(this);
};

NeMV.Tags.Game_Event_lock = Game_Event.prototype.lock;
Game_Event.prototype.lock = function() {
	NeMV.Tags.Game_Event_lock.call(this);
	NeMV.Tags.baseEventSetup(this);
};

NeMV.Tags.Game_Event_refresh = Game_Event.prototype.refresh;
Game_Event.prototype.refresh = function() {
	NeMV.Tags.Game_Event_refresh.call(this);
	NeMV.Tags.baseEventSetup(this);
};

// MAP PROTO ------------------------------------------------------------------

NeMV.Tags.Scene_Map_onMapLoaded = Scene_Map.prototype.onMapLoaded;
Scene_Map.prototype.onMapLoaded = function() {
	NeMV.Tags.Scene_Map_onMapLoaded.call(this);
	$gameMap.events().forEach(function(event) {
		NeMV.Tags.baseEventSetup(event);
	});
};

repo_name: Rexhunk/karryn

license: unknown


code:
//=============================================================================
// NeMV - Actor Equip Points
// NeMV_X_ActorEquipPoints.js
//=============================================================================

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

var NeMV = NeMV || {};
NeMV.Tags = NeMV.Tags || {};
NeMV.Tags.AEP = NeMV.Tags.AEP || {};

//=============================================================================
 /*:
 * @plugindesc v1.0.2 (Requires NeMV_Tags.js & YEP_X_EquipRequirements.js) Provides a point-based equipment system with the help of NeMV Tags and YEP - Equip Requirements.
 * @author Nekoyoubi
 *
 * @param --- Equipment Tags ---
 * @default
 *
 * @param Equipment Tag 1
 * @desc Define the type, tag to be counted, and its value.
 * Format: type tag variable (e.g. "gear chest 4")
 * @default gear chest 4
 *
 * @param Equipment Tag 2
 * @desc Define the type, tag to be counted, and its value.
 * Format: type tag variable (e.g. "gear helm 2")
 * @default gear helm 2
 *
 * @param Equipment Tag 3
 * @desc Define the type, tag to be counted, and its value.
 * Format: type tag variable (e.g. "bracers 2")
 * @default gear bracers 2
 *
 * @param Equipment Tag 4
 * @desc Define the type, tag to be counted, and its value.
 * Format: type tag variable (e.g. "gear twohand 4")
 * @default gear twohand 4
 *
 * @param Equipment Tag 5
 * @desc Define the type, tag to be counted, and its value.
 * Format: type tag variable (e.g. "gear onehand 2")
 * @default gear onehand 2
 *
 * @param Equipment Tag 6
 * @desc Define the type, tag to be counted, and its value.
 * Format: type tag variable (e.g. "gear bow 3")
 * @default gear bow 3
 *
 * @param Equipment Tag 7
 * @desc Define the type, tag to be counted, and its value.
 * Format: type tag variable (e.g. "gear boots 2")
 * @default gear boots 2
 *
 * @param Equipment Tag 8
 * @desc Define the type, tag to be counted, and its value.
 * Format: type tag variable (e.g. "gear shield 3")
 * @default gear shield 3
 *
 * @param Equipment Tag 9
 * @desc Define the type, tag to be counted, and its value.
 * Format: type tag variable (e.g. "gear dagger 1")
 * @default gear dagger 1
 *
 * @param Equipment Tag 10
 * @desc Define the type, tag to be counted, and its value.
 * Format: type tag variable (e.g. "gear quiver 1")
 * @default gear quiver 1
 *
 * @param Equipment Tags CSV
 * @desc CSV array of strings for more equipment tags counters.
 * Example: gear halberd 5, piety holysymbol 2, cursed voodoodoll 3
 * @default
 *
 * @param --- Misc. ---
 * @default
 *
 * @param Debug AEP
 * @desc Whether or not to output debug information for AEP.
 * Example: true (debug) or false (no debug)
 * @default false
 *
 * @help
 * ============================================================================
 * Introduction
 * ============================================================================
 *
 * This plugin provides a point-based equipment system with the help of
 * NeMV - Tags & YEP - Equip Requirements. It allows you to build an equipment
 * monitoring system, where when equipping and unequipping weapons and armor to
 * your actors, you can track that equipment based on tags. This can be used to
 * build a point-based equipment system, determine an encumbrance for your
 * actors, or even grant or deny skills, quests, event interactions, etc based
 * on the points associated to an actors tagged equipment.
 *
 * ============================================================================
 * Usage
 * ============================================================================
 *
 * First, configure the respective equipment entries in the plugin's parameters
 * as the default plugin parameters illustrate.
 *
 * Next, tag your equipment with the appropriate tags...
 *
 * Weapon  >  Notebox  >  <tags: twohand, sword, demonic>
 *
 * Armor  >  Notebox  >  <tags: shield, angelic, quest>
 *
 * Now add an equipment limiting tag to your actors. You will set the inital
 * maximum here, but this can be changed during the course of play via plugin
 * commands and scripts.
 *
 * Format:  <MAX TYPE POINTS: AMOUNT>
 *
 * Example:
 *
 * Actor  >  Notebox  >  <Max Gear Points: 10>
 *
 * Plugin Commands ------------------------------------------------------------
 *
 * AEP comes equipped with plugin commands for adding, removing, and manually
 * setting Equip Point tags. The format for these commands is as follows.
 *
 * AEP COMMAND TYPE TAG [ AMOUNT ]
 *
 * Examples:
 *
 * aep add gear buckler 2
 * aep remove gear buckler
 * aep set holy symbol 1
 * aep add gear necklace
 *
 * In the examples above, the first adds a new Gear-type entry with the tag
 * "buckler". The second removes the buckler from the Gear-type. This will not
 * remove buckler from any other types that may be watching for it though.
 * The third assumes that a Holy-type "symbol" tag is already setup, and sets
 * sets its point value to 1 going forward. The fourth example creates a new
 * Gear-type entry that defaults to a 0-point value.
 *
 * ============================================================================
 * Support
 * ============================================================================
 *
 * Should this plugin not work for you for any reason, please notify me by
 * creating a GitHub issue, emailing me at lance-at-nekoyoubi.com, or message
 * me in any social convention you happen to see me in.
 *
 * Thanks, and happy equipping!
 *
 * ============================================================================
 * Changelog
 * ============================================================================
 *
 * Version 1.0.2:
 * - fixed a bug where the available equip point threshold needed to be one below
 *
 * Version 1.0.1:
 * - removed unintentional YEP - Item Core requirement
 *
 * Version 1.0:
 * - initial plugin
 *
 */
//=============================================================================

// PARAMS ---------------------------------------------------------------------

if (true) { //PARAMS COLLAPSE
	NeMV.Tags.AEP.Parameters = PluginManager.parameters('NeMV_X_ActorEquipPoints');
	NeMV.Tags.AEP.Param = NeMV.Tags.AEP.Param || {};

	NeMV.Tags.AEP.Param.EquipPoints = [];
	NeMV.Tags.AEP.Param.EquipPoints.push(String(NeMV.Tags.AEP.Parameters['Equipment Tag 1']));
	NeMV.Tags.AEP.Param.EquipPoints.push(String(NeMV.Tags.AEP.Parameters['Equipment Tag 2']));
	NeMV.Tags.AEP.Param.EquipPoints.push(String(NeMV.Tags.AEP.Parameters['Equipment Tag 3']));
	NeMV.Tags.AEP.Param.EquipPoints.push(String(NeMV.Tags.AEP.Parameters['Equipment Tag 4']));
	NeMV.Tags.AEP.Param.EquipPoints.push(String(NeMV.Tags.AEP.Parameters['Equipment Tag 5']));
	NeMV.Tags.AEP.Param.EquipPoints.push(String(NeMV.Tags.AEP.Parameters['Equipment Tag 6']));
	NeMV.Tags.AEP.Param.EquipPoints.push(String(NeMV.Tags.AEP.Parameters['Equipment Tag 7']));
	NeMV.Tags.AEP.Param.EquipPoints.push(String(NeMV.Tags.AEP.Parameters['Equipment Tag 8']));
	NeMV.Tags.AEP.Param.EquipPoints.push(String(NeMV.Tags.AEP.Parameters['Equipment Tag 9']));
	NeMV.Tags.AEP.Param.EquipPoints.push(String(NeMV.Tags.AEP.Parameters['Equipment Tag 10']));
	NeMV.Tags.AEP.Param.EquipPoints = NeMV.Tags.AEP.Param.EquipPoints.concat(
		String(NeMV.Tags.AEP.Parameters['Equipment Tag CSV']).split(/\s*,\s*/)||[]);

	NeMV.Tags.AEP.Debug = eval(NeMV.Tags.AEP.Parameters['Debug AEP']);
}

// INITIALIZATION -------------------------------------------------------------

NeMV.Tags.AEP.EquipPoints = NeMV.Tags.AEP.EquipPoints || [];

NeMV.Tags.AEP.init = function() {
	for (var i = 0; i < this.Param.EquipPoints.length; i++) {
		var points = this.Param.EquipPoints[i].trim();
		if (points === null || points == 'undefined' || points === "") {
			this.Param.EquipPoints.splice(i, 1);
		} else {
			this.addEquipPoints(points);
		}
	}
	if ($dataActors !== null && $dataActors !== undefined) this.processNotetags($dataActors);
	if ($dataWeapons !== null && $dataWeapons !== undefined) this.processEquipment($dataWeapons);
	if ($dataArmors !== null && $dataArmors !== undefined) this.processEquipment($dataArmors);
};

NeMV.Tags.AEP.processEquipment = function(data) {
	for (var n = 1; n < data.length; n++) {
		var obj = data[n];
		if (obj !== null && obj !== undefined) {
			obj.getEquipPointsValue = function(type) {
				return NeMV.Tags.AEP.baseGetEquipPointsValue(type, this);
			};
		}
	}
};

NeMV.Tags.AEP.processNotetags = function(data) {
	var tagRegex = /<(?:MAX[ ](\w+)[ ]POINTS):\s*(\d+)>/i;
	for (var n = 1; n < data.length; n++) {
		var obj = data[n];
		if (obj === null || obj == 'undefined') continue;
		obj.maxEquipPoints = obj.maxEquipPoints || [];
		obj.getEquipPointsMax = function(type) {
			return NeMV.Tags.AEP.baseGetEquipPointsMax(type, this.maxEquipPoints);
		};
		obj.setEquipPointsMax = function(type, max) {
			return NeMV.Tags.AEP.baseSetEquipPointsMax(type, max, this.maxEquipPoints);
		};
		obj.getEquipPoints = function(type) {
			return NeMV.Tags.AEP.baseGetEquipPoints(type, this.id);
		};
		var notelines = obj.note.split(/[\r\n]+/);
		for (var i = 0; i < notelines.length; i++) {
			var line = notelines[i];
			lineMatch = line.match(tagRegex);
			if (lineMatch) {
				var type = lineMatch[1].toUpperCase();
				var max = Number(lineMatch[2]);
	    		obj.maxEquipPoints.push({ 'type' : type, 'max' : max });
			}
		}
	}
};

NeMV.Tags.AEP.Scene_Boot_terminate = Scene_Boot.prototype.terminate;
Scene_Boot.prototype.terminate = function() {
	NeMV.Tags.AEP.Scene_Boot_terminate.call(this);
	NeMV.Tags.AEP.init();
};

// BASE METHODS ---------------------------------------------------------------

NeMV.Tags.AEP.baseGetEquipPointsMax = function(type, array) {
	for (var i = 0; i < array.length; i++)
		if (array[i].type.toUpperCase() == type.toUpperCase())
			return array[i].max;
	return -1;
};

NeMV.Tags.AEP.baseSetEquipPointsMax = function(type, max, array) {
	for (var i = 0; i < array.length; i++) {
		if (array[i].type.toUpperCase() == type.toUpperCase()) {
			array[i].max = max;
			return;
		}
	}
};

NeMV.Tags.AEP.baseGetEquipPoints = function(type, actorId) {
	var actor = $gameActors.actor(actorId);
	var equips = actor._equips;
	var points = 0;
	for (var ep = 0; ep < this.EquipPoints.length; ep++) {
		for (var e = 0; e < equips.length; e++) {
			if (equips[e]._dataClass !== "" &&
				this.EquipPoints[ep].type.toUpperCase() == type.toUpperCase() &&
				equips[e].hasTag(this.EquipPoints[ep].tag)) {
				points += this.EquipPoints[ep].points;
			}
		}
	}
	return points;
};

NeMV.Tags.AEP.baseGetEquipPointsValue = function(type, item) {
	for (var ep = 0; ep < this.EquipPoints.length; ep++) {
		if (this.EquipPoints[ep].type.toUpperCase() == type.toUpperCase() &&
			item.hasTag(this.EquipPoints[ep].tag)) {
			return this.EquipPoints[ep].points;
		}
	}
	return 0;
};

// EQUIP POINT METHODS ------------------------------------------------------------

NeMV.Tags.AEP.addEquipPoints = function(points) {
	var split = points.split(/\s+/);
	this.EquipPoints.push({
		'type' : split[0].toUpperCase(),
		'tag' : split[1].toUpperCase(),
		'points' : (split.length > 2 && !isNaN(parseInt(split[2]))) ? Number(split[2]) : 0
	});
	if (this.Debug) console.log("AEP - Tag added: "+points);
};

NeMV.Tags.AEP.removeEquipPoints = function(tag) {
	var index = -1;
	for (var i = 0; i < this.EquipPoints.length; i++)
		if (this.EquipPoints[i].tag.toUpperCase() == tag.toUpperCase())
			index = i;
	if (index > -1) {
		this.EquipPoints.splice(index, 1);
		if (this.Debug) console.log("AEP - "+tag+" removed");
	} else {
		if (this.Debug) console.log("AEP - "+tag+" not found");
	}
};

NeMV.Tags.AEP.setEquipPoints = function(points) {
	var split = points.split(/\s+/);
	for (var i = 0; i < this.EquipPoints.length; i++) {
		if (this.EquipPoints[i].type.toUpperCase() == split[0].toUpperCase() &&
			this.EquipPoints[i].tag.toUpperCase() == split[1].toUpperCase()) {
			this.EquipPoints[i].points = (split.length > 2 && !isNaN(parseInt(split[2]))) ? Number(split[2]) : 0;
			if (this.Debug) console.log("AEP - Tag set: "+this.EquipPoints[i].type.toUpperCase()+":"+this.EquipPoints[i].tag.toUpperCase()+" to "+this.EquipPoints[i].points);
		}
	}
};

// PLUGIN COMMANDS ------------------------------------------------------------

NeMV.Tags.AEP.Game_Interpreter_pluginCommand = Game_Interpreter.prototype.pluginCommand;
Game_Interpreter.prototype.pluginCommand = function(command, args) {
	NeMV.Tags.AEP.Game_Interpreter_pluginCommand.call(this, command, args);
	if (command.toUpperCase() == "AEP") {
		var regex = /(?:AEP)\s(ADD|REMOVE|SET)\s(([a-z_-]+)\s([a-z_-]+)((?:\s)(\d+))?)/i;
		var data = (command+" "+args.join(" ")).toUpperCase().match(regex);
		if (data !== null) {
			var comm = data[1];
			var tagdata = data[2];
			var tag = data[3];
			var points = (data[5].length > 0) ? Number(data[5]) : 0;
			switch (comm.toUpperCase()) {
				case 'ADD':
					NeMV.Tags.AEP.addEquipPoints(tagdata);
					break;
				case 'REMOVE':
					NeMV.Tags.AEP.removeEquipPoints(tag);
					break;
				case 'SET':
					NeMV.Tags.AEP.setEquipPoints(tagdata);
					break;
			}
		}
	}
};

// EQUIP REQUIREMENTS INTEGRATION ---------------------------------------------

NeMV.Tags.AEP.getBaseItem = function(item) {
	return (Imported.YEP_ItemCore) ? DataManager.getBaseItem(item) : item;
};

if (Imported.YEP_X_EquipRequirements) {
	Game_BattlerBase.prototype.meetEquipPointsRequirements = function(item, currentItem) {
		var actor = this.actor();
		var baseItem = (item.hasTag === undefined) ? NeMV.Tags.AEP.getBaseItem(item) : item;

		var epa = NeMV.Tags.AEP.EquipPoints;
		var safe = true;
		for (var ep = 0; ep < epa.length; ep++) {
			if (baseItem.hasTag(epa[ep].tag) && actor.getEquipPointsMax(epa[ep].type) > -1) {
				var max = actor.getEquipPointsMax(epa[ep].type);
				var current = actor.getEquipPoints(epa[ep].type);
				var ipoints = baseItem.getEquipPointsValue(epa[ep].type);
				var cpoints = 0;
				if(currentItem != false) {
					cpoints = currentItem.getEquipPointsValue(epa[ep].type);
				}
				safe &= (max >= (current + ipoints - cpoints));
			}
		}
		return safe;
	};

	Game_BattlerBase.prototype.meetAllEquipRequirements = function(item, currentItem) {
		if (!item.equipRequirements) {
			if (item.baseItemId) {
				item.equipRequirements = NeMV.Tags.AEP.getBaseItem(item).equipRequirements;
			} else {
	    		return true;
	    	}
		}
		if (!this.meetEquipPointsRequirements(item, currentItem)) return false; // the only change in the override
		if (!this.meetEquipParamRequirements(item)) return false;
		if (!this.meetEquipClassRequirements(item)) return false;
		if (!this.meetEquipSkillRequirements(item)) return false;
		if (!this.meetEquipSwitchRequirements(item)) return false;
		if (!this.meetEquipUniqueRequirements(item)) return false;
		if (!this.meetEquipEvalRequirements(item)) return false;
		return true;
	};
}

// ACTOR PROTO ----------------------------------------------------------------

Game_Actor.prototype.getEquipPoints = function(type) {
	return NeMV.Tags.AEP.baseGetEquipPoints(type, this.actor().id);
};

Game_Actor.prototype.getEquipPointsMax = function(type) {
	return NeMV.Tags.AEP.baseGetEquipPointsMax(type, this.actor().maxEquipPoints);
};

// ITEM PROTO ----------------------------------------------------------------

Game_Item.prototype.getEquipPointsValue = function(type) {
	return NeMV.Tags.AEP.baseGetEquipPointsValue(type, this.object());
};


code:
/*=============================================================================
 * Orange - Greenworks
 * By Hudell - www.hudell.com
 * OrangeGreenworks.js
 * Version: 1.2
 * Free for commercial and non commercial use.
 *=============================================================================*/
/*:
 * @plugindesc Steamworks Integration <OrangeGreenworks>
 * @author Hudell
 *
 * @help
 * ============================================================================
 * Hudell's Plugins
 * ============================================================================
 *
 * Check out my website to learn how to use this plugin:
 * http://hudell.com/blog/orangegreenworks/
 *
 *=============================================================================*/
var Imported = Imported || {};
var Hudell = Hudell || {};
Hudell.OrangeGreenworks = Hudell.OrangeGreenworks || {};

(function($) {
  "use strict";

  $.getScreenName = function() {
    return 'Play Test';
  };

  $.getUILanguage = function() {
    return 'english';
  };

  $.getGameLanguage = function() {
    return 'english';
  };

  $.activateAchievement = function(achievementName) {
    console.log('Activate achievement ', achievementName);
  };

  $.getAchievement = function(achievementName) {
    return false;
  };

  $.clearAchievement = function(achievementName) {
    console.log('Clear achievement ', achievementName);
  };

  $.getNumberOfAchievements = function() {
    return 0;
  };

  $.isSteamRunning = function() {
    return false;
  };

  $.activateGameOverlay = function(option) {
  };

  $.isGameOverlayEnabled = function() {
    return false;
  };

  $.activateGameOverlayToWebPage = function(url) {
    console.log('Open URL');
  };

  $.getDLCCount = function() {
    return 0;
  };

  $.isDLCInstalled = function(dlcAppId) {
    return false;
  };

  $.installDLC = function(dlcAppId) {
  };

  $.uninstallDLC = function(dlcAppId) {
  };

  $.getStatInt = function(name) {
    return 0;
  };

  $.getStatFloat = function(name) {
    return 0;
  };

  $.setStat = function(name, value) {
    console.log('Change Stat', name, value);
    return false;
  };

  $.storeStats = function() {
    console.log('Store Stats');
    return false;
  };

  $.isSubscribedApp = function(appId) {
    return false;
  };

  if (Utils.isNwjs()) {
    $.initialized = false;

    try {
      $.greenworks = require('./greenworks');
    }
    catch(e) {
      $.greenworks = false;
      console.log('Greenworks failed to load. Make sure you copied all files from the Steamworks SDK to the right folders;');
      console.log('http://hudell.com/blog/orange-greenworks');
      console.error(e);
    }

    if (!!$.greenworks) {
      $.initialized = $.greenworks.initAPI();

      if (!$.initialized) {
        console.log('Greenworks failed to initialize.');
        return;
      }

      $.steamId = $.greenworks.getSteamId();
      console.log('Steam User: ', $.steamId.screenName);

      $.getScreenName = function() {
        return $.steamId.screenName;
      };

      $.getUILanguage = function() {
        return $.greenworks.getCurrentUILanguage();
      };

      $.getGameLanguage = function() {
        return $.greenworks.getCurrentGameLanguage();
      };

      $.isSteamRunning = function() {
        return $.greenworks.isSteamRunning();
      };

      $._storeStatsSuccess = function(){
        console.log('Stored Stats Successfully', arguments);
      };

      $._storeStatsError = function(){
        console.log('Failed to Store Stats', arguments);
      };

      $._achievementSuccess = function(){
        console.log('Achievement activated', arguments);
      };

      $._achievementError = function(){
        console.log('Achievement activation error', arguments);
      };

      $._clearAchievementSuccess = function(){
        console.log('Successfully Cleared Achievement', arguments);
      };

      $._clearAchievementError = function(){
        console.log('Failed to Clear Achievement', arguments);
      };

      $._getAchievementSuccess = function(){
      };

      $._getAchievementError = function(){
        console.log('Failed to check Achievement', arguments);
      };

      $.activateAchievement = function(achievementName) {
        if (!achievementName) {
          console.log('Achievement name not provided.');
          return;
        }

        if (!$.isSteamRunning()) {
          console.log('Steam isn\'t running');
          return;
        }

        $.greenworks.activateAchievement(achievementName, $._achievementSuccess, $._achievementError);
      };

      $.getAchievement = function(achievementName) {
        if (!achievementName) {
          console.log('Achievement name not provided.');
          return false;
        }

        if (!$.isSteamRunning()) {
          console.log('Steam isn\'t running');
          return false;
        }

        return $.greenworks.getAchievement(achievementName, $._getAchievementSuccess, $._getAchievementError);
      };

      $.clearAchievement = function(achievementName) {
        if (!achievementName) {
          console.log('Achievement name not provided.');
          return false;
        }

        if (!$.isSteamRunning()) {
          console.log('Steam isn\'t running');
          return false;
        }

        $.greenworks.clearAchievement(achievementName, $._clearAchievementSuccess, $._clearAchievementError);
      };

      $.getNumberOfAchievements = function() {
        if (!$.isSteamRunning()) {
          console.log('Steam isn\'t running');
          return false;
        }

        return $.greenworks.getNumberOfAchievements();
      };

      $.activateGameOverlay = function(option) {
        if (!$.isSteamRunning()) {
          console.log('Steam isn\'t running');
          return false;
        }

        $.greenworks.activateGameOverlay(option);
      };

      $.isGameOverlayEnabled = function() {
        if (!$.isSteamRunning()) {
          console.log('Steam isn\'t running');
          return false;
        }

        return $.greenworks.isGameOverlayEnabled();
      };

      $.activateGameOverlayToWebPage = function(url) {
        if (!$.isSteamRunning()) {
          console.log('Steam isn\'t running');
          return false;
        }

        $.greenworks.activateGameOverlayToWebPage(url);
      };

      $.isSubscribedApp = function(appId) {
        if (!$.isSteamRunning()) {
          console.log('Steam isn\'t running');
          return false;
        }

        return $.greenworks.isSubscribedApp(appId);
      };

      $.getDLCCount = function() {
        if (!$.isSteamRunning()) {
          console.log('Steam isn\'t running');
          return 0;
        }

        return $.greenworks.getDLCCount();
      };

      $.isDLCInstalled = function(dlcAppId) {
        if (!$.isSteamRunning()) {
          console.log('Steam isn\'t running');
          return false;
        }

        return $.greenworks.isDLCInstalled(dlcAppId);
      };

      $.installDLC = function(dlcAppId) {
        if (!$.isSteamRunning()) {
          console.log('Steam isn\'t running');
          return false;
        }

        $.greenworks.installDLC(dlcAppId);
      };

      $.uninstallDLC = function(dlcAppId) {
        if (!$.isSteamRunning()) {
          console.log('Steam isn\'t running');
          return false;
        }

        $.greenworks.uninstallDLC(dlcAppId);
      };

      $.getStatInt = function(name) {
        if (!$.isSteamRunning()) {
          console.log('Steam isn\'t running');
          return 0;
        }

        return $.greenworks.getStatInt(name);
      };

      $.getStatFloat = function(name) {
        if (!$.isSteamRunning()) {
          console.log('Steam isn\'t running');
          return 0;
        }

        return $.greenworks.getStatFloat(name);
      };

      $.setStat = function(name, value) {
        if (!$.isSteamRunning()) {
          console.log('Steam isn\'t running');
          return false;
        }

        return $.greenworks.setStat(name, value);
      };

      $.storeStats = function() {
        if (!$.isSteamRunning()) {
          console.log('Steam isn\'t running');
          return false;
        }

        return $.greenworks.setStat($._storeStatsSuccess, $._storeStatsError);
      };

      $.getFriendCount = function() {
        return $.greenworks.getFriendCount($.greenworks.FriendFlags.Immediate);
      };

      $.isCloudEnabled = function() {
        return $.greenworks.isCloudEnabled();
      };

      $.isCloudEnabledForUser = function() {
        return $.greenworks.isCloudEnabledForUser();
      };
    }
  }
})(Hudell.OrangeGreenworks);

OrangeGreenworks = Hudell.OrangeGreenworks;
Imported.OrangeGreenworks = 1.2;


code:
//=============================================================================
// PD_FootStepSound.js
//=============================================================================

/*:
 * @plugindesc Add to sound of player character footsteps.
 * @author Shio_inu
 *
 * @help 面倒なので誰か代わりに翻訳して。
 * last update : 29th Dec 2015 v1.0
 *
 * @param File Name
 * @desc ファイル名です。「ここに入力したファイル名+地形タグ」のファイルが再生されます。
 * @default foot_
 */

/*:ja
 * @plugindesc プレイヤーの移動に合わせて足音を再生するプラグインです。
 * @author しおいぬ
 *
 * @help 地形タグによって再生される足音が変化します。
 * last update : 2015/12/29 v1.0
 *
 * @param File Name
 * @desc ファイル名です。「ここに入力したファイル名+地形タグ」のファイルが再生されます。
 * @default foot_
 */
(function(){

    var parameters = PluginManager.parameters('PD_FootStepSound');
    var fileName = String(parameters['File Name'] || "foot_");

    var updatePlayer = Game_Player.prototype.update;
    Game_Player.prototype.update = function(sceneActive) {
        updatePlayer.call(this, sceneActive);

        if(!this._prevpattern){
            this._prevpattern = this.pattern();
        }

        if(this._prevpattern != this.pattern() && !this.isInVehicle()){
            var id = $gameMap.terrainTag(this._x, this._y);
			if($gameSwitches.value(SWITCH_FOOTSTEPS_SE_OFF_ID)) {

			}
            else if(this.pattern() != 1) {
                var seObj = {"name":fileName + id,"volume":90,"pitch":100 + (10 * this.pattern()),"pan":0};
                AudioManager.playSe(seObj);
            }

        }

        this._prevpattern = this.pattern();
    };
})();


code:
//=============================================================================
// PictureCallCommon.js
// ----------------------------------------------------------------------------
// Copyright (c) 2015 Triacontane
// This plugin is released under the MIT License.
// http://opensource.org/licenses/mit-license.php
// ----------------------------------------------------------------------------
// Version
// 1.10.1 2017/05/27 動的文字列ピクチャプラグインのウィンドウフレームクリックをピクチャクリックに対応
// 1.9.3 2017/05/27 競合の可能性のある記述（Objectクラスへのプロパティ追加）をリファクタリング（by liplyさん）
// 1.9.2 2017/03/16 1.9.0で戦闘中にコモンイベント実行が正しく動作していなかった問題を修正
// 1.9.1 2017/03/16 透明色を考慮する場合、不透明度が0のピクチャは一切反応しなくなるように仕様変更
// 1.9.0 2017/03/13 戦闘中常にピクチャクリックイベントを実行できる機能を追加
// 1.8.2 2017/02/14 1.8.0の修正により、ピクチャクリック時に変数に値を格納する機能が無効化されていたのを修正
// 1.8.1 2017/02/07 端末依存の記述を削除
// 1.8.0 2017/02/03 ピクチャクリックを任意のボタンにバインドできる機能を追加
// 1.7.0 2017/02/02 マップのズームおよびシェイク中でも正確にピクチャをクリックできるようになりました。
//                  マウスポインタがピクチャ内にあるかどうかをスクリプトで判定できる機能を追加。
// 1.6.0 2016/12/29 ピクチャクリックでイベントが発生したらマップタッチを無効化するよう仕様修正
// 1.5.1 2016/11/20 1.5.0で混入した不要なコードを削除
// 1.5.0 2016/11/19 ピクチャクリック時にコモンイベントではなくスイッチをONにできる機能を追加
// 1.4.0 2016/08/20 ピクチャごとに透明色を考慮するかどうかを設定できる機能を追加
//                  プラグインを適用していないセーブデータをロードした場合に発生するエラーを修正
// 1.3.5 2016/04/20 リファクタリングによりピクチャの優先順位が逆転していたのをもとに戻した
// 1.3.4 2016/04/08 ピクチャが隣接する状態でマウスオーバーとマウスアウトが正しく機能しない場合がある問題を修正
// 1.3.3 2016/03/19 トリガー条件を満たした場合に以後のタッチ処理を抑制するパラメータを追加
// 1.3.2 2016/02/28 処理の負荷を少し軽減
// 1.3.1 2016/02/21 トリガーにマウスを押したまま移動を追加
// 1.3.0 2016/01/24 ピクチャをなでなでする機能を追加
//                  トリガーにマウスムーブを追加
//                  ピクチャが回転しているときに正しく位置を補足できるよう修正
// 1.2.1 2016/01/21 呼び出すコモンイベントの上限を100から1000（DB上の最大値）に修正
//                  競合対策（YEP_MessageCore.js）
// 1.2.0 2016/01/14 ホイールクリック、ダブルクリックなどトリガーを10種類に拡充
// 1.1.3 2016/01/02 競合対策（TDDP_BindPicturesToMap.js）
// 1.1.2 2015/12/20 長押しイベント発生時に1秒間のインターバルを設定するよう仕様変更
// 1.1.1 2015/12/10 ピクチャを消去後にマウスオーバーするとエラーになる現象を修正
// 1.1.0 2015/11/23 コモンイベントを呼び出した対象のピクチャ番号を特定する機能を追加
//                  設定で透明色を考慮する機能を追加
//                  トリガーとして「右クリック」や「長押し」を追加
// 1.0.0 2015/11/14 初版
// ----------------------------------------------------------------------------
// [Blog]   : http://triacontane.blogspot.jp/
// [Twitter]: https://twitter.com/triacontane/
// [GitHub] : https://github.com/triacontane/
//=============================================================================

/*:ja
 * @plugindesc ピクチャのボタン化プラグイン
 * @author トリアコンタン
 *
 * @param 透明色を考慮
 * @desc クリックされた箇所が透明色だった場合は、クリックを無効にする。
 * @default ON
 *
 * @param ピクチャ番号の変数番号
 * @desc ピクチャクリック時にピクチャ番号を格納するゲーム変数の番号。
 * @default 0
 *
 * @param ポインタX座標の変数番号
 * @desc マウスカーソルもしくはタッチした位置のX座標を常に格納するゲーム変数の番号
 * @default 0
 *
 * @param ポインタY座標の変数番号
 * @desc マウスカーソルもしくはタッチした位置のY座標を常に格納するゲーム変数の番号
 * @default 0
 *
 * @param タッチ操作抑制
 * @desc トリガー条件を満たした際にタッチ情報をクリアします。(ON/OFF)
 * 他のタッチ操作と動作が重複する場合にONにします。
 * @default OFF
 *
 * @param 戦闘中常にコモン実行
 * @desc 戦闘中にピクチャをクリックしたとき、常にコモンイベントを実行します。(ON/OFF)
 * @default OFF
 *
 * @help ピクチャをクリックすると、指定したコモンイベントが
 * 呼び出される、もしくは任意のスイッチをONにするプラグインコマンドを提供します。
 * このプラグインを利用すれば、JavaScriptの知識がなくても
 * 誰でも簡単にクリックやタッチを主体にしたゲームを作れます。
 *
 * 戦闘中でも実行可能ですが、ツクールMVの仕様により限られたタイミングでしか
 * イベントは実行されません。パラメータ「戦闘中常にコモン実行」を有効にすると
 * 常にイベントが実行されるようになりますが、
 * 一部イベントコマンドは正しく動作しない制約があります。
 *
 * 注意！
 * 一度関連づけたピクチャとコモンイベントはピクチャを消去しても有効です。
 * ピクチャが存在しなければどこをクリックしても反応しませんが、
 * 同じ番号で再度、ピクチャの表示を行うと反応するようになります。
 *
 * プラグインコマンド詳細
 *  イベントコマンド「プラグインコマンド」から実行。
 *  （引数の間は半角スペースで区切る）
 *
 *  ピクチャのボタン化 or
 *  P_CALL_CE [ピクチャ番号] [コモンイベントID] [トリガー] [透明色を考慮]:
 *      ピクチャの領域内でトリガー条件を満たした場合に呼び出されるコモンイベントを関連づけます。
 *  　　トリガーは以下の通りです。(省略すると 1 になります)
 *      1  : クリックした場合
 *      2  : 右クリックした場合
 *      3  : 長押しした場合
 *      4  : マウスをピクチャに重ねた場合
 *      5  : マウスをピクチャから放した場合
 *      6  : クリックを解放（リリース）した場合
 *      7  : クリックした場合（かつ長押しの際の繰り返しを考慮）
 *      8  : クリックしている間ずっと
 *      9  : ホイールクリックした場合（PCの場合のみ有効）
 *      10 : ダブルクリックした場合
 *      11 : マウスをピクチャ内で移動した場合
 *      12 : マウスを押しつつピクチャ内で移動した場合
 *
 *      透明色を考慮のパラメータ(ON/OFF)を指定するとピクチャごとに透明色を考慮するかを
 *      設定できます。何も設定しないとプラグインパラメータの設定が適用されます。(従来の仕様)
 *
 *  例：P_CALL_CE 1 3 7 ON
 *  　：ピクチャのボタン化 \v[1] \v[2] \v[3] OFF
 *
 *  ピクチャのスイッチ化 or
 *  P_CALL_SWITCH [ピクチャ番号] [スイッチID] [トリガー] [透明色を考慮]:
 *  　　ピクチャの領域内でトリガー条件を満たした場合に、任意のスイッチをONにします。
 *  　　トリガーの設定などは、ピクチャのボタン化と同一です。
 *
 *  ピクチャのキーバインド or
 *  P_CALL_KEY_BIND [ピクチャ番号] [ボタン名称] [トリガー] [透明色を考慮]:
 *  　　ピクチャの領域内でトリガー条件を満たした場合に、任意のボタンを押したことにします。
 *  　　ボタン名の設定は以下の通りです。(Windows基準)
 *  ok      : Enter,Z
 *  shift   : Shift
 *  control : Ctrl,Alt
 *  escape  : Esc,X
 *  left    : ←
 *  up      : ↑
 *  right   : →
 *  down    : ↓
 *
 *  ピクチャのボタン化解除 or
 *  P_CALL_CE_REMOVE [ピクチャ番号] :
 *      ピクチャとコモンイベントもしくはスイッチの関連づけを解除します。
 *      全てのトリガーが削除対象です。
 *
 *  例：P_CALL_CE_REMOVE 1
 *  　：ピクチャのボタン化解除 \v[1]
 *
 *  ピクチャのなでなで設定 or
 *  P_STROKE [ピクチャ番号] [変数番号]
 *  　　指定したピクチャの上でマウスやタッチを動かすと、
 *  　　速さに応じた値が指定した変数に値が加算されるようになります。
 *  　　この設定はピクチャを差し替えたり、一時的に非表示にしても有効です。
 *  　　10秒でだいたい1000くらいまで溜まります。
 *
 *  例：P_STROKE 1 2
 *  　：ピクチャのなでなで設定 \v[1] \v[2]
 *
 *  ピクチャのなでなで解除 or
 *  P_STROKE_REMOVE [ピクチャ番号]
 *  　　指定したピクチャのなでなで設定を解除します。
 *
 *  例：P_STROKE_REMOVE 1
 *  　：ピクチャのなでなで解除 \v[1]
 *
 *  ピクチャのポインタ化 or
 *  P_POINTER [ピクチャ番号]
 *  　　指定したピクチャがタッチ座標を自動で追従するようになります。
 *  　　タッチしていないと自動で非表示になります。
 *
 *  例：P_POINTER 1
 *  　：ピクチャのポインタ化 \v[1]
 *
 *  ピクチャのポインタ化解除 or
 *  P_POINTER_REMOVE [ピクチャ番号]
 *  　　指定したピクチャのポインタ化を解除します。
 *
 *  例：P_POINTER_REMOVE 1
 *  　：ピクチャのポインタ化解除 \v[1]
 *
 *  ・スクリプト（上級者向け）
 *  $gameScreen.isPointerInnerPicture([ID]);
 *
 *  指定した[ID]のピクチャ内にマウスポインタもしくはタッチ座標が存在する場合に
 *  trueを返します。このスクリプトは[P_CALL_CE]を使用していなくても有効です。
 *
 *  例：$gameScreen.isPointerInnerPicture(5);
 *
 * 利用規約：
 *  作者に無断で改変、再配布が可能で、利用形態（商用、18禁利用等）
 *  についても制限はありません。
 *  このプラグインはもうあなたのものです。
 */
/*:
 * @plugindesc Clickable picture plugin
 * @author triacontane
 *
 * @param TransparentConsideration
 * @desc if click position is transparent, click is disabled.
 * @default ON
 *
 * @param GameVariablePictureNum
 * @desc Game variable number that stores the picture number when common event called.
 * @default 0
 *
 * @param GameVariableTouchX
 * @desc Game variable number that stores touch x position
 * @default 0
 *
 * @param GameVariableTouchY
 * @desc Game variable number that stores touch y position
 * @default 0
 *
 * @param SuppressTouch
 * @desc Suppress touch event for others(ON/OFF)
 * @default OFF
 *
 * @param AlwaysCommonInBattle
 * @desc Always execute common event in battle(ON/OFF)
 * @default OFF
 *
 * @help When clicked picture, call common event.
 *
 * Plugin Command
 *
 *  P_CALL_CE [Picture number] [Common event ID] [Trigger] [TransparentConsideration]:
 *      When picture was clicked, assign common event id.
 *  　　Trigger are As below(if omit, It is specified to 1)
 *      1  : Left click
 *      2  : Right click
 *      3  : Long click
 *      4  : Mouse over
 *      5  : Mouse out
 *      6  : Mouse release
 *      7  : Mouse repeat click
 *      8  : Mouse press
 *      9  : Wheel click
 *      10 : Double click
 *      11 : Mouse move
 *      12 : Mouse move and press
 *
 *  P_CALL_CE_REMOVE [Picture number] :
 *      break relation from picture to common event.
 *
 *  - Script
 *  $gameScreen.isPointerInnerPicture([ID]);
 *
 *  If mouse pointer inner the picture, return true.
 *
 *  ex：$gameScreen.isPointerInnerPicture(5);
 *
 *  This plugin is released under the MIT License.
 */
(function() {
    'use strict';
    var pluginName = 'PictureCallCommon';

    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 getParamBoolean = function(paramNames) {
        var value = getParamOther(paramNames);
        return (value || '').toUpperCase() === 'ON';
    };

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

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

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

    var getArgBoolean = function(arg) {
        return (arg || '').toUpperCase() === 'ON';
    };

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

    var iterate = function(that, handler) {
        Object.keys(that).forEach(function(key, index) {
            handler.call(that, key, that[key], index);
        });
    };

    //=============================================================================
    // パラメータの取得とバリデーション
    //=============================================================================
    var paramGameVariableTouchX       = getParamNumber(['GameVariableTouchX', 'ポインタX座標の変数番号'], 0);
    var paramGameVariableTouchY       = getParamNumber(['GameVariableTouchY', 'ポインタY座標の変数番号'], 0);
    var paramGameVariablePictNum      = getParamNumber(['GameVariablePictureNum', 'ピクチャ番号の変数番号'], 0);
    var paramTransparentConsideration = getParamBoolean(['TransparentConsideration', '透明色を考慮']);
    var paramSuppressTouch            = getParamBoolean(['SuppressTouch', 'タッチ操作抑制']);
    var paramAlwaysCommonInBattle     = getParamBoolean(['AlwaysCommonInBattle', '戦闘中常にコモン実行']);

    //=============================================================================
    // Game_Interpreter
    //  プラグインコマンド[P_CALL_CE]などを追加定義します。
    //=============================================================================
    var _Game_Interpreter_pluginCommand      = Game_Interpreter.prototype.pluginCommand;
    Game_Interpreter.prototype.pluginCommand = function(command, args) {
        _Game_Interpreter_pluginCommand.apply(this, arguments);
        var pictureId, touchParam, trigger, variableNum, transparent;
        switch (getCommandName(command)) {
            case 'P_CALL_CE' :
            case 'ピクチャのボタン化':
                pictureId   = getArgNumber(args[0], 1, $gameScreen.maxPictures());
                touchParam  = getArgNumber(args[1], 1, $dataCommonEvents.length - 1);
                trigger     = getArgNumber(args[2], 1);
                transparent = (args.length > 3 ? getArgBoolean(args[3]) : null);
                $gameScreen.setPictureCallCommon(pictureId, touchParam, trigger, transparent);
                break;
            case 'P_CALL_SWITCH' :
            case 'ピクチャのスイッチ化':
                pictureId   = getArgNumber(args[0], 1, $gameScreen.maxPictures());
                touchParam  = getArgNumber(args[1], 1);
                trigger     = getArgNumber(args[2], 1);
                transparent = (args.length > 3 ? getArgBoolean(args[3]) : null);
                $gameScreen.setPictureCallCommon(pictureId, touchParam * -1, trigger, transparent);
                break;
            case 'P_CALL_KEY_BIND' :
            case 'ピクチャのキーバインド':
                pictureId   = getArgNumber(args[0], 1, $gameScreen.maxPictures());
                touchParam  = convertEscapeCharacters(args[1]).toLowerCase();
                trigger     = getArgNumber(args[2], 1);
                transparent = (args.length > 3 ? getArgBoolean(args[3]) : null);
                $gameScreen.setPictureCallCommon(pictureId, touchParam, trigger, transparent);
                break;
            case 'P_CALL_CE_REMOVE' :
            case 'ピクチャのボタン化解除':
                pictureId = getArgNumber(args[0], 1, $gameScreen.maxPictures());
                $gameScreen.setPictureRemoveCommon(pictureId);
                break;
            case 'P_STROKE' :
            case 'ピクチャのなでなで設定':
                pictureId   = getArgNumber(args[0], 1, $gameScreen.maxPictures());
                variableNum = getArgNumber(args[1], 1, $dataSystem.variables.length - 1);
                $gameScreen.setPictureStroke(pictureId, variableNum);
                break;
            case 'P_STROKE_REMOVE' :
            case 'ピクチャのなでなで解除':
                pictureId = getArgNumber(args[0], 1, $gameScreen.maxPictures());
                $gameScreen.removePictureStroke(pictureId);
                break;
            case 'P_POINTER' :
            case 'ピクチャのポインタ化':
                pictureId = getArgNumber(args[0], 1, $gameScreen.maxPictures());
                $gameScreen.setPicturePointer(pictureId);
                break;
            case 'P_POINTER_REMOVE' :
            case 'ピクチャのポインタ化解除':
                pictureId = getArgNumber(args[0], 1, $gameScreen.maxPictures());
                $gameScreen.removePicturePointer(pictureId);
                break;
        }
    };

    var _Game_Interpreter_terminate      = Game_Interpreter.prototype.terminate;
    Game_Interpreter.prototype.terminate = function() {
        _Game_Interpreter_terminate.apply(this, arguments);
        this._setupFromPicture = false;
    };

    Game_Interpreter.prototype.setupFromPicture = function(eventList) {
        this.setup(eventList, null);
        this._setupFromPicture = true;
    };

    Game_Interpreter.prototype.isSetupFromPicture = function() {
        return this._setupFromPicture;
    };

    //=============================================================================
    // Game_Temp
    //  呼び出し予定のコモンイベントIDのフィールドを追加定義します。
    //=============================================================================
    var _Game_Temp_initialize      = Game_Temp.prototype.initialize;
    Game_Temp.prototype.initialize = function() {
        _Game_Temp_initialize.call(this);
        this.clearPictureCallInfo();
    };

    Game_Temp.prototype.clearPictureCallInfo = function() {
        this.setPictureCallInfo(0);
    };

    Game_Temp.prototype.setPictureCallInfo = function(pictureCommonId) {
        this._pictureCommonId = pictureCommonId;
    };

    Game_Temp.prototype.pictureCommonId = function() {
        return this._pictureCommonId;
    };

    Game_Temp.prototype.onTouchPicture = function(param, pictureId) {
        this._touchPictureParam = param;
        if (this.isTouchPictureSetSwitch()) {
            $gameSwitches.setValue(param * -1, true);
        }
        if (this.isTouchPictureCallCommon()) {
            this.setPictureCallInfo(param);
        }
        if (this.isTouchPictureButtonTrigger()) {
            Input.bindKeyState(param);
        }
        if (paramGameVariablePictNum > 0) {
            $gameVariables.setValue(paramGameVariablePictNum, pictureId);
        }
    };

    Game_Temp.prototype.isTouchPictureButtonTrigger = function() {
        return isNaN(this._touchPictureParam);
    };

    Game_Temp.prototype.isTouchPictureSetSwitch = function() {
        return !isNaN(this._touchPictureParam) && this._touchPictureParam < 0;
    };

    Game_Temp.prototype.isTouchPictureCallCommon = function() {
        return !isNaN(this._touchPictureParam) && this._touchPictureParam > 0;
    };

    //=============================================================================
    // Game_System
    //  ロード時にピクチャ関連メンバを初期化します。
    //=============================================================================
    var _Game_System_onAfterLoad      = Game_System.prototype.onAfterLoad;
    Game_System.prototype.onAfterLoad = function() {
        _Game_System_onAfterLoad.apply(this, arguments);
        $gameScreen.initPictureArray();
    };

    //=============================================================================
    // Game_Map
    //  ピクチャがタッチされたときのコモンイベント呼び出し処理を追加定義します。
    //=============================================================================
    var _Game_Map_setupStartingEvent      = Game_Map.prototype.setupStartingEvent;
    Game_Map.prototype.setupStartingEvent = function() {
        var result = _Game_Map_setupStartingEvent.call(this);
        return result || this.setupPictureCommonEvent();
    };

    Game_Map.prototype.setupPictureCommonEvent = function() {
        var commonId = $gameTemp.pictureCommonId();
        var event    = $dataCommonEvents[commonId];
        var result   = false;
        if (commonId > 0 && !this.isEventRunning() && event) {
            this._interpreter.setupFromPicture(event.list);
            result = true;
        }
        $gameTemp.clearPictureCallInfo();
        return result;
    };

    //=============================================================================
    // Game_Troop
    //  ピクチャがタッチされたときのコモンイベント呼び出し処理を追加定義します。
    //=============================================================================
    Game_Troop.prototype.setupPictureCommonEvent = Game_Map.prototype.setupPictureCommonEvent;

    Game_Troop.prototype.isExistPictureCommon = function() {
        return this._interpreter.isSetupFromPicture();
    };

    //=============================================================================
    // Game_Screen
    //  ピクチャに対応するコモンイベント呼び出し用のID配列を追加定義します。
    //=============================================================================
    var _Game_Screen_initialize      = Game_Screen.prototype.initialize;
    Game_Screen.prototype.initialize = function() {
        _Game_Screen_initialize.apply(this, arguments);
        this.initPictureArray();
    };

    Game_Screen.prototype.initPictureArray = function() {
        this._pictureCidArray         = this._pictureCidArray || [];
        this._pictureSidArray         = this._pictureSidArray || [];
        this._picturePidArray         = this._picturePidArray || [];
        this._pictureTransparentArray = this._pictureTransparentArray || [];
    };

    var _Game_Screen_update      = Game_Screen.prototype.update;
    Game_Screen.prototype.update = function() {
        _Game_Screen_update.apply(this, arguments);
        this.updatePointer();
    };

    Game_Screen.prototype.updatePointer = function() {
        if (paramGameVariableTouchX)
            $gameVariables._data[paramGameVariableTouchX] = TouchInput.x;
        if (paramGameVariableTouchY)
            $gameVariables._data[paramGameVariableTouchY] = TouchInput.y;
    };

    Game_Screen.prototype.setPictureCallCommon = function(pictureId, touchParameter, trigger, transparent) {
        var realPictureId = this.realPictureId(pictureId);
        if (this._pictureCidArray[realPictureId] == null) this._pictureCidArray[realPictureId] = [];
        this._pictureCidArray[realPictureId][trigger] = touchParameter;
        this._pictureTransparentArray[realPictureId]  = transparent;
    };

    Game_Screen.prototype.setPictureRemoveCommon = function(pictureId) {
        this._pictureCidArray[this.realPictureId(pictureId)] = [];
    };

    Game_Screen.prototype.setPictureStroke = function(pictureId, variableNum) {
        this._pictureSidArray[this.realPictureId(pictureId)] = variableNum;
    };

    Game_Screen.prototype.removePictureStroke = function(pictureId) {
        this._pictureSidArray[this.realPictureId(pictureId)] = null;
    };

    Game_Screen.prototype.setPicturePointer = function(pictureId) {
        this._picturePidArray[this.realPictureId(pictureId)] = true;
    };

    Game_Screen.prototype.removePicturePointer = function(pictureId) {
        this._picturePidArray[this.realPictureId(pictureId)] = null;
    };

    Game_Screen.prototype.getPictureCid = function(pictureId) {
        return this._pictureCidArray[this.realPictureId(pictureId)];
    };

    Game_Screen.prototype.getPictureSid = function(pictureId) {
        return this._pictureSidArray[this.realPictureId(pictureId)];
    };

    Game_Screen.prototype.getPicturePid = function(pictureId) {
        return this._picturePidArray[this.realPictureId(pictureId)];
    };

    Game_Screen.prototype.getPictureTransparent = function(pictureId) {
        return this._pictureTransparentArray[this.realPictureId(pictureId)];
    };

    Game_Screen.prototype.disConvertPositionX = function(x) {
        return Math.round((x + this.zoomX() - this.shake()) / this.zoomScale());
    };

    Game_Screen.prototype.disConvertPositionY = function(y) {
        return Math.round((y + this.zoomY()) / this.zoomScale());
    };

    Game_Screen.prototype.disConvertPositionY = function(y) {
        return Math.round((y + this.zoomY()) / this.zoomScale());
    };

    Game_Screen.prototype.isPointerInnerPicture = function(pictureId) {
        var picture = SceneManager.getPictureSprite(pictureId);
        return picture ? picture.isIncludePointer() : false;
    };

    //=============================================================================
    // SceneManager
    //  ピクチャスプライトを取得します。
    //=============================================================================
    SceneManager.getPictureSprite = function(pictureId) {
        return this._scene.getPictureSprite(pictureId);
    };

    //=============================================================================
    // BattleManager
    //  ピクチャコモンを常に実行できるようにします。
    //=============================================================================
    BattleManager.updatePictureCommon = function() {
        if ($gameTroop.isExistPictureCommon() && paramAlwaysCommonInBattle) {
            this.updateEventMain();
            return true;
        }
        return false;
    };

    //=============================================================================
    // Scene_Base
    //  ピクチャに対する繰り返し処理を追加定義します。
    //=============================================================================
    Scene_Base.prototype.updateTouchPictures = function() {
        this._spriteset.iteratePictures(function(picture) {
            if (typeof picture.callTouch === 'function') picture.callTouch();
            return $gameTemp.pictureCommonId() === 0;
        });
    };

    Scene_Base.prototype.getPictureSprite = function(pictureId) {
        var result = null;
        this._spriteset.iteratePictures(function(picture) {
            if (picture.isIdEquals(pictureId)) {
                result = picture;
                return false;
            }
            return true;
        });
        return result;
    };

    //=============================================================================
    // Scene_Map
    //  ピクチャのタッチ状態からのコモンイベント呼び出し予約を追加定義します。
    //=============================================================================
    var _Scene_Map_update      = Scene_Map.prototype.update;
    Scene_Map.prototype.update = function() {
        this.updateTouchPictures();
        _Scene_Map_update.apply(this, arguments);
    };

    var _Scene_Map_processMapTouch      = Scene_Map.prototype.processMapTouch;
    Scene_Map.prototype.processMapTouch = function() {
        _Scene_Map_processMapTouch.apply(this, arguments);
        if ($gameTemp.isDestinationValid() && $gameTemp.pictureCommonId() > 0) {
            $gameTemp.clearDestination();
        }
    };

    //=============================================================================
    // Scene_Battle
    //  ピクチャのタッチ状態からのコモンイベント呼び出し予約を追加定義します。
    //=============================================================================
    var _Scene_Battle_update      = Scene_Battle.prototype.update;
    Scene_Battle.prototype.update = function() {
        this.updateTouchPictures();
        $gameTroop.setupPictureCommonEvent();
        _Scene_Battle_update.apply(this, arguments);
    };

    var _Scene_Battle_updateBattleProcess      = Scene_Battle.prototype.updateBattleProcess;
    Scene_Battle.prototype.updateBattleProcess = function() {
        var result = BattleManager.updatePictureCommon();
        if (result) return;
        _Scene_Battle_updateBattleProcess.apply(this, arguments);
    };

    //=============================================================================
    // Spriteset_Base
    //  ピクチャに対するイテレータを追加定義します。
    //=============================================================================
    Spriteset_Base.prototype.iteratePictures = function(callBackFund) {
        var containerChildren = this._pictureContainer.children;
        if (!Array.isArray(containerChildren)) {
            iterate(this._pictureContainer, function(property) {
                if (this._pictureContainer[property].hasOwnProperty('children')) {
                    containerChildren = this._pictureContainer[property].children;
                    this._iteratePicturesSub(containerChildren, callBackFund);
                }
            }.bind(this));
        } else {
            this._iteratePicturesSub(containerChildren, callBackFund);
        }
    };

    Spriteset_Base.prototype._iteratePicturesSub = function(containerChildren, callBackFund) {
        for (var i = containerChildren.length - 1; i >= 0; i--) {
            if (!callBackFund(containerChildren[i])) {
                break;
            }
        }
    };

    //=============================================================================
    // Sprite_Picture
    //  ピクチャのタッチ状態からのコモンイベント呼び出し予約を追加定義します。
    //=============================================================================
    var _Sprite_Picture_initialize      = Sprite_Picture.prototype.initialize;
    Sprite_Picture.prototype.initialize = function(pictureId) {
        _Sprite_Picture_initialize.call(this, pictureId);
        this._triggerHandler     = [];
        this._triggerHandler[1]  = this.isTriggered;
        this._triggerHandler[2]  = this.isCancelled;
        this._triggerHandler[3]  = this.isLongPressed;
        this._triggerHandler[4]  = this.isOnFocus;
        this._triggerHandler[5]  = this.isOutFocus;
        this._triggerHandler[6]  = this.isReleased;
        this._triggerHandler[7]  = this.isRepeated;
        this._triggerHandler[8]  = this.isPressed;
        this._triggerHandler[9]  = this.isWheelTriggered;
        this._triggerHandler[10] = this.isDoubleTriggered;
        this._triggerHandler[11] = this.isMoved;
        this._triggerHandler[12] = this.isMovedAndPressed;
        this._onMouse            = false;
        this._outMouse           = false;
        this._wasOnMouse         = false;
    };

    var _Sprite_update              = Sprite_Picture.prototype.update;
    Sprite_Picture.prototype.update = function() {
        _Sprite_update.apply(this, arguments);
        this.updateMouseMove();
        this.updateStroke();
        this.updatePointer();
    };

    Sprite_Picture.prototype.updateMouseMove = function() {
        if (this.isIncludePointer()) {
            if (!this._wasOnMouse) {
                this._onMouse    = true;
                this._wasOnMouse = true;
            }
        } else {
            if (this._wasOnMouse) {
                this._outMouse   = true;
                this._wasOnMouse = false;
            }
        }
    };

    Sprite_Picture.prototype.isIncludePointer = function() {
        return this.isTouchable() && this.isTouchPosInRect() && !this.isTransparent();
    };

    Sprite_Picture.prototype.updateStroke = function() {
        var strokeNum = $gameScreen.getPictureSid(this._pictureId);
        if (strokeNum > 0 && TouchInput.isPressed()) {
            var value = $gameVariables.value(strokeNum);
            $gameVariables.setValue(strokeNum, value + TouchInput.pressedDistance);
        }
    };

    Sprite_Picture.prototype.updatePointer = function() {
        var strokeNum = $gameScreen.getPicturePid(this._pictureId);
        if (strokeNum > 0) {
            this.opacity  = TouchInput.isPressed() ? 255 : 0;
            this.x        = TouchInput.x;
            this.y        = TouchInput.y;
            this.anchor.x = 0.5;
            this.anchor.y = 0.5;
        }
    };

    Sprite_Picture.prototype.callTouch = function() {
        var commandIds = $gameScreen.getPictureCid(this._pictureId);
        if (!commandIds) return;
        for (var i = 0, n = this._triggerHandler.length; i < n; i++) {
            var handler = this._triggerHandler[i];
            if (handler && commandIds[i] && handler.call(this) && (this.triggerIsFocus(i) || !this.isTransparent())) {
                this.fireTouchEvent(commandIds, i);
            }
        }
    };

    Sprite_Picture.prototype.fireTouchEvent = function(commandIds, i) {
        if (paramSuppressTouch) TouchInput.suppressEvents();
        if (this.triggerIsLongPressed(i)) TouchInput._pressedTime = -60;
        if (this.triggerIsOnFocus(i)) this._onMouse = false;
        if (this.triggerIsOutFocus(i)) this._outMouse = false;
        $gameTemp.onTouchPicture(commandIds[i], this._pictureId);
    };

    Sprite_Picture.prototype.triggerIsLongPressed = function(triggerId) {
        return triggerId === 3;
    };

    Sprite_Picture.prototype.triggerIsOnFocus = function(triggerId) {
        return triggerId === 4;
    };

    Sprite_Picture.prototype.triggerIsOutFocus = function(triggerId) {
        return triggerId === 5;
    };

    Sprite_Picture.prototype.triggerIsFocus = function(triggerId) {
        return this.triggerIsOnFocus(triggerId) || this.triggerIsOutFocus(triggerId);
    };

    Sprite_Picture.prototype.isTransparent = function() {
        if (this.isTouchPosInFrameWindow()) return false;
        if (!this.isValidTransparent()) return false;
        if (this.opacity === 0) return true;
        var dx  = this.getTouchScreenX() - this.x;
        var dy  = this.getTouchScreenY() - 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_Picture.prototype.isValidTransparent = function() {
        var transparent = $gameScreen.getPictureTransparent(this._pictureId);
        return transparent !== null ? transparent : paramTransparentConsideration;
    };

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

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

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

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

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

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

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

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

    Sprite_Picture.prototype.isTouchPosInRect = function() {
        if (this.isTouchPosInFrameWindow()) return true;
        var dx  = this.getTouchScreenX() - this.x;
        var dy  = this.getTouchScreenY() - 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_Picture.prototype.isTouchPosInFrameWindow = function() {
        if (!this._frameWindow) return false;
        var frame = this._frameWindow;
        var x  = this.getTouchScreenX();
        var y  = this.getTouchScreenY();
        return frame.x <= x && frame.x + frame.width >= x && frame.y <= y && frame.y + frame.height >= y;
    };

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

    Sprite_Picture.prototype.isTriggered = function() {
        return this.isTouchEvent(TouchInput.isTriggered);
    };

    Sprite_Picture.prototype.isCancelled = function() {
        return this.isTouchEvent(TouchInput.isCancelled);
    };

    Sprite_Picture.prototype.isLongPressed = function() {
        return this.isTouchEvent(TouchInput.isLongPressed);
    };

    Sprite_Picture.prototype.isPressed = function() {
        return this.isTouchEvent(TouchInput.isPressed);
    };

    Sprite_Picture.prototype.isReleased = function() {
        return this.isTouchEvent(TouchInput.isReleased);
    };

    Sprite_Picture.prototype.isRepeated = function() {
        return this.isTouchEvent(TouchInput.isRepeated);
    };

    Sprite_Picture.prototype.isOnFocus = function() {
        return this._onMouse;
    };

    Sprite_Picture.prototype.isOutFocus = function() {
        return this._outMouse;
    };

    Sprite_Picture.prototype.isMoved = function() {
        return this.isTouchEvent(TouchInput.isMoved);
    };

    Sprite_Picture.prototype.isMovedAndPressed = function() {
        return this.isTouchEvent(TouchInput.isMoved) && TouchInput.isPressed();
    };

    Sprite_Picture.prototype.isWheelTriggered = function() {
        return this.isTouchEvent(TouchInput.isWheelTriggered);
    };

    Sprite_Picture.prototype.isDoubleTriggered = function() {
        return this.isTouchEvent(TouchInput.isDoubleTriggered);
    };

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

    Sprite_Picture.prototype.getTouchScreenX = function() {
        return $gameScreen.disConvertPositionX(TouchInput.x);
    };

    Sprite_Picture.prototype.getTouchScreenY = function() {
        return $gameScreen.disConvertPositionY(TouchInput.y);
    };

    Sprite_Picture.prototype.isIdEquals = function(pictureId) {
        return this._pictureId === pictureId;
    };

    //=============================================================================
    // Input
    //  ピクチャクリックをキー入力に紐付けます。
    //=============================================================================
    Input._bindKeyStateFrames = new Map();
    Input.bindKeyState        = function(name) {
        this._currentState[name] = true;
        this._bindKeyStateFrames.set(name, 5);
    };

    var _Input_update = Input.update;
    Input.update      = function() {
        _Input_update.apply(this, arguments);
        this._updateBindKeyState();
    };

    Input._updateBindKeyState = function() {
        this._bindKeyStateFrames.forEach(function(frame, keyName) {
            frame--;
            if (frame === 0 || !this._currentState[keyName]) {
                this._currentState[keyName] = false;
                this._bindKeyStateFrames.delete(keyName);
            } else {
                this._bindKeyStateFrames.set(keyName, frame);
            }
        }, this)
    };

    //=============================================================================
    // TouchInput
    //  ホイールクリック、ダブルクリック等を実装
    //=============================================================================
    TouchInput.keyDoubleClickInterval = 300;
    TouchInput._pressedDistance       = 0;
    TouchInput._prevX                 = -1;
    TouchInput._prevY                 = -1;

    Object.defineProperty(TouchInput, 'pressedDistance', {
        get         : function() {
            return this._pressedDistance;
        },
        configurable: true
    });

    TouchInput.suppressEvents = function() {
        this._triggered       = false;
        this._cancelled       = false;
        this._released        = false;
        this._wheelTriggered  = false;
        this._doubleTriggered = false;
    };

    TouchInput._onMouseMove = function(event) {
        var x = Graphics.pageToCanvasX(event.pageX);
        var y = Graphics.pageToCanvasY(event.pageY);
        this._onMove(x, y);
    };

    var _TouchInput_clear = TouchInput.clear;
    TouchInput.clear      = function() {
        _TouchInput_clear.apply(this, arguments);
        this._events.wheelTriggered  = false;
        this._events.doubleTriggered = false;
    };

    var _TouchInput_update = TouchInput.update;
    TouchInput.update      = function() {
        _TouchInput_update.apply(this, arguments);
        this._wheelTriggered         = this._events.wheelTriggered;
        this._doubleTriggered        = this._events.doubleTriggered;
        this._events.wheelTriggered  = false;
        this._events.doubleTriggered = false;
    };

    TouchInput.isWheelTriggered = function() {
        return this._wheelTriggered;
    };

    TouchInput.isDoubleTriggered = function() {
        return this._doubleTriggered;
    };

    var _TouchInput_onMiddleButtonDown = TouchInput._onMiddleButtonDown;
    TouchInput._onMiddleButtonDown     = function(event) {
        _TouchInput_onMiddleButtonDown.apply(this, arguments);
        var x = Graphics.pageToCanvasX(event.pageX);
        var y = Graphics.pageToCanvasY(event.pageY);
        if (Graphics.isInsideCanvas(x, y)) {
            this._onWheelTrigger(x, y);
        }
    };

    TouchInput._onWheelTrigger = function(x, y) {
        this._events.wheelTriggered = true;
        this._x                     = x;
        this._y                     = y;
    };

    var _TouchInput_onTrigger = TouchInput._onTrigger;
    TouchInput._onTrigger     = function(x, y) {
        if (this._date && Date.now() - this._date < this.keyDoubleClickInterval)
            this._events.doubleTriggered = true;
        this._pressedDistance = 0;
        this._prevX           = x;
        this._prevY           = y;
        _TouchInput_onTrigger.apply(this, arguments);
    };

    var _TouchInput_onMove = TouchInput._onMove;
    TouchInput._onMove     = function(x, y) {
        if (this.isPressed()) this._pressedDistance = Math.abs(this._prevX - x) + Math.abs(this._prevY - y);
        this._prevX = x;
        this._prevY = y;
        _TouchInput_onMove.apply(this, arguments);
    };

    var _TouchInput_onRelease = TouchInput._onRelease;
    TouchInput._onRelease     = function(x, y) {
        this._pressedDistance = 0;
        this._prevX           = x;
        this._prevY           = y;
        _TouchInput_onRelease.apply(this, arguments);
    };
})();