kakuriyo/js/plugins/LL_GalgeChoiceWindow.js
2023-06-29 14:42:52 -05:00

585 lines
20 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.

//=============================================================================
// RPGツクールMZ - LL_GalgeChoiceWindow.js v1.0.5
//-----------------------------------------------------------------------------
// ルルの教会 (Lulu's Church)
// https://nine-yusha.com/
//
// URL below for license details.
// https://nine-yusha.com/plugin/
//=============================================================================
/*:
* @target MZ
* @plugindesc ノベルゲーム風選択肢ウィンドウプラグイン
* @author ルルの教会
* @url https://nine-yusha.com/plugin-galgechoicewindow/
*
* @help LL_GalgeChoiceWindow.js
*
* ノベルゲーム風の選択肢ウィンドウを表示します。
* 独自のウィンドウ画像、ボタン画像を設定することもできます。
* (画像はimg/systemフォルダに配置してください)
*
* プラグインコマンド:
* 選択肢の表示: 選択肢を表示し、結果を変数で受け取ります。
*
* 利用規約:
* ・著作権表記は必要ございません。
* ・利用するにあたり報告の必要は特にございません。
* ・商用・非商用問いません。
* ・R18作品にも使用制限はありません。
* ・ゲームに合わせて自由に改変していただいて問題ございません。
* ・プラグイン素材としての再配布(改変後含む)は禁止させていただきます。
*
* 作者: ルルの教会
* 作成日: 2022/3/25
*
* @command showChoice
* @text 選択肢の表示
* @desc 選択肢を表示し、結果を変数で受け取ります。
*
* @arg messageText
* @text 質問メッセージ
* @desc 質問メッセージです。 (2行以内推奨)
* \V[n]、\N[n]、\P[n]、\Gの制御文字が使用できます。
* @type multiline_string
*
* @arg choices
* @text 選択肢リスト
* @desc 選択肢として表示する文字列のリストです。
* @default []
* @type struct<choices>[]
*
* @arg maxCols
* @text 選択肢列数
* @desc 選択肢を何列で表示するかの設定です。
* @default 1
* @min 1
* @max 20
* @type number
*
* @arg variableNumber
* @text 結果受け取り変数
* @desc 選択結果を受け取る変数IDを指定します。
* @type variable
*
* @arg cancelType
* @text キャンセル許可
* @desc キャンセルされた場合は-1が変数に代入されます。
* @default true
* @type boolean
*
* @arg iniPosition
* @text 初期カーソル位置
* @desc カーソルの初期位置です。(0にすると選択なし)
* 数値を入力するか変数で指定することもできます。
* @default 1
* @type combo
* @option $gameVariables.value(1) // 変数ID:1の値
* @option 0
* @option 1
* @option 2
* @option 3
* @option 4
* @option 5
* @option 6
*
* @arg windowWidth
* @text ウィンドウ幅
* @desc 選択肢ウィンドウの幅です。
* 背景画像を使用する場合は横幅を調整してください。
* @default 480
* @min 0
* @max 9999
* @type number
*
* @arg windowBgImage
* @text ウィンドウ画像
* @desc ウィンドウ画像を使用する場合は画像を選択してください。
* 標準のウィンドウ枠は非表示になります。
* @dir img/system
* @type file
* @require 1
*
* @arg buttonBgImage
* @text ボタン画像
* @desc ボタン画像を使用する場合は画像を選択してください。
* @dir img/system
* @type file
* @require 1
*
* @arg buttonFocusImage
* @text ボタン画像(選択時)
* @desc フォーカス時のボタン画像を選択してください。
* ベースとなるボタン画像と大きさを必ず統一してください。
* @dir img/system
* @type file
* @require 1
*
* @arg buttonImageAdjustX
* @text ボタン画像X座標
* @desc ボタン画像の表示位置(X)の調整値です。(初期値: 0)
* +で右へ、-で左へ調整します。
* @default 0
* @min -9999
* @max 9999
* @type number
*
* @arg buttonImageAdjustY
* @text ボタン画像Y座標
* @desc ボタン画像の表示位置(Y)の調整値です。(初期値: 0)
* +で下へ、-で上へ調整します。
* @default 0
* @min -9999
* @max 9999
* @type number
*
* @arg itemHeightAdjust
* @text 選択肢項目高さ
* @desc 選択肢項目の高さの調整値です。(初期値: 8)
* 画像が重なってしまう場合はこの数値を大きくしてください。
* @default 8
* @min -9999
* @max 9999
* @type number
*
* @arg backgroundBitmapOpacity
* @text 背景の明るさ
* @desc 選択肢を表示する時の背景の明るさです。(0255)
* 0にすると真っ暗になります。
* @default 128
* @min 0
* @max 255
* @type number
*/
/*~struct~choices:
*
* @param label
* @text 選択肢文字列
* @desc 選択肢として表示する文字列です。
* \V[n]、\N[n]、\P[n]、\Gの制御文字が使用できます。
* @type string
*
* @param switchId
* @text スイッチID
* @desc スイッチON時のみ選択肢を表示したい場合に設定します。
* 通常は「なし」のままで問題ありません。
* @type switch
*
* @param resultNumber
* @text 結果返却値
* @desc この選択肢が選ばれた時に変数に入力する値を指定できます。
* 「0」にすると自動で選択肢番号が返却されます。
* @default 0
* @min 0
* @max 99999999
* @type number
*/
(() => {
"use strict";
const pluginName = "LL_GalgeChoiceWindow";
const parameters = PluginManager.parameters(pluginName);
// Padding
const gcwWindowPadding = 32;
// キャンセル許可時のタッチUI戻るボタンの表示
const gcwCancelButtonEnabled = false;
// フェードイン効果フレーム
const gcwFadeInFrame = 32;
// 設定保存用変数定義
let messageTextLists = [];
let choiceLists = [];
let maxCols = 1;
let variableNumber = 0;
let cancelType = true;
let iniPosition = 1;
let gcwWindowWidth = 480;
let backgroundImage = "";
let gcwButtonImage = "";
let gcwButtonFocusImage = "";
let gcwButtonAdjustX = 0;
let gcwButtonAdjustY = 0;
let gcwItemHeightAdjust = 8;
let backgroundBitmapOpacity = 128;
PluginManager.registerCommand(pluginName, "showChoice", function (args) {
// 戦闘中は実行不可
if ($gameParty.inBattle()) return;
// 設定を取得
const messageText = String(args.messageText).split("\n");
const choices = JSON.parse(args.choices || "null");
maxCols = Number(args.maxCols || 1);
variableNumber = Number(args.variableNumber);
cancelType = String(args.cancelType) === "true" ? true : false;
iniPosition = eval(args.iniPosition);
gcwWindowWidth = Number(args.windowWidth || 480);
backgroundImage = String(args.windowBgImage || "");
gcwButtonImage = String(args.buttonBgImage || "");
gcwButtonFocusImage = String(args.buttonFocusImage || "");
gcwButtonAdjustX = Number(args.buttonImageAdjustX || 0);
gcwButtonAdjustY = Number(args.buttonImageAdjustY || 0);
gcwItemHeightAdjust = Number(args.itemHeightAdjust || 8);
backgroundBitmapOpacity = Number(args.backgroundBitmapOpacity || 128);
messageTextLists = [];
if (messageText != "") {
messageText.forEach((elm) => {
messageTextLists.push(String(elm));
});
}
// 選択肢を定義
choiceLists = [];
if (choices) {
choices.forEach((elm) => {
if (Number(JSON.parse(elm).switchId) === 0 || $gameSwitches.value(Number(JSON.parse(elm).switchId))) {
choiceLists.push(JSON.parse(elm));
}
});
}
// 選択肢が空の場合、終了
if (choiceLists.length == 0) {
console.log(pluginName + ": 有効な選択肢が存在しなかったため、コマンドがスキップされました");
return;
}
SceneManager.push(Scene_GalgeChoice);
});
//-----------------------------------------------------------------------------
// Scene_GalgeChoice
//
// ノベルゲーム風選択肢を表示する独自のシーンを定義します。
function Scene_GalgeChoice() {
this.initialize(...arguments);
}
Scene_GalgeChoice.prototype = Object.create(Scene_MenuBase.prototype);
Scene_GalgeChoice.prototype.constructor = Scene_GalgeChoice;
Scene_GalgeChoice.prototype.initialize = function () {
Scene_MenuBase.prototype.initialize.call(this);
};
Scene_GalgeChoice.prototype.create = function () {
Scene_MenuBase.prototype.create.call(this);
this.createChoiceWindow();
};
Scene_GalgeChoice.prototype.start = function () {
Scene_MenuBase.prototype.start.call(this);
};
Scene_GalgeChoice.prototype.createChoiceWindow = function () {
this._choiceWindow = new Window_GalgeChoiceList();
this._choiceWindow.setHandler("ok", this.popScene.bind(this));
this._choiceWindow.setHandler("cancel", this.popScene.bind(this));
this.addWindow(this._choiceWindow);
};
Scene_GalgeChoice.prototype.createButtons = function () {
//
};
Scene_GalgeChoice.prototype.createBackground = function () {
this._backgroundFilter = new PIXI.filters.BlurFilter();
this._backgroundSprite = new Sprite();
this._backgroundSprite.bitmap = SceneManager.backgroundBitmap();
// this._backgroundSprite.filters = [this._backgroundFilter];
this.addChild(this._backgroundSprite);
this.setBackgroundOpacity(backgroundBitmapOpacity);
};
Scene_GalgeChoice.prototype.onInputOk = function () {
this.popScene();
};
//-----------------------------------------------------------------------------
// Window_GalgeChoiceList
//
// ノベルゲーム風選択肢ウィンドウを定義します。
function Window_GalgeChoiceList() {
this.initialize(...arguments);
}
Window_GalgeChoiceList.prototype = Object.create(Window_Command.prototype);
Window_GalgeChoiceList.prototype.constructor = Window_GalgeChoiceList;
Window_GalgeChoiceList.prototype.initialize = function () {
const wh = this.calcWindowHeight();
const ww = gcwWindowWidth;
const wx = (Graphics.boxWidth - ww) / 2;
const wy = (Graphics.boxHeight - wh) / 2;
Window_Command.prototype.initialize.call(this, new Rectangle(wx, wy, ww, wh));
this.openness = 0;
// ウィンドウ画像
this._bgSprite = null;
// フォーカスアニメーション判定
this._originalCursorSpriteFade = true;
// 押しっぱなし判定
this._pressedOkRelease = false;
this.start();
};
Window_GalgeChoiceList.prototype.start = function () {
this.open();
this.setQuestionText();
this.setSymbol();
this.createOriginalBackground();
this.createCancelButton();
this.placeCancelButton();
};
Window_GalgeChoiceList.prototype.calcWindowHeight = function () {
// ウィンドウの高さを計算
const itemCols = Math.ceil(choiceLists.length / maxCols);
let height = this.lineHeight() * messageTextLists.length;
if (messageTextLists.length > 0) height += gcwWindowPadding;
height += (this.itemHeight()) * itemCols;
height += gcwWindowPadding * 2; // padding
return height;
};
Window_GalgeChoiceList.prototype.createCancelButton = function () {
if (ConfigManager.touchUI) {
this._cancelButton = new Sprite_Button("cancel");
this._cancelButton.visible = false;
this.addChild(this._cancelButton);
}
};
Window_GalgeChoiceList.prototype.createOriginalBackground = function () {
if (backgroundImage != "") {
this._bgSprite = new Sprite();
this._bgSprite.bitmap = ImageManager.loadSystem(backgroundImage);
this._bgSprite.bitmap.addLoadListener(function () {
this._bgSprite.x = this.width / 2 - this._bgSprite.width / 2;
this._bgSprite.y = this.height / 2 - this._bgSprite.height / 2;
}.bind(this));
this._bgSprite.opacity = 0;
this.addChildToBack(this._bgSprite);
// ウィンドウ枠を消去
this.opacity = 0;
}
};
Window_GalgeChoiceList.prototype.drawAllItems = function () {
this.createOriginalCursor();
this.createOriginalButton();
Window_Selectable.prototype.drawAllItems.call(this);
};
Window_GalgeChoiceList.prototype.createOriginalCursor = function () {
if (gcwButtonFocusImage != "") {
this._originalCursorSprite = null;
this._originalCursorSprite = new Sprite();
this._originalCursorSprite.bitmap = ImageManager.loadSystem(gcwButtonFocusImage);
this._originalCursorSprite.opacity = 128;
this._originalCursorSprite.visible = true;
this.addChildToBack(this._originalCursorSprite);
}
};
Window_GalgeChoiceList.prototype.createOriginalButton = function () {
if (gcwButtonImage != "") {
this._originalButtonSprite = null;
this._originalButtonSprite = new Sprite();
this._originalButtonSprite.visible = false;
this.addChildToBack(this._originalButtonSprite);
}
};
Window_GalgeChoiceList.prototype.drawBackgroundRect = function (rect) {
const c1 = ColorManager.itemBackColor1();
const c2 = ColorManager.itemBackColor2();
const x = rect.x;
const y = rect.y;
const w = rect.width;
const h = rect.height;
if (gcwButtonImage != "") {
const originalButtonSprite = new Sprite();
originalButtonSprite.bitmap = ImageManager.loadSystem(gcwButtonImage);
originalButtonSprite.x = x + gcwButtonAdjustX + gcwWindowPadding;
originalButtonSprite.y = y + gcwButtonAdjustY + gcwWindowPadding;
this._originalButtonSprite.addChild(originalButtonSprite);
} else {
this.contentsBack.gradientFillRect(x, y, w, h, c1, c2, true);
this.contentsBack.strokeRect(x, y, w, h, c1);
}
};
Window_GalgeChoiceList.prototype.refreshCursor = function () {
if (this._cursorAll) {
this.refreshCursorForAll();
} else if (this.index() >= 0) {
const rect = this.itemRect(this.index());
if (gcwButtonFocusImage != "") {
if (this._originalCursorSprite) {
this._originalCursorSprite.x = rect.x + gcwButtonAdjustX + gcwWindowPadding;
this._originalCursorSprite.y = rect.y + gcwButtonAdjustY + gcwWindowPadding;
}
} else {
this.setCursorRect(rect.x, rect.y, rect.width, rect.height);
}
} else {
this.setCursorRect(0, 0, 0, 0);
}
};
Window_GalgeChoiceList.prototype.refreshCursorForAll = function () {
const maxItems = this.maxItems();
if (maxItems > 0) {
const rect = this.itemRect(0);
rect.enlarge(this.itemRect(maxItems - 1));
if (gcwButtonFocusImage != "") {
if (this._originalCursorSprite) {
this._originalCursorSprite.x = rect.x + gcwButtonAdjustX;
this._originalCursorSprite.y = rect.y + gcwButtonAdjustY;
}
} else {
this.setCursorRect(rect.x, rect.y, rect.width, rect.height);
}
} else {
this.setCursorRect(0, 0, 0, 0);
}
};
Window_GalgeChoiceList.prototype.update = function () {
Window_Command.prototype.update.call(this);
this.updateCancelButton();
this.updateOriginalButton();
this.updateOriginalCursorButton();
if (this._bgSprite) this._bgSprite.opacity = this.openness;
// 押しっぱなし判定
if (this.isOpen()) {
if (!Input.isPressed("ok")) {
this._pressedOkRelease = true;
}
}
};
Window_GalgeChoiceList.prototype.updateOriginalButton = function () {
if (this._originalButtonSprite) {
if (this.isOpen()) {
this._originalButtonSprite.visible = true;
} else {
this._originalButtonSprite.visible = false;
}
}
};
Window_GalgeChoiceList.prototype.updateOriginalCursorButton = function () {
if (this._originalCursorSprite) {
if (this.isOpen() && this._index > -1) {
this._originalCursorSprite.visible = true;
if (this._originalCursorSprite.opacity >= 255) this._originalCursorSpriteFade = false;
if (this._originalCursorSprite.opacity <= 128) this._originalCursorSpriteFade = true;
this._originalCursorSprite.opacity += this._originalCursorSpriteFade ? 6 : -6;
} else {
this._originalCursorSprite.visible = false;
}
}
};
Window_GalgeChoiceList.prototype.updateOpen = function () {
if (this._opening) {
this.openness += gcwFadeInFrame;
if (this.isOpen()) {
this._opening = false;
}
}
};
Window_GalgeChoiceList.prototype.updateCancelButton = function () {
if (this._cancelButton) {
this._cancelButton.visible = this.needsCancelButton() && this.isOpen() && gcwCancelButtonEnabled;
}
};
Window_GalgeChoiceList.prototype.needsCancelButton = function () {
return cancelType;
};
Window_GalgeChoiceList.prototype.placeCancelButton = function () {
if (this._cancelButton) {
const spacing = 8;
const button = this._cancelButton;
const right = this.x + this.width;
if (right < Graphics.boxWidth - button.width + spacing) {
button.x = this.width + spacing;
} else {
button.x = -button.width - spacing;
}
button.y = this.height / 2 - button.height / 2;
}
};
Window_GalgeChoiceList.prototype.maxCols = function () {
return maxCols;
};
Window_GalgeChoiceList.prototype.setQuestionText = function () {
messageTextLists.forEach((text, index) => {
this.drawText(this.convertEscapeCharacters(text), 0, this.lineHeight() * index, this.innerWidth, "center");
}, this);
};
Window_GalgeChoiceList.prototype.makeCommandList = function () {
choiceLists.forEach(function (elm, index) {
this.addCommand(String(elm.label), Number(elm.resultNumber || 0) !== 0 ? Number(elm.resultNumber) : index + 1);
}, this);
};
Window_GalgeChoiceList.prototype.processOk = function () {
if (this._pressedOkRelease) {
$gameVariables.setValue(variableNumber, this.currentSymbol());
Window_Command.prototype.processOk.call(this);
}
};
Window_GalgeChoiceList.prototype.processCancel = function () {
if (!cancelType) return;
$gameVariables.setValue(variableNumber, -1);
Window_Command.prototype.processCancel.call(this);
};
Window_GalgeChoiceList.prototype.updatePadding = function () {
this.padding = gcwWindowPadding;
};
Window_GalgeChoiceList.prototype.scrollBaseY = function (index) {
let margin = this.lineHeight() * messageTextLists.length;
if (messageTextLists.length > 0) margin += gcwWindowPadding;
return this._scrollBaseY - margin;
};
Window_GalgeChoiceList.prototype.setSymbol = function () {
if (iniPosition > 0) {
this.selectSymbol(iniPosition);
} else {
this.deselect();
}
};
Window_GalgeChoiceList.prototype.itemHeight = function () {
return Window_Scrollable.prototype.itemHeight.call(this) + gcwItemHeightAdjust;
};
Window_GalgeChoiceList.prototype.drawItem = function (index) {
const rect = this.itemLineRect(index);
const align = this.itemTextAlign();
this.resetTextColor();
this.changePaintOpacity(this.isCommandEnabled(index));
this.drawText(this.convertEscapeCharacters(this.commandName(index)), rect.x, rect.y, rect.width, align);
};
})();