/*: * @target MZ * @plugindesc Auto-scrolls help window text when it's too long to fit * @author GitHub Copilot * @url https://github.com/ * * @param scrollSpeed * @text Scroll Speed * @desc Speed of auto-scroll in pixels per frame (default: 0.5) * @type number * @decimals 2 * @default 0.5 * * @param pauseAtTop * @text Pause At Top * @desc Frames to pause when at top before scrolling (default: 90) * @type number * @default 90 * * @param pauseAtBottom * @text Pause At Bottom * @desc Frames to pause when scrolled to bottom (default: 90) * @type number * @default 90 * * @help AutoScrollHelpWindow.js * * This plugin automatically scrolls the help window text when it's too long * to fit in the window. This is particularly useful for passive skill * descriptions in the body history menu. * * No plugin commands needed - it works automatically! */ (() => { 'use strict'; const pluginName = 'AutoScrollHelpWindow'; const parameters = PluginManager.parameters(pluginName); const scrollSpeed = Number(parameters['scrollSpeed'] || 0.5); const pauseAtTop = Number(parameters['pauseAtTop'] || 90); const pauseAtBottom = Number(parameters['pauseAtBottom'] || 90); //----------------------------------------------------------------------------- // Window_Help //----------------------------------------------------------------------------- const _Window_Help_initialize = Window_Help.prototype.initialize; Window_Help.prototype.initialize = function(rect) { _Window_Help_initialize.call(this, rect); this._scrollData = { y: 0, timer: pauseAtTop, state: 'waiting', maxScroll: 0, enabled: false }; this._baseContentsHeight = this.contents.height; }; const _Window_Help_setText = Window_Help.prototype.setText; Window_Help.prototype.setText = function(text) { const changed = (this._text !== text); _Window_Help_setText.call(this, text); if (changed) { this._scrollData.y = 0; this._scrollData.timer = pauseAtTop; this._scrollData.state = 'waiting'; this.origin.y = 0; } }; // Call original refresh, then setup scrolling after const _Window_Help_refresh = Window_Help.prototype.refresh; Window_Help.prototype.refresh = function() { // Measure text first const textSize = this._text ? this.textSizeEx(this._text) : { width: 0, height: 0 }; const neededHeight = textSize.height + 16; // Ensure contents is big enough if (neededHeight > this.contents.height) { this.contents.resize(this.contents.width, neededHeight); } // Call original refresh (clears and draws) _Window_Help_refresh.call(this); // Setup scroll parameters const rect = this.baseTextRect(); this._scrollData.maxScroll = Math.max(0, textSize.height - rect.height); this._scrollData.enabled = this._scrollData.maxScroll > 2; }; const _Window_Help_update = Window_Help.prototype.update; Window_Help.prototype.update = function() { _Window_Help_update.call(this); this.updateAutoScroll(); }; Window_Help.prototype.updateAutoScroll = function() { const s = this._scrollData; if (!s || !s.enabled) { if (this.origin.y !== 0) this.origin.y = 0; return; } switch (s.state) { case 'waiting': if (--s.timer <= 0) s.state = 'down'; break; case 'down': s.y = Math.min(s.y + scrollSpeed, s.maxScroll); this.origin.y = Math.floor(s.y); if (s.y >= s.maxScroll) { s.state = 'paused'; s.timer = pauseAtBottom; } break; case 'paused': if (--s.timer <= 0) s.state = 'up'; break; case 'up': s.y = Math.max(s.y - scrollSpeed * 2, 0); this.origin.y = Math.floor(s.y); if (s.y <= 0) { s.state = 'waiting'; s.timer = pauseAtTop; } break; } }; })();