code:
//=============================================================================
// SAN_ExtendedEventPage.js
//=============================================================================
// Copyright (c) 2016-2018 Sanshiro
// Released under the MIT license
// http://opensource.org/licenses/mit-license.php
//=============================================================================
// GitHub  https://github.com/rev2nym
// Twitter https://twitter.com/rev2nym
//=============================================================================

/*:
 * @plugindesc 拡張イベントページ制御 ver1.1.0
 * 任意のイベントページの出現条件と出現時処理を設定します。
 * @author Sanshiro https://twitter.com/rev2nym
 * @help
 * ■概要
 * イベントページの制御を拡張します。
 * イベントコマンド「注釈」によって
 * 任意のイベントページの出現条件と出現時処理を設定します。
 *
 * ■書式
 * イベントページの先頭にイベントコマンド「注釈」を以下の書式で記述します。
 *
 * <SAN_ExtendedEventPage:{
 *   "trigger":"「出現条件のスクリプト」",
 *   "handler":"「出現時処理のスクリプト」"
 * }>
 *
 * "trigger"要素と"handler"要素はいずれも省略可能です。
 * ただしカンマの有無に注意してください。
 * また記号", <, >は使用できません。
 *
 * ■出現条件の拡張
 * 前述の書式に従って条件式のスクリプト記述してください。
 * 例えば次の記述は出現条件「変数1が5のとき」を表します。
 *
 * <SAN_ExtendedEventPage:{
 *   "trigger":"$gameVariables.value(1) === 5"
 * }>
 *
 * なお"trigger"要素が設定されている場合
 * 通常のイベントページの出現条件は無視されます。
 *
 * ■出現時処理の設定
 * 前述の書式に従って出現時処理のスクリプト記述してください。
 * 例えば次の記述で「このイベントを左90度回転」を表します。
 *
 * <SAN_ExtendedEventPage:{
 *   "handler":"this.turnLeft90()"
 * }>
 *
 * ■利用規約
 * MITライセンスのもと、商用利用、改変、再配布が可能です。
 * ただし冒頭のコメントは削除や改変をしないでください。
 * これを利用したことによるいかなる損害にも作者は責任を負いません。
 * サポートは期待しないでください＞＜。
 */

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

var Sanshiro = Sanshiro || {};
Sanshiro.ExtendedEventPage = Sanshiro.ExtendedEventPage || {};
Sanshiro.ExtendedEventPage.version = '1.1.0';

(function () {
    'use strict';

    //-----------------------------------------------------------------------------
    // Game_Event
    //
    // イベント

    // メンバ変数の初期化
    var _Game_Event_initMembers =
        Game_Event.prototype.initMembers;
    Game_Event.prototype.initMembers = function () {
        _Game_Event_initMembers.call(this);
        this._exTriggres = []; // 拡張イベントページ出現条件
        this._exHandlers = []; // 拡張イベントページ出現時処理
    };

    // リフレッシュ
    var _Game_Event_refresh =
        Game_Event.prototype.refresh;
    Game_Event.prototype.refresh = function () {
        this.setupExtendedEventPage();
        _Game_Event_refresh.call(this);
    };

    // 拡張イベントページのセットアップ
    Game_Event.prototype.setupExtendedEventPage = function () {
        this.event().pages.forEach(
            function (page, pageIndex) {
                var parameters = this.extractExtendedEventPageParameters(page);
                if (!parameters) {
                    return;
                }
                if (!!parameters.trigger) {
                    var trigger = new Function('return ' + parameters.trigger);
                    this._exTriggres[pageIndex] = trigger;
                }
                if (!!parameters.handler) {
                    var handler = new Function('return ' + parameters.handler);
                    this._exHandlers[pageIndex] = handler;
                }
            }, this
        );
    };

    // 拡張イベントページパラメータの抽出
    Game_Event.prototype.extractExtendedEventPageParameters = function (page) {
        var comment = this.extractPageHeaderComment(page);
        if (!comment) {
            return null;
        }
        var data = this.extractPageMetadata(comment);
        if (!data || !data.meta.SAN_ExtendedEventPage) {
            return null;
        }
        var json = data.meta.SAN_ExtendedEventPage;
        var parameters = JSON.parse(json);
        return parameters;
    };

    // ページ先頭コメントの抽出
    Game_Event.prototype.extractPageHeaderComment = function (page) {
        var comment = "";
        var commandIndex = 0;
        while (this.isCommentCommand(page.list[commandIndex])) {
            comment += page.list[commandIndex].parameters[0];
            commandIndex++;
        }
        return comment;
    };

    // コメントコマンド判定
    Game_Event.prototype.isCommentCommand = function (command) {
        return !!command && (
            command.code === 108 ||
            command.code === 408
        );
    };

    // メタデータの抽出
    Game_Event.prototype.extractPageMetadata = function (note) {
        var data = {
            note: note,
            meta: undefined
        };
        DataManager.extractMetadata(data);
        return data;
    };

    // ページ出現条件合致判定
    var _Game_Event_meetsConditions =
        Game_Event.prototype.meetsConditions;
    Game_Event.prototype.meetsConditions = function (page) {
        var pageIndex = this.event().pages.indexOf(page);
        var trigger = this._exTriggres[pageIndex];
        if (!!trigger) {
            return trigger.call(this);
        } else {
            return _Game_Event_meetsConditions.call(this, page);
        }
    };

    // イベントページ設定のセットアップ
    var _Game_Event_setupPageSettings =
        Game_Event.prototype.setupPageSettings;
    Game_Event.prototype.setupPageSettings = function () {
        _Game_Event_setupPageSettings.call(this);
        var handler = this._exHandlers[this._pageIndex];
        if (!!handler) {
            handler.call(this);
        }
    };

})();

repo_name: dazed/translations

license: unknown


code:
//=============================================================================
// SAN_MapGenerator.js
//=============================================================================
// Copyright (c) 2015 Sanshiro
// Released under the MIT license
// http://opensource.org/licenses/mit-license.php
//=============================================================================

/*:
 * @plugindesc SAN_MapGenerator ver1.11
 * Generate map and allocate events automatically.
 * @author Sanshiro https://twitter.com/rev2nym
 *
 * @help
 * When the plugin command is called, the map is generated
 * and the player moves to position of start(entrance) event.
 *
 * Set following tiles and events in a position on the base map.
 *
 * -Tiles
 *   space :{x:0, y:0}
 *   room  :{x:0, y:1}
 *   pass  :{x:0, y:2}
 *   roof  :{x:0, y:3}
 *   wall  :{x:0, y:4}
 *   rubble:{x:0, y:5}
 *
 * -Events
 *   start:{x:1, y:0}
 *   goal :{x:1, y:1}
 *   other:other position than above
 *
 * Appearance rate can be set as events besides the start and the goal.
 * Set as the following on a memo space of events.
 * The event which has no setting of the appearance rate isn't generated.
 *
 * -Appearance rate
 *   each map :<RateMap: [Positive small number of less than 1.0]>
 *   each room:<RateRoom:[Positive small number of less than 1.0]>
 *
 * -Plugin Command
 *   MapGenerator RoomAndPass # Generate map consists of rooms and passes.
 *   MapGenerator FillRoom    # Generate map consists of a room whole the map.
 *
 * It's possible to commercial use, distribute, and modify under the MIT license.
 * But, don't eliminate and don't alter a comment of the beginning.
 * If it's good, please indicate an author name on credit.
 *
 * Author doesn't shoulder any responsibility in all kind of damage by using this.
 * And please don't expect support. X(
 *
 * @param WallHight
 * @desc Set wall height. (1-3)
 * @default 1
 *
 * @param MinRoomSize
 * @desc Set minimum room size. (3-)
 * @default 3
 *
 * @param MaxRoomSize
 * @desc Set maximum room size. (3-)
 * If less than MinRoomSize, it make MaxRoomSize same as MinRoomSize.
 * @default 3
 *
 * @param ShowOuterWall
 * @desc Show outer wall. ('ON' is valid)
 * @default ON
 */

/*:ja
 * @plugindesc 自動マップ生成 ver1.11
 * 自動的にマップを生成しイベントを配置します。
 * @author サンシロ https://twitter.com/rev2nym
 * @version 1.11 2016/04/05 稀に壁をすり抜ける不具合を修正、通行判定機能を強化。
 * 1.10 2016/03/19 壁の高さ、部屋の大きさ、外壁表示を指定するプラグインパラメータを追加、 壁を表示するスペースを確保するよう部屋と通路の生成規則を変更。
 * 1.00a 2015/12/19 ヘルプ文書のイベントメモ欄設定の誤りを修正。
 * 1.00 2015/11/29 公開
 *
 * @help
 * プラグインコマンドを実行するとマップが生成され
 * プレイヤーが入口イベントの地点に移動します。
 *
 * ベースとなるマップの座標に下記のタイルとイベントをそれぞれ配置して下さい。
 * ・タイル
 *  空白:{x:0, y:0}
 *  部屋:{x:0, y:1}
 *  通路:{x:0, y:2}
 *  天井:{x:0, y:3}
 *  壁　:{x:0, y:4}
 *  瓦礫:{x:0, y:5}
 *
 * ・イベント
 *  入口:{x:1, y:0}
 *  出口:{x:1, y:1}
 *  他　:上記以外の座標
 *
 * 入口と出口以外のイベントには出現率を設定できます。
 * イベントのメモ欄に下記を記載して下さい。
 * 出現率設定がないイベント生成されません。
 *
 * ・イベント出現率
 *  マップ毎の出現率:<RateMap: [1.0以下の正の小数]>
 *  部屋毎の出現率　:<RateRoom:[1.0以下の正の小数]>
 *
 * ・プラグインコマンド
 * MapGenerator RoomAndPass # 部屋と通路から構成されるマップを生成します。
 * MapGenerator FillRoom    # マップ全体に及ぶ一つの部屋を生成します。
 *
 * MITライセンスのもと、商用利用、改変、再配布が可能です。
 * ただし冒頭のコメントは削除や改変をしないでください。
 * よかったらクレジットに作者名を記載してください。
 *
 * これを利用したことによるいかなる損害にも作者は責任を負いません。
 * サポートは期待しないでください＞＜。
 *
 * @param WallHight
 * @desc 壁の高さを指定します。（1～3）
 * @default 1
 *
 * @param MinRoomSize
 * @desc 部屋の大きさの最小値を指定します。（3～）
 * @default 5
 *
 * @param MaxRoomSize
 * @desc 部屋の大きさの最大値を指定します。（3～）
 * MaxRoomSizeがMinRoomSizeより小さい場合、MinRoomSizeと同じ値に補正されます。
 * @default 10
 *
 * @param ShowOuterWall
 * @desc 部屋の外側の壁を表示します。（ONで有効）
 * @default ON
 */

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

var Sanshiro = Sanshiro || {};
Sanshiro.Game_MapGenerator = Sanshiro.Game_MapGenerator || {};

//-----------------------------------------------------------------------------
// Game_MapGenerator
//
// マップジェネレーター（大部屋）

function Game_MapGenerator() {
    this.initialize();
}

// オートタイル解析タイルidリスト
//   tileIdsFloor : 床
//   tileIdsWall  : 壁
//   candidate    : 候補タイル ID
//   connect      : 接続タイル ID
//   noConnect    : 非接続タイル ID
Game_MapGenerator.tileIdsFloor = {};

Game_MapGenerator.tileIdsFloor.candidate =
    [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11,
        12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23,
        24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35,
        36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47];

Game_MapGenerator.tileIdsFloor.connect = {
    1: [0, 1, 2, 3, 4, 5, 6, 7, 16, 17, 18, 19,
        20, 21, 24, 26, 28, 29, 30, 31, 32, 33, 34, 35,
        36, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47],         // 1:左下
    2: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11,
        12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23,
        24, 25, 26, 27, 32, 34, 35, 36, 37, 42, 47],         // 2:下
    3: [0, 1, 2, 3, 8, 9, 10, 11, 16, 17, 20, 22,
        24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 36,
        37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47],         // 3:右下
    4: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11,
        12, 13, 14, 15, 20, 21, 22, 23, 24, 25, 26, 27,
        28, 29, 30, 31, 33, 36, 37, 38, 39, 45, 47],         // 4:左
    6: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11,
        12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23,
        28, 29, 30, 31, 33, 34, 35, 40, 41, 43, 47],         // 6:右
    7: [0, 2, 4, 6, 8, 10, 12, 14, 16, 17, 18, 19,
        20, 21, 22, 23, 24, 25, 28, 30, 32, 33, 34, 35,
        36, 37, 38, 40, 41, 42, 43, 44, 45, 46, 47],         // 7:左上
    8: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11,
        12, 13, 14, 15, 16, 17, 18, 19, 24, 25, 26, 27,
        28, 29, 30, 31, 32, 38, 39, 40, 41, 44, 47],         // 8:上
    9: [0, 1, 4, 5, 8, 9, 12, 13, 16, 18, 20, 21,
        22, 23, 24, 25, 26, 27, 28, 29, 32, 33, 34, 35,
        36, 37, 38, 39, 40, 42, 43, 44, 45, 46, 47]          // 9:右上
};

