Source: Window_Base.js

Window_Base.js

//-----------------------------------------------------------------------------
// Window_Base
//
// The superclass of all windows within the game.
/**
 * The superclass of all windows within the game.
 *
 * @class
 * @extends Window
 */
function Window_Base() {
    this.initialize(...arguments);
}

Window_Base.prototype = Object.create(Window.prototype);
Window_Base.prototype.constructor = Window_Base;

Window_Base.prototype.initialize = function(rect) {
    Window.prototype.initialize.call(this);
    this.loadWindowskin();
    this.checkRectObject(rect);
    this.move(rect.x, rect.y, rect.width, rect.height);
    this.updatePadding();
    this.updateBackOpacity();
    this.updateTone();
    this.createContents();
    this._opening = false;
    this._closing = false;
    this._dimmerSprite = null;
};

Window_Base.prototype.destroy = function(options) {
    this.destroyContents();
    if (this._dimmerSprite) {
        this._dimmerSprite.bitmap.destroy();
    }
    Window.prototype.destroy.call(this, options);
};

/**
 * Checks if the given rect parameter is a valid {@link Rectangle}
 *
 * @param {*} rect - The object to check for validity
 * @return {boolean} True if the object is a valid rectangle
 * @throws Error if the object is not a valid rectangle
 */
Window_Base.prototype.checkRectObject = function(rect) {
    if (typeof rect !== "object" || !("x" in rect)) {
        // Probably MV plugin is used
        throw new Error("Argument must be a Rectangle");
    }
};

/**
 * Gets the height in pixels of one line
 *
 * @return {number} Height of a line
 */
Window_Base.prototype.lineHeight = function() {
    return 36;
};

/**
 * Gets the width in pixels of an item
 *
 * @return {number} Width of an item
 */
Window_Base.prototype.itemWidth = function() {
    return this.innerWidth;
};

/**
 * Gets the height in pixels of an item
 *
 * @return {number} Height of an item
 */
Window_Base.prototype.itemHeight = function() {
    return this.lineHeight();
};

/**
 * Gets the padding for an item
 *
 * @return {number} Amount of item padding
 */
Window_Base.prototype.itemPadding = function() {
    return 8;
};

/**
 * Creates a rectangle for an item of text
 *
 * @return {Rectangle} Rectangle that encompasses the text item
 */
Window_Base.prototype.baseTextRect = function() {
    const rect = new Rectangle(0, 0, this.innerWidth, this.innerHeight);
    rect.pad(-this.itemPadding(), 0);
    return rect;
};

/**
 * Loads the windowskin for the window
 */
Window_Base.prototype.loadWindowskin = function() {
    this.windowskin = ImageManager.loadSystem("Window");
};

/**
 * Updates the window's padding
 */
Window_Base.prototype.updatePadding = function() {
    this.padding = $gameSystem.windowPadding();
};

/**
 * Updates the window's background opacity
 */
Window_Base.prototype.updateBackOpacity = function() {
    this.backOpacity = $gameSystem.windowOpacity();
};

/**
 * Calculates the height needed for a given number of lines
 *
 * @param {number} numLines - The number of lines to calculate the height of
 * @return {number} The height needed to fit the amount of lines
 */
Window_Base.prototype.fittingHeight = function(numLines) {
    return numLines * this.itemHeight() + $gameSystem.windowPadding() * 2;
};

/**
 * Updates the window's tone
 */
Window_Base.prototype.updateTone = function() {
    const tone = $gameSystem.windowTone();
    this.setTone(tone[0], tone[1], tone[2]);
};

/**
 * Creates the contents of the window
 */
Window_Base.prototype.createContents = function() {
    const width = this.contentsWidth();
    const height = this.contentsHeight();
    this.destroyContents();
    this.contents = new Bitmap(width, height);
    this.contentsBack = new Bitmap(width, height);
    this.resetFontSettings();
};

/**
 * Destroys the contents of the window
 */
Window_Base.prototype.destroyContents = function() {
    if (this.contents) {
        this.contents.destroy();
    }
    if (this.contentsBack) {
        this.contentsBack.destroy();
    }
};

/**
 * Gets the width needed for the window contents
 *
 * @return {number} Width needed for the window contents
 */
Window_Base.prototype.contentsWidth = function() {
    return this.innerWidth;
};

/**
 * Gets the height needed for the window contents
 *
 * @return {number} Height needed for the window contents
 */
Window_Base.prototype.contentsHeight = function() {
    return this.innerHeight;
};

