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

/*:
 * @plugindesc 自動マップ生成 1.1.9
 * 自動的にマップを生成しイベントを配置します。
 * @author サンシロ https://twitter.com/rev2nym
 *
 * @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
 *
 * @help
 * ■概要
 * マップ生成プラグインコマンドを実行するとマップが自動生成され
 * プレイヤーが入口イベントの地点に移動します。
 *
 * ■設定
 * ツクールMVのエディタ上でベースとなるマップの下記の座標に
 * タイルとイベントを配置して下さい。
 *
 * ・タイル
 *  空白:{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
 *  マップ全体に及ぶ一つの部屋を生成します。
 *
 * ■スクリプトコマンド
 * ・Game_Character.prototype.isSameRoomWithPlayer()
 *  キャラクターのプレイヤーとの同部屋判定です。
 *  例：条件分岐イベントコマンドのスクリプト欄に
 *      「this.character().isSameRoomWithPlayer()」
 *      と記述するとそのイベントがプレイヤーと同じ部屋に
 *      存在するか判定します。
 *
 * ・Game_Map.prototype.pickel()
 *  ツルハシコマンドです。
 *  プレイヤーの正面の非地面タイルを通路タイルに変換します。
 *  このコマンドは自動生成マップ内のみ有効です。
 *  例：コモンイベントのスクリプトコマンドに
 *     「$gameMap.pickel()」
 *      と記述して実行すると正面の壁を掘ることができます。
 *
 * ・Game_Map.prototype.bomb(x, y)
 *  バクダンコマンドです。
 *  指定した座標と周囲の9タイルの非地面タイルを通路タイルに変換します。
 *  このコマンドは自動生成マップ内のみ有効です。
 *  例：コモンイベントのスクリプトコマンドに
 *      「$gameMap.bomb($gamePlayer.x, $gamePlayer.y)」
 *      と記述して実行するとプレイヤーの周囲の壁を取り除くことができます。
 *
 * ・Game_Map.prototype.makeWall(x, y)
 *  壁生成コマンドです。
 *  指定した座標の地面タイルを壁(瓦礫)タイルに変換します。
 *  このコマンドは自動生成マップ内のみ有効です。
 *  例：コモンイベントのスクリプトコマンドに
 *      「var x = $gamePlayer.x;
 *        var y = $gamePlayer.y;
 *        var d = $gamePlayer.direction();
 *        $gameMap.makeWall(
 *            $gameMap.xWithDirection(x, d),
 *            $gameMap.yWithDirection(y, d)
 *        );」
 *      と記述して実行するとプレイヤーの正面に壁を設置することができます。
 *
 * ・Game_Map.prototype.bigRoom()
 *  大部屋コマンドです。
 *  マップ全体に及ぶ一つの部屋を生成します。
 *  このコマンドは自動生成マップ内のみ有効です。
 *  例：コモンイベントのスクリプトコマンドに
 *     「$gameMap.bigRoom()」
 *      と記述して実行すると大部屋を生成します。
 *
 * ■利用規約
 * MITライセンスのもと、商用利用、改変、再配布が可能です。
 * ただし冒頭のコメントは削除や改変をしないでください。
 * よかったらクレジットに作者名を記載してください。
 *
 * これを利用したことによるいかなる損害にも作者は責任を負いません。
 * サポートは期待しないでください＞＜。
 *
 */

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 = [undefined];
  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.isWall = function (x, y) {
  if (!this._symbolMap[x] || !this._symbolMap[x][y]) {
    return false;
  }
  return this._symbolMap[x][y] === "wall";
};

// シンボルマップ生成
Game_MapGenerator.prototype.generateMap = function () {
  var block = {
    x: 1,
    y: 1,
    w: $dataMap.width - 2,
    h: $dataMap.height - 2,
  };
  var room = {
    x: block.x + 2,
    y: block.y + 2 + this._wallHeight,
    w: block.w - 4,
    h: block.h - 4 - this._wallHeight * 2,
    hasPass: { t: false, b: false, l: false, r: false },
  };
  this._blocks = [block];
  this._rooms = [room];
  this._passes = [];
  this.initSymbolMap();
  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";
    }
  }
};

// イベントの設置
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 >= 0; x--) {
    for (var y = this._symbolMap[x].length - 1; y >= 0; 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.isGround(x, y - wH)) {
        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.isGround(x, y + wH) && !this.isWall(x, y)) {
        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) {
  var baseTileId = this._symbolTable[this._symbolMap[x][y]].baseTileId[z];
  if (x < 0 || x >= $dataMap.width || y < 0 || y >= $dataMap.height) {
    return undefined;
  } else if (z === 4) {
    return this.shadow(x, y);
  } else if (!Tilemap.isAutotile(baseTileId)) {
    return baseTileId;
  }
  var candidateTileIds = [];
  if (!Tilemap.isWallSideTile(baseTileId)) {
    // 壁以外の場合
    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; // マップ範囲外なら判定しない
      }
      var roundTileId =
        this._symbolTable[this._symbolMap[dx][dy]].baseTileId[z];
      if (Tilemap.isSameKindTile(baseTileId, roundTileId)) {
        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; // マップ範囲外なら判定しない
      }
      var roundTileId =
        this._symbolTable[this._symbolMap[dx][dy]].baseTileId[z];
      if (Tilemap.isSameKindTile(baseTileId, roundTileId)) {
        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; // マップ範囲外なら判定しない
      }
      var upperSideTileId =
        this._symbolTable[this._symbolMap[dx][ty]].baseTileId[z];
      var downerSideTileId =
        this._symbolTable[this._symbolMap[dx][by]].baseTileId[z];
      if (
        (Tilemap.isWallTile(upperSideTileId) ||
          Tilemap.isRoofTile(upperSideTileId)) &&
        (Tilemap.isWallTile(downerSideTileId) ||
          Tilemap.isRoofTile(downerSideTileId))
      ) {
        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.isSameKindTileSymbol = function (symbol1, symbol2) {
  return Tilemap.isSameKindTile(symbol1, symbol2);
};

// 影の算出
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.notGroundToPass = function (x, y) {
  var wH = this._wallHeight;
  if (x < 2 || $gameMap.width() - 2 <= x) {
    return;
  }
  if (y < wH + 2 || $gameMap.height() - wH - 2 <= y) {
    return;
  }
  if (!this.isGround(x, y)) {
    this._symbolMap[x][y] = "pass";
  }
};

// ツルハシ(プレイヤーの前方1タイルを通路タイルに変換)
Game_MapGenerator.prototype.pickel = function () {
  this.notGroundToPass(
    $gameMap.xWithDirection($gamePlayer.x, $gamePlayer.direction()),
    $gameMap.yWithDirection($gamePlayer.y, $gamePlayer.direction())
  );
  this.refreshWallAndRoof();
  this.makeData();
  if (Imported.SAN_AnalogMove) {
    Game_CollideMap.setup();
  }
};

// バクダン(指定座標と周囲の計9タイルを通路タイルに変換)
Game_MapGenerator.prototype.bomb = function (x, y) {
  for (var x2 = x - 1; x2 <= x + 1; x2++) {
    for (var y2 = y - 1; y2 <= y + 1; y2++) {
      this.notGroundToPass(x2, y2);
    }
  }
  this.refreshWallAndRoof();
  this.makeData();
  if (Imported.SAN_AnalogMove) {
    Game_CollideMap.setup();
  }
};

// 大部屋
Game_MapGenerator.prototype.bigRoom = function () {
  Game_MapGenerator.prototype.generateMap.call(this);
  this.refreshWallAndRoof();
  this.makeData();
  if (Imported.SAN_AnalogMove) {
    Game_CollideMap.setup();
  }
};

// 指定したタイルを空白タイルに変換
Game_MapGenerator.prototype.anyToSpace = function (x, y) {
  if (x < 0 || $gameMap.width() <= x) {
    return;
  }
  if (y < 0 || $gameMap.height() <= y) {
    return;
  }
  this._symbolMap[x][y] = "space";
};

// 壁生成
Game_MapGenerator.prototype.makeWall = function (x, y) {
  this.anyToSpace(x, y);
  this.refreshWallAndRoof();
  this.makeData();
  if (Imported.SAN_AnalogMove) {
    Game_CollideMap.setup();
  }
};

// マップデータ
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);
};

//-----------------------------------------------------------------------------
// 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,
    w: $dataMap.width - 2,
    h: $dataMap.height - 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) {
  for (i = 0; i < this._rooms.length; i++) {
    var room = this._rooms[i];
    if (
      room.x <= x &&
      x < room.x + room.w &&
      room.y <= y &&
      y < room.y + room.h
    ) {
      return room;
    }
  }
  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);
};

