nyacronomicon/js/plugins/KN_SimpleMenu.js

391 lines
16 KiB
JavaScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*:
* @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;
}
}
})();