/**
 * Resets font settings to defaults
 */
Window_Base.prototype.resetFontSettings = function() {
    this.contents.fontFace = $gameSystem.mainFontFace();
    this.contents.fontSize = $gameSystem.mainFontSize();
    this.resetTextColor();
};

/**
 * Resets text and outline color to defaults
 */
Window_Base.prototype.resetTextColor = function() {
    this.changeTextColor(ColorManager.normalColor());
    this.changeOutlineColor(ColorManager.outlineColor());
};

Window_Base.prototype.update = function() {
    Window.prototype.update.call(this);
    this.updateTone();
    this.updateOpen();
    this.updateClose();
    this.updateBackgroundDimmer();
};

/**
 * Updates the opening effect
 */
Window_Base.prototype.updateOpen = function() {
    if (this._opening) {
        this.openness += 32;
        if (this.isOpen()) {
            this._opening = false;
        }
    }
};

/**
 * Updates the closing effect
 */
Window_Base.prototype.updateClose = function() {
    if (this._closing) {
        this.openness -= 32;
        if (this.isClosed()) {
            this._closing = false;
        }
    }
};

/**
 * Start opening the window
 */
Window_Base.prototype.open = function() {
    if (!this.isOpen()) {
        this._opening = true;
    }
    this._closing = false;
};

/**
 * Start closing the window
 */
Window_Base.prototype.close = function() {
    if (!this.isClosed()) {
        this._closing = true;
    }
    this._opening = false;
};

/**
 * Check if the window is opening
 *
 * @return {boolean} True if window is currently opening
 */
Window_Base.prototype.isOpening = function() {
    return this._opening;
};

/**
 * Check if the window is closing
 *
 * @return {boolean} True if window is currently closing
 */
Window_Base.prototype.isClosing = function() {
    return this._closing;
};

/**
 * Displays the window
 */
Window_Base.prototype.show = function() {
    this.visible = true;
};

/**
 * Stops displaying the window
 */
Window_Base.prototype.hide = function() {
    this.visible = false;
};

/**
 * Activates the window
 */
Window_Base.prototype.activate = function() {
    this.active = true;
};

/**
 * Deactivates the window
 */
Window_Base.prototype.deactivate = function() {
    this.active = false;
};

/**
 * Gets the system text color
 *
 * @return {string} The system text color
 */
Window_Base.prototype.systemColor = function() {
    return ColorManager.systemColor();
};

/**
 * Gets the opacity to use for a translucent effect
 *
 * @return {number} The opacity to use for a translucent effect
 */
Window_Base.prototype.translucentOpacity = function() {
    return 160;
};

/**
 * Changes the text color of text drawn to the window
 *
 * @param {string} color - The new color to draw text in
 */
Window_Base.prototype.changeTextColor = function(color) {
    this.contents.textColor = color;
};

/**
 * Changes the text outline color of text drawn to the window
 *
 * @param {string} color - The new outline color to use
 */
Window_Base.prototype.changeOutlineColor = function(color) {
    this.contents.outlineColor = color;
};

/**
 * Changes the opacity of what is painted to the contents of the window
 *
 * @param {boolean} enabled - True = use full opacity | False = use translucent opacity
 */
Window_Base.prototype.changePaintOpacity = function(enabled) {
    this.contents.paintOpacity = enabled ? 255 : this.translucentOpacity();
};

/**
 * Draws a rectangle of given width/height at given x/y coordinates
 *
 * @param {number} x - The X coordinate of the upper left corner of the rectangle
 * @param {number} y - The Y coordinate of the upper left corner of the rectangle
 * @param {number} width - The width in pixels of the rectangle
 * @param {number} height - The height in pixels of the rectangle
 */
Window_Base.prototype.drawRect = function(x, y, width, height) {
    const outlineColor = this.contents.outlineColor;
    const mainColor = this.contents.textColor;
    this.contents.fillRect(x, y, width, height, outlineColor);
    this.contents.fillRect(x + 1, y + 1, width - 2, height - 2, mainColor);
};

/**
 * Draws text to the window's contents. Does not support text codes in the text, but will fit the text within the maximum width without overflowing.
 *
 * @param {string} text - The text to draw
 * @param {number} x - The x coordinate to begin drawing the text
 * @param {number} y - The y coordinate to begin drawing the text
 * @param {number} maxWidth - The maximum width in pixels of the text
 * @param {string} align - The alignment of the text
 */
