pastime/js/plugins/MultipleMessageWindows.js
2026-03-15 16:45:22 -05:00

736 lines
No EOL
20 KiB
JavaScript
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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.

// MultipleMessageWindows.js Ver.1.3.0
// MIT License (C) 2023 あわやまたな
// http://opensource.org/licenses/mit-license.php
/*:
* @target MZ
* @plugindesc Allows multiple message windows to be displayed.
* @orderAfter MessagePlus
* @orderAfter MessageWindowPopup
* @author あわやまたな (Awaya_Matana)
* @url https://awaya3ji.seesaa.net/article/498781437.html
* @help Ver.1.3.0
*
* @param numWindows
* @text Number of Windows
* @desc Number of message windows to increase.
* @type number
* @default 2
* @min 1
*
* @command changeTarget
* @text Change Target
* @desc Select the message window you want to operate on.
* 0 is the original window.
*
* @arg id
* @text Window ID
* @type number
* @default 0
*
* @command setWaitMode
* @text Set Wait Mode
* @desc Whether to wait to execute the event until the message window closes.
*
* @arg id
* @text Window ID
* @desc -1 for all windows.
* @type number
* @default -1
* @min -1
*
* @arg bool
* @text Boolean Value
* @type boolean
* @default true
*
* @command setNotClose
* @text Set Not Close
* @desc Prevents message windows from closing.
*
* @arg id
* @text Window ID
* @desc -1 for all windows.
* @type number
* @default -1
* @min -1
*
* @arg bool
* @text Boolean Value
* @type boolean
* @default false
*
* @command setAll
* @text Set All
* @desc Set all at once.
* If left blank, the status quo will be maintained.
*
* @arg id
* @text Window ID
* @desc -1 for all windows.
* @type number
* @default -1
* @min -1
*
* @arg waitMode
* @text Wait Mode
* @desc Whether to wait to execute the event until the message window closes.
* @type boolean
* @default true
*
* @arg notClose
* @text Set Not Close
* @desc Prevents message windows from closing.
* @type boolean
* @default false
*
* @command forceClose
* @text Force Close
* @desc Close the message window.
*
* @arg id
* @text Window ID
* @desc -1 for all windows.
* @type number
* @default -1
* @min -1
*
* @command synchronize
* @text Synchronize
* @desc Wait until all message windows are displayed.
*
* @arg bool
* @text Boolean Value
* @type boolean
* @default false
*
* @command setAnimation
* @text Set Animation
* @desc Enable open/close animation.
*
* @arg bool
* @text Boolean Value
* @type boolean
* @default true
*
* @command waitForCompletion
* @text Wait for Completion
* @desc Wait until the last targeted window completes its operation.
*
* @command resetAll
* @text Reset All
* @desc Initializes all target, wait mode, etc.
* We recommend doing this after every event.
*
*/
/*:ja
* @target MZ
* @plugindesc メッセージウィンドウを複数表示可能にします。
* @orderAfter MessagePlus
* @orderAfter MessageWindowPopup
* @author あわやまたな (Awaya_Matana)
* @url https://awaya3ji.seesaa.net/article/498781437.html
* @help 不具合がある場合は無効化して下さい。
*
* [更新履歴]
* 2023/03/29Ver.0.9.0b 公開。
* 2023/03/29Ver.0.9.1b シンクロさせた時に次の文章表示前に閉じてしまう不具合を修正。
* 2023/03/31Ver.0.9.2b 固定中はポーズサインを非表示に。MultipleMessagesクラスを追加。
* 2023/10/20Ver.1.0.0 対象切り替え時の仕様を修正。
* 2024/01/13Ver.1.1.0 MessageWindowPopupに暫定的に対応。
* 2025/02/27Ver.1.2.0 競合対策。
* 2025/03/13Ver.1.3.0 [強制的に閉じる]を[全てリセット]で解除されないようにしました。
*
* @param numWindows
* @text ウィンドウ数
* @desc 増やすメッセージウィンドウの数です。
* @type number
* @default 2
* @min 1
*
* @param numWindows
* @text ウィンドウ数
* @desc 増やすメッセージウィンドウの数です。
* @type number
* @default 2
* @min 1
*
* @command changeTarget
* @text 対象変更
* @desc 操作するメッセージウィンドウを選択します。
* 0が元からあるウィンドウです。
*
* @arg id
* @text ウィンドウID
* @type number
* @default 0
*
* @command setWaitMode
* @text 待機モード
* @desc メッセージウィンドウが閉じるまでイベント実行を待機するかどうか。いわゆる完了までウェイトを行うか。
*
* @arg id
* @text ウィンドウID
* @desc -1で全てのウィンドウ。
* @type number
* @default -1
* @min -1
*
* @arg bool
* @text 真偽値
* @type boolean
* @default true
*
* @command setNotClose
* @text 固定
* @desc メッセージウィンドウを閉じなくします。
*
* @arg id
* @text ウィンドウID
* @desc -1で全てのウィンドウ。
* @type number
* @default -1
* @min -1
*
* @arg bool
* @text 真偽値
* @type boolean
* @default false
*
* @command setAll
* @text 一括設定
* @desc 一括で設定します。
* 空白にすると現状維持。
*
* @arg id
* @text ウィンドウID
* @desc -1で全てのウィンドウ。
* @type number
* @default -1
* @min -1
*
* @arg waitMode
* @text 待機モード
* @desc メッセージウィンドウが閉じるまでイベント実行を待機するかどうか。いわゆる完了までウェイトを行うか。
* @type boolean
* @default true
*
* @arg notClose
* @text 固定
* @desc メッセージウィンドウを閉じなくします。
* @type boolean
* @default false
*
* @command forceClose
* @text 強制的に閉じる
* @desc メッセージウィンドウを閉じます。
*
* @arg id
* @text ウィンドウID
* @desc -1で全てのウィンドウ。
* @type number
* @default -1
* @min -1
*
* @command synchronize
* @text シンクロする
* @desc 全てのメッセージウィンドウが表示し終わるまで待ちます。
*
* @arg bool
* @text 真偽値
* @type boolean
* @default false
*
* @command setAnimation
* @text 開閉アニメ
* @desc 開閉アニメーションを有効化する。
*
* @arg bool
* @text 真偽値
* @type boolean
* @default true
*
* @command waitForCompletion
* @text 完了までウェイト
* @desc 最後に対象となったウィンドウの動作が完了するまで待ちます。
* 待機モードが無効なウィンドウに適用します。
*
* @command resetAll
* @text 全てリセット
* @desc 対象、待機モードなどを全て初期化します。
* イベント終了後に毎回行うことを推奨します。
*
*/
$multipleMessages = null;
'use strict';
class MultipleMessages {
constructor() {
this._data = [];
this._waitMode = [];
this._notClose = [];
this._forceClose = [];
this._synchronize = false;
this._animation = true;
this._windowId = 0;
}
data(index = this._windowId) {
return this._data[index];
}
pushData(data) {
this._data.push(data);
const len = this._data.length;
this._waitMode.length = len;
this._notClose.length = len;
this._forceClose.length = len;
}
resetLength() {
this._data.length = numWindows;
this._waitMode.length = numWindows;
this._notClose.length = numWindows;
this._forceClose.length = numWindows;
}
windowId() {
return this._windowId;
}
setWindowId(value) {
this._windowId = value;
}
waitMode(index = this._windowId) {
return this._waitMode[index];
}
setWaitMode(index, value) {
if (index === -1) {
this._waitMode.fill(value);
return;
}
this._waitMode[index] = value;
}
notClose(index = this._windowId) {
return this._notClose[index];
}
setNotClose(index, value) {
if (index === -1) {
this._notClose.fill(value);
return;
}
this._notClose[index] = value;
}
forceClose(index = this._windowId) {
return this._forceClose[index];
}
setForceClose(index, value) {
if (index === -1) {
this._forceClose.fill(value);
return;
}
this._forceClose[index] = value;
}
synchronize() {
return this._synchronize;
}
setSynchronize(value) {
this._synchronize = value;
}
animation() {
return this._animation;
}
setAnimation(value) {
this._animation = value;
}
resetAll() {
$gameMessage = this.data(0);
this.setWindowId(0);
this.setSynchronize(false);
this.setAnimation(true);
this.setWaitMode(-1, true);
this.setNotClose(-1, false);
//this.setForceClose(-1, false);
}
}
{
const pluginName = document.currentScript.src.match(/^.*\/(.*).js$/)[1];
const parameters = PluginManager.parameters(pluginName);
const numWindows = Number(parameters["numWindows"]);
const hasPluginCommonBase = typeof PluginManagerEx === "function";
const hasMessageWindowPopup = $plugins.some(plugin => Utils.extractFileName(plugin.name) === "MessageWindowPopup" && plugin.status);
//-----------------------------------------------------------------------------
// PluginManager
PluginManager.registerCommand(pluginName, "changeTarget", function (args) {
const id = Number(args.id);
if (id > numWindows) return;
$multipleMessages.setWindowId(id);
$gameMessage = $multipleMessages.data(id);
});
PluginManager.registerCommand(pluginName, "setWaitMode", function (args) {
const id = Number(args.id);
if (id > numWindows) return;
const bool = args.bool === "true";
$multipleMessages.setWaitMode(id, bool);
});
PluginManager.registerCommand(pluginName, "setNotClose", function (args) {
const id = Number(args.id);
if (id > numWindows) return;
const bool = args.bool === "true";
$multipleMessages.setNotClose(id, bool);
});
PluginManager.registerCommand(pluginName, "setAll", function (args) {
let bool = "";
const id = Number(args.id);
if (id > numWindows) return;
bool = args.waitMode;
if (bool) {
$multipleMessages.setWaitMode(id, bool === "true");
}
bool = args.notClose;
if (bool) {
$multipleMessages.setNotClose(id, bool === "true");
}
});
PluginManager.registerCommand(pluginName, "forceClose", function (args) {
const id = Number(args.id);
if (id > numWindows) return;
$multipleMessages.setForceClose(id, true);
$multipleMessages.setNotClose(id, false);
});
PluginManager.registerCommand(pluginName, "waitForCompletion", function (args) {
this.setWaitMode("message");
});
PluginManager.registerCommand(pluginName, "setAnimation", function (args) {
$multipleMessages.setAnimation(args.bool === "true");
});
PluginManager.registerCommand(pluginName, "synchronize", function (args) {
$multipleMessages.setSynchronize(args.bool === "true");
});
PluginManager.registerCommand(pluginName, "resetAll", function (args) {
$multipleMessages.resetAll();
});
//-----------------------------------------------------------------------------
// DataManager
const _DataManager_createGameObjects = DataManager.createGameObjects;
DataManager.createGameObjects = function() {
_DataManager_createGameObjects.call(this);
$multipleMessages = new MultipleMessages();
$multipleMessages.pushData($gameMessage);
for (let i = 1; i <= numWindows; i++) {
$multipleMessages.pushData(new Game_Message());
}
$multipleMessages.resetAll();
};
//-----------------------------------------------------------------------------
// Game_Interpreter
const _Game_Interpreter_command101 = Game_Interpreter.prototype.command101;
Game_Interpreter.prototype.command101 = function(params) {
const id = $multipleMessages.windowId();
if ($multipleMessages.forceClose(id)) {
return false;
}
const r = _Game_Interpreter_command101.call(this, params);
if (!$multipleMessages.waitMode()) {
this.setWaitMode("");
}
return r;
};
//-----------------------------------------------------------------------------
// Scene_Message
const _Scene_Message_createAllWindows = Scene_Message.prototype.createAllWindows;
Scene_Message.prototype.createAllWindows = function() {
_Scene_Message_createAllWindows.call(this);
this.createAllMultipleMessageWindows();
};
Scene_Message.prototype.createAllMultipleMessageWindows = function() {
this.createMultipleMessageWindows();
if (this._faceBoxWindow) {
this.createMultipleFaceBoxWindows();
}
this.createMultipleNameBoxWindows();
this.associateMultipleMessageWindows();
};
Scene_Message.prototype.createMultipleMessageWindows = function() {
const rect = this.messageWindowRect();
const index = this._windowLayer.children.indexOf(this._messageWindow);
this._messageWindows = [this._messageWindow];
this._messageWindow._messageWindows = this._messageWindows;
for (let i = 1; i <= numWindows; i++) {
const sprite = new Window_Message(rect);
if (index === -1) {
this.addWindow(sprite);
} else {
this._windowLayer.addChildAt(sprite, index + i);
}
sprite._messageId = i;
sprite._messageWindows = this._messageWindows;
this._messageWindows.push(sprite);
}
};
Scene_Message.prototype.createMultipleFaceBoxWindows = function() {
const index = this._windowLayer.children.indexOf(this._faceBoxWindow);
this._faceBoxWindows = [this._faceBoxWindow];
for (let i = 1; i <= numWindows; i++) {
const rect = this.faceBoxWindowRect();
const sprite = new Window_FaceBox(rect);
this._faceBoxWindows.push(sprite);
if (index === -1) {
this.addWindow(sprite);
} else {
this._windowLayer.addChildAt(sprite, index + i);
}
}
};
Scene_Message.prototype.createMultipleNameBoxWindows = function() {
const index = this._windowLayer.children.indexOf(this._nameBoxWindow);
this._nameBoxWindows = [this._nameBoxWindow];
for (let i = 1; i <= numWindows; i++) {
const sprite = new Window_NameBox();
this._nameBoxWindows.push(sprite);
if (index === -1) {
this.addWindow(sprite);
} else {
this._windowLayer.addChildAt(sprite, index + i);
}
}
};
Scene_Message.prototype.associateMultipleMessageWindows = function() {
for (let i = 1; i <= numWindows; i++) {
const messageWindow = this._messageWindows[i];
const nameBoxWindow = this._nameBoxWindows[i];
const faceBoxWindow = this._faceBoxWindows && this._faceBoxWindows[i];
messageWindow.setGoldWindow(this._goldWindow);
messageWindow.setNameBoxWindow(nameBoxWindow);
messageWindow.setChoiceListWindow(this._choiceListWindow);
messageWindow.setNumberInputWindow(this._numberInputWindow);
messageWindow.setEventItemWindow(this._eventItemWindow);
nameBoxWindow.setMessageWindow(messageWindow);
if (faceBoxWindow) {
messageWindow.setFaceBoxWindow(faceBoxWindow);
faceBoxWindow.setMessageWindow(messageWindow);
}
}
};
//-----------------------------------------------------------------------------
// Window_Message
const _Window_Message_initMembers = Window_Message.prototype.initMembers;
Window_Message.prototype.initMembers = function() {
_Window_Message_initMembers.call(this);
this._messageId = 0;
this._messageWindows = null;
this._synchronized = false;
};
const _Window_Message_update = Window_Message.prototype.update;
Window_Message.prototype.update = function() {
const id = this._messageId;
$gameMessage = $multipleMessages.data(id);
_Window_Message_update.call(this);
$gameMessage = $multipleMessages.data();
};
const _Window_Message_updateWait = Window_Message.prototype.updateWait;
Window_Message.prototype.updateWait = function() {
const id = this._messageId;
if ($multipleMessages.forceClose(id)) {
this.forceClose();
return false;
}
return _Window_Message_updateWait.call(this);
};
Window_Message.prototype.forceClose = function() {
const id = this._messageId;
this.pause = false;
this.startWait(0);
$multipleMessages.setForceClose(id, false);
this.terminateMessage();
this.close();
this._synchronized = false;
};
let updateInput = false;
const _Window_Message_updateInput = Window_Message.prototype.updateInput;
Window_Message.prototype.updateInput = function() {
updateInput = true;
const r = _Window_Message_updateInput.call(this);
updateInput = false;
return r;
};
const _Window_Message_terminateMessage = Window_Message.prototype.terminateMessage;
Window_Message.prototype.terminateMessage = function() {
_Window_Message_terminateMessage.call(this);
const notClose = $multipleMessages.notClose(this._messageId);
if (notClose) {
this.open();
} else if ($multipleMessages.synchronize() && !this._synchronized) {
$multipleMessages.setSynchronize(false);
this.terminateAllMessageWindows();
$multipleMessages.setSynchronize(true);
}
};
Window_Message.prototype.terminateAllMessageWindows = function() {
if (!this._messageWindows) return;
for (const message of this._messageWindows) {
const id = message._messageId;
const notClose = $multipleMessages.notClose(id);
$gameMessage = $multipleMessages.data(id);
if (!notClose && !message._textState && !message._synchronized) {
message._synchronized = true;
if (id < this._messageId) {
message.forceClose();
} else if (id > this._messageId) {
$multipleMessages.setForceClose(id, true);
} else {
this._synchronized = false;
}
}
}
$gameMessage = $multipleMessages.data(this._messageId);
};
const _Window_Message_updateOpen = Window_Message.prototype.updateOpen;
Window_Message.prototype.updateOpen = function() {
if (this._opening && !$multipleMessages.animation()) {
this.openness = 255;
}
_Window_Message_updateOpen.call(this);
};
const _Window_Message_updateClose = Window_Message.prototype.updateClose;
Window_Message.prototype.updateClose = function() {
if (this._closing && !$multipleMessages.animation()) {
this.openness = 0;
}
_Window_Message_updateClose.call(this);
};
const _Window_Message_startInput = Window_Message.prototype.startInput;
Window_Message.prototype.startInput = function() {
if (this._messageWindows) {
this._choiceListWindow.setMessageWindow(this);
this._numberInputWindow.setMessageWindow(this);
this._eventItemWindow.setMessageWindow(this);
}
return _Window_Message_startInput.call(this);
};
const _Window_Message_isTriggered = Window_Message.prototype.isTriggered;
Window_Message.prototype.isTriggered = function() {
const isTriggered = _Window_Message_isTriggered.call(this);
if (!this._messageWindows) {
return isTriggered;
}
if (!isTriggered) {
return false;
}
//ページ送り受付中でない時は普段通りの処理
const synchronize = $multipleMessages.synchronize();
if (!synchronize || this._textState || !updateInput) {
return true;
}
const textStates = synchronize && this._messageWindows.find(win => {
const notClose = $multipleMessages.notClose(win._messageId);
return notClose ? false : win._textState;
});
return !textStates;
};
if (hasMessageWindowPopup) {
//-----------------------------------------------------------------------------
// Game_System
const _Game_System_setMessagePopup = Game_System.prototype.setMessagePopup;
Game_System.prototype.setMessagePopup = function(id) {
_Game_System_setMessagePopup.apply(this, arguments);
$gameMessage._messagePopupCharacterId = this._messagePopupCharacterId;
};
const _Game_System_clearMessagePopup = Game_System.prototype.clearMessagePopup;
Game_System.prototype.clearMessagePopup = function() {
_Game_System_clearMessagePopup.apply(this, arguments);
$gameMessage._messagePopupCharacterId = this._messagePopupCharacterId;
$gameMessage._messagePopupPositionEvents = this._messagePopupPositionEvents.clone();
};
const _Game_System_setPopupFixPosition = Game_System.prototype.setPopupFixPosition;
Game_System.prototype.setPopupFixPosition = function(characterId, position) {
_Game_System_setPopupFixPosition.apply(this, arguments);
if (characterId !== null) {
$gameMessage._messagePopupPositionEvents = this._messagePopupPositionEvents.clone();
}
};
//-----------------------------------------------------------------------------
// Window_Message
const _Window_Message_startMessage = Window_Message.prototype.startMessage;
Window_Message.prototype.startMessage = function() {
_Window_Message_startMessage.call(this);
const $gameMessage = $multipleMessages.data(this._messageId);
if ($gameMessage._messagePopupPositionEvents) {
this._messagePopupPositionEvents = $gameMessage._messagePopupPositionEvents.clone();
}
};
const _Window_Message_updateTargetCharacterId = Window_Message.prototype.updateTargetCharacterId;
Window_Message.prototype.updateTargetCharacterId = function() {
const $gameMessage = $multipleMessages.data(this._messageId);
const messagePopupCharacterId = $gameSystem._messagePopupCharacterId;
$gameSystem._messagePopupCharacterId = $gameMessage._messagePopupCharacterId;
_Window_Message_updateTargetCharacterId.apply(this, arguments);
$gameSystem._messagePopupCharacterId = messagePopupCharacterId;
};
const _Window_Message_isPopupLower = Window_Message.prototype.isPopupLower;
Window_Message.prototype.isPopupLower = function() {
const messagePopupPositionEvents = $gameSystem._messagePopupPositionEvents;
$gameSystem._messagePopupPositionEvents = this._messagePopupPositionEvents;
const result = _Window_Message_isPopupLower.call(this);
$gameSystem._messagePopupPositionEvents = messagePopupPositionEvents;
return result;
};
}
}