1510 lines
54 KiB
JavaScript
1510 lines
54 KiB
JavaScript
//=============================================================================
|
||
// MPP_Pseudo3DBattle.js
|
||
//=============================================================================
|
||
// Copyright (c) 2021 Mokusei Penguin
|
||
// Released under the MIT license
|
||
// http://opensource.org/licenses/mit-license.php
|
||
//=============================================================================
|
||
|
||
/*:
|
||
* @target MZ
|
||
* @plugindesc A function to move the camera three-dimensionally during battle is added.
|
||
* @author Mokusei Penguin
|
||
* @url
|
||
*
|
||
* @help [version 1.3.0]
|
||
* This plugin is for RPG Maker MZ.
|
||
*
|
||
* ※ Note
|
||
* 1. This plugin is not compatible with plugins that move or change
|
||
* the shape of combat characters. We cannot handle conflicts
|
||
* with such plugins.
|
||
* 2. Due to the fact that 2D images are used originally,
|
||
* not all images can be supported.
|
||
* 3. If you place an enemy character in the lower left (or lower right),
|
||
* you may see the edges of the background. Avoid placement or adjust
|
||
* with plugin parameters.
|
||
* 4. If you want to change the movement of the camera,
|
||
* modify the code directly.
|
||
*
|
||
* ▼ Plugin command
|
||
* - In the item to enter a numerical value, select the text and
|
||
* write v[N] to refer to the variable N.
|
||
*
|
||
* 〇 enemyFocus
|
||
* - The viewpoint moves so that the specified enemy is near the center.
|
||
*
|
||
* 〇 actorFocus
|
||
* - The viewpoint moves so that the specified actor is near the center.
|
||
*
|
||
* 〇 moveHome
|
||
* - Move to the viewpoint at the beginning of the battle.
|
||
*
|
||
* ================================
|
||
* Mail : wood_penguin@yahoo.co.jp (@ is half-width)
|
||
* Blog : http://woodpenguin.blog.fc2.com/
|
||
* License : MIT license
|
||
*
|
||
* @command enemyFocus
|
||
* @desc
|
||
* @arg index
|
||
* @desc -1:Entire Troop
|
||
* @type number
|
||
* @min -1
|
||
* @max 7
|
||
* @default 0
|
||
* @arg scale
|
||
* @desc 100:1x
|
||
* @type number
|
||
* @min 50
|
||
* @max 150
|
||
* @default 100
|
||
* @arg duration
|
||
* @desc
|
||
* @type number
|
||
* @min 0
|
||
* @max 999
|
||
* @default 60
|
||
*
|
||
* @command actorFocus
|
||
* @desc
|
||
* @arg id
|
||
* @text ID
|
||
* @desc 0:Entire Party
|
||
* @type number
|
||
* @min 0
|
||
* @max 999
|
||
* @default 1
|
||
* @arg scale
|
||
* @desc 100:1x
|
||
* @type number
|
||
* @min 50
|
||
* @max 150
|
||
* @default 100
|
||
* @arg duration
|
||
* @desc
|
||
* @type number
|
||
* @min 0
|
||
* @max 999
|
||
* @default 60
|
||
*
|
||
* @command moveHome
|
||
* @desc
|
||
* @arg duration
|
||
* @desc
|
||
* @type number
|
||
* @min 0
|
||
* @max 999
|
||
* @default 60
|
||
*
|
||
*
|
||
*
|
||
* @param Battleback Scale
|
||
* @desc Increase the value slightly only if you can see the edges of the background.
|
||
* @type number
|
||
* @min 1.0
|
||
* @max 9.9
|
||
* @decimals 1
|
||
* @default 1.3
|
||
*
|
||
* @param Drift Delay
|
||
* @desc No changes are needed unless you have a good reason.
|
||
* @type number
|
||
* @min 0
|
||
* @max 999
|
||
* @default 120
|
||
*
|
||
* @param Battleback2 Pivot Y Fixes
|
||
* @desc If you don't like the position of the origin Y in the battle background, set it.
|
||
* @type struct<Battleback>[]
|
||
* @default ["{\"Battleback2 Image\":\"Town2\",\"Pivot Y\":\"182\"}"]
|
||
*
|
||
*/
|
||
|
||
/*~struct~Battleback:
|
||
* @param Battleback2 Image
|
||
* @desc
|
||
* @type file
|
||
* @require 1
|
||
* @dir img/battlebacks2
|
||
* @default
|
||
*
|
||
* @param Pivot Y
|
||
* @desc
|
||
* @type number
|
||
* @min 1
|
||
* @max 9999
|
||
* @default 256
|
||
*
|
||
*/
|
||
|
||
/*:ja
|
||
* @target MZ
|
||
* @plugindesc 戦闘中、立体的にカメラが移動する機能が追加されます。
|
||
* @author 木星ペンギン
|
||
* @url
|
||
*
|
||
* @help [version 1.3.0]
|
||
* このプラグインはRPGツクールMZ用です。
|
||
*
|
||
* ※ 注意
|
||
* 1. 本プラグインは戦闘キャラを移動させたり、形を変えるプラグインとの相性は
|
||
* よくないです。そういったプラグインとの競合には対応できません。
|
||
* 2. もともと2D用の画像を使用している都合上、全ての画像には対応できていません。
|
||
* 3. 敵キャラを左下(または右下)に配置すると、背景の端が見えることがあります。
|
||
* 配置を避けるか、プラグインパラメータで調整してください。
|
||
* 4. カメラの動きを変更したい場合は、直接コードを修正してください。
|
||
*
|
||
* ▼ プラグインコマンド
|
||
* - 数値を入力する項目で、テキストを選択して v[N] と記述することで
|
||
* 変数N番を参照します。
|
||
*
|
||
* 〇 敵キャラフォーカス / enemyFocus
|
||
* - 指定した敵キャラが中央付近に来るように視点が移動します。
|
||
*
|
||
* 〇 アクターフォーカス / actorFocus
|
||
* - 指定したアクターが中央付近に来るように視点が移動します。
|
||
*
|
||
* 〇 ホームに移動 / moveHome
|
||
* - 戦闘開始時の視点に移動します。
|
||
*
|
||
* ================================
|
||
* Mail : wood_penguin@yahoo.co.jp (@は半角)
|
||
* Blog : http://woodpenguin.blog.fc2.com/
|
||
* License : MIT license
|
||
*
|
||
* @command enemyFocus
|
||
* @text 敵キャラフォーカス
|
||
* @desc
|
||
* @arg index
|
||
* @text インデックス
|
||
* @desc -1:敵全体
|
||
* @type number
|
||
* @min -1
|
||
* @max 7
|
||
* @default 0
|
||
* @arg scale
|
||
* @text 拡大率
|
||
* @desc 100:等倍
|
||
* @type number
|
||
* @min 50
|
||
* @max 150
|
||
* @default 100
|
||
* @arg duration
|
||
* @text 時間
|
||
* @desc
|
||
* @type number
|
||
* @min 0
|
||
* @max 999
|
||
* @default 60
|
||
*
|
||
* @command actorFocus
|
||
* @text アクターフォーカス
|
||
* @desc
|
||
* @arg id
|
||
* @text ID
|
||
* @desc 0:味方全体
|
||
* @type number
|
||
* @min 0
|
||
* @max 999
|
||
* @default 1
|
||
* @arg scale
|
||
* @text 拡大率
|
||
* @desc 100:等倍
|
||
* @type number
|
||
* @min 50
|
||
* @max 150
|
||
* @default 100
|
||
* @arg duration
|
||
* @text 時間
|
||
* @desc
|
||
* @type number
|
||
* @min 0
|
||
* @max 999
|
||
* @default 60
|
||
*
|
||
* @command moveHome
|
||
* @text ホームに移動
|
||
* @desc
|
||
* @arg duration
|
||
* @text 時間
|
||
* @desc
|
||
* @type number
|
||
* @min 0
|
||
* @max 999
|
||
* @default 60
|
||
*
|
||
*
|
||
* @param Battleback Scale
|
||
* @text 戦闘背景 拡大率
|
||
* @desc 背景の端が見えてしまう場合に限り、値を少し上げてください。
|
||
* @type number
|
||
* @min 1.0
|
||
* @max 9.9
|
||
* @decimals 1
|
||
* @default 1.3
|
||
*
|
||
* @param Drift Delay
|
||
* @text ドリフトディレイ
|
||
* @desc 理由がない限り、変更の必要はありません。
|
||
* @type number
|
||
* @min 0
|
||
* @max 999
|
||
* @default 120
|
||
*
|
||
* @param Battleback2 Pivot Y Fixes
|
||
* @text 戦闘背景2 原点Y修正
|
||
* @desc 戦闘背景の原点Yの位置が気に入らない場合、設定してください。
|
||
* @type struct<Battleback>[]
|
||
* @default ["{\"Battleback2 Image\":\"Town2\",\"Pivot Y\":\"182\"}"]
|
||
*
|
||
*/
|
||
|
||
/*~struct~Battleback:ja
|
||
* @param Battleback2 Image
|
||
* @text 戦闘背景2 画像
|
||
* @desc
|
||
* @type file
|
||
* @require 1
|
||
* @dir img/battlebacks2
|
||
* @default
|
||
*
|
||
* @param Pivot Y
|
||
* @text 原点Y
|
||
* @desc
|
||
* @type number
|
||
* @min 1
|
||
* @max 9999
|
||
* @default 256
|
||
*
|
||
*/
|
||
|
||
/**
|
||
* ▼ プラグイン製作者さん向け - 疑似3D表示への対応方法
|
||
* - Spriteset_Battle の this._effectsContainer.children に入っている
|
||
* スプライト系オブジェクトは、自動的に3D表示にします。
|
||
*
|
||
* 〇 変数 _pseudo3dType
|
||
* - スプライトの _pseudo3dType という変数を使用することで、
|
||
* 以下のように表示方法を指定することができます。
|
||
* 'obj' : 2D表示時の x, y をもとに、3D用の x, y, scale が設定されます。
|
||
* 本プラグインでは Sprite_Battler がこの設定になっています。
|
||
* 'excl' : 3D表示に対応しません。
|
||
* 上記以外 : 2D表示時の x, y をもとに、3D用の x, y が設定されます。
|
||
* Sprite_Damage のように拡大率を変更しない表示物用の設定です。
|
||
*
|
||
* 〇 メソッド pseudo3dAltitude
|
||
* - スプライトに pseudo3dAltitude というメソッドが定義されている場合、
|
||
* その返り値が地面からの高さ(高度)として計算されます。
|
||
* - 本プラグインでは Sprite_Battler がこのメソッドを使用しています。
|
||
*
|
||
*/
|
||
|
||
(() => {
|
||
'use strict';
|
||
|
||
const pluginName = 'MPP_Pseudo3DBattle';
|
||
|
||
// Plugin Parameters
|
||
const parameters = PluginManager.parameters(pluginName);
|
||
const reviverParse = function(key, value) {
|
||
try {
|
||
return JSON.parse(value, reviverParse);
|
||
} catch (e) {
|
||
return value;
|
||
}
|
||
};
|
||
const param_BattlebackScale = Number(parameters['Battleback Scale'] || 1.3);
|
||
const param_DriftDelay = Number(parameters['Drift Delay'] || 0);
|
||
const param_Battleback2PivotYFixes = JSON.parse(parameters['Battleback2 Pivot Y Fixes'] || '[]', reviverParse);
|
||
|
||
// プラグインの導入順によって起こる競合を回避するための関数
|
||
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); };
|
||
}
|
||
};
|
||
|
||
//-------------------------------------------------------------------------
|
||
// Pseudo3DBattle
|
||
//
|
||
// 疑似3Dの動作を管理する静的クラスです。
|
||
// 現在の仕様では外部プラグインからの上書き、及び再定義はできません。
|
||
// BattleManager から最低限のメソッドにアクセスできます。
|
||
|
||
function Pseudo3DBattle() {
|
||
throw new Error('This is a static class');
|
||
}
|
||
|
||
Pseudo3DBattle._sideViewDriftBase = { x:20, y:8, altitude:16, skew:0.2 };
|
||
Pseudo3DBattle._sideViewMoveMethods = {
|
||
// ここのメソッドは Pseudo3DBattle を this として呼び出します。
|
||
setup() {
|
||
return { altitude: 50, scale: 0.7 };
|
||
},
|
||
startBattle() {
|
||
return { duration: 150 };
|
||
},
|
||
home(duration = 60) {
|
||
return { duration, type: 'Slow start and end' };
|
||
},
|
||
inputting(user) {
|
||
const pos = this.targets2dPosition([user]);
|
||
return {
|
||
x: this.bringInsideX(pos.x),
|
||
y: pos.y,
|
||
altitude: -15,
|
||
scale: 1.1,
|
||
duration: 40
|
||
};
|
||
},
|
||
targeting(targets) {
|
||
const pos = this.targets2dPosition(targets);
|
||
if (!pos) return null;
|
||
return {
|
||
x: this.bringInsideXByRate(pos.x, 0.4),
|
||
y: this.bringInsideYByRate(pos.y, 0.4),
|
||
altitude: targets.length > 1 ? 10 : -10,
|
||
scale: targets.length > 1 ? 1 : 1.1,
|
||
duration: this.isAction() ? 12 : 30
|
||
};
|
||
},
|
||
endTargeting() {
|
||
return { duration: this.isAction() ? 12 : 30 };
|
||
},
|
||
showAnimation(targets) {
|
||
const pos = this.targets2dPosition(targets);
|
||
if (!pos) return null;
|
||
return {
|
||
x: this.bringInsideXByRate(pos.x, 0.3),
|
||
y: this.bringInsideYByRate(pos.y, 0.3),
|
||
altitude: -20,
|
||
scale: targets.length > 1 ? 1.05 : 1.1,
|
||
duration: 16
|
||
};
|
||
},
|
||
damage(target) {
|
||
const pos = this.targets2dPosition([target]);
|
||
return {
|
||
x: this.bringInsideXByRate(pos.x, 0.3),
|
||
y: this.bringInsideYByRate(pos.y, 0.3),
|
||
altitude: -20,
|
||
scale: 1.1,
|
||
duration: 30,
|
||
type: 'Slow start and end'
|
||
};
|
||
},
|
||
collapse(target) {
|
||
const pos = this.targets2dPosition([target]);
|
||
return {
|
||
x: this.bringInsideXByRate(pos.x, 0.4),
|
||
y: this.bringInsideYByRate(pos.y, 0.4),
|
||
altitude: -20,
|
||
scale: 1.13,
|
||
duration: 12
|
||
};
|
||
},
|
||
endAction(duration = 45) {
|
||
return { duration, type: 'Slow start and end' };
|
||
},
|
||
driftOn() {
|
||
return {}; // can only be used with 'isWait'
|
||
},
|
||
driftOff() {
|
||
return {}; // can only be used with 'isWait'
|
||
},
|
||
victory() {
|
||
const pos = this.targets2dPosition($gameParty.members());
|
||
if (!pos) return {};
|
||
return {
|
||
x: this.bringInsideX(pos.x),
|
||
y: pos.y,
|
||
altitude: -10,
|
||
scale: 1.15,
|
||
skew: pos.x < this.centerX() ? -0.12 : 0.12,
|
||
duration: 90,
|
||
isWait: true,
|
||
type: 'Slow start and end'
|
||
};
|
||
},
|
||
escape() {
|
||
return {
|
||
x: this.centerX(),
|
||
y: this.centerY(),
|
||
altitude: 50,
|
||
scale: 0.87,
|
||
duration: 120
|
||
};
|
||
},
|
||
defeat() {
|
||
return {
|
||
x: this.centerX(),
|
||
y: this.centerY(),
|
||
altitude: 40,
|
||
scale: 0.8,
|
||
duration: 240,
|
||
isWait: true
|
||
};
|
||
},
|
||
focus(targets, scale, duration) {
|
||
const pos = this.targets2dPosition(targets);
|
||
if (!pos) return null;
|
||
return {
|
||
x: this.bringInsideXByRate(pos.x, 0.4),
|
||
y: this.bringInsideYByRate(pos.y, 0.4),
|
||
altitude: -10,
|
||
scale,
|
||
duration
|
||
};
|
||
},
|
||
startAction: null
|
||
};
|
||
Pseudo3DBattle._frontViewDriftBase = { x:12, y:8, altitude:16, skew:0.1 };
|
||
Pseudo3DBattle._frontViewMoveMethods = {
|
||
// goma durationいじってる
|
||
// ここのメソッドは Pseudo3DBattle を this として呼び出します。
|
||
setup() {
|
||
return { y: this.centerY() + 32, altitude: -15, scale: 0.8 };
|
||
},
|
||
startBattle() {
|
||
return { duration: 120/2 };
|
||
},
|
||
home(duration = 60/2) {
|
||
return { duration, type: 'Slow start and end' };
|
||
},
|
||
showAnimation(targets) {
|
||
if (targets.length === 0 || targets[0].isActor()) {
|
||
return null;
|
||
}
|
||
const pos = this.targets2dPosition(targets);
|
||
return {
|
||
x: this.bringInsideXByRate(pos.x, 0.5),
|
||
y: this.bringInsideYByRate(pos.y, 0.1),
|
||
altitude: -5,
|
||
scale: 1.03,
|
||
duration: 30/2
|
||
};
|
||
},
|
||
endAction(duration = 45/2) {
|
||
return { duration, type: 'Slow start and end' };
|
||
},
|
||
driftOn() {
|
||
return {}; // can only be used with 'isWait'
|
||
},
|
||
driftOff() {
|
||
return {}; // can only be used with 'isWait'
|
||
},
|
||
victory() {
|
||
return {
|
||
altitude: -15,
|
||
duration: 150/2,
|
||
isWait: true,
|
||
type: 'Slow start and end'
|
||
};
|
||
},
|
||
escape() {
|
||
return {
|
||
x: this.centerX(),
|
||
y: this.centerY() + 8,
|
||
altitude: -5,
|
||
scale: 0.95,
|
||
duration: 60,
|
||
type: 'Slow start and end'
|
||
};
|
||
},
|
||
focus(targets, scale, duration) {
|
||
const pos = this.targets2dPosition(targets);
|
||
if (!pos) return null;
|
||
return {
|
||
x: this.bringInsideXByRate(pos.x, 0.4),
|
||
y: this.bringInsideYByRate(pos.y, 0.1),
|
||
altitude: -10,
|
||
scale,
|
||
duration
|
||
};
|
||
},
|
||
startAction: null
|
||
};
|
||
Pseudo3DBattle._waitMoveMethodNames = [
|
||
'startBattle', 'home', 'inputting'
|
||
];
|
||
|
||
Object.defineProperties(Pseudo3DBattle, {
|
||
moveMethods: {
|
||
get() {
|
||
if ($gameSystem.isSideView()) {
|
||
return this._sideViewMoveMethods;
|
||
} else {
|
||
return this._frontViewMoveMethods;
|
||
}
|
||
},
|
||
configurable: true
|
||
},
|
||
driftBase: {
|
||
get() {
|
||
if ($gameSystem.isSideView()) {
|
||
return this._sideViewDriftBase;
|
||
} else {
|
||
return this._frontViewDriftBase;
|
||
}
|
||
},
|
||
configurable: true
|
||
}
|
||
});
|
||
|
||
Pseudo3DBattle.initMembers = function() {
|
||
this._centerX = Graphics.boxWidth / 2;
|
||
this._centerY = Graphics.boxHeight / 2 + 32;
|
||
this._homeMoveParams = {
|
||
x: this._centerX,
|
||
y: this._centerY,
|
||
altitude: 0,
|
||
scale: 1.0,
|
||
skew: 0,
|
||
duration: 50,
|
||
type: 'Slow end'
|
||
};
|
||
this.clearBaseStatus();
|
||
this.clearMoveCommands();
|
||
this.clearMoveParams();
|
||
this.clearDriftParams();
|
||
};
|
||
|
||
Pseudo3DBattle.clearBaseStatus = function() {
|
||
this._baseDisplayX = this._centerX;
|
||
this._baseDisplayY = this._centerY;
|
||
this._baseAltitude = 0;
|
||
this._baseScale = 1.0;
|
||
this._baseSkew = 0;
|
||
};
|
||
|
||
Pseudo3DBattle.clearMoveCommands = function() {
|
||
this._commands = [];
|
||
};
|
||
|
||
Pseudo3DBattle.clearMoveParams = function() {
|
||
this._targetingMoveParams = null;
|
||
this._actionMoveParams = null;
|
||
this._waitMoveParams = {};
|
||
this._moveEasing = new Easing();
|
||
};
|
||
|
||
Pseudo3DBattle.clearDriftParams = function() {
|
||
const type = 'Slow start and end';
|
||
const delay = param_DriftDelay;
|
||
this._drift = Object.assign( ...Object.keys(this.driftBase).map(
|
||
key => ({ [key]:new EasingValue(type, delay) } )
|
||
) );
|
||
this._isDrift = true;
|
||
};
|
||
|
||
Pseudo3DBattle.onBattleStart = function() {
|
||
this.clearBaseStatus();
|
||
this.clearMoveCommands();
|
||
this.clearMoveParams();
|
||
this.clearDriftParams();
|
||
};
|
||
|
||
Pseudo3DBattle.driftOn = function() {
|
||
if (!this._isDrift) {
|
||
this._isDrift = true;
|
||
this.refreahDrift();
|
||
}
|
||
};
|
||
|
||
Pseudo3DBattle.driftOff = function() {
|
||
if (this._isDrift) {
|
||
this._isDrift = false;
|
||
this.refreahDrift();
|
||
}
|
||
};
|
||
|
||
Pseudo3DBattle.refreahDrift = function() {
|
||
for (const [key, easing] of Object.entries(this._drift)) {
|
||
this.setupDriftParams(key, easing)
|
||
}
|
||
};
|
||
|
||
Pseudo3DBattle.isAction = function() {
|
||
return !!this._actionMoveParams;
|
||
};
|
||
|
||
Pseudo3DBattle.isTargeting = function() {
|
||
return !!this._targetingMoveParams;
|
||
};
|
||
|
||
Pseudo3DBattle.centerX = function() {
|
||
return this._centerX;
|
||
};
|
||
|
||
Pseudo3DBattle.centerY = function() {
|
||
return this._centerY;
|
||
};
|
||
|
||
Pseudo3DBattle.displayX = function() {
|
||
return this._baseDisplayX + this._drift.x.current;
|
||
};
|
||
|
||
Pseudo3DBattle.displayY = function() {
|
||
return this._baseDisplayY + this._drift.y.current;
|
||
};
|
||
|
||
Pseudo3DBattle.altitude = function() {
|
||
return this._baseAltitude + this._drift.altitude.current;
|
||
};
|
||
|
||
Pseudo3DBattle.scaleX = function() {
|
||
return this._baseScale;
|
||
};
|
||
|
||
Pseudo3DBattle.scaleY = function() {
|
||
return (this._baseScale + this.altitude() / 100) / Math.cos(this.skew());
|
||
};
|
||
|
||
Pseudo3DBattle.skew = function() {
|
||
const baseSkew = this._baseSkew + this._drift.skew.current;
|
||
const deffXSkew = $gameSystem.isSideView()
|
||
? (this._centerX - this.displayX()) / 1000
|
||
: (this.displayX() - this._centerX) / 1500;
|
||
return Math.max(Math.min(baseSkew + deffXSkew, 1), -1);
|
||
};
|
||
|
||
Pseudo3DBattle.adjustPosition = function(x, y) {
|
||
const displayX = this.displayX();
|
||
const displayY = this.displayY();
|
||
const scaleX = this.scaleX();
|
||
const scaleY = this.scaleY();
|
||
const radian = this.skew();
|
||
const dy = (y - displayY) * scaleY;
|
||
const sx = dy * Math.sin(radian);
|
||
const sy = dy * Math.cos(radian) - dy;
|
||
return {
|
||
x: (x - displayX) * scaleX + this._centerX + sx,
|
||
y: (y - displayY) * scaleY + this._centerY + sy,
|
||
scale: scaleX + (y - displayY) / 1600
|
||
};
|
||
};
|
||
|
||
Pseudo3DBattle.targets2dPosition = function(targets) {
|
||
const sprites = BattleManager._spriteset.makeTargetSprites(targets);
|
||
return this.targetSprites2dPosition(sprites);
|
||
};
|
||
|
||
Pseudo3DBattle.targetSprites2dPosition = function(targetSprites) {
|
||
if (targetSprites.length === 0) {
|
||
return null;
|
||
}
|
||
const pos = targetSprites.reduce((pos, target) => {
|
||
pos.x += target.targetGroundX();
|
||
pos.y += target.targetGroundY();
|
||
return pos;
|
||
}, new Point());
|
||
pos.x /= targetSprites.length;
|
||
pos.y /= targetSprites.length;
|
||
return pos;
|
||
};
|
||
|
||
Pseudo3DBattle.bringInsideX = function(x) {
|
||
return x + 64 * (x < this._centerX ? 1 : -1);
|
||
};
|
||
|
||
Pseudo3DBattle.bringInsideXByRate = function(x, rate) {
|
||
return (x - this._centerX) * rate + this._centerX;
|
||
};
|
||
|
||
Pseudo3DBattle.bringInsideYByRate = function(y, rate) {
|
||
return (y - this._centerY) * rate + this._centerY;
|
||
};
|
||
|
||
Pseudo3DBattle.moveTo = function(params) {
|
||
const realParams = { ...this._homeMoveParams, ...params };
|
||
this._baseDisplayX = realParams.x;
|
||
this._baseDisplayY = realParams.y;
|
||
this._baseAltitude = realParams.altitude;
|
||
this._baseScale = realParams.scale;
|
||
this._baseSkew = realParams.skew;
|
||
this._moveEasing.clear();
|
||
};
|
||
|
||
Pseudo3DBattle.moveForTargeting = function(params) {
|
||
const realParams = { ...this._homeMoveParams, ...params };
|
||
const easing = this._moveEasing;
|
||
this._targetingMoveParams = realParams;
|
||
easing.setType(realParams.type);
|
||
easing.setDuration(realParams.duration);
|
||
if (!easing.isMoving()) {
|
||
this.moveTo(realParams);
|
||
}
|
||
};
|
||
|
||
Pseudo3DBattle.endTargeting = function(params) {
|
||
if (this.isTargeting()) {
|
||
this._targetingMoveParams = null;
|
||
const realParams = { ...this.currentParams(), ...params };
|
||
if (this.isAction()) {
|
||
this.moveForAction(realParams);
|
||
} else {
|
||
this._waitMoveParams = {};
|
||
this.moveForWait(realParams);
|
||
}
|
||
}
|
||
};
|
||
|
||
Pseudo3DBattle.moveForAction = function(params) {
|
||
const realParams = { ...this._homeMoveParams, ...params };
|
||
this._actionMoveParams = realParams;
|
||
if (!this.isTargeting()) {
|
||
const easing = this._moveEasing;
|
||
easing.setType(realParams.type);
|
||
easing.setDuration(realParams.duration);
|
||
if (!easing.isMoving()) {
|
||
this.moveTo(realParams);
|
||
}
|
||
}
|
||
};
|
||
|
||
Pseudo3DBattle.endAction = function(params) {
|
||
if (this.isAction()) {
|
||
this._actionMoveParams = null;
|
||
if (!this.isTargeting()) {
|
||
const realParams = { ...this._waitMoveParams, ...params };
|
||
this._waitMoveParams = {};
|
||
this.moveForWait(realParams);
|
||
}
|
||
}
|
||
};
|
||
|
||
Pseudo3DBattle.moveForWait = function(params) {
|
||
const realParams = { ...this._homeMoveParams, ...params };
|
||
if (this.differentWaitParams(realParams)) {
|
||
this._waitMoveParams = realParams;
|
||
if (!this.isAction() && !this.isTargeting()) {
|
||
const easing = this._moveEasing;
|
||
easing.setType(realParams.type);
|
||
easing.setDuration(realParams.duration);
|
||
if (!easing.isMoving()) {
|
||
this.moveTo(realParams);
|
||
}
|
||
}
|
||
}
|
||
};
|
||
|
||
Pseudo3DBattle.differentWaitParams = function(params) {
|
||
return ['x', 'y', 'altitude', 'scale', 'skew'].some(
|
||
prop => this._waitMoveParams[prop] !== params[prop]
|
||
);
|
||
};
|
||
|
||
Pseudo3DBattle.update = function() {
|
||
this.updateMove();
|
||
this.updateDrift();
|
||
};
|
||
|
||
Pseudo3DBattle.updateMove = function() {
|
||
if (this._moveEasing.isMoving()) {
|
||
this.updatePosition(this.currentParams());
|
||
this._moveEasing.update();
|
||
}
|
||
};
|
||
|
||
Pseudo3DBattle.currentParams = function() {
|
||
return (
|
||
this._targetingMoveParams ||
|
||
this._actionMoveParams ||
|
||
this._waitMoveParams
|
||
);
|
||
};
|
||
|
||
Pseudo3DBattle.updatePosition = function(params) {
|
||
const { x, y, altitude, scale, skew } = params;
|
||
const easing = this._moveEasing;
|
||
this._baseDisplayX = easing.apply(this._baseDisplayX, x);
|
||
this._baseDisplayY = easing.apply(this._baseDisplayY, y);
|
||
this._baseAltitude = easing.apply(this._baseAltitude, altitude);
|
||
this._baseScale = easing.apply(this._baseScale, scale);
|
||
this._baseSkew = easing.apply(this._baseSkew, skew);
|
||
};
|
||
|
||
Pseudo3DBattle.updateDrift = function() {
|
||
for (const [key, easing] of Object.entries(this._drift)) {
|
||
easing.update();
|
||
if (!easing.isMoving()) {
|
||
this.setupDriftParams(key, easing);
|
||
}
|
||
}
|
||
};
|
||
|
||
Pseudo3DBattle.setupDriftParams = function(key, easing) {
|
||
easing.setTarget(this.driftTarget(key) * (Math.random() - 0.5));
|
||
easing.setDuration(100 + Math.floor(100 * Math.random()));
|
||
};
|
||
|
||
Pseudo3DBattle.driftTarget = function(key) {
|
||
const value = this._isDrift ? this.driftBase[key] || 0 : 0;
|
||
return value / (this.isAction() ? 2 : 1);
|
||
};
|
||
|
||
Pseudo3DBattle.addCommand = function(methodName, args) {
|
||
const func = this.moveMethods[methodName];
|
||
if (typeof func === 'function') {
|
||
const callback = func.bind(this, ...args);
|
||
this._commands.push({ methodName, callback });
|
||
}
|
||
};
|
||
|
||
Pseudo3DBattle.executeCommands = function() {
|
||
while (this._commands.length > 0) {
|
||
const { methodName, callback } = this._commands[0];
|
||
const params = callback();
|
||
if (params) {
|
||
if (params.isWait && this._moveEasing.isMoving()) {
|
||
return;
|
||
}
|
||
this.applyMoveParams(methodName, params);
|
||
}
|
||
this._commands.shift();
|
||
}
|
||
};
|
||
|
||
Pseudo3DBattle.applyMoveParams = function(methodName, params) {
|
||
switch (methodName) {
|
||
case 'setup':
|
||
return this.moveTo(params);
|
||
case 'targeting':
|
||
return this.moveForTargeting(params);
|
||
case 'endTargeting':
|
||
return this.endTargeting(params);
|
||
case 'driftOn':
|
||
return this.driftOn();
|
||
case 'driftOff':
|
||
return this.driftOff();
|
||
case 'endAction':
|
||
return this.endAction(params);
|
||
default:
|
||
if (this._waitMoveMethodNames.includes(methodName)) {
|
||
return this.moveForWait(params);
|
||
} else {
|
||
return this.moveForAction(params);
|
||
}
|
||
}
|
||
};
|
||
|
||
//-------------------------------------------------------------------------
|
||
// Easing
|
||
|
||
class Easing {
|
||
constructor(type = '', duration = 0) {
|
||
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;
|
||
}
|
||
}
|
||
};
|
||
|
||
//-------------------------------------------------------------------------
|
||
// EasingValue
|
||
|
||
class EasingValue extends Easing {
|
||
constructor(type = '', duration = 0) {
|
||
super(type, duration);
|
||
this._value = 0;
|
||
this._targetValue = 0;
|
||
}
|
||
get current() {
|
||
return this._value;
|
||
}
|
||
setTarget(target) {
|
||
this._targetValue = target;
|
||
}
|
||
update() {
|
||
this._value = this.apply(this._value, this._targetValue);
|
||
super.update();
|
||
}
|
||
};
|
||
|
||
//-------------------------------------------------------------------------
|
||
// BattleManager
|
||
|
||
BattleManager.callPseudo3dMethod = function(methodName, ...args) {
|
||
// 戦闘キャラの移動が Sprite_Battler クラスで行われている都合上、
|
||
// Spriteset_Battle.prototype.update で実行します。
|
||
Pseudo3DBattle.addCommand(methodName, args);
|
||
};
|
||
|
||
/**
|
||
* 別プラグインから視点操作を行うためのメソッドです。
|
||
* @param {string} methodName - メソッド名。
|
||
* @param {function} func - 移動先のパラメータを入れた連想配列を返す関数。
|
||
* この関数は Pseudo3DBattle を this として呼び出されます。
|
||
* 設定可能なパラメータ。
|
||
* [x] : 移動先のX座標。(デフォルト戦闘時の画面座標)
|
||
* [y] : 移動先のY座標。(同上)
|
||
* [altitude] : 視点の高さ。0がデフォルト。-50~50を推奨。
|
||
* [scale] : 拡大率。1.0がデフォルト。小さくしすぎると背景の端が見える可能性あり。
|
||
* [skew] : 傾き。-1.0~1.0で指定。
|
||
* [duration] : 時間。(フレーム数)
|
||
* [isWait] : true で前の移動が終わってから実行。
|
||
* [type] : イージングタイプ。(ピクチャにあるものと同じ)
|
||
* 'Constant speed' : 一定速度。
|
||
* 'Slow start' : ゆっくり始まる。
|
||
* 'Slow end' : ゆっくり終わる。(デフォルト)
|
||
* 'Slow start and end' : ゆっくり始まってゆっくり終わる。
|
||
* @param {boolean} [wait=false] - ウェイトメソッドフラグ。
|
||
*/
|
||
BattleManager.registerPseudo3dMethod = function(methodName, func, wait = false) {
|
||
Pseudo3DBattle.moveMethods[methodName] = func;
|
||
if (wait) {
|
||
Pseudo3DBattle._waitMoveMethodNames.push(methodName);
|
||
}
|
||
};
|
||
|
||
/**
|
||
* ドリフト(画面の揺れ)幅を設定します。
|
||
* @param {string} paramName - パラメータ名。'x','y','altitude','skew' で指定。
|
||
* @param {number} value - パラメータの値。
|
||
*/
|
||
BattleManager.setPseudo3dDriftParam = function(paramName, value) {
|
||
if (paramName in Pseudo3DBattle.driftBase) {
|
||
Pseudo3DBattle.driftBase[paramName] = value;
|
||
}
|
||
};
|
||
|
||
const _BattleManager_updateEventMain = BattleManager.updateEventMain;
|
||
BattleManager.updateEventMain = function() {
|
||
const lastEventRunning = $gameTroop.isEventRunning();
|
||
const result = _BattleManager_updateEventMain.apply(this, arguments);
|
||
if (lastEventRunning && !result) {
|
||
this.callPseudo3dMethod('endAction');
|
||
}
|
||
return result;
|
||
};
|
||
|
||
const _BattleManager_startBattle = BattleManager.startBattle;
|
||
BattleManager.startBattle = function() {
|
||
_BattleManager_startBattle.apply(this, arguments);
|
||
Pseudo3DBattle.onBattleStart();
|
||
this.callPseudo3dMethod('setup');
|
||
this.callPseudo3dMethod('startBattle');
|
||
};
|
||
|
||
const _BattleManager_startAction = BattleManager.startAction;
|
||
BattleManager.startAction = function() {
|
||
_BattleManager_startAction.apply(this, arguments);
|
||
this.callPseudo3dMethod('startAction', this._subject);
|
||
};
|
||
|
||
const _BattleManager_endBattlerActions = BattleManager.endBattlerActions;
|
||
BattleManager.endBattlerActions = function(battler) {
|
||
_BattleManager_endBattlerActions.apply(this, arguments);
|
||
if (!$gameTemp.isCommonEventReserved() && !$gameTroop.isEventRunning()) {
|
||
this.callPseudo3dMethod('endAction');
|
||
}
|
||
};
|
||
|
||
const _BattleManager_processVictory = BattleManager.processVictory;
|
||
BattleManager.processVictory = function() {
|
||
_BattleManager_processVictory.apply(this, arguments);
|
||
this.callPseudo3dMethod('victory');
|
||
if (!$gameSystem.isSideView()) {
|
||
this.callPseudo3dMethod('driftOff');
|
||
}
|
||
};
|
||
|
||
const _BattleManager_processEscape = BattleManager.processEscape;
|
||
BattleManager.processEscape = function() {
|
||
const success = _BattleManager_processEscape.apply(this, arguments);
|
||
this.callPseudo3dMethod('escape');
|
||
return success;
|
||
};
|
||
|
||
const _BattleManager_processDefeat = BattleManager.processDefeat;
|
||
BattleManager.processDefeat = function() {
|
||
_BattleManager_processDefeat.apply(this, arguments);
|
||
this.callPseudo3dMethod('defeat');
|
||
this.callPseudo3dMethod('driftOff');
|
||
};
|
||
|
||
//-------------------------------------------------------------------------
|
||
// Sprite_Battler
|
||
|
||
const _Sprite_Battler_initMembers = Sprite_Battler.prototype.initMembers;
|
||
Sprite_Battler.prototype.initMembers = function() {
|
||
_Sprite_Battler_initMembers.apply(this, arguments);
|
||
this._pseudo3dType = 'obj';
|
||
};
|
||
|
||
Sprite_Battler.prototype.pseudo3dAltitude = function() {
|
||
return this._homeY + this._offsetY - this.y;
|
||
};
|
||
|
||
Sprite_Battler.prototype.targetGroundX = function() {
|
||
return this._homeX + (this._targetOffsetX || 0);
|
||
};
|
||
|
||
Sprite_Battler.prototype.targetGroundY = function() {
|
||
return this._homeY + (this._targetOffsetY || 0);
|
||
};
|
||
|
||
//-------------------------------------------------------------------------
|
||
// Sprite_Enemy
|
||
|
||
Sprite_Enemy.prototype.targetGroundY = function() {
|
||
const groundY = Sprite_Battler.prototype.targetGroundY.call(this);
|
||
return groundY - this.height / 8;
|
||
};
|
||
|
||
Sprite_Enemy.prototype.pseudo3dAltitude = function() {
|
||
const altitude = Sprite_Battler.prototype.pseudo3dAltitude.call(this);
|
||
return altitude - this.height / 20;
|
||
};
|
||
|
||
//-------------------------------------------------------------------------
|
||
// Sprite_Animation
|
||
|
||
const _Sprite_Animation_updateEffectGeometry = Sprite_Animation.prototype.updateEffectGeometry;
|
||
Sprite_Animation.prototype.updateEffectGeometry = function() {
|
||
_Sprite_Animation_updateEffectGeometry.apply(this, arguments);
|
||
if (this._handle && $gameParty.inBattle()) {
|
||
const scale = this._animation.scale / 100 * this.pseudo3dTargetsScale();
|
||
this._handle.setScale(scale, scale, scale);
|
||
}
|
||
};
|
||
|
||
Sprite_Animation.prototype.pseudo3dTargetsScale = function() {
|
||
if (this._animation.displayType === 2) {
|
||
return 1;
|
||
}
|
||
const pos = Pseudo3DBattle.targetSprites2dPosition(this._targets);
|
||
return pos ? Pseudo3DBattle.adjustPosition(pos.x, pos.y).scale : 1;
|
||
};
|
||
|
||
//-------------------------------------------------------------------------
|
||
// Sprite_AnimationMV
|
||
|
||
const _Sprite_AnimationMV_setup = Sprite_AnimationMV.prototype.setup;
|
||
Sprite_AnimationMV.prototype.setup = function(t, a, m, d) {
|
||
_Sprite_AnimationMV_setup.apply(this, arguments);
|
||
this._pseudo3dType = this._animation.position === 3 ? 'excl' : 'obj';
|
||
};
|
||
|
||
Sprite_AnimationMV.prototype.pseudo3dAltitude = function() {
|
||
if (this._targets.length > 0) {
|
||
const target = this._targets[0];
|
||
if (this._animation.position === 0) {
|
||
return target.height;
|
||
} else if (this._animation.position === 1) {
|
||
return target.height / 2;
|
||
}
|
||
}
|
||
return 0;
|
||
};
|
||
|
||
//-------------------------------------------------------------------------
|
||
// ImageManager
|
||
|
||
ImageManager.battlebackWidth = 1000;
|
||
ImageManager.battlebackHeight = 740;
|
||
|
||
//-------------------------------------------------------------------------
|
||
// Sprite_Battleback
|
||
|
||
const _Sprite_Battleback_initialize = Sprite_Battleback.prototype.initialize;
|
||
Sprite_Battleback.prototype.initialize = function(type) {
|
||
_Sprite_Battleback_initialize.apply(this, arguments);
|
||
this._isPseudo3dGround = false;
|
||
this._homeX = 0;
|
||
this._homeY = 0;
|
||
this._effectsOffsetX = 0;
|
||
this._effectsOffsetY = 0;
|
||
};
|
||
|
||
const _Sprite_Battleback_adjustPosition = Sprite_Battleback.prototype.adjustPosition;
|
||
Sprite_Battleback.prototype.adjustPosition = function() {
|
||
_Sprite_Battleback_adjustPosition.apply(this, arguments);
|
||
this.width = ImageManager.battlebackWidth;
|
||
this.height = ImageManager.battlebackHeight;
|
||
};
|
||
|
||
Sprite_Battleback.prototype.setEffectsOffset = function(x, y) {
|
||
this._effectsOffsetX = x;
|
||
this._effectsOffsetY = y;
|
||
};
|
||
|
||
Sprite_Battleback.prototype.setupPseudo3dPosition = function(pivotY) {
|
||
this._homeX = Graphics.width / 2;
|
||
if ($gameSystem.isSideView()) {
|
||
this._homeY = Graphics.height - this.height + pivotY;
|
||
} else {
|
||
this._homeY = pivotY;
|
||
}
|
||
this.anchor.x = 0.5;
|
||
this.anchor.y = pivotY / this.height;
|
||
};
|
||
|
||
Sprite_Battleback.prototype.applyPseudo3dPlacement = function() {
|
||
// 拡大率の計算式は正確なものではありません。
|
||
const groundX = this._homeX - this._effectsOffsetX;
|
||
const groundY = this._homeY - this._effectsOffsetY;
|
||
const pos3d = Pseudo3DBattle.adjustPosition(groundX, groundY);
|
||
this.x = pos3d.x + this._effectsOffsetX;
|
||
this.y = pos3d.y + this._effectsOffsetY;
|
||
const scale = this.minScreenRatio() * param_BattlebackScale;
|
||
if (this._isPseudo3dGround) {
|
||
this.scale.x = Pseudo3DBattle.scaleX() * scale;
|
||
this.scale.y = Pseudo3DBattle.scaleY() * scale;
|
||
this.skew.x = Pseudo3DBattle.skew();
|
||
} else {
|
||
this.scale.x = Pseudo3DBattle.scaleX() * scale;
|
||
this.scale.y = Pseudo3DBattle.scaleX() * scale;
|
||
}
|
||
};
|
||
|
||
Sprite_Battleback.prototype.minScreenRatio = function() {
|
||
const { battlebackWidth:bw, battlebackHeight:bh } = ImageManager;
|
||
const ratioX = (Graphics.width + bw - 816) / bw;
|
||
const ratioY = (Graphics.height + bh - 624) / bh;
|
||
return Math.max(ratioX, ratioY, 1.0);
|
||
};
|
||
|
||
//-------------------------------------------------------------------------
|
||
// Sprite_StateIcon
|
||
|
||
const _Sprite_StateIcon_updateIcon = Sprite_StateIcon.prototype.updateIcon;
|
||
Sprite_StateIcon.prototype.updateIcon = function() {
|
||
_Sprite_StateIcon_updateIcon.apply(this, arguments);
|
||
this.updateVisibility();
|
||
};
|
||
|
||
const _Sprite_StateIcon_updateVisibility = __base(Sprite_StateIcon.prototype, 'updateVisibility');
|
||
Sprite_StateIcon.prototype.updateVisibility = function() {
|
||
_Sprite_StateIcon_updateVisibility.apply(this, arguments);
|
||
this.visible = this.visible && this._iconIndex > 0;
|
||
};
|
||
|
||
//-------------------------------------------------------------------------
|
||
// Spriteset_Battle
|
||
|
||
const _Spriteset_Battle_initialize = Spriteset_Battle.prototype.initialize;
|
||
Spriteset_Battle.prototype.initialize = function() {
|
||
_Spriteset_Battle_initialize.apply(this, arguments);
|
||
this._sprite2dPlacements = new WeakMap();
|
||
};
|
||
|
||
const _Spriteset_Battle_createBattleback = Spriteset_Battle.prototype.createBattleback;
|
||
Spriteset_Battle.prototype.createBattleback = function() {
|
||
_Spriteset_Battle_createBattleback.apply(this, arguments);
|
||
this._back1Sprite._isPseudo3dGround = true;
|
||
if (this._back1Sprite.battleback1Name() !== '') {
|
||
this._backgroundSprite.visible = false; // Just weight reduction
|
||
}
|
||
if (this.fixBattlebackPivotY() > 0) {
|
||
const index = this._baseSprite.children.indexOf(this._back1Sprite);
|
||
this._back1FixSprite = new Sprite_Battleback(0);
|
||
this._baseSprite.addChildAt(this._back1FixSprite, index + 1);
|
||
}
|
||
};
|
||
|
||
const _Spriteset_Battle_update = Spriteset_Battle.prototype.update;
|
||
Spriteset_Battle.prototype.update = function() {
|
||
this.restoreSprite2dPlacements();
|
||
_Spriteset_Battle_update.apply(this, arguments);
|
||
this.applyPseudo3dPlacements();
|
||
Pseudo3DBattle.executeCommands();
|
||
};
|
||
|
||
/**
|
||
* 競合対策として、位置とサイズを2Dの状態に戻す。
|
||
*/
|
||
Spriteset_Battle.prototype.restoreSprite2dPlacements = function() {
|
||
for (const sprite of this.pseudo3dSprites()) {
|
||
const placement = this._sprite2dPlacements.get(sprite);
|
||
if (placement) {
|
||
sprite.x = placement.x;
|
||
sprite.y = placement.y;
|
||
sprite.scale.x = placement.scaleX;
|
||
sprite.scale.y = placement.scaleY;
|
||
}
|
||
}
|
||
};
|
||
|
||
/**
|
||
* 疑似3D表示に対応させるスプライトの配列。
|
||
* 追加することで疑似3D表示にある程度対応させることができます。
|
||
* 破壊してよい配列ではないことに注意してください。
|
||
* @returns {array}
|
||
*/
|
||
Spriteset_Battle.prototype.pseudo3dSprites = function() {
|
||
return this._effectsContainer.children;
|
||
};
|
||
|
||
Spriteset_Battle.prototype.applyPseudo3dPlacements = function() {
|
||
this._back1Sprite.applyPseudo3dPlacement();
|
||
this._back2Sprite.applyPseudo3dPlacement();
|
||
if (this._back1FixSprite) {
|
||
this._back1FixSprite.applyPseudo3dPlacement();
|
||
}
|
||
for (const sprite of this.pseudo3dSprites()) {
|
||
if (sprite._pseudo3dType !== 'excl') {
|
||
this.saveSprite2dPlacement(sprite);
|
||
this.convertSprite3dPlacement(sprite);
|
||
} else {
|
||
this._sprite2dPlacements.delete(sprite);
|
||
}
|
||
}
|
||
};
|
||
|
||
Spriteset_Battle.prototype.saveSprite2dPlacement = function(sprite) {
|
||
if (!this._sprite2dPlacements.has(sprite)) {
|
||
this._sprite2dPlacements.set(sprite, {});
|
||
}
|
||
const placement = this._sprite2dPlacements.get(sprite);
|
||
placement.x = sprite.x;
|
||
placement.y = sprite.y;
|
||
placement.scaleX = sprite.scale.x;
|
||
placement.scaleY = sprite.scale.y;
|
||
};
|
||
|
||
Spriteset_Battle.prototype.convertSprite3dPlacement = function(sprite) {
|
||
const alt = sprite.pseudo3dAltitude ? sprite.pseudo3dAltitude() : 0;
|
||
const groundX = sprite.x;
|
||
const groundY = sprite.y + alt;
|
||
const pos3d = Pseudo3DBattle.adjustPosition(groundX, groundY);
|
||
sprite.x = pos3d.x;
|
||
sprite.y = pos3d.y - alt * pos3d.scale;
|
||
if (sprite._pseudo3dType === 'obj') {
|
||
// sprite.mirrored is a parameter of OcRam_Battle_Core.js
|
||
sprite.scale.x *= sprite.mirrored ? -pos3d.scale : pos3d.scale;
|
||
sprite.scale.y *= pos3d.scale;
|
||
}
|
||
};
|
||
|
||
const _Spriteset_Battle_updateBattleback = Spriteset_Battle.prototype.updateBattleback;
|
||
Spriteset_Battle.prototype.updateBattleback = function() {
|
||
const lastBattlebackLocated = this._battlebackLocated;
|
||
_Spriteset_Battle_updateBattleback.apply(this, arguments);
|
||
if (!lastBattlebackLocated) {
|
||
this.setupBattlebackEffectsOffset();
|
||
this.setupBattlebackPseudo3dPosition();
|
||
}
|
||
};
|
||
|
||
Spriteset_Battle.prototype.setupBattlebackEffectsOffset = function() {
|
||
const { x, y } = this._effectsContainer;
|
||
this._back1Sprite.setEffectsOffset(x, y);
|
||
this._back2Sprite.setEffectsOffset(x, y);
|
||
if (this._back1FixSprite) {
|
||
this._back1FixSprite.setEffectsOffset(x, y);
|
||
}
|
||
};
|
||
|
||
Spriteset_Battle.prototype.setupBattlebackPseudo3dPosition = function() {
|
||
const pivotY = this.fixBattlebackPivotY() || this.getBattlebackPivotY();
|
||
this._back1Sprite.setupPseudo3dPosition(pivotY);
|
||
this._back2Sprite.setupPseudo3dPosition(pivotY);
|
||
if (this._back1FixSprite) {
|
||
this._back1FixSprite.adjustPosition();
|
||
this._back1FixSprite.setupPseudo3dPosition(pivotY);
|
||
this._back1FixSprite.height = pivotY;
|
||
this._back1FixSprite.anchor.y = 1;
|
||
}
|
||
};
|
||
|
||
Spriteset_Battle.prototype.fixBattlebackPivotY = function() {
|
||
const battleback2Name = this._back2Sprite.battleback2Name();
|
||
const param = param_Battleback2PivotYFixes.find(
|
||
param => param['Battleback2 Image'] === battleback2Name
|
||
);
|
||
return param ? param['Pivot Y'] || 0 : 0;
|
||
};
|
||
|
||
Spriteset_Battle.prototype.getBattlebackPivotY = function() {
|
||
const bitmap = this._back2Sprite.bitmap;
|
||
const x = Math.floor(bitmap.width / 2);
|
||
const h = bitmap.height;
|
||
const data = bitmap.context.getImageData(x, 0, 1, h).data;
|
||
return [...Array(h).keys()].reverse().find(
|
||
n => data[n * 4 + 3] > 192
|
||
) || 0;
|
||
};
|
||
|
||
//-------------------------------------------------------------------------
|
||
// Window_BattleLog
|
||
|
||
const _Window_BattleLog_performCollapse = Window_BattleLog.prototype.performCollapse;
|
||
Window_BattleLog.prototype.performCollapse = function(target) {
|
||
_Window_BattleLog_performCollapse.apply(this, arguments);
|
||
BattleManager.callPseudo3dMethod('collapse', target);
|
||
};
|
||
|
||
const _Window_BattleLog_showAnimation = Window_BattleLog.prototype.showAnimation;
|
||
Window_BattleLog.prototype.showAnimation = function(s, targets, a) {
|
||
_Window_BattleLog_showAnimation.apply(this, arguments);
|
||
const realTargets = [ ...new Set(targets) ];
|
||
BattleManager.callPseudo3dMethod('showAnimation', realTargets);
|
||
};
|
||
|
||
const _Window_BattleLog_displayDamage = Window_BattleLog.prototype.displayDamage;
|
||
Window_BattleLog.prototype.displayDamage = function(target) {
|
||
_Window_BattleLog_displayDamage.apply(this, arguments);
|
||
BattleManager.callPseudo3dMethod('damage', target);
|
||
};
|
||
|
||
//-------------------------------------------------------------------------
|
||
// Scene_Boot
|
||
|
||
const _Scene_Boot_start = Scene_Boot.prototype.start;
|
||
Scene_Boot.prototype.start = function() {
|
||
_Scene_Boot_start.apply(this, arguments);
|
||
Pseudo3DBattle.initMembers();
|
||
};
|
||
|
||
//-------------------------------------------------------------------------
|
||
// Scene_Battle
|
||
|
||
const _Scene_Battle_update = Scene_Battle.prototype.update;
|
||
Scene_Battle.prototype.update = function() {
|
||
Pseudo3DBattle.update();
|
||
_Scene_Battle_update.apply(this, arguments);
|
||
};
|
||
|
||
const _Scene_Battle_terminate = Scene_Battle.prototype.terminate;
|
||
Scene_Battle.prototype.terminate = function() {
|
||
_Scene_Battle_terminate.apply(this, arguments);
|
||
Pseudo3DBattle.clearMoveCommands();
|
||
};
|
||
|
||
const _Scene_Battle_hideSubInputWindows = Scene_Battle.prototype.hideSubInputWindows;
|
||
Scene_Battle.prototype.hideSubInputWindows = function() {
|
||
_Scene_Battle_hideSubInputWindows.apply(this, arguments);
|
||
if (!$gameTroop.isEventRunning()) {
|
||
BattleManager.callPseudo3dMethod('endTargeting');
|
||
BattleManager.callPseudo3dMethod('home');
|
||
}
|
||
};
|
||
|
||
const _Scene_Battle_startPartyCommandSelection = Scene_Battle.prototype.startPartyCommandSelection;
|
||
Scene_Battle.prototype.startPartyCommandSelection = function() {
|
||
_Scene_Battle_startPartyCommandSelection.apply(this, arguments);
|
||
BattleManager.callPseudo3dMethod('home');
|
||
};
|
||
|
||
const _Scene_Battle_startActorCommandSelection = Scene_Battle.prototype.startActorCommandSelection;
|
||
Scene_Battle.prototype.startActorCommandSelection = function() {
|
||
_Scene_Battle_startActorCommandSelection.apply(this, arguments);
|
||
BattleManager.callPseudo3dMethod('inputting', BattleManager.actor());
|
||
};
|
||
|
||
const _Scene_Battle_startActorSelection = Scene_Battle.prototype.startActorSelection;
|
||
Scene_Battle.prototype.startActorSelection = function() {
|
||
_Scene_Battle_startActorSelection.apply(this, arguments);
|
||
BattleManager.callPseudo3dMethod('targeting', $gameParty.members());
|
||
};
|
||
|
||
const _Scene_Battle_onActorCancel = Scene_Battle.prototype.onActorCancel;
|
||
Scene_Battle.prototype.onActorCancel = function() {
|
||
_Scene_Battle_onActorCancel.apply(this, arguments);
|
||
BattleManager.callPseudo3dMethod('endTargeting');
|
||
};
|
||
|
||
const _Scene_Battle_startEnemySelection = Scene_Battle.prototype.startEnemySelection;
|
||
Scene_Battle.prototype.startEnemySelection = function() {
|
||
_Scene_Battle_startEnemySelection.apply(this, arguments);
|
||
BattleManager.callPseudo3dMethod('targeting', $gameTroop.aliveMembers());
|
||
};
|
||
|
||
const _Scene_Battle_onEnemyCancel = Scene_Battle.prototype.onEnemyCancel;
|
||
Scene_Battle.prototype.onEnemyCancel = function() {
|
||
_Scene_Battle_onEnemyCancel.apply(this, arguments);
|
||
BattleManager.callPseudo3dMethod('endTargeting');
|
||
};
|
||
|
||
//-------------------------------------------------------------------------
|
||
// PluginManager
|
||
|
||
PluginManager.registerCommand(pluginName, 'enemyFocus', function(args) {
|
||
const index = PluginManager.mppValue(args.index);
|
||
const scale = PluginManager.mppValue(args.scale) / 100;
|
||
const duration = PluginManager.mppValue(args.duration);
|
||
const targets = [];
|
||
this.iterateBattler(0, index, battler => {
|
||
if (battler.isAlive()) {
|
||
targets.push(battler);
|
||
}
|
||
});
|
||
BattleManager.callPseudo3dMethod('focus', targets, scale, duration);
|
||
});
|
||
|
||
PluginManager.registerCommand(pluginName, 'actorFocus', function(args) {
|
||
const id = PluginManager.mppValue(args.id);
|
||
const scale = PluginManager.mppValue(args.scale) / 100;
|
||
const duration = PluginManager.mppValue(args.duration);
|
||
const targets = [];
|
||
this.iterateBattler(1, id, battler => {
|
||
targets.push(battler);
|
||
});
|
||
BattleManager.callPseudo3dMethod('focus', targets, scale, duration);
|
||
});
|
||
|
||
PluginManager.registerCommand(pluginName, 'moveHome', args => {
|
||
const duration = PluginManager.mppValue(args.duration);
|
||
BattleManager.callPseudo3dMethod('endAction', duration);
|
||
});
|
||
|
||
PluginManager.mppValue = function(value) {
|
||
const match = /^V\[(\d+)\]$/i.exec(value);
|
||
return match ? $gameVariables.value(+match[1]) : +value;
|
||
};
|
||
|
||
})();
|