Window_Base.prototype.drawText = function(text, x, y, maxWidth, align) {
    this.contents.drawText(text, x, y, maxWidth, this.lineHeight(), align);
};

/**
 * Calculates the width needed for a given string of text. Does not support text codes.
 *
 * @param {string} text - The text to calculate the width for
 * @return {number} The width of the text
 */
Window_Base.prototype.textWidth = function(text) {
    return this.contents.measureTextWidth(text);
};

/**
 * Draws text to the window's contents. Does support text codes.
 *
 * @param {string} text - The text to draw
 * @param {number} x - The x coordinate to draw the text
 * @param {number} y - The y coordinate to draw the text
 * @param {number} width - The width of the text
 * @return {number} The width of the drawn text
 */
Window_Base.prototype.drawTextEx = function(text, x, y, width) {
    this.resetFontSettings();
    const textState = this.createTextState(text, x, y, width);
    this.processAllText(textState);
    return textState.outputWidth;
};

/**
 * Calculates the width needed for a given string of text. Does support text codes.
 *
 * @param {string} text - The text to calculate the width for
 * @return {{width: number, height: number}} The width and height of the text
 */
Window_Base.prototype.textSizeEx = function(text) {
    this.resetFontSettings();
    const textState = this.createTextState(text, 0, 0, 0);
    textState.drawing = false;
    this.processAllText(textState);
    return { width: textState.outputWidth, height: textState.outputHeight };
};

/**
 * Creates a text state object for drawing text with text codes
 *
 * @param {string} text - The text to draw
 * @param {number} x - The x coordinate to draw the text
 * @param {number} y - The y coordinate to draw the text
 * @param {number} width - The width of the text
 * @return {Object} The text state object
 */
Window_Base.prototype.createTextState = function(text, x, y, width) {
    const rtl = Utils.containsArabic(text);
    const textState = {};
    textState.text = this.convertEscapeCharacters(text);
    textState.index = 0;
    textState.x = rtl ? x + width : x;
    textState.y = y;
    textState.width = width;
    textState.height = this.calcTextHeight(textState);
    textState.startX = textState.x;
    textState.startY = textState.y;
    textState.rtl = rtl;
    textState.buffer = this.createTextBuffer(rtl);
    textState.drawing = true;
    textState.outputWidth = 0;
    textState.outputHeight = 0;
    return textState;
};

/**
 * Processes all text within a text state object
 *
 * @param {Object} textState - The text state to process
 */
Window_Base.prototype.processAllText = function(textState) {
    while (textState.index < textState.text.length) {
        this.processCharacter(textState);
    }
    this.flushTextState(textState);
};

/**
 * Flushes the text state
 *
 * @param {Object} textState - The text state to flush
 */
Window_Base.prototype.flushTextState = function(textState) {
    const text = textState.buffer;
    const rtl = textState.rtl;
    const width = this.textWidth(text);
    const height = textState.height;
    const x = rtl ? textState.x - width : textState.x;
    const y = textState.y;
    if (textState.drawing) {
        this.contents.drawText(text, x, y, width, height);
    }
    textState.x += rtl ? -width : width;
    textState.buffer = this.createTextBuffer(rtl);
    const outputWidth = Math.abs(textState.x - textState.startX);
    if (textState.outputWidth < outputWidth) {
        textState.outputWidth = outputWidth;
    }
    textState.outputHeight = y - textState.startY + height;
};

/**
 * Creates a text buffer
 *
 * @param {boolean} rtl - If the text is right to left (such as arabic text)
 * @return {string} The buffer for text embedding either right to left or left to right
 */
Window_Base.prototype.createTextBuffer = function(rtl) {
    // U+202B: RIGHT-TO-LEFT EMBEDDING
    return rtl ? "\u202B" : "";
};

/**
 * Converts escape code characters in text, for example \v[x]
 *
 * @param {string} text - The text to convert
 * @return {string} Text with escape characters converted
 */
Window_Base.prototype.convertEscapeCharacters = function(text) {
    /* eslint no-control-regex: 0 */
    text = text.replace(/\\/g, "\x1b");
    text = text.replace(/\x1b\x1b/g, "\\");
    while (text.match(/\x1bV\[(\d+)\]/gi)) {
        text = text.replace(/\x1bV\[(\d+)\]/gi, (_, p1) =>
            $gameVariables.value(parseInt(p1))
        );
    }
    text = text.replace(/\x1bN\[(\d+)\]/gi, (_, p1) =>
        this.actorName(parseInt(p1))
    );
    text = text.replace(/\x1bP\[(\d+)\]/gi, (_, p1) =>
        this.partyMemberName(parseInt(p1))
    );
    text = text.replace(/\x1bG/gi, TextManager.currencyUnit);
    return text;
};