Game_MapGenerator.tileIdsFloor.noConnect = {
    1: [8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
        22, 23, 25, 27, 28, 29, 30, 31, 32, 33, 34, 35,
        37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47],         // 1:左下
    2: [28, 29, 30, 31, 33, 38, 39, 40, 41, 43, 44, 45, 46], // 2:下
    3: [4, 5, 6, 7, 12, 13, 14, 15, 18, 19, 21, 23,
        24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 35, 36,
        37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47],         // 3:右下
    4: [16, 17, 18, 19, 32, 34, 35, 40, 41, 42, 43, 44, 46], // 4:左
    6: [24, 25, 26, 27, 32, 36, 37, 38, 39, 42, 44, 45, 46], // 6:右
    7: [1, 3, 5, 7, 9, 11, 13, 15, 16, 17, 18, 19,
        20, 21, 22, 23, 26, 27, 29, 31, 32, 33, 34, 35,
        36, 37, 39, 40, 41, 42, 43, 44, 45, 46, 47],         // 7:左上
    8: [20, 21, 22, 23, 33, 34, 35, 36, 37, 42, 43, 45, 46], // 8:上
    9: [2, 3, 6, 7, 10, 11, 14, 15, 17, 19, 20, 21,
        22, 23, 24, 25, 26, 27, 30, 31, 32, 33, 34, 35,
        36, 37, 38, 39, 41, 42, 43, 44, 45, 46, 47]          // 9:右上
};

Game_MapGenerator.tileIdsWall = {};

Game_MapGenerator.tileIdsWall.candidate =
    [0, 1, 2, 3, 4, 5, 6, 7,
        8, 9, 10, 11, 12, 13, 14, 15];

Game_MapGenerator.tileIdsWall.connect = {
    2: [0, 1, 2, 3, 4, 5, 6, 7],  // 2:下
    4: [0, 2, 4, 6, 8, 10, 12, 14],  // 4:左
    6: [0, 1, 2, 3, 8, 9, 10, 11],  // 6:右
    8: [0, 1, 4, 5, 8, 9, 12, 13]   // 8:上
};

Game_MapGenerator.tileIdsWall.noConnect = {
    2: [8, 9, 10, 11, 12, 13, 14, 15],  // 2:下
    4: [1, 3, 5, 7, 9, 11, 13, 15],  // 4:左
    6: [4, 5, 6, 7, 12, 13, 14, 15],  // 6:右
    8: [2, 3, 6, 7, 10, 11, 14, 15]   // 8:上
};

// 初期化
Game_MapGenerator.prototype.initialize = function () {
    this._wallHeight = Number(PluginManager.parameters('SAN_MapGenerator')['WallHight']);
    this._showOuterWall = (PluginManager.parameters('SAN_MapGenerator')['ShowOuterWall'] === 'ON');
    this._startXY = { x: 0, y: 0 };
    this._goalXY = { x: 0, y: 0 };
    this._blocks = [];
    this._rooms = [];
    this._passes = [];
    this._data = [];
    this._isReady = false;
};

// マップ生成
Game_MapGenerator.prototype.setup = function () {
    $gameMap._events = [];
    for (key in $gameSelfSwitches._data) {
        if (key.split(",")[0] === String($gameMap.mapId())) {
            delete $gameSelfSwitches._data[key];
        }
    }
    this._isReady = false;
    this._blocks = [];
    this._rooms = [];
    this._passes = [];
    this._startXY = { x: 0, y: 0 };
    this._goalXY = { x: 0, y: 0 };
    this._data = [];
    this.initSymbolTable();
    this.initSymbolMap();
    this.generateMap();
    this.refreshWallAndRoof();
    this.makeData();
    this.setStart();
    this.setGoal();
    this.setRateEvents();
    SceneManager._scene.createDisplayObjects();
    this._isReady = true;
}

// シンボル定義表の初期化
Game_MapGenerator.prototype.initSymbolTable = function () {
    // シンボル定義
    //  refXY      : シンボルに対応するタイルのツクールのマップ上の座標
    //  baseTileId : シンボルに対応するタイル ID
    //  dispChar   : 生成したマップを文字列として表示する際の文字
    this._symbolTable = {
        player: { refXY: { x: 0, y: 0 }, baseTileId: [], dispChar: '＠', passable: ['room', 'pass'] },
        space: { refXY: { x: 0, y: 0 }, baseTileId: [], dispChar: '　', passable: ['space'] },
        room: { refXY: { x: 0, y: 1 }, baseTileId: [], dispChar: '□', passable: ['room', 'pass'] },
        pass: { refXY: { x: 0, y: 2 }, baseTileId: [], dispChar: '■', passable: ['room', 'pass'] },
        roof: { refXY: { x: 0, y: 3 }, baseTileId: [], dispChar: '＃', passable: ['roof'] },
        wall: { refXY: { x: 0, y: 4 }, baseTileId: [], dispChar: '＝', passable: [] },
        rubble: { refXY: { x: 0, y: 5 }, baseTileId: [], dispChar: '＊', passable: [] },
        start: { refXY: { x: 1, y: 0 }, baseTileId: [], dispChar: '△', passable: ['room', 'pass'] },
        goal: { refXY: { x: 1, y: 1 }, baseTileId: [], dispChar: '▽', passable: ['room', 'pass'] }//,
        //  fence:  {refXY:{x:0, y:6}, baseTileId:[], dispChar:'只'},
        //  pond:   {refXY:{x:0, y:7}, baseTileId:[], dispChar:'○'},
        //  hole:   {refXY:{x:0, y:8}, baseTileId:[], dispChar:'●'},
        //  brink:  {refXY:{x:0, y:9}, baseTileId:[], dispChar:'＾'},
        //  enemy:  {refXY:{x:1, y:2}, baseTileId:[], dispChar:'＄'},
        //  crawler:{refXY:{x:0, y:1}, baseTileId:[], dispChar:'＆'}
    };
    for (symbol in this._symbolTable) {
        var x = this._symbolTable[symbol].refXY.x;
        var y = this._symbolTable[symbol].refXY.y;
        for (var z = 0; z < 6; z++) {
            // z0:タイルA下層, z1:タイルA上層, z2:タイルB下層, z3:タイルB上層, z4:影, z5:リージョン
            this._symbolTable[symbol].baseTileId[z] = this.baseAutoTileId(x, y, z);
        }
    }
};

// オートタイルタイルの基点タイルID
Game_MapGenerator.prototype.baseAutoTileId = function (x, y, z) {
    if ($gameMap.tileId(x, y, z) >= Tilemap.TILE_ID_A1) {
        return (Math.floor(($gameMap.tileId(x, y, z) - Tilemap.TILE_ID_A1) / 48)) * 48 + Tilemap.TILE_ID_A1;
    } else {
        return $gameMap.tileId(x, y, z);
    }
};

// シンボルで表現されるマップの初期化（初期化時はスペースで埋める）
Game_MapGenerator.prototype.initSymbolMap = function () {
    this._symbolMap = new Array($gameMap.width());
    for (var x = 0; x < $gameMap.width(); x++) {
        this._symbolMap[x] = new Array($gameMap.height());
        for (var y = 0; y < $gameMap.height(); y++) {
            this._symbolMap[x][y] = 'space';
        }
    }
};

// シンボルによる通行可能判定
Game_MapGenerator.prototype.isPassable = function (x, y, d) {
    var x2 = $gameMap.roundXWithDirection(x, d);
    var y2 = $gameMap.roundYWithDirection(y, d);
    if (!this._symbolMap[x] || !this._symbolMap[x][y] ||
        !this._symbolMap[x2] || !this._symbolMap[x2][y2]) {
        return false;
    }
    var symbol = this._symbolMap[x][y];
    var symbol2 = this._symbolMap[x2][y2];
    return this._symbolTable[symbol].passable.contains(symbol2);
}

// シンボルによる地面判定
Game_MapGenerator.prototype.isGround = function (x, y) {
    if (!this._symbolMap[x] || !this._symbolMap[x][y]) {
        return false;
    }
    return ['room', 'pass', 'start', 'goal'].indexOf(this._symbolMap[x][y]) !== -1;
};

// シンボルマップ生成
Game_MapGenerator.prototype.generateMap = function () {
    var room = { x: 0, y: 0, w: 0, h: 0 };
    room.x = 1;
    room.y = 1 + this._wallHeight;
    room.w = $dataMap.width - 2;
    room.h = $dataMap.height - (this._wallHeight + 1) * 2;
    for (var oX = 0; oX < room.w; oX++) {
        for (var oY = 0; oY < room.h; oY++) {
            this._symbolMap[oX + room.x][oY + room.y] = 'room';
        }
    }
    this._rooms.push(room);
}

// イベントの設置
Game_MapGenerator.prototype.setEvent = function (event, targetSymbols, targetArea) {
    targetSymbols = targetSymbols || ['room'];
    targetArea = targetArea || { x: 0, y: 0, w: $dataMap.width, h: $dataMap.height };
    var canSet = false;
    for (var x = targetArea.x; x < targetArea.x + targetArea.w && !canSet; x++) {
        for (var y = targetArea.y; y < targetArea.y + targetArea.h && !canSet; y++) {
            canSet = (targetSymbols.indexOf(this._symbolMap[x][y]) !== -1);
        }
    }
    if (canSet) {
        for (var i = 0; i < Math.pow(targetArea.w * targetArea.h, 2); i++) {
            var x = targetArea.x + Math.randomInt(targetArea.w);
            var y = targetArea.y + Math.randomInt(targetArea.h);
            if ($gameMap.eventsXy(x, y).length === 0 &&
                targetSymbols.indexOf(this._symbolMap[x][y]) !== -1) {
                break;
            }
        }
        $gameMap._events.push(event);
        event._eventId = $gameMap._events.indexOf(event);
        event.setPosition(x, y);
        return { x: x, y: y }
    } else {
        return undefined;
    }
};

// 座標によるイベントデータの配列
Game_MapGenerator.prototype.dataMapEventsXy = function (x, y) {
    return $dataMap.events.filter(function (event) {
        return (!!event && event.x === x && event.y === y);
    }, this);
};

// スタート地点イベントの設置
Game_MapGenerator.prototype.setStart = function () {
    var refXY = this._symbolTable['start'].refXY;
    var event = new Game_Event($gameMap.mapId(), this.dataMapEventsXy(refXY.x, refXY.y)[0].id);
    this._startXY = this.setEvent(event);
    $gamePlayer.locate(this._startXY.x, this._startXY.y);
    $gamePlayer.reserveTransfer($gameMap.mapId(), this._startXY.x, this._startXY.y);
    $gameMap._interpreter.setWaitMode('transfer')
};

// ゴール地点イベントの設置
Game_MapGenerator.prototype.setGoal = function () {
    var refXY = this._symbolTable['goal'].refXY;
    var event = new Game_Event($gameMap.mapId(), this.dataMapEventsXy(refXY.x, refXY.y)[0].id);
    this._goalXY = this.setEvent(event);
};

// 確率イベントの設置
Game_MapGenerator.prototype.setRateEvents = function () {
    var mapDataRateMapEvents = $dataMap.events.filter(function (event) {
        return !!event && !!event.meta.RateMap;
    });
    mapDataRateMapEvents.forEach(function (mapDataEvent) {
        if (this.randBool(parseFloat(mapDataEvent.meta.RateMap))) {
            var event = new Game_Event($gameMap.mapId(), mapDataEvent.id);
            this.setEvent(event);
        }
    }, this);
    var mapDataRateRoomEvents = $dataMap.events.filter(function (event) {
        return !!event && !!event.meta.RateRoom;
    });
    mapDataRateRoomEvents.forEach(function (mapDataEvent) {
        this._rooms.forEach(function (room) {
            if (this.randBool(parseFloat(mapDataEvent.meta.RateRoom))) {
                var event = new Game_Event($gameMap.mapId(), mapDataEvent.id);
                this.setEvent(event, 'room', room);
            }
        }, this);
    }, this);
};

//ランダムブール
//probability : true が返る確立
Game_MapGenerator.prototype.randBool = function (probability) {
    return Math.random() < probability;
};

// シンボルマップの壁と天井を設置：マップ全体
// 床と通路だけのシンボルマップに壁と天井を追加する
Game_MapGenerator.prototype.refreshWallAndRoof = function () {
    for (var x = 0; x < this._symbolMap.length; x++) {
        for (var y = 0; y < this._symbolMap[x].length; y++) {
            if (!this.isGround(x, y)) {
                continue;
            }
            this.refreshWallAndRoofUpperSide(x - 1, y - 1);  // 左上
            this.refreshWallAndRoofUpper(x, y - 1);          // 上
            this.refreshWallAndRoofUpperSide(x + 1, y - 1);  // 右上
            this.refreshWallAndRoofSide(x - 1, y);           // 左
            this.refreshWallAndRoofSide(x + 1, y);           // 右
            this.refreshWallAndRoofDowner(x - 1, y + 1);     // 左下
            this.refreshWallAndRoofDowner(x, y + 1);         // 下
            this.refreshWallAndRoofDowner(x + 1, y + 1);     // 右下
        }
    }
    for (var x = this._symbolMap.length - 1; x >= this._symbolMap.length; x--) {
        for (var y = this._symbolMap[x].length - 1; y >= this._symbolMap[x].length; y--) {
            if (this._symbolMap[x][y] === 'roof' && this._symbolMap[x][y - 1] === 'wall') {
                this._symbolMap[x][y - 1] = 'roof';
            }
        }
    }
};