// マップジェネレーターの取得
Game_Map.prototype.mapGenerator = function () {
  return this._mapGenerator;
};

// マップクラスのセットアップ
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_Map.prototype.pickel = function () {
  if (this.isGenegratedMap()) {
    this._mapGenerator.pickel();
  }
};

// バクダン
Game_Map.prototype.bomb = function (x, y) {
  if (this.isGenegratedMap()) {
    this._mapGenerator.bomb(x, y);
  }
};

// 大部屋
Game_Map.prototype.bigRoom = function () {
  if (this.isGenegratedMap()) {
    this._mapGenerator.bigRoom();
  }
};

// 壁生成
Game_Map.prototype.makeWall = function (x, y) {
  if (this.isGenegratedMap()) {
    this._mapGenerator.makeWall(x, y);
  }
};

//-----------------------------------------------------------------------------
// Game_Character
//
// キャラクタークラス

Game_Character.prototype.currentRoom = function () {
  if (
    !$gameMap.isGenegratedMap ||
    !($gameMap.mapGenerator() instanceof Game_MapGeneratorRoomAndPass)
  ) {
    return undefined;
  }
  return $gameMap.mapGenerator().roomByXY(this.x, this.y);
};

// プレイヤーと同部屋判定
Game_Character.prototype.isSameRoomWithPlayer = function () {
  if ($gameMap.mapGenerator().constructor === Game_MapGenerator) {
    return true;
  }
  var room1 = this.currentRoom();
  var room2 = $gamePlayer.currentRoom();
  return !!room1 && !!room2 && room1 === room2;
};

//-----------------------------------------------------------------------------
// 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") {
    switch (args[0]) {
      case "FillRoom":
        $gameMap.generateMap(args[0]);
        break;
      case "RoomAndPass":
        $gameMap.generateMap(args[0]);
        break;
    }
  }
};


code:
//=============================================================================
// SNH_MsgNameLabel.js
//=============================================================================

/*:
 * @plugindesc Change something.
 * @author Gabacho
 *
 * @help OMG! Sory. I can not write a English. Because I am Japanese!
 *
 * This plugin is released under the MIT License.
 */

/*:ja
 * @plugindesc メッセージ名前ラベルプラグイン
 * @author ガバチョ（溟犬一六）(https:/star-write-dream.com)
 * @help プラグインコマンドはありません。
 * このプラグインはMITライセンスです。
 * ----------------------------------------------------------------------------
 *
 * 文章の表示をする時、指定した名前を表示します。
 * 文字と背景（ネームプレート）の色、サイズ、位置を設定できます。
 *
 * また飾りつけ用に四角形・円を複数描画できます。
 * 画像ファイルも追加可能です。
 *
 * ----------------------------------------------------------------------------
 *
 * ■使い方
 * メッセージ内に「\nl<名前>」と入れると「名前」が表示されます。
 *
 * ----------------------------------------------------------------------------
 * ☆パラメーター設定の前に
 *
 * ○位置調整
 * デフォルト値は、顔グラフィックの下側に表示する設定になっています。
 * 名前文字の0位置はメッセージウィンドウの左上、
 * 追加部品の0位置は名前文字の左上です。
 *
 * ○ネームプレート
 * 名前文字の背景として使う四角形です。
 * 表示したくない場合は以下の設定で透明にできます。
 * ・gradationMode：false
 * ・color1のopacity：0
 *
 *
 * ○必須項目
 * 「文字サイズ」から「ネームプレート」までが必須です。
 * 「追加四角部品」から下はデータなしでかまいません。
 * ※「ネームプレート」は初期データが入っていませんので、
 *   手動で登録してください。
 *
 *
 * ○入力方法
 * 「ネームプレート」「追加四角部品」「追加円部品」
 * 「追加ネームプレート画像」「追加画像部品」は、ダブルクリックすると子画面が出てきます。
 * 子画面で「行」をダブルクリックすると、中身を登録できます。
 * 「行」は何件も登録できます。
 * ただし、「ネームプレート」と「追加ネームプレート画像」は１行目だけ使用されます。
 *
 * ----------------------------------------------------------------------------
 *
 * ☆パラメータ説明
 *   入力画面の下側に表示される説明を読んでください。
 *   補足が必要なものだけ記載します。
 *
 * ■文字サイズ自動調整（初期値:ON）
 * ネームプレートのwidthが0の場合、OFFで動作します。
 *
 * 【ネームプレート】
 * 一番奥に表示されます。
 * 表示順を設定できる文字・部品より手前には表示できません。
 * 見せたくない場合は以下の設定で透明にしてください。
 * ・color1のopasity:0
 * ・gradationMode:OFF（false）
 *
 * ■width（初期値:144）
 * 0だと文字の長さに合わせて伸び縮みします。
 *
 * ■文字の寄せ方（縦）
 * 中央寄せ、下寄せにしたい時は、
 * ネームプレートの高さに余裕をもたせてください。
 *
 * 【追加ネームプレート画像】
 * ネームプレートのすぐ手前に表示されます。
 * 表示順を設定できる文字・部品より手前には表示できません。
 *
 * ■autoScaleMode
 * ONにすると、文字の長さに合わせて横方向に伸び縮みします。
 * （scaleXが、名前の長さに合わせて自動設定されるイメージです）
 *
 * ----------------------------------------------------------------------------
 *
 * ☆こんな時はどうする？
 *
 * ■名前とネームプレートの位置をずらしたい
 *  ネームプレートを透明にして、四角部品を使ってください。
 *  ただし、四角部品は文字の長さによる伸び縮みはできません。
 *
 *
 * ■ネームプレート画像を使う時、文字の「寄せ方」がずれる気がする
 *  文字の寄せ方は、「ネームプレート」の幅、高さを相手にしています。
 *  まずは「ネームプレート画像」の幅・高さを調べて、
 *  「ネームプレート」のwidth・heightに設定してください。
 *  その後は目視確認をしながら、
 *  「ネームプレート画像」のpositionXとposionYの値を使って調整してください。
 *
 *
 * ■名前ラベルをメッセージウィンドウの上にはみ出させると、
 *  ウィンドウ位置「上」の時画面外に出てしまう。
 * 「SNH_MessageWindowPosition.js」を使うと、
 * メッセージウィンドウの上下位置を調整できるようになります。
 *
 * ----------------------------------------------------------------------------
 *
 * @param 文字サイズ
 * @type number
 * @desc 名前ラベルのフォントサイズを指定。（初期値：24）
 * @default 24
 *
 * @param 文字サイズ自動調整
 * @type boolean
 * @desc ON:ネームプレートに収まるように文字サイズを自動調整します。 OFF:設定した文字サイズのままで表示します。
 * @default true
 *
 * @param 文字色
 * @type number
 * @desc 名前ラベルの文字色を指定。数値と色の対応は、メッセージの文字色指定と同じ。（初期値：17）
 * @default 17
 * @min 0
 * @max 31
 *
 * @param 文字フチ色
 * @type number
 * @desc 名前ラベルの文字色を指定。数値と色の対応は、メッセージの文字色指定と同じ。（初期値：19）
 * @default 19
 * @min 0
 * @max 31
 *
 * @param 文字の寄せ方（縦）
 * @type select
 * @desc 名前ラベルの縦位置の寄せ方を指定。（初期値：中央寄せ）
 * @option 上寄せ
 * @value up
 * @option 中央寄せ
 * @value center
 * @option 下寄せ
 * @value down
 * @default center
 *
 * @param 文字の寄せ方（横）
 * @type select
 * @desc 名前ラベルの横位置の寄せ方を指定。（初期値：中央寄せ）
 * @option 左寄せ
 * @value left
 * @option 中央寄せ
 * @value center
 * @option 右寄せ
 * @value right
 * @default center
 *
 *
 * @param 左右位置調整
 * @type number
 * @desc 左右位置を調整する値をピクセルで指定。プラスで右、マイナスで左に調整。（初期値：18）
 * @default 18
 * @min -9999
 *
 * @param 上下位置調整
 * @type number
 * @desc 上下位置を調整する値をピクセルで指定。プラスで下、マイナスで上に調整。（初期値：134）
 * @default 134
 * @min -9999
 *
 *
 * @param 文字の表示順
 * @type number
 * @desc 部品と重なった時、どちらを手前にするかの値を指定します。この値が大きいほど手前になります。
 * @default 99
 * @max 99
 *
 * @param ネームプレート
 * @type struct<NamePlate>[]
 * @desc ネームプレートの設定。１件目のデータしか使われません。表示しない場合は透明にしてください。
 *
 * @param 追加四角部品
 * @type struct<AttachmentRect>[]
 * @desc 追加する四角部品の設定。複数登録可能ですが、処理が重くなるかもしれません。
 *
 * @param 追加円部品
 * @type struct<AttachmentCircle>[]
 * @desc 追加する円部品の設定。複数登録可能ですが、処理が重くなるかもしれません。
 *
 * @param 追加ネームプレート画像
 * @type struct<PlatePicture>[]
 * @desc 追加する画像ファイルの設定。１件目のデータしか使われません。ネームプレートのように配置されます。
 * @dir img/pictures/
 *
 * @param 追加画像部品
 * @type struct<Picture>[]
 * @desc 追加する画像ファイルの設定。
 * @dir img/pictures/
 *
 */
