code:
//=============================================================================
// TRP_SkitMZ_ExBlink.js
//=============================================================================
// Copyright (c) 2020 Thirop
//============================================================================

/*:
 * @target MZ
 * @author Thirop
 * @plugindesc TRP_SkitMZ、まばたき拡張パッチ
 * @help
 * 立ち絵表示時にまばたき動作を有効化します。
 * （※表情の階層レイヤーを使用する必要があります。）
 *
 * 1.各キャラの各ポーズごとに表情ピッカーを起動し
 * 「Bキー」よりまばたきパーツ選択モードに入る。
 * 2.目パーツにあたる表情パーツ種類を選択
 * 3.まばたき時のパーツIDを順にクリックで選択
 * （複数フレームでアニメーションさせる場合は順に選択）
 * 4.決定キーで確定後、「Sキー」で保存
 *
 *
 * □まばたきの制御
 * ▷まばたき無効
 * 表情IDを指定時に「表情ID-nb」
 * 例）メッセージ中の制御文字で「\SE[1-nb]」
 *
 * ▷強制的に目を閉じる
 * 表情IDを指定時に「表情ID-b」
 * 例）メッセージ中の制御文字で「\SE[1-b]」
 *
 *
 *
 * 【更新履歴】
 * 1.04 2023/03/29 不具合の修正
 * 1.02 2023/03/21 不具合の修正
 * 1.01 2022/01/20 不具合の修正
 * 1.00 2020/11/10 初版
 *
 * @param blinkFrame
 * @text 瞬きフレーム
 * @desc 目を閉じてる間のフレーム数
 * @type number
 * @default 4
 *
 * @param maxFrame
 * @text 瞬き間隔の最大フレーム数
 * @desc 瞬き間隔の最大フレーム数
 * @type number
 * @min 1
 * @default 240
 *
 * @param minFrame
 * @text 瞬き間隔の最小フレーム数
 * @desc 瞬き間隔の最小フレーム数
 * @type number
 * @min 1
 * @default 20
 *
 */
//=============================================================================

(function () {
  "use strict";

  var pluginName = "TRP_SkitMZ_ExBlink";
  var parameters = JSON.parse(
    JSON.stringify(PluginManager.parameters(pluginName), function (key, value) {
      try {
        return JSON.parse(value);
      } catch (e) {
        try {
          if (value[0] === "[" || value[0] === "{") {
            if (value.contains(" ")) {
              return value;
            }
            return eval(value);
          } else if (value === "") {
            return value;
          } else if (!isNaN(value)) {
            return Number(value);
          } else if (value === "true") {
            return true;
          } else if (value === "false") {
            return false;
          } else {
            return value;
          }
        } catch (e) {
          return value;
        }
      }
    })
  );

  var _SkitActor_clearParameters = SkitActor.prototype.clearParameters;
  SkitActor.prototype.clearParameters = function () {
    _SkitActor_clearParameters.call(this);
    this.clearBlink();
  };

  var _SkitActor_show = SkitActor.prototype.show;
  SkitActor.prototype.show = function () {
    this.clearBlink();

    _SkitActor_show.apply(this, arguments);
    this.setupBlink();
  };

  var _SkitActor_changeImage = SkitActor.prototype.changeImage;
  SkitActor.prototype.changeImage = function () {
    var lastOverlayName = this._overlayName;
    this.clearBlink();

    _SkitActor_changeImage.apply(this, arguments);
    this.setupBlink();
  };

  var _SkitActor_changeImageWithoutAnimation =
    SkitActor.prototype.changeImageWithoutAnimation;
  SkitActor.prototype.changeImageWithoutAnimation = function (
    wait,
    duration,
    poseChange,
    expressionChange
  ) {
    _SkitActor_changeImageWithoutAnimation.call(this, ...arguments);

    var picture = this.picture();
    if (!picture) return;
    if (expressionChange) return;

    //change overlay if blinkIdx changed
    var overlayName = this.overlayName();
    if (this._overlayName !== overlayName) {
      this.applyOverlay(poseChange ? 0 : duration);
      if (wait) {
        this.wait(duration);
      }
    }
  };

  var _SkitActor_update = SkitActor.prototype.update;
  SkitActor.prototype.update = function () {
    _SkitActor_update.call(this);

    if (this._showing && (this._blinkCount > 0 || this._blinkWait > 0)) {
      this.updateBlink();
    }
  };

  SkitActor.prototype.clearBlink = function () {
    this._blinkCount = 0; //currentFrameCount
    this._blinkWait = 0; //waitToStartBlink
  };

  SkitActor.prototype.setupBlink = function () {
    this.clearBlink();

    var pose = this._pose;
    var exp = this._expression;
    if (/-(?:b|B|nb|NB)(?:-|$)/.test(exp)) {
      return;
    }

    var expActorData = $dataTrpSkit[this._name];
    if (!expActorData) return;

    var poseData = expActorData.poses[pose];
    if (!poseData || !poseData.blinkIds) return;

    this.setBlinkWait();
  };

  SkitActor.prototype.updateBlink = function () {
    if (this._blinkWait === 0) {
      var blinkCount = this.blinkFrame();
      if (this._blinkCount % blinkCount === 0) {
        var blinkIdx = this._blinkCount / blinkCount;
        if (blinkIdx > this.exData().poses[this._pose].blinkIds.length) {
          this._blinkCount = 0;
          this.setBlinkWait();
        }
        this.applyOverlay();
      }

      if (this._blinkWait === 0) {
        this._blinkCount += 1;
      }
    } else {
      this._blinkWait -= 1;
      if (this._blinkWait <= 0) {
        this._blinkCount = 1;
        this.applyOverlay();
      }
    }
  };

  SkitActor.prototype.setBlinkWait = function () {
    this._blinkWait =
      parameters.minFrame +
      Math.max(0, Math.randomInt(parameters.maxFrame - parameters.minFrame));
    this._blinkCount = 0;
  };
  SkitActor.prototype.blinkFrame = function () {
    return Math.max(1, parameters.blinkFrame);
  };

  var _SkitActor_overlayName = SkitActor.prototype.overlayName;
  SkitActor.prototype.overlayName = function () {
    var overlay = _SkitActor_overlayName.call(this);
    if (this._showing && !this._blinkWait && this._blinkCount) {
      overlay += "-" + this.blinkOverlayParts();
    }
    return overlay;
  };

  SkitActor.prototype.blinkOverlayParts = function () {
    var blinkIdx = Math.ceil(this._blinkCount / this.blinkFrame()) - 1;
    return "b:" + blinkIdx;
  };

  //=============================================================================
  // Sprite_Picture
  //=============================================================================
  var _Sprite_Picture_convertSkitOverlayPartsId =
    Sprite_Picture.convertSkitOverlayPartsId;
  Sprite_Picture.convertSkitOverlayPartsId = function (
    ret,
    elem,
    poseData,
    exps
  ) {
    var separatorIdx = elem.indexOf(":");
    if (
      (elem[0] === "B" || elem[0] === "b") &&
      (elem === "B" || elem === "b" || separatorIdx === 1)
    ) {
      if (poseData.blinkIds) {
        var blinkIdx = poseData.blinkIds.length - 1;
        if (separatorIdx > 0) {
          blinkIdx = Number(elem.substring(separatorIdx + 1));
          if (isNaN(blinkIdx)) {
            blinkIdx = poseData.blinkIds.length - 1;
          }
        }
        elem =
          "p" +
          poseData.blinkKind +
          ":" +
          poseData.blinkIds[Math.min(blinkIdx, poseData.blinkIds.length - 1)];
      } else {
        return;
      }
    } else if (elem === "NB" || elem === "nb") {
      return;
    }

    _Sprite_Picture_convertSkitOverlayPartsId.call(
      this,
      ret,
      elem,
      poseData,
      exps
    );
  };
})();


code:
//=============================================================================
// TRP_SkitMZ_ExLipSync.js
//=============================================================================
// Copyright (c) 2020 Thirop
//============================================================================

/*:
 * @target MZ
 * @author Thirop
 * @plugindesc TRP_SkitMZ、口パク拡張パッチ
 * @help
 * 立ち絵表示時にセリフに合わせて口パク動作を有効化します。
 * （※表情の階層レイヤーを使用する必要があります。）
 *
 * 1.各キャラの各ポーズごとに表情ピッカーを起動し
 * 「Lキー」より口パクパーツ選択モードに入る。
 * 2.口パーツにあたる表情パーツ種類を選択
 * 3.口パク時にランダム表示するパーツIDをクリックで選択
 * 4.決定キーで確定後、「Sキー」で保存
 *
 *
 * ◆口パクの停止
 * 制御文字やプラグインコマンドで表情指定時に「表情名-NL」と-NLを付記。
 *
 *
 * 【更新履歴】
 * 1.00 2020/11/10 初版
 *
 * @param animationFrame
 * @text フレーム数
 * @desc １コマあたりのフレーム数
 * @type number
 * @default 9
 *
 */