// シンボルマップの壁と天井を設置：上
Game_MapGenerator.prototype.refreshWallAndRoofUpper = function (x, y) {
    if (!this._symbolMap[x] || !this._symbolMap[x][y] || this.isGround(x, y)) {
        return;
    }
    for (var h = 0; h < y && !this.isGround(x, y - h); h++);
    if (h > this._wallHeight) {
        for (var wH = 0; wH < this._wallHeight; wH++) {
            this._symbolMap[x][y - wH] = 'wall';
        }
        this._symbolMap[x][y - this._wallHeight] = 'roof';
    } else {
        for (var wH = 0; wH < h; wH++) {
            if (this._symbolMap[x][y - wH] === 'space') {
                this._symbolMap[x][y - wH] = 'rubble';
            }
        }
    }
};

// シンボルマップの壁と天井を設置：下
Game_MapGenerator.prototype.refreshWallAndRoofDowner = function (x, y) {
    if (!this._symbolMap[x] || !this._symbolMap[x][y] || this.isGround(x, y)) {
        return;
    }
    for (var h = 0; h + y < $gameMap.height() && !this.isGround(x, y + h); h++);
    if (h > this._wallHeight) {
        this._symbolMap[x][y] = 'roof';
        if (this._showOuterWall) {
            for (var wH = 0; wH < this._wallHeight; wH++) {
                if (this._symbolMap[x][y + wH + 1] !== 'roof') {
                    this._symbolMap[x][y + wH + 1] = 'wall';
                }
            }
        }
    } else {
        for (var wH = 0; wH < h; wH++) {
            if (this._symbolMap[x][y + wH] === 'space') {
                this._symbolMap[x][y + wH] = 'rubble';
            }
        }
    }
};

//シンボルマップの壁と天井を設置：横
Game_MapGenerator.prototype.refreshWallAndRoofSide = function (x, y) {
    if (!this._symbolMap[x] || !this._symbolMap[x][y] || this.isGround(x, y)) {
        return;
    }
    if (this.isGround(x, y + 1)) {
        this.refreshWallAndRoofUpper(x, y);
    } else {
        this.refreshWallAndRoofDowner(x, y);
    }
};

// シンボルマップの壁と天井を設置：斜め上
Game_MapGenerator.prototype.refreshWallAndRoofUpperSide = function (x, y) {
    if (!this._symbolMap[x] || !this._symbolMap[x][y] || this.isGround(x, y)) {
        return;
    }
    this.refreshWallAndRoofDowner(x, y - this._wallHeight);
};

// オートタイルを考慮したタイルID
Game_MapGenerator.prototype.autoTileId = function (x, y, z) {
    if ((x < 0 || x >= $dataMap.width) || (y < 0 || y >= $dataMap.height)) {
        return 0;
    } else if (z === 4) {
        return this.shadow(x, y);
    } else if ((z !== 0 && z !== 1) || this._symbolTable[this._symbolMap[x][y]].baseTileId[z] === 0) {
        return this._symbolTable[this._symbolMap[x][y]].baseTileId[z];
    }
    var candidateTileIds = [];
    if (this._symbolMap[x][y] !== 'wall') {
        // 壁以外の場合
        candidateTileIds = Game_MapGenerator.tileIdsFloor.candidate.concat();
        [1, 2, 3, 4, 6, 7, 8, 9].forEach(function (direction) {
            var dx = x + Math.floor((direction - 1) % 3) - 1;
            var dy = y - Math.floor((direction - 1) / 3) + 1;
            if ((dx < 0 || dx >= $dataMap.width) || (dy < 0 || dy >= $dataMap.height)) {
                return; // マップ範囲外なら判定しない
            }
            if (this._symbolMap[x][y] === this._symbolMap[dx][dy]) {
                candidateTileIds = candidateTileIds.filter(function (Id) {
                    return Game_MapGenerator.tileIdsFloor.connect[direction].indexOf(Id) !== -1;
                }); // 同種シンボルの場合候補タイルIDから接続タイルIDを選択
            } else {
                candidateTileIds = candidateTileIds.filter(function (Id) {
                    return Game_MapGenerator.tileIdsFloor.noConnect[direction].indexOf(Id) !== -1;
                }); // 異種シンボルの場合候補タイルIDから非接続タイルIDを選択
            }
        }, this);
    } else {
        // 壁の場合
        candidateTileIds = Game_MapGenerator.tileIdsWall.candidate.concat();
        for (var by = y; this._symbolMap[x][y] === this._symbolMap[x][by + 1]; by++);  // 壁の下端
        for (var ty = y; this._symbolMap[x][y] === this._symbolMap[x][ty - 1]; ty--);  // 壁の上端
        // 上下の処理
        [2, 8].forEach(function (direction) {
            var dx = x + Math.floor((direction - 1) % 3) - 1;
            var dy = y - Math.floor((direction - 1) / 3) + 1;
            if ((dx < 0 || dx >= $dataMap.width) || (dy < 0 || dy >= $dataMap.height)) {
                return; // マップ範囲外なら判定しない
            }
            if (this._symbolMap[x][y] === this._symbolMap[dx][dy]) {
                candidateTileIds = candidateTileIds.filter(function (Id) {
                    return Game_MapGenerator.tileIdsWall.connect[direction].indexOf(Id) !== -1;
                }); // 同種シンボルの場合候補タイルIDから接続タイルIDを選択
            } else {
                candidateTileIds = candidateTileIds.filter(function (Id) {
                    return Game_MapGenerator.tileIdsWall.noConnect[direction].indexOf(Id) !== -1;
                }); // 異種シンボルの場合候補タイルIDから非接続タイルIDを選択
            }
        }, this);
        // 左右の処理
        [4, 6].forEach(function (direction) {
            var dx = x + Math.floor((direction - 1) % 3) - 1;
            var dy = y - Math.floor((direction - 1) / 3) + 1;
            if ((dx < 0 || dx >= $dataMap.width) || (dy < 0 || dy >= $dataMap.height)) {
                return; // マップ範囲外なら判定しない
            }
            if ((this._symbolMap[dx][ty] === 'wall' || this._symbolMap[dx][ty] === 'roof') &&
                (this._symbolMap[dx][by] === 'wall' || this._symbolMap[dx][by] === 'roof')) {
                candidateTileIds = candidateTileIds.filter(function (Id) {
                    return Game_MapGenerator.tileIdsWall.connect[direction].indexOf(Id) !== -1;
                });　// 壁の下端の両横隣が壁または天井でかつ上端の両横隣が壁または天井でなければ接続タイルIDを選択
            } else {
                candidateTileIds = candidateTileIds.filter(function (Id) {
                    return Game_MapGenerator.tileIdsWall.noConnect[direction].indexOf(Id) !== -1;
                });　// 非接続タイルIDを選択
            }
        }, this);
    }
    return this._symbolTable[this._symbolMap[x][y]].baseTileId[z] + candidateTileIds[0];
};

// 影の算出
Game_MapGenerator.prototype.shadow = function (x, y) {
    if (!this._symbolMap[x - 1] ||
        this._symbolMap[x][y] === 'space' ||
        this._symbolMap[x][y] === 'roof' ||
        this._symbolMap[x][y] === 'wall') {
        return 0;
    } else if (this._symbolMap[x - 1][y] === 'roof') {
        if (this._symbolMap[x - 1][y - 1] === 'roof' ||
            this._symbolMap[x - 1][y - 1] === 'wall') {
            return 5;
        }
    } else if (this._symbolMap[x - 1][y] === 'wall') {
        return 5;
    }
    return 0;
};

//マップデータ作成
Game_MapGenerator.prototype.makeData = function () {
    var width = $dataMap.width;
    var height = $dataMap.height;
    for (var x = 0; x < this._symbolMap.length; x++) {
        for (var y = 0; y < this._symbolMap[x].length; y++) {
            for (var z = 0; z < 6; z++) {
                this._data[(z * height + y) * width + x] = this.autoTileId(x, y, z);
            }
        }
    }
};

// マップデータ
Game_MapGenerator.prototype.data = function () {
    return this._data;
};

// タイルID
Game_MapGenerator.prototype.tileId = function (x, y, z) {
    return this._data[(z * $dataMap.height + y) * $dataMap.width + x];
};

// 準備完了判定
Game_MapGenerator.prototype.isReady = function () {
    return this._isReady;
};

// マップのコンソール表示（デバッグ用）
Game_MapGenerator.prototype.printMap = function () {
    var dispMap = "";
    for (var y = 0; y < this._symbolMap[0].length; y++) {
        for (var x = 0; x < this._symbolMap.length; x++) {
            dispMap += this._symbolTable[this._symbolMap[x][y]].dispChar;
        }
        dispMap += "\r\n";
    }
    console.log(dispMap);
    // this.fPrintMap(dispMap);
};

// テキスト出力（デバッグ用）
Game_MapGenerator.prototype.fPrintMap = function (mapString) {
    var data = LZString.compressToBase64(mapString);
    var fs = require('fs');
    var dirPath = StorageManager.localFileDirectoryPath();
    var filePath = StorageManager.localFileDirectoryPath() + 'mapData.txt';
    if (!fs.existsSync(dirPath)) {
        fs.mkdirSync(dirPath);
    }
    fs.writeFileSync(filePath, mapString);
};

//-----------------------------------------------------------------------------
// Game_MapGeneratorRoomAndPass
//
// マップジェネレーター（部屋と通路）

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

Game_MapGeneratorRoomAndPass.prototype = Object.create(Game_MapGenerator.prototype);
Game_MapGeneratorRoomAndPass.prototype.constructor = Game_MapGeneratorRoomAndPass;

// 初期化
Game_MapGeneratorRoomAndPass.prototype.initialize = function () {
    Game_MapGenerator.prototype.initialize.call(this);
};

// マップ（ダンジョン）自動生成
Game_MapGeneratorRoomAndPass.prototype.generateMap = function () {
    this._minRoomSize = Number(PluginManager.parameters('SAN_MapGenerator')['MinRoomSize']);
    this._maxRoomSize = Number(PluginManager.parameters('SAN_MapGenerator')['MaxRoomSize']);
    if (this._maxRoomSize < this._minRoomSize) {
        this._maxRoomSize = this._minRoomSize;
    }
    this._minBlockSize = this._minRoomSize + (this._wallHeight + 1) * 2 + 2;
    this._minRooms = 2;
    this._maxRooms = 5;
    this._adjacentBlockIndexList = [];
    var block = {
        x: 1,
        y: 1 + this._wallHeight,
        w: $dataMap.width - 2,
        h: $dataMap.height - (this._wallHeight + 1) * 2
    };
    this._blocks.push(block);
    this.splitBlock(this._blocks[0]);
    this.makeAdjacentBlockIndexList();
    this.makeRooms();
    this.makePasses();
};

// 隣り合うブロックのリスト作成
Game_MapGeneratorRoomAndPass.prototype.makeAdjacentBlockIndexList = function () {
    for (var crntIndex = 0; crntIndex < this._blocks.length; crntIndex++) {
        var crntBlock = this._blocks[crntIndex];
        this._adjacentBlockIndexList[crntIndex] = { t: [], b: [], l: [], r: [] };
        for (var tgetIndex = 0; tgetIndex < this._blocks.length; tgetIndex++) {
            var tgetBlock = this._blocks[tgetIndex];
            if (crntBlock === tgetBlock) {
                continue;
            }
            var adjacentT = (crntBlock.y === tgetBlock.y + tgetBlock.h + 1);
            var adjacentB = (tgetBlock.y === crntBlock.y + crntBlock.h + 1);
            var adjacentL = (crntBlock.x === tgetBlock.x + tgetBlock.w + 1);
            var adjacentR = (tgetBlock.x === crntBlock.x + crntBlock.w + 1);
            if (!adjacentT && !adjacentB && !adjacentL && !adjacentR) {
                continue;
            }
            var matchH =
                (tgetBlock.x <= crntBlock.x + crntBlock.w && tgetBlock.x >= crntBlock.x) ||
                (tgetBlock.x + tgetBlock.w <= crntBlock.x + crntBlock.w && tgetBlock.x + tgetBlock.w >= crntBlock.x) ||
                (crntBlock.x <= tgetBlock.x + tgetBlock.w && crntBlock.x >= tgetBlock.x) ||
                (crntBlock.x + crntBlock.w <= tgetBlock.x + tgetBlock.w && crntBlock.x + crntBlock.w >= tgetBlock.x);
            var matchV =
                (tgetBlock.y <= crntBlock.y + crntBlock.h && tgetBlock.y >= crntBlock.y) ||
                (tgetBlock.y + tgetBlock.h <= crntBlock.y + crntBlock.h && tgetBlock.y + tgetBlock.h >= crntBlock.y) ||
                (crntBlock.y <= tgetBlock.y + tgetBlock.h && crntBlock.y >= tgetBlock.y) ||
                (crntBlock.y + crntBlock.h <= tgetBlock.y + tgetBlock.h && crntBlock.y + crntBlock.h >= tgetBlock.y);
            if (adjacentT && matchH) {
                this._adjacentBlockIndexList[crntIndex].t.push(tgetIndex);
                continue;
            } else if (adjacentB && matchH) {
                this._adjacentBlockIndexList[crntIndex].b.push(tgetIndex);
                continue;
            }
            if (adjacentL && matchV) {
                this._adjacentBlockIndexList[crntIndex].l.push(tgetIndex);
                continue;
            } else if (adjacentR && matchV) {
                this._adjacentBlockIndexList[crntIndex].r.push(tgetIndex);
                continue;
            }
        }
    }
};