/*~struct~NamePlate:
 *
 * @param width
 * @type number
 * @desc 幅をピクセルで指定。（初期値：144） 0だと文字数に合わせて伸び縮みします。
 * @default 144
 *
 * @param height
 * @type number
 * @desc 高さをピクセルで指定 。（初期値：34）文字サイズ＋paddingY×2でぴったりサイズです。
 * @default 34
 *
 * @param paddingX
 * @type number
 * @desc 左右の内側余白をピクセルで指定。（初期値：5）値を大きくするとネームプレートと文字のスキマが増えます。
 * @default 5
 *
 * @param paddingY
 * @type number
 * @desc 上下の内側余白をピクセルで指定。（初期値：5）値を大きくするとネームプレートと文字のスキマが増えます。
 * @default 5
 *
 * @param color1
 * @type struct<Color>
 * @desc ネームプレートの色
 * @default {"red":"240","green":"248","blue":"255", "opacity":"0.3"}
 *
 * @param gradationMode
 * @type boolean
 * @desc true:color1からcolor2へグラデーションします。 false:color1単色です。
 * @default false
 *
 * @param gradationVertical
 * @type boolean
 * @desc true:縦にグラデーションします。 false:横にグラデーションします。
 * @default false
 *
 *
 * @param color2
 * @type struct<Color>
 * @desc グラデーションカラー
 * @default {"red":"0","green":"0","blue":"0", "opacity":"1"}
 *
 */
/*~struct~AttachmentRect:
 *
 * @param orderNo
 * @type number
 * @desc この値が大きいほど手前に表示されます。同じ値だと後に定義された部品ほど手前に表示されます。
 * @default 0
 * @max 99
 * @min 0
 *
 * @param width
 * @type number
 * @desc 四角形の幅をピクセルで指定。
 * @default 0
 *
 * @param height
 * @type number
 * @desc 四角形の高さをピクセルで指定。
 * @default 0
 *
 * @param positionX
 * @type number
 * @desc 横方向の表示位置を調整する値をピクセルで指定。
 * @min -999
 * @default 0
 *
 * @param positionY
 * @type number
 * @desc 縦方向の表示位置を調整する値をピクセルで指定。
 * @min -999
 * @default 0
 *
 * @param color1
 * @type struct<Color>
 * @desc 四角形の色
 * @default {"red":"0","green":"0","blue":"0", "opacity":"1"}
 *
 * @param gradationMode
 * @type boolean
 * @desc true:color1からcolor2へグラデーションします。 false:color1単色です。
 * @default false
 *
 * @param gradationVertical
 * @type boolean
 * @desc true:縦にグラデーションします。 false:横にグラデーションします。
 * @default false
 *
 * @param color2
 * @type struct<Color>
 * @desc グラデーションカラー
 * @default {"red":"0","green":"0","blue":"0", "opacity":"1"}
 *
 * @param rotation
 * @type number
 * @desc 何度かたむけるかを指定。（0～360）
 * @max 360
 * @default 0
 *
 */
/*~struct~AttachmentCircle:
 *
 * @param orderNo
 * @type number
 * @desc この値が大きいほど手前に表示されます。同じ値だと後に定義された部品ほど手前に表示されます。
 * @default 0
 * @max 99
 * @min 0
 *
 * @param radius
 * @type number
 * @desc 円の半径をピクセルで指定。
 * @default 0
 *
 * @param positionX
 * @type number
 * @desc 横方向の表示位置を調整する値をピクセルで指定。
 * @default 0
 * @min -9999
 *
 * @param positionY
 * @type number
 * @desc 縦方向の表示位置を調整する値をピクセルで指定。
 * @default 0
 * @min -9999
 *
 * @param color
 * @type struct<Color>
 * @desc 円の色
 * @default {"red":"0","green":"0","blue":"0", "opacity":"1"}
 *
 */
/*~struct~Color:
 *
 * @param red
 * @type number
 * @max 255
 * @desc 赤(R)。0～255で指定してください。
 * @default 0
 *
 * @param green
 * @type number
 * @max 255
 * @desc 緑(G)。0～255で指定してください。
 * @default 0
 *
 * @param blue
 * @type number
 * @max 255
 * @desc 青(B)。0～255で指定してください。
 * @default 0
 *
 * @param opacity
 * @type number
 * @max 1
 * @desc 不透明度を0～1で指定してください。0で透明です。
 * @default 1
 * @decimals 1
 *
 */
/*~struct~Picture:
 *
 * @param orderNo
 * @type number
 * @desc この値が大きいほど手前に表示されます。同じ値だと後に定義された画像ほど手前に表示されます。
 * @default 0
 * @max 99
 *
 * @param fileName
 * @type file
 * @desc img/picturesフォルダの画像ファイルを指定。
 * @dir img/pictures/
 * @default fileName_Nothing
 *
 * @param positionX
 * @type number
 * @desc 横方向の表示位置を調整する値をピクセルで指定。
 * @min -999
 * @default 0
 *
 * @param positionY
 * @type number
 * @desc 縦方向の表示位置を調整する値をピクセルで指定。
 * @min -999
 * @default 0
 *
 * @param scaleX
 * @type number
 * @desc 横方向の拡大倍率を指定。1で等倍。2で2倍。マイナスだと画像が反転します。
 * @default 1
 * @max 10
 * @min -10
 * @decimals 1
 *
 * @param scaleY
 * @type number
 * @desc 縦方向の拡大倍率を指定。1で等倍。2で2倍。マイナスだと画像が反転します。
 * @default 1
 * @max 10
 * @min -10
 * @decimals 1
 *
 * @param opacity
 * @type number
 * @max 255
 * @desc 不透明度を0～255で指定してください。0で透明です。
 * @default 255
 *
 * @param rotation
 * @type number
 * @desc 何度かたむけるかを指定。（0～360）
 * @max 360
 * @default 0
 *
 */
/*~struct~PlatePicture:
 *
 * @param fileName
 * @type file
 * @desc img/picturesフォルダの画像ファイルを指定。
 * @dir img/pictures/
 * @default fileName_Nothing
 *
 * @param positionX
 * @type number
 * @desc 横方向の表示位置を調整する値をピクセルで指定。
 * @min -999
 * @default 0
 *
 * @param positionY
 * @type number
 * @desc 縦方向の表示位置を調整する値をピクセルで指定。
 * @min -999
 * @default 0
 *
 * @param autoScaleMode
 * @type boolean
 * @desc true:名前文字が長い時自動で伸びます。 false:伸びません。
 * @default false
 *
 * @param scaleX
 * @type number
 * @desc 横方向の拡大倍率を指定。1で等倍。2で2倍。マイナスだと画像が反転します。
 * @default 1
 * @max 10
 * @min -10
 * @decimals 1
 *
 * @param scaleY
 * @type number
 * @desc 縦方向の拡大倍率を指定。1で等倍。2で2倍。マイナスだと画像が反転します。
 * @default 1
 * @max 10
 * @min -10
 * @decimals 1
 *
 * @param opacity
 * @type number
 * @max 255
 * @desc 不透明度を0～255で指定してください。0で透明です。
 * @default 255
 *
 */

