'use strict'; /*: @plugindesc Display enemy actions in combat @help This works with turn based battle systems where enemy actions are selected at the start of the turn. The X and Y adjustments may be helpful to get out of the way of other plugins that draw things above the heads of enemy sprites. Note tags: On an enemy, use the telepathy note tag to turn action display on or off. The value is evaluated and actions are displayed if it returns a true value. <telepathy:true> - display actions for this enemy <telepathy:false> - do not display actions for this enemy <telepathy:$gameSwitches.switch(1)> - display only if switch 1 is on 1.0: original release 2.0: configurable screen border for Luna MV compatibility documented dependency on YEP_BattleEngineCore 3.0: Rewritten to depend only on core scripts. Added window background option Added dynamic positioning to avoid state icons only when needed @author Coelocanth @param FontSize @desc Font size to use for displaying enemy action @type Number @default 24 @param X @desc Horizontal offset for the action display @type Number @default 0 @param Y @desc Vertical offset for the action display @type Number @default 0 @param StateAdjustX @desc Horizontal offset when afflicted by states with icons @type Number @default 0 @param StateAdjustY @desc Vertical offset when afflicted by states with icons @type Number @default -32 @param ShowDefault @desc Should enemy actions be shown by default? @type boolean @default true @param ShowState @desc Show enemy action if affected by this state @type Number @default 0 @param HideState @desc Hide enemy action if affected by this state @type Number @default 0 @param ScreenBorderLeft @desc Do not draw left of this point, to avoid collision with HUD elements @type Number @default 0 @param ScreenBorderRight @desc Do not draw right of this point, to avoid collision with HUD elements @type Number @default 0 @param ScreenBorderTop @desc Do not draw above of this point, to avoid collision with HUD elements @type Number @default 0 @param ScreenBorderBottom @desc Do not draw below of this point, to avoid collision with HUD elements @type Number @default 0 @param WindowBackground @desc Type of background for enemy action window, like "show text" command The "dim" option may be helpful if text is hard to read on light battle backs @type select @option transparent @option dim @option visible @default transparent */ var Imported = Imported || {}; Imported.CC_Telepathy = true; var CC_Telepathy = { params: PluginManager.parameters('CC_Telepathy') } CC_Telepathy.params.FontSize = Number(CC_Telepathy.params.FontSize); CC_Telepathy.params.X = Number(CC_Telepathy.params.X); CC_Telepathy.params.Y = Number(CC_Telepathy.params.Y); CC_Telepathy.params.StateAdjustX = Number(CC_Telepathy.params.StateAdjustX); CC_Telepathy.params.StateAdjustY = Number(CC_Telepathy.params.StateAdjustY); CC_Telepathy.params.ShowDefault = eval(CC_Telepathy.params.ShowDefault); CC_Telepathy.params.ShowState = Number(CC_Telepathy.params.ShowState); CC_Telepathy.params.HideState = Number(CC_Telepathy.params.HideState); CC_Telepathy.params.ScreenBorderLeft = Number(CC_Telepathy.params.ScreenBorderLeft); CC_Telepathy.params.ScreenBorderRight = Number(CC_Telepathy.params.ScreenBorderRight); CC_Telepathy.params.ScreenBorderTop = Number(CC_Telepathy.params.ScreenBorderTop); CC_Telepathy.params.ScreenBorderBottom = Number(CC_Telepathy.params.ScreenBorderBottom); if(CC_Telepathy.params.WindowBackground == 'visible') { CC_Telepathy.params.WindowBackgroundType = 0; } else if(CC_Telepathy.params.WindowBackground == 'dim') { CC_Telepathy.params.WindowBackgroundType = 1; } else { CC_Telepathy.params.WindowBackgroundType = 2; } (function() { // Window_Telepathy observes a battler and displays its next action function Window_Telepathy() { this.initialize.apply(this, arguments); } Window_Telepathy.prototype = Object.create(Window_Base.prototype); Window_Telepathy.prototype.constructor = Window_Telepathy; Window_Telepathy.prototype.initialize = function(sprite, battler) { Window_Base.prototype.initialize.call(this, 0,0,0,0); this._sprite = sprite; this.setBattler(battler); } Window_Telepathy.prototype.setBattler = function(battler) { this._battler = battler; this._icon = 0; this._text = ""; this.update(); } Window_Telepathy.prototype.update = function() { Window_Base.prototype.update.call(this); this.updateParent(); this.updateContents(); this.updatePosition(); this.updateOpacity(); } Window_Telepathy.prototype.updateParent = function() { // Reparent to the scene as soon as it's set if(this._sprite && this._sprite.parent && this.parent !== this._sprite.parent) { this._sprite.removeChild(this); this._sprite.parent.addChild(this); this.calculateBoundingBox(); } } Window_Telepathy.prototype.updateContents = function() { if(!this._battler) return; let action = this._battler.numActions() ? this._battler.action(0) : null; var icon = 0; var text = ""; if(action) { let dbitem = action.item(); icon = dbitem.iconIndex; text = dbitem.name; } if(icon == this._icon && text == this._text) return; // action has changed, need to redraw this._icon = icon; this._text = text; this.width = this.fittingWidth(text); this.height = this.fittingHeight(1); this.createContents(); this.contents.fontSize = CC_Telepathy.params.FontSize; this.setBackgroundType(CC_Telepathy.params.WindowBackgroundType); this.drawIcon(icon, 0, 2); this.drawText(text, Window_Base._iconWidth + 4, 0); this.calculateBoundingBox(); } Window_Telepathy.prototype.calculateBoundingBox = function() { this._minX = -1 * this.standardPadding(); this._maxX = Graphics.boxWidth - this.width + this.standardPadding(); this._minY = -1 * this.standardPadding(); this._maxY = Graphics.boxHeight - this.height + this.standardPadding(); this._minY += CC_Telepathy.params.ScreenBorderTop; this._maxY -= CC_Telepathy.params.ScreenBorderBottom; this._minX += CC_Telepathy.params.ScreenBorderLeft; this._maxX -= CC_Telepathy.params.ScreenBorderRight; } // icon + text + padding Window_Telepathy.prototype.fittingWidth = function(text) { return this.textWidth(text) + this.standardPadding() * 2 + Window_Base._iconWidth + 4; } Window_Telepathy.prototype.updatePosition = function() { if(!this._sprite) return; var x = this._sprite.x - this.width / 2; var y = this._sprite.y - this._sprite.height * this._sprite.anchor.y - this.height; x += CC_Telepathy.params.X; y += CC_Telepathy.params.Y; // move out of the way of visible state icons if(this._battler.stateIcons().length || this._battler.buffIcons().length) { x += CC_Telepathy.params.StateAdjustX; y += CC_Telepathy.params.StateAdjustY; } this.x = x.clamp(this._minX, this._maxX); this.y = y.clamp(this._minY, this._maxY); } Window_Telepathy.prototype.isTelepathyActive = function() { if (!this._battler || this._battler.isDead()) { return false; } if (CC_Telepathy.params.ShowState && this._battler.isStateAffected(CC_Telepathy.params.ShowState)) { return true; } if (CC_Telepathy.params.HideState && this._battler.isStateAffected(CC_Telepathy.params.HideState)) { return false; } if (this._battler.isEnemy()) { var enemy = this._battler.enemy(); if(enemy.meta.telepathy !== undefined) { return eval(enemy.meta.telepathy); } } return CC_Telepathy.params.ShowDefault; } // fade in/out like map name window Window_Telepathy.prototype.updateOpacity = function() { if (this.isTelepathyActive() && this._text) { this.contentsOpacity += 16; } else { this.contentsOpacity -= 32; } }; Window_Telepathy.prototype.updateBackgroundDimmer = function() { if (this._dimmerSprite) { this._dimmerSprite.opacity = this.contentsOpacity; } } // Sprite_Enemy is parasited to attach the window let cct_Sprite_Enemy_setBattler = Sprite_Enemy.prototype.setBattler; Sprite_Enemy.prototype.setBattler = function(battler) { cct_Sprite_Enemy_setBattler.call(this, battler); if(!this._cct_window) { this._cct_window = new Window_Telepathy(this, battler); this.addChild(this._cct_window); } else { this._cct_window.setBattler(battler); } } })();