1587 lines
45 KiB
JavaScript
1587 lines
45 KiB
JavaScript
//=============================================================================
|
||
// KMS_MapActiveMessage.js
|
||
// Last update: 2022/05/22
|
||
//=============================================================================
|
||
|
||
/*:
|
||
* @plugindesc
|
||
* [v0.3.2] Show messages automatically for events on map.
|
||
*
|
||
* @author Kameo (Kamesoft)
|
||
*
|
||
* @param Balloon offset Y
|
||
* @default 20
|
||
* @desc Vertical position offset for balloons by pixel.
|
||
*
|
||
* @param Balloon margin
|
||
* @default -8
|
||
* @desc Adjust frame size of balloons by pixel.
|
||
*
|
||
* @param Default range
|
||
* @default 4
|
||
* @desc Default distance for displaying message by tile unit.
|
||
*
|
||
* @param Display duration
|
||
* @default 300
|
||
* @desc Display frame count.
|
||
*
|
||
* @param Max message count
|
||
* @default 10
|
||
* @desc Max number of active messages.
|
||
*
|
||
* @param Message skin
|
||
* @default ActiveMessageSkin
|
||
* @require 1
|
||
* @dir img/system/
|
||
* @type file
|
||
* @desc Message skin for active message. Load from img/system.
|
||
*
|
||
*
|
||
* @help
|
||
*
|
||
* ## Plugin command
|
||
*
|
||
* MapActiveMessage enable # Enable active message
|
||
* MapActiveMessage disable # Display active message
|
||
* MapActiveMessage show 10 # Show message of the event whose ID is 10
|
||
* MapActiveMessage show # Show messages of all events
|
||
*
|
||
*/
|
||
|
||
/*:ja
|
||
* @plugindesc
|
||
* フキダシのヤツ、CBRって所が改造
|
||
* [v0.3.2] プレイヤーが近付いたときに、自動的にメッセージを表示するイベントを作成します。
|
||
*
|
||
* @author かめお (Kamesoft)
|
||
*
|
||
* @param Balloon offset Y
|
||
* @default 20
|
||
* @desc 吹き出しの縦方向の位置をピクセル単位で調整します。
|
||
*
|
||
* @param Balloon margin
|
||
* @default -8
|
||
* @desc 吹き出しの枠サイズをピクセル単位で調整します。
|
||
*
|
||
* @param Default range
|
||
* @default 4
|
||
* @desc メッセージを表示する距離をタイル単位で指定します。
|
||
*
|
||
* @param Display duration
|
||
* @default 300
|
||
* @desc メッセージ表示時間をフレーム単位で指定します。
|
||
*
|
||
* @param Max message count
|
||
* @default 10
|
||
* @desc 表示できるメッセージの最大数です。
|
||
*
|
||
* @param Message skin
|
||
* @default ActiveMessageSkin
|
||
* @require 1
|
||
* @dir img/system/
|
||
* @type file
|
||
* @desc メッセージの表示に使用するスキン画像です。 img/system から読み込みます。
|
||
*
|
||
*
|
||
* @help
|
||
*
|
||
* ■ プラグインコマンド
|
||
*
|
||
* MapActiveMessage enable # アクティブメッセージを有効にします。
|
||
* MapActiveMessage disable # アクティブメッセージを無効にします。
|
||
* MapActiveMessage show 10 # イベント ID:10 のメッセージを表示します。
|
||
* MapActiveMessage show # 全イベントのメッセージを表示します。
|
||
*
|
||
*/
|
||
|
||
var KMS = KMS || {};
|
||
|
||
(function () {
|
||
"use strict";
|
||
|
||
// 定数
|
||
var Const = {
|
||
debug: false, // デバッグモード
|
||
pluginCode: "MapActiveMessage", // プラグインコード
|
||
regex: {
|
||
activeMessage: /<(?:アクティブメッセージ|ActiveMessage)\s*[:\s]\s*([^>]+)>/i,
|
||
displayRange: /<(?:アクティブメッセージ距離|ActiveMessageRange)\s*[:\s]\s*(\d+)>/i,
|
||
displayDuration: /<(?:アクティブメッセージ表示時間|ActiveMessageDuration)\s*[:\s]\s*(\d+)>/i,
|
||
loopMessage: /<(?:アクティブメッセージループ|ActiveMessageLoop)>/i,
|
||
beginMessage: /<(?:アクティブメッセージ|ActiveMessage)\s*[:\s][^>]+$/i,
|
||
endMessage: /([^>]*)>/
|
||
},
|
||
|
||
balloonFrameInfo: { margin: 4, size: 24, lineLength: 48, srcSize: 96 },
|
||
balloonVertexSize: { width: 24, height: 48 },
|
||
|
||
// 吹き出しの表示位置
|
||
balloonPosition: { below: 0, above: 1 }
|
||
};
|
||
|
||
var PluginName = "KMS_" + Const.pluginCode;
|
||
|
||
KMS.imported = KMS.imported || {};
|
||
KMS.imported[Const.pluginCode] = true;
|
||
|
||
function isNullOrUndefined(value) {
|
||
return value === null || value === undefined;
|
||
}
|
||
|
||
// デフォルト値つきで文字列から int を解析
|
||
function parseIntWithDefault(param, defaultValue) {
|
||
var value = parseInt(param);
|
||
return isNaN(value) ? defaultValue : value;
|
||
}
|
||
|
||
var pluginParams = PluginManager.parameters(PluginName);
|
||
var Params = {};
|
||
Params.messageSkin = pluginParams["Message skin"] || "ActiveMessageSkin";
|
||
Params.messageCountMax = Math.max(parseIntWithDefault(pluginParams["Max message count"], 8), 1);
|
||
Params.balloonOffsetY = parseIntWithDefault(pluginParams["Balloon offset Y"], 20);
|
||
Params.balloonMargin = parseIntWithDefault(pluginParams["Balloon margin"], -8);
|
||
Params.defaultRange = Math.max(parseIntWithDefault(pluginParams["Default range"], 4), 1);
|
||
Params.displayDuration = Math.max(parseIntWithDefault(pluginParams["Display duration"], 300), 1);
|
||
Params.fadeFrameCount = Math.max(parseIntWithDefault(pluginParams["Fade frame count"], 8), 1);
|
||
Params.fontSize = Math.max(parseIntWithDefault(pluginParams["Font size"], 18), 1);
|
||
|
||
// デバッグログ
|
||
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.setMapActiveMessageEnabled(true);
|
||
break;
|
||
|
||
case "disable": // 無効化
|
||
$gameSystem.setMapActiveMessageEnabled(false);
|
||
break;
|
||
|
||
case "show": // 強制表示 (eventId)
|
||
// eventId 省略時 (undefined) は全イベントが対象
|
||
$gameMap.forceDisplayActiveMessage(parseInt(args[1]));
|
||
break;
|
||
|
||
default:
|
||
// 不明なコマンド
|
||
console.error("[%s %s] Unknown command.", Const.pluginCode, args[0]);
|
||
break;
|
||
}
|
||
};
|
||
|
||
// タイリング描画
|
||
function tileBlt(dstImage, srcImage, sx, sy, sw, sh, dx, dy, dw, dh) {
|
||
for (var offY = 0; offY < dh; offY += sh) {
|
||
for (var offX = 0; offX < dw; offX += sw) {
|
||
var tempSh = Math.min(sh, dh - offY);
|
||
var tempSw = Math.min(sw, dw - offX);
|
||
dstImage.blt(srcImage, sx, sy, tempSw, tempSh, dx + offX, dy + offY, tempSw, tempSh);
|
||
}
|
||
}
|
||
}
|
||
|
||
//-----------------------------------------------------------------------------
|
||
// Game_Temp
|
||
|
||
var _Game_Temp_initialize = Game_Temp.prototype.initialize;
|
||
Game_Temp.prototype.initialize = function () {
|
||
_Game_Temp_initialize.call(this);
|
||
|
||
this.clearMapActiveMessage();
|
||
};
|
||
|
||
/**
|
||
* アクティブメッセージの登録
|
||
*/
|
||
Game_Temp.prototype.pushMapActiveMessages = function (targetEvent, messages, needsLoop, isForced) {
|
||
var message = {
|
||
id: this._mapActiveMessageNextId++,
|
||
event: targetEvent,
|
||
messages: messages,
|
||
needsLoop: needsLoop,
|
||
isForced: isForced
|
||
};
|
||
this._mapActiveMessages.push(message);
|
||
};
|
||
|
||
/**
|
||
* アクティブメッセージのクリア
|
||
*/
|
||
Game_Temp.prototype.clearMapActiveMessage = function () {
|
||
this._mapActiveMessageNextId = 0;
|
||
this._mapActiveMessages = [];
|
||
};
|
||
|
||
/**
|
||
* 次のアクティブメッセージを取得
|
||
*/
|
||
Game_Temp.prototype.popNextMapActiveMessage = function () {
|
||
return this._mapActiveMessages.shift();
|
||
};
|
||
|
||
/**
|
||
* アクティブメッセージが登録されているか
|
||
*/
|
||
Game_Temp.prototype.isMapActiveMessageReady = function () {
|
||
return this._mapActiveMessages.length > 0;
|
||
};
|
||
|
||
//-----------------------------------------------------------------------------
|
||
// Game_System
|
||
|
||
/**
|
||
* アクティブメッセージの有効状態を取得
|
||
*/
|
||
Game_System.prototype.isMapActiveMessageEnabled = function () {
|
||
return !isNullOrUndefined(this._mapActiveMessageEnabled) ? this._mapActiveMessageEnabled : true;
|
||
};
|
||
|
||
/**
|
||
* アクティブメッセージの有効状態を設定
|
||
*/
|
||
Game_System.prototype.setMapActiveMessageEnabled = function (enabled) {
|
||
this._mapActiveMessageEnabled = !!enabled;
|
||
};
|
||
|
||
//-----------------------------------------------------------------------------
|
||
// Game_Map
|
||
|
||
var _Game_Map_setup = Game_Map.prototype.setup;
|
||
Game_Map.prototype.setup = function (mapId) {
|
||
_Game_Map_setup.call(this, mapId);
|
||
|
||
this.initializeActiveMessage();
|
||
};
|
||
|
||
/**
|
||
* アクティブメッセージの初期化
|
||
*/
|
||
Game_Map.prototype.initializeActiveMessage = function () {
|
||
// 最初は全イベントの表示済みフラグを解除
|
||
this.clearActiveMessageShownFlags();
|
||
};
|
||
|
||
/**
|
||
* アクティブメッセージの表示済みフラグを解除
|
||
*/
|
||
Game_Map.prototype.clearActiveMessageShownFlags = function () {
|
||
this.events().forEach(function (event) {
|
||
event.setMapActiveMessageShown(false);
|
||
});
|
||
|
||
this.requestUpdateActiveMessage();
|
||
};
|
||
|
||
/**
|
||
* アクティブメッセージの更新要求
|
||
*/
|
||
Game_Map.prototype.requestUpdateActiveMessage = function () {
|
||
this._needsUpdateActiveMessage = true;
|
||
};
|
||
|
||
var _Game_Map_update = Game_Map.prototype.update;
|
||
Game_Map.prototype.update = function (sceneActive) {
|
||
_Game_Map_update.call(this, sceneActive);
|
||
|
||
this.updateDisplayActiveMessage();
|
||
};
|
||
|
||
/**
|
||
* アクティブメッセージの表示判定
|
||
*/
|
||
Game_Map.prototype.updateDisplayActiveMessage = function () {
|
||
if (!this._needsUpdateActiveMessage) {
|
||
return;
|
||
}
|
||
|
||
this._needsUpdateActiveMessage = false;
|
||
|
||
// アクティブメッセージの登録
|
||
var events = $gamePlayer.findAvailableMapActiveMessageEvents();
|
||
events.forEach(function (event) {
|
||
$gameTemp.pushMapActiveMessages(event, event.getMapActiveMessages(), event.needsMapActiveMessageLoop());
|
||
});
|
||
};
|
||
|
||
/**
|
||
* アクティブメッセージの強制表示
|
||
*/
|
||
Game_Map.prototype.forceDisplayActiveMessage = function (eventId) {
|
||
var invoker = function (event) {
|
||
$gameTemp.pushMapActiveMessages(event, event.getMapActiveMessages(), event.needsMapActiveMessageLoop(), true);
|
||
};
|
||
|
||
if (isNullOrUndefined(eventId) || isNaN(eventId)) {
|
||
// 全表示
|
||
this.events().forEach(invoker);
|
||
} else {
|
||
// イベント ID 指定
|
||
this.events()
|
||
.filter(function (event) {
|
||
return event.eventId() === eventId;
|
||
})
|
||
.forEach(invoker);
|
||
}
|
||
};
|
||
|
||
var _Game_Map_refresh = Game_Map.prototype.refresh;
|
||
Game_Map.prototype.refresh = function () {
|
||
_Game_Map_refresh.call(this);
|
||
|
||
this.requestUpdateActiveMessage();
|
||
};
|
||
|
||
//-----------------------------------------------------------------------------
|
||
// Game_CharacterBase
|
||
|
||
var _Game_CharacterBase = Game_CharacterBase.prototype.setDirection;
|
||
Game_CharacterBase.prototype.setDirection = function (d) {
|
||
_Game_CharacterBase.call(this, d);
|
||
|
||
// 移動時には方向指定があるはずなので、ここでメッセージの更新要求を出す
|
||
if (!isNullOrUndefined($gameMap)) {
|
||
$gameMap.requestUpdateActiveMessage();
|
||
}
|
||
};
|
||
|
||
//-----------------------------------------------------------------------------
|
||
// Game_Player
|
||
|
||
/**
|
||
* アクティブメッセージを表示可能なイベントを探す
|
||
*/
|
||
Game_Player.prototype.findAvailableMapActiveMessageEvents = function () {
|
||
if (!this.canMove()) {
|
||
return [];
|
||
}
|
||
|
||
// 指定距離内でメッセージ未表示のイベントを列挙
|
||
var candidateEvents = $gameMap.events().filter(function (event) {
|
||
return (
|
||
event.hasMapActiveMessage() &&
|
||
!event.isMapActiveMessageShown() &&
|
||
this.calcDistanceForMapActiveMessage(event) <= event.getMapActiveMessageRange()
|
||
);
|
||
}, this);
|
||
|
||
// 表示済みフラグの解除判定
|
||
$gameMap.events().forEach(function (event) {
|
||
var distance = this.calcDistanceForMapActiveMessage(event);
|
||
if (event.isMapActiveMessageShown()) {
|
||
// メッセージ表示距離から出ていれば表示済みフラグ解除
|
||
if (distance > event.getMapActiveMessageRange()) {
|
||
event.setMapActiveMessageShown(false);
|
||
}
|
||
}
|
||
}, this);
|
||
|
||
return candidateEvents;
|
||
};
|
||
|
||
Game_Player.prototype.calcDistanceForMapActiveMessage = function (event) {
|
||
var diffX = this.x - event.x;
|
||
var diffY = this.y - event.y;
|
||
|
||
return Math.sqrt(diffX * diffX + diffY * diffY);
|
||
};
|
||
|
||
//-----------------------------------------------------------------------------
|
||
// Game_Event
|
||
|
||
var _Game_Event_setupPage = Game_Event.prototype.setupPage;
|
||
Game_Event.prototype.setupPage = function () {
|
||
_Game_Event_setupPage.call(this);
|
||
|
||
this.setupMapActiveMessage();
|
||
};
|
||
|
||
/**
|
||
* 現在のページ番号を取得
|
||
*/
|
||
Game_Event.prototype.pageIndex = function () {
|
||
return this._pageIndex;
|
||
};
|
||
|
||
/**
|
||
* アクティブメッセージを構築
|
||
*/
|
||
Game_Event.prototype.setupMapActiveMessage = function () {
|
||
this._mapActiveMessageList = [];
|
||
this._mapActiveMessageRange = Params.defaultRange;
|
||
this._mapActiveMessageDuration = Params.displayDuration;
|
||
this._needsMapActiveMessageLoop = false;
|
||
this._isMapActiveMessageShown = false;
|
||
|
||
var page = this.page();
|
||
if (isNullOrUndefined(page)) {
|
||
return;
|
||
}
|
||
|
||
var parsed = this.parseCommentForMapActiveMessage(page);
|
||
var mergedComment = parsed.mergedComment;
|
||
var commentUnits = parsed.commentUnits;
|
||
|
||
// メッセージ距離を解析
|
||
var rangeMatch = Const.regex.displayRange.exec(mergedComment);
|
||
if (!isNullOrUndefined(rangeMatch)) {
|
||
this._mapActiveMessageRange = Math.max(parseIntWithDefault(rangeMatch[1], Params.defaultRange), 1);
|
||
}
|
||
|
||
// ループ設定を解析
|
||
var loopMatch = Const.regex.loopMessage.exec(mergedComment);
|
||
if (!isNullOrUndefined(loopMatch)) {
|
||
this._needsMapActiveMessageLoop = true;
|
||
}
|
||
|
||
commentUnits.forEach(function (unit) {
|
||
// メッセージ定義を解析
|
||
var messageMatch = Const.regex.activeMessage.exec(unit);
|
||
if (!isNullOrUndefined(messageMatch)) {
|
||
this._mapActiveMessageList.push({
|
||
text: messageMatch[1],
|
||
duration: this._mapActiveMessageDuration
|
||
});
|
||
}
|
||
|
||
// メッセージ表示時間を解析
|
||
var durationMatch = Const.regex.displayDuration.exec(unit);
|
||
if (!isNullOrUndefined(durationMatch)) {
|
||
var duration = parseIntWithDefault(durationMatch[1], Params.displayDuration);
|
||
this._mapActiveMessageDuration = duration;
|
||
|
||
// 直前のメッセージの duration を変更
|
||
if (this._mapActiveMessageList.length > 0) {
|
||
this._mapActiveMessageList[this._mapActiveMessageList.length - 1].duration = duration;
|
||
}
|
||
}
|
||
}, this);
|
||
};
|
||
|
||
/**
|
||
* アクティブメッセージ用のコメント解析
|
||
*
|
||
* @param {Object} page 解析対象のイベントページ
|
||
*/
|
||
Game_Event.prototype.parseCommentForMapActiveMessage = function (page) {
|
||
function isComment(command) {
|
||
return command && (command.code === 108 || command.code === 408);
|
||
}
|
||
|
||
// 注釈以外に達するまで解析
|
||
var commandIndex = 0;
|
||
var command = page.list[commandIndex];
|
||
var mergedComment = ""; // コメントを結合した文字列
|
||
var commentUnit = "";
|
||
var commentUnits = []; // 解析単位ごとに結合した文字列のリスト
|
||
var inMessage = false;
|
||
while (isComment(command)) {
|
||
if (mergedComment.length > 0) {
|
||
mergedComment += "\n";
|
||
}
|
||
|
||
var commentText = command.parameters[0];
|
||
mergedComment += commentText;
|
||
|
||
if (inMessage) {
|
||
if (commentUnit.length > 0) {
|
||
commentUnit += "\n";
|
||
}
|
||
|
||
commentUnit += commentText;
|
||
|
||
if (Const.regex.endMessage.test(commentText)) {
|
||
commentUnits.push(commentUnit);
|
||
commentUnit = "";
|
||
inMessage = false;
|
||
}
|
||
} else {
|
||
if (Const.regex.beginMessage.test(commentText)) {
|
||
commentUnit = commentText;
|
||
inMessage = true;
|
||
} else {
|
||
commentUnits.push(commentText);
|
||
}
|
||
}
|
||
|
||
command = page.list[++commandIndex];
|
||
}
|
||
|
||
if (inMessage) {
|
||
commentUnits.push(commentUnit);
|
||
}
|
||
|
||
return {
|
||
mergedComment: mergedComment,
|
||
commentUnits: commentUnits
|
||
};
|
||
};
|
||
|
||
/**
|
||
* アクティブメッセージを取得
|
||
*
|
||
* @return {String} メッセージ
|
||
*/
|
||
Game_Event.prototype.getMapActiveMessages = function () {
|
||
return this._mapActiveMessageList;
|
||
};
|
||
|
||
/**
|
||
* アクティブメッセージが存在するか
|
||
*
|
||
* @return {Boolean} true if exists
|
||
*/
|
||
Game_Event.prototype.hasMapActiveMessage = function () {
|
||
return this._mapActiveMessageList.length !== 0;
|
||
};
|
||
|
||
/**
|
||
* アクティブメッセージを表示可能な範囲
|
||
*
|
||
* @return {Number} タイル単位の表示範囲半径
|
||
*/
|
||
Game_Event.prototype.getMapActiveMessageRange = function () {
|
||
return this._mapActiveMessageRange;
|
||
};
|
||
|
||
/**
|
||
* アクティブメッセージをループするか
|
||
*
|
||
* @return {Boolean} true if needs loop
|
||
*/
|
||
Game_Event.prototype.needsMapActiveMessageLoop = function () {
|
||
return this._needsMapActiveMessageLoop;
|
||
};
|
||
|
||
/**
|
||
* アクティブメッセージを表示するフレーム数
|
||
*
|
||
* @return {Number} 自動消去するまでのフレーム数
|
||
*/
|
||
Game_Event.prototype.getMapActiveMessageDuration = function () {
|
||
return this._mapActiveMessageDuration;
|
||
};
|
||
|
||
/**
|
||
* アクティブメッセージを表示済みか
|
||
*
|
||
* @return {Boolean} true if shown
|
||
*/
|
||
Game_Event.prototype.isMapActiveMessageShown = function () {
|
||
return this._isMapActiveMessageShown;
|
||
};
|
||
|
||
/**
|
||
* アクティブメッセージ表示済みかどうかを設定
|
||
*
|
||
* @param {Boolean} shown 設定する値
|
||
*/
|
||
Game_Event.prototype.setMapActiveMessageShown = function (shown) {
|
||
this._isMapActiveMessageShown = !!shown;
|
||
};
|
||
|
||
//-----------------------------------------------------------------------------
|
||
// Sprite_MapActiveMessageBalloon
|
||
//
|
||
// アクティブメッセージの吹き出し用スプライト
|
||
|
||
function Sprite_MapActiveMessageBalloon() {
|
||
this.initialize.apply(this, arguments);
|
||
}
|
||
|
||
Sprite_MapActiveMessageBalloon.prototype = Object.create(Sprite.prototype);
|
||
Sprite_MapActiveMessageBalloon.prototype.constructor = Sprite_MapActiveMessageBalloon;
|
||
|
||
Sprite_MapActiveMessageBalloon.prototype.initialize = function () {
|
||
Sprite.prototype.initialize.call(this);
|
||
|
||
this.anchor.y = 0.5;
|
||
this.initMembers();
|
||
};
|
||
|
||
Sprite_MapActiveMessageBalloon.prototype.initMembers = function () {
|
||
this._owner = null;
|
||
};
|
||
|
||
/**
|
||
* オーナーウィンドウの設定
|
||
*/
|
||
Sprite_MapActiveMessageBalloon.prototype.setOwner = function (owner) {
|
||
this._owner = owner;
|
||
};
|
||
|
||
/**
|
||
* 位置をオーナーウィンドウに合わせる
|
||
*/
|
||
Sprite_MapActiveMessageBalloon.prototype.followOwner = function () {
|
||
this.y = this._owner.height / 2;
|
||
};
|
||
|
||
/**
|
||
* サイズをオーナーウィンドウに合わせる
|
||
*/
|
||
Sprite_MapActiveMessageBalloon.prototype.fitToOwner = function () {
|
||
if (isNullOrUndefined(this._owner)) {
|
||
return;
|
||
}
|
||
|
||
var frameSize = Const.balloonFrameInfo.size;
|
||
var vertexHeight = Const.balloonVertexSize.height;
|
||
var heightOffset = (vertexHeight - frameSize) * 2;
|
||
|
||
// Bitmap のサイズ調整
|
||
var bitmapWidth = this._owner.width;
|
||
var bitmapHeight = this._owner.height + heightOffset;
|
||
if (isNullOrUndefined(this.bitmap) || this.width != bitmapWidth || this.height != bitmapHeight) {
|
||
this.bitmap = new Bitmap(bitmapWidth, bitmapHeight);
|
||
} else {
|
||
this.bitmap.clear();
|
||
}
|
||
|
||
if (Const.debug) {
|
||
this.bitmap.fillRect(0, 0, bitmapWidth, bitmapHeight, "rgba(160, 255, 160, 0.5)");
|
||
}
|
||
};
|
||
|
||
/**
|
||
* 吹き出しの再描画
|
||
*/
|
||
Sprite_MapActiveMessageBalloon.prototype.refresh = function () {
|
||
if (isNullOrUndefined(this._owner)) {
|
||
return;
|
||
}
|
||
|
||
// サイズの調整
|
||
this.fitToOwner();
|
||
|
||
// 吹き出しの描画
|
||
var frameSize = Const.balloonFrameInfo.size;
|
||
var vertexHeight = Const.balloonVertexSize.height;
|
||
var offsetX = -Params.balloonMargin;
|
||
var offsetY = vertexHeight - frameSize - Params.balloonMargin;
|
||
this.drawBalloon(offsetX, offsetY, this.width - offsetX * 2, this.height - offsetY * 2);
|
||
};
|
||
|
||
/**
|
||
* 吹き出しを描画
|
||
*/
|
||
Sprite_MapActiveMessageBalloon.prototype.drawBalloon = function (x, y, width, height) {
|
||
if (isNullOrUndefined(this._owner)) {
|
||
return;
|
||
}
|
||
|
||
this.drawBalloonBackground(x, y, width, height);
|
||
this.drawBalloonFrame(x, y, width, height);
|
||
};
|
||
|
||
/**
|
||
* 吹き出しの背景を描画
|
||
*/
|
||
Sprite_MapActiveMessageBalloon.prototype.drawBalloonBackground = function (x, y, width, height) {
|
||
var srcImage = this._owner.getWindowSkin();
|
||
var frame = Const.balloonFrameInfo;
|
||
|
||
var prevOpacity = this.bitmap.paintOpacity;
|
||
this.bitmap.paintOpacity = this._owner.backOpacity;
|
||
|
||
// 背景下層
|
||
this.bitmap.blt(
|
||
srcImage,
|
||
0,
|
||
0,
|
||
frame.srcSize,
|
||
frame.srcSize,
|
||
x + frame.margin,
|
||
y + frame.margin,
|
||
width - frame.margin * 2,
|
||
height - frame.margin * 2
|
||
);
|
||
|
||
// 背景上層
|
||
tileBlt(
|
||
this.bitmap,
|
||
srcImage,
|
||
0,
|
||
frame.srcSize,
|
||
frame.srcSize,
|
||
frame.srcSize,
|
||
x + frame.margin,
|
||
y + frame.margin,
|
||
width - frame.margin * 2,
|
||
height - frame.margin * 2
|
||
);
|
||
|
||
this.bitmap.paintOpacity = prevOpacity;
|
||
};
|
||
|
||
/**
|
||
* 吹き出しの枠を描画
|
||
*/
|
||
Sprite_MapActiveMessageBalloon.prototype.drawBalloonFrame = function (x, y, width, height) {
|
||
var srcImage = this._owner.getWindowSkin();
|
||
var vertexOffset = this._owner.getBalloonVertexX();
|
||
var balloonPos = this._owner.getBalloonPosition();
|
||
|
||
var frame = Const.balloonFrameInfo;
|
||
var vertexSize = Const.balloonVertexSize;
|
||
|
||
// 吹き出しの頂点は枠内に収める
|
||
vertexOffset = Math.min(Math.max(vertexOffset, 0), width - (frame.size * 2 + vertexSize.width));
|
||
|
||
// 縦枠 + コーナーを描画
|
||
function drawFrameV(sx, dx, dy) {
|
||
this.bitmap.blt(srcImage, sx, 0, frame.size, frame.size, dx, dy, frame.size, frame.size);
|
||
this.bitmap.blt(srcImage, sx, frame.size, frame.size, frame.lineLength, dx, dy + frame.size, frame.size, height - frame.size * 2);
|
||
this.bitmap.blt(
|
||
srcImage,
|
||
sx,
|
||
frame.size + frame.lineLength,
|
||
frame.size,
|
||
frame.size,
|
||
dx,
|
||
dy + height - frame.size,
|
||
frame.size,
|
||
frame.size
|
||
);
|
||
}
|
||
|
||
// 横枠と頂点を描画
|
||
function drawFrameH(sy, dx, dy, showVertex) {
|
||
var baseSx = frame.srcSize + frame.size;
|
||
var frameWidth = width - frame.size * 2;
|
||
var leftWidth = showVertex ? vertexOffset : frameWidth;
|
||
|
||
// 枠線の左側 (頂点がない場合は全体)]
|
||
this.bitmap.blt(srcImage, baseSx, sy, frame.lineLength, frame.size, dx, dy, leftWidth + 4, frame.size);
|
||
|
||
if (!showVertex) {
|
||
// 頂点を描画しない
|
||
return;
|
||
}
|
||
|
||
// sy > 0 なら下枠、sy === 0 なら上枠のはず
|
||
var newDx = dx + leftWidth;
|
||
var newDy = dy + (sy > 0 ? 0 : -(vertexSize.height - frame.size));
|
||
|
||
// 頂点
|
||
var vertexSx = frame.srcSize + (sy > 0 ? 0 : vertexSize.width);
|
||
this.bitmap.blt(
|
||
srcImage,
|
||
vertexSx + 1,
|
||
frame.srcSize,
|
||
vertexSize.width - 2,
|
||
vertexSize.height,
|
||
newDx + 1,
|
||
newDy,
|
||
vertexSize.width - 2,
|
||
vertexSize.height
|
||
);
|
||
|
||
if (Const.debug) {
|
||
this.bitmap.fillRect(newDx, newDy, vertexSize.width, vertexSize.height, "rgba(255, 160, 160, 0.5)");
|
||
}
|
||
|
||
// 枠線の右側
|
||
var rightWidth = frameWidth - (leftWidth + vertexSize.width);
|
||
if (rightWidth > 0) {
|
||
newDx += vertexSize.width;
|
||
this.bitmap.blt(srcImage, baseSx, sy, frame.lineLength, frame.size, newDx - 2, dy, rightWidth + 4, frame.size);
|
||
}
|
||
}
|
||
|
||
// 左枠
|
||
drawFrameV.call(this, frame.srcSize, x, y);
|
||
|
||
// 右枠
|
||
drawFrameV.call(this, frame.srcSize + frame.size + frame.lineLength, x + width - frame.size, y);
|
||
|
||
// 上枠 + 頂点
|
||
drawFrameH.call(this, 0, x + frame.size, y, balloonPos === Const.balloonPosition.below);
|
||
|
||
// 下枠 + 頂点
|
||
drawFrameH.call(this, frame.size + frame.lineLength, x + frame.size, y + height - frame.size, balloonPos === Const.balloonPosition.above);
|
||
};
|
||
|
||
//-----------------------------------------------------------------------------
|
||
// Sprite_Character
|
||
|
||
/**
|
||
* 同一のイベントか判定
|
||
*/
|
||
Sprite_Character.prototype.isSameEvent = function (event) {
|
||
if (isNullOrUndefined(this._character) || isNullOrUndefined(event) || !(this._character instanceof Game_Event)) {
|
||
return false;
|
||
}
|
||
|
||
return this._character.eventId() === event.eventId();
|
||
};
|
||
|
||
//-----------------------------------------------------------------------------
|
||
// Spriteset_Map
|
||
|
||
/**
|
||
* 指定されたイベントに対応するキャラクタースプライトを取得
|
||
*/
|
||
Spriteset_Map.prototype.findCharacterSpriteByEvent = function (event) {
|
||
var sameSprites = this._characterSprites.filter(function (sprite) {
|
||
return sprite.isSameEvent(event);
|
||
});
|
||
|
||
if (sameSprites.length > 0) {
|
||
return sameSprites[0];
|
||
} else {
|
||
return null;
|
||
}
|
||
};
|
||
|
||
//-----------------------------------------------------------------------------
|
||
// Window_MapActiveMessage
|
||
//
|
||
// マップ上でアクティブメッセージを表示するウィンドウ
|
||
// (スプライトでも良いが、メッセージ周りはウィンドウの方が扱いやすい)
|
||
|
||
function Window_MapActiveMessage() {
|
||
this.initialize.apply(this, arguments);
|
||
}
|
||
|
||
Window_MapActiveMessage.prototype = Object.create(Window_Base.prototype);
|
||
Window_MapActiveMessage.prototype.constructor = Window_MapActiveMessage;
|
||
|
||
// メッセージの一時描画バッファ
|
||
Window_MapActiveMessage.tempMessageBuffer = null;
|
||
|
||
/**
|
||
* アクティブメッセージ用スキンの事前読み込み
|
||
*/
|
||
Window_MapActiveMessage.preloadWindowskin = function () {
|
||
ImageManager.loadSystem(Params.messageSkin);
|
||
};
|
||
|
||
Window_MapActiveMessage.prototype.initialize = function () {
|
||
// コンテンツサイズは内容に応じて可変なので、ウィンドウサイズは仮
|
||
Window_Base.prototype.initialize.call(this, { x: 0, y: 0, width: 64, height: 64 });
|
||
|
||
if (isNullOrUndefined(Window_MapActiveMessage.tempMessageBuffer)) {
|
||
Window_MapActiveMessage.tempMessageBuffer = new Bitmap(Graphics.boxWidth, Graphics.boxHeight / 2);
|
||
}
|
||
|
||
this._balloonSprite = null;
|
||
|
||
this.opacity = 0;
|
||
this.contentsOpacity = 0;
|
||
this.initMembers();
|
||
|
||
this.CBR_t = 0;
|
||
};
|
||
|
||
Window_MapActiveMessage.prototype.standardFontSize = function () {
|
||
return Params.fontSize;
|
||
};
|
||
|
||
Window_MapActiveMessage.prototype.loadWindowskin = function () {
|
||
// デフォルトのスキンの代わりに、アクティブメッセージ用のスキンを読み込む
|
||
this._windowskin = ImageManager.loadSystem(Params.messageSkin);
|
||
};
|
||
|
||
/**
|
||
* ウィンドウスキンを取得
|
||
*/
|
||
Window_MapActiveMessage.prototype.getWindowSkin = function () {
|
||
return this._windowskin;
|
||
};
|
||
|
||
Window_MapActiveMessage.prototype.initMembers = function () {
|
||
this._message = null;
|
||
this._pendingMessages = [];
|
||
this._textState = null;
|
||
this._event = null;
|
||
this._characterSprite = null;
|
||
this._targetPageIndex = 0;
|
||
this._duration = 0;
|
||
this._isHiding = false;
|
||
this._balloonPosition = Const.balloonPosition.above;
|
||
};
|
||
|
||
Window_MapActiveMessage.prototype.printDebug = function (message) {
|
||
if (Const.debug) {
|
||
console.log("[MapActiveMessage] " + this.getId() + ": " + message);
|
||
}
|
||
};
|
||
|
||
Window_MapActiveMessage.prototype.show = function () {
|
||
Window_Base.prototype.show.call(this);
|
||
|
||
if (!isNullOrUndefined(this._balloonSprite)) {
|
||
this._balloonSprite.show();
|
||
}
|
||
};
|
||
|
||
Window_MapActiveMessage.prototype.hide = function () {
|
||
// ロールバック処理中はメッセージ無しで呼ばれる
|
||
if (this._message) {
|
||
this.printDebug("Hide");
|
||
}
|
||
|
||
this._duration = 0;
|
||
this._isHiding = true;
|
||
|
||
Window_Base.prototype.hide.call(this);
|
||
|
||
if (!isNullOrUndefined(this._balloonSprite)) {
|
||
this._balloonSprite.hide();
|
||
}
|
||
};
|
||
|
||
/**
|
||
* フェードアウト
|
||
*/
|
||
Window_MapActiveMessage.prototype.fadeOut = function () {
|
||
if (this.isFadingOut()) {
|
||
return;
|
||
}
|
||
|
||
this.printDebug("Fading out");
|
||
|
||
this._isHiding = true;
|
||
|
||
if (this.isFadingIn()) {
|
||
// フェードイン中は同じ不透明度からフェードアウトする
|
||
this._duration = this._initialDisplayDuration - this._duration;
|
||
} else {
|
||
this._duration = Params.fadeFrameCount;
|
||
}
|
||
};
|
||
|
||
Window_MapActiveMessage.prototype.numVisibleRows = function () {
|
||
return 4;
|
||
};
|
||
|
||
/**
|
||
* 吹き出しスプライトの設定
|
||
*/
|
||
Window_MapActiveMessage.prototype.setBalloonSprite = function (sprite) {
|
||
sprite.setOwner(this);
|
||
this._balloonSprite = sprite;
|
||
|
||
// ウィンドウの裏に表示
|
||
this.addChildAt(sprite, 0);
|
||
};
|
||
|
||
/**
|
||
* イベントに対する吹き出しの表示位置を取得
|
||
*/
|
||
Window_MapActiveMessage.prototype.getBalloonPosition = function () {
|
||
return this._balloonPosition;
|
||
};
|
||
|
||
/**
|
||
* メッセージ表示中か
|
||
*/
|
||
Window_MapActiveMessage.prototype.isDisplaying = function () {
|
||
return this._duration > 0;
|
||
};
|
||
|
||
/**
|
||
* メッセージ ID を取得
|
||
*/
|
||
Window_MapActiveMessage.prototype.getId = function () {
|
||
return this._message.id;
|
||
};
|
||
|
||
/**
|
||
* ループ表示するか
|
||
*/
|
||
Window_MapActiveMessage.prototype.needsLoop = function () {
|
||
return this._message.needsLoop;
|
||
};
|
||
|
||
/**
|
||
* 強制表示されたか
|
||
*/
|
||
Window_MapActiveMessage.prototype.isForced = function () {
|
||
return this._message.isForced;
|
||
};
|
||
|
||
/**
|
||
* フェードイン中か
|
||
*/
|
||
Window_MapActiveMessage.prototype.isFadingIn = function () {
|
||
return this._duration >= this._initialDisplayDuration - Params.fadeFrameCount;
|
||
};
|
||
|
||
/**
|
||
* フェードアウト中か
|
||
*/
|
||
Window_MapActiveMessage.prototype.isFadingOut = function () {
|
||
return this._duration < Params.fadeFrameCount;
|
||
};
|
||
|
||
/**
|
||
* 消去されているか
|
||
*/
|
||
Window_MapActiveMessage.prototype.isHiding = function () {
|
||
return this._isHiding;
|
||
};
|
||
|
||
/**
|
||
* 表示中のイベントと同一イベントか
|
||
*/
|
||
Window_MapActiveMessage.prototype.isSameEvent = function (event) {
|
||
if (isNullOrUndefined(this._event)) {
|
||
return false;
|
||
}
|
||
|
||
// ページ番号まで同じ場合に同一と見なす
|
||
if (this._event.eventId() === event.eventId() && this._targetPageIndex === event.pageIndex()) {
|
||
return true;
|
||
}
|
||
|
||
return false;
|
||
};
|
||
|
||
/**
|
||
* イベントが画面内にあるか判定
|
||
*/
|
||
Window_MapActiveMessage.prototype.isEventInScreen = function () {
|
||
if (isNullOrUndefined(this._event)) {
|
||
return false;
|
||
}
|
||
|
||
var x = this._event.screenX();
|
||
var y = this._event.screenY();
|
||
return x >= 0 && y >= 0 && x <= Graphics.boxWidth && y <= Graphics.boxHeight;
|
||
};
|
||
|
||
/**
|
||
* メッセージの表示開始
|
||
*
|
||
* @param {String} message 表示するメッセージ
|
||
* @param {Sprite_Character} sprite 表示対象のキャラクタースプライト
|
||
*/
|
||
Window_MapActiveMessage.prototype.display = function (message, sprite) {
|
||
if (isNullOrUndefined(message)) {
|
||
throw "'message' must not be null or undefined.";
|
||
}
|
||
|
||
// 表示のキャンセル
|
||
function rollback() {
|
||
this.initMembers();
|
||
this.hide();
|
||
}
|
||
|
||
if (message.messages.length <= 0 || isNullOrUndefined(message.event)) {
|
||
rollback.call(this);
|
||
return;
|
||
}
|
||
|
||
this._message = message;
|
||
this._event = message.event;
|
||
this._characterSprite = sprite;
|
||
|
||
if (!this.isEventInScreen()) {
|
||
rollback.call(this);
|
||
return;
|
||
}
|
||
|
||
this._targetPageIndex = this._event.pageIndex();
|
||
|
||
this.initializeMessage();
|
||
this.show();
|
||
|
||
this.printDebug("Display new message for event " + this._event.eventId() + ".");
|
||
|
||
// 多重表示抑止のため、表示済みフラグを立てる
|
||
this._event.setMapActiveMessageShown(true);
|
||
};
|
||
|
||
/**
|
||
* メッセージの初期化
|
||
*/
|
||
Window_MapActiveMessage.prototype.initializeMessage = function () {
|
||
this._pendingMessages = this._message.messages.slice();
|
||
|
||
this.displayNextMessage();
|
||
};
|
||
|
||
/**
|
||
* 次のメッセージを表示
|
||
*/
|
||
Window_MapActiveMessage.prototype.displayNextMessage = function () {
|
||
var message = this._pendingMessages.shift();
|
||
if (isNullOrUndefined(message)) {
|
||
return false;
|
||
}
|
||
|
||
this._textState = {
|
||
index: 0,
|
||
text: this.convertEscapeCharacters(message.text.replace(/_/g, " "))
|
||
};
|
||
this._allTextWidth = 0;
|
||
this._initialDisplayDuration = message.duration;
|
||
this._duration = this._initialDisplayDuration;
|
||
|
||
this.newPage(this._textState);
|
||
this.updatePosition();
|
||
this.updateOpacity();
|
||
this.refreshBalloon();
|
||
/// CBRここでテキスト入力
|
||
this.drawTextEx(this._textState.text, 10, 10, this._textState.width);
|
||
|
||
return true;
|
||
};
|
||
|
||
/**
|
||
* 新しいページの表示
|
||
*/
|
||
Window_MapActiveMessage.prototype.newPage = function (textState) {
|
||
// コンテンツを一時領域に書く
|
||
this.contents = Window_MapActiveMessage.tempMessageBuffer;
|
||
this.contents.clear();
|
||
this.resetFontSettings();
|
||
textState.x = this.newLineX();
|
||
textState.y = 0;
|
||
textState.left = this.newLineX();
|
||
textState.height = this.calcTextHeight(textState, false);
|
||
//CBR heightはここ
|
||
this.contents.fontSize = 22;
|
||
var lines = textState.text.split("\n");
|
||
this._allTextHeight = this.calcTextHeight(textState, false) * lines.length + 20;
|
||
|
||
textState.width = 0;
|
||
for (var i = 0; i < lines.length; i++) {
|
||
var w = this.textWidth(lines[i]);
|
||
if (w && textState.width < w) {
|
||
textState.width = w;
|
||
}
|
||
}
|
||
//this._allTextWidth = 598;
|
||
|
||
//textState.width = this.textWidth(textState.text)
|
||
|
||
this.updateMessage();
|
||
|
||
// コンテンツを一時領域から正式に反映
|
||
this.createContents();
|
||
this.contents.blt(
|
||
Window_MapActiveMessage.tempMessageBuffer,
|
||
0,
|
||
0,
|
||
this._allTextWidth,
|
||
this._allTextHeight,
|
||
0,
|
||
0,
|
||
this._allTextWidth,
|
||
this._allTextHeight
|
||
);
|
||
};
|
||
|
||
var Window_MapActiveMessage_update = Window_MapActiveMessage.prototype.update;
|
||
Window_MapActiveMessage.prototype.update = function () {
|
||
Window_MapActiveMessage_update.call(this);
|
||
this.CBR_t++;
|
||
};
|
||
/**
|
||
* メッセージの表示位置を設定
|
||
*/
|
||
Window_MapActiveMessage.prototype.updatePosition = function () {
|
||
if (isNullOrUndefined(this._event)) {
|
||
return;
|
||
}
|
||
|
||
// 画面外に出る場合は消去
|
||
if (!this.isEventInScreen()) {
|
||
this.hide();
|
||
return;
|
||
}
|
||
|
||
// 吹き出しの枠ぶんのマージン
|
||
var margin = Const.balloonFrameInfo.size - 24;
|
||
|
||
var balloonOffsetY = Const.balloonVertexSize.height - Params.balloonOffsetY - margin;
|
||
var heightOffset = this.height + (!isNullOrUndefined(this._characterSprite) ? this._characterSprite.patternHeight() : $gameMap.tileHeight());
|
||
|
||
// デフォルトの位置は上
|
||
var x = this._event.screenX() - this.width / 2;
|
||
var y = this._event.screenY() - (heightOffset + balloonOffsetY);
|
||
var beforePosit = this.getBalloonPosition();
|
||
this._balloonPosition = Const.balloonPosition.above;
|
||
|
||
// 画面左右にははみ出させない
|
||
//CBRまだよくわかんないから発生した時にやる
|
||
x = Math.min(Math.max(x, margin), Graphics.boxWidth - this.width - margin);
|
||
|
||
// 画面上側にはみ出る場合は下に表示
|
||
if (y < margin) {
|
||
y = this._event.screenY() + balloonOffsetY;
|
||
this._balloonPosition = Const.balloonPosition.below;
|
||
}
|
||
|
||
// 画面下側にはみ出る場合は上に表示
|
||
else if (y + this.height > Graphics.boxHeight - margin) {
|
||
y -= heightOffset + balloonOffsetY;
|
||
this._balloonPosition = Const.balloonPosition.above;
|
||
}
|
||
|
||
this.x = x;
|
||
this.y = y;
|
||
|
||
if (!isNullOrUndefined(this._balloonSprite)) {
|
||
// 吹き出しの頂点表示を考慮した位置に移動
|
||
this._balloonSprite.followOwner();
|
||
}
|
||
|
||
//##################### CBR、位置が違う場合は再描写
|
||
if (beforePosit != this._balloonPosition) {
|
||
this.refreshBalloon();
|
||
}
|
||
};
|
||
|
||
/**
|
||
* ウィンドウのサイズを更新
|
||
*/
|
||
Window_MapActiveMessage.prototype.updateWindowSize = function () {
|
||
var offset = $gameSystem.windowPadding() * 2;
|
||
this.width = this._allTextWidth + offset;
|
||
this.height = this._allTextHeight + offset;
|
||
};
|
||
|
||
/**
|
||
* 不透明度の更新
|
||
*/
|
||
Window_MapActiveMessage.prototype.updateOpacity = function () {
|
||
var opacity = 255;
|
||
if (this.isFadingIn()) {
|
||
// フェードイン
|
||
opacity = (255 * (this._initialDisplayDuration - this._duration)) / Params.fadeFrameCount;
|
||
} else if (this.isFadingOut()) {
|
||
// フェードアウト
|
||
opacity = (255 * this._duration) / Params.fadeFrameCount;
|
||
}
|
||
|
||
this.contentsOpacity = opacity;
|
||
if (!isNullOrUndefined(this._balloonSprite)) {
|
||
this._balloonSprite.opacity = opacity;
|
||
}
|
||
};
|
||
|
||
/**
|
||
* 吹き出しの再描画
|
||
*/
|
||
Window_MapActiveMessage.prototype.refreshBalloon = function () {
|
||
if (!isNullOrUndefined(this._balloonSprite)) {
|
||
this._balloonSprite.refresh();
|
||
}
|
||
};
|
||
|
||
/**
|
||
* プレイヤーと距離が離れていたら消去する
|
||
*
|
||
* @return {Boolean} true if hidden
|
||
*/
|
||
Window_MapActiveMessage.prototype.hideFarMessage = function () {
|
||
// 表示範囲外に出た場合は消す
|
||
var distance = $gamePlayer.calcDistanceForMapActiveMessage(this._event);
|
||
if (distance > this._event.getMapActiveMessageRange()) {
|
||
this.fadeOut();
|
||
return true;
|
||
}
|
||
|
||
return false;
|
||
};
|
||
|
||
/**
|
||
* プレイヤーとの距離を確認
|
||
*/
|
||
Window_MapActiveMessage.prototype.checkPlayerDistance = function () {
|
||
// 強制表示 or 消去中は距離判定しない
|
||
if (this.isForced() || this._duration <= Params.fadeFrameCount) {
|
||
return;
|
||
}
|
||
|
||
this.hideFarMessage();
|
||
};
|
||
|
||
Window_MapActiveMessage.prototype.update = function () {
|
||
Window_Base.prototype.update.call(this);
|
||
|
||
if (!isNullOrUndefined(this._balloonSprite)) {
|
||
this._balloonSprite.update();
|
||
}
|
||
|
||
if (!this.isDisplaying()) {
|
||
return;
|
||
}
|
||
|
||
this._duration--;
|
||
this.updateOpacity();
|
||
this.updatePosition();
|
||
this.checkPlayerDistance();
|
||
|
||
if (!this.isDisplaying()) {
|
||
if (this.displayNextMessage()) {
|
||
this.printDebug("Display next message.");
|
||
} else if (this.needsLoop() && !this.isHiding()) {
|
||
// 距離が離れていたらループしない
|
||
if (!this.hideFarMessage()) {
|
||
//this.printDebug('Loop message.');
|
||
//this.initializeMessage();
|
||
}
|
||
} else {
|
||
// 表示が終了したら初期化
|
||
this.printDebug("Finished to display.");
|
||
this.initMembers();
|
||
}
|
||
}
|
||
};
|
||
|
||
/**
|
||
* メッセージの更新
|
||
*/
|
||
Window_MapActiveMessage.prototype.updateMessage = function () {
|
||
if (isNullOrUndefined(this._textState)) {
|
||
return false;
|
||
}
|
||
|
||
while (!this.isEndOfText(this._textState)) {
|
||
this.processCharacter(this._textState);
|
||
//this._allTextWidth = Math.max(this._allTextWidth, this._textState.width+20);
|
||
if (this._textState.width) {
|
||
this._allTextWidth = this._textState.width + 20;
|
||
}
|
||
}
|
||
|
||
this.updateWindowSize();
|
||
|
||
return true;
|
||
};
|
||
|
||
/**
|
||
* 吹き出しの頂点位置を取得
|
||
*/
|
||
Window_MapActiveMessage.prototype.getBalloonVertexX = function () {
|
||
if (isNullOrUndefined(this._event)) {
|
||
return 0;
|
||
}
|
||
|
||
return this._event.screenX() - this.x - Const.balloonFrameInfo.size - Const.balloonVertexSize.width / 2 + Params.balloonMargin;
|
||
};
|
||
|
||
/**
|
||
* 改行時の描画先 X 座標
|
||
*/
|
||
Window_MapActiveMessage.prototype.newLineX = function () {
|
||
return 0;
|
||
};
|
||
|
||
/**
|
||
* 改行の処理
|
||
*/
|
||
Window_MapActiveMessage.prototype.processNewLine = function (textState) {
|
||
this._allTextWidth = Math.max(this._allTextWidth, textState.x);
|
||
|
||
Window_Base.prototype.processNewLine.call(this, textState);
|
||
};
|
||
|
||
/**
|
||
* 改ページの処理
|
||
*/
|
||
Window_MapActiveMessage.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_MapActiveMessage.prototype.isEndOfText = function (textState) {
|
||
return textState.index >= textState.text.length;
|
||
};
|
||
|
||
/**
|
||
* 改ページが必要か
|
||
*/
|
||
Window_MapActiveMessage.prototype.needsNewPage = function (textState) {
|
||
return !this.isEndOfText(textState) && textState.y + textState.height > this.contents.height;
|
||
};
|
||
|
||
//-----------------------------------------------------------------------------
|
||
// Scene_Map
|
||
|
||
var _Scene_Map_createAllWindows = Scene_Map.prototype.createAllWindows;
|
||
Scene_Map.prototype.createAllWindows = function () {
|
||
_Scene_Map_createAllWindows.call(this);
|
||
|
||
this.createActiveMessageWindow();
|
||
};
|
||
|
||
/**
|
||
* アクティブメッセージウィンドウの作成
|
||
*/
|
||
Scene_Map.prototype.createActiveMessageWindow = function () {
|
||
if (!isNullOrUndefined(this._activeMessageWindowLayer)) {
|
||
return;
|
||
}
|
||
|
||
var width = Graphics.boxWidth;
|
||
var height = Graphics.boxHeight;
|
||
var x = (Graphics.width - width) / 2;
|
||
var y = (Graphics.height - height) / 2;
|
||
this._activeMessageWindowLayer = new WindowLayer();
|
||
//this._activeMessageWindowLayer.x = x;
|
||
//this._activeMessageWindowLayer.y = y;
|
||
//this._activeMessageWindowLayer.width = width;
|
||
//this._activeMessageWindowLayer.height = height;
|
||
|
||
//this._activeMessageWindowLayer.move(x, y, width, height);
|
||
this.addChild(this._activeMessageWindowLayer);
|
||
|
||
Window_MapActiveMessage.preloadWindowskin();
|
||
};
|
||
|
||
var _Scene_Map_update = Scene_Map.prototype.update;
|
||
Scene_Map.prototype.update = function () {
|
||
_Scene_Map_update.call(this);
|
||
|
||
this.updateActiveMessageDisplay();
|
||
};
|
||
|
||
var _Scene_Map_stop = Scene_Map.prototype.stop;
|
||
Scene_Map.prototype.stop = function () {
|
||
_Scene_Map_stop.call(this);
|
||
|
||
$gameTemp.clearMapActiveMessage();
|
||
};
|
||
|
||
var _Scene_Map_terminate = Scene_Map.prototype.terminate;
|
||
Scene_Map.prototype.terminate = function () {
|
||
_Scene_Map_terminate.call(this);
|
||
|
||
this.destroyActiveMessageWindows();
|
||
};
|
||
|
||
/**
|
||
* アクティブメッセージウィンドウの破棄
|
||
*/
|
||
Scene_Map.prototype.destroyActiveMessageWindows = function () {
|
||
this._activeMessageWindowLayer.removeChildren();
|
||
this.removeChild(this._activeMessageWindowLayer);
|
||
this._activeMessageWindowLayer = null;
|
||
};
|
||
|
||
/**
|
||
* アクティブメッセージの表示を更新
|
||
*/
|
||
Scene_Map.prototype.updateActiveMessageDisplay = function () {
|
||
if (!$gameSystem.isMapActiveMessageEnabled() || $gameMap.isEventRunning()) {
|
||
// メッセージを表示できないときは非表示にしつつ各種フラグを解除
|
||
$gameTemp.clearMapActiveMessage();
|
||
$gameMap.clearActiveMessageShownFlags();
|
||
this._activeMessageWindowLayer.children.forEach(function (child) {
|
||
child.fadeOut();
|
||
});
|
||
return;
|
||
}
|
||
|
||
// 表示が完了したものを削除
|
||
this._activeMessageWindowLayer.children
|
||
.filter(function (child) {
|
||
return !child.isDisplaying();
|
||
})
|
||
.forEach(function (item) {
|
||
this._activeMessageWindowLayer.removeChild(item);
|
||
}, this);
|
||
|
||
// 要求されているメッセージを表示できるだけ表示
|
||
while ($gameTemp.isMapActiveMessageReady()) {
|
||
if (!this.displayActiveMessage()) {
|
||
break;
|
||
}
|
||
}
|
||
};
|
||
|
||
/**
|
||
* 指定されたイベントのアクティブメッセージが表示されているか判定
|
||
*/
|
||
Scene_Map.prototype.isActiveMessageDisplayed = function (event) {
|
||
var layer = this._activeMessageWindowLayer;
|
||
for (var i = 0; i < layer.children.length; i++) {
|
||
var window = layer.children[i];
|
||
if (window.isDisplaying() && window.isSameEvent(event)) {
|
||
return true;
|
||
}
|
||
}
|
||
|
||
return false;
|
||
};
|
||
|
||
/**
|
||
* アクティブメッセージの表示
|
||
*/
|
||
Scene_Map.prototype.displayActiveMessage = function () {
|
||
var layer = this._activeMessageWindowLayer;
|
||
|
||
// 最大数に達していたら表示を諦める
|
||
// (children には吹き出しも含まれるので / 2)
|
||
if (layer.children.length / 2 >= Params.messageCountMax) {
|
||
return false;
|
||
}
|
||
|
||
// 予約されているメッセージを表示
|
||
var message = $gameTemp.popNextMapActiveMessage();
|
||
while (!isNullOrUndefined(message)) {
|
||
// まだ表示していないもののみ表示
|
||
if (!this.isActiveMessageDisplayed(message.event)) {
|
||
var character = this._spriteset.findCharacterSpriteByEvent(message.event);
|
||
var balloon = new Sprite_MapActiveMessageBalloon();
|
||
|
||
const ww = Graphics.boxWidth;
|
||
const wh = this.calcWindowHeight(4, false) + 8;
|
||
const wx = (Graphics.boxWidth - ww) / 2;
|
||
const wy = 0;
|
||
const rect = new Rectangle(wx, wy, ww, wh);
|
||
|
||
var window = new Window_MapActiveMessage(rect);
|
||
window.setBalloonSprite(balloon);
|
||
window.display(message, character);
|
||
layer.addChild(window);
|
||
}
|
||
|
||
message = $gameTemp.popNextMapActiveMessage();
|
||
}
|
||
|
||
return true;
|
||
};
|
||
|
||
var _Scene_Map_snapForBattleBackground = Scene_Map.prototype.snapForBattleBackground;
|
||
Scene_Map.prototype.snapForBattleBackground = function () {
|
||
// アクティブメッセージはキャプチャしない
|
||
var layer = this._activeMessageWindowLayer;
|
||
if (!isNullOrUndefined(layer)) {
|
||
layer.visible = false;
|
||
}
|
||
|
||
_Scene_Map_snapForBattleBackground.call(this);
|
||
|
||
if (!isNullOrUndefined(layer)) {
|
||
layer.visible = true;
|
||
}
|
||
};
|
||
})();
|