(function () {
  "use strict";

  var convertToNumber = function (obj) {
    for (var prop in obj) {
      obj[prop] = Number(obj[prop]);
    }
    return obj;
  };

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

  var convertArrayParam = function (param) {
    if (!param) {
      return;
    }

    if (param !== undefined) {
      try {
        const array = JSON.parse(param);
        for (let i = 0; i < array.length; i++) {
          array[i] = JSON.parse(array[i]);
        }
        return array;
      } catch (e) {
        console.group();
        console.error(
          "%cParameter is invalid ! SNH_MsgNameLableのパラメータ準備に失敗しました。",
          "background-color: #5174FF"
        );
        console.error("Parameter:" + eval(param));
        console.error("Error message :" + e);
        console.groupEnd();
      }
    }
  };

  var convertParam = function (param) {
    if (param !== undefined) {
      try {
        return JSON.parse(param);
      } catch (e) {
        console.group();
        console.error(
          "%cParameter is invalid ! SNH_MsgNameLableのパラメータ準備に失敗しました。",
          "background-color: #5174FF"
        );
        console.error("Parameter:" + eval(param));
        console.error("Error message :" + e);
        console.groupEnd();
      }
    }
  };

  var parameters = PluginManager.parameters("SNH_MsgNameLabel");
  var nameLabelFontSize = Number(parameters["文字サイズ"] || 24);
  var nameLabelFontColor = Number(parameters["文字色"] || 0);
  var nameLabelFontOutLineColor = Number(parameters["文字フチ色"] || 15);
  var nameLabelAlignY = String(parameters["文字の寄せ方（縦）"] || "center");
  var nameLabelAlignX = String(parameters["文字の寄せ方（横）"] || "center");
  var nameAutoMode = Boolean(
    parameters["文字サイズ自動調整"] === "true" || false
  );
  var nameLabelBackHeight = Number(parameters["背景の高さ調整"] || 10);
  var nameLabelChoseiX = Number(parameters["左右位置調整"] || 0);
  var nameLabelChoseiY = Number(parameters["上下位置調整"] || 0);
  var nameLabelOrderNo = Number(parameters["文字の表示順"] || 99);

  var param = {};
  param.NamePlate = String(parameters["ネームプレート"]);
  param.NamePlate = convertArrayParam(param.NamePlate);
  param.AttachmentRect = String(parameters["追加四角部品"]);
  param.AttachmentRect = convertArrayParam(param.AttachmentRect);
  param.AttachmentCircle = String(parameters["追加円部品"]);
  param.AttachmentCircle = convertArrayParam(param.AttachmentCircle);
  param.NamePlatePictures = String(parameters["追加ネームプレート画像"]);
  param.NamePlatePictures = convertArrayParam(param.NamePlatePictures);
  param.AttachmentPictures = String(parameters["追加画像部品"]);
  param.AttachmentPictures = convertArrayParam(param.AttachmentPictures);

  let partsList = [];
  let namePlate = [];
  let namePlatePicture = [];
  let namePlatePictureWidth = 0;

  // 矩形bitmap作成
  function createPartsSpriteRect(parts) {
    let bitmap = new Bitmap(0, 0);
    bitmap.resize(parts.width, parts.height);

    if (parts.gradationMode) {
      bitmap.gradientFillRect(
        0,
        0,
        parts.width,
        parts.height,
        "rgba(" +
          parts.color1.red +
          "," +
          parts.color1.green +
          "," +
          parts.color1.blue +
          "," +
          parts.color1.opacity +
          ")",
        "rgba(" +
          parts.color2.red +
          "," +
          parts.color2.green +
          "," +
          parts.color2.blue +
          "," +
          parts.color2.opacity +
          ")",
        parts.gradationVertical
      );
    } else {
      bitmap.fillRect(
        0,
        0,
        parts.width,
        parts.height,
        "rgba(" +
          parts.color1.red +
          "," +
          parts.color1.green +
          "," +
          parts.color1.blue +
          "," +
          parts.color1.opacity +
          ")"
      );
    }
    return bitmap;
  }

  //円bitmap作成
  function createPartsSpriteCircle(parts) {
    let bitmap = new Bitmap(0, 0);
    bitmap.resize(parts.radius * 2, parts.radius * 2);

    bitmap.drawCircle(
      parts.radius,
      parts.radius,
      parts.radius,
      "rgba(" +
        parts.color.red +
        "," +
        parts.color.green +
        "," +
        parts.color.blue +
        "," +
        parts.color.opacity +
        ")"
    );
    return bitmap;
  }

  //画像bitmap作成
  function createPartsSpritePicture(parts) {
    let bitmap = new Bitmap(0, 0);
    bitmap = ImageManager.loadBitmap("img/pictures/", parts.fileName, 0, false);
    return bitmap;
  }

  //初期処理：構造体の整形とbitmapの準備
  (function initPartsList() {
    if (param.NamePlate && param.NamePlate.length > 0) {
      let plate = param.NamePlate[0];
      plate.type = "rect";
      plate.orderNo = -1;
      plate.width = Number(plate.width);
      plate.height = Number(plate.height);
      plate.paddingX = Number(plate.paddingX);
      plate.paddingY = Number(plate.paddingY);
      plate.gradationMode = Boolean(plate.gradationMode === "true" || false);
      plate.gradationVertical = Boolean(
        plate.gradationVertical === "true" || false
      );
      plate.color1 = convertToNumber(convertParam(plate.color1));
      plate.color2 = convertToNumber(convertParam(plate.color2));
      plate.rotation = 0;
      if (plate.height === 0) {
        plate.height = nameLabelFontSize;
      }

      plate.bitmap = createPartsSpriteRect(plate);
      namePlate.push(plate);
    }

    if (param.AttachmentRect && param.AttachmentRect.length > 0) {
      for (let rect of param.AttachmentRect) {
        rect.type = "rect";
        rect.orderNo = Number(rect.orderNo);
        rect.width = Number(rect.width);
        rect.heigth = Number(rect.heigth);
        rect.positionX = Number(rect.positionX);
        rect.positionY = Number(rect.positionY);
        rect.gradationMode = Boolean(rect.gradationMode === "true" || false);
        rect.gradationVertical = Boolean(
          rect.gradationVertical === "true" || false
        );
        rect.color1 = convertToNumber(convertParam(rect.color1));
        rect.color2 = convertToNumber(convertParam(rect.color2));
        rect.rotation = Number(rect.rotation);
        rect.bitmap = createPartsSpriteRect(rect);
        if (rect.width === 0 || rect.height === 0) {
          continue;
        }

        partsList.push(rect);
      }
    }

    if (param.AttachmentCircle && param.AttachmentCircle.length > 0) {
      for (let circle of param.AttachmentCircle) {
        circle.type = "circle";
        circle.orderNo = Number(circle.orderNo);
        circle.radius = Number(circle.radius);
        circle.positionX = Number(circle.positionX);
        circle.positionY = Number(circle.positionY);
        circle.color = convertToNumber(convertParam(circle.color));
        circle.bitmap = createPartsSpriteCircle(circle);
        if (circle.radius === 0) {
          continue;
        }
        partsList.push(circle);
      }
    }

    if (param.AttachmentPictures && param.AttachmentPictures.length > 0) {
      let pictureBitmap = new Bitmap(0, 0);
      for (let picture of param.AttachmentPictures) {
        picture.type = "picture";
        picture.orderNo = Number(picture.orderNo);
        picture.fileName = String(picture.fileName);
        picture.positionX = Number(picture.positionX);
        picture.positionY = Number(picture.positionY);
        picture.scaleX = Number(picture.scaleX);
        picture.scaleY = Number(picture.scaleY);
        picture.opacity = Number(picture.opacity);
        picture.rotation = Number(picture.rotation);
        if (picture.fileName === "fileName_Nothing") {
          continue;
        }
        picture.bitmap = createPartsSpritePicture(picture);
        partsList.push(picture);
      }
    }

    if (param.NamePlatePictures && param.NamePlatePictures.length > 0) {
      let pPictureBitmap = new Bitmap(0, 0);
      let pPicture = param.NamePlatePictures[0];

      pPicture.type = "picture";
      pPicture.orderNo = 0;
      pPicture.fileName = String(pPicture.fileName);
      pPicture.positionX = Number(pPicture.positionX);
      pPicture.positionY = Number(pPicture.positionY);
      pPicture.autoScaleMode = Boolean(
        pPicture.autoScaleMode === "true" || false
      );
      pPicture.scaleX = Number(pPicture.scaleX);
      pPicture.scaleY = Number(pPicture.scaleY);
      pPicture.opacity = Number(pPicture.opacity);
      pPicture.rotation = 0;
      if (pPicture.fileName != "fileName_Nothing") {
        pPicture.bitmap = createPartsSpritePicture(pPicture);
        namePlatePictureWidth = pPicture.bitmap.width;
        namePlatePicture.push(pPicture);
      }
    }

    //並び替え
    partsList.sort(function (a, b) {
      if (a.orderNo < b.orderNo) return -1;
      if (a.orderNo > b.orderNo) return 1;
      return 0;
    });
  })();

  //-----------------------------------------------
  // Window_Messageの機能追加
  //-----------------------------------------------

  // 名前ラベルのテキストを取得
  let nameLabelText = "";
  var escapeNameLabel = function (nameText) {
    // 名前ラベルの描画
    if (nameText != "") {
      nameLabelText = nameText;
    }

    return "";
  };

  var _Window_Message_initialize = Window_Message.prototype.initialize;
  Window_Message.prototype.initialize = function () {
    _Window_Message_initialize.call(this);
    this._snhNameLabelList = [];
  };

  var _Window_Message_startMessage = Window_Message.prototype.startMessage;
  Window_Message.prototype.startMessage = function () {
    _Window_Message_startMessage.call(this);

    //制御文字の除去
    if (this._textState) {
      this._textState.text = this._textState.text.replace(
        /\x1bNL\<(.*?)\>/gi,
        function () {
          return escapeNameLabel(arguments[1]);
        },
        this
      );

      if (nameLabelText != "") {
        this.snhDrawNameLabel();
      }
    }
  };

  var _Window_Message_terminateMessage =
    Window_Message.prototype.terminateMessage;
  Window_Message.prototype.terminateMessage = function () {
    _Window_Message_terminateMessage.call(this);

    //ラベルの除去
    this.snhRemoveNameLabel();
  };

  //メイン処理
  Window_Message.prototype.snhDrawNameLabel = function () {
    let spriteBase = new Sprite();

    let nameBitmap = new Bitmap(0, 0);
    let nameSprite = new Sprite();

    let cSize = nameBitmap.measureTextWidth("幅");
    let nameWidth = nameBitmap.measureTextWidth(nameLabelText);

    let scene = SceneManager._scene;

    //位置調整
    let startX = nameLabelChoseiX;
    let startY = nameLabelChoseiY;
    spriteBase.move(startX, startY);

    //文字の設定
    nameBitmap.fontSize = nameLabelFontSize;
    nameBitmap.textColor = scene._messageWindow.textColor(nameLabelFontColor);
    nameBitmap.outlineColor = scene._messageWindow.textColor(
      nameLabelFontOutLineColor
    );

    //ネームプレートがない時は終わり
    let wNamePlate = namePlate[0];
    if (!wNamePlate) {
      return;
    }

    let height = wNamePlate.height;
    let width = wNamePlate.width;

    //ネームプレートを設定
    let namePlateSprite = new Sprite();
    if (width > 0) {
      namePlateSprite.bitmap = wNamePlate.bitmap;
      spriteBase.addChild(namePlateSprite);
    } else {
      //描画
      width = nameWidth + wNamePlate.paddingX * 2;
      let namePlateBitmap = new Bitmap(width, wNamePlate.height);
      namePlateSprite.bitmap = namePlateBitmap;
      namePlateSprite.rotation = (wNamePlate.rotation * Math.PI) / 180;

      if (wNamePlate.gradationMode) {
        namePlateBitmap.gradientFillRect(
          0,
          0,
          width,
          wNamePlate.height,
          "rgba(" +
            wNamePlate.color1.red +
            "," +
            wNamePlate.color1.green +
            "," +
            wNamePlate.color1.blue +
            "," +
            wNamePlate.color1.opacity +
            ")",
          "rgba(" +
            wNamePlate.color2.red +
            "," +
            wNamePlate.color2.green +
            "," +
            wNamePlate.color2.blue +
            "," +
            wNamePlate.color2.opacity +
            ")",
          wNamePlate.gradationVertical
        );
      } else {
        namePlateBitmap.fillRect(
          0,
          0,
          width,
          wNamePlate.height,
          "rgba(" +
            wNamePlate.color1.red +
            "," +
            wNamePlate.color1.green +
            "," +
            wNamePlate.color1.blue +
            "," +
            wNamePlate.color1.opacity +
            ")"
        );
      }

      spriteBase.addChild(namePlateSprite);
    }

    //ネームプレート画像
    if (namePlatePicture && namePlatePicture.length > 0) {
      namePlatePicture[0];
      let platePictureSprite = new Sprite();
      platePictureSprite.bitmap = namePlatePicture[0].bitmap;
      if (!nameAutoMode && namePlatePicture[0].autoScaleMode) {
        if (namePlatePictureWidth === 0) {
          namePlatePictureWidth = namePlatePicture[0].width;
        }

        width = nameWidth + wNamePlate.paddingX * 2;
        platePictureSprite.scale.x = width / namePlatePictureWidth;
      }
      platePictureSprite.move(
        namePlatePicture[0].positionX,
        namePlatePicture[0].positionY
      );
      spriteBase.addChild(platePictureSprite);
    }

    //名前の描画の準備
    let yChosei = 0;

    //プレートの高さが十分な時
    if (nameLabelFontSize < wNamePlate.height - wNamePlate.paddingY * 2) {
      let wHeight = wNamePlate.height - wNamePlate.paddingY;
      if (nameLabelAlignY === "up") {
        yChosei = wNamePlate.paddingY;
      } else if (nameLabelAlignY === "center") {
        yChosei =
          wNamePlate.paddingY +
          (wHeight - wNamePlate.paddingY - nameLabelFontSize) / 2;
      } else if (nameLabelAlignY === "down") {
        yChosei =
          wNamePlate.paddingY +
          (wHeight - nameLabelFontSize - wNamePlate.paddingY);
      }
    } else {
      yChosei = wNamePlate.paddingY;
    }

    if (nameAutoMode && wNamePlate.width > 0) {
      width -= wNamePlate.paddingX * 2;
    } else {
      width = nameWidth;
    }

    nameBitmap.resize(width, cSize);
    nameSprite.bitmap = nameBitmap;

    let drawNameFinish = false;
    nameSprite.move(wNamePlate.paddingX, yChosei);

    //パーツと名前の描画
    if (partsList.length > 0) {
      for (let parts of partsList) {
        if (nameLabelOrderNo < parts.orderNo && !drawNameFinish) {
          spriteBase.addChild(this.snhDrawingName(nameSprite, width, cSize));
          drawNameFinish = true;
        }
        let sprite = new Sprite(parts.bitmap);
        sprite.move(parts.positionX, parts.positionY);

        if (parts.type === "rect") {
          sprite.rotation = (parts.rotation * Math.PI) / 180;
        } else if (parts.type === "picture") {
          sprite.opacity = parts.opacity;
          sprite.rotation = (parts.rotation * Math.PI) / 180;
          sprite.scale.x = parts.scaleX;
          sprite.scale.y = parts.scaleY;
        }

        spriteBase.addChild(sprite);
      }
    }

    if (!drawNameFinish) {
      spriteBase.addChild(this.snhDrawingName(nameSprite, width, cSize));
    }

    this.snhSetNameLabelSprite(spriteBase);
  };

  // 名前を描画して返す
  Window_Message.prototype.snhDrawingName = function (sprite, width, height) {
    sprite.bitmap.drawText(nameLabelText, 0, 0, width, height, nameLabelAlignX);
    return sprite;
  };

  // スプライトの登録
  Window_Message.prototype.snhSetNameLabelSprite = function (sprite) {
    this.addChild(sprite);
    //実際に入るスプライトは１件なのでリストに入れる必要はないですが、作る時に紆余曲折あり、その名残です。
    this._snhNameLabelList.push(sprite);
  };

  //名前ラベルの除去
  Window_Message.prototype.snhRemoveNameLabel = function () {
    if (this._snhNameLabelList && this._snhNameLabelList.length > 0) {
      for (let label of this._snhNameLabelList) {
        this.removeChild(label);
      }
    }

    this._snhNameLabelList = [];
    nameLabelText = "";
  };
})();