//=============================================================================

(function () {
  "use strict";

  var pluginName = "TRP_SkitMZ_ExLipSync";
  var parameters = JSON.parse(
    JSON.stringify(PluginManager.parameters(pluginName), function (key, value) {
      try {
        return JSON.parse(value);
      } catch (e) {
        try {
          if (value[0] === "[" || value[0] === "{") {
            if (value.contains(" ")) {
              return value;
            }
            return eval(value);
          } else if (value === "") {
            return value;
          } else if (!isNaN(value)) {
            return Number(value);
          } else if (value === "true") {
            return true;
          } else if (value === "false") {
            return false;
          } else {
            return value;
          }
        } catch (e) {
          return value;
        }
      }
    })
  );

  var _Window_Message_flushTextState = Window_Message.prototype.flushTextState;
  Window_Message.prototype.flushTextState = function (textState) {
    if (textState.drawing && textState.buffer) {
      $gameMessage.onPronounce(textState.buffer);
    }
    _Window_Message_flushTextState.call(this, textState);
  };

  Game_Message.prototype.onPronounce = function (text) {
    if (this._talkingActorName) {
      $gameSkit.onPronounce(this._talkingActorName, text);
    }
  };

  Skit.prototype.onPronounce = function (target, text) {
    if (!this.isSkitOn()) return;

    var actor = this.actor(target);
    if (actor && actor._showing) {
      actor.onPronounce(text);
    }
  };

  var _SkitActor_clearParameters = SkitActor.prototype.clearParameters;
  SkitActor.prototype.clearParameters = function () {
    _SkitActor_clearParameters.call(this);
    this.clearLipSync();
  };

  var _SkitActor_show = SkitActor.prototype.show;
  SkitActor.prototype.show = function () {
    this.clearLipSync();
    _SkitActor_show.apply(this, arguments);

    this.setupLipSync();
  };

  var _SkitActor_changeImage = SkitActor.prototype.changeImage;
  SkitActor.prototype.changeImage = function () {
    this.clearLipSync();
    _SkitActor_changeImage.apply(this, arguments);

    this.setupLipSync();
  };

  var _SkitActor_overlayName = SkitActor.prototype.overlayName;
  SkitActor.prototype.overlayName = function () {
    var overlay = _SkitActor_overlayName.call(this);
    if (this._lipSyncIdx >= 0) {
      overlay += "-L:" + this._lipSyncIdx;
    }
    return overlay;
  };

  var _SkitActor_update = SkitActor.prototype.update;
  SkitActor.prototype.update = function () {
    _SkitActor_update.call(this);
    if (this._lipSyncWait > 0) {
      this.updateLipSyncWait();
    }
  };

  SkitActor.prototype.onPronounce = function (text) {
    if (this._lipSyncWait !== 0) return;

    var lipSyncIds = this.exData().poses[this._pose].lipSyncIds;
    var idx;

    if (this._lipSyncIdx >= 0) {
      idx = Math.randomInt(lipSyncIds.length - 1);
      if (idx >= this._lipSyncIdx) {
        idx += 1;
      }
    } else {
      idx = Math.randomInt(lipSyncIds.length);
    }

    this._lipSyncIdx = idx;
    this._lipSyncWait = this.lipSyncWait();

    this.applyOverlay();
  };

  SkitActor.prototype.clearLipSync = function () {
    this._lipSyncWait = 0;
    this._lipSyncIdx = -1;
  };

  SkitActor.prototype.setupLipSync = function () {
    this.clearLipSync();

    var exp = this._expression;
    if (/-(?:nl|NL)(?:-|$)/.test(exp)) {
      this._lipSyncWait = -1;
      return;
    }

    var actorData = this.exData();
    var pose = actorData ? actorData.poses[this._pose] : null;
    var lipSyncIds = pose ? pose.lipSyncIds : null;
    if (!lipSyncIds || lipSyncIds.length === 0) {
      this._lipSyncWait = -1;
      return;
    }
  };

  SkitActor.prototype.updateLipSyncWait = function () {
    this._lipSyncWait -= 1;
    if (this._lipSyncWait <= 0) {
      this._lipSyncWait = 0;
      this._lipSyncIdx = -1;
      this.applyOverlay();
    }
  };

  SkitActor.prototype.lipSyncWait = function () {
    return parameters.animationFrame;
  };

  //=============================================================================
  // Sprite_Picture
  //=============================================================================
  var _Sprite_Picture_convertSkitOverlayPartsId =
    Sprite_Picture.convertSkitOverlayPartsId;
  Sprite_Picture.convertSkitOverlayPartsId = function (
    ret,
    elem,
    poseData,
    exps
  ) {
    if ((elem[0] === "L" || elem[0] === "l") && elem[1] === ":") {
      if (poseData.lipSyncIds) {
        var lipSyncIdx = Number(elem.substring(2));
        if (isNaN(lipSyncIdx)) {
          lipSyncIdx = poseData.lipSyncIds.length - 1;
        }
        elem =
          "p" + poseData.lipSyncKind + ":" + poseData.lipSyncIds[lipSyncIdx];
      } else {
        return;
      }
    } else if (elem === "NL" || elem === "nl") {
      return;
    }

    _Sprite_Picture_convertSkitOverlayPartsId.call(
      this,
      ret,
      elem,
      poseData,
      exps
    );
  };
})();

repo_name: dazed/translations

license: unknown


code:
//=============================================================================
// TRP_SpriteSheets.js
//=============================================================================
// Copyright (c) 2020 Thirop
//=============================================================================
/*:
 * @target MZ
 * @author Thirop
 * @plugindesc スプライトシート機能の提供
 * @help
 * TRP_SkitMZにて階層レイヤー方式の画像形式で
 * スプライトシート化した表情画像を使用する際に必要な
 * プラグインです。
 *
 * 【更新履歴】
 * 1.01 2022/2/27  画像読み込みが遅れた際のエラー修正
 * 1.00 2020/11/10 初版
 */

var TRP_SpriteSheet = function () {};

(() => {
  "use strict";

  var _DataManager_loadDatabase = DataManager.loadDatabase;
  DataManager.loadDatabase = function () {
    _DataManager_loadDatabase.call(this);

    TRP_SpriteSheet.setup();
  };

  var _DataManager_isDatabaseLoaded = DataManager.isDatabaseLoaded;
  DataManager.isDatabaseLoaded = function () {
    if (!_DataManager_isDatabaseLoaded.call(this)) return false;
    if (!TRP_SpriteSheet.isReady()) return false;

    return true;
  };

  //=============================================================================
  // TRP_SpriteSheet
  //=============================================================================
  TRP_SpriteSheet._loadingCount = 0;
  TRP_SpriteSheet.data = {};

  TRP_SpriteSheet.setup = function () {};

  TRP_SpriteSheet.load = function (file, completion = null) {
    if (this.data[file]) return;

    this._loadingCount += 1;

    file = file.replace(".json", "");

    var xhr = new XMLHttpRequest();
    var url = "dataEx/spritesheets/" + file + ".json";
    xhr.open("GET", url);
    xhr.overrideMimeType("application/json");
    xhr.onload = this._onLoad.bind(this, file, xhr, completion);

    xhr.onerror = this._onError.bind(this, url);
    xhr.send();
  };

  TRP_SpriteSheet._onLoad = function (file, xhr, completion = null) {
    if (xhr.status < 400) {
      this.data[file] = JSON.parse(xhr.responseText);
    }
    this._loadingCount -= 1;

    if (completion) {
      completion();
    }
  };
  TRP_SpriteSheet._onError = function (url) {
    DataManager._errorUrl = DataManager._errorUrl || url;
  };
  TRP_SpriteSheet.isReady = function () {
    return this._loadingCount === 0;
  };

  //=============================================================================
  // Sprite
  //=============================================================================
  Sprite.prototype.setupWithSheet = function (sheet, image, bitmap) {
    if (!this.bitmap) return;
    if (bitmap && this.bitmap !== bitmap) return;

    if (!this.bitmap.isReady()) {
      this.bitmap.addLoadListener(this.setupWithSheet.bind(this, sheet, image));
      return;
    }

    if (!TRP_SpriteSheet.data[sheet]) {
      throw new Error("spritesheet not loaded:" + sheet);
    }

    var data = TRP_SpriteSheet.data[sheet].frames[image];
    if (!data) {
      throw new Error(
        "spritesheet image data not found:" + sheet + ">" + image
      );
    }

    var rect = data.frame;
    if (!rect) return;

    var frame = null;
    var trim = null;
    var sourceSize =
      data.trimmed !== false && data.sourceSize ? data.sourceSize : data.frame;
    var orig = new Rectangle(
      0,
      0,
      Math.floor(sourceSize.w),
      Math.floor(sourceSize.h)
    );
    if (data.rotated) {
      frame = new Rectangle(
        Math.floor(rect.x),
        Math.floor(rect.y),
        Math.floor(rect.h),
        Math.floor(rect.w)
      );
    } else {
      frame = new Rectangle(
        Math.floor(rect.x),
        Math.floor(rect.y),
        Math.floor(rect.w),
        Math.floor(rect.h)
      );
    }
    //  Check to see if the sprite is trimmed
    if (data.trimmed !== false && data.spriteSourceSize) {
      trim = new Rectangle(
        Math.floor(data.spriteSourceSize.x),
        Math.floor(data.spriteSourceSize.y),
        Math.floor(rect.w),
        Math.floor(rect.h)
      );
    }

    this._frame = frame;
    this.texture.trim = trim;
    this.texture.orig = orig;
    this.texture._rotate = data.rotated ? 2 : 0;
    this.texture.frame = frame.clone();

    this.texture.updateUvs();
  };
})();


