/*: * @target MZ * @plugindesc シンプルメニュー * @help * * ●ブラー消去 * ●ステータス非表示(ダミー) * ●コマンドをプレイヤー右側に表示 * ●コマンド数に応じ高さを自動調整 * ●装備メニューを使用可能に * ●ゴールドウィンドウを非表示 * ●メニュー中もプレイヤーの足踏みアニメのみ再生 * ●アイテム画面と装備画面のウィンドウ幅を Kurogoma.Map.getStandAreaWidth() 分だけ縮小 * */ (() => { // // 背景のブラーを打ち消す処理 // Scene_MenuBase.prototype.createBackground = function() { // // メニュー背景として、マップ画面のスナップ(デフォルト処理)を描画 // this._backgroundSprite = new Sprite(); // this._backgroundSprite.bitmap = SceneManager.backgroundBitmap(); // this.addChild(this._backgroundSprite); // // // 画面全体に、少し暗くするための黒スプライトを重ねる // // Graphics.width / Graphics.height で描画サイズを指定 // const overlayBitmap = new Bitmap(Graphics.width, Graphics.height); // overlayBitmap.fillAll("black"); // const overlaySprite = new Sprite(overlayBitmap); // overlaySprite.opacity = 64; // 0〜255 の範囲で半透明度を調整 // // this.addChild(overlaySprite); // }; // ステータスウィンドウをダミーで生成して非表示に Scene_Menu.prototype.createStatusWindow = function() { const rect = new Rectangle(0, 0, 0, 0); this._statusWindow = new Window_MenuStatus(rect); this._statusWindow.hide(); this.addWindow(this._statusWindow); }; // メニューコマンド数に合わせて行数を返す Window_MenuCommand.prototype.numVisibleRows = function() { return this.maxItems(); }; // コマンドリストを最小限にカスタマイズ(装備を常に使えるようにtrueに) Window_MenuCommand.prototype.makeCommandList = function() { // 既存コマンド this.addCommand("Items", "item", true); this.addCommand("Equip", "equip", $gameVariables.value(Kurogoma.VariableConst.Progress) >= 2); // 進行度が 2 以上のときのみ選択可能にする(表示は常にする) this.addCommand("Log", "log", true); this.addCommand("Stat Points", "statusPoint", true); this.addCommand(TextManager.options, "options", true); this.addCommand("Retry", "retry", true); this.addCommand("Suspend", "suspend", true); }; // メニューコマンドウィンドウの座標をプレイヤー右側に Scene_Menu.prototype.commandWindowRect = function() { // メニューコマンドウィンドウの幅を 180 に固定 const ww = 180; // ウィンドウの高さを算出 const temp = new Window_MenuCommand(new Rectangle(0, 0, ww, 0)); const wh = temp.fittingHeight(temp.numVisibleRows()); // X座標を 20 に固定、Y座標は画面中央になるように const x = (Graphics.boxWidth - standWidth - ww); let y = (Graphics.boxHeight - wh) / 3 * 2; // 画面からはみ出ないよう念のためチェック(不要なら削除してOK) // ただし左側にはみ出るケースは通常起こらないので省略 if (y < 0) { y = 0; } else if (y + wh > Graphics.boxHeight) { y = Graphics.boxHeight - wh; } return new Rectangle(x, y, ww, wh); }; // キャンセル・装備ハンドラーを設定 const _Scene_Menu_createCommandWindow = Scene_Menu.prototype.createCommandWindow; Scene_Menu.prototype.createCommandWindow = function() { _Scene_Menu_createCommandWindow.call(this); this._commandWindow.setHandler("equip", this.commandEquip.bind(this)); this._commandWindow.setHandler("cancel", this.popScene.bind(this)); this._commandWindow.setHandler("retry", this.commandRetry.bind(this)); this._commandWindow.setHandler("suspend", this.commandsuspend.bind(this)); this._commandWindow.setHandler("log", this.commandLog.bind(this)); this._commandWindow.setHandler("statusPoint", this.commandStatusPoint.bind(this)); }; // ゴールドウィンドウ Scene_Menu.prototype.createGoldWindow = function() { // ゴールドウィンドウの表示位置を指定 const rect = this.goldWindowRect(); this._goldWindow = new Window_Gold(rect); this.addWindow(this._goldWindow); }; // 万が一Equipコマンドが呼ばれない場合の保険 これないとメニュー開いたときエラーでる if (!Scene_Menu.prototype.commandEquip) { Scene_Menu.prototype.commandEquip = function() { SceneManager.push(Scene_Equip); }; } //============================================================================ // アイテム画面・装備画面ウィンドウ幅を縮める処理 //============================================================================ // シーン全体で共通利用するため、一旦関数呼び出しで取得 const standWidth = Kurogoma.Map.getStandAreaWidth(); // helpWindowRect const _Scene_Item_helpWindowRect = Scene_Item.prototype.helpWindowRect; Scene_Item.prototype.helpWindowRect = function() { const rect = _Scene_Item_helpWindowRect.call(this); rect.width = Math.max(rect.width - standWidth, 0); return rect; }; // categoryWindowRect const _Scene_Item_categoryWindowRect = Scene_Item.prototype.categoryWindowRect; Scene_Item.prototype.categoryWindowRect = function() { const rect = _Scene_Item_categoryWindowRect.call(this); rect.y += this.calcWindowHeight(1, true); // 1行分縮める調整 rect.width = Math.max(rect.width - standWidth, 0); return rect; }; // itemWindowRect const _Scene_Item_itemWindowRect = Scene_Item.prototype.itemWindowRect; Scene_Item.prototype.itemWindowRect = function() { const rect = _Scene_Item_itemWindowRect.call(this); rect.width = Math.max(rect.width - standWidth, 0); return rect; }; // helpWindowRect const _Scene_Equip_helpWindowRect = Scene_Equip.prototype.helpWindowRect; Scene_Equip.prototype.helpWindowRect = function() { const rect = _Scene_Equip_helpWindowRect.call(this); rect.width = Math.max(rect.width - standWidth, 0); return rect; }; // commandWindowRect const _Scene_Equip_commandWindowRect = Scene_Equip.prototype.commandWindowRect; Scene_Equip.prototype.commandWindowRect = function() { const rect = _Scene_Equip_commandWindowRect.call(this); rect.y += this.calcWindowHeight(2, true); // 縮める調整 rect.width = Math.max(rect.width - standWidth, 0); return rect; }; // slotWindowRect const _Scene_Equip_slotWindowRect = Scene_Equip.prototype.slotWindowRect; Scene_Equip.prototype.slotWindowRect = function() { const rect = _Scene_Equip_slotWindowRect.call(this); rect.width = Math.max(rect.width - standWidth, 0); rect.height -= this.calcWindowHeight(2, true); // 縮める調整 return rect; }; // statusWindowRect const _Scene_Equip_statusWindowRect = Scene_Equip.prototype.statusWindowRect; Scene_Equip.prototype.statusWindowRect = function() { const rect = _Scene_Equip_statusWindowRect.call(this); rect.y += this.calcWindowHeight(2, true); // 位置調整 rect.height -= this.calcWindowHeight(2, true); // 縮める調整 return rect; }; // itemWindowRect const _Scene_Equip_itemWindowRect = Scene_Equip.prototype.itemWindowRect; Scene_Equip.prototype.itemWindowRect = function() { const rect = _Scene_Equip_itemWindowRect.call(this); return rect; }; //============================================================================ // オプション位置調整 const _Scene_Options_optionsWindowRect = Scene_Options.prototype.optionsWindowRect; Scene_Options.prototype.optionsWindowRect = function() { const rect = _Scene_Options_optionsWindowRect.call(this); const usableWidth = Graphics.boxWidth - standWidth; const fromTitle = SceneManager._previousClass === Scene_Title; if (fromTitle) { rect.x = (Graphics.boxWidth - rect.width) / 2; } else { rect.x = (usableWidth - rect.width) / 2; } if (rect.x < 0) rect.x = 0; return rect; }; // メニューコマンドリストを左寄せする Window_MenuCommand.prototype.itemTextAlign = function() { return "left"; }; // メニューコマンド描画を上書きしてアイコンを表示 Window_MenuCommand.prototype.drawItem = function(index) { const rect = this.itemLineRect(index); const align = this.itemTextAlign(); const symbol = this.commandSymbol(index); const commandName = this.commandName(index); const iconIndex = this.commandIconIndex(symbol); this.changePaintOpacity(this.isCommandEnabled(index)); this.drawIconText(iconIndex, commandName, rect.x, rect.y, rect.width, align); }; Window_MenuCommand.prototype.commandIconIndex = function(symbol) { switch (symbol) { case "item": return 209; case "equip": return 135; case "options": return 83; case "retry": return 75; case "suspend": return 297; case "log": return 189; case "statusPoint": return 356; // アイコンは必要に応じて調整 default: return 0; } }; // 中断 Scene_Menu.prototype.commandsuspend = function() { $gameTemp.reserveCommonEvent(8); // 中断コモン SceneManager.goto(Scene_Map); }; // リトライコマンドの実装 Scene_Menu.prototype.commandRetry = function() { $gameTemp.reserveCommonEvent(7); // リトライコモン SceneManager.goto(Scene_Map); }; // ログ Scene_Menu.prototype.commandLog = function() { SceneManager.push(Scene_Log); }; // ステ振り Scene_Menu.prototype.commandStatusPoint = function() { SceneManager.push(Kurogoma.Scene_StatusPointAllocate); }; // ゴールド Scene_Menu.prototype.goldWindowRect = function() { const ww = this.mainCommandWidth(); const wh = this.calcWindowHeight(1, true); const x = (Graphics.boxWidth - standWidth) - ww; const y = Graphics.boxHeight - wh; return new Rectangle(x, y, ww, wh); }; // ◆ ウィンドウを追加 const _Scene_Menu_create = Scene_Menu.prototype.create; Scene_Menu.prototype.create = function() { _Scene_Menu_create.call(this); this.createLocationWindow(); }; // 現在地 Scene_Menu.prototype.createLocationWindow = function() { const rect = this.locationWindowRect(); this._locationWindow = new Window_Location(rect); this.addWindow(this._locationWindow); }; Scene_Menu.prototype.locationWindowRect = function() { const ww = 360; const wh = this.calcWindowHeight(1, true); const wx = 0; const wy = 0; return new Rectangle(wx, wy, ww, wh); }; // Window_Location function Window_Location() { this.initialize(...arguments); } Window_Location.prototype = Object.create(Window_Selectable.prototype); // 選択しないがitemLineRect使いたいのでこれ使う Window_Location.prototype.constructor = Window_Location; Window_Location.prototype.initialize = function(rect) { Window_Selectable.prototype.initialize.call(this, rect); this.refresh(); }; Window_Location.prototype.colSpacing = function() { return 0; }; Window_Location.prototype.refresh = function() { this.contents.clear(); const rect = this.itemLineRect(0); const floor = Kurogoma.floorManager.currentFloor; const mapName = $gameMap.displayName() || $dataMapInfos[$gameMap.mapId()].name; const displayText = floor > 0 ? `B${floor}F - ${mapName}` : mapName; this.drawIconText(357, `${displayText}`, rect.x, rect.y, rect.width); }; //===================================================================== // Scene_Log : メニュー専用ログ画面 //===================================================================== class Scene_Log extends Scene_MenuBase { create() { super.create(); this.createLogWindow(); this._logWindow.setHandler("cancel", this.popScene.bind(this)); this._logWindow.activate(); } createLogWindow() { const rect = this.logWindowRect(); this._logWindow = new Window_MenuLog(rect); this.addWindow(this._logWindow); } logWindowRect() { const x = 0; const y = 0; const ww = Graphics.boxWidth - Kurogoma.Map.getStandAreaWidth(); const wh = Graphics.boxHeight; return new Rectangle(x, y, ww, wh); } } //===================================================================== // Window_MenuLog : ログ表示ウィンドウ class Window_MenuLog extends Window_Selectable { constructor(rect) { super(rect); this.opacity = 200; this.refresh(); this.activate(); } refresh() { this.contents.clear(); const logs = Torigoya.NotifyMessage.Manager.getLogs?.() || []; const lineHeight = this.lineHeight(); let y = 0; // === ヘッダー === this.drawText("* System Log *", 0, y, this.contentsWidth(), "center"); y += lineHeight; // 区切り線 y += 10; this.contents.fillRect(0, y - 2, this.contentsWidth(), 2, "rgba(255,255,255,0.3)"); y += 10; // === 本文 === if (logs.length === 0) { this.changeTextColor(ColorManager.textColor(8)); this.contents.paintOpacity = 160; this.drawText("Nothing has been recorded yet...", 0, y, this.contentsWidth(), "center"); this.contents.paintOpacity = 255; return; } const total = logs.length; for (let i = total - 1; i >= 0; i--) { const line = logs[i]; const opacity = Math.max(255 - (total - 1 - i) * 10, 128); this.contents.paintOpacity = opacity; this.drawTextExNoReset(line, 0, y, this.contentsWidth()); y += lineHeight; } this.contents.paintOpacity = 255; this.changeTextColor(ColorManager.normalColor()); } drawTextExNoReset(text, x, y, width) { const textState = this.createTextState(text, x, y, width); this.processAllText(textState); return textState.outputWidth; } } })();