repo_name: Idkwtcm/violated

license: unknown


code:
/*============================================================================
 _SentenceExtractor.js
----------------------------------------------------------------------------
 (C)2020 kiki
 This software is released under the MIT License.
 http://opensource.org/licenses/mit-license.php
----------------------------------------------------------------------------
 [Blog]   : http://sctibacromn.hatenablog.com/
============================================================================*/
/*:ja
 * @plugindesc ツクールｍｖ内の文章と選択肢を全て出力し、csv形式で保存する。
 * @author kiki
 * @version 1.00
 *
 * @help
 */

function SentenceData() {
  throw new Error("This is a static class");
}
(function () {
  var Sentence = {};
  Sentence.Param = PluginManager.parameters("SentenceExtractor");
  const DIR_NAME = "文章出力";
  const SENTENCE_TYPE_NUM = 0;
  const CHOICE_TYPE_NUM = 1;
  Sentence.saveMapFileNames = ["マップ文章", "マップ選択肢"];
  Sentence.saveComFileNames = ["コモン文章", "コモン選択肢"];
  Sentence.saveMapName = "マップ名";

  const _Scene_Boot_start = Scene_Boot.prototype.start;
  Scene_Boot.prototype.start = function () {
    _Scene_Boot_start.call(this);
    SentenceData.start();
  };
  SentenceData.start = function () {
    if (!Utils.isNwjs()) {
      return;
    }
    let path = require("path");
    this._fs = require("fs");
    this._projectFilePath = path.dirname(process.mainModule.filename);
    let mapInfo = this._fs.readFileSync(
      this._projectFilePath + "/data/MapInfos.json"
    );
    this._jsonMapData = JSON.parse(mapInfo);
    this.makeDir();
    this.writeMapSentence(SENTENCE_TYPE_NUM);
    this.writeMapSentence(CHOICE_TYPE_NUM);
    this.writeCommonSentence(SENTENCE_TYPE_NUM);
    this.writeCommonSentence(CHOICE_TYPE_NUM);
    this.writeMapNames();
  };
  SentenceData.makeDir = function () {
    let fs = this._fs;
    let dirPath = this._projectFilePath + "/" + DIR_NAME;
    if (!fs.existsSync(dirPath)) {
      fs.mkdirSync(dirPath);
    }
  };
  SentenceData.writeMapNames = function () {
    let jsonMapData = this._jsonMapData;
    var dataStr = "";
    for (i = 1; i < jsonMapData.length; i++) {
      if (jsonMapData[i] == null) continue;
      dataStr += '"' + jsonMapData[i].name + '"' + ':{"en":""},' + "\n";
    }
    let saveFileName = Sentence.saveMapName;
    this.saveText(dataStr, saveFileName);
  };
  SentenceData.saveText = function (dataStr, saveFileName) {
    // 後方「,改行」削除
    dataStr = dataStr.replace(/\,\n$/g, "");
    let saveFilePath =
      this._projectFilePath + "/" + DIR_NAME + "/" + saveFileName + ".txt";
    this._fs.writeFileSync(saveFilePath, dataStr);
  };
  SentenceData.writeMapSentence = function (typeNum) {
    let jsonMapData = this._jsonMapData;
    var dataStr = "";
    for (i = 1; i < jsonMapData.length; i++) {
      if (jsonMapData[i] == null) continue;
      var filename = "Map%1.json".format(i.padZero(3));
      let dataMapName = "/data/" + filename;
      let data = this._fs.readFileSync(this._projectFilePath + dataMapName);
      let jsonData = JSON.parse(data);
      let mapId = jsonMapData[i].id;
      dataStr += this.extractInMap(typeNum, mapId, jsonData);
    }
    // 空でも表示
    // エラーじゃないことを示すため
    let saveFileName = Sentence.saveMapFileNames[typeNum];
    this.saveCsv(dataStr, saveFileName);
  };
  SentenceData.extractInMap = function (typeNum, mapId, jsonData) {
    var dataStr = "";
    for (n = 1; n < jsonData.events.length; n++) {
      let event = jsonData.events[n];
      if (event == null) continue;
      let extracted = "";
      switch (typeNum) {
        case 0:
          extracted = this.serifInMap(event, mapId);
          break;
        case 1:
          extracted = this.choicesInMap(event);
          break;
      }
      if (extracted != "") {
        dataStr += extracted;
      }
    }
    return dataStr;
  };
  SentenceData.saveCsv = function (dataStr, saveFileName) {
    let saveFilePath =
      this._projectFilePath + "/" + DIR_NAME + "/" + saveFileName + ".csv";
    let fs = this._fs;
    if (dataStr == "") {
      fs.writeFileSync(saveFilePath, dataStr);
    } else {
      // bom付きじゃないとエクセル表示で文字化けするため、追加
      fs.writeFileSync(saveFilePath, "\uFEFF");
      fs.appendFile(saveFilePath, dataStr);
    }
  };
  SentenceData.serifInMap = function (event, mapId) {
    var serifInMap = "";
    for (m = 0; m < event.pages.length; m++) {
      let page = event.pages[m];
      let l = 0;
      let list = page.list;
      while (list[l]) {
        var oneSerif = "";
        //一イベントコマンドにある文章を抽出
        while (this.nextEventCode(list, l) === 401) {
          l++;
          oneSerif += list[l].parameters[0] + "\n";
        }
        if (oneSerif != "") {
          // 後方改行削除
          oneSerif = oneSerif.replace(/\r?\n$/g, "");
          oneSerif = '"' + oneSerif + '"';
          // マップＩＤ，イベントＩＤを文章の前に接頭文字で入れる
          let prefix = String(mapId) + "," + String(event.id) + ",";
          oneSerif = prefix + oneSerif;
          serifInMap += oneSerif + "\n";
        }
        l++;
      }
    }
    return serifInMap;
  };
  SentenceData.choicesInMap = function (event) {
    var choicesInMap = "";
    for (let i = 0; i < event.pages.length; i++) {
      let page = event.pages[i];
      for (let i = 0; i < page.list.length; i++) {
        let command = page.list[i];
        if (command.code == 402) {
          choicesInMap += command.parameters[1] + "\n";
        }
      }
    }
    return choicesInMap;
  };
  SentenceData.nextEventCode = function (list, l) {
    var command = list[l + 1];
    if (command) {
      return command.code;
    } else {
      return 0;
    }
  };
  SentenceData.writeCommonSentence = function (typeNum) {
    let fs = this._fs;
    var data = fs.readFileSync(
      this._projectFilePath + "/data/CommonEvents.json"
    );
    var jsonData = JSON.parse(data);
    var dataStr = "";
    dataStr += this.extractInCommonEv(typeNum, jsonData);
    let saveFileName = Sentence.saveComFileNames[typeNum];
    this.saveCsv(dataStr, saveFileName);
  };
  SentenceData.extractInCommonEv = function (typeNum, jsonData) {
    var dataStr = "";
    for (i = 1; i < jsonData.length; i++) {
      if (jsonData[i] == null) continue;
      commonId = jsonData[i].id;
      let list = jsonData[i].list;
      switch (typeNum) {
        case 0:
          dataStr += this.serifInCommonEv(list, commonId);
          break;
        case 1:
          dataStr += this.choicesInCommonEv(list);
          break;
      }
    }
    return dataStr;
  };
  SentenceData.serifInCommonEv = function (list, commonId) {
    var serIfInCommonEv = "";
    let i = 0;
    while (list[i]) {
      var oneSerif = "";
      //一イベントコマンドにある文章を抽出
      while (this.nextEventCode(list, i) === 401) {
        i++;
        oneSerif += list[i].parameters[0] + "\n";
      }
      if (oneSerif != "") {
        // 後方改行削除
        oneSerif = oneSerif.replace(/\r?\n$/g, "");
        oneSerif = '"' + oneSerif + '"';
        // コモンイベントＩＤを文章の前に接頭文字で入れる
        let prefix = String(commonId) + ",";
        oneSerif = prefix + oneSerif;
        serIfInCommonEv += oneSerif + "\n";
      }
      i++;
    }
    return serIfInCommonEv;
  };
  SentenceData.choicesInCommonEv = function (list) {
    var choicesInCommon = "";
    for (let i = 0; i < list.length; i++) {
      let command = list[i];
      if (command.code == 402) {
        choicesInCommon += command.parameters[1] + "\n";
      }
    }
    return choicesInCommon;
  };
})();


