Video

This plugin adds more options to the Battle Popups!
You have more customization over the attributes of the popups and also
have the ability to add custom popups.

Battle Popup Customizer
Version 1.20
SomeRanDev

This plugin adds more options to the Battle Popups!
You have more customization over the attributes of the popups and also
have the ability to add custom popups.

Furthermore, this plugin changes a lot of the core mechanics of the system,
including the fact that the popup text requires an external file.
Now it just requires you to input the font/colors you wish.

==========================================================================
Global Options
==========================================================================

You can manipulate the various properties of all the popups.

This includes the font and the font size.
As mentioned before, a font is used instead an image file.

Furthermore, if there are multiple popups in the same section, you can set
how much the proceeding popups shift on the X and Y axis.

==========================================================================
Existing Popups
==========================================================================

You can manipulate the following existing popups:

HP Damage
HP Heal
MP Damage
MP Heal
TP Damage
TP Heal
-------------
Miss
Evade
Critical
Guarded

The first six will be set into one section, and the remaining popups will
fall into their own section. These sections each move the popups so they
don't overlap.

==========================================================================
Popup Attributes
==========================================================================

Here is a list of all the manipulatable attributes:

Condition

If this JavaScript condition is true, the popup will be used.

==========================================================================

Text

The text shown for the popup.

==========================================================================

Location

The X and Y coordinates of the popup.
This refers to the initial position of the popup.
Use the format: x, y

For example: 20, -20

==========================================================================

Colors

The colors used by the popup text.
Use the format: mainColor | outlineColor

For example: #FFFFFF | #000000

==========================================================================

Animations

A list of all the animations that affect the popup.
All of the available animations are:

default
horizontal
float
fall
left
right
rotation

You can use one or multiple animations.
Seperate multiple animations with a comma.

For example: default, rotation

==========================================================================

Duration

The duration of the popup in frames.

==========================================================================

Flash

The flash of the popup.
Use the format: red, green, blue, intensity, duration

For example: 255, 0, 0, 160, 60

==========================================================================
End of Help File
==========================================================================

Welcome to the bottom of the Help file.

Thanks for reading!
If you have questions, or if you enjoyed this Plugin, please check
out my YouTube channel!

https://www.youtube.com/c/SumRndmDde

Until next time,
~ SomeRanDev
var SRD = SRD || {};
SRD.BattlePopupCustomizer = SRD.BattlePopupCustomizer || {};

var Imported = Imported || {};
Imported["SumRndmDde Battle Popup Customizer"] = 1.20;