code:
//=============================================================================
// RPG Maker MZ - Text Picture
//=============================================================================

/*:
 * @target MZ
 * @plugindesc Displays text as a picture.
 * @author Yoji Ojima
 *
 * @help TextPicture.js
 *
 * This plugin provides a command to show text as a picture.
 *
 * Use it in the following procedure.
 *   1. Call the plugin command "Set Text Picture".
 *   2. Execute "Show Picture" without specifying an image.
 *
 * @command set
 * @text Set Text Picture
 * @desc Sets text to display as a picture.
 *       After this, execute "Show Picture" without specifying an image.
 *
 * @arg text
 * @type multiline_string
 * @text Text
 * @desc Text to display as a picture.
 *       Control characters are allowed.
 */

/*:ja
 * @target MZ
 * @plugindesc テキストをピクチャとして表示します。
 * @author Yoji Ojima
 *
 * @help TextPicture.js
 *
 * このプラグインは、テキストをピクチャとして表示するコマンドを提供します。
 *
 * 次の手順で使用してください。
 *   1. プラグインコマンド「テキストピクチャの設定」を呼び出します。
 *   2. 画像を指定せずに「ピクチャの表示」を実行します。
 *
 * @command set
 * @text テキストピクチャの設定
 * @desc ピクチャとして表示するテキストを設定します。
 *       この後、画像を指定せずに「ピクチャの表示」を実行してください。
 *
 * @arg text
 * @type multiline_string
 * @text テキスト
 * @desc ピクチャとして表示するテキストです。
 *       制御文字が使用可能です。
 */

(() => {
  const pluginName = "TextPicture";
  let textPictureText = "";

  PluginManager.registerCommand(pluginName, "set", (args) => {
    textPictureText = String(args.text);
  });

  const _Game_Picture_show = Game_Picture.prototype.show;
  Game_Picture.prototype.show = function () {
    _Game_Picture_show.apply(this, arguments);
    if (this._name === "" && textPictureText) {
      this.mzkp_text = textPictureText;
      this.mzkp_textChanged = true;
      textPictureText = "";
    }
  };

  const _Sprite_Picture_destroy = Sprite_Picture.prototype.destroy;
  Sprite_Picture.prototype.destroy = function () {
    destroyTextPictureBitmap(this.bitmap);
    _Sprite_Picture_destroy.apply(this, arguments);
  };

  const _Sprite_Picture_updateBitmap = Sprite_Picture.prototype.updateBitmap;
  Sprite_Picture.prototype.updateBitmap = function () {
    _Sprite_Picture_updateBitmap.apply(this, arguments);
    if (this.visible && this._pictureName === "") {
      const picture = this.picture();
      const text = picture ? picture.mzkp_text || "" : "";
      const textChanged = picture && picture.mzkp_textChanged;
      if (this.mzkp_text !== text || textChanged) {
        this.mzkp_text = text;
        destroyTextPictureBitmap(this.bitmap);
        this.bitmap = createTextPictureBitmap(text);
        picture.mzkp_textChanged = false;
      }
    } else {
      this.mzkp_text = "";
    }
  };

  function createTextPictureBitmap(text) {
    const tempWindow = new Window_Base(new Rectangle());
    const size = tempWindow.textSizeEx(text);
    tempWindow.padding = 0;
    tempWindow.move(0, 0, size.width, size.height);
    tempWindow.createContents();
    tempWindow.drawTextEx(text, 0, 0, 0);
    const bitmap = tempWindow.contents;
    tempWindow.contents = null;
    tempWindow.destroy();
    bitmap.mzkp_isTextPicture = true;
    return bitmap;
  }

  function destroyTextPictureBitmap(bitmap) {
    if (bitmap && bitmap.mzkp_isTextPicture) {
      bitmap.destroy();
    }
  }
})();


code:
/*---------------------------------------------------------------------------*
 * TorigoyaMZ_EnemyHpBar.js v.1.3.2
 *---------------------------------------------------------------------------*
 * 2021/10/10 20:48 (JST)
 *---------------------------------------------------------------------------*
 * Ruたん ( @ru_shalm )
 * https://torigoya-plugin.rutan.dev
 *---------------------------------------------------------------------------*/

/*:
 * @target MZ
 * @plugindesc 敵にHPバーを表示プラグイン (v.1.3.2)
 * @author Ruたん（ru_shalm）
 * @license public domain
 * @version 1.3.2
 * @url https://raw.githubusercontent.com/rutan/torigoya-rpg-maker-plugin/gh-pages/TorigoyaMZ_EnemyHpBar.js
 * @help
 * 敵にHPバーを表示プラグイン (v.1.3.2)
 * https://torigoya-plugin.rutan.dev
 *
 * 敵キャラにHPバーを表示します
 *
 * ------------------------------------------------------------
 * ■ 使い方
 * ------------------------------------------------------------
 * このプラグインを入れるだけでOK！
 * 細かい表示はプラグイン設定で変更できます。
 *
 * ------------------------------------------------------------
 * ■ 敵キャラ個別にいろいろ設定したい！
 * ------------------------------------------------------------
 * いくつかの設定は、敵キャラのメモ欄に指定を書くことで変更できます。
 *
 * ▼ 特定の敵キャラにはHPを表示したくない場合
 * <HPバー非表示>
 *
 * ▼ 特定の敵キャラのHPゲージを横にずらしたい場合
 * <HPバーX: 100>
 *
 * ※100の部分をずらす量に変えよう。マイナスだと左にいくよ
 *
 * ▼ 特定の敵キャラのHPゲージを上下にずらしたい場合
 * <HPバーY: 100>
 *
 * ※100の部分をずらす量に変えよう。マイナスだと上にいくよ
 *
 * ▼ 特定の敵キャラのHPゲージの幅を変えたい場合
 * <HPバー幅: 320>
 *
 * ▼ 特定の敵キャラのHPゲージの太さを変えたい場合
 * <HPバー高さ: 30>
 *
 * ▼ 敵キャラのHPの数値を「????」にしたい場合
 *
 * <HP表示条件: false>
 *
 * ▼ いや、HPが半分切ったら「????」じゃなくしたいな
 *
 * <HP表示条件: a.hp < a.mhp * 0.5>
 *
 * ダメージ計算式のような形式で条件を書くことができます。
 * （a には敵の情報が入ります。ただし b はありません）
 * 条件が真になるとHPが数値で表示され、
 * 偽の場合はプラグイン設定で指定したマスク文字（?????等）で表示されます。
 *
 * ▼ 一度「????」じゃなくなったら、条件が解けても戻さないで！
 *
 * <HP表示条件: a.hp < a.mhp * 0.5>
 * <HP表示状態継続>
 *
 * このように <HP表示状態継続> というのを追加することで、
 * その戦闘中は一度HP表示状態になると、
 * ずっとHPが表示されるようになります。
 *
 * @param base
 * @text ■ 基本設定
 *
 * @param basePosition
 * @text 表示場所
 * @desc ゲージを表示する場所を選択します
 * @type select
 * @parent base
 * @option 敵画像の上
 * @value top
 * @option 敵画像の下
 * @value bottom
 * @default top
 *
 * @param basePosX
 * @text 位置:X
 * @desc ゲージの横方向の位置を調整します
 * マイナスだと左、プラスだと右にずれます
 * @type number
 * @parent base
 * @min -10000
 * @max 10000
 * @default 0
 *
 * @param basePosY
 * @text 位置:Y
 * @desc ゲージの縦方向の位置を調整します
 * マイナスだと上、プラスだと下にずれます
 * @type number
 * @parent base
 * @min -10000
 * @max 10000
 * @default 0
 *
 * @param customize
 * @text ■ 表示カスタマイズ
 *
 * @param customizeCondition
 * @text 表示条件
 * @desc いつゲージを表示するかを選択します
 * @type select
 * @parent customize
 * @option 常に表示
 * @value always
 * @option 選択中・ダメージ中のみ
 * @value selectOrDamage
 * @default always
 *
 * @param customizeGaugeWidth
 * @text バーの幅
 * @desc HPバーの幅
 * @type number
 * @parent customize
 * @min 1
 * @default 100
 *
 * @param customizeGaugeHeight
 * @text バーの高さ
 * @desc HPバーの高さ
 * @type number
 * @parent customize
 * @min 1
 * @default 10
 *
 * @param customizeDrawLabel
 * @text HP数値
 * @desc HP数値を表示するか？
 * @type boolean
 * @parent customize
 * @on 表示する
 * @off 表示しない
 * @default true
 *
 * @param customizeLabelWidth
 * @text HPラベルの横幅
 * @desc HPのラベルエリアの横幅
 * @type number
 * @parent customize
 * @min 0
 * @default 20
 *
 * @param customizeLabelFontSize
 * @text HPラベルの文字サイズ
 * @desc HPのラベルの文字サイズ
 * @type number
 * @parent customize
 * @min 1
 * @default 16
 *
 * @param customizeValueFontSize
 * @text HP数値の文字サイズ
 * @desc HPの値の文字サイズ
 * @type number
 * @parent customize
 * @min 1
 * @default 20
 *
 * @param customizeMaskHpValue
 * @text HPのマスク表記
 * @desc HP数値を秘密にする場合の表示
 * @type string
 * @parent customize
 * @default ?????
 */