code:
//=============================================================================
// SimpleMsgSideView.js
//=============================================================================

/*:
 * @plugindesc at sideview battle, only display item/skill names.
 * @author Sasuke KANNAZUKI
 *
 * @param displayAttack
 * @desc Whether to display normal attack. 1:yes 0:no
 * @default 0
 *
 * @param position
 * @desc Skill name display position. 0:left, 1:center
 * @default 1
 *
 * @help This plugin does not provide plugin commands.
 *
 * By not displaying the log and only displaying the skill name,
 * the speed of battle will increase slightly.
 */

/*:ja
 * @plugindesc サイドビューバトルで技/アイテムの名前のみ表示します。
 * @author 神無月サスケ
 *
 * @param displayAttack
 * @desc 通常攻撃も表示するか (1:する 0:しない)
 * @default 0
 *
 * @param position
 * @desc 技名を表示する位置 (0:左寄せ, 1:中央)
 * @default 1
 *
 * @help このプラグインには、プラグインコマンドはありません。
 *
 * ログを表示せず、技名のみを表示することで、戦闘のテンポが若干高速になります。
 */

(function () {
  var parameters = PluginManager.parameters("SimpleMsgSideView");
  var displayAttack = Number(parameters["displayAttack"]) != 0;
  var position = Number(parameters["position"] || 1);

  var _Window_BattleLog_addText = Window_BattleLog.prototype.addText;
  Window_BattleLog.prototype.addText = function (text) {
    if ($gameSystem.isSideView()) {
      this.refresh();
      this.wait();
      return; // not display battle log
    }
    _Window_BattleLog_addText.call(this, text);
  };

  // for sideview battle only
  Window_BattleLog.prototype.addItemNameText = function (itemName) {
    this._lines.push(itemName);
    this.refresh();
    this.wait();
  };

  var _Window_BattleLog_displayAction =
    Window_BattleLog.prototype.displayAction;
  Window_BattleLog.prototype.displayAction = function (subject, item) {
    if ($gameSystem.isSideView()) {
      if (
        displayAttack ||
        !(DataManager.isSkill(item) && item.id == subject.attackSkillId())
      ) {
        this.push("addItemNameText", item.name); // display item/skill name
      } else {
        this.push("wait");
      }
      return;
    }
    _Window_BattleLog_displayAction.call(this, subject, item);
  };

  // to put skill/item name at center
  var _Window_BattleLog_drawLineText = Window_BattleLog.prototype.drawLineText;
  Window_BattleLog.prototype.drawLineText = function (index) {
    if ($gameSystem.isSideView() && position == 1) {
      var rect = this.itemRectForText(index);
      this.contents.clearRect(rect.x, rect.y, rect.width, rect.height);
      this.drawText(this._lines[index], rect.x, rect.y, rect.width, "center");
      return;
    }
    _Window_BattleLog_drawLineText.call(this, index);
  };
})();