// 部屋作成
Game_MapGeneratorRoomAndPass.prototype.makeRooms = function () {
    this._blocks.forEach(function (block) {
        var roomW = this._minRoomSize + Math.randomInt((block.w - (this._wallHeight + 1) * 2) - this._minRoomSize - 2);
        var roomH = this._minRoomSize + Math.randomInt((block.h - (this._wallHeight + 1) * 2) - this._minRoomSize - 2);
        if (roomW > this._maxRoomSize) {
            roomW = this._maxRoomSize;
        }
        if (roomH > this._maxRoomSize) {
            roomH = this._maxRoomSize;
        }
        var roomX = block.x + (this._wallHeight + 1) + 1 + Math.randomInt(block.w - roomW - (this._wallHeight + 1) * 2 - 1);
        var roomY = block.y + (this._wallHeight + 1) + 1 + Math.randomInt(block.h - roomH - (this._wallHeight + 1) * 2 - 1);
        var room = { x: roomX, y: roomY, w: roomW, h: roomH, hasPass: { t: false, b: false, l: false, r: false } };
        this._rooms.push(room);
    }, this);
    this._rooms.forEach(function (room) {
        for (var y = 0; y < room.h; y++) {
            for (var x = 0; x < room.w; x++) {
                this._symbolMap[room.x + x][room.y + y] = 'room';
            }
        }
    }, this);
};

// 通路作成
Game_MapGeneratorRoomAndPass.prototype.makePasses = function () {
    var cache = {};
    for (var crntIndex = 0; crntIndex < this._adjacentBlockIndexList.length; crntIndex++) {
        cache[crntIndex] = [];
        var crngBlock = this._blocks[crntIndex];
        for (var direction in this._adjacentBlockIndexList[crntIndex]) {
            var tgetIndexList = this._adjacentBlockIndexList[crntIndex][direction];
            tgetIndexList.forEach(function (tgetIndex) {
                if (cache[tgetIndex] !== undefined && cache[tgetIndex].indexOf(crntIndex) !== -1) {
                    return;
                }
                cache[crntIndex].push(tgetIndex);
                var tgetBlock = this._blocks[tgetIndex];
                var crntRoom = this._rooms[crntIndex];
                var tgetRoom = this._rooms[tgetIndex];
                var crntPass = { x: 0, y: 0, w: 0, h: 0 };
                var tgetPass = { x: 0, y: 0, w: 0, h: 0 };
                var bordPass = { x: 0, y: 0, w: 0, h: 0 };
                switch (direction) {
                    case 't':
                        if (crntRoom.hasPass.t || tgetRoom.hasPass.b) {
                            return;
                        }
                        crntPass.x = crntRoom.x + 1 + Math.randomInt(crntRoom.w - 2);
                        crntPass.y = crngBlock.y;
                        crntPass.w = 1;
                        crntPass.h = crntRoom.y - crngBlock.y;
                        tgetPass.x = tgetRoom.x + 1 + Math.randomInt(tgetRoom.w - 2);
                        tgetPass.y = tgetRoom.y + tgetRoom.h;
                        tgetPass.w = 1;
                        tgetPass.h = crngBlock.y - tgetPass.y;
                        bordPass.x = Math.min(crntPass.x, tgetPass.x);
                        bordPass.y = crngBlock.y - 1;
                        bordPass.w = Math.max(crntPass.x, tgetPass.x) - bordPass.x + 1;
                        bordPass.h = 1;
                        crntRoom.hasPass.t = true;
                        tgetRoom.hasPass.b = true;
                        break;
                    case 'b':
                        if (crntRoom.hasPass.b || tgetRoom.hasPass.t) {
                            return;
                        }
                        crntPass.x = crntRoom.x + 1 + Math.randomInt(crntRoom.w - 2);
                        crntPass.y = crntRoom.y + crntRoom.h;
                        crntPass.w = 1;
                        crntPass.h = tgetBlock.y - crntPass.y;
                        tgetPass.x = tgetRoom.x + 1 + Math.randomInt(tgetRoom.w - 2);
                        tgetPass.y = tgetBlock.y;
                        tgetPass.w = 1;
                        tgetPass.h = tgetRoom.y - tgetBlock.y;
                        bordPass.x = Math.min(crntPass.x, tgetPass.x);
                        bordPass.y = tgetBlock.y - 1;
                        bordPass.w = Math.max(crntPass.x, tgetPass.x) - bordPass.x + 1;
                        bordPass.h = 1;
                        crntRoom.hasPass.b = true;
                        tgetRoom.hasPass.t = true;
                        break;
                    case 'l':
                        if (crntRoom.hasPass.l || tgetRoom.hasPass.r) {
                            return;
                        }
                        crntPass.x = crngBlock.x - 1;
                        crntPass.y = crntRoom.y + 1 + Math.randomInt(crntRoom.h - 2);
                        crntPass.w = crntRoom.x - crntPass.x;
                        crntPass.h = 1;
                        tgetPass.x = tgetRoom.x + tgetRoom.w;
                        tgetPass.y = tgetRoom.y + 1 + Math.randomInt(tgetRoom.h - 2);
                        tgetPass.w = crntPass.x - tgetRoom.x - tgetRoom.w;
                        tgetPass.h = 1;
                        bordPass.x = crngBlock.x - 1;
                        bordPass.y = Math.min(crntPass.y, tgetPass.y);
                        bordPass.w = 1;
                        bordPass.h = Math.max(crntPass.y, tgetPass.y) - bordPass.y + 1;
                        crntRoom.hasPass.l = true;
                        tgetRoom.hasPass.r = true;
                        break;
                    case 'r':
                        if (crntRoom.hasPass.r || tgetRoom.hasPass.l) {
                            return;
                        }
                        crntPass.x = crntRoom.x + crntRoom.w
                        crntPass.w = tgetBlock.x - 1 - crntRoom.x - crntRoom.w
                        crntPass.y = crntRoom.y + 1 + Math.randomInt(crntRoom.h - 2);
                        crntPass.h = 1;
                        tgetPass.x = tgetBlock.x - 1;
                        tgetPass.y = tgetRoom.y + 1 + Math.randomInt(tgetRoom.h - 2);
                        tgetPass.w = tgetRoom.x - tgetPass.x;
                        tgetPass.h = 1;
                        bordPass.x = tgetBlock.x - 1;
                        bordPass.y = Math.min(crntPass.y, tgetPass.y);
                        bordPass.w = 1;
                        bordPass.h = Math.max(crntPass.y, tgetPass.y) - bordPass.y + 1;
                        crntRoom.hasPass.r = true;
                        tgetRoom.hasPass.l = true;
                        break;
                }
                this._passes.push(crntPass);
                this._passes.push(tgetPass);
                this._passes.push(bordPass);
            }, this);
        }
    }
    this._passes.forEach(function (pass) {
        for (var y = 0; y < pass.h; y++) {
            for (var x = 0; x < pass.w; x++) {
                this._symbolMap[pass.x + x][pass.y + y] = 'pass';
            }
        }
    }, this);
};

// ブロック分割：ランダム
Game_MapGeneratorRoomAndPass.prototype.splitBlock = function (block) {
    if (this.randBool(0.5)) {
        if (this.isSplitableH(block)) {
            this.splitBlockH(block);
        }
        if (this.isSplitableV(block)) {
            this.splitBlockV(block);
        }
    } else {
        if (this.isSplitableV(block)) {
            this.splitBlockV(block);
        }
        if (this.isSplitableH(block)) {
            this.splitBlockH(block);
        }
    }
};

//ブロック分割：横分割
Game_MapGeneratorRoomAndPass.prototype.splitBlockH = function (block) {
    var orgBlockW = 0;
    var newBlockW = 0;
    while (orgBlockW < this._minBlockSize || newBlockW < this._minBlockSize) {
        orgBlockW = Math.floor(block.w / 4 + block.w * Math.random() / 2);
        newBlockW = block.w - orgBlockW - 1;
    }
    block.w = orgBlockW;
    var newBlock = { x: block.x + orgBlockW + 1, y: block.y, w: newBlockW, h: block.h };
    this._blocks.push(newBlock);
    this.splitBlock(block);
    this.splitBlock(newBlock);
};

// ブロック分割：縦分割
Game_MapGeneratorRoomAndPass.prototype.splitBlockV = function (block) {
    var orgBlockH = 0;
    var newBlockH = 0;
    while (orgBlockH < this._minBlockSize || newBlockH < this._minBlockSize) {
        orgBlockH = Math.floor(block.h / 4 + block.h * Math.random() / 2);
        newBlockH = block.h - orgBlockH - 1;
    }
    block.h = orgBlockH;
    var newBlock = { x: block.x, y: block.y + orgBlockH + 1, w: block.w, h: newBlockH };
    this._blocks.push(newBlock);
    this.splitBlock(block);
    this.splitBlock(newBlock);
};

// ブロック分割可能判定：部屋数
Game_MapGeneratorRoomAndPass.prototype.isSplitableByRoomNum = function () {
    if (this._blocks.length >= this._maxRooms) {
        return false;
    }
    if (this._blocks.length >= this._minRooms &&
        this.randBool((this._blocks.length - this._minRooms + 1) / (this._maxRooms - this.minRooms + 1))) {
        return false;
    }
    return true;
};

// ブロック分割可能判定：横分割
Game_MapGeneratorRoomAndPass.prototype.isSplitableV = function (block) {
    return block.h > (this._minBlockSize * 2 + 1) && this.isSplitableByRoomNum();
};

// ブロック分割可能判定：縦分割
Game_MapGeneratorRoomAndPass.prototype.isSplitableH = function (block) {
    return block.w > (this._minBlockSize * 2 + 1) && this.isSplitableByRoomNum();
};

// 座標によって部屋を取得
Game_MapGeneratorRoomAndPass.prototype.roomByXY = function (x, y) {
    this._rooms.forEach(function (room) {
        if (room.x <= x && x <= room.x + room.w && room.y <= y && y <= room.y + room.h) {
            return result = room;
        }
    }, this);
    return undefined;
};

//-----------------------------------------------------------------------------
// Game_Map
//
// マップクラス

// マップクラスの初期化
Sanshiro.Game_MapGenerator.Game_Map_initialize = Game_Map.prototype.initialize;
Game_Map.prototype.initialize = function () {
    Sanshiro.Game_MapGenerator.Game_Map_initialize.call(this);
};

// マップクラスのセットアップ
Sanshiro.Game_MapGenerator.Game_Map_setup = Game_Map.prototype.setup;
Game_Map.prototype.setup = function (mapId) {
    Sanshiro.Game_MapGenerator.Game_Map_setup.call(this, mapId)
    this._mapGenerator = null;
};

// マップクラスのタイルID
Sanshiro.Game_MapGenerator.Game_Map_tileId = Game_Map.prototype.tileId
Game_Map.prototype.tileId = function (x, y, z) {
    if (this.isGenegratedMap()) {
        return this._mapGenerator.tileId(x, y, z);
    }
    return Sanshiro.Game_MapGenerator.Game_Map_tileId.call(this, x, y, z);
};

// マップクラスのマップデータ
Sanshiro.Game_MapGenerator.Game_Map_data = Game_Map.prototype.data
Game_Map.prototype.data = function () {
    if (this.isGenegratedMap()) {
        return this._mapGenerator.data();
    }
    return Sanshiro.Game_MapGenerator.Game_Map_data.call(this);
};

// マップクラスの通行判定
Sanshiro.Game_MapGenerator.Game_Map_isPassable = Game_Map.prototype.isPassable
Game_Map.prototype.isPassable = function (x, y, d) {
    if (this.isGenegratedMap()) {
        return this._mapGenerator.isPassable(x, y, d);
    }
    return Sanshiro.Game_MapGenerator.Game_Map_isPassable.call(this, x, y, d);
};

// マップクラスのマップ自動生成
Game_Map.prototype.generateMap = function (mapType) {
    mapType = mapType || 'FillRoom';
    switch (mapType) {
        case 'RoomAndPass':
            this._mapGenerator = new Game_MapGeneratorRoomAndPass();
            break;
        case 'FillRoom':
            this._mapGenerator = new Game_MapGenerator();
            break;
    }
    this._mapGenerator.setup();
    if (Imported.SAN_AnalogMove) {
        Game_CollideMap.setup();
    }
};

// 自動生成マップ判定
Game_Map.prototype.isGenegratedMap = function () {
    return !!this._mapGenerator && this._mapGenerator.isReady();
};

//-----------------------------------------------------------------------------
// Game_Event
//
// イベントクラス

// イベントクラスの初期化
Sanshiro.Game_MapGenerator.Game_Event_initialize = Game_Event.prototype.initialize;
Game_Event.prototype.initialize = function (mapId, eventId) {
    this._dataEventId = eventId;
    Sanshiro.Game_MapGenerator.Game_Event_initialize.call(this, mapId, eventId);
};

// イベントクラスのデータベースのイベントデータ
Game_Event.prototype.event = function () {
    return $dataMap.events[this._dataEventId];
};

//-----------------------------------------------------------------------------
// Game_Interpreter
//
// インタープリタークラス

