3313 lines
106 KiB
JavaScript
3313 lines
106 KiB
JavaScript
/*:
|
|
@plugindesc Renders the tilemap in 3D. Supports various parameters such as yaw rotation,
|
|
pitch, field of view, etc.
|
|
@author Blizzard
|
|
|
|
@help Version: 1.6.0
|
|
|
|
- licensed under BSD License 2.0
|
|
|
|
--License--
|
|
|
|
Copyright (c) Boris "Blizzard" Mikić
|
|
All rights reserved.
|
|
|
|
Redistribution and use in source and binary forms, with or without
|
|
modification, are permitted provided that the following conditions are met:
|
|
|
|
1. Redistributions of source code must retain the above copyright notice,
|
|
this list of conditions and the following disclaimer.
|
|
|
|
2. Redistributions in binary form must reproduce the above copyright notice,
|
|
this list of conditions and the following disclaimer in the documentation
|
|
and/or other materials provided with the distribution.
|
|
|
|
3. Neither the name of the copyright holder nor the names of its contributors
|
|
may be used to endorse or promote products derived from this software
|
|
without specific prior written permission.
|
|
|
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
|
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
|
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
|
IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
|
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
|
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
|
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
|
WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
|
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
|
POSSIBILITY OF SUCH DAMAGE.
|
|
|
|
--Usage and giving credit--
|
|
|
|
You may use this script for both non-commercial and commercial products without
|
|
limitations as long as you fulfill the conditions presented by the above license.
|
|
The "complete" way to give credit is to include the license somewhere in your
|
|
product (e.g. in the credits screen), but a "simple" way is also acceptable.
|
|
The "simple" way to give credit is as follows:
|
|
|
|
Ultra Mode 7 licensed under BSD License 2.0
|
|
Copyright (c) Boris "Blizzard" Mikić
|
|
|
|
Alternatively, if your font doesn't support diacritic characters, you may use this
|
|
variant:
|
|
|
|
Ultra Mode 7 licensed under BSD License 2.0
|
|
Copyright (c) Boris "Blizzard" Mikic
|
|
|
|
In general other similar variants are allowed as long as it is clear who the
|
|
creator is (e.g. "Ultra Mode 7 created by Blizzard" is acceptable). But if
|
|
possible, prefer to use one of the two variants listed above.
|
|
|
|
If you fail to give credit and/or claim that this work was created by you, this
|
|
may result in legal action and/or payment of damages even though this work is
|
|
free of charge to use normally.
|
|
|
|
--Introduction--
|
|
|
|
Ultra Mode 7 simulates the Mode 7 rendering mode from the SNES by using 3D
|
|
rendering. Sprites are scaled appropriately and use additional code to
|
|
determine whether they are visible, because of cut-off distance. The view
|
|
of a Mode 7 map is defined by the following parameters:
|
|
|
|
- camera distance
|
|
- camera Y position
|
|
- field of view
|
|
- pitch rotation angle
|
|
- yaw rotation angle
|
|
- maximum Z coordinate
|
|
|
|
--Changelog--
|
|
|
|
v1.6.0:
|
|
- implemented improved scaling of sprites on map which doesn't get messed up by near and far clipping planes
|
|
- changed some of the default parameters to accommodate the fixed scaling issues
|
|
- added LEGACY_SCALING parameter for backwards compatibility
|
|
|
|
v1.5.4:
|
|
- fixed bug with screen-to-map calculations when using orthogonal projection
|
|
|
|
v1.5.3:
|
|
- improved compatibility code for KhasUltraLighting
|
|
|
|
v1.5.2:
|
|
- added camera y poaition
|
|
|
|
v1.5.1:
|
|
- added color fade begin to map parameters
|
|
- added color fade end to map parameters
|
|
|
|
v1.5.0:
|
|
- added map parameters for map borders
|
|
|
|
v1.4.6:
|
|
- added compatibility for newer pixi-tilemap versions
|
|
|
|
v1.4.5:
|
|
- added compatibility with Quasi Simple Shadows
|
|
|
|
v1.4.4:
|
|
- added compatibility with Thomas Edison MV
|
|
- fixed issue with fixed-coordinate parallax not working
|
|
|
|
v1.4.3:
|
|
- changed NEAR_CLIP_Z from constant to plugin parameter
|
|
|
|
v1.4.2:
|
|
- added new parameter FADE_Z_COLOR
|
|
- added option to setup custom fade colors for specific maps
|
|
- added option to change fade color at any time
|
|
|
|
v1.4.1:
|
|
- added compatibility with Yanfly's Gridfree Doodads
|
|
- added compatibility with MOG's Character Motion
|
|
|
|
v1.4.0:
|
|
- added new license
|
|
- added usage and crediting instructions
|
|
|
|
v1.3.8:
|
|
- added script call to enable/disable pixelated rendering during runtime
|
|
- reduced WEBGL_MAX_VERTICES to reduce possibility of glitched rendering
|
|
|
|
v1.3.7:
|
|
- added experimental compatibility for BattleLighting plugin
|
|
|
|
v1.3.6:
|
|
- added experimental compatibility for BattleLighting plugin
|
|
|
|
v1.3.5:
|
|
- corrected some minor positioning and scaling calculation errors
|
|
- improved compatibility code for KhasUltraLighting
|
|
|
|
v1.3.4:
|
|
- added compatibility code for KhasUltraLighting
|
|
- added compatibility instructions for Terrax Plugins - Lighting system
|
|
|
|
v1.3.3:
|
|
- fixed issue with event visibility on map borders when using looping maps
|
|
|
|
v1.3.2:
|
|
- added coordinate rounding for X and Y coordinates
|
|
- improved code that handles sprite visibility when outside of the view frustum
|
|
- removed some leftover debug prints
|
|
|
|
v1.3.1:
|
|
- fixed a crash with event testing
|
|
|
|
v1.3.0:
|
|
- implemented map looping functionality
|
|
- added workaround for PIXI bug where a lag spike would occur about every 10 seconds
|
|
- fixed issue where sprite direction didn't display properly at certain yaw angles
|
|
- fixed issue where movement controls didn't adjust to yaw angle
|
|
- added CHARACTERS_ADJUST_SPRITE_DIRECTION option
|
|
- fixed coordinate offset when using yaw angle
|
|
|
|
v1.2.4:
|
|
- fixed accidental removal of animateCameraDistance function
|
|
|
|
v1.2.3:
|
|
- added parallax distance parameter in maps for parallax movement with yaw and pitch
|
|
- renamed "Camera" functions to "CameraDistance"
|
|
- fixed bug with parallax scrolling on non-Mode 7 maps
|
|
- fixed bug with shaking the screen
|
|
- removed FOV limit and implemented orthogonal projection with FOV of 0°
|
|
|
|
v1.2.2:
|
|
- fixed a syntax error that was caused by code cleanup
|
|
|
|
v1.2.1:
|
|
- fixed save data issue
|
|
|
|
v1.2.0:
|
|
- fixed FPS drop problem while moving
|
|
|
|
v1.1.0:
|
|
- added animation function for parameters
|
|
- renamed RENDER_PIXELATED option to TILEMAP_PIXELATED
|
|
- added CHARACTERS_PIXELATED option
|
|
- fixed issue with floating characters
|
|
- fixed issue with normal maps not working anymore
|
|
- added some code to prevent compatibility issues with some map scripts
|
|
|
|
--How to use--
|
|
|
|
Separate maps can control and even dynamically change most paramaters. In
|
|
order to turn a normal map into a Mode 7 map, custom parameters need to be
|
|
defined in the "Note" section of the map. To use the default values for a
|
|
map, simply add the following entry to the map "note":
|
|
|
|
<UltraMode7>
|
|
|
|
If any other parameter is defined, this is not necessary. The following
|
|
parameters can be defined:
|
|
|
|
- UltraMode7_FOV
|
|
- UltraMode7_Pitch
|
|
- UltraMode7_Yaw
|
|
- UltraMode7_CameraDistance
|
|
- UltraMode7_CameraY
|
|
- UltraMode7_FadeColor
|
|
- UltraMode7_ParallaxDistance
|
|
- UltraMode7_Border
|
|
- UltraMode7_BorderHorizontal
|
|
- UltraMode7_BorderVertical
|
|
- UltraMode7_BorderLeft
|
|
- UltraMode7_BorderRight
|
|
- UltraMode7_BorderTop
|
|
- UltraMode7_BorderBottom
|
|
|
|
Example:
|
|
|
|
<UltraMode7_FOV:50>
|
|
|
|
When multiple parameters are defined, simply add them one after another.
|
|
Example:
|
|
|
|
<UltraMode7_Pitch:50>
|
|
<UltraMode7_CameraDistance:400>
|
|
<UltraMode7_CameraY:20>
|
|
<UltraMode7_Yaw:45>
|
|
<UltraMode7_FadeColor:1,1,0.5>
|
|
<UltraMode7_ParallaxDistance:800>
|
|
<UltraMode7_BorderVertical:4>
|
|
|
|
--How to change parameters dynamically--
|
|
|
|
The 4 parameters that can be defined in the note section of a map can also
|
|
be changed at any time during the map. Following calls are available:
|
|
|
|
UltraMode7.setFov(DEGREES)
|
|
UltraMode7.setPitch(DEGREES)
|
|
UltraMode7.setYaw(DEGREES)
|
|
UltraMode7.setCameraDistance(Z_DISTANCE)
|
|
UltraMode7.setCameraY(Y_POSITION)
|
|
UltraMode7.setFadeColor(RGB_COLOR)
|
|
UltraMode7.setFadeBegin(RGB_COLOR)
|
|
UltraMode7.setFadeEnd(RGB_COLOR)
|
|
UltraMode7.setParallaxDistance(DISTANCE)
|
|
UltraMode7.setTilemapPixelated(TRUE_FALSE)
|
|
|
|
You can also obtain the current values with these calls:
|
|
|
|
UltraMode7.getFov()
|
|
UltraMode7.getPitch()
|
|
UltraMode7.getYaw()
|
|
UltraMode7.getCameraDistance()
|
|
UltraMode7.getCameraY()
|
|
UltraMode7.getFadeColor()
|
|
UltraMode7.getFadeBegin()
|
|
UltraMode7.getFadeEnd()
|
|
UltraMode7.getParallaxDistance()
|
|
UltraMode7.isTilemapPixelated()
|
|
|
|
You can also change the values in an animated manner:
|
|
|
|
UltraMode7.animateFov(TARGET_VALUE, FRAMES_DURATION)
|
|
UltraMode7.animatePitch(TARGET_VALUE, FRAMES_DURATION)
|
|
UltraMode7.animateYaw(TARGET_VALUE, FRAMES_DURATION)
|
|
UltraMode7.animateCameraDistance(TARGET_VALUE, FRAMES_DURATION)
|
|
UltraMode7.animateCameraY(TARGET_VALUE, FRAMES_DURATION)
|
|
UltraMode7.animateFadeColor(TARGET_VALUE, FRAMES_DURATION)
|
|
UltraMode7.animateFadeBegin(TARGET_VALUE, FRAMES_DURATION)
|
|
UltraMode7.animateFadeEnd(TARGET_VALUE, FRAMES_DURATION)
|
|
|
|
Parallax distance cannot be animated due to its internal implementation relying
|
|
on fixed values.
|
|
|
|
--Additional Notes--
|
|
|
|
- When using parallax backgrounds due to how rendering is done, it's useful
|
|
to have a custom parallax that fades into white and creates a seamless
|
|
transition into the faded tiles. Make sure to adjust for changes in the
|
|
pitch angle as well.
|
|
- Larger values for NEAR_CLIP_Z can help reduce problems with characters
|
|
becoming very large when they are close to the camera and if a low pitch
|
|
value is used.
|
|
- Smaller values of FAR_CLIP_Z will cause characters and the tilemap
|
|
to be cut off earlier. Effectively it moves the cut-off horizon closer.
|
|
- If you don't want white fade-out, set both FADE_Z values to a larger value
|
|
than FAR_CLIP_Z.
|
|
- When the yaw value is changed, characters are turned around accordingly, but
|
|
controls aren't changed.
|
|
- Consider using the same values for BASE_SCALE_Z and DEFAULT_CAMERA_DISTANCE.
|
|
- Ultra Mode 7 is setup to display the player character in the middle of the
|
|
screen with a pixel-perfect scale of 1:1. When using DEFAULT_CAMERA_Y, keep
|
|
in mind that positioning the camera above or below changes the player
|
|
position in 3D space and you may want to consider using a different value for
|
|
BASE_SCALE_Z.
|
|
- If you use a FOV of 0, the display mode will switch to orthogonal projection.
|
|
- When using looping maps, the change of FOV, camera distance and far-clip
|
|
Z-plane might require recalculation of the entire tilemap and can cause
|
|
momentary performance drops so it should be used sparingly. If you absolutely
|
|
require dynamic changes of these parameters by large values, you can increase
|
|
the option LOOP_MAPS_EXTEND_TILES to decrease the likelyhood of the
|
|
recalculation to happen.
|
|
- When using a real-time system with day-night transition, it might be better
|
|
to apply the fade color constantly as a derived value from the day-night
|
|
coloring rather than using fade color animation.
|
|
- When using UltraMode7_Border, all other border options will be ignored.
|
|
- When using UltraMode7_BorderHorizontal, UltraMode7_BorderLeft and
|
|
UltraMode7_BorderRight will be ignored.
|
|
- When using UltraMode7_BorderVertical, UltraMode7_BorderTop and
|
|
UltraMode7_BorderBottom will be ignored.
|
|
- Looped maps ignore all border settings.
|
|
|
|
--Technical details, limitations and compatibility--
|
|
|
|
- Requires WebGL. Does not work with canvas and due to how canvas works, it
|
|
can never support canvas.
|
|
- Due to sprite scaling, how character sprite sheets are organized and how
|
|
pixel interpolation is done when scaling is applied, there can be artifacts
|
|
during rendering of characters. Manipulating the FAR_CLIP_Z value can
|
|
help remove these artifacts to some degree.
|
|
- The tilemap is rendered in its entirety and the projection matrix is used
|
|
to limit visibility. The hardware should take care of optimizing rendering.
|
|
- Due to a hard limit of 65536 vertices being rendered at once in WebGL, the
|
|
code has been adjusted to render the tilemap in as many passes as necessary.
|
|
Since some people reported issues even with 65536 vertices, a soft lower
|
|
limit is being used within the script.
|
|
- Because the tilemap is rendered entirely flat, tile priority isn't used.
|
|
- The option TILEMAP_PIXELATED and change via UltraMode7.setTilemapPixelated()
|
|
affects non-Mode 7 maps as well.
|
|
- Scaling has been optimized for usage of an FOV of 60°. Using different
|
|
values will cause some weird scales being used for characters.
|
|
- Using low values for FOV will likely cause display issues (except for 0°
|
|
which will activate orthogonal projection).
|
|
- Due to yaw rotation requiring turning of characters, 8-directional
|
|
characters sprites might have only limited support.
|
|
- When using looping maps, don't make them too small. Event positioning on the
|
|
map border could cause issues otherwise.
|
|
- Possibly not compatible with scripts that manipulate tilemap data too much
|
|
or too deeply.
|
|
- Compatible with KhasUltraLighting. Put Ultra Mode 7 BELOW that plugin.
|
|
- Compatible with Yanfly's Gridfree Doodads. Put Ultra Mode 7 BELOW that plugin.
|
|
The "z" coordinate in doodads is not supported.
|
|
- Compatible with MOG's Character Motion. Put Ultra Mode 7 BELOW that plugin.
|
|
- Compatible with Thomas Edison MV. Put Ultra Mode 7 BELOW that plugin.
|
|
- Compatible with Quasi Simple Shadows. Put Ultra Mode 7 BELOW that plugin.
|
|
- Compatible with some newer pixi-tilemap versions.
|
|
- Possibly not compatible with custom character objects that don't derive
|
|
from Game_Event.
|
|
|
|
--Custom compatibility code
|
|
|
|
- This script can be made compatible with the script
|
|
"Terrax Plugins - Lighting system", but due to the way it's
|
|
written, the compatibility needs to be done manually. Find this segment of
|
|
code:
|
|
|
|
if (flashlight == true) {
|
|
this._maskBitmap.radialgradientFillRect2(lx1, ly1, 0, light_radius, colorvalue, '#000000', ldir, flashlength, flashwidth);
|
|
} else {
|
|
this._maskBitmap.radialgradientFillRect(lx1, ly1, 0, light_radius, colorvalue, '#000000', objectflicker, brightness, direction);
|
|
}
|
|
|
|
Replace it with this:
|
|
|
|
var visible = true;
|
|
if ($gameMap.useUltraMode7)
|
|
{
|
|
const position = UltraMode7.mapToScreen(lx1, ly1 + ph / 2);
|
|
if ($gameMap.ultraMode7Fov > 0)
|
|
{
|
|
const z = position.z;
|
|
if (z <= UltraMode7.NEAR_CLIP_Z && z >= UltraMode7.FAR_CLIP_Z)
|
|
{
|
|
visible = false;
|
|
}
|
|
}
|
|
if (visible)
|
|
{
|
|
const scale = UltraMode7.mapToScreenScale(lx1, ly1);
|
|
lx1 = position.x;
|
|
ly1 = position.y -= ph / 2 * scale;
|
|
light_radius *= scale;
|
|
}
|
|
}
|
|
if (visible)
|
|
{
|
|
if (flashlight === true)
|
|
{
|
|
this._maskBitmap.radialgradientFillRect2(lx1, ly1, 0, light_radius, colorvalue, '#000000', ldir, flashlength, flashwidth);
|
|
}
|
|
else
|
|
{
|
|
this._maskBitmap.radialgradientFillRect(lx1, ly1, 0, light_radius, colorvalue, '#000000', objectflicker, brightness, direction);
|
|
}
|
|
}
|
|
|
|
This will make "Terrax Plugins - Lighting system" work with Ultra Mode 7.
|
|
|
|
@param NEAR_CLIP_Z
|
|
@desc Defines the minimum Z-coordinate for visibility of tiles and characters.
|
|
@default 100
|
|
|
|
@param FAR_CLIP_Z
|
|
@desc Defines the maximum Z-coordinate for visibility of tiles and characters.
|
|
@default 1200
|
|
|
|
@param FADE_Z_COLOR
|
|
@desc Defines the global fade color on the tilemap as RGB in interval [0, 1].
|
|
@default 1,1,1
|
|
|
|
@param FADE_Z_BEGIN
|
|
@desc Defines the Z-coordinate at which white fading will start on the tilemap.
|
|
@default 500
|
|
|
|
@param FADE_Z_END
|
|
@desc Defines the Z-coordinate at which white fading will be at full on the tilemap.
|
|
@default 1150
|
|
|
|
@param BASE_SCALE_Z
|
|
@desc Defines the Z-coordinate at which character scaling is 1.0.
|
|
@default 550
|
|
|
|
@param LEGACY_SCALING
|
|
@desc Activates the sprite scaling calculation before v1.6.0.
|
|
ON = true, OFF = false
|
|
@default false
|
|
|
|
@param PARALLAX_SCROLL_X_MULTIPLIER
|
|
@desc Defines the multiplier for parallax X-scrolling.
|
|
@default 0.5
|
|
|
|
@param PARALLAX_SCROLL_Y_MULTIPLIER
|
|
@desc Defines the multiplier for parallax Y-scrolling.
|
|
@default 1.0
|
|
|
|
@param TILEMAP_PIXELATED
|
|
@desc Whether the tilemap should be rendered pixelated.
|
|
ON = true, OFF = false
|
|
@default true
|
|
|
|
@param CHARACTERS_PIXELATED
|
|
@desc Whether the characters should be rendered pixelated.
|
|
ON = true, OFF = false
|
|
@default true
|
|
|
|
@param CHARACTERS_ADJUST_SPRITE_DIRECTION
|
|
@desc Whether characters should have their sprite direction adjusted to yaw angle.
|
|
ON = true, OFF = false
|
|
@default true
|
|
|
|
@param PLAYER_ADJUST_MOVE_DIRECTION
|
|
@desc Whether player directional input should be adjusted to yaw angle.
|
|
ON = true, OFF = false
|
|
@default true
|
|
|
|
@param LOOP_MAPS_EXTEND_TILES
|
|
@desc The additional tiles that are rendered in looping maps.
|
|
@default 3
|
|
|
|
@param DEFAULT_FOV
|
|
@desc Defines the default value for the field-of-view parameter (in degrees).
|
|
@default 60
|
|
|
|
@param DEFAULT_PITCH
|
|
@desc Defines the default value for the pitch rotation angle parameter (in degrees).
|
|
@default 45
|
|
|
|
@param DEFAULT_YAW
|
|
@desc Defines the default value for the yaw rotation angle parameter (in degrees).
|
|
@default 0
|
|
|
|
@param DEFAULT_CAMERA_DISTANCE
|
|
@desc Defines the default distance of the camera from the tilemap in screen space.
|
|
@default 550
|
|
|
|
@param DEFAULT_CAMERA_Y
|
|
@desc Defines the default y-position of the camera from the tilemap in screen space.
|
|
@default 0
|
|
|
|
@param DEFAULT_PARALLAX_DISTANCE
|
|
@desc Defines the distance of the parallax from the center position of the camera.
|
|
@default 550
|
|
|
|
*/
|
|
|
|
//=============================================================================
|
|
// Compatibility
|
|
//=============================================================================
|
|
|
|
var Imported = Imported || {};
|
|
Imported.Blizzard_UltraMode7 = true;
|
|
Imported.Blizzard_UltraMode7.VERSION = 160;
|
|
|
|
//=============================================================================
|
|
// Vector3
|
|
//=============================================================================
|
|
|
|
function Vector3() {
|
|
this.initialize.apply(this, arguments);
|
|
}
|
|
|
|
Vector3.prototype.initialize = function (x, y, z) {
|
|
this.x = x || 0;
|
|
this.y = y || 0;
|
|
this.z = z || 0;
|
|
};
|
|
|
|
Vector3.prototype.set = function (x, y, z) {
|
|
this.x = x;
|
|
this.y = y;
|
|
this.z = z;
|
|
};
|
|
|
|
Vector3.prototype.length = function () {
|
|
return Math.sqrt(this.x * this.x + this.y * this.y + this.z * this.z);
|
|
};
|
|
|
|
Vector3.prototype.normalize = function () {
|
|
var length = this.length();
|
|
if (length !== 0) {
|
|
length = 1 / length;
|
|
this.x *= length;
|
|
this.y *= length;
|
|
this.z *= length;
|
|
}
|
|
};
|
|
|
|
Vector3.prototype.negative = function () {
|
|
this.x = -this.x;
|
|
this.y = -this.y;
|
|
this.z = -this.z;
|
|
};
|
|
|
|
Vector3.prototype.multiply = function (factor) {
|
|
this.x *= factor;
|
|
this.y *= factor;
|
|
this.z *= factor;
|
|
};
|
|
|
|
Vector3.prototype.plused = function (other) {
|
|
return new Vector3(this.x + other.x, this.y + other.y, this.z + other.z);
|
|
};
|
|
|
|
Vector3.prototype.minused = function (other) {
|
|
return new Vector3(this.x - other.x, this.y - other.y, this.z - other.z);
|
|
};
|
|
|
|
Vector3.prototype.averaged = function (other) {
|
|
return new Vector3(
|
|
(this.x + other.x) / 2,
|
|
(this.y + other.y) / 2,
|
|
(this.z + other.z) / 2
|
|
);
|
|
};
|
|
|
|
Vector3.prototype.dotted = function (other) {
|
|
return this.x * other.x + this.y * other.y + this.z * other.z;
|
|
};
|
|
|
|
Vector3.prototype.crossed = function (other) {
|
|
return new Vector3(
|
|
this.y * other.z - this.z * other.y,
|
|
this.z * other.x - this.x * other.z,
|
|
this.x * other.y - this.y * other.x
|
|
);
|
|
};
|
|
|
|
//=============================================================================
|
|
// Matrix4
|
|
//=============================================================================
|
|
|
|
function Matrix4() {
|
|
this.initialize.apply(this, arguments);
|
|
}
|
|
|
|
Matrix4.prototype.initialize = function (data) {
|
|
if (data) {
|
|
this.data = data.slice();
|
|
} else {
|
|
this.data = [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1];
|
|
}
|
|
};
|
|
|
|
Matrix4.prototype.setIdentity = function () {
|
|
this.setZero();
|
|
this.data[0] = this.data[5] = this.data[10] = this.data[15] = 1;
|
|
};
|
|
|
|
Matrix4.prototype.setZero = function () {
|
|
for (var i = 0; i < 16; ++i) {
|
|
this.data[i] = 0;
|
|
}
|
|
};
|
|
|
|
Matrix4.prototype.set = function (data) {
|
|
this.data = data.slice();
|
|
};
|
|
|
|
Matrix4.prototype.setTranslation = function (vector) {
|
|
this.setIdentity();
|
|
this.data[12] = vector.x;
|
|
this.data[13] = vector.y;
|
|
this.data[14] = vector.z;
|
|
};
|
|
|
|
Matrix4.prototype.translate = function (x, y, z) {
|
|
const matrix = new Matrix4();
|
|
matrix.setTranslation(new Vector3(x, y, z));
|
|
this.multiply(matrix);
|
|
};
|
|
|
|
Matrix4.prototype.rotateX = function (angle) {
|
|
const matrix = new Matrix4();
|
|
matrix.setRotationX(angle);
|
|
this.multiply(matrix);
|
|
};
|
|
|
|
Matrix4.prototype.rotateY = function (angle) {
|
|
const matrix = new Matrix4();
|
|
matrix.setRotationY(angle);
|
|
this.multiply(matrix);
|
|
};
|
|
|
|
Matrix4.prototype.rotateZ = function (angle) {
|
|
const matrix = new Matrix4();
|
|
matrix.setRotationZ(angle);
|
|
this.multiply(matrix);
|
|
};
|
|
|
|
Matrix4.prototype.setRotationX = function (angle) {
|
|
this.setZero();
|
|
const rad = BlizzardUtility.degreesToRadians(angle);
|
|
this.data[0] = this.data[15] = 1;
|
|
this.data[5] = this.data[10] = Math.cos(rad);
|
|
this.data[6] = Math.sin(rad);
|
|
this.data[9] = -this.data[6];
|
|
};
|
|
|
|
Matrix4.prototype.setRotationY = function (angle) {
|
|
this.setZero();
|
|
const rad = BlizzardUtility.degreesToRadians(angle);
|
|
this.data[5] = this.data[15] = 1;
|
|
this.data[0] = this.data[10] = Math.cos(rad);
|
|
this.data[8] = Math.sin(rad);
|
|
this.data[2] = -this.data[8];
|
|
};
|
|
|
|
Matrix4.prototype.setRotationZ = function (angle) {
|
|
this.setZero();
|
|
const rad = BlizzardUtility.degreesToRadians(angle);
|
|
this.data[10] = this.data[15] = 1;
|
|
this.data[0] = this.data[5] = Math.cos(rad);
|
|
this.data[1] = Math.sin(rad);
|
|
this.data[4] = -this.data[1];
|
|
};
|
|
|
|
Matrix4.prototype.multiply = function (other) {
|
|
this.set([
|
|
this.data[0] * other.data[0] +
|
|
this.data[4] * other.data[1] +
|
|
this.data[8] * other.data[2] +
|
|
this.data[12] * other.data[3],
|
|
this.data[1] * other.data[0] +
|
|
this.data[5] * other.data[1] +
|
|
this.data[9] * other.data[2] +
|
|
this.data[13] * other.data[3],
|
|
this.data[2] * other.data[0] +
|
|
this.data[6] * other.data[1] +
|
|
this.data[10] * other.data[2] +
|
|
this.data[14] * other.data[3],
|
|
this.data[3] * other.data[0] +
|
|
this.data[7] * other.data[1] +
|
|
this.data[11] * other.data[2] +
|
|
this.data[15] * other.data[3],
|
|
this.data[0] * other.data[4] +
|
|
this.data[4] * other.data[5] +
|
|
this.data[8] * other.data[6] +
|
|
this.data[12] * other.data[7],
|
|
this.data[1] * other.data[4] +
|
|
this.data[5] * other.data[5] +
|
|
this.data[9] * other.data[6] +
|
|
this.data[13] * other.data[7],
|
|
this.data[2] * other.data[4] +
|
|
this.data[6] * other.data[5] +
|
|
this.data[10] * other.data[6] +
|
|
this.data[14] * other.data[7],
|
|
this.data[3] * other.data[4] +
|
|
this.data[7] * other.data[5] +
|
|
this.data[11] * other.data[6] +
|
|
this.data[15] * other.data[7],
|
|
this.data[0] * other.data[8] +
|
|
this.data[4] * other.data[9] +
|
|
this.data[8] * other.data[10] +
|
|
this.data[12] * other.data[11],
|
|
this.data[1] * other.data[8] +
|
|
this.data[5] * other.data[9] +
|
|
this.data[9] * other.data[10] +
|
|
this.data[13] * other.data[11],
|
|
this.data[2] * other.data[8] +
|
|
this.data[6] * other.data[9] +
|
|
this.data[10] * other.data[10] +
|
|
this.data[14] * other.data[11],
|
|
this.data[3] * other.data[8] +
|
|
this.data[7] * other.data[9] +
|
|
this.data[11] * other.data[10] +
|
|
this.data[15] * other.data[11],
|
|
this.data[0] * other.data[12] +
|
|
this.data[4] * other.data[13] +
|
|
this.data[8] * other.data[14] +
|
|
this.data[12] * other.data[15],
|
|
this.data[1] * other.data[12] +
|
|
this.data[5] * other.data[13] +
|
|
this.data[9] * other.data[14] +
|
|
this.data[13] * other.data[15],
|
|
this.data[2] * other.data[12] +
|
|
this.data[6] * other.data[13] +
|
|
this.data[10] * other.data[14] +
|
|
this.data[14] * other.data[15],
|
|
this.data[3] * other.data[12] +
|
|
this.data[7] * other.data[13] +
|
|
this.data[11] * other.data[14] +
|
|
this.data[15] * other.data[15],
|
|
]);
|
|
};
|
|
|
|
Matrix4.prototype.multiplied = function (vector) {
|
|
return new Vector3(
|
|
this.data[0] * vector.x +
|
|
this.data[4] * vector.y +
|
|
this.data[8] * vector.z +
|
|
this.data[12],
|
|
this.data[1] * vector.x +
|
|
this.data[5] * vector.y +
|
|
this.data[9] * vector.z +
|
|
this.data[13],
|
|
this.data[2] * vector.x +
|
|
this.data[6] * vector.y +
|
|
this.data[10] * vector.z +
|
|
this.data[14]
|
|
);
|
|
};
|
|
|
|
Matrix4.prototype.lookAt = function (eye, target, up) {
|
|
this.setZero();
|
|
const bz = eye.minused(target);
|
|
bz.normalize();
|
|
const bx = up.crossed(bz);
|
|
bx.normalize();
|
|
const by = bz.crossed(bx);
|
|
by.normalize();
|
|
this.data[0] = bx.x;
|
|
this.data[1] = by.x;
|
|
this.data[2] = bz.x;
|
|
this.data[4] = bx.y;
|
|
this.data[5] = by.y;
|
|
this.data[6] = bz.y;
|
|
this.data[8] = bx.z;
|
|
this.data[9] = by.z;
|
|
this.data[10] = bz.z;
|
|
this.data[15] = 1;
|
|
eye.negative();
|
|
const b = new Matrix4();
|
|
b.setTranslation(eye);
|
|
this.multiply(b);
|
|
};
|
|
|
|
Matrix4.prototype.setPerspective = function (fov, width, height, nearZ, farZ) {
|
|
this.setZero();
|
|
const iy = 1 / Math.tan(BlizzardUtility.degreesToRadians(fov * 0.5));
|
|
const zDiff = farZ - nearZ;
|
|
this.data[0] = (iy * height) / width;
|
|
this.data[5] = iy;
|
|
this.data[10] = -(farZ + nearZ) / zDiff;
|
|
this.data[11] = -1;
|
|
this.data[14] = (-2 * farZ * nearZ) / zDiff;
|
|
};
|
|
|
|
Matrix4.prototype.setOrthoProjection = function (x, y, width, height) {
|
|
this.setZero();
|
|
this.data[0] = 2 / width;
|
|
this.data[5] = 2 / height;
|
|
this.data[12] = (x * 2) / width;
|
|
this.data[13] = (y * 2) / height;
|
|
this.data[15] = 1;
|
|
};
|
|
|
|
Matrix4.prototype.inversed = function () {
|
|
const invDet = 1 / this.determinant();
|
|
m = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1];
|
|
m[0] = (this.data[5] * this.data[10] - this.data[9] * this.data[6]) * invDet;
|
|
m[1] = -(this.data[1] * this.data[10] - this.data[9] * this.data[2]) * invDet;
|
|
m[2] = (this.data[1] * this.data[6] - this.data[5] * this.data[2]) * invDet;
|
|
m[4] = -(this.data[4] * this.data[10] - this.data[8] * this.data[6]) * invDet;
|
|
m[5] = (this.data[0] * this.data[10] - this.data[8] * this.data[2]) * invDet;
|
|
m[6] = -(this.data[0] * this.data[6] - this.data[4] * this.data[2]) * invDet;
|
|
m[8] = (this.data[4] * this.data[9] - this.data[8] * this.data[5]) * invDet;
|
|
m[9] = -(this.data[0] * this.data[9] - this.data[8] * this.data[1]) * invDet;
|
|
m[10] = (this.data[0] * this.data[5] - this.data[4] * this.data[1]) * invDet;
|
|
m[12] = -(this.data[12] * m[0] + this.data[13] * m[4] + this.data[14] * m[8]);
|
|
m[13] = -(this.data[12] * m[1] + this.data[13] * m[5] + this.data[14] * m[9]);
|
|
m[14] = -(
|
|
this.data[12] * m[2] +
|
|
this.data[13] * m[6] +
|
|
this.data[14] * m[10]
|
|
);
|
|
return new Matrix4(m);
|
|
};
|
|
|
|
Matrix4.prototype.determinant = function () {
|
|
return (
|
|
this.data[0] * this.data[5] * this.data[10] +
|
|
this.data[2] * this.data[4] * this.data[9] +
|
|
this.data[1] * this.data[6] * this.data[8] -
|
|
this.data[2] * this.data[5] * this.data[8] -
|
|
this.data[1] * this.data[4] * this.data[10] -
|
|
this.data[0] * this.data[6] * this.data[9]
|
|
);
|
|
};
|
|
|
|
Matrix4.prototype.transpose = function () {
|
|
this.set([
|
|
this.data[0],
|
|
this.data[4],
|
|
this.data[8],
|
|
this.data[12],
|
|
this.data[1],
|
|
this.data[5],
|
|
this.data[9],
|
|
this.data[13],
|
|
this.data[2],
|
|
this.data[6],
|
|
this.data[10],
|
|
this.data[14],
|
|
this.data[3],
|
|
this.data[7],
|
|
this.data[11],
|
|
this.data[15],
|
|
]);
|
|
};
|
|
|
|
//=============================================================================
|
|
// Ultra Mode 7
|
|
//=============================================================================
|
|
|
|
(function () {
|
|
if (!Graphics.hasWebGL()) {
|
|
console.error("Ultra Mode 7 requires WebGL support!");
|
|
return;
|
|
}
|
|
|
|
//=============================================================================
|
|
// BlizzardUtility
|
|
//=============================================================================
|
|
|
|
if (typeof BlizzardUtility === "undefined") {
|
|
BlizzardUtility = function () {
|
|
throw new Error("This is a static class");
|
|
};
|
|
}
|
|
|
|
BlizzardUtility.degreesToRadians = function (degrees) {
|
|
return degrees * 0.01745329251994329576923690768489;
|
|
};
|
|
|
|
BlizzardUtility.radiansToDegrees = function (radians) {
|
|
return radians * 57.295779513082320876798154814105;
|
|
};
|
|
|
|
BlizzardUtility.hypot = function (x, y) {
|
|
return Math.sqrt(x * x + y * y);
|
|
};
|
|
|
|
BlizzardUtility.Numeric = function (value, defaultValue) {
|
|
const result = Number(value);
|
|
if (result || result === 0) {
|
|
return result;
|
|
}
|
|
return defaultValue;
|
|
};
|
|
|
|
//=============================================================================
|
|
// UltraMode7
|
|
//=============================================================================
|
|
|
|
UltraMode7 = {};
|
|
|
|
UltraMode7.log = function (message) {
|
|
console.log("Ultra Mode 7: " + message);
|
|
};
|
|
|
|
// constants
|
|
// NOTE: Don't change these unless you know what you are doing!
|
|
|
|
UltraMode7.WEBGL_MAX_VERTICES = 65520; // stay under the WebGL limit of 65536, some have reported bugs
|
|
UltraMode7.MIN_FOV = 0;
|
|
UltraMode7.MIN_PITCH = 0;
|
|
UltraMode7.MAX_PITCH = 90;
|
|
|
|
// configuration parameters
|
|
|
|
const _parameters = PluginManager.parameters("UltraMode7");
|
|
UltraMode7.NEAR_CLIP_Z = BlizzardUtility.Numeric(
|
|
_parameters["NEAR_CLIP_Z"],
|
|
100
|
|
);
|
|
UltraMode7.FAR_CLIP_Z = Math.max(
|
|
BlizzardUtility.Numeric(_parameters["FAR_CLIP_Z"], 1200),
|
|
UltraMode7.NEAR_CLIP_Z + 1
|
|
);
|
|
UltraMode7.FADE_Z_COLOR = JSON.parse("[" + _parameters["FADE_Z_COLOR"] + "]");
|
|
UltraMode7.FADE_Z_BEGIN = BlizzardUtility.Numeric(
|
|
_parameters["FADE_Z_BEGIN"],
|
|
500
|
|
);
|
|
UltraMode7.FADE_Z_END = BlizzardUtility.Numeric(
|
|
_parameters["FADE_Z_END"],
|
|
1150
|
|
);
|
|
UltraMode7.BASE_SCALE_Z = BlizzardUtility.Numeric(
|
|
_parameters["BASE_SCALE_Z"],
|
|
550
|
|
);
|
|
UltraMode7.LEGACY_SCALING = JSON.parse(_parameters["LEGACY_SCALING"]);
|
|
UltraMode7.PARALLAX_SCROLL_X_MULTIPLIER = BlizzardUtility.Numeric(
|
|
_parameters["PARALLAX_SCROLL_X_MULTIPLIER"],
|
|
0.5
|
|
);
|
|
UltraMode7.PARALLAX_SCROLL_Y_MULTIPLIER = BlizzardUtility.Numeric(
|
|
_parameters["PARALLAX_SCROLL_Y_MULTIPLIER"],
|
|
1.0
|
|
);
|
|
UltraMode7.TILEMAP_PIXELATED = JSON.parse(_parameters["TILEMAP_PIXELATED"]);
|
|
UltraMode7.CHARACTERS_PIXELATED = JSON.parse(
|
|
_parameters["CHARACTERS_PIXELATED"]
|
|
);
|
|
UltraMode7.CHARACTERS_ADJUST_SPRITE_DIRECTION = JSON.parse(
|
|
_parameters["CHARACTERS_ADJUST_SPRITE_DIRECTION"]
|
|
);
|
|
UltraMode7.PLAYER_ADJUST_MOVE_DIRECTION = JSON.parse(
|
|
_parameters["PLAYER_ADJUST_MOVE_DIRECTION"]
|
|
);
|
|
UltraMode7.LOOP_MAPS_EXTEND_TILES = Math.max(
|
|
BlizzardUtility.Numeric(_parameters["LOOP_MAPS_EXTEND_TILES"], 3),
|
|
0
|
|
);
|
|
UltraMode7.DEFAULT_FOV = BlizzardUtility.Numeric(
|
|
_parameters["DEFAULT_FOV"],
|
|
60
|
|
);
|
|
UltraMode7.DEFAULT_PITCH = BlizzardUtility.Numeric(
|
|
_parameters["DEFAULT_PITCH"],
|
|
45
|
|
);
|
|
UltraMode7.DEFAULT_YAW = BlizzardUtility.Numeric(
|
|
_parameters["DEFAULT_YAW"],
|
|
0
|
|
);
|
|
UltraMode7.DEFAULT_CAMERA_DISTANCE = Math.max(
|
|
BlizzardUtility.Numeric(_parameters["DEFAULT_CAMERA_DISTANCE"], 550),
|
|
0
|
|
);
|
|
UltraMode7.DEFAULT_CAMERA_Y = BlizzardUtility.Numeric(
|
|
_parameters["DEFAULT_CAMERA_Y"],
|
|
0
|
|
);
|
|
UltraMode7.DEFAULT_PARALLAX_DISTANCE = Math.max(
|
|
BlizzardUtility.Numeric(_parameters["DEFAULT_PARALLAX_DISTANCE"], 550),
|
|
1
|
|
);
|
|
|
|
// validation of parameters
|
|
|
|
UltraMode7.validateFadeColor = function (color) {
|
|
if (!Array.isArray(color) || color.length !== 3) {
|
|
UltraMode7.log(
|
|
"Parameter for 'fade Z color' is malformed! Defaulting back to '1,1,1'."
|
|
);
|
|
return [1.0, 1.0, 1.0];
|
|
}
|
|
return [
|
|
color[0].clamp(0.0, 1.0),
|
|
color[1].clamp(0.0, 1.0),
|
|
color[2].clamp(0.0, 1.0),
|
|
];
|
|
};
|
|
|
|
UltraMode7.FADE_Z_COLOR = UltraMode7.validateFadeColor(
|
|
UltraMode7.FADE_Z_COLOR
|
|
);
|
|
|
|
// additional compatibility code
|
|
|
|
UltraMode7.NEWER_PIXI_TILEMAP =
|
|
!!PIXI.tilemap.RectTileLayer.prototype.renderWebGLCore;
|
|
if (UltraMode7.NEWER_PIXI_TILEMAP) {
|
|
UltraMode7.log(
|
|
"Detected a newer 'pixi-tilemap' implementation, enabling compatibility code."
|
|
);
|
|
}
|
|
|
|
// interface functions for script calls
|
|
|
|
UltraMode7.getFov = function () {
|
|
return $gameMap.ultraMode7Fov;
|
|
};
|
|
|
|
UltraMode7.setFov = function (value) {
|
|
$gameMap.setUltraMode7Fov(value);
|
|
};
|
|
|
|
UltraMode7.getPitch = function () {
|
|
return $gameMap.ultraMode7Pitch;
|
|
};
|
|
|
|
UltraMode7.setPitch = function (value) {
|
|
$gameMap.setUltraMode7Pitch(value);
|
|
};
|
|
|
|
UltraMode7.getYaw = function () {
|
|
return $gameMap.ultraMode7Yaw;
|
|
};
|
|
|
|
UltraMode7.setYaw = function (value) {
|
|
$gameMap.setUltraMode7Yaw(value);
|
|
};
|
|
|
|
UltraMode7.getCameraDistance = function () {
|
|
return $gameMap.ultraMode7CameraDistance;
|
|
};
|
|
|
|
UltraMode7.setCameraDistance = function (value) {
|
|
$gameMap.setUltraMode7CameraDistance(value);
|
|
};
|
|
|
|
UltraMode7.getCameraY = function () {
|
|
return $gameMap.ultraMode7CameraY;
|
|
};
|
|
|
|
UltraMode7.setCameraY = function (value) {
|
|
$gameMap.setUltraMode7CameraY(value);
|
|
};
|
|
|
|
UltraMode7.getParallaxDistance = function () {
|
|
return $gameMap.ultraMode7ParallaxDistance;
|
|
};
|
|
|
|
UltraMode7.setParallaxDistance = function (value) {
|
|
$gameMap.setUltraMode7ParallaxDistance(value);
|
|
};
|
|
|
|
UltraMode7.isTilemapPixelated = function () {
|
|
return PIXI.tilemap.TileRenderer.SCALE_MODE === PIXI.SCALE_MODES.NEAREST;
|
|
};
|
|
|
|
UltraMode7.setTilemapPixelated = function (value) {
|
|
if (value) {
|
|
PIXI.tilemap.TileRenderer.SCALE_MODE = PIXI.SCALE_MODES.NEAREST;
|
|
} else {
|
|
PIXI.tilemap.TileRenderer.SCALE_MODE = PIXI.SCALE_MODES.LINEAR;
|
|
}
|
|
};
|
|
|
|
UltraMode7.getFadeColor = function () {
|
|
return $gameMap.ultraMode7FadeColor;
|
|
};
|
|
|
|
UltraMode7.setFadeColor = function (value) {
|
|
$gameMap.setUltraMode7FadeColor(value);
|
|
};
|
|
|
|
UltraMode7.getFadeBegin = function () {
|
|
return $gameMap.ultraMode7FadeBegin;
|
|
};
|
|
|
|
UltraMode7.setFadeBegin = function (value) {
|
|
$gameMap.setUltraMode7FadeBegin(value);
|
|
};
|
|
|
|
UltraMode7.getFadeEnd = function () {
|
|
return $gameMap.ultraMode7FadeEnd;
|
|
};
|
|
|
|
UltraMode7.setFadeEnd = function (value) {
|
|
$gameMap.setUltraMode7FadeEnd(value);
|
|
};
|
|
|
|
UltraMode7.animateFov = function (target, frameDuration) {
|
|
$gameMap.animateUltraMode7Fov(target, frameDuration);
|
|
};
|
|
|
|
UltraMode7.animatePitch = function (target, frameDuration) {
|
|
$gameMap.animateUltraMode7Pitch(target, frameDuration);
|
|
};
|
|
|
|
UltraMode7.animateYaw = function (target, frameDuration) {
|
|
$gameMap.animateUltraMode7Yaw(target, frameDuration);
|
|
};
|
|
|
|
UltraMode7.animateCameraDistance = function (target, frameDuration) {
|
|
$gameMap.animateUltraMode7CameraDistance(target, frameDuration);
|
|
};
|
|
|
|
UltraMode7.animateCameraY = function (target, frameDuration) {
|
|
$gameMap.animateUltraMode7CameraY(target, frameDuration);
|
|
};
|
|
|
|
UltraMode7.animateFadeColor = function (target, frameDuration) {
|
|
$gameMap.animateUltraMode7FadeColor(target, frameDuration);
|
|
};
|
|
|
|
UltraMode7.animateFadeBegin = function (target, frameDuration) {
|
|
$gameMap.animateUltraMode7FadeBegin(target, frameDuration);
|
|
};
|
|
|
|
UltraMode7.animateFadeEnd = function (target, frameDuration) {
|
|
$gameMap.animateUltraMode7FadeEnd(target, frameDuration);
|
|
};
|
|
|
|
// functions
|
|
|
|
UltraMode7.screenToMap = function (x, y) {
|
|
// transform 2 point ray from projection into world
|
|
const projectionMatrix = $gameMap.ultraMode7ProjectionMatrix;
|
|
const halfWidth = Graphics.boxWidth / 2;
|
|
const halfHeight = Graphics.boxHeight / 2;
|
|
var origin = new Vector3(x - halfWidth, y - halfHeight, -1);
|
|
var target = new Vector3(x - halfWidth, y - halfHeight, 1);
|
|
if ($gameMap.ultraMode7Fov > 0) {
|
|
const scaleZ = projectionMatrix.data[10];
|
|
const offsetZ = projectionMatrix.data[14];
|
|
origin.x = (origin.x * (offsetZ - origin.z)) / scaleZ / halfWidth;
|
|
origin.y = (origin.y * (offsetZ - origin.z)) / scaleZ / halfHeight;
|
|
target.x = (target.x * (offsetZ - target.z)) / scaleZ / halfWidth;
|
|
target.y = (target.y * (offsetZ - target.z)) / scaleZ / halfHeight;
|
|
const inversedProjectionMatrix = projectionMatrix.inversed();
|
|
origin = inversedProjectionMatrix.multiplied(origin);
|
|
target = inversedProjectionMatrix.multiplied(target);
|
|
}
|
|
const mapWidth = $gameMap.width() * $gameMap.tileWidth();
|
|
const mapHeight = $gameMap.height() * $gameMap.tileHeight();
|
|
// first transform 4 points from model into world space
|
|
const modelviewMatrix = $gameMap.ultraMode7ModelviewMatrix;
|
|
const topLeft = modelviewMatrix.multiplied(new Vector3(0, 0, 0));
|
|
const topRight = modelviewMatrix.multiplied(new Vector3(mapWidth, 0, 0));
|
|
const bottomLeft = modelviewMatrix.multiplied(new Vector3(0, mapHeight, 0));
|
|
const bottomRight = modelviewMatrix.multiplied(
|
|
new Vector3(mapWidth, mapHeight, 0)
|
|
);
|
|
// solve equation Ax + By + Cz + D = 0
|
|
const equations = [
|
|
[topLeft.x, topLeft.y, topLeft.z, 0],
|
|
[topRight.x, topRight.y, topRight.z, 0],
|
|
[bottomLeft.x, bottomLeft.y, bottomLeft.z, 0],
|
|
[bottomRight.x, bottomRight.y, bottomRight.z, 0],
|
|
];
|
|
const factors =
|
|
UltraMode7._solveLinearEquationWithGaussianElimination(equations);
|
|
// create plane equation
|
|
const ray = target.minused(origin);
|
|
const normal = new Vector3(factors[0], factors[1], factors[2]);
|
|
ray.multiply((factors[3] - normal.dotted(origin)) / normal.dotted(ray));
|
|
const intersection = origin.plused(ray);
|
|
return modelviewMatrix.inversed().multiplied(intersection);
|
|
};
|
|
|
|
UltraMode7._solveLinearEquationWithGaussianElimination = function (M) {
|
|
const mLength = M.length;
|
|
for (var i = 0; i < mLength; ++i) {
|
|
M[i].push(1);
|
|
}
|
|
for (var i = 0; i < mLength; ++i) {
|
|
// Search for maximum in this column
|
|
var maxElement = Math.abs(M[i][i]);
|
|
var maxRow = i;
|
|
for (var k = i + 1; k < mLength; ++k) {
|
|
const newMax = Math.abs(M[k][i]);
|
|
if (maxElement < newMax) {
|
|
maxElement = newMax;
|
|
maxRow = k;
|
|
}
|
|
}
|
|
// Swap maximum row with current row (column by column)
|
|
for (var k = i; k < mLength + 1; ++k) {
|
|
const swap = M[maxRow][k];
|
|
M[maxRow][k] = M[i][k];
|
|
M[i][k] = swap;
|
|
}
|
|
if (M[i][i] !== 0) {
|
|
// Make all rows below this one 0 in current column
|
|
for (var k = i + 1; k < mLength; ++k) {
|
|
const value = -M[k][i] / M[i][i];
|
|
for (var j = i; j < mLength + 1; ++j) {
|
|
if (i === j) {
|
|
M[k][j] = 0;
|
|
} else {
|
|
M[k][j] += value * M[i][j];
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
// Solve equation Mx=b for the upper triangular matrix M
|
|
result = [];
|
|
for (var i = mLength - 1; i >= 0; --i) {
|
|
if (M[i][i] === 0) {
|
|
result[i] = 1;
|
|
} else {
|
|
result[i] = M[i][mLength] / M[i][i];
|
|
}
|
|
for (var k = i - 1; k >= 0; --k) {
|
|
M[k][mLength] -= M[k][i] * result[i];
|
|
}
|
|
}
|
|
return result;
|
|
};
|
|
|
|
UltraMode7.mapToScreen = function (x, y, z) {
|
|
const position = new Vector3(
|
|
x + $gameMap.displayX() * $gameMap.tileWidth(),
|
|
y + $gameMap.displayY() * $gameMap.tileHeight(),
|
|
z || 0
|
|
);
|
|
const worldPosition =
|
|
$gameMap.ultraMode7ModelviewMatrix.multiplied(position);
|
|
const projection = $gameMap.ultraMode7ProjectionMatrix;
|
|
const result = projection.multiplied(worldPosition);
|
|
// W is needed for perspective projection
|
|
const vectorW =
|
|
projection.data[3] * worldPosition.x +
|
|
projection.data[7] * worldPosition.y +
|
|
projection.data[11] * worldPosition.z +
|
|
projection.data[15];
|
|
// calculate perspective projection and offset to screen coordinates
|
|
const halfWidth = Graphics.boxWidth / 2;
|
|
const halfHeight = Graphics.boxHeight / 2;
|
|
result.x =
|
|
(result.x * halfWidth) / vectorW + halfWidth - $gameScreen.shake();
|
|
result.y = (result.y * halfHeight) / vectorW + halfHeight;
|
|
if (!UltraMode7.LEGACY_SCALING) {
|
|
const factor = -projection.data[10];
|
|
result.z =
|
|
result.z / factor + ((factor - 1) / factor) * UltraMode7.FAR_CLIP_Z;
|
|
}
|
|
return result;
|
|
};
|
|
|
|
UltraMode7.mapToScreenScale = function (x, y, z) {
|
|
if ($gameMap.ultraMode7Fov <= 0) {
|
|
return 1.0;
|
|
}
|
|
return UltraMode7.mapZToScreenScale(UltraMode7.mapToScreen(x, y, z).z);
|
|
};
|
|
|
|
UltraMode7.mapZToScreenScale = function (z) {
|
|
// clamping to 10000 for safety infinity
|
|
return z !== 0.0
|
|
? UltraMode7.BASE_SCALE_Z / Math.abs(z).clamp(0.0, 10000.0)
|
|
: 10000.0;
|
|
};
|
|
|
|
UltraMode7.rotateDirection = function (direction, clockwise) {
|
|
const angle = $gameMap.ultraMode7Yaw.mod(360);
|
|
if (
|
|
(clockwise && angle >= 45 && angle <= 135) ||
|
|
(!clockwise && angle >= 225 && angle <= 315)
|
|
) {
|
|
switch (direction) {
|
|
case 2:
|
|
direction = 4;
|
|
break;
|
|
case 4:
|
|
direction = 8;
|
|
break;
|
|
case 6:
|
|
direction = 2;
|
|
break;
|
|
case 8:
|
|
direction = 6;
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
} else if (angle > 135 && angle < 225) {
|
|
direction = 10 - direction;
|
|
} else if (
|
|
(!clockwise && angle >= 45 && angle <= 135) ||
|
|
(clockwise && angle >= 225 && angle <= 315)
|
|
) {
|
|
switch (direction) {
|
|
case 2:
|
|
direction = 6;
|
|
break;
|
|
case 4:
|
|
direction = 2;
|
|
break;
|
|
case 6:
|
|
direction = 8;
|
|
break;
|
|
case 8:
|
|
direction = 4;
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
return direction;
|
|
};
|
|
|
|
//=============================================================================
|
|
// Shader
|
|
//=============================================================================
|
|
|
|
UltraMode7.Shader = (function (_super) {
|
|
RECT_SHADER_VERTEX =
|
|
"\n\
|
|
attribute vec2 aVertexPosition;\n\
|
|
attribute vec2 aTextureCoord;\n\
|
|
attribute vec4 aFrame;\n\
|
|
attribute vec2 aAnim;\n\
|
|
attribute float aTextureId;\n\
|
|
\n\
|
|
uniform mat4 mode7ProjectionMatrix;\n\
|
|
uniform mat4 mode7ModelviewMatrix;\n\
|
|
uniform vec2 animationFrame;\n\
|
|
uniform float fadeBegin;\n\
|
|
uniform float fadeRange;\n\
|
|
\n\
|
|
varying vec2 vTextureCoord;\n\
|
|
varying vec4 vFrame;\n\
|
|
varying float vTextureId;\n\
|
|
varying float vFade;\n\
|
|
\n\
|
|
void main(void){\n\
|
|
vec4 position = mode7ModelviewMatrix * vec4(aVertexPosition, 0.0, 1.0);\n\
|
|
position = mode7ProjectionMatrix * vec4(position.x, position.y, position.z, position.w);\
|
|
gl_Position = position;\
|
|
vec2 anim = aAnim * animationFrame;\n\
|
|
vTextureCoord = aTextureCoord + anim;\n\
|
|
vFrame = aFrame + vec4(anim, anim);\n\
|
|
vTextureId = aTextureId;\n\
|
|
vFade = clamp((position.z - fadeBegin) / fadeRange, 0.0, 1.0);\n\
|
|
}\n";
|
|
|
|
RECT_SHADER_FRAGMENT =
|
|
"\
|
|
varying vec2 vTextureCoord;\n\
|
|
varying vec4 vFrame;\n\
|
|
varying float vTextureId;\n\
|
|
varying float vFade;\n\
|
|
uniform vec4 shadowColor;\n\
|
|
uniform vec3 fadeColor;\n\
|
|
uniform sampler2D uSamplers[%count%];\n\
|
|
uniform vec2 uSamplerSize[%count%];\n\
|
|
\n\
|
|
void main(void){\n\
|
|
vec2 textureCoord = clamp(vTextureCoord, vFrame.xy, vFrame.zw);\n\
|
|
float textureId = floor(vTextureId + 0.5);\n\
|
|
\n\
|
|
vec4 color;\n\
|
|
%forloop%\n\
|
|
if (color.a < 0.01)\n\
|
|
{\n\
|
|
discard;\n\
|
|
}\n\
|
|
vec3 multipliedFadeColor = vec3(color.a, color.a, color.a) * fadeColor;\n\
|
|
gl_FragColor = vec4(mix(color.rgb, multipliedFadeColor, vFade), color.a);\n\
|
|
}";
|
|
__extends(Shader, _super);
|
|
FLOAT_SIZE = 4;
|
|
function Shader(gl, maxTextures) {
|
|
var _this =
|
|
_super.call(
|
|
this,
|
|
gl,
|
|
maxTextures,
|
|
RECT_SHADER_VERTEX,
|
|
PIXI.tilemap.shaderGenerator.generateFragmentSrc(
|
|
maxTextures,
|
|
RECT_SHADER_FRAGMENT
|
|
)
|
|
) || this;
|
|
_this.vertSize = 11;
|
|
_this.vertPerQuad = 4;
|
|
_this.stride = _this.vertSize * FLOAT_SIZE;
|
|
PIXI.tilemap.shaderGenerator.fillSamplers(_this, maxTextures);
|
|
return _this;
|
|
}
|
|
Shader.prototype.createVao = function (renderer, vb) {
|
|
var gl = renderer.gl;
|
|
this.uniforms.mode7ProjectionMatrix =
|
|
$gameMap.ultraMode7ProjectionMatrix.data;
|
|
this.uniforms.mode7ModelviewMatrix =
|
|
$gameMap.ultraMode7ModelviewMatrix.data;
|
|
this.uniforms.fadeColor = [1.0, 1.0, 1.0];
|
|
this.uniforms.fadeBegin = UltraMode7.FADE_Z_BEGIN;
|
|
this.uniforms.fadeRange = UltraMode7.FADE_Z_END - UltraMode7.FADE_Z_BEGIN;
|
|
return renderer
|
|
.createVao()
|
|
.addIndex(this.indexBuffer)
|
|
.addAttribute(
|
|
vb,
|
|
this.attributes.aVertexPosition,
|
|
gl.FLOAT,
|
|
false,
|
|
this.stride,
|
|
0
|
|
)
|
|
.addAttribute(
|
|
vb,
|
|
this.attributes.aTextureCoord,
|
|
gl.FLOAT,
|
|
false,
|
|
this.stride,
|
|
2 * FLOAT_SIZE
|
|
)
|
|
.addAttribute(
|
|
vb,
|
|
this.attributes.aFrame,
|
|
gl.FLOAT,
|
|
false,
|
|
this.stride,
|
|
4 * FLOAT_SIZE
|
|
)
|
|
.addAttribute(
|
|
vb,
|
|
this.attributes.aAnim,
|
|
gl.FLOAT,
|
|
false,
|
|
this.stride,
|
|
8 * FLOAT_SIZE
|
|
)
|
|
.addAttribute(
|
|
vb,
|
|
this.attributes.aTextureId,
|
|
gl.FLOAT,
|
|
false,
|
|
this.stride,
|
|
10 * FLOAT_SIZE
|
|
);
|
|
};
|
|
return Shader;
|
|
})(PIXI.tilemap.TilemapShader);
|
|
|
|
//=============================================================================
|
|
// PIXI.tilemap.TileRenderer
|
|
//=============================================================================
|
|
|
|
if (UltraMode7.TILEMAP_PIXELATED) {
|
|
PIXI.tilemap.TileRenderer.SCALE_MODE = PIXI.SCALE_MODES.NEAREST;
|
|
} else {
|
|
PIXI.tilemap.TileRenderer.SCALE_MODE = PIXI.SCALE_MODES.LINEAR;
|
|
}
|
|
|
|
const UltraMode7_PIXI_tilemap_TileRenderer_prototype_onContextChange =
|
|
PIXI.tilemap.TileRenderer.prototype.onContextChange;
|
|
PIXI.tilemap.TileRenderer.prototype.onContextChange = function () {
|
|
UltraMode7_PIXI_tilemap_TileRenderer_prototype_onContextChange.call(this);
|
|
var maxTextures = this.maxTextures;
|
|
if (UltraMode7.NEWER_PIXI_TILEMAP) {
|
|
maxTextures = PIXI.tilemap.Constant.maxTextures;
|
|
}
|
|
this._ultraMode7Shader = new UltraMode7.Shader(
|
|
this.renderer.gl,
|
|
maxTextures
|
|
);
|
|
this._ultraMode7Shader.indexBuffer = this.indexBuffer;
|
|
};
|
|
|
|
const UltraMode7_PIXI_tilemap_TileRenderer_prototype_bindTextures =
|
|
PIXI.tilemap.TileRenderer.prototype.bindTextures;
|
|
PIXI.tilemap.TileRenderer.prototype.bindTextures = function (
|
|
renderer,
|
|
shader,
|
|
textures
|
|
) {
|
|
UltraMode7_PIXI_tilemap_TileRenderer_prototype_bindTextures.call(
|
|
this,
|
|
renderer,
|
|
shader,
|
|
textures
|
|
);
|
|
if (!$gameMap.useUltraMode7) {
|
|
return;
|
|
}
|
|
var maxTextures = this.maxTextures;
|
|
if (UltraMode7.NEWER_PIXI_TILEMAP) {
|
|
maxTextures = PIXI.tilemap.Constant.maxTextures;
|
|
}
|
|
if (textures.length > 4 * maxTextures) {
|
|
return;
|
|
}
|
|
for (var i = 0; i < textures.length; ++i) {
|
|
const texture = textures[i];
|
|
if (
|
|
texture &&
|
|
texture.valid &&
|
|
texture.baseTexture.scaleMode !== PIXI.tilemap.TileRenderer.SCALE_MODE
|
|
) {
|
|
texture.baseTexture.scaleMode = PIXI.tilemap.TileRenderer.SCALE_MODE;
|
|
const glTexture = this.glTextures[i >> 2];
|
|
if (
|
|
glTexture &&
|
|
glTexture.baseTexture.hasLoaded &&
|
|
glTexture.baseTexture._glTextures[renderer.CONTEXT_UID]
|
|
) {
|
|
if (
|
|
PIXI.tilemap.TileRenderer.SCALE_MODE === PIXI.SCALE_MODES.NEAREST
|
|
) {
|
|
glTexture.baseTexture._glTextures[
|
|
renderer.CONTEXT_UID
|
|
].enableNearestScaling();
|
|
} else {
|
|
glTexture.baseTexture._glTextures[
|
|
renderer.CONTEXT_UID
|
|
].enableLinearScaling();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
};
|
|
|
|
const UltraMode7_PIXI_tilemap_TileRenderer_prototype_destroy =
|
|
PIXI.tilemap.TileRenderer.prototype.destroy;
|
|
PIXI.tilemap.TileRenderer.prototype.destroy = function () {
|
|
UltraMode7_PIXI_tilemap_TileRenderer_prototype_destroy.call(this);
|
|
this._ultraMode7Shader.destroy();
|
|
this._ultraMode7Shader = null;
|
|
};
|
|
|
|
const UltraMode7_PIXI_tilemap_TileRenderer_prototype_getShader =
|
|
PIXI.tilemap.TileRenderer.prototype.getShader;
|
|
PIXI.tilemap.TileRenderer.prototype.getShader = function (useSquare) {
|
|
if (!$gameMap.useUltraMode7) {
|
|
return UltraMode7_PIXI_tilemap_TileRenderer_prototype_getShader.call(
|
|
this,
|
|
useSquare
|
|
);
|
|
}
|
|
return this._ultraMode7Shader;
|
|
};
|
|
|
|
if (!UltraMode7.NEWER_PIXI_TILEMAP) {
|
|
// this fixes a bug in PIXI regarding an incorrectly named variable
|
|
const UltraMode7_PIXI_tilemap_TileRenderer_prototype_getVb =
|
|
PIXI.tilemap.TileRenderer.prototype.getVb;
|
|
PIXI.tilemap.TileRenderer.prototype.getVb = function (id) {
|
|
const vb = UltraMode7_PIXI_tilemap_TileRenderer_prototype_getVb.call(
|
|
this,
|
|
id
|
|
);
|
|
if (vb && vb.lastAccessTime) {
|
|
vb.lastTimeAccess = vb.lastAccessTime;
|
|
delete vb.lastAccessTime;
|
|
}
|
|
return vb;
|
|
};
|
|
}
|
|
|
|
//=============================================================================
|
|
// PIXI.tilemap.RectTileLayer
|
|
//=============================================================================
|
|
|
|
if (!UltraMode7.NEWER_PIXI_TILEMAP) {
|
|
const UltraMode7_PIXI_tilemap_RectTileLayer_prototype_renderWebGL =
|
|
PIXI.tilemap.RectTileLayer.prototype.renderWebGL;
|
|
PIXI.tilemap.RectTileLayer.prototype.renderWebGL = function (
|
|
renderer,
|
|
useSquare
|
|
) {
|
|
if (!$gameMap || !$gameMap.useUltraMode7) {
|
|
UltraMode7_PIXI_tilemap_RectTileLayer_prototype_renderWebGL.call(
|
|
this,
|
|
renderer,
|
|
useSquare
|
|
);
|
|
return;
|
|
}
|
|
this.ultraMode7Render(renderer, renderer.plugins.tilemap);
|
|
};
|
|
} else {
|
|
const UltraMode7_PIXI_tilemap_RectTileLayer_prototype_renderWebGLCore =
|
|
PIXI.tilemap.RectTileLayer.prototype.renderWebGLCore;
|
|
PIXI.tilemap.RectTileLayer.prototype.renderWebGLCore = function (
|
|
renderer,
|
|
plugin
|
|
) {
|
|
if (!$gameMap || !$gameMap.useUltraMode7) {
|
|
UltraMode7_PIXI_tilemap_RectTileLayer_prototype_renderWebGLCore.call(
|
|
this,
|
|
renderer,
|
|
plugin
|
|
);
|
|
return;
|
|
}
|
|
this.ultraMode7Render(renderer, plugin || renderer.plugins.tilemap);
|
|
};
|
|
|
|
PIXI.tilemap.RectTileLayer.prototype.getUltraMode7Vb = function (
|
|
renderer,
|
|
vbId
|
|
) {
|
|
if (this.vbs) {
|
|
const _vb = this.vbs[vbId];
|
|
if (_vb) {
|
|
if (_vb.rendererSN === renderer.sn) {
|
|
return _vb;
|
|
}
|
|
const otherVb = this.vb;
|
|
this.vb = _vb;
|
|
UltraMode7_PIXI_tilemap_RectTileLayer_prototype_destroyVb.call(this);
|
|
this.vb = otherVb;
|
|
}
|
|
}
|
|
return null;
|
|
};
|
|
|
|
const UltraMode7_PIXI_tilemap_RectTileLayer_prototype_destroyVb =
|
|
PIXI.tilemap.RectTileLayer.prototype.destroyVb;
|
|
PIXI.tilemap.RectTileLayer.prototype.destroyVb = function () {
|
|
UltraMode7_PIXI_tilemap_RectTileLayer_prototype_destroyVb.call(this);
|
|
if (this.vbs) {
|
|
for (var id in this.vbs) {
|
|
this.vb = this.vbs[id];
|
|
UltraMode7_PIXI_tilemap_RectTileLayer_prototype_destroyVb.call(this);
|
|
}
|
|
this.vbs = null;
|
|
}
|
|
};
|
|
}
|
|
|
|
PIXI.tilemap.RectTileLayer.prototype.ultraMode7Render = function (
|
|
renderer,
|
|
tile
|
|
) {
|
|
const points = this.pointsBuf;
|
|
if (points.length === 0) {
|
|
return;
|
|
}
|
|
const shader = tile.getShader();
|
|
const textures = this.textures;
|
|
if (textures.length === 0) {
|
|
return;
|
|
}
|
|
const rectsCount = points.length / 9;
|
|
if (rectsCount === 0) {
|
|
return;
|
|
}
|
|
const gl = renderer.gl;
|
|
const length = textures.length;
|
|
for (var i = 0; i < length; ++i) {
|
|
if (!textures[i] || !textures[i].valid) {
|
|
return;
|
|
}
|
|
const texture = textures[i].baseTexture;
|
|
}
|
|
if (!this.vbIds) {
|
|
this.vbIds = [];
|
|
this.vbBuffers = [];
|
|
this.modificationMarkers = [];
|
|
this.vbArrays = [];
|
|
}
|
|
tile.checkIndexBuffer(rectsCount);
|
|
tile.bindTextures(renderer, shader, textures);
|
|
shader.uniforms.mode7ProjectionMatrix =
|
|
$gameMap.ultraMode7ProjectionMatrix.data;
|
|
shader.uniforms.mode7ModelviewMatrix =
|
|
$gameMap.ultraMode7ModelviewMatrix.data;
|
|
shader.uniforms.fadeColor = $gameMap.ultraMode7FadeColor;
|
|
shader.uniforms.fadeBegin = $gameMap.ultraMode7FadeBegin;
|
|
shader.uniforms.fadeRange =
|
|
$gameMap.ultraMode7FadeEnd - $gameMap.ultraMode7FadeBegin;
|
|
const maxRects = UltraMode7.WEBGL_MAX_VERTICES / shader.vertPerQuad;
|
|
const maxLoops = Math.floor((rectsCount + maxRects - 1) / maxRects);
|
|
for (var j = 0; j < maxLoops; ++j) {
|
|
if (!this.vbIds[j]) {
|
|
this.vbIds[j] = 0;
|
|
this.vbBuffers[j] = null;
|
|
this.modificationMarkers[j] = 0;
|
|
this.vbArrays[j] = null;
|
|
}
|
|
const currentRectsCount = Math.min(maxRects, rectsCount - j * maxRects);
|
|
var vb = null;
|
|
if (!UltraMode7.NEWER_PIXI_TILEMAP) {
|
|
vb = tile.getVb(this.vbIds[j]);
|
|
} else {
|
|
if (!this.vbs) {
|
|
this.vbs = {};
|
|
}
|
|
vb = this.getUltraMode7Vb(tile, this.vbIds[j]);
|
|
}
|
|
if (!vb) {
|
|
if (!UltraMode7.NEWER_PIXI_TILEMAP) {
|
|
vb = tile.createVb(false);
|
|
} else {
|
|
vb = tile.createVb();
|
|
this.vbs[vb.id] = vb;
|
|
}
|
|
this.vbIds[j] = vb.id;
|
|
this.vbBuffers[j] = null;
|
|
this.modificationMarkers[j] = 0;
|
|
this.vbArrays[j] = null;
|
|
}
|
|
const vao = vb.vao;
|
|
renderer.bindVao(vao);
|
|
const vertexBuf = vb.vb;
|
|
vertexBuf.bind();
|
|
const currentVertices = currentRectsCount * shader.vertPerQuad;
|
|
if (this.modificationMarkers[j] !== currentVertices) {
|
|
this.modificationMarkers[j] = currentVertices;
|
|
const vs = shader.stride * currentVertices;
|
|
if (!this.vbBuffers[j] || this.vbBuffers[j].byteLength < vs) {
|
|
var bk = shader.stride;
|
|
while (bk < vs) {
|
|
bk *= 2;
|
|
}
|
|
this.vbBuffers[j] = new ArrayBuffer(bk);
|
|
this.vbArrays[j] = new Float32Array(this.vbBuffers[j]);
|
|
vertexBuf.upload(this.vbBuffers[j], 0, true);
|
|
}
|
|
const arr = this.vbArrays[j];
|
|
var sz = 0;
|
|
const eps = 0.5;
|
|
for (
|
|
i = j * maxRects * 9;
|
|
i < points.length && i < (j + 1) * maxRects * 9;
|
|
i += 9
|
|
) {
|
|
const x = points[i + 2];
|
|
const y = points[i + 3];
|
|
const w = points[i + 4];
|
|
const h = points[i + 5];
|
|
const u = points[i] + 1024 * (points[i + 8] & 1);
|
|
const v = points[i + 1] + 1024 * ((points[i + 8] >> 1) & 1);
|
|
const animX = points[i + 6];
|
|
const animY = points[i + 7];
|
|
const textureId = points[i + 8] >> 2;
|
|
arr[sz++] = x;
|
|
arr[sz++] = y;
|
|
arr[sz++] = u;
|
|
arr[sz++] = v;
|
|
arr[sz++] = u + eps;
|
|
arr[sz++] = v + eps;
|
|
arr[sz++] = u + w - eps;
|
|
arr[sz++] = v + h - eps;
|
|
arr[sz++] = animX;
|
|
arr[sz++] = animY;
|
|
arr[sz++] = textureId;
|
|
arr[sz++] = x + w;
|
|
arr[sz++] = y;
|
|
arr[sz++] = u + w;
|
|
arr[sz++] = v;
|
|
arr[sz++] = u + eps;
|
|
arr[sz++] = v + eps;
|
|
arr[sz++] = u + w - eps;
|
|
arr[sz++] = v + h - eps;
|
|
arr[sz++] = animX;
|
|
arr[sz++] = animY;
|
|
arr[sz++] = textureId;
|
|
arr[sz++] = x + w;
|
|
arr[sz++] = y + h;
|
|
arr[sz++] = u + w;
|
|
arr[sz++] = v + h;
|
|
arr[sz++] = u + eps;
|
|
arr[sz++] = v + eps;
|
|
arr[sz++] = u + w - eps;
|
|
arr[sz++] = v + h - eps;
|
|
arr[sz++] = animX;
|
|
arr[sz++] = animY;
|
|
arr[sz++] = textureId;
|
|
arr[sz++] = x;
|
|
arr[sz++] = y + h;
|
|
arr[sz++] = u;
|
|
arr[sz++] = v + h;
|
|
arr[sz++] = u + eps;
|
|
arr[sz++] = v + eps;
|
|
arr[sz++] = u + w - eps;
|
|
arr[sz++] = v + h - eps;
|
|
arr[sz++] = animX;
|
|
arr[sz++] = animY;
|
|
arr[sz++] = textureId;
|
|
}
|
|
vertexBuf.upload(arr, 0, true);
|
|
}
|
|
gl.drawElements(
|
|
gl.TRIANGLES,
|
|
currentRectsCount * 6,
|
|
gl.UNSIGNED_SHORT,
|
|
0
|
|
);
|
|
}
|
|
};
|
|
|
|
//=============================================================================
|
|
// Tilemap
|
|
//=============================================================================
|
|
|
|
const UltraMode7_Tilemap_prototype_initialize = Tilemap.prototype.initialize;
|
|
Tilemap.prototype.initialize = function () {
|
|
if (!$gameMap.useUltraMode7) {
|
|
UltraMode7_Tilemap_prototype_initialize.call(this);
|
|
return;
|
|
}
|
|
PIXI.Container.call(this);
|
|
this._margin = 0;
|
|
this._width = $gameMap.width() * $gameMap.tileWidth();
|
|
this._height = $gameMap.height() * $gameMap.tileHeight();
|
|
this._tileWidth = 48;
|
|
this._tileHeight = 48;
|
|
this._mapWidth = 0;
|
|
this._mapHeight = 0;
|
|
this._mapData = null;
|
|
this._layerWidth = 0;
|
|
this._layerHeight = 0;
|
|
this._lastTiles = [];
|
|
this.bitmaps = [];
|
|
this.origin = new Point();
|
|
this.flags = [];
|
|
this.animationCount = 0;
|
|
this.horizontalWrap = false;
|
|
this.verticalWrap = false;
|
|
this._createLayers();
|
|
this.refresh();
|
|
};
|
|
|
|
//=============================================================================
|
|
// ShaderTilemap
|
|
//=============================================================================
|
|
|
|
const UltraMode7_ShaderTilemap_prototype_updateTransform =
|
|
ShaderTilemap.prototype.updateTransform;
|
|
ShaderTilemap.prototype.updateTransform = function () {
|
|
if (!$gameMap.useUltraMode7) {
|
|
UltraMode7_ShaderTilemap_prototype_updateTransform.call(this);
|
|
return;
|
|
}
|
|
var marginX = 0;
|
|
var marginY = 0;
|
|
if ($gameMap.isLoopHorizontal()) {
|
|
marginX =
|
|
($gameMap.ultraMode7LoopMapsExtendX +
|
|
UltraMode7.LOOP_MAPS_EXTEND_TILES) *
|
|
this._tileWidth -
|
|
Graphics.boxWidth / 2;
|
|
}
|
|
if ($gameMap.isLoopVertical()) {
|
|
marginY =
|
|
($gameMap.ultraMode7LoopMapsExtendY +
|
|
UltraMode7.LOOP_MAPS_EXTEND_TILES) *
|
|
this._tileHeight -
|
|
Graphics.boxHeight / 2;
|
|
}
|
|
const startX = Math.floor(-marginX / this._tileWidth);
|
|
const startY = Math.floor(-marginY / this._tileHeight);
|
|
if (
|
|
this._needsRepaint ||
|
|
this._lastStartX !== startX ||
|
|
this._lastStartY !== startY
|
|
) {
|
|
this._lastStartX = startX;
|
|
this._lastStartY = startY;
|
|
this._paintAllTiles(startX, startY);
|
|
this._needsRepaint = false;
|
|
}
|
|
this._sortChildren();
|
|
PIXI.Container.prototype.updateTransform.call(this);
|
|
};
|
|
|
|
const UltraMode7_ShaderTilemap_prototype__createLayers =
|
|
ShaderTilemap.prototype._createLayers;
|
|
ShaderTilemap.prototype._createLayers = function () {
|
|
if (!$gameMap.useUltraMode7) {
|
|
UltraMode7_ShaderTilemap_prototype__createLayers.call(this);
|
|
return;
|
|
}
|
|
// width/height forcing is needed, because some scripts manipulate the width and height values of the tilemap
|
|
this._width = $gameMap.width() * $gameMap.tileWidth();
|
|
this._height = $gameMap.height() * $gameMap.tileHeight();
|
|
if ($gameMap.isLoopHorizontal()) {
|
|
this._width += Graphics.boxWidth;
|
|
}
|
|
if ($gameMap.isLoopVertical()) {
|
|
this._height += Graphics.boxHeight;
|
|
}
|
|
const width = this._width;
|
|
const height = this._height;
|
|
const tileCols = Math.ceil(width / this._tileWidth) + 1;
|
|
const tileRows = Math.ceil(height / this._tileHeight) + 1;
|
|
this._layerWidth = tileCols * this._tileWidth;
|
|
this._layerHeight = tileRows * this._tileHeight;
|
|
this._needsRepaint = true;
|
|
if (!this.lowerZLayer) {
|
|
this.lowerZLayer = new PIXI.tilemap.ZLayer(this, 0);
|
|
this.upperZLayer = new PIXI.tilemap.ZLayer(this, 0);
|
|
this.addChild(this.lowerZLayer);
|
|
this.addChild(this.upperZLayer);
|
|
const parameters = PluginManager.parameters("ShaderTilemap");
|
|
const useSquareShader = Number(
|
|
parameters.hasOwnProperty("squareShader")
|
|
? parameters["squareShader"]
|
|
: 0
|
|
);
|
|
this.lowerLayer = new PIXI.tilemap.CompositeRectTileLayer(
|
|
0,
|
|
[],
|
|
useSquareShader
|
|
);
|
|
this.lowerLayer.shadowColor = new Float32Array([0.0, 0.0, 0.0, 0.5]);
|
|
this.lowerZLayer.addChild(this.lowerLayer);
|
|
this.upperLayer = new PIXI.tilemap.CompositeRectTileLayer(
|
|
0,
|
|
[],
|
|
useSquareShader
|
|
);
|
|
this.upperZLayer.addChild(this.upperLayer);
|
|
}
|
|
};
|
|
|
|
const UltraMode7_ShaderTilemap_prototype__paintAllTiles =
|
|
ShaderTilemap.prototype._paintAllTiles;
|
|
ShaderTilemap.prototype._paintAllTiles = function (startX, startY) {
|
|
if (!$gameMap.useUltraMode7) {
|
|
UltraMode7_ShaderTilemap_prototype__paintAllTiles.call(
|
|
this,
|
|
startX,
|
|
startY
|
|
);
|
|
return;
|
|
}
|
|
this.lowerZLayer.clear();
|
|
this.upperZLayer.clear();
|
|
const tileCols = Math.ceil(this._width / this._tileWidth);
|
|
const tileRows = Math.ceil(this._height / this._tileHeight);
|
|
for (var y = startY; y < tileRows - startY; ++y) {
|
|
for (var x = startX; x < tileCols - startX; ++x) {
|
|
this._paintTiles(0, 0, x, y);
|
|
}
|
|
}
|
|
};
|
|
|
|
//=============================================================================
|
|
// Game_CharacterBase
|
|
//=============================================================================
|
|
|
|
const UltraMode7_Game_CharacterBase_prototype_screenX =
|
|
Game_CharacterBase.prototype.screenX;
|
|
Game_CharacterBase.prototype.screenX = function () {
|
|
const x = UltraMode7_Game_CharacterBase_prototype_screenX.call(this);
|
|
if (!$gameMap.useUltraMode7) {
|
|
return x;
|
|
}
|
|
const y =
|
|
UltraMode7_Game_CharacterBase_prototype_screenY.call(this) +
|
|
this.shiftY();
|
|
return UltraMode7.mapToScreen(x, y).x;
|
|
};
|
|
|
|
const UltraMode7_Game_CharacterBase_prototype_screenY =
|
|
Game_CharacterBase.prototype.screenY;
|
|
Game_CharacterBase.prototype.screenY = function () {
|
|
var y = UltraMode7_Game_CharacterBase_prototype_screenY.call(this);
|
|
if (!$gameMap.useUltraMode7) {
|
|
return y;
|
|
}
|
|
y += this.shiftY();
|
|
const x = UltraMode7_Game_CharacterBase_prototype_screenX.call(this);
|
|
return UltraMode7.mapToScreen(x, y).y;
|
|
};
|
|
|
|
Game_CharacterBase.prototype.screenScale = function () {
|
|
if (!$gameMap.useUltraMode7) {
|
|
return 1.0;
|
|
}
|
|
const x = UltraMode7_Game_CharacterBase_prototype_screenX.call(this);
|
|
const y =
|
|
UltraMode7_Game_CharacterBase_prototype_screenY.call(this) +
|
|
this.shiftY();
|
|
return UltraMode7.mapToScreenScale(x, y);
|
|
};
|
|
|
|
Game_CharacterBase.prototype.isUltraMode7Visible = function (z) {
|
|
if (!$gameMap.useUltraMode7) {
|
|
return true;
|
|
}
|
|
if ($gameMap.ultraMode7Fov <= 0) {
|
|
return true;
|
|
}
|
|
if (!z) {
|
|
const x = UltraMode7_Game_CharacterBase_prototype_screenX.call(this);
|
|
const y =
|
|
UltraMode7_Game_CharacterBase_prototype_screenY.call(this) +
|
|
this.shiftY();
|
|
z = UltraMode7.mapToScreen(x, y).z;
|
|
}
|
|
return z > UltraMode7.NEAR_CLIP_Z && z < UltraMode7.FAR_CLIP_Z;
|
|
};
|
|
|
|
//=============================================================================
|
|
// Game_Player
|
|
//=============================================================================
|
|
|
|
const UltraMode7_Game_Player_prototype_getInputDirection =
|
|
Game_Player.prototype.getInputDirection;
|
|
Game_Player.prototype.getInputDirection = function () {
|
|
var result = UltraMode7_Game_Player_prototype_getInputDirection.call(this);
|
|
if (
|
|
$gameMap.useUltraMode7 &&
|
|
result > 0 &&
|
|
UltraMode7.PLAYER_ADJUST_MOVE_DIRECTION
|
|
) {
|
|
result = UltraMode7.rotateDirection(result, false);
|
|
}
|
|
return result;
|
|
};
|
|
|
|
//=============================================================================
|
|
// Game_Vehicle
|
|
//=============================================================================
|
|
|
|
Game_Vehicle.prototype.scrolledX = function () {
|
|
if (!$gameMap.useUltraMode7 || !$gameMap.isLoopHorizontal()) {
|
|
return Game_Character.prototype.scrolledX.call(this);
|
|
}
|
|
return $gameMap.adjustUltraMode7X(this._realX);
|
|
};
|
|
|
|
Game_Vehicle.prototype.scrolledY = function () {
|
|
if (!$gameMap.useUltraMode7 || !$gameMap.isLoopVertical()) {
|
|
return Game_Character.prototype.scrolledY.call(this);
|
|
}
|
|
return $gameMap.adjustUltraMode7Y(this._realY);
|
|
};
|
|
|
|
//=============================================================================
|
|
// Game_Event
|
|
//=============================================================================
|
|
|
|
Game_Event.prototype.scrolledX = function () {
|
|
if (!$gameMap.useUltraMode7 || !$gameMap.isLoopHorizontal()) {
|
|
return Game_Character.prototype.scrolledX.call(this);
|
|
}
|
|
return $gameMap.adjustUltraMode7X(this._realX);
|
|
};
|
|
|
|
Game_Event.prototype.scrolledY = function () {
|
|
if (!$gameMap.useUltraMode7 || !$gameMap.isLoopVertical()) {
|
|
return Game_Character.prototype.scrolledY.call(this);
|
|
}
|
|
return $gameMap.adjustUltraMode7Y(this._realY);
|
|
};
|
|
|
|
//=============================================================================
|
|
// Game_Map
|
|
//=============================================================================
|
|
|
|
Object.defineProperties(Game_Map.prototype, {
|
|
useUltraMode7: {
|
|
get: function () {
|
|
return this._useUltraMode7;
|
|
},
|
|
configurable: true,
|
|
},
|
|
ultraMode7Fov: {
|
|
get: function () {
|
|
return this._ultraMode7Fov;
|
|
},
|
|
configurable: true,
|
|
},
|
|
ultraMode7Pitch: {
|
|
get: function () {
|
|
return this._ultraMode7Pitch;
|
|
},
|
|
configurable: true,
|
|
},
|
|
ultraMode7Yaw: {
|
|
get: function () {
|
|
return this._ultraMode7Yaw;
|
|
},
|
|
configurable: true,
|
|
},
|
|
ultraMode7CameraDistance: {
|
|
get: function () {
|
|
return this._ultraMode7CameraDistance;
|
|
},
|
|
configurable: true,
|
|
},
|
|
ultraMode7CameraY: {
|
|
get: function () {
|
|
return this._ultraMode7CameraY;
|
|
},
|
|
configurable: true,
|
|
},
|
|
ultraMode7FadeColor: {
|
|
get: function () {
|
|
return this._ultraMode7FadeColor;
|
|
},
|
|
configurable: true,
|
|
},
|
|
ultraMode7FadeBegin: {
|
|
get: function () {
|
|
return this._ultraMode7FadeBegin;
|
|
},
|
|
configurable: true,
|
|
},
|
|
ultraMode7FadeEnd: {
|
|
get: function () {
|
|
return this._ultraMode7FadeEnd;
|
|
},
|
|
configurable: true,
|
|
},
|
|
ultraMode7ParallaxDistance: {
|
|
get: function () {
|
|
return this._ultraMode7ParallaxDistance;
|
|
},
|
|
configurable: true,
|
|
},
|
|
ultraMode7LoopMapsExtendX: {
|
|
get: function () {
|
|
return this._ultraMode7LoopMapsExtendX;
|
|
},
|
|
configurable: true,
|
|
},
|
|
ultraMode7LoopMapsExtendY: {
|
|
get: function () {
|
|
return this._ultraMode7LoopMapsExtendY;
|
|
},
|
|
configurable: true,
|
|
},
|
|
ultraMode7ProjectionMatrix: {
|
|
get: function () {
|
|
return this._ultraMode7ProjectionMatrix;
|
|
},
|
|
configurable: true,
|
|
},
|
|
ultraMode7ModelviewMatrix: {
|
|
get: function () {
|
|
return this._ultraMode7ModelviewMatrix;
|
|
},
|
|
configurable: true,
|
|
},
|
|
});
|
|
|
|
const UltraMode7_Game_Map_prototype_initialize =
|
|
Game_Map.prototype.initialize;
|
|
Game_Map.prototype.initialize = function () {
|
|
UltraMode7_Game_Map_prototype_initialize.call(this);
|
|
this.initUltraMode7();
|
|
};
|
|
|
|
const UltraMode7_Game_Map_prototype_setup = Game_Map.prototype.setup;
|
|
Game_Map.prototype.setup = function (mapId) {
|
|
UltraMode7_Game_Map_prototype_setup.call(this, mapId);
|
|
this.setupUltraMode7();
|
|
};
|
|
|
|
Game_Map.prototype.initUltraMode7 = function () {
|
|
this._useUltraMode7 = false;
|
|
this._ultraMode7Pitch = 0;
|
|
this._ultraMode7Yaw = 0;
|
|
this._ultraMode7CameraDistance = UltraMode7.DEFAULT_CAMERA_DISTANCE;
|
|
this._ultraMode7CameraY = UltraMode7.DEFAULT_CAMERA_Y;
|
|
this._ultraMode7ParallaxDistance = UltraMode7.DEFAULT_PARALLAX_DISTANCE;
|
|
this._ultraMode7FadeColor = UltraMode7.FADE_Z_COLOR.slice();
|
|
this._ultraMode7FadeBegin = UltraMode7.FADE_Z_BEGIN;
|
|
this._ultraMode7FadeEnd = UltraMode7.FADE_Z_END;
|
|
this._ultraMode7LoopMapsExtendX = 0;
|
|
this._ultraMode7LoopMapsExtendY = 0;
|
|
this._ultraMode7BorderLeft = 0;
|
|
this._ultraMode7BorderRight = 0;
|
|
this._ultraMode7BorderTop = 0;
|
|
this._ultraMode7BorderBottom = 0;
|
|
this._ultraMode7ProjectionMatrix = new Matrix4();
|
|
this._ultraMode7ModelviewMatrix = new Matrix4();
|
|
const eye = new Vector3(0, 0, this._ultraMode7CameraDistance);
|
|
const target = new Vector3(0, 0, 0);
|
|
const up = new Vector3(0, 1, 0);
|
|
this._ultraMode7ModelviewMatrix.lookAt(eye, target, up);
|
|
};
|
|
|
|
Game_Map.prototype.setupUltraMode7 = function () {
|
|
this.initUltraMode7();
|
|
if (!$dataMap) {
|
|
throw new Error("The map data is not available");
|
|
}
|
|
if (
|
|
$dataMap.meta &&
|
|
($dataMap.meta.UltraMode7 ||
|
|
$dataMap.meta.UltraMode7_FOV ||
|
|
$dataMap.meta.UltraMode7_Pitch ||
|
|
$dataMap.meta.UltraMode7_Yaw ||
|
|
$dataMap.meta.UltraMode7_CameraDistance ||
|
|
$dataMap.meta.UltraMode7_CameraY ||
|
|
$dataMap.meta.UltraMode7_FadeColor ||
|
|
$dataMap.meta.UltraMode7_ParallaxDistance)
|
|
) {
|
|
this._useUltraMode7 = true;
|
|
this._ultraMode7Fov = Math.max(
|
|
BlizzardUtility.Numeric(
|
|
$dataMap.meta.UltraMode7_FOV,
|
|
UltraMode7.DEFAULT_FOV
|
|
),
|
|
UltraMode7.MIN_FOV
|
|
);
|
|
this._ultraMode7Pitch = BlizzardUtility.Numeric(
|
|
$dataMap.meta.UltraMode7_Pitch,
|
|
UltraMode7.DEFAULT_PITCH
|
|
).clamp(UltraMode7.MIN_PITCH, UltraMode7.MAX_PITCH);
|
|
this._ultraMode7Yaw = BlizzardUtility.Numeric(
|
|
$dataMap.meta.UltraMode7_Yaw,
|
|
UltraMode7.DEFAULT_YAW
|
|
);
|
|
this._ultraMode7CameraDistance = Math.max(
|
|
BlizzardUtility.Numeric(
|
|
$dataMap.meta.UltraMode7_CameraDistance,
|
|
UltraMode7.DEFAULT_CAMERA_DISTANCE
|
|
),
|
|
0
|
|
);
|
|
this._ultraMode7CameraY = BlizzardUtility.Numeric(
|
|
$dataMap.meta.UltraMode7_CameraY,
|
|
UltraMode7.DEFAULT_CAMERA_Y
|
|
);
|
|
if ($dataMap.meta.UltraMode7_FadeColor) {
|
|
this._ultraMode7FadeColor = UltraMode7.validateFadeColor(
|
|
JSON.parse("[" + $dataMap.meta.UltraMode7_FadeColor + "]")
|
|
);
|
|
} else {
|
|
this._ultraMode7FadeColor = UltraMode7.FADE_Z_COLOR.slice();
|
|
}
|
|
this._ultraMode7FadeBegin = Math.max(
|
|
BlizzardUtility.Numeric(
|
|
$dataMap.meta.UltraMode7_FadeBegin,
|
|
UltraMode7.FADE_Z_BEGIN
|
|
),
|
|
UltraMode7.NEAR_CLIP_Z
|
|
);
|
|
this._ultraMode7FadeEnd = Math.max(
|
|
Math.min(
|
|
BlizzardUtility.Numeric(
|
|
$dataMap.meta.UltraMode7_FadeEnd,
|
|
UltraMode7.FADE_Z_END
|
|
),
|
|
UltraMode7.FAR_CLIP_Z
|
|
),
|
|
this._ultraMode7FadeBegin
|
|
);
|
|
this._ultraMode7ParallaxDistance = Math.max(
|
|
BlizzardUtility.Numeric(
|
|
$dataMap.meta.UltraMode7_ParallaxDistance,
|
|
UltraMode7.DEFAULT_PARALLAX_DISTANCE
|
|
),
|
|
1
|
|
);
|
|
this._ultraMode7LoopMapsExtendX = 0;
|
|
this._ultraMode7LoopMapsExtendY = 0;
|
|
// borders
|
|
this._ultraMode7BorderLeft = 0;
|
|
this._ultraMode7BorderRight = 0;
|
|
this._ultraMode7BorderTop = 0;
|
|
this._ultraMode7BorderBottom = 0;
|
|
if ($dataMap.meta.UltraMode7_Border) {
|
|
const border = BlizzardUtility.Numeric(
|
|
$dataMap.meta.UltraMode7_Border,
|
|
0
|
|
);
|
|
this._ultraMode7BorderLeft = border;
|
|
this._ultraMode7BorderRight = border;
|
|
this._ultraMode7BorderTop = border;
|
|
this._ultraMode7BorderBottom = border;
|
|
} else {
|
|
if ($dataMap.meta.UltraMode7_BorderHorizontal) {
|
|
const border = BlizzardUtility.Numeric(
|
|
$dataMap.meta.UltraMode7_BorderHorizontal,
|
|
0
|
|
);
|
|
this._ultraMode7BorderLeft = border;
|
|
this._ultraMode7BorderRight = border;
|
|
} else {
|
|
this._ultraMode7BorderLeft = BlizzardUtility.Numeric(
|
|
$dataMap.meta.UltraMode7_BorderLeft,
|
|
0
|
|
);
|
|
this._ultraMode7BorderRight = BlizzardUtility.Numeric(
|
|
$dataMap.meta.UltraMode7_BorderRight,
|
|
0
|
|
);
|
|
}
|
|
if ($dataMap.meta.UltraMode7_BorderVertical) {
|
|
const border = BlizzardUtility.Numeric(
|
|
$dataMap.meta.UltraMode7_BorderVertical,
|
|
0
|
|
);
|
|
this._ultraMode7BorderTop = border;
|
|
this._ultraMode7BorderBottom = border;
|
|
} else {
|
|
this._ultraMode7BorderTop = BlizzardUtility.Numeric(
|
|
$dataMap.meta.UltraMode7_BorderTop,
|
|
0
|
|
);
|
|
this._ultraMode7BorderBottom = BlizzardUtility.Numeric(
|
|
$dataMap.meta.UltraMode7_BorderBottom,
|
|
0
|
|
);
|
|
}
|
|
}
|
|
this.refreshUltraMode7View();
|
|
}
|
|
};
|
|
|
|
Game_Map.prototype.setUltraMode7Fov = function (value) {
|
|
if (!this._useUltraMode7) {
|
|
return;
|
|
}
|
|
this._ultraMode7Fov = Math.max(value, UltraMode7.MIN_FOV); // more or less arbitrary limit, but there are huge issues with smaller values
|
|
this.refreshUltraMode7View();
|
|
};
|
|
|
|
Game_Map.prototype.setUltraMode7Pitch = function (value) {
|
|
if (!this._useUltraMode7) {
|
|
return;
|
|
}
|
|
this._ultraMode7Pitch = value.clamp(
|
|
UltraMode7.MIN_PITCH,
|
|
UltraMode7.MAX_PITCH
|
|
);
|
|
this.refreshUltraMode7View();
|
|
};
|
|
|
|
Game_Map.prototype.setUltraMode7Yaw = function (value) {
|
|
if (!this._useUltraMode7) {
|
|
return;
|
|
}
|
|
this._ultraMode7Yaw = value;
|
|
this.refreshUltraMode7View();
|
|
};
|
|
|
|
Game_Map.prototype.setUltraMode7CameraDistance = function (value) {
|
|
if (!this._useUltraMode7) {
|
|
return;
|
|
}
|
|
this._ultraMode7CameraDistance = Math.max(value, 0);
|
|
this.refreshUltraMode7View();
|
|
};
|
|
|
|
Game_Map.prototype.setUltraMode7CameraY = function (value) {
|
|
if (!this._useUltraMode7) {
|
|
return;
|
|
}
|
|
this._ultraMode7CameraY = value;
|
|
this.refreshUltraMode7View();
|
|
};
|
|
|
|
Game_Map.prototype.setUltraMode7ParallaxDistance = function (value) {
|
|
if (!this._useUltraMode7) {
|
|
return;
|
|
}
|
|
this._ultraMode7ParallaxDistance = Math.max(value, 1);
|
|
this.refreshUltraMode7View();
|
|
};
|
|
|
|
Game_Map.prototype.refreshUltraMode7View = function () {
|
|
if (!this._useUltraMode7) {
|
|
return;
|
|
}
|
|
if (this.isLoopHorizontal() || this.isLoopVertical()) {
|
|
const halfFov = (this._ultraMode7Fov * Math.PI) / 180;
|
|
const sideVector = UltraMode7.FAR_CLIP_Z / Math.cos(halfFov);
|
|
var maxVector = Math.abs(
|
|
sideVector /
|
|
Math.cos((halfFov * Graphics.boxHeight) / Graphics.boxWidth)
|
|
);
|
|
maxVector =
|
|
(maxVector * this._ultraMode7CameraDistance) / UltraMode7.FAR_CLIP_Z;
|
|
this._ultraMode7LoopMapsExtendX =
|
|
Math.ceil(maxVector / this.tileWidth()) + 1; // +1, because the tile coordinate is centered in Mode7
|
|
this._ultraMode7LoopMapsExtendY =
|
|
Math.ceil(maxVector / this.tileHeight()) + 1; // +1, because the tile coordinate is centered in Mode7
|
|
} else {
|
|
this._ultraMode7LoopMapsExtendX = 0;
|
|
this._ultraMode7LoopMapsExtendY = 0;
|
|
}
|
|
// setup the matrices
|
|
if (this._ultraMode7Fov > 0) {
|
|
this._ultraMode7ProjectionMatrix.setPerspective(
|
|
this._ultraMode7Fov,
|
|
Graphics.boxWidth,
|
|
Graphics.boxHeight,
|
|
UltraMode7.NEAR_CLIP_Z,
|
|
UltraMode7.FAR_CLIP_Z
|
|
);
|
|
} else {
|
|
this._ultraMode7ProjectionMatrix.setOrthoProjection(
|
|
0,
|
|
0,
|
|
Graphics.boxWidth,
|
|
Graphics.boxHeight
|
|
);
|
|
}
|
|
const eye = new Vector3(0, 0, this._ultraMode7CameraDistance);
|
|
const target = new Vector3(0, 0, 0);
|
|
const up = new Vector3(0, 1, 0);
|
|
this._ultraMode7ModelviewMatrix.lookAt(eye, target, up);
|
|
this._ultraMode7ModelviewMatrix.translate($gameScreen.shake(), 0, 0);
|
|
this._ultraMode7ModelviewMatrix.rotateX(this._ultraMode7Pitch);
|
|
this._ultraMode7ModelviewMatrix.rotateZ(this._ultraMode7Yaw);
|
|
this._ultraMode7ModelviewMatrix.translate(
|
|
-Graphics.boxWidth / 2 - this.displayX() * this.tileWidth(),
|
|
-Graphics.boxHeight / 2 - (this.displayY() + 0.5) * this.tileHeight(),
|
|
-this._ultraMode7CameraY
|
|
);
|
|
};
|
|
|
|
Game_Map.prototype.adjustUltraMode7X = function (x) {
|
|
const centerX = this.width() / 2;
|
|
const displayCenterX = centerX - this.screenTileX() / 2;
|
|
if (x >= centerX) {
|
|
if (this._displayX < displayCenterX) {
|
|
return x - this._displayX - $dataMap.width;
|
|
}
|
|
} else if (this._displayX >= displayCenterX) {
|
|
return x - this._displayX + $dataMap.width;
|
|
}
|
|
return x - this._displayX;
|
|
};
|
|
|
|
Game_Map.prototype.adjustUltraMode7Y = function (y) {
|
|
const centerY = this.height() / 2;
|
|
const displayCenterY = centerY - this.screenTileY() / 2;
|
|
if (y >= centerY) {
|
|
if (this._displayY < displayCenterY) {
|
|
return y - this._displayY - $dataMap.height;
|
|
}
|
|
} else if (this._displayY >= displayCenterY) {
|
|
return y - this._displayY + $dataMap.height;
|
|
}
|
|
return y - this._displayY;
|
|
};
|
|
|
|
const UltraMode7_Game_Map_prototype_parallaxOx =
|
|
Game_Map.prototype.parallaxOx;
|
|
Game_Map.prototype.parallaxOx = function () {
|
|
if (!this._useUltraMode7) {
|
|
return UltraMode7_Game_Map_prototype_parallaxOx.call(this);
|
|
}
|
|
const offset =
|
|
(-2 *
|
|
UltraMode7.DEFAULT_PARALLAX_DISTANCE *
|
|
Math.PI *
|
|
this._ultraMode7Yaw) /
|
|
360;
|
|
if (this._parallaxZero) {
|
|
return (
|
|
this._parallaxX *
|
|
UltraMode7.PARALLAX_SCROLL_X_MULTIPLIER *
|
|
this.tileWidth() +
|
|
offset
|
|
);
|
|
}
|
|
if (this._parallaxLoopX) {
|
|
return (
|
|
(this._parallaxX *
|
|
UltraMode7.PARALLAX_SCROLL_X_MULTIPLIER *
|
|
this.tileWidth()) /
|
|
2 +
|
|
offset
|
|
);
|
|
}
|
|
return 0;
|
|
};
|
|
|
|
const UltraMode7_Game_Map_prototype_parallaxOy =
|
|
Game_Map.prototype.parallaxOy;
|
|
Game_Map.prototype.parallaxOy = function () {
|
|
if (!this._useUltraMode7) {
|
|
return UltraMode7_Game_Map_prototype_parallaxOy.call(this);
|
|
}
|
|
const offset =
|
|
(-2 *
|
|
UltraMode7.DEFAULT_PARALLAX_DISTANCE *
|
|
Math.PI *
|
|
this._ultraMode7Pitch) /
|
|
360;
|
|
if (this._parallaxZero) {
|
|
return (
|
|
this._parallaxY *
|
|
UltraMode7.PARALLAX_SCROLL_Y_MULTIPLIER *
|
|
this.tileHeight() +
|
|
offset
|
|
);
|
|
}
|
|
if (this._parallaxLoopY) {
|
|
return (
|
|
(this._parallaxY *
|
|
UltraMode7.PARALLAX_SCROLL_Y_MULTIPLIER *
|
|
this.tileHeight()) /
|
|
2 +
|
|
offset
|
|
);
|
|
}
|
|
return 0;
|
|
};
|
|
|
|
Game_Map.prototype.clampUltraMode7DisplayX = function (x) {
|
|
const screenTileX = this.screenTileX();
|
|
const left = -(screenTileX - 1) * 0.5 + this._ultraMode7BorderLeft;
|
|
const right =
|
|
this.width() - (screenTileX + 1) * 0.5 - this._ultraMode7BorderRight;
|
|
const width =
|
|
this.width() - (this._ultraMode7BorderLeft + this._ultraMode7BorderRight);
|
|
return width < 0 ? width / 2 : x.clamp(left, right);
|
|
};
|
|
|
|
Game_Map.prototype.clampUltraMode7DisplayY = function (y) {
|
|
const screenTileY = this.screenTileY();
|
|
const top = -(screenTileY - 1) * 0.5 + this._ultraMode7BorderTop;
|
|
const bottom =
|
|
this.height() - (screenTileY + 1) * 0.5 - this._ultraMode7BorderBottom;
|
|
const height =
|
|
this.height() -
|
|
(this._ultraMode7BorderTop + this._ultraMode7BorderBottom);
|
|
return height < 0 ? height / 2 : y.clamp(top, bottom);
|
|
};
|
|
|
|
const UltraMode7_Game_Map_prototype_setDisplayPos =
|
|
Game_Map.prototype.setDisplayPos;
|
|
Game_Map.prototype.setDisplayPos = function (x, y) {
|
|
if (!this._useUltraMode7) {
|
|
UltraMode7_Game_Map_prototype_setDisplayPos.call(this, x, y);
|
|
return;
|
|
}
|
|
if (this.isLoopHorizontal()) {
|
|
this._displayX = x.mod(this.width());
|
|
this._parallaxX = x;
|
|
} else {
|
|
this._displayX = this.clampUltraMode7DisplayX(x);
|
|
this._parallaxX = this._displayX;
|
|
}
|
|
if (this.isLoopVertical()) {
|
|
this._displayY = y.mod(this.height());
|
|
this._parallaxY = y;
|
|
} else {
|
|
this._displayY = this.clampUltraMode7DisplayY(y);
|
|
this._parallaxY = this._displayY;
|
|
}
|
|
this.refreshUltraMode7View();
|
|
};
|
|
|
|
const UltraMode7_Game_Map_prototype_scrollDown =
|
|
Game_Map.prototype.scrollDown;
|
|
Game_Map.prototype.scrollDown = function (distance) {
|
|
if (!this._useUltraMode7) {
|
|
UltraMode7_Game_Map_prototype_scrollDown.call(this, distance);
|
|
return;
|
|
}
|
|
if (this.isLoopVertical()) {
|
|
this._displayY = (this._displayY + distance) % $dataMap.height;
|
|
if (this._parallaxLoopY) {
|
|
this._parallaxY += distance;
|
|
}
|
|
} else {
|
|
const lastY = this._displayY;
|
|
this._displayY = this.clampUltraMode7DisplayY(this._displayY + distance);
|
|
this._parallaxY += this._displayY - lastY;
|
|
}
|
|
this.refreshUltraMode7View();
|
|
};
|
|
|
|
const UltraMode7_Game_Map_prototype_scrollLeft =
|
|
Game_Map.prototype.scrollLeft;
|
|
Game_Map.prototype.scrollLeft = function (distance) {
|
|
if (!this._useUltraMode7) {
|
|
UltraMode7_Game_Map_prototype_scrollLeft.call(this, distance);
|
|
return;
|
|
}
|
|
if (this.isLoopHorizontal()) {
|
|
this._displayX =
|
|
(this._displayX + $dataMap.width - distance) % $dataMap.width;
|
|
if (this._parallaxLoopX) {
|
|
this._parallaxX -= distance;
|
|
}
|
|
} else {
|
|
const lastX = this._displayX;
|
|
this._displayX = this.clampUltraMode7DisplayX(this._displayX - distance);
|
|
this._parallaxX += this._displayX - lastX;
|
|
}
|
|
this.refreshUltraMode7View();
|
|
};
|
|
|
|
const UltraMode7_Game_Map_prototype_scrollRight =
|
|
Game_Map.prototype.scrollRight;
|
|
Game_Map.prototype.scrollRight = function (distance) {
|
|
if (!this._useUltraMode7) {
|
|
UltraMode7_Game_Map_prototype_scrollRight.call(this, distance);
|
|
return;
|
|
}
|
|
if (this.isLoopHorizontal()) {
|
|
this._displayX = (this._displayX + distance) % $dataMap.width;
|
|
if (this._parallaxLoopX) {
|
|
this._parallaxX += distance;
|
|
}
|
|
} else {
|
|
const lastX = this._displayX;
|
|
this._displayX = this.clampUltraMode7DisplayX(this._displayX + distance);
|
|
this._parallaxX += this._displayX - lastX;
|
|
}
|
|
this.refreshUltraMode7View();
|
|
};
|
|
|
|
const UltraMode7_Game_Map_prototype_scrollUp = Game_Map.prototype.scrollUp;
|
|
Game_Map.prototype.scrollUp = function (distance) {
|
|
if (!this._useUltraMode7) {
|
|
UltraMode7_Game_Map_prototype_scrollUp.call(this, distance);
|
|
return;
|
|
}
|
|
if (this.isLoopVertical()) {
|
|
this._displayY =
|
|
(this._displayY + $dataMap.height - distance) % $dataMap.height;
|
|
if (this._parallaxLoopY) {
|
|
this._parallaxY -= distance;
|
|
}
|
|
} else {
|
|
const lastY = this._displayY;
|
|
this._displayY = this.clampUltraMode7DisplayY(this._displayY - distance);
|
|
this._parallaxY += this._displayY - lastY;
|
|
}
|
|
this.refreshUltraMode7View();
|
|
};
|
|
|
|
const UltraMode7_Game_Map_prototype_update = Game_Map.prototype.update;
|
|
Game_Map.prototype.update = function (sceneActive) {
|
|
UltraMode7_Game_Map_prototype_update.call(this, sceneActive);
|
|
if (this._useUltraMode7) {
|
|
this.updateUltraMode7();
|
|
}
|
|
};
|
|
|
|
Game_Map.prototype.updateUltraMode7 = function () {
|
|
var needRefresh = false;
|
|
const shake = $gameScreen.shake();
|
|
if (this._ultraMode7Shake != shake) {
|
|
this._ultraMode7Shake = shake;
|
|
needRefresh = true;
|
|
}
|
|
if (
|
|
this._ultraMode7FovDuration !== undefined &&
|
|
this._ultraMode7FovDuration > 0
|
|
) {
|
|
const duration = this._ultraMode7FovDuration;
|
|
this._ultraMode7Fov = Math.max(
|
|
(this._ultraMode7Fov * (duration - 1) + this._ultraMode7FovTarget) /
|
|
duration,
|
|
UltraMode7.MIN_FOV
|
|
);
|
|
--this._ultraMode7FovDuration;
|
|
needRefresh = true;
|
|
}
|
|
if (
|
|
this._ultraMode7PitchDuration !== undefined &&
|
|
this._ultraMode7PitchDuration > 0
|
|
) {
|
|
const duration = this._ultraMode7PitchDuration;
|
|
this._ultraMode7Pitch = (
|
|
(this._ultraMode7Pitch * (duration - 1) + this._ultraMode7PitchTarget) /
|
|
duration
|
|
).clamp(UltraMode7.MIN_PITCH, UltraMode7.MAX_PITCH);
|
|
--this._ultraMode7PitchDuration;
|
|
needRefresh = true;
|
|
}
|
|
if (
|
|
this._ultraMode7YawDuration !== undefined &&
|
|
this._ultraMode7YawDuration > 0
|
|
) {
|
|
const duration = this._ultraMode7YawDuration;
|
|
this._ultraMode7Yaw =
|
|
(this._ultraMode7Yaw * (duration - 1) + this._ultraMode7YawTarget) /
|
|
duration;
|
|
--this._ultraMode7YawDuration;
|
|
needRefresh = true;
|
|
}
|
|
if (
|
|
this._ultraMode7CameraDistanceDuration !== undefined &&
|
|
this._ultraMode7CameraDistanceDuration > 0
|
|
) {
|
|
const duration = this._ultraMode7CameraDistanceDuration;
|
|
this._ultraMode7CameraDistance = Math.max(
|
|
(this._ultraMode7CameraDistance * (duration - 1) +
|
|
this._ultraMode7CameraDistanceTarget) /
|
|
duration,
|
|
0
|
|
);
|
|
--this._ultraMode7CameraDistanceDuration;
|
|
needRefresh = true;
|
|
}
|
|
if (
|
|
this._ultraMode7CameraYDuration !== undefined &&
|
|
this._ultraMode7CameraYDuration > 0
|
|
) {
|
|
const duration = this._ultraMode7CameraYDuration;
|
|
this._ultraMode7CameraY =
|
|
(this._ultraMode7CameraY * (duration - 1) +
|
|
this._ultraMode7CameraYTarget) /
|
|
duration;
|
|
--this._ultraMode7CameraYDuration;
|
|
needRefresh = true;
|
|
}
|
|
if (
|
|
this._ultraMode7FadeColorDuration !== undefined &&
|
|
this._ultraMode7FadeColorDuration > 0
|
|
) {
|
|
const duration = this._ultraMode7FadeColorDuration;
|
|
for (var i = 0; i < this._ultraMode7FadeColor.length; ++i) {
|
|
this._ultraMode7FadeColor[i] = Math.max(
|
|
(this._ultraMode7FadeColor[i] * (duration - 1) +
|
|
this._ultraMode7FadeColorTarget[i]) /
|
|
duration,
|
|
0
|
|
);
|
|
}
|
|
--this._ultraMode7FadeColorDuration;
|
|
needRefresh = true;
|
|
}
|
|
if (
|
|
this._ultraMode7FadeBeginDuration !== undefined &&
|
|
this._ultraMode7FadeBeginDuration > 0
|
|
) {
|
|
const duration = this._ultraMode7FadeBeginDuration;
|
|
this._ultraMode7FadeBegin = Math.max(
|
|
(this._ultraMode7FadeBegin * (duration - 1) +
|
|
this._ultraMode7FadeBeginTarget) /
|
|
duration,
|
|
0
|
|
);
|
|
--this._ultraMode7FadeBeginDuration;
|
|
needRefresh = true;
|
|
}
|
|
if (
|
|
this._ultraMode7FadeEndDuration !== undefined &&
|
|
this._ultraMode7FadeEndDuration > 0
|
|
) {
|
|
const duration = this._ultraMode7FadeEndDuration;
|
|
this._ultraMode7FadeEnd = Math.max(
|
|
(this._ultraMode7FadeEnd * (duration - 1) +
|
|
this._ultraMode7FadeEndTarget) /
|
|
duration,
|
|
0
|
|
);
|
|
--this._ultraMode7FadeEndDuration;
|
|
needRefresh = true;
|
|
}
|
|
if (needRefresh) {
|
|
this.refreshUltraMode7View();
|
|
}
|
|
};
|
|
|
|
Game_Map.prototype.animateUltraMode7Fov = function (target, frameDuration) {
|
|
this._ultraMode7FovTarget = target;
|
|
this._ultraMode7FovDuration = frameDuration;
|
|
};
|
|
|
|
Game_Map.prototype.animateUltraMode7Pitch = function (target, frameDuration) {
|
|
this._ultraMode7PitchTarget = target;
|
|
this._ultraMode7PitchDuration = frameDuration;
|
|
};
|
|
|
|
Game_Map.prototype.animateUltraMode7Yaw = function (target, frameDuration) {
|
|
this._ultraMode7YawTarget = target;
|
|
this._ultraMode7YawDuration = frameDuration;
|
|
};
|
|
|
|
Game_Map.prototype.animateUltraMode7CameraDistance = function (
|
|
target,
|
|
frameDuration
|
|
) {
|
|
this._ultraMode7CameraDistanceTarget = target;
|
|
this._ultraMode7CameraDistanceDuration = frameDuration;
|
|
};
|
|
|
|
Game_Map.prototype.animateUltraMode7CameraY = function (
|
|
target,
|
|
frameDuration
|
|
) {
|
|
this._ultraMode7CameraYTarget = target;
|
|
this._ultraMode7CameraYDuration = frameDuration;
|
|
};
|
|
|
|
Game_Map.prototype.animateUltraMode7FadeColor = function (
|
|
target,
|
|
frameDuration
|
|
) {
|
|
this._ultraMode7FadeColorTarget = UltraMode7.validateFadeColor(target);
|
|
this._ultraMode7FadeColorDuration = frameDuration;
|
|
};
|
|
|
|
Game_Map.prototype.animateUltraMode7FadeBegin = function (
|
|
target,
|
|
frameDuration
|
|
) {
|
|
this._ultraMode7FadeBeginTarget = target;
|
|
this._ultraMode7FadeBeginDuration = frameDuration;
|
|
};
|
|
|
|
Game_Map.prototype.animateUltraMode7FadeEnd = function (
|
|
target,
|
|
frameDuration
|
|
) {
|
|
this._ultraMode7FadeEndTarget = target;
|
|
this._ultraMode7FadeEndDuration = frameDuration;
|
|
};
|
|
|
|
//=============================================================================
|
|
// Sprite_Character
|
|
//=============================================================================
|
|
|
|
const UltraMode7_Sprite_Character_prototype_updateBitmap =
|
|
Sprite_Character.prototype.updateBitmap;
|
|
Sprite_Character.prototype.updateBitmap = function () {
|
|
const imageChanged = this.isImageChanged();
|
|
UltraMode7_Sprite_Character_prototype_updateBitmap.call(this);
|
|
if ($gameMap.useUltraMode7 && imageChanged && this.bitmap) {
|
|
this.bitmap.smooth = !UltraMode7.CHARACTERS_PIXELATED;
|
|
}
|
|
};
|
|
|
|
const UltraMode7_Sprite_Character_prototype_characterPatternY =
|
|
Sprite_Character.prototype.characterPatternY;
|
|
Sprite_Character.prototype.characterPatternY = function () {
|
|
if (
|
|
!$gameMap.useUltraMode7 ||
|
|
!UltraMode7.CHARACTERS_ADJUST_SPRITE_DIRECTION
|
|
) {
|
|
return UltraMode7_Sprite_Character_prototype_characterPatternY.call(this);
|
|
}
|
|
return (
|
|
(UltraMode7.rotateDirection(this._character.direction(), true) - 2) / 2
|
|
);
|
|
};
|
|
|
|
const UltraMode7_Sprite_Character_prototype_updatePosition =
|
|
Sprite_Character.prototype.updatePosition;
|
|
Sprite_Character.prototype.updatePosition = function () {
|
|
UltraMode7_Sprite_Character_prototype_updatePosition.call(this);
|
|
if (!$gameMap.useUltraMode7) {
|
|
return;
|
|
}
|
|
const scale = this._character.screenScale();
|
|
this.scale.x = scale;
|
|
this.scale.y = scale;
|
|
};
|
|
|
|
//=============================================================================
|
|
// Sprite_Character
|
|
//=============================================================================
|
|
|
|
const UltraMode7_Sprite_Character_prototype_updateVisibility =
|
|
Sprite_Character.prototype.updateVisibility;
|
|
Sprite_Character.prototype.updateVisibility = function () {
|
|
UltraMode7_Sprite_Character_prototype_updateVisibility.call(this);
|
|
if (!$gameMap.useUltraMode7) {
|
|
return;
|
|
}
|
|
if (!this._character.isUltraMode7Visible()) {
|
|
this.visible = false;
|
|
}
|
|
};
|
|
|
|
//=============================================================================
|
|
// Sprite_Destination
|
|
//=============================================================================
|
|
|
|
const UltraMode7_Sprite_Destination_prototype_updatePosition =
|
|
Sprite_Destination.prototype.updatePosition;
|
|
Sprite_Destination.prototype.updatePosition = function () {
|
|
UltraMode7_Sprite_Destination_prototype_updatePosition.call(this);
|
|
if (!$gameMap.useUltraMode7) {
|
|
return;
|
|
}
|
|
const position = UltraMode7.mapToScreen(this.x, this.y);
|
|
this.x = position.x;
|
|
this.y = position.y;
|
|
};
|
|
|
|
//=============================================================================
|
|
// Scene_Map
|
|
//=============================================================================
|
|
|
|
const UltraMode7_Scene_Map_prototype_processMapTouch =
|
|
Scene_Map.prototype.processMapTouch;
|
|
Scene_Map.prototype.processMapTouch = function () {
|
|
if (!$gameMap.useUltraMode7) {
|
|
UltraMode7_Scene_Map_prototype_processMapTouch.call(this);
|
|
return;
|
|
}
|
|
if (TouchInput.isTriggered() || this._touchCount > 0) {
|
|
if (TouchInput.isPressed()) {
|
|
if (this._touchCount === 0 || this._touchCount >= 15) {
|
|
const position = UltraMode7.screenToMap(TouchInput.x, TouchInput.y);
|
|
$gameTemp.setDestination(
|
|
Math.floor(position.x / $gameMap.tileWidth()),
|
|
Math.floor(position.y / $gameMap.tileHeight())
|
|
);
|
|
}
|
|
++this._touchCount;
|
|
} else {
|
|
this._touchCount = 0;
|
|
}
|
|
}
|
|
};
|
|
|
|
//=============================================================================
|
|
// MOG's Character Motion compatibility
|
|
//=============================================================================
|
|
|
|
if (Imported && Imported.MOG_CharacterMotion) {
|
|
UltraMode7.log(
|
|
"Detected 'MOG'S Character Motion', enabling compatibility code."
|
|
);
|
|
|
|
//=============================================================================
|
|
// Sprite_Character
|
|
//=============================================================================
|
|
|
|
const UltraMode7_Sprite_Character_prototype_updateSprParameters =
|
|
Sprite_Character.prototype.updateSprParameters;
|
|
Sprite_Character.prototype.updateSprParameters = function () {
|
|
UltraMode7_Sprite_Character_prototype_updateSprParameters.call(this);
|
|
if (!$gameMap.useUltraMode7) {
|
|
return;
|
|
}
|
|
// some safety guards
|
|
if (this._character && this._character.screenScale) {
|
|
const scale = this._character.screenScale();
|
|
this.scale.x *= scale;
|
|
this.scale.y *= scale;
|
|
}
|
|
};
|
|
}
|
|
|
|
//=============================================================================
|
|
// Yanfly's Gridfree Doodads compatibility
|
|
//=============================================================================
|
|
|
|
if (Imported && Imported.YEP_GridFreeDoodads) {
|
|
UltraMode7.log(
|
|
"Detected 'Yanfly's Gridfree Doodads', enabling compatibility code."
|
|
);
|
|
|
|
//=============================================================================
|
|
// Sprite_Doodad
|
|
//=============================================================================
|
|
|
|
const UltraMode7_Sprite_Doodad_updatePosition =
|
|
Sprite_Doodad.prototype.updatePosition;
|
|
Sprite_Doodad.prototype.updatePosition = function () {
|
|
UltraMode7_Sprite_Doodad_updatePosition.call(this);
|
|
if (!$gameMap.useUltraMode7) {
|
|
return;
|
|
}
|
|
const scale = this.screenScale();
|
|
this.scale.x = (scale * this._data.scaleX) / 100;
|
|
this.scale.y = (scale * this._data.scaleY) / 100;
|
|
if (!this.isUltraMode7Visible()) {
|
|
this.visible = false;
|
|
}
|
|
};
|
|
|
|
const UltraMode7_Sprite_Doodad_prototype_screenX =
|
|
Sprite_Doodad.prototype.screenX;
|
|
Sprite_Doodad.prototype.screenX = function () {
|
|
const x = UltraMode7_Sprite_Doodad_prototype_screenX.call(this);
|
|
if (!$gameMap.useUltraMode7) {
|
|
return x;
|
|
}
|
|
const y = UltraMode7_Sprite_Doodad_prototype_screenY.call(this);
|
|
return UltraMode7.mapToScreen(x, y).x;
|
|
};
|
|
|
|
const UltraMode7_Sprite_Doodad_prototype_screenY =
|
|
Sprite_Doodad.prototype.screenY;
|
|
Sprite_Doodad.prototype.screenY = function () {
|
|
const y = UltraMode7_Sprite_Doodad_prototype_screenY.call(this);
|
|
if (!$gameMap.useUltraMode7) {
|
|
return y;
|
|
}
|
|
const x = UltraMode7_Sprite_Doodad_prototype_screenX.call(this);
|
|
return UltraMode7.mapToScreen(x, y).y;
|
|
};
|
|
|
|
Sprite_Doodad.prototype.screenScale = function () {
|
|
if (!$gameMap.useUltraMode7) {
|
|
return 1.0;
|
|
}
|
|
const x = UltraMode7_Sprite_Doodad_prototype_screenX.call(this);
|
|
const y = UltraMode7_Sprite_Doodad_prototype_screenY.call(this);
|
|
return UltraMode7.mapToScreenScale(x, y);
|
|
};
|
|
|
|
Sprite_Doodad.prototype.isUltraMode7Visible = function (z) {
|
|
if (!$gameMap.useUltraMode7) {
|
|
return true;
|
|
}
|
|
if ($gameMap.ultraMode7Fov <= 0) {
|
|
return true;
|
|
}
|
|
if (!z) {
|
|
const x = UltraMode7_Sprite_Doodad_prototype_screenX.call(this);
|
|
const y = UltraMode7_Sprite_Doodad_prototype_screenY.call(this);
|
|
z = UltraMode7.mapToScreen(x, y).z;
|
|
}
|
|
return z > UltraMode7.NEAR_CLIP_Z && z < UltraMode7.FAR_CLIP_Z;
|
|
};
|
|
|
|
//=============================================================================
|
|
// Sprite_DoodadCursor
|
|
//=============================================================================
|
|
|
|
const UltraMode7_Sprite_DoodadCursor_prototype_updatePosition =
|
|
Sprite_DoodadCursor.prototype.updatePosition;
|
|
Sprite_DoodadCursor.prototype.updatePosition = function () {
|
|
UltraMode7_Sprite_DoodadCursor_prototype_updatePosition.call(this);
|
|
if (!$gameMap.useUltraMode7) {
|
|
return;
|
|
}
|
|
const scale = this.screenScale();
|
|
this.scale.x = (scale * this._data.scaleX) / 100;
|
|
this.scale.y = (scale * this._data.scaleY) / 100;
|
|
};
|
|
|
|
Sprite_DoodadCursor.prototype.screenScale = function () {
|
|
if (!$gameMap.useUltraMode7) {
|
|
return 1.0;
|
|
}
|
|
const position = UltraMode7.screenToMap(this.x, this.y);
|
|
const x = Math.round(
|
|
$gameMap.adjustUltraMode7X(position.x / $gameMap.tileWidth()) *
|
|
$gameMap.tileWidth()
|
|
);
|
|
const y = Math.round(
|
|
$gameMap.adjustUltraMode7Y(position.y / $gameMap.tileHeight()) *
|
|
$gameMap.tileHeight()
|
|
);
|
|
return UltraMode7.mapToScreenScale(x, y);
|
|
};
|
|
|
|
Sprite_DoodadCursor.prototype.ultraMode7ScreenScale = function (x, y) {
|
|
if (!$gameMap.useUltraMode7) {
|
|
return 1.0;
|
|
}
|
|
return UltraMode7.mapToScreenScale(x, y);
|
|
};
|
|
|
|
DoodadManager.getUltraMode7DoodadScreenX = function (x) {
|
|
return x - $gameMap.displayX() * $gameMap.tileWidth();
|
|
};
|
|
|
|
DoodadManager.getUltraMode7DoodadScreenY = function (y) {
|
|
return y - $gameMap.displayY() * $gameMap.tileHeight();
|
|
};
|
|
|
|
const UltraMode7_DoodadManager_addNew = DoodadManager.addNew;
|
|
DoodadManager.addNew = function (doodad) {
|
|
if ($gameMap.useUltraMode7) {
|
|
const position = UltraMode7.screenToMap(
|
|
DoodadManager.getUltraMode7DoodadScreenX(doodad.x),
|
|
DoodadManager.getUltraMode7DoodadScreenY(doodad.y)
|
|
);
|
|
doodad.x = position.x;
|
|
doodad.y = position.y;
|
|
}
|
|
UltraMode7_DoodadManager_addNew.call(this, doodad);
|
|
};
|
|
}
|
|
|
|
//=============================================================================
|
|
// KhasUltraLighting compatibility
|
|
//=============================================================================
|
|
|
|
UltraMode7.Khas = Khas || {}; // prevents an undefined reference error right below
|
|
|
|
if (
|
|
UltraMode7.Khas &&
|
|
UltraMode7.Khas.Lighting &&
|
|
UltraMode7.Khas.Lighting.version >= 4.2
|
|
) {
|
|
UltraMode7.log(
|
|
"Detected 'KhasUltraLighting', enabling compatibility code."
|
|
);
|
|
|
|
//=============================================================================
|
|
// Game_CharacterBase
|
|
//=============================================================================
|
|
|
|
Game_CharacterBase.prototype.lightScreenUltraMode7X = function () {
|
|
return Math.round(
|
|
(this.scrolledX() + 0.5) * $gameMap.tileWidth() + $gameScreen.shake()
|
|
);
|
|
};
|
|
|
|
Game_CharacterBase.prototype.lightScreenUltraMode7Y = function () {
|
|
return Math.round((this.scrolledY() + 0.5) * $gameMap.tileHeight());
|
|
};
|
|
|
|
const UltraMode7_Game_CharacterBase_prototype_lightScreenX =
|
|
Game_CharacterBase.prototype.lightScreenX;
|
|
Game_CharacterBase.prototype.lightScreenX = function () {
|
|
if (!$gameMap.useUltraMode7) {
|
|
return UltraMode7_Game_CharacterBase_prototype_lightScreenX.call(this);
|
|
}
|
|
const x = this.lightScreenUltraMode7X();
|
|
const y = this.lightScreenUltraMode7Y() + $gameMap.tileHeight() / 2;
|
|
return UltraMode7.mapToScreen(x, y).x;
|
|
};
|
|
|
|
const UltraMode7_Game_CharacterBase_prototype_lightScreenY =
|
|
Game_CharacterBase.prototype.lightScreenY;
|
|
Game_CharacterBase.prototype.lightScreenY = function () {
|
|
if (!$gameMap.useUltraMode7) {
|
|
return UltraMode7_Game_CharacterBase_prototype_lightScreenY.call(this);
|
|
}
|
|
const halfTileHeight = $gameMap.tileHeight() / 2;
|
|
const x = this.lightScreenUltraMode7X();
|
|
const y = this.lightScreenUltraMode7Y() + halfTileHeight;
|
|
return (
|
|
UltraMode7.mapToScreen(x, y).y - halfTileHeight * this.screenScale()
|
|
);
|
|
};
|
|
|
|
//=============================================================================
|
|
// Game_LightTile
|
|
//=============================================================================
|
|
|
|
Game_LightTile.prototype.scrolledX = function () {
|
|
if (!$gameMap.useUltraMode7 || !$gameMap.isLoopHorizontal()) {
|
|
return $gameMap.adjustX(this._realX);
|
|
}
|
|
return $gameMap.adjustUltraMode7X(this._realX);
|
|
};
|
|
|
|
Game_LightTile.prototype.scrolledY = function () {
|
|
if (!$gameMap.useUltraMode7 || !$gameMap.isLoopVertical()) {
|
|
return $gameMap.adjustY(this._realY);
|
|
}
|
|
return $gameMap.adjustUltraMode7Y(this._realY);
|
|
};
|
|
|
|
Game_LightTile.prototype.lightScreenUltraMode7X = function () {
|
|
return Math.round(
|
|
this.scrolledX() * $gameMap.tileWidth() + $gameScreen.shake()
|
|
);
|
|
};
|
|
|
|
Game_LightTile.prototype.lightScreenUltraMode7Y = function () {
|
|
return Math.round(this.scrolledY() * $gameMap.tileHeight());
|
|
};
|
|
|
|
Game_LightTile.prototype.screenScale = function () {
|
|
if (!$gameMap.useUltraMode7) {
|
|
return 1.0;
|
|
}
|
|
const x = this.lightScreenUltraMode7X() + $gameMap.tileWidth() / 2;
|
|
const y = this.lightScreenUltraMode7Y() + $gameMap.tileHeight() / 2;
|
|
return UltraMode7.mapToScreenScale(x, y);
|
|
};
|
|
|
|
Game_LightTile.prototype.isUltraMode7Visible = function (z) {
|
|
if (!$gameMap.useUltraMode7) {
|
|
return true;
|
|
}
|
|
if ($gameMap.ultraMode7Fov <= 0) {
|
|
return true;
|
|
}
|
|
if (!z) {
|
|
const x = this.lightScreenUltraMode7X() + $gameMap.tileWidth() / 2;
|
|
const y = this.lightScreenUltraMode7Y() + $gameMap.tileHeight() / 2;
|
|
z = UltraMode7.mapToScreen(x, y).z;
|
|
}
|
|
return z > UltraMode7.NEAR_CLIP_Z && z < UltraMode7.FAR_CLIP_Z;
|
|
};
|
|
|
|
const UltraMode7_Game_LightTile_prototype_lightScreenX =
|
|
Game_LightTile.prototype.lightScreenX;
|
|
Game_LightTile.prototype.lightScreenX = function () {
|
|
if (!$gameMap.useUltraMode7) {
|
|
return UltraMode7_Game_LightTile_prototype_lightScreenX.call(this);
|
|
}
|
|
const x = this.lightScreenUltraMode7X();
|
|
const y = this.lightScreenUltraMode7Y() + $gameMap.tileHeight() / 2;
|
|
return UltraMode7.mapToScreen(x, y).x;
|
|
};
|
|
|
|
const UltraMode7_Game_LightTile_prototype_lightScreenY =
|
|
Game_LightTile.prototype.lightScreenY;
|
|
Game_LightTile.prototype.lightScreenY = function () {
|
|
if (!$gameMap.useUltraMode7) {
|
|
return UltraMode7_Game_LightTile_prototype_lightScreenY.call(this);
|
|
}
|
|
const halfTileHeight = $gameMap.tileHeight() / 2;
|
|
const x = this.lightScreenUltraMode7X();
|
|
const y = this.lightScreenUltraMode7Y() + halfTileHeight;
|
|
return (
|
|
UltraMode7.mapToScreen(x, y).y - halfTileHeight * this.screenScale()
|
|
);
|
|
};
|
|
|
|
//=============================================================================
|
|
// Sprite_Light
|
|
//=============================================================================
|
|
|
|
const UltraMode7_Sprite_Light_prototype_refreshScreenPosition =
|
|
Sprite_Light.prototype.refreshScreenPosition;
|
|
Sprite_Light.prototype.refreshScreenPosition = function () {
|
|
UltraMode7_Sprite_Light_prototype_refreshScreenPosition.call(this);
|
|
if (!$gameMap.useUltraMode7) {
|
|
return;
|
|
}
|
|
// some safety guards to ensure compatibility with custom objects
|
|
if (this._character) {
|
|
if (this._character.screenScale) {
|
|
const scale = this._character.screenScale();
|
|
this.scale.x = scale;
|
|
this.scale.y = scale;
|
|
}
|
|
if (this._character.isUltraMode7Visible) {
|
|
this.visible = this._character.isUltraMode7Visible();
|
|
}
|
|
}
|
|
};
|
|
}
|
|
|
|
//=============================================================================
|
|
// MOG's Character Motion compatibility
|
|
//=============================================================================
|
|
|
|
if (Imported && Imported.Soul_ThomasEdisonMV) {
|
|
UltraMode7.log("Detected 'Thomas Edison MV', enabling compatibility code.");
|
|
|
|
//=============================================================================
|
|
// EdisonLightMVCustom
|
|
//=============================================================================
|
|
|
|
const UltraMode7_EdisonLightMVCustom_prototype_updateLight =
|
|
EdisonLightMVCustom.prototype.updateLight;
|
|
EdisonLightMVCustom.prototype.updateLight = function () {
|
|
UltraMode7_EdisonLightMVCustom_prototype_updateLight.call(this);
|
|
if (!$gameMap.useUltraMode7) {
|
|
return;
|
|
}
|
|
const character = $gameMap._events[this.eventId];
|
|
// some safety guards
|
|
if (character && character.screenScale) {
|
|
const scale = character.screenScale();
|
|
this.lightImage.x += (scale - 1) * this.ax;
|
|
this.lightImage.y += (scale - 1) * this.ay;
|
|
this.lightImage.scale.x *= scale;
|
|
this.lightImage.scale.y *= scale;
|
|
}
|
|
};
|
|
|
|
//=============================================================================
|
|
// EdisonLightMV
|
|
//=============================================================================
|
|
|
|
const UltraMode7_EdisonLightMV_prototype_updateLight =
|
|
EdisonLightMV.prototype.updateLight;
|
|
EdisonLightMV.prototype.updateLight = function () {
|
|
UltraMode7_EdisonLightMV_prototype_updateLight.call(this);
|
|
if (!$gameMap.useUltraMode7) {
|
|
return;
|
|
}
|
|
const character = $gameMap._events[this.eventId];
|
|
// some safety guards
|
|
if (character && character.screenScale) {
|
|
const scale = character.screenScale();
|
|
const ax = this.lightImage.x - character.screenX();
|
|
const ay = this.lightImage.y - character.screenY();
|
|
this.lightImage.x += (scale - 1) * ax;
|
|
this.lightImage.y += (scale - 1) * ay;
|
|
this.lightImage.scale.x *= scale;
|
|
this.lightImage.scale.y *= scale;
|
|
}
|
|
};
|
|
}
|
|
|
|
//=============================================================================
|
|
// Quasi Simple Shadows compatibility
|
|
//=============================================================================
|
|
|
|
if (Imported && Imported.QuasiSimpleShadows) {
|
|
UltraMode7.log(
|
|
"Detected 'Quasi Simple Shadows', enabling compatibility code."
|
|
);
|
|
|
|
//=============================================================================
|
|
// Sprite_CharacterShadow
|
|
//=============================================================================
|
|
|
|
const UltraMode7_Sprite_CharacterShadow_prototype_updateScaleOpacity =
|
|
Sprite_CharacterShadow.prototype.updateScaleOpacity;
|
|
Sprite_CharacterShadow.prototype.updateScaleOpacity = function () {
|
|
UltraMode7_Sprite_CharacterShadow_prototype_updateScaleOpacity.call(this);
|
|
if (!$gameMap.useUltraMode7) {
|
|
return;
|
|
}
|
|
if (this._character && this._character.screenScale) {
|
|
const scale = this._character.screenScale();
|
|
this.scale.x *= scale;
|
|
this.scale.y *= scale;
|
|
}
|
|
};
|
|
}
|
|
|
|
//=============================================================================
|
|
})();
|