(function(_) {

"use strict";

//-----------------------------------------------------------------------------
// SRD.BattlePopupCustomizer
//-----------------------------------------------------------------------------

var params = PluginManager.parameters('SRD_BattlePopupCustomizer');

_.font = String(params['Font']);
_.size = parseInt(params['Font Size']);
_.xShift = parseFloat(params['X Shift']);
_.yShift = parseFloat(params['Y Shift']);
_.condition = String(params['Global Condition']);

_.popups = [];
_.prefixes = ['HP Damage', 'HP Heal', 'MP Damage', 'MP Heal', 'TP Damage', 'TP Heal', 'Miss', 'Evade', 'Critical', 'Guarded'];
for(var i = 0; i < _.prefixes.length; i++) {
	_.popups[i] = {};
	var location = String(params[_.prefixes[i] + ' Location']).split(/\s*,\s*/);
	var colors = String(params[_.prefixes[i] + ' Colors']).split(/\s*\|\s*/);
	var flash = String(params[_.prefixes[i] + ' Flash']).split(/\s*,\s*/);
	_.popups[i].x = String(location[0]);
	_.popups[i].y = String(location[1]);
	_.popups[i].color = String(colors[0]);
	_.popups[i].outline = String(colors[1]);
	_.popups[i].text = String(params[_.prefixes[i] + ' Text']);
	_.popups[i].condition = String(params[_.prefixes[i] + ' Condition']);
	_.popups[i].duration = parseInt(params[_.prefixes[i] + ' Duration']);
	_.popups[i].animations = String(params[_.prefixes[i] + ' Animations']).split(/\s*,\s*/);
	_.popups[i].flashColor = [parseInt(flash[0]), parseInt(flash[1]), parseInt(flash[2]), parseInt(flash[3])];
	_.popups[i].flashDuration = parseInt(flash[4]);
}

_.customPops = [];
for(var i = 1; i <= 50; i++) {
	var condition = String(params['Custom ' + i + ' Condition']).trim();
	if(condition != 'false') {
		_.customPops[i] = {};
		var location = String(params['Custom ' + i + ' Location']).split(/\s*,\s*/);
		var colors = String(params['Custom ' + i + ' Colors']).split(/\s*\|\s*/);
		var flash = String(params['Custom ' + i + ' Flash']).split(/\s*,\s*/);
		_.customPops[i].x = String(location[0]);
		_.customPops[i].y = String(location[1]);
		_.customPops[i].color = String(colors[0]);
		_.customPops[i].outline = String(colors[1]);
		_.customPops[i].text = String(params['Custom ' + i + ' Text']);
		_.customPops[i].condition = condition;
		_.customPops[i].duration = parseInt(params['Custom ' + i + ' Duration']);
		_.customPops[i].animations = String(params['Custom ' + i + ' Animations']).split(/\s*,\s*/);
		_.customPops[i].flashColor = [parseInt(flash[0]), parseInt(flash[1]), parseInt(flash[2]), parseInt(flash[3])];
		_.customPops[i].flashDuration = parseInt(flash[4]);
	}
}

//-----------------------------------------------------------------------------
// Game_Action
//-----------------------------------------------------------------------------

if(Imported.YEP_BattleEngineCore) {

Game_Battler.prototype.startDamagePopup = function() {
	var result = this.result();
	this._damagePopup.push(result);
};

}

//-----------------------------------------------------------------------------
// Game_Action
//-----------------------------------------------------------------------------

var _Game_Action_applyGuard = Game_Action.prototype.applyGuard;
Game_Action.prototype.applyGuard = function(damage, target) {
	var newDamage = _Game_Action_applyGuard.apply(this, arguments);
	if(newDamage != damage) {
		target.result().guarded = true;
	}
	return newDamage;
};

var _Game_Action_calcElementRate = Game_Action.prototype.calcElementRate;
Game_Action.prototype.calcElementRate = function(target) {
	var rate = _Game_Action_calcElementRate.apply(this, arguments);
	target.result().elementRate = rate;
	return rate;
};

//-----------------------------------------------------------------------------
// Game_ActionResult
//-----------------------------------------------------------------------------

var _Game_ActionResult_clear = Game_ActionResult.prototype.clear;
Game_ActionResult.prototype.clear = function() {
	_Game_ActionResult_clear.apply(this, arguments);
	this.guarded = false;
	this.elementRate = 1;
};

//-----------------------------------------------------------------------------
// Sprite_Battler
//-----------------------------------------------------------------------------

if(!Imported.YEP_BattleEngineCore) {

var _Sprite_Battler_setBattler = Sprite_Battler.prototype.setBattler;
Sprite_Battler.prototype.setBattler = function(battler) {
	_Sprite_Battler_setBattler.call(this, battler);
	if(battler) battler._dpu_sprite = this;
};

}

//-----------------------------------------------------------------------------
// Sprite_Damage
//-----------------------------------------------------------------------------

Sprite_Damage.prototype.setup = function(target) {
	this._target = target;
	this._sprite = (Imported.YEP_BattleEngineCore) ? target.battler() : target._dpu_sprite;
	this._xOffsetSpecial = 0;
	this._yOffsetSpecial = 0;
	this._xOffsetDigits = 0;
	this._yOffsetDigits = 0;
	if(Imported.YEP_BattleEngineCore) {
		this._result = target.shiftDamagePopup();
	} else {
		this._result = target.result();
	}
	var result = this._result;

	if(!eval(_.condition)) return;

	var damages = [result.hpDamage, result.mpDamage, result.tpDamage];
	for(var i = 0; i <= 5; i++) {
		if(eval(_.popups[i].condition)) {
			this.createDigits(i, damages[Math.floor(i/2)]);
			this.incrementDigits(_.xShift, _.yShift);
		}
	}

	for(var i = 6; i <= 9; i++) {
		if(eval(_.popups[i].condition)) {
			this.createSpecial(i);
			this.incrementSpecial(_.xShift, _.yShift);
		}
	}

	for(var i = 1; i < _.customPops.length; i++) {
		if(_.customPops[i] && eval(_.customPops[i].condition)) {
			this.createSpecialCustom(i);
			this.incrementSpecial(_.xShift, _.yShift);
		}
	}
};

Sprite_Damage.prototype.incrementSpecial = function(x, y) {
	this._xOffsetSpecial += x;
	this._yOffsetSpecial += y;
};

Sprite_Damage.prototype.incrementDigits = function(x, y) {
	this._xOffsetDigits += x;
	this._yOffsetDigits += y;
};

Sprite_Damage.prototype.digitWidthFromBitmap = function(bitmap) {
	return bitmap.measureTextWidth('0');
};

Sprite_Damage.prototype.digitHeightFromBitmap = function(bitmap) {
	return bitmap.fontSize;
};

Sprite_Damage.prototype.createSpecial = function(index) {
	var info = _.popups[index];
	var bitmap = this.createChildBitmap(info, info.text.length);
	var sprite = this.createChildSprite(bitmap);
	sprite.bitmap.drawText(info.text, 2, 0, bitmap.width, bitmap.height, 'left');
	sprite.dy = 0;
	sprite.x = eval(info.x);
	sprite.y = eval(info.y);
	sprite.xBase = this._xOffsetSpecial;
	sprite.yBase = this._yOffsetSpecial;
	sprite.animations = info.animations.clone();
	sprite.duration = info.duration;
	sprite.oriDuration = sprite.duration;
	sprite.flashColor = info.flashColor.clone();
	sprite.flashDuration = info.flashDuration;
	sprite.oriX = sprite.x;
	sprite.oriY = sprite.y;
};

Sprite_Damage.prototype.createSpecialCustom = function(index) {
	var info = _.customPops[index];
	var bitmap = this.createChildBitmap(info, info.text.length);
	var sprite = this.createChildSprite(bitmap);
	sprite.bitmap.drawText(info.text, 2, 0, bitmap.width, bitmap.height, 'left');
	sprite.dy = 0;
	sprite.x = eval(info.x);
	sprite.y = eval(info.y);
	sprite.xBase = this._xOffsetSpecial;
	sprite.yBase = this._yOffsetSpecial;
	sprite.animations = info.animations.clone();
	sprite.duration = info.duration;
	sprite.oriDuration = sprite.duration;
	sprite.flashColor = info.flashColor.clone();
	sprite.flashDuration = info.flashDuration;
	sprite.oriX = sprite.x;
	sprite.oriY = sprite.y;
};

Sprite_Damage.prototype.createDigits = function(baseRow, value) {
	var string = Math.abs(value).toString();
	var info = _.popups[baseRow];
	string = info.text.replace(/%1/, string);
	var dummy = this.createChildBitmap(info);
	var w = this.digitWidthFromBitmap(dummy);
	var h = this.digitHeightFromBitmap(dummy);
	for (var i = 0; i < string.length; i++) {
		var bitmap = this.createChildBitmap(info);
		bitmap.resize(bitmap.width + (bitmap.outlineWidth*2), bitmap.height)
		var sprite = this.createChildSprite(bitmap);
		sprite.bitmap.drawText(string[i], 2, 0, w, h, 'left');
		sprite.xBase = this._xOffsetDigits;
		sprite.yBase = this._yOffsetDigits;
		sprite.x = ((i - (string.length - 1) / 2) * w) + eval(info.x);
		sprite.y = eval(info.y);
		sprite.ry = sprite.y;
		sprite.dy = -i;
		sprite.animations = info.animations.clone();
		sprite.duration = info.duration;
		sprite.oriDuration = sprite.duration;
		sprite.oriX = sprite.x;
		sprite.oriY = sprite.y;
		if(this._result.critical) {
			sprite.flashColor = [255, 0, 0, 160];
			sprite.flashDuration = 60;
		} else if(Imported.YEP_AbsorptionBarrier && this._result._barrierAffected) {
			sprite.flashColor = Yanfly.Param.ABRPop.slice();
			sprite.flashDuration = 180;
		} else {
			sprite.flashColor = info.flashColor.clone();
			sprite.flashDuration = info.flashDuration;
		}
	}
};

Sprite_Damage.prototype.createChildSprite = function(bitmap) {
	var sprite = new Sprite();
	sprite.bitmap = bitmap;
	sprite.anchor.x = 0.5;
	sprite.anchor.y = 0.5;
	this.addChild(sprite);
	return sprite;
};

Sprite_Damage.prototype.createChildBitmap = function(info, width, height) {
	width = width || 1;
	height = height || 1;
	var bitmap = new Bitmap();
	bitmap.fontFace = _.font;
	bitmap.fontSize = _.size;
	bitmap.textColor = info.color;
	bitmap.outlineColor = info.outline;
	if(Imported.YEP_AbsorptionBarrier && this._result._barrierAffected) {
		bitmap.textColor = "#FFFFFF"; 
	}
	var w = this.digitWidthFromBitmap(bitmap) * width;
	var h = this.digitHeightFromBitmap(bitmap) * height;
	bitmap.resize(w + 20, h);
	return bitmap;
};

Sprite_Damage.prototype.update = function() {
	Sprite.prototype.update.call(this);
	for (var i = 0; i < this.children.length; i++) {
		if(this.children[i].duration > 0) this.updateChild(this.children[i]);
	}
};

Sprite_Damage.prototype.updateChild = function(sprite) {
	sprite.duration--;
	this.updateChildOpacity(sprite);
	this.updateChildFlash(sprite);
	if(sprite.animations.indexOf('default') > -1) {
		if(!sprite.xIsAdded) {
			sprite.x += sprite.xBase;
			sprite.ry = -48;
			sprite.xIsAdded = true;
		}
		sprite.dy += 0.5;
		sprite.ry += sprite.dy;
		if (sprite.ry >= sprite.yBase) {
			sprite.ry = sprite.yBase;
			sprite.dy *= -0.6;
		}
		sprite.y = Math.round(sprite.ry) + sprite.oriY;
	} 
	if(sprite.animations.indexOf('horizontal') > -1) {
		if(!sprite.yIsAdded) {
			sprite.y += sprite.yBase;
			sprite.ry = -48;
			sprite.yIsAdded = true;
		}
		sprite.dy += 0.5;
		sprite.ry += sprite.dy;
		if (sprite.ry >= sprite.xBase) {
			sprite.ry = sprite.xBase;
			sprite.dy *= -0.6;
		}
		sprite.x = Math.round(sprite.ry) + sprite.oriX;
	}
	if(sprite.animations.indexOf('float') > -1) {
		if(!sprite.xIsAdded) {
			sprite.x += sprite.xBase;
			sprite.xIsAdded = true;
		}
		sprite.yBase--;
		sprite.y = sprite.yBase + sprite.oriY;
	}
	if(sprite.animations.indexOf('fall') > -1) {
		if(!sprite.xIsAdded) {
			sprite.x += sprite.xBase;
			sprite.xIsAdded = true;
		}
		sprite.yBase++;
		sprite.y = sprite.yBase + sprite.oriY;
	}
	if(sprite.animations.indexOf('left') > -1) {
		if(!sprite.yIsAdded) {
			sprite.y += sprite.yBase;
			sprite.yIsAdded = true;
		}
		sprite.xBase--;
		sprite.x = sprite.xBase + sprite.oriX;
	}
	if(sprite.animations.indexOf('right') > -1) {
		if(!sprite.yIsAdded) {
			sprite.y += sprite.yBase;
			sprite.yIsAdded = true;
		}
		sprite.xBase++;
		sprite.x = sprite.xBase + sprite.oriX;
	}
	if(sprite.animations.indexOf('rotation') > -1) {
		if(!sprite.xIsAdded) {
			sprite.x += sprite.xBase;
			sprite.xIsAdded = true;
		}
		if(!sprite.yIsAdded) {
			sprite.y += sprite.yBase;
			sprite.yIsAdded = true;
		}
		if(!sprite.applRotationsAndStuff) {
			sprite.anchor.x = 0.5;
			sprite.anchor.y = 0.5;
			sprite.y -= sprite.height/2;
			sprite.applRotationsAndStuff = true;
		}
		if(sprite.duration > (sprite.oriDuration/2)) {
			sprite.rotation = (sprite.duration - (sprite.oriDuration/2)) * (0.1);
		} else {
			sprite.rotation = 0;
		}
	} 
};

Sprite_Damage.prototype.updateChildOpacity = function(sprite) {
	if(sprite.duration < 10) {
		sprite.opacity = 255 * sprite.duration / 10;
	}
};

Sprite_Damage.prototype.updateChildFlash = function(sprite) {
	if (sprite.flashDuration > 0) {
		var d = sprite.flashDuration--;
		sprite.flashColor[3] *= (d - 1) / d;
		sprite.setBlendColor(sprite.flashColor);
	}
};

Sprite_Damage.prototype.isPlaying = function() {
	for(var i = 0; i < this.children.length; i++) {
		if(this.children[i].duration > 0) {
			return true;
		}
	}
	return false;
};

})(SRD.BattlePopupCustomizer);