// プラグインコマンド
Sanshiro.Game_MapGenerator.Game_Interpreter_pluginCommand = Game_Interpreter.prototype.pluginCommand;
Game_Interpreter.prototype.pluginCommand = function (command, args) {
    Sanshiro.Game_MapGenerator.Game_Interpreter_pluginCommand.call(this, command, args);
    if (command === 'MapGenerator') {
        $gameMap.generateMap(args[0]);
    }
};


code:
//=============================================================================
// SGExpanA.js
//=============================================================================

/*:ja
 * @plugindesc ver1.00 笑顔拡張パック(SceneGrow)
 * @author まっつＵＰ
 *
 * @param comtext
 * @desc 表示するコマンド名。
 * @default HAPPY
 *
 * @param display
 * @desc この値のIDのスイッチがオンのときコマンドを表示します。
 * @default 10
 *
 * @param enabled
 * @desc この値のIDの変数が0を超えるときコマンドを有効にします。
 * @default 5
 *
 * @help
 *
 * RPGで笑顔を・・・
 *
 * このヘルプとパラメータの説明をよくお読みになってからお使いください。
 *
 * SceneGrowより下にこのプラグインを配置して両方をオンにしてください。
 * メニューコマンドにSceneGrowの機能を呼び出すコマンドをバインドします。
 *
 * 免責事項：
 * このプラグインを利用したことによるいかなる損害も制作者は一切の責任を負いません。
 *
 */

(function () {

    var parameters = PluginManager.parameters('SGExpanA');
    var SGcomtext = String(parameters['comtext'] || 'HAPPY');
    var SGdisplay = Number(parameters['display'] || 10);
    var SGenabled = Number(parameters['enabled'] || 5);

    var _Scene_Menu_createCommandWindow = Scene_Menu.prototype.createCommandWindow;
    Scene_Menu.prototype.createCommandWindow = function () {
        _Scene_Menu_createCommandWindow.call(this);
        this._commandWindow.setHandler('grow', this.commandGrow.bind(this)); //追加
    };

    Scene_Menu.prototype.commandGrow = function () { //新規
        SceneManager.push(Scene_Growing); //SceneGrowで新規に作ったシーンに飛ばす。
    };

    var _Window_MenuCommand_addOriginalCommands = Window_MenuCommand.prototype.addOriginalCommands;
    Window_MenuCommand.prototype.addOriginalCommands = function () {
        _Window_MenuCommand_addOriginalCommands.call(this);
        if (this.isGrowDisplay()) { //条件により表示する。
            var enabled = this.isGrowEnabled(); //条件により有効状態を変更する。
            this.addCommand(SGcomtext, 'grow', enabled);
        }
    };

    Window_MenuCommand.prototype.isGrowDisplay = function () { //新規
        return $gameSwitches.value(SGdisplay) > 0; //つまりスイッチの真偽を返す。
    };

    Window_MenuCommand.prototype.isGrowEnabled = function () { //新規
        return $gameVariables.value(SGenabled) > 0 && $gameParty.size() > 0;
    };

})();


code:
//=============================================================================
// Saba_DirectionFix.js
//=============================================================================
/*:ja
 * @plugindesc イベントページの設定で「向き固定」にチェックを入れた場合、直前の向きに関わらず、イベントで指定した向きにします。
 * @author Sabakan
 *
 * @help
 * デフォルトでは、イベントページの１枚目と２枚目のキャラの向きが同じ場合、
 * イベントページ１枚目で向きを変えてからイベントページ２枚目になっても、
 * イベントページ２枚目の向きは無視されて、現在の向きがそのまま使われます。
 * しかし、イベントページ２枚目が倒れている時のグラなどで、
 * 必ず下向きにしたい場合、この機能が邪魔になります。
 * このプラグインでは、「向き固定」にチェックを入れた場合は、
 * 必ずイベントで指定した向きになるようにします。
 *
 *
 * プラグインコマンドはありません。
 */
var Saba;
(function (Saba) {
    var Game_Event_setupPageSettings = Game_Event.prototype.setupPageSettings;
    Game_Event.prototype.setupPageSettings = function () {
        var page = this.page();
        var image = page.image;
        if (page.directionFix) {
            this._originalDirection = image.direction;
            this._prelockDirection = 0;
            this.setDirectionFix(false);
            this.setDirection(image.direction);
        }
        Game_Event_setupPageSettings.call(this);
    };
})(Saba || (Saba = {}));


code:
//=============================================================================
// Saba_Performance.js
//=============================================================================
/*:ja
 * @plugindesc まだテスト版です。OFFにする場合は 0 を入力してください
 * @author Sabakan
 *
 * @param notDrawAtBitmapSnap
 * @desc snap作成時に canvas を経由しないようにします。
■副作用:　小。画面遷移系を変更している場合はエラーになります。
 * @default 1
 *
 * @param recycleCanvas
 * @desc Canvas を使い回すことで生成コストを下げます。また、必要でないときは作成しないようにします。■副作用:　中。
 * @default 1
 *
 * @param skipSnapForBackgroundByNewGame
 * @desc ゲーム開始時にSnapForBackgroundをしないようにします。
■副作用:　小。ゲーム開始時に特殊な処理をしている場合は無効にしてください
 * @default 1
 *
 * @param skipSnapForBackgroundByMapChange
 * @desc マップ移動時にSnapForBackgroundをしないようにします。
■副作用:　小
 * @default 1
 *
 * @param usePixiSpriteToDrawWindow_Base
 * @desc PIXI.Spriteを使ってWindow_Baseを描画します。
■副作用:　中。Windowの描画を変更している場合は無効にしてください
 * @default 1
 *
 * @param useFilterToChangePictureTone
 * @desc PIXI のフィルタを使ってピクチャの色調を変化させます。
■副作用:　大。グレー効果は効かなくなります
 * @default 1
 *
 * @param reduceWindowInitializeProcess
 * @desc ウィンドウの初期化の無駄な処理を減らします
■副作用:　なし
 * @default 1
 *
 * @param alternateBitmapClearMethod
 * @desc Bitmap.clear() メソッドを高速な方法に切り替えます
■副作用:　中。Bitmap.clear()を呼ぶと、CanvasRenderingContext2Dのスタイルもクリアされます
 * @default 1
 *
 * @param usePixiSpriteToDrawIcon
 * @desc PIXI.Spriteを使ってIconを描画します。
■副作用:　中。アイコンのZ順に影響が出ることがあります
 * @default 1
 *
 * @param usePixiSpriteToDrawFace
 * @desc PIXI.Spriteを使ってFaceを描画します。
■副作用:　中。顔グラのZ順に影響が出ることがあります
 * @default 1
 *
 * @param usePixiSpriteToDrawCharacter
 * @desc PIXI.Spriteを使ってCharacterを描画します。
■副作用:　中。キャラグラのZ順に影響が出ることがあります
 * @default 1
 *
 * @param usePixiGraphicsToDrawMenuBg
 * @desc
 * @default 1
 *
 * @param skipUnnecessaryRefresh
 * @desc ウィンドウの初期化の無駄な処理を減らします
■副作用:　なし
 * @default 1
 *
 * @param lazyInitializationBitmapAtSprite_Timer
 * @desc タイマー用の Bitmap を、必要になるまで作成しないようにします
■副作用:　小
 * @default 1
 *
 * @param lazyInitializationWeather
 * @desc 天気用の Bitmap を、必要になるまで作成しないようにします
■副作用:　小
 * @default 1
 *
 * @param lazyCreationWindow_MapName
 * @desc マップネームウィンドウを、必要になるまで作成しないようにします
■副作用:　小
 * @default 1
 *
 * @param lazyCreationWindow_ScrollText
 * @desc スクロールテキストウィンドウを、必要になるまで作成しないようにします
■副作用:　小
 * @default 1
 *
 * @param useSpriteToDrawSprite_Destination
 * @desc
 * @default 1
 *
 * @param skipWindow_CommandFirstCreateContents
 * @desc 不要な createContents をスキップします
■副作用:　小。通常は影響がないはずです
 * @default 1
 *
 * @param useDefaultTextColor
 * @desc pixelを調べずにテキストカラーを取得するようにします
■副作用:　小。テキストカラーを変更していても、それが反映されません
 * @default 1
 *
 * @param reduceLoadingGlobalInfo
 * @desc
 * @default 1
 *
 * @param notLoadingVolumeZeroAudio
 * @desc config でボリュームが 0 に設定したオーディオを読み込まないようにします
■副作用:　小。ボリュームを 0 から 1 以上にあげると、最初から再生されます
 * @default 1
 *
 * @param usePixiByWindow_BattleLogBg
 * @desc バトルログの背景を PIXI を使って描画しますbr>■副作用:　小
 * @default 1
 *
 * @help
 * ・MV1.3 WebGL モード限定です
 * ・canvas 呼び出しで固まってしまう機種に対して効果を発揮します
 */