(function () {
  "use strict";

  const Torigoya = (window.Torigoya = window.Torigoya || {});

  function getPluginName() {
    const cs = document.currentScript;
    return cs
      ? cs.src.split("/").pop().replace(/\.js$/, "")
      : "TorigoyaMZ_EnemyHpBar";
  }

  function pickStringValueFromParameter(parameter, key, defaultValue = "") {
    if (!parameter.hasOwnProperty(key)) return defaultValue;
    return "".concat(parameter[key] || "");
  }

  function pickIntegerValueFromParameter(parameter, key, defaultValue = 0) {
    if (!parameter.hasOwnProperty(key) || parameter[key] === "")
      return defaultValue;
    return parseInt(parameter[key], 10);
  }

  function pickBooleanValueFromParameter(
    parameter,
    key,
    defaultValue = "false"
  ) {
    return "".concat(parameter[key] || defaultValue) === "true";
  }

  function readParameter() {
    const parameter = PluginManager.parameters(getPluginName());
    return {
      version: "1.3.2",
      basePosition: pickStringValueFromParameter(
        parameter,
        "basePosition",
        "top"
      ),
      basePosX: pickIntegerValueFromParameter(parameter, "basePosX", 0),
      basePosY: pickIntegerValueFromParameter(parameter, "basePosY", 0),
      customizeCondition: pickStringValueFromParameter(
        parameter,
        "customizeCondition",
        "always"
      ),
      customizeGaugeWidth: pickIntegerValueFromParameter(
        parameter,
        "customizeGaugeWidth",
        100
      ),
      customizeGaugeHeight: pickIntegerValueFromParameter(
        parameter,
        "customizeGaugeHeight",
        10
      ),
      customizeDrawLabel: pickBooleanValueFromParameter(
        parameter,
        "customizeDrawLabel",
        "true"
      ),
      customizeLabelWidth: pickIntegerValueFromParameter(
        parameter,
        "customizeLabelWidth",
        20
      ),
      customizeLabelFontSize: pickIntegerValueFromParameter(
        parameter,
        "customizeLabelFontSize",
        16
      ),
      customizeValueFontSize: pickIntegerValueFromParameter(
        parameter,
        "customizeValueFontSize",
        20
      ),
      customizeMaskHpValue: pickStringValueFromParameter(
        parameter,
        "customizeMaskHpValue",
        "?????"
      ),
    };
  }

  function unescapeMetaString(string) {
    return ""
      .concat(string || "")
      .trim()
      .replace(/</g, "<")
      .replace(/>/g, ">");
  }

  Torigoya.EnemyHpBar = {
    name: getPluginName(),
    parameter: readParameter(),
  };

  function isHiddenHpBar(enemy) {
    return !enemy || enemy.meta["hiddenHpBar"] || enemy.meta["HPバー非表示"];
  }

  function hpBarX(enemy) {
    return parseInt(
      (enemy && (enemy.meta["hpBarPosX"] || enemy.meta["HPバーX"])) || 0,
      10
    );
  }

  function hpBarY(enemy) {
    return parseInt(
      (enemy && (enemy.meta["hpBarPosY"] || enemy.meta["HPバーY"])) || 0,
      10
    );
  }

  function hpBarWidth(enemy) {
    return parseInt(
      (enemy && (enemy.meta["hpBarWidth"] || enemy.meta["HPバー幅"])) || 0,
      10
    );
  }

  function hpBarHeight(enemy) {
    return parseInt(
      (enemy && (enemy.meta["hpBarHeight"] || enemy.meta["HPバー高さ"])) || 0,
      10
    );
  }

  const forceShowHpValueCache = new WeakSet();

  function isShowHpValueOfBattler(a) {
    if (!a) return true;
    if (forceShowHpValueCache.has(a)) return true;

    const enemy = a.enemy();
    const code =
      enemy.meta["hpShowCondition"] || enemy.meta["HP表示条件"] || "";
    if (!code) return true;
    try {
      if (eval(unescapeMetaString(code))) {
        if (enemy.meta["hpShowPermanently"] || enemy.meta["HP表示状態継続"]) {
          forceShowHpValueCache.add(a);
        }
        return true;
      }
    } catch (e) {
      if ($gameTemp.isPlaytest()) console.error(e);
    }

    return false;
  }

  class Sprite_EnemyHpGauge extends Sprite_Gauge {
    constructor() {
      super();
      this._durationWait = 0;
    }

    setup(battler, statusType) {
      if (this._battler === battler) return;
      this._battler = battler;
      this.reCreateBitmap();
      super.setup(battler, statusType);
    }

    reCreateBitmap() {
      if (this.bitmap) this.bitmap.destroy();
      this.bitmap = null;
      this.createBitmap();
    }

    bitmapWidth() {
      return this.gaugeWidth() + this.gaugeX();
    }

    bitmapHeight() {
      // コアスクリプトv.1.3.3 の以下の修正内容を適用
      // > HP（略）MP（略）TP（略）に一部の英文字を利用すると見切れる問題を修正
      if (Sprite_Gauge.prototype.textHeight) {
        return Math.round(this.textHeight() * 1.5);
      } else {
        return this.textHeight();
      }
    }

    textHeight() {
      if (Torigoya.EnemyHpBar.parameter.customizeDrawLabel) {
        return Math.max(
          this.labelFontSize() + this.labelOutlineWidth(),
          this.valueFontSize() + this.valueOutlineWidth(),
          this.gaugeHeight()
        );
      } else {
        return this.gaugeHeight();
      }
    }

    gaugeWidth() {
      return (
        hpBarWidth(this._battler && this._battler.enemy()) ||
        Torigoya.EnemyHpBar.parameter.customizeGaugeWidth
      );
    }

    gaugeHeight() {
      return (
        hpBarHeight(this._battler && this._battler.enemy()) ||
        Torigoya.EnemyHpBar.parameter.customizeGaugeHeight
      );
    }

    gaugeX() {
      if (!Torigoya.EnemyHpBar.parameter.customizeDrawLabel) return 0;
      return Torigoya.EnemyHpBar.parameter.customizeLabelWidth;
    }

    labelFontSize() {
      return Torigoya.EnemyHpBar.parameter.customizeLabelFontSize;
    }

    valueFontSize() {
      return Torigoya.EnemyHpBar.parameter.customizeValueFontSize;
    }

    updateTargetValue(value, maxValue) {
      const oldDuration = this._duration;

      super.updateTargetValue(value, maxValue);

      if (oldDuration !== this._duration && BattleManager._phase !== "") {
        this._durationWait = this.durationWait();
      }
    }

    updateGaugeAnimation() {
      super.updateGaugeAnimation();
      if (this._durationWait > 0 && this._duration <= 0) {
        --this._durationWait;
      }
    }

    drawLabel() {
      if (!Torigoya.EnemyHpBar.parameter.customizeDrawLabel) return;
      super.drawLabel();
    }

    drawValue() {
      if (!Torigoya.EnemyHpBar.parameter.customizeDrawLabel) return;
      if (isShowHpValueOfBattler(this._battler)) {
        super.drawValue();
      } else {
        this.drawMaskValue();
      }
    }

    drawMaskValue() {
      const width = this.bitmapWidth();
      const height = this.bitmapHeight();
      this.setupValueFont();
      this.bitmap.drawText(
        Torigoya.EnemyHpBar.parameter.customizeMaskHpValue,
        0,
        0,
        width,
        height,
        "right"
      );
    }

    durationWait() {
      return this._statusType === "time" ? 0 : 60;
    }

    shouldShow() {
      if (!this._battler) return false;
      if (this._battler.isDead()) return false;
      if (isHiddenHpBar(this._battler.enemy())) return false;

      switch (Torigoya.EnemyHpBar.parameter.customizeCondition) {
        case "always": {
          return true;
        }
        case "selectOrDamage": {
          if (BattleManager._phase === "start") return false;

          if (this._battler && this._battler.isSelected()) return true;
          if (BattleManager._phase === "input") return false;

          if (this._duration > 0) return true;
          if (this._durationWait > 0) return true;

          break;
        }
      }

      return false;
    }
  }

  Torigoya.EnemyHpBar.Sprite_EnemyHpGauge = Sprite_EnemyHpGauge;

  (() => {
    const upstream_Sprite_Enemy_initMembers =
      Sprite_Enemy.prototype.initMembers;
    Sprite_Enemy.prototype.initMembers = function () {
      upstream_Sprite_Enemy_initMembers.apply(this);
      this.torigoyaEnemyHpBar_createGaugeSprite();
    };

    Sprite_Enemy.prototype.torigoyaEnemyHpBar_createGaugeSprite = function () {
      this._torigoyaEnemyHpBar_gaugeSprite =
        new Torigoya.EnemyHpBar.Sprite_EnemyHpGauge();
      this._torigoyaEnemyHpBar_gaugeSprite.anchor.x = 0.5;
      this._torigoyaEnemyHpBar_gaugeSprite.opacity = 0;
      this.addChild(this._torigoyaEnemyHpBar_gaugeSprite);
    };

    const upstream_Sprite_Enemy_setBattler = Sprite_Enemy.prototype.setBattler;
    Sprite_Enemy.prototype.setBattler = function (battler) {
      upstream_Sprite_Enemy_setBattler.apply(this, arguments);
      this._torigoyaEnemyHpBar_gaugeSprite.setup(battler, "hp");
    };

    const upstream_Sprite_Enemy_update = Sprite_Enemy.prototype.update;
    Sprite_Enemy.prototype.update = function () {
      upstream_Sprite_Enemy_update.apply(this);
      if (this._enemy) {
        this.torigoyaEnemyHpBar_updateGaugeSprite();
      }
    };

    Sprite_Enemy.prototype.torigoyaEnemyHpBar_updateGaugeSprite = function () {
      this._torigoyaEnemyHpBar_gaugeSprite.x = this.torigoyaEnemyHpBar_posX();
      this._torigoyaEnemyHpBar_gaugeSprite.y = this.torigoyaEnemyHpBar_posY();

      this._torigoyaEnemyHpBar_gaugeSprite.opacity +=
        this._torigoyaEnemyHpBar_gaugeSprite.shouldShow() ? 48 : -48;
    };

    Sprite_Enemy.prototype.torigoyaEnemyHpBar_posX = function () {
      let x = Torigoya.EnemyHpBar.parameter.basePosX;
      x += hpBarX(this._battler && this._battler.enemy());
      return x;
    };

    Sprite_Enemy.prototype.torigoyaEnemyHpBar_posY = function () {
      let y = Torigoya.EnemyHpBar.parameter.basePosY;
      if (this.bitmap && this.bitmap.isReady()) {
        switch (Torigoya.EnemyHpBar.parameter.basePosition) {
          case "top":
            y -=
              this.bitmap.height +
              this._torigoyaEnemyHpBar_gaugeSprite.textHeight();
            break;
        }
      }
      y += hpBarY(this._battler && this._battler.enemy());

      return y;
    };
  })();
})();