/**
 * Gets an actor name from their id
 *
 * @param {number} n - Actor id
 * @return {string} The actor's name
 */
Window_Base.prototype.actorName = function(n) {
    const actor = n >= 1 ? $gameActors.actor(n) : null;
    return actor ? actor.name() : "";
};

/**
 * Gets an actor name from their position in the party
 *
 * @param {number} n - Position in the party
 * @return {string} The actor's name
 */
Window_Base.prototype.partyMemberName = function(n) {
    const actor = n >= 1 ? $gameParty.members()[n - 1] : null;
    return actor ? actor.name() : "";
};

/**
 * Processes a character in a text state at the current index of the text state
 *
 * @param {Object} textState - The text state object for processing a character
 */
Window_Base.prototype.processCharacter = function(textState) {
    const c = textState.text[textState.index++];
    if (c.charCodeAt(0) < 0x20) {
        this.flushTextState(textState);
        this.processControlCharacter(textState, c);
    } else {
        textState.buffer += c;
    }
};

/**
 * Processes a control character within a text state
 *
 * @param {Object} textState - The text state object with the character
 * @param {string} c - The character to process
 */
Window_Base.prototype.processControlCharacter = function(textState, c) {
    if (c === "\n") {
        this.processNewLine(textState);
    }
    if (c === "\x1b") {
        const code = this.obtainEscapeCode(textState);
        this.processEscapeCharacter(code, textState);
    }
};

/**
 * Processing for a new line
 *
 * @param {Object} textState - The text state object
 */
Window_Base.prototype.processNewLine = function(textState) {
    textState.x = textState.startX;
    textState.y += textState.height;
    textState.height = this.calcTextHeight(textState);
};

/**
 * Gets an escape code
 *
 * @param {Object} textState - The text state object
 * @return {string} The escape code, will be empty string if none
 */
Window_Base.prototype.obtainEscapeCode = function(textState) {
    const regExp = /^[$.|^!><{}\\]|^[A-Z]+/i;
    const arr = regExp.exec(textState.text.slice(textState.index));
    if (arr) {
        textState.index += arr[0].length;
        return arr[0].toUpperCase();
    } else {
        return "";
    }
};

/**
 * Gets an escape param
 *
 * @param {Object} textState - The text state object
 * @return {int|string} The escape param, will be empty string if none
 */
Window_Base.prototype.obtainEscapeParam = function(textState) {
    const regExp = /^\[\d+\]/;
    const arr = regExp.exec(textState.text.slice(textState.index));
    if (arr) {
        textState.index += arr[0].length;
        return parseInt(arr[0].slice(1));
    } else {
        return "";
    }
};

/**
 * Processes an escape character in a text state
 *
 * @param {string} code - The escape character's code
 * @param {Object} textState - The text state object
 */
Window_Base.prototype.processEscapeCharacter = function(code, textState) {
    switch (code) {
        case "C":
            this.processColorChange(this.obtainEscapeParam(textState));
            break;
        case "I":
            this.processDrawIcon(this.obtainEscapeParam(textState), textState);
            break;
        case "PX":
            textState.x = this.obtainEscapeParam(textState);
            break;
        case "PY":
            textState.y = this.obtainEscapeParam(textState);
            break;
        case "FS":
            this.contents.fontSize = this.obtainEscapeParam(textState);
            break;
        case "{":
            this.makeFontBigger();
            break;
        case "}":
            this.makeFontSmaller();
            break;
    }
};

/**
 * Processes a color change
 *
 * @param {number} colorIndex - The index of the color to change to
 */
Window_Base.prototype.processColorChange = function(colorIndex) {
    this.changeTextColor(ColorManager.textColor(colorIndex));
};

/**
 * Processes drawing an icon
 *
 * @param {number} iconIndex - The index of the icon to draw
 * @param {Object} textState - The text state object
 */
Window_Base.prototype.processDrawIcon = function(iconIndex, textState) {
    const deltaX = ImageManager.standardIconWidth - ImageManager.iconWidth;
    const deltaY = ImageManager.standardIconHeight - ImageManager.iconHeight;
    if (textState.drawing) {
        const x = textState.x + deltaX / 2 + 2;
        const y = textState.y + deltaY / 2 + 2;
        this.drawIcon(iconIndex, x, y);
    }
    textState.x += ImageManager.standardIconWidth + 4;
};

