brainwashing-school/js/plugins/MPP_EncounterEffect.js
2025-05-30 08:36:40 -05:00

1999 lines
62 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

//=============================================================================
// MPP_EncounterEffect.js
//=============================================================================
// Copyright (c) 2021 - 2024 Mokusei Penguin
// Released under the MIT license
// http://opensource.org/licenses/mit-license.php
//=============================================================================
/*:
* @target MZ
* @plugindesc Change the effect at the time of encounter to a special effect.
* @author Mokusei Penguin
* @url
*
* @help [version 4.2.2]
* - This plugin is for RPG Maker MZ.
* - Change the effect at the time of encounter to a special effect.
*
* ▼ Plugin command
* - In the item to enter a numerical value,
* select the text and write 'v[N]' to refer to the variable N.
*
* setType
* - The effect type will be changed to the specified number
* only once next.
*
* setCharacter
* - The effect will be executed around the specified character
* only once next.
* - This setting is valid only for effect type 1.
*
* setColor
* - The effect will change to the specified color only once next.
*
* ▼ Effect type
* -1 : No SE & effects
* 0 : Default.
* 1 : Breaks around the character.
* 2 : The screen splits from the left and scatters to the left.
* 3 : The entire screen scatters to the front.
* 4 : The screen splits from the left and scatters to the right.
* 5 : Divide into squares and expand to the front.
*
* ▼ Other
* - In effect type 1, if the main character is not specified,
* [Player] will be the center for random encounters,
* and [This Event] will be the center for
* the event command [Battle Processing].
* - Effect type -1 does not allow the map screen to be used as
* the background.
*
* ================================
* Mail : wood_penguinyahoo.co.jp ( is half-width)
* Blog : http://woodpenguin.blog.fc2.com/
* License : MIT license
*
* @command setType
* @desc Change the effect type only in the next battle.
* @arg type
* @desc
* @type number
* @min -1
* @max 5
* @default 1
*
*
* @command setCharacter
* @desc Specify the main character for the next effect.
* This setting is valid only for effect type 1.
* @arg character
* @desc -1:Player, 0:This event, 1-:Event with specified ID
* @type number
* @min -1
* @max 999
* @default 0
*
* @command setColor
* @desc Specifies the color of the next effect.
* @arg color
* @desc R,G,B
* @default 255,255,255
*
*
* @param Effect Type
* @desc
* @type number
* @min 0
* @max 5
* @default 1
*
* @param Effect Color
* @desc R,G,B
* @default 255,255,255
*
*/
/*:ja
* @target MZ
* @plugindesc エンカウント時の演出を特殊なエフェクトに変更します。
* @author 木星ペンギン
* @url
*
* @help [version 4.2.2]
* - このプラグインはRPGツクールMZ用です。
* - エンカウント時の演出を特殊なエフェクトに変更します。
*
* ▼ プラグインコマンド
* - 数値を入力する項目で、テキストを選択して v[N] と記述することで
* 変数N番を参照します。
*
* エフェクトタイプ変更
* - 次の1回のみ、エフェクトタイプが指定した番号に変更されます。
*
* 中心キャラ指定
* - 次の1回のみ、エフェクトが指定したキャラクターを中心に実行されます。
* - この設定はエフェクトタイプ1のみ有効です。
*
* エフェクト色指定
* - 次の1回のみ、エフェクトが指定した色に変更されます。
*
* ▼ エフェクトタイプ
* -1: SE & エフェクトなし
* 0 : デフォルト
* 1 : キャラクターを中心に割れる
* 2 : 画面が左から割れて左に散る
* 3 : 画面全体が前面に飛び散る
* 4 : 画面が左から割れて右に散る
* 5 : 四角く区切り、手前に拡大する
*
* ▼ その他
* - エフェクトタイプ 1 にて、中心となるキャラクターを指定していない場合、
* ランダムエンカウントでは[プレイヤー]、
* イベントコマンドの【戦闘の処理】では[このイベント]が中心となります。
* - エフェクトタイプ -1 ではマップ画面を背景にはできません。
*
* ================================
* Mail : wood_penguinyahoo.co.jp (@は半角)
* Blog : http://woodpenguin.blog.fc2.com/
* License : MIT license
*
* @command setType
* @text エフェクトタイプ変更
* @desc 次に行う戦闘のみエフェクトタイプを変更します。
* @arg type
* @text タイプ
* @desc エフェクトタイプ
* @type number
* @min -1
* @max 5
* @default 1
*
* @command setCharacter
* @text 中心キャラ指定
* @desc 次に行うエフェクトで中心となるキャラクターを指定します。
* この設定はエフェクトタイプ1でのみ有効です。
* @arg character
* @text キャラクター
* @desc 中心となるキャラクター
* -1:プレイヤー, 0:このイベント, 1:指定したIDのイベント
* @type number
* @min -1
* @max 999
* @default 0
*
* @command setColor
* @text エフェクト色指定
* @desc 次に行うエフェクトの色を指定します。
* @arg color
* @text 色(RGB)
* @desc
* @default 255,255,255
*
*
* @param Effect Type
* @text エフェクトタイプ
* @desc 画面割れエフェクトのタイプ
* @type number
* @min 0
* @max 5
* @default 1
*
* @param Effect Color
* @text エフェクト色
* @desc エフェクトのデフォルト色
* (r,g,bで指定)
* @default 255,255,255
*
*
*/
(() => {
'use strict';
const pluginName = 'MPP_EncounterEffect';
// Plugin Parameters
const parameters = PluginManager.parameters(pluginName);
const param_EffectType = Number(parameters['Effect Type'] || 1);
const param_DefaultColor = parameters['Effect Color'].split(',').map(Number);
const _importedPlugin = (...names) => {
return names.some(name => PluginManager._scripts.includes(name));
};
const pluginOptions = [
'MPP_EncounterEffect_Op1',
'MPP_EncounterEffect_Op2',
'MPP_EncounterEffect_Op3'
];
// JsExtensions 代替
const MathExt = (() => {
// Number.prototype.clamp と違い、下限優先
const clamp = (x, min, max) => Math.max(Math.min(x, max), min);
const mod = (x, n) => ((x % n) + n) % n;
const randomInt = (x) => Math.floor(x * Math.random());
return { clamp, mod, randomInt };
})();
// 各タイプのパラメータ
const baseTypeParameters = [
null,
// Type 1
{
'Shape Type': 'square',
'Center': 'character',
'Break Direction': 'none',
'Break Duration': 45,
'Interval Duration': 45,
'Scatter Duration': 0,
'Move Duration': 60,
'Split Radial': 8,
'Radial Random Rate': 90,
'Circle Radius': 96,
'Circle Increase Rate': 150,
'Circle Random Rate': 40
},
// Type 2
{
'Shape Type': 'random',
'Break Direction': 'left',
'Break Duration': 30,
'Interval Duration': 45,
'Scatter Direction': 'left',
'Scatter Duration': 24,
'Move Duration': 60,
'Split X': 7,
'X Random Rate': 75,
'Split Y': 5,
'Y Random Rate': 75
},
// Type 3
{
'Shape Type': 'triangle',
'Break Direction': 'inside',
'Break Duration': 35,
'Interval Duration': 40,
'Scatter Direction': 'inside',
'Scatter Duration': 16,
'Move Duration': 100,
'Split X': 8,
'X Random Rate': 75,
'Split Y': 6,
'Y Random Rate': 75,
'Jump': true
},
// Type 4
{
'Shape Type': 'random',
'Break Direction': 'left',
'Break Duration': 30,
'Interval Duration': 45,
'Scatter Direction': 'right',
'Scatter Duration': 6,
'Move Duration': 45,
'Split X': 9,
'X Random Rate': 70,
'Split Y': 7,
'Y Random Rate': 70
},
// Type 5
{
'Shape Type': 'square',
'Break Direction': 'outside',
'Break Duration': 30,
'Interval Duration': 45,
'Scatter Direction': 'left',
'Scatter Duration': 50,
'Move Duration': 80,
'Split X': 15,
'X Random Rate': 0,
'Split Y': 11,
'Y Random Rate': 0
},
];
// 競合対策
const __base = (obj, prop) => {
if (obj.hasOwnProperty(prop)) {
return obj[prop];
} else {
const proto = Object.getPrototypeOf(obj);
return function () { return proto[prop].apply(this, arguments); };
}
};
//-------------------------------------------------------------------------
// EncounterEffect
function EncounterEffect() {
throw new Error('This is a static class');
}
if (_importedPlugin(...pluginOptions)) {
window.EncounterEffect = EncounterEffect;
}
EncounterEffect.centerPoint = new Point();
EncounterEffect.windowBounds = null;
EncounterEffect.clear = function() {
this._fadeSign = 0;
this._duration = 0;
this._opacity = 0;
this._backOpacity = 0;
this._fragments = null;
this._angle = 0;
this._type = param_EffectType;
this._character = null;
this._color = param_DefaultColor;
this._params = null;
this.destroy();
};
EncounterEffect.destroy = function() {
if (this._snapTexture) {
this._snapTexture.destroy();
}
this._snapTexture = null;
};
EncounterEffect.clear();
EncounterEffect.params = function() {
return this._type >= 0 ? baseTypeParameters[this._type] : null;
};
EncounterEffect.type = function() {
return this._type;
};
EncounterEffect.isValid = function() {
return !!this.params();
};
EncounterEffect.isRunning = function() {
return this._fadeSign !== 0;
};
EncounterEffect.isFadeOut = function() {
return this._fadeSign < 0;
};
EncounterEffect.isFadeIn = function() {
return this._fadeSign > 0;
};
EncounterEffect.isReady = function() {
return !this.isRunning() || this._duration < 45;
};
EncounterEffect.isSpritesetVisible = function() {
return this._opacity < 255 || this._backOpacity < 255;
};
EncounterEffect.currentParam = function(name, def = null) {
return this._params ? this._params[name] || def : def;
};
EncounterEffect.maxItems = function() {
return this._fragments ? this._fragments.length : 0;
};
EncounterEffect.fragments = function() {
return this._fragments || [];
};
EncounterEffect.breakDuration = function() {
return this.currentParam('Break Duration', 45);
};
EncounterEffect.effectSpeed = function() {
const d = this.currentParam('Interval Duration', 45);
return this.breakDuration() + d + 2;
};
EncounterEffect.fadeSpeed = function() {
return this.currentParam('Move Duration', 60);
};
EncounterEffect.rotation = function() {
return this._angle * Math.PI / 180;
};
EncounterEffect.snapTexture = function() {
return this._snapTexture;
};
EncounterEffect.setType = function(type) {
this._type = type;
};
EncounterEffect.opacity = function() {
return this._opacity;
};
EncounterEffect.backOpacity = function() {
return this._backOpacity;
};
EncounterEffect.setColor = function(...color) {
this._color = color;
};
EncounterEffect.color = function() {
return this._color;
};
EncounterEffect.setCharacter = function(character) {
this._character = character;
};
EncounterEffect.centerCharacter = function() {
return (
this._character ||
$gameMap.getInterpreterCharacter(0) ||
$gamePlayer
);
};
EncounterEffect.setup = function(snapTexture) {
this.destroy();
this._snapTexture = snapTexture;
this._params = this.params();
this.setupWindowBounds();
this.setupCenterPoint();
};
EncounterEffect.setupWindowBounds = function() {
const { width, height } = Graphics;
this.windowBounds = { minX: 0, maxX: width, minY: 0, maxY: height };
};
EncounterEffect.setupCenterPoint = function() {
if (this.currentParam('Center') === 'character') {
const { minX, maxX, minY, maxY } = this.windowBounds;
const character = this.centerCharacter();
const charX = character.screenX();
const charY = character.screenY();
const cx = Math.round(MathExt.clamp(charX, minX, maxX));
const cy = Math.round(MathExt.clamp(charY - 24, minY, maxY));
this.centerPoint.set(cx, cy);
} else {
const cx = Graphics.width / 2;
const cy = Graphics.height / 2;
this.centerPoint.set(cx, cy);
}
};
EncounterEffect.startFadeOut = function() {
this._fadeSign = -1;
this._duration = this.effectSpeed();
this._opacity = 255;
this._backOpacity = 255;
this.createFragments();
this.sortFragment(this.currentParam('Break Direction'));
this.startFadeOutAngle();
};
EncounterEffect.startFadeOutAngle = function() {
this._angle = 0;
this._targetAngle = 0;
this._angleEasing = new Easing();
if (this._type === 5) {
const speed = this.effectSpeed();
this._targetAngle = -3;
this._angleEasing.start('Slow end', speed);
}
};
EncounterEffect.createFragments = function() {
this._fragments = [];
switch (this._type) {
case 1:
this.createFragmentsT1();
break;
case 2:
case 3:
case 4:
case 5:
this.createFragmentsT2();
break;
}
};
EncounterEffect.createFragmentsT1 = function() {
const { minX, maxX, minY, maxY } = this.windowBounds;
const allPoints = this.createAllPointsT1();
for (let points of this.generatorPointsT1(allPoints)) {
points = this.cutProtrusionX(points, minX, false);
points = this.cutProtrusionX(points, maxX, true);
points = this.cutProtrusionY(points, minY, false);
points = this.cutProtrusionY(points, maxY, true);
points = this.removeOuterPoint(points);
if (points.length >= 3) {
this.addFragment(this.uniqPoints(points));
}
}
};
EncounterEffect.generatorPointsT1 = function*(allPoints) {
const square = this.currentParam('Shape Type', 'square') === 'square';
const max = allPoints[0] ? allPoints[0].length : 1;
for (const [i, outPoints] of allPoints.entries()) {
const inPoints = i > 0 ? allPoints[i - 1] : null;
for (const [j, point2] of outPoints.entries()) {
const point3 = outPoints[(j + 1) % max];
if (inPoints) {
const point4 = inPoints[(j + 1) % max];
const point1 = inPoints[j];
if (square) {
yield [point1, point2, point3, point4];
} else {
yield [point1, point2, point4];
yield [point2, point3, point4];
}
} else {
yield [this.centerPoint, point2, point3];
}
}
}
};
EncounterEffect.cutProtrusionX = function(points, x, cutAbove) {
const size = points.length;
for (const p1 of points) {
const i = points.indexOf(p1);
const p2 = points[(i + 1) % points.length];
const p3 = this.verticalIntersectionPoint(p1, p2, x);
if (p3) {
points.splice(i + 1, 0, p3);
}
}
if (size < points.length) {
return points.filter(p => cutAbove ? p.x <= x : p.x >= x);
}
return points;
};
EncounterEffect.verticalIntersectionPoint = function(point1, point2, x) {
const x1 = point1.x;
const y1 = point1.y;
const x2 = point2.x;
const y2 = point2.y;
if ((x1 < x && x2 > x) || (x1 > x && x2 < x)) {
const y = y1 + Math.round((y2 - y1) * (x - x1) / (x2 - x1));
return new Point(x, y);
}
return null;
};
EncounterEffect.cutProtrusionY = function(points, y, cutAbove) {
const size = points.length;
for (const p1 of points) {
const i = points.indexOf(p1);
const p2 = points[(i + 1) % points.length];
const p3 = this.horizontalIntersectionPoint(p1, p2, y);
if (p3) {
points.splice(i + 1, 0, p3);
}
}
if (size < points.length) {
return points.filter(p => cutAbove ? p.y <= y : p.y >= y);
}
return points;
};
EncounterEffect.horizontalIntersectionPoint = function(point1, point2, y) {
const x1 = point1.x;
const y1 = point1.y;
const x2 = point2.x;
const y2 = point2.y;
if ((y1 < y && y2 > y) || (y1 > y && y2 < y)) {
const x = x1 + Math.round((x2 - x1) * (y - y1) / (y2 - y1));
return new Point(x, y);
}
return null;
};
EncounterEffect.removeOuterPoint = function(points) {
const { minX, maxX, minY, maxY } = this.windowBounds;
return points.filter(
({ x, y }) => x >= minX && x <= maxX && y >= minY && y <= maxY
);
};
EncounterEffect.uniqPoints = function(points) {
return points.filter(
(p1, i) => points.findIndex(p2 => p2.equals(p1)) === i
);
};
EncounterEffect.createAllPointsT1 = function() {
const {
'Shape Type': sType = 'square',
'Split Radial': splitX = 8,
'Circle Radius': baseRadius = 96,
'Circle Increase Rate': circleRate = 150
} = this._params;
const maxRadius = this.maxRadius();
const allPoints = [];
let startAngle = 360 * Math.random();
let innerR = 0;
let currentR = baseRadius;
for (let i = 0; i < 8; i++) {
if (sType === 'triangle') startAngle += 180 / splitX;
if (i === 7) innerR = 1000000;
allPoints.push(this.createRoundPoints(startAngle, innerR, currentR));
if (innerR > maxRadius) break;
innerR += currentR;
currentR *= circleRate / 100;
}
return allPoints;
};
EncounterEffect.createRoundPoints = function(startAngle, innerR, currentR) {
const {
'Split Radial': splitX = 8,
'Radial Random Rate': rRate = 90,
'Circle Random Rate': cRate = 40
} = this._params;
const baseAngle = 360 / splitX;
const randomAngle = (n) => {
return (startAngle + baseAngle * n +
baseAngle * rRate * Math.random() / 100) % 360;
};
const randomRadius = () => {
return innerR +
currentR * (1 - cRate * (0.75 - Math.random()) / 100);
};
return [...Array(splitX).keys()].map(
i => this.calculatePoint(randomAngle(i), randomRadius())
);
};
EncounterEffect.calculatePoint = function(angle, radius) {
const { x, y } = this.centerPoint;
const sx = Math.round(radius * Math.cos(angle * Math.PI / 180));
const sy = Math.round(radius * Math.sin(angle * Math.PI / 180));
return new Point(x + sx, y + sy);
};
EncounterEffect.maxRadius = function() {
const { width, height } = Graphics;
const { x, y } = this.centerPoint;
const deltaX = x < width / 2 ? width - x : x;
const deltaY = y < height / 2 ? height - y : y;
return Math.hypot(deltaX, deltaY);
};
EncounterEffect.createFragmentsT2 = function() {
switch (this.currentParam('Shape Type', 'square')) {
case 'square':
this.createFragmentsT2Square();
break;
case 'triangle':
this.createFragmentsT2Triangle();
break;
case 'random':
this.createFragmentsT2Random();
break;
}
};
EncounterEffect.createFragmentsT2Square = function() {
const allPoints = this.createAllPointsT2Square();
for (const points of this.generatorPointsT2(allPoints)) {
this.addFragment(points);
}
};
EncounterEffect.generatorPointsT2 = function*(allPoints) {
const {
'Shape Type': sType = 'square',
'Split X': splitX = 12,
'Split Y': splitY = 9
} = this._params;
for (let i = 0; i < splitX; i++) {
const leftPoints = allPoints[i];
const rightPoints = allPoints[i + 1];
for (let j = 0; j < splitY; j++) {
const point1 = leftPoints[j];
const point2 = rightPoints[j];
const point3 = rightPoints[j + 1];
const point4 = leftPoints[j + 1];
if (sType === 'triangle') {
if (i % 2 === 0) {
yield [point1, point2, point3];
yield [point1, point3, point4];
} else {
yield [point1, point2, point4];
yield [point2, point3, point4];
}
} else {
yield [point1, point2, point3, point4];
}
}
}
};
EncounterEffect.createAllPointsT2Square = function() {
const {
'Split X': splitX = 12,
'Split Y': splitY = 9,
'X Random Rate': xRate = 80,
'Y Random Rate': yRate = 80
} = this._params;
const { minX, maxX, minY, maxY } = this.windowBounds;
const width = Graphics.width / Math.max(splitX - xRate / 100, 1);
const height = Graphics.height / Math.max(splitY - yRate / 100, 1);
const pointX = (i) => {
if (i === 0) {
return minX;
} else if (i === splitX) {
return maxX;
}
return this.randomValue(width, i, xRate);
};
const pointY = (j) => {
if (j === 0) {
return minY;
} else if (j === splitY) {
return maxY;
}
return this.randomValue(height, j, yRate);
};
return [...Array(splitX + 1).keys()].map(i => {
return [...Array(splitY + 1).keys()].map(j => {
return new Point(pointX(i), pointY(j));
});
});
};
EncounterEffect.randomValue = function(value, index, rate) {
return Math.round(value * (index - rate * Math.random() / 100));
};
EncounterEffect.createFragmentsT2Triangle = function() {
const allPoints = this.createAllPointsT2Triangle();
for (const points of this.generatorPointsT2(allPoints)) {
this.addFragment(points);
}
};
EncounterEffect.createAllPointsT2Triangle = function() {
const {
'Split X': splitX = 12,
'Split Y': splitY = 9,
'X Random Rate': xRate = 80,
'Y Random Rate': yRate = 80
} = this._params;
const { minX, maxX, minY, maxY } = this.windowBounds;
const width = Graphics.width / Math.max(splitX - xRate / 100, 1);
const height = Graphics.height / Math.max(splitY - 0.5, 1);
const bottomY = height / 2 * yRate / 100;
const pointX = (i) =>{
if (i === 0) {
return minX;
} else if (i === splitX) {
return maxX;
}
return this.randomValue(width, i, xRate);
};
const pointY = (i, j) => {
if (j === 0) {
return minY;
} else if (j === splitY) {
return maxY;
}
if (i % 2 === 1 && j === 1) {
return this.randomValue(height / 2, j, yRate);
}
const py = bottomY - (i % 2 === 0 ? 0 : height / 2);
return py + this.randomValue(height, j, yRate);
};
return [...Array(splitX + 1).keys()].map(i => {
return [...Array(splitY + 1).keys()].map(j => {
return new Point(pointX(i), pointY(i, j));
});
});
};
EncounterEffect.createFragmentsT2Random = function() {
const allPolygons = this.createPolygonsT2Random();
const sidePolygon = (i, j, pos) => {
const si = i + (pos === 0 || pos === 1 ? -1 : 1);
const subPolygons = allPolygons[si];
if (!subPolygons) {
return null;
}
const sj = Math.floor(j / 2) * 2;
const polygon2 = subPolygons[sj];
if (Math.floor(pos / 2) === Math.floor(polygon2.pos / 2)) {
return subPolygons[sj + 1];
}
return polygon2;
};
for (const [i, mainPolygons] of allPolygons.entries()) {
for (const [j, polygon1] of mainPolygons.entries()) {
if (polygon1.state === 'none') {
const d = MathExt.randomInt(3);
let polygon2;
if (d === 0) {
// 上
polygon2 = mainPolygons[j - 1];
} else if (d === 1) {
// 下
polygon2 = mainPolygons[j + 1];
} else {
// 横
polygon2 = sidePolygon(i, j, polygon1.pos);
}
if (polygon2 && polygon2.state === 'none') {
this.joinPolygon(polygon1, polygon2, d);
}
}
}
}
for (const polygon of allPolygons.flat()) {
if (polygon.state === 'none' || polygon.state === 'received') {
this.addFragment(polygon.points);
}
}
};
/**
*
* @returns {array} 二次元配列。
* pos: 分割した際の位置。0=左上, 1=左下, 2=右上, 3=右下。
*/
EncounterEffect.createPolygonsT2Random = function() {
const allPoints = this.createAllPointsT2Square();
const polygons = [];
for (const [p1, p2, p3, p4] of this.generatorPointsT2(allPoints)) {
if (Math.random() < 0.5) {
polygons.push(
{ points:[p4, p1, p2], pos:0, state:'none' },
{ points:[p4, p2, p3], pos:3, state:'none' }
);
} else {
polygons.push(
{ points:[p1, p2, p3], pos:2, state:'none' },
{ points:[p4, p1, p3], pos:1, state:'none' }
);
}
}
const splitY = this.currentParam('Split Y', 9);
const allPolygons = [];
while (polygons.length > 0) {
allPolygons.push(polygons.splice(0, splitY * 2));
}
return allPolygons;
};
EncounterEffect.joinPolygon = function(polygon1, polygon2, d) {
const pos1 = polygon1.pos;
const pos2 = polygon2.pos;
let start = 0, index = 0;
if (d === 0) {
start = pos1 === 0 || pos1 === 1 ? 2 : 1;
index = 1;
} else if (d === 1) {
start = 0;
index = pos1 === 0 ? 2 : pos1 === 2 ? 0 : pos2 === 0 ? 0 : 2;
} else {
start = pos1 === 0 || pos1 === 1 ? 1 : 2;
index = pos2 === 0 || pos2 === 1 ? 2 : 0;
}
polygon1.points.splice(start, 0, polygon2.points[index]);
polygon1.state = 'received';
polygon2.state = 'joined';
};
EncounterEffect.addFragment = function(points) {
const fragment = new Encounter_Fragment(points);
if (fragment.isValid()) {
fragment.setup();
this._fragments.push(fragment);
}
};
EncounterEffect.sortFragment = function(direction) {
const formula = this.compareFormula(direction);
if (formula) {
this._fragments.sort((a, b) => formula(a) - formula(b));
}
};
EncounterEffect.compareFormula = function(direction) {
const { x, y } = this.centerPoint;
switch (direction) {
case 'left':
return (f) => {
return f._x;
};
case 'center':
return (f) => {
return Math.abs(x - f._x);
};
case 'right':
return (f) => {
return -f._x;
};
case 'inside':
return (f) => {
return Math.abs(x - f._x) + Math.abs(y - f._y) * y / x;
};
case 'outside':
return (f) => {
return -Math.abs(x - f._x) - Math.abs(y - f._y) * y / x;
};
}
return null;
};
EncounterEffect.breakFragments = function(start, end, duration) {
for (let i = start; i < end; i++) {
this._fragments[i].onBreak(duration, i);
}
};
EncounterEffect.startFadeIn = function() {
if (!this.isFadeOut()) {
return;
}
this._fadeSign = 1;
const {
'Move Duration': duration = 60,
'Scatter Direction': direction = 'none',
'Scatter Duration': delay = 0
} = this._params;
this._duration = duration;
this.sortFragment(direction);
this.startFadeInFragments(duration, delay);
this.startFadeInAngle(duration);
};
EncounterEffect.startFadeInFragments = function(duration, delay) {
const maxItems = this.maxItems();
for (const [i, fragment] of this._fragments.entries()) {
fragment.startFadeIn(duration, delay);
fragment.setDelay(Math.floor(delay * i / maxItems));
}
};
EncounterEffect.startFadeInAngle = function(duration) {
if (this._type === 5) {
this._targetAngle = -4;
this._angleEasing.start('Straight', duration);
}
};
EncounterEffect.update = function() {
if (this.isRunning()) {
this._fragments.forEach(fragment => fragment.update());
this.updateMain();
this.updateOpacity();
this.updateBackOpacity();
this.updateAngle();
if (this.isFadeIn() && this._duration === 0) {
this.clear();
}
}
};
EncounterEffect.updateMain = function() {
if (this._duration > 0) {
if (this.isFadeOut()) {
const speed = this.effectSpeed();
const n = speed - this._duration;
const breakEnd = this.breakDuration();
if (n > 2 && n <= breakEnd + 2) {
const maxItems = this.maxItems();
const start = Math.floor(maxItems * (n - 3) / breakEnd);
const end = Math.floor(maxItems * (n - 2) / breakEnd);
this.breakFragments(start, end, speed);
}
}
this._duration--;
}
};
EncounterEffect.updateOpacity = function() {
if (this.isFadeIn()) {
const d = this._duration;
const speed = this.effectSpeed();
const delay = this._type === 5 ? speed - 1 : Math.floor(speed / 2);
if (d < speed - delay) {
this._opacity -= this._opacity / d;
}
}
};
EncounterEffect.updateBackOpacity = function() {
if (this.isFadeIn()) {
const d = this._duration;
const speed = this.effectSpeed();
const delay = Math.floor(speed / 3);
if (d < speed - delay) {
this._backOpacity -= this._backOpacity / d;
}
}
};
EncounterEffect.updateAngle = function() {
const easing = this._angleEasing;
if (easing.isMoving()) {
this._angle = easing.apply(this._angle, this._targetAngle);
easing.update();
}
};
//-------------------------------------------------------------------------
// SceneManager
SceneManager.snapTexture = function() {
const stage = this._scene;
const width = Graphics.width;
const height = Graphics.height;
const renderTexture = PIXI.RenderTexture.create(width, height);
if (stage) {
const renderer = Graphics.app.renderer;
renderer.render(stage, renderTexture);
stage.worldTransform.identity();
}
return renderTexture;
};
//-------------------------------------------------------------------------
// SoundManager
const _SoundManager_playBattleStart = SoundManager.playBattleStart;
SoundManager.playBattleStart = function() {
if (EncounterEffect.type() >= 0) {
_SoundManager_playBattleStart.apply(this, arguments);
}
};
//-------------------------------------------------------------------------
// Encounter_Fragment
class Encounter_Fragment {
constructor(points) {
this._points = points;
this.initRect(points);
this.initMembers();
}
initMembers() {
const rect = this._rect;
this._x = rect.x + Math.floor(rect.width / 2);
this._y = rect.y + Math.floor(rect.height / 2);
this._targetX = 0;
this._targetY = 0;
this._jumpHeight = 0;
this._scale = 1;
this._targetScale = 1;
this._moveEasing = new Easing();
this._opacity = 255;
this._opacityDuration = 0;
this._delay = 0;
this._flash = false;
this._break = false;
this._slideX = 0;
this._slideY = 0;
this.visible = true;
}
initRect(points) {
const allX = points.map( point => point.x );
const allY = points.map( point => point.y );
const x = Math.min(...allX);
const y = Math.min(...allY);
const width = Math.max(...allX) - x;
const height = Math.max(...allY) - y;
this._rect = new Rectangle(x, y, width, height);
}
isValid() {
return this._rect.width > 4 && this._rect.height > 4;
}
setDelay(delay) {
this._delay = delay;
}
clearFlash() {
this._flash = false;
}
isFlashRequested() {
return this._flash;
}
rect() {
return this._rect;
}
isBreak() {
return this._break;
}
lineWidth() {
return 4;
}
flashOpacity() {
return 255;
}
breakRate() {
return 1;
}
slideRate() {
return 1;
}
rotationRate() {
return 1;
}
screenX() {
return this._x;
}
screenY() {
return this._y - this._jumpHeight;
}
flashColor() {
return [...EncounterEffect.color(), this.flashOpacity()];
}
points() {
return this._points;
}
setup() {
this.setupRotation();
}
setupRotation() {
this._speed = 0;
this._pace = 0;
this._rotationX = 0;
this._rotationY = 0;
this._rotationZ = 0;
const rate = this.rotationRate();
if (Math.random() < 0.5) {
this._rotationSpeedX = (Math.random() + 0.5) * 2 * rate;
this._rotationSpeedY = 0;
} else {
this._rotationSpeedX = 0;
this._rotationSpeedY = (Math.random() + 0.5) * 2 * rate;
}
this._rotationSpeedZ = (Math.random() - 0.5) * 3 * rate;
}
textureMatrix() {
const tx = this._break ? this._slideX : 0;
const ty = this._break ? this._slideY : 0;
return new PIXI.Matrix(1, 0, 0, 1, tx, ty);
}
onBreak(duration, index) {
this.startEncounter(duration, index);
this._flash = true;
this._break = true;
}
startEncounter(duration, index) {
switch (EncounterEffect.type()) {
case 1:
this.setupMoveT1(duration);
this.setupSlideT1()
break;
case 2:
case 3:
case 4:
this.setupMoveT2();
this.setupSlideT2();
break;
case 5:
this.setupMoveT5(duration);
break;
}
}
setupMoveT1(duration) {
const breakRate = this.breakRate();
this._moveEasing.start('Slow end', duration);
this._speed = this.hypotSpeed(1.5) * breakRate;
this._pace = -1;
this.setMoveT1(breakRate / 100, breakRate / 100);
}
setupMoveT2() {
const breakRate = this.breakRate();
this._speed = 0.125 * breakRate;
this._pace = -1;
}
setupSlideT1() {
const slideRate = this.slideRate();
const { x, y } = EncounterEffect.centerPoint;
const radian = Math.atan2(this._y - y, this._x - x);
this._slideX = 20 * Math.cos(radian) * slideRate;
this._slideY = 20 * Math.sin(radian) * slideRate;
}
setupSlideT2() {
const slideRate = this.slideRate();
const { x, y, width, height } = this._rect;
const mx = (MathExt.randomInt(21) - 10) * slideRate;
const my = (MathExt.randomInt(21) - 10) * slideRate;
const minX = x + width - Graphics.width;
const minY = y + height - Graphics.height;
this._slideX = MathExt.clamp(mx, minX, x);
this._slideY = MathExt.clamp(my, minY, y);
}
setupMoveT5(duration) {
this._moveEasing.start('Slow end', duration);
this._speed = 0;
this._pace = 0;
this.setMoveAway('outside', 1.1);
}
update() {
if (this.visible && this.updateDelay()) {
this.updateMove();
this.updateOpacity();
this.updateRotation();
}
}
updateDelay() {
if (this._delay > 0) {
this._delay--;
return false;
}
return true;
}
updateMove() {
const easing = this._moveEasing;
if (easing.isMoving()) {
this._x = easing.apply(this._x, this._targetX);
this._y = easing.apply(this._y, this._targetY);
this._scale = easing.apply(this._scale, this._targetScale);
this.visible = this._scale < 8;
if (EncounterEffect.currentParam('Jump')) {
const d = easing._duration;
const wd = easing._wholeDuration;
const m = 4 * (d - 1) / wd;
this._jumpHeight = (2 * 2 - Math.pow(m - 2, 2)) * 96;
}
easing.update();
}
}
updateOpacity() {
if (this._opacityDuration > 0) {
const d = this._opacityDuration--;
this._opacity *= (d - 1) / d;
}
}
updateRotation() {
if (this._speed > 0) {
this._speed *= 1 + 0.04 * this._pace;
this._rotationX += this._rotationSpeedX * this._speed;
this._rotationY += this._rotationSpeedY * this._speed;
this._rotationZ += this._rotationSpeedZ * this._speed;
}
}
startFadeIn(duration, delay) {
switch (EncounterEffect.type()) {
case 1:
this.startFadeInT1(duration);
break;
case 2:
this.startFadeInT2(Math.max(duration - delay, 1));
break;
case 3:
this.startFadeInT3(duration);
break;
case 4:
this.startFadeInT4(duration);
break;
case 5:
this.startFadeInT5(Math.max(duration - delay, 1));
break;
}
}
startFadeInT1(duration) {
this._moveEasing.start('Slow end', duration);
this._speed = this.hypotSpeed(40);
this._pace = -1;
this.setMoveT1(0.8 + Math.random() / 2, 0.8 + Math.random() / 2);
}
hypotSpeed(baseSpeed) {
const { x, y } = EncounterEffect.centerPoint;
return baseSpeed / Math.sqrt(Math.hypot(this._x - x, this._y - y));
}
setMoveT1(rateX, rateY) {
const { minX, maxX, minY, maxY } = EncounterEffect.windowBounds;
const { x: cx, y: cy } = EncounterEffect.centerPoint;
const sx = this._x - cx;
const sy = this._y - cy;
let ox = sx;
let oy = sy;
if (ox < 0) {
oy *= (minX - cx) / ox;
ox = minX - cx;
} else if (ox > 0) {
oy *= (maxX - cx) / ox;
ox = maxX - cx;
} else {
oy = oy < cy ? minY - cy : maxY - cy;
}
if (oy < minY - cy) {
ox *= (minY - cy) / oy;
oy = minY - cy;
} else if (oy > maxY - cy) {
ox *= (maxY - cy) / oy;
oy = maxY - cy;
}
this._targetX = this._x + (ox - sx) * rateX;
this._targetY = this._y + (oy - sy) * rateY;
}
startFadeInT2(duration) {
this._moveEasing.start('Slow start', duration);
this._speed = 1;
this._pace = 1;
const dir = EncounterEffect.currentParam('Scatter Direction');
this.setMoveT2(dir);
}
setMoveT2(direction) {
const { x: cx, y: cy } = EncounterEffect.centerPoint;
switch (direction) {
case 'left':
this._targetX = this._x - Graphics.width;
this._targetY = this._y + (this._y - cy);
break;
case 'right':
this._targetX = this._x + Graphics.width;
this._targetY = this._y + (this._y - cy);
break;
case 'outside': {
const radian = Math.atan2(this._y - cy, this._x - cx);
const d = (cx + cy) / 2;
this._targetX = this._x + d * Math.cos(radian);
this._targetY = this._y + d * Math.sin(radian);
break;
}
}
}
startFadeInT3(duration) {
this._moveEasing.start('Slow end', duration);
this._speed = 2;
this._pace = 0;
this.setMoveT3();
}
setMoveT3() {
const { x: cx, y: cy } = EncounterEffect.centerPoint;
const sx = this._x - cx;
const sy = this._y - cy;
const rate = 3;
this._targetX = (sx + 80 * (Math.random() - 0.5)) * rate + cx;
this._targetY = (sy + 32 * (Math.random() - 0.5)) * rate + cy * 3;
const delta = Math.abs(sx) + Math.abs(sy);
this._targetScale = delta < 128 && Math.random() < 0.4 ? 12 : 1;
this._targetScale += 2.5 * Math.random();
}
startFadeInT4(duration) {
this._moveEasing.start('Slow end', duration);
this._speed = 2;
this._pace = -1;
const dir = EncounterEffect.currentParam('Scatter Direction');
this.setMoveAway(dir, 2);
}
startFadeInT5(duration) {
this._moveEasing.start('Straight', duration);
this._speed = 0;
this._pace = 0;
this.setMoveAway('outside', 2.25);
this._targetScale = 1.75;
this._opacityDuration = duration;
}
setMoveAway(direction, rate) {
let { x, y } = EncounterEffect.centerPoint;
switch (direction) {
case 'left':
x = Graphics.width;
break;
case 'right':
x = 0;
break;
}
this._targetX = x + (this._x - x) * rate;
this._targetY = y + (this._y - y) * rate;
}
opacity() {
return this._opacity;
}
scaleX() {
return Math.cos(this._rotationX * Math.PI / 180) * this._scale;
}
scaleY() {
return Math.cos(this._rotationY * Math.PI / 180) * this._scale;
}
rotation() {
return this._rotationZ * Math.PI / 180;
}
}
if (_importedPlugin(...pluginOptions)) {
window.Encounter_Fragment = Encounter_Fragment;
}
//-------------------------------------------------------------------------
// Easing
class Easing {
constructor(type = '', duration = 0) {
this.setType(type);
this.setDuration(duration);
}
start(type, duration) {
this.setType(type);
this.setDuration(duration);
}
setType(type) {
this._type = type || 'Slow end';
}
setDuration(duration) {
this._duration = duration;
this._wholeDuration = duration;
}
clear() {
this._duration = 0;
}
isMoving() {
return this._duration > 0;
}
update() {
if (this._duration > 0) {
this._duration--;
}
}
apply(current, target) {
const d = this._duration;
const wd = this._wholeDuration;
const lt = this.calc((wd - d) / wd);
const t = this.calc((wd - d + 1) / wd);
const start = (current - target * lt) / (1 - lt);
return start + (target - start) * t;
}
calc(t) {
switch (this._type) {
case 'Slow start':
return this.easeIn(t);
case 'Slow end':
return this.easeOut(t);
case 'Slow start and end':
return this.easeInOut(t);
default:
return t;
}
}
easeIn(t) {
return Math.pow(t, 2);
}
easeOut(t) {
return 1 - Math.pow(1 - t, 2);
}
easeInOut(t) {
if (t < 0.5) {
return this.easeIn(t * 2) / 2;
} else {
return this.easeOut(t * 2 - 1) / 2 + 0.5;
}
}
};
//-------------------------------------------------------------------------
// PluginManager
PluginManager.registerCommand(pluginName, 'setType', args => {
EncounterEffect.setType(PluginManager.mppValue(args.type));
});
PluginManager.registerCommand(pluginName, 'setCharacter', function(args) {
const eId = PluginManager.mppValue(args.character);
EncounterEffect.setCharacter(this.character(eId));
});
PluginManager.registerCommand(pluginName, 'setColor', args => {
const color = args.color.split(',');
const r = PluginManager.mppValue(color[0]);
const g = PluginManager.mppValue(color[1]);
const b = PluginManager.mppValue(color[2]);
EncounterEffect.setColor(r, g, b);
});
PluginManager.mppValue = function(value) {
const match = /^V\[(\d+)\]$/i.exec(value);
return match ? $gameVariables.value(+match[1]) : +value;
};
//-------------------------------------------------------------------------
// Game_Map
Game_Map.prototype.getInterpreterCharacter = function(param) {
const interpreter = this._interpreter;
return interpreter.isRunning() ? interpreter.character(param) : null;
};
//-------------------------------------------------------------------------
// Graphics_Fragment
class Graphics_Fragment extends PIXI.Graphics {
constructor(fragment) {
super();
this._fragment = fragment;
this._blendColor = [0, 0, 0, 0];
this._break = fragment.isBreak();
this._flashDuration = 0;
this.initPivot();
this.refresh();
this.update();
}
initPivot() {
const rect = this._fragment.rect();
const x = rect.x + Math.floor(rect.width / 2);
const y = rect.y + Math.floor(rect.height / 2);
this.pivot.set(x, y);
}
refreshIfNeeded() {
if (!this._break && this._fragment.isBreak()) {
this._break = true;
this.refresh();
}
}
refresh() {
this.clear();
const options = {
texture: EncounterEffect.snapTexture(),
matrix: this._fragment.textureMatrix()
};
this.beginTextureFill(options);
this.drawPolygon();
this.endFill();
const lw = this._fragment.lineWidth() / 2;
if (this._break && lw > 0) {
const c = EncounterEffect.color();
const color = c[0] * 256 * 256 + c[1] * 256 + c[2];
this.lineStyle(lw + 0.5, color, 0.25, 0.3);
this.drawPolygon();
this.lineStyle(lw, color, 0.5, 0.3);
this.drawPolygon();
}
}
drawPolygon() {
for (const [i, point] of this._fragment.points().entries()) {
i === 0
? this.moveTo(point.x, point.y)
: this.lineTo(point.x, point.y);
}
this.closePath();
}
update() {
this.refreshIfNeeded();
this.updatePosition();
this.updateOpacity();
this.updateFlash();
this.updateVisibility();
}
updatePosition() {
const fragment = this._fragment;
this.x = fragment.screenX();
this.y = fragment.screenY();
this.scale.x = fragment.scaleX();
this.scale.y = fragment.scaleY();
this.rotation = fragment.rotation();
}
updateOpacity() {
this.alpha = this._fragment.opacity() / 255;
}
updateFlash() {
this.setupFlash();
if (this._flashDuration > 0) {
const d = this._flashDuration--;
this._blendColor[3] *= (d - 1) / d;
if (this._flashDuration % 8 === 0) {
this._updateColorFilter();
}
}
}
setupFlash() {
if (this._fragment.isFlashRequested()) {
this._flashDuration = 25;
this._blendColor = this._fragment.flashColor();
this._fragment.clearFlash();
}
}
_createColorFilter() {
this._colorFilter = new BlendColorFilter();
this.filters = [this._colorFilter];
}
_removeColorFilter() {
this.filters = null;
this._colorFilter = null;
}
_updateColorFilter() {
if (this._colorFilter && this._blendColor[3] === 0) {
this._removeColorFilter();
return;
}
if (!this._colorFilter) {
this._createColorFilter();
}
this._colorFilter.setColor(this._blendColor);
}
updateVisibility() {
this.visible = this._fragment.visible;
}
}
//-------------------------------------------------------------------------
// BlendColorFilter
class BlendColorFilter extends PIXI.Filter {
constructor() {
super(null, BlendColorFilter._fragmentSrc);
this.uniforms.blendColor = [0, 0, 0, 0];
}
static _fragmentSrc = (
'varying vec2 vTextureCoord;' +
'uniform sampler2D uSampler;' +
'uniform vec4 blendColor;' +
'void main() {' +
' vec4 sample = texture2D(uSampler, vTextureCoord);' +
' float a = sample.a;' +
' vec3 rgb = sample.rgb;' +
' float r = rgb.r;' +
' float g = rgb.g;' +
' float b = rgb.b;' +
' float r3 = blendColor.r / 255.0;' +
' float g3 = blendColor.g / 255.0;' +
' float b3 = blendColor.b / 255.0;' +
' float i3 = blendColor.a / 255.0;' +
' float i1 = 1.0 - i3;' +
' r = clamp(r * i1 + r3 * i3 * a, 0.0, 1.0);' +
' g = clamp(g * i1 + g3 * i3 * a, 0.0, 1.0);' +
' b = clamp(b * i1 + b3 * i3 * a, 0.0, 1.0);' +
' gl_FragColor = vec4(r, g, b, a);' +
'}'
);
setColor(color) {
if (!(color instanceof Array)) {
throw new Error('Argument must be an array');
}
this.uniforms.blendColor = [...color];
}
}
//-------------------------------------------------------------------------
// Sprite_EncounterEffect
//
// スプライトクラスではないですが、
// RPGツクールのSpriteクラスのような扱いをするという意味でのクラス名です。
class Sprite_EncounterEffect extends PIXI.Container {
constructor() {
super();
this.createBlackBack();
this.createFragments();
this.initPosition();
this.updateRotation();
}
destroy() {
const options = { children: true };
super.destroy(options);
}
createBlackBack() {
const p = 40;
const width = Graphics.width + p * 2;
const height = Graphics.height + p * 2;
this._backGraphics = new PIXI.Graphics();
this._backGraphics.beginFill(0);
this._backGraphics.drawRect(-p, -p, width, height);
this._backGraphics.endFill();
this.addChild(this._backGraphics);
}
createFragments() {
for (const fragment of EncounterEffect.fragments()) {
this.addChild(new Graphics_Fragment(fragment));
}
}
initPosition() {
const { x, y } = EncounterEffect.centerPoint;
this.x = x;
this.y = y;
this.pivot.set(x, y);
}
update() {
this.updateChildren();
this.updateRotation();
this.updateOpacity();
}
updateChildren() {
for (const child of this.children) {
if (child.update) {
child.update();
}
}
}
updateRotation() {
this.rotation = EncounterEffect.rotation();
}
updateOpacity() {
this.alpha = EncounterEffect.opacity() / 255;
this._backGraphics.alpha = EncounterEffect.backOpacity() / 255;
}
updateFadeDelay() {
if (this._fadeDelay > 0) {
this._fadeDelay--;
return false;
}
return true;
}
}
//-------------------------------------------------------------------------
// Sprite_Actor
const _Sprite_Actor_updateMove = Sprite_Actor.prototype.updateMove;
Sprite_Actor.prototype.updateMove = function() {
if (EncounterEffect.isReady()) {
_Sprite_Actor_updateMove.apply(this, arguments);
}
};
//-------------------------------------------------------------------------
// Spriteset_Map
Spriteset_Map.prototype.showDestination = function() {
this._destinationSprite.visible = true;
};
Spriteset_Map.prototype.hideDestination = function() {
this._destinationSprite.visible = false;
};
//-------------------------------------------------------------------------
// Scene_Base
Scene_Base.prototype.createEncEffSprite = function() {
if (EncounterEffect.isRunning() && !this._encEffSprite) {
this._encEffSprite = new Sprite_EncounterEffect();
this.addChild(this._encEffSprite);
}
};
Scene_Base.prototype.destroyEncEffSprite = function() {
if (this._encEffSprite) {
this.removeChild(this._encEffSprite);
this._encEffSprite.destroy();
delete this._encEffSprite;
}
};
Scene_Base.prototype.startEncEffFadeOut = function() {
if (!EncounterEffect.isRunning()) {
this.snapEncEffTexture();
EncounterEffect.startFadeOut();
this.createEncEffSprite();
}
};
Scene_Base.prototype.snapEncEffTexture = function() {
this._windowLayer.visible = false;
EncounterEffect.setup(SceneManager.snapTexture());
this._windowLayer.visible = true;
};
Scene_Base.prototype.startEncEffFadeIn = function() {
if (EncounterEffect.isFadeOut()) {
EncounterEffect.startFadeIn();
this.createEncEffSprite();
}
};
Scene_Base.prototype.updateMppEncEffManager = function() {
if (EncounterEffect.isRunning()) {
EncounterEffect.update();
this._spriteset.visible = EncounterEffect.isSpritesetVisible();
if (!EncounterEffect.isRunning()) {
this.destroyEncEffSprite();
this._spriteset.visible = true;
}
}
};
//-------------------------------------------------------------------------
// Scene_Title
const _Scene_Title_initialize = Scene_Title.prototype.initialize;
Scene_Title.prototype.initialize = function() {
_Scene_Title_initialize.apply(this, arguments);
EncounterEffect.clear();
};
//-------------------------------------------------------------------------
// Scene_Map
const _Scene_Map_startFadeIn = __base(Scene_Map.prototype, 'startFadeIn');
Scene_Map.prototype.startFadeIn = function(duration, white) {
if (!EncounterEffect.isRunning()) {
_Scene_Map_startFadeIn.apply(this, arguments);
}
};
const _Scene_Map_update = Scene_Map.prototype.update;
Scene_Map.prototype.update = function() {
_Scene_Map_update.apply(this, arguments);
this.updateMppEncEffManager();
};
const _Scene_Map_startEncounterEffect = Scene_Map.prototype.startEncounterEffect;
Scene_Map.prototype.startEncounterEffect = function() {
if (EncounterEffect.type() < 0) {
this.startFadeOut(this.fadeSpeed(), false);
EncounterEffect.clear();
return;
}
if (EncounterEffect.isValid()) {
this.startEncEffFadeOut();
} else {
EncounterEffect.clear();
}
_Scene_Map_startEncounterEffect.apply(this, arguments);
};
const _Scene_Map_updateEncounterEffect = Scene_Map.prototype.updateEncounterEffect
Scene_Map.prototype.updateEncounterEffect = function() {
EncounterEffect.isRunning()
? this.updateMppEncounterEffect()
: _Scene_Map_updateEncounterEffect.apply(this, arguments);
};
const _Scene_Map_encounterEffectSpeed = Scene_Map.prototype.encounterEffectSpeed;
Scene_Map.prototype.encounterEffectSpeed = function() {
return EncounterEffect.isRunning()
? EncounterEffect.effectSpeed()
: _Scene_Map_encounterEffectSpeed.apply(this, arguments);
};
Scene_Map.prototype.snapEncEffTexture = function() {
this._spriteset.hideDestination();
Scene_Message.prototype.snapEncEffTexture.call(this);
this._spriteset.showDestination();
};
Scene_Map.prototype.updateMppEncounterEffect = function() {
if (this._encounterEffectDuration > 0) {
this._encounterEffectDuration--;
const speed = this.encounterEffectSpeed();
const n = speed - this._encounterEffectDuration;
if (n === 2) {
this._spriteset.visible = true;
this._encEffSprite.visible = false;
this.snapForBattleBackground();
this._encEffSprite.visible = true;
}
if (n === Math.floor(speed / 4)) {
BattleManager.playBattleBgm();
}
}
};
//-------------------------------------------------------------------------
// Scene_Battle
const _Scene_Battle_create = Scene_Battle.prototype.create;
Scene_Battle.prototype.create = function() {
_Scene_Battle_create.apply(this, arguments);
this.startEncEffFadeIn();
};
const _Scene_Battle_startFadeIn = __base(Scene_Battle.prototype, 'startFadeIn');
Scene_Battle.prototype.startFadeIn = function(duration, white) {
if (!EncounterEffect.isRunning()) {
_Scene_Battle_startFadeIn.apply(this, arguments);
}
};
const _Scene_Battle_update = Scene_Battle.prototype.update;
Scene_Battle.prototype.update = function() {
_Scene_Battle_update.apply(this, arguments);
this.updateMppEncEffManager();
};
})();