250 lines
No EOL
9 KiB
JavaScript
250 lines
No EOL
9 KiB
JavaScript
//=============================================================================
|
|
// MogBattleHud_StateTooltip.js
|
|
//=============================================================================
|
|
//
|
|
//=============================================================================
|
|
// Copyright (c) 2024 Your Name
|
|
// Released under the MIT license.
|
|
// http://opensource.org/licenses/mit-license.php
|
|
//=============================================================================
|
|
|
|
/*:
|
|
* @target MZ
|
|
* @plugindesc MOG_BattleHudのステートアイコンにマウスオーバーで説明を表示します。
|
|
* @author Your Name
|
|
* @version 1.0.0
|
|
*
|
|
* @param list
|
|
* @text アイコン説明リスト
|
|
* @desc アイコンと説明文を紐づけるリストです。
|
|
* @default []
|
|
* @type struct<Description>[]
|
|
*
|
|
* @param hoverDelay
|
|
* @text ホバー遅延
|
|
* @desc マウスを重ねてから説明が表示されるまでの時間(フレーム数)。
|
|
* @default 30
|
|
* @type number
|
|
*
|
|
* @param fontSize
|
|
* @text フォントサイズ
|
|
* @desc 説明ウィンドウのフォントサイズです。0でデフォルトサイズ。
|
|
* @default 22
|
|
* @type number
|
|
*
|
|
* @param padding
|
|
* @text 余白
|
|
* @desc 説明ウィンドウの余白です。0でデフォルトの余白。
|
|
* @default 8
|
|
* @type number
|
|
*
|
|
* @param backOpacity
|
|
* @text 背景不透明度
|
|
* @desc 説明ウィンドウの背景不透明度です。0でデフォルト値。255で完全不透明。
|
|
* @default 224
|
|
* @type number
|
|
*
|
|
* @help
|
|
* このプラグインは、MOG_BattleHud.jsと連携して、戦闘中の
|
|
* ステートアイコンにマウスカーソルを合わせると、ツールチップで
|
|
* 説明を表示する機能を提供します。
|
|
*
|
|
* 【重要】
|
|
* ・このプラグインは「MOG_BattleHud.js」より下に配置してください。
|
|
* ・「IconDescription.js」は不要です。
|
|
*
|
|
* 【設定】
|
|
* プラグインパラメータの「アイコン説明リスト」に、対象のアイコンと
|
|
* 表示したい説明文を登録してください。
|
|
*/
|
|
|
|
/*~struct~Description:
|
|
* @param iconIndex
|
|
* @text アイコン
|
|
* @desc 説明を表示するアイコンのインデックスです。
|
|
* @default 1
|
|
* @type icon
|
|
*
|
|
* @param caption
|
|
* @text 説明テキスト
|
|
* @desc アイコンの説明文です。制御文字が使えます。
|
|
* @default
|
|
* @type multiline_string
|
|
*/
|
|
|
|
(() => {
|
|
'use strict';
|
|
|
|
const pluginName = 'MogBattleHud_StateTooltip';
|
|
const params = PluginManager.parameters(pluginName);
|
|
const paramList = JSON.parse(params.list || '[]').map(JSON.parse);
|
|
const paramHoverDelay = Number(params.hoverDelay) || 30;
|
|
const paramFontSize = Number(params.fontSize) || 22;
|
|
const paramPadding = Number(params.padding) || 8;
|
|
const paramBackOpacity = Number(params.backOpacity) || 224;
|
|
|
|
function findIconCaptionParam(iconIndex) {
|
|
return paramList.find(desc => Number(desc.iconIndex) === iconIndex);
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Window_StateTooltip
|
|
//
|
|
// 説明文を表示するためのウィンドウです。
|
|
|
|
class Window_StateTooltip extends Window_Base {
|
|
constructor(iconIndex, x, y) {
|
|
super(new Rectangle(x, y + ImageManager.iconHeight, 1, 1));
|
|
this._iconIndex = iconIndex;
|
|
this.setup();
|
|
this.updatePlacement(x, y);
|
|
this.update(); // Force a single update to ensure visibility
|
|
}
|
|
|
|
setup() {
|
|
const item = findIconCaptionParam(this._iconIndex);
|
|
if (!item) return;
|
|
|
|
const text = item.caption;
|
|
const rect = this.textSizeEx(text);
|
|
this.updatePadding();
|
|
this.width = rect.width + this.padding * 2;
|
|
this.height = rect.height + this.padding * 2;
|
|
this.createContents();
|
|
this.drawTextEx(text, 0, 0);
|
|
}
|
|
|
|
updatePlacement(x, y) {
|
|
this.x = x;
|
|
this.y = y + ImageManager.iconHeight;
|
|
|
|
if (this.y + this.height > Graphics.height) {
|
|
this.y = y - this.height;
|
|
}
|
|
if (this.x + this.width > Graphics.width) {
|
|
this.x = Math.max(0, Graphics.width - this.width);
|
|
}
|
|
}
|
|
|
|
resetFontSettings() {
|
|
super.resetFontSettings();
|
|
if (paramFontSize > 0) {
|
|
this.contents.fontSize = paramFontSize;
|
|
}
|
|
}
|
|
|
|
updatePadding() {
|
|
this.padding = paramPadding > 0 ? paramPadding : this.defaultPadding();
|
|
}
|
|
|
|
updateBackOpacity() {
|
|
this.backOpacity = paramBackOpacity;
|
|
}
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// SceneManager
|
|
//
|
|
// ツールチップウィンドウを管理します。
|
|
|
|
SceneManager._stateTooltipWindow = null;
|
|
|
|
SceneManager.showStateTooltip = function(iconIndex, x, y) {
|
|
if (this._stateTooltipWindow && this._stateTooltipWindow._iconIndex === iconIndex) {
|
|
return;
|
|
}
|
|
this.hideStateTooltip();
|
|
if (findIconCaptionParam(iconIndex)) {
|
|
this._stateTooltipWindow = new Window_StateTooltip(iconIndex, x, y);
|
|
this._scene.addChild(this._stateTooltipWindow);
|
|
}
|
|
};
|
|
|
|
SceneManager.hideStateTooltip = function() {
|
|
if (this._stateTooltipWindow) {
|
|
this._scene.removeChild(this._stateTooltipWindow);
|
|
this._stateTooltipWindow = null;
|
|
}
|
|
};
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Battle_Hud (MOG_BattleHud.js) の機能を拡張
|
|
//
|
|
if (typeof Battle_Hud !== 'undefined') {
|
|
|
|
const _Battle_Hud_initialize = Battle_Hud.prototype.initialize;
|
|
Battle_Hud.prototype.initialize = function(hud_id) {
|
|
_Battle_Hud_initialize.apply(this, arguments);
|
|
this._hoveredIconSprite = null;
|
|
this._hoverCount = 0;
|
|
};
|
|
|
|
const _Battle_Hud_refresh_states = Battle_Hud.prototype.refresh_states;
|
|
Battle_Hud.prototype.refresh_states = function() {
|
|
_Battle_Hud_refresh_states.apply(this, arguments);
|
|
if (this._state_icon) {
|
|
this._state_icon.iconIndex = this._states_data[0];
|
|
}
|
|
};
|
|
|
|
const _Battle_Hud_refresh_states2 = Battle_Hud.prototype.refresh_states2;
|
|
Battle_Hud.prototype.refresh_states2 = function() {
|
|
_Battle_Hud_refresh_states2.apply(this, arguments);
|
|
const icons = this._battler.allIcons();
|
|
if (this._stateIcons) {
|
|
for (let i = 0; i < this._stateIcons.length; i++) {
|
|
if (this._stateIcons[i] && icons[i]) {
|
|
this._stateIcons[i].iconIndex = icons[i];
|
|
}
|
|
}
|
|
}
|
|
};
|
|
|
|
const _Battle_Hud_update = Battle_Hud.prototype.update;
|
|
Battle_Hud.prototype.update = function() {
|
|
_Battle_Hud_update.apply(this, arguments);
|
|
if (this.visible) {
|
|
this.updateStateTooltip();
|
|
}
|
|
};
|
|
|
|
Battle_Hud.prototype.getHoveredIconSprite = function() {
|
|
const touchPos = new Point(TouchInput.x, TouchInput.y);
|
|
const checkSprite = (sprite) => {
|
|
if (!sprite || !sprite.visible || !findIconCaptionParam(sprite.iconIndex)) {
|
|
return false;
|
|
}
|
|
const localPos = sprite.worldTransform.applyInverse(touchPos);
|
|
const rect = new Rectangle(0, 0, sprite.width, sprite.height);
|
|
return rect.contains(localPos.x, localPos.y);
|
|
};
|
|
|
|
if (this._stateType === 0 && this._state_icon) {
|
|
if (checkSprite(this._state_icon)) return this._state_icon;
|
|
} else if (this._stateType === 1 && this._stateIcons) {
|
|
for (const iconSprite of this._stateIcons) {
|
|
if (checkSprite(iconSprite)) return iconSprite;
|
|
}
|
|
}
|
|
return null;
|
|
};
|
|
|
|
Battle_Hud.prototype.updateStateTooltip = function() {
|
|
const currentlyHovered = this.getHoveredIconSprite();
|
|
|
|
if (this._hoveredIconSprite === currentlyHovered) {
|
|
if (currentlyHovered) {
|
|
this._hoverCount++;
|
|
if (this._hoverCount >= paramHoverDelay) {
|
|
const worldPos = currentlyHovered.worldTransform.apply(new Point(0, 0));
|
|
SceneManager.showStateTooltip(currentlyHovered.iconIndex, worldPos.x, worldPos.y);
|
|
}
|
|
}
|
|
} else {
|
|
this._hoveredIconSprite = currentlyHovered;
|
|
this._hoverCount = 0;
|
|
SceneManager.hideStateTooltip();
|
|
}
|
|
};
|
|
}
|
|
})(); |