/**
 * Makes the font size bigger by 12
 */
Window_Base.prototype.makeFontBigger = function() {
    if (this.contents.fontSize <= 96) {
        this.contents.fontSize += 12;
    }
};

/**
 * Makes the font size smaller by 12
 */
Window_Base.prototype.makeFontSmaller = function() {
    if (this.contents.fontSize >= 24) {
        this.contents.fontSize -= 12;
    }
};

/**
 * Calculates the height of the text in a text state
 *
 * @param {Object} textState - The text state object
 * @return {string} The height of the text
 */
Window_Base.prototype.calcTextHeight = function(textState) {
    const lineSpacing = this.lineHeight() - $gameSystem.mainFontSize();
    const lastFontSize = this.contents.fontSize;
    const lines = textState.text.slice(textState.index).split("\n");
    const textHeight = this.maxFontSizeInLine(lines[0]) + lineSpacing;
    this.contents.fontSize = lastFontSize;
    return textHeight;
};

/**
 * Gets the max font size in a line of text
 *
 * @param {string} line - The line of text
 * @return {number} The largest font size seen in the line of text
 */
Window_Base.prototype.maxFontSizeInLine = function(line) {
    let maxFontSize = this.contents.fontSize;
    const regExp = /\x1b({|}|FS)(\[(\d+)])?/gi;
    for (;;) {
        const array = regExp.exec(line);
        if (!array) {
            break;
        }
        const code = String(array[1]).toUpperCase();
        if (code === "{") {
            this.makeFontBigger();
        } else if (code === "}") {
            this.makeFontSmaller();
        } else if (code === "FS") {
            this.contents.fontSize = parseInt(array[3]);
        }
        if (this.contents.fontSize > maxFontSize) {
            maxFontSize = this.contents.fontSize;
        }
    }
    return maxFontSize;
};

/**
 * Draws an icon at x/y coordinates
 *
 * @param {number} iconIndex - The index of the icon to draw
 * @param {number} x - The x coordinate
 * @param {number} y - The y coordinate
 */
Window_Base.prototype.drawIcon = function(iconIndex, x, y) {
    const bitmap = ImageManager.loadSystem("IconSet");
    const pw = ImageManager.iconWidth;
    const ph = ImageManager.iconHeight;
    const sx = (iconIndex % 16) * pw;
    const sy = Math.floor(iconIndex / 16) * ph;
    this.contents.blt(bitmap, sx, sy, pw, ph, x, y);
};

// prettier-ignore
/**
 * Draws a face at x/y coordinates with width/height
 *
 * @param {string} faceName - The name of the face sheet bitmap
 * @param {number} faceIndex - The index of the face on the sheet
 * @param {number} x - The x coordinate
 * @param {number} y - The y coordinate
 * @param {number} width - The width of the face
 * @param {number} height - The height of the face
 */
Window_Base.prototype.drawFace = function(
    faceName, faceIndex, x, y, width, height
) {
    width = width || ImageManager.standardFaceWidth;
    height = height || ImageManager.standardFaceHeight;
    const bitmap = ImageManager.loadFace(faceName);
    const pw = ImageManager.faceWidth;
    const ph = ImageManager.faceHeight;
    const sw = Math.min(width, pw);
    const sh = Math.min(height, ph);
    const dx = Math.floor(x + Math.max(width - pw, 0) / 2);
    const dy = Math.floor(y + Math.max(height - ph, 0) / 2);
    const sx = Math.floor((faceIndex % 4) * pw + (pw - sw) / 2);
    const sy = Math.floor(Math.floor(faceIndex / 4) * ph + (ph - sh) / 2);
    this.contents.blt(bitmap, sx, sy, sw, sh, dx, dy);
};

// prettier-ignore
/**
 * Draws a character at x/y coordinates
 *
 * @param {string} characterName - The name of the character sheet bitmap
 * @param {number} characterIndex - The index of the character on the sheet
 * @param {number} x - The x coordinate
 * @param {number} y - The y coordinate
 */
Window_Base.prototype.drawCharacter = function(
    characterName, characterIndex, x, y
) {
    const bitmap = ImageManager.loadCharacter(characterName);
    const big = ImageManager.isBigCharacter(characterName);
    const pw = bitmap.width / (big ? 3 : 12);
    const ph = bitmap.height / (big ? 4 : 8);
    const n = big ? 0: characterIndex;
    const sx = ((n % 4) * 3 + 1) * pw;
    const sy = Math.floor(n / 4) * 4 * ph;
    this.contents.blt(bitmap, sx, sy, pw, ph, x - pw / 2, y - ph);
};