code:
//=============================================================================
// UTA_CommonSaveMZ.js
//=============================================================================
/*:
 * @target MZ
 * @plugindesc Share state of game switches and variables between each save data.
 *
 * @author t-akatsuki
 * @url https://www.utakata-no-yume.net
 *
 * @param targetSwitches
 * @text Share target switches
 * @desc Set target switches number you want make shared.
 * Using "-", the range can be specified.
 * @default []
 * @type string[]
 *
 * @param targetVariables
 * @text Share target variables
 * @desc Set target variables number you want make shared.
 * Using "-", the range can be specified.
 * @default []
 * @type string[]
 *
 * @param applyOnLoad
 * @text Apply common save on load game
 * @desc Automatically loading common save on load game timing.
 * ON(true): enabled, OFF(false): disabled
 * @default true
 * @type boolean
 *
 * @param applyOnSave
 * @text Save common save on save game
 * @desc Automatically saving common save on save game timing.
 * ON(true): enabled, OFF(false): disabled
 * @default true
 * @type boolean
 *
 * @param applyOnNewGame
 * @text Apply common save on new game
 * @desc Automatically loading common save on start new game.
 * ON(true): enabled, OFF(false): disabled
 * @default true
 * @type boolean
 *
 * @param applyOnAutoSave
 * @text Save common save on auto-save
 * @desc Automatically saving common save on auto-save timing.
 * ON(true): enabled, OFF(false): disabled
 * @default false
 * @type boolean
 *
 * @param applyOnGameover
 * @text Save common save on gameover
 * @desc Automatically saving common save on gameover timing.
 * ON(true): enabled, OFF(false): disabled
 * @default true
 * @type boolean
 *
 * @param saveFileName
 * @text Save file name
 * @desc Definition of common save file name,
 * which not contained extension.
 * @default uta_common
 * @type string
 *
 * @command load
 * @text Load common save
 * @desc Loading shared target switches/variables from common save.
 * This command used when you want to load common save.
 *
 * @command save
 * @text Save common save
 * @desc Saving shared target switches/variables to common save.
 * This command used when you want to save common save.
 *
 * @command remove
 * @text Remove common save
 * @desc Remove common save data.
 * This command used when you want to reset common save.
 *
 * @command check
 * @text Check shared switches/variables number
 * @desc Output shared target switches/variables numbers to console.
 * This command for test.
 *
 * @help # Overview
 * UTA_CommonSaveMZ plugin creates shared save data and shares the state of
 * the specified switches/variables between game save data.
 * You can have it applied automatically at the time of save/load
 * according to your settings.
 *
 * The "common save data" can be manipulated at any time by
 * using plugin commands.
 *
 * This plugin creates shared save data as "common save data" separately
 * from game save datas.
 * In the local version, "common save data" files are created in
 * the save directory.
 * In web version, the "common save data" is saved in LocalStorage.
 *
 * # Plugin Parameters
 * ## Share target switches
 *    Set target switches number you want make shared.
 *    You can specify multiple settings.
 *    Using "-", the range can be specified.
 *    (ex1) 10
 *      => switch of number (10) will be set shared target.
 *    (ex2) 10-15
 *      => switches of number (10,11,12,13,14,15) will be set shared targets.
 *
 * ## Share target variables
 *    Set target variables number you want make shared.
 *    You can specify multiple settings.
 *    Using "-", the range can be specified.
 *    The rules for specifiying the number is the same as for
 *    "Share target switches".
 *
 * ## Apply common save on load game
 *    Automatically loading common save on load game timing.
 *    ON(true)   : enabled(default)
 *    OFF(false): disabled
 *
 * ## Save common save on save game
 *    Automatically saving common save on save game timing.
 *    ON(true)  : enabled(default)
 *    OFF(false): disabled
 *
 * ## Apply common save on new game
 *    Automatically loading common save on start new game.
 *    ON(true)  : enabled(default)
 *    OFF(false): disabled
 *
 * ## Save common save on auto-save
 *    Automatically saving common save on auto-save timing.
 *    ON(true)  : enabled
 *    OFF(false): disabled(default)
 *
 * ## Save common save on gameover
 *    Automatically saving common save on gameover timing.
 *    ON(true)  : enabled(default)
 *    OFF(false): disabled
 *
 * ## Save file name
 *    Definition of common save file name,
 *    which not contained extension.
 *    Do not use the same name as the existing save data
 *    (file0, global, confid, etc...).
 *    (default: uta_common)
 *
 * # Plugin Commands
 * ## Load common save
 *    Loading shared target switches/variables from common save.
 *    This command used when you want to load common save.
 *
 * ## Save common save
 *    Saving shared target switches/variables to common save.
 *    This command used when you want to save common save.
 *
 * ## Remove common save
 *    Remove common save data.
 *    This command used when you want to reset common save.
 *
 * ## Check shared switches/variables number
 *    Output shared target switches/variables numbers to console.
 *    This command for test.
 *
 * # Plugin Informations
 * Version      : 0.9.1
 * Last Updated : 2020/11/11
 * Author       : t-akatsuki
 * Web Site     : https://www.utakata-no-yume.net
 * GitHub       : https://github.com/t-akatsuki
 * Twitter      : https://twitter.com/T_Akatsuki
 * License      : MIT License
 *
 * # Changelog
 * ## 0.9.1 (2020/11/11)
 *   Fixed a bug that it doesn't work when the plugin parameter
 *   "Share target switches" or "Share target variables" is not specified.
 *   Added English annotation and README_EN.txt.
 *
 * ## 0.9.0 (2020/08/22)
 *   Beta version.
 *   Remake for RPG Maker MV based on UTA_CommonSave plugin for RPG Maker MV.
 *   Supports auto-save function.
 */