code:
//=============================================================================
// Skittle.js
//=============================================================================

/*:ja
 * v0.1.0
 * @plugindesc
 * 自作ゲージのメーターを増減する
 *
 * @author オオホタルサイコ
 *
 * @param Container
 * @default
 * @desc 容器(img/system)
 *
 * @param Content
 * @default
 * @desc 容量(img/system)
 *
 * @param Capacity
 * @default 100
 * @desc 最大値
 *
 * @param Default
 * @default 100
 * @desc 開始値
 *
 * @param Variable
 * @default 1
 * @desc 容量値格納先変数番号
 *
 * @param Visible
 * @default true
 * @desc 表示状態
 *
 * @param Location
 * @default 0 0
 * @desc 座標[X Y]を設定
 *
 * @param Size
 * @default 100 100
 * @desc 画像のサイズ[Width Height]を設定
 *
 * @param Margin
 * @default 0 0
 * @desc 中身の余白(上下)[MarginTop MarginBottom]を指定
 *
 * @help ■概要
 * Skittleプラグインを利用するにはプラグインコマンドから実行します。
 * プラグインコマンドを実行するとイベント内でメーターの増減、表示を行います。
 *
 * ■プラグインコマンド
 *   Skittle add [増減値]            # ゲージの増減を行う
 *   Skittle visivle [表示状態]      # ゲージの表示状態を制御
 */

/*
 * 共通処理系
 */
var parseIntStrict = function (value) {
  var result = parseInt(value, 10);
  if (isNaN(result)) result = 0;
  return result;
};

/*
 * 中身
 */
var Content = (function () {
  // クラス変数
  var sprite = null;

  // コンストラクタ
  var Content = function (skittle, location, size, parameters) {
    if (!(this instanceof Content)) {
      return new Content(skittle, fileName, location, size, margin);
    }
    this.skittle = skittle;
    this.size = size;
    this.remains = 0;

    var fileName = parameters["Content"] || "";
    this.margin = parameters["Margin"].split(" ").map((s) => parseIntStrict(s));
    this.variable = parseIntStrict(parameters["Variable"]) || 0;

    this.LoadSprite(fileName, location, size);
    this.ReflectsRemainigHeight();
  };

  // プロトタイプ内でメソッドを定義
  Content.prototype.LoadSprite = function (fileName, location, size) {
    sprite = new Sprite();
    sprite.bitmap = ImageManager.loadSystem(fileName);
    sprite.x = location[0] + size[0];
    sprite.y = location[1] + size[1];
    sprite.rotation = (180 * Math.PI) / 180;
  };

  Content.prototype.Scale = function () {
    // 純粋な画像部分の高さ / ゲージの最大量
    return (
      (this.size[1] - this.margin[0] - this.margin[1]) / this.skittle.Capacity
    );
  };
  Content.prototype.RemainingHeight = function () {
    // 余白下を差し引いて画像の表示幅を調整
    return this.remains * this.Scale() - this.margin[1];
  };

  Content.prototype.Sprite = function () {
    return sprite;
  };
  Content.prototype.getX = function () {
    return this.Sprite().x;
  };
  Content.prototype.getY = function () {
    return this.Sprite().y;
  };

  Content.prototype.ReflectsRemainigHeight = function () {
    this.Sprite().setFrame(0, 0, this.size[0], this.RemainingHeight());
  };

  Content.prototype.setValue = function (value) {
    this.remains += value;
    if (this.remains < 0) this.remains = 0;
    if (this.remains > this.skittle.Capacity)
      this.remains = this.skittle.Capacity;
    this.ReflectsRemainigHeight();
    $gameVariables.setValue(this.variable, this.remains);
  };

  return Content;
})();

/*
 *本体
 */