/**
 * Draws an item's name with its icon
 *
 * @param {Object} item - The item object to draw, must at least have iconIndex and name properties
 * @param {number} x - The x coordinate
 * @param {number} y - The y coordinate
 * @param {number} width - The width available to draw the item name
 */
Window_Base.prototype.drawItemName = function(item, x, y, width) {
    if (item) {
        const iconY = y + (this.lineHeight() - ImageManager.iconHeight) / 2;
        const delta = ImageManager.standardIconWidth - ImageManager.iconWidth;
        const textMargin = ImageManager.standardIconWidth + 4;
        const itemWidth = Math.max(0, width - textMargin);
        this.resetTextColor();
        this.drawIcon(item.iconIndex, x + delta / 2, iconY);
        this.drawText(item.name, x + textMargin, y, itemWidth);
    }
};

/**
 * Draws a currency value
 *
 * @param {number} value - The amount of currency
 * @param {string} unit - The currency unit
 * @param {number} x - The x coordinate
 * @param {number} y - The y coordinate
 * @param {number} width - The width available to draw the item name
 */
Window_Base.prototype.drawCurrencyValue = function(value, unit, x, y, width) {
    const unitWidth = Math.min(80, this.textWidth(unit));
    this.resetTextColor();
    this.drawText(value, x, y, width - unitWidth - 6, "right");
    this.changeTextColor(ColorManager.systemColor());
    this.drawText(unit, x + width - unitWidth, y, unitWidth, "right");
};

/**
 * Sets the background type of the window
 *
 * @param {number} type - The type of background (0 = normal, 1 = dim, 2 = transparent)
 */
Window_Base.prototype.setBackgroundType = function(type) {
    if (type === 0) {
        this.opacity = 255;
    } else {
        this.opacity = 0;
    }
    if (type === 1) {
        this.showBackgroundDimmer();
    } else {
        this.hideBackgroundDimmer();
    }
};

/**
 * Shows the background dimmer sprite
 */
Window_Base.prototype.showBackgroundDimmer = function() {
    if (!this._dimmerSprite) {
        this.createDimmerSprite();
    }
    const bitmap = this._dimmerSprite.bitmap;
    if (bitmap.width !== this.width || bitmap.height !== this.height) {
        this.refreshDimmerBitmap();
    }
    this._dimmerSprite.visible = true;
    this.updateBackgroundDimmer();
};

/**
 * Creates the background dimmer sprite
 */
Window_Base.prototype.createDimmerSprite = function() {
    this._dimmerSprite = new Sprite();
    this._dimmerSprite.bitmap = new Bitmap(0, 0);
    this._dimmerSprite.x = -4;
    this.addChildToBack(this._dimmerSprite);
};

/**
 * Hides the background dimmer sprite
 */
Window_Base.prototype.hideBackgroundDimmer = function() {
    if (this._dimmerSprite) {
        this._dimmerSprite.visible = false;
    }
};

/**
 * Updates the background dimmer sprite
 */
Window_Base.prototype.updateBackgroundDimmer = function() {
    if (this._dimmerSprite) {
        this._dimmerSprite.opacity = this.openness;
    }
};

/**
 * Refreshes the background dimmer sprite
 */
Window_Base.prototype.refreshDimmerBitmap = function() {
    if (this._dimmerSprite) {
        const bitmap = this._dimmerSprite.bitmap;
        const w = this.width > 0 ? this.width + 8 : 0;
        const h = this.height;
        const m = this.padding;
        const c1 = ColorManager.dimColor1();
        const c2 = ColorManager.dimColor2();
        bitmap.resize(w, h);
        bitmap.gradientFillRect(0, 0, w, m, c2, c1, true);
        bitmap.fillRect(0, m, w, h - m * 2, c1);
        bitmap.gradientFillRect(0, h - m, w, m, c1, c2, true);
        this._dimmerSprite.setFrame(0, 0, w, h);
    }
};

/**
 * Plays the cursor sound effect
 */
Window_Base.prototype.playCursorSound = function() {
    SoundManager.playCursor();
};

/**
 * Plays the ok sound effect
 */
Window_Base.prototype.playOkSound = function() {
    SoundManager.playOk();
};

/**
 * Plays the buzzer sound effect
 */
Window_Base.prototype.playBuzzerSound = function() {
    SoundManager.playBuzzer();
};