/*:ja
 * @target MZ
 * @plugindesc セーブデータ間で共有のセーブデータを作成し、
 * 指定したスイッチ・変数の状態をセーブデータ間で共有します。
 *
 * @author 赤月 智平(t-akatsuki)
 * @url https://www.utakata-no-yume.net
 *
 * @param targetSwitches
 * @text 共有対象スイッチ番号
 * @desc セーブデータ間で共有するスイッチ番号の定義です。
 * 「-」で範囲指定が可能です。
 * @default []
 * @type string[]
 *
 * @param targetVariables
 * @text 共有対象変数番号
 * @desc セーブデータ間で共有する変数番号の定義です。
 * 「-」で範囲指定が可能です。
 * @default []
 * @type string[]
 *
 * @param applyOnLoad
 * @text ロード時の共有セーブ自動適用
 * @desc ロード時に共有セーブデータの自動適用を行うか。
 * ON(true): 自動適用する, OFF(false): 自動適用しない
 * @default true
 * @type boolean
 *
 * @param applyOnSave
 * @text セーブ時の共有セーブ自動保存
 * @desc セーブ時に共有セーブデータの自動保存を行うか。
 * ON(true): 自動保存する, OFF(false): 自動保存しない
 * @default true
 * @type boolean
 *
 * @param applyOnNewGame
 * @text ニューゲーム時の共有セーブ自動適用
 * @desc ニューゲーム時に共有セーブの自動適用を行うか。
 * ON(true): 自動適用する, OFF(false): 自動適用しない
 * @default true
 * @type boolean
 *
 * @param applyOnAutoSave
 * @text オートセーブ時の共有セーブ自動保存
 * @desc オートセーブ時に共有セーブの自動保存を行うか。
 * ON(true): 自動保存する, OFF(false): 自動保存しない
 * @default false
 * @type boolean
 *
 * @param applyOnGameover
 * @text ゲームオーバー時の共有セーブ自動保存
 * @desc ゲームオーバー時に共有セーブデータの自動保存を行うか。
 * ON(true): 自動保存する, OFF(false): 自動保存しない
 * @default true
 * @type boolean
 *
 * @param saveFileName
 * @text 共有セーブデータファイル名
 * @desc 共有セーブデータファイル名の定義です。
 * 拡張子は自動設定される為含めません。
 * @default uta_common
 * @type string
 *
 * @command load
 * @text 共有セーブデータのロード
 * @desc 共有セーブデータからスイッチ・変数を読み込み反映させます。
 * 任意のタイミングで共有セーブデータをロードする際に使用します。
 *
 * @command save
 * @text 共有セーブデータのセーブ
 * @desc 共有セーブデータに対象のスイッチ・変数の状態を記録します。
 * 任意のタイミングで共有セーブデータをセーブする際に使用します。
 *
 * @command remove
 * @text 共有セーブデータの削除
 * @desc 共有セーブデータファイルを削除します。
 * 共有セーブデータをリセットしたい場合に使用します。
 *
 * @command check
 * @text 共有対象スイッチ/変数の確認
 * @desc 共有対象のスイッチ/変数番号をコンソールに表示します。
 * 動作確認用のプラグインコマンドです。
 *
 * @help # 概要
 * セーブデータ間で共有のセーブデータを作成し、
 * 指定したスイッチ・変数の状態をセーブデータ間で共有するプラグインです。
 * 設定に応じてセーブ・ロード時に自動的に反映を行わせる事ができます。
 * プラグインコマンドを利用すると、任意のタイミングで共有セーブデータの
 * 操作が可能です。
 *
 * 本プラグインでは通常のセーブデータとは別に共有セーブデータを作成します。
 * local版ではsaveディレクトリ以下に共有セーブデータファイルが作成されます。
 * web版ではLocalStorageに共有セーブデータが保存されます。
 *
 * # プラグインパラメータ
 * ## 共有対象スイッチ番号
 *    セーブデータ間で共有するスイッチ番号の定義です。
 *    複数設定する事ができます。
 *    「-」で範囲指定が可能です。
 *    (例1) 10
 *      => 10番のスイッチが対象になります。
 *    (例2) 10-15
 *      => 10,11,12,13,14,15番のスイッチが対象になります。
 *
 * ## 共有対象変数番号
 *    セーブデータ間で共有する変数番号の定義です。
 *    複数設定する事ができます。
 *    「-」で範囲指定が可能です。
 *    番号の指定方法及び規則は「共有対象スイッチ番号」と同様です。
 *
 * ## ロード時の共有セーブ自動適用
 *    ロード時に共有セーブデータの自動適用を行うか。
 *    ON(true)  : 自動適用する。(デフォルト値)
 *    OFF(false): 自動適用しない。
 *
 * ## セーブ時の共有セーブ自動保存
 *    セーブ時に共有セーブデータの自動保存を行うか。
 *    この設定はオートセーブには適用されません。
 *    ON(true)  : 自動保存する。(デフォルト値)
 *    OFF(false): 自動保存しない。
 *
 * ## ニューゲーム時の共有セーブ自動適用
 *    ニューゲーム時に共有セーブの自動適用を行うか。
 *    ON(true)  : 自動適用する。(デフォルト値)
 *    OFF(false): 自動適用しない。
 *
 * ## オートセーブ時の共有セーブ自動保存
 *    オートセーブ時に共有セーブの自動保存を行うか。
 *    ON(true)  : 自動保存する。
 *    OFF(false): 自動保存しない。(デフォルト値)
 *
 * ## ゲームオーバー時の共有セーブ自動保存
 *    ゲームオーバー時に共有セーブデータの自動保存を行うか。
 *    ON(true)  : 自動保存する。(デフォルト値)
 *    OFF(false): 自動保存しない。
 *
 * ## 共有セーブデータファイル名
 *    共有セーブデータファイル名の定義です。
 *    拡張子は自動設定される為含めません。
 *    既存セーブデータと重複する名前(file0, global, config等)は
 *    利用しないで下さい。
 *    (デフォルト設定値: uta_common)
 *
 * # プラグインコマンド
 * ## 共有セーブデータのロード
 *    共有セーブデータからスイッチ・変数を読み込み反映させます。
 *    任意のタイミングで共有セーブデータをロードする際に使用します。
 *
 * ## 共有セーブデータのセーブ
 *    共有セーブデータに対象のスイッチ・変数の状態を記録します。
 *    任意のタイミングで共有セーブデータをセーブする際に使用します。
 *
 * ## 共有セーブデータの削除
 *    共有セーブデータファイルを削除します。
 *    共有セーブデータをリセットしたい場合に使用します。
 *
 * ## 共有対象スイッチ/変数の確認
 *    共有対象のスイッチ/変数番号をコンソールに表示します。
 *    動作確認用のプラグインコマンドです。
 *
 * # プラグインの情報
 * バージョン : 0.9.1
 * 最終更新日 : 2020/11/11
 * 制作者     : 赤月 智平(t-akatsuki)
 * Webサイト  : https://www.utakata-no-yume.net
 * GitHub     : https://github.com/t-akatsuki
 * Twitter    : https://twitter.com/T_Akatsuki
 * ライセンス : MIT License
 *
 * # 更新履歴
 * ## 0.9.1 (2020/11/11)
 *   プラグインパラメータ「共有対象スイッチ番号」もしくは「共有対象変数番号」を
 *   指定していないと正常動作しない不具合の修正。
 *   英語版アノテーション, README_EN.txtの追加。
 *
 * ## 0.9.0 (2020/08/22)
 *   β版。
 *   RPGツクールMV用UTA_CommonSaveをベースにRPGツクールMZ用に移植。
 *   オートセーブ機能への対応。
 */
/**
 * @namespace utakata
 */
namespace utakata {
    "use strict";

    interface Version {
        major: number;
        minor: number;
        release: number;
    }

    interface CommonSavePluginParameters {
        saveFileName: string;
        targetSwitches: string;
        targetVariables: string;
        applyOnLoad: string;
        applyOnSave: string;
        applyOnNewGame: string;
        applyOnAutoSave: string;
        applyOnGameover: string;
    }

    interface CommonSaveData {
        version: Version;
        gameSwitches: { [idx: number]: boolean };
        gameVariables: { [idx: number]: number };
    }

    /**
     * @static
     * @class CommonSave
     * @classdesc 共有セーブ関連の処理を扱う静的クラス
     */
    export class CommonSave {
        /**
         * プラグイン名称定義
         * @type {string}
         */
        public static readonly PLUGIN_NAME: string = "UTA_CommonSaveMZ";
        /**
         * プラグインのバージョン定義
         * @type {object}
         */
        public static readonly PLUGIN_VERSION: Version = {
            major: 0,
            minor: 9,
            release: 1
        };
        /**
         * 共有対象のスイッチ番号定義
         * @type {number[]}
         */
        private static targetSwitches: number[] = [];
        /**
         * 共有対象の変数番号定義
         * @type {number[]}
         */
        private static targetVariables: number[] = [];
        /**
         * プラグインパラメータの参照
         * @type {object}
         */
        private static parameters: CommonSavePluginParameters;