var Skittle = (function () {
  // クラス内変数
  var parameters = null;
  // コンストラクタ
  var Skittle = function () {
    if (!(this instanceof Skittle)) {
      return new Skittle();
    }
    this.isFirst = true;
    this.IsDisp = true;
    this.startAnimetion = false;
    this.animeContents = "";
    this.addContent = 0;
    this.initialize();
  };

  Skittle.prototype.clearValue = function () {
    this.clearAnimetion();
    this.addContent = 0;
  };

  Skittle.prototype.clearAnimetion = function () {
    this.animeContents = "";
    this.startAnimetion = false;
  };

  // プロトタイプ内でメソッドを定義
  Skittle.prototype.initialize = function () {
    parameters = PluginManager.parameters("Skittle");

    var container = parameters["Container"] || "";
    var location = parameters["Location"]
      .split(" ")
      .map((s) => parseIntStrict(s));
    var size = parameters["Size"].split(" ").map((s) => parseIntStrict(s));
    this.IsDisp = eval(parameters["Visible"]);
    this.Displyed = !this.IsDisp;
    this.Capacity = parseIntStrict(parameters["Capacity"]) || 0;

    // 中身の描画
    this.content = new Content(this, location, size, parameters);
    this.content.setValue(parseIntStrict(parameters["Default"]) || 0);

    // 容器の描画
    this.LoadSprite(container, location);

    this.clearValue();
  };

  Skittle.prototype.LoadSprite = function (fileName, location) {
    sprite = new Sprite();
    sprite.bitmap = ImageManager.loadSystem(fileName);
    sprite.x = location[0];
    sprite.y = location[1];
  };

  Skittle.prototype.Sprite = function () {
    return sprite;
  };

  Skittle.prototype.setParameter = function (args) {
    //parse
    if (args.length < 2) {
      throw new SyntaxError("setParameter: args is invalid.");
    }
    this.animeContents = args[0];
    if (args[0] == "visible") {
      this.IsDisp = eval(args[1]);
    } else {
      this.addContent = parseIntStrict(args[1]);
      this.startAnimetion = true;
    }
    return true;
  };

  Skittle.prototype.update = function () {
    if (this.startAnimetion) {
      if (this.animeContents == "add") {
        //ゲージのアニメーションを行う
        if (this.addContent > 0) {
          var add = 1;
          this.addContent -= add;
          this.content.setValue(add);
        } else if (this.addContent < 0) {
          var add = -1;
          this.addContent -= add;
          this.content.setValue(add);
        } else {
          this.startAnimetion = false;
        }
      }
    }
    return true;
  };

  return Skittle;
})();

// グローバル変数
var $skittle = null;

/*
 * インスタンスの生成
 * プラグイン実行
 * セーブデータの保存・読み込み
 * メーターの表示制御
 */
(function () {
  //-----------------------------------------------------------------------------
  // インスタンスの生成（ゲーム起動時に呼ばれる）
  //-----------------------------------------------------------------------------
  var createGameObjects = DataManager.createGameObjects;
  DataManager.createGameObjects = function () {
    createGameObjects.call(this);

    // ゲージの作成
    $skittle = new Skittle();
  };

  //-----------------------------------------------------------------------------
  // プラグイン実行
  //-----------------------------------------------------------------------------
  var _Game_Interpreter_pluginCommand =
    Game_Interpreter.prototype.pluginCommand;
  Game_Interpreter.prototype.pluginCommand = function (command, args) {
    _Game_Interpreter_pluginCommand.call(this, command, args);
    if (command === "Skittle") {
      switch (args[0]) {
        case "add":
        case "visible":
          //増減したい値を設定したい
          //表示するかの設定をしたい
          if ($skittle.startAnimetion) return;
          $skittle.setParameter(args);
          break;
        default:
          break;
      }
    }
  };

  //-----------------------------------------------------------------------------
  // セーブデータの生成
  //-----------------------------------------------------------------------------
  var makeSaveContents = DataManager.makeSaveContents;
  DataManager.makeSaveContents = function () {
    // セーブデータ本体
    var contents = makeSaveContents.call(this);

    // ゲージをセーブデータに設定する。
    contents.skittle = $skittle;
    return contents;
  };

  //-----------------------------------------------------------------------------
  // セーブデータの読み込み
  //-----------------------------------------------------------------------------
  var extractSaveContents = DataManager.extractSaveContents;
  DataManager.extractSaveContents = function (contents) {
    // セーブデータ本体を取得
    extractSaveContents.call(this, contents);

    // Skittleを読み込み
    $skittle = contents.skittle;
    $skittle.content.ReflectsRemainigHeight();
  };

  //-----------------------------------------------------------------------------
  // メーターの表示制御
  // 画像の表示・非表示は子の追加・削除で対応
  //-----------------------------------------------------------------------------
  var _Spriteset_Map = Spriteset_Map.prototype.update;
  Spriteset_Map.prototype.update = function () {
    _Spriteset_Map.call(this);
    $skittle.update();
    // ゲージが表示状態になっていない場合で表示フラグがONの場合に表示
    if ($skittle != null && $skittle.IsDisp) {
      $skittle.Displyed = true;
      this.addChild($skittle.content.Sprite());
      this.addChild($skittle.Sprite());
    }
    // ゲージが非表示状態になっていない場合で表示フラグがOFFの場合に表示
    else if ($skittle != null && !$skittle.IsDisp) {
      $skittle.Displyed = false;
      this.removeChild($skittle.content.Sprite());
      this.removeChild($skittle.Sprite());
    }
  };
})();


code:
//=============================================================================
// SwitchOnWithLevelUp.js
//=============================================================================

/*:
 * @plugindesc レベルアップ時に、指定したスイッチをONにします。
 * @author 奏ねこま（おとぶきねこま）
 *
 * @param Switch ID
 * @desc レベルアップ時にONにするスイッチのIDを指定してください。
 * @default 0
 *
 * @param Variable ID for Actor ID
 * @desc レベルアップしたアクターのIDを格納する変数のIDを指定してください。
 * @default 0
 *
 * @help
 * レベルアップ時に、指定したスイッチをONにしますが、自動でOFFにはしません。
 * 同スイッチをトリガーにしたコモンイベント等でOFFにしてください。
 *
 * バトル終了時のリザルトでのレベルアップではスイッチはONになりません。
 *
 * レベルアップしたアクターのIDを変数に格納する機能を有していますが、そのアクターID
 * を使って何ができるかという説明はここでは割愛します。
 * ざっくり言うと、スクリプトを使っていろいろなアクター情報を取得できたりします。
 * 複数のアクターが同時にレベルアップした場合に、どのアクターのIDが格納されるかは
 * 保証できませんので、予めご了承ください。
 *
 * *このプラグインには、プラグインコマンドはありません。
 *
 * [ 利用規約 ] ...................................................................
 *  本プラグインの利用者は、RPGツクールMV/RPGMakerMVの正規ユーザーに限られます。
 *  商用、非商用、ゲームの内容（年齢制限など）を問わず利用可能です。
 *  ゲームへの利用の際、報告や出典元の記載等は必須ではありません。
 *  二次配布や転載、ソースコードURLやダウンロードURLへの直接リンクは禁止します。
 *  （プラグインを利用したゲームに同梱する形での結果的な配布はOKです）
 *  不具合対応以外のサポートやリクエストは受け付けておりません。
 *  本プラグインにより生じたいかなる問題においても、一切の責任を負いかねます。
 * [ 改訂履歴 ] ...................................................................
 *   Version 1.00  2016/07/06  初版
 * -+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 *  Web Site: http://i.gmobb.jp/nekoma/rpg_tkool/
 *  Twitter : https://twitter.com/koma_neko
 */

(function () {
  "use strict";

  const _PNAME = "SwitchOnWithLevelUp";
  const _PARAMETERS = PluginManager.parameters(_PNAME);

  const _SWITCH_ID = +_PARAMETERS["Switch ID"] || 0;
  const _VARIABLE_ID = +_PARAMETERS["Variable ID for Actor ID"] || 0;

  var _Game_Actor_levelUp = Game_Actor.prototype.levelUp;
  Game_Actor.prototype.levelUp = function () {
    _Game_Actor_levelUp.call(this);
    if (!$gameParty.inBattle() && _SWITCH_ID) {
      $gameSwitches.setValue(_SWITCH_ID, true);
    }
    if (_VARIABLE_ID) {
      $gameVariables.setValue(_VARIABLE_ID, this.actorId());
    }
  };
})();