var Saba;
(function (Saba) {

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

    /**
     * 子供を destroy しつつ削除します
     */
    PIXI.Container.prototype.destroyAndRemoveChildren = function () {
        for (var i = this.children.length; i >= 0; i--) {
            if (this.children[i]) {
                this.children[i].destroy({ children: true, texture: true });
            }
        }
        this.removeChildren();
    };

    Saba.toPixiColor = function (color) {
        var r = parseInt(color.substring(1, 3), 16);
        var g = parseInt(color.substring(3, 5), 16);
        var b = parseInt(color.substring(5, 7), 16);
        var intColor = (r << 16) | (g << 8) | b;
        return intColor;
    };

    if (parseInt(parameters['notDrawAtBitmapSnap'])) {
        /**
         * snap作成時に canvas を経由しない。
         * メニューのオープンが速くなる。
         */
        var renderTexture;
        Bitmap.snap = function (stage) {
            var width = Graphics.width;
            var height = Graphics.height;
            // var bitmap = new Bitmap(width, height);
            if (!renderTexture) {
                renderTexture = PIXI.RenderTexture.create(width, height);
            }
            if (stage) {
                Graphics._renderer.render(stage, renderTexture);
                stage.worldTransform.identity();
                return new PIXI.Sprite(new PIXI.Texture(renderTexture));
                // context.drawImage(canvas, 0, 0);
            } else {
                //TODO: Ivan: what if stage is not present?
            }
            return null;
        };
        /**
         * Bitmap.blur が使えなくなるのでフィルタで代用
         */
        Scene_MenuBase.prototype.createBackground = function () {
            this._backgroundSprite = SceneManager.backgroundBitmap();
            var blurFilter = new PIXI.filters.BlurFilter(1);
            this._backgroundSprite.filters = [blurFilter];
            var destroy = this._backgroundSprite.destroy;
            this._backgroundSprite.destroy = function (options) {
                // DO nothing
                this.filters = null;
            };
            this.addChild(this._backgroundSprite);
        };
        SceneManager.snapForBackground = function () {
            this._backgroundBitmap = this.snap();
            this._backgroundBitmap.isBackgroundBitmap = true;
            // this._backgroundBitmap.blur();
        };
        Spriteset_Battle.prototype.createBackground = function () {
        };
    }

    if (parseInt(parameters['recycleCanvas'])) {
        PIXI.extras.TilingSprite.prototype.destroy = function () {
            PIXI.Sprite.prototype.destroy.call(this);
        };
        PIXI.DisplayObject.prototype.returnChildCanvas = function () {
            if (this.returnCanvas) {
                this.returnCanvas();
            }
        };
        PIXI.Container.prototype.returnChildCanvas = function () {
            if (this.returnCanvas) {
                this.returnCanvas();
            }
            for (var i = 0; i < this.children.length; i++) {
                var child = this.children[i];
                if (child.returnChildCanvas) {
                    child.returnChildCanvas();
                }
            }
        };
        /**
         * 一度作成した canvas を使い回すことで、初期化のコストを減らす。
         * ゲームの起動、シーン遷移などが速くなる。
         */
        SceneManager.changeScene = function () {
            if (this.isSceneChanging() && !this.isCurrentSceneBusy()) {
                if (this._scene) {
                    this._scene.terminate();
                    this._scene.returnChildCanvas();
                    this._previousClass = this._scene.constructor;
                    this._previousScene = this._scene;
                }
                this._scene = this._nextScene;
                if (this._scene) {
                    this._scene.create();
                    this._nextScene = null;
                    this._sceneStarted = false;
                    this.onSceneCreate();
                }
                if (this._exiting) {
                    this.terminate();
                }
                if (this._previousScene) {
                    this._previousScene.destroy({ children: true, texture: true });
                    this._previousScene.visible = false;
                    this._previousScene = null;
                }
            }
        };
        SceneManager.renderScene = function () {
            if (this.isCurrentSceneStarted()) {
                Graphics.render(this._scene);
            } else if (this._scene) {
                this.onSceneLoading();
            }
        };

        Window.prototype.returnCanvas = function () {
            if (this.contents && this.contents.returnCanvas) {
                this.contents.returnCanvas();
            }
        };
        Sprite.prototype.returnCanvas = function () {
            if (this.bitmap && this.bitmap.returnCanvas) {
                this.bitmap.returnCanvas();
            }
        };
        var canvasCacheMap = {};
        function getCanvasCache(width, height) {
            var key = width + '_' + height;
            canvasCacheMap[key] = canvasCacheMap[key] || [];
            if (canvasCacheMap[key].length > 0) {
                return canvasCacheMap[key].pop();
            }
            var canvasCache = {};
            canvasCache._canvas = document.createElement('canvas');
            canvasCache._context = canvasCache._canvas.getContext('2d');

            canvasCache._canvas.width = width;
            canvasCache._canvas.height = height;

            return canvasCache;
        }
        function putCanvasCache(bitmap) {
            var canvasCache = {};
            canvasCache._canvas = bitmap._canvas;
            canvasCache._context = bitmap._context;
            var key = bitmap._canvas.width + '_' + bitmap._canvas.height;
            canvasCacheMap[key] = canvasCacheMap[key] || [];
            canvasCacheMap[key].push(canvasCache);
        }
        Bitmap.prototype.returnCanvas = function () {
            if (this._disposed) {
                return;
            }
            this._disposed = true;
            if (!this._context) {
                return;
            }
            //this._baseTexture.destroy();
            putCanvasCache(this);
        };
        Bitmap.prototype.destroy = function () {
            this._context = null;
            this._canvas = null;
            if (this._baseTexture) {
                this._baseTexture.destroy();
            }
            this._baseTexture = null;
            this._image = null;
            this._url = null;
            this.textColor = null;
            this.outlineColor = null;
            this._loadListeners = null;
        };
        Bitmap.prototype.initialize = function (width, height) {
            if (width !== undefined) {
                width = Math.max(width || 0, 1);
                height = Math.max(height || 0, 1);
                var cache = getCanvasCache(width, height);
                this._canvas = cache._canvas;
                this._context = cache._context;

                this._baseTexture = new PIXI.BaseTexture(this._canvas);
                this.clear();
                this.paintOpacity = 255;
            } else {
                // 幅を指定しない場合は canvas を作成しない
                this._baseTexture = new PIXI.BaseTexture(null);
                this._canvas = { dummy: true };  // dummy
                this._canvas.width = Math.max(width || 0, 1);
                this._canvas.height = Math.max(height || 0, 1);
                this._baseTexture.source = this._canvas;
            }
            this._baseTexture.mipmap = false;
            this._baseTexture.scaleMode = PIXI.SCALE_MODES.NEAREST;
            this._image = null;
            this._url = '';
            this._paintOpacity = 255;
            this._smooth = false;
            this._loadListeners = [];
            this._isLoading = false;
            this._hasError = false;

            /**
             * Cache entry, for images. In all cases _url is the same as cacheEntry.key
             * @type CacheEntry
             */
            this.cacheEntry = null;

            /**
             * The face name of the font.
             *
             * @property fontFace
             * @type String
             */
            this.fontFace = 'GameFont';

            /**
             * The size of the font in pixels.
             *
             * @property fontSize
             * @type Number
             */
            this.fontSize = 28;

            /**
             * Whether the font is italic.
             *
             * @property fontItalic
             * @type Boolean
             */
            this.fontItalic = false;

            /**
             * The color of the text in CSS format.
             *
             * @property textColor
             * @type String
             */
            this.textColor = '#ffffff';

            /**
             * The color of the outline of the text in CSS format.
             *
             * @property outlineColor
             * @type String
             */
            this.outlineColor = 'rgba(0, 0, 0, 0.5)';

            /**
             * The width of the outline of the text.
             *
             * @property outlineWidth
             * @type Number
             */
            this.outlineWidth = 4;
        };
        Bitmap.prototype._onLoad = function () {
            if (Decrypter.hasEncryptedImages) {
                window.URL.revokeObjectURL(this._image.src);
            }
            this._isLoading = false;
            this._baseTexture.loadSource(this._image);
            this._canvas = this._image;

            this.resize(this._image.width, this._image.height);
            this._baseTexture.emit('loaded', this._baseTexture);
            // this._context.drawImage(this._image, 0, 0);
            this._setDirty();
            this._callLoadListeners();
        };
        var _Bitmap_rotateHue = Bitmap.prototype.rotateHue;
        Bitmap.prototype.rotateHue = function (offset) {
            if (offset && this.width > 0 && this.height > 0) {
                if (!this._context) {
                    // この時だけ仕方なく描画。
                    var cache = getCanvasCache();
                    this._canvas = cache._canvas;
                    this._context = cache._context;
                    this.resize(this._image.width, this._image.height);
                    this._context.drawImage(this._image, 0, 0);
                }
            }
            _Bitmap_rotateHue.call(this, offset);
        };
        Object.defineProperty(Sprite.prototype, 'bitmap', {
            set: function (value) {
                if (this._bitmap !== value) {
                    if (this._bitmap) {
                        this._bitmap.returnCanvas();
                        this._bitmap._loadListeners = [];
                    }
                    this._bitmap = value;
                    if (this._bitmap) {
                        this.setFrame(0, 0, 0, 0);
                        this._bitmap.addLoadListener(this._onBitmapLoad.bind(this));
                    } else {
                        this.texture.frame = Rectangle.emptyRectangle;
                    }
                }
            },
            configurable: true
        });
        Bitmap.prototype.getPixel = function (x, y) {
            if (!this._context) {
                // この時だけ仕方なく描画。
                var cache = getCanvasCache();
                this._canvas = cache._canvas;
                this._context = cache._context;
                this.resize(this._image.width, this._image.height);
                this._context.drawImage(this._image, 0, 0);
            }
            var data = this._context.getImageData(x, y, 1, 1).data;
            var result = '#';
            for (var i = 0; i < 3; i++) {
                result += data[i].toString(16).padZero(2);
            }
            return result;
        };
        var _Bitmap_getAlphaPixel = Bitmap.prototype.getAlphaPixel;
        Bitmap.prototype.getAlphaPixel = function (x, y) {
            if (!this._context) {
                // この時だけ仕方なく描画。
                var cache = getCanvasCache();
                this._canvas = cache._canvas;
                this._context = cache._context;
                this.resize(this._image.width, this._image.height);
                this._context.drawImage(this._image, 0, 0);
            }
            return _Bitmap_getAlphaPixel.call(this, x, y);
        };
        ImageManager.loadEmptyBitmap = function () {
            var empty = this.cache.getItem('empty');
            if (!empty) {
                empty = new Bitmap(1);
                this.cache.setItem('empty', empty);
            }
            return empty;
        };
        Sprite.prototype._createTinter = function (w, h) {
            if (!this._canvas2) {
                this._canvas2 = document.createElement('canvas');
                this._context = this._canvas2.getContext('2d');
            }

            this._canvas2.width = w;
            this._canvas2.height = h;

            if (!this._tintTexture) {
                this._tintTexture = new PIXI.BaseTexture(this._canvas2);
            }

            this._tintTexture.width = w;
            this._tintTexture.height = h;
            this._tintTexture.scaleMode = this._bitmap.baseTexture.scaleMode;
        };
    }

    if (parseInt(parameters['skipSnapForBackgroundByNewGame'])) {
        /**
         * Scene_Title から newGame の選択時は、snapForBackground が不必要
         */
        Scene_Title.prototype.terminate = function () {
            Scene_Base.prototype.terminate.call(this);
            if (!SceneManager.isNextScene(Scene_Map)) {
                SceneManager.snapForBackground();
            }
        };
    }

    if (parseInt(parameters['skipSnapForBackgroundByMapChange'])) {
        /**
         * マップ切り替え時は SceneManager.snapForBackground を呼ばないようにした
         */
        Scene_Map.prototype.terminate = function () {
            Scene_Base.prototype.terminate.call(this);
            if (!SceneManager.isNextScene(Scene_Battle) && !SceneManager.isNextScene(Scene_Map)) {
                this._spriteset.update();
                this._mapNameWindow.hide();
                SceneManager.snapForBackground();
            }
            $gameScreen.clearZoom();
        };
    }

    if (parseInt(parameters['usePixiSpriteToDrawWindow_Base'])) {
        /**
         * Window の描画は drawImage が何度も走るので PIXI.Sprite で代用
         */
        Window.prototype._refreshBack = function () {
            var m = this._margin;
            var w = this._width - m * 2;
            var h = this._height - m * 2;
            var bitmap = new Bitmap(w, h);
            this._windowBackSprite.bitmap = bitmap;
            this._windowBackSprite.setFrame(0, 0, w, h);
            this._windowBackSprite.move(m, m);

            this._windowBackSprite._toneFilter = new ToneFilter();

            if (w > 0 && h > 0 && this._windowskin) {
                this._windowBackSprite.destroyAndRemoveChildren();

                var baseTexture = this.getBaseTexture();
                var p = 96;
                var texture = new PIXI.Texture(baseTexture);
                texture.frame = new PIXI.Rectangle(0, 0, p, p);
                var backSprite = new PIXI.Sprite(texture);
                backSprite.width = w;
                backSprite.height = h;
                this._windowBackSprite.addChild(backSprite);
                // bitmap.blt(this._windowskin, 0, 0, p, p, 0, 0, w, h);

                var tileTexture = new PIXI.Texture(baseTexture, new PIXI.Rectangle(0, p, p, p));
                var tilingSprite = new PIXI.extras.TilingSprite(tileTexture, w, h);
                this._windowBackSprite.addChild(tilingSprite);

                var tone = this._colorTone;
                this._windowBackSprite._toneFilter.reset();
                this._windowBackSprite._toneFilter.adjustTone(tone[0], tone[1], tone[2]);
                //bitmap.adjustTone(tone[0], tone[1], tone[2]);
            }
        };
        Window.prototype.getBaseTexture = function () {
            var baseTexture = PIXI.utils.BaseTextureCache[this._windowskin._image.src];
            if (!baseTexture) {
                baseTexture = new PIXI.BaseTexture(this._windowskin._image, PIXI.SCALE_MODES.DEFAULT);
                baseTexture.imageUrl = this._windowskin._image.src;
                PIXI.utils.BaseTextureCache[this._windowskin._image.src] = baseTexture;
            }
            return baseTexture;
        };
        Window.prototype._refreshFrame = function () {
            var w = this._width;
            var h = this._height;
            var m = 24;
            // var bitmap = new Bitmap(w, h);

            // this._windowFrameSprite.bitmap = bitmap;
            this._windowFrameSprite.setFrame(0, 0, w, h);

            if (w > 0 && h > 0 && this._windowskin) {
                // var skin = this._windowskin;
                var baseTexture = this.getBaseTexture();

                var parent = this._windowFrameSprite;
                parent.destroyAndRemoveChildren();
                var p = 96;
                var q = 96;
                this._addPixiSprite(parent, baseTexture, p + m, 0 + 0, p - m * 2, m, m, 0, w - m * 2, m);
                this._addPixiSprite(parent, baseTexture, p + m, 0 + q - m, p - m * 2, m, m, h - m, w - m * 2, m);
                this._addPixiSprite(parent, baseTexture, p + 0, 0 + m, m, p - m * 2, 0, m, m, h - m * 2);
                this._addPixiSprite(parent, baseTexture, p + q - m, 0 + m, m, p - m * 2, w - m, m, m, h - m * 2);
                this._addPixiSprite(parent, baseTexture, p + 0, 0 + 0, m, m, 0, 0, m, m);
                this._addPixiSprite(parent, baseTexture, p + q - m, 0 + 0, m, m, w - m, 0, m, m);
                this._addPixiSprite(parent, baseTexture, p + 0, 0 + q - m, m, m, 0, h - m, m, m);
                this._addPixiSprite(parent, baseTexture, p + q - m, 0 + q - m, m, m, w - m, h - m, m, m);

                // bitmap.blt(skin, p+m, 0+0, p-m*2, m, m, 0, w-m*2, m);
                // bitmap.blt(skin, p+m, 0+q-m, p-m*2, m, m, h-m, w-m*2, m);
                // bitmap.blt(skin, p+0, 0+m, m, p-m*2, 0, m, m, h-m*2);
                // bitmap.blt(skin, p+q-m, 0+m, m, p-m*2, w-m, m, m, h-m*2);
                // bitmap.blt(skin, p+0, 0+0, m, m, 0, 0, m, m);
                // bitmap.blt(skin, p+q-m, 0+0, m, m, w-m, 0, m, m);
                // bitmap.blt(skin, p+0, 0+q-m, m, m, 0, h-m, m, m);
                // bitmap.blt(skin, p+q-m, 0+q-m, m, m, w-m, h-m, m, m);
            }
        };
        Window.prototype._addPixiSprite = function (parent, baseTexture, sx, sy, sw, sh, dx, dy, dw, dh) {
            var texture = new PIXI.Texture(baseTexture);
            texture.frame = new PIXI.Rectangle(sx, sy, sw, sh);
            var sprite = new PIXI.Sprite(texture);
            sprite.width = dw;
            sprite.height = dh;
            sprite.position.x = dx;
            sprite.position.y = dy;
            parent.addChild(sprite);
        };
        Window.prototype._refreshCursor = function () {
            var pad = this._padding;
            var x = this._cursorRect.x + pad - this.origin.x;
            var y = this._cursorRect.y + pad - this.origin.y;
            var w = this._cursorRect.width;
            var h = this._cursorRect.height;
            var m = 4;
            var x2 = Math.max(x, pad);
            var y2 = Math.max(y, pad);
            var ox = x - x2;
            var oy = y - y2;
            var w2 = Math.min(w, this._width - pad - x2);
            var h2 = Math.min(h, this._height - pad - y2);
            // var bitmap = new Bitmap(w2, h2);

            // this._windowCursorSprite.bitmap = bitmap;
            this._windowCursorSprite.setFrame(0, 0, w2, h2);
            this._windowCursorSprite.move(x2, y2);
            var parent = this._windowCursorSprite;
            parent.destroyAndRemoveChildren();

            if (w > 0 && h > 0 && this._windowskin) {
                // var skin = this._windowskin;
                var p = 96;
                var q = 48;

                var baseTexture = this.getBaseTexture();

                this._addPixiSprite(parent, baseTexture, p + m, p + m, q - m * 2, q - m * 2, ox + m, oy + m, w - m * 2, h - m * 2);
                this._addPixiSprite(parent, baseTexture, p + m, p + 0, q - m * 2, m, ox + m, oy + 0, w - m * 2, m);
                this._addPixiSprite(parent, baseTexture, p + m, p + q - m, q - m * 2, m, ox + m, oy + h - m, w - m * 2, m);
                this._addPixiSprite(parent, baseTexture, p + 0, p + m, m, q - m * 2, ox + 0, oy + m, m, h - m * 2);
                this._addPixiSprite(parent, baseTexture, p + q - m, p + m, m, q - m * 2, ox + w - m, oy + m, m, h - m * 2);
                this._addPixiSprite(parent, baseTexture, p + 0, p + 0, m, m, ox + 0, oy + 0, m, m);
                this._addPixiSprite(parent, baseTexture, p + q - m, p + 0, m, m, ox + w - m, oy + 0, m, m);
                this._addPixiSprite(parent, baseTexture, p + 0, p + q - m, m, m, ox + 0, oy + h - m, m, m);
                this._addPixiSprite(parent, baseTexture, p + q - m, p + q - m, m, m, ox + w - m, oy + h - m, m, m);

                // bitmap.blt(skin, p+m, p+m, q-m*2, q-m*2, ox+m, oy+m, w-m*2, h-m*2);
                // bitmap.blt(skin, p+m, p+0, q-m*2, m, ox+m, oy+0, w-m*2, m);
                // bitmap.blt(skin, p+m, p+q-m, q-m*2, m, ox+m, oy+h-m, w-m*2, m);
                // bitmap.blt(skin, p+0, p+m, m, q-m*2, ox+0, oy+m, m, h-m*2);
                // bitmap.blt(skin, p+q-m, p+m, m, q-m*2, ox+w-m, oy+m, m, h-m*2);
                // bitmap.blt(skin, p+0, p+0, m, m, ox+0, oy+0, m, m);
                // bitmap.blt(skin, p+q-m, p+0, m, m, ox+w-m, oy+0, m, m);
                // bitmap.blt(skin, p+0, p+q-m, m, m, ox+0, oy+h-m, m, m);
                // bitmap.blt(skin, p+q-m, p+q-m, m, m, ox+w-m, oy+h-m, m, m);
            }
        };
    }

    if (parseInt(parameters['useFilterToChangePictureTone'])) {
        /**
         * 色調の変化の度に drawImage が走るのでフィルタで代用
         */
        Sprite.prototype.setColorTone = function (tone) {
            if (!(tone instanceof Array)) {
                throw new Error('Argument must be an array');
            }
            if (!this._colorTone.equals(tone)) {
                if (!this._toneFilter) {
                    this._toneFilter = new ToneFilter();
                    this.filters = [this._toneFilter];
                }
                this._colorTone = tone.clone();
                this._toneFilter.reset();
                this._toneFilter.adjustTone(tone[0], tone[1], tone[2]);
            }
        };
    }

    if (parseInt(parameters['reduceWindowInitializeProcess'])) {
        /**
         * ウィンドウの初期化で3回 _refreshAllParts が走るので1回にまとめた
         */
        var _Window_Base_initialize = Window_Base.prototype.initialize;
        Window_Base.prototype.initialize = function (x, y, width, height) {
            this._initializing = true;
            _Window_Base_initialize.call(this, x, y, width, height);
            this._initializing = false;
            this._refreshAllParts();
        };
        var _Window__refreshAllParts = Window.prototype._refreshAllParts;
        Window.prototype._refreshAllParts = function () {
            if (this._initializing) {
                return;
            }
            _Window__refreshAllParts.call(this);
        };
    }

    if (parseInt(parameters['alternateBitmapClearMethod'])) {
        /**
         * Chromium の clearRect は遅い
         */
        Bitmap.prototype.clear = function () {
            this._canvas.width = this._canvas.width;    // 裏技
            this._setDirty();
            //this.clearRect(0, 0, this.width, this.height);
        };
    }

    if (parseInt(parameters['usePixiSpriteToDrawIcon'])) {
        /**
         * drawIcon では drawImage が行われるので PIXI.Sprite で代用
         */
        Window_Base.prototype.drawIcon = function (iconIndex, x, y) {
            var baseTexture = PIXI.utils.BaseTextureCache['system/IconSet'];
            if (!baseTexture) {
                var bitmap = ImageManager.loadSystem('IconSet');
                if (!bitmap.isReady()) {
                    return;
                }
                baseTexture = new PIXI.BaseTexture(bitmap._image, PIXI.SCALE_MODES.DEFAULT);
                baseTexture.imageUrl = 'system/IconSet';
                PIXI.utils.BaseTextureCache['system/IconSet'] = baseTexture;
            }

            var pw = Window_Base._iconWidth;
            var ph = Window_Base._iconHeight;
            var sx = iconIndex % 16 * pw;
            var sy = Math.floor(iconIndex / 16) * ph;

            var texture = new PIXI.Texture(baseTexture);
            texture.frame = new PIXI.Rectangle(sx, sy, pw, ph);
            var sprite = new PIXI.Sprite(texture);
            sprite.position.x = x;
            sprite.position.y = y;
            sprite.alpha = this.contents.paintOpacity / 255.0;
            this._windowContentsSprite.addChild(sprite);

            // this.contents.blt(bitmap, sx, sy, pw, ph, x, y);
        };
    }

    if (parseInt(parameters['usePixiSpriteToDrawFace'])) {
        /**
         * drawFace では drawImage が行われるので PIXI.Sprite で代用
         */
        Window_Base.prototype.drawFace = function (faceName, faceIndex, x, y, width, height) {
            if (!faceName) {
                return;
            }
            width = width || Window_Base._faceWidth;
            height = height || Window_Base._faceHeight;

            var baseTexture = PIXI.utils.BaseTextureCache['face/' + faceName];
            if (!baseTexture) {
                var bitmap = ImageManager.loadFace(faceName);
                if (!bitmap.isReady()) {
                    return;
                }
                baseTexture = new PIXI.BaseTexture(bitmap._image, PIXI.SCALE_MODES.DEFAULT);
                baseTexture.imageUrl = 'face/' + faceName;
                PIXI.utils.BaseTextureCache['face/' + faceName] = baseTexture;
            }

            var pw = Window_Base._faceWidth;
            var ph = Window_Base._faceHeight;
            var sw = Math.min(width, pw);
            var sh = Math.min(height, ph);
            var dx = Math.floor(x + Math.max(width - pw, 0) / 2);
            var dy = Math.floor(y + Math.max(height - ph, 0) / 2);
            var sx = faceIndex % 4 * pw + (pw - sw) / 2;
            var sy = Math.floor(faceIndex / 4) * ph + (ph - sh) / 2;

            if (sx + sw > baseTexture.width || sy + sh > baseTexture.height) {
                console.error(faceName + ' グラフィックの描画領域が画像サイズをはみ出しています');
                return;
            }
            var texture = new PIXI.Texture(baseTexture);
            texture.frame = new PIXI.Rectangle(sx, sy, sw, sh);
            var sprite = new PIXI.Sprite(texture);
            sprite.position.x = dx;
            sprite.position.y = dy;
            sprite.alpha = this.contents.paintOpacity / 255.0;
            this._windowContentsSprite.addChild(sprite);

            //this.contents.blt(bitmap, sx, sy, sw, sh, dx, dy);
        };
    }

    if (parseInt(parameters['usePixiSpriteToDrawCharacter'])) {
        /**
         * drawCharacter では drawImage が行われるので PIXI.Sprite で代用
         */
        Window_Base.prototype.drawCharacter = function (characterName, characterIndex, x, y) {
            if (!characterName) {
                return;
            }
            var baseTexture = PIXI.utils.BaseTextureCache['character/' + characterName];
            if (!baseTexture) {
                var bitmap = ImageManager.loadCharacter(characterName);
                if (!bitmap.isReady()) {
                    return;
                }
                baseTexture = new PIXI.BaseTexture(bitmap._image, PIXI.SCALE_MODES.DEFAULT);
                baseTexture.imageUrl = 'character/' + characterName;
                PIXI.utils.BaseTextureCache['character/' + characterName] = baseTexture;
            }

            var big = ImageManager.isBigCharacter(characterName);
            var pw = baseTexture.width / (big ? 3 : 12);
            var ph = baseTexture.height / (big ? 4 : 8);
            var n = characterIndex;
            var sx = (n % 4 * 3 + 1) * pw;
            var sy = (Math.floor(n / 4) * 4) * ph;

            var texture = new PIXI.Texture(baseTexture);
            texture.frame = new PIXI.Rectangle(sx, sy, pw, ph);
            var sprite = new PIXI.Sprite(texture);
            sprite.position.x = x - pw / 2;
            sprite.position.y = y - ph;
            this._windowContentsSprite.addChild(sprite);

            //this.contents.blt(bitmap, sx, sy, pw, ph, x - pw / 2, y - ph);
        };
    }

    if (parseInt(parameters['usePixiSpriteToDrawIcon']) ||
        parseInt(parameters['usePixiSpriteToDrawFace']) ||
        parseInt(parameters['usePixiSpriteToDrawCharacter'])) {
        /**
         * drawXXX 系を PIXI.Sprite で代用するときに必要なもの
         */
        Bitmap.prototype.setClearHandler = function (onClear) {
            this.onClear = onClear;
        };
        var _Bitmap_clear = Bitmap.prototype.clear;
        Bitmap.prototype.clear = function () {
            _Bitmap_clear.call(this);
            if (this.onClear) {
                this.onClear();
            }
        };
        var _Window_Base_createContents = Window_Base.prototype.createContents;
        Window_Base.prototype.createContents = function () {
            _Window_Base_createContents.call(this);
            this.contents.setClearHandler(this.onClearContents.bind(this));
            this.contents.clear();
        };
        var _Window_Base_destroy = Window_Base.prototype.destroy;
        Window_Base.prototype.destroy = function (options) {
            if (this.contents && this.contents.onClear) {
                this.contents.onClear = null;
            }
            _Window_Base_destroy.call(this, options);
        };

        Window_Base.prototype.onClearContents = function () {
            // PIXI.Sprite を消去
            this._windowContentsSprite.destroyAndRemoveChildren();
        };
    }

    if (parseInt(parameters['usePixiGraphicsToDrawMenuBg'])) {
        /**
         * メニュー背景の描画を PIXI.Graphics で代用する
         */
        Window_MenuStatus.prototype.drawItemBackground = function (index) {
            if (index === this._pendingIndex) {
                var rect = this.itemRect(index);
                var color = this.pendingColor();
                var graphics = new PIXI.Graphics();
                graphics.beginFill(color, this.translucentOpacity() / 255.0);
                graphics.drawRect(rect.x, rect.y, rect.width, rect.height);
                this.addChild(graphics);
                // this.changePaintOpacity(false);
                // this.contents.fillRect(rect.x, rect.y, rect.width, rect.height, color);
                // this.changePaintOpacity(true);
            }
        };
    }

    if (parseInt(parameters['skipUnnecessaryRefresh'])) {
        /**
         * 以下のウィンドウの初期化時の refresh() は不要
         */
        Window_MapName.prototype.initialize = function () {
            var wight = this.windowWidth();
            var height = this.windowHeight();
            Window_Base.prototype.initialize.call(this, 0, 0, wight, height);
            this.opacity = 0;
            this.contentsOpacity = 0;
            this._showCount = 0;
            // this.refresh();
        };
        Window_BattleEnemy.prototype.initialize = function (x, y) {
            this._enemies = [];
            var width = this.windowWidth();
            var height = this.windowHeight();
            Window_Selectable.prototype.initialize.call(this, x, y, width, height);
            // this.refresh();
            this.hide();
        };
    }

    if (parseInt(parameters['lazyInitializationBitmapAtSprite_Timer'])) {
        /**
         * タイマーを表示する必要があるまでタイマーの Bitmap を作成しない。
         */
        Sprite_Timer.prototype.initialize = function () {
            Sprite.prototype.initialize.call(this);
            this._seconds = 0;
            // this.createBitmap();
            this.update();
        };
        var _Sprite_Timer_redraw = Sprite_Timer.prototype.redraw;
        Sprite_Timer.prototype.redraw = function () {
            if (!this._bitmap) {
                this.createBitmap();
            }
            _Sprite_Timer_redraw.call(this);
        };
        var _Sprite_Timer_updatePosition = Sprite_Timer.prototype.updatePosition;
        Sprite_Timer.prototype.updatePosition = function () {
            if (!this._bitmao) {
                return;
            }
            _Sprite_Timer_updatePosition.call(this);
        };
    }

    if (parseInt(parameters['lazyInitializationWeather'])) {
        /**
         * 天気を表示する直前まで Bitmap を作成しない
         */
        Weather.prototype._createBitmaps = function () {
            // this._rainBitmap = new Bitmap(1, 60);
            // this._rainBitmap.fillAll('white');
            // this._stormBitmap = new Bitmap(2, 100);
            // this._stormBitmap.fillAll('white');
            // this._snowBitmap = new Bitmap(9, 9);
            // this._snowBitmap.drawCircle(4, 4, 4, 'white');
        };
        var _Weather_updateRainSprite = Weather.prototype._updateRainSprite;
        Weather.prototype._updateRainSprite = function (sprite) {
            if (!this._rainBitmap) {
                this._rainBitmap = new Bitmap(1, 60);
                this._rainBitmap.fillAll('white');
            }
            _Weather_updateRainSprite.call(this, sprite);
        };

        var _Weather__updateStormSprite = Weather.prototype._updateStormSprite;
        Weather.prototype._updateStormSprite = function (sprite) {
            if (!this._stormBitmap) {
                this._stormBitmap = new Bitmap(2, 100);
                this._stormBitmap.fillAll('white');
            }
            _Weather__updateStormSprite.call(this, sprite);
        };

        var _Weather_updateSnowSprite = Weather.prototype._updateSnowSprite;
        Weather.prototype._updateSnowSprite = function (sprite) {
            if (!this._snowBitmap) {
                this._snowBitmap = new Bitmap(9, 9);
                this._snowBitmap.drawCircle(4, 4, 4, 'white');
            }
            _Weather_updateSnowSprite.call(this, sprite);
        };
    }

    if (parseInt(parameters['lazyCreationWindow_MapName'])) {
        /**
         * Window_MapName は、open() が呼ばれて、かつマップ名を表示する必要があるまで作成しない。
         * window 順がずれる可能性あり（最前面になる）
         */
        var _Scene_Map_createMapNameWindow = Scene_Map.prototype.createMapNameWindow;
        Scene_Map.prototype.createMapNameWindow = function () {
            var self = this;
            // dummy
            this._mapNameWindow = {
                hide: function () { },
                close: function () { },
                open: function () {
                    if ($gameMap.displayName()) {
                        _Scene_Map_createMapNameWindow.call(self);
                        self._mapNameWindow.open();
                    }
                }
            };
            // this._mapNameWindow = new Window_MapName();
            // this.addChild(this._mapNameWindow);
        };
    }

    if (parseInt(parameters['lazyCreationWindow_ScrollText'])) {
        /**
         * Scene_Map の Window_ScrollText は、必要になるまで作成しない。
         */
        var _Scene_Map_createScrollTextWindow = Scene_Map.prototype.createScrollTextWindow;
        Scene_Map.prototype.createScrollTextWindow = function () {
            // this._scrollTextWindow = new Window_ScrollText();
            // this.addWindow(this._scrollTextWindow);
        };
        var _Scene_Map_update = Scene_Map.prototype.update;
        Scene_Map.prototype.update = function () {
            if ($gameMessage.scrollMode()) {
                if (!this._scrollTextWindow) {
                    _Scene_Map_createScrollTextWindow.call(this);
                }
            }
            _Scene_Map_update.call(this);
        };

        /**
         * Scene_Battle の Window_ScrollText は、必要になるまで作成しない。
         */
        var _Scene_Battle_createScrollTextWindow = Scene_Battle.prototype.createScrollTextWindow;
        Scene_Battle.prototype.createScrollTextWindow = function () {
            // this._scrollTextWindow = new Window_ScrollText();
            // this.addWindow(this._scrollTextWindow);
        };
        var _Scene_Battle_update = Scene_Battle.prototype.update;
        Scene_Battle.prototype.update = function () {
            if ($gameMessage.scrollMode()) {
                if (!this._scrollTextWindow) {
                    _Scene_Battle_createScrollTextWindow.call(this);
                }
            }
            _Scene_Battle_update.call(this);
        };
    }

    if (parseInt(parameters['useSpriteToDrawSprite_Destination'])) {
        /**
         * 行き先を表示するスプライトは PIXI.Texture を使う
         */
        Sprite_Destination.prototype.createBitmap = function () {
            var tileWidth = $gameMap.tileWidth();
            var tileHeight = $gameMap.tileHeight();

            var bitmap = ImageManager.loadSystem('Window');
            baseTexture = new PIXI.BaseTexture(bitmap._image, PIXI.SCALE_MODES.DEFAULT);
            var texture = new PIXI.Texture(baseTexture);
            texture.frame = new PIXI.Rectangle(96, 144, 12, 12);
            this.texture = texture;

            this.anchor.x = 0.5;
            this.anchor.y = 0.5;
            this.blendMode = Graphics.BLEND_ADD;
        };
        Sprite_Destination.prototype.updateAnimation = function () {
            this._frameCount++;
            this._frameCount %= 20;
            this.opacity = (20 - this._frameCount) * 6;
            this.scale.x = (1 + this._frameCount / 20) * 4;
            this.scale.y = this.scale.x;
        };
    }

    if (parseInt(parameters['skipWindow_CommandFirstCreateContents'])) {
        /**
         * Window_Command の初回の createContents は必ず無駄になるのでスキップ
         */
        var _Window_Command_createContents = Window_Command.prototype.createContents;
        Window_Command.prototype.createContents = function () {
            // this.contents = new Bitmap(this.contentsWidth(), this.contentsHeight());
            // this.resetFontSettings();
        };
        Window_Command.prototype.refresh = function () {
            this.clearCommandList();
            this.makeCommandList();
            _Window_Command_createContents.call(this);
            Window_Selectable.prototype.refresh.call(this);
        };
    }

    if (parseInt(parameters['useDefaultTextColor'])) {
        /**
         * テキストカラーを定義しておくことで、pixel を調べずにテキストカラーを取得する
         * @param  {[type]} n [description]
         * @return {[type]}   [description]
         */
        Window_Base.prototype.textColor = function (n) {
            switch (n) {
                case 0: return '#ffffff';
                case 1: return '#20a0d6';
                case 2: return '#ff784c';
                case 3: return '#66cc40';
                case 4: return '#99ccff';
                case 5: return '#ccc0ff';
                case 6: return '#ffffa0';
                case 7: return '#808080';
                case 8: return '#c0c0c0';
                case 9: return '#2080cc';
                case 10: return '#ff3810';
                case 11: return '#00a010';
                case 12: return '#3e9ade';
                case 13: return '#a098ff';
                case 14: return '#ffcc20';
                case 15: return '#000000';
                case 16: return '#84aaff';
                case 17: return '#ffff40';
                case 18: return '#ff2020';
                case 19: return '#202040';
                case 20: return '#e08040';
                case 21: return '#f0c040';
                case 22: return '#4080c0';
                case 23: return '#40c0f0';
                case 24: return '#80ff80';
                case 25: return '#c08080';
                case 26: return '#8080ff';
                case 27: return '#ff80ff';
                case 28: return '#00a040';
                case 29: return '#00e060';
                case 30: return '#a060e0';
                case 31: return '#c080ff';
            }
            return '#000000';
        };
    }

    if (parseInt(parameters['reduceLoadingGlobalInfo'])) {
        /**
         * タイトル、セーブ画面、ロード画面で loadingGlobalInfo が何度も走るので減らす
         */
        var _Scene_File_initialize = Scene_File.prototype.initialize;
        Scene_File.prototype.initialize = function () {
            this._globalInfo = DataManager.loadGlobalInfo();
            _Scene_File_initialize.call(this);
        };
        Scene_File.prototype.create = function () {
            Scene_MenuBase.prototype.create.call(this);
            DataManager.loadAllSavefileImages(this._globalInfo);
            this.createHelpWindow();
            this.createListWindow();
        };
        Scene_Load.prototype.firstSavefileIndex = function () {
            return DataManager.latestSavefileId(this._globalInfo) - 1;
        };

        var _Window_SavefileList_initialize = Window_SavefileList.prototype.initialize;
        Window_SavefileList.prototype.initialize = function (x, y, width, height) {
            this._globalInfo = DataManager.loadGlobalInfo();

            _Window_SavefileList_initialize.call(this, x, y, width, height);
        };
        Window_SavefileList.prototype.drawItem = function (index) {
            var id = index + 1;
            var valid = DataManager.isThisGameFileInfo(this._globalInfo[id]);
            var info = this._globalInfo[id] ? this._globalInfo[id] : null;
            var rect = this.itemRectForText(index);
            this.resetTextColor();
            if (this._mode === 'load') {
                this.changePaintOpacity(valid);
            }
            this.drawFileId(id, rect.x, rect.y);
            if (info) {
                this.changePaintOpacity(valid);
                this.drawContents(info, rect, valid);
                this.changePaintOpacity(true);
            }
        };
        DataManager.loadAllSavefileImages = function (globalInfo) {
            if (!globalInfo) {
                globalInfo = this.loadGlobalInfo();
            }
            if (globalInfo) {
                for (var i = 1; i < globalInfo.length; i++) {
                    var info = globalInfo[i];
                    if (this.isThisGameFileInfo(info)) {
                        this.loadSavefileImages(info);
                    }
                }
            }
        };
        DataManager.isThisGameFileInfo = function (savefile) {
            if (!savefile) {
                return false;
            }
            if (StorageManager.isLocalMode()) {
                return true;
            }
            return (savefile.globalId === this._globalId &&
                savefile.title === $dataSystem.gameTitle);
        };
        DataManager.isAnySavefileExists = function (globalInfo) {
            if (!globalInfo) {
                globalInfo = this.loadGlobalInfo();
            }
            if (globalInfo) {
                for (var i = 1; i < globalInfo.length; i++) {
                    var info = globalInfo[i];
                    if (this.isThisGameFileInfo(info)) {
                        return true;
                    }
                }
            }
            return false;
        };
        DataManager.latestSavefileId = function (globalInfo) {
            if (!globalInfo) {
                globalInfo = this.loadGlobalInfo();
            }
            var savefileId = 1;
            var timestamp = 0;
            if (globalInfo) {
                for (var i = 1; i < globalInfo.length; i++) {
                    var info = globalInfo[i];
                    if (this.isThisGameFileInfo(info) && info.timestamp > timestamp) {
                        timestamp = info.timestamp;
                        savefileId = i;
                    }
                }
            }
            return savefileId;
        };
        Window_TitleCommand.prototype.isContinueEnabled = function () {
            if (!this._globalInfo) {
                this._globalInfo = DataManager.loadGlobalInfo();
            }
            return DataManager.isAnySavefileExists(this._globalInfo);
        };
    }

    if (parseInt(parameters['notLoadingVolumeZeroAudio'])) {
        var _AudioManager_playSe = AudioManager.playSe;
        AudioManager.playSe = function (se) {
            if (this._seVolume <= 0) {
                return;
            }
            _AudioManager_playSe.call(this, se);
        };
        var _AudioManager_playStaticSe = AudioManager.playStaticSe;
        AudioManager.playStaticSe = function (se) {
            if (this._seVolume <= 0) {
                return;
            }
            _AudioManager_playStaticSe.call(this, se);
        };
        var _AudioManager_playMe2 = AudioManager.playMe;
        AudioManager.playMe = function (me, isCache) {
            if (this._meVolume <= 0) {
                return;
            }
            _AudioManager_playMe2.call(this, me, isCache);
        };
        var _AudioManager_playBgs = AudioManager.playBgs;
        AudioManager.playBgs = function (bgs, pos) {
            if (this._bgsVolume <= 0) {
                this.stopBgs();
                return;
            }
            _AudioManager_playBgs.call(this, bgs, pos);
        };
        var _AudioManager_playBgm = AudioManager.playBgm;
        AudioManager.playBgm = function (bgm, pos) {
            if (this._bgmVolume <= 0) {
                this._lastVolumeZeroBgm = bgm;
                return;
            }
            _AudioManager_playBgm.call(this, bgm, pos);
        };
        var _AudioManager_stopBgm = AudioManager.stopBgm;
        AudioManager.stopBgm = function () {
            this._lastVolumeZeroBgm = null;
            _AudioManager_stopBgm.call(this);
        };
        Object.defineProperty(AudioManager, 'bgmVolume', {
            set: function (value) {
                if (this._bgmVolume <= 0 && value > 0 && this._lastVolumeZeroBgm) {
                    this._bgmVolume = value;
                    this.playBgm(this._lastVolumeZeroBgm, 0);
                    this._lastVolumeZeroBgm = null;
                } else {
                    this._bgmVolume = value;
                    this.updateBgmParameters(this._currentBgm);
                }
            },
            configurable: true
        });
    }

    if (parseInt(parameters['usePixiByWindow_BattleLogBg'])) {
        Window_BattleLog.prototype.createBackBitmap = function () {
        };

        Window_BattleLog.prototype.createBackSprite = function () {
            this._backSprite = new Sprite();
            this._backSprite.y = this.y;
            this.addChildToBack(this._backSprite);
        };
        Window_BattleLog.prototype.drawBackground = function () {
            var rect = this.backRect();
            var color = this.backColor();

            var graphics = new PIXI.Graphics();
            graphics.beginFill(Saba.toPixiColor(color), this.backPaintOpacity() / 255 / 0);
            graphics.drawRect(rect.x, rect.y, rect.width, rect.height);
            graphics.endFill();
            this._backSprite.addChild(graphics);
        };
    }

    var _Sprite_refresh = Sprite.prototype._refresh;
    Sprite.prototype._refresh = function () {
        if (!this.texture) {
            return;
        }
        _Sprite_refresh.call(this);
    };

})(Saba || (Saba = {}));