        constructor() {
            throw new Error("CommonSave is static class.");
        }

        /**
         * 初期化処理
         * @static
         */
        public static initialize(): void {
            this.targetSwitches = [];
            this.targetVariables = [];
            this.parameters = <CommonSavePluginParameters>PluginManager.parameters(this.PLUGIN_NAME);

            // プラグインパラメータに指定された値を読み込む
            try {
                var targetSwitchesList: string[] = this.parameters.targetSwitches ? JsonEx.parse(this.parameters.targetSwitches) : [];
                var targetVariablesList: string[] = this.parameters.targetVariables ? JsonEx.parse(this.parameters.targetVariables) : [];
                this.loadTargetSwitchesNumber(targetSwitchesList);
                this.loadTargetVariablesNumber(targetVariablesList);
            } catch (e) {
                throw new Error(this.PLUGIN_NAME + ": plugin parameter parse error: " + e.message);
            }
        }

        /**
         * 文字列配列から対象番号配列をロードする。
         * 重複する番号が含まれていた場合はuniqueな状態になる。
         * @param {string[]} targetList 読み込み対象番号文字配列。
         * @return {number[]} 対象番号配列。
         */
        private static loadTargetCoreNumber(targetList: string[]): number[] {
            var ret: number[] = [];
            for (const targetStr of targetList) {
                const targetList = this.parseTargetNumber(targetStr);
                Array.prototype.push.apply(ret, targetList);
            }
            // unique
            ret = ret.filter((x: number, i: number, self: number[]) => {
                return self.indexOf(x) === i;
            });
            return ret;
        }

        /**
         * 共有対象スイッチ番号を読み込む。
         * @static
         * @param {string[]} targetSwitches 読み込み対象のスイッチ番号文字配列。
         * プラグインパラメータに設定された配列を渡す。
         */
        private static loadTargetSwitchesNumber(targetSwitches: string[]): void {
            this.targetSwitches = this.loadTargetCoreNumber(targetSwitches);
        }

        /**
         * 共有対象変数番号を読み込む。
         * @static
         * @param {string[]} targetVariables 読み込み対象の変数番号文字配列。
         * プラグインパラメータ似設定された配列を渡す。
         */
        private static loadTargetVariablesNumber(targetVariables: string[]): void {
            this.targetVariables = this.loadTargetCoreNumber(targetVariables);
        }

        /**
         * 引数で渡した数字文字列をparseして対象番号のリストを得る。
         * 「-]を利用して範囲指定された番号の解釈も行う。
         * @static
         * @param {string} targetStr parse対象の文字列。
         * @return {number[]} 文字列から得た対象番号のリスト。
         */
        private static parseTargetNumber(targetStr: string): number[] {
            var ret: number[] = [];
            const emptyPattern = /^$/;
            const singlePattern = /^[0-9]+$/;
            const regionPattern = /^[0-9]+-[0-9]+$/;

            try {
                targetStr = targetStr.trim();
                if (targetStr.match(emptyPattern)) {
                    // empty
                    console.info("CommonSave.parseTargetNumber: skip parsing because ditected empty string.");
                } else if (targetStr.match(singlePattern)) {
                    // single number
                    // ex. 10
                    const num = parseInt(targetStr, 10);
                    if (num !== num) {
                        throw new Error(this.PLUGIN_NAME + ": parse error: NaN returned. (" + targetStr + ")");
                    }
                    ret.push(num);
                } else if (targetStr.match(regionPattern)) {
                    // region number
                    // ex. 10-15
                    const numStrs = targetStr.split("-");
                    const sNum = parseInt(numStrs[0], 10);
                    const eNum = parseInt(numStrs[1], 10);
                    if (sNum !== sNum || eNum !== eNum) {
                        throw new Error(this.PLUGIN_NAME + ": parse error: NaN returned. (" + targetStr + ")");
                    }
                    if (sNum >= eNum) {
                        throw new Error(this.PLUGIN_NAME + ": parse error: invaliad format. (" + targetStr + ")");
                    }
                    for (let num = sNum; num <= eNum; num++) {
                        ret.push(num);
                    }
                } else {
                    throw new Error(this.PLUGIN_NAME + ": parse error: invaliad format. (" + targetStr + ")");
                }
            } catch (e) {
                console.error("CommonSave.parseTargetNumber: Invalid format string has comming. (" + targetStr + ")");
                console.error(e.message);
                console.error(e.stack);
                throw e;
            }
            return ret;
        }

        /**
         * 現在の$gameSwitchesのデータから、共有セーブ対象としているものを連想配列で取得する。
         * @static
         * @return {object} 共有セーブ対象$gameSwitchesの連想配列。
         */
        private static makeTargetGameSwitchesJson(): { [idx: number]: boolean } {
            var ret: { [idx: number]: boolean } = {};
            for (const idx of this.targetSwitches) {
                // $gameSwitchesは触った事が無いと要素が作られないので範囲チェックできない
                if (idx < 1) {
                    console.warn("ComonSave.getTargetSwitchesJson: target switch index is out of range. (" + idx + ")");
                    continue;
                }
                ret[idx] = $gameSwitches.value(idx);
            }
            return ret;
        }

        /**
         * 現在の$gameVariablesのデータから、共有セーブの対象としているものを連想配列で取得する。
         * @static
         * @return {object} 共有セーブ対象$gameVariablesの連想配列。
         */
        private static makeTargetGameVariablesJson(): { [idx: number]: number } {
            var ret: { [idx: number]: number } = {};
            for (const idx of this.targetVariables) {
                // $gameVariablesは触った事が無いと要素が作られないので範囲チェックできない
                if (idx < 1) {
                    console.warn("ComonSave.getTargetGameVariablesJson: target variable index is out of range. (" + idx + ")");
                    continue;
                }
                ret[idx] = $gameVariables.value(idx);
            }
            return ret;
        }

        /**
         * 共有セーブするデータを作成する。
         * @static
         * @return {object} 共有セーブするデータの連想配列。
         */
        private static makeSaveContents(): CommonSaveData {
            const contents: CommonSaveData = {
                "version": this.PLUGIN_VERSION,
                "gameSwitches": this.makeTargetGameSwitchesJson(),
                "gameVariables": this.makeTargetGameVariablesJson()
            };
            return contents;
        }

        /**
         * プラグインパラメータで設定された共有セーブデータファイル名を取得する。
         * 拡張子は含めない。
         * @static
         * @return {string} 共有セーブデータファイル名の文字列。
         */
        private static makeSaveName(): string {
            return this.parameters.saveFileName;
        }

        /**
         * 共有セーブデータが存在するか。
         * @static
         * @return {boolean} 共有セーブデータが存在する場合trueを返す。
         */
        private static exists(): boolean {
            const saveName = this.makeSaveName();
            return StorageManager.exists(saveName);
        }

        /**
         * 共有セーブオブジェクトから$gameSwitchesにデータをロードする。
         * @static
         * @param {object} contents ロードした共有セーブデータオブジェクト
         */
        private static loadCommonSaveSwitches(contents: CommonSaveData): void {
            if (!("gameSwitches" in contents)) {
                return;
            }
            for (const key in contents.gameSwitches) {
                const idx = parseInt(key, 10);
                const value = contents.gameSwitches[key];
                $gameSwitches.setValue(idx, value);
            }
            return;
        }

        /**
         * 共有セーブオブジェクトから$gameVariablesにデータをロードする。
         * @static
         * @param {object} contents ロードした共有セーブデータオブジェクト
         */
        private static loadCommonSaveVariables(contents: CommonSaveData): void {
            if (!("gameVariables" in contents)) {
                return;
            }
            for (const key in contents.gameVariables) {
                const idx = parseInt(key, 10);
                const value = contents.gameVariables[key];
                $gameVariables.setValue(idx, value);
            }
            return;
        }

        /**
         * 共有セーブデータのロード処理。
         * local版, web版共通。
         * @static
         * @return {Promise<number>}
         */
        public static load(): Promise<number> {
            // 共有セーブデータが存在しない場合は何もしない
            // 途中から導入した場合を考慮してエラーにしない事
            if (!this.exists()) {
                return new Promise((resolve) => {
                    console.info("ComonSave.load: common save is not existed.");
                    resolve(0);
                });
            }
            const saveName = this.makeSaveName();
            return StorageManager.loadObject(saveName).then((contents: CommonSaveData) => {
                this.loadCommonSaveSwitches(contents);
                this.loadCommonSaveVariables(contents);
                console.log("CommonSave.load: completed to load common save.");
                return 0;
            });
        }

        /**
         * 共有セーブデータのセーブ処理。
         * local版, web版共通。
         * @static
         * @return {Promise<number>}
         */
        public static save(): Promise<number> {
            const contents = this.makeSaveContents();
            const saveName = this.makeSaveName();
            return StorageManager.saveObject(saveName, contents).then(() => {
                console.log("CommonSave.save: completed to save common save.");
                return 0;
            });
        }

