513 lines
17 KiB
JavaScript
513 lines
17 KiB
JavaScript
//=============================================================================
|
||
// NRP_OptionCustomize.js
|
||
//=============================================================================
|
||
/*:
|
||
* @target MZ
|
||
* @plugindesc v1.001 Customize the display of the options scene.
|
||
* @author Takeshi Sunagawa (http://newrpg.seesaa.net/)
|
||
* @url https://newrpg.seesaa.net/article/502777639.html
|
||
*
|
||
* @help Customize the display of the options scene.
|
||
*
|
||
* ◆Main functions
|
||
* - Insert a separator.
|
||
* - Change window width.
|
||
* - Change the number of items displayed.
|
||
* - Change the amount of volume increase/decrease. (Default:20)
|
||
*
|
||
* -------------------------------------------------------------------
|
||
* [Notice]
|
||
* -------------------------------------------------------------------
|
||
* Separators are also counted internally as items.
|
||
* Note that if multiple separators are inserted,
|
||
* the other separators will also affect the insertion position.
|
||
*
|
||
* In the list of plugins,
|
||
* it would be better to place them below the plugins
|
||
* that add items to the options to reduce the effect of conflicts.
|
||
*
|
||
* -------------------------------------------------------------------
|
||
* [Terms]
|
||
* -------------------------------------------------------------------
|
||
* There are no restrictions.
|
||
* Modification, redistribution freedom, commercial availability,
|
||
* and rights indication are also optional.
|
||
* The author is not responsible,
|
||
* but will deal with defects to the extent possible.
|
||
*
|
||
* @------------------------------------------------------------------
|
||
* @ [Plugin Parameters]
|
||
* @------------------------------------------------------------------
|
||
*
|
||
* @param SeparateList
|
||
* @type struct<Separate>[]
|
||
* @desc Defines a separator.
|
||
*
|
||
* @param SeparateCenter
|
||
* @type boolean
|
||
* @default false
|
||
* @desc Center the separator.
|
||
*
|
||
* @param MaxVisibleCommands
|
||
* @type number
|
||
* @desc The number of optional commands to be displayed in the window. Default value is 12
|
||
*
|
||
* @param WindowWidth
|
||
* @type number
|
||
* @desc Width of the options window.
|
||
* Default value is 400.
|
||
*
|
||
* @param WindowBackgroundType
|
||
* @type select
|
||
* @option Normal @value 0
|
||
* @option Dimmer @value 1
|
||
* @option Transparency @value 2
|
||
* @default 0
|
||
* @desc The background of the options window.
|
||
*
|
||
* @param VolumeOffset
|
||
* @type number @min 1 @max 100 @decimals 2
|
||
* @desc The amount by which the volume item is to be increased or decreased at one time. Default is 20.
|
||
*
|
||
* @param MagnifiedVolume
|
||
* @type number @min 1 @max 100
|
||
* @desc Multiply the volume display only; at 5, 100% will be displayed as 500%.
|
||
*/
|
||
|
||
/*~struct~Separate:
|
||
* @param SeparateText
|
||
* @type string
|
||
* @desc The content to be displayed as a separator. Control characters are also valid. (e.g.: \c[1]Separate)
|
||
*
|
||
* @param Position
|
||
* @type number
|
||
* @default 0
|
||
* @desc The position at which the separator is to be inserted.
|
||
* Set 0 as the beginning.
|
||
*/
|
||
|
||
/*:ja
|
||
* @target MZ
|
||
* @plugindesc v1.001 オプション画面の表示をカスタマイズ
|
||
* @author 砂川赳(http://newrpg.seesaa.net/)
|
||
* @url https://newrpg.seesaa.net/article/502777639.html
|
||
*
|
||
* @help オプション画面の表示をカスタマイズします。
|
||
*
|
||
* ◆主な機能
|
||
* ・区切りを挿入
|
||
* ・ウィンドウのサイズを変更
|
||
* ・表示項目数を変更
|
||
* ・音量の増減量(標準は20)を変更
|
||
*
|
||
* -------------------------------------------------------------------
|
||
* ■注意点
|
||
* -------------------------------------------------------------------
|
||
* 区切りも内部的には項目としてカウントされます。
|
||
* 複数の区切りを挿入した場合は、
|
||
* 他の区切りも挿入位置に影響するのでご注意ください。
|
||
*
|
||
* プラグイン一覧では、オプションに項目を追加するプラグインよりも、
|
||
* 下に配置したほうが競合の影響を抑えられると思います。
|
||
*
|
||
* -------------------------------------------------------------------
|
||
* ■利用規約
|
||
* -------------------------------------------------------------------
|
||
* 特に制約はありません。
|
||
* 改変、再配布自由、商用可、権利表示も任意です。
|
||
* 作者は責任を負いませんが、不具合については可能な範囲で対応します。
|
||
*
|
||
* @------------------------------------------------------------------
|
||
* @ プラグインパラメータ
|
||
* @------------------------------------------------------------------
|
||
*
|
||
* @param SeparateList
|
||
* @text 区切りリスト
|
||
* @type struct<Separate>[]
|
||
* @desc 区切りを定義します。
|
||
*
|
||
* @param SeparateCenter
|
||
* @text 区切りを中央寄せ
|
||
* @type boolean
|
||
* @default false
|
||
* @desc 区切りを中央寄せします。
|
||
*
|
||
* @param MaxVisibleCommands
|
||
* @text 表示項目数
|
||
* @type number
|
||
* @desc ウィンドウ内に表示するオプションのコマンド数です。
|
||
* 初期値は12
|
||
*
|
||
* @param WindowWidth
|
||
* @text ウィンドウの横幅
|
||
* @type number
|
||
* @desc オプションウィンドウの横幅です。
|
||
* 初期値は400
|
||
*
|
||
* @param WindowBackgroundType
|
||
* @text ウィンドウ背景
|
||
* @type select
|
||
* @option 0:ウィンドウ @value 0
|
||
* @option 1:暗くする @value 1
|
||
* @option 2:透明 @value 2
|
||
* @default 0
|
||
* @desc オプションウィンドウの背景です。
|
||
*
|
||
* @param VolumeOffset
|
||
* @text 音量の増減量
|
||
* @type number @min 1 @max 100 @decimals 2
|
||
* @desc 音量項目を一度に増減させる量です。デフォルトは20です。
|
||
*
|
||
* @param MagnifiedVolume
|
||
* @text 音量表示を倍増
|
||
* @type number @min 1 @max 100
|
||
* @desc 音量の表示だけを倍増させます。5にすると100%が500%として表示されるようになります。
|
||
*/
|
||
|
||
/*~struct~Separate:ja
|
||
* @param SeparateText
|
||
* @text 区切りの文字
|
||
* @type string
|
||
* @desc 区切りとして表示する内容です。
|
||
* 制御文字も有効です。(例:\c[1]区切り)
|
||
*
|
||
* @param Position
|
||
* @text 挿入位置
|
||
* @type number
|
||
* @default 0
|
||
* @desc 区切りを挿入する位置です。
|
||
* 0を先頭として設定してください。
|
||
*/
|
||
|
||
(function() {
|
||
"use strict";
|
||
|
||
/**
|
||
* ●構造体(二重配列)をJSで扱えるように変換
|
||
*/
|
||
function parseStruct2(arg) {
|
||
const ret = [];
|
||
if (arg) {
|
||
for (const str of JSON.parse(arg)) {
|
||
ret.push(JSON.parse(str));
|
||
}
|
||
}
|
||
return ret;
|
||
}
|
||
function toBoolean(str, def) {
|
||
if (str === true || str === "true") {
|
||
return true;
|
||
} else if (str === false || str === "false") {
|
||
return false;
|
||
}
|
||
return def;
|
||
}
|
||
function toNumber(str, def) {
|
||
if (str == undefined || str == "") {
|
||
return def;
|
||
}
|
||
return isNaN(str) ? def : +(str || def);
|
||
}
|
||
function setDefault(str, def) {
|
||
if (str == undefined || str == "") {
|
||
return def;
|
||
}
|
||
return str;
|
||
}
|
||
|
||
const PLUGIN_NAME = "NRP_OptionCustomize";
|
||
const parameters = PluginManager.parameters(PLUGIN_NAME);
|
||
const pSeparateList = parseStruct2(parameters["SeparateList"]);
|
||
const pSeparateCenter = toBoolean(parameters["SeparateCenter"], false);
|
||
const pMaxVisibleCommands = toNumber(parameters["MaxVisibleCommands"]);
|
||
const pWindowWidth = toNumber(parameters["WindowWidth"]);
|
||
const pWindowBackgroundType = toNumber(parameters["WindowBackgroundType"], 0);
|
||
const pVolumeOffset = toNumber(parameters["VolumeOffset"]);
|
||
const pMagnifiedVolume = toNumber(parameters["MagnifiedVolume"]);
|
||
|
||
// 区切り識別用のキー
|
||
const SYMBOL_SEPARATE = "separate";
|
||
|
||
//-----------------------------------------------------------------------------
|
||
// Scene_Options
|
||
//-----------------------------------------------------------------------------
|
||
|
||
if (pWindowWidth) {
|
||
/**
|
||
* ●オプションウィンドウの表示領域
|
||
*/
|
||
const _Scene_Options_optionsWindowRect = Scene_Options.prototype.optionsWindowRect;
|
||
Scene_Options.prototype.optionsWindowRect = function() {
|
||
const ret = _Scene_Options_optionsWindowRect.apply(this, arguments);
|
||
ret.width = pWindowWidth;
|
||
ret.x = (Graphics.boxWidth - ret.width) / 2;
|
||
return ret;
|
||
};
|
||
}
|
||
|
||
/**
|
||
* ●コマンド数を設定
|
||
*/
|
||
const _Scene_Options_maxCommands = Scene_Options.prototype.maxCommands;
|
||
Scene_Options.prototype.maxCommands = function() {
|
||
// 表示項目数の指定があれば優先
|
||
if (pMaxVisibleCommands) {
|
||
return pMaxVisibleCommands;
|
||
}
|
||
|
||
// 追加した区切りの数を加算
|
||
let count = 0;
|
||
if (pSeparateList) {
|
||
count += pSeparateList.length;
|
||
}
|
||
return _Scene_Options_maxCommands.apply(this, arguments) + count;
|
||
};
|
||
|
||
/**
|
||
* ●最大表示数を設定
|
||
*/
|
||
const _Scene_Options_maxVisibleCommands = Scene_Options.prototype.maxVisibleCommands;
|
||
Scene_Options.prototype.maxVisibleCommands = function() {
|
||
// 表示項目数の指定があれば優先
|
||
if (pMaxVisibleCommands) {
|
||
return pMaxVisibleCommands;
|
||
}
|
||
return _Scene_Options_maxVisibleCommands.apply(this, arguments);
|
||
};
|
||
|
||
//-----------------------------------------------------------------------------
|
||
// Window_Options
|
||
//-----------------------------------------------------------------------------
|
||
|
||
const _Window_Options_initialize = Window_Options.prototype.initialize;
|
||
Window_Options.prototype.initialize = function(rect) {
|
||
_Window_Options_initialize.apply(this, arguments);
|
||
|
||
const symbol = this.commandSymbol(this.index());
|
||
// 区切りの場合は次の行を設定
|
||
if (this.isSeparateSymbol(symbol)) {
|
||
this.smoothSelect(this._index + 1);
|
||
}
|
||
|
||
// ウィンドウの背景を変更。
|
||
this.setBackgroundType(pWindowBackgroundType);
|
||
};
|
||
|
||
/**
|
||
* ●コマンドの生成
|
||
*/
|
||
const _Window_Options_makeCommandList = Window_Options.prototype.makeCommandList;
|
||
Window_Options.prototype.makeCommandList = function() {
|
||
_Window_Options_makeCommandList.apply(this, arguments);
|
||
|
||
// 区切りを追加
|
||
for (const separate of pSeparateList) {
|
||
this._list.splice(separate.Position, 0, { name: separate.SeparateText, symbol: SYMBOL_SEPARATE, enabled: true, ext: null});
|
||
}
|
||
};
|
||
|
||
/**
|
||
* 【独自】シンボルが区切りかどうか?
|
||
*/
|
||
Window_Options.prototype.isSeparateSymbol = function(symbol) {
|
||
return symbol == SYMBOL_SEPARATE;
|
||
};
|
||
|
||
const _Window_Options_statusText = Window_Options.prototype.statusText;
|
||
Window_Options.prototype.statusText = function(index) {
|
||
const symbol = this.commandSymbol(index);
|
||
// 区切りの場合は空白
|
||
if (this.isSeparateSymbol(symbol)) {
|
||
return "";
|
||
}
|
||
return _Window_Options_statusText.apply(this, arguments);
|
||
};
|
||
|
||
const _Window_Options_drawItem = Window_Options.prototype.drawItem;
|
||
Window_Options.prototype.drawItem = function(index) {
|
||
const symbol = this.commandSymbol(index);
|
||
// 区切りの場合
|
||
if (this.isSeparateSymbol(symbol)) {
|
||
const title = this.commandName(index);
|
||
const rect = this.itemLineRect(index);
|
||
this.resetTextColor();
|
||
this.changePaintOpacity(this.isCommandEnabled(index));
|
||
|
||
let x = rect.x;
|
||
|
||
// 中央寄せの場合はX座標を調整
|
||
if (pSeparateCenter) {
|
||
const textWidth = this.textSizeEx(title).width;
|
||
x += (rect.width - textWidth) / 2;
|
||
}
|
||
|
||
// drawTextExによってタイトルを描画(制御文字を使用可能に)
|
||
this.drawTextEx(title, x, rect.y, rect.width);
|
||
return;
|
||
}
|
||
_Window_Options_drawItem.apply(this, arguments);
|
||
};
|
||
|
||
const _Window_Options_processOk = Window_Options.prototype.processOk;
|
||
Window_Options.prototype.processOk = function() {
|
||
const symbol = this.commandSymbol(this.index());
|
||
// 区切りの場合は何もしない
|
||
if (this.isSeparateSymbol(symbol)) {
|
||
return;
|
||
}
|
||
_Window_Options_processOk.apply(this, arguments);
|
||
};
|
||
|
||
const _Window_Options_cursorRight = Window_Options.prototype.cursorRight;
|
||
Window_Options.prototype.cursorRight = function() {
|
||
const symbol = this.commandSymbol(this.index());
|
||
// 区切りの場合は何もしない
|
||
if (this.isSeparateSymbol(symbol)) {
|
||
return;
|
||
}
|
||
_Window_Options_cursorRight.apply(this, arguments);
|
||
};
|
||
|
||
const _Window_Options_cursorLeft = Window_Options.prototype.cursorLeft;
|
||
Window_Options.prototype.cursorLeft = function() {
|
||
const symbol = this.commandSymbol(this.index());
|
||
// 区切りの場合は何もしない
|
||
if (this.isSeparateSymbol(symbol)) {
|
||
return;
|
||
}
|
||
_Window_Options_cursorLeft.apply(this, arguments);
|
||
};
|
||
|
||
/*
|
||
* メソッドが未定義の場合は事前に定義
|
||
* ※これをしておかないと以後の親クラスへの追記が反映されない。
|
||
*/
|
||
if (Window_Options.prototype.cursorDown == Window_Selectable.prototype.cursorDown) {
|
||
Window_Options.prototype.cursorDown = function(wrap) {
|
||
return Window_Selectable.prototype.cursorDown.apply(this, arguments);
|
||
}
|
||
}
|
||
if (Window_Options.prototype.cursorUp == Window_Selectable.prototype.cursorUp) {
|
||
Window_Options.prototype.cursorUp = function(wrap) {
|
||
return Window_Selectable.prototype.cursorUp.apply(this, arguments);
|
||
}
|
||
}
|
||
|
||
const _Window_Options_cursorDown = Window_Options.prototype.cursorDown;
|
||
Window_Options.prototype.cursorDown = function(wrap) {
|
||
const keepIndex = this.index();
|
||
_Window_Options_cursorDown.apply(this, arguments);
|
||
const symbol = this.commandSymbol(this.index());
|
||
// 区切りの場合はスルーして次へ
|
||
if (this.isSeparateSymbol(symbol)) {
|
||
// 先頭の場合はスクロールも先頭に。
|
||
// ※下からループしてきた場合を想定
|
||
if (this.index() == 0) {
|
||
this.scrollTo(this._scrollX, 0);
|
||
}
|
||
|
||
let index = this.index() + 1;
|
||
// 一番下へ到達した場合はループ
|
||
if (index >= this._list.length) {
|
||
// 端で停止する場合はインデックスを戻す。
|
||
if (!wrap) {
|
||
this.smoothSelect(keepIndex);
|
||
return;
|
||
}
|
||
index = 0;
|
||
}
|
||
this.smoothSelect(index);
|
||
return;
|
||
}
|
||
};
|
||
|
||
const _Window_Options_cursorUp = Window_Options.prototype.cursorUp;
|
||
Window_Options.prototype.cursorUp = function(wrap) {
|
||
const keepIndex = this.index();
|
||
_Window_Options_cursorUp.apply(this, arguments);
|
||
const symbol = this.commandSymbol(this.index());
|
||
// 区切りの場合はスルーして前へ
|
||
if (this.isSeparateSymbol(symbol)) {
|
||
let index = this.index() - 1;
|
||
// 一番上へ到達した場合はループ
|
||
if (index < 0) {
|
||
// 端で停止する場合はインデックスを戻す。
|
||
if (!wrap) {
|
||
this.smoothSelect(keepIndex);
|
||
return;
|
||
}
|
||
index = this._list.length - 1;
|
||
}
|
||
this.smoothSelect(index);
|
||
return;
|
||
}
|
||
};
|
||
|
||
/*
|
||
* メソッドが未定義の場合は事前に定義
|
||
* ※これをしておかないと以後の親クラスへの追記が反映されない。
|
||
*/
|
||
if (Window_Options.prototype.drawItemBackground == Window_Selectable.prototype.drawItemBackground) {
|
||
Window_Options.prototype.drawItemBackground = function(index) {
|
||
return Window_Selectable.prototype.drawItemBackground.apply(this, arguments);
|
||
}
|
||
}
|
||
|
||
/**
|
||
* ●黒背景の描画
|
||
*/
|
||
const _Window_Options_drawItemBackground = Window_Options.prototype.drawItemBackground;
|
||
Window_Options.prototype.drawItemBackground = function(index) {
|
||
const symbol = this.commandSymbol(index);
|
||
// 区切りの場合は無視
|
||
if (this.isSeparateSymbol(symbol)) {
|
||
return;
|
||
}
|
||
_Window_Options_drawItemBackground.apply(this, arguments);
|
||
};
|
||
|
||
/*
|
||
* メソッドが未定義の場合は事前に定義
|
||
* ※これをしておかないと以後の親クラスへの追記が反映されない。
|
||
*/
|
||
if (Window_Options.prototype.refreshCursor == Window_Selectable.prototype.refreshCursor) {
|
||
Window_Options.prototype.refreshCursor = function() {
|
||
return Window_Selectable.prototype.refreshCursor.apply(this, arguments);
|
||
}
|
||
}
|
||
|
||
/**
|
||
* ●選択行のカーソル更新
|
||
*/
|
||
const _Window_Options_refreshCursor = Window_Options.prototype.refreshCursor;
|
||
Window_Options.prototype.refreshCursor = function() {
|
||
if (this.index() >= 0) {
|
||
const symbol = this.commandSymbol(this.index());
|
||
// 区切りの場合はクリア
|
||
if (this.isSeparateSymbol(symbol)) {
|
||
this.setCursorRect(0, 0, 0, 0);
|
||
return;
|
||
}
|
||
}
|
||
_Window_Options_refreshCursor.apply(this, arguments);
|
||
};
|
||
|
||
if (pVolumeOffset) {
|
||
/**
|
||
* 【上書】音量の増減単位
|
||
*/
|
||
Window_Options.prototype.volumeOffset = function() {
|
||
return pVolumeOffset;
|
||
};
|
||
}
|
||
|
||
if (pMagnifiedVolume) {
|
||
/**
|
||
* 【上書】音量表示の倍増
|
||
*/
|
||
Window_Options.prototype.volumeStatusText = function(value) {
|
||
return value * pMagnifiedVolume + "%";
|
||
};
|
||
}
|
||
|
||
})();
|