979 lines
26 KiB
JavaScript
979 lines
26 KiB
JavaScript
//=============================================================================
|
|
// KMS_QuickNotification.js
|
|
// Last update: 2020/02/01
|
|
//=============================================================================
|
|
|
|
/*:
|
|
* @plugindesc
|
|
* [v0.1.1] Show popup notification.
|
|
*
|
|
* @author Kameo (Kamesoft)
|
|
*
|
|
* @param Display duration
|
|
* @default 300
|
|
* @desc Display frame count.
|
|
*
|
|
* @param Display position
|
|
* @default 0
|
|
* @desc
|
|
* Notification position.
|
|
* 0: TopLeft 1: TopRight 2: BottomLeft 3: BottomRight
|
|
*
|
|
* @param Face image size
|
|
* @default 64
|
|
* @desc Face image size in notification by pixel.
|
|
*
|
|
* @param Font size
|
|
* @default 18
|
|
* @desc Font size for notification.
|
|
*
|
|
* @param Max notification count
|
|
* @default 4
|
|
* @desc Max number of notifications which can be displayed together.
|
|
*
|
|
* @param Notification SE
|
|
* @default Saint5
|
|
* @require 1
|
|
* @dir audio/se/
|
|
* @type file
|
|
* @desc SE for showing notification.
|
|
*
|
|
* @param Notification SE param
|
|
* @default 100, 50
|
|
* @desc
|
|
* Format: Volume, Pitch, Pan
|
|
* Parameters for notification SE.
|
|
*
|
|
* @param Notification skin
|
|
* @default QuickNotificationSkin
|
|
* @require 1
|
|
* @dir img/system/
|
|
* @type file
|
|
* @desc Skin for notifications. Load from img/system.
|
|
*
|
|
*
|
|
* @help
|
|
*
|
|
* ## Plugin command
|
|
*
|
|
* QuickNotification enable # Enable quick notification
|
|
* QuickNotification disable # Display quick notification
|
|
* QuickNotification register # Register quick notification by the next message event
|
|
*
|
|
*/
|
|
|
|
/*:ja
|
|
* @plugindesc
|
|
* [v0.1.1] ポップアップ通知を表示する機能を追加します。
|
|
*
|
|
* @author かめお (Kamesoft)
|
|
*
|
|
* @param Display duration
|
|
* @default 180
|
|
* @desc 通知表示時間をフレーム単位で指定します。
|
|
*
|
|
* @param Display position
|
|
* @default 0
|
|
* @desc
|
|
* 通知を表示する位置です。
|
|
* 0: 左上 1: 右上 2: 左下 3: 右下
|
|
*
|
|
* @param Face image size
|
|
* @default 64
|
|
* @desc 通知用顔グラフィックのサイズをピクセル単位で指定します。
|
|
*
|
|
* @param Font size
|
|
* @default 18
|
|
* @desc 通知のフォントサイズを指定します。
|
|
*
|
|
* @param Max notification count
|
|
* @default 4
|
|
* @desc 同時に表示できる通知の最大数です。
|
|
*
|
|
* @param Notification SE
|
|
* @default Saint5
|
|
* @require 1
|
|
* @dir audio/se/
|
|
* @type file
|
|
* @desc 通知表示時に演奏する SE のファイル名です。 audio/se から読み込みます。
|
|
*
|
|
* @param Notification SE param
|
|
* @default 100, 50
|
|
* @desc
|
|
* 書式: ボリューム, ピッチ, パン
|
|
* 通知表示時に演奏する SE のパラメータです。ピッチ以降省略可。
|
|
*
|
|
* @param Notification skin
|
|
* @default QuickNotificationSkin
|
|
* @require 1
|
|
* @dir img/system/
|
|
* @type file
|
|
* @desc 通知の表示に使用するスキン画像です。 img/system から読み込みます。
|
|
*
|
|
*
|
|
* @help
|
|
*
|
|
* ■ プラグインコマンド
|
|
*
|
|
* QuickNotification enable # 通知を有効にします。
|
|
* QuickNotification disable # 通知を無効にします。
|
|
* QuickNotification register # 次の「文章の表示」コマンドで通知を登録します。
|
|
*
|
|
*/
|
|
|
|
var KMS = KMS || {};
|
|
|
|
(function () {
|
|
"use strict";
|
|
|
|
// 定数
|
|
var Const = {
|
|
debug: false, // デバッグモード
|
|
pluginCode: "QuickNotification", // プラグインコード
|
|
|
|
// 表示位置
|
|
displayPosition: {
|
|
topLeft: 0, // 左上
|
|
topRight: 1, // 右上
|
|
bottomLeft: 2, // 左下
|
|
bottomRight: 3, // 右下
|
|
},
|
|
};
|
|
|
|
var PluginName = "KMS_" + Const.pluginCode;
|
|
|
|
KMS.imported = KMS.imported || {};
|
|
KMS.imported[Const.pluginCode] = true;
|
|
|
|
// デフォルト値つきで文字列から int を解析
|
|
function parseIntWithDefault(param, defaultValue) {
|
|
var value = parseInt(param);
|
|
return isNaN(value) ? defaultValue : value;
|
|
}
|
|
|
|
var pluginParams = PluginManager.parameters(PluginName);
|
|
var Params = {};
|
|
Params.displayDuration = Math.max(
|
|
parseIntWithDefault(pluginParams["Display duration"], 300),
|
|
1
|
|
);
|
|
Params.displayGap = parseIntWithDefault(pluginParams["Display gap"], 16);
|
|
Params.displayOffsetX = parseIntWithDefault(
|
|
pluginParams["Display offset X"],
|
|
-2
|
|
);
|
|
Params.displayOffsetY = parseIntWithDefault(
|
|
pluginParams["Display offset Y"],
|
|
32
|
|
);
|
|
Params.faceImageSize = Math.max(
|
|
parseIntWithDefault(pluginParams["Face image size"], 64),
|
|
1
|
|
);
|
|
Params.fadeFrameCount = Math.max(
|
|
parseIntWithDefault(pluginParams["Fade frame count"], 8),
|
|
1
|
|
);
|
|
Params.fontSize = Math.max(
|
|
parseIntWithDefault(pluginParams["Font size"], 18),
|
|
1
|
|
);
|
|
Params.notificationCountMax = Math.max(
|
|
parseIntWithDefault(pluginParams["Max notification count"], 4),
|
|
1
|
|
);
|
|
Params.notificationSkin =
|
|
pluginParams["Notification skin"] || "QuickNotificationSkin";
|
|
Params.displayPosition = Math.min(
|
|
Math.max(
|
|
parseIntWithDefault(
|
|
pluginParams["Display position"],
|
|
Const.displayPosition.topLeft
|
|
),
|
|
Const.displayPosition.topLeft
|
|
),
|
|
Const.displayPosition.bottomRight
|
|
);
|
|
|
|
// 通知 SE の解析
|
|
(function () {
|
|
Params.notificationSe = null;
|
|
|
|
var paramFile = pluginParams["Notification SE"];
|
|
if (!paramFile) {
|
|
return;
|
|
}
|
|
|
|
var paramFileArgs = paramFile.replace(/\s+/g, "").split(/,/);
|
|
if (paramFileArgs.length <= 0) {
|
|
return;
|
|
}
|
|
|
|
Params.notificationSe = { name: paramFileArgs[0] };
|
|
|
|
var paramArgs = { volume: 90, pitch: 100, pan: 0 };
|
|
var paramDetail = pluginParams["Notification SE param"];
|
|
if (paramDetail != null) {
|
|
var paramDetailArgs = paramDetail.replace(/\s+/g, "").split(/,/);
|
|
paramArgs.volume = Number(paramDetailArgs[0]) || paramArgs.volume;
|
|
paramArgs.pitch = Number(paramDetailArgs[1]) || paramArgs.pitch;
|
|
paramArgs.pan = Number(paramDetailArgs[2]) || paramArgs.pan;
|
|
}
|
|
|
|
Params.notificationSe.volume = Number(paramArgs.volume) || 90;
|
|
Params.notificationSe.pitch = Number(paramArgs.pitch) || 100;
|
|
Params.notificationSe.pan = Number(paramArgs.pan) || 0;
|
|
})();
|
|
|
|
// デバッグログ
|
|
var debuglog;
|
|
if (Const.debug) {
|
|
debuglog = function () {
|
|
console.log(arguments);
|
|
};
|
|
} else {
|
|
debuglog = function () {};
|
|
}
|
|
|
|
var _Game_Interpreter_pluginCommand =
|
|
Game_Interpreter.prototype.pluginCommand;
|
|
Game_Interpreter.prototype.pluginCommand = function (command, args) {
|
|
_Game_Interpreter_pluginCommand.call(this, command, args);
|
|
|
|
if (command !== Const.pluginCode) {
|
|
return;
|
|
}
|
|
|
|
switch (args[0]) {
|
|
case "enable": // 有効化
|
|
$gameSystem.setQuickNotificationEnabled(true);
|
|
break;
|
|
|
|
case "disable": // 無効化
|
|
$gameSystem.setQuickNotificationEnabled(false);
|
|
break;
|
|
|
|
case "register": // 通知の登録開始
|
|
$gameTemp.setQuickNotificationRegistrationMode(true);
|
|
break;
|
|
|
|
default:
|
|
// 不明なコマンド
|
|
console.error("[%s %s] Unknown command.", Const.pluginCode, args[0]);
|
|
break;
|
|
}
|
|
};
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Game_Temp
|
|
|
|
var _Game_Temp_initialize = Game_Temp.prototype.initialize;
|
|
Game_Temp.prototype.initialize = function () {
|
|
_Game_Temp_initialize.call(this);
|
|
|
|
this.setQuickNotificationRegistrationMode(false);
|
|
this.clearQuickNotification();
|
|
};
|
|
|
|
/**
|
|
* 通知登録モードの切り替え
|
|
*/
|
|
Game_Temp.prototype.setQuickNotificationRegistrationMode = function (flag) {
|
|
this._isQuickNotificationRegistering = !!flag;
|
|
};
|
|
|
|
/**
|
|
* 通知登録モードに設定されているか
|
|
*/
|
|
Game_Temp.prototype.isQuickNotificationRegistrationMode = function () {
|
|
return this._isQuickNotificationRegistering;
|
|
};
|
|
|
|
/**
|
|
* 通知の登録
|
|
*/
|
|
Game_Temp.prototype.registerQuickNotification = function (notification) {
|
|
this._quickNotifications.push(notification);
|
|
};
|
|
|
|
/**
|
|
* 通知のクリア
|
|
*/
|
|
Game_Temp.prototype.clearQuickNotification = function () {
|
|
this._quickNotifications = [];
|
|
};
|
|
|
|
/**
|
|
* 次の通知を取得
|
|
*/
|
|
Game_Temp.prototype.retrieveNextQuickNotification = function () {
|
|
return this._quickNotifications.shift();
|
|
};
|
|
|
|
/**
|
|
* 通知が登録されているか
|
|
*/
|
|
Game_Temp.prototype.isQuickNotificationReady = function () {
|
|
return this._quickNotifications.length > 0;
|
|
};
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Game_System
|
|
|
|
/**
|
|
* 通知の有効状態を取得
|
|
*/
|
|
Game_System.prototype.isQuickNotificationEnabled = function () {
|
|
return this._quickNotificationEnabled != null
|
|
? this._quickNotificationEnabled
|
|
: true;
|
|
};
|
|
|
|
/**
|
|
* 通知の有効状態を設定
|
|
*/
|
|
Game_System.prototype.setQuickNotificationEnabled = function (enabled) {
|
|
this._quickNotificationEnabled = !!enabled;
|
|
};
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Game_Interpreter
|
|
|
|
var _Game_Interpreter_command101 = Game_Interpreter.prototype.command101;
|
|
Game_Interpreter.prototype.command101 = function () {
|
|
if (
|
|
!$gameMessage.isBusy() &&
|
|
$gameTemp.isQuickNotificationRegistrationMode()
|
|
) {
|
|
$gameTemp.setQuickNotificationRegistrationMode(false);
|
|
|
|
var notification = {
|
|
text: "",
|
|
faceName: this._params[0],
|
|
faceIndex: this._params[1],
|
|
};
|
|
//$gameMessage.setBackground(this._params[2]);
|
|
//$gameMessage.setPositionType(this._params[3]);
|
|
|
|
// テキストを改行区切りで連結
|
|
while (this.nextEventCode() === 401) {
|
|
if (notification.text.length > 0) {
|
|
notification.text += "\n";
|
|
}
|
|
|
|
this._index++;
|
|
notification.text += this.currentCommand().parameters[0];
|
|
}
|
|
|
|
// 通知の登録
|
|
$gameTemp.registerQuickNotification(notification);
|
|
|
|
// 次のコマンドへ
|
|
this._index++;
|
|
|
|
return false;
|
|
}
|
|
|
|
return _Game_Interpreter_command101.call(this);
|
|
};
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Window_QuickNotification
|
|
//
|
|
// 通知を表示するウィンドウ
|
|
|
|
function Window_QuickNotification() {
|
|
this.initialize.apply(this, arguments);
|
|
}
|
|
|
|
Window_QuickNotification.prototype = Object.create(Window_Base.prototype);
|
|
Window_QuickNotification.prototype.constructor = Window_QuickNotification;
|
|
|
|
// メッセージの一時描画バッファ
|
|
Window_QuickNotification.tempMessageBuffer = null;
|
|
|
|
/**
|
|
* 通知用スキンの事前読み込み
|
|
*/
|
|
Window_QuickNotification.preloadWindowskin = function () {
|
|
ImageManager.loadSystem(Params.notificationSkin);
|
|
};
|
|
|
|
Window_QuickNotification.prototype.initialize = function () {
|
|
// コンテンツサイズは内容に応じて可変なので、ウィンドウサイズは仮
|
|
Window_Base.prototype.initialize.call(this, 0, 0, 64, 64);
|
|
|
|
if (Window_QuickNotification.tempMessageBuffer == null) {
|
|
Window_QuickNotification.tempMessageBuffer = new Bitmap(
|
|
Graphics.boxWidth,
|
|
Graphics.boxHeight / 2
|
|
);
|
|
}
|
|
|
|
this.opacity = 0;
|
|
this.contentsOpacity = 0;
|
|
this.initMembers();
|
|
};
|
|
|
|
Window_QuickNotification.prototype.standardFontSize = function () {
|
|
return Params.fontSize;
|
|
};
|
|
|
|
Window_QuickNotification.prototype.loadWindowskin = function () {
|
|
// デフォルトのスキンの代わりに、通知用のスキンを読み込む
|
|
this._windowskin = ImageManager.loadSystem(Params.notificationSkin);
|
|
};
|
|
|
|
Window_QuickNotification.prototype.initMembers = function () {
|
|
this._textState = null;
|
|
this._allTextWidth = 0;
|
|
this._allTextHeight = 0;
|
|
this._duration = 0;
|
|
this._destinationY = -1;
|
|
this._faceName = "";
|
|
this._faceIndex = 0;
|
|
this._faceBitmap = null;
|
|
};
|
|
|
|
/**
|
|
* 目標 Y 座標を設定
|
|
*/
|
|
Window_QuickNotification.prototype.setDestinationY = function (y) {
|
|
// 最初は目標位置にそのまま表示する
|
|
if (this._destinationY < 0) {
|
|
this.y = y;
|
|
}
|
|
|
|
this._destinationY = y;
|
|
};
|
|
|
|
Window_QuickNotification.prototype.hide = function () {
|
|
this._duration = 0;
|
|
|
|
Window_Base.prototype.hide.call(this);
|
|
};
|
|
|
|
/**
|
|
* フェードアウト
|
|
*/
|
|
Window_QuickNotification.prototype.fadeOut = function () {
|
|
if (this.isFadingOut()) {
|
|
return;
|
|
}
|
|
|
|
if (this.isFadingIn()) {
|
|
// フェードイン中は同じ不透明度からフェードアウトする
|
|
this._duration = Params.displayDuration - this._duration;
|
|
} else {
|
|
this._duration = Params.fadeFrameCount;
|
|
}
|
|
};
|
|
|
|
Window_QuickNotification.prototype.numVisibleRows = function () {
|
|
return 4;
|
|
};
|
|
|
|
/**
|
|
* 通知を表示中か
|
|
*/
|
|
Window_QuickNotification.prototype.isDisplaying = function () {
|
|
return this._duration > 0;
|
|
};
|
|
|
|
/**
|
|
* フェードイン中か
|
|
*/
|
|
Window_QuickNotification.prototype.isFadingIn = function () {
|
|
return this._duration >= Params.displayDuration - Params.fadeFrameCount;
|
|
};
|
|
|
|
/**
|
|
* フェードアウト中か
|
|
*/
|
|
Window_QuickNotification.prototype.isFadingOut = function () {
|
|
return this._duration < Params.fadeFrameCount;
|
|
};
|
|
|
|
/**
|
|
* 顔グラフィックのロード中処理
|
|
*/
|
|
Window_QuickNotification.prototype.updateLoading = function () {
|
|
if (this._faceBitmap == null) {
|
|
return false;
|
|
}
|
|
|
|
if (ImageManager.isReady()) {
|
|
this.drawMessageFace();
|
|
this._faceBitmap = null;
|
|
return false;
|
|
} else {
|
|
return true;
|
|
}
|
|
};
|
|
|
|
/**
|
|
* 目標不透明度の取得
|
|
*/
|
|
Window_QuickNotification.prototype.getTargetOpacity = function () {
|
|
if (this.isFadingIn()) {
|
|
// フェードイン
|
|
return (
|
|
(255 * (Params.displayDuration - this._duration)) /
|
|
Params.fadeFrameCount
|
|
);
|
|
} else if (this.isFadingOut()) {
|
|
// フェードアウト
|
|
return (255 * this._duration) / Params.fadeFrameCount;
|
|
} else {
|
|
return 255;
|
|
}
|
|
};
|
|
|
|
/**
|
|
* 通知の表示開始
|
|
*/
|
|
Window_QuickNotification.prototype.display = function (notification) {
|
|
this.initMembers();
|
|
|
|
if (notification == null || notification.text == null) {
|
|
this.hide();
|
|
return;
|
|
}
|
|
|
|
// 表示パラメータの設定
|
|
this._textState = {
|
|
index: 0,
|
|
text: this.convertEscapeCharacters(notification.text),
|
|
};
|
|
this._allTextWidth = 0;
|
|
this._duration = Params.displayDuration;
|
|
this._faceName = notification.faceName || "";
|
|
this._faceIndex = notification.faceIndex;
|
|
this._faceBitmap = null;
|
|
|
|
this.newPage(this._textState);
|
|
this.updatePosition();
|
|
this.updateOpacity();
|
|
this.show();
|
|
};
|
|
|
|
/**
|
|
* 新しいページの表示
|
|
*/
|
|
Window_QuickNotification.prototype.newPage = function (textState) {
|
|
// コンテンツを一時領域に書く
|
|
this.contents = Window_QuickNotification.tempMessageBuffer;
|
|
this.contents.clear();
|
|
this.resetFontSettings();
|
|
this.loadMessageFace();
|
|
textState.x = this.newLineX();
|
|
textState.y = 0;
|
|
textState.left = this.newLineX();
|
|
textState.height = this.calcTextHeight(textState, false);
|
|
this._allTextHeight = this.calcTextHeight(textState, true);
|
|
if (this._faceName) {
|
|
this._allTextHeight = Math.max(this._allTextHeight, Params.faceImageSize);
|
|
}
|
|
|
|
this.updateMessage();
|
|
|
|
// コンテンツを一時領域から正式に反映
|
|
this.createContents();
|
|
this.contents.blt(
|
|
Window_QuickNotification.tempMessageBuffer,
|
|
0,
|
|
0,
|
|
this._allTextWidth,
|
|
this._allTextHeight,
|
|
0,
|
|
0,
|
|
this._allTextWidth,
|
|
this._allTextHeight
|
|
);
|
|
};
|
|
|
|
/**
|
|
* 顔グラフィックを読み込む
|
|
*/
|
|
Window_QuickNotification.prototype.loadMessageFace = function () {
|
|
this._faceBitmap = ImageManager.loadFace(this._faceName);
|
|
};
|
|
|
|
/**
|
|
* 表示位置を設定
|
|
*/
|
|
Window_QuickNotification.prototype.updatePosition = function () {
|
|
// 不透明度に応じて位置をずらす
|
|
var xOffset =
|
|
Params.displayOffsetX -
|
|
((this.width / 2) * (255 - this.getTargetOpacity())) / 255;
|
|
switch (Params.displayPosition) {
|
|
case Const.displayPosition.topRight:
|
|
case Const.displayPosition.bottomRight:
|
|
// 右側
|
|
this.x = Graphics.boxWidth - this.width - xOffset;
|
|
break;
|
|
|
|
default:
|
|
// 左側
|
|
this.x = xOffset;
|
|
break;
|
|
}
|
|
|
|
var epsilon = 8;
|
|
var diffY = this.y - this._destinationY;
|
|
if (Math.abs(diffY) > epsilon) {
|
|
// 目標位置とズレている場合はぬるっと移動
|
|
if (diffY > 0) {
|
|
this.y -= Math.max(diffY / 8, epsilon);
|
|
} else {
|
|
this.y -= Math.min(diffY / -8, -epsilon);
|
|
}
|
|
} else {
|
|
this.y = this._destinationY;
|
|
}
|
|
};
|
|
|
|
/**
|
|
* ウィンドウのサイズを更新
|
|
*/
|
|
Window_QuickNotification.prototype.updateWindowSize = function () {
|
|
var offset = this.standardPadding() * 2;
|
|
this.width = this._allTextWidth + offset;
|
|
this.height = this._allTextHeight + offset;
|
|
};
|
|
|
|
/**
|
|
* 不透明度の更新
|
|
*/
|
|
Window_QuickNotification.prototype.updateOpacity = function () {
|
|
this.opacity = this.contentsOpacity = this.getTargetOpacity();
|
|
};
|
|
|
|
Window_QuickNotification.prototype.update = function () {
|
|
Window_Base.prototype.update.call(this);
|
|
|
|
if (!this.isDisplaying()) {
|
|
return;
|
|
}
|
|
|
|
if (this.updateLoading()) {
|
|
// スキンのロード中
|
|
return;
|
|
}
|
|
|
|
this._duration--;
|
|
this.updateOpacity();
|
|
this.updatePosition();
|
|
|
|
// 表示が終了したら初期化
|
|
if (!this.isDisplaying()) {
|
|
this.initMembers();
|
|
}
|
|
};
|
|
|
|
/**
|
|
* メッセージの更新
|
|
*/
|
|
Window_QuickNotification.prototype.updateMessage = function () {
|
|
if (this._textState == null) {
|
|
return false;
|
|
}
|
|
|
|
while (!this.isEndOfText(this._textState)) {
|
|
this.processCharacter(this._textState);
|
|
this._allTextWidth = Math.max(this._allTextWidth, this._textState.x);
|
|
}
|
|
|
|
this.updateWindowSize();
|
|
|
|
return true;
|
|
};
|
|
|
|
/**
|
|
* 顔グラフィックを描画
|
|
*/
|
|
Window_QuickNotification.prototype.drawMessageFace = function () {
|
|
// 指定サイズに拡縮して描画
|
|
var size = Params.faceImageSize;
|
|
var bitmap = ImageManager.loadFace(this._faceName);
|
|
var sw = Window_Base._faceWidth;
|
|
var sh = Window_Base._faceHeight;
|
|
var sx = (this._faceIndex % 4) * sw;
|
|
var sy = Math.floor(this._faceIndex / 4) * sh;
|
|
this.contents.blt(bitmap, sx, sy, sw, sh, 0, 0, size, size);
|
|
};
|
|
|
|
/**
|
|
* 改行時の描画先 X 座標
|
|
*/
|
|
Window_QuickNotification.prototype.newLineX = function () {
|
|
return this._faceName === "" ? 0 : Params.faceImageSize + 24;
|
|
};
|
|
|
|
/**
|
|
* 改行の処理
|
|
*/
|
|
Window_QuickNotification.prototype.processNewLine = function (textState) {
|
|
this._allTextWidth = Math.max(this._allTextWidth, textState.x);
|
|
|
|
Window_Base.prototype.processNewLine.call(this, textState);
|
|
};
|
|
|
|
/**
|
|
* 改ページの処理
|
|
*/
|
|
Window_QuickNotification.prototype.processNewPage = function (textState) {
|
|
Window_Base.prototype.processNewPage.call(this, textState);
|
|
if (textState.text[textState.index] === "\n") {
|
|
textState.index++;
|
|
}
|
|
|
|
textState.y = this.contents.height;
|
|
};
|
|
|
|
/**
|
|
* テキスト終端か
|
|
*/
|
|
Window_QuickNotification.prototype.isEndOfText = function (textState) {
|
|
return textState.index >= textState.text.length;
|
|
};
|
|
|
|
/**
|
|
* 改ページが必要か
|
|
*/
|
|
Window_QuickNotification.prototype.needsNewPage = function (textState) {
|
|
return (
|
|
!this.isEndOfText(textState) &&
|
|
textState.y + textState.height > this.contents.height
|
|
);
|
|
};
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Scene_Base
|
|
|
|
// シーンをまたいで保持するための通知ウィンドウの一覧
|
|
Scene_Base._gQuickNotificationWindows = [];
|
|
|
|
/**
|
|
* 通知ウィンドウの作成
|
|
*/
|
|
Scene_Base.prototype.createQuickNotificationWindow = function () {
|
|
if (this._quickNotificationWindowLayer != null) {
|
|
return;
|
|
}
|
|
|
|
var width = Graphics.boxWidth;
|
|
var height = Graphics.boxHeight;
|
|
var x = (Graphics.width - width) / 2;
|
|
var y = (Graphics.height - height) / 2;
|
|
this._quickNotificationWindowLayer = new WindowLayer();
|
|
this._quickNotificationWindowLayer.move(x, y, width, height);
|
|
this.addChild(this._quickNotificationWindowLayer);
|
|
|
|
Window_QuickNotification.preloadWindowskin();
|
|
|
|
// 表示終了前の通知があれば表示
|
|
Scene_Base._gQuickNotificationWindows.forEach(function (windowObj) {
|
|
this._quickNotificationWindowLayer.addChild(windowObj);
|
|
}, this);
|
|
};
|
|
|
|
/**
|
|
* 通知ウィンドウを表示可能か
|
|
*/
|
|
Scene_Base.prototype.isQuickNotificationAvailable = function () {
|
|
// ゲーム起動時は $gameTemp と $gameSystem が生成されていない可能性があるのでチェック
|
|
return (
|
|
this._quickNotificationWindowLayer != null &&
|
|
$gameTemp != null &&
|
|
$gameSystem != null
|
|
);
|
|
};
|
|
|
|
var _Scene_Base_update = Scene_Base.prototype.update;
|
|
Scene_Base.prototype.update = function () {
|
|
_Scene_Base_update.call(this);
|
|
|
|
this.updateQuickNotificationDisplay();
|
|
};
|
|
|
|
var _Scene_Base_terminate = Scene_Base.prototype.terminate;
|
|
Scene_Base.prototype.terminate = function () {
|
|
_Scene_Base_terminate.call(this);
|
|
|
|
this.destroyQuickNotificationWindows();
|
|
};
|
|
|
|
/**
|
|
* 通知ウィンドウの破棄
|
|
*/
|
|
Scene_Base.prototype.destroyQuickNotificationWindows = function () {
|
|
if (!this.isQuickNotificationAvailable()) {
|
|
return;
|
|
}
|
|
|
|
var layer = this._quickNotificationWindowLayer;
|
|
layer.children.forEach(function (child) {
|
|
this._quickNotificationWindowLayer.removeChild(child);
|
|
}, this);
|
|
|
|
this.removeChild(layer);
|
|
this._quickNotificationWindowLayer = null;
|
|
};
|
|
|
|
/**
|
|
* 通知の表示を更新
|
|
*/
|
|
Scene_Base.prototype.updateQuickNotificationDisplay = function () {
|
|
if (!this.isQuickNotificationAvailable()) {
|
|
return;
|
|
}
|
|
|
|
if (!$gameSystem.isQuickNotificationEnabled()) {
|
|
// 通知を表示できないときは非表示にしつつ各種フラグを解除
|
|
$gameTemp.clearQuickNotification();
|
|
this._quickNotificationWindowLayer.children.forEach(function (windowObj) {
|
|
windowObj.fadeOut();
|
|
});
|
|
return;
|
|
}
|
|
|
|
this.removeFinishedQuickNotification();
|
|
|
|
// 最大数まで表示されている場合は追加表示しない
|
|
if (
|
|
this._quickNotificationWindowLayer.children.length >=
|
|
Params.notificationCountMax
|
|
) {
|
|
return;
|
|
}
|
|
|
|
// 要求されているメッセージを表示できるだけ表示
|
|
while ($gameTemp.isQuickNotificationReady()) {
|
|
if (!this.displayQuickNotification()) {
|
|
break;
|
|
}
|
|
}
|
|
|
|
this.updateQuickNotificationPosition();
|
|
};
|
|
|
|
/**
|
|
* 表示が終了した通知を削除
|
|
*/
|
|
Scene_Base.prototype.removeFinishedQuickNotification = function () {
|
|
var finishedWindows = this._quickNotificationWindowLayer.children.filter(
|
|
function (child) {
|
|
return !child.isDisplaying();
|
|
}
|
|
);
|
|
|
|
if (finishedWindows.length <= 0) {
|
|
// 終了した通知がない
|
|
return;
|
|
}
|
|
|
|
finishedWindows.forEach(function (windowObj) {
|
|
this._quickNotificationWindowLayer.removeChild(windowObj);
|
|
}, this);
|
|
|
|
Scene_Base._gQuickNotificationWindows =
|
|
Scene_Base._gQuickNotificationWindows.filter(function (windowObj) {
|
|
return finishedWindows.indexOf(windowObj) < 0;
|
|
});
|
|
};
|
|
|
|
/**
|
|
* 通知の表示
|
|
*/
|
|
Scene_Base.prototype.displayQuickNotification = function () {
|
|
var notification = $gameTemp.retrieveNextQuickNotification();
|
|
if (notification == null) {
|
|
return false;
|
|
}
|
|
|
|
// 予約されている通知を表示
|
|
var windowObj = new Window_QuickNotification();
|
|
windowObj.display(notification);
|
|
this._quickNotificationWindowLayer.addChild(windowObj);
|
|
Scene_Base._gQuickNotificationWindows.push(windowObj);
|
|
|
|
// 通知音を再生
|
|
if (Params.notificationSe) {
|
|
AudioManager.playSe(Params.notificationSe);
|
|
}
|
|
|
|
return true;
|
|
};
|
|
|
|
/**
|
|
* 通知の表示位置を更新
|
|
*/
|
|
Scene_Base.prototype.updateQuickNotificationPosition = function () {
|
|
// 表示位置に応じた調整
|
|
var isBottom;
|
|
var y;
|
|
var sign;
|
|
switch (Params.displayPosition) {
|
|
case Const.displayPosition.bottomLeft:
|
|
case Const.displayPosition.bottomRight:
|
|
// 下側
|
|
isBottom = true;
|
|
y = Graphics.boxHeight - Params.displayOffsetY;
|
|
sign = -1;
|
|
break;
|
|
|
|
default:
|
|
// 上側
|
|
isBottom = false;
|
|
y = Params.displayOffsetY;
|
|
sign = 1;
|
|
break;
|
|
}
|
|
|
|
var children = this._quickNotificationWindowLayer.children;
|
|
for (var i = 0; i < children.length; i++) {
|
|
var windowObj = children[i];
|
|
if (isBottom) {
|
|
y -= windowObj.height;
|
|
}
|
|
windowObj.setDestinationY(y);
|
|
if (!isBottom) {
|
|
y += windowObj.height;
|
|
}
|
|
|
|
y += sign * Params.displayGap;
|
|
}
|
|
};
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Scene_Base
|
|
|
|
var _Scene_Base_start = Scene_Base.prototype.start;
|
|
Scene_Base.prototype.start = function () {
|
|
_Scene_Base_start.call(this);
|
|
|
|
// 他のオブジェクトより前面に表示するため、シーン開始時まで生成を遅延
|
|
this.createQuickNotificationWindow();
|
|
};
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Scene_Map
|
|
|
|
var _Scene_Map_snapForBattleBackground =
|
|
Scene_Map.prototype.snapForBattleBackground;
|
|
Scene_Map.prototype.snapForBattleBackground = function () {
|
|
// 通知はキャプチャしない
|
|
var layer = this._quickNotificationWindowLayer;
|
|
if (layer != null) {
|
|
layer.visible = false;
|
|
}
|
|
|
|
_Scene_Map_snapForBattleBackground.call(this);
|
|
|
|
if (layer != null) {
|
|
layer.visible = true;
|
|
}
|
|
};
|
|
})();
|