/*:
 * @plugindesc マップカメラオフセット - 画面右側に立ち絵用スペースを確保
 * @target MZ
 * @author M
 * @url https://github.com/
 *
 * @param offsetWidth
 * @text オフセット幅（px）
 * @desc 画面右側に確保する空白スペースの幅（ピクセル単位）。
 * @type number
 * @min 0
 * @max 400
 * @default 200
 *
 * @param maskColor
 * @text マスク背景色
 * @desc 右側空白部分の背景色。CSS色指定が使えます。
 * @type string
 * @default #000000
 *
 * @param maskOpacity
 * @text マスク不透明度
 * @desc 右側マスクの不透明度（0～255）。0で完全透明。
 * @type number
 * @min 0
 * @max 255
 * @default 255
 *
 * @param enableSwitch
 * @text 有効化スイッチ
 * @desc このスイッチがONの時のみオフセットを有効にします。0で常時有効。
 * @type switch
 * @default 0
 *
 * @help
 * ============================================================================
 * MapCameraOffset.js
 * ============================================================================
 *
 * マップ画面のカメラ表示位置を左にオフセットし、
 * 画面右側に立ち絵やUI表示用の空白スペースを作成します。
 *
 * ■ 仕組み
 *   - マップのスクロール計算における「画面幅」を狭めることで、
 *     プレイヤーキャラの表示位置が左寄りになります。
 *   - 右側の余白にはマスク（黒帯等）を配置し、マップタイルの
 *     はみ出しを隠します。
 *   - マスクはピクチャコンテナより下の描画層に配置されるため、
 *     ピクチャで表示する立ち絵はマスクの上に重なって見えます。
 *
 * ■ 描画順序（下から上）
 *   1. タイルマップ（マップチップ、キャラクター、影等）
 *   2. ★ オフセットマスク（ここで右側を覆う）
 *   3. ピクチャコンテナ（立ち絵やUI画像 → マスクの上に表示！）
 *   4. タイマー、天候エフェクト
 *   5. ウィンドウレイヤー
 *
 * ■ 使い方
 *   1. このプラグインを js/plugins/ に配置して有効化。
 *   2. プラグインパラメータで「オフセット幅」を設定（200推奨）。
 *   3. 立ち絵はピクチャで表示してください。
 *      配置例（オフセット200pxの場合）:
 *        X座標 = 616 ～ 816 の範囲に立ち絵を配置
 *      コモンイベント（並列処理）で常時表示するのが便利です。
 *
 * ■ 注意事項
 *   - マップの横幅が狭いとスクロールが発生せず、
 *     オフセットが見た目に反映されません。
 *     マップは横幅を十分に広く（20タイル以上推奨）してください。
 *   - 戦闘画面・メニュー画面には影響しません。
 *   - 有効化スイッチでシーンに応じたON/OFF切替が可能です。
 *
 * 
 *   
 * ============================================================================
 */

(() => {
    "use strict";

    const PLUGIN_NAME = "MapCameraOffset";

    // =========================================================================
    // パラメータ取得
    // =========================================================================
    const parameters = PluginManager.parameters(PLUGIN_NAME);
    const OFFSET_WIDTH   = Number(parameters["offsetWidth"]   || 200);
    const MASK_COLOR     = String(parameters["maskColor"]     || "#000000");
    const MASK_OPACITY   = Number(parameters["maskOpacity"]   ?? 255);
    const ENABLE_SWITCH  = Number(parameters["enableSwitch"]  || 0);

    // =========================================================================
    // オフセット有効判定
    // =========================================================================
    function isOffsetEnabled() {
        if (ENABLE_SWITCH === 0) return true;
        return $gameSwitches && $gameSwitches.value(ENABLE_SWITCH);
    }

    function currentOffset() {
        return isOffsetEnabled() ? OFFSET_WIDTH : 0;
    }

    // =========================================================================
    // Game_Map: 画面タイル数の計算を狭める
    // =========================================================================
    const _Game_Map_screenTileX = Game_Map.prototype.screenTileX;
    Game_Map.prototype.screenTileX = function() {
        const offset = currentOffset();
        if (offset > 0) {
            return Math.round(
                ((Graphics.width - offset) / this.tileWidth()) * 16
            ) / 16;
        }
        return _Game_Map_screenTileX.call(this);
    };

    // =========================================================================
    // Game_Player: プレイヤー中心位置を左寄りにする
    // =========================================================================
    const _Game_Player_centerX = Game_Player.prototype.centerX;
    Game_Player.prototype.centerX = function() {
        const offset = currentOffset();
        if (offset > 0) {
            return ((Graphics.width - offset) / $gameMap.tileWidth() - 1) / 2.0;
        }
        return _Game_Player_centerX.call(this);
    };

    // =========================================================================
    // Spriteset_Map: 右側マスクスプライトの追加
    //
    //   ★ 描画順の制御 ★
    //   createUpperLayer の先頭（super の前）でマスクを addChild する。
    //   super 内で createPictures が呼ばれてピクチャコンテナが追加される。
    //   結果:
    //     LowerLayer → マスク → ピクチャコンテナ → タイマー → 天候
    //   立ち絵ピクチャはマスクの上に表示される！
    // =========================================================================
    Spriteset_Map.prototype._createOffsetMask = function() {
        this._offsetMaskSprite = new Sprite();
        this._offsetMaskSprite.bitmap = new Bitmap(OFFSET_WIDTH, Graphics.height);
        this._offsetMaskSprite.bitmap.fillRect(
            0, 0, OFFSET_WIDTH, Graphics.height, MASK_COLOR
        );
        this._offsetMaskSprite.x = Graphics.width - OFFSET_WIDTH;
        this._offsetMaskSprite.y = 0;
        this._offsetMaskSprite.opacity = MASK_OPACITY;
        this.addChild(this._offsetMaskSprite);
    };

    const _Spriteset_Map_createUpperLayer = Spriteset_Map.prototype.createUpperLayer;
    Spriteset_Map.prototype.createUpperLayer = function() {
        // マスクをピクチャコンテナより先に追加 → 描画順でマスクが下
        this._createOffsetMask();
        // この中で createPictures → createTimer 等が実行される
        _Spriteset_Map_createUpperLayer.call(this);
    };

    // マスクの表示/非表示をスイッチで動的に切り替え
    const _Spriteset_Map_update = Spriteset_Map.prototype.update;
    Spriteset_Map.prototype.update = function() {
        _Spriteset_Map_update.call(this);
        if (this._offsetMaskSprite) {
            this._offsetMaskSprite.visible = isOffsetEnabled();
        }
    };

})();
