391 lines
16 KiB
JavaScript
391 lines
16 KiB
JavaScript
/*:
|
||
* @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;
|
||
}
|
||
}
|
||
|
||
})();
|