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

333 lines
9.8 KiB
JavaScript

/*:
* @target MZ
* @plugindesc 隣接時メッセージ表示
* @url https://twitter.com/kuroudo119/
* @url https://github.com/kuroudo119/RPGMZ-Plugin
* @author kuroudo119 (くろうど)
* @base DTextPicture
* @base KRD_MZ_NeighborBalloon
*
* @param MESSAGE_COUNT
* @text メッセージカウント
* @desc メッセージを消去するまでのカウントです。1秒60カウント。初期値:100
* @default 100
* @type number
*
* @param USE_LENGTH
* @text 文字数カウント
* @desc メッセージを消去するまでのカウントに文字数を追加します。1文字あたりのカウントです。初期値:5
* @default 5
* @type number
*
* @param FONT_SIZE
* @text フォントサイズ
* @desc フォントサイズを変更したい場合に設定します。初期値:0
* @default 0
* @type number
*
* @param MINUS_Y
* @text Y座標補正値
* @desc ウィンドウの表示位置を上に移動する固定値です。初期値:18
* @default 18
* @type number
*
* @command doDTextPicture
* @text イベントメッセージ表示
* @desc イベントにメッセージを表示します。自動消去あり。
* @arg text
* @text メッセージ
* @desc 表示するメッセージです。
* @type multiline_string
*
* @help
# KRD_MZ_NeighborMessage.js
隣接時メッセージ表示
## 権利表記
(c) 2021 kuroudo119 (くろうど)
## 利用規約
このプラグインはMITライセンスです。
https://github.com/kuroudo119/RPGMZ-Plugin/blob/master/LICENSE
## 必要プラグイン
以下のプラグインが必要です。
DTextPicture
KRD_MZ_NeighborBalloon
## 使い方
イベントのメモ欄に msgText, msgZone の2つのタグを書きます。
イベントのメモ欄が狭いことに注意してください。
### msgText
<msgText:"テキスト","テキスト2">
表示する文章をクォーテーション(' または ")で囲んで記述します。
複数ページある場合はカンマ区切りで記述します。
改行したい場合は \n を記述します。
### msgZone
<msgZone:2,1>
メッセージを表示するプレイヤーとイベントの距離を記述します。
複数ページある場合はカンマ区切りで記述します。
省略すると 1 になります。
## プラグインコマンド
### イベントメッセージ表示 (doDTextPicture)
プラグインコマンド実行のタイミングで、
イベントにメッセージを表示します。
タグと同様に自動で消去します。
宝箱の中身を表示する等を想定しています。
## 制約事項
本プラグインでは、動的文字列ピクチャ生成プラグインを利用しています。
そのため、動的文字列ピクチャ生成プラグインの設定に影響します。
本プラグインでは、設定のウィンドウを true にします。
## 更新履歴
- ver.0.0.1 (2024/03/24) 作成開始
- ver.0.1.0 (2024/03/24) 非公開版完成
- ver.1.0.0 (2024/03/24) 公開
- ver.1.0.1 (2024/03/24) ピクチャIDの修正
- ver.1.0.2 (2024/03/25) ヘルプに制約事項を追記
- ver.1.1.0 (2024/03/26) 内部処理を修正
- ver.1.1.1 (2024/03/26) 既存セーブデータに対応
- ver.2.0.0 (2024/03/29) プラグインパラメータなど大きな変更
- ver.2.1.0 (2024/03/31) イベントにメッセージ表示を追加
- ver.2.1.1 (2024/04/11) 隣接時フキダシ表示への競合を修正
- ver.2.2.0 (2024/11/14) プラグインコマンドの複数回実行に対応
- ver.2.2.1 (2024/12/02) 出るかもしれないエラー対応
- ver.2.2.2 (2024/12/16) eraseAllMessage を修正
*
*
*/
(() => {
"use strict";
const PLUGIN_NAME = document.currentScript.src.match(/^.*\/(.*).js$/)[1];
const PARAM = PluginManager.parameters(PLUGIN_NAME);
const MESSAGE_COUNT = Number(PARAM["MESSAGE_COUNT"]) || 0;
const USE_LENGTH = Number(PARAM["USE_LENGTH"]) || 0;
const FONT_SIZE = Number(PARAM["FONT_SIZE"]) || 0;
const MINUS_Y = Number(PARAM["MINUS_Y"]) || 0;
const ADD_PICTURE_ID = 20;
const TAG_TEXT = "msgText";
const TAG_ZONE = "msgZone";
const NAME = "";
const ORIGIN = 1;
const SCALE_X = 100;
const SCALE_Y = 100;
const OPACITY = 255;
const BLEND_MODE = 0;
const DURATION = 1;
const EASING_TYPE = 0;
const D_TEXT_SETTING = {window: true};
//--------------------------------------
PluginManager.registerCommand(PLUGIN_NAME, "doDTextPicture", function(args) {
this.doDTextPicture(args.text);
});
//--------------------------------------
const _Game_Event_updateStop = Game_Event.prototype.updateStop;
Game_Event.prototype.updateStop = function() {
_Game_Event_updateStop.call(this, ...arguments);
this.doNeighborMessage();
};
Game_Event.prototype.doNeighborMessage = function() {
if (this._pageIndex < 0) {
return;
}
const tagText = this.event().meta[TAG_TEXT];
const tagZone = this.event().meta[TAG_ZONE];
const textPage = tagText ? JSON.parse("[" + tagText + "]") : null;
const zonePage = tagZone ? JSON.parse("[" + tagZone + "]") : null;
const text = textPage ? textPage[this._pageIndex] : "";
const zone = zonePage ? parseInt(zonePage[this._pageIndex]) : 1;
this.doMessage(text, zone);
};
Game_Event.prototype.doMessage = function(text, zone = 1) {
this._oldPositionMsg = this._oldPositionMsg ? this._oldPositionMsg : false;
const newPosition = this.playerIsInZone(zone);
if (text && this._msgPictureId == null && newPosition && this._oldPositionMsg !== newPosition) {
this.doDTextPicture(text);
}
this._oldPositionMsg = newPosition;
};
Game_Event.prototype.doDTextPicture = function(text) {
const convText = Window_Base.prototype.convertEscapeCharacters(text);
const cutRubyText = cutRuby(convText);
const plusCount = cutRubyText.toString().length * USE_LENGTH;
const minusY = this.minusY(cutRubyText);
// DTextPicture プラグインの設定をする。
$gameScreen.setDTextPicture(convText, FONT_SIZE);
$gameScreen.setDtextSetting(D_TEXT_SETTING);
const msgPicture = {
pictureId: $gameScreen.getMsgPictureId(),
pictureCount: MESSAGE_COUNT + plusCount,
x: this.screenX(),
minusY: minusY,
y: this.screenY() - minusY,
};
this._msgPictureList = this._msgPictureList ? this._msgPictureList : [];
this._msgPictureList.push(msgPicture);
$gameScreen.showPicture(msgPicture.pictureId, NAME, ORIGIN, msgPicture.x, msgPicture.y, SCALE_X, SCALE_Y, OPACITY, BLEND_MODE);
};
Game_Event.prototype.minusY = function(text) {
const line = text.toString().split("\n").length;
const fontSize = FONT_SIZE || $gameSystem.mainFontSize();
const msgheight = line * fontSize;
const sprites = SceneManager._scene._spriteset._characterSprites;
// 同じ _characterName が複数ある場合に、最初のものを取得するが、
// 同じ画像なので、同じ height であるはず。
const sprite = sprites.find(sprite => sprite._characterName === this._characterName);
const eventHeight = sprite._frame.height;
return eventHeight + msgheight + MINUS_Y;
};
function cutRuby(text) {
return typeof KRD_RUBY !== "undefined" ? KRD_RUBY.cutRuby(text) : text;
}
Game_Event.prototype.moveMessage = function(msgPicture) {
if (msgPicture) {
const x = this.screenX();
const y = this.screenY() - msgPicture.minusY;
$gameScreen.movePicture(msgPicture.pictureId, ORIGIN, x, y, SCALE_X, SCALE_Y, OPACITY, BLEND_MODE, DURATION, EASING_TYPE);
}
};
Game_Event.prototype.eraseMessage = function(msgPicture) {
if (msgPicture) {
$gameScreen.erasePicture(msgPicture.pictureId);
$gameScreen.setMsgPictureId(msgPicture.pictureId);
msgPicture.pictureId = null;
}
};
const _Game_Event_update = Game_Event.prototype.update;
Game_Event.prototype.update = function() {
_Game_Event_update.call(this, ...arguments);
this.updatePictureCountAll();
};
Game_Event.prototype.updatePictureCountAll = function() {
if (this._msgPictureList) {
for (const msgPicture of this._msgPictureList) {
this.updatePictureCount(msgPicture);
}
this._msgPictureList = this._msgPictureList.filter(msgPicture => msgPicture.pictureCount != null);
}
};
Game_Event.prototype.updatePictureCount = function(msgPicture) {
if (msgPicture.pictureCount != null) {
if (msgPicture.pictureCount > 0) {
this.moveMessage(msgPicture);
msgPicture.pictureCount--;
} else if (msgPicture.pictureCount <= 0) {
this.eraseMessage(msgPicture);
msgPicture.pictureCount = null;
}
}
};
//--------------------------------------
const _Game_Screen_clear = Game_Screen.prototype.clear;
Game_Screen.prototype.clear = function() {
_Game_Screen_clear.call(this, ...arguments);
this.initMsgPictureIdList();
};
Game_Screen.prototype.initMsgPictureIdList = function() {
const maxId = this.maxPictures();
this._msgPictureIdList = [];
this._msgPictureIdListMaster = [];
for (let i = 0; i < ADD_PICTURE_ID; i++) {
this._msgPictureIdList.push(maxId - i);
this._msgPictureIdListMaster.push(maxId - i);
}
};
Game_Screen.prototype.getMsgPictureId = function() {
if (!this._msgPictureIdList) {
this.initMsgPictureIdList();
}
return this._msgPictureIdList.pop();
};
Game_Screen.prototype.setMsgPictureId = function(id) {
if (id != null) {
this._msgPictureIdList.push(id);
}
};
const _Game_Screen_maxPictures = Game_Screen.prototype.maxPictures;
Game_Screen.prototype.maxPictures = function() {
return _Game_Screen_maxPictures.call(this, ...arguments) + ADD_PICTURE_ID;
};
//--------------------------------------
Game_Map.prototype.eraseAllMessage = function() {
$gameScreen._msgPictureIdListMaster.forEach(pid => $gameScreen.erasePicture(pid));
};
const _Scene_Map_terminate = Scene_Map.prototype.terminate;
Scene_Map.prototype.terminate = function() {
$gameMap.eraseAllMessage();
_Scene_Map_terminate.call(this, ...arguments);
};
//--------------------------------------
// イベントにピクチャ付与
Game_Interpreter.prototype.doDTextPicture = function(text) {
const event = this.character();
if (event) {
event.doDTextPicture(text);
}
};
//--------------------------------------
})();