mutation/www/js/plugins/MPP_EncounterEffect.js
2024-08-10 09:53:59 -05:00

1802 lines
53 KiB
JavaScript
Raw Permalink 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 Mokusei Penguin
// Released under the MIT license
// http://opensource.org/licenses/mit-license.php
//=============================================================================
/*:
* @target MV MZ
* @plugindesc Change the effect at the time of encounter to a special effect.
* @author Mokusei Penguin
* @url
*
* @help [version 3.3.3]
* This plugin is for RPG Maker MV and MZ.
*
* ▼ Plugin command
* In the item to enter a numerical value, the variable N is
* referred to by writing v[N].
*
* MV / MZ
*
* EncEffType type / setType
* type : Effect type
* - The effect type will be changed to the specified number
* only once next.
*
* EncEffChar evId / setCharacter
* evId : ID of the event that is the core of the effect
* - The effect will be executed around the specified character
* only once next.
* (-1:Player, 0:This Event, 1-:Event with specified ID)
* - This setting is valid only for effect type 1.
*
* EncEffColor r g b / setColor
* r g b : Effect color(RGB)
* - The effect will change to the specified color
* only once next.
*
* ▼ Plugin command supplement (MZ)
* In the item to enter a numerical value, select the Text and
* write v[N] to refer to the variable N.
*
* ▼ Effect type
* 0 : Default
* 1 : Breaks around the character
* 2 : Break from the left side of the screen
* 3 : The entire screen scatters 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].
* - When executed on a mobile device, some effects will be
* omitted due to weight reduction.
*
* ================================
* 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 0
* @max 3
* @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 3
* @default 1
*
* @param Effect Color
* @desc R,G,B
* @default 255,255,255
*
*/
/*:ja
* @target MV MZ
* @plugindesc エンカウント時の演出を特殊なエフェクトに変更します。
* @author 木星ペンギン
* @url
*
* @help [version 3.3.3]
* このプラグインはRPGツクールMVおよびMZ用です。
*
* ▼ プラグインコマンド(MV)
* 数値を入力する項目では、v[N] と記述することで変数N番を参照します。
*
* MV / MZ
*
* EncEffType type / エフェクトタイプ変更
* type : エフェクトタイプ
* - 次の1回のみ、エフェクトタイプが指定した番号に変更されます。
*
* EncEffChar evId / 中心キャラ指定
* evId : エフェクトの中心となるイベントのID
* - 次の1回のみ、エフェクトが指定したキャラクターを中心に実行されます。
* (-1:プレイヤー, 0:このイベント, 1:指定したIDのイベント)
* - この設定はエフェクトタイプ1のみ有効です。
*
* EncEffColor r g b / エフェクト色指定
* r g b : エフェクトの色(RGB)
* - 次の1回のみ、エフェクトが指定した色に変更されます。
*
* ▼ プラグインコマンド 補足(MZ)
* 数値を入力する項目で、テキストを選択して v[N] と記述することで
* 変数N番を参照します。
*
* ▼ エフェクトタイプ
* 0 : デフォルト
* 1 : キャラクターを中心に割れる
* 2 : 画面の左から割れる
* 3 : 画面全体が前面に飛び散る
*
* ▼ その他
* - エフェクトタイプ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 0
* @max 3
* @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 3
* @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"] || 2);
const param_DefaultColor = parameters["Effect Color"].split(",").map(Number);
// Dealing with other plugins
const _importedPlugin = (...names) => {
return names.some((name) => PluginManager._scripts.includes(name));
};
const pluginOptions = ["MPP_EncounterEffect_Op1", "MPP_EncounterEffect_Op2"];
// Database
const DATABASE = [
null,
{
// Type 1
"Shape Type": "square",
"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": 35,
"Move Duration": 70,
"Split X": 7,
"X Random Rate": 80,
"Split Y": 5,
"Y Random Rate": 80,
},
{
// Type 3
"Shape Type": "triangle",
"Break Direction": "inside",
"Break Duration": 35,
"Interval Duration": 40,
"Scatter Duration": 16,
"Move Duration": 100,
"Split X": 8,
"X Random Rate": 80,
"Split Y": 6,
"Y Random Rate": 80,
},
];
//-------------------------------------------------------------------------
// Array
if (!Array.prototype.flat) {
Array.prototype.flat = function (depth) {
const rec = (flattend, array, depth) => {
for (const elem of array) {
if (Array.isArray(elem) && depth > 0) {
rec(flattend, elem, depth - 1);
} else {
flattend.push(elem);
}
}
return flattend;
};
return rec([], this, depth !== undefined ? Math.floor(depth) : 1);
};
}
//-------------------------------------------------------------------------
// EncounterEffect
function EncounterEffect() {
throw new Error("This is a static class");
}
if (_importedPlugin(...pluginOptions)) {
window.EncounterEffect = EncounterEffect;
}
EncounterEffect.snap = null;
EncounterEffect.center = new Point();
EncounterEffect.opacity = 0;
EncounterEffect._fragments = null;
EncounterEffect._type = param_EffectType;
EncounterEffect._character = null;
EncounterEffect._color = param_DefaultColor;
EncounterEffect._effectDelay = 0;
EncounterEffect.clear = function () {
this.snap = null;
this.opacity = 0;
this._fragments = null;
this._type = param_EffectType;
this._character = null;
this._color = param_DefaultColor;
this._effectDelay = 0;
};
EncounterEffect.destroy = function () {
this.snap.destroy();
this._fragments.forEach((fragment) => fragment.destroy());
};
EncounterEffect.params = function () {
return DATABASE[this._type];
};
EncounterEffect.zoom = function () {
return Utils.isMobileDevice() ? 4 : 2;
};
EncounterEffect.setup = function (snap) {
this.snap = snap;
this.opacity = 255;
this._opacityDuration = 0;
this._fragments = [];
this._params = this.params();
this.setupwindowBounds();
this.setupCenter();
this.createPolygons();
this.startEffectDelay();
};
EncounterEffect.setupwindowBounds = function () {
this.windowBounds = {
minX: 0,
maxX: Graphics.width,
minY: 0,
maxY: Graphics.height,
};
};
EncounterEffect.setupCenter = function () {
const bounds = this.windowBounds;
const char = this.centerCharacter();
const cx = Math.round(char.screenX()).clamp(bounds.minX, bounds.maxX);
const cy = Math.round(char.screenY() - 24).clamp(bounds.minY, bounds.maxY);
this.center.set(cx, cy);
};
EncounterEffect.createPolygons = function () {
switch (this._type) {
case 1:
this.createPolygonsT1();
break;
case 2:
case 3:
this.createPolygonsT2();
break;
}
};
EncounterEffect.setType = function (type) {
this._type = type;
};
EncounterEffect.type = function () {
return this._type;
};
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
? this._character
: $gameMap.getInterpreterCharacter(0) || $gamePlayer;
};
EncounterEffect.createPolygonsT1 = function () {
const sType = this._params["Shape Type"] || "square";
const allPoints = this.createAllPointsT1();
this.iteratePointT1(allPoints, (p1, p2, p3, p4) => {
const polygon = [];
if (p2) {
if (this.isOutPolygon(p1, p2)) return;
if (sType === "square") {
polygon.push(p1, p2);
} else {
this.addPolygon(this.uniqPolygon([p1, p2, p3]));
polygon.push(p1);
}
} else {
polygon.push(p1);
}
if (this.setCorrectPoints(polygon, p3, p4)) {
this.addPolygon(this.uniqPolygon(polygon));
}
});
};
EncounterEffect.iteratePointT1 = function (allPoints, callback) {
const splitX = this._params["Split Radial"] || 8;
this._cornerFlag = [null, null, null, null];
for (let i = 0; i < allPoints.length; i++) {
const inPoints = i > 0 ? allPoints[i - 1] : null;
const outPoints = allPoints[i];
for (let j = 0; j < splitX; j++) {
const point3 = outPoints[j];
const point4 = outPoints[(j + 1) % splitX];
if (i > 0) {
const point1 = inPoints[(j + 1) % splitX];
const point2 = inPoints[j];
callback(point1, point2, point3, point4);
} else {
callback(this.center, null, point3, point4);
}
}
if (!this._cornerFlag.includes(null)) break;
}
};
EncounterEffect.uniqPolygon = function (polygon) {
return polygon.filter((point1, i) => {
return polygon.findIndex((point2) => point2.equals(point1)) === i;
});
};
EncounterEffect.createAllPointsT1 = function () {
const {
"Shape Type": sType = "square",
"Split Radial": splitX = 8,
"Circle Radius": baseHeight = 96,
"Circle Increase Rate": circleRate = 150,
} = this._params;
const maxRadius = this.maxRadius();
const allPoints = [];
let startR = Math.random() * 2;
let baseR = 0;
let height = baseHeight;
for (let i = 0; i < 8; i++) {
if (sType === "triangle") startR += 1 / splitX;
if (i === 7) baseR = 1000000;
allPoints[i] = this.createRoundPoints(startR, baseR, height);
if (baseR > maxRadius) break;
baseR += height;
height *= circleRate / 100;
}
return allPoints;
};
EncounterEffect.createRoundPoints = function (startR, baseR, height) {
const {
"Split Radial": splitX = 8,
"Radial Random Rate": rRate = 90,
"Circle Random Rate": cRate = 40,
} = this._params;
const baseAngle = 2 / splitX;
const randomAngle = (n) => {
return startR + baseAngle * n + (baseAngle * rRate * Math.random()) / 100;
};
const randomRadius = () => {
return baseR + height * (1 - (cRate * (0.75 - Math.random())) / 100);
};
const points = [];
for (let i = 0; i < splitX; i++) {
points[i] = this.calculatePoint(randomAngle(i) % 2, randomRadius());
}
return points;
};
EncounterEffect.calculatePoint = function (angle, radius) {
const bounds = this.windowBounds;
const { x: cx, y: cy } = this.center;
let sx = radius * Math.cos(angle * Math.PI);
let sy = radius * Math.sin(angle * Math.PI);
if (sx !== 0 && cx + sx < bounds.minX) {
sy *= (bounds.minX - cx) / sx;
sx = bounds.minX - cx;
}
if (sx !== 0 && cx + sx > bounds.maxX) {
sy *= (bounds.maxX - cx) / sx;
sx = bounds.maxX - cx;
}
if (sy !== 0 && cy + sy < bounds.minY) {
sx *= (bounds.minY - cy) / sy;
sy = bounds.minY - cy;
}
if (sy !== 0 && cy + sy > bounds.maxY) {
sx *= (bounds.maxY - cy) / sy;
sy = bounds.maxY - cy;
}
return new Point(Math.round(cx + sx), Math.round(cy + sy));
};
EncounterEffect.maxRadius = function () {
const { width, height } = Graphics;
const { x: cx, y: cy } = this.center;
const deltaX = cx < width / 2 ? width - cx : cx;
const deltaY = cy < height / 2 ? height - cy : cy;
return Math.hypot(deltaX, deltaY);
};
EncounterEffect.createPolygonsT2 = function () {
const {
"Shape Type": sType = "square",
"Break Direction": direction = "left",
} = this._params;
switch (sType) {
case "square":
this.createPolygonsT2Square();
break;
case "triangle":
this.createPolygonsT2Triangle();
break;
case "random":
this.createPolygonsT2Random();
break;
}
this.sortFragment(direction);
};
EncounterEffect.createPolygonsT2Square = function () {
const allPoints = this.createAllPointsT2Square();
this.iteratePointT2(allPoints, (...points) => {
this.addPolygon(points);
});
};
EncounterEffect.iteratePointT2 = function (allPoints, callback) {
const { "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 + 1];
const point2 = leftPoints[j];
const point3 = rightPoints[j];
const point4 = rightPoints[j + 1];
callback(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 bounds = 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 bounds.minX;
if (i === splitX) return bounds.maxX;
return this.randomValue(width, i, xRate);
};
const pointY = (j) => {
if (j === 0) return bounds.minY;
if (j === splitY) return bounds.maxY;
return this.randomValue(height, j, yRate);
};
const allPoints = [];
for (let i = 0; i <= splitX; i++) {
const points = [];
for (let j = 0; j <= splitY; j++) {
points[j] = new Point(pointX(i), pointY(j));
}
allPoints[i] = points;
}
return allPoints;
};
EncounterEffect.randomValue = function (value, index, rate) {
return Math.round(value * (index - (rate * Math.random()) / 100));
};
EncounterEffect.createPolygonsT2Triangle = function () {
const allPoints = this.createAllPointsT2Triangle();
this.iteratePointT2(allPoints, (p1, p2, p3, p4) => {
if (p2.y > p3.y || (p2.y === p3.y && p1.y > p4.y)) {
this.addPolygon([p1, p2, p4]);
this.addPolygon([p2, p3, p4]);
} else {
this.addPolygon([p1, p2, p3]);
this.addPolygon([p1, p3, p4]);
}
});
};
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 bounds = 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 bounds.minX;
if (i === splitX) return bounds.maxX;
return this.randomValue(width, i, xRate);
};
const pointY = (i, j) => {
if (j === 0) return bounds.minY;
if (j === splitY) return bounds.maxY;
let py = bottomY;
if (i % 2 === 1) {
if (j === 1) return this.randomValue(height / 2, j, yRate);
py -= height / 2;
}
return py + this.randomValue(height, j, yRate);
};
const allPoints = [];
for (let i = 0; i <= splitX; i++) {
const points = [];
for (let j = 0; j <= splitY; j++) {
points[j] = new Point(pointX(i), pointY(i, j));
}
allPoints[i] = points;
}
return allPoints;
};
EncounterEffect.createPolygonsT2Random = function () {
const allBasePolygons = this.createBasePolygonsT2Random();
const sidePolygon = (n, m, pos) => {
const si = n + (pos === 0 || pos === 1 ? -1 : 1);
const subPolygons = allBasePolygons[si];
if (subPolygons) {
const sj = Math.floor(m / 2) * 2;
const polygon2 = subPolygons[sj];
if (Math.floor(pos / 2) === Math.floor(polygon2.pos / 2)) {
return subPolygons[sj + 1];
}
return polygon2;
}
return null;
};
allBasePolygons.forEach((mainPolygons, i) => {
mainPolygons.forEach((polygon1, j) => {
if (polygon1.state === "none") {
const d = Math.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);
}
}
});
});
allBasePolygons.flat().forEach((polygon) => {
if (polygon.state === "none" || polygon.state === "received") {
this.addPolygon(polygon.polygon);
}
});
};
EncounterEffect.createBasePolygonsT2Random = function () {
const allPoints = this.createAllPointsT2Square();
const polygons = [];
this.iteratePointT2(allPoints, (p1, p2, p3, p4) => {
if (Math.random() < 0.5) {
polygons.push(
{ polygon: [p1, p2, p3], pos: 0, state: "none" },
{ polygon: [p1, p3, p4], pos: 3, state: "none" }
);
} else {
polygons.push(
{ polygon: [p2, p3, p4], pos: 2, state: "none" },
{ polygon: [p1, p2, p4], pos: 1, state: "none" }
);
}
});
const splitY = this._params["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.polygon.splice(start, 0, polygon2.polygon[index]);
polygon1.state = "received";
polygon2.state = "joined";
};
EncounterEffect.addPolygon = function (polygon) {
const fragment = new Encounter_Fragment(polygon);
if (fragment.isValid()) {
fragment.setup(this.snap);
this._fragments.push(fragment);
}
};
EncounterEffect.isOutPolygon = function (pos1, pos2) {
const bounds = this.windowBounds;
if (pos1.x === bounds.minX && pos2.x === bounds.minX) return true;
if (pos1.x === bounds.maxX && pos2.x === bounds.maxX) return true;
if (pos1.y === bounds.minY && pos2.y === bounds.minY) return true;
if (pos1.y === bounds.maxY && pos2.y === bounds.maxY) return true;
return false;
};
EncounterEffect.setCorrectPoints = function (polygon, pos1, pos2) {
const bounds = this.windowBounds;
polygon.push(pos1);
if (pos1.x === bounds.minX && pos2.y === bounds.minY) {
if (!this.pushCorner(polygon, 0)) return false;
} else if (pos1.y === bounds.maxY && pos2.x === bounds.minX) {
if (!this.pushCorner(polygon, 1)) return false;
} else if (pos1.y === bounds.minY && pos2.x === bounds.maxX) {
if (!this.pushCorner(polygon, 2)) return false;
} else if (pos1.x === bounds.maxX && pos2.y === bounds.maxY) {
if (!this.pushCorner(polygon, 3)) return false;
} else if (pos1.x === bounds.minX && pos2.x === bounds.maxX) {
if (!this.pushCorner(polygon, 0)) return false;
if (!this.pushCorner(polygon, 2)) return false;
} else if (pos1.y === bounds.maxY && pos2.y === bounds.minY) {
if (!this.pushCorner(polygon, 1)) return false;
if (!this.pushCorner(polygon, 0)) return false;
} else if (pos1.y === bounds.minY && pos2.y === bounds.maxY) {
if (!this.pushCorner(polygon, 2)) return false;
if (!this.pushCorner(polygon, 3)) return false;
} else if (pos1.x === bounds.maxX && pos2.x === bounds.minX) {
if (!this.pushCorner(polygon, 3)) return false;
if (!this.pushCorner(polygon, 1)) return false;
}
polygon.push(pos2);
return true;
};
EncounterEffect.pushCorner = function (polygon, c) {
if (!this._cornerFlag[c]) {
polygon.push(this.getCornerPoint(c));
this._cornerFlag[c] = polygon;
return true;
}
return false;
};
EncounterEffect.getCornerPoint = function (c) {
const bounds = this.windowBounds;
return new Point(
c === 0 || c === 1 ? bounds.minX : bounds.maxX,
c === 0 || c === 2 ? bounds.minY : bounds.maxY
);
};
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 cx = Graphics.width / 2;
const cy = Graphics.height / 2;
switch (direction) {
case "left":
return (p) => {
return p.x;
};
case "center":
return (p) => {
return Math.abs(cx - p.x);
};
case "right":
return (p) => {
return -p.x;
};
case "inside":
return (p) => {
return Math.abs(cx - p.x) + (Math.abs(cy - p.y) * cy) / cx;
};
case "outside":
return (p) => {
return -Math.abs(cx - p.x) - (Math.abs(cy - p.y) * cy) / cx;
};
}
return null;
};
EncounterEffect.breakFragments = function (start, end, duration) {
this._fragments
.slice(start, end)
.forEach((fragment) => fragment.onBreak(this._color, duration));
};
EncounterEffect.onClip = function (polygon, rect) {
const context = this.snap.context;
context.save();
context.beginPath();
polygon.forEach((point, i) => {
i === 0
? context.moveTo(point.x, point.y)
: context.lineTo(point.x, point.y);
});
context.closePath();
context.clip();
context.clearRect(rect.x, rect.y, rect.width, rect.height);
context.restore();
this.snap._baseTexture.update();
};
EncounterEffect.onBreakEnd = function () {
this.snap.fillAll("black");
this._fragments.forEach((fragment) => fragment.clearClip());
};
EncounterEffect.onBattleStart = function () {
const { "Move Duration": duration = 60, "Scatter Duration": delay = 0 } =
this._params;
this.startFragments(duration);
this.setFragmentsDelay(delay);
this._opacityDuration = duration;
};
EncounterEffect.startFragments = function (duration) {
switch (this._type) {
case 1:
this._fragments.forEach((f) => f.onBattleStartT1(duration));
this.opacity = 300;
break;
case 2: {
const d = this._params["Scatter Direction"] || "left";
this.sortFragment(d);
this._fragments.forEach((f) => f.onBattleStartT2(duration, d));
this.opacity = 640;
break;
}
case 3:
this.sortFragment("inside");
this._fragments.forEach((f) => f.onBattleStartT3(duration));
this.opacity = 640;
break;
}
};
EncounterEffect.setFragmentsDelay = function (delay) {
const maxItems = this.maxItems();
this._fragments.forEach((fragment, i) => {
fragment.setDelay(Math.floor((delay * i) / maxItems));
});
};
EncounterEffect.update = function () {
if (this.isRunning()) {
this._fragments.forEach((fragment) => fragment.update());
this.updateOpacity();
if (this.opacity === 0) {
this.destroy();
this.clear();
}
}
};
EncounterEffect.updateOpacity = function () {
if (this._opacityDuration > 0) {
const d = this._opacityDuration;
this.opacity *= (d - 1) / d;
this._opacityDuration--;
}
};
EncounterEffect.maxItems = function () {
return this._fragments ? this._fragments.length : 0;
};
EncounterEffect.fragments = function () {
return this._fragments || [];
};
EncounterEffect.isValid = function () {
return !!this.params();
};
EncounterEffect.isRunning = function () {
return !!this._fragments;
};
EncounterEffect.isReady = function () {
return !this.isRunning() || this._opacityDuration < 45;
};
EncounterEffect.breakDuration = function () {
return this._params ? this._params["Break Duration"] || 45 : 45;
};
EncounterEffect.effectSpeed = function () {
const d = this._params ? this._params["Interval Duration"] || 45 : 45;
return this.breakDuration() + d;
};
EncounterEffect.fadeSpeed = function () {
return this._params
? Math.min(this._params["Move Duration"] || 60, 60)
: 60;
};
EncounterEffect.startEffectDelay = function () {
this._effectDelay = 4;
};
EncounterEffect.updateEffectDelay = function () {
if (this._effectDelay > 0) this._effectDelay--;
};
EncounterEffect.isEffectReady = function () {
return this._effectDelay === 0;
};
//-------------------------------------------------------------------------
// Encounter_Fragment
function Encounter_Fragment() {
this.initialize(...arguments);
}
if (_importedPlugin(...pluginOptions)) {
window.Encounter_Fragment = Encounter_Fragment;
}
Encounter_Fragment.prototype.initialize = function (polygon) {
this._polygon = polygon;
this.initRect();
this._flash = false;
this._clip = false;
this._delay = 0;
this.visible = false;
};
Encounter_Fragment.prototype.initRect = function () {
const polygon = this._polygon;
const allX = polygon.map((point) => point.x);
const allY = polygon.map((point) => point.y);
const rect = new Rectangle();
rect.x = Math.min(...allX);
rect.y = Math.min(...allY);
rect.width = Math.max(...allX) - rect.x;
rect.height = Math.max(...allY) - rect.y;
this._rect = rect;
};
Encounter_Fragment.prototype.createBitmap = function () {
const rect = this._rect;
const zoom = EncounterEffect.zoom();
const bw = Math.ceil(rect.width / zoom) + 2;
const bh = Math.ceil(rect.height / zoom) + 2;
this.bitmap = new Bitmap(bw, bh);
this.bitmap.smooth = true;
};
Encounter_Fragment.prototype.initPolygon = function () {
const polygon = this._polygon;
const rect = this._rect;
const zoom = EncounterEffect.zoom();
const context = this.bitmap.context;
context.translate(-rect.x / zoom + 1, -rect.y / zoom + 1);
context.beginPath();
polygon.forEach((point, i) => {
i === 0
? context.moveTo(point.x / zoom, point.y / zoom)
: context.lineTo(point.x / zoom, point.y / zoom);
});
context.closePath();
};
Encounter_Fragment.prototype.initPosition = function () {
const rect = this._rect;
this.x = rect.x + Math.floor(rect.width / 2);
this.y = rect.y + Math.floor(rect.height / 2);
this.jumpHeight = 0;
this._targetX = 0;
this._targetY = 0;
this._zoom = EncounterEffect.zoom();
this._targetZoom = this._zoom;
this._moveDuration = 0;
};
Encounter_Fragment.prototype.initRotation = function () {
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._rotationSpeedX *= Math.random() < 0.5 ? -1 : 1;
this._rotationSpeedY = 0;
} else {
this._rotationSpeedX = 0;
this._rotationSpeedY = (Math.random() + 0.5) * 2 * rate;
this._rotationSpeedY *= Math.random() < 0.5 ? -1 : 1;
}
this._rotationSpeedZ = (Math.random() - 0.5) * 2 * rate;
};
Encounter_Fragment.prototype.destroy = function () {
this.bitmap.destroy();
};
Encounter_Fragment.prototype.isValid = function () {
return this._rect.width > 4 && this._rect.height > 4;
};
Encounter_Fragment.prototype.clearFlash = function () {
this._flash = false;
};
Encounter_Fragment.prototype.isFlashRequested = function () {
return !!this._flash;
};
Encounter_Fragment.prototype.needClip = function () {
return !Utils.isMobileDevice();
};
Encounter_Fragment.prototype.clearClip = function () {
this._clip = false;
};
Encounter_Fragment.prototype.isClipRequested = function () {
return !!this._clip;
};
Encounter_Fragment.prototype.lineWidth = function () {
return 4;
};
Encounter_Fragment.prototype.flashOpacity = function () {
return 255;
};
Encounter_Fragment.prototype.breakRate = function () {
return 1;
};
Encounter_Fragment.prototype.slideRate = function () {
return 1;
};
Encounter_Fragment.prototype.rotationRate = function () {
return 1;
};
Encounter_Fragment.prototype.flashColor = function () {
const color = [...EncounterEffect.color()];
color[3] = this.flashOpacity();
return color;
};
Encounter_Fragment.prototype.setup = function (snap) {
this.createBitmap();
this.initPolygon();
this.initPosition();
this.initRotation();
this.setupSnap(snap);
};
Encounter_Fragment.prototype.setupSnap = function (snap) {
const rect = this._rect;
const zoom = EncounterEffect.zoom();
const context = this.bitmap.context;
context.save();
context.clip();
let sx = rect.x;
let sy = rect.y;
switch (EncounterEffect.type()) {
case 1: {
const center = EncounterEffect.center;
const radian = Math.atan2(this.y - center.y, this.x - center.x);
sx -= 20 * Math.cos(radian) * this.slideRate();
sy -= 20 * Math.sin(radian) * this.slideRate();
break;
}
case 2:
case 3: {
const bounds = EncounterEffect.windowBounds;
sx += (Math.randomInt(21) - 10) * this.slideRate();
sy += (Math.randomInt(21) - 10) * this.slideRate();
sx = sx.clamp(bounds.minX, bounds.maxX - rect.width);
sy = sy.clamp(bounds.minY, bounds.maxY - rect.height);
break;
}
}
const dx = rect.x / zoom;
const dy = rect.y / zoom;
const dw = rect.width / zoom;
const dh = rect.height / zoom;
context.drawImage(
snap.canvas,
sx,
sy,
rect.width,
rect.height,
dx,
dy,
dw,
dh
);
context.restore();
this.bitmap.baseTexture.update();
};
Encounter_Fragment.prototype.onBreak = function (color, duration) {
this.drawLine(color);
this.startEncounter(duration);
this._flash = true;
this._clip = true;
this.visible = true;
};
Encounter_Fragment.prototype.onClip = function () {
if (this.needClip()) EncounterEffect.onClip(this._polygon, this._rect);
};
Encounter_Fragment.prototype.drawLine = function (color) {
const lineWidth = this.lineWidth();
if (lineWidth > 0) {
const context = this.bitmap.context;
context.lineWidth = lineWidth / EncounterEffect.zoom();
context.strokeStyle = "rgb(%1,%2,%3)".format(...color);
context.globalAlpha = 0.5;
context.stroke();
context.globalAlpha = 1;
}
};
Encounter_Fragment.prototype.update = function () {
if (this.visible && this.updateDelay()) {
this.updateMove();
this.updateRotation();
}
};
Encounter_Fragment.prototype.updateDelay = function () {
if (this._delay > 0) {
this._delay--;
return false;
}
return true;
};
Encounter_Fragment.prototype.updateMove = function () {
if (this._moveDuration > 0) {
const d = this._moveDuration;
const triangular = (n) => (n * (n + 1)) / 2;
switch (EncounterEffect.type()) {
case 1:
this.updateRateMove(d / triangular(d));
break;
case 2: {
const n = this._moveMax - d;
const max = triangular(this._moveMax) - triangular(n);
this.updateRateMove((n + 1) / max);
break;
}
case 3: {
const rate = d / triangular(d);
this.updateRateMove(rate);
this._zoom += (this._targetZoom - this._zoom) * rate;
const m = (4 * (d - 1)) / this._moveMax;
this.jumpHeight = (2 * 2 - Math.pow(m - 2, 2)) * 96;
this.visible = this._zoom < 8;
break;
}
}
this._moveDuration--;
}
};
Encounter_Fragment.prototype.updateRateMove = function (rate) {
this.x += (this._targetX - this.x) * rate;
this.y += (this._targetY - this.y) * rate;
};
Encounter_Fragment.prototype.updateRotation = function () {
if (this._speed > 0) {
if (this._pace > 0) this._speed *= 1.18;
else if (this._pace < 0) this._speed *= 0.96;
this._rotationX += this._rotationSpeedX * this._speed;
this._rotationY += this._rotationSpeedY * this._speed;
this._rotationZ += this._rotationSpeedZ * this._speed;
}
};
Encounter_Fragment.prototype.startEncounter = function (duration) {
const breakRate = this.breakRate();
switch (EncounterEffect.type()) {
case 1:
this._moveDuration = duration;
this._speed = this.hypotSpeed(1.5);
this._pace = -1;
this.setMoveT1(breakRate / 100, breakRate / 100);
break;
case 2:
case 3:
this._moveDuration = 0;
this._speed = 0.2;
this._pace = -1;
break;
}
this._speed *= breakRate;
};
Encounter_Fragment.prototype.onBattleStartT1 = function (d) {
this._moveDuration = d;
this._speed = this.hypotSpeed(40);
this._pace = -1;
this.setMoveT1(0.75 + Math.random() / 2, 0.75 + Math.random() / 2);
};
Encounter_Fragment.prototype.hypotSpeed = function (baseSpeed) {
const { x: cx, y: cy } = EncounterEffect.center;
return baseSpeed / Math.sqrt(Math.hypot(this.x - cx, this.y - cy));
};
Encounter_Fragment.prototype.setMoveT1 = function (rateX, rateY) {
const bounds = EncounterEffect.windowBounds;
const { x: cx, y: cy } = EncounterEffect.center;
const sx = this.x - cx;
const sy = this.y - cy;
let ox = sx;
let oy = sy;
if (ox < 0) {
oy *= (bounds.minX - cx) / ox;
ox = bounds.minX - cx;
} else if (ox > 0) {
oy *= (bounds.maxX - cx) / ox;
ox = bounds.maxX - cx;
}
if (oy < bounds.minY - cy) {
ox *= (bounds.minY - cy) / oy;
oy = bounds.minY - cy;
} else if (oy > bounds.maxY - cy) {
ox *= (bounds.maxY - cy) / oy;
oy = bounds.maxY - cy;
}
this._targetX = this.x + (ox - sx) * rateX;
this._targetY = this.y + (oy - sy) * rateY;
};
Encounter_Fragment.prototype.onBattleStartT2 = function (
duration,
direction
) {
this._moveDuration = Math.floor(duration / 2);
this._moveMax = this._moveDuration;
this._speed = 1.6;
this._pace = -1;
this.setMoveT2(direction);
};
Encounter_Fragment.prototype.setMoveT2 = function (direction) {
const cx = Graphics.width / 2;
const cy = Graphics.height / 2;
switch (direction) {
case "left":
this._targetX = this.x - Graphics.width;
this._targetY = this.y + (this.y - cy) * 1.0;
break;
case "right":
this._targetX = this.x + Graphics.width;
this._targetY = this.y + (this.y - cy) * 1.0;
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;
}
}
};
Encounter_Fragment.prototype.onBattleStartT3 = function (duration) {
this._moveDuration = duration;
this._moveMax = duration;
this._speed = 2;
this._pace = 0;
this.setMoveT3();
};
Encounter_Fragment.prototype.setMoveT3 = function () {
const cx = Graphics.width / 2;
const cy = Graphics.height / 2;
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._targetZoom = delta < 128 && Math.random() < 0.4 ? 12 : 1;
this._targetZoom += 3 * Math.random();
};
Encounter_Fragment.prototype.setDelay = function (delay) {
this._delay = delay;
};
Encounter_Fragment.prototype.scaleX = function () {
return Math.cos((this._rotationX * Math.PI) / 180) * this._zoom;
};
Encounter_Fragment.prototype.scaleY = function () {
return Math.cos((this._rotationY * Math.PI) / 180) * this._zoom;
};
Encounter_Fragment.prototype.rotation = function () {
return (this._rotationZ * Math.PI) / 180;
};
//-----------------------------------------------------------------------------
// Bitmap
if (Utils.RPGMAKER_NAME === "MV") {
Bitmap.prototype.destroy = function () {
if (this._baseTexture) {
this._baseTexture.destroy();
this.__baseTexture = null;
}
this._destroyCanvas();
};
Bitmap.prototype._destroyCanvas = function () {
if (this._canvas) {
this._canvas.width = 0;
this._canvas.height = 0;
this.__canvas = null;
}
};
}
//-----------------------------------------------------------------------------
// SceneManager
const _SceneManager_update = SceneManager.update;
SceneManager.update = function () {
_SceneManager_update.apply(this, arguments);
EncounterEffect.updateEffectDelay();
};
const _SceneManager_determineRepeatNumber =
SceneManager.determineRepeatNumber;
SceneManager.determineRepeatNumber = function (deltaTime) {
if (EncounterEffect.isRunning()) {
this._smoothDeltaTime *= 0.8;
this._smoothDeltaTime += Math.min(deltaTime, 5) * 0.2; //2to5
if (this._smoothDeltaTime >= 0.9) {
this._elapsedTime = 0;
return Math.round(this._smoothDeltaTime);
} else {
this._elapsedTime += deltaTime;
if (this._elapsedTime >= 1) {
this._elapsedTime -= 1;
return 1;
}
return 0;
}
}
return _SceneManager_determineRepeatNumber.apply(this, arguments);
};
//-------------------------------------------------------------------------
// PluginManager
PluginManager._commands = PluginManager._commands || {};
if (!PluginManager.registerCommand) {
PluginManager.registerCommand = function (pluginName, commandName, func) {
const key = pluginName + ":" + commandName;
this._commands[key] = func;
};
}
if (!PluginManager.callCommand) {
PluginManager.callCommand = function (self, pluginName, commandName, args) {
const key = pluginName + ":" + commandName;
const func = this._commands[key];
if (typeof func === "function") {
func.bind(self)(args);
}
};
}
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;
};
//-----------------------------------------------------------------------------
// Game_Interpreter
const _mzCommands = {
EncEffType: { name: "setType", keys: ["type"] },
EncEffChar: { name: "setCharacter", keys: ["character"] },
EncEffColor: { name: "setColor", keys: [], join: "color" },
};
Object.assign(_mzCommands, {
エフェクトタイプ変更: _mzCommands.EncEffType,
中心キャラ指定: _mzCommands.EncEffChar,
エフェクト色指定: _mzCommands.EncEffColor,
});
const _Game_Interpreter_pluginCommand =
Game_Interpreter.prototype.pluginCommand;
Game_Interpreter.prototype.pluginCommand = function (command, args) {
_Game_Interpreter_pluginCommand.apply(this, arguments);
const mzCommand = _mzCommands[command];
if (mzCommand) {
const args2 = Object.assign(
...mzCommand.keys.map((k, i) => ({ [k]: args[i] }))
);
if (mzCommand.join) args2[mzCommand.join] = args.join();
PluginManager.callCommand(this, pluginName, mzCommand.name, args2);
}
};
//-----------------------------------------------------------------------------
// Sprite
if (Utils.RPGMAKER_NAME === "MZ" && !_importedPlugin("MPP_PatchMZ")) {
Sprite.prototype._removeColorFilter = function () {
if (this._colorFilter) {
this.filters.remove(this._colorFilter);
this._colorFilter = null;
}
};
const _Sprite__updateColorFilter = Sprite.prototype._updateColorFilter;
Sprite.prototype._updateColorFilter = function () {
if (
this._hue === 0 &&
this._blendColor[3] === 0 &&
this._colorTone.equals([0, 0, 0, 0])
) {
this._removeColorFilter();
} else {
_Sprite__updateColorFilter.apply(this, arguments);
}
};
}
//-----------------------------------------------------------------------------
// Sprite_Fragment
function Sprite_Fragment() {
this.initialize(...arguments);
}
Sprite_Fragment.prototype = Object.create(Sprite.prototype);
Sprite_Fragment.prototype.constructor = Sprite_Fragment;
Sprite_Fragment.prototype.initialize = function (fragment) {
this._fragment = fragment;
Sprite.prototype.initialize.call(this, fragment.bitmap);
this.anchor.x = 0.5;
this.anchor.y = 0.5;
this.clearFlash();
this.setupRate();
this.update();
};
Sprite_Fragment.prototype.clearFlash = function () {
this._flashColor = [0, 0, 0, 0];
this._flashDuration = 0;
};
Sprite_Fragment.prototype.setupRate = function () {
this._rate = Utils.isMobileDevice() ? 6 : 8;
};
Sprite_Fragment.prototype.update = function () {
Sprite.prototype.update.call(this);
this.updatePosition();
this.updateScale();
this.updateRotation();
this.updateFlash();
this.updateClip();
this.updateVisibility();
};
Sprite_Fragment.prototype.updatePosition = function () {
const fragment = this._fragment;
this.x = fragment.x;
this.y = fragment.y - fragment.jumpHeight;
};
Sprite_Fragment.prototype.updateScale = function () {
const fragment = this._fragment;
this.scale.x = fragment.scaleX();
this.scale.y = fragment.scaleY();
};
Sprite_Fragment.prototype.updateRotation = function () {
this.rotation = this._fragment.rotation();
};
Sprite_Fragment.prototype.updateFlash = function () {
this.setupFlash();
if (this._flashDuration > 0) {
const d = this._flashDuration--;
this._flashColor[3] *= (d - 1) / d;
if (this._flashDuration % this._rate === 0) {
this.setBlendColor(this._flashColor);
}
}
};
Sprite_Fragment.prototype.setupFlash = function () {
if (this._fragment.isFlashRequested()) {
this._flashDuration = Utils.isMobileDevice() ? 13 : 25;
this._flashColor = this._fragment.flashColor();
this._fragment.clearFlash();
}
};
Sprite_Fragment.prototype.updateClip = function () {
if (this._fragment.isClipRequested()) {
this._fragment.onClip();
this._fragment.clearClip();
}
};
Sprite_Fragment.prototype.updateVisibility = function () {
this.visible = this._fragment.visible;
};
//-----------------------------------------------------------------------------
// Sprite_EncounterEffect
function Sprite_EncounterEffect() {
this.initialize(...arguments);
}
Sprite_EncounterEffect.prototype = Object.create(Sprite.prototype);
Sprite_EncounterEffect.prototype.constructor = Sprite_EncounterEffect;
Sprite_EncounterEffect.prototype.initialize = function () {
Sprite.prototype.initialize.call(this);
this.createBackSprite();
this.createFragments();
this._fadeDelay = 0;
this._fadeDuration = 0;
};
Sprite_EncounterEffect.prototype.createBackSprite = function () {
this._backSprite = new Sprite(EncounterEffect.snap);
this.addChild(this._backSprite);
};
Sprite_EncounterEffect.prototype.createFragments = function () {
this._fragmentSprites = [];
const fragments = EncounterEffect.fragments();
for (let i = 0; i < fragments.length; i++) {
const sprite = new Sprite_Fragment(fragments[i]);
this._fragmentSprites[i] = sprite;
this.addChild(sprite);
}
};
Sprite_EncounterEffect.prototype.startFadeIn = function (duration) {
const rate = 3; //Utils.isMobileDevice() ? 2 : 3;
this._fadeDelay = Math.floor(duration / rate);
this._fadeDuration = duration - this._fadeDelay;
};
Sprite_EncounterEffect.prototype.update = function () {
Sprite.prototype.update.call(this);
this.opacity = EncounterEffect.opacity;
this.updateFadeIn();
};
Sprite_EncounterEffect.prototype.updateFadeIn = function () {
if (this._fadeDuration > 0 && this.updateFadeDelay()) {
const d = this._fadeDuration;
this._backSprite.opacity -= this._backSprite.opacity / d;
this._fadeDuration--;
}
};
Sprite_EncounterEffect.prototype.updateFadeDelay = function () {
if (this._fadeDelay > 0) {
this._fadeDelay--;
return false;
}
return true;
};
Sprite_EncounterEffect.prototype.isSpritesetVisible = function () {
return this.opacity < 255 || this._backSprite.opacity < 255;
};
//-----------------------------------------------------------------------------
// 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.temporaryHideDestination = function () {
this._destinationSprite.visible = false;
};
//-----------------------------------------------------------------------------
// Scene_Base
Scene_Base.prototype.createEncEffSprite = function () {
this._encEffSprite = new Sprite_EncounterEffect();
this.addChild(this._encEffSprite);
};
Scene_Base.prototype.destroyEncEffSprite = function () {
this.removeChild(this._encEffSprite);
if (Utils.RPGMAKER_NAME === "MZ") this._encEffSprite.destroy();
delete this._encEffSprite;
};
Scene_Base.prototype.clearFade = function () {
this._fadeSign = 0;
this._fadeDuration = 0;
this._fadeWhite = 0;
this._fadeOpacity = 0;
if (Utils.RPGMAKER_NAME === "MV") {
this._fadeSprite.opacity = 0;
} else {
this.updateColorFilter();
}
};
//-----------------------------------------------------------------------------
// Scene_Map
const _Scene_Map_launchBattle = Scene_Map.prototype.launchBattle;
Scene_Map.prototype.launchBattle = function () {
if (EncounterEffect.isValid()) {
this.snapForBattleBackground();
this._windowLayer.visible = false;
this._spriteset.temporaryHideDestination();
EncounterEffect.setup(SceneManager.snap());
_Scene_Map_launchBattle.apply(this, arguments);
this.createEncEffSprite();
this._spriteset.visible = false;
} else {
EncounterEffect.clear();
_Scene_Map_launchBattle.apply(this, arguments);
}
};
const _Scene_Map_updateEncounterEffect =
Scene_Map.prototype.updateEncounterEffect;
Scene_Map.prototype.updateEncounterEffect = function () {
if (EncounterEffect.isRunning()) {
if (!EncounterEffect.isEffectReady()) return;
if (this._encounterEffectDuration > 0) {
EncounterEffect.update();
this._encounterEffectDuration--;
const speed = this.encounterEffectSpeed();
const n = speed - this._encounterEffectDuration;
const breakEnd = EncounterEffect.breakDuration();
if (n <= breakEnd) {
const maxItems = EncounterEffect.maxItems();
const start = Math.floor((maxItems * (n - 1)) / breakEnd);
const end = Math.floor((maxItems * n) / breakEnd);
EncounterEffect.breakFragments(start, end, speed);
}
if (n === breakEnd) {
EncounterEffect.onBreakEnd();
}
if (n === Math.floor(speed / 5)) {
BattleManager.playBattleBgm();
}
if (n === speed && !ImageManager.isReady()) {
this._encounterEffectDuration = 1;
}
}
} else {
_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_Battle
const _Scene_Battle_create = Scene_Battle.prototype.create;
Scene_Battle.prototype.create = function () {
_Scene_Battle_create.apply(this, arguments);
if (EncounterEffect.isRunning()) {
EncounterEffect.startEffectDelay();
}
};
const _Scene_Battle_start = Scene_Battle.prototype.start;
Scene_Battle.prototype.start = function () {
_Scene_Battle_start.apply(this, arguments);
if (EncounterEffect.isRunning()) {
this.clearFade();
EncounterEffect.onBattleStart();
this.createEncEffSprite();
this._encEffSprite.startFadeIn(EncounterEffect.fadeSpeed());
}
};
const _Scene_Battle_update = Scene_Battle.prototype.update;
Scene_Battle.prototype.update = function () {
_Scene_Battle_update.apply(this, arguments);
if (EncounterEffect.isRunning() && EncounterEffect.isEffectReady()) {
EncounterEffect.update();
this._spriteset.visible = this._encEffSprite.isSpritesetVisible();
if (!EncounterEffect.isRunning()) {
this.destroyEncEffSprite();
}
}
};
})();