        /**
         * 共有セーブデータを削除する。
         * @static
         */
        public static remove(): void {
            const saveName = this.makeSaveName();
            StorageManager.remove(saveName);
            console.log("CommonSave.remove: remove common save data. (" + saveName + ")");
        }

        /**
         * 現在共有対象としているスイッチ/変数番号をコンソールに表示する。
         * デバッグ用機能。
         * @static
         */
        public static check(): void {
            console.info("CommonSave.check: current target switches number.");
            console.info(this.targetSwitches.join(","));
            console.info("CommonSave.check: current target variables number.");
            console.info(this.targetVariables.join(","));
        }

        /**
         * セーブデータロード時に共有セーブデータをロードするか。
         * @static
         * @return {boolean}
         */
        public static isApplyOnLoad(): boolean {
            return this.parameters.applyOnLoad === "true";
        }

        /**
         * セーブデータセーブ時に共有セーブデータをセーブするか。
         * @static
         * @return {boolean}
         */
        public static isApplyOnSave(): boolean {
            return this.parameters.applyOnSave === "true";
        }

        /**
         * オートセーブ時に共有セーブデータをセーブするか。
         * @static
         * @return {boolean}
         */
        public static isApplyOnAutoSave(): boolean {
            return this.parameters.applyOnAutoSave === "true";
        }

        /**
         * ニューゲーム時に共有セーブデータをロードするか。
         * @static
         * @return {boolean}
         */
        public static isApplyOnNewGame(): boolean {
            return this.parameters.applyOnNewGame === "true";
        }

        /**
         * ゲームオーバー時に共有セーブデータをセーブするか。
         * @static
         * @return {boolean}
         */
        public static isApplyOnGameover(): boolean {
            return this.parameters.applyOnGameover === "true";
        }

        /**
         * 「初めから」即セーブ状態であるかを判定する。
         * 一度タイトル画面に戻ってから「初めから」を選んだ場合に
         * 何故かオートセーブ処理が実行されてしまい共有セーブが初期状態で上書きされてしまう状態を
         * 回避する為の判定処理。
         * 対症療法である為、この処理はコアスクリプトの改修に合わせて修正する。
         * @static
         * @return {boolean} 「初めから」即セーブの場合はtrueを返す。
         */
        public static checkNewGame(): boolean {
            // 「初めから」の場合はセーブカウントが必ず0から始まる
            // $gameSystem.onBeforeSaveでインクリメントされる為、
            // StorageManager.saveObjectのタイミングで必ず1以上になる
            // 初めから即セーブ時は必ず1になる
            if ($gameSystem.saveCount() > 1) {
                return false;
            }
            // 「初めから」の場合は必ず初期設定座標にプレイヤーが配置されるはず
            if ($gameMap.mapId() !== $dataSystem.startMapId || $gamePlayer.x !== $dataSystem.startX || $gamePlayer.y !== $dataSystem.startY || $gamePlayer.direction() !== 2) {
                return false;
            }
            // 「初めから」即セーブのタイミングでは歩数カウントが0であるはず
            if ($gameParty.steps() > 0) {
                return false;
            }
            return true;
        }
    }
    CommonSave.initialize();

    /**
     * register plugin command
     */
    PluginManager.registerCommand(CommonSave.PLUGIN_NAME, "load", () => {
        CommonSave.load();
    });
    PluginManager.registerCommand(CommonSave.PLUGIN_NAME, "save", () => {
        CommonSave.save();
    });
    PluginManager.registerCommand(CommonSave.PLUGIN_NAME, "remove", () => {
        CommonSave.remove();
    });
    PluginManager.registerCommand(CommonSave.PLUGIN_NAME, "check", () => {
        CommonSave.check();
    });

    /**
     * DataManager
     */
    const _DataManager_setupNewGame = DataManager.setupNewGame;
    DataManager.setupNewGame = function (): void {
        _DataManager_setupNewGame.call(this);
        if (CommonSave.isApplyOnNewGame()) {
            CommonSave.load();
        }
    };

    const _DataManager_saveGame = DataManager.saveGame;
    DataManager.saveGame = function (savefileId: number): Promise<number> {
        return _DataManager_saveGame.call(this, savefileId).then((ret: number) => {
            // savefileId = 0 is auto save
            // RPGMakerMZ v1.0.1:
            // 一度タイトル画面に戻ってから「初めから」を選んだ場合に
            // 何故かオートセーブ処理が実行されてしまい共有セーブが初期状態で上書きされてしまう
            // この現象を回避する為に明らかにゲームスタート直後の場合は共有セーブしないようにする
            if (savefileId === 0) {
                if (CommonSave.isApplyOnAutoSave() && !CommonSave.checkNewGame()) {
                    return CommonSave.save();
                }
                return ret;
            }

            if (CommonSave.isApplyOnSave()) {
                return CommonSave.save();
            }
            return ret;
        });
    };

    const _DataManager_loadGame = DataManager.loadGame;
    DataManager.loadGame = function (savefileId: number): Promise<number> {
        return _DataManager_loadGame.call(this, savefileId).then((ret: number) => {
            if (CommonSave.isApplyOnLoad()) {
                return CommonSave.load();
            }
            return ret;
        });
    };

    /**
     * Scene_Gameover
     */
    const _Scene_Gameover_prototype_start = Scene_Gameover.prototype.start;
    Scene_Gameover.prototype.start = function (): void {
        if (CommonSave.isApplyOnGameover()) {
            CommonSave.save();
        }
        _Scene_Gameover_prototype_start.call(this);
    };
}


code:
//=============================================================================
// VeryFastBattle.js
//=============================================================================

/*:
 * @plugindesc battle exceeds very fast when specified keys down
 * @author Sasuke KANNAZUKI (Thx to 星潟)
 *
 * @help This plugin does not provide plugin commands.
 *
 * When 'pageup' key(=PageUp or Q) or 'control' key (=Ctrl or Alt) is down
 * at battle turn, it exceeds very fast.
 *
 * There is no operation for mouse and touch panel.
 *
 * Copyright:
 * This plugin's specification is based on、星潟's RGSS3 material.
 * Artificial Providence http://artificialprovidence.web.fc2.com/
 * Thanks to 星潟.
 *
 * This plugin is released under MIT license.
 * http://opensource.org/licenses/mit-license.php
 */
/*:ja
 * @plugindesc 特定のキーが押された時、超高速に戦闘シーンが進みます
 * @author 神無月サスケ (原案:星潟)
 *
 * @help このプラグインには、プラグインコマンドはありません
 *
 * 'pageup' キー か 'control' キーが押されている間、超高速になります。
 * - 'pageup' とは、キーボードの PgUp か Q, またはパッドの Lボタンです。
 * - 'control' とは、キーボードの Ctrl か Alt です。
 *
 * タッチパネルやマウスでは、該当する動作はありません。
 *
 * 謝辞:
 * このプラグインの仕様は、星潟様の RGSS3 素材を参考にしました。
 * Artificial Providence http://artificialprovidence.web.fc2.com/
 * 星潟様に謝意を示します。
 *
 * このプラグインは MIT ライセンスで配布されます。
 * ご自由にお使いください。
 * http://opensource.org/licenses/mit-license.php
 */

(function () {
  //
  // Check Very Fast
  //
  Game_System.prototype.isVeryFastForward = function () {
    return Input.isPressed("pageup") || Input.isPressed("control");
  };

  //
  // skip all wait
  //
  var _Window_BattleLog_updateWaitCount =
    Window_BattleLog.prototype.updateWaitCount;
  Window_BattleLog.prototype.updateWaitCount = function () {
    if (this._waitCount > 0 && $gameSystem.isVeryFastForward()) {
      this._waitCount = 1;
    }
    return _Window_BattleLog_updateWaitCount.call(this);
  };

  var _Window_BattleLog_updateWaitMode =
    Window_BattleLog.prototype.updateWaitMode;
  Window_BattleLog.prototype.updateWaitMode = function () {
    if ($gameSystem.isVeryFastForward() && this._waitMode === "effect") {
      this._waitMode = "";
      return false;
    }
    return _Window_BattleLog_updateWaitMode.call(this);
  };

  var _Sprite_Battler_updateMove = Sprite_Battler.prototype.updateMove;
  Sprite_Battler.prototype.updateMove = function () {
    if (this._movementDuration > 0 && $gameSystem.isVeryFastForward()) {
      this._movementDuration = 1;
    }
    return _Sprite_Battler_updateMove.call(this);
  };

  var _Spriteset_Battle_isBusy = Spriteset_Battle.prototype.isBusy;
  Spriteset_Battle.prototype.isBusy = function () {
    if ($gameSystem.isVeryFastForward()) {
      return false;
    } else {
      return _Spriteset_Battle_isBusy.call(